Advertisement
Guest User

Untitled

a guest
Apr 13th, 2020
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 113.49 KB | None | 0 0
  1. #pragma semicolon 1
  2.  
  3. #include <sourcemod>
  4. #include <basecomm>
  5. #include "include/sourcecomms.inc"
  6.  
  7. #undef REQUIRE_PLUGIN
  8. #include <adminmenu>
  9. #include <updater>
  10.  
  11. #define UNBLOCK_FLAG ADMFLAG_CUSTOM2
  12. #define DATABASE "sourcecomms"
  13.  
  14. // #define DEBUG
  15. // #define LOG_QUERIES
  16.  
  17. // Do not edit below this line //
  18. //-----------------------------//
  19.  
  20. #define PLUGIN_VERSION "0.9.266"
  21. #define PREFIX "\x04[SourceComms]\x01 "
  22.  
  23. #define UPDATE_URL "http://s.ppalex.com/updater/sourcecomms-0.9/sc-updatefile.txt"
  24.  
  25. #define MAX_TIME_MULTI 30 // maximum mass-target punishment length
  26.  
  27. #define NOW 0
  28. #define TYPE_TEMP_SHIFT 10
  29.  
  30. #define TYPE_MUTE 1
  31. #define TYPE_GAG 2
  32. #define TYPE_SILENCE 3
  33. #define TYPE_UNMUTE 4
  34. #define TYPE_UNGAG 5
  35. #define TYPE_UNSILENCE 6
  36. #define TYPE_TEMP_UNMUTE 14 // TYPE_TEMP_SHIFT + TYPE_UNMUTE
  37. #define TYPE_TEMP_UNGAG 15 // TYPE_TEMP_SHIFT + TYPE_UNGAG
  38. #define TYPE_TEMP_UNSILENCE 16 // TYPE_TEMP_SHIFT + TYPE_UNSILENCE
  39.  
  40. #define MAX_REASONS 32
  41. #define DISPLAY_SIZE 64
  42. #define REASON_SIZE 192
  43.  
  44. new iNumReasons;
  45. new String:g_sReasonDisplays[MAX_REASONS][DISPLAY_SIZE], String:g_sReasonKey[MAX_REASONS][REASON_SIZE];
  46.  
  47. #define MAX_TIMES 32
  48. new iNumTimes, g_iTimeMinutes[MAX_TIMES];
  49. new String:g_sTimeDisplays[MAX_TIMES][DISPLAY_SIZE];
  50.  
  51. enum State /* ConfigState */
  52. {
  53. ConfigStateNone = 0,
  54. ConfigStateConfig,
  55. ConfigStateReasons,
  56. ConfigStateTimes,
  57. ConfigStateServers,
  58. }
  59. enum DatabaseState /* Database connection state */
  60. {
  61. DatabaseState_None = 0,
  62. DatabaseState_Wait,
  63. DatabaseState_Connecting,
  64. DatabaseState_Connected,
  65. }
  66.  
  67. new DatabaseState:g_DatabaseState;
  68. new g_iConnectLock = 0;
  69. new g_iSequence = 0;
  70.  
  71. new State:ConfigState;
  72. new Handle:ConfigParser;
  73.  
  74. new Handle:hTopMenu = INVALID_HANDLE;
  75.  
  76. /* Cvar handle*/
  77. new Handle:CvarHostIp;
  78. new Handle:CvarPort;
  79.  
  80. new String:ServerIp[24];
  81. new String:ServerPort[7];
  82.  
  83. /* Database handle */
  84. new Handle:g_hDatabase;
  85. new Handle:SQLiteDB;
  86.  
  87. new String:DatabasePrefix[10] = "sb";
  88.  
  89. /* Timer handles */
  90. new Handle:g_hPlayerRecheck[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
  91. new Handle:g_hGagExpireTimer[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
  92. new Handle:g_hMuteExpireTimer[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
  93.  
  94.  
  95. /* Log Stuff */
  96. #if defined LOG_QUERIES
  97. new String:logQuery[256];
  98. #endif
  99.  
  100. new Float:RetryTime = 15.0;
  101. new DefaultTime = 30;
  102. new DisUBImCheck = 0;
  103. new ConsoleImmunity = 0;
  104. new ConfigMaxLength = 0;
  105. new ConfigWhiteListOnly = 0;
  106. new serverID = 0;
  107.  
  108. /* List menu */
  109. enum PeskyPanels
  110. {
  111. curTarget,
  112. curIndex,
  113. viewingMute,
  114. viewingGag,
  115. viewingList,
  116. }
  117. new g_iPeskyPanels[MAXPLAYERS + 1][PeskyPanels];
  118.  
  119. new bool:g_bPlayerStatus[MAXPLAYERS + 1]; // Player block check status
  120. new String:g_sName[MAXPLAYERS + 1][MAX_NAME_LENGTH];
  121.  
  122. new bType:g_MuteType[MAXPLAYERS + 1];
  123. new g_iMuteTime[MAXPLAYERS + 1];
  124. new g_iMuteLength[MAXPLAYERS + 1]; // in sec
  125. new g_iMuteLevel[MAXPLAYERS + 1]; // immunity level of admin
  126. new String:g_sMuteAdminName[MAXPLAYERS + 1][MAX_NAME_LENGTH];
  127. new String:g_sMuteReason[MAXPLAYERS + 1][256];
  128. new String:g_sMuteAdminAuth[MAXPLAYERS + 1][64];
  129.  
  130. new bType:g_GagType[MAXPLAYERS + 1];
  131. new g_iGagTime[MAXPLAYERS + 1];
  132. new g_iGagLength[MAXPLAYERS + 1]; // in sec
  133. new g_iGagLevel[MAXPLAYERS + 1]; // immunity level of admin
  134. new String:g_sGagAdminName[MAXPLAYERS + 1][MAX_NAME_LENGTH];
  135. new String:g_sGagReason[MAXPLAYERS + 1][256];
  136. new String:g_sGagAdminAuth[MAXPLAYERS + 1][64];
  137.  
  138. new Handle:g_hServersWhiteList = INVALID_HANDLE;
  139.  
  140. public Plugin:myinfo =
  141. {
  142. name = "SourceComms",
  143. author = "Alex",
  144. description = "Advanced punishments management for the Source engine in SourceBans style",
  145. version = PLUGIN_VERSION,
  146. url = "https://forums.alliedmods.net/showthread.php?t=207176"
  147. };
  148.  
  149. public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
  150. {
  151. CreateNative("SourceComms_SetClientMute", Native_SetClientMute);
  152. CreateNative("SourceComms_SetClientGag", Native_SetClientGag);
  153. CreateNative("SourceComms_GetClientMuteType", Native_GetClientMuteType);
  154. CreateNative("SourceComms_GetClientGagType", Native_GetClientGagType);
  155. MarkNativeAsOptional("SQL_SetCharset");
  156. RegPluginLibrary("sourcecomms");
  157. return APLRes_Success;
  158. }
  159.  
  160. public OnPluginStart()
  161. {
  162. LoadTranslations("common.phrases");
  163. LoadTranslations("sourcecomms.phrases");
  164.  
  165. new Handle:hTemp = INVALID_HANDLE;
  166. if (LibraryExists("adminmenu") && ((hTemp = GetAdminTopMenu()) != INVALID_HANDLE))
  167. OnAdminMenuReady(hTemp);
  168.  
  169. CvarHostIp = FindConVar("hostip");
  170. CvarPort = FindConVar("hostport");
  171. g_hServersWhiteList = CreateArray();
  172.  
  173. CreateConVar("sourcecomms_version", PLUGIN_VERSION, _, FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
  174. AddCommandListener(CommandCallback, "sm_gag");
  175. AddCommandListener(CommandCallback, "sm_mute");
  176. AddCommandListener(CommandCallback, "sm_silence");
  177. AddCommandListener(CommandCallback, "sm_ungag");
  178. AddCommandListener(CommandCallback, "sm_unmute");
  179. AddCommandListener(CommandCallback, "sm_unsilence");
  180. RegServerCmd("sc_fw_block", FWBlock, "Blocking player comms by command from sourceban web site", FCVAR_PLUGIN);
  181. RegServerCmd("sc_fw_ungag", FWUngag, "Ungagging player by command from sourceban web site", FCVAR_PLUGIN);
  182. RegServerCmd("sc_fw_unmute",FWUnmute, "Unmuting player by command from sourceban web site", FCVAR_PLUGIN);
  183. RegConsoleCmd("sm_comms", CommandComms, "Shows current player communications status", FCVAR_PLUGIN);
  184.  
  185. HookEvent("player_changename", Event_OnPlayerName, EventHookMode_Post);
  186.  
  187. #if defined LOG_QUERIES
  188. BuildPath(Path_SM, logQuery, sizeof(logQuery), "logs/sourcecomms-q.log");
  189. #endif
  190.  
  191. #if defined DEBUG
  192. PrintToServer("Sourcecomms plugin loading. Version %s", PLUGIN_VERSION);
  193. #endif
  194.  
  195. // Catch config error
  196. if (!SQL_CheckConfig(DATABASE))
  197. {
  198. SetFailState("Database failure: could not find database conf %s", DATABASE);
  199. return;
  200. }
  201. DB_Connect();
  202. InitializeBackupDB();
  203.  
  204. ServerInfo();
  205.  
  206. if (LibraryExists("updater"))
  207. {
  208. Updater_AddPlugin(UPDATE_URL);
  209. }
  210. }
  211.  
  212. public OnLibraryAdded(const String:name[])
  213. {
  214. if (StrEqual(name, "updater"))
  215. {
  216. Updater_AddPlugin(UPDATE_URL);
  217. }
  218. }
  219.  
  220. public Updater_OnPluginUpdated()
  221. {
  222. LogMessage("Plugin updated. Old version was %s. Now reloading.", PLUGIN_VERSION);
  223.  
  224. ReloadPlugin();
  225. }
  226.  
  227. public OnLibraryRemoved(const String:name[])
  228. {
  229. if (StrEqual(name, "adminmenu"))
  230. hTopMenu = INVALID_HANDLE;
  231. }
  232.  
  233. public OnMapStart()
  234. {
  235. ReadConfig();
  236. }
  237.  
  238. public OnMapEnd()
  239. {
  240. // Clean up on map end just so we can start a fresh connection when we need it later.
  241. // Also it is necessary for using SQL_SetCharset
  242. if(g_hDatabase)
  243. CloseHandle(g_hDatabase);
  244.  
  245. g_hDatabase = INVALID_HANDLE;
  246. }
  247.  
  248.  
  249. // CLIENT CONNECTION FUNCTIONS //
  250.  
  251. public OnClientDisconnect(client)
  252. {
  253. if (g_hPlayerRecheck[client] != INVALID_HANDLE && CloseHandle(g_hPlayerRecheck[client]))
  254. g_hPlayerRecheck[client] = INVALID_HANDLE;
  255.  
  256. CloseMuteExpireTimer(client);
  257. CloseGagExpireTimer(client);
  258. }
  259.  
  260. public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
  261. {
  262. g_bPlayerStatus[client] = false;
  263. return true;
  264. }
  265.  
  266. public OnClientConnected(client)
  267. {
  268. g_sName[client][0] = '\0';
  269.  
  270. MarkClientAsUnMuted(client);
  271. MarkClientAsUnGagged(client);
  272. }
  273.  
  274. public OnClientPostAdminCheck(client)
  275. {
  276. decl String:clientAuth[64];
  277. GetClientAuthString(client, clientAuth, sizeof(clientAuth));
  278. GetClientName(client, g_sName[client], sizeof(g_sName[]));
  279.  
  280. /* Do not check bots or check player with lan steamid. */
  281. if (clientAuth[0] == 'B' || clientAuth[9] == 'L' || !DB_Connect())
  282. {
  283. g_bPlayerStatus[client] = true;
  284. return;
  285. }
  286.  
  287. if (client > 0 && IsClientInGame(client) && !IsFakeClient(client))
  288. {
  289. // if plugin was late loaded
  290. if (BaseComm_IsClientMuted(client))
  291. {
  292. MarkClientAsMuted(client);
  293. }
  294. if (BaseComm_IsClientGagged(client))
  295. {
  296. MarkClientAsGagged(client);
  297. }
  298.  
  299. new String:sClAuthYZEscaped[sizeof(clientAuth) * 2 + 1];
  300. SQL_EscapeString(g_hDatabase, clientAuth[8], sClAuthYZEscaped, sizeof(sClAuthYZEscaped));
  301.  
  302. decl String:Query[4096];
  303. FormatEx(Query, sizeof(Query),
  304. "SELECT (c.ends - UNIX_TIMESTAMP()) AS remaining, \
  305. c.length, c.type, c.created, c.reason, a.user, \
  306. IF (a.immunity>=g.immunity, a.immunity, IFNULL(g.immunity,0)) AS immunity, \
  307. c.aid, c.sid, a.authid \
  308. FROM %s_comms AS c \
  309. LEFT JOIN %s_admins AS a ON a.aid = c.aid \
  310. LEFT JOIN %s_srvgroups AS g ON g.name = a.srv_group \
  311. WHERE RemoveType IS NULL \
  312. AND c.authid REGEXP '^STEAM_[0-9]:%s$' \
  313. AND (length = '0' OR ends > UNIX_TIMESTAMP())",
  314. DatabasePrefix, DatabasePrefix, DatabasePrefix, sClAuthYZEscaped);
  315. #if defined LOG_QUERIES
  316. LogToFile(logQuery, "OnClientPostAdminCheck for: %s. QUERY: %s", clientAuth, Query);
  317. #endif
  318. SQL_TQuery(g_hDatabase, Query_VerifyBlock, Query, GetClientUserId(client), DBPrio_High);
  319. }
  320. }
  321.  
  322.  
  323. // OTHER CLIENT CODE //
  324.  
  325. public Action:Event_OnPlayerName(Handle:event, const String:name[], bool:dontBroadcast)
  326. {
  327. new client = GetClientOfUserId(GetEventInt(event, "userid"));
  328. if (client > 0 && IsClientInGame(client))
  329. GetEventString(event, "newname", g_sName[client], sizeof(g_sName[]));
  330. }
  331.  
  332. public BaseComm_OnClientMute(client, bool:muteState)
  333. {
  334. if (client > 0 && client <= MaxClients)
  335. {
  336. if (muteState)
  337. {
  338. if (g_MuteType[client] == bNot)
  339. {
  340. MarkClientAsMuted(client, _, _, _, _, _, "Muted through BaseComm natives");
  341. SavePunishment(_, client, TYPE_MUTE, _, "Muted through BaseComm natives");
  342. }
  343. }
  344. else
  345. {
  346. if (g_MuteType[client] > bNot)
  347. {
  348. MarkClientAsUnMuted(client);
  349. }
  350. }
  351. }
  352. }
  353.  
  354. public BaseComm_OnClientGag(client, bool:gagState)
  355. {
  356. if (client > 0 && client <= MaxClients)
  357. {
  358. if (gagState)
  359. {
  360. if (g_GagType[client] == bNot)
  361. {
  362. MarkClientAsGagged(client, _, _, _, _, _, "Gagged through BaseComm natives");
  363. SavePunishment(_, client, TYPE_GAG, _, "Gagged through BaseComm natives");
  364. }
  365. }
  366. else
  367. {
  368. if (g_GagType[client] > bNot)
  369. {
  370. MarkClientAsUnGagged(client);
  371. }
  372. }
  373. }
  374. }
  375.  
  376. // COMMAND CODE //
  377.  
  378. public Action:CommandComms(client, args)
  379. {
  380. if (!client)
  381. {
  382. ReplyToCommand(client, "%s%t", PREFIX, "CommandComms_na");
  383. return Plugin_Continue;
  384. }
  385.  
  386. if (g_MuteType[client] > bNot || g_GagType[client] > bNot)
  387. AdminMenu_ListTarget(client, client, 0);
  388. else
  389. ReplyToCommand(client, "%s%t", PREFIX, "CommandComms_nb");
  390.  
  391. return Plugin_Handled;
  392. }
  393.  
  394. public Action:FWBlock(args)
  395. {
  396. new String:arg_string[256], String:sArg[3][64];
  397. GetCmdArgString(arg_string, sizeof(arg_string));
  398.  
  399. new type, length;
  400. if(ExplodeString(arg_string, " ", sArg, 3, 64) != 3 || !StringToIntEx(sArg[0], type) || type < 1 || type > 3 || !StringToIntEx(sArg[1], length))
  401. {
  402. LogError("Wrong usage of sc_fw_block");
  403. return Plugin_Stop;
  404. }
  405.  
  406. LogMessage("Received block command from web: steam %s, type %d, length %d", sArg[2], type, length);
  407.  
  408. for (new i = 1; i <= MaxClients; i++)
  409. {
  410. if (IsClientInGame(i) && IsClientAuthorized(i) && !IsFakeClient(i))
  411. {
  412. decl String:clientAuth[64];
  413. GetClientAuthString(i, clientAuth, sizeof(clientAuth));
  414. if (strcmp(clientAuth, sArg[2], false) == 0)
  415. {
  416. #if defined DEBUG
  417. PrintToServer("Catched %s for blocking from web", clientAuth);
  418. #endif
  419.  
  420. if (g_MuteType[i] == bNot && (type == 1 || type == 3))
  421. {
  422. PerformMute(i, _, length / 60, _, _, _, _);
  423. PrintToChat(i, "%s%t", PREFIX, "Muted on connect");
  424. LogMessage("%s is muted from web", clientAuth);
  425. }
  426. if (g_GagType[i] == bNot && (type == 2 || type == 3))
  427. {
  428. PerformGag(i, _, length / 60, _, _, _, _);
  429. PrintToChat(i, "%s%t", PREFIX, "Gagged on connect");
  430. LogMessage("%s is gagged from web", clientAuth);
  431. }
  432. break;
  433. }
  434. }
  435. }
  436.  
  437. return Plugin_Handled;
  438. }
  439.  
  440. public Action:FWUngag(args)
  441. {
  442. new String:arg_string[256], String:sArg[1][64];
  443. GetCmdArgString(arg_string, sizeof(arg_string));
  444. if(!ExplodeString(arg_string, " ", sArg, 1, 64))
  445. {
  446. LogError("Wrong usage of sc_fw_ungag");
  447. return Plugin_Stop;
  448. }
  449.  
  450. LogMessage("Received ungag command from web: steam %s", sArg[0]);
  451.  
  452. for (new i = 1; i <= MaxClients; i++)
  453. {
  454. if (IsClientInGame(i) && IsClientAuthorized(i) && !IsFakeClient(i))
  455. {
  456. decl String:clientAuth[64];
  457. GetClientAuthString(i, clientAuth, sizeof(clientAuth));
  458. if (strcmp(clientAuth, sArg[0], false) == 0)
  459. {
  460. #if defined DEBUG
  461. PrintToServer("Catched %s for ungagging from web", clientAuth);
  462. #endif
  463.  
  464. if (g_GagType[i] > bNot)
  465. {
  466. PerformUnGag(i);
  467. PrintToChat(i, "%s%t", PREFIX, "FWUngag");
  468. LogMessage("%s is ungagged from web", clientAuth);
  469. }
  470. else
  471. LogError("Can't ungag %s from web, it isn't gagged", clientAuth);
  472. break;
  473. }
  474. }
  475. }
  476. return Plugin_Handled;
  477. }
  478.  
  479. public Action:FWUnmute(args)
  480. {
  481. new String:arg_string[256], String:sArg[1][64];
  482. GetCmdArgString(arg_string, sizeof(arg_string));
  483. if(!ExplodeString(arg_string, " ", sArg, 1, 64))
  484. {
  485. LogError("Wrong usage of sc_fw_ungag");
  486. return Plugin_Stop;
  487. }
  488.  
  489. LogMessage("Received unmute command from web: steam %s", sArg[0]);
  490.  
  491. for (new i = 1; i <= MaxClients; i++)
  492. {
  493. if (IsClientInGame(i) && IsClientAuthorized(i) && !IsFakeClient(i))
  494. {
  495. decl String:clientAuth[64];
  496. GetClientAuthString(i, clientAuth, sizeof(clientAuth));
  497. if (strcmp(clientAuth, sArg[0], false) == 0)
  498. {
  499. #if defined DEBUG
  500. PrintToServer("Catched %s for unmuting from web", clientAuth);
  501. #endif
  502.  
  503. if (g_MuteType[i] > bNot)
  504. {
  505. PerformUnMute(i);
  506. PrintToChat(i, "%s%t", PREFIX, "FWUnmute");
  507. LogMessage("%s is unmuted from web", clientAuth);
  508. }
  509. else
  510. LogError("Can't unmute %s from web, it isn't muted", clientAuth);
  511. break;
  512. }
  513. }
  514. }
  515. return Plugin_Handled;
  516. }
  517.  
  518.  
  519. public Action:CommandCallback(client, const String:command[], args)
  520. {
  521. if (client && !CheckCommandAccess(client, command, ADMFLAG_CHAT))
  522. return Plugin_Continue;
  523.  
  524. new type;
  525. if (StrEqual(command, "sm_gag", false))
  526. type = TYPE_GAG;
  527. else if (StrEqual(command, "sm_mute", false))
  528. type = TYPE_MUTE;
  529. else if (StrEqual(command, "sm_ungag", false))
  530. type = TYPE_UNGAG;
  531. else if (StrEqual(command, "sm_unmute", false))
  532. type = TYPE_UNMUTE;
  533. else if (StrEqual(command, "sm_silence", false))
  534. type = TYPE_SILENCE;
  535. else if (StrEqual(command, "sm_unsilence", false))
  536. type = TYPE_UNSILENCE;
  537. else
  538. return Plugin_Stop;
  539.  
  540. if (args < 1)
  541. {
  542. ReplyToCommand(client, "%sUsage: %s <#userid|name> %s", PREFIX, command, type <= TYPE_SILENCE ? "[time|0] [reason]" : "[reason]");
  543. if (type <= TYPE_SILENCE)
  544. ReplyToCommand(client, "%sUsage: %s <#userid|name> [reason]", PREFIX, command);
  545. return Plugin_Stop;
  546. }
  547.  
  548. new String:sBuffer[256];
  549. GetCmdArgString(sBuffer, sizeof(sBuffer));
  550.  
  551. if (type <= TYPE_SILENCE)
  552. CreateBlock(client, _, _, type, _, sBuffer);
  553. else
  554. ProcessUnBlock(client, _, type, _, sBuffer);
  555.  
  556. return Plugin_Stop;
  557. }
  558.  
  559.  
  560. // MENU CODE //
  561.  
  562. public OnAdminMenuReady(Handle:topmenu)
  563. {
  564. /* Block us from being called twice */
  565. if (topmenu == hTopMenu)
  566. return;
  567.  
  568. /* Save the Handle */
  569. hTopMenu = topmenu;
  570.  
  571. new TopMenuObject:MenuObject = AddToTopMenu(hTopMenu, "sourcecomm_cmds", TopMenuObject_Category, Handle_Commands, INVALID_TOPMENUOBJECT);
  572. if (MenuObject == INVALID_TOPMENUOBJECT)
  573. return;
  574.  
  575. AddToTopMenu(hTopMenu, "sourcecomm_gag", TopMenuObject_Item, Handle_MenuGag, MenuObject, "sm_gag", ADMFLAG_CHAT);
  576. AddToTopMenu(hTopMenu, "sourcecomm_ungag", TopMenuObject_Item, Handle_MenuUnGag, MenuObject, "sm_ungag", ADMFLAG_CHAT);
  577. AddToTopMenu(hTopMenu, "sourcecomm_mute", TopMenuObject_Item, Handle_MenuMute, MenuObject, "sm_mute", ADMFLAG_CHAT);
  578. AddToTopMenu(hTopMenu, "sourcecomm_unmute", TopMenuObject_Item, Handle_MenuUnMute, MenuObject, "sm_unmute", ADMFLAG_CHAT);
  579. AddToTopMenu(hTopMenu, "sourcecomm_silence", TopMenuObject_Item, Handle_MenuSilence, MenuObject, "sm_silence", ADMFLAG_CHAT);
  580. AddToTopMenu(hTopMenu, "sourcecomm_unsilence", TopMenuObject_Item, Handle_MenuUnSilence, MenuObject, "sm_unsilence", ADMFLAG_CHAT);
  581. AddToTopMenu(hTopMenu, "sourcecomm_list", TopMenuObject_Item, Handle_MenuList, MenuObject, "sm_commlist", ADMFLAG_CHAT);
  582. }
  583.  
  584. public Handle_Commands(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  585. {
  586. switch(action)
  587. {
  588. case TopMenuAction_DisplayOption:
  589. Format(buffer, maxlength, "%T", "AdminMenu_Main", param1);
  590. case TopMenuAction_DisplayTitle:
  591. Format(buffer, maxlength, "%T", "AdminMenu_Select_Main", param1);
  592. }
  593. }
  594.  
  595. public Handle_MenuGag(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  596. {
  597. if (action == TopMenuAction_DisplayOption)
  598. Format(buffer, maxlength, "%T", "AdminMenu_Gag", param1);
  599. else if (action == TopMenuAction_SelectOption)
  600. AdminMenu_Target(param1, TYPE_GAG);
  601. }
  602.  
  603. public Handle_MenuUnGag(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  604. {
  605. if (action == TopMenuAction_DisplayOption)
  606. Format(buffer, maxlength, "%T", "AdminMenu_UnGag", param1);
  607. else if (action == TopMenuAction_SelectOption)
  608. AdminMenu_Target(param1, TYPE_UNGAG);
  609. }
  610.  
  611. public Handle_MenuMute(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  612. {
  613. if (action == TopMenuAction_DisplayOption)
  614. Format(buffer, maxlength, "%T", "AdminMenu_Mute", param1);
  615. else if (action == TopMenuAction_SelectOption)
  616. AdminMenu_Target(param1, TYPE_MUTE);
  617. }
  618.  
  619. public Handle_MenuUnMute(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  620. {
  621. if (action == TopMenuAction_DisplayOption)
  622. Format(buffer, maxlength, "%T", "AdminMenu_UnMute", param1);
  623. else if (action == TopMenuAction_SelectOption)
  624. AdminMenu_Target(param1, TYPE_UNMUTE);
  625. }
  626.  
  627. public Handle_MenuSilence(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  628. {
  629. if (action == TopMenuAction_DisplayOption)
  630. Format(buffer, maxlength, "%T", "AdminMenu_Silence", param1);
  631. else if (action == TopMenuAction_SelectOption)
  632. AdminMenu_Target(param1, TYPE_SILENCE);
  633. }
  634.  
  635. public Handle_MenuUnSilence(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  636. {
  637. if (action == TopMenuAction_DisplayOption)
  638. Format(buffer, maxlength, "%T", "AdminMenu_UnSilence", param1);
  639. else if (action == TopMenuAction_SelectOption)
  640. AdminMenu_Target(param1, TYPE_UNSILENCE);
  641. }
  642.  
  643. public Handle_MenuList(Handle:menu, TopMenuAction:action, TopMenuObject:object_id, param1, String:buffer[], maxlength)
  644. {
  645. if (action == TopMenuAction_DisplayOption)
  646. Format(buffer, maxlength, "%T", "AdminMenu_List", param1);
  647. else if (action == TopMenuAction_SelectOption)
  648. {
  649. g_iPeskyPanels[param1][viewingList] = false;
  650. AdminMenu_List(param1, 0);
  651. }
  652. }
  653.  
  654. AdminMenu_Target(client, type)
  655. {
  656. decl String:Title[192], String:Option[32];
  657. switch(type)
  658. {
  659. case TYPE_GAG:
  660. Format(Title, sizeof(Title), "%T", "AdminMenu_Select_Gag", client);
  661. case TYPE_MUTE:
  662. Format(Title, sizeof(Title), "%T", "AdminMenu_Select_Mute", client);
  663. case TYPE_SILENCE:
  664. Format(Title, sizeof(Title), "%T", "AdminMenu_Select_Silence", client);
  665. case TYPE_UNGAG:
  666. Format(Title, sizeof(Title), "%T", "AdminMenu_Select_Ungag", client);
  667. case TYPE_UNMUTE:
  668. Format(Title, sizeof(Title), "%T", "AdminMenu_Select_Unmute", client);
  669. case TYPE_UNSILENCE:
  670. Format(Title, sizeof(Title), "%T", "AdminMenu_Select_Unsilence", client);
  671. }
  672.  
  673. new Handle:hMenu = CreateMenu(MenuHandler_MenuTarget); // Common menu - players list. Almost full for blocking, and almost empty for unblocking
  674. SetMenuTitle(hMenu, Title);
  675. SetMenuExitBackButton(hMenu, true);
  676.  
  677. new iClients;
  678. if (type <= 3) // Mute, gag, silence
  679. {
  680. for (new i = 1; i <= MaxClients; i++)
  681. {
  682. if (IsClientInGame(i) && !IsFakeClient(i))
  683. {
  684. switch(type)
  685. {
  686. case TYPE_MUTE:
  687. if (g_MuteType[i] > bNot)
  688. continue;
  689. case TYPE_GAG:
  690. if (g_GagType[i] > bNot)
  691. continue;
  692. case TYPE_SILENCE:
  693. if (g_MuteType[i] > bNot || g_GagType[i] > bNot)
  694. continue;
  695. }
  696. iClients++;
  697. strcopy(Title, sizeof(Title), g_sName[i]);
  698. AdminMenu_GetPunishPhrase(client, i, Title, sizeof(Title));
  699. Format(Option, sizeof(Option), "%d %d", GetClientUserId(i), type);
  700. AddMenuItem(hMenu, Option, Title, (CanUserTarget(client, i) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED));
  701. }
  702. }
  703. }
  704. else // UnMute, ungag, unsilence
  705. {
  706. for (new i = 1; i <= MaxClients; i++)
  707. {
  708. if (IsClientInGame(i) && !IsFakeClient(i))
  709. {
  710. switch(type)
  711. {
  712. case TYPE_UNMUTE:
  713. {
  714. if (g_MuteType[i] > bNot)
  715. {
  716. iClients++;
  717. strcopy(Title, sizeof(Title), g_sName[i]);
  718. Format(Option, sizeof(Option), "%d %d", GetClientUserId(i), type);
  719. AddMenuItem(hMenu, Option, Title, (CanUserTarget(client, i) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED));
  720. }
  721. }
  722. case TYPE_UNGAG:
  723. {
  724. if (g_GagType[i] > bNot)
  725. {
  726. iClients++;
  727. strcopy(Title, sizeof(Title), g_sName[i]);
  728. Format(Option, sizeof(Option), "%d %d", GetClientUserId(i), type);
  729. AddMenuItem(hMenu, Option, Title, (CanUserTarget(client, i) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED));
  730. }
  731. }
  732. case TYPE_UNSILENCE:
  733. {
  734. if (g_MuteType[i] > bNot && g_GagType[i] > bNot)
  735. {
  736. iClients++;
  737. strcopy(Title, sizeof(Title), g_sName[i]);
  738. Format(Option, sizeof(Option), "%d %d", GetClientUserId(i), type);
  739. AddMenuItem(hMenu, Option, Title, (CanUserTarget(client, i) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED));
  740. }
  741. }
  742. }
  743. }
  744. }
  745. }
  746. if (!iClients)
  747. {
  748. switch(type)
  749. {
  750. case TYPE_UNMUTE:
  751. Format(Title, sizeof(Title), "%T", "AdminMenu_Option_Mute_Empty", client);
  752. case TYPE_UNGAG:
  753. Format(Title, sizeof(Title), "%T", "AdminMenu_Option_Gag_Empty", client);
  754. case TYPE_UNSILENCE:
  755. Format(Title, sizeof(Title), "%T", "AdminMenu_Option_Silence_Empty", client);
  756. default:
  757. Format(Title, sizeof(Title), "%T", "AdminMenu_Option_Empty", client);
  758. }
  759. AddMenuItem(hMenu, "0", Title, ITEMDRAW_DISABLED);
  760. }
  761.  
  762. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  763. }
  764.  
  765. public MenuHandler_MenuTarget(Handle:menu, MenuAction:action, param1, param2)
  766. {
  767. switch(action)
  768. {
  769. case MenuAction_End:
  770. CloseHandle(menu);
  771. case MenuAction_Cancel:
  772. {
  773. if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
  774. DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
  775. }
  776. case MenuAction_Select:
  777. {
  778. decl String:Option[32], String:Temp[2][8];
  779. GetMenuItem(menu, param2, Option, sizeof(Option));
  780. ExplodeString(Option, " ", Temp, 2, 8);
  781. new target = GetClientOfUserId(StringToInt(Temp[0]));
  782.  
  783. if (Bool_ValidMenuTarget(param1, target))
  784. {
  785. new type = StringToInt(Temp[1]);
  786. if (type <= TYPE_SILENCE)
  787. AdminMenu_Duration(param1, target, type);
  788. else
  789. ProcessUnBlock(param1, target, type);
  790. }
  791. }
  792. }
  793. }
  794.  
  795. AdminMenu_Duration(client, target, type)
  796. {
  797. new Handle:hMenu = CreateMenu(MenuHandler_MenuDuration);
  798. decl String:sBuffer[192], String:sTemp[64];
  799. Format(sBuffer, sizeof(sBuffer), "%T", "AdminMenu_Title_Durations", client);
  800. SetMenuTitle(hMenu, sBuffer);
  801. SetMenuExitBackButton(hMenu, true);
  802.  
  803. for (new i = 0; i <= iNumTimes; i++)
  804. {
  805. if (IsAllowedBlockLength(client, g_iTimeMinutes[i]))
  806. {
  807. Format(sTemp, sizeof(sTemp), "%d %d %d", GetClientUserId(target), type, i); // TargetID TYPE_BLOCK index_of_Time
  808. AddMenuItem(hMenu, sTemp, g_sTimeDisplays[i]);
  809. }
  810. }
  811.  
  812. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  813. }
  814.  
  815. public MenuHandler_MenuDuration(Handle:menu, MenuAction:action, param1, param2)
  816. {
  817. switch(action)
  818. {
  819. case MenuAction_End:
  820. CloseHandle(menu);
  821. case MenuAction_Cancel:
  822. {
  823. if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
  824. DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
  825. }
  826. case MenuAction_Select:
  827. {
  828. decl String:sOption[32], String:sTemp[3][8];
  829. GetMenuItem(menu, param2, sOption, sizeof(sOption));
  830. ExplodeString(sOption, " ", sTemp, 3, 8);
  831. // TargetID TYPE_BLOCK index_of_Time
  832. new target = GetClientOfUserId(StringToInt(sTemp[0]));
  833.  
  834. if (Bool_ValidMenuTarget(param1, target))
  835. {
  836. new type = StringToInt(sTemp[1]);
  837. new lengthIndex = StringToInt(sTemp[2]);
  838.  
  839. if (iNumReasons) // we have reasons to show
  840. AdminMenu_Reason(param1, target, type, lengthIndex);
  841. else
  842. CreateBlock(param1, target, g_iTimeMinutes[lengthIndex], type);
  843. }
  844. }
  845. }
  846. }
  847.  
  848. AdminMenu_Reason(client, target, type, lengthIndex)
  849. {
  850. new Handle:hMenu = CreateMenu(MenuHandler_MenuReason);
  851. decl String:sBuffer[192], String:sTemp[64];
  852. Format(sBuffer, sizeof(sBuffer), "%T", "AdminMenu_Title_Reasons", client);
  853. SetMenuTitle(hMenu, sBuffer);
  854. SetMenuExitBackButton(hMenu, true);
  855.  
  856. for (new i = 0; i <= iNumReasons; i++)
  857. {
  858. Format(sTemp, sizeof(sTemp), "%d %d %d %d", GetClientUserId(target), type, i, lengthIndex); // TargetID TYPE_BLOCK ReasonIndex LenghtIndex
  859. AddMenuItem(hMenu, sTemp, g_sReasonDisplays[i]);
  860. }
  861.  
  862. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  863. }
  864.  
  865. public MenuHandler_MenuReason(Handle:menu, MenuAction:action, param1, param2)
  866. {
  867. switch(action)
  868. {
  869. case MenuAction_End:
  870. CloseHandle(menu);
  871. case MenuAction_Cancel:
  872. {
  873. if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
  874. DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
  875. }
  876. case MenuAction_Select:
  877. {
  878. decl String:sOption[64], String:sTemp[4][8];
  879. GetMenuItem(menu, param2, sOption, sizeof(sOption));
  880. ExplodeString(sOption, " ", sTemp, 4, 8);
  881. // TargetID TYPE_BLOCK ReasonIndex LenghtIndex
  882. new target = GetClientOfUserId(StringToInt(sTemp[0]));
  883.  
  884. if (Bool_ValidMenuTarget(param1, target))
  885. {
  886. new type = StringToInt(sTemp[1]);
  887. new reasonIndex = StringToInt(sTemp[2]);
  888. new lengthIndex = StringToInt(sTemp[3]);
  889. new length;
  890. if (lengthIndex >= 0 && lengthIndex <= iNumTimes)
  891. length = g_iTimeMinutes[lengthIndex];
  892. else
  893. {
  894. length = DefaultTime;
  895. LogError("Wrong length index in menu - using default time");
  896. }
  897.  
  898. CreateBlock(param1, target, length, type, g_sReasonKey[reasonIndex]);
  899. }
  900. }
  901. }
  902. }
  903.  
  904. AdminMenu_List(client, index)
  905. {
  906. decl String:sTitle[192], String:sOption[32];
  907. Format(sTitle, sizeof(sTitle), "%T", "AdminMenu_Select_List", client);
  908. new iClients, Handle:hMenu = CreateMenu(MenuHandler_MenuList);
  909. SetMenuTitle(hMenu, sTitle);
  910. if (!g_iPeskyPanels[client][viewingList])
  911. SetMenuExitBackButton(hMenu, true);
  912.  
  913. for (new i = 1; i <= MaxClients; i++)
  914. {
  915. if (IsClientInGame(i) && !IsFakeClient(i) && (g_MuteType[i] > bNot || g_GagType[i] > bNot))
  916. {
  917. iClients++;
  918. strcopy(sTitle, sizeof(sTitle), g_sName[i]);
  919. AdminMenu_GetPunishPhrase(client, i, sTitle, sizeof(sTitle));
  920. Format(sOption, sizeof(sOption), "%d", GetClientUserId(i));
  921. AddMenuItem(hMenu, sOption, sTitle);
  922. }
  923. }
  924.  
  925. if (!iClients)
  926. {
  927. Format(sTitle, sizeof(sTitle), "%T", "ListMenu_Option_Empty", client);
  928. AddMenuItem(hMenu, "0", sTitle, ITEMDRAW_DISABLED);
  929. }
  930.  
  931. DisplayMenuAtItem(hMenu, client, index, MENU_TIME_FOREVER);
  932. }
  933.  
  934. public MenuHandler_MenuList(Handle:menu, MenuAction:action, param1, param2)
  935. {
  936. switch(action)
  937. {
  938. case MenuAction_End:
  939. CloseHandle(menu);
  940. case MenuAction_Cancel:
  941. {
  942. if (!g_iPeskyPanels[param1][viewingList])
  943. if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
  944. DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
  945. }
  946. case MenuAction_Select:
  947. {
  948. decl String:sOption[32];
  949. GetMenuItem(menu, param2, sOption, sizeof(sOption));
  950. new target = GetClientOfUserId(StringToInt(sOption));
  951.  
  952. if (Bool_ValidMenuTarget(param1, target))
  953. AdminMenu_ListTarget(param1, target, GetMenuSelectionPosition());
  954. else
  955. AdminMenu_List(param1, GetMenuSelectionPosition());
  956. }
  957. }
  958. }
  959.  
  960. AdminMenu_ListTarget(client, target, index, viewMute = 0, viewGag = 0)
  961. {
  962. new userid = GetClientUserId(target), Handle:hMenu = CreateMenu(MenuHandler_MenuListTarget);
  963. decl String:sBuffer[192], String:sOption[32];
  964. SetMenuTitle(hMenu, g_sName[target]);
  965. SetMenuPagination(hMenu, MENU_NO_PAGINATION);
  966. SetMenuExitButton(hMenu, true);
  967. SetMenuExitBackButton(hMenu, false);
  968.  
  969. if (g_MuteType[target] > bNot)
  970. {
  971. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Mute", client);
  972. Format(sOption, sizeof(sOption), "0 %d %d %b %b", userid, index, viewMute, viewGag);
  973. AddMenuItem(hMenu, sOption, sBuffer);
  974.  
  975. if (viewMute)
  976. {
  977. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Admin", client, g_sMuteAdminName[target]);
  978. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  979.  
  980. decl String:sMuteTemp[192], String:_sMuteTime[192];
  981. Format(sMuteTemp, sizeof(sMuteTemp), "%T", "ListMenu_Option_Duration", client);
  982. if (g_MuteType[target] == bPerm)
  983. Format(sBuffer, sizeof(sBuffer), "%s%T", sMuteTemp, "ListMenu_Option_Duration_Perm", client);
  984. else if (g_MuteType[target] == bTime)
  985. Format(sBuffer, sizeof(sBuffer), "%s%T", sMuteTemp, "ListMenu_Option_Duration_Time", client, g_iMuteLength[target]);
  986. else if (g_MuteType[target] == bSess)
  987. Format(sBuffer, sizeof(sBuffer), "%s%T", sMuteTemp, "ListMenu_Option_Duration_Temp", client);
  988. else
  989. Format(sBuffer, sizeof(sBuffer), "error");
  990. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  991.  
  992. FormatTime(_sMuteTime, sizeof(_sMuteTime), NULL_STRING, g_iMuteTime[target]);
  993. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Issue", client, _sMuteTime);
  994. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  995.  
  996. Format(sMuteTemp, sizeof(sMuteTemp), "%T", "ListMenu_Option_Expire", client);
  997. if (g_MuteType[target] == bPerm)
  998. Format(sBuffer, sizeof(sBuffer), "%s%T", sMuteTemp, "ListMenu_Option_Expire_Perm", client);
  999. else if (g_MuteType[target] == bTime)
  1000. {
  1001. FormatTime(_sMuteTime, sizeof(_sMuteTime), NULL_STRING, (g_iMuteTime[target] + g_iMuteLength[target] * 60));
  1002. Format(sBuffer, sizeof(sBuffer), "%s%T", sMuteTemp, "ListMenu_Option_Expire_Time", client, _sMuteTime);
  1003. }
  1004. else if (g_MuteType[target] == bSess)
  1005. Format(sBuffer, sizeof(sBuffer), "%s%T", sMuteTemp, "ListMenu_Option_Expire_Temp_Reconnect", client);
  1006. else
  1007. Format(sBuffer, sizeof(sBuffer), "error");
  1008. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1009.  
  1010. if (strlen(g_sMuteReason[target]) > 0)
  1011. {
  1012. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Reason", client);
  1013. Format(sOption, sizeof(sOption), "1 %d %d %b %b", userid, index, viewMute, viewGag);
  1014. AddMenuItem(hMenu, sOption, sBuffer);
  1015. }
  1016. else
  1017. {
  1018. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Reason_None", client);
  1019. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1020. }
  1021. }
  1022. }
  1023.  
  1024. if (g_GagType[target] > bNot)
  1025. {
  1026. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Gag", client);
  1027. Format(sOption, sizeof(sOption), "2 %d %d %b %b", userid, index, viewMute, viewGag);
  1028. AddMenuItem(hMenu, sOption, sBuffer);
  1029.  
  1030. if (viewGag)
  1031. {
  1032. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Admin", client, g_sGagAdminName[target]);
  1033. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1034.  
  1035. decl String:sGagTemp[192], String:_sGagTime[192];
  1036. Format(sGagTemp, sizeof(sGagTemp), "%T", "ListMenu_Option_Duration", client);
  1037. if (g_GagType[target] == bPerm)
  1038. Format(sBuffer, sizeof(sBuffer), "%s%T", sGagTemp, "ListMenu_Option_Duration_Perm", client);
  1039. else if (g_GagType[target] == bTime)
  1040. Format(sBuffer, sizeof(sBuffer), "%s%T", sGagTemp, "ListMenu_Option_Duration_Time", client, g_iGagLength[target]);
  1041. else if (g_GagType[target] == bSess)
  1042. Format(sBuffer, sizeof(sBuffer), "%s%T", sGagTemp, "ListMenu_Option_Duration_Temp", client);
  1043. else
  1044. Format(sBuffer, sizeof(sBuffer), "error");
  1045. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1046.  
  1047. FormatTime(_sGagTime, sizeof(_sGagTime), NULL_STRING, g_iGagTime[target]);
  1048. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Issue", client, _sGagTime);
  1049. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1050.  
  1051. Format(sGagTemp, sizeof(sGagTemp), "%T", "ListMenu_Option_Expire", client);
  1052. if (g_GagType[target] == bPerm)
  1053. Format(sBuffer, sizeof(sBuffer), "%s%T", sGagTemp, "ListMenu_Option_Expire_Perm", client);
  1054. else if (g_GagType[target] == bTime)
  1055. {
  1056. FormatTime(_sGagTime, sizeof(_sGagTime), NULL_STRING, (g_iGagTime[target] + g_iGagLength[target] * 60));
  1057. Format(sBuffer, sizeof(sBuffer), "%s%T", sGagTemp, "ListMenu_Option_Expire_Time", client, _sGagTime);
  1058. }
  1059. else if (g_GagType[target] == bSess)
  1060. Format(sBuffer, sizeof(sBuffer), "%s%T", sGagTemp, "ListMenu_Option_Expire_Temp_Reconnect", client);
  1061. else
  1062. Format(sBuffer, sizeof(sBuffer), "error");
  1063. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1064.  
  1065. if (strlen(g_sGagReason[target]) > 0)
  1066. {
  1067. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Reason", client);
  1068. Format(sOption, sizeof(sOption), "3 %d %d %b %b", userid, index, viewMute, viewGag);
  1069. AddMenuItem(hMenu, sOption, sBuffer);
  1070. }
  1071. else
  1072. {
  1073. Format(sBuffer, sizeof(sBuffer), "%T", "ListMenu_Option_Reason_None", client);
  1074. AddMenuItem(hMenu, "", sBuffer, ITEMDRAW_DISABLED);
  1075. }
  1076. }
  1077. }
  1078.  
  1079. g_iPeskyPanels[client][curIndex] = index;
  1080. g_iPeskyPanels[client][curTarget] = target;
  1081. g_iPeskyPanels[client][viewingGag] = viewGag;
  1082. g_iPeskyPanels[client][viewingMute] = viewMute;
  1083. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  1084. }
  1085.  
  1086. public MenuHandler_MenuListTarget(Handle:menu, MenuAction:action, param1, param2)
  1087. {
  1088. switch(action)
  1089. {
  1090. case MenuAction_End:
  1091. CloseHandle(menu);
  1092. case MenuAction_Cancel:
  1093. {
  1094. if (param2 == MenuCancel_ExitBack)
  1095. AdminMenu_List(param1, g_iPeskyPanels[param1][curIndex]);
  1096. }
  1097. case MenuAction_Select:
  1098. {
  1099. decl String:sOption[64], String:sTemp[5][8];
  1100. GetMenuItem(menu, param2, sOption, sizeof(sOption));
  1101. ExplodeString(sOption, " ", sTemp, 5, 8);
  1102.  
  1103. new target = GetClientOfUserId(StringToInt(sTemp[1]));
  1104. if (param1 == target || Bool_ValidMenuTarget(param1, target))
  1105. {
  1106. switch(StringToInt(sTemp[0]))
  1107. {
  1108. case 0:
  1109. AdminMenu_ListTarget(param1, target, StringToInt(sTemp[2]), !(StringToInt(sTemp[3])), 0);
  1110. case 1, 3:
  1111. AdminMenu_ListTargetReason(param1, target, g_iPeskyPanels[param1][viewingMute], g_iPeskyPanels[param1][viewingGag]);
  1112. case 2:
  1113. AdminMenu_ListTarget(param1, target, StringToInt(sTemp[2]), 0, !(StringToInt(sTemp[4])));
  1114. }
  1115. }
  1116. else
  1117. AdminMenu_List(param1, StringToInt(sTemp[2]));
  1118.  
  1119. }
  1120. }
  1121. }
  1122.  
  1123. AdminMenu_ListTargetReason(client, target, showMute, showGag)
  1124. {
  1125. decl String:sTemp[192], String:sBuffer[192];
  1126. new Handle:hPanel = CreatePanel();
  1127. SetPanelTitle(hPanel, g_sName[target]);
  1128. DrawPanelItem(hPanel, " ", ITEMDRAW_SPACER|ITEMDRAW_RAWLINE);
  1129.  
  1130. if (showMute)
  1131. {
  1132. Format(sTemp, sizeof(sTemp), "%T", "ReasonPanel_Punishment_Mute", client);
  1133. if (g_MuteType[target] == bPerm)
  1134. Format(sBuffer, sizeof(sBuffer), "%s%T", sTemp, "ReasonPanel_Perm", client);
  1135. else if (g_MuteType[target] == bTime)
  1136. Format(sBuffer, sizeof(sBuffer), "%s%T", sTemp, "ReasonPanel_Time", client, g_iMuteLength[target]);
  1137. else if (g_MuteType[target] == bSess)
  1138. Format(sBuffer, sizeof(sBuffer), "%s%T", sTemp, "ReasonPanel_Temp", client);
  1139. else
  1140. Format(sBuffer, sizeof(sBuffer), "error");
  1141. DrawPanelText(hPanel, sBuffer);
  1142.  
  1143. Format(sBuffer, sizeof(sBuffer), "%T", "ReasonPanel_Reason", client, g_sMuteReason[target]);
  1144. DrawPanelText(hPanel, sBuffer);
  1145. }
  1146. else if (showGag)
  1147. {
  1148. Format(sTemp, sizeof(sTemp), "%T", "ReasonPanel_Punishment_Gag", client);
  1149. if (g_GagType[target] == bPerm)
  1150. Format(sBuffer, sizeof(sBuffer), "%s%T", sTemp, "ReasonPanel_Perm", client);
  1151. else if (g_GagType[target] == bTime)
  1152. Format(sBuffer, sizeof(sBuffer), "%s%T", sTemp, "ReasonPanel_Time", client, g_iGagLength[target]);
  1153. else if (g_GagType[target] == bSess)
  1154. Format(sBuffer, sizeof(sBuffer), "%s%T", sTemp, "ReasonPanel_Temp", client);
  1155. else
  1156. Format(sBuffer, sizeof(sBuffer), "error");
  1157. DrawPanelText(hPanel, sBuffer);
  1158.  
  1159. Format(sBuffer, sizeof(sBuffer), "%T", "ReasonPanel_Reason", client, g_sGagReason[target]);
  1160. DrawPanelText(hPanel, sBuffer);
  1161. }
  1162.  
  1163. DrawPanelItem(hPanel, " ", ITEMDRAW_SPACER|ITEMDRAW_RAWLINE);
  1164. SetPanelCurrentKey(hPanel, 10);
  1165. Format(sBuffer, sizeof(sBuffer), "%T", "ReasonPanel_Back", client);
  1166. DrawPanelItem(hPanel, sBuffer);
  1167. SendPanelToClient(hPanel, client, PanelHandler_ListTargetReason, MENU_TIME_FOREVER);
  1168. CloseHandle(hPanel);
  1169. }
  1170.  
  1171. public PanelHandler_ListTargetReason(Handle:menu, MenuAction:action, param1, param2)
  1172. {
  1173. switch(action)
  1174. {
  1175. case MenuAction_Select:
  1176. {
  1177. AdminMenu_ListTarget(param1, g_iPeskyPanels[param1][curTarget], g_iPeskyPanels[param1][curIndex], g_iPeskyPanels[param1][viewingMute], g_iPeskyPanels[param1][viewingGag]);
  1178. }
  1179. }
  1180. }
  1181.  
  1182.  
  1183. // SQL CALLBACKS //
  1184.  
  1185. public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)
  1186. {
  1187. #if defined DEBUG
  1188. PrintToServer("GotDatabase(data: %d, lock: %d, g_h: %d, hndl: %d)", data, g_iConnectLock, g_hDatabase, hndl);
  1189. #endif
  1190.  
  1191. // If this happens to be an old connection request, ignore it.
  1192. if(data != g_iConnectLock || g_hDatabase)
  1193. {
  1194. if(hndl)
  1195. CloseHandle(hndl);
  1196. return;
  1197. }
  1198.  
  1199. g_iConnectLock = 0;
  1200. g_DatabaseState = DatabaseState_Connected;
  1201. g_hDatabase = hndl;
  1202.  
  1203. // See if the connection is valid. If not, don't un-mark the caches
  1204. // as needing rebuilding, in case the next connection request works.
  1205. if(!g_hDatabase)
  1206. {
  1207. LogError("Connecting to database failed: %s", error);
  1208. return;
  1209. }
  1210.  
  1211. // Set character set to UTF-8 in the database
  1212. if (GetFeatureStatus(FeatureType_Native, "SQL_SetCharset") == FeatureStatus_Available)
  1213. {
  1214. SQL_SetCharset(g_hDatabase, "utf8");
  1215. }
  1216. else
  1217. {
  1218. decl String:query[128];
  1219. FormatEx(query, sizeof(query), "SET NAMES 'UTF8'");
  1220. #if defined LOG_QUERIES
  1221. LogToFile(logQuery, "Set encoding. QUERY: %s", query);
  1222. #endif
  1223. SQL_TQuery(g_hDatabase, Query_ErrorCheck, query);
  1224. }
  1225.  
  1226. // Process queue
  1227. SQL_TQuery(SQLiteDB, Query_ProcessQueue,
  1228. "SELECT id, steam_id, time, start_time, reason, name, admin_id, admin_ip, type \
  1229. FROM queue2");
  1230.  
  1231. // Force recheck players
  1232. ForcePlayersRecheck();
  1233. }
  1234.  
  1235. public Query_AddBlockInsert(Handle:owner, Handle:hndl, const String:error[], any:data)
  1236. {
  1237. if (DB_Conn_Lost(hndl) || error[0])
  1238. {
  1239. LogError("Query_AddBlockInsert failed: %s", error);
  1240.  
  1241. ResetPack(data);
  1242. new length = ReadPackCell(data);
  1243. new type = ReadPackCell(data);
  1244. new String:reason[256], String:name[MAX_NAME_LENGTH], String:auth[64], String:adminAuth[32], String:adminIp[20];
  1245. ReadPackString(data, name, sizeof(name));
  1246. ReadPackString(data, auth, sizeof(auth));
  1247. ReadPackString(data, reason, sizeof(reason));
  1248. ReadPackString(data, adminAuth, sizeof(adminAuth));
  1249. ReadPackString(data, adminIp, sizeof(adminIp));
  1250.  
  1251. InsertTempBlock(length, type, name, auth, reason, adminAuth, adminIp);
  1252. }
  1253. CloseHandle(data);
  1254. }
  1255.  
  1256. public Query_UnBlockSelect(Handle:owner, Handle:hndl, const String:error[], any:data)
  1257. {
  1258. decl String:adminAuth[30], String:targetAuth[30], String:reason[256];
  1259.  
  1260. ResetPack(data);
  1261. new adminUserID = ReadPackCell(data);
  1262. new targetUserID = ReadPackCell(data);
  1263. new type = ReadPackCell(data); // not in use unless DEBUG
  1264. ReadPackString(data, adminAuth, sizeof(adminAuth));
  1265. ReadPackString(data, targetAuth, sizeof(targetAuth));
  1266. ReadPackString(data, reason, sizeof(reason));
  1267.  
  1268. new admin = GetClientOfUserId(adminUserID);
  1269. new target = GetClientOfUserId(targetUserID);
  1270.  
  1271. #if defined DEBUG
  1272. PrintToServer("Query_UnBlockSelect(adminUID: %d/%d, targetUID: %d/%d, type: %d, adminAuth: %s, targetAuth: %s, reason: %s)",
  1273. adminUserID, admin, targetUserID, target, type, adminAuth, targetAuth, reason);
  1274. #endif
  1275.  
  1276. new String:targetName[MAX_NAME_LENGTH];
  1277. strcopy(targetName, MAX_NAME_LENGTH, target && IsClientInGame(target) ? g_sName[target] : targetAuth); //FIXME
  1278.  
  1279. new bool:hasErrors = false;
  1280. // If error is not an empty string the query failed
  1281. if (DB_Conn_Lost(hndl) || error[0] != '\0')
  1282. {
  1283. LogError("Query_UnBlockSelect failed: %s", error);
  1284. if (admin && IsClientInGame(admin))
  1285. {
  1286. PrintToChat(admin, "%s%T", PREFIX, "Unblock Select Failed", admin, targetAuth);
  1287. PrintToConsole(admin, "%s%T", PREFIX, "Unblock Select Failed", admin, targetAuth);
  1288. }
  1289. else
  1290. {
  1291. PrintToServer("%s%T", PREFIX, "Unblock Select Failed", LANG_SERVER, targetAuth);
  1292. }
  1293. hasErrors = true;
  1294. }
  1295.  
  1296. // If there was no results then a ban does not exist for that id
  1297. if (!DB_Conn_Lost(hndl) && !SQL_GetRowCount(hndl))
  1298. {
  1299. if (admin && IsClientInGame(admin))
  1300. {
  1301. PrintToChat(admin, "%s%t", PREFIX, "No blocks found", targetAuth);
  1302. PrintToConsole(admin, "%s%t", PREFIX, "No blocks found", targetAuth);
  1303. }
  1304. else
  1305. {
  1306. PrintToServer("%s%T", PREFIX, "No blocks found", LANG_SERVER, targetAuth);
  1307. }
  1308. hasErrors = true;
  1309. }
  1310.  
  1311. if (hasErrors)
  1312. {
  1313. #if defined DEBUG
  1314. PrintToServer("Calling TempUnBlock from Query_UnBlockSelect");
  1315. #endif
  1316.  
  1317. TempUnBlock(data); // Datapack closed inside.
  1318. return;
  1319. }
  1320. else
  1321. {
  1322. new bool:b_success = false;
  1323. // Get the values from the founded blocks.
  1324. while(SQL_MoreRows(hndl))
  1325. {
  1326. // Oh noes! What happened?!
  1327. if (!SQL_FetchRow(hndl))
  1328. continue;
  1329.  
  1330. new bid = SQL_FetchInt(hndl, 0);
  1331. new iAID = SQL_FetchInt(hndl, 1);
  1332. new cAID = SQL_FetchInt(hndl, 2);
  1333. new cImmunity = SQL_FetchInt(hndl, 3);
  1334. new cType = SQL_FetchInt(hndl, 4);
  1335.  
  1336. #if defined DEBUG
  1337. PrintToServer("Fetched from DB: bid %d, iAID: %d, cAID: %d, cImmunity: %d, cType: %d", bid, iAID, cAID, cImmunity, cType);
  1338. // WHO WE ARE?
  1339. PrintToServer("WHO WE ARE CHECKING!");
  1340. if (iAID == cAID)
  1341. PrintToServer("we are block author");
  1342. if (!admin)
  1343. PrintToServer("we are console (possibly)");
  1344. if (AdmHasFlag(admin))
  1345. PrintToServer("we have special flag");
  1346. if (GetAdmImmunity(admin) > cImmunity)
  1347. PrintToServer("we have %d immunity and block has %d. we cool", GetAdmImmunity(admin), cImmunity);
  1348. #endif
  1349.  
  1350. // Checking - has we access to unblock?
  1351. if (iAID == cAID || (!admin && StrEqual(adminAuth, "STEAM_ID_SERVER")) || AdmHasFlag(admin) || (DisUBImCheck == 0 && (GetAdmImmunity(admin) > cImmunity)))
  1352. {
  1353. // Ok! we have rights to unblock
  1354. b_success = true;
  1355. // UnMute/UnGag, Show & log activity
  1356. if (target && IsClientInGame(target))
  1357. {
  1358. switch(cType)
  1359. {
  1360. case TYPE_MUTE:
  1361. {
  1362. PerformUnMute(target);
  1363. LogAction(admin, target, "\"%L\" unmuted \"%L\" (reason \"%s\")", admin, target, reason);
  1364. }
  1365. //-------------------------------------------------------------------------------------------------
  1366. case TYPE_GAG:
  1367. {
  1368. PerformUnGag(target);
  1369. LogAction(admin, target, "\"%L\" ungagged \"%L\" (reason \"%s\")", admin, target, reason);
  1370. }
  1371. }
  1372. }
  1373.  
  1374. new Handle:dataPack = CreateDataPack();
  1375. WritePackCell(dataPack, adminUserID);
  1376. WritePackCell(dataPack, cType);
  1377. WritePackString(dataPack, g_sName[target]);
  1378. WritePackString(dataPack, targetAuth);
  1379.  
  1380. new String:unbanReason[sizeof(reason) * 2 + 1];
  1381. SQL_EscapeString(g_hDatabase, reason, unbanReason, sizeof(unbanReason));
  1382.  
  1383. decl String:query[2048];
  1384. Format(query, sizeof(query),
  1385. "UPDATE %s_comms \
  1386. SET RemovedBy = %d, \
  1387. RemoveType = 'U', \
  1388. RemovedOn = UNIX_TIMESTAMP(), \
  1389. ureason = '%s' \
  1390. WHERE bid = %d",
  1391. DatabasePrefix, iAID, unbanReason, bid);
  1392. #if defined LOG_QUERIES
  1393. LogToFile(logQuery, "Query_UnBlockSelect. QUERY: %s", query);
  1394. #endif
  1395. SQL_TQuery(g_hDatabase, Query_UnBlockUpdate, query, dataPack);
  1396. }
  1397. else
  1398. {
  1399. // sorry, we don't have permission to unblock!
  1400. #if defined DEBUG
  1401. PrintToServer("No permissions to unblock in Query_UnBlockSelect");
  1402. #endif
  1403. switch(cType)
  1404. {
  1405. case TYPE_MUTE:
  1406. {
  1407. if (admin && IsClientInGame(admin))
  1408. {
  1409. PrintToChat(admin, "%s%t", PREFIX, "No permission unmute", targetName);
  1410. PrintToConsole(admin, "%s%t", PREFIX, "No permission unmute", targetName);
  1411. }
  1412. LogAction(admin, target, "\"%L\" tried (and didn't have permission) to unmute %s (reason \"%s\")", admin, targetAuth, reason);
  1413. }
  1414. //-------------------------------------------------------------------------------------------------
  1415. case TYPE_GAG:
  1416. {
  1417. if (admin && IsClientInGame(admin))
  1418. {
  1419. PrintToChat(admin, "%s%t", PREFIX, "No permission ungag", targetName);
  1420. PrintToConsole(admin, "%s%t", PREFIX, "No permission ungag", targetName);
  1421. }
  1422. LogAction(admin, target, "\"%L\" tried (and didn't have permission) to ungag %s (reason \"%s\")", admin, targetAuth, reason);
  1423. }
  1424. }
  1425. }
  1426. }
  1427.  
  1428. if (b_success && target && IsClientInGame(target))
  1429. {
  1430. #if defined DEBUG
  1431. PrintToServer("Showing activity to server in Query_UnBlockSelect");
  1432. #endif
  1433. ShowActivityToServer(admin, type, _, _, g_sName[target], _);
  1434.  
  1435. if (type == TYPE_UNSILENCE)
  1436. {
  1437. // check result for possible combination with temp and time punishments (temp was skipped in code above)
  1438. SetPackPosition(data, 16);
  1439. if (g_MuteType[target] > bNot)
  1440. {
  1441. WritePackCell(data, TYPE_UNMUTE);
  1442. TempUnBlock(data);
  1443. data = INVALID_HANDLE;
  1444. }
  1445. else if (g_GagType[target] > bNot)
  1446. {
  1447. WritePackCell(data, TYPE_UNGAG);
  1448. TempUnBlock(data);
  1449. data = INVALID_HANDLE;
  1450. }
  1451. }
  1452. }
  1453. }
  1454. if (data != INVALID_HANDLE)
  1455. CloseHandle(data);
  1456. }
  1457.  
  1458. public Query_UnBlockUpdate(Handle:owner, Handle:hndl, const String:error[], any:data)
  1459. {
  1460. new admin, type;
  1461. new String:targetName[MAX_NAME_LENGTH], String:targetAuth[30];
  1462.  
  1463. ResetPack(data);
  1464. admin = GetClientOfUserId(ReadPackCell(data));
  1465. type = ReadPackCell(data);
  1466. ReadPackString(data, targetName, sizeof(targetName));
  1467. ReadPackString(data, targetAuth, sizeof(targetAuth));
  1468. CloseHandle(data);
  1469.  
  1470. if (DB_Conn_Lost(hndl) || error[0] != '\0')
  1471. {
  1472. LogError("Query_UnBlockUpdate failed: %s", error);
  1473. if (admin && IsClientInGame(admin))
  1474. {
  1475. PrintToChat(admin, "%s%t", PREFIX, "Unblock insert failed");
  1476. PrintToConsole(admin, "%s%t", PREFIX, "Unblock insert failed");
  1477. }
  1478. return;
  1479. }
  1480.  
  1481. switch(type)
  1482. {
  1483. case TYPE_MUTE:
  1484. {
  1485. LogAction(admin, -1, "\"%L\" removed mute for %s from DB", admin, targetAuth);
  1486. if (admin && IsClientInGame(admin))
  1487. {
  1488. PrintToChat(admin, "%s%t", PREFIX, "successfully unmuted", targetName);
  1489. PrintToConsole(admin, "%s%t", PREFIX, "successfully unmuted", targetName);
  1490. }
  1491. else
  1492. {
  1493. PrintToServer("%s%T", PREFIX, "successfully unmuted", LANG_SERVER, targetName);
  1494. }
  1495. }
  1496. //-------------------------------------------------------------------------------------------------
  1497. case TYPE_GAG:
  1498. {
  1499. LogAction(admin, -1, "\"%L\" removed gag for %s from DB", admin, targetAuth);
  1500. if (admin && IsClientInGame(admin)){
  1501. PrintToChat(admin, "%s%t", PREFIX, "successfully ungagged", targetName);
  1502. PrintToConsole(admin, "%s%t", PREFIX, "successfully ungagged", targetName);
  1503. }
  1504. else
  1505. {
  1506. PrintToServer("%s%T", PREFIX, "successfully ungagged", LANG_SERVER, targetName);
  1507. }
  1508. }
  1509. }
  1510. }
  1511.  
  1512. // ProcessQueueCallback is called as the result of selecting all the rows from the queue table
  1513. public Query_ProcessQueue(Handle:owner, Handle:hndl, const String:error[], any:data)
  1514. {
  1515. if (hndl == INVALID_HANDLE || error[0])
  1516. {
  1517. LogError("Query_ProcessQueue failed: %s", error);
  1518. return;
  1519. }
  1520.  
  1521. decl String:auth[64];
  1522. new String:name[MAX_NAME_LENGTH];
  1523. decl String:reason[256];
  1524. decl String:adminAuth[64], String:adminIp[20];
  1525. decl String:query[4096];
  1526.  
  1527. while(SQL_MoreRows(hndl))
  1528. {
  1529. // Oh noes! What happened?!
  1530. if (!SQL_FetchRow(hndl))
  1531. continue;
  1532.  
  1533. new String:sAuthEscaped[sizeof(auth) * 2 + 1];
  1534. new String:banName[MAX_NAME_LENGTH * 2 + 1];
  1535. new String:banReason[sizeof(reason) * 2 + 1];
  1536. new String:sAdmAuthEscaped[sizeof(adminAuth) * 2 + 1];
  1537. new String:sAdmAuthYZEscaped[sizeof(adminAuth) * 2 + 1];
  1538.  
  1539. // if we get to here then there are rows in the queue pending processing
  1540. //steam_id TEXT, time INTEGER, start_time INTEGER, reason TEXT, name TEXT, admin_id TEXT, admin_ip TEXT, type INTEGER
  1541. new id = SQL_FetchInt(hndl, 0);
  1542. SQL_FetchString(hndl, 1, auth, sizeof(auth));
  1543. new time = SQL_FetchInt(hndl, 2);
  1544. new startTime = SQL_FetchInt(hndl, 3);
  1545. SQL_FetchString(hndl, 4, reason, sizeof(reason));
  1546. SQL_FetchString(hndl, 5, name, sizeof(name));
  1547. SQL_FetchString(hndl, 6, adminAuth, sizeof(adminAuth));
  1548. SQL_FetchString(hndl, 7, adminIp, sizeof(adminIp));
  1549. new type = SQL_FetchInt(hndl, 8);
  1550.  
  1551. if (DB_Connect()) {
  1552. SQL_EscapeString(g_hDatabase, auth, sAuthEscaped, sizeof(sAuthEscaped));
  1553. SQL_EscapeString(g_hDatabase, name, banName, sizeof(banName));
  1554. SQL_EscapeString(g_hDatabase, reason, banReason, sizeof(banReason));
  1555. SQL_EscapeString(g_hDatabase, adminAuth, sAdmAuthEscaped, sizeof(sAdmAuthEscaped));
  1556. SQL_EscapeString(g_hDatabase, adminAuth[8], sAdmAuthYZEscaped, sizeof(sAdmAuthYZEscaped));
  1557. }
  1558. else
  1559. continue;
  1560. // all blocks should be entered into db!
  1561.  
  1562. FormatEx(query, sizeof(query),
  1563. "INSERT INTO %s_comms (authid, name, created, ends, length, reason, aid, adminIp, sid, type) \
  1564. VALUES ('%s', '%s', %d, %d, %d, '%s', \
  1565. IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '0'), \
  1566. '%s', %d, %d)",
  1567. DatabasePrefix, sAuthEscaped, banName, startTime, (startTime + (time*60)), (time*60), banReason, DatabasePrefix, sAdmAuthEscaped, sAdmAuthYZEscaped, adminIp, serverID, type);
  1568. #if defined LOG_QUERIES
  1569. LogToFile(logQuery, "Query_ProcessQueue. QUERY: %s", query);
  1570. #endif
  1571. SQL_TQuery(g_hDatabase, Query_AddBlockFromQueue, query, id);
  1572. }
  1573. }
  1574.  
  1575. public Query_AddBlockFromQueue(Handle:owner, Handle:hndl, const String:error[], any:data)
  1576. {
  1577. decl String:query[512];
  1578. if (error[0] == '\0')
  1579. {
  1580. // The insert was successful so delete the record from the queue
  1581. FormatEx(query, sizeof(query),
  1582. "DELETE FROM queue2 \
  1583. WHERE id = %d",
  1584. data);
  1585. #if defined LOG_QUERIES
  1586. LogToFile(logQuery, "Query_AddBlockFromQueue. QUERY: %s", query);
  1587. #endif
  1588. SQL_TQuery(SQLiteDB, Query_ErrorCheck, query);
  1589. }
  1590. }
  1591.  
  1592. public Query_ErrorCheck(Handle:owner, Handle:hndl, const String:error[], any:data)
  1593. {
  1594. if (DB_Conn_Lost(hndl) || error[0])
  1595. LogError("%T (%s)", "Failed to query database", LANG_SERVER, error);
  1596. }
  1597.  
  1598. public Query_VerifyBlock(Handle:owner, Handle:hndl, const String:error[], any:userid)
  1599. {
  1600. decl String:clientAuth[64];
  1601. new client = GetClientOfUserId(userid);
  1602.  
  1603. #if defined DEBUG
  1604. PrintToServer("Query_VerifyBlock(userid: %d, client: %d)", userid, client);
  1605. #endif
  1606.  
  1607. if (!client)
  1608. return;
  1609.  
  1610. /* Failure happen. Do retry with delay */
  1611. if (DB_Conn_Lost(hndl))
  1612. {
  1613. LogError("Query_VerifyBlock failed: %s", error);
  1614. if (g_hPlayerRecheck[client] == INVALID_HANDLE)
  1615. g_hPlayerRecheck[client] = CreateTimer(RetryTime, ClientRecheck, userid);
  1616. return;
  1617. }
  1618.  
  1619. GetClientAuthString(client, clientAuth, sizeof(clientAuth));
  1620.  
  1621. //SELECT (c.ends - UNIX_TIMESTAMP()) as remaining, c.length, c.type, c.created, c.reason, a.user,
  1622. //IF (a.immunity>=g.immunity, a.immunity, IFNULL(g.immunity,0)) as immunity, c.aid, c.sid, c.authid
  1623. //FROM %s_comms c LEFT JOIN %s_admins a ON a.aid=c.aid LEFT JOIN %s_srvgroups g ON g.name = a.srv_group
  1624. //WHERE c.authid REGEXP '^STEAM_[0-9]:%s$' AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL",
  1625. if (SQL_GetRowCount(hndl) > 0)
  1626. {
  1627. while(SQL_FetchRow(hndl))
  1628. {
  1629. if (NotApplyToThisServer(SQL_FetchInt(hndl, 8)))
  1630. continue;
  1631.  
  1632. new String:sReason[256], String:sAdmName[MAX_NAME_LENGTH], String:sAdmAuth[64];
  1633. new remaining_time = SQL_FetchInt(hndl, 0);
  1634. new length = SQL_FetchInt(hndl, 1);
  1635. new type = SQL_FetchInt(hndl, 2);
  1636. new time = SQL_FetchInt(hndl, 3);
  1637. SQL_FetchString(hndl, 4, sReason, sizeof(sReason));
  1638. SQL_FetchString(hndl, 5, sAdmName, sizeof(sAdmName));
  1639. new immunity = SQL_FetchInt(hndl, 6);
  1640. new aid = SQL_FetchInt(hndl, 7);
  1641. SQL_FetchString(hndl, 9, sAdmAuth, sizeof(sAdmAuth));
  1642.  
  1643. // Block from CONSOLE (aid=0) and we have `console immunity` value in config
  1644. if (!aid && ConsoleImmunity > immunity)
  1645. immunity = ConsoleImmunity;
  1646.  
  1647. #if defined DEBUG
  1648. PrintToServer("Fetched from DB: remaining %d, length %d, type %d", remaining_time, length, type);
  1649. #endif
  1650.  
  1651. switch(type)
  1652. {
  1653. case TYPE_MUTE:
  1654. {
  1655. if (g_MuteType[client] < bTime)
  1656. {
  1657. PerformMute(client, time, length / 60, sAdmName, sAdmAuth, immunity, sReason, remaining_time);
  1658. PrintToChat(client, "%s%t", PREFIX, "Muted on connect");
  1659. }
  1660. }
  1661. case TYPE_GAG:
  1662. {
  1663. if (g_GagType[client] < bTime)
  1664. {
  1665. PerformGag(client, time, length / 60, sAdmName, sAdmAuth, immunity, sReason, remaining_time);
  1666. PrintToChat(client, "%s%t", PREFIX, "Gagged on connect");
  1667. }
  1668. }
  1669. }
  1670. }
  1671. }
  1672.  
  1673. g_bPlayerStatus[client] = true;
  1674. }
  1675.  
  1676.  
  1677. // TIMER CALL BACKS //
  1678.  
  1679. public Action:ClientRecheck(Handle:timer, any:userid)
  1680. {
  1681. #if defined DEBUG
  1682. PrintToServer("ClientRecheck(userid: %d)", userid);
  1683. #endif
  1684.  
  1685. new client = GetClientOfUserId(userid);
  1686. if (!client)
  1687. return;
  1688.  
  1689. if (IsClientConnected(client))
  1690. OnClientPostAdminCheck(client);
  1691.  
  1692. g_hPlayerRecheck[client] = INVALID_HANDLE;
  1693. }
  1694.  
  1695. public Action:Timer_MuteExpire(Handle:timer, any:userid)
  1696. {
  1697. new client = GetClientOfUserId(userid);
  1698. if (!client)
  1699. return;
  1700.  
  1701. #if defined DEBUG
  1702. decl String:clientAuth[64];
  1703. GetClientAuthString(client, clientAuth,sizeof(clientAuth));
  1704. PrintToServer("Mute expired for %s", clientAuth);
  1705. #endif
  1706.  
  1707. PrintToChat(client, "%s%t", PREFIX, "Mute expired");
  1708.  
  1709. g_hMuteExpireTimer[client] = INVALID_HANDLE;
  1710. MarkClientAsUnMuted(client);
  1711. if (IsClientInGame(client))
  1712. BaseComm_SetClientMute(client, false);
  1713. }
  1714.  
  1715. public Action:Timer_GagExpire(Handle:timer, any:userid)
  1716. {
  1717. new client = GetClientOfUserId(userid);
  1718. if (!client)
  1719. return;
  1720.  
  1721. #if defined DEBUG
  1722. decl String:clientAuth[64];
  1723. GetClientAuthString(client, clientAuth,sizeof(clientAuth));
  1724. PrintToServer("Gag expired for %s", clientAuth);
  1725. #endif
  1726.  
  1727. PrintToChat(client, "%s%t", PREFIX, "Gag expired");
  1728.  
  1729. g_hGagExpireTimer[client] = INVALID_HANDLE;
  1730. MarkClientAsUnGagged(client);
  1731. if (IsClientInGame(client))
  1732. BaseComm_SetClientGag(client, false);
  1733. }
  1734.  
  1735. public Action:Timer_StopWait(Handle:timer, any:data)
  1736. {
  1737. g_DatabaseState = DatabaseState_None;
  1738. DB_Connect();
  1739. }
  1740.  
  1741. // PARSER //
  1742.  
  1743. static InitializeConfigParser()
  1744. {
  1745. if (ConfigParser == INVALID_HANDLE)
  1746. {
  1747. ConfigParser = SMC_CreateParser();
  1748. SMC_SetReaders(ConfigParser, ReadConfig_NewSection, ReadConfig_KeyValue, ReadConfig_EndSection);
  1749. }
  1750. }
  1751.  
  1752. static InternalReadConfig(const String:path[])
  1753. {
  1754. ConfigState = ConfigStateNone;
  1755.  
  1756. new SMCError:err = SMC_ParseFile(ConfigParser, path);
  1757.  
  1758. if (err != SMCError_Okay)
  1759. {
  1760. decl String:buffer[64];
  1761. if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
  1762. {
  1763. PrintToServer(buffer);
  1764. }
  1765. else
  1766. {
  1767. PrintToServer("Fatal parse error");
  1768. }
  1769. }
  1770. }
  1771.  
  1772. public SMCResult:ReadConfig_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
  1773. {
  1774. if (name[0])
  1775. {
  1776. if (strcmp("Config", name, false) == 0)
  1777. {
  1778. ConfigState = ConfigStateConfig;
  1779. }
  1780. else if (strcmp("CommsReasons", name, false) == 0)
  1781. {
  1782. ConfigState = ConfigStateReasons;
  1783. }
  1784. else if (strcmp("CommsTimes", name, false) == 0)
  1785. {
  1786. ConfigState = ConfigStateTimes;
  1787. }
  1788. else if (strcmp("ServersWhiteList", name, false) == 0)
  1789. {
  1790. ConfigState = ConfigStateServers;
  1791. }
  1792. }
  1793. return SMCParse_Continue;
  1794. }
  1795.  
  1796. public SMCResult:ReadConfig_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
  1797. {
  1798. if (!key[0])
  1799. return SMCParse_Continue;
  1800.  
  1801. switch(ConfigState)
  1802. {
  1803. case ConfigStateConfig:
  1804. {
  1805. if (strcmp("DatabasePrefix", key, false) == 0)
  1806. {
  1807. strcopy(DatabasePrefix, sizeof(DatabasePrefix), value);
  1808.  
  1809. if (DatabasePrefix[0] == '\0')
  1810. {
  1811. DatabasePrefix = "sb";
  1812. }
  1813. }
  1814. else if (strcmp("RetryTime", key, false) == 0)
  1815. {
  1816. RetryTime = StringToFloat(value);
  1817. if (RetryTime < 15.0)
  1818. {
  1819. RetryTime = 15.0;
  1820. }
  1821. else if (RetryTime > 60.0)
  1822. {
  1823. RetryTime = 60.0;
  1824. }
  1825. }
  1826. else if (strcmp("ServerID", key, false) == 0)
  1827. {
  1828. if (!StringToIntEx(value, serverID) || serverID < 1)
  1829. {
  1830. serverID = 0;
  1831. }
  1832. }
  1833. else if (strcmp("DefaultTime", key, false) == 0)
  1834. {
  1835. DefaultTime = StringToInt(value);
  1836. if (DefaultTime < 0)
  1837. {
  1838. DefaultTime = -1;
  1839. }
  1840. if (DefaultTime == 0)
  1841. {
  1842. DefaultTime = 30;
  1843. }
  1844. }
  1845. else if (strcmp("DisableUnblockImmunityCheck", key, false) == 0)
  1846. {
  1847. DisUBImCheck = StringToInt(value);
  1848. if (DisUBImCheck != 1)
  1849. {
  1850. DisUBImCheck = 0;
  1851. }
  1852. }
  1853. else if (strcmp("ConsoleImmunity", key, false) == 0)
  1854. {
  1855. ConsoleImmunity = StringToInt(value);
  1856. if (ConsoleImmunity < 0 || ConsoleImmunity > 100)
  1857. {
  1858. ConsoleImmunity = 0;
  1859. }
  1860. }
  1861. else if (strcmp("MaxLength", key, false) == 0)
  1862. {
  1863. ConfigMaxLength = StringToInt(value);
  1864. }
  1865. else if (strcmp("OnlyWhiteListServers", key, false) == 0)
  1866. {
  1867. ConfigWhiteListOnly = StringToInt(value);
  1868. if (ConfigWhiteListOnly != 1)
  1869. {
  1870. ConfigWhiteListOnly = 0;
  1871. }
  1872. }
  1873. }
  1874. case ConfigStateReasons:
  1875. {
  1876. Format(g_sReasonKey[iNumReasons], REASON_SIZE, "%s", key);
  1877. Format(g_sReasonDisplays[iNumReasons], DISPLAY_SIZE, "%s", value);
  1878. #if defined DEBUG
  1879. PrintToServer("Loaded reason. index %d, key \"%s\", display_text \"%s\"", iNumReasons, g_sReasonKey[iNumReasons], g_sReasonDisplays[iNumReasons]);
  1880. #endif
  1881. iNumReasons++;
  1882. }
  1883. case ConfigStateTimes:
  1884. {
  1885. Format(g_sTimeDisplays[iNumTimes], DISPLAY_SIZE, "%s", value);
  1886. g_iTimeMinutes[iNumTimes] = StringToInt(key);
  1887. #if defined DEBUG
  1888. PrintToServer("Loaded time. index %d, time %d minutes, display_text \"%s\"", iNumTimes, g_iTimeMinutes[iNumTimes] , g_sTimeDisplays[iNumTimes]);
  1889. #endif
  1890. iNumTimes++;
  1891. }
  1892. case ConfigStateServers:
  1893. {
  1894. if (strcmp("id", key, false) == 0)
  1895. {
  1896. new srvID = StringToInt(value);
  1897. if (srvID >= 0)
  1898. {
  1899. PushArrayCell(g_hServersWhiteList, srvID);
  1900. #if defined DEBUG
  1901. PrintToServer("Loaded white list server id %d", srvID);
  1902. #endif
  1903. }
  1904. }
  1905. }
  1906. }
  1907. return SMCParse_Continue;
  1908. }
  1909.  
  1910. public SMCResult:ReadConfig_EndSection(Handle:smc)
  1911. {
  1912. return SMCParse_Continue;
  1913. }
  1914.  
  1915. // STOCK FUNCTIONS //
  1916.  
  1917. stock bool:DB_Connect()
  1918. {
  1919. #if defined DEBUG
  1920. PrintToServer("DB_Connect(handle %d, state %d, lock %d)", g_hDatabase, g_DatabaseState, g_iConnectLock);
  1921. #endif
  1922.  
  1923. if (g_hDatabase)
  1924. {
  1925. return true;
  1926. }
  1927.  
  1928. if (g_DatabaseState == DatabaseState_Wait) // 100500 connections in a minute is bad idea..
  1929. {
  1930. return false;
  1931. }
  1932.  
  1933. if(g_DatabaseState != DatabaseState_Connecting)
  1934. {
  1935. g_DatabaseState = DatabaseState_Connecting;
  1936. g_iConnectLock = ++g_iSequence;
  1937. // Connect using the "sourcebans" section, or the "default" section if "sourcebans" does not exist
  1938. SQL_TConnect(GotDatabase, DATABASE, g_iConnectLock);
  1939. }
  1940.  
  1941. return false;
  1942. }
  1943.  
  1944. stock bool:DB_Conn_Lost(Handle:hndl)
  1945. {
  1946. if (hndl == INVALID_HANDLE)
  1947. {
  1948. if (g_hDatabase != INVALID_HANDLE)
  1949. {
  1950. LogError("Lost connection to DB. Reconnect after delay.");
  1951. CloseHandle(g_hDatabase);
  1952. g_hDatabase = INVALID_HANDLE;
  1953. }
  1954. if (g_DatabaseState != DatabaseState_Wait)
  1955. {
  1956. g_DatabaseState = DatabaseState_Wait;
  1957. CreateTimer(RetryTime, Timer_StopWait, _, TIMER_FLAG_NO_MAPCHANGE);
  1958. }
  1959. return true;
  1960. }
  1961. else
  1962. {
  1963. return false;
  1964. }
  1965. }
  1966.  
  1967. stock InitializeBackupDB()
  1968. {
  1969. decl String:error[255];
  1970. SQLiteDB = SQLite_UseDatabase("sourcecomms-queue", error, sizeof(error));
  1971. if (SQLiteDB == INVALID_HANDLE)
  1972. {
  1973. SetFailState(error);
  1974. }
  1975.  
  1976. SQL_TQuery(SQLiteDB, Query_ErrorCheck,
  1977. "CREATE TABLE IF NOT EXISTS queue2 ( \
  1978. id INTEGER PRIMARY KEY, \
  1979. steam_id TEXT, \
  1980. time INTEGER, \
  1981. start_time INTEGER, \
  1982. reason TEXT, \
  1983. name TEXT, \
  1984. admin_id TEXT, \
  1985. admin_ip TEXT, \
  1986. type INTEGER)");
  1987. }
  1988.  
  1989. stock CreateBlock(client, targetId = 0, length = -1, type, const String:sReason[] = "", const String:sArgs[] = "")
  1990. {
  1991. #if defined DEBUG
  1992. PrintToServer("CreateBlock(admin: %d, target: %d, length: %d, type: %d, reason: %s, args: %s)", client, targetId, length, type, sReason, sArgs);
  1993. #endif
  1994.  
  1995. decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml, String:target_name[MAX_NAME_LENGTH], String:reason[256];
  1996. new bool:skipped = false;
  1997.  
  1998. // checking args
  1999. if (targetId)
  2000. {
  2001. target_list[0] = targetId;
  2002. target_count = 1;
  2003. tn_is_ml = false;
  2004. strcopy(target_name, sizeof(target_name), g_sName[targetId]);
  2005. strcopy(reason, sizeof(reason), sReason);
  2006. }
  2007. else if (strlen(sArgs))
  2008. {
  2009. new String:sArg[3][192];
  2010.  
  2011. if (ExplodeString(sArgs, "\"", sArg, 3, 192, true) == 3 && strlen(sArg[0]) == 0) // exploding by quotes
  2012. {
  2013. new String:sTempArg[2][192];
  2014. TrimString(sArg[2]);
  2015. sArg[0] = sArg[1]; // target name
  2016. ExplodeString(sArg[2], " ", sTempArg, 2, 192, true); // get length and reason
  2017. sArg[1] = sTempArg[0]; // lenght
  2018. sArg[2] = sTempArg[1]; // reason
  2019. }
  2020. else
  2021. {
  2022. ExplodeString(sArgs, " ", sArg, 3, 192, true); // exploding by spaces
  2023. }
  2024.  
  2025. // Get the target, find target returns a message on failure so we do not
  2026. if ((target_count = ProcessTargetString(
  2027. sArg[0],
  2028. client,
  2029. target_list,
  2030. MAXPLAYERS,
  2031. COMMAND_FILTER_NO_BOTS,
  2032. target_name,
  2033. sizeof(target_name),
  2034. tn_is_ml)) <= 0)
  2035. {
  2036. ReplyToTargetError(client, target_count);
  2037. return;
  2038. }
  2039.  
  2040. // Get the block length
  2041. if (!StringToIntEx(sArg[1], length)) // not valid number in second argument
  2042. {
  2043. length = DefaultTime;
  2044. Format(reason, sizeof(reason), "%s %s", sArg[1], sArg[2]);
  2045. }
  2046. else
  2047. {
  2048. strcopy(reason, sizeof(reason), sArg[2]);
  2049. }
  2050.  
  2051. // Strip spaces and quotes from reason
  2052. TrimString(reason);
  2053. StripQuotes(reason);
  2054.  
  2055. if (!IsAllowedBlockLength(client, length, target_count))
  2056. {
  2057. ReplyToCommand(client, "%s%t", PREFIX, "★\x04[Mevid]\x02 Nu ai acces la aceasta comanda! ");
  2058. return;
  2059. }
  2060. }
  2061. else
  2062. {
  2063. return;
  2064. }
  2065.  
  2066. new admImmunity = GetAdmImmunity(client);
  2067. decl String:adminAuth[64];
  2068.  
  2069. if (client && IsClientInGame(client))
  2070. {
  2071. GetClientAuthString(client, adminAuth, sizeof(adminAuth));
  2072. }
  2073. else
  2074. {
  2075. // setup dummy adminAuth and adminIp for server
  2076. strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  2077. }
  2078.  
  2079. for (new i = 0; i < target_count; i++)
  2080. {
  2081. new target = target_list[i];
  2082.  
  2083. #if defined DEBUG
  2084. decl String:auth[64];
  2085. GetClientAuthString(target, auth, sizeof(auth));
  2086. PrintToServer("Processing block for %s", auth);
  2087. #endif
  2088.  
  2089. if (!g_bPlayerStatus[target])
  2090. {
  2091. // The target has not been blocks verify. It must be completed before you can block anyone.
  2092. ReplyToCommand(client, "%s%t", PREFIX, "Player Comms Not Verified");
  2093. skipped = true;
  2094. continue; // skip
  2095. }
  2096.  
  2097. switch(type)
  2098. {
  2099. case TYPE_MUTE:
  2100. {
  2101. if (!BaseComm_IsClientMuted(target))
  2102. {
  2103. #if defined DEBUG
  2104. PrintToServer("%s not muted. Mute him, creating unmute timer and add record to DB", auth);
  2105. #endif
  2106.  
  2107. PerformMute(target, _, length, g_sName[client], adminAuth, admImmunity, reason);
  2108.  
  2109. LogAction(client, target, "\"%L\"\x04★[Mevid] \x02 Admin-ul \"%L\" \x01 i-a dat \x04Mute\x02 jucatorului \"%L\!" ( \"\x02Durata \"%d\" ,\x04Motiv \"%s\")", client, target, length, reason);
  2110. }
  2111. else
  2112. {
  2113. #if defined DEBUG
  2114. PrintToServer("%s already muted", auth);
  2115. #endif
  2116.  
  2117. ReplyToCommand(client, "%s%t", PREFIX, "Player already muted", g_sName[target]);
  2118.  
  2119. skipped = true;
  2120. continue;
  2121. }
  2122. }
  2123. //-------------------------------------------------------------------------------------------------
  2124. case TYPE_GAG:
  2125. {
  2126. if (!BaseComm_IsClientGagged(target))
  2127. {
  2128. #if defined DEBUG
  2129. PrintToServer("%s not gagged. Gag him, creating ungag timer and add record to DB", auth);
  2130. #endif
  2131.  
  2132. PerformGag(target, _, length, g_sName[client], adminAuth, admImmunity, reason);
  2133.  
  2134. LogAction(client, target,
  2135. LogAction(client, target, "\"%L\"\x04★[Mevid] \x02 Admin-ul \"%L\" \x01 i-a dat \x04Gag \x02 jucatorului \"%L\!" ( \"\x02Durata \"%d\" ,\x04Motiv \"%s\")", client, target, length, reason);
  2136. }
  2137. else
  2138. {
  2139. #if defined DEBUG
  2140. PrintToServer("%s already gagged", auth);
  2141. #endif
  2142.  
  2143. ReplyToCommand(client, "%s%t", PREFIX, "Player already gagged", g_sName[target]);
  2144.  
  2145. skipped = true;
  2146. continue;
  2147. }
  2148. }
  2149. //-------------------------------------------------------------------------------------------------
  2150. case TYPE_SILENCE:
  2151. {
  2152. if (!BaseComm_IsClientGagged(target) && !BaseComm_IsClientMuted(target))
  2153. {
  2154. #if defined DEBUG
  2155. PrintToServer("%s not silenced. Silence him, creating ungag & unmute timers and add records to DB", auth);
  2156. #endif
  2157.  
  2158. PerformMute(target, _, length, g_sName[client], adminAuth, admImmunity, reason);
  2159. PerformGag(target, _, length, g_sName[client], adminAuth, admImmunity, reason);
  2160.  
  2161. LogAction(client, target, "\"%L\"\x04★[Mevid] \x02 Admin-ul \"%L\" \x01 i-a dat \x04Silence\x02 jucatorului \"%L\!" ( \"\x02Durata \"%d\" ,\x04Motiv \"%s\")", client, target, length, reason);
  2162. }
  2163. else
  2164. {
  2165. #if defined DEBUG
  2166. PrintToServer("%s already gagged or/and muted", auth);
  2167. #endif
  2168.  
  2169. ReplyToCommand(client, "%s%t", PREFIX, "Player already silenced", g_sName[target]);
  2170.  
  2171. skipped = true;
  2172. continue;
  2173. }
  2174. }
  2175. }
  2176. }
  2177. if (target_count == 1 && !skipped)
  2178. SavePunishment(client, target_list[0], type, length, reason);
  2179. if (target_count > 1 || !skipped)
  2180. ShowActivityToServer(client, type, length, reason, target_name, tn_is_ml);
  2181.  
  2182. return;
  2183. }
  2184.  
  2185. stock ProcessUnBlock(client, targetId = 0, type, String:sReason[] = "", const String:sArgs[] = "")
  2186. {
  2187. #if defined DEBUG
  2188. PrintToServer("ProcessUnBlock(admin: %d, target: %d, type: %d, reason: %s, args: %s)", client, targetId, type, sReason, sArgs);
  2189. #endif
  2190.  
  2191. decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml, String:target_name[MAX_NAME_LENGTH], String:reason[256];
  2192.  
  2193. if(targetId)
  2194. {
  2195. target_list[0] = targetId;
  2196. target_count = 1;
  2197. tn_is_ml = false;
  2198. strcopy(target_name, sizeof(target_name), g_sName[targetId]);
  2199. strcopy(reason, sizeof(reason), sReason);
  2200. }
  2201. else
  2202. {
  2203. new String:sBuffer[256], String:sArg[3][192];
  2204. GetCmdArgString(sBuffer, sizeof(sBuffer));
  2205.  
  2206. if (ExplodeString(sBuffer, "\"", sArg, 3, 192, true) == 3 && strlen(sArg[0]) == 0)
  2207. {
  2208. TrimString(sArg[2]);
  2209. sArg[0] = sArg[1]; // target name
  2210. sArg[1] = sArg[2]; // reason; sArg[2] - not in use
  2211. }
  2212. else
  2213. {
  2214. ExplodeString(sBuffer, " ", sArg, 2, 192, true);
  2215. }
  2216. strcopy(reason, sizeof(reason), sArg[1]);
  2217. // Strip spaces and quotes from reason
  2218. TrimString(reason);
  2219. StripQuotes(reason);
  2220.  
  2221. // Get the target, find target returns a message on failure so we do not
  2222. if ((target_count = ProcessTargetString(
  2223. sArg[0],
  2224. client,
  2225. target_list,
  2226. MAXPLAYERS,
  2227. COMMAND_FILTER_NO_BOTS,
  2228. target_name,
  2229. sizeof(target_name),
  2230. tn_is_ml)) <= 0)
  2231. {
  2232. ReplyToTargetError(client, target_count);
  2233. return;
  2234. }
  2235. }
  2236.  
  2237. decl String:adminAuth[64];
  2238. decl String:targetAuth[64];
  2239.  
  2240. if (client && IsClientInGame(client))
  2241. {
  2242. GetClientAuthString(client, adminAuth, sizeof(adminAuth));
  2243. }
  2244. else
  2245. {
  2246. // setup dummy adminAuth and adminIp for server
  2247. strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  2248. }
  2249.  
  2250. if (target_count > 1)
  2251. {
  2252. #if defined DEBUG
  2253. PrintToServer("ProcessUnBlock - targets_count > 1");
  2254. #endif
  2255.  
  2256. for (new i = 0; i < target_count; i++)
  2257. {
  2258. new target = target_list[i];
  2259.  
  2260. if (IsClientInGame(target))
  2261. GetClientAuthString(target, targetAuth, sizeof(targetAuth));
  2262. else
  2263. continue;
  2264.  
  2265. new Handle:dataPack = CreateDataPack();
  2266. WritePackCell(dataPack, GetClientUserId2(client));
  2267. WritePackCell(dataPack, GetClientUserId(target));
  2268. WritePackCell(dataPack, type);
  2269. WritePackString(dataPack, adminAuth);
  2270. WritePackString(dataPack, targetAuth); // not in use in this case
  2271. WritePackString(dataPack, reason);
  2272.  
  2273. TempUnBlock(dataPack);
  2274. }
  2275.  
  2276. #if defined DEBUG
  2277. PrintToServer("Showing activity to server in ProcessUnBlock for targets_count > 1");
  2278. #endif
  2279. ShowActivityToServer(client, type + TYPE_TEMP_SHIFT, _, _, target_name, tn_is_ml);
  2280. }
  2281. else
  2282. {
  2283. decl String:typeWHERE[100];
  2284. new bool:dontCheckDB = false;
  2285. new target = target_list[0];
  2286.  
  2287. if (IsClientInGame(target))
  2288. {
  2289. GetClientAuthString(target, targetAuth, sizeof(targetAuth));
  2290. }
  2291. else
  2292. {
  2293. return;
  2294. }
  2295.  
  2296. switch(type)
  2297. {
  2298. case TYPE_UNMUTE:
  2299. {
  2300. if (!BaseComm_IsClientMuted(target))
  2301. {
  2302. ReplyToCommand(client, "%s%t", PREFIX, "\x04★[Mevid]\x02Jucatorul nu are mute!);
  2303. return;
  2304. }
  2305. else
  2306. {
  2307. FormatEx(typeWHERE, sizeof(typeWHERE), "c.type = '%d'", TYPE_MUTE);
  2308. if (g_MuteType[target] == bSess)
  2309. dontCheckDB = true;
  2310. }
  2311. }
  2312. //-------------------------------------------------------------------------------------------------
  2313. case TYPE_UNGAG:
  2314. {
  2315. if (!BaseComm_IsClientGagged(target))
  2316. {
  2317. ReplyToCommand(client, "%s%t", PREFIX, "\x04★[Mevid]\x02Jucatorul nu are mute!);
  2318. return;
  2319. }
  2320. else
  2321. {
  2322. FormatEx(typeWHERE, sizeof(typeWHERE), "c.type = '%d'", TYPE_GAG);
  2323. if (g_GagType[target] == bSess)
  2324. dontCheckDB = true;
  2325. }
  2326. }
  2327. //-------------------------------------------------------------------------------------------------
  2328. case TYPE_UNSILENCE:
  2329. {
  2330. if (!BaseComm_IsClientMuted(target) || !BaseComm_IsClientGagged(target))
  2331. {
  2332. ReplyToCommand(client, "%s%t", PREFIX, "\x04★[Mevid]\x02Jucatorul nu are silence");
  2333. return;
  2334. }
  2335. else
  2336. {
  2337. FormatEx(typeWHERE, sizeof(typeWHERE), "(c.type = '%d' OR c.type = '%d')", TYPE_MUTE, TYPE_GAG);
  2338. if (g_MuteType[target] == bSess && g_GagType[target] == bSess)
  2339. dontCheckDB = true;
  2340. }
  2341. }
  2342. }
  2343.  
  2344. // Pack everything into a data pack so we can retain it
  2345. new Handle:dataPack = CreateDataPack();
  2346. WritePackCell(dataPack, GetClientUserId2(client));
  2347. WritePackCell(dataPack, GetClientUserId(target));
  2348. WritePackCell(dataPack, type);
  2349. WritePackString(dataPack, adminAuth);
  2350. WritePackString(dataPack, targetAuth);
  2351. WritePackString(dataPack, reason);
  2352.  
  2353. // Check current player status. If player has temporary punishment - don't get info from DB
  2354. if (!dontCheckDB && DB_Connect())
  2355. {
  2356. new String:sAdminAuthEscaped[sizeof(adminAuth) * 2 + 1];
  2357. new String:sAdminAuthYZEscaped[sizeof(adminAuth) * 2 + 1];
  2358. new String:sTargetAuthEscaped[sizeof(targetAuth) * 2 + 1];
  2359. new String:sTargetAuthYZEscaped[sizeof(targetAuth) * 2 + 1];
  2360.  
  2361. SQL_EscapeString(g_hDatabase, adminAuth, sAdminAuthEscaped, sizeof(sAdminAuthEscaped));
  2362. SQL_EscapeString(g_hDatabase, adminAuth[8], sAdminAuthYZEscaped, sizeof(sAdminAuthYZEscaped));
  2363. SQL_EscapeString(g_hDatabase, targetAuth, sTargetAuthEscaped, sizeof(sTargetAuthEscaped));
  2364. SQL_EscapeString(g_hDatabase, targetAuth[8], sTargetAuthYZEscaped, sizeof(sTargetAuthYZEscaped));
  2365.  
  2366. decl String:query[4096];
  2367. Format(query, sizeof(query),
  2368. "SELECT c.bid, \
  2369. IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '0') as iaid, \
  2370. c.aid, \
  2371. IF (a.immunity>=g.immunity, a.immunity, IFNULL(g.immunity,0)) as immunity, \
  2372. c.type \
  2373. FROM %s_comms AS c \
  2374. LEFT JOIN %s_admins AS a ON a.aid = c.aid \
  2375. LEFT JOIN %s_srvgroups AS g ON g.name = a.srv_group \
  2376. WHERE RemoveType IS NULL \
  2377. AND (c.authid = '%s' OR c.authid REGEXP '^STEAM_[0-9]:%s$') \
  2378. AND (length = '0' OR ends > UNIX_TIMESTAMP()) \
  2379. AND %s",
  2380. DatabasePrefix, sAdminAuthEscaped, sAdminAuthYZEscaped, DatabasePrefix, DatabasePrefix, DatabasePrefix, sTargetAuthEscaped, sTargetAuthYZEscaped, typeWHERE);
  2381.  
  2382. #if defined LOG_QUERIES
  2383. LogToFile(logQuery, "ProcessUnBlock. QUERY: %s", query);
  2384. #endif
  2385.  
  2386. SQL_TQuery(g_hDatabase, Query_UnBlockSelect, query, dataPack);
  2387. }
  2388. else
  2389. {
  2390. #if defined DEBUG
  2391. PrintToServer("Calling TempUnBlock from ProcessUnBlock");
  2392. #endif
  2393.  
  2394. if (TempUnBlock(dataPack))
  2395. ShowActivityToServer(client, type + TYPE_TEMP_SHIFT, _, _, g_sName[target], _);
  2396. }
  2397. }
  2398. }
  2399.  
  2400. stock bool:TempUnBlock(Handle:data)
  2401. {
  2402. decl String:adminAuth[30], String:targetAuth[30], String:reason[256];
  2403. ResetPack(data);
  2404. new adminUserID = ReadPackCell(data);
  2405. new targetUserID = ReadPackCell(data);
  2406. new type = ReadPackCell(data);
  2407. ReadPackString(data, adminAuth, sizeof(adminAuth));
  2408. ReadPackString(data, targetAuth, sizeof(targetAuth));
  2409. ReadPackString(data, reason, sizeof(reason));
  2410. CloseHandle(data); // Need to close datapack
  2411.  
  2412. #if defined DEBUG
  2413. PrintToServer("TempUnBlock(adminUID: %d, targetUID: %d, type: %d, adminAuth: %s, targetAuth: %s, reason: %s)", adminUserID, targetUserID, type, adminAuth, targetAuth, reason);
  2414. #endif
  2415.  
  2416. new admin = GetClientOfUserId(adminUserID);
  2417. new target = GetClientOfUserId(targetUserID);
  2418. if (!target)
  2419. return false; // target has gone away
  2420.  
  2421. new AdmImmunity = GetAdmImmunity(admin);
  2422. new bool:AdmImCheck = ( DisUBImCheck == 0
  2423. && ( ( type == TYPE_MUTE && AdmImmunity > g_iMuteLevel[target] )
  2424. || ( type == TYPE_GAG && AdmImmunity > g_iGagLevel[target] )
  2425. || ( type == TYPE_SILENCE && AdmImmunity > g_iMuteLevel[target]
  2426. && AdmImmunity > g_iGagLevel[target])
  2427. )
  2428. );
  2429.  
  2430. #if defined DEBUG
  2431. PrintToServer("WHO WE ARE CHECKING!");
  2432. if (!admin)
  2433. PrintToServer("we are console (possibly)");
  2434. if (AdmHasFlag(admin))
  2435. PrintToServer("we have special flag");
  2436. #endif
  2437.  
  2438. // Check access for unblock without db changes (temporary unblock)
  2439. new bool:bHasPermission = (!admin && StrEqual(adminAuth, "STEAM_ID_SERVER")) || AdmHasFlag(admin) || AdmImCheck;
  2440. // can, if we are console or have special flag. else - deep checking by issuer authid
  2441. if (!bHasPermission) {
  2442. switch(type)
  2443. {
  2444. case TYPE_UNMUTE:
  2445. {
  2446. bHasPermission = StrEqual(adminAuth, g_sMuteAdminAuth[target]);
  2447. }
  2448. case TYPE_UNGAG:
  2449. {
  2450. bHasPermission = StrEqual(adminAuth, g_sGagAdminAuth[target]);
  2451. }
  2452. case TYPE_UNSILENCE:
  2453. {
  2454. bHasPermission = StrEqual(adminAuth, g_sMuteAdminAuth[target]) && StrEqual(adminAuth, g_sGagAdminAuth[target]);
  2455. }
  2456. }
  2457. }
  2458.  
  2459. if (bHasPermission)
  2460. {
  2461. switch(type)
  2462. {
  2463. case TYPE_UNMUTE:
  2464. {
  2465. PerformUnMute(target);
  2466. LogAction(admin, target, "\"%L\"\x04★[Mevid]\x04 \x02Jucatorul \"%L\" \x01 a primit \x02ungag \x04de la \"%d\" (reason \"%s\")", admin, target, reason);
  2467. }
  2468. //-------------------------------------------------------------------------------------------------
  2469. case TYPE_UNGAG:
  2470. {
  2471. PerformUnGag(target);
  2472. LogAction(admin, target, "\"%L\"\x04★[Mevid]\x04 \x02Jucatorul \"%L\" \x01 a primit \x02unmute\x04de la \"%d\" (reason \"%s\")",, admin, target, reason);
  2473. }
  2474. //-------------------------------------------------------------------------------------------------
  2475. case TYPE_UNSILENCE:
  2476. {
  2477. PerformUnMute(target);
  2478. PerformUnGag(target);
  2479. LogAction(admin, target, "\"%L\"\x04★[Mevid]\x04 \x02Jucatorul \"%L\" \x01 a primit \x02unsilence \x04de la \"%d\" (reason \"%s\")",, admin, target, reason);
  2480. }
  2481. default:
  2482. {
  2483. return false;
  2484. }
  2485. }
  2486. return true;
  2487. }
  2488. else
  2489. {
  2490. if (admin && IsClientInGame(admin))
  2491. {
  2492. PrintToChat(admin, "%s%t", PREFIX, "No db error unlock perm");
  2493. PrintToConsole(admin, "%s%t", PREFIX, "No db error unlock perm");
  2494. }
  2495. return false;
  2496. }
  2497. }
  2498.  
  2499. stock InsertTempBlock(length, type, const String:name[], const String:auth[], const String:reason[], const String:adminAuth[], const String:adminIp[])
  2500. {
  2501. LogMessage("Saving punishment for %s into queue", auth);
  2502.  
  2503. new String:banName[MAX_NAME_LENGTH * 2 + 1];
  2504. new String:banReason[256 * 2 + 1];
  2505. new String:sAuthEscaped[64 * 2 + 1];
  2506. new String:sAdminAuthEscaped[64 * 2 + 1];
  2507. decl String:sQuery[4096], String:sQueryVal[2048];
  2508. new String:sQueryMute[2048], String:sQueryGag[2048];
  2509.  
  2510. // escaping everything
  2511. SQL_EscapeString(SQLiteDB, name, banName, sizeof(banName));
  2512. SQL_EscapeString(SQLiteDB, reason, banReason, sizeof(banReason));
  2513. SQL_EscapeString(SQLiteDB, auth, sAuthEscaped, sizeof(sAuthEscaped));
  2514. SQL_EscapeString(SQLiteDB, adminAuth, sAdminAuthEscaped, sizeof(sAdminAuthEscaped));
  2515.  
  2516. // steam_id time start_time reason name admin_id admin_ip
  2517. FormatEx(sQueryVal, sizeof(sQueryVal),
  2518. "'%s', %d, %d, '%s', '%s', '%s', '%s'",
  2519. sAuthEscaped, length, GetTime(), banReason, banName, sAdminAuthEscaped, adminIp);
  2520.  
  2521. if (type == TYPE_MUTE || type == TYPE_SILENCE)
  2522. {
  2523. FormatEx(sQueryMute, sizeof(sQueryMute), "(%s, %d)", sQueryVal, TYPE_MUTE);
  2524. }
  2525. if (type == TYPE_GAG || type == TYPE_SILENCE)
  2526. {
  2527. FormatEx(sQueryGag, sizeof(sQueryGag), "(%s, %d)", sQueryVal, TYPE_GAG);
  2528. }
  2529.  
  2530. FormatEx(sQuery, sizeof(sQuery),
  2531. "INSERT INTO queue2 (steam_id, time, start_time, reason, name, admin_id, admin_ip, type) VALUES %s%s%s",
  2532. sQueryMute, type == TYPE_SILENCE ? ", " : "", sQueryGag);
  2533.  
  2534. #if defined LOG_QUERIES
  2535. LogToFile(logQuery, "InsertTempBlock. QUERY: %s", sQuery);
  2536. #endif
  2537.  
  2538. SQL_TQuery(SQLiteDB, Query_ErrorCheck, sQuery);
  2539. }
  2540.  
  2541. stock ServerInfo()
  2542. {
  2543. decl pieces[4];
  2544. new longip = GetConVarInt(CvarHostIp);
  2545. pieces[0] = (longip >> 24) & 0x000000FF;
  2546. pieces[1] = (longip >> 16) & 0x000000FF;
  2547. pieces[2] = (longip >> 8) & 0x000000FF;
  2548. pieces[3] = longip & 0x000000FF;
  2549. FormatEx(ServerIp, sizeof(ServerIp), "%d.%d.%d.%d", pieces[0], pieces[1], pieces[2], pieces[3]);
  2550. GetConVarString(CvarPort, ServerPort, sizeof(ServerPort));
  2551. }
  2552.  
  2553. stock ReadConfig()
  2554. {
  2555. InitializeConfigParser();
  2556.  
  2557. if (ConfigParser == INVALID_HANDLE)
  2558. {
  2559. return;
  2560. }
  2561.  
  2562. decl String:ConfigFile1[PLATFORM_MAX_PATH], String:ConfigFile2[PLATFORM_MAX_PATH];
  2563. BuildPath(Path_SM, ConfigFile1, sizeof(ConfigFile1), "configs/sourcebans/sourcebans.cfg");
  2564. BuildPath(Path_SM, ConfigFile2, sizeof(ConfigFile2), "configs/sourcebans/sourcecomms.cfg");
  2565.  
  2566. if (FileExists(ConfigFile1))
  2567. {
  2568. PrintToServer("%sLoading configs/sourcebans/sourcebans.cfg config file", PREFIX);
  2569. InternalReadConfig(ConfigFile1);
  2570. }
  2571. else
  2572. {
  2573. SetFailState("FATAL *** ERROR *** can't find %s", ConfigFile1);
  2574. }
  2575. if (FileExists(ConfigFile2))
  2576. {
  2577. PrintToServer("%sLoading configs/sourcebans/sourcecomms.cfg config file", PREFIX);
  2578. iNumReasons = 0;
  2579. iNumTimes = 0;
  2580. InternalReadConfig(ConfigFile2);
  2581. if (iNumReasons)
  2582. iNumReasons--;
  2583. if (iNumTimes)
  2584. iNumTimes--;
  2585. if (serverID == 0)
  2586. {
  2587. LogError("You must set valid `ServerID` value in sourcebans.cfg!");
  2588. if (ConfigWhiteListOnly)
  2589. {
  2590. LogError("ServersWhiteList feature disabled!");
  2591. ConfigWhiteListOnly = 0;
  2592. }
  2593. }
  2594. }
  2595. else
  2596. {
  2597. SetFailState("FATAL *** ERROR *** can't find %s", ConfigFile2);
  2598. }
  2599. #if defined DEBUG
  2600. PrintToServer("Loaded DefaultTime value: %d", DefaultTime);
  2601. PrintToServer("Loaded DisableUnblockImmunityCheck value: %d", DisUBImCheck);
  2602. #endif
  2603. }
  2604.  
  2605.  
  2606. // some more
  2607.  
  2608. AdminMenu_GetPunishPhrase(client, target, String:name[], length)
  2609. {
  2610. decl String:Buffer[192];
  2611. if (g_MuteType[target] > bNot && g_GagType[target] > bNot)
  2612. Format(Buffer, sizeof(Buffer), "%T", "AdminMenu_Display_Silenced", client, name);
  2613. else if (g_MuteType[target] > bNot)
  2614. Format(Buffer, sizeof(Buffer), "%T", "AdminMenu_Display_Muted", client, name);
  2615. else if (g_GagType[target] > bNot)
  2616. Format(Buffer, sizeof(Buffer), "%T", "AdminMenu_Display_Gagged", client, name);
  2617. else
  2618. Format(Buffer, sizeof(Buffer), "%T", "AdminMenu_Display_None", client, name);
  2619.  
  2620. strcopy(name, length, Buffer);
  2621. }
  2622.  
  2623. bool:Bool_ValidMenuTarget(client, target)
  2624. {
  2625. if (target <= 0)
  2626. {
  2627. if (client)
  2628. PrintToChat(client, "%s%t", PREFIX, "AdminMenu_Not_Available");
  2629. else
  2630. ReplyToCommand(client, "%s%t", PREFIX, "AdminMenu_Not_Available");
  2631.  
  2632. return false;
  2633. }
  2634. else if (!CanUserTarget(client, target))
  2635. {
  2636. if (client)
  2637. PrintToChat(client, "%s%t", PREFIX, "Command_Target_Not_Targetable");
  2638. else
  2639. ReplyToCommand(client, "%s%t", PREFIX, "Command_Target_Not_Targetable");
  2640.  
  2641. return false;
  2642. }
  2643.  
  2644. return true;
  2645. }
  2646.  
  2647. stock bool:IsAllowedBlockLength(admin, length, target_count = 1)
  2648. {
  2649. if (target_count == 1)
  2650. {
  2651. if (!ConfigMaxLength)
  2652. return true; // Restriction disabled
  2653. if (!admin)
  2654. return true; // all allowed for console
  2655. if (AdmHasFlag(admin))
  2656. return true; // all allowed for admins with special flag
  2657. if (!length || length > ConfigMaxLength)
  2658. return false;
  2659. else
  2660. return true;
  2661. }
  2662. else
  2663. {
  2664. if (length < 0)
  2665. return true; // session punishments allowed for mass-tergeting
  2666. if (!length)
  2667. return false;
  2668. if (length > MAX_TIME_MULTI)
  2669. return false;
  2670. if (length > DefaultTime)
  2671. return false;
  2672. else
  2673. return true;
  2674. }
  2675. }
  2676.  
  2677. stock bool:AdmHasFlag(admin)
  2678. {
  2679. return admin && CheckCommandAccess(admin, "", UNBLOCK_FLAG, true);
  2680. }
  2681.  
  2682. stock _:GetAdmImmunity(admin)
  2683. {
  2684. if (admin > 0 && GetUserAdmin(admin) != INVALID_ADMIN_ID)
  2685. return GetAdminImmunityLevel(GetUserAdmin(admin));
  2686. else
  2687. return 0;
  2688. }
  2689.  
  2690. stock _:GetClientUserId2(client)
  2691. {
  2692. if (client)
  2693. return GetClientUserId(client);
  2694. else
  2695. return 0; // for CONSOLE
  2696. }
  2697.  
  2698. stock ForcePlayersRecheck()
  2699. {
  2700. for (new i = 1; i <= MaxClients; i++)
  2701. {
  2702. if (IsClientInGame(i) && IsClientAuthorized(i) && !IsFakeClient(i) && g_hPlayerRecheck[i] == INVALID_HANDLE)
  2703. {
  2704. #if defined DEBUG
  2705. {
  2706. decl String:clientAuth[64];
  2707. GetClientAuthString(i, clientAuth, sizeof(clientAuth));
  2708. PrintToServer("Creating Recheck timer for %s", clientAuth);
  2709. }
  2710. #endif
  2711. g_hPlayerRecheck[i] = CreateTimer(float(i), ClientRecheck, GetClientUserId(i));
  2712. }
  2713. }
  2714. }
  2715.  
  2716. stock bool:NotApplyToThisServer(srvID)
  2717. {
  2718. if (ConfigWhiteListOnly && FindValueInArray(g_hServersWhiteList, srvID) == -1)
  2719. return true;
  2720. else
  2721. return false;
  2722. }
  2723.  
  2724. stock MarkClientAsUnMuted(target)
  2725. {
  2726. g_MuteType[target] = bNot;
  2727. g_iMuteTime[target] = 0;
  2728. g_iMuteLength[target] = 0;
  2729. g_iMuteLevel[target] = -1;
  2730. g_sMuteAdminName[target][0] = '\0';
  2731. g_sMuteReason[target][0] = '\0';
  2732. g_sMuteAdminAuth[target][0] = '\0';
  2733. }
  2734.  
  2735. stock MarkClientAsUnGagged(target)
  2736. {
  2737. g_GagType[target] = bNot;
  2738. g_iGagTime[target] = 0;
  2739. g_iGagLength[target] = 0;
  2740. g_iGagLevel[target] = -1;
  2741. g_sGagAdminName[target][0] = '\0';
  2742. g_sGagReason[target][0] = '\0';
  2743. g_sGagAdminAuth[target][0] = '\0';
  2744. }
  2745.  
  2746. stock MarkClientAsMuted(target, time = NOW, length = -1, const String:adminName[] = "CONSOLE", const String:adminAuth[] = "STEAM_ID_SERVER", adminImmunity = 0, const String:reason[] = "")
  2747. {
  2748. if (time)
  2749. g_iMuteTime[target] = time;
  2750. else
  2751. g_iMuteTime[target] = GetTime();
  2752.  
  2753. g_iMuteLength[target] = length;
  2754. g_iMuteLevel[target] = adminImmunity ? adminImmunity : ConsoleImmunity;
  2755. strcopy(g_sMuteAdminName[target], sizeof(g_sMuteAdminName[]), adminName);
  2756. strcopy(g_sMuteReason[target], sizeof(g_sMuteReason[]), reason);
  2757. strcopy(g_sMuteAdminAuth[target], sizeof(g_sMuteAdminAuth[]), adminAuth);
  2758.  
  2759. if (length > 0)
  2760. g_MuteType[target] = bTime;
  2761. else if (length == 0)
  2762. g_MuteType[target] = bPerm;
  2763. else
  2764. g_MuteType[target] = bSess;
  2765. }
  2766.  
  2767. stock MarkClientAsGagged(target, time = NOW, length = -1, const String:adminName[] = "CONSOLE", const String:adminAuth[] = "STEAM_ID_SERVER", adminImmunity = 0, const String:reason[] = "")
  2768. {
  2769. if (time)
  2770. g_iGagTime[target] = time;
  2771. else
  2772. g_iGagTime[target] = GetTime();
  2773.  
  2774. g_iGagLength[target] = length;
  2775. g_iGagLevel[target] = adminImmunity ? adminImmunity : ConsoleImmunity;
  2776. strcopy(g_sGagAdminName[target], sizeof(g_sGagAdminName[]), adminName);
  2777. strcopy(g_sGagReason[target], sizeof(g_sGagReason[]), reason);
  2778. strcopy(g_sGagAdminAuth[target], sizeof(g_sGagAdminAuth[]), adminAuth);
  2779.  
  2780. if (length > 0)
  2781. g_GagType[target] = bTime;
  2782. else if (length == 0)
  2783. g_GagType[target] = bPerm;
  2784. else
  2785. g_GagType[target] = bSess;
  2786. }
  2787.  
  2788. stock CloseMuteExpireTimer(target)
  2789. {
  2790. if (g_hMuteExpireTimer[target] != INVALID_HANDLE && CloseHandle(g_hMuteExpireTimer[target]))
  2791. g_hMuteExpireTimer[target] = INVALID_HANDLE;
  2792. }
  2793.  
  2794. stock CloseGagExpireTimer(target)
  2795. {
  2796. if (g_hGagExpireTimer[target] != INVALID_HANDLE && CloseHandle(g_hGagExpireTimer[target]))
  2797. g_hGagExpireTimer[target] = INVALID_HANDLE;
  2798. }
  2799.  
  2800. stock CreateMuteExpireTimer(target, remainingTime = 0)
  2801. {
  2802. if (g_iMuteLength[target] > 0)
  2803. {
  2804. if (remainingTime)
  2805. g_hMuteExpireTimer[target] = CreateTimer(float(remainingTime), Timer_MuteExpire, GetClientUserId(target), TIMER_FLAG_NO_MAPCHANGE);
  2806. else
  2807. g_hMuteExpireTimer[target] = CreateTimer(float(g_iMuteLength[target] * 60), Timer_MuteExpire, GetClientUserId(target), TIMER_FLAG_NO_MAPCHANGE);
  2808. }
  2809. }
  2810.  
  2811. stock CreateGagExpireTimer(target, remainingTime = 0)
  2812. {
  2813. if (g_iGagLength[target] > 0)
  2814. {
  2815. if (remainingTime)
  2816. g_hGagExpireTimer[target] = CreateTimer(float(remainingTime), Timer_GagExpire, GetClientUserId(target), TIMER_FLAG_NO_MAPCHANGE);
  2817. else
  2818. g_hGagExpireTimer[target] = CreateTimer(float(g_iGagLength[target] * 60), Timer_GagExpire, GetClientUserId(target), TIMER_FLAG_NO_MAPCHANGE);
  2819. }
  2820. }
  2821.  
  2822. stock PerformUnMute(target)
  2823. {
  2824. MarkClientAsUnMuted(target);
  2825. BaseComm_SetClientMute(target, false);
  2826. CloseMuteExpireTimer(target);
  2827. }
  2828.  
  2829. stock PerformUnGag(target)
  2830. {
  2831. MarkClientAsUnGagged(target);
  2832. BaseComm_SetClientGag(target, false);
  2833. CloseGagExpireTimer(target);
  2834. }
  2835.  
  2836. stock PerformMute(target, time = NOW, length = -1, const String:adminName[] = "CONSOLE", const String:adminAuth[] = "STEAM_ID_SERVER", adminImmunity = 0, const String:reason[] = "", remaining_time = 0)
  2837. {
  2838. MarkClientAsMuted(target, time, length, adminName, adminAuth, adminImmunity, reason);
  2839. BaseComm_SetClientMute(target, true);
  2840. CreateMuteExpireTimer(target, remaining_time);
  2841. }
  2842.  
  2843. stock PerformGag(target, time = NOW, length = -1, const String:adminName[] = "CONSOLE", const String:adminAuth[] = "STEAM_ID_SERVER", adminImmunity = 0, const String:reason[] = "", remaining_time = 0)
  2844. {
  2845. MarkClientAsGagged(target, time, length, adminName, adminAuth, adminImmunity, reason);
  2846. BaseComm_SetClientGag(target, true);
  2847. CreateGagExpireTimer(target, remaining_time);
  2848. }
  2849.  
  2850. stock SavePunishment(admin = 0, target, type, length = -1 , const String:reason[] = "")
  2851. {
  2852. if (type < TYPE_MUTE || type > TYPE_SILENCE)
  2853. return;
  2854.  
  2855. // target information
  2856. new String:targetAuth[64];
  2857. if (IsClientInGame(target))
  2858. {
  2859. GetClientAuthString(target, targetAuth, sizeof(targetAuth));
  2860. }
  2861. else
  2862. {
  2863. return;
  2864. }
  2865.  
  2866. new String:adminIp[24];
  2867. new String:adminAuth[64];
  2868. if (admin && IsClientInGame(admin))
  2869. {
  2870. GetClientIP(admin, adminIp, sizeof(adminIp));
  2871. GetClientAuthString(admin, adminAuth, sizeof(adminAuth));
  2872. }
  2873. else
  2874. {
  2875. // setup dummy adminAuth and adminIp for server
  2876. strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  2877. strcopy(adminIp, sizeof(adminIp), ServerIp);
  2878. }
  2879.  
  2880. new String:sName[MAX_NAME_LENGTH];
  2881. strcopy(sName, sizeof(sName), g_sName[target]);
  2882.  
  2883. if (DB_Connect())
  2884. {
  2885. // Accepts length in minutes, writes to db in seconds! In all over places in plugin - length is in minutes.
  2886. new String:banName[MAX_NAME_LENGTH * 2 + 1];
  2887. new String:banReason[256 * 2 + 1];
  2888. new String:sAuthidEscaped[64 * 2 + 1];
  2889. new String:sAdminAuthIdEscaped[64 * 2 + 1];
  2890. new String:sAdminAuthIdYZEscaped[64 * 2 + 1];
  2891. decl String:sQuery[4096], String:sQueryAdm[512], String:sQueryVal[1024];
  2892. new String:sQueryMute[1024], String:sQueryGag[1024];
  2893.  
  2894. // escaping everything
  2895. SQL_EscapeString(g_hDatabase, sName, banName, sizeof(banName));
  2896. SQL_EscapeString(g_hDatabase, reason, banReason, sizeof(banReason));
  2897. SQL_EscapeString(g_hDatabase, targetAuth, sAuthidEscaped, sizeof(sAuthidEscaped));
  2898. SQL_EscapeString(g_hDatabase, adminAuth, sAdminAuthIdEscaped, sizeof(sAdminAuthIdEscaped));
  2899. SQL_EscapeString(g_hDatabase, adminAuth[8], sAdminAuthIdYZEscaped, sizeof(sAdminAuthIdYZEscaped));
  2900.  
  2901. // bid authid name created ends lenght reason aid adminip sid removedBy removedType removedon type ureason
  2902. FormatEx(sQueryAdm, sizeof(sQueryAdm),
  2903. "IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), 0)",
  2904. DatabasePrefix, sAdminAuthIdEscaped, sAdminAuthIdYZEscaped);
  2905.  
  2906. // authid name, created, ends, length, reason, aid, adminIp, sid
  2907. FormatEx(sQueryVal, sizeof(sQueryVal),
  2908. "'%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', %s, '%s', %d",
  2909. sAuthidEscaped, banName, length*60, length*60, banReason, sQueryAdm, adminIp, serverID);
  2910.  
  2911. if (type == TYPE_MUTE || type == TYPE_SILENCE)
  2912. {
  2913. FormatEx(sQueryMute, sizeof(sQueryMute), "(%s, %d)", sQueryVal, TYPE_MUTE);
  2914. }
  2915. if (type == TYPE_GAG || type == TYPE_SILENCE)
  2916. {
  2917. FormatEx(sQueryGag, sizeof(sQueryGag), "(%s, %d)", sQueryVal, TYPE_GAG);
  2918. }
  2919.  
  2920. // litle magic - one query for all actions (mute, gag or silence)
  2921. FormatEx(sQuery, sizeof(sQuery),
  2922. "INSERT INTO %s_comms (authid, name, created, ends, length, reason, aid, adminIp, sid, type) VALUES %s%s%s",
  2923. DatabasePrefix, sQueryMute, type == TYPE_SILENCE ? ", " : "", sQueryGag);
  2924.  
  2925. #if defined LOG_QUERIES
  2926. LogToFile(logQuery, "SavePunishment. QUERY: %s", sQuery);
  2927. #endif
  2928.  
  2929. // all data cached before calling asynchronous functions
  2930. new Handle:dataPack = CreateDataPack();
  2931. WritePackCell(dataPack, length);
  2932. WritePackCell(dataPack, type);
  2933. WritePackString(dataPack, sName);
  2934. WritePackString(dataPack, targetAuth);
  2935. WritePackString(dataPack, reason);
  2936. WritePackString(dataPack, adminAuth);
  2937. WritePackString(dataPack, adminIp);
  2938.  
  2939. SQL_TQuery(g_hDatabase, Query_AddBlockInsert, sQuery, dataPack, DBPrio_High);
  2940. }
  2941. else
  2942. InsertTempBlock(length, type, sName, targetAuth, reason, adminAuth, adminIp);
  2943. }
  2944.  
  2945. stock ShowActivityToServer(admin, type, length = 0, String:reason[] = "", String:targetName[], bool:ml = false)
  2946. {
  2947. #if defined DEBUG
  2948. PrintToServer("ShowActivityToServer(admin: %d, type: %d, length: %d, reason: %s, name: %s, ml: %b",
  2949. admin, type, length, reason, targetName, ml);
  2950. #endif
  2951.  
  2952. new String:actionName[32], String:translationName[64];
  2953. switch(type)
  2954. {
  2955. case TYPE_MUTE:
  2956. {
  2957. if (length > 0)
  2958. strcopy(actionName, sizeof(actionName), "Muted");
  2959. else if (length == 0)
  2960. strcopy(actionName, sizeof(actionName), "Permamuted");
  2961. else // temp block
  2962. strcopy(actionName, sizeof(actionName), "Temp muted");
  2963. }
  2964. //-------------------------------------------------------------------------------------------------
  2965. case TYPE_GAG:
  2966. {
  2967. if (length > 0)
  2968. strcopy(actionName, sizeof(actionName), "Gagged");
  2969. else if (length == 0)
  2970. strcopy(actionName, sizeof(actionName), "Permagagged");
  2971. else //temp block
  2972. strcopy(actionName, sizeof(actionName), "Temp gagged");
  2973. }
  2974. //-------------------------------------------------------------------------------------------------
  2975. case TYPE_SILENCE:
  2976. {
  2977. if (length > 0)
  2978. strcopy(actionName, sizeof(actionName), "Silenced");
  2979. else if (length == 0)
  2980. strcopy(actionName, sizeof(actionName), "Permasilenced");
  2981. else //temp block
  2982. strcopy(actionName, sizeof(actionName), "Temp silenced");
  2983. }
  2984. //-------------------------------------------------------------------------------------------------
  2985. case TYPE_UNMUTE:
  2986. {
  2987. strcopy(actionName, sizeof(actionName), "Unmuted");
  2988. }
  2989. //-------------------------------------------------------------------------------------------------
  2990. case TYPE_UNGAG:
  2991. {
  2992. strcopy(actionName, sizeof(actionName), "Ungagged");
  2993. }
  2994. //-------------------------------------------------------------------------------------------------
  2995. case TYPE_TEMP_UNMUTE:
  2996. {
  2997. strcopy(actionName, sizeof(actionName), "Temp unmuted");
  2998. }
  2999. //-------------------------------------------------------------------------------------------------
  3000. case TYPE_TEMP_UNGAG:
  3001. {
  3002. strcopy(actionName, sizeof(actionName), "Temp ungagged");
  3003. }
  3004. //-------------------------------------------------------------------------------------------------
  3005. case TYPE_TEMP_UNSILENCE:
  3006. {
  3007. strcopy(actionName, sizeof(actionName), "Temp unsilenced");
  3008. }
  3009. //-------------------------------------------------------------------------------------------------
  3010. default:
  3011. {
  3012. return;
  3013. }
  3014. }
  3015.  
  3016. Format(translationName, sizeof(translationName), "%s %s", actionName, reason[0] == '\0' ? "player" : "player reason");
  3017. #if defined DEBUG
  3018. PrintToServer("translation name: %s", translationName);
  3019. #endif
  3020.  
  3021. if (length > 0)
  3022. {
  3023. if (ml)
  3024. ShowActivity2(admin, PREFIX, "%t", translationName, targetName, length, reason);
  3025. else
  3026. ShowActivity2(admin, PREFIX, "%t", translationName, "_s", targetName, length, reason);
  3027. }
  3028. else
  3029. {
  3030. if (ml)
  3031. ShowActivity2(admin, PREFIX, "%t", translationName, targetName, reason);
  3032. else
  3033. ShowActivity2(admin, PREFIX, "%t", translationName, "_s", targetName, reason);
  3034. }
  3035. }
  3036.  
  3037. // Natives //
  3038. public Native_SetClientMute(Handle:hPlugin, numParams)
  3039. {
  3040. new target = GetNativeCell(1);
  3041. if (target < 1 || target > MaxClients)
  3042. {
  3043. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02Invalid %d!", target);
  3044. }
  3045.  
  3046. if (!IsClientInGame(target))
  3047. {
  3048. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02 Jucatorul %d nu este in joc", target);
  3049. }
  3050.  
  3051. new bool:muteState = GetNativeCell(2);
  3052. new muteLength = GetNativeCell(3);
  3053. if (muteState && muteLength == 0)
  3054. {
  3055. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02 Mute-ul permanent nu este permis!");
  3056. }
  3057.  
  3058. new bool:bSaveToDB = GetNativeCell(4);
  3059. if (!muteState && bSaveToDB)
  3060. {
  3061. return ThrowNativeError(SP_ERROR_NATIVE, "Removing punishments from DB is not allowed!");
  3062. }
  3063.  
  3064. decl String:sReason[256];
  3065. GetNativeString(5, sReason, sizeof(sReason));
  3066.  
  3067. if (muteState)
  3068. {
  3069. if (g_MuteType[target] > bNot)
  3070. {
  3071. return false;
  3072. }
  3073.  
  3074. PerformMute(target, _, muteLength, _, _, _, sReason);
  3075.  
  3076. if (bSaveToDB)
  3077. SavePunishment(_, target, TYPE_MUTE, muteLength, sReason);
  3078. }
  3079. else
  3080. {
  3081. if (g_MuteType[target] == bNot)
  3082. {
  3083. return false;
  3084. }
  3085.  
  3086. PerformUnMute(target);
  3087. }
  3088.  
  3089. return true;
  3090. }
  3091.  
  3092. public Native_SetClientGag(Handle:hPlugin, numParams)
  3093. {
  3094. new target = GetNativeCell(1);
  3095. if (target < 1 || target > MaxClients)
  3096. {
  3097. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02Invalid %d!", target);
  3098. }
  3099.  
  3100. if (!IsClientInGame(target))
  3101. {
  3102. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02 Jucatorul %d nu este in joc",, target);
  3103. }
  3104.  
  3105. new bool:gagState = GetNativeCell(2);
  3106. new gagLength = GetNativeCell(3);
  3107. if (gagState && gagLength == 0)
  3108. {
  3109. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02 Mute-ul permanent nu este permis!");
  3110. }
  3111.  
  3112. new bool:bSaveToDB = GetNativeCell(4);
  3113. if (!gagState && bSaveToDB)
  3114. {
  3115. return ThrowNativeError(SP_ERROR_NATIVE, "Removing punishments from DB is not allowed!");
  3116. }
  3117.  
  3118. decl String:sReason[256];
  3119. GetNativeString(5, sReason, sizeof(sReason));
  3120.  
  3121. if (gagState)
  3122. {
  3123. if (g_GagType[target] > bNot)
  3124. {
  3125. return false;
  3126. }
  3127.  
  3128. PerformGag(target, _, gagLength, _, _, _, sReason);
  3129.  
  3130. if (bSaveToDB)
  3131. SavePunishment(_, target, TYPE_GAG, gagLength, sReason);
  3132. }
  3133. else
  3134. {
  3135. if (g_GagType[target] == bNot)
  3136. {
  3137. return false;
  3138. }
  3139.  
  3140. PerformUnGag(target);
  3141. }
  3142.  
  3143. return true;
  3144. }
  3145.  
  3146. public Native_GetClientMuteType(Handle:hPlugin, numParams)
  3147. {
  3148. new target = GetNativeCell(1);
  3149. if (target < 1 || target > MaxClients)
  3150. {
  3151. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02Invalid %d!", target);
  3152. }
  3153.  
  3154. if (!IsClientInGame(target))
  3155. {
  3156. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02 Jucatorul %d nu este in joc",, target);
  3157. }
  3158.  
  3159. return bType:g_MuteType[target];
  3160. }
  3161.  
  3162. public Native_GetClientGagType(Handle:hPlugin, numParams)
  3163. {
  3164. new target = GetNativeCell(1);
  3165. if (target < 1 || target > MaxClients)
  3166. {
  3167. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02Invalid %d!", target);
  3168. }
  3169.  
  3170. if (!IsClientInGame(target))
  3171. {
  3172. return ThrowNativeError(SP_ERROR_NATIVE, "\x04★[Mevid]\x02 Jucatorul %d nu este in joc", target);
  3173. }
  3174.  
  3175. return bType:g_GagType[target];
  3176. }
  3177. //Yarr!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement