Advertisement
Guest User

sourcebans.sp

a guest
Sep 20th, 2014
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 65.83 KB | None | 0 0
  1. /**
  2. * sourcebans.sp
  3. *
  4. * This file contains all Source Server Plugin Functions
  5. * @author SourceBans Development Team
  6. * @version 0.0.0.$Rev: 108 $
  7. * @copyright InterWave Studios (www.interwavestudios.com)
  8. * @package SourceBans
  9. * @link http://www.sourcebans.net
  10. */
  11.  
  12. #pragma semicolon 1
  13. #include <sourcemod>
  14. #include <sourcebans>
  15.  
  16. #undef REQUIRE_PLUGIN
  17. #include <adminmenu>
  18. #include "dbi.inc"
  19.  
  20. #define SB_VERSION "1.4.11"
  21.  
  22. //GLOBAL DEFINES
  23. #define YELLOW              0x01
  24. #define NAMECOLOR           0x02
  25. #define TEAMCOLOR           0x03
  26. #define GREEN               0x04
  27.  
  28. #define DISABLE_ADDBAN      1
  29. #define DISABLE_UNBAN       2
  30.  
  31. //#define DEBUG
  32.  
  33. enum State /* ConfigState */
  34. {
  35.     ConfigStateNone = 0,
  36.     ConfigStateConfig,
  37.     ConfigStateReasons,
  38.     ConfigStateHacking
  39. }
  40.  
  41. new g_BanTarget[MAXPLAYERS+1] = {-1, ...};
  42. new g_BanTime[MAXPLAYERS+1] = {-1, ...};
  43.  
  44. new State:ConfigState;
  45. new Handle:ConfigParser;
  46.  
  47. new Handle:hTopMenu = INVALID_HANDLE;
  48.  
  49. new const String:BLANK[] = "";
  50. new const String:Prefix[] = "[SourceBans] ";
  51.  
  52. new String:ServerIp[24];
  53. new String:ServerPort[7];
  54. new String:DatabasePrefix[10] = "sb";
  55. new String:WebsiteAddress[128];
  56.  
  57. /* Admin Stuff*/
  58. new AdminCachePart:loadPart;
  59. new bool:loadAdmins;
  60. new bool:loadGroups;
  61. new bool:loadOverrides;
  62. new curLoading=0;
  63. new AdminFlag:g_FlagLetters[26];
  64.  
  65. /* Admin KeyValues */
  66. new String:groupsLoc[128];
  67. new String:adminsLoc[128];
  68.    
  69. /* Cvar handle*/
  70. new Handle:CvarHostIp;
  71. new Handle:CvarPort;
  72.  
  73. /* Database handle */
  74. new Handle:Database;
  75. new Handle:SQLiteDB;
  76.  
  77. /* Menu file globals */
  78. new Handle:ReasonMenuHandle;
  79. new Handle:HackingMenuHandle;
  80.  
  81. /* Datapack and Timer handles */
  82. new Handle:PlayerRecheck[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
  83. new Handle:PlayerDataPack[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
  84.  
  85. /* Player ban check status */
  86. new bool:PlayerStatus[MAXPLAYERS + 1];
  87.  
  88. /* Disable of addban and unban */
  89. new CommandDisable;
  90. new bool:backupConfig = true;
  91. new bool:enableAdmins = true;
  92.  
  93. /* Require a lastvisited from SB site */
  94. new bool:requireSiteLogin = false;
  95.  
  96. /* Log Stuff */
  97. new String:logFile[256];
  98.  
  99. /* Own Chat Reason */
  100. new g_ownReasons[MAXPLAYERS+1] = {false, ...};
  101.  
  102. new MaxSlots;
  103. new Float:RetryTime = 15.0;
  104. new ProcessQueueTime = 5;
  105. new bool:LateLoaded;
  106. new bool:AutoAdd;
  107. new bool:g_bConnecting = false;
  108.  
  109. new serverID = -1;
  110.  
  111. public Plugin:myinfo =
  112. {
  113.     name = "SourceBans",
  114.     author = "SourceBans Development Team",
  115.     description = "Advanced ban management for the Source engine",
  116.     version = SB_VERSION,
  117.     url = "http://www.sourcebans.net"
  118. };
  119.  
  120. #if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
  121. public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
  122. #else
  123. public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
  124. #endif
  125. {
  126.     RegPluginLibrary("sourcebans");
  127.     CreateNative("SBBanPlayer", Native_SBBanPlayer);
  128.     LateLoaded = late;
  129.    
  130.     #if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
  131.         return APLRes_Success;
  132.     #else
  133.         return true;
  134.     #endif
  135. }
  136.  
  137. public OnPluginStart()
  138. {  
  139.     LoadTranslations("common.phrases");
  140.     LoadTranslations("plugin.basecommands");
  141.     LoadTranslations("sourcebans.phrases");
  142.     LoadTranslations("basebans.phrases");
  143.     loadAdmins = loadGroups = loadOverrides = false;
  144.    
  145.     CvarHostIp = FindConVar("hostip");
  146.     CvarPort = FindConVar("hostport");
  147.     CreateConVar("sb_version", SB_VERSION, _, FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
  148.     RegServerCmd("sm_rehash",sm_rehash,"Reload SQL admins");
  149.     RegAdminCmd("sm_ban", CommandBan, ADMFLAG_BAN, "sm_ban <#userid|name> <minutes|0> [reason]");
  150.     RegAdminCmd("sm_banip", CommandBanIp, ADMFLAG_BAN, "sm_banip <ip|#userid|name> <time> [reason]");
  151.     RegAdminCmd("sm_addban", CommandAddBan, ADMFLAG_RCON, "sm_addban <time> <steamid> [reason]");
  152.     RegAdminCmd("sm_unban", CommandUnban, ADMFLAG_UNBAN, "sm_unban <steamid|ip> [reason]");
  153.     RegAdminCmd("sb_reload",
  154.                 _CmdReload,
  155.                 ADMFLAG_RCON,
  156.                 "Reload sourcebans config and ban reason menu options",
  157.                 BLANK);
  158.    
  159.     RegConsoleCmd("say", ChatHook);
  160.     RegConsoleCmd("say_team", ChatHook);
  161.    
  162.     if((ReasonMenuHandle = CreateMenu(ReasonSelected)) != INVALID_HANDLE)
  163.     {
  164.         SetMenuPagination(ReasonMenuHandle, 8);
  165.         SetMenuExitBackButton(ReasonMenuHandle, true);
  166.     }
  167.  
  168.     if((HackingMenuHandle = CreateMenu(HackingSelected)) != INVALID_HANDLE)
  169.     {
  170.         SetMenuPagination(HackingMenuHandle, 8);
  171.         SetMenuExitBackButton(HackingMenuHandle, true);
  172.     }
  173.    
  174.     g_FlagLetters['a'-'a'] = Admin_Reservation;
  175.     g_FlagLetters['b'-'a'] = Admin_Generic;
  176.     g_FlagLetters['c'-'a'] = Admin_Kick;
  177.     g_FlagLetters['d'-'a'] = Admin_Ban;
  178.     g_FlagLetters['e'-'a'] = Admin_Unban;
  179.     g_FlagLetters['f'-'a'] = Admin_Slay;
  180.     g_FlagLetters['g'-'a'] = Admin_Changemap;
  181.     g_FlagLetters['h'-'a'] = Admin_Convars;
  182.     g_FlagLetters['i'-'a'] = Admin_Config;
  183.     g_FlagLetters['j'-'a'] = Admin_Chat;
  184.     g_FlagLetters['k'-'a'] = Admin_Vote;
  185.     g_FlagLetters['l'-'a'] = Admin_Password;
  186.     g_FlagLetters['m'-'a'] = Admin_RCON;
  187.     g_FlagLetters['n'-'a'] = Admin_Cheats;
  188.     g_FlagLetters['o'-'a'] = Admin_Custom1;
  189.     g_FlagLetters['p'-'a'] = Admin_Custom2;
  190.     g_FlagLetters['q'-'a'] = Admin_Custom3;
  191.     g_FlagLetters['r'-'a'] = Admin_Custom4;
  192.     g_FlagLetters['s'-'a'] = Admin_Custom5;
  193.     g_FlagLetters['t'-'a'] = Admin_Custom6;
  194.     g_FlagLetters['z'-'a'] = Admin_Root;
  195.    
  196.    
  197.     BuildPath(Path_SM, logFile, sizeof(logFile), "logs/sourcebans.log");
  198.     g_bConnecting = true;
  199.    
  200.     // Catch config error and show link to FAQ
  201.     if(!SQL_CheckConfig("sourcebans"))
  202.     {
  203.         if(ReasonMenuHandle != INVALID_HANDLE)
  204.             CloseHandle(ReasonMenuHandle);
  205.         if(HackingMenuHandle != INVALID_HANDLE)
  206.             CloseHandle(HackingMenuHandle);
  207.         LogToFile(logFile, "Database failure: Could not find Database conf \"sourcebans\". See FAQ: http://sourcebans.net/node/19");
  208.         SetFailState("Database failure: Could not find Database conf \"sourcebans\"");
  209.         return;
  210.     }
  211.     SQL_TConnect(GotDatabase, "sourcebans");
  212.    
  213.     BuildPath(Path_SM,groupsLoc,sizeof(groupsLoc),"configs/admin_groups.cfg");
  214.    
  215.     BuildPath(Path_SM,adminsLoc,sizeof(adminsLoc),"configs/admins.cfg");
  216.    
  217.     InitializeBackupDB();
  218.    
  219.     // This timer is what processes the SQLite queue when the database is unavailable
  220.     CreateTimer(float(ProcessQueueTime * 60), ProcessQueue);
  221.    
  222.     /* Account for late loading */
  223.     if(LateLoaded)
  224.     {
  225.         decl String:auth[30];
  226.         for(new i = 1; i <= GetMaxClients(); i++)
  227.         {
  228.             if(IsClientConnected(i) && !IsFakeClient(i))
  229.             {
  230.                 PlayerStatus[i] = false;
  231.             }
  232.             if(IsClientInGame(i) && !IsFakeClient(i))
  233.             {
  234.                 GetClientAuthString(i, auth, sizeof(auth));
  235.                 OnClientAuthorized(i, auth);
  236.             }
  237.         }
  238.     }
  239. }
  240.  
  241. public OnAllPluginsLoaded()
  242. {
  243.     new Handle:topmenu;
  244. #if defined DEBUG
  245.     LogToFile(logFile, "OnAllPluginsLoaded()");
  246. #endif
  247.        
  248.     if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
  249.     {
  250.         OnAdminMenuReady(topmenu);
  251.     }
  252. }
  253.  
  254. public OnConfigsExecuted()
  255. {
  256.     decl String:filename[200];
  257.     BuildPath(Path_SM, filename, sizeof(filename), "plugins/basebans.smx");
  258.     if(FileExists(filename))
  259.     {
  260.         decl String:newfilename[200];
  261.         BuildPath(Path_SM, newfilename, sizeof(newfilename), "plugins/disabled/basebans.smx");
  262.         ServerCommand("sm plugins unload basebans");
  263.         if(FileExists(newfilename))
  264.             DeleteFile(newfilename);
  265.         RenameFile(newfilename, filename);
  266.         LogToFile(logFile, "plugins/basebans.smx was unloaded and moved to plugins/disabled/basebans.smx");
  267.     }
  268. }
  269.  
  270. public OnMapStart()
  271. {
  272.     MaxSlots = GetMaxClients();
  273.     ResetSettings();
  274. }
  275.  
  276. public OnMapEnd()
  277. {
  278.     for(new i = 0; i <= MaxSlots; i++)
  279.     {
  280.         if(PlayerDataPack[i] != INVALID_HANDLE)
  281.         {
  282.             /* Need to close reason pack */
  283.             CloseHandle(PlayerDataPack[i]);
  284.             PlayerDataPack[i] = INVALID_HANDLE;
  285.         }
  286.     }
  287. }
  288.  
  289. // CLIENT CONNECTION FUNCTIONS //
  290.  
  291. public Action:OnClientPreAdminCheck(client)
  292. {
  293.     if (curLoading > 0)
  294.         return Plugin_Stop;
  295.     return Plugin_Continue;
  296. }
  297.  
  298. public OnClientDisconnect(client)
  299. {
  300.     if(PlayerRecheck[client] != INVALID_HANDLE)
  301.     {
  302.         KillTimer(PlayerRecheck[client]);
  303.         PlayerRecheck[client] = INVALID_HANDLE;
  304.     }
  305.     g_ownReasons[client] = false;
  306. }
  307.  
  308. public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
  309. {
  310.     PlayerStatus[client] = false;
  311.     return true;
  312. }
  313.  
  314. public OnClientAuthorized(client, const String:auth[])
  315. {
  316.     /* Do not check bots nor check player with lan steamid. */
  317.     if(auth[0] == 'B' || auth[9] == 'L' || Database == INVALID_HANDLE)
  318.     {
  319.         PlayerStatus[client] = true;
  320.         return;
  321.     }
  322.    
  323.     decl String:Query[256], String:ip[30];
  324.     GetClientIP(client, ip, sizeof(ip));
  325.     FormatEx(Query, sizeof(Query), "SELECT bid FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL", DatabasePrefix, auth[8], ip);
  326. #if defined DEBUG
  327.     LogToFile(logFile, "Checking ban for: %s", auth);
  328. #endif
  329.    
  330.     SQL_TQuery(Database, VerifyBan, Query, GetClientUserId(client), DBPrio_High);
  331. }
  332.  
  333. public OnRebuildAdminCache(AdminCachePart:part)
  334. {
  335.     loadPart = part;
  336.     switch(loadPart)
  337.     {
  338.         case AdminCache_Overrides:
  339.         loadOverrides = true;
  340.         case AdminCache_Groups:
  341.             loadGroups = true;
  342.         case AdminCache_Admins:
  343.             loadAdmins = true;
  344.     }
  345.     if(enableAdmins)
  346.     {
  347.         if(Database == INVALID_HANDLE) {
  348.             if(!g_bConnecting) {
  349.                 g_bConnecting = true;
  350.                 SQL_TConnect(GotDatabase,"sourcebans");
  351.             }
  352.         }
  353.         else {
  354.             GotDatabase(Database,Database,"",0);
  355.         }
  356.     }
  357. }
  358.  
  359. // COMMAND CODE //
  360.  
  361. public Action:ChatHook(client, args)
  362. {
  363.     // is this player preparing to ban someone
  364.     if (g_ownReasons[client])
  365.     {
  366.         // get the reason
  367.         new String:reason[512];
  368.         GetCmdArgString(reason, sizeof(reason));
  369.         StripQuotes(reason);
  370.        
  371.         g_ownReasons[client] = false;
  372.        
  373.         if(StrEqual(reason[0], "!noreason"))
  374.         {
  375.             PrintToChat(client, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Chat Reason Aborted");
  376.             return Plugin_Handled;
  377.         }
  378.        
  379.         // ban him!
  380.         PrepareBan(client, g_BanTarget[client], g_BanTime[client], reason, sizeof(reason));
  381.        
  382.         // block the reason to be sent in chat
  383.         return Plugin_Handled;
  384.     }
  385.     return Plugin_Continue;
  386. }
  387.  
  388. public Action:_CmdReload(client, args)
  389. {
  390.     ResetSettings();
  391.     return Plugin_Handled;
  392. }
  393.  
  394. public Action:CommandBan(client, args)
  395. {
  396.     if(args < 2)
  397.     {
  398.         ReplyToCommand(client, "%sUsage: sm_ban <#userid|name> <time|0> [reason]", Prefix);
  399.         return Plugin_Handled;
  400.     }
  401.  
  402.     // This is mainly for me sanity since client used to be called admin and target used to be called client
  403.     new admin = client;
  404.    
  405.     // Get the target, find target returns a message on failure so we do not
  406.     decl String:buffer[100];
  407.     GetCmdArg(1, buffer, sizeof(buffer));
  408.     new target = FindTarget(client, buffer, true);
  409.     if(target == -1)
  410.     {
  411.         return Plugin_Handled;
  412.     }
  413.  
  414.     // Get the ban time
  415.     GetCmdArg(2, buffer, sizeof(buffer));
  416.     new time = StringToInt(buffer);
  417.     if(!time && client && !(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN|ADMFLAG_ROOT)))
  418.     {
  419.         ReplyToCommand(client, "You do not have Perm Ban Permission");
  420.         return Plugin_Handled;
  421.     }
  422.    
  423.     // Get the reason
  424.     decl String:reason[128];
  425.     if(args >= 3)
  426.     {
  427.         GetCmdArg(3, reason, sizeof(reason));
  428.     }
  429.     else
  430.     {
  431.         reason[0] = '\0';
  432.     }
  433.    
  434.     g_BanTarget[client] = target;
  435.     g_BanTime[client] = time;
  436.    
  437.     if(!PlayerStatus[target])
  438.     {
  439.         // The target has not been banned verify. It must be completed before you can ban anyone.
  440.         ReplyToCommand(admin, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Ban Not Verified");
  441.         return Plugin_Handled;
  442.     }
  443.  
  444.    
  445.     CreateBan(client, target, time, reason);
  446.     return Plugin_Handled;
  447. }
  448.  
  449. public Action:CommandBanIp(client, args)
  450. {
  451.     if (args < 2)
  452.     {
  453.         ReplyToCommand(client, "%sUsage: sm_banip <ip|#userid|name> <time> [reason]", Prefix);
  454.         return Plugin_Handled;
  455.     }
  456.  
  457.     decl len, next_len;
  458.     decl String:Arguments[256];
  459.     decl String:arg[50], String:time[20];
  460.    
  461.     GetCmdArgString(Arguments, sizeof(Arguments));
  462.     len = BreakString(Arguments, arg, sizeof(arg));
  463.    
  464.     if ((next_len = BreakString(Arguments[len], time, sizeof(time))) != -1)
  465.     {
  466.         len += next_len;
  467.     }
  468.     else
  469.     {
  470.         len = 0;
  471.         Arguments[0] = '\0';
  472.     }
  473.    
  474.     decl String:target_name[MAX_TARGET_LENGTH];
  475.     decl target_list[1], bool:tn_is_ml;
  476.     new target = -1;
  477.    
  478.     if (ProcessTargetString(
  479.             arg,
  480.             client,
  481.             target_list,
  482.             1,
  483.             COMMAND_FILTER_CONNECTED|COMMAND_FILTER_NO_MULTI,
  484.             target_name,
  485.             sizeof(target_name),
  486.             tn_is_ml) > 0)
  487.     {
  488.         target = target_list[0];
  489.        
  490.         if (!IsFakeClient(target) && CanUserTarget(client, target))
  491.             GetClientIP(target, arg, sizeof(arg));
  492.     }
  493.    
  494.     decl String:adminIp[24], String:adminAuth[64];
  495.     new minutes = StringToInt(time);
  496.     if(!minutes && client && !(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN|ADMFLAG_ROOT)))
  497.     {
  498.         ReplyToCommand(client, "You do not have Perm Ban Permission");
  499.         return Plugin_Handled;
  500.     }
  501.     if(!client)
  502.     {
  503.         // setup dummy adminAuth and adminIp for server
  504.         strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  505.         strcopy(adminIp, sizeof(adminIp), ServerIp);
  506.     } else {
  507.         GetClientIP(client, adminIp, sizeof(adminIp));
  508.         GetClientAuthString(client, adminAuth, sizeof(adminAuth));
  509.     }
  510.    
  511.     // Pack everything into a data pack so we can retain it
  512.     new Handle:dataPack = CreateDataPack();
  513.     WritePackCell(dataPack, client);
  514.     WritePackCell(dataPack, minutes);
  515.     WritePackString(dataPack, Arguments[len]);
  516.     WritePackString(dataPack, arg);
  517.     WritePackString(dataPack, adminAuth);
  518.     WritePackString(dataPack, adminIp);
  519.    
  520.     decl String:Query[256];
  521.     FormatEx(Query, sizeof(Query), "SELECT bid FROM %s_bans WHERE type = 1 AND ip     = '%s' AND (length = 0 OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL",
  522.                                                                     DatabasePrefix, arg);
  523.    
  524.     SQL_TQuery(Database, SelectBanIpCallback,  Query, dataPack, DBPrio_High);
  525.     return Plugin_Handled;
  526. }
  527.  
  528. public Action:CommandUnban(client, args)
  529. {
  530.     if(args < 1)
  531.     {
  532.         ReplyToCommand(client, "%sUsage: sm_unban <steamid|ip> [reason]", Prefix);
  533.         return Plugin_Handled;
  534.     }
  535.    
  536.     if(CommandDisable & DISABLE_UNBAN)
  537.     {
  538.         // They must go to the website to unban people
  539.         ReplyToCommand(client, "%s%t", Prefix, "Can Not Unban", WebsiteAddress);
  540.         return Plugin_Handled;
  541.     }
  542.    
  543.     decl len, String:Arguments[256], String:arg[50], String:adminAuth[64];
  544.     GetCmdArgString(Arguments, sizeof(Arguments));
  545.    
  546.     if ((len = BreakString(Arguments, arg, sizeof(arg))) == -1)
  547.     {
  548.         len = 0;
  549.         Arguments[0] = '\0';
  550.     }
  551.     if(!client)
  552.     {
  553.         // setup dummy adminAuth and adminIp for server
  554.         strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  555.     } else {
  556.         GetClientAuthString(client, adminAuth, sizeof(adminAuth));
  557.     }
  558.    
  559.     // Pack everything into a data pack so we can retain it
  560.     new Handle:dataPack = CreateDataPack();
  561.     WritePackCell(dataPack, client);
  562.     WritePackString(dataPack, Arguments[len]);
  563.     WritePackString(dataPack, arg);
  564.     WritePackString(dataPack, adminAuth);
  565.    
  566.     decl String:query[200];
  567.     if (strncmp(arg, "STEAM_", 6) == 0)
  568.     {
  569.         Format(query, sizeof(query), "SELECT bid FROM %s_bans WHERE (type = 0 AND authid = '%s') AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL", DatabasePrefix, arg);
  570.     } else {
  571.         Format(query, sizeof(query), "SELECT bid FROM %s_bans WHERE (type = 1 AND ip     = '%s') AND (length = '0' OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL", DatabasePrefix, arg);
  572.     }
  573.     SQL_TQuery(Database, SelectUnbanCallback, query, dataPack);
  574.     return Plugin_Handled;
  575. }
  576.  
  577. public Action:CommandAddBan(client, args)
  578. {
  579.     if (args < 2)
  580.     {
  581.         ReplyToCommand(client, "%sUsage: sm_addban <time> <steamid> [reason]", Prefix);
  582.         return Plugin_Handled;
  583.     }
  584.    
  585.     if(CommandDisable & DISABLE_ADDBAN)
  586.     {
  587.         // They must go to the website to add bans
  588.         ReplyToCommand(client, "%s%t", Prefix, "Can Not Add Ban", WebsiteAddress);
  589.         return Plugin_Handled;
  590.     }
  591.    
  592.     decl String:arg_string[256], String:time[50], String:authid[50];
  593.     GetCmdArgString(arg_string, sizeof(arg_string));
  594.    
  595.     new len, total_len;
  596.    
  597.     /* Get time */
  598.     if ((len = BreakString(arg_string, time, sizeof(time))) == -1)
  599.     {
  600.         ReplyToCommand(client, "%sUsage: sm_addban <time> <steamid> [reason]", Prefix);
  601.         return Plugin_Handled;
  602.     }  
  603.     total_len += len;
  604.    
  605.     /* Get steamid */
  606.     if ((len = BreakString(arg_string[total_len], authid, sizeof(authid))) != -1)
  607.     {
  608.         total_len += len;
  609.     }
  610.     else
  611.     {
  612.         total_len = 0;
  613.         arg_string[0] = '\0';
  614.     }
  615.    
  616.     decl String:adminIp[24], String:adminAuth[64];
  617.     new minutes = StringToInt(time);
  618.     if(!minutes && client && !(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN|ADMFLAG_ROOT)))
  619.     {
  620.         ReplyToCommand(client, "You do not have Perm Ban Permission");
  621.         return Plugin_Handled;
  622.     }
  623.     if(!client)
  624.     {
  625.         // setup dummy adminAuth and adminIp for server
  626.         strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  627.         strcopy(adminIp, sizeof(adminIp), ServerIp);
  628.     } else {
  629.         GetClientIP(client, adminIp, sizeof(adminIp));
  630.         GetClientAuthString(client, adminAuth, sizeof(adminAuth));
  631.     }
  632.    
  633.     // Pack everything into a data pack so we can retain it
  634.     new Handle:dataPack = CreateDataPack();
  635.     WritePackCell(dataPack, client);
  636.     WritePackCell(dataPack, minutes);
  637.     WritePackString(dataPack, arg_string[total_len]);
  638.     WritePackString(dataPack, authid);
  639.     WritePackString(dataPack, adminAuth);
  640.     WritePackString(dataPack, adminIp);
  641.    
  642.     decl String:Query[256];
  643.     FormatEx(Query, sizeof(Query), "SELECT bid FROM %s_bans WHERE type = 0 AND authid = '%s' AND (length = 0 OR ends > UNIX_TIMESTAMP()) AND RemoveType IS NULL",
  644.                                                                     DatabasePrefix, authid);
  645.    
  646.     SQL_TQuery(Database, SelectAddbanCallback, Query, dataPack, DBPrio_High);
  647.     return Plugin_Handled;
  648. }
  649.  
  650. public Action:sm_rehash(args)
  651. {
  652.     if(enableAdmins)
  653.         DumpAdminCache(AdminCache_Groups,true);
  654.     return Plugin_Handled;  
  655. }
  656.  
  657. public OnClientPutInServer(client)
  658. {
  659.     if (enableAdmins)
  660.     {
  661.         DumpAdminCache(AdminCache_Groups,true);
  662.     }
  663. }
  664.  
  665.  
  666. // MENU CODE //
  667.  
  668. public OnAdminMenuReady(Handle:topmenu)
  669. {
  670. #if defined DEBUG
  671.     LogToFile(logFile, "OnAdminMenuReady()");
  672. #endif
  673.  
  674.     /* Block us from being called twice */
  675.     if (topmenu == hTopMenu)
  676.     {
  677.         return;
  678.     }
  679.        
  680.     /* Save the Handle */
  681.     hTopMenu = topmenu;
  682.    
  683.     /* Find the "Player Commands" category */
  684.     new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
  685.  
  686.     if (player_commands != INVALID_TOPMENUOBJECT)
  687.     {
  688. // just to avoid "unused variable 'res'" warning
  689. #if defined DEBUG
  690.         new TopMenuObject:res = AddToTopMenu(hTopMenu,
  691.                             "sm_ban",       // Name
  692.                             TopMenuObject_Item, // We are a submenu
  693.                             AdminMenu_Ban,      // Handler function
  694.                             player_commands,    // We are a submenu of Player Commands
  695.                             "sm_ban",       // The command to be finally called (Override checks)
  696.                             ADMFLAG_BAN);       // What flag do we need to see the menu option
  697.         decl String:temp[125];
  698.         Format(temp, 125, "Result of AddToTopMenu: %d", res);
  699.         LogToFile(logFile, temp);
  700.         LogToFile(logFile, "Added Ban option to admin menu");
  701. #else
  702.         AddToTopMenu(hTopMenu,
  703.                             "sm_ban",       // Name
  704.                             TopMenuObject_Item, // We are a submenu
  705.                             AdminMenu_Ban,      // Handler function
  706.                             player_commands,    // We are a submenu of Player Commands
  707.                             "sm_ban",       // The command to be finally called (Override checks)
  708.                             ADMFLAG_BAN);       // What flag do we need to see the menu option
  709. #endif
  710.     }
  711. }
  712.  
  713. public AdminMenu_Ban(Handle:topmenu,
  714.                     TopMenuAction:action,   // Action being performed
  715.                     TopMenuObject:object_id,// The object ID (if used)
  716.                     param,          // client idx of admin who chose the option (if used)
  717.                     String:buffer[],    // Output buffer (if used)
  718.                     maxlength)      // Output buffer (if used)
  719. {
  720.     /* Clear the Ownreason bool, so he is able to chat again;) */
  721.     g_ownReasons[param] = false;
  722.    
  723. #if defined DEBUG
  724.     LogToFile(logFile, "AdminMenu_Ban()");
  725. #endif
  726.     if (action == TopMenuAction_DisplayOption)  // We are only being displayed, We only need to show the option name
  727.     {
  728.         Format(buffer, maxlength, "%T", "Ban player", param);
  729.         //Format(buffer, maxlength, "Ban player", param);   // Show the menu option
  730. #if defined DEBUG
  731.     LogToFile(logFile, "AdminMenu_Ban() -> Formatted the Ban option text");
  732. #endif
  733.     }
  734.     else if (action == TopMenuAction_SelectOption)
  735.     {
  736.         DisplayBanTargetMenu(param);    // Someone chose to ban someone, show the list of users menu
  737. #if defined DEBUG
  738.     LogToFile(logFile, "AdminMenu_Ban() -> DisplayBanTargetMenu()");
  739. #endif
  740.     }
  741. }
  742.  
  743. public ReasonSelected(Handle:menu, MenuAction:action, param1, param2)
  744. {
  745.     if (action == MenuAction_Select)
  746.     {
  747.         decl String:info[128];
  748.         decl String:key[128];
  749.         GetMenuItem(menu, param2, key, sizeof(key), _, info, sizeof(info));
  750.         if(g_BanTarget[param1] != -1 && g_BanTime[param1] != -1)
  751.             PrepareBan(param1, g_BanTarget[param1], g_BanTime[param1], info, sizeof(info));
  752.  
  753.     }
  754.     else if (action == MenuAction_Cancel && param2 == MenuCancel_Disconnected)
  755.     {
  756.         if(PlayerDataPack[param1] != INVALID_HANDLE)
  757.         {
  758.             CloseHandle(PlayerDataPack[param1]);
  759.             PlayerDataPack[param1] = INVALID_HANDLE;
  760.         }
  761.  
  762.     }
  763.     else if (action == MenuAction_Cancel)
  764.     {
  765.         DisplayBanTimeMenu(param1);
  766.     }
  767. }
  768.  
  769. public HackingSelected(Handle:menu, MenuAction:action, param1, param2)
  770. {
  771.     if (action == MenuAction_Select)
  772.     {
  773.         decl String:info[128];
  774.         decl String:key[128];
  775.         GetMenuItem(menu, param2, key, sizeof(key), _, info, sizeof(info));
  776.        
  777.         if(g_BanTarget[param1] != -1 && g_BanTime[param1] != -1)
  778.             PrepareBan(param1, g_BanTarget[param1], g_BanTime[param1], info, sizeof(info));
  779.        
  780.     } else if (action == MenuAction_Cancel && param2 == MenuCancel_Disconnected) {
  781.  
  782.         new Handle:Pack = PlayerDataPack[param1];
  783.  
  784.         if(Pack != INVALID_HANDLE)
  785.         {
  786.             SetPackPosition(Pack, 40);
  787.             new Handle:ReasonPack = Handle:ReadPackCell(Pack);
  788.  
  789.             if(ReasonPack != INVALID_HANDLE)
  790.             {
  791.                 CloseHandle(ReasonPack);
  792.             }
  793.  
  794.             CloseHandle(Pack);
  795.             PlayerDataPack[param1] = INVALID_HANDLE;
  796.         }
  797.     }
  798.     else if (action == MenuAction_Cancel)
  799.     {
  800.         DisplayMenu(ReasonMenuHandle, param1, MENU_TIME_FOREVER);
  801.     }
  802. }
  803.  
  804. public MenuHandler_BanPlayerList(Handle:menu, MenuAction:action, param1, param2)
  805. {
  806. #if defined DEBUG
  807.     LogToFile(logFile, "MenuHandler_BanPlayerList()");
  808. #endif
  809.     if (action == MenuAction_End)
  810.     {
  811.         CloseHandle(menu);              // Chose to close the menu
  812.     }
  813.     else if (action == MenuAction_Cancel)
  814.     {
  815.         if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
  816.         {
  817.             DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
  818.         }
  819.     }
  820.     else if (action == MenuAction_Select)           // Chose someone!
  821.     {
  822.         decl String:info[32], String:name[32];
  823.         new userid, target;
  824.        
  825.         GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
  826.         userid = StringToInt(info);
  827.  
  828.         if ((target = GetClientOfUserId(userid)) == 0)
  829.         {
  830.             PrintToChat(param1, "%s%t", Prefix, "Player no longer available");
  831.         }
  832.         else if (!CanUserTarget(param1, target))
  833.         {
  834.             PrintToChat(param1, "%s%t", Prefix, "Unable to target");
  835.         }
  836.         else
  837.         {
  838.             g_BanTarget[param1] = target;
  839.             DisplayBanTimeMenu(param1);
  840.         }
  841.     }
  842. }
  843.  
  844. public MenuHandler_BanTimeList(Handle:menu, MenuAction:action, param1, param2)
  845. {
  846. #if defined DEBUG
  847.     LogToFile(logFile, "MenuHandler_BanTimeList()");
  848. #endif
  849.     if (action == MenuAction_End)
  850.     {
  851.         CloseHandle(menu);
  852.     }
  853.     else if (action == MenuAction_Cancel)
  854.     {
  855.         if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
  856.         {
  857.             DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
  858.         }
  859.     }
  860.     else if (action == MenuAction_Select)
  861.     {
  862.         decl String:info[32];
  863.        
  864.         GetMenuItem(menu, param2, info, sizeof(info));
  865.         g_BanTime[param1] = StringToInt(info);
  866.        
  867.         //DisplayBanReasonMenu(param1);
  868.         DisplayMenu(ReasonMenuHandle, param1, MENU_TIME_FOREVER);
  869.     }
  870. }
  871.  
  872. stock DisplayBanTargetMenu(client)
  873. {
  874. #if defined DEBUG
  875.     LogToFile(logFile, "DisplayBanTargetMenu()");
  876. #endif
  877.     new Handle:menu = CreateMenu(MenuHandler_BanPlayerList);// Create a new menu, pass it the handler.
  878.    
  879.     decl String:title[100];
  880.     Format(title, sizeof(title), "%T:", "Ban player", client);
  881.    
  882.     //Format(title, sizeof(title), "Ban player", client);   // Create the title of the menu
  883.     SetMenuTitle(menu, title);              // Set the title
  884.     SetMenuExitBackButton(menu, true);          // Yes we want back/exit
  885.    
  886.     AddTargetsToMenu(menu,                  // Add clients to our menu
  887.             client,                 // The client that called the display
  888.             false,                  // We want to see people connecting
  889.             false);                 // And dead people
  890.    
  891.     DisplayMenu(menu, client, MENU_TIME_FOREVER);       // Show the menu to the client FOREVER!
  892. }
  893.  
  894. stock DisplayBanTimeMenu(client)
  895. {
  896. #if defined DEBUG
  897.     LogToFile(logFile, "DisplayBanTimeMenu()");
  898. #endif
  899.        
  900.     new Handle:menu = CreateMenu(MenuHandler_BanTimeList);
  901.    
  902.     decl String:title[100];
  903.     Format(title, sizeof(title), "%T:", "Ban player", client);
  904.     //Format(title, sizeof(title), "Ban player", client);
  905.     SetMenuTitle(menu, title);
  906.     SetMenuExitBackButton(menu, true);
  907.    
  908.     if(CheckCommandAccess(client, "sm_unban", ADMFLAG_UNBAN|ADMFLAG_ROOT))
  909.     AddMenuItem(menu, "0", "Навсегда");
  910.     AddMenuItem(menu, "60", "Час");
  911.     AddMenuItem(menu, "720", "6 Часов");
  912.     AddMenuItem(menu, "1440", "Сутки");
  913.     AddMenuItem(menu, "10080", "Неделя");
  914.    
  915.     DisplayMenu(menu, client, MENU_TIME_FOREVER);
  916. }
  917.  
  918. stock ResetMenu()
  919. {
  920.     if(ReasonMenuHandle != INVALID_HANDLE)
  921.     {
  922.         RemoveAllMenuItems(ReasonMenuHandle);
  923.     }
  924. }
  925.  
  926. // QUERY CALL BACKS //
  927.  
  928. public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)
  929. {
  930.     if (hndl == INVALID_HANDLE)
  931.     {
  932.         LogToFile(logFile, "Database failure: %s. See FAQ: http://www.sourcebans.net/node/20", error);
  933.         g_bConnecting = false;
  934.         return;
  935.     }
  936.  
  937.     Database = hndl;
  938.  
  939.     decl String:query[1024];
  940.     FormatEx(query, sizeof(query), "SET NAMES `utf8`");
  941.     SQL_TQuery(Database, ErrorCheckCallback, query);
  942.  
  943.     InsertServerInfo();
  944.  
  945.     //CreateTimer(900.0, PruneBans);
  946.  
  947.     if(loadOverrides)
  948.     {
  949.         loadOverrides = false;
  950.     }
  951.  
  952.     if(loadGroups && enableAdmins)
  953.     {
  954.         FormatEx(query,1024,"SELECT name, flags, immunity, groups_immune   \
  955.                     FROM %s_srvgroups ORDER BY id",DatabasePrefix);
  956.         curLoading++;
  957.         SQL_TQuery(Database,GroupsDone,query);
  958.        
  959. #if defined DEBUG
  960.     LogToFile(logFile, "Fetching Group List");
  961. #endif
  962.         loadGroups = false;
  963.     }
  964.  
  965.     if(loadAdmins && enableAdmins)
  966.     {
  967.         new String:queryLastLogin[50] = "";
  968.  
  969.         if (requireSiteLogin)
  970.             queryLastLogin = "lastvisit IS NOT NULL AND lastvisit != '' AND";
  971.  
  972.         if( serverID == -1 )
  973.         {
  974.             FormatEx(query,1024,"SELECT authid, srv_password, (SELECT name FROM %s_srvgroups WHERE name = srv_group AND flags != '') AS srv_group, srv_flags, user, immunity  \
  975.                         FROM %s_admins_servers_groups AS asg \
  976.                         LEFT JOIN %s_admins AS a ON a.aid = asg.admin_id \
  977.                         WHERE %s (expired > UNIX_TIMESTAMP() OR expired = 0)  AND (server_id = (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1)  \
  978.                         OR srv_group_id = ANY (SELECT group_id FROM %s_servers_groups WHERE server_id = (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1))) \
  979.                         GROUP BY aid, authid, srv_password, srv_group, srv_flags, user",
  980.                     DatabasePrefix, DatabasePrefix,DatabasePrefix, queryLastLogin, DatabasePrefix, ServerIp, ServerPort,DatabasePrefix, DatabasePrefix, ServerIp, ServerPort);
  981.         }else{
  982.             FormatEx(query,1024,"SELECT authid, srv_password, (SELECT name FROM %s_srvgroups WHERE name = srv_group AND flags != '') AS srv_group, srv_flags, user, immunity  \
  983.                         FROM %s_admins_servers_groups AS asg \
  984.                         LEFT JOIN %s_admins AS a ON a.aid = asg.admin_id \
  985.                         WHERE %s (expired > UNIX_TIMESTAMP() OR expired = 0) AND server_id = %d  \
  986.                         OR srv_group_id = ANY (SELECT group_id FROM %s_servers_groups WHERE server_id = %d) \
  987.                         GROUP BY aid, authid, srv_password, srv_group, srv_flags, user",
  988.                     DatabasePrefix, DatabasePrefix,DatabasePrefix, queryLastLogin, serverID, DatabasePrefix, serverID);
  989.         }
  990.         curLoading++;
  991.         SQL_TQuery(Database,AdminsDone,query);
  992.  
  993. #if defined DEBUG
  994.         LogToFile(logFile, "Fetching Admin List");
  995.         LogToFile(logFile, query);
  996. #endif
  997.         loadAdmins = false;
  998.     }
  999.     g_bConnecting = false;
  1000. }
  1001.  
  1002. public VerifyInsert(Handle:owner, Handle:hndl, const String:error[], any:dataPack)
  1003. {
  1004.     if(dataPack == INVALID_HANDLE)
  1005.     {
  1006.         LogToFile(logFile, "Ban Failed: %s", error);
  1007.         return;
  1008.     }
  1009.    
  1010.     if(hndl == INVALID_HANDLE || error[0])
  1011.     {
  1012.         LogToFile(logFile, "Verify Insert Query Failed: %s", error);
  1013.         new admin = ReadPackCell(dataPack);
  1014.         SetPackPosition(dataPack, 32);
  1015.         new time = ReadPackCell(dataPack);
  1016.         new Handle:reasonPack = Handle:ReadPackCell(dataPack);
  1017.         decl String:reason[128];
  1018.         ReadPackString(reasonPack, reason, sizeof(reason));
  1019.         decl String:name[50];
  1020.         ReadPackString(dataPack, name, sizeof(name));
  1021.         decl String:auth[30];
  1022.         ReadPackString(dataPack, auth, sizeof(auth));
  1023.         decl String:ip[20];
  1024.         ReadPackString(dataPack, ip, sizeof(ip));
  1025.         decl String:adminAuth[30];
  1026.         ReadPackString(dataPack, adminAuth, sizeof(adminAuth));
  1027.         decl String:adminIp[20];
  1028.         ReadPackString(dataPack, adminIp, sizeof(adminIp));
  1029.         ResetPack(dataPack);
  1030.         ResetPack(reasonPack);
  1031.  
  1032.         PlayerDataPack[admin] = INVALID_HANDLE;
  1033.         UTIL_InsertTempBan(time, name, auth, ip, reason, adminAuth, adminIp, Handle:dataPack);
  1034.         return;
  1035.     }
  1036.  
  1037.     new admin = ReadPackCell(dataPack);
  1038.     new client = ReadPackCell(dataPack);
  1039.    
  1040.     if( !IsClientConnected(client) || IsFakeClient(client) )
  1041.         return;
  1042.    
  1043.     SetPackPosition(dataPack, 24);
  1044.     new UserId = ReadPackCell(dataPack);
  1045.     new time = ReadPackCell(dataPack);
  1046.     new Handle:ReasonPack = Handle:ReadPackCell(dataPack);
  1047.  
  1048.     decl String:Name[64], String:Reason[128];
  1049.  
  1050.     ReadPackString(dataPack, Name, sizeof(Name));
  1051.     ReadPackString(ReasonPack, Reason, sizeof(Reason));
  1052.  
  1053.     if (!time)
  1054.     {
  1055.         if (Reason[0] == '\0')
  1056.         {
  1057.             ShowActivityEx(admin, Prefix, "%t", "Permabanned player", Name);
  1058.         } else {
  1059.             ShowActivityEx(admin, Prefix, "%t","Permabanned player reason", Name, Reason);
  1060.         }
  1061.     } else {
  1062.         if (Reason[0] == '\0')
  1063.         {
  1064.             ShowActivityEx(admin, Prefix, "%t", "Banned player", Name, time);
  1065.         } else {
  1066.             ShowActivityEx(admin, Prefix, "%t", "Banned player reason", Name, time, Reason);
  1067.         }
  1068.     }
  1069.  
  1070.     LogAction(admin, client, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", admin, client, time, Reason);
  1071.  
  1072.     if(PlayerDataPack[admin] != INVALID_HANDLE)
  1073.     {
  1074.         CloseHandle(PlayerDataPack[admin]);
  1075.         CloseHandle(ReasonPack);
  1076.         PlayerDataPack[admin] = INVALID_HANDLE;
  1077.     }
  1078.  
  1079.     // Kick player
  1080.     if(GetClientUserId(client) == UserId)
  1081.         KickClient(client, "%t", "Banned Check Site", WebsiteAddress);
  1082. }
  1083.  
  1084. public SelectBanIpCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1085. {
  1086.     decl admin, minutes, String:adminAuth[30], String:adminIp[30], String:banReason[256], String:ip[16], String:Query[512], String:reason[128];
  1087.     ResetPack(data);
  1088.     admin = ReadPackCell(data);
  1089.     minutes = ReadPackCell(data);
  1090.     ReadPackString(data, reason,    sizeof(reason));
  1091.     ReadPackString(data, ip,        sizeof(ip));
  1092.     ReadPackString(data, adminAuth, sizeof(adminAuth));
  1093.     ReadPackString(data, adminIp,   sizeof(adminIp));
  1094.     SQL_EscapeString(Database, reason, banReason, sizeof(banReason));
  1095.    
  1096.     if(error[0])
  1097.     {
  1098.         LogToFile(logFile, "Ban IP Select Query Failed: %s", error);
  1099.         if(admin    && IsClientInGame(admin))
  1100.             PrintToChat(admin,   "%sFailed to ban %s.",   Prefix, ip);
  1101.         else
  1102.             PrintToServer("%sFailed to ban %s.",          Prefix, ip);
  1103.         return;
  1104.     }
  1105.     if(SQL_GetRowCount(hndl))
  1106.     {
  1107.         if(admin    && IsClientInGame(admin))
  1108.             PrintToChat(admin, "%s%s is already banned.", Prefix, ip);
  1109.         else
  1110.             PrintToServer("%s%s is already banned.",      Prefix, ip);
  1111.         return;
  1112.     }
  1113.     if( serverID == -1 )
  1114.     {
  1115.         FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (type, ip, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
  1116.                         (1, '%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
  1117.                         (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), ' ')",
  1118.                         DatabasePrefix, ip, (minutes*60), (minutes*60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, DatabasePrefix, ServerIp, ServerPort);
  1119.     } else {
  1120.         FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (type, ip, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
  1121.                         (1, '%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
  1122.                         %d, ' ')",
  1123.                         DatabasePrefix, ip, (minutes*60), (minutes*60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, serverID);
  1124.     }
  1125.    
  1126.     SQL_TQuery(Database, InsertBanIpCallback, Query, data, DBPrio_High);
  1127. }
  1128.  
  1129. public InsertBanIpCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1130. {
  1131.     // if the pack is good unpack it and close the handle
  1132.     new admin, minutes;
  1133.     decl String:reason[128], String:arg[30];
  1134.     if(data != INVALID_HANDLE)
  1135.     {
  1136.         ResetPack(data);
  1137.         admin = ReadPackCell(data);
  1138.         minutes = ReadPackCell(data);
  1139.         ReadPackString(data, reason, sizeof(reason));
  1140.         ReadPackString(data, arg, sizeof(arg));
  1141.         CloseHandle(data);
  1142.     } else {
  1143.         // Technically this should not be possible
  1144.         ThrowError("Invalid Handle in InsertBanIpCallback");
  1145.     }
  1146.    
  1147.     // If error is not an empty string the query failed
  1148.     if(error[0] != '\0')
  1149.     {
  1150.         LogToFile(logFile, "Ban IP Insert Query Failed: %s", error);
  1151.         if(admin && IsClientInGame(admin))
  1152.             PrintToChat(admin, "%ssm_banip failed", Prefix);
  1153.         return;
  1154.     }
  1155.    
  1156.     LogAction(admin,
  1157.               -1,
  1158.               "\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")",
  1159.               admin,
  1160.               minutes,
  1161.               arg,
  1162.               reason);
  1163.     if(admin && IsClientInGame(admin))
  1164.         PrintToChat(admin, "%s%s successfully banned", Prefix, arg);
  1165.     else
  1166.         PrintToServer("%s%s successfully banned",      Prefix, arg);
  1167. }
  1168.  
  1169. public SelectUnbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1170. {
  1171.     decl admin, String:arg[30], String:adminAuth[30], String:unbanReason[256], String:reason[128];
  1172.     ResetPack(data);
  1173.     admin = ReadPackCell(data);
  1174.     ReadPackString(data, reason, sizeof(reason));
  1175.     ReadPackString(data, arg, sizeof(arg));
  1176.     ReadPackString(data, adminAuth, sizeof(adminAuth));
  1177.     SQL_EscapeString(Database, reason, unbanReason, sizeof(unbanReason));
  1178.    
  1179.     // If error is not an empty string the query failed
  1180.     if(error[0] != '\0')
  1181.     {
  1182.         LogToFile(logFile, "Unban Select Query Failed: %s", error);
  1183.         if(admin && IsClientInGame(admin))
  1184.         {
  1185.             PrintToChat(admin, "%ssm_unban failed", Prefix);
  1186.         }
  1187.         return;
  1188.     }
  1189.    
  1190.     // If there was no results then a ban does not exist for that id
  1191.     if(hndl == INVALID_HANDLE || !SQL_GetRowCount(hndl))
  1192.     {
  1193.         if(admin && IsClientInGame(admin))
  1194.         {
  1195.             PrintToChat(admin, "%sNo active bans found for that filter", Prefix);
  1196.         } else {
  1197.             PrintToServer("%sNo active bans found for that filter",      Prefix);
  1198.         }
  1199.         return;
  1200.     }
  1201.    
  1202.     // There is ban
  1203.     if(hndl != INVALID_HANDLE && SQL_FetchRow(hndl))
  1204.     {
  1205.         // Get the values from the existing ban record
  1206.         new bid = SQL_FetchInt(hndl, 0);
  1207.        
  1208.         decl String:query[1000];
  1209.         Format(query, sizeof(query), "UPDATE %s_bans SET RemovedBy = (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), RemoveType = 'U', RemovedOn = UNIX_TIMESTAMP(), ureason = '%s' WHERE bid = %d",
  1210.                                                                     DatabasePrefix, DatabasePrefix, adminAuth, adminAuth[8], unbanReason, bid);
  1211.        
  1212.         SQL_TQuery(Database, InsertUnbanCallback, query, data);
  1213.     }
  1214.     return;
  1215. }
  1216.  
  1217. public InsertUnbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1218. {
  1219.     // if the pack is good unpack it and close the handle
  1220.     decl admin, String:reason[128], String:arg[30];
  1221.     if(data != INVALID_HANDLE)
  1222.     {
  1223.         ResetPack(data);
  1224.         admin = ReadPackCell(data);
  1225.         ReadPackString(data, reason, sizeof(reason));
  1226.         ReadPackString(data, arg, sizeof(arg));
  1227.         CloseHandle(data);
  1228.     } else {
  1229.         // Technically this should not be possible
  1230.         ThrowError("Invalid Handle in InsertUnbanCallback");
  1231.     }
  1232.    
  1233.     // If error is not an empty string the query failed
  1234.     if(error[0] != '\0')
  1235.     {
  1236.         LogToFile(logFile, "Unban Insert Query Failed: %s", error);
  1237.         if(admin && IsClientInGame(admin))
  1238.         {
  1239.             PrintToChat(admin, "%ssm_unban failed", Prefix);
  1240.         }
  1241.         return;
  1242.     }
  1243.    
  1244.     LogAction(admin, -1, "\"%L\" removed ban (filter \"%s\") (reason \"%s\")", admin, arg, reason);
  1245.     if(admin && IsClientInGame(admin))
  1246.     {
  1247.         PrintToChat(admin, "%s%s successfully unbanned", Prefix, arg);
  1248.     } else {
  1249.         PrintToServer("%s%s successfully unbanned",      Prefix, arg);
  1250.     }
  1251. }
  1252.  
  1253. public SelectAddbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1254. {
  1255.     decl admin, minutes, String:adminAuth[30], String:adminIp[30], String:authid[20], String:banReason[256], String:Query[512], String:reason[128];
  1256.     ResetPack(data);
  1257.     admin = ReadPackCell(data);
  1258.     minutes = ReadPackCell(data);
  1259.     ReadPackString(data, reason,    sizeof(reason));
  1260.     ReadPackString(data, authid,    sizeof(authid));
  1261.     ReadPackString(data, adminAuth, sizeof(adminAuth));
  1262.     ReadPackString(data, adminIp,   sizeof(adminIp));
  1263.     SQL_EscapeString(Database, reason, banReason, sizeof(banReason));
  1264.    
  1265.     if(error[0])
  1266.     {
  1267.         LogToFile(logFile, "Add Ban Select Query Failed: %s", error);
  1268.         if(admin    && IsClientInGame(admin))
  1269.             PrintToChat(admin, "%sFailed to ban %s.",     Prefix, authid);
  1270.         else
  1271.             PrintToServer("%sFailed to ban %s.",          Prefix, authid);
  1272.         return;
  1273.     }
  1274.     if(SQL_GetRowCount(hndl))
  1275.     {
  1276.         if(admin    && IsClientInGame(admin))
  1277.             PrintToChat(admin, "%s%s is already banned.", Prefix, authid);
  1278.         else
  1279.             PrintToServer("%s%s is already banned.",      Prefix, authid);
  1280.         return;
  1281.     }
  1282.     if( serverID == -1 )
  1283.     {
  1284.         FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
  1285.                         ('%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
  1286.                         (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), ' ')",
  1287.                         DatabasePrefix, authid, (minutes*60), (minutes*60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, DatabasePrefix, ServerIp, ServerPort);
  1288.     } else {
  1289.         FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
  1290.                         ('%s', '', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
  1291.                         %d, ' ')",
  1292.                         DatabasePrefix, authid, (minutes*60), (minutes*60), banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, serverID);
  1293.     }
  1294.    
  1295.     SQL_TQuery(Database, InsertAddbanCallback, Query, data, DBPrio_High);
  1296. }
  1297.  
  1298. public InsertAddbanCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1299. {
  1300.     decl admin, minutes, String:authid[20], String:reason[128];
  1301.     ResetPack(data);
  1302.     admin = ReadPackCell(data);
  1303.     minutes = ReadPackCell(data);
  1304.     ReadPackString(data, reason,    sizeof(reason));
  1305.     ReadPackString(data, authid,    sizeof(authid));
  1306.    
  1307.     // If error is not an empty string the query failed
  1308.     if(error[0] != '\0')
  1309.     {
  1310.         LogToFile(logFile, "Add Ban Insert Query Failed: %s", error);
  1311.         if(admin && IsClientInGame(admin))
  1312.         {
  1313.             PrintToChat(admin, "%ssm_addban failed", Prefix);
  1314.         }
  1315.         return;
  1316.     }
  1317.    
  1318.     LogAction(admin,
  1319.                 -1,
  1320.                 "\"%L\" added ban (minutes \"%i\") (id \"%s\") (reason \"%s\")",
  1321.                 admin,
  1322.                 minutes,
  1323.                 authid,
  1324.                 reason);
  1325.     if(admin && IsClientInGame(admin))
  1326.     {
  1327.         PrintToChat(admin, "%s%s successfully banned", Prefix, authid);
  1328.     } else {
  1329.         PrintToServer("%s%s successfully banned", Prefix, authid);
  1330.     }
  1331. }
  1332.  
  1333. // ProcessQueueCallback is called as the result of selecting all the rows from the queue table
  1334. public ProcessQueueCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1335. {
  1336.     if (hndl == INVALID_HANDLE || strlen(error) > 0)
  1337.     {
  1338.         LogToFile(logFile, "Failed to retrieve queued bans from sqlite database, %s", error);
  1339.         return;
  1340.     }
  1341.  
  1342.     decl String:auth[30];
  1343.     decl time;
  1344.     decl startTime;
  1345.     decl String:reason[128];
  1346.     decl String:name[64];
  1347.     decl String:ip[20];
  1348.     decl String:adminAuth[30];
  1349.     decl String:adminIp[20];
  1350.     decl String:query[1024];
  1351.     decl String:banName[128];
  1352.     decl String:banReason[256];
  1353.     while(SQL_MoreRows(hndl))
  1354.     {
  1355.         // Oh noes! What happened?!
  1356.         if(!SQL_FetchRow(hndl))
  1357.             continue;
  1358.        
  1359.         // if we get to here then there are rows in the queue pending processing
  1360.         SQL_FetchString(hndl, 0, auth, sizeof(auth));
  1361.         time = SQL_FetchInt(hndl, 1);
  1362.         startTime = SQL_FetchInt(hndl, 2);
  1363.         SQL_FetchString(hndl, 3, reason, sizeof(reason));
  1364.         SQL_FetchString(hndl, 4, name, sizeof(name));
  1365.         SQL_FetchString(hndl, 5, ip, sizeof(ip));
  1366.         SQL_FetchString(hndl, 6, adminAuth, sizeof(adminAuth));
  1367.         SQL_FetchString(hndl, 7, adminIp, sizeof(adminIp));
  1368.         SQL_EscapeString(SQLiteDB, name, banName, sizeof(banName));
  1369.         SQL_EscapeString(SQLiteDB, reason, banReason, sizeof(banReason));
  1370.         if(startTime + time * 60 > GetTime() || time == 0)
  1371.         {
  1372.             // This ban is still valid and should be entered into the db
  1373.             if( serverID == -1 )
  1374.             {
  1375.                 FormatEx(query, sizeof(query),
  1376.                         "INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid) VALUES  \
  1377.                         ('%s', '%s', '%s', %d, %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
  1378.                         (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1))",
  1379.                         DatabasePrefix, ip, auth, banName, startTime, startTime + time * 60, time * 60, banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, DatabasePrefix, ServerIp, ServerPort);
  1380.             }
  1381.             else
  1382.             {
  1383.                 FormatEx(query, sizeof(query),
  1384.                         "INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid) VALUES  \
  1385.                         ('%s', '%s', '%s', %d, %d, %d, '%s', (SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'), '%s', \
  1386.                         %d)",
  1387.                         DatabasePrefix, ip, auth, banName, startTime, startTime + time * 60, time * 60, banReason, DatabasePrefix, adminAuth, adminAuth[8], adminIp, serverID);
  1388.             }
  1389.             new Handle:authPack = CreateDataPack();
  1390.             WritePackString(authPack, auth);
  1391.             ResetPack(authPack);
  1392.             SQL_TQuery(Database, AddedFromSQLiteCallback, query, authPack);
  1393.         } else {
  1394.             // The ban is no longer valid and should be deleted from the queue
  1395.             FormatEx(query, sizeof(query), "DELETE FROM queue WHERE steam_id = '%s'", auth);
  1396.             SQL_TQuery(SQLiteDB, ErrorCheckCallback, query);
  1397.         }
  1398.     }
  1399.     // We have finished processing the queue but should process again in ProcessQueueTime minutes
  1400.     CreateTimer(float(ProcessQueueTime * 60), ProcessQueue);
  1401. }
  1402.  
  1403. public AddedFromSQLiteCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1404. {
  1405.     decl String:buffer[512];
  1406.     decl String:auth[40];
  1407.     ReadPackString(data, auth, sizeof(auth));
  1408.     if(error[0] == '\0')
  1409.     {
  1410.         // The insert was successful so delete the record from the queue
  1411.         FormatEx(buffer, sizeof(buffer), "DELETE FROM queue WHERE steam_id = '%s'", auth);
  1412.         SQL_TQuery(SQLiteDB, ErrorCheckCallback, buffer);
  1413.        
  1414.         // They are added to main banlist, so remove the temp ban
  1415.         RemoveBan(auth, BANFLAG_AUTHID);
  1416.        
  1417.     } else {
  1418.         // the insert failed so we leave the record in the queue and increase our temporary ban
  1419.         FormatEx(buffer, sizeof(buffer), "banid %d %s", ProcessQueueTime, auth);
  1420.         ServerCommand(buffer);
  1421.     }
  1422.     CloseHandle(data);
  1423. }
  1424.  
  1425. public ServerInfoCallback(Handle:owner, Handle:hndl, const String:error[], any:data)
  1426. {
  1427.     if(error[0])
  1428.     {
  1429.         LogToFile(logFile, "Server Select Query Failed: %s", error);
  1430.         return;
  1431.     }
  1432.  
  1433.     if(hndl == INVALID_HANDLE || SQL_GetRowCount(hndl)==0)
  1434.     {  
  1435.         // get the game folder name used to determine the mod
  1436.         decl String:desc[64], String:query[200];
  1437.         GetGameFolderName(desc, sizeof(desc));
  1438.         FormatEx(query, sizeof(query), "INSERT INTO %s_servers (ip, port, rcon, modid) VALUES ('%s', '%s', '', (SELECT mid FROM %s_mods WHERE modfolder = '%s'))", DatabasePrefix, ServerIp, ServerPort, DatabasePrefix, desc);
  1439.         SQL_TQuery(Database, ErrorCheckCallback, query);
  1440.     }
  1441. }
  1442.  
  1443. public ErrorCheckCallback(Handle:owner, Handle:hndle, const String:error[], any:data)
  1444. {
  1445.     if(error[0])
  1446.     {
  1447.         LogToFile(logFile, "Query Failed: %s", error);
  1448.     }
  1449. }
  1450.  
  1451. public VerifyBan(Handle:owner, Handle:hndl, const String:error[], any:userid)
  1452. {
  1453.     decl String:clientName[64];
  1454.     decl String:clientAuth[64];
  1455.     decl String:clientIp[64];
  1456.     new client = GetClientOfUserId(userid);
  1457.    
  1458.     if(!client)
  1459.         return;
  1460.    
  1461.     /* Failure happen. Do retry with delay */
  1462.     if(hndl == INVALID_HANDLE)
  1463.     {
  1464.         LogToFile(logFile, "Verify Ban Query Failed: %s", error);
  1465.         PlayerRecheck[client] = CreateTimer(RetryTime, ClientRecheck, client);
  1466.         return;
  1467.     }
  1468.     GetClientIP(client, clientIp, sizeof(clientIp));
  1469.     GetClientAuthString(client, clientAuth, sizeof(clientAuth));
  1470.     GetClientName(client, clientName, sizeof(clientName));
  1471.     if(SQL_GetRowCount(hndl) > 0)
  1472.     {
  1473.         decl String:buffer[40];
  1474.         decl String:Name[128];
  1475.         decl String:Query[512];
  1476.        
  1477.         SQL_EscapeString(Database, clientName, Name, sizeof(Name));
  1478.         if( serverID == -1 )
  1479.         {
  1480.             FormatEx(Query, sizeof(Query), "INSERT INTO %s_banlog (sid ,time ,name ,bid) VALUES  \
  1481.                 ((SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), UNIX_TIMESTAMP(), '%s', \
  1482.                 (SELECT bid FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND RemoveType IS NULL LIMIT 0,1))",
  1483.                 DatabasePrefix, DatabasePrefix, ServerIp, ServerPort, Name, DatabasePrefix, clientAuth[8], clientIp);
  1484.         }
  1485.         else
  1486.         {
  1487.             FormatEx(Query, sizeof(Query), "INSERT INTO %s_banlog (sid ,time ,name ,bid) VALUES  \
  1488.                 (%d, UNIX_TIMESTAMP(), '%s', \
  1489.                 (SELECT bid FROM %s_bans WHERE ((type = 0 AND authid REGEXP '^STEAM_[0-9]:%s$') OR (type = 1 AND ip = '%s')) AND RemoveType IS NULL LIMIT 0,1))",
  1490.                 DatabasePrefix, serverID, Name, DatabasePrefix, clientAuth[8], clientIp);
  1491.         }
  1492.        
  1493.         SQL_TQuery(Database, ErrorCheckCallback, Query, client, DBPrio_High);
  1494.         FormatEx(buffer, sizeof(buffer), "banid 5 %s", clientAuth);
  1495.         ServerCommand(buffer);
  1496.         KickClient(client, "%t", "Banned Check Site", WebsiteAddress);
  1497.         return;
  1498.     }
  1499. #if defined DEBUG
  1500.     LogToFile(logFile, "%s is NOT banned.", clientAuth);
  1501. #endif
  1502.        
  1503.     PlayerStatus[client] = true;
  1504. }
  1505.  
  1506. public AdminsDone(Handle:owner, Handle:hndl, const String:error[], any:data)
  1507. {
  1508.     //SELECT authid, srv_password , srv_group, srv_flags, user
  1509.     if (hndl == INVALID_HANDLE || strlen(error) > 0)
  1510.     {
  1511.         --curLoading;
  1512.         CheckLoadAdmins();
  1513.         LogToFile(logFile, "Failed to retrieve admins from the database, %s", error);
  1514.         return;
  1515.     }
  1516.     decl String:authType[] = "steam";
  1517.     decl String:identity[66];
  1518.     decl String:password[66];
  1519.     decl String:groups[256];
  1520.     decl String:flags[32];
  1521.     decl String:name[66];
  1522.     new admCount=0;
  1523.     new Immunity=0;
  1524.     new AdminId:curAdm = INVALID_ADMIN_ID;
  1525.     new Handle:adminsKV = CreateKeyValues("Admins");
  1526.    
  1527.     while (SQL_MoreRows(hndl))
  1528.     {
  1529.         SQL_FetchRow(hndl);
  1530.         if(SQL_IsFieldNull(hndl, 0))
  1531.             continue;  // Sometimes some rows return NULL due to some setups
  1532.            
  1533.         SQL_FetchString(hndl,0,identity,66);
  1534.         SQL_FetchString(hndl,1,password,66);
  1535.         SQL_FetchString(hndl,2,groups,256);
  1536.         SQL_FetchString(hndl,3,flags,32);
  1537.         SQL_FetchString(hndl,4,name,66);
  1538.  
  1539.         Immunity = SQL_FetchInt(hndl,5);
  1540.        
  1541.         TrimString(name);
  1542.         TrimString(identity);
  1543.         TrimString(groups);
  1544.         TrimString(flags);
  1545.  
  1546.         // Disable writing to file if they chose to
  1547.         if(backupConfig)
  1548.         {
  1549.             KvJumpToKey(adminsKV, name, true);
  1550.            
  1551.             KvSetString(adminsKV, "auth", "steam");
  1552.             KvSetString(adminsKV, "identity", identity);
  1553.            
  1554.             if(strlen(flags) > 0)
  1555.                 KvSetString(adminsKV, "flags", flags);
  1556.            
  1557.             if(strlen(groups) > 0)
  1558.                 KvSetString(adminsKV, "group", groups);
  1559.        
  1560.             if(strlen(password) > 0)
  1561.                 KvSetString(adminsKV, "password", password);
  1562.            
  1563.             if(Immunity > 0)
  1564.                 KvSetNum(adminsKV, "immunity", Immunity);
  1565.            
  1566.             KvRewind(adminsKV);
  1567.         }
  1568.        
  1569.         curAdm = CreateAdmin(name);      
  1570.         BindAdminIdentity(curAdm,authType,identity);
  1571.        
  1572. #if defined DEBUG
  1573.         LogToFile(logFile, "Given %s (%s) admin", name, identity);
  1574. #endif
  1575.        
  1576.         decl String:grp[64];
  1577.         new curPos = 0;
  1578.         new nextPos = 0;
  1579.         new GroupId:curGrp = INVALID_GROUP_ID;
  1580.         while ((nextPos = SplitString(groups[curPos],",",grp,64)) != -1)
  1581.         {
  1582.             curPos += nextPos;
  1583.             curGrp = FindAdmGroup(grp);
  1584.             if (curGrp == INVALID_GROUP_ID)
  1585.             {
  1586.                 LogToFile(logFile, "Unknown group \"%s\"",grp);
  1587.             }
  1588.             else
  1589.             {
  1590.                 if (!AdminInheritGroup(curAdm,curGrp))
  1591.                 {
  1592.                     LogToFile(logFile, "Unable to inherit group \"%s\"",grp);
  1593.                 }
  1594.             }
  1595.         }
  1596.        
  1597.         if (strcmp(groups[curPos], "") != 0)
  1598.         {
  1599.             curGrp = FindAdmGroup(groups[curPos]);
  1600.             if (curGrp == INVALID_GROUP_ID)
  1601.             {
  1602.                 LogToFile(logFile, "Unknown group \"%s\"",groups[curPos]);
  1603.             }
  1604.             else
  1605.             {
  1606.                 if (!AdminInheritGroup(curAdm,curGrp))
  1607.                 {
  1608.                     LogToFile(logFile, "Unable to inherit group \"%s\"",groups[curPos]);
  1609.                 }
  1610.                
  1611.                 if( Immunity > GetAdmGroupImmunityLevel(curGrp) )
  1612.                 {
  1613.                     SetAdminImmunityLevel(curAdm, Immunity);
  1614.                 }
  1615.                 else
  1616.                 {
  1617.                     SetAdminImmunityLevel(curAdm, GetAdmGroupImmunityLevel(curGrp));
  1618.                 }
  1619. #if defined DEBUG
  1620.                 LogToFile(logFile, "Admin %s (%s) has %d immunity", name, identity, Immunity);
  1621. #endif
  1622.             }
  1623.         }
  1624.        
  1625.         if (strlen(password) > 0)
  1626.             SetAdminPassword(curAdm, password);
  1627.        
  1628.         for (new i=0;i<strlen(flags);++i)
  1629.         {
  1630.             if (flags[i] < 'a' || flags[i] > 'z')
  1631.                 continue;
  1632.                
  1633.             if (g_FlagLetters[flags[i] - 'a'] < Admin_Reservation)
  1634.                 continue;
  1635.                
  1636.             SetAdminFlag(curAdm, g_FlagLetters[flags[i] - 'a'],true);
  1637.         }
  1638.         ++admCount;
  1639.     }
  1640.    
  1641.     if(backupConfig)
  1642.         KeyValuesToFile(adminsKV, adminsLoc);
  1643.     CloseHandle(adminsKV);
  1644.    
  1645. #if defined DEBUG
  1646.         LogToFile(logFile, "Finished loading %i admins.",admCount);
  1647. #endif
  1648.    
  1649.     --curLoading;
  1650.     CheckLoadAdmins();
  1651. }
  1652.  
  1653. public GroupsDone(Handle:owner, Handle:hndl, const String:error[], any:data)
  1654. {
  1655.     if (hndl == INVALID_HANDLE)
  1656.     {
  1657.         curLoading--;
  1658.         CheckLoadAdmins();
  1659.         LogToFile(logFile, "Failed to retrieve groups from the database, %s",error);
  1660.         return;
  1661.     }
  1662.     decl String:grpName[128];
  1663.     decl String:grpFlags[32];
  1664.     new Immunity;
  1665.     new bool:reparse = false;
  1666.     new grpCount = 0;
  1667.     new Handle:groupsKV = CreateKeyValues("Groups");
  1668.    
  1669.     new GroupId:curGrp = INVALID_GROUP_ID;
  1670.     while (SQL_MoreRows(hndl))
  1671.     {
  1672.         SQL_FetchRow(hndl);
  1673.         if(SQL_IsFieldNull(hndl, 0))
  1674.             continue;  // Sometimes some rows return NULL due to some setups
  1675.         SQL_FetchString(hndl,0,grpName,128);
  1676.         SQL_FetchString(hndl,1,grpFlags,32);
  1677.         Immunity = SQL_FetchInt(hndl,2);
  1678.  
  1679.         TrimString(grpName);
  1680.         TrimString(grpFlags);  
  1681.        
  1682.         if(!strcmp(grpName, " "))
  1683.             continue;
  1684.        
  1685.         curGrp = CreateAdmGroup(grpName);
  1686.        
  1687.         if(backupConfig)
  1688.         {
  1689.             KvJumpToKey(groupsKV, grpName, true);
  1690.             if(strlen(grpFlags) > 0)
  1691.                 KvSetString(groupsKV, "flags", grpFlags);
  1692.             if(Immunity > 0)
  1693.                 KvSetNum(groupsKV, "immunity", Immunity);
  1694.            
  1695.             KvRewind(groupsKV);
  1696.         }
  1697.        
  1698.         if (curGrp == INVALID_GROUP_ID)
  1699.         {   //This occurs when the group already exists
  1700.             curGrp = FindAdmGroup(grpName);  
  1701.         }
  1702.        
  1703.         for (new i=0;i<strlen(grpFlags);++i)
  1704.         {
  1705.             if (grpFlags[i] < 'a' || grpFlags[i] > 'z')
  1706.                 continue;
  1707.                
  1708.             if (g_FlagLetters[grpFlags[i] - 'a'] < Admin_Reservation)
  1709.                 continue;
  1710.                
  1711.             SetAdmGroupAddFlag(curGrp, g_FlagLetters[grpFlags[i] - 'a'], true);
  1712.         }
  1713.            
  1714.         SetAdmGroupImmunityLevel(curGrp, Immunity);
  1715.        
  1716. #if defined DEBUG
  1717.             LogToFile(logFile, "Group %s has %d immunity", grpName, Immunity);
  1718. #endif
  1719.        
  1720.         grpCount++;
  1721.     }
  1722.    
  1723.     if(backupConfig)
  1724.         KeyValuesToFile(groupsKV, groupsLoc);
  1725.     CloseHandle(groupsKV);
  1726.    
  1727. #if defined DEBUG
  1728.         LogToFile(logFile, "Finished loading %i groups.",grpCount);
  1729. #endif
  1730.    
  1731.     if (reparse)
  1732.     {
  1733.         decl String:query[512];
  1734.         FormatEx(query,512,"SELECT name, immunity, groups_immune FROM %s_srvgroups ORDER BY id",DatabasePrefix);
  1735.         SQL_TQuery(Database,GroupsSecondPass,query);
  1736.     }
  1737.     else
  1738.     {
  1739.         curLoading--;
  1740.         CheckLoadAdmins();
  1741.     }
  1742. }
  1743.  
  1744. public GroupsSecondPass(Handle:owner, Handle:hndl, const String:error[], any:data)
  1745. {
  1746.     if (hndl == INVALID_HANDLE)
  1747.     {
  1748.         curLoading--;
  1749.         CheckLoadAdmins();
  1750.         LogToFile(logFile, "Failed to retrieve groups from the database, %s",error);
  1751.         return;
  1752.     }
  1753.     decl String:grpName[128];
  1754.     new Immunity;
  1755.    
  1756.     new GroupId:curGrp = INVALID_GROUP_ID;
  1757.     while (SQL_MoreRows(hndl))
  1758.     {
  1759.         SQL_FetchRow(hndl);
  1760.         if(SQL_IsFieldNull(hndl, 0))
  1761.             continue;  // Sometimes some rows return NULL due to some setups
  1762.         SQL_FetchString(hndl,0,grpName,128);
  1763.         TrimString(grpName);
  1764.         if(!strcmp(grpName, " "))
  1765.             continue;
  1766.         Immunity = SQL_FetchInt(hndl,1);
  1767.        
  1768.         curGrp = FindAdmGroup(grpName);
  1769.         if (curGrp == INVALID_GROUP_ID)
  1770.             curGrp = CreateAdmGroup(grpName);
  1771.        
  1772.         SetAdmGroupImmunityLevel(curGrp, Immunity);
  1773.        
  1774. #if defined DEBUG
  1775.             LogToFile(logFile, "Group %s has %d immunity", grpName, Immunity);
  1776. #endif
  1777.        
  1778.     }
  1779.     --curLoading;
  1780.     CheckLoadAdmins();
  1781. }
  1782.  
  1783.  
  1784. // TIMER CALL BACKS //
  1785.  
  1786. public Action:ClientRecheck(Handle:timer, any:client)
  1787. {
  1788.     if(!PlayerStatus[client] && IsClientConnected(client))
  1789.     {
  1790.         decl String:Authid[64];
  1791.         GetClientAuthString(client, Authid, sizeof(Authid));
  1792.         OnClientAuthorized(client, Authid);
  1793.     }
  1794.  
  1795.     PlayerRecheck[client] =  INVALID_HANDLE;
  1796.     return Plugin_Stop;
  1797. }
  1798.  
  1799. /*
  1800. public Action:PruneBans(Handle:timer)
  1801. {
  1802.     decl String:Query[512];
  1803.     FormatEx(Query, sizeof(Query),
  1804.             "UPDATE %s_bans SET RemovedBy = 0, RemoveType = 'E', RemovedOn = UNIX_TIMESTAMP() WHERE length != '0' AND ends < UNIX_TIMESTAMP()",
  1805.             DatabasePrefix);
  1806.            
  1807.     SQL_TQuery(Database, ErrorCheckCallback, Query);
  1808.     return Plugin_Continue;
  1809. }
  1810. */
  1811.  
  1812. public Action:ProcessQueue(Handle:timer, any:data)
  1813. {
  1814.     decl String:buffer[512];
  1815.     Format(buffer, sizeof(buffer), "SELECT steam_id, time, start_time, reason, name, ip, admin_id, admin_ip FROM queue");
  1816.     SQL_TQuery(SQLiteDB, ProcessQueueCallback, buffer);
  1817. }
  1818.  
  1819. // PARSER //
  1820.  
  1821. static InitializeConfigParser()
  1822. {
  1823.     if (ConfigParser == INVALID_HANDLE)
  1824.     {
  1825.         ConfigParser = SMC_CreateParser();
  1826.         SMC_SetReaders(ConfigParser, ReadConfig_NewSection, ReadConfig_KeyValue, ReadConfig_EndSection);
  1827.     }
  1828. }
  1829.  
  1830. static InternalReadConfig(const String:path[])
  1831. {
  1832.     ConfigState = ConfigStateNone;
  1833.  
  1834.     new SMCError:err = SMC_ParseFile(ConfigParser, path);
  1835.  
  1836.     if (err != SMCError_Okay)
  1837.     {
  1838.         decl String:buffer[64];
  1839.         if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
  1840.         {
  1841.             PrintToServer(buffer);
  1842.         } else {
  1843.             PrintToServer("Fatal parse error");
  1844.         }
  1845.     }
  1846. }
  1847.  
  1848. public SMCResult:ReadConfig_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
  1849. {
  1850.     if(name[0])
  1851.     {
  1852.         if(strcmp("Config", name, false) == 0)
  1853.         {
  1854.             ConfigState = ConfigStateConfig;
  1855.         } else if(strcmp("BanReasons", name, false) == 0) {
  1856.             ConfigState = ConfigStateReasons;
  1857.         } else if(strcmp("HackingReasons", name, false) == 0) {
  1858.             ConfigState = ConfigStateHacking;
  1859.         }
  1860.     }
  1861.     return SMCParse_Continue;
  1862. }
  1863.  
  1864. public SMCResult:ReadConfig_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
  1865. {
  1866.     if(!key[0])
  1867.         return SMCParse_Continue;
  1868.  
  1869.     switch(ConfigState)
  1870.     {
  1871.         case ConfigStateConfig:
  1872.         {
  1873.             if(strcmp("website", key, false) == 0)
  1874.             {
  1875.                 strcopy(WebsiteAddress, sizeof(WebsiteAddress), value);
  1876.             } else if(strcmp("Addban", key, false) == 0)
  1877.             {
  1878.                 if(StringToInt(value) == 0)
  1879.                 {
  1880.                     CommandDisable |= DISABLE_ADDBAN;
  1881.                 }
  1882.             }
  1883.             else if(strcmp("AutoAddServer", key, false) == 0)
  1884.             {
  1885.                 if(StringToInt(value) == 1)
  1886.                     AutoAdd = true;
  1887.                 else
  1888.                     AutoAdd = false;
  1889.             } else if(strcmp("Unban", key, false) == 0)
  1890.             {
  1891.                 if(StringToInt(value) == 0)
  1892.                 {
  1893.                     CommandDisable |= DISABLE_UNBAN;
  1894.                 }
  1895.             }
  1896.             else if(strcmp("DatabasePrefix", key, false) == 0)
  1897.             {
  1898.                 strcopy(DatabasePrefix, sizeof(DatabasePrefix), value);
  1899.  
  1900.                 if(DatabasePrefix[0] == '\0')
  1901.                 {
  1902.                     DatabasePrefix = "sb";
  1903.                 }
  1904.             }
  1905.             else if(strcmp("RetryTime", key, false) == 0)
  1906.             {
  1907.                 RetryTime   = StringToFloat(value);
  1908.                 if(RetryTime < 15.0)
  1909.                 {
  1910.                     RetryTime = 15.0;
  1911.                 } else if(RetryTime > 60.0) {
  1912.                     RetryTime = 60.0;
  1913.                 }
  1914.             }
  1915.             else if(strcmp("ProcessQueueTime", key, false) == 0)
  1916.             {
  1917.                 ProcessQueueTime = StringToInt(value);
  1918.             }
  1919.             else if(strcmp("BackupConfigs", key, false) == 0)
  1920.             {
  1921.                 if(StringToInt(value) == 1)
  1922.                     backupConfig = true;
  1923.                 else
  1924.                     backupConfig = false;
  1925.             }
  1926.             else if(strcmp("EnableAdmins", key, false) == 0)
  1927.             {
  1928.                 if(StringToInt(value) == 1)
  1929.                     enableAdmins = true;
  1930.                 else
  1931.                     enableAdmins = false;
  1932.             }
  1933.             else if(strcmp("RequireSiteLogin", key, false) == 0)
  1934.             {
  1935.                 if(StringToInt(value) == 1)
  1936.                     requireSiteLogin = true;
  1937.                 else
  1938.                     requireSiteLogin = false;
  1939.             }
  1940.             else if(strcmp("ServerID", key, false) == 0)
  1941.             {
  1942.                 serverID = StringToInt(value);
  1943.             }
  1944.         }
  1945.  
  1946.         case ConfigStateReasons:
  1947.         {
  1948.             if(ReasonMenuHandle != INVALID_HANDLE)
  1949.             {
  1950.                 AddMenuItem(ReasonMenuHandle, key, value);
  1951.             }
  1952.         }
  1953.         case ConfigStateHacking:
  1954.         {
  1955.             if(HackingMenuHandle != INVALID_HANDLE)
  1956.             {
  1957.                 AddMenuItem(HackingMenuHandle, key, value);
  1958.             }
  1959.         }
  1960.     }
  1961.     return SMCParse_Continue;
  1962. }
  1963.  
  1964. public SMCResult:ReadConfig_EndSection(Handle:smc)
  1965. {
  1966.     return SMCParse_Continue;
  1967. }
  1968.  
  1969.  
  1970. /*********************************************************
  1971.  * Ban Player from server
  1972.  *
  1973.  * @param client    The client index of the player to ban
  1974.  * @param time      The time to ban the player for (in minutes, 0 = permanent)
  1975.  * @param reason    The reason to ban the player from the server
  1976.  * @noreturn       
  1977.  *********************************************************/
  1978. public Native_SBBanPlayer(Handle:plugin, numParams)
  1979. {
  1980.     new client = GetNativeCell(1);
  1981.     new target = GetNativeCell(2);
  1982.     new time = GetNativeCell(3);
  1983.     decl String:reason[128];
  1984.     GetNativeString(4, reason, 128);
  1985.    
  1986.     if(reason[0] == '\0')
  1987.         strcopy(reason, sizeof(reason), "Banned by SourceBans");
  1988.    
  1989.     if(client && IsClientInGame(client))
  1990.     {
  1991.         new AdminId:aid = GetUserAdmin(client);
  1992.         if(aid == INVALID_ADMIN_ID)
  1993.         {
  1994.             ThrowNativeError(1, "Ban Error: Player is not an admin.");
  1995.             return 0;
  1996.         }
  1997.        
  1998.         if(!GetAdminFlag(aid, Admin_Ban))
  1999.         {
  2000.             ThrowNativeError(2, "Ban Error: Player does not have BAN flag.");
  2001.             return 0;
  2002.         }
  2003.     }
  2004.    
  2005.     PrepareBan(client, target, time, reason, sizeof(reason));
  2006.     return true;
  2007. }
  2008.  
  2009.  
  2010. // STOCK FUNCTIONS //
  2011.  
  2012. public InitializeBackupDB()
  2013. {
  2014.     decl String:error[255];
  2015.     SQLiteDB = SQLite_UseDatabase("sourcebans-queue", error, sizeof(error));
  2016.     if(SQLiteDB == INVALID_HANDLE)
  2017.         SetFailState(error);
  2018.    
  2019.     SQL_LockDatabase(SQLiteDB);
  2020.     SQL_FastQuery(SQLiteDB, "CREATE TABLE IF NOT EXISTS queue (steam_id TEXT PRIMARY KEY ON CONFLICT REPLACE, time INTEGER, start_time INTEGER, reason TEXT, name TEXT, ip TEXT, admin_id TEXT, admin_ip TEXT);");
  2021.     SQL_UnlockDatabase(SQLiteDB);
  2022. }
  2023.  
  2024. public bool:CreateBan(client, target, time, String:reason[])
  2025. {
  2026.     decl String:adminIp[24], String:adminAuth[64];
  2027.     new admin = client;
  2028.    
  2029.     // The server is the one calling the ban
  2030.     if(!admin)
  2031.     {
  2032.         if(reason[0] == '\0')
  2033.         {
  2034.             // We cannot pop the reason menu if the command was issued from the server
  2035.             PrintToServer("%s%T", Prefix, "Include Reason", LANG_SERVER);
  2036.             return false;
  2037.         }
  2038.  
  2039.         // setup dummy adminAuth and adminIp for server
  2040.         strcopy(adminAuth, sizeof(adminAuth), "STEAM_ID_SERVER");
  2041.         strcopy(adminIp, sizeof(adminIp), ServerIp);
  2042.     } else {
  2043.         GetClientIP(admin, adminIp, sizeof(adminIp));
  2044.         GetClientAuthString(admin, adminAuth, sizeof(adminAuth));
  2045.     }
  2046.  
  2047.     // target information
  2048.     decl String:ip[24], String:auth[64], String:name[64];
  2049.  
  2050.     GetClientName(target, name, sizeof(name));
  2051.     GetClientIP(target, ip, sizeof(ip));
  2052.     GetClientAuthString(target, auth, sizeof(auth));
  2053.  
  2054.     new userid = admin ? GetClientUserId(admin) : 0;
  2055.  
  2056.     // Pack everything into a data pack so we can retain it
  2057.     new Handle:dataPack = CreateDataPack();
  2058.     new Handle:reasonPack = CreateDataPack();
  2059.     WritePackString(reasonPack, reason);
  2060.  
  2061.     WritePackCell(dataPack, admin);
  2062.     WritePackCell(dataPack, target);
  2063.     WritePackCell(dataPack, userid);
  2064.     WritePackCell(dataPack, GetClientUserId(target));
  2065.     WritePackCell(dataPack, time);
  2066.     WritePackCell(dataPack, _:reasonPack);
  2067.     WritePackString(dataPack, name);
  2068.     WritePackString(dataPack, auth);
  2069.     WritePackString(dataPack, ip);
  2070.     WritePackString(dataPack, adminAuth);
  2071.     WritePackString(dataPack, adminIp);
  2072.  
  2073.     ResetPack(dataPack);
  2074.     ResetPack(reasonPack);
  2075.  
  2076.     if(reason[0] != '\0')
  2077.     {
  2078.         // if we have a valid reason pass move forward with the ban
  2079.         if(Database != INVALID_HANDLE)
  2080.         {
  2081.             UTIL_InsertBan(time, name, auth, ip, reason, adminAuth, adminIp, dataPack);
  2082.         } else {
  2083.             UTIL_InsertTempBan(time, name, auth, ip, reason, adminAuth, adminIp, dataPack);
  2084.         }
  2085.     } else {
  2086.         // We need a reason so offer the administrator a menu of reasons
  2087.         PlayerDataPack[admin] = dataPack;
  2088.         DisplayMenu(ReasonMenuHandle, admin, MENU_TIME_FOREVER);
  2089.         ReplyToCommand(admin, "%c[%cSourceBans%c]%c %t", GREEN, NAMECOLOR, GREEN, NAMECOLOR, "Check Menu");
  2090.     }
  2091.    
  2092.     return true;
  2093. }
  2094.  
  2095. stock UTIL_InsertBan(time, const String:Name[], const String:Authid[], const String:Ip[], const String:Reason[], const String:AdminAuthid[], const String:AdminIp[], Handle:Pack)
  2096. {
  2097.     //new Handle:dummy;
  2098.     //PruneBans(dummy);
  2099.     decl String:banName[128];
  2100.     decl String:banReason[256];
  2101.     decl String:Query[1024];
  2102.     SQL_EscapeString(Database, Name, banName, sizeof(banName));
  2103.     SQL_EscapeString(Database, Reason, banReason, sizeof(banReason));
  2104.     if( serverID == -1 )
  2105.     {
  2106.         FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
  2107.                         ('%s', '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'),'0'), '%s', \
  2108.                         (SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s' LIMIT 0,1), ' ')",
  2109.                         DatabasePrefix, Ip, Authid, banName, (time*60), (time*60), banReason, DatabasePrefix, AdminAuthid, AdminAuthid[8], AdminIp, DatabasePrefix, ServerIp, ServerPort);
  2110.     }else{
  2111.         FormatEx(Query, sizeof(Query), "INSERT INTO %s_bans (ip, authid, name, created, ends, length, reason, aid, adminIp, sid, country) VALUES \
  2112.                         ('%s', '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP() + %d, %d, '%s', IFNULL((SELECT aid FROM %s_admins WHERE authid = '%s' OR authid REGEXP '^STEAM_[0-9]:%s$'),'0'), '%s', \
  2113.                         %d, ' ')",
  2114.                         DatabasePrefix, Ip, Authid, banName, (time*60), (time*60), banReason, DatabasePrefix, AdminAuthid, AdminAuthid[8], AdminIp, serverID);
  2115.     }
  2116.    
  2117.     SQL_TQuery(Database, VerifyInsert, Query, Pack, DBPrio_High);
  2118. }
  2119.  
  2120. stock UTIL_InsertTempBan(time, const String:name[], const String:auth[], const String:ip[], const String:reason[], const String:adminAuth[], const String:adminIp[], Handle:dataPack)
  2121. {
  2122.     ReadPackCell(dataPack);
  2123.     new client = ReadPackCell(dataPack);
  2124.     SetPackPosition(dataPack, 40);
  2125.     new Handle:reasonPack = Handle:ReadPackCell(dataPack);
  2126.     if(reasonPack != INVALID_HANDLE)
  2127.     {
  2128.         CloseHandle(reasonPack);
  2129.     }
  2130.     CloseHandle(dataPack);
  2131.    
  2132.     // we add a temporary ban and then add the record into the queue to be processed when the database is available
  2133.     decl String:buffer[50];
  2134.     Format(buffer, sizeof(buffer), "banid %d %s", ProcessQueueTime, auth);
  2135.     ServerCommand(buffer);
  2136.     if(IsClientInGame(client))
  2137.         KickClient(client, "%t", "Banned Check Site", WebsiteAddress);
  2138.    
  2139.     decl String:banName[128];
  2140.     decl String:banReason[256];
  2141.     decl String:query[512];
  2142.     SQL_EscapeString(SQLiteDB, name, banName, sizeof(banName));
  2143.     SQL_EscapeString(SQLiteDB, reason, banReason, sizeof(banReason));
  2144.     FormatEx(   query, sizeof(query), "INSERT INTO queue VALUES ('%s', %i, %i, '%s', '%s', '%s', '%s', '%s')",
  2145.                 auth, time, GetTime(), banReason, banName, ip, adminAuth, adminIp);
  2146.     SQL_TQuery(SQLiteDB, ErrorCheckCallback, query);
  2147. }
  2148.  
  2149. stock CheckLoadAdmins()
  2150. {
  2151.     for(new i = 1; i <= MaxClients; i++)
  2152.     {
  2153.         if(IsClientInGame(i) && IsClientAuthorized(i))
  2154.         {
  2155.             RunAdminCacheChecks(i);
  2156.             NotifyPostAdminCheck(i);
  2157.         }
  2158.     }    
  2159. }
  2160.  
  2161. stock InsertServerInfo()
  2162. {
  2163.     if(Database == INVALID_HANDLE)
  2164.     {
  2165.         return;
  2166.     }
  2167.    
  2168.     decl String:query[100], pieces[4];
  2169.     new longip = GetConVarInt(CvarHostIp);
  2170.     pieces[0] = (longip >> 24) & 0x000000FF;
  2171.     pieces[1] = (longip >> 16) & 0x000000FF;
  2172.     pieces[2] = (longip >> 8) & 0x000000FF;
  2173.     pieces[3] = longip & 0x000000FF;
  2174.     FormatEx(ServerIp, sizeof(ServerIp), "%d.%d.%d.%d", pieces[0], pieces[1], pieces[2], pieces[3]);
  2175.     GetConVarString(CvarPort, ServerPort, sizeof(ServerPort));
  2176.    
  2177.     if(AutoAdd != false)
  2178.     {
  2179.         FormatEx(query, sizeof(query), "SELECT sid FROM %s_servers WHERE ip = '%s' AND port = '%s'", DatabasePrefix, ServerIp, ServerPort);
  2180.         SQL_TQuery(Database, ServerInfoCallback, query);
  2181.     }
  2182. }
  2183.  
  2184. stock PrepareBan(client, target, time, String:reason[], size)
  2185. {
  2186. #if defined DEBUG
  2187.             LogToFile(logFile, "PrepareBan()");
  2188. #endif
  2189.     if(!target || !IsClientInGame(target))
  2190.         return;
  2191.     decl String:authid[64], String:name[32], String:bannedSite[512];
  2192.     GetClientAuthString(target, authid, sizeof(authid));
  2193.     GetClientName(target, name, sizeof(name));
  2194.  
  2195.    
  2196.     if(CreateBan(client, target, time, reason))
  2197.     {
  2198.         if (!time)
  2199.         {
  2200.             if (reason[0] == '\0')
  2201.             {
  2202.                 ShowActivity(client, "%t", "Permabanned player", name);
  2203.             } else {
  2204.                 ShowActivity(client, "%t", "Permabanned player reason", name, reason);
  2205.             }
  2206.         } else {
  2207.             if (reason[0] == '\0')
  2208.             {
  2209.                 ShowActivity(client, "%t", "Banned player", name, time);
  2210.             } else {
  2211.                 ShowActivity(client, "%t", "Banned player reason", name, time, reason);
  2212.             }
  2213.         }
  2214.         LogAction(client, target, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason);
  2215.        
  2216.         if(time > 5 || time == 0)
  2217.             time = 5;
  2218.         Format(bannedSite, sizeof(bannedSite), "%T", "Banned Check Site", target, WebsiteAddress);
  2219.         BanClient(target, time, BANFLAG_AUTO, bannedSite, bannedSite, "sm_ban", client);
  2220.     }
  2221.    
  2222.     g_BanTarget[client] = -1;
  2223.     g_BanTime[client] = -1;
  2224. }
  2225.  
  2226. stock ReadConfig()
  2227. {
  2228.     InitializeConfigParser();
  2229.  
  2230.     if (ConfigParser == INVALID_HANDLE)
  2231.     {
  2232.         return;
  2233.     }
  2234.  
  2235.     decl String:ConfigFile[PLATFORM_MAX_PATH];
  2236.     BuildPath(Path_SM, ConfigFile, sizeof(ConfigFile), "configs/sourcebans/sourcebans.cfg");
  2237.  
  2238.     if(FileExists(ConfigFile))
  2239.     {
  2240.         InternalReadConfig(ConfigFile);
  2241.         PrintToServer("%sLoading configs/sourcebans.cfg config file", Prefix);
  2242.     } else {
  2243.         decl String:Error[PLATFORM_MAX_PATH + 64];
  2244.         FormatEx(Error, sizeof(Error), "%sFATAL *** ERROR *** can not find %s", Prefix, ConfigFile);
  2245.         LogToFile(logFile, "FATAL *** ERROR *** can not find %s", ConfigFile);
  2246.         SetFailState(Error);
  2247.     }
  2248. }
  2249.  
  2250. stock ResetSettings()
  2251. {
  2252.     CommandDisable = 0;
  2253.  
  2254.     ResetMenu();
  2255.     ReadConfig();
  2256. }
  2257.  
  2258. //Yarr!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement