Advertisement
Guest User

Untitled

a guest
Apr 5th, 2010
348
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 49.20 KB | None | 0 0
  1. /************************************************
  2.  *      Kigen's Anti-Cheat      *
  3.  *----------------------------------------------*
  4.  * Author: Kigen @ codingdirect.com         *
  5.  * Thanks to: SourceMod Team for covering a lot *
  6.  * of the grunt work. :P            *
  7.  ************************************************
  8.  *      Copyright Notice        *
  9.  *----------------------------------------------*
  10.  *  Copyright (c) 2009 Max Krivanek aka Kigen   *
  11.  ************************************************
  12.  *      Websites to Visit       *
  13.  *----------------------------------------------*
  14.  * http://www.kigenac.com/ - KAC's home.    *
  15.  * http://www.codingdirect.com/ - My website    *
  16.  * http://www.n00bsalad.net/ - Best servers on  *
  17.  * the west coast. Users of KAC private version.*
  18.  ************************************************
  19.  *       Version History        *
  20.  * ---------------------------------------------*
  21.  * 1.0 Public - Initial Released Public Version *
  22.  * 1.0.1 Pub - Removed useless dependencies.    *
  23.  * 1.0.2 Pub - Fixed round_freeze_end for   *
  24.  * servers that don't have it. :P       *
  25.  * 1.1 Pub - Added Cafe banning and using KAC   *
  26.  * global banlist.  Added blocking names with   *
  27.  * multibyte characters.  Fixed possible error  *
  28.  * with format.                 *
  29.  * 1.1.1 Pub - Fixed problem with replication.  *
  30.  * 1.1.2 Pub - Replaced bobcycle cvar check.    *
  31.  * 1.1.3 Pub - Fixed problems relating to mis-  *
  32.  * documented/used functions in SourceMod.  *
  33.  * 1.1.4 Pub - Fixed various bugs.  Reworked    *
  34.  * some of the code. Added logging to separate  *
  35.  * file. Now requires Sockets for use.  Added   *
  36.  * support for MySQL bans.          *
  37.  * 1.1.5 Pub - Some new things, probably more   *
  38.  * than needed but shouldn't affect KAC's   *
  39.  * performance.  Added check for mat_dxlevel.   *
  40.  * 1.1.6 Pub - Fixed an error preventing a ban. *
  41.  * 1.1.7 Pub - Updated various things.  Added   *
  42.  * update checker to check for updates.     *
  43.  * Optimizations have been done as well.    *
  44.  * 1.1.8 Pub - Added Spam Checking.  More   *
  45.  * optimizations to the code.  Added define to  *
  46.  * exclude Sockets at will.         *
  47.  * 1.1.9 Pub - Added a lot of crash exploit     *
  48.  * fixes for exploits that have gotten wild.    *
  49.  * Fixed some false positives that could be     *
  50.  * created by a admin changing server convars.  *
  51.  * Added some more cvar checks for third party  *
  52.  * server plugins loaded on a client. Readded   *
  53.  * check for mat_dxlevel. Removed useless block *
  54.  * IP functions.  Use srcds internal.       *
  55.  * 1.1.9.1 Pub - Fixed issues with file not *
  56.  * maintaining ANSII.               *
  57.  ************************************************
  58.  *           License            *
  59.  *----------------------------------------------*
  60.  * All below code is to be covered under the    *
  61.  * GPL v3 or a later version.           *
  62.  * http://www.gnu.org/licenses/gpl-3.0.txt  *
  63.  ************************************************
  64.  *            Notes         *
  65.  *----------------------------------------------*
  66.  * This is a public version of the plugin.  It  *
  67.  * is indeed pretty much KAC as it stands now,  *
  68.  * however, it will not recieve all the future  *
  69.  * features that maybe added to my own private  *
  70.  * version of the plugin.  What made me decide  *
  71.  * to go ahead and release a public version of  *
  72.  * this plugin is the release of other similar  *
  73.  * plugins such as ES Anti-Cheat and VBAC.  *
  74.  * Since they currently use the Query ConVar    *
  75.  * feature present in the Source engine they're *
  76.  * likely to get bypassed or dodged due to the  *
  77.  * releases.  Because of this I decided to go   *
  78.  * ahead and give the community something   *
  79.  * useful instead of just these little plugins  *
  80.  * that only detect sv_cheats and in the case   *
  81.  * of VBAC mat_wireframe.           *
  82.  * Also note that this was originally built     *
  83.  * before the releases of both above said ACs.  *
  84.  ************************************************
  85.  
  86.     This program is free software: you can redistribute it and/or modify
  87.     it under the terms of the GNU General Public License as published by
  88.     the Free Software Foundation, either version 3 of the License, or
  89.     (at your option) any later version.
  90.  
  91.     This program is distributed in the hope that it will be useful,
  92.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  93.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  94.     GNU General Public License for more details.
  95.  
  96.     You should have received a copy of the GNU General Public License
  97.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  98.  
  99.     **** DO NOT MODIFY THE ABOVE NOTICES PLEASE! (Unless just to note additions.) ****
  100.  
  101. */
  102.  
  103. #define SOCKET_ENABLED  // Comment this line out to disable Sockets.
  104.  
  105. #pragma semicolon 1
  106. #include <sourcemod>
  107. #include <sdktools>
  108. #if defined SOCKET_ENABLED
  109. #include <socket>
  110. #endif
  111.  
  112. // Defined Native here rather than including the larger IRC include.
  113. #if defined SOCKET_ENABLED // No Sockets, no IRC.
  114. native IRC_PrivMsg(const String:destination[], const String:message[], any:...);
  115. #endif
  116.  
  117. #define PLUGIN_VERSION "1.1.9"
  118. #define MAX_HACKCVAR 41 /* !!!!!! If you add Cvars you need to change this number to reflect how many there are! !!!!!! */
  119.  
  120. // Connection States
  121. #define CS_BOT      -1
  122. #define CS_NOTCONN  0
  123. #define CS_CONNING  1
  124. #define CS_AUTHED   2
  125. #define CS_VALIDATED    3
  126. #define CS_BANNING  4
  127.  
  128. // Action Types
  129. #define ACTION_BAN  0
  130. #define ACTION_KICK 1
  131. #define ACTION_WARN 2
  132.  
  133. // Compare Types
  134. #define COMP_EQUAL  0
  135. #define COMP_LESS   1
  136. #define COMP_GREATER    2
  137. #define COMP_NONEXIST   3
  138.  
  139. new const String:g_CompareString[3][] = { "equal to", "less than or equal to", "greater than or equal to" };
  140.  
  141. // Booleans
  142. #if defined SOCKET_ENABLED
  143. new bool:HasIRC = false;
  144. new bool:Locked = false;
  145. new bool:Checked = false;
  146. #endif
  147. new bool:Enabled = true;
  148. new ConnState[MAXPLAYERS+1] = {CS_NOTCONN, ...};
  149. new count[MAXPLAYERS+1] = {0,...};
  150. new cmdspam = 15;
  151.  
  152. // CVAR Handles
  153. new Handle:CVar_BlockNameCopy = INVALID_HANDLE;
  154. new Handle:CVar_Cheats = INVALID_HANDLE;
  155. new Handle:CVar_IRCChan = INVALID_HANDLE;
  156. new Handle:CVar_BanCafe = INVALID_HANDLE;
  157. new Handle:CVar_BlockMultiByte = INVALID_HANDLE;
  158. new Handle:CVar_Enable = INVALID_HANDLE;
  159. new Handle:CVar_CmdSpam = INVALID_HANDLE;
  160.  
  161. // Timer handles.
  162. new Handle:PTimer[MAXPLAYERS+1] = {INVALID_HANDLE, ...};
  163.  
  164. // Socket
  165. #if defined SOCKET_ENABLED
  166. new Handle:TSocket = INVALID_HANDLE;
  167. #endif
  168.  
  169. // Reason Strings
  170. new String:g_Reason[MAXPLAYERS+1][512];
  171. new String:g_Reason2[MAXPLAYERS+1][512];
  172.  
  173. // Arrays
  174. new Handle:CacheAuthArray = INVALID_HANDLE;
  175. new Handle:CacheReasonArray = INVALID_HANDLE;
  176. #if defined SOCKET_ENABLED
  177. new Handle:AllowArray = INVALID_HANDLE;
  178. #endif
  179.  
  180. /* Cvars to protect
  181.  * If you wish to add more CVars then please make sure they are replicated properly on normal clients
  182.  * and that you add at the end of this list and add the proper value for that CVar at the end of
  183.  * g_HackCVarValues.  You will also need to add one to MAX_HACKCVAR.
  184.  */
  185. new String:g_HackCVars[][] = {
  186.     "cl_clock_correction",      // 15   0
  187.     "cl_leveloverview",     // 9    1
  188.     "cl_overdraw_test",     //  2
  189.     "cl_particles_show_bbox",   // 11   3
  190.     "cl_phys_timescale",        //  4
  191.     "cl_showevents",        //  5
  192.     "fog_enable",           // 7    6
  193.     "host_timescale",       // 2    7
  194.     "mat_fillrate",         // 8    8
  195.     "mat_proxy",            // 5    9
  196.     "mat_wireframe",        //  10
  197.     "mem_force_flush",      // 10   11
  198.     "snd_show",         // 17   12
  199.     "snd_visualize",        // 18   13
  200.     "sv_cheats",            // 0    14
  201.     "sv_consistency",       // 3    15
  202.     "sv_gravity",           // 1    16
  203.     "r_aspectratio",        // 14   17
  204.     "r_colorstaticprops",       // 19   18
  205.     "r_DispWalkable",       // 20   19
  206.     "r_DrawBeams",          // 21   20
  207.     "r_drawbrushmodels",        // 22   21
  208.     "r_drawclipbrushes",        // 23   22
  209.     "r_drawdecals",         // 24   23
  210.     "r_drawentities",       //  24
  211.     "r_drawopaqueworld",        //  25
  212.     "r_drawothermodels",        // 16   26
  213.     "r_drawparticles",      // 4    27
  214.     "r_drawrenderboxes",        // 12   28
  215.     "r_drawtranslucentworld",   //  29
  216.     "r_shadowwireframe",        // 6    30
  217.     "r_skybox",         //  31
  218.     "r_visocclusion",       //  32
  219.     "vcollide_wireframe",       // 13   33
  220.     "sourcemod_version",        //  34
  221.     "metamod_version",      //  35
  222.     "bat_version",          //  36
  223.     "est_version",          //  37
  224.     "eventscripts_ver",     //  38
  225.     "mani_admin_plugin_version",    //  39
  226.     "zb_version",           //  40
  227.     "mat_dxlevel"           //  41
  228. };
  229. new Float:g_HackCVarValues[] = {
  230.     1.0, // cl_clock_correction 15  0
  231.     0.0, // cl_leveloverview    9   1
  232.     0.0, // cl_overdraw_test        2
  233.     0.0, // cl_particles_show_bbox  11  3
  234.     1.0, // cl_phys_timescale       4
  235.     0.0, // cl_showevents           5
  236.     1.0, // fog_enable      7   6
  237.     1.0, // host_timescale      2   7
  238.     0.0, // mat_fillrate        8   8
  239.     0.0, // mat_proxy       5   9
  240.     0.0, // mat_wireframe           10
  241.     0.0, // mem_force_flush     10  11
  242.     0.0, // snd_show        17  12
  243.     0.0, // snd_visualize       18  13
  244.     0.0, // sv_cheats       0   14
  245.     1.0, // sv_consistency      3   15
  246.     800.0, // sv_gravity        1   16
  247.     0.0, // r_aspectratio       14  17
  248.     0.0, // r_colorstaticprops  19  18
  249.     0.0, // r_DispWalkable      20  19
  250.     1.0, // r_DrawBeams     21  20
  251.     1.0, // r_drawbrushmodels   22  21
  252.     0.0, // r_drawclipbrushes   23  22
  253.     1.0, // r_drawdecals        24  23
  254.     1.0, // r_drawentities          24
  255.     1.0, // r_drawopaqueworld       25
  256.     1.0, // r_drawothermodels   16  26
  257.     1.0, // r_drawparticles     4   27
  258.     0.0, // r_drawrenderboxes   12  28
  259.     1.0, // r_drawtranslucentworld      29
  260.     0.0, // r_shadowwireframe   6   30
  261.     1.0, // r_skybox            31
  262.     0.0, // r_visocclusion          32
  263.     0.0, // vcollide_wireframe  13  33
  264.     0.0, // sourcemod_version       34
  265.     0.0, // metamod_version         35
  266.     0.0, // bat_version         36
  267.     0.0, // est_version         37
  268.     0.0, // eventscripts_ver        38
  269.     0.0, // mani_admin_plugin_version   39
  270.     0.0, // zb_version          40
  271.     70.0 // mat_dxlevel         41
  272. };
  273. new g_HackCVarsComp[] = {
  274.     COMP_EQUAL, // cl_clock_correction  15  0
  275.     COMP_EQUAL, // cl_leveloverview 9   1
  276.     COMP_EQUAL, // cl_overdraw_test     2
  277.     COMP_EQUAL, // cl_particles_show_bbox 11    3
  278.     COMP_EQUAL, // cl_phys_timescale        4
  279.     COMP_EQUAL, // cl_showevents        5
  280.     COMP_EQUAL, // fog_enable       7   6
  281.     COMP_EQUAL, // host_timescale   2   7
  282.     COMP_EQUAL, // mat_fillrate     8   8
  283.     COMP_EQUAL, // mat_proxy        5   9
  284.     COMP_EQUAL, // mat_wireframe        10
  285.     COMP_EQUAL, // mem_force_flush  10  11
  286.     COMP_EQUAL, // snd_show     17  12
  287.     COMP_EQUAL, // snd_visualize    18  13
  288.     COMP_EQUAL, // sv_cheats        0   14
  289.     COMP_EQUAL, // sv_consistency   3   15
  290.     COMP_EQUAL, // sv_gravity       1   16
  291.     COMP_EQUAL, // r_aspectratio    14  17
  292.     COMP_EQUAL, // r_colorstaticprops   19  18
  293.     COMP_EQUAL, // r_DispWalkable   20  19
  294.     COMP_EQUAL, // r_DrawBeams      21  20
  295.     COMP_EQUAL, // r_drawbrushmodels    22  21
  296.     COMP_EQUAL, // r_drawclipbrushes    23  22
  297.     COMP_EQUAL, // r_drawdecals     24  23
  298.     COMP_EQUAL, // r_drawentities       24
  299.     COMP_EQUAL, // r_drawopaqueworld        25
  300.     COMP_EQUAL, // r_drawothermodels    16  26
  301.     COMP_EQUAL, // r_drawparticles  4   27
  302.     COMP_EQUAL, // r_drawrenderboxes    12  28
  303.     COMP_EQUAL, // r_drawtranslucentworld   29
  304.     COMP_EQUAL, // r_shadowwireframe    6   30
  305.     COMP_EQUAL, // r_skybox         31
  306.     COMP_EQUAL, // r_visocclusion       32
  307.     COMP_EQUAL, // vcollide_wireframe   13  33
  308.     COMP_NONEXIST,  // sourcemod_version        34
  309.     COMP_NONEXIST,  // metamod_version      35
  310.     COMP_NONEXIST,  // bat_version          36
  311.     COMP_NONEXIST,  // est_version          37
  312.     COMP_NONEXIST,  // eventscripts_ver     38
  313.     COMP_NONEXIST,  // mani_admin_plugin_version    39
  314.     COMP_NONEXIST,  // zb_version           40
  315.     COMP_GREATER    // mat_dxlevel          41
  316. };
  317. new g_HackCVarsAction[] = {
  318.     ACTION_BAN, // cl_clock_correction  15  0
  319.     ACTION_BAN, // cl_leveloverview 9       1
  320.     ACTION_BAN, // cl_overdraw_test         2
  321.     ACTION_BAN, // cl_particles_show_bbox   11  3
  322.     ACTION_BAN, // cl_phys_timescale        4
  323.     ACTION_BAN, // cl_showevents            5
  324.     ACTION_BAN, // fog_enable       7   6
  325.     ACTION_BAN, // host_timescale       2   7
  326.     ACTION_BAN, // mat_fillrate     8   8
  327.     ACTION_BAN, // mat_proxy        5   9
  328.     ACTION_BAN, // mat_wireframe            10
  329.     ACTION_BAN, // mem_force_flush      10  11
  330.     ACTION_BAN, // snd_show         17  12
  331.     ACTION_BAN, // snd_visualize        18  13
  332.     ACTION_BAN, // sv_cheats        0   14
  333.     ACTION_BAN, // sv_consistency       3   15
  334.     ACTION_BAN, // sv_gravity       1   16
  335.     ACTION_KICK, // r_aspectratio       14  17
  336.     ACTION_BAN, // r_colorstaticprops   19  18
  337.     ACTION_BAN, // r_DispWalkable       20  19
  338.     ACTION_BAN, // r_DrawBeams      21  20
  339.     ACTION_BAN, // r_drawbrushmodels    22  21
  340.     ACTION_BAN, // r_drawclipbrushes    23  22
  341.     ACTION_BAN, // r_drawdecals     24  23
  342.     ACTION_BAN, // r_drawentities           24
  343.     ACTION_BAN, // r_drawopaqueworld        25
  344.     ACTION_BAN, // r_drawothermodels    16  26
  345.     ACTION_BAN, // r_drawparticles      4   27
  346.     ACTION_BAN, // r_drawrenderboxes    12  28
  347.     ACTION_BAN, // r_drawtranslucentworld       29
  348.     ACTION_BAN, // r_shadowwireframe    6   30
  349.     ACTION_BAN, // r_skybox             31
  350.     ACTION_BAN, // r_visocclusion           32
  351.     ACTION_BAN, // vcollide_wireframe   13  33
  352.     ACTION_KICK, // sourcemod_version       34
  353.     ACTION_KICK, // metamod_version         35
  354.     ACTION_KICK, // bat_version         36
  355.     ACTION_KICK, // est_version         37
  356.     ACTION_KICK, // eventscripts_ver        38
  357.     ACTION_KICK, // mani_admin_plugin_version   39
  358.     ACTION_KICK, // zb_version          40
  359.     ACTION_KICK  // mat_dxlevel         41
  360. };
  361.  
  362. new Handle:g_HackCVarHandles[MAX_HACKCVAR+1] = {INVALID_HANDLE, ...};
  363. new Handle:g_HackCVarUseTHandle[MAX_HACKCVAR+1] = {INVALID_HANDLE, ...};
  364. new g_HackCheckOrder[MAX_HACKCVAR*2+2] = {0, ...};
  365. new CVarI[MAXPLAYERS+1];
  366.  
  367. public Plugin:myinfo =
  368. {
  369.     name = "Kigen's Anti-Cheat",
  370.     author = "Kigen",
  371.     description = "The cheats stop here!",
  372.     version = PLUGIN_VERSION,
  373.     url = "http://www.kigenac.com/"
  374. };
  375.  
  376. #if defined SOCKET_ENABLED
  377. public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
  378. {
  379.     // Mark Native
  380.     MarkNativeAsOptional("IRC_PrivMsg");
  381.     return true;
  382. }
  383. #endif
  384.  
  385. public OnPluginStart()
  386. {
  387.     decl Handle:t_ConVar;
  388.  
  389.     CacheAuthArray = CreateArray(64);
  390.     CacheReasonArray = CreateArray(256);
  391. #if defined SOCKET_ENABLED
  392.     AllowArray = CreateArray(64);
  393. #endif
  394.  
  395.     if ( !HookEventEx("player_changename", EventNameChange) )
  396.         LogError("Unable to hook player_changename");
  397.  
  398.     CreateConVar("kac_version", PLUGIN_VERSION, "KAC version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_CHEAT);
  399.     CVar_BlockNameCopy = CreateConVar("kac_block_namecopy", "0", "Blocks name copying and short names (name < 3)");
  400.     CVar_IRCChan = CreateConVar("kac_irc_channel", "", "Channel to broadcast KAC messages on.  Set to nothing to disable.");
  401.     CVar_BanCafe = CreateConVar("kac_block_cafe", "0", "Blocks all Cafe accounts from entering the server.");
  402.     CVar_BlockMultiByte = CreateConVar("kac_block_multibyte_names", "0", "Blocks the usage of multibyte characters in a name.");
  403.     CVar_Enable = CreateConVar("kac_enable", "1", "Enables/Disables KAC's cheat detection. (Does not affect other features.)");
  404.     CVar_CmdSpam = CreateConVar("kac_cmdspam", "15", "Amount of commands in one second before kick.  0 for disable.");
  405.     CVar_Cheats = FindConVar("sv_cheats");
  406.     SetConVarInt(CVar_Cheats, 0, true);
  407.  
  408.     if ( CVar_BlockNameCopy == INVALID_HANDLE || CVar_IRCChan == INVALID_HANDLE
  409.       || CVar_BanCafe == INVALID_HANDLE || CVar_BlockMultiByte == INVALID_HANDLE
  410.       || CVar_Cheats == INVALID_HANDLE || CVar_CmdSpam == INVALID_HANDLE
  411.       || CVar_Enable == INVALID_HANDLE )
  412.         SetFailState("Unable to create/hook needed convars.");
  413.  
  414.     SetConVarBounds(CVar_CmdSpam, ConVarBound_Upper, true, 50.0);
  415.     SetConVarBounds(CVar_CmdSpam, ConVarBound_Lower, true, 0.0);
  416.     // SetConVarBounds(CVar_BlockNameCopy, ConVarBound_Upper, true, 1.0);
  417.     // SetConVarBounds(CVar_BlockNameCopy, ConVarBound_Lower, true, 0.0);
  418.     // SetConVarBounds(CVar_BanCafe, ConVarBound_Upper, true, 1.0);
  419.     // SetConVarBounds(CVar_BanCafe, ConVarBound_Lower, true, 0.0);
  420.     // SetConVarBounds(CVar_BlockMultiByte, ConVarBound_Upper, true, 1.0);
  421.     // SetConVarBounds(CVar_BlockMultiByte, ConVarBound_Lower, true, 0.0);
  422.     // SetConVarBounds(CVar_Enable, ConVarBound_Upper, true, 1.0);
  423.     // SetConVarBounds(CVar_Enable, ConVarBound_Lower, true, 0.0);
  424.  
  425.     HookConVarChange(CVar_Enable, EnableChange);
  426.     HookConVarChange(CVar_CmdSpam, CmdSpamChange);
  427.  
  428.     // Uncomment to just block speed hackers.
  429.     // t_ConVar = FindConVar("sv_max_usercmd_future_ticks");
  430.     // if ( t_ConVar != INVALID_HANDLE )
  431.     //  SetConVarInt(t_ConVar, 1);
  432.  
  433.     // Exploit
  434.     RegConsoleCmd("changelevel", BlockExploit, "Do not use this command.");
  435.     RegConsoleCmd("ent_create", BlockExploit, "Do not use this command.");
  436.     RegConsoleCmd("ent_fire", BlockExploit, "Do not use this command."); // Exploit that cheaters can do.
  437.  
  438.     // Cheat
  439.     RegConsoleCmd("snd_restart", BlockCheat);
  440.  
  441.     // Crash (Thanks to devicenull and a few others for these)
  442.     RegConsoleCmd("ai_test_los", BlockCrash, "Do not use this command.");
  443.     RegConsoleCmd("dbghist_dump", BlockCrash, "Do not use this command.");
  444.     RegConsoleCmd("dump_entity_sizes", BlockCrash, "Do not use this command.");
  445.     RegConsoleCmd("dump_globals", BlockCrash, "Do not use this command.");
  446.     RegConsoleCmd("dump_terrain", BlockCrash, "Do not use this command.");
  447.     RegConsoleCmd("dumpcountedstrings", BlockCrash, "Do not use this command.");
  448.     RegConsoleCmd("dumpentityfactories", BlockCrash, "Do not use this command.");
  449.     RegConsoleCmd("dumpeventqueue", BlockCrash, "Do not use this command.");
  450.     RegConsoleCmd("mem_dump", BlockCrash, "Do not use this command.");
  451.     RegConsoleCmd("mp_dump_timers", BlockCrash, "Do not use this command.");
  452.     RegConsoleCmd("physics_debug_entity", BlockCrash, "Do not use this command.");
  453.     RegConsoleCmd("physics_select", BlockCrash, "Do not use this command.");
  454.     RegConsoleCmd("soundscape_flush", BlockCrash, "Do not use this command.");
  455.     RegConsoleCmd("sv_benchmark_force_start", BlockCrash, "Do not use this command.");
  456.     RegConsoleCmd("sv_findsoundname", BlockCrash, "Do not use this command.");
  457.     RegConsoleCmd("sv_soundemitter_filecheck", BlockCrash, "Do not use this command.");
  458.     RegConsoleCmd("sv_soundemitter_flush", BlockCrash, "Do not use this command.");
  459.     RegConsoleCmd("sv_soundscape_printdebuginfo", BlockCrash, "Do not use this command.");
  460.     RegConsoleCmd("rr_reloadresponsesystems", BlockCrash, "Do not use this command.");
  461.  
  462.     // KAC commands
  463. #if defined SOCKET_ENABLED
  464.     RegAdminCmd("kac_allow", KACAllow, ADMFLAG_ROOT);
  465. #endif
  466.  
  467.     for(new i=0;i<MAX_HACKCVAR;i++)
  468.     {
  469.         t_ConVar = FindConVar(g_HackCVars[i]);
  470.         if ( t_ConVar != INVALID_HANDLE && (GetConVarFlags(t_ConVar) & FCVAR_REPLICATED) )
  471.             g_HackCVarHandles[i] = t_ConVar;
  472.     }
  473. }
  474.  
  475. public OnAllPluginsLoaded()
  476. {
  477.     decl Handle:cvar, String:name[64], bool:comm, flags, Handle:t_ConVar, String:t_String[256];
  478.     // Hook replicated convars and cheat commands.
  479.     cvar = FindFirstConCommand(name, sizeof(name), comm, flags);
  480.     if (cvar == INVALID_HANDLE)
  481.         SetFailState("Failed getting first command/convar.");
  482.     do
  483.     {
  484.         if (!comm && (flags & FCVAR_REPLICATED) )
  485.         {
  486.             t_ConVar = FindConVar(name);
  487.             if ( t_ConVar == INVALID_HANDLE ) // wtf protection
  488.                 continue;
  489.             GetConVarString(t_ConVar, t_String, sizeof(t_String));
  490.             ReplicateConVar(t_ConVar, "", t_String); // Replicate it now for idoit protection in case of late loading.
  491.             HookConVarChange(t_ConVar, ReplicateConVar);
  492.         }
  493.         if (comm)
  494.         {
  495.             if ( StrContains(name, "buy") == -1 && !StrEqual(name, "use") && StrContains(name, "es_") == -1 )
  496.                 RegConsoleCmd(name, SpamCheck);
  497.             else
  498.                 RegConsoleCmd(name, ClientCheck);
  499.         }
  500.         if (comm && (flags & FCVAR_CHEAT))
  501.             RegConsoleCmd(name, BlockCheat);
  502.        
  503.     } while (FindNextConCommand(cvar, name, sizeof(name), comm, flags));
  504.  
  505.     // Stuff for if we're late.
  506.     for(new i=1;i<=MaxClients;i++)
  507.     {
  508.         if ( IsClientConnected(i) )
  509.         {
  510.             if ( IsFakeClient(i) )
  511.             {
  512.                 ConnState[i] = CS_BOT;
  513.                 continue;
  514.             }
  515.             CVarI[i] = 0;
  516.             if ( IsClientAuthorized(i) )
  517.             {
  518. #if defined SOCKET_ENABLED
  519.                 ConnState[i] = CS_AUTHED;
  520. #else
  521.                 ConnState[i] = CS_VALIDATED;
  522. #endif
  523.                 PTimer[i] = CreateTimer(GetRandomFloat(10.5, 123.8), PeriodicTimer, i, TIMER_FLAG_NO_MAPCHANGE);
  524.             }
  525.             else
  526.                 ConnState[i] = CS_CONNING;
  527.         }
  528.     }
  529.  
  530. #if defined SOCKET_ENABLED
  531.     CreateTimer(10.0, CheckVersion);
  532. #endif
  533.     CreateTimer(1.0, Clear, _, TIMER_REPEAT);
  534. }
  535.  
  536. // SourceMod likes to crash the server if we don't kill all the timers before unload. - Kigen
  537. public OnPluginEnd()
  538. {
  539.     for(new i=1;i<=MaxClients;i++)
  540.         KillTimers(i);
  541. #if defined SOCKET_ENABLED
  542.     if ( TSocket != INVALID_HANDLE )
  543.         CloseHandle(TSocket);
  544. #endif
  545. }
  546.  
  547. #if defined SOCKET_ENABLED
  548. public Action:KACAllow(client, args)
  549. {
  550.     if ( args != 1 )
  551.     {
  552.         ReplyToCommand(client, "Usage: kac_allow <steam ID> count: %d", args);
  553.         return Plugin_Handled;
  554.     }
  555.  
  556.     new index, String:authString[64];
  557.     GetCmdArg(1, authString, sizeof(authString));
  558.  
  559.     if ( strncmp(authString, "STEAM_0:", 8) != 0 )
  560.     {
  561.         ReplyToCommand(client, "You must use a properly formatted STEAM ID.");
  562.         return Plugin_Handled;
  563.     }
  564.    
  565.     index = FindStringInArray(CacheAuthArray, authString);
  566.     if ( index != -1 )
  567.     {
  568.         RemoveFromArray(CacheAuthArray, index);
  569.         RemoveFromArray(CacheReasonArray, index);
  570.     }
  571.     index = FindStringInArray(AllowArray, authString);
  572.     if ( index == -1 )
  573.         PushArrayString(AllowArray, authString);
  574.     ReplyToCommand(client, "Steam ID '%s' added to exceptions list.", authString);
  575.     return Plugin_Handled;
  576. }
  577.  
  578. public OnConfigsExecuted()
  579. {
  580.     decl Handle:t_ConVar;
  581.     t_ConVar = FindConVar("irc_version");
  582.     if ( t_ConVar != INVALID_HANDLE )
  583.     {
  584.         HasIRC = true;
  585.         CloseHandle(t_ConVar);
  586.     }
  587. }
  588. #endif
  589.  
  590. // This apparently gets called whenever the plugin is loaded.
  591. public OnMapStart()
  592. {
  593.     CreateNewCheckOrder();
  594.     ClearArray(CacheAuthArray);
  595.     ClearArray(CacheReasonArray);
  596. }
  597.  
  598. public OnMapEnd()
  599. {
  600.     for(new i=1;i<=MaxClients;i++)
  601.     {
  602.         CVarI[i] = 0;
  603.         PTimer[i] = INVALID_HANDLE;
  604.     }
  605. }
  606.  
  607. public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
  608. {
  609.     if ( IsFakeClient(client) )
  610.     {
  611.         ConnState[client] = CS_BOT;
  612.         return true;
  613.     }
  614.  
  615.     decl String:ip[64], String:name[64], len;
  616.     GetClientName(client, name, sizeof(name));
  617.     GetClientIP(client, ip, sizeof(ip));
  618.     // Uncomment the below two lines to see the IP of connect spammers. - Kigen
  619.     // Format(buff, sizeof(buff), "%s IP:%s.", name, ip);
  620.     // PrintToAdmins(buff);
  621.  
  622.     len = strlen(name);
  623.     if ( len <= 0 )
  624.     {
  625.         Format(rejectmsg, maxlen, "Don't even think about it");
  626.         return false;
  627.     }
  628.  
  629.     if ( GetConVarBool(CVar_BlockNameCopy) )
  630.     {
  631.         decl String:PlayerName[64], diff;
  632.         if ( len <= 3 )
  633.         {
  634.             Format(rejectmsg, maxlen, "You need a longer name to play in this server");
  635.             return false;
  636.         }
  637.         for(new i=1;i<=MaxClients;i++)
  638.         {
  639.             if (IsClientConnected(i) && client != i)
  640.             {
  641.                 GetClientName(i, PlayerName, 64);
  642.                 diff = CmpString(PlayerName, name);
  643.                 if ( strlen(PlayerName) > 3 && diff < 2 )
  644.                 {
  645.                     decl String:authString2[64], String:reason[255];
  646.                     if ( !GetClientAuthString(i, authString2, 64) )
  647.                         strcopy(authString2, sizeof(authString2), "STEAM_ID_PENDING");
  648.                     Format(reason, 255, "%s (%s) was blocked from entering the server for having a similar name to %s (%s). KAC ID:1 Diff: %d", name, ip, PlayerName, authString2, diff);
  649.                     KACLog(reason);
  650.                     PrintToAdmins(reason);
  651.                     Format(rejectmsg, maxlen, "You were blocked from entering the server for having a name similar to %s", PlayerName);
  652.                     return false;
  653.                 }
  654.             }
  655.         }
  656.     }
  657.  
  658.     if ( GetConVarBool(CVar_BlockMultiByte) )
  659.     {
  660.         for(new i=0;i<len;i++)
  661.         {
  662.             if ( IsCharMB(name[i]) )
  663.             {
  664.                 decl String:reason[255];
  665.                 Format(reason, 255, "%s (%s) was blocked from entering the server for having a multibyte character (UTF) in their name.", name, ip);
  666.                 KACLog(reason);
  667.                 PrintToAdmins(reason);
  668.                 Format(rejectmsg, maxlen, "You were blocked from entering this server for having a multibyte character (UTF) in your name");
  669.                 return false;
  670.             }
  671.         }
  672.     }
  673.  
  674.     if ( StrContains(name, "Â ") != -1 )
  675.     {
  676.         decl String:reason[255];
  677.         FormatEx(reason, sizeof(reason), "%s (%s) was blocked from entering for invalid character in their name.", name, ip);
  678.         KACLog(reason);
  679.         PrintToAdmins(reason);
  680.         strcopy(rejectmsg, maxlen, "You were blocked from entering for having a invalid character in your name");
  681.         return false;
  682.     }
  683.  
  684.     ConnState[client] = CS_CONNING;
  685.     return true;
  686. }
  687.  
  688. public Action:KickThem(Handle:timer, any:client)
  689. {
  690.     if ( IsClientConnected(client) && !IsClientInKickQueue(client) && !IsFakeClient(client) )
  691.         KickClient(client, "%s", g_Reason[client]);
  692.     return Plugin_Stop;
  693. }
  694.  
  695. public OnClientAuthorized(client, const String:auth[])
  696. {
  697.     if ( IsFakeClient(client) )
  698.         return;
  699.    
  700. #if defined SOCKET_ENABLED
  701.     decl index;
  702.     index = FindStringInArray(CacheAuthArray, auth);
  703.     if ( index != -1 )
  704.     {
  705.         GetArrayString(CacheReasonArray, index, g_Reason[client], 512);
  706.         CreateTimer(0.1, KickThem, client);
  707.         return;
  708.     }
  709.  
  710.     index = FindStringInArray(AllowArray, auth);
  711.     if ( index != -1 )
  712.         ConnState[client] = CS_VALIDATED;
  713.     else
  714.         ConnState[client] = CS_AUTHED;
  715. #else
  716.     ConnState[client] = CS_VALIDATED;
  717. #endif
  718.  
  719.     decl  Handle:t_PTimer;
  720.     t_PTimer = PTimer[client];
  721.  
  722.     CVarI[client] = 0;
  723.     PTimer[client] = CreateTimer(GetRandomFloat(5.5, 17.8), PeriodicTimer, client, TIMER_FLAG_NO_MAPCHANGE);
  724.  
  725.     if ( t_PTimer != INVALID_HANDLE ) // Kill an already existing PTimer to prevent over-checking.
  726.         CloseHandle(t_PTimer);
  727. }
  728.  
  729. public OnClientDisconnect(client)
  730. {
  731.     ConnState[client] = CS_NOTCONN;
  732.     strcopy(g_Reason[client], 255, "");
  733.     strcopy(g_Reason2[client], 255, "");
  734.     KillTimers(client);
  735. }
  736.  
  737. public Action:BlockCheat(client, args)
  738. {
  739.     if ( !client )
  740.         return Plugin_Continue; // Server operation.
  741.     new String:log[256], String:cmd[255], String:name[64], String:authString[64];
  742.     GetCmdArgString(cmd, 255);
  743.     GetClientName(client, name, 64);
  744.     GetClientAuthString(client, authString, 64);
  745.     FormatEx(log, 256, "Player %s (%s) tried to execute cheat command: %s", name, authString, cmd);
  746.     KACLog(log);
  747.     return Plugin_Stop;
  748. }
  749.  
  750. public Action:BlockCrash(client, args)
  751. {
  752.     if ( !client )
  753.         return Plugin_Stop; // Server operation.  Don't allow server to crash itself.
  754.     if ( ConnState[client] == CS_BANNING )
  755.         return Plugin_Stop;
  756.     new String:log[256], String:cmd[255], String:name[64], String:authString[64];
  757.     GetCmdArg(0, cmd, 255);
  758.     GetClientName(client, name, 64);
  759.     GetClientAuthString(client, authString, 64);
  760.     FormatEx(log, 256, "%s (%s) attempted to crash this server with %s.", name, authString, cmd);
  761.     KACLog(log);
  762.     KACBan(client, 0, "Attempting to crash server", "You have been banned for attempting to crash this server");
  763.     return Plugin_Stop;
  764. }
  765.  
  766. public Action:BlockExploit(client, args)
  767. {
  768.     if ( !client )
  769.         return Plugin_Continue; // Server operation.
  770.     if ( ConnState[client] == CS_BANNING )
  771.         return Plugin_Stop;
  772.     new String:log[256], String:cmd[255], String:cmd2[255], String:name[64], String:authString[64];
  773.     GetCmdArg(0, cmd, 255);
  774.     GetCmdArgString(cmd2, 255);
  775.     GetClientName(client, name, 64);
  776.     GetClientAuthString(client, authString, 64);
  777.     FormatEx(log, 256, "%s (%s) attempted to exploit this server with: %s %s.", name, authString, cmd, cmd2);
  778.     KACLog(log);
  779.     KACBan(client, 0, "Attempting to exploit server", "You have been banned for attempting to exploit this server");
  780.     return Plugin_Stop;
  781. }
  782.  
  783. public Action:SpamCheck(client, args)
  784. {
  785.     if ( !client )
  786.         return Plugin_Continue;
  787.     if ( ConnState[client] == CS_BANNING || !IsClientInGame(client) )
  788.         return Plugin_Stop;
  789.     if ( cmdspam == 0 )
  790.         return Plugin_Continue;
  791.     count[client]++;
  792.     if ( count[client] > cmdspam )
  793.     {
  794.         new String:log[256], String:cmd[255], String:cmd2[255], String:name[64], String:authString[64];
  795.         GetCmdArg(0, cmd, 255);
  796.         GetCmdArgString(cmd2, 255);
  797.         GetClientName(client, name, 64);
  798.         GetClientAuthString(client, authString, 64);
  799.         FormatEx(log, 256, "%s (%s) was command spamming this server with: %s %s.", name, authString, cmd, cmd2);
  800.         KACLog(log);
  801.         strcopy(g_Reason[client], 512, "You have been kicked for command spamming");
  802.         CreateTimer(0.1, KickThem, client);
  803.         ConnState[client] = CS_BANNING;
  804.         return Plugin_Stop;
  805.     }
  806.     return Plugin_Continue;
  807. }
  808.  
  809. public Action:ClientCheck(client, args)
  810. {
  811.     if ( client && !IsClientInGame(client) )
  812.         return Plugin_Stop;
  813.     return Plugin_Continue;
  814. }
  815.  
  816. public Action:Clear(Handle:timer, any:arg)
  817. {
  818.     for(new i=1;i<=MaxClients;i++)
  819.         count[i] = 0;
  820.     return Plugin_Continue;
  821. }
  822.  
  823. public Action:PeriodicTimer(Handle:timer, any:client)
  824. {
  825.     if ( PTimer[client] == INVALID_HANDLE )
  826.         return Plugin_Stop;
  827.     PTimer[client] = INVALID_HANDLE;
  828.     if ( !IsClientConnected(client) || IsClientInKickQueue(client) )
  829.         return Plugin_Stop;
  830.  
  831.     decl String:name[64];
  832.     if ( GetClientName(client, name, 64) && strlen(name) < 1 )
  833.     {
  834.         decl String:authString[64], String:reason[255];
  835.         GetClientAuthString(client, authString, 64);
  836.         FormatEx(reason, 255, "%s (%s) was banned for attempting to name hack. KAC ID:2", name, authString);
  837.         KACLog(reason);
  838.         PrintToAdmins(reason);
  839.         KACBan(client, 0, "Banned for name exploit. KAC ID:2", "You have been banned for name exploiting.");
  840.         return Plugin_Stop;
  841.     }
  842.     if ( CVarI[client] > MAX_HACKCVAR*2 )
  843.         CVarI[client] = 0;
  844.     if ( Enabled )
  845.         QueryClientConVar(client, g_HackCVars[g_HackCheckOrder[CVarI[client]]], ClientCVarCallback, client);
  846.     else
  847.         PTimer[client] = CreateTimer(GetRandomFloat(11.5, 25.8), PeriodicTimer, client, TIMER_FLAG_NO_MAPCHANGE);
  848.     return Plugin_Stop;
  849. }
  850.  
  851. #if defined SOCKET_ENABLED
  852. public Action:CheckVersion(Handle:timer, any:we)
  853. {
  854.     new Handle:socket = SocketCreate(SOCKET_TCP, OnSockErrVer);
  855.     SocketConnect(socket, OnSockConnVer, OnSockRecvVer, OnSockDiscVer, "kigen.ath.cx", 9652);
  856.     return Plugin_Stop;
  857. }
  858.  
  859. public Action:Warn(Handle:timer, any:bad)
  860. {
  861.     if ( bad )
  862.     {
  863.         PrintToAdmins("Your KAC version is out-of-date! You need to update!");
  864.         PrintToAdmins("KAC is disabled.");
  865.     }
  866.     else
  867.     {
  868.         PrintToAdmins("Your KAC version is out-of-date.  Please update as soon as possible.");
  869.     }
  870. }
  871.  
  872. public OnSockDiscVer(Handle:socket, any:we)
  873. {
  874.     CreateTimer(0.1, TKills, socket);
  875.     if ( !Checked )
  876.         CreateTimer(60.0, CheckVersion);
  877. }
  878.  
  879. public OnSockErrVer(Handle:socket, const errorType, const errorNum, any:we)
  880. {
  881.     CreateTimer(0.1, TKills, socket);
  882.     if ( !Checked )
  883.         CreateTimer(60.0, CheckVersion);
  884. }
  885.  
  886. public OnSockConnVer(Handle:socket, any:we)
  887. {
  888.     if ( !SocketIsConnected(socket) )
  889.     {
  890.         CreateTimer(0.1, TKills, socket);
  891.         CreateTimer(60.0, CheckVersion);
  892.         return;
  893.     }
  894.     new String:version[15];
  895.     Format(version, sizeof(version), "_VERSION %s", PLUGIN_VERSION);
  896.     SocketSend(socket, version, strlen(version)+1); // Send that \0!
  897.     return;
  898. }
  899.  
  900. public OnSockRecvVer(Handle:socket, String:data[], const size, any:we)
  901. {
  902.     Checked = true;
  903.     if ( StrEqual(data, "_UPTODATE") )
  904.     {
  905.         CreateTimer(10.0, CheckPlayers, INVALID_HANDLE, TIMER_REPEAT);
  906.         // PrintToAdmins("Your KAC version is up-to-date.");
  907.     }
  908.     else if ( StrEqual(data, "_OLDFINE") )
  909.     {
  910.         CreateTimer(20.0, CheckPlayers, INVALID_HANDLE, TIMER_REPEAT);
  911.         PrintToAdmins("Your KAC version is out-to-date.  You should update.");
  912.         CreateTimer(360.0, Warn, false, TIMER_REPEAT);
  913.     }
  914.     else if ( StrEqual(data, "_OLDBAD") )
  915.     {
  916.         SetConVarBool(CVar_Enable, false);
  917.         Locked = true;
  918.         Enabled = false;
  919.         CreateTimer(60.0, Warn, true, TIMER_REPEAT);
  920.     }
  921.     else
  922.         Checked = false;
  923.     CreateTimer(0.1, TKills, socket);
  924.     if ( SocketIsConnected(socket) )
  925.         SocketDisconnect(socket);
  926. }
  927.  
  928. public Action:CheckPlayers(Handle:timer, any:dsocket)
  929. {
  930.     if ( TSocket != INVALID_HANDLE )
  931.     {
  932.         CreateTimer(0.1, TKills, TSocket);
  933.         if ( SocketIsConnected(TSocket) )
  934.             SocketDisconnect(TSocket);
  935.         return Plugin_Continue;
  936.     }
  937.     for(new client=1;client<=MaxClients;client++)
  938.     {
  939.         if ( ConnState[client] != CS_AUTHED )
  940.             continue;
  941.    
  942.         new Handle:socket = SocketCreate(SOCKET_TCP, OnSocketError);
  943.         if ( socket == INVALID_HANDLE )
  944.         {
  945.             LogError("Unable to create socket.");
  946.             return Plugin_Continue;
  947.         }
  948.         TSocket = socket;
  949.         SocketSetArg(socket, client);
  950.         SocketConnect(socket, OnSocketConnect, OnSocketReceive, OnSocketDisconnect, "kigenac.ath.cx", 9652);
  951.         return Plugin_Continue;
  952.     }
  953.     return Plugin_Continue;
  954. }
  955.  
  956. public OnSocketConnect(Handle:socket, any:client)
  957. {
  958.     if ( !SocketIsConnected(socket) )
  959.     {
  960.         CreateTimer(0.1, TKills, socket);
  961.         return;
  962.     }
  963.     decl String:authString[64];
  964.     if ( ConnState[client] != CS_AUTHED || !GetClientAuthString(client, authString, 64) )
  965.     {
  966.         SocketDisconnect(socket);
  967.         CreateTimer(0.1, TKills, socket);
  968.         return;
  969.     }
  970.     SocketSend(socket, authString, strlen(authString)+1); // Send that \0! - Kigen
  971.     return;
  972. }
  973.  
  974. public Action:TKills(Handle:timer, any:socket)
  975. {
  976. #if defined SOCKET_ENABLED
  977.     if ( socket == TSocket )
  978.         TSocket = INVALID_HANDLE;
  979. #endif
  980.     if ( socket != INVALID_HANDLE )
  981.         CloseHandle(socket);
  982.     return Plugin_Stop;
  983. }
  984.  
  985. public OnSocketDisconnect(Handle:socket, any:client)
  986. {
  987.     if ( socket == INVALID_HANDLE )
  988.         return;
  989.  
  990.     if ( SocketIsConnected(socket) ) // Why it would be like this is beyond me.  But there isn't threading safety.
  991.         SocketDisconnect(socket);
  992.  
  993.     CreateTimer(0.1, TKills, socket);
  994.     return;
  995. }
  996.  
  997. public OnSocketReceive(Handle:socket, String:data[], const size, any:client)
  998. {
  999.     if ( socket == INVALID_HANDLE || ConnState[client] != CS_AUTHED )
  1000.         return;
  1001.  
  1002.     decl String:authString[64], String:name[64], String:buff[256];
  1003.     GetClientAuthString(client, authString, 64);
  1004.     GetClientName(client, name, 64);
  1005.     ConnState[client] = CS_VALIDATED;
  1006.     if ( StrEqual(data, "_BAN") )
  1007.     {
  1008.         FormatEx(buff, 256, "%s (%s) is on the KAC global banlist.", name, authString);
  1009.         PrintToAdmins(buff);
  1010.         KACLog(buff);
  1011.         strcopy(g_Reason[client], 512, "You have been banned from all KAC secured servers for a cheating infraction.  See http://www.kigenac.com/ for more information");
  1012.         PushArrayString(CacheAuthArray, authString);
  1013.         PushArrayString(CacheReasonArray, g_Reason[client]);
  1014.         CreateTimer(0.1, KickThem, client);
  1015.     }
  1016.     else if ( StrEqual(data, "_CAFE") )
  1017.     {
  1018.         if ( !GetConVarBool(CVar_BanCafe) )
  1019.             return;
  1020.         FormatEx(buff, 256, "%s (%s) is on the KAC Cafe List.", name, authString);
  1021.         PrintToAdmins(buff);
  1022.         KACLog(buff);
  1023.         strcopy(g_Reason[client], 512, "This KAC protected server does not allow Cafe Accounts.  See http://www.kigenac.com/ for more information and possible whitelisting.");
  1024.         PushArrayString(CacheAuthArray, authString);
  1025.         PushArrayString(CacheReasonArray, g_Reason[client]);
  1026.         CreateTimer(0.1, KickThem, client);
  1027.     }
  1028.     else if ( StrEqual(data, "_OK") )
  1029.     {
  1030.         // sigh here.
  1031.     }
  1032.     else
  1033.     {
  1034.         ConnState[client] = CS_AUTHED;
  1035.         FormatEx(buff, 256, "%s (%s) got unknown reply from KAC master server. Data: %s", name, authString, data);
  1036.         PrintToAdmins(buff);
  1037.         KACLog(buff);
  1038.     }
  1039. //  CreateTimer(0.1, TKills, socket);
  1040.     if ( SocketIsConnected(socket) )
  1041.         SocketDisconnect(socket);
  1042. }
  1043.  
  1044. public OnSocketError(Handle:socket, const errorType, const errorNum, any:client)
  1045. {
  1046.     if ( socket == INVALID_HANDLE )
  1047.         return;
  1048.  
  1049.     // LogError("Socket Error: eT: %d, eN, %d, c, %d", errorType, errorNum, client);
  1050.     CreateTimer(0.1, TKills, socket);
  1051. }
  1052. #endif
  1053.  
  1054. public Action:TimedBan(Handle:timer, any:userid)
  1055. {
  1056.     new client = GetClientOfUserId(userid);
  1057.     if (!client || !IsClientConnected(client) || IsClientInKickQueue(client))
  1058.         return Plugin_Stop;
  1059.  
  1060.     decl String:name[64];
  1061.     GetClientName(client, name, 64);
  1062.     PrintToChatAll("%s was banned by KAC for a cheating infraction.", name);
  1063.     PrintToAdmins(g_Reason2[client]);
  1064.     KACBan(client, 0, g_Reason[client], "You have been banned for a cheating infraction");
  1065.     CreateTimer(GetRandomFloat(4.5, 30.4), TimedBan2, userid, TIMER_FLAG_NO_MAPCHANGE); // Make sure they're gone.
  1066.     return Plugin_Stop;
  1067. }
  1068.  
  1069. public Action:TimedBan2(Handle:timer, any:userid)
  1070. {
  1071.     new client = GetClientOfUserId(userid);
  1072.     if (!client || !IsClientConnected(client) || IsClientInKickQueue(client))
  1073.         return Plugin_Stop;
  1074.  
  1075.     BanClient(client, 0, BANFLAG_AUTO, g_Reason2[client], "You have been banned for a cheating infraction", "KAC", 0);
  1076.     CreateTimer(GetRandomFloat(4.5, 30.4), TimedBan2, userid, TIMER_FLAG_NO_MAPCHANGE);
  1077.     return Plugin_Stop;
  1078. }
  1079.  
  1080. public EnableChange(Handle:convar, const String:oldValue[], const String:newValue[])
  1081. {
  1082. #if defined SOCKET_ENABLED
  1083.     if ( Locked )
  1084.     {
  1085.         if ( GetConVarBool(convar) != Enabled )
  1086.             SetConVarBool(convar, Enabled);
  1087.         return;
  1088.     }
  1089. #endif
  1090.     if ( GetConVarBool(convar) )
  1091.     {
  1092.         if ( Enabled )
  1093.             return;
  1094.         Enabled = true;
  1095.         PrintToAdmins("KAC has been enabled.");
  1096.         SetConVarInt(CVar_Cheats, 0, true);
  1097.     }
  1098.     else
  1099.     {
  1100.         if ( !Enabled )
  1101.             return;
  1102.         Enabled = false;
  1103.         PrintToAdmins("KAC has been disabled.");
  1104.     }
  1105. }
  1106.  
  1107. public CmdSpamChange(Handle:convar, const String:oldValue[], const String:newValue[])
  1108. {
  1109.     new int = GetConVarInt(convar);
  1110.     cmdspam = int;
  1111. }
  1112.  
  1113. // Base Fun Votes (sm_votegravity) and other things like it don't properly replicated values like they should. -.-
  1114. public ReplicateConVar(Handle:convar, String:oldValue[], String:newValue[])
  1115. {
  1116.     if ( StrEqual(oldValue, newValue) ) // No Change.
  1117.         return;
  1118.     decl String:name[64], cvarid;
  1119.     cvarid = -1;
  1120.     GetConVarName(convar, name, sizeof(name));
  1121.     for( new i=0;i<MAX_HACKCVAR;i++)
  1122.         if ( StrEqual(g_HackCVars[i], name) )
  1123.         {
  1124.             cvarid = i;
  1125.             break;
  1126.         }
  1127.     if ( cvarid != -1 )
  1128.     {
  1129.         if ( g_HackCVarUseTHandle[cvarid] != INVALID_HANDLE )
  1130.             CloseHandle(g_HackCVarUseTHandle[cvarid]);
  1131.         g_HackCVarUseTHandle[cvarid] = CreateTimer(0.5, CVarUseTimer, cvarid);
  1132.     }
  1133.     if ( Enabled && convar == CVar_Cheats )
  1134.         CreateTimer(0.1, SetSvCheats);
  1135.     else
  1136.         for(new i=1;i<=MaxClients;i++)
  1137.             if ( IsClientConnected(i) && !IsFakeClient(i) )
  1138.                 SendConVarValue(i, convar, newValue);
  1139. }
  1140.  
  1141. public Action:SetSvCheats(Handle:timer, any:na)
  1142. {
  1143.     SetConVarInt(CVar_Cheats, 0, true, false); // For some reason a setting conflict occurs if I don't delay by 0.1 seconds on sv_cheats. - Kigen
  1144.     for(new i=1;i<=MaxClients;i++)
  1145.         if ( IsClientConnected(i) && !IsFakeClient(i) )
  1146.             SendConVarValue(i, CVar_Cheats, "0");
  1147.     return Plugin_Stop;
  1148. }
  1149.  
  1150. public Action:CVarUseTimer(Handle:timer, any:cvarid)
  1151. {
  1152.     g_HackCVarUseTHandle[cvarid] = INVALID_HANDLE;
  1153.     return Plugin_Stop;
  1154. }
  1155.  
  1156. // param 2 (client) is always passing the client that returned the cookie, does not pass anything else
  1157. public ClientCVarCallback(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
  1158. {
  1159.     if ( !client || !IsClientConnected(client) || IsFakeClient(client) )
  1160.         return;
  1161.     decl String:name[64], Handle:cvar, cvarid, bool:continuechecks, String:authString[64], ComparisonID, CompTest, Float:clientValue, Float:serverValue, len;
  1162.     ComparisonID = 0;
  1163.     continuechecks = true;
  1164.     cvarid = g_HackCheckOrder[CVarI[client]];
  1165.     GetClientName(client, name, 64);
  1166.     if ( strcmp(g_HackCVars[cvarid], cvarName) != 0 ) // Lets go ahead and make use of this call.
  1167.     {
  1168.         decl String:buff[256];
  1169.         GetClientAuthString(client, authString, 64);
  1170.         FormatEx(buff, 256, "Cvar out of sync: %s (%s) on %s (%s) is %s", g_HackCVars[cvarid], cvarName, name, authString, cvarValue);
  1171.         KACLog(buff);
  1172.         for(new i=0;i<MAX_HACKCVAR;i++)
  1173.         {
  1174.             if ( StrEqual(g_HackCVars[i], cvarName) )
  1175.             {
  1176.                 cvarid = i;
  1177.                 continuechecks = false;
  1178.                 break;
  1179.             }
  1180.         }
  1181.         if ( continuechecks ) // CVar not found, weird.  Possible corrupted client. - Kigen
  1182.         {
  1183.             decl String:reason[255];
  1184.             GetClientAuthString(client, authString, 64);
  1185.             FormatEx(g_Reason[client], 512, "Your game's memory has become corrupted.  Please restart your game client");
  1186.             FormatEx(reason, 255, "Corrupted CVar response! %s (%s) was kicked for returning a invalid CVar. (cvar expected %s; had \"%s\" set to \"%s\").", name, authString, g_HackCVars[cvarid], cvarName, cvarValue);
  1187.             KACLog(reason);
  1188.             CreateTimer(0.1, KickThem, client);
  1189.             return;
  1190.         }
  1191.     }
  1192.     cvar = g_HackCVarHandles[cvarid];
  1193.     if ( Enabled && g_HackCVarUseTHandle[cvarid] == INVALID_HANDLE )
  1194.     {
  1195.         CompTest = g_HackCVarsComp[cvarid];
  1196.         if ( CompTest != COMP_NONEXIST )
  1197.         {
  1198.             len = strlen(cvarValue);
  1199.             for(new i=0;i<len;i++)
  1200.             {
  1201.                 if ( !IsCharNumeric(cvarValue[i]) && cvarValue[i] != '.' )
  1202.                 {
  1203.                     decl String:reason[255];
  1204.                     GetClientAuthString(client, authString, 64);
  1205.                     FormatEx(g_Reason[client], 512, "Your game's memory has become corrupted.  Please restart your game client");
  1206.                     FormatEx(reason, 255, "Corrupted CVar response! %s (%s) was kicked for having a corrupted value on %s (had \"%s\").", name, authString, g_HackCVars[cvarid], cvarValue);
  1207.                     KACLog(reason);
  1208.                     CreateTimer(0.1, KickThem, client);
  1209.                     return;
  1210.                 }
  1211.             }
  1212.         }
  1213.         if ( cvar != INVALID_HANDLE )
  1214.             serverValue = GetConVarFloat(cvar);
  1215.         else
  1216.             serverValue = g_HackCVarValues[cvarid];
  1217.         clientValue = StringToFloat(cvarValue);
  1218.         if ( result == ConVarQuery_Okay )
  1219.         {
  1220.             switch (CompTest) // This is actually more efficent. - Kigen
  1221.             {
  1222.                 case COMP_EQUAL:
  1223.                 {
  1224.                     if ( clientValue != serverValue )
  1225.                         ComparisonID = 5;
  1226.                 }
  1227.                 case COMP_LESS:
  1228.                 {
  1229.                     if ( clientValue > serverValue )
  1230.                         ComparisonID = 5;
  1231.                 }
  1232.                 case COMP_GREATER:
  1233.                 {
  1234.                     if ( clientValue < serverValue )
  1235.                         ComparisonID = 5;
  1236.                 }
  1237.                 case COMP_NONEXIST:
  1238.                 {
  1239.                     ComparisonID = 8;
  1240.                 }
  1241.             }
  1242.         }
  1243.         else if ( !(result == ConVarQuery_NotFound && CompTest == COMP_NONEXIST) )
  1244.             ComparisonID = 4;
  1245.     }
  1246.     if ( ComparisonID )
  1247.     {
  1248.         if ( ComparisonID == 5 && cvar == INVALID_HANDLE )
  1249.             ComparisonID++;
  1250.         decl String:reason[255], String:buff[256];
  1251.         GetClientAuthString(client, authString, 64);
  1252.         if ( ComparisonID == 4 )
  1253.             FormatEx(buff, sizeof(buff), "Bad CVar response! Client %s (%s) failed to reply properly to convar query!  %s (%s) set to %s", name, authString, cvarName, g_HackCVars[cvarid], cvarValue);
  1254.         else
  1255.             FormatEx(buff, sizeof(buff), "Bad CVar response! %s (%s) has %s (%s) set to %s", name, authString, cvarName, g_HackCVars[cvarid], cvarValue);
  1256.         KACLog(buff);
  1257.         if ( g_HackCVarsAction[cvarid] == ACTION_BAN || ComparisonID == 4 )
  1258.         {
  1259.             FormatEx(reason, 255, "%s (%s) was banned for cheating. KAC ID:%d.%d", name, authString, ComparisonID, cvarid);
  1260.             KACLog(reason);
  1261.             FormatEx(g_Reason[client], 512, "Cheating. KAC ID:%d.%d", ComparisonID, cvarid);
  1262.             CreateTimer(GetRandomFloat(2.5, 11.4), TimedBan, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);
  1263.         }
  1264.         else if ( g_HackCVarsAction[cvarid] == ACTION_KICK )
  1265.         {
  1266.             decl String:value[64];
  1267.             if ( cvar != INVALID_HANDLE )
  1268.                 GetConVarString(cvar, value, 64);
  1269.             else
  1270.                 FloatToString(g_HackCVarValues[cvarid], value, 64);
  1271.             if ( ComparisonID == 8 )
  1272.             {
  1273.                 FormatEx(g_Reason[client], 512, "You are not allowed to run plugins on this server");
  1274.                 FormatEx(reason, sizeof(reason), "%s (%s) was kicked for running a plugin %s (set to %s).", name, authString, g_HackCVars[cvarid], cvarValue);
  1275.             }
  1276.             else
  1277.             {
  1278.                 FormatEx(g_Reason[client], 512, "The cvar %s needs to be %s %s", g_HackCVars[cvarid], g_CompareString[CompTest], value);
  1279.                 FormatEx(reason, 255, "%s (%s) was kicked for having a bad value on %s (had %s).", name, authString, g_HackCVars[cvarid], cvarValue);
  1280.             }
  1281.             KACLog(reason);
  1282.             CreateTimer(0.1, KickThem, client);
  1283.         }
  1284.         strcopy(g_Reason2[client], 255, reason);
  1285.     }
  1286.     if ( continuechecks || PTimer[client] == INVALID_HANDLE )
  1287.     {
  1288.         if ( continuechecks )
  1289.             CVarI[client]++;
  1290.         if ( CVarI[client] > MAX_HACKCVAR*2 )
  1291.         {
  1292.             CVarI[client] = 0;
  1293.             PTimer[client] = CreateTimer(GetRandomFloat(43.5, 65.8), PeriodicTimer, client, TIMER_FLAG_NO_MAPCHANGE);
  1294.             return;
  1295.         }
  1296.         PTimer[client] = CreateTimer(GetRandomFloat(2.5, 7.8), PeriodicTimer, client, TIMER_FLAG_NO_MAPCHANGE);
  1297.     }
  1298. }
  1299.  
  1300. public EventNameChange(Handle:event, const String:name[], bool:dontBroadcast)
  1301. {
  1302.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  1303.     if ( !client || !IsClientConnected(client) || IsClientInKickQueue(client) || IsFakeClient(client) )
  1304.         return;
  1305.  
  1306.     decl String:oldName[64], String:newName[64], String:PlayerName[64], String:authString[64];
  1307.     GetEventString(event, "oldname", oldName, sizeof(oldName));
  1308.     GetEventString(event, "newname", newName, sizeof(newName));
  1309.     if ( !GetClientAuthString(client, authString, 64) )
  1310.         strcopy(authString, 64, "STEAM_ID_PENDING");
  1311.     if ( strlen(newName) < 1 )
  1312.     {
  1313.         decl String:reason[255]; // String:authString[64],
  1314.         // GetClientAuthString(client, authString, 64);
  1315.         FormatEx(reason, sizeof(reason), "%s (%s) was banned for attempting to name hack. KAC ID:2", oldName, authString);
  1316.         KACLog(reason);
  1317.         KACBan(client, 0, "Banned for name exploit. KAC ID:2", "You have been banned for name exploiting");
  1318.         PrintToAdmins(reason);
  1319.         return;
  1320.     }
  1321.  
  1322.     if ( GetConVarBool(CVar_BlockMultiByte) )
  1323.     {
  1324.         decl len;
  1325.         len = strlen(newName);
  1326.         for(new i=0;i<len;i++)
  1327.         {
  1328.             if ( IsCharMB(newName[i]) )
  1329.             {
  1330.                 decl String:reason[255];
  1331.                 FormatEx(reason, 255, "%s was kicked from the server for having a multibyte character (UTF) in their name.", name);
  1332.                 KACLog(reason);
  1333.                 PrintToAdmins(reason);
  1334.                 strcopy(g_Reason[client], 512, "You were kicked from this server for having a multibyte character (UTF) in your name");
  1335.                 CreateTimer(0.1, KickThem, client);
  1336.                 return;
  1337.             }
  1338.         }
  1339.     }
  1340.  
  1341.     if ( StrContains(newName, "Â ") != -1 )
  1342.     {
  1343.         decl String:reason[255];
  1344.         FormatEx(reason, sizeof(reason), "%s (%s) was kicked for invalid character in their name.", newName, authString);
  1345.         KACLog(reason);
  1346.         PrintToAdmins(reason);
  1347.         strcopy(g_Reason[client], 512, "You were kicked for having a invalid character in your name");
  1348.         CreateTimer(0.1, KickThem, client);
  1349.         return;
  1350.     }
  1351.  
  1352.     if ( !GetConVarBool(CVar_BlockNameCopy) )
  1353.         return;
  1354.  
  1355.     // Why the kick/ban?  Why not block?  Answer: Cheats mess up the way things are handled, thus not always promising that a return Plugin_Handled will do the job.
  1356.     if ( strlen(newName) <= 3 )
  1357.     {
  1358.         strcopy(g_Reason[client], 512, "Your name is too short, please come back with a longer name");
  1359.         CreateTimer(0.1, KickThem, client);
  1360.     }
  1361.     else
  1362.     {
  1363.         for(new i=1;i<=MaxClients;i++)
  1364.         {
  1365.             if (IsClientConnected(i) && client != i)
  1366.             {
  1367.                 decl diff;
  1368.                 GetClientName(i, PlayerName, 64);
  1369.                 diff = CmpString(PlayerName, newName);
  1370.                 if ( strlen(PlayerName) > 3 && diff < 2 )
  1371.                 {
  1372.                     decl String:authString2[64], String:reason[255];
  1373.                     if ( !GetClientAuthString(i, authString2, 64) )
  1374.                         strcopy(authString2, 64, "STEAM_ID_PENDING");
  1375.                     FormatEx(reason, 255, "%s (%s) was banned for attempting to name copy on %s (%s). KAC ID:1 Diff: %d NewName: %s", oldName, authString, PlayerName, authString2, diff, newName);
  1376.                     KACLog(reason);
  1377.                     PrintToAdmins(reason);
  1378.                     KACBan(client, 5, "Banned for name copying. KAC ID:1", "You have been banned for name copying");
  1379.                     return;
  1380.                 }
  1381.             }
  1382.         }
  1383.     }
  1384. }
  1385.  
  1386.  
  1387. /* Private KAC functions */
  1388.  
  1389. /*
  1390.  * CreateNewCheckOrder()
  1391.  * Description: Creates a new convar checking order.  Used to prevent guessing when a check on a specific convar is going to happen.
  1392.  */
  1393. CreateNewCheckOrder()
  1394. {
  1395.     new temp, bool:done = false, test;
  1396.     for(new i=0;i<MAX_HACKCVAR+1;i++)
  1397.     {
  1398.         done = false;
  1399.         while (!done)
  1400.         {
  1401.             if ( i < 8 ) // 0 1 2 3 4 5 6 7
  1402.                 temp = GetRandomInt(34, 41); // Check for third-party plugins plus mat_dxlevel.  Come on VALVe. -.-
  1403.             else if ( i < 12 ) // 8 9 10 11
  1404.                 temp = GetRandomInt(13, 16); // Check sv_cheats and sv_consistency first.  They're common to be on the blatant cheaters.
  1405.             else
  1406.                 temp = GetRandomInt(0, MAX_HACKCVAR);
  1407.             done = true;
  1408.             for(new t=0;t<i;t++)
  1409.                 if ( g_HackCheckOrder[t] == temp )
  1410.                     done = false;
  1411.         }
  1412.         g_HackCheckOrder[i] = temp;
  1413.     }
  1414.     test = MAX_HACKCVAR*2+1;
  1415.     for(new i=MAX_HACKCVAR+1;i<test;i++)
  1416.     {
  1417.         done = false;
  1418.         while (!done)
  1419.         {
  1420.             temp = GetRandomInt(0, MAX_HACKCVAR);
  1421.             done = true;
  1422.             for(new t=MAX_HACKCVAR+1;t<i;t++)
  1423.                 if ( g_HackCheckOrder[t] == temp )
  1424.                     done = false;
  1425.         }
  1426.         g_HackCheckOrder[i] = temp;
  1427.     }
  1428. }
  1429.  
  1430. /*
  1431.  * KACLog(String:log[])
  1432.  * log: String to log.
  1433.  * Description: Logs actions to KAC log and SourceMod logs.
  1434.  */
  1435. KACLog(String:log[])
  1436. {
  1437.     LogMessage("%s", log);
  1438.     decl String:path[256];
  1439.     BuildPath(Path_SM, path, 256, "logs/KAC.log");
  1440.     LogToFileEx(path, "%s", log); // Use Ex since we should be the only ones logging.
  1441. }
  1442.  
  1443. KACBan(client, time, String:IReason[], String:EReason[])
  1444. {
  1445.     if ( ConnState[client] == CS_BANNING || !IsClientConnected(client) || IsFakeClient(client) || IsClientInKickQueue(client) )
  1446.         return;
  1447.     ConnState[client] = CS_BANNING;
  1448.     decl String:authString[64], Handle:t_ConVar, bool:test;
  1449.     test = GetClientAuthString(client, authString, 64);
  1450.     if ( !test || StrEqual(authString, "STEAM_ID_LAN") )
  1451.     {
  1452.         BanClient(client, time, BANFLAG_IP, IReason, EReason, "KAC", 0);
  1453.         return;
  1454.     }
  1455.     else
  1456.     {
  1457.         t_ConVar = FindConVar("sb_version");
  1458.         if ( t_ConVar != INVALID_HANDLE )
  1459.         {
  1460.             ServerCommand("sm_ban #%d %d \"%s\"", GetClientUserId(client), time, IReason);
  1461.             CloseHandle(t_ConVar);
  1462.             return;
  1463.         }
  1464.         t_ConVar = FindConVar("mysql_bans_version");
  1465.         if ( t_ConVar != INVALID_HANDLE )
  1466.         {
  1467.             ServerCommand("mysql_ban #%d %d %s", GetClientUserId(client), time, IReason);
  1468.             CloseHandle(t_ConVar);
  1469.             return;
  1470.         }
  1471.         BanClient(client, time, BANFLAG_AUTO, IReason, EReason, "KAC", 0);
  1472.     }
  1473.     return;
  1474.    
  1475. }
  1476.  
  1477. /*
  1478.  * PrintToAdmins(String:text[])
  1479.  * text: String to display to all admins.
  1480.  * Description: Prints text to all admins on the server.
  1481.  */
  1482. PrintToAdmins(String:text[])
  1483. {
  1484.     for(new i=1;i<=MaxClients;i++)
  1485.         if ( IsClientInGame(i) && (GetUserFlagBits(i) & ADMFLAG_BAN) )
  1486.             PrintToChat(i, "KAC: %s", text);
  1487. #if defined SOCKET_ENABLED
  1488.     if ( HasIRC )
  1489.     {
  1490.         decl String:ircChan[64];
  1491.         GetConVarString(CVar_IRCChan, ircChan, 64);
  1492.         if ( strlen(ircChan) > 0 )
  1493.             IRC_PrivMsg(ircChan, "KAC: %s", text);
  1494.     }
  1495. #endif
  1496. }
  1497.  
  1498. /*
  1499.  * CmpString(String:str1[], String:str2[])
  1500.  * str1: First String to Compare.
  1501.  * str2: Second String to Compare.
  1502.  * Returns difference.
  1503.  * Counts the number of differences between two strings.
  1504.  */
  1505. CmpString(String:str1[], String:str2[])
  1506. {
  1507.     decl len, diff;
  1508.     diff = 0;
  1509.     len = strlen(str1);
  1510.     if ( len > strlen(str2) )
  1511.         len = strlen(str2);
  1512.  
  1513.     for(new i=0;i<len;i++)
  1514.     {
  1515.         if ( str1[i] != str2[i] )
  1516.             diff++;
  1517.     }
  1518.     return diff;
  1519. }
  1520.  
  1521. /*
  1522.  * KillTimers(client)
  1523.  * client: Client Index number.
  1524.  * Description: Kills all active KAC timers on client.
  1525.  */
  1526. KillTimers(client)
  1527. {
  1528.     decl Handle:t_PTimer;
  1529.     t_PTimer = PTimer[client];
  1530.     PTimer[client] = INVALID_HANDLE;
  1531.  
  1532.     if ( t_PTimer != INVALID_HANDLE )
  1533.         CloseHandle(t_PTimer);
  1534. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement