Advertisement
Guest User

Untitled

a guest
Aug 21st, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 117.27 KB | None | 0 0
  1. /* [CS:S/CS:GO] CT Bans
  2. Copyright (C) 2011-2017 by databomb
  3.  
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16.  
  17. ***************************************************************************
  18.  
  19. Description:
  20. Allows admins to restrict access to the CT team from those who violate the server's rules. Designed for specific usage in Jailbreak environments.
  21.  
  22. Features:
  23. - CT Bans are stored in the ClientPrefs database and survive map changes, re-joins, and server crashes.
  24. - The Rage Ban feature allows admins to CT ban rage quitters who break the server's rules and then quickly disconnect.
  25. - You may give a timed CT ban which will work based on in minutes spent alive (so idlers in spectate or those who suicide at the beginning of the round will not be working toward an unban.)
  26. - The timed CT bans are stored in a SQL table for stateful access.
  27. - The plugin logs CT ban to a SQL table in addition to your regular SM logs.
  28. - Re-displays the team selection screen after an improper selection was made.
  29. - SM Menu integration for the rageban and ctban commands.
  30. - Displays helpful message to users who are CT banned when they join the server.
  31. - SM Translations support.
  32. - Custom reasons permitted (configs/ctban_reasons.ini).
  33. - Custom lengths permitted (configs/ctban_times.ini).
  34.  
  35. Installation:
  36. Place the ctban.phrases.txt file in your addons/sourcemod/translations directory.
  37. Place the sm_ctban.smx file in your addons/sourcemod/plugins directory.
  38. Check your logs/server-console after the initial load for any SQL errors. If you have any SQL errors check your addons/sourcemod/configs/databases.cfg file and verify you can connect using the drivers you have specified.
  39. Upgrade: Delete cfg/sourcemod/ctban.cfg and re-configure convars after the file is re-created.
  40. Optional: Generate custom reasons list by creating a simple text file (addons/sourcemod/configs/ctban_reasons.ini) with 1 reason per line.
  41.  
  42. Command Usage:
  43.  
  44. sm_ctban <player> <time> <optional: reason>
  45. Bans the selected player from joining the CT team.
  46.  
  47. sm_removectban <player> | sm_unctban <player>
  48. Removes the CT ban on the selected player.
  49.  
  50. sm_isbanned <player>
  51. Reports back the status of the current player's CT ban and the time remaining on the ban, if any.
  52.  
  53. sm_rageban
  54. Brings up a menu so you may choose a recently disconnected player to permanently CT ban.
  55.  
  56. sm_ctban_offline <steamid>
  57. Bans the given Steam Id from playing on the CT team.
  58.  
  59. sm_removectban_offline <steamid> | sm_unctban_offline <steamid>
  60. Unbans the given Steam Id from the CT team.
  61.  
  62. sm_reset_ctban_cookies <'force'>
  63. Resets the entire CTBan cookie database.
  64.  
  65. sm_forcect <player>
  66. Overrides any CTBans and swaps a player to CT team.
  67.  
  68. sm_unforcect <player>
  69. Removes overrides and moves player to T team.
  70.  
  71. sm_isbanned_offline <steamid>
  72. Reports back the status of the target Steam Id from the ban database.
  73.  
  74. sm_change_ctban_time <player> <time>
  75. Changes an existing CTBan to the new time specified. 0 would be permanently CTBan.
  76.  
  77. sm_ctbanlist
  78. Displays a menu of active players who are CT Banned.
  79.  
  80. Settings:
  81. sm_ctban_soundfile, <path>: The path to the soundfile to play when denying a team-change request. Set to "" to disable.
  82. sm_ctban_joinbanmsg, <message>: This message is appended to a time-stamp when a CT banned user joins the server.
  83. sm_ctban_table_prefix, <prefix>: This prefix will be added in front of the table names.
  84. sm_ctban_database_driver, <driver>: This specifies which driver to use from database.cfg
  85. sm_ctban_force_reason, [0,1]: Specifies whether a reason is required for the CT Ban command.
  86. sm_ctban_checkctbans_adminflags, [a-z]: Specifies the admin flag levels that may use the !ctbanlist and !isbanned command targeting anyone. Blank allows all players access on everyone.
  87. sm_ctban_isbanned_selftarget, [0,1]: Specifies whether a non-admin can target themselves using the !isbanned command.
  88. sm_ctban_respawn, [0,1]: Specifies whether to respawn players after team changes.
  89.  
  90. Special Thanks (Development):
  91. Azelphur for snippets of cross-mod code.
  92. Kigen for the idea of CT banning based on time spent alive.
  93. oaaron99 for the idea of smart !ctban menu re-directs.
  94. Bara for include file ideas and lengths code.
  95.  
  96. Future Considerations:
  97. Using API-- Steam Group CTBans
  98. Using API-- New Admin Level and Command for CT Banning for Only Small Durations
  99.  
  100. Change Log:
  101. 2.0.3 Adds !rageban console user support. Fixed bug where !rageban was not permanent. Fixed bug with custom times (configs/ctban_times.ini) not displaying menu options correctly.
  102. Adds multi-targeting filters for other admin commands: @ctban @!ctban and @noctbans (@noctbans specifies players who have never had a CT Ban).
  103. 2.0.2 Adds SQLite support. Updated include file: Adds more intelligent #tryinclude and pre-compile directives.
  104. Alerts admins if someone is swapped to CT without !forcect. Added custom times options (configs/ctban_times.ini).
  105. Times file should be formatted as a Key Values file with each section having the number of minutes and a description such as: "90" "1 Hour 30 Minutes"
  106. 2.0.1 Bug fixes in UnForceCT, ForceCT, and OnClientAuthorized which were each generating errors.
  107. 2.0.0 Ported to the new syntax. Translation file updated. CS:GO Fixes bug where mp_force_pick_time could assign a banned player to CT. Made !ctban open menus if more info is needed.
  108. CS:GO Fixes incompatibility with Zephyrus's Team Limit Bypass plugin. Adds spawn check to verify CTBans. Added !forcect/!unforcect to override CTBan and swap players.
  109. Allows custom reasons (configs/ctban_reasons.ini). Allows non-admins to use !isbanned. Added command to reset all CT Ban cookies. Added Player Commands menu for !unctban.
  110. Adds CT Ban to !admin Player Commands menu. Allowed fallback for !isbanned to return ban info even if database log entries were missing. Added !ctbanlist command.
  111. Added CT Ban reason to !ctban chat output where possible. Changed from [SM] to [CTBAN] chat tag and added colors. Removing compile option USESQL (Now Always Uses SQL).
  112. Added !isbanned_offline to find CT Ban info of offline players. !ctban_offline and !unctban_offline now update the log database records.
  113. Added convar sm_ctban_respawn to allow respawns after team swaps due to !ctban or !forcect. Added !change_ctban_time command to edit the time remaining on CTBans.
  114. Added API (ctban.inc) for 3rd-party plugin interfaces. The convar sm_ctban_enable is being removed (disable the plugin to disable functionality).
  115. Upgraded database log table to include an auto incrementing primary key (ban_id) -- automatically upgrades from tables.
  116. Added check for enforcing CTBans if the plugin is loaded late.
  117. 1.6.2 Translation file updated. Added admin, time, reason information for !isbanned. Show !rageban results in chat to players. Added ConVar for forcing !ctban reason.
  118. 1.6.1.4 Fixed bug preventing console CT bans (thanks Kailo!)
  119. 1.6.1.3 Fixed bug with EscapeString function which caused query failures
  120. 1.6.1.2 Fixed SQL Injection vulnerability
  121. 1.6.1.1 Fixed problem in UTIL_TeamMenu()
  122. 1.6.1 Support for new SM1.4 natives, Added config file generation
  123. 1.6.0 Added support for new SM1.4 natives
  124. 1.5.0 Initial public release
  125. 1.4.4 Stable internal build
  126. */
  127.  
  128. // Compilation Settings
  129. //#define CTBAN_DEBUG
  130.  
  131. #define PLUGIN_VERSION "2.0.3"
  132.  
  133. #include <sourcemod>
  134. #include <clientprefs>
  135. #include <sdktools>
  136. #include <adminmenu>
  137. #include <cstrike>
  138. #include <multicolors>
  139. #include <multicolors/morecolors>
  140. #include <multicolors/colors>
  141.  
  142. #tryinclude <hosties>
  143. #tryinclude <ctban>
  144.  
  145. #if !defined _CTBan_Included_
  146.  
  147. // Common constant verifications
  148. #if !defined INVALID_WEAPON
  149. #define INVALID_WEAPON -1
  150. #else
  151. #assert INVALID_WEAPON == -1
  152. #endif
  153. #if !defined ZERO
  154. #define ZERO 0
  155. #else
  156. #assert ZERO == 0
  157. #endif
  158. #if !defined ONE
  159. #define ONE 1
  160. #else
  161. #assert ONE == 1
  162. #endif
  163. #if !defined TWO 2
  164. #define TWO 2
  165. #else
  166. #assert TWO == 2
  167. #endif
  168. #if !defined THREE
  169. #define THREE 3
  170. #else
  171. #assert THREE == 3
  172. #endif
  173. #if !defined FOUR
  174. #define FOUR 4
  175. #else
  176. #assert FOUR == 4
  177. #endif
  178. #if !defined FIVE
  179. #define FIVE 5
  180. #else
  181. #assert FIVE == 5
  182. #endif
  183. #if !defined SIX
  184. #define SIX 6
  185. #else
  186. #assert SIX == 6
  187. #endif
  188. #if !defined SEVEN
  189. #define SEVEN 7
  190. #else
  191. #assert SEVEN == 7
  192. #endif
  193.  
  194. // General constants
  195. #define VALUE_NOT_FOUND_IN_ARRAY -1
  196. #define SUBSTRING_NOT_FOUND -1
  197. #define RAGEBAN_ADMIN_LEVEL ADMFLAG_SLAY
  198. #define CTBAN_ADMIN_LEVEL ADMFLAG_SLAY
  199. #define UNCTBAN_ADMIN_LEVEL ADMFLAG_SLAY
  200. #define FORCECT_ADMIN_LEVEL ADMFLAG_SLAY
  201. #define UNFORCECT_ADMIN_LEVEL ADMFLAG_SLAY
  202. #define JOINFAILREASON_ONECHANGE 0
  203. #define MENUCHOICE_USERID 0
  204. #define MENUCHOICE_TIME 1
  205. #define CALLER_NATIVE -2
  206. #define COOKIE_BANNED_STRING "1"
  207. #define COOKIE_UNBANNED_STRING "0"
  208. #define ARG_ZERO_GET_COMMAND_NAME 0
  209. #define FORCECT_ARG_TARGET 1
  210. #define UNFORCECT_ARG_TARGET 1
  211. #define ISBANNED_ARG_TARGET 1
  212. #define CTBAN_ARG_PLAYER 1
  213. #define CTBAN_ARG_TIME 2
  214. #define CTBAN_ARG_REASON 3
  215. #define CTBAN_NO_REASON_GIVEN -1
  216. #define CTBAN_PERM_BAN_LENGTH 0
  217. #define RAGEBAN_ARG_CONSOLE_TARGET 1
  218. #define UNCTBAN_ARG_TARGET 1
  219. #define CHANGE_TIME_ARG_TARGET 1
  220. #define CHANGE_TIME_ARG_TIME 2
  221. #define JOINTEAM_ARG_TEAM_STRING 1
  222. #define CLIENT_DISCONNECT_CB_FIELD_TIMELEFT 0
  223. #define FIND_COOKIE_CB_FIELD_COOKIE_ID 0
  224. #define CLIENT_AUTHED_CB_FIELD_TIMELEFT 0
  225. #define ISBANNED_CB_FIELD_TIMESTAMP 0
  226. #define ISBANNED_CB_FIELD_ADMINNAME 1
  227. #define ISBANNED_CB_FIELD_REASON 2
  228. #define ISBANNED_OFF_CB_FIELD_TIMESTAMP 0
  229. #define ISBANNED_OFF_CB_FIELD_ADMINNAME 1
  230. #define ISBANNED_OFF_CB_FIELD_REASON 2
  231. #define ISBANNED_OFF_CB_FIELD_TIMELEFT 3
  232. #define ISBANNED_OFF_CB_FIELD_PERPNAME 4
  233. #define NATIVE_ISBANNED_CELL_CLIENT 1
  234. #define NATIVE_GET_TIMELEFT_CELL_CLIENT 1
  235. #define NATIVE_GET_OVERRIDE_CELL_CLIENT 1
  236. #define NATIVE_GETBANINFO_CELL_CLIENT 1
  237. #define NATIVE_GETBANINFO_OFF_STR_AUTHID 1
  238. #define NATIVE_CTBAN_CELL_CLIENT 1
  239. #define NATIVE_CTBAN_CELL_TIME 2
  240. #define NATIVE_CTBAN_CELL_ADMIN 3
  241. #define NATIVE_CTBAN_STR_REASON 4
  242. #define NATIVE_CTBAN_OFF_STR_AUTHID 1
  243. #define NATIVE_CHANGE_TIME_CELL_CLIENT 1
  244. #define NATIVE_CHANGE_TIME_CELL_TIME 2
  245. #define NATIVE_CHANGE_TIME_CELL_ADMIN 3
  246. #define NATIVE_UNBAN_CELL_CLIENT 1
  247. #define NATIVE_UNBAN_CELL_ADMIN 2
  248. #define NATIVE_UNBAN_OFF_STR_AUTHID 1
  249. #define NATIVE_FORCECT_CELL_CLIENT 1
  250. #define NATIVE_FORCECT_CELL_ADMIN 2
  251. #define NATIVE_UNFORCECT_CELL_CLIENT 1
  252. #define NATIVE_UNFORCECT_CELL_ADMIN 2
  253. #define NATIVE_MIN_AUTHID_LENGTH 3
  254. #define FIELD_AUTHID_MAXLENGTH 22
  255. #define FIELD_NAME_MAXLENGTH 32
  256. #define FIELD_REASON_MAXLENGTH 200
  257. #define QUERY_MAXLENGTH 350
  258. #define COOKIE_INIT_CHECK_TIME 0.0
  259. #define COOKIE_RESCAN_TIME 5.0
  260. #define DELAY_ENFORCEMENT_TIME 1.8
  261. #define AUTH_RESCAN_TIME 4.0
  262. #define DECREMENT_TIMEBAN_INTERVAL 60.0
  263. #define PLAY_COMMAND_STRING "play "
  264. #define PLAY_COMMAND_STRING_LENGTH 5
  265. #define CSGO_MAX_PAGE_MENU_ITEMS 6
  266. #define CSS_MAX_PAGE_MENU_ITEMS 7
  267. #define CTBAN_COMMAND "sm_ctban"
  268. #define REMOVECTBAN_COMMAND "sm_removectban"
  269. #define RAGEBAN_COMMAND "sm_rageban"
  270. #define FORCECT_COMMAND "sm_forcect"
  271. #define UNFORCECT_COMMAND "sm_unforcect"
  272. #define MAX_UNBAN_CMD_LENGTH 16
  273. #define MAX_TABLE_LENGTH 32
  274. #define MAX_DEFAULT_TABLE_LENGTH 12
  275. #define MAX_CHAT_BANNER_LENGTH 36
  276. #define MAX_RESET_ARG_LENGTH 10
  277. #define MAX_USERID_LENGTH 32
  278. #define MAX_COOKIE_STR_LENGTH 7
  279. #define MAX_JOINTEAM_ARG_LENGTH 5
  280. #define MAX_TIME_ARG_LENGTH 32
  281. #define MAX_TIME_INFO_STR_LENGTH 150
  282. #define MAX_JOIN_BAN_MSG_LENGTH 100
  283. #define MAX_ADMINFLAGS_LENGTH 27
  284. #define MAX_REASON_MENU_CHOICE_LENGTH 10
  285. #define MAX_MENU_INT_CHOICE_LENGTH 4
  286. #define MAX_DATABASE_ID_LENGTH 7
  287. #define CTBAN_ADMIN_IS_CONSOLE 0
  288. #define CONSOLE_USER_NAME "Console"
  289. #define CONSOLE_AUTHID "STEAM_0:1:1"
  290. #define RAGEBAN_LOG_REASON "Rage ban"
  291. #define OFFLINE_NAME_UNAVAILBLE "Unavailable"
  292. #define REASON_OFFLINECTBAN "Offline AuthId Ban"
  293. #define CALLER_DO_NOT_REPLY -1
  294.  
  295. // Pre-processor macros
  296. #define MAX_SAFE_ESCAPE_QUERY(%1) (TWO*(%1)+ONE)
  297.  
  298. #endif
  299.  
  300. // SQL Queries
  301. #define CTBAN_QUERY_CP_FIND_COOKIE_ID "SELECT id FROM sm_cookies WHERE name = 'Banned_From_CT'"
  302. #define CTBAN_QUERY_CP_SELECT_BAN_COOKIE "SELECT value FROM sm_cookie_cache WHERE player = '%s' and cookie_id = '%i'"
  303. #define CTBAN_QUERY_CP_RESET_COOKIES "UPDATE sm_cookie_cache SET value = '' WHERE cookie_id = '%i'"
  304.  
  305. #define CTBAN_QUERY_TIME_CREATE "CREATE TABLE IF NOT EXISTS %s (steamid VARCHAR(%d), ctbantime INT(16), PRIMARY KEY (steamid))"
  306. #define CTBAN_QUERY_TIME_SELECT_BANTIME "SELECT ctbantime FROM %s WHERE steamid = '%s'"
  307. #define CTBAN_QUERY_TIME_INSERT_SQLITE "INSERT OR REPLACE INTO %s (steamid, ctbantime) VALUES ('%s', %d)"
  308. #define CTBAN_QUERY_TIME_INSERT_MYSQL "INSERT INTO %s (steamid, ctbantime) VALUES ('%s', %d) ON DUPLICATE KEY UPDATE ctbantime=%d"
  309. #define CTBAN_QUERY_TIME_UPDATE "UPDATE %s SET ctbantime = %d WHERE steamid = '%s'"
  310. #define CTBAN_QUERY_TIME_DELETE "DELETE FROM %s WHERE steamid = '%s'"
  311.  
  312. #define CTBAN_QUERY_LOG_CREATE "CREATE TABLE IF NOT EXISTS %s (ban_id INT UNSIGNED AUTO_INCREMENT, timestamp INT, perp_steamid VARCHAR(%d), perp_name VARCHAR(%d), admin_steamid VARCHAR(%d), admin_name VARCHAR(%d), bantime INT(16), timeleft INT(16), reason VARCHAR(%d), PRIMARY KEY (ban_id))"
  313. #define CTBAN_QUERY_LOG_INSERT "INSERT INTO %s (timestamp, perp_steamid, perp_name, admin_steamid, admin_name, bantime, timeleft, reason) VALUES (%d, '%s', '%s', '%s', '%s', %d, %d, '%s')"
  314. #define CTBAN_QUERY_LOG_ISBANNED "SELECT timestamp, admin_name, reason FROM %s WHERE perp_steamid = '%s' AND timeleft >= 0 ORDER BY timestamp DESC LIMIT 1"
  315. #define CTBAN_QUERY_LOG_ISBANNED_OFFLINE "SELECT timestamp, admin_name, reason, timeleft, perp_name FROM %s WHERE perp_steamid = '%s' AND timeleft >= 0 ORDER BY timestamp DESC LIMIT 1"
  316. #define CTBAN_QUERY_LOG_EXPIRE "UPDATE %s SET timeleft=-1 WHERE perp_steamid = '%s' and timeleft >= 0"
  317. #define CTBAN_QUERY_LOG_V1_CHECK "SELECT ban_id FROM %s LIMIT 1"
  318. #define CTBAN_QUERY_LOG_TO_V2_DROPKEY "ALTER TABLE %s DROP PRIMARY KEY"
  319. #define CTBAN_QUERY_LOG_TO_V2_ADD_BANID "ALTER TABLE %s ADD ban_id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT FIRST"
  320. #define CTBAN_QUERY_LOG_UPDATE "UPDATE %s SET timeleft = %d WHERE perp_steamid = '%s' AND timeleft >= 0"
  321. #define CTBAN_QUERY_LOG_TIME_TO_PERM_MYSQL "UPDATE %s SET (bantime, timeleft) VALUES (0, 0) WHERE perp_steamid = '%s' AND timeleft > 0"
  322. #define CTBAN_QUERY_LOG_TIME_TO_PERM_SQLITE "UPDATE %s SET bantime = 0, timeleft = 0 WHERE perp_steamid = '%s' AND timeleft > 0"
  323. #define CTBAN_QUERY_LOG_PERM_TO_TIME_MYSQL "UPDATE %s SET (bantime, timeleft) VALUES (%d, %d) WHERE perp_steamid = '%s' AND timeleft = 0 AND bantime = 0"
  324. #define CTBAN_QUERY_LOG_PERM_TO_TIME_SQLITE "UPDATE %s SET bantime = %d, timeleft = %d WHERE perp_steamid = '%s' AND timeleft = 0 AND bantime = 0"
  325.  
  326. #pragma semicolon 1
  327. #pragma newdecls required
  328.  
  329. char g_sChatBanner[MAX_CHAT_BANNER_LENGTH];
  330. EngineVersion g_EngineVersion = Engine_Unknown;
  331. Handle g_CT_Cookie = INVALID_HANDLE;
  332. Handle gH_TopMenu = INVALID_HANDLE;
  333. Handle gH_Cvar_SoundName = INVALID_HANDLE;
  334. char gS_SoundPath[PLATFORM_MAX_PATH];
  335. Handle gH_Cvar_JoinBanMessage = INVALID_HANDLE;
  336. Handle gH_Cvar_Database_Driver = INVALID_HANDLE;
  337. Handle gA_DNames = INVALID_HANDLE;
  338. Handle gA_DSteamIDs = INVALID_HANDLE;
  339. Handle gH_CP_DataBase = INVALID_HANDLE;
  340. Handle gH_BanDatabase = INVALID_HANDLE;
  341. Handle gH_Cvar_Table_Prefix = INVALID_HANDLE;
  342. int g_iCookieIndex;
  343. bool g_bAuthIdNativeExists = false;
  344. Handle gA_TimedBanLocalList = INVALID_HANDLE;
  345. int gA_LocalTimeRemaining[MAXPLAYERS+ONE];
  346. char g_sLogTableName[MAX_TABLE_LENGTH];
  347. char g_sTimesTableName[MAX_TABLE_LENGTH];
  348. Handle gH_Cvar_Force_Reason = INVALID_HANDLE;
  349. Handle gH_DArray_Reasons = INVALID_HANDLE;
  350. Handle gH_KV_BanLengths = INVALID_HANDLE;
  351. Handle gH_Cvar_CheckCTBans_Flags = INVALID_HANDLE;
  352. Handle gH_Cvar_IsBanned_Self = INVALID_HANDLE;
  353. Handle gH_Cvar_Respawn = INVALID_HANDLE;
  354. bool g_bA_Temp_CTBan_Override[MAXPLAYERS+ONE];
  355. bool g_bIgnoreOverrideResets;
  356. bool g_bRageBanArrayChanged;
  357.  
  358. Handle g_hFrwd_OnForceCT = INVALID_HANDLE;
  359. Handle g_hFrwd_OnUnforceCT = INVALID_HANDLE;
  360. Handle g_hFrwd_OnCTBan_Offline = INVALID_HANDLE;
  361. Handle g_hFrwd_OnUnCTBan_Offline = INVALID_HANDLE;
  362. Handle g_hFrwd_OnCTBan = INVALID_HANDLE;
  363. Handle g_hFrwd_OnUnCTBan = INVALID_HANDLE;
  364. Handle g_hFrwd_CTBanInfo = INVALID_HANDLE;
  365. Handle g_hFrwd_CTBanInfoOffline = INVALID_HANDLE;
  366.  
  367. enum eCTBanMenuHandler
  368. {
  369. e_RemoveCTBan=ZERO,
  370. e_CTBanList=ONE,
  371. e_ForceCT=TWO
  372. }
  373.  
  374. enum eQueryCallback
  375. {
  376. e_QueryLogTableTwo=ZERO
  377. }
  378.  
  379. enum eDatabaseType
  380. {
  381. e_Unknown=ZERO,
  382. e_MySQL=ONE,
  383. e_SQLite=TWO
  384. }
  385.  
  386. eDatabaseType g_eDatabaseType = e_Unknown;
  387.  
  388. public Plugin myinfo =
  389. {
  390. name = "CT Ban",
  391. author = "databomb",
  392. description = "Allows admins to ban players from joining the CT team.",
  393. version = PLUGIN_VERSION,
  394. url = "https://forums.alliedmods.net/showthread.php?t=166080"
  395. };
  396.  
  397. public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int iErr_Max)
  398. {
  399. g_EngineVersion = GetEngineVersion();
  400.  
  401. SetCTBanChatBanner(g_EngineVersion, g_sChatBanner);
  402.  
  403. RegPluginLibrary("ctban");
  404.  
  405. CreateForwards();
  406. CreateNatives();
  407.  
  408. return APLRes_Success;
  409. }
  410.  
  411. public void OnPluginStart()
  412. {
  413. CreateConVar("sm_ctban_version", PLUGIN_VERSION, "CT Ban Version", FCVAR_SPONLY|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY);
  414. gH_Cvar_SoundName = CreateConVar("sm_ctban_soundfile", "buttons/button11.wav", "The name of the sound to play when an action is denied.", FCVAR_NONE);
  415. gH_Cvar_JoinBanMessage = CreateConVar("sm_ctban_joinbanmsg", "Contact an admin if you would like to request an unban.", "This text is appended to the time the user was last CT banned when they join T or Spectator teams.", FCVAR_NONE);
  416. gH_Cvar_Table_Prefix = CreateConVar("sm_ctban_table_prefix", "", "Adds a prefix to the CT Bans table, leave this blank unless you have a need to add a prefix for multiple servers on one database.", FCVAR_NONE);
  417. gH_Cvar_Database_Driver = CreateConVar("sm_ctban_database_driver", "default", "Specifies the configuration driver to use from SourceMod's database.cfg", FCVAR_NONE);
  418. gH_Cvar_Force_Reason = CreateConVar("sm_ctban_force_reason", "0", "Specifies whether to force admins to specify a reason when using CTBan command", FCVAR_NONE);
  419. gH_Cvar_CheckCTBans_Flags = CreateConVar("sm_ctban_checkctbans_adminflags", "bz", "The admin flag(s) that may use !isbanned command on anyone. Blank allows all players access on anyone.", FCVAR_NONE);
  420. gH_Cvar_IsBanned_Self = CreateConVar("sm_ctban_isbanned_selftarget", "0", "Specifies whether to allow non-admins to use !isbanned on themselves.", FCVAR_NONE);
  421. gH_Cvar_Respawn = CreateConVar("sm_ctban_respawn", "0", "Specifies whether players are respawned after being team changed.", FCVAR_NONE);
  422.  
  423. AutoExecConfig(true, "ctban");
  424.  
  425. g_CT_Cookie = RegClientCookie("Banned_From_CT", "Tells if you are restricted from joining the CT team", CookieAccess_Protected);
  426.  
  427. RegConsoleCmd("sm_isbanned", Command_IsBanned, "sm_isbanned <player> - Lets you know if a player is banned from CT team.");
  428. RegConsoleCmd("sm_ctbanlist", Command_CTBanList, "sm_ctbanlist - Displays a list of active players who are CT Banned.");
  429.  
  430. RegAdminCmd(CTBAN_COMMAND, Command_CTBan, CTBAN_ADMIN_LEVEL, "sm_ctban <player> <time> <optional: reason> - Bans a player from being a CT.");
  431. RegAdminCmd(REMOVECTBAN_COMMAND, Command_UnCTBan, UNCTBAN_ADMIN_LEVEL, "sm_removectban <player> - Unrestricts a player from being a CT.");
  432. RegAdminCmd("sm_unctban", Command_UnCTBan, UNCTBAN_ADMIN_LEVEL, "sm_unctban <player> - Unrestricts a player from being a CT.");
  433. RegAdminCmd(RAGEBAN_COMMAND, Command_RageBan, RAGEBAN_ADMIN_LEVEL, "sm_rageban <player> - Allows you to ban those who rage quit.");
  434. RegAdminCmd("sm_ctban_offline", Command_Offline_CTBan, ADMFLAG_KICK, "sm_ctban_offline <steamid> - Allows admins to CT Ban players who have long left the server using their Steam Id.");
  435. RegAdminCmd("sm_unctban_offline", Command_Offline_UnCTBan, ADMFLAG_KICK, "sm_unctban_offline <steamid> - Allows admins to remove CT Bans on players who have long left the server using their Steam Id.");
  436. RegAdminCmd("sm_removectban_offline", Command_Offline_UnCTBan, ADMFLAG_KICK, "sm_unctban_offline <steamid> - Allows admins to remove CT Bans on players who have long left the server using their Steam Id.");
  437. RegAdminCmd("sm_reset_ctban_cookies", Command_ResetCookies, ADMFLAG_ROOT, "sm_reset_ctban_cookies <'force'> - Allows the admin to reset all CTBan cookies to be unbanned.");
  438. RegAdminCmd(FORCECT_COMMAND, Command_ForceCT, FORCECT_ADMIN_LEVEL, "sm_forcect <player> - Temporarily overrides CTBan status and swaps player to CT team.");
  439. RegAdminCmd(UNFORCECT_COMMAND, Command_UnForceCT, UNFORCECT_ADMIN_LEVEL, "sm_unforcect <player> - Removes any temporary overrides and removes player from CT team.");
  440. RegAdminCmd("sm_isbanned_offline", Command_Offline_IsBanned, ADMFLAG_SLAY, "sm_isbanned_offline <steamid> - Allows admins to get CT Ban information on offline players user their Steam Id.");
  441. RegAdminCmd("sm_change_ctban_time", Command_Change_CTBan_Time, ADMFLAG_KICK, "sm_change_ctban_time <player> <time> - Allows the admin to change the time remaining for an existing CTBan.");
  442.  
  443. LoadTranslations("ctban.phrases");
  444. LoadTranslations("common.phrases");
  445. LoadTranslations("clientprefs.phrases");
  446. LoadTranslations("core.phrases");
  447.  
  448. // create arrays for the rage bans
  449. gA_DNames = CreateArray(MAX_TARGET_LENGTH);
  450. gA_DSteamIDs = CreateArray(22);
  451. g_iCookieIndex = ZERO;
  452.  
  453. // Hook this to block joins when player is banned
  454. AddCommandListener(Command_CheckJoin, "jointeam");
  455. // This is the only sane way to deal with CS:GO auto-assign and plugin conflicts as in CS:GO Team Limit Bypass
  456. HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post);
  457. // This will catch anyone that gets swapped manually
  458. HookEvent("player_team", Event_PlayerTeam, EventHookMode_Post);
  459.  
  460. // create local array for timed bans
  461. // block 0: client index
  462. gA_TimedBanLocalList = CreateArray(2);
  463. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  464. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  465. {
  466. gA_LocalTimeRemaining[iIndex] = ZERO;
  467.  
  468. // Check if we need to remove anyone from CT team immediately
  469. if (IsClientInGame(iIndex))
  470. {
  471. if (GetClientTeam(iIndex) == CS_TEAM_CT && GetCTBanStatus(iIndex))
  472. {
  473. EnforceCTBan(iIndex);
  474.  
  475. // Gather the time component, if needed
  476. if (IsClientAuthorized(iIndex))
  477. {
  478. GetClientAuthId(iIndex, AuthId_Steam2, sAuthID, sizeof(sAuthID));
  479. OnClientAuthorized(iIndex, sAuthID);
  480. }
  481. }
  482. }
  483. }
  484.  
  485. // periodic timer to handle timed bans
  486. CreateTimer(DECREMENT_TIMEBAN_INTERVAL, Timer_CheckTimedCTBans, _, TIMER_REPEAT);
  487.  
  488. // Account for late loading
  489. Handle hTopMenu;
  490. if (LibraryExists("adminmenu") && ((hTopMenu = GetAdminTopMenu()) != INVALID_HANDLE))
  491. {
  492. OnAdminMenuReady(hTopMenu);
  493. }
  494.  
  495. gH_DArray_Reasons = CreateArray(FIELD_REASON_MAXLENGTH);
  496.  
  497. if (g_EngineVersion == Engine_CSGO)
  498. {
  499. HookEvent("jointeam_failed", Event_JoinTeamFailed, EventHookMode_Pre);
  500. }
  501.  
  502. AddMultiTargetFilter("@ctban", Filter_CTBanned_Players, "CT Banned Players", false);
  503. AddMultiTargetFilter("@!ctban", Filter_NotCTBanned_Players, "Players without a CT Ban", false);
  504. AddMultiTargetFilter("@noctbans", Filter_NeverCTBanned_Players, "Players who have never had a CT Ban", false);
  505. }
  506.  
  507. public bool Filter_CTBanned_Players(const char[] sPattern, Handle hClients)
  508. {
  509. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  510. {
  511. if (IsClientInGame(iIndex))
  512. {
  513. if (GetCTBanStatus(iIndex))
  514. {
  515. PushArrayCell(hClients, iIndex);
  516. }
  517. }
  518. }
  519.  
  520. return true;
  521. }
  522.  
  523. public bool Filter_NotCTBanned_Players(const char[] sPattern, Handle hClients)
  524. {
  525. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  526. {
  527. if (IsClientInGame(iIndex))
  528. {
  529. if (!GetCTBanStatus(iIndex))
  530. {
  531. PushArrayCell(hClients, iIndex);
  532. }
  533. }
  534. }
  535.  
  536. return true;
  537. }
  538.  
  539. public bool Filter_NeverCTBanned_Players(const char[] sPattern, Handle hClients)
  540. {
  541. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  542. {
  543. if (IsClientInGame(iIndex))
  544. {
  545. if (AreClientCookiesCached(iIndex))
  546. {
  547. char sCookie[MAX_COOKIE_STR_LENGTH];
  548. GetClientCookie(iIndex, g_CT_Cookie, sCookie, sizeof(sCookie));
  549.  
  550. if (!strlen(sCookie))
  551. {
  552. PushArrayCell(hClients, iIndex);
  553. }
  554. }
  555. }
  556. }
  557.  
  558. return true;
  559. }
  560.  
  561. void CreateNatives()
  562. {
  563. CreateNative("CTBan_IsClientBanned", Native_IsClientBanned);
  564. CreateNative("CTBan_GetTimeRemaining", Native_GetTimeRemaining);
  565. CreateNative("CTBan_GetOverrideStatus", Native_GetOverrideStatus);
  566. CreateNative("CTBan_GetBanInfo", Native_GetBanInfo);
  567. CreateNative("CTBan_GetBanInfo_Offline", Native_GetBanInfo_Offline);
  568.  
  569. CreateNative("CTBan_Client", Native_CTBan_Client);
  570. CreateNative("CTBan_Client_Offline", Native_CTBan_Client_Offline);
  571. CreateNative("CTBan_ChangeBanLength", Native_CTBan_ChangeBanLength);
  572.  
  573. CreateNative("CTBan_UnbanClient", Native_CTBan_UnbanClient);
  574. CreateNative("CTBan_UnbanClient_Offline", Native_CTBan_UnbanClient_Offline);
  575.  
  576. CreateNative("CTBan_ForceCT", Native_CTBan_ForceCT);
  577. CreateNative("CTBan_UnForceCT", Native_CTBan_UnForceCT);
  578. }
  579.  
  580. void CreateForwards()
  581. {
  582. g_hFrwd_OnForceCT = CreateGlobalForward("CTBan_OnForceCT", ET_Ignore, Param_Cell, Param_Cell);
  583. g_hFrwd_OnUnforceCT = CreateGlobalForward("CTBan_OnUnforceCT", ET_Ignore, Param_Cell, Param_Cell);
  584.  
  585. g_hFrwd_OnCTBan = CreateGlobalForward("CTBan_OnClientBan", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_String);
  586. g_hFrwd_OnCTBan_Offline = CreateGlobalForward("CTBan_OnClientBan_Offline", ET_Ignore, Param_String, Param_Cell);
  587.  
  588. g_hFrwd_OnUnCTBan = CreateGlobalForward("CTBan_OnClientUnban", ET_Ignore, Param_Cell, Param_Cell);
  589. g_hFrwd_OnUnCTBan_Offline = CreateGlobalForward("CTBan_OnClientUnban_Offline", ET_Ignore, Param_String, Param_Cell);
  590.  
  591. g_hFrwd_CTBanInfo = CreateGlobalForward("CTBan_GetBanInfoReturn", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_String, Param_String);
  592. g_hFrwd_CTBanInfoOffline = CreateGlobalForward("CTBan_GetOfflineBanInfoReturn", ET_Ignore, Param_Cell, Param_String, Param_Cell, Param_Cell, Param_String, Param_String, Param_String);
  593. }
  594.  
  595. public int Native_IsClientBanned(Handle hPlugin, int iParams)
  596. {
  597. int iClient = GetNativeCell(NATIVE_ISBANNED_CELL_CLIENT);
  598.  
  599. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  600. {
  601. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  602. return ZERO;
  603. }
  604.  
  605. return GetCTBanStatus(iClient);
  606. }
  607.  
  608. public int Native_GetTimeRemaining(Handle hPlugin, int iParams)
  609. {
  610. int iClient = GetNativeCell(NATIVE_GET_TIMELEFT_CELL_CLIENT);
  611.  
  612. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  613. {
  614. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  615. }
  616.  
  617. return gA_LocalTimeRemaining[iClient];
  618. }
  619.  
  620. public int Native_GetOverrideStatus(Handle hPlugin, int iParams)
  621. {
  622. int iClient = GetNativeCell(NATIVE_GET_OVERRIDE_CELL_CLIENT);
  623.  
  624. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  625. {
  626. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  627. return false;
  628. }
  629.  
  630. return g_bA_Temp_CTBan_Override[iClient];
  631. }
  632.  
  633. public int Native_GetBanInfo(Handle hPlugin, int iParams)
  634. {
  635. int iClient = GetNativeCell(NATIVE_GETBANINFO_CELL_CLIENT);
  636.  
  637. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  638. {
  639. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  640. }
  641.  
  642. ProcessIsBannedTarget(iClient, CALLER_NATIVE);
  643.  
  644. return SP_ERROR_NONE;
  645. }
  646.  
  647. public int Native_GetBanInfo_Offline(Handle hPlugin, int iParams)
  648. {
  649. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  650. int iReturn = GetNativeString(NATIVE_GETBANINFO_OFF_STR_AUTHID, sAuthId, sizeof(sAuthId));
  651.  
  652. if (iReturn != SP_ERROR_NONE || strlen(sAuthId) < NATIVE_MIN_AUTHID_LENGTH)
  653. {
  654. ThrowNativeError(SP_ERROR_NATIVE, "Invalid Authid");
  655. }
  656.  
  657. if (IsAuthIdConnected(sAuthId))
  658. {
  659. ThrowNativeError(SP_ERROR_NATIVE, "AuthID currently connected.");
  660. }
  661. else
  662. {
  663. ProcessIsBannedOffline(CALLER_NATIVE, sAuthId);
  664. }
  665.  
  666. return SP_ERROR_NONE;
  667. }
  668.  
  669. public int Native_CTBan_Client(Handle hPlugin, int iParams)
  670. {
  671. int iClient = GetNativeCell(NATIVE_CTBAN_CELL_CLIENT);
  672.  
  673. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  674. {
  675. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  676. }
  677.  
  678. int iMinutes = GetNativeCell(NATIVE_CTBAN_CELL_TIME);
  679.  
  680. if (iMinutes < ZERO)
  681. {
  682. ThrowNativeError(SP_ERROR_NATIVE, "Invalid time specified (%d).", iMinutes);
  683. }
  684.  
  685. int iAdmin = GetNativeCell(NATIVE_CTBAN_CELL_ADMIN);
  686.  
  687. if (iAdmin < ZERO || iAdmin > MaxClients || (iAdmin && !IsClientInGame(iAdmin)))
  688. {
  689. ThrowNativeError(SP_ERROR_NATIVE, "Admin (%d) is invalid!", iAdmin);
  690. }
  691.  
  692. char sReason[FIELD_REASON_MAXLENGTH];
  693. int iReturn = GetNativeString(NATIVE_CTBAN_STR_REASON, sReason, sizeof(sReason));
  694.  
  695. if (iReturn != SP_ERROR_NONE)
  696. {
  697. ThrowNativeError(SP_ERROR_NATIVE, "Invalid reason string");
  698. }
  699.  
  700. if (!GetCTBanStatus(iClient))
  701. {
  702. PerformCTBan(iClient, iAdmin, iMinutes, _, sReason);
  703. }
  704. else
  705. {
  706. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Already CT Banned", iClient);
  707. }
  708.  
  709. return SP_ERROR_NONE;
  710. }
  711.  
  712. public int Native_CTBan_Client_Offline(Handle hPlugin, int iParams)
  713. {
  714. if (!g_bAuthIdNativeExists)
  715. {
  716. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Feature Not Available");
  717. }
  718.  
  719. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  720. int iReturn = GetNativeString(NATIVE_CTBAN_OFF_STR_AUTHID, sAuthId, sizeof(sAuthId));
  721.  
  722. if (iReturn != SP_ERROR_NONE || strlen(sAuthId) < NATIVE_MIN_AUTHID_LENGTH)
  723. {
  724. ThrowNativeError(SP_ERROR_NATIVE, "Invalid Authid");
  725. }
  726.  
  727. if (IsAuthIdConnected(sAuthId))
  728. {
  729. ThrowNativeError(SP_ERROR_NATIVE, "AuthID currently connected.");
  730. }
  731. else
  732. {
  733. PerformOfflineCTBan(sAuthId, CALLER_NATIVE);
  734. }
  735.  
  736. return SP_ERROR_NONE;
  737. }
  738.  
  739. public int Native_CTBan_ChangeBanLength(Handle hPlugin, int iParams)
  740. {
  741. int iClient = GetNativeCell(NATIVE_CHANGE_TIME_CELL_CLIENT);
  742.  
  743. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  744. {
  745. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  746. }
  747.  
  748. int iMinutes = GetNativeCell(NATIVE_CHANGE_TIME_CELL_TIME);
  749.  
  750. if (iMinutes < ZERO)
  751. {
  752. ThrowNativeError(SP_ERROR_NATIVE, "Invalid time specified (%d).", iMinutes);
  753. }
  754.  
  755. int iAdmin = GetNativeCell(NATIVE_CHANGE_TIME_CELL_ADMIN);
  756.  
  757. if (iAdmin < ZERO || iAdmin > MaxClients || (iAdmin && !IsClientInGame(iAdmin)))
  758. {
  759. ThrowNativeError(SP_ERROR_NATIVE, "Admin (%d) is invalid!", iAdmin);
  760. }
  761.  
  762. if (GetCTBanStatus(iClient))
  763. {
  764. // check if time is not changing
  765. if (gA_LocalTimeRemaining[iClient] == iMinutes || (gA_LocalTimeRemaining[iClient] <= CTBAN_PERM_BAN_LENGTH && iMinutes == CTBAN_PERM_BAN_LENGTH))
  766. {
  767. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Invalid Amount");
  768. }
  769. else
  770. {
  771. PerformChangeCTBanTime(iClient, iAdmin, iMinutes);
  772. }
  773. }
  774. else
  775. {
  776. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Not CT Banned", iClient);
  777. }
  778.  
  779. return SP_ERROR_NONE;
  780. }
  781.  
  782. public int Native_CTBan_UnbanClient(Handle hPlugin, int iParams)
  783. {
  784. int iClient = GetNativeCell(NATIVE_UNBAN_CELL_CLIENT);
  785.  
  786. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  787. {
  788. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  789. }
  790.  
  791. int iAdmin = GetNativeCell(NATIVE_UNBAN_CELL_ADMIN);
  792.  
  793. if (iAdmin < ZERO || iAdmin > MaxClients || (iAdmin && !IsClientInGame(iAdmin)))
  794. {
  795. ThrowNativeError(SP_ERROR_NATIVE, "Admin (%d) is invalid!", iAdmin);
  796. }
  797.  
  798. if (GetCTBanStatus(iClient))
  799. {
  800. // check if the cookies are ready
  801. if (AreClientCookiesCached(iClient))
  802. {
  803. Remove_CTBan(iAdmin, iClient);
  804. }
  805. else
  806. {
  807. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Cookie Status Unavailable");
  808. }
  809. }
  810. else
  811. {
  812. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Not CT Banned", iClient);
  813. }
  814.  
  815. return SP_ERROR_NONE;
  816. }
  817.  
  818. public int Native_CTBan_UnbanClient_Offline(Handle hPlugin, int iParams)
  819. {
  820. if (!g_bAuthIdNativeExists)
  821. {
  822. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Feature Not Available");
  823. }
  824.  
  825. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  826. int iReturn = GetNativeString(NATIVE_UNBAN_OFF_STR_AUTHID, sAuthId, sizeof(sAuthId));
  827.  
  828. if (iReturn != SP_ERROR_NONE || strlen(sAuthId) < NATIVE_MIN_AUTHID_LENGTH)
  829. {
  830. ThrowNativeError(SP_ERROR_NATIVE, "Invalid Authid");
  831. }
  832.  
  833. if (IsAuthIdConnected(sAuthId))
  834. {
  835. ThrowNativeError(SP_ERROR_NATIVE, "AuthID currently connected.");
  836. }
  837. else
  838. {
  839. PerformOfflineUnCTBan(sAuthId, CALLER_NATIVE);
  840. }
  841.  
  842. return SP_ERROR_NONE;
  843. }
  844.  
  845. public int Native_CTBan_ForceCT(Handle hPlugin, int iParams)
  846. {
  847. int iClient = GetNativeCell(NATIVE_FORCECT_CELL_CLIENT);
  848.  
  849. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  850. {
  851. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  852. }
  853.  
  854. int iAdmin = GetNativeCell(NATIVE_FORCECT_CELL_ADMIN);
  855.  
  856. if (iAdmin < ZERO || iAdmin > MaxClients || (iAdmin && !IsClientInGame(iAdmin)))
  857. {
  858. ThrowNativeError(SP_ERROR_NATIVE, "Admin (%d) is invalid!", iAdmin);
  859. }
  860.  
  861. if (GetClientTeam(iClient) == CS_TEAM_CT)
  862. {
  863. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Unable to target");
  864. }
  865. else
  866. {
  867. ForceCTActions(iAdmin, iClient);
  868. }
  869.  
  870. return SP_ERROR_NONE;
  871. }
  872.  
  873. public int Native_CTBan_UnForceCT(Handle hPlugin, int iParams)
  874. {
  875. int iClient = GetNativeCell(NATIVE_UNFORCECT_CELL_CLIENT);
  876.  
  877. if (iClient <= ZERO || iClient > MaxClients || !IsClientInGame(iClient))
  878. {
  879. ThrowNativeError(SP_ERROR_NATIVE, "Client (%d) is invalid!", iClient);
  880. }
  881.  
  882. int iAdmin = GetNativeCell(NATIVE_UNFORCECT_CELL_ADMIN);
  883.  
  884. if (iAdmin < ZERO || iAdmin > MaxClients || (iAdmin && !IsClientInGame(iAdmin)))
  885. {
  886. ThrowNativeError(SP_ERROR_NATIVE, "Admin (%d) is invalid!", iAdmin);
  887. }
  888.  
  889. UnForceCTActions(iAdmin, iClient, true);
  890.  
  891. return SP_ERROR_NONE;
  892. }
  893.  
  894. public void OnAllPluginsLoaded()
  895. {
  896. g_bAuthIdNativeExists = IsSetAuthIdNativePresent();
  897. }
  898.  
  899. public Action Event_PlayerSpawn(Event hEvent, const char[] sName, bool bDontBroadcast)
  900. {
  901. int iClient = GetClientOfUserId(GetEventInt(hEvent, "userid"));
  902.  
  903. if (IsClientInGame(iClient) && GetClientTeam(iClient) == CS_TEAM_CT)
  904. {
  905. if (!g_bA_Temp_CTBan_Override[iClient] && GetCTBanStatus(iClient))
  906. {
  907. #if defined CTBAN_DEBUG
  908. LogMessage("%N spawned as CT but was CTBanned. Moving to Terrorist team.", iClient);
  909. #endif
  910.  
  911. EnforceCTBan(iClient);
  912. }
  913. }
  914.  
  915. return Plugin_Continue;
  916. }
  917.  
  918. public Action Event_PlayerTeam(Event hEvent, const char[] sName, bool bDontBroadcast)
  919. {
  920. int iUserID = GetEventInt(hEvent, "userid");
  921. int iClient = GetClientOfUserId(iUserID);
  922. int iTeam = GetEventInt(hEvent, "team");
  923. bool bDisconnected = GetEventBool(hEvent, "disconnect");
  924.  
  925. if (bDisconnected || !iClient || !IsClientInGame(iClient))
  926. {
  927. return Plugin_Continue;
  928. }
  929.  
  930. if (iTeam == CS_TEAM_CT && GetCTBanStatus(iClient))
  931. {
  932. // if a CT banned player is on CT and did not get an override they will be swapped after they spawn
  933. // BUT an admin likely did this and should get instruction to use !forcect
  934. if (!g_bA_Temp_CTBan_Override[iClient])
  935. {
  936. // only admins need the message
  937. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  938. {
  939. if (IsClientInGame(iIndex) && CheckCommandAccess(iIndex, "sm_chat", ADMFLAG_CHAT))
  940. {
  941. CPrintToChat(iIndex, g_sChatBanner, "CTBanned Player On CT Team", iClient);
  942. }
  943. }
  944. }
  945.  
  946. // if they are still alive then we should not even wait until the respawn
  947. if (IsPlayerAlive(iClient))
  948. {
  949. CreateTimer(DELAY_ENFORCEMENT_TIME, Timer_DelayEnforcement, iUserID, TIMER_FLAG_NO_MAPCHANGE);
  950. }
  951. }
  952.  
  953. return Plugin_Continue;
  954. }
  955.  
  956. public Action Timer_DelayEnforcement(Handle hTimer, any iUserID)
  957. {
  958. int iClient = GetClientOfUserId(iUserID);
  959.  
  960. if (iClient && IsClientInGame(iClient) && GetClientTeam(iClient) == CS_TEAM_CT && GetCTBanStatus(iClient))
  961. {
  962. EnforceCTBan(iClient);
  963. }
  964. }
  965.  
  966. public Action Event_JoinTeamFailed(Handle hEvent, const char[] sName, bool bDontBroadcast)
  967. {
  968. int iClient = GetClientOfUserId(GetEventInt(hEvent, "userid"));
  969. if (iClient && IsClientInGame(iClient))
  970. {
  971. int iReason = GetEventInt(hEvent, "reason");
  972.  
  973. if (iReason == JOINFAILREASON_ONECHANGE)
  974. {
  975. // Check if client is banned and is blocked
  976. if (GetCTBanStatus(iClient))
  977. {
  978. #if defined CTBAN_DEBUG
  979. LogMessage("%N was unable to join a team due to limit. Forcing to Terrorist team.");
  980. #endif
  981.  
  982. ChangeClientTeam(iClient, CS_TEAM_T);
  983.  
  984. return Plugin_Handled;
  985. }
  986. }
  987. }
  988.  
  989. return Plugin_Continue;
  990. }
  991.  
  992. // consider if someone does a 'retry' and clientprefs is accessinsg on its ClientConnectCallback and this is also trying to set a value
  993. public void OnClientAuthorized(int iClient, const char[] sAuthID)
  994. {
  995. // check if the Steam ID is in the Rage Ban list
  996. int iNeedle = FindStringInArray(gA_DSteamIDs, sAuthID);
  997. if (iNeedle != VALUE_NOT_FOUND_IN_ARRAY)
  998. {
  999. g_bRageBanArrayChanged = true;
  1000.  
  1001. RemoveFromArray(gA_DNames, iNeedle);
  1002. RemoveFromArray(gA_DSteamIDs, iNeedle);
  1003. #if defined CTBAN_DEBUG
  1004. LogMessage("removed %N from Rage Bannable player list for re-connecting to the server", iClient);
  1005. #endif
  1006. }
  1007.  
  1008. // check if we have a database connection
  1009. if (gH_BanDatabase != INVALID_HANDLE)
  1010. {
  1011. // check if the Steam ID is in the Timed Ban list
  1012. char sQuery[QUERY_MAXLENGTH];
  1013. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_SELECT_BANTIME, g_sTimesTableName, sAuthID);
  1014. SQL_TQuery(gH_BanDatabase, DB_Callback_OnClientAuthed, sQuery, view_as<int>(iClient));
  1015. }
  1016. else
  1017. {
  1018. CreateTimer(AUTH_RESCAN_TIME, Timer_OnAuthCheckDatabase, iClient, TIMER_FLAG_NO_MAPCHANGE);
  1019. }
  1020. }
  1021.  
  1022. public Action Timer_OnAuthCheckDatabase(Handle hTimer, any iClient)
  1023. {
  1024. if (gH_BanDatabase != INVALID_HANDLE && IsClientInGame(iClient))
  1025. {
  1026. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  1027. GetClientAuthId(iClient, AuthId_Steam2, sAuthID, sizeof(sAuthID));
  1028.  
  1029. char sQuery[QUERY_MAXLENGTH];
  1030. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_SELECT_BANTIME, g_sTimesTableName, sAuthID);
  1031. SQL_TQuery(gH_BanDatabase, DB_Callback_OnClientAuthed, sQuery, view_as<int>(iClient));
  1032. }
  1033. else if(IsClientInGame(iClient))
  1034. {
  1035. CreateTimer(AUTH_RESCAN_TIME, Timer_OnAuthCheckDatabase, iClient, TIMER_FLAG_NO_MAPCHANGE);
  1036. }
  1037. }
  1038.  
  1039. public void DB_Callback_OnClientAuthed(Handle hOwner, Handle hCallback, const char[] sError, any iClient)
  1040. {
  1041. if (hCallback == INVALID_HANDLE)
  1042. {
  1043. LogError("Error in OnClientAuthorized query: %s", sError);
  1044. }
  1045. else
  1046. {
  1047. int iRowCount = SQL_GetRowCount(hCallback);
  1048. #if defined CTBAN_DEBUG
  1049. LogMessage("SQL Auth: %d row count", iRowCount);
  1050. #endif
  1051. if (iRowCount)
  1052. {
  1053. SQL_FetchRow(hCallback);
  1054. int iBanTimeRemaining = SQL_FetchInt(hCallback, CLIENT_AUTHED_CB_FIELD_TIMELEFT);
  1055. #if defined CTBAN_DEBUG
  1056. LogMessage("SQL Auth: %N joined with %i time remaining on ban", iClient, iBanTimeRemaining);
  1057. #endif
  1058. // update local time
  1059. PushArrayCell(gA_TimedBanLocalList, iClient);
  1060. gA_LocalTimeRemaining[iClient] = iBanTimeRemaining;
  1061. }
  1062. }
  1063. }
  1064.  
  1065. public void AdminMenu_RageBan(Handle hTopMenu, TopMenuAction eAction, TopMenuObject eObjectID, int iClient, char[] sBuffer, int iMaxLength)
  1066. {
  1067. if (eAction == TopMenuAction_DisplayOption)
  1068. {
  1069. Format(sBuffer, iMaxLength, "%T", "Rage Ban Admin Menu", iClient);
  1070. }
  1071. else if (eAction == TopMenuAction_SelectOption)
  1072. {
  1073. DisplayRageBanMenu(iClient, GetArraySize(gA_DNames));
  1074. }
  1075. }
  1076.  
  1077. void DisplayRageBanMenu(int iClient, int iArraySize)
  1078. {
  1079. if (iArraySize == ZERO)
  1080. {
  1081. CPrintToChat(iClient, g_sChatBanner, "No Targets");
  1082. }
  1083. else
  1084. {
  1085. Handle hMenu = CreateMenu(MenuHandler_RageBan);
  1086.  
  1087. SetMenuTitle(hMenu, "%T", "Rage Ban Menu Title", iClient);
  1088. SetMenuExitBackButton(hMenu, true);
  1089.  
  1090. for (int iArrayIndex = ZERO; iArrayIndex < iArraySize; iArrayIndex++)
  1091. {
  1092. char sName[FIELD_NAME_MAXLENGTH];
  1093. GetArrayString(gA_DNames, iArrayIndex, sName, sizeof(sName));
  1094.  
  1095. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  1096. GetArrayString(gA_DSteamIDs, iArrayIndex, sAuthID, sizeof(sAuthID));
  1097.  
  1098. AddMenuItem(hMenu, sAuthID, sName);
  1099. }
  1100.  
  1101. DisplayMenu(hMenu, iClient, MENU_TIME_FOREVER);
  1102. }
  1103. }
  1104.  
  1105. public int MenuHandler_RageBan(Handle hMenu, MenuAction action, int iClient, int iMenuChoice)
  1106. {
  1107. if (action == MenuAction_End)
  1108. {
  1109. CloseHandle(hMenu);
  1110. }
  1111. else if (action == MenuAction_Cancel)
  1112. {
  1113. if ((iMenuChoice == MenuCancel_ExitBack) && (gH_TopMenu != INVALID_HANDLE))
  1114. {
  1115. DisplayTopMenu(gH_TopMenu, iClient, TopMenuPosition_LastCategory);
  1116. }
  1117. }
  1118. else if (action == MenuAction_Select)
  1119. {
  1120. if (!g_bAuthIdNativeExists)
  1121. {
  1122. ReplyToCommand(iClient, g_sChatBanner, "Feature Not Available");
  1123. }
  1124. else
  1125. {
  1126. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  1127. char sTargetName[MAX_TARGET_LENGTH];
  1128. GetMenuItem(hMenu, iMenuChoice, sAuthID, sizeof(sAuthID), _, sTargetName, sizeof(sTargetName));
  1129.  
  1130. #if defined CTBAN_DEBUG
  1131. CPrintToChat(iClient, g_sChatBanner, "Ready to CT Ban", sAuthID);
  1132. #endif
  1133.  
  1134. SetAuthIdCookie(sAuthID, g_CT_Cookie, COOKIE_BANNED_STRING);
  1135.  
  1136. char sAdminSteamID[FIELD_AUTHID_MAXLENGTH];
  1137. GetClientAuthId(iClient, AuthId_Steam2, sAdminSteamID, sizeof(sAdminSteamID));
  1138.  
  1139. LogMessage("%N (%s) has issued a rage ban on %s (%s) indefinitely.", iClient, sAdminSteamID, sTargetName, sAuthID);
  1140.  
  1141. ShowActivity2(iClient, "", g_sChatBanner, "Rage Ban", sTargetName);
  1142.  
  1143. int iTimeStamp = GetTime();
  1144. char sTempName[FIELD_NAME_MAXLENGTH];
  1145. char sQuery[QUERY_MAXLENGTH];
  1146. char sEscapedPerpName[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  1147. char sEscapedAdminName[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  1148. Format(sTempName, sizeof(sTempName), "%s", sTargetName);
  1149. SQL_EscapeString(gH_BanDatabase, sTempName, sEscapedPerpName, sizeof(sEscapedPerpName));
  1150. Format(sTempName, sizeof(sTempName), "%N", iClient);
  1151. SQL_EscapeString(gH_BanDatabase, sTempName, sEscapedAdminName, sizeof(sEscapedAdminName));
  1152.  
  1153. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_INSERT, g_sLogTableName, iTimeStamp, sAuthID, sEscapedPerpName, sAdminSteamID, sEscapedAdminName, CTBAN_PERM_BAN_LENGTH, CTBAN_PERM_BAN_LENGTH, RAGEBAN_LOG_REASON);
  1154.  
  1155. #if defined CTBAN_DEBUG
  1156. LogMessage("log query: %s", sQuery);
  1157. #endif
  1158.  
  1159. SQL_TQuery(gH_BanDatabase, DB_Callback_CTBan, sQuery, iClient);
  1160.  
  1161. // Remove any existing time information to make the CTBan permanently
  1162. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_DELETE, g_sTimesTableName, sAuthID);
  1163. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  1164. }
  1165. }
  1166. }
  1167.  
  1168. public void CP_Callback_ResetAllCTBans(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1169. {
  1170. if (hCallback == INVALID_HANDLE)
  1171. {
  1172. LogError("Error reseting the CTBan cookies: %s", sError);
  1173. }
  1174. else
  1175. {
  1176. LogMessage("CTBans Cookie Bans were successfully RESET by the administrator.");
  1177. }
  1178. }
  1179.  
  1180. public Action Command_Offline_CTBan(int iClient, int iArgs)
  1181. {
  1182. if (g_bAuthIdNativeExists)
  1183. {
  1184. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  1185. GetCmdArgString(sAuthId, sizeof(sAuthId));
  1186.  
  1187. if (IsAuthIdConnected(sAuthId))
  1188. {
  1189. ReplyToCommand(iClient, g_sChatBanner, "Unable to target");
  1190. }
  1191. else
  1192. {
  1193. PerformOfflineCTBan(sAuthId, iClient);
  1194. }
  1195. }
  1196. else
  1197. {
  1198. ReplyToCommand(iClient, g_sChatBanner, "Feature Not Available");
  1199. }
  1200. return Plugin_Handled;
  1201. }
  1202.  
  1203. void PerformOfflineCTBan(char[] sAuthId, int iAdmin)
  1204. {
  1205. SetAuthIdCookie(sAuthId, g_CT_Cookie, COOKIE_BANNED_STRING);
  1206.  
  1207. char sAdminSteamID[FIELD_AUTHID_MAXLENGTH];
  1208. if (iAdmin > ZERO)
  1209. {
  1210. GetClientAuthId(iAdmin, AuthId_Steam2, sAdminSteamID, sizeof(sAdminSteamID));
  1211. }
  1212. else
  1213. {
  1214. sAdminSteamID = CONSOLE_AUTHID;
  1215. }
  1216.  
  1217. int iTimeStamp = GetTime();
  1218. char sQuery[QUERY_MAXLENGTH];
  1219. char sTempName[FIELD_NAME_MAXLENGTH];
  1220. char sEscapedPerpAuthId[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  1221. SQL_EscapeString(gH_BanDatabase, sAuthId, sEscapedPerpAuthId, sizeof(sEscapedPerpAuthId));
  1222.  
  1223. char sEscapedAdminName[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  1224. if (iAdmin > ZERO)
  1225. {
  1226. Format(sTempName, sizeof(sTempName), "%N", iAdmin);
  1227. SQL_EscapeString(gH_BanDatabase, sTempName, sEscapedAdminName, sizeof(sEscapedAdminName));
  1228. }
  1229. else
  1230. {
  1231. sEscapedAdminName = CONSOLE_USER_NAME;
  1232. }
  1233.  
  1234. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_INSERT, g_sLogTableName, iTimeStamp, sEscapedPerpAuthId, OFFLINE_NAME_UNAVAILBLE, sAdminSteamID, sEscapedAdminName, CTBAN_PERM_BAN_LENGTH, CTBAN_PERM_BAN_LENGTH, REASON_OFFLINECTBAN);
  1235.  
  1236. #if defined CTBAN_DEBUG
  1237. LogMessage("log query: %s", sQuery);
  1238. #endif
  1239.  
  1240. SQL_TQuery(gH_BanDatabase, DB_Callback_CTBan, sQuery, iAdmin);
  1241.  
  1242. if (iAdmin == CALLER_NATIVE)
  1243. {
  1244. // No response
  1245. }
  1246. {
  1247. ReplyToCommand(iAdmin, g_sChatBanner, "Banned AuthId", sAuthId);
  1248. }
  1249.  
  1250. Call_StartForward(g_hFrwd_OnCTBan_Offline);
  1251. Call_PushString(sAuthId);
  1252. Call_PushCell(iAdmin);
  1253. Call_Finish();
  1254. }
  1255.  
  1256. public Action Command_ForceCT(int iClient, int iArgs)
  1257. {
  1258. if (!iClient && !iArgs)
  1259. {
  1260. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_forcect <player>");
  1261. return Plugin_Handled;
  1262. }
  1263.  
  1264. if (!iArgs)
  1265. {
  1266. DisplayCTBannedPlayerMenu(iClient, e_ForceCT);
  1267. return Plugin_Handled;
  1268. }
  1269.  
  1270. char sTarget[MAX_TARGET_LENGTH];
  1271. GetCmdArg(FORCECT_ARG_TARGET, sTarget, sizeof(sTarget));
  1272.  
  1273. char sClientName[MAX_TARGET_LENGTH];
  1274. int aiTargetList[MAXPLAYERS];
  1275. int iTargetCount;
  1276. bool b_tn_is_ml;
  1277. iTargetCount = ProcessTargetString(sTarget, iClient, aiTargetList, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sClientName, sizeof(sClientName), b_tn_is_ml);
  1278.  
  1279. if (iTargetCount < ONE)
  1280. {
  1281. ReplyToTargetError(iClient, iTargetCount);
  1282. }
  1283. else
  1284. {
  1285. int iTarget = aiTargetList[ZERO];
  1286.  
  1287. if (iTarget && IsClientInGame(iTarget))
  1288. {
  1289. if (GetClientTeam(iTarget) == CS_TEAM_CT)
  1290. {
  1291. ReplyToCommand(iClient, g_sChatBanner, "Unable to target");
  1292. }
  1293. else
  1294. {
  1295. ForceCTActions(iClient, iTarget);
  1296. }
  1297. }
  1298. }
  1299. return Plugin_Handled;
  1300. }
  1301.  
  1302. void ForceCTActions(int iAdmin, int iTarget)
  1303. {
  1304. if (IsClientInGame(iTarget))
  1305. {
  1306. g_bA_Temp_CTBan_Override[iTarget] = true;
  1307.  
  1308. if (IsPlayerAlive(iTarget))
  1309. {
  1310. StripAllWeapons(iTarget);
  1311. ForcePlayerSuicide(iTarget);
  1312. }
  1313.  
  1314. ChangeClientTeam(iTarget, CS_TEAM_CT);
  1315.  
  1316. if (GetConVarBool(gH_Cvar_Respawn))
  1317. {
  1318. CS_RespawnPlayer(iTarget);
  1319. }
  1320.  
  1321. ShowActivity2(iAdmin, "", g_sChatBanner, "Force CT", iTarget);
  1322.  
  1323. Call_StartForward(g_hFrwd_OnForceCT);
  1324. Call_PushCell(iTarget);
  1325. Call_PushCell(iAdmin);
  1326. Call_Finish();
  1327. }
  1328. }
  1329.  
  1330. public Action Command_UnForceCT(int iClient, int iArgs)
  1331. {
  1332. if (!iClient && !iArgs)
  1333. {
  1334. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_unforcect <player>");
  1335. return Plugin_Handled;
  1336. }
  1337.  
  1338. if (!iArgs)
  1339. {
  1340. DisplayUnForceCTPlayerMenu(iClient);
  1341. return Plugin_Handled;
  1342. }
  1343.  
  1344. char sTarget[MAX_TARGET_LENGTH];
  1345. GetCmdArg(UNFORCECT_ARG_TARGET, sTarget, sizeof(sTarget));
  1346.  
  1347. char sClientName[MAX_TARGET_LENGTH];
  1348. int aiTargetLlist[MAXPLAYERS];
  1349. int iTargetCount;
  1350. bool b_tn_is_ml;
  1351. iTargetCount = ProcessTargetString(sTarget, iClient, aiTargetLlist, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sClientName, sizeof(sClientName), b_tn_is_ml);
  1352.  
  1353. if (iTargetCount < ONE)
  1354. {
  1355. ReplyToTargetError(iClient, iTargetCount);
  1356. }
  1357. else
  1358. {
  1359. int iTarget = aiTargetLlist[ZERO];
  1360. UnForceCTActions(iClient, iTarget);
  1361. }
  1362. return Plugin_Handled;
  1363. }
  1364.  
  1365. void UnForceCTActions(int iAdmin, int iTarget, bool bQuiet = false)
  1366. {
  1367. if (!g_bA_Temp_CTBan_Override[iTarget])
  1368. {
  1369. if (!bQuiet)
  1370. {
  1371. ReplyToCommand(iAdmin, g_sChatBanner, "Unable to target");
  1372. }
  1373. }
  1374. else
  1375. {
  1376. if (IsClientInGame(iTarget))
  1377. {
  1378. if (GetClientTeam(iTarget) == CS_TEAM_CT)
  1379. {
  1380. if (IsPlayerAlive(iTarget))
  1381. {
  1382. StripAllWeapons(iTarget);
  1383. ForcePlayerSuicide(iTarget);
  1384. }
  1385.  
  1386. ChangeClientTeam(iTarget, CS_TEAM_T);
  1387.  
  1388. if (GetConVarBool(gH_Cvar_Respawn))
  1389. {
  1390. CS_RespawnPlayer(iTarget);
  1391. }
  1392. }
  1393. g_bA_Temp_CTBan_Override[iTarget] = false;
  1394.  
  1395. if (!bQuiet)
  1396. {
  1397. ShowActivity2(iAdmin, "", g_sChatBanner, "Unforce CT", iTarget);
  1398. }
  1399.  
  1400. Call_StartForward(g_hFrwd_OnUnforceCT);
  1401. Call_PushCell(iTarget);
  1402. Call_PushCell(iAdmin);
  1403. Call_Finish();
  1404. }
  1405. }
  1406. }
  1407.  
  1408. void DisplayUnForceCTPlayerMenu(int iClient)
  1409. {
  1410. Handle hMenu = CreateMenu(MenuHandler_UnForceCT);
  1411.  
  1412. SetMenuTitle(hMenu, "%T", "UnForce CT Menu Title", iClient);
  1413. SetMenuExitBackButton(hMenu, true);
  1414.  
  1415. int iCount = ZERO;
  1416. char sUserId[MAX_USERID_LENGTH];
  1417. char sName[MAX_NAME_LENGTH];
  1418.  
  1419. // filter away those with current overrides
  1420. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  1421. {
  1422. if (IsClientInGame(iIndex))
  1423. {
  1424. if (g_bA_Temp_CTBan_Override[iIndex])
  1425. {
  1426. IntToString(GetClientUserId(iIndex), sUserId, sizeof(sUserId));
  1427. GetClientName(iIndex, sName, sizeof(sName));
  1428.  
  1429. AddMenuItem(hMenu, sUserId, sName);
  1430.  
  1431. iCount++;
  1432. }
  1433. }
  1434. }
  1435.  
  1436. if (!iCount)
  1437. {
  1438. CPrintToChat(iClient, g_sChatBanner, "No matching clients");
  1439. }
  1440.  
  1441. DisplayMenu(hMenu, iClient, MENU_TIME_FOREVER);
  1442. }
  1443.  
  1444. public Action Command_ResetCookies(int iClient, int iArgs)
  1445. {
  1446. char sArgs[MAX_RESET_ARG_LENGTH];
  1447. GetCmdArgString(sArgs, sizeof(sArgs));
  1448.  
  1449. if (StrEqual("force", sArgs))
  1450. {
  1451. if (!g_iCookieIndex)
  1452. {
  1453. ReplyToCommand(iClient, g_sChatBanner, "Cookie not Found", "Banned_From_CT");
  1454. }
  1455. else
  1456. {
  1457. char sQuery[QUERY_MAXLENGTH];
  1458. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_CP_RESET_COOKIES, g_iCookieIndex);
  1459.  
  1460. #if defined CTBAN_DEBUG
  1461. LogMessage("Query to run: %s", sQuery);
  1462. #endif
  1463.  
  1464. SQL_TQuery(gH_CP_DataBase, CP_Callback_ResetAllCTBans, sQuery);
  1465.  
  1466. ShowActivity2(iClient, "", g_sChatBanner, "Reset Cookies");
  1467. }
  1468. }
  1469. else
  1470. {
  1471. ReplyToCommand(iClient, g_sChatBanner, "Reset Cookie Confirmation");
  1472. }
  1473.  
  1474. return Plugin_Handled;
  1475. }
  1476.  
  1477. public Action Command_Offline_UnCTBan(int iClient, int iArgs)
  1478. {
  1479. if (g_bAuthIdNativeExists)
  1480. {
  1481. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  1482. GetCmdArgString(sAuthId, sizeof(sAuthId));
  1483.  
  1484. if (IsAuthIdConnected(sAuthId))
  1485. {
  1486. ReplyToCommand(iClient, g_sChatBanner, "Unable to target");
  1487. }
  1488. else
  1489. {
  1490. PerformOfflineUnCTBan(sAuthId, iClient);
  1491. }
  1492. }
  1493. else
  1494. {
  1495. ReplyToCommand(iClient, g_sChatBanner, "Feature Not Available");
  1496. }
  1497.  
  1498. return Plugin_Handled;
  1499. }
  1500.  
  1501. void PerformOfflineUnCTBan(char[] sAuthId, int iAdmin)
  1502. {
  1503. SetAuthIdCookie(sAuthId, g_CT_Cookie, COOKIE_UNBANNED_STRING);
  1504.  
  1505. char sEscapedAuthId[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  1506. SQL_EscapeString(gH_BanDatabase, sAuthId, sEscapedAuthId, sizeof(sEscapedAuthId));
  1507.  
  1508. char sQuery[QUERY_MAXLENGTH];
  1509. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_EXPIRE, g_sLogTableName, sEscapedAuthId);
  1510.  
  1511. #if defined CTBAN_DEBUG
  1512. LogMessage("log query: %s", sQuery);
  1513. #endif
  1514.  
  1515. SQL_TQuery(gH_BanDatabase, DB_Callback_RemoveCTBan, sQuery, CALLER_DO_NOT_REPLY);
  1516.  
  1517. // delete from the timedban database if there was one
  1518. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_DELETE, g_sTimesTableName, sEscapedAuthId);
  1519.  
  1520. #if defined CTBAN_DEBUG
  1521. LogMessage("log query: %s", sQuery);
  1522. #endif
  1523.  
  1524. SQL_TQuery(gH_BanDatabase, DB_Callback_RemoveCTBan, sQuery, CALLER_DO_NOT_REPLY);
  1525.  
  1526. if (iAdmin == CALLER_NATIVE)
  1527. {
  1528. // No response
  1529. }
  1530. else
  1531. {
  1532. ReplyToCommand(iAdmin, g_sChatBanner, "Unbanned AuthId", sAuthId);
  1533.  
  1534. LogMessage("%N has removed the CT ban on %s.", iAdmin, sAuthId);
  1535. }
  1536.  
  1537. Call_StartForward(g_hFrwd_OnUnCTBan_Offline);
  1538. Call_PushString(sAuthId);
  1539. Call_PushCell(iAdmin);
  1540. Call_Finish();
  1541. }
  1542.  
  1543. public Action Command_RageBan(int iClient, int iArgs)
  1544. {
  1545. int iArraySize = GetArraySize(gA_DNames);
  1546. if (iArraySize == ZERO)
  1547. {
  1548. ReplyToCommand(iClient, g_sChatBanner, "No Targets");
  1549. return Plugin_Handled;
  1550. }
  1551.  
  1552. if (!iArgs)
  1553. {
  1554. if (iClient)
  1555. {
  1556. DisplayRageBanMenu(iClient, iArraySize);
  1557. }
  1558. // Console user
  1559. else
  1560. {
  1561. PrintToServer(g_sChatBanner, "Rage Ban Menu Title");
  1562.  
  1563. for (int iArrayIndex = ZERO; iArrayIndex < iArraySize; iArrayIndex++)
  1564. {
  1565. char sName[FIELD_NAME_MAXLENGTH];
  1566. GetArrayString(gA_DNames, iArrayIndex, sName, sizeof(sName));
  1567.  
  1568. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  1569. GetArrayString(gA_DSteamIDs, iArrayIndex, sAuthID, sizeof(sAuthID));
  1570.  
  1571. PrintToServer("[CTBAN] (%d.) %s [%s]", iArrayIndex + ONE, sName, sAuthID);
  1572. }
  1573.  
  1574. g_bRageBanArrayChanged = false;
  1575. }
  1576. return Plugin_Handled;
  1577. }
  1578. else
  1579. {
  1580. if (iClient)
  1581. {
  1582. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", RAGEBAN_COMMAND);
  1583. }
  1584. // Console user
  1585. else
  1586. {
  1587. char sTarget[MAX_MENU_INT_CHOICE_LENGTH];
  1588. GetCmdArg(RAGEBAN_ARG_CONSOLE_TARGET, sTarget, sizeof(sTarget));
  1589.  
  1590. int iArrayIndex = StringToInt(sTarget) - ONE;
  1591.  
  1592. if ((iArrayIndex >= iArraySize) || (iArrayIndex < ZERO))
  1593. {
  1594. ReplyToCommand(iClient, g_sChatBanner, "No matching client");
  1595. }
  1596. else if (g_bRageBanArrayChanged)
  1597. {
  1598. ReplyToCommand(iClient, g_sChatBanner, "Player no longer available");
  1599. }
  1600. else
  1601. {
  1602. char sTargetName[FIELD_NAME_MAXLENGTH];
  1603. GetArrayString(gA_DNames, iArrayIndex, sTargetName, sizeof(sTargetName));
  1604.  
  1605. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  1606. GetArrayString(gA_DSteamIDs, iArrayIndex, sAuthID, sizeof(sAuthID));
  1607.  
  1608. #if defined CTBAN_DEBUG
  1609. PrintToServer(g_sChatBanner, "Ready to CT Ban", sAuthID);
  1610. #endif
  1611.  
  1612. SetAuthIdCookie(sAuthID, g_CT_Cookie, COOKIE_BANNED_STRING);
  1613.  
  1614. LogMessage("%N has issued a rage ban on %s (%s) indefinitely.", iClient, sTargetName, sAuthID);
  1615.  
  1616. ShowActivity2(iClient, "", g_sChatBanner, "Rage Ban", sTargetName);
  1617.  
  1618. int iTimeStamp = GetTime();
  1619. char sTempName[FIELD_NAME_MAXLENGTH];
  1620. char sQuery[QUERY_MAXLENGTH];
  1621. char sEscapedPerpName[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  1622. Format(sTempName, sizeof(sTempName), "%s", sTargetName);
  1623. SQL_EscapeString(gH_BanDatabase, sTempName, sEscapedPerpName, sizeof(sEscapedPerpName));
  1624.  
  1625. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_INSERT, g_sLogTableName, iTimeStamp, sAuthID, sEscapedPerpName, CONSOLE_AUTHID, CONSOLE_USER_NAME, CTBAN_PERM_BAN_LENGTH, CTBAN_PERM_BAN_LENGTH, RAGEBAN_LOG_REASON);
  1626.  
  1627. #if defined CTBAN_DEBUG
  1628. LogMessage("log query: %s", sQuery);
  1629. #endif
  1630.  
  1631. SQL_TQuery(gH_BanDatabase, DB_Callback_CTBan, sQuery, iClient);
  1632.  
  1633. // Remove any existing time information to make the CTBan permanently
  1634. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_DELETE, g_sTimesTableName, sAuthID);
  1635. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  1636. }
  1637. }
  1638. }
  1639.  
  1640. return Plugin_Handled;
  1641. }
  1642.  
  1643. public Action Timer_CheckTimedCTBans(Handle hTimer)
  1644. {
  1645. // check if anyone has a time
  1646. int iTimeArraySize = GetArraySize(gA_TimedBanLocalList);
  1647.  
  1648. // credit for this idea goes to Kigen
  1649. for (int iIndex = ZERO; iIndex < iTimeArraySize; iIndex++)
  1650. {
  1651. int iBannedClientIndex = GetArrayCell(gA_TimedBanLocalList, iIndex);
  1652. if (IsClientInGame(iBannedClientIndex))
  1653. {
  1654. if (IsPlayerAlive(iBannedClientIndex))
  1655. {
  1656. gA_LocalTimeRemaining[iBannedClientIndex]--;
  1657.  
  1658. #if defined CTBAN_DEBUG
  1659. LogMessage("found alive time banned client with %i remaining", gA_LocalTimeRemaining[iBannedClientIndex]);
  1660. #endif
  1661.  
  1662. // check if we should remove the CT ban
  1663. if (gA_LocalTimeRemaining[iBannedClientIndex] <= ZERO)
  1664. {
  1665. // remove CT ban
  1666. RemoveFromArray(gA_TimedBanLocalList, iIndex);
  1667. iTimeArraySize--;
  1668.  
  1669. Remove_CTBan(ZERO, iBannedClientIndex, true);
  1670.  
  1671. #if defined CTBAN_DEBUG
  1672. LogMessage("removed CT ban on %N", iBannedClientIndex);
  1673. #endif
  1674. }
  1675. }
  1676. }
  1677. }
  1678. }
  1679.  
  1680. public void OnConfigsExecuted()
  1681. {
  1682. #if defined CTBAN_DEBUG
  1683. LogMessage("Connecting to clientprefs database");
  1684. #endif
  1685.  
  1686. SQL_TConnect(CP_Callback_Connect, "clientprefs");
  1687.  
  1688. char sDatabaseDriver[64];
  1689. GetConVarString(gH_Cvar_Database_Driver, sDatabaseDriver, sizeof(sDatabaseDriver));
  1690.  
  1691. #if defined CTBAN_DEBUG
  1692. LogMessage("Connecting to log database");
  1693. #endif
  1694.  
  1695. SQL_TConnect(DB_Callback_Connect, sDatabaseDriver);
  1696.  
  1697. ParseCTBanReasonsFile(gH_DArray_Reasons);
  1698.  
  1699. gH_KV_BanLengths = ParseCTBanLengthsFile(gH_KV_BanLengths);
  1700. }
  1701.  
  1702. public void DB_Callback_Connect(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1703. {
  1704. if (hCallback == INVALID_HANDLE)
  1705. {
  1706. LogError("Default database database connection failure: %s", sError);
  1707. SetFailState("Error while connecting to default database. Exiting.");
  1708. }
  1709. else
  1710. {
  1711. gH_BanDatabase = hCallback;
  1712.  
  1713. // Determine the type of database we're on so we may modify the syntax of queries
  1714. char sDatabaseID[MAX_DATABASE_ID_LENGTH];
  1715. SQL_GetDriverIdent(SQL_ReadDriver(gH_BanDatabase), sDatabaseID, sizeof(sDatabaseID));
  1716. if (StrEqual(sDatabaseID, "mysql"))
  1717. {
  1718. g_eDatabaseType = e_MySQL;
  1719. }
  1720. else if (StrEqual(sDatabaseID, "sqlite"))
  1721. {
  1722. g_eDatabaseType = e_SQLite;
  1723. }
  1724. else
  1725. {
  1726. g_eDatabaseType = e_Unknown;
  1727. }
  1728.  
  1729. // figure out table prefix situation
  1730. char sPrefix[MAX_TABLE_LENGTH - MAX_DEFAULT_TABLE_LENGTH];
  1731. GetConVarString(gH_Cvar_Table_Prefix, sPrefix, sizeof(sPrefix));
  1732. if (strlen(sPrefix) > ZERO)
  1733. {
  1734. Format(g_sTimesTableName, sizeof(g_sTimesTableName), "%s_CTBan_Times", sPrefix);
  1735. }
  1736. else
  1737. {
  1738. Format(g_sTimesTableName, sizeof(g_sTimesTableName), "CTBan_Times");
  1739. }
  1740.  
  1741. char sQuery[QUERY_MAXLENGTH];
  1742. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_CREATE, g_sTimesTableName, FIELD_AUTHID_MAXLENGTH);
  1743.  
  1744. #if defined CTBAN_DEBUG
  1745. LogMessage("times table create query %s", sQuery);
  1746. #endif
  1747.  
  1748. // create database if not already there
  1749. SQL_TQuery(gH_BanDatabase, DB_Callback_CreateTime, sQuery);
  1750.  
  1751. if (strlen(sPrefix) > ZERO)
  1752. {
  1753. Format(g_sLogTableName, sizeof(g_sLogTableName), "%s_CTBan_Log", sPrefix);
  1754. }
  1755. else
  1756. {
  1757. Format(g_sLogTableName, sizeof(g_sLogTableName), "CTBan_Log");
  1758. }
  1759.  
  1760. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_CREATE, g_sLogTableName, FIELD_AUTHID_MAXLENGTH, FIELD_NAME_MAXLENGTH, FIELD_AUTHID_MAXLENGTH, FIELD_NAME_MAXLENGTH, FIELD_REASON_MAXLENGTH);
  1761.  
  1762. #if defined CTBAN_DEBUG
  1763. LogMessage("log table create query %s", sQuery);
  1764. #endif
  1765.  
  1766. SQL_TQuery(gH_BanDatabase, DB_Callback_CreateLog, sQuery);
  1767. }
  1768. }
  1769.  
  1770. public void DB_Callback_CheckTableVersion(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1771. {
  1772. if (hCallback == INVALID_HANDLE)
  1773. {
  1774. #if defined CTBAN_DEBUG
  1775. LogMessage("Table layout check revealed this error: %s", sError);
  1776. #endif
  1777.  
  1778. // Check specifically for if there was a problem finding the ban_id column
  1779. if (StrContains(sError, "column", false) != SUBSTRING_NOT_FOUND)
  1780. {
  1781. LogMessage("Upgrading CTBan_Log Table to Version Two...");
  1782.  
  1783. char sQuery[QUERY_MAXLENGTH];
  1784. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_TO_V2_DROPKEY, g_sLogTableName);
  1785.  
  1786. #if defined CTBAN_DEBUG
  1787. LogMessage("alter primary key query: %s", sQuery);
  1788. #endif
  1789.  
  1790. SQL_TQuery(gH_BanDatabase, DB_Callback_UpgradeToLogTableTwo, sQuery);
  1791. }
  1792. }
  1793. }
  1794.  
  1795. public void DB_Callback_UpgradeToLogTableTwo(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1796. {
  1797. if (hCallback == INVALID_HANDLE)
  1798. {
  1799. LogError("Error upgrading log table: %s", sError);
  1800. SetFailState("Error while upgrading to Log Table Version Two. Exiting.");
  1801. }
  1802.  
  1803. char sQuery[QUERY_MAXLENGTH];
  1804. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_TO_V2_ADD_BANID, g_sLogTableName);
  1805.  
  1806. #if defined CTBAN_DEBUG
  1807. LogMessage("add ban_id query: %s", sQuery);
  1808. #endif
  1809.  
  1810. SQL_TQuery(gH_BanDatabase, DB_Callback_LogError, sQuery, e_QueryLogTableTwo);
  1811. }
  1812.  
  1813. public void DB_Callback_LogError(Handle hOwner, Handle hCallback, const char[] sError, any eCallback)
  1814. {
  1815. if (hCallback == INVALID_HANDLE)
  1816. {
  1817. LogError("Error: %s", sError);
  1818. }
  1819. else
  1820. {
  1821. switch (eCallback)
  1822. {
  1823. case e_QueryLogTableTwo:
  1824. {
  1825. LogMessage("CTBan_Log Table Successfully Upgraded to Version Two");
  1826. }
  1827. }
  1828. }
  1829. }
  1830.  
  1831. public void DB_Callback_CreateTime(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1832. {
  1833. if (hCallback == INVALID_HANDLE)
  1834. {
  1835. LogError("Error establishing table creation: %s", sError);
  1836. SetFailState("Unable to ascertain creation of table in default database. Exiting.");
  1837. }
  1838. }
  1839.  
  1840. public void DB_Callback_CreateLog(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1841. {
  1842. if (hCallback == INVALID_HANDLE)
  1843. {
  1844. LogError("Error establishing table creation: %s", sError);
  1845. SetFailState("Unable to ascertain creation of table in default database. Exiting.");
  1846. }
  1847.  
  1848. // Check the log table and upgrade to the new version if needed
  1849. char sQuery[QUERY_MAXLENGTH];
  1850.  
  1851. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_V1_CHECK, g_sLogTableName);
  1852.  
  1853. #if defined CTBAN_DEBUG
  1854. LogMessage("check table version query %s", sQuery);
  1855. #endif
  1856.  
  1857. SQL_TQuery(gH_BanDatabase, DB_Callback_CheckTableVersion, sQuery);
  1858. }
  1859.  
  1860. public void CP_Callback_Connect(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1861. {
  1862. if (hCallback == INVALID_HANDLE)
  1863. {
  1864. LogError("Clientprefs database connection failure: %s", sError);
  1865. SetFailState("Error while connecting to clientprefs database. Exiting.");
  1866. }
  1867. else
  1868. {
  1869. gH_CP_DataBase = hCallback;
  1870.  
  1871. // find the Banned_From_CT Cookie id #
  1872. SQL_TQuery(gH_CP_DataBase, CP_Callback_FindCookie, CTBAN_QUERY_CP_FIND_COOKIE_ID);
  1873. }
  1874. }
  1875.  
  1876. public void CP_Callback_FindCookie(Handle hOwner, Handle hCallback, const char[] sError, any data)
  1877. {
  1878. if (hCallback == INVALID_HANDLE)
  1879. {
  1880. LogError("Cookie query failure: %s", sError);
  1881. }
  1882. else
  1883. {
  1884. int iRowCount = SQL_GetRowCount(hCallback);
  1885. if (iRowCount)
  1886. {
  1887. SQL_FetchRow(hCallback);
  1888. int iCookieIDIndex = SQL_FetchInt(hCallback, FIND_COOKIE_CB_FIELD_COOKIE_ID);
  1889. #if defined CTBAN_DEBUG
  1890. LogMessage("found cookie index as %i", iCookieIDIndex);
  1891. #endif
  1892. g_iCookieIndex = iCookieIDIndex;
  1893. }
  1894. else
  1895. {
  1896. LogError("Could not find the cookie index. Rageban functionality disabled.");
  1897. }
  1898. }
  1899. }
  1900.  
  1901. public void OnMapEnd()
  1902. {
  1903. g_bIgnoreOverrideResets = true;
  1904. }
  1905.  
  1906. public void OnMapStart()
  1907. {
  1908. // pre-cache deny sound
  1909. char sCommand[PLATFORM_MAX_PATH];
  1910. GetConVarString(gH_Cvar_SoundName, gS_SoundPath, sizeof(gS_SoundPath));
  1911. if(strcmp(gS_SoundPath, ""))
  1912. {
  1913. PrecacheSound(gS_SoundPath, true);
  1914. Format(sCommand, sizeof(sCommand), "sound/%s", gS_SoundPath);
  1915. AddFileToDownloadsTable(sCommand);
  1916. }
  1917.  
  1918. g_bIgnoreOverrideResets = false;
  1919. }
  1920.  
  1921. public void OnAdminMenuReady(Handle hTopMenu)
  1922. {
  1923. // Block us from being called twice
  1924. if (hTopMenu == gH_TopMenu)
  1925. {
  1926. return;
  1927. }
  1928.  
  1929. // Save the Handle
  1930. gH_TopMenu = hTopMenu;
  1931.  
  1932. // Build the "Player Commands" category
  1933. TopMenuObject player_commands = FindTopMenuCategory(gH_TopMenu, ADMINMENU_PLAYERCOMMANDS);
  1934.  
  1935. if (player_commands != INVALID_TOPMENUOBJECT)
  1936. {
  1937. AddToTopMenu(gH_TopMenu,
  1938. RAGEBAN_COMMAND,
  1939. TopMenuObject_Item,
  1940. AdminMenu_RageBan,
  1941. player_commands,
  1942. RAGEBAN_COMMAND,
  1943. RAGEBAN_ADMIN_LEVEL);
  1944.  
  1945. AddToTopMenu(gH_TopMenu,
  1946. CTBAN_COMMAND,
  1947. TopMenuObject_Item,
  1948. AdminMenu_CTBan,
  1949. player_commands,
  1950. CTBAN_COMMAND,
  1951. CTBAN_ADMIN_LEVEL);
  1952.  
  1953. AddToTopMenu(gH_TopMenu,
  1954. REMOVECTBAN_COMMAND,
  1955. TopMenuObject_Item,
  1956. AdminMenu_RemoveCTBan,
  1957. player_commands,
  1958. REMOVECTBAN_COMMAND,
  1959. UNCTBAN_ADMIN_LEVEL);
  1960.  
  1961. AddToTopMenu(gH_TopMenu,
  1962. FORCECT_COMMAND,
  1963. TopMenuObject_Item,
  1964. AdminMenu_ForceCT,
  1965. player_commands,
  1966. FORCECT_COMMAND,
  1967. FORCECT_ADMIN_LEVEL);
  1968.  
  1969. AddToTopMenu(gH_TopMenu,
  1970. UNFORCECT_COMMAND,
  1971. TopMenuObject_Item,
  1972. AdminMenu_UnForceCT,
  1973. player_commands,
  1974. UNFORCECT_COMMAND,
  1975. UNFORCECT_ADMIN_LEVEL);
  1976. }
  1977. }
  1978.  
  1979. public void AdminMenu_ForceCT(Handle hTopMenu,
  1980. TopMenuAction eAction,
  1981. TopMenuObject eObjectID,
  1982. int iClient,
  1983. char[] sBuffer,
  1984. int iMaxLength)
  1985. {
  1986. if (eAction == TopMenuAction_DisplayOption)
  1987. {
  1988. Format(sBuffer, iMaxLength, "%T", "Force CT Admin Menu", iClient);
  1989. }
  1990. else if (eAction == TopMenuAction_SelectOption)
  1991. {
  1992. DisplayCTBannedPlayerMenu(iClient, e_ForceCT);
  1993. }
  1994. }
  1995.  
  1996. public void AdminMenu_UnForceCT(Handle hTopMenu,
  1997. TopMenuAction eAction,
  1998. TopMenuObject eObjectID,
  1999. int iClient,
  2000. char[] sBuffer,
  2001. int iMaxLength)
  2002. {
  2003. if (eAction == TopMenuAction_DisplayOption)
  2004. {
  2005. Format(sBuffer, iMaxLength, "%T", "UnForce CT Admin Menu", iClient);
  2006. }
  2007. else if (eAction == TopMenuAction_SelectOption)
  2008. {
  2009. DisplayUnForceCTPlayerMenu(iClient);
  2010. }
  2011. }
  2012.  
  2013. public void AdminMenu_RemoveCTBan(Handle hTopMenu,
  2014. TopMenuAction eAction,
  2015. TopMenuObject eObjectID,
  2016. int iClient,
  2017. char[] sBuffer,
  2018. int iMaxLength)
  2019. {
  2020. if (eAction == TopMenuAction_DisplayOption)
  2021. {
  2022. Format(sBuffer, iMaxLength, "%T", "Remove CT Ban Admin Menu", iClient);
  2023. }
  2024. else if (eAction == TopMenuAction_SelectOption)
  2025. {
  2026. DisplayCTBannedPlayerMenu(iClient, e_RemoveCTBan);
  2027. }
  2028. }
  2029.  
  2030. // displaying the list of CT Banned players is used by two commands
  2031. // default is for Remove CT Ban
  2032. // optional boolean is for CTBan List
  2033. void DisplayCTBannedPlayerMenu(int iClient, eCTBanMenuHandler eChoice)
  2034. {
  2035. Handle hMenu = INVALID_HANDLE;
  2036.  
  2037. switch (eChoice)
  2038. {
  2039. case e_RemoveCTBan:
  2040. {
  2041. hMenu = CreateMenu(MenuHandler_RemoveCTBanPlayerList);
  2042. SetMenuTitle(hMenu, "%T", "Remove CT Ban Menu Title", iClient);
  2043. SetMenuExitBackButton(hMenu, true);
  2044. }
  2045. case e_CTBanList:
  2046. {
  2047. hMenu = CreateMenu(MenuHandler_CTBanList);
  2048. SetMenuTitle(hMenu, "%T", "CTBanList Menu Title", iClient);
  2049. SetMenuExitBackButton(hMenu, false);
  2050. }
  2051. case e_ForceCT:
  2052. {
  2053. hMenu = CreateMenu(MenuHandler_ForceCT);
  2054. SetMenuTitle(hMenu, "%T", "Force CT Menu Title", iClient);
  2055. SetMenuExitBackButton(hMenu, true);
  2056. }
  2057. }
  2058.  
  2059. int iCount = ZERO;
  2060. char sUserId[MAX_USERID_LENGTH];
  2061. char sName[MAX_NAME_LENGTH];
  2062.  
  2063. // display only people with existing CTBans
  2064. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  2065. {
  2066. if (IsClientInGame(iIndex))
  2067. {
  2068. if (GetCTBanStatus(iIndex))
  2069. {
  2070. // Do no list people with overrides for Force CT Menu
  2071. if (eChoice == e_ForceCT && g_bA_Temp_CTBan_Override[iIndex])
  2072. {
  2073. continue;
  2074. }
  2075.  
  2076. IntToString(GetClientUserId(iIndex), sUserId, sizeof(sUserId));
  2077. GetClientName(iIndex, sName, sizeof(sName));
  2078.  
  2079. AddMenuItem(hMenu, sUserId, sName);
  2080.  
  2081. iCount++;
  2082. }
  2083. }
  2084. }
  2085.  
  2086. if (!iCount)
  2087. {
  2088. CPrintToChat(iClient, g_sChatBanner, "No matching clients");
  2089. }
  2090.  
  2091. DisplayMenu(hMenu, iClient, MENU_TIME_FOREVER);
  2092. }
  2093.  
  2094. public int MenuHandler_UnForceCT(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2095. {
  2096. if (eAction == MenuAction_End)
  2097. {
  2098. CloseHandle(hMenu);
  2099. }
  2100. else if (eAction == MenuAction_Select)
  2101. {
  2102. char sTargetUserId[MAX_USERID_LENGTH];
  2103. GetMenuItem(hMenu, iMenuChoice, sTargetUserId, sizeof(sTargetUserId));
  2104. int iTargetUserId = StringToInt(sTargetUserId);
  2105. int iTarget = GetClientOfUserId(iTargetUserId);
  2106.  
  2107. if (!iTarget || !IsClientInGame(iTarget))
  2108. {
  2109. CPrintToChat(iClient, g_sChatBanner, "Player no longer available");
  2110. }
  2111. else if (!g_bA_Temp_CTBan_Override[iTarget])
  2112. {
  2113. CPrintToChat(iClient, g_sChatBanner, "Player no longer available");
  2114. }
  2115. else
  2116. {
  2117. UnForceCTActions(iClient, iTarget);
  2118. }
  2119. }
  2120. }
  2121.  
  2122.  
  2123. public int MenuHandler_ForceCT(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2124. {
  2125. if (eAction == MenuAction_End)
  2126. {
  2127. CloseHandle(hMenu);
  2128. }
  2129. else if (eAction == MenuAction_Select)
  2130. {
  2131. char sTargetUserId[MAX_USERID_LENGTH];
  2132. GetMenuItem(hMenu, iMenuChoice, sTargetUserId, sizeof(sTargetUserId));
  2133. int iTargetUserId = StringToInt(sTargetUserId);
  2134. int iTarget = GetClientOfUserId(iTargetUserId);
  2135.  
  2136. if (!iTarget || !IsClientInGame(iTarget))
  2137. {
  2138. CPrintToChat(iClient, g_sChatBanner, "Player no longer available");
  2139. }
  2140. else if (GetClientTeam(iTarget) == CS_TEAM_CT)
  2141. {
  2142. CPrintToChat(iClient, g_sChatBanner, "Unable to target");
  2143. }
  2144. else
  2145. {
  2146. ForceCTActions(iClient, iTarget);
  2147. }
  2148. }
  2149. }
  2150.  
  2151. public int MenuHandler_CTBanList(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2152. {
  2153. if (eAction == MenuAction_End)
  2154. {
  2155. CloseHandle(hMenu);
  2156. }
  2157. else if (eAction == MenuAction_Select)
  2158. {
  2159. char sTargetUserId[MAX_USERID_LENGTH];
  2160. GetMenuItem(hMenu, iMenuChoice, sTargetUserId, sizeof(sTargetUserId));
  2161. int iTargetUserId = StringToInt(sTargetUserId);
  2162. int iTarget = GetClientOfUserId(iTargetUserId);
  2163.  
  2164. if (!iTarget || !IsClientInGame(iTarget))
  2165. {
  2166. CPrintToChat(iClient, g_sChatBanner, "Player no longer available");
  2167. }
  2168. else if (!GetCTBanStatus(iTarget, iClient))
  2169. {
  2170. CPrintToChat(iClient, g_sChatBanner, "Not CT Banned", iTarget);
  2171. }
  2172. else
  2173. {
  2174. ProcessIsBannedTarget(iTarget, iClient);
  2175. }
  2176. }
  2177. }
  2178.  
  2179. public int MenuHandler_RemoveCTBanPlayerList(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2180. {
  2181. if (eAction == MenuAction_End)
  2182. {
  2183. CloseHandle(hMenu);
  2184. }
  2185. else if (eAction == MenuAction_Cancel)
  2186. {
  2187. if (iMenuChoice == MenuCancel_ExitBack && gH_TopMenu != INVALID_HANDLE)
  2188. {
  2189. DisplayTopMenu(gH_TopMenu, iClient, TopMenuPosition_LastCategory);
  2190. }
  2191. }
  2192. else if (eAction == MenuAction_Select)
  2193. {
  2194. char sTargetUserId[MAX_USERID_LENGTH];
  2195. GetMenuItem(hMenu, iMenuChoice, sTargetUserId, sizeof(sTargetUserId));
  2196. int iTargetUserId = StringToInt(sTargetUserId);
  2197. int iTarget = GetClientOfUserId(iTargetUserId);
  2198.  
  2199. if (!iTarget || !IsClientInGame(iTarget))
  2200. {
  2201. CPrintToChat(iClient, g_sChatBanner, "Player no longer available");
  2202. }
  2203. else if (!CanUserTarget(iClient, iTarget))
  2204. {
  2205. CPrintToChat(iClient, g_sChatBanner, "Unable to target");
  2206. }
  2207. else if (!GetCTBanStatus(iTarget, iClient))
  2208. {
  2209. CPrintToChat(iClient, g_sChatBanner, "Not CT Banned", iTarget);
  2210. }
  2211. else
  2212. {
  2213. if (AreClientCookiesCached(iTarget))
  2214. {
  2215. Remove_CTBan(iClient, iTarget);
  2216. }
  2217. else
  2218. {
  2219. ReplyToCommand(iClient, g_sChatBanner, "Cookie Status Unavailable");
  2220. }
  2221. }
  2222. }
  2223. }
  2224.  
  2225. public void AdminMenu_CTBan(Handle hTopMenu,
  2226. TopMenuAction eAction,
  2227. TopMenuObject eObjectID,
  2228. int iClient,
  2229. char[] sBuffer,
  2230. int iMaxLength)
  2231. {
  2232. if (eAction == TopMenuAction_DisplayOption)
  2233. {
  2234. Format(sBuffer, iMaxLength, "%T", "CT Ban Admin Menu", iClient);
  2235. }
  2236. else if (eAction == TopMenuAction_SelectOption)
  2237. {
  2238. DisplayCTBanPlayerMenu(iClient);
  2239. }
  2240. }
  2241.  
  2242. void DisplayCTBanPlayerMenu(int iClient)
  2243. {
  2244. Handle hMenu = CreateMenu(MenuHandler_CTBanPlayerList);
  2245.  
  2246. SetMenuTitle(hMenu, "%T", "CT Ban Menu Title", iClient);
  2247. SetMenuExitBackButton(hMenu, true);
  2248.  
  2249. int iCount = ZERO;
  2250. char sUserId[MAX_USERID_LENGTH];
  2251. char sName[MAX_NAME_LENGTH];
  2252.  
  2253. // filter away those with current CTBans
  2254. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  2255. {
  2256. if (IsClientInGame(iIndex))
  2257. {
  2258. if (!GetCTBanStatus(iIndex))
  2259. {
  2260. IntToString(GetClientUserId(iIndex), sUserId, sizeof(sUserId));
  2261. GetClientName(iIndex, sName, sizeof(sName));
  2262.  
  2263. AddMenuItem(hMenu, sUserId, sName);
  2264.  
  2265. iCount++;
  2266. }
  2267. }
  2268. }
  2269.  
  2270. if (!iCount)
  2271. {
  2272. CPrintToChat(iClient, g_sChatBanner, "No Targets");
  2273. }
  2274.  
  2275. DisplayMenu(hMenu, iClient, MENU_TIME_FOREVER);
  2276. }
  2277.  
  2278. void DisplayCTBanTimeMenu(int iClient, int iTargetUserId)
  2279. {
  2280. Handle hMenu = CreateMenu(MenuHandler_CTBanTimeList);
  2281.  
  2282. SetMenuTitle(hMenu, "%T", "CT Ban Length Menu", iClient, GetClientOfUserId(iTargetUserId));
  2283. SetMenuExitBackButton(hMenu, true);
  2284.  
  2285. char sUserId[MAX_USERID_LENGTH];
  2286. IntToString(iTargetUserId, sUserId, sizeof(sUserId));
  2287. AddMenuItem(hMenu, sUserId, "", ITEMDRAW_IGNORE);
  2288.  
  2289. if (gH_KV_BanLengths != INVALID_HANDLE)
  2290. {
  2291. char sBanDuration[MAX_TIME_ARG_LENGTH];
  2292. char sDurationDescription[MAX_TIME_INFO_STR_LENGTH];
  2293.  
  2294. KvGotoFirstSubKey(gH_KV_BanLengths, false);
  2295. do
  2296. {
  2297. KvGetSectionName(gH_KV_BanLengths, sBanDuration, sizeof(sBanDuration));
  2298. KvGetString(gH_KV_BanLengths, NULL_STRING, sDurationDescription, sizeof(sDurationDescription));
  2299.  
  2300. AddMenuItem(hMenu, sBanDuration, sDurationDescription);
  2301. }
  2302. while (KvGotoNextKey(gH_KV_BanLengths, false));
  2303.  
  2304. KvRewind(gH_KV_BanLengths);
  2305. }
  2306. else
  2307. {
  2308. AddMenuItem(hMenu, "0", "Permanent");
  2309. AddMenuItem(hMenu, "5", "5 Minutes");
  2310. // Only add 6 items in CS:GO menus so we don't paginate
  2311. if (g_EngineVersion != Engine_CSGO)
  2312. {
  2313. AddMenuItem(hMenu, "10", "10 Minutes");
  2314. }
  2315. AddMenuItem(hMenu, "30", "30 Minutes");
  2316. AddMenuItem(hMenu, "60", "1 Hour");
  2317. AddMenuItem(hMenu, "120", "2 Hours");
  2318. AddMenuItem(hMenu, "240", "4 Hours");
  2319. }
  2320.  
  2321. DisplayMenu(hMenu, iClient, MENU_TIME_FOREVER);
  2322. }
  2323.  
  2324. void DisplayCTBanReasonMenu(int iClient, int iTargetUserId, int iMinutesToBan)
  2325. {
  2326. Handle hMenu = CreateMenu(MenuHandler_CTBanReasonList);
  2327.  
  2328. SetMenuTitle(hMenu, "%T", "CT Ban Reason Menu", iClient, GetClientOfUserId(iTargetUserId));
  2329. SetMenuExitBackButton(hMenu, true);
  2330.  
  2331. char sTargetUserId[MAX_USERID_LENGTH];
  2332. IntToString(iTargetUserId, sTargetUserId, sizeof(sTargetUserId));
  2333. AddMenuItem(hMenu, sTargetUserId, "", ITEMDRAW_IGNORE);
  2334.  
  2335. char sTimeInMinutes[MAX_TIME_ARG_LENGTH];
  2336. IntToString(iMinutesToBan, sTimeInMinutes, sizeof(sTimeInMinutes));
  2337. AddMenuItem(hMenu, sTimeInMinutes, "", ITEMDRAW_IGNORE);
  2338.  
  2339. int iNumManualReasons = GetArraySize(gH_DArray_Reasons);
  2340.  
  2341. char sMenuReason[FIELD_REASON_MAXLENGTH];
  2342. char sMenuInt[MAX_MENU_INT_CHOICE_LENGTH];
  2343.  
  2344. if (iNumManualReasons > ZERO)
  2345. {
  2346. for (int iLineNumber = ZERO; iLineNumber < iNumManualReasons; iLineNumber++)
  2347. {
  2348. GetArrayString(gH_DArray_Reasons, iLineNumber, sMenuReason, sizeof(sMenuReason));
  2349. IntToString(iLineNumber, sMenuInt, sizeof(sMenuInt));
  2350. AddMenuItem(hMenu, sMenuInt, sMenuReason);
  2351. }
  2352. }
  2353. else
  2354. {
  2355. // Only display 6 reasons in CS:GO by default to avoid pagination
  2356. // Freekill Massacre is a redundant reason with Freekilling "CT Ban Reason 5"
  2357. if (g_EngineVersion != Engine_CSGO)
  2358. {
  2359. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 1", iClient);
  2360. AddMenuItem(hMenu, "1", sMenuReason);
  2361. }
  2362. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 2", iClient);
  2363. AddMenuItem(hMenu, "2", sMenuReason);
  2364. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 3", iClient);
  2365. AddMenuItem(hMenu, "3", sMenuReason);
  2366. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 4", iClient);
  2367. AddMenuItem(hMenu, "4", sMenuReason);
  2368. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 5", iClient);
  2369. AddMenuItem(hMenu, "5", sMenuReason);
  2370. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 6", iClient);
  2371. AddMenuItem(hMenu, "6", sMenuReason);
  2372. Format(sMenuReason, sizeof(sMenuReason), "%T", "CT Ban Reason 7", iClient);
  2373. AddMenuItem(hMenu, "7", sMenuReason);
  2374. }
  2375.  
  2376. DisplayMenu(hMenu, iClient, MENU_TIME_FOREVER);
  2377. }
  2378.  
  2379. public int MenuHandler_CTBanReasonList(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2380. {
  2381. if (eAction == MenuAction_End)
  2382. {
  2383. CloseHandle(hMenu);
  2384. }
  2385. else if (eAction == MenuAction_Cancel)
  2386. {
  2387. if (iMenuChoice == MenuCancel_ExitBack && gH_TopMenu != INVALID_HANDLE)
  2388. {
  2389. DisplayTopMenu(gH_TopMenu, iClient, TopMenuPosition_LastCategory);
  2390. }
  2391. }
  2392. else if (eAction == MenuAction_Select)
  2393. {
  2394. char sTargetUserId[MAX_USERID_LENGTH];
  2395. GetMenuItem(hMenu, MENUCHOICE_USERID, sTargetUserId, sizeof(sTargetUserId));
  2396. int iTargetUserId = StringToInt(sTargetUserId);
  2397.  
  2398. char sTimeInMinutes[MAX_TIME_ARG_LENGTH];
  2399. GetMenuItem(hMenu, MENUCHOICE_TIME, sTimeInMinutes, sizeof(sTimeInMinutes));
  2400. int iMinutesToBan = StringToInt(sTimeInMinutes);
  2401.  
  2402. char sBanChoice[MAX_REASON_MENU_CHOICE_LENGTH];
  2403. GetMenuItem(hMenu, iMenuChoice, sBanChoice, sizeof(sBanChoice));
  2404. int iBanReason = StringToInt(sBanChoice);
  2405.  
  2406. int iTarget = GetClientOfUserId(iTargetUserId);
  2407.  
  2408. if (!GetCTBanStatus(iTarget))
  2409. {
  2410. PerformCTBan(iTarget, iClient, iMinutesToBan, iBanReason);
  2411. }
  2412. else
  2413. {
  2414. CPrintToChat(iClient, g_sChatBanner, "Already CT Banned", iTarget);
  2415. }
  2416. }
  2417. }
  2418.  
  2419. public int MenuHandler_CTBanPlayerList(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2420. {
  2421. if (eAction == MenuAction_End)
  2422. {
  2423. CloseHandle(hMenu);
  2424. }
  2425. else if (eAction == MenuAction_Cancel)
  2426. {
  2427. if (iMenuChoice == MenuCancel_ExitBack && gH_TopMenu != INVALID_HANDLE)
  2428. {
  2429. DisplayTopMenu(gH_TopMenu, iClient, TopMenuPosition_LastCategory);
  2430. }
  2431. }
  2432. else if (eAction == MenuAction_Select)
  2433. {
  2434. char sTargetUserId[MAX_USERID_LENGTH];
  2435. GetMenuItem(hMenu, iMenuChoice, sTargetUserId, sizeof(sTargetUserId));
  2436. int iTargetUserId = StringToInt(sTargetUserId);
  2437. int iTarget = GetClientOfUserId(iTargetUserId);
  2438.  
  2439. if (!iTarget || !IsClientInGame(iTarget))
  2440. {
  2441. CPrintToChat(iClient, g_sChatBanner, "Player no longer available");
  2442. }
  2443. else if (!CanUserTarget(iClient, iTarget))
  2444. {
  2445. CPrintToChat(iClient, g_sChatBanner, "Unable to target");
  2446. }
  2447. else if (GetCTBanStatus(iTarget, iClient))
  2448. {
  2449. CPrintToChat(iClient, g_sChatBanner, "Already CT Banned", iTarget);
  2450. }
  2451. else
  2452. {
  2453. DisplayCTBanTimeMenu(iClient, iTargetUserId);
  2454. }
  2455. }
  2456. }
  2457.  
  2458. public int MenuHandler_CTBanTimeList(Handle hMenu, MenuAction eAction, int iClient, int iMenuChoice)
  2459. {
  2460. if (eAction == MenuAction_End)
  2461. {
  2462. CloseHandle(hMenu);
  2463. }
  2464. else if (eAction == MenuAction_Cancel)
  2465. {
  2466. if (iMenuChoice == MenuCancel_ExitBack && gH_TopMenu != INVALID_HANDLE)
  2467. {
  2468. DisplayTopMenu(gH_TopMenu, iClient, TopMenuPosition_LastCategory);
  2469. }
  2470. }
  2471. else if (eAction == MenuAction_Select)
  2472. {
  2473. char sTargetUserId[MAX_USERID_LENGTH];
  2474. GetMenuItem(hMenu, MENUCHOICE_USERID, sTargetUserId, sizeof(sTargetUserId));
  2475. int iTargetUserId = StringToInt(sTargetUserId);
  2476.  
  2477. char sTimeInMinutes[MAX_TIME_ARG_LENGTH];
  2478. GetMenuItem(hMenu, iMenuChoice, sTimeInMinutes, sizeof(sTimeInMinutes));
  2479. int iMinutesToBan = StringToInt(sTimeInMinutes);
  2480.  
  2481. DisplayCTBanReasonMenu(iClient, iTargetUserId, iMinutesToBan);
  2482. }
  2483. }
  2484.  
  2485. public void OnClientConnected(int iClient)
  2486. {
  2487. g_bA_Temp_CTBan_Override[iClient] = false;
  2488. }
  2489.  
  2490. public void OnClientPostAdminCheck(int iClient)
  2491. {
  2492. CreateTimer(COOKIE_INIT_CHECK_TIME, Timer_CheckBanCookies, iClient, TIMER_FLAG_NO_MAPCHANGE);
  2493. }
  2494.  
  2495. public void OnClientDisconnect(int iClient)
  2496. {
  2497. char sDisconnectSteamID[FIELD_AUTHID_MAXLENGTH];
  2498. GetClientAuthId(iClient, AuthId_Steam2, sDisconnectSteamID, sizeof(sDisconnectSteamID));
  2499.  
  2500. // add information to rage ban list
  2501. char sName[MAX_TARGET_LENGTH];
  2502. GetClientName(iClient, sName, sizeof(sName));
  2503.  
  2504. // add information to array
  2505. // if information isn't already in the arrays then add it
  2506. if (FindStringInArray(gA_DSteamIDs, sDisconnectSteamID) == VALUE_NOT_FOUND_IN_ARRAY)
  2507. {
  2508. g_bRageBanArrayChanged = true;
  2509.  
  2510. PushArrayString(gA_DNames, sName);
  2511. PushArrayString(gA_DSteamIDs, sDisconnectSteamID);
  2512.  
  2513. if (GetArraySize(gA_DNames) >= (g_EngineVersion == Engine_CSGO ? CSGO_MAX_PAGE_MENU_ITEMS : CSS_MAX_PAGE_MENU_ITEMS))
  2514. {
  2515. // Remove the oldest entry
  2516. RemoveFromArray(gA_DNames, ZERO);
  2517. RemoveFromArray(gA_DSteamIDs, ZERO);
  2518. }
  2519. }
  2520.  
  2521. // check if they were in the timed array
  2522. int iBannedArrayIndex = FindValueInArray(gA_TimedBanLocalList, iClient);
  2523. if (iBannedArrayIndex != VALUE_NOT_FOUND_IN_ARRAY)
  2524. {
  2525. // remove them from the local array
  2526. RemoveFromArray(gA_TimedBanLocalList, iBannedArrayIndex);
  2527.  
  2528. // make a datapack for the next query
  2529. Handle hDisconnectPack = CreateDataPack();
  2530. WritePackCell(hDisconnectPack, iClient);
  2531. WritePackString(hDisconnectPack, sDisconnectSteamID);
  2532.  
  2533. // update steam array
  2534. char sQuery[QUERY_MAXLENGTH];
  2535. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_SELECT_BANTIME, g_sTimesTableName, sDisconnectSteamID);
  2536. SQL_TQuery(gH_BanDatabase, DB_Callback_ClientDisconnect, sQuery, hDisconnectPack);
  2537. }
  2538.  
  2539. // if there are no admins left then swap all the !forcect players back to T team!
  2540. bool bAdminPresent = false;
  2541. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  2542. {
  2543. if (IsClientInGame(iIndex))
  2544. {
  2545. if (CheckCommandAccess(iIndex, FORCECT_COMMAND, ADMFLAG_SLAY))
  2546. {
  2547. bAdminPresent = true;
  2548. break;
  2549. }
  2550. }
  2551. }
  2552.  
  2553. // if no admins are present then move *everyone* back to Terrorist team who has an override
  2554. if (!bAdminPresent && !g_bIgnoreOverrideResets)
  2555. {
  2556. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  2557. {
  2558. UnForceCTActions(ZERO, iIndex, true);
  2559. }
  2560. }
  2561. }
  2562.  
  2563. public void DB_Callback_ClientDisconnect(Handle hOwner, Handle hCallback, const char[] sError, any hDataPack)
  2564. {
  2565. if (hCallback == INVALID_HANDLE)
  2566. {
  2567. LogError("Error with query on client disconnect: %s", sError);
  2568. CloseHandle(hDataPack);
  2569. }
  2570. else
  2571. {
  2572. ResetPack(hDataPack);
  2573. int iClient = ReadPackCell(hDataPack);
  2574. char sAuthID[FIELD_AUTHID_MAXLENGTH];
  2575. ReadPackString(hDataPack, sAuthID, sizeof(sAuthID));
  2576.  
  2577. int iRowCount = SQL_GetRowCount(hCallback);
  2578. if (iRowCount)
  2579. {
  2580. #if defined CTBAN_DEBUG
  2581. SQL_FetchRow(hCallback);
  2582. int iBanTimeRemaining = SQL_FetchInt(hCallback, CLIENT_DISCONNECT_CB_FIELD_TIMELEFT);
  2583.  
  2584. if (IsClientInGame(iClient))
  2585. {
  2586. LogMessage("SQL: %N disconnected with %i time remaining on ban", iClient, iBanTimeRemaining);
  2587. }
  2588. else
  2589. {
  2590. LogMessage("SQL: %i client index disconnected with %i time remaining on ban", iClient, iBanTimeRemaining);
  2591. }
  2592. #endif
  2593.  
  2594. char sQuery[QUERY_MAXLENGTH];
  2595. if (gA_LocalTimeRemaining[iClient] <= ZERO)
  2596. {
  2597. // remove steam array
  2598. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_DELETE, g_sTimesTableName, sAuthID);
  2599. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  2600.  
  2601. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_EXPIRE, g_sLogTableName, sAuthID);
  2602. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  2603. }
  2604. else
  2605. {
  2606. // update the time
  2607. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_UPDATE, g_sTimesTableName, gA_LocalTimeRemaining[iClient], sAuthID);
  2608. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  2609.  
  2610. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_UPDATE, g_sLogTableName, gA_LocalTimeRemaining[iClient], sAuthID);
  2611. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  2612. }
  2613. }
  2614. }
  2615. }
  2616.  
  2617. public void DB_Callback_DisconnectAction(Handle hOwner, Handle hCallback, const char[] sError, any data)
  2618. {
  2619. if (hCallback == INVALID_HANDLE)
  2620. {
  2621. LogError("Error with updating/deleting record after client disconnect: %s", sError);
  2622. }
  2623. }
  2624.  
  2625. public Action Timer_CheckBanCookies(Handle hTimer, any iClient)
  2626. {
  2627. if (AreClientCookiesCached(iClient))
  2628. {
  2629. ProcessBanCookies(iClient);
  2630. }
  2631. else if(IsClientInGame(iClient))
  2632. {
  2633. CreateTimer(COOKIE_RESCAN_TIME, Timer_CheckBanCookies, iClient, TIMER_FLAG_NO_MAPCHANGE);
  2634. }
  2635. }
  2636.  
  2637. void ProcessBanCookies(int iClient)
  2638. {
  2639. if(iClient && IsClientInGame(iClient))
  2640. {
  2641. if (GetCTBanStatus(iClient))
  2642. {
  2643. // check to see if they joined CT
  2644. if (GetClientTeam(iClient) == CS_TEAM_CT)
  2645. {
  2646. EnforceCTBan(iClient);
  2647. }
  2648. }
  2649. }
  2650. }
  2651.  
  2652. public Action Command_UnCTBan(int iClient, int iArgs)
  2653. {
  2654. if (!iClient && !iArgs)
  2655. {
  2656. char sCommandName[MAX_UNBAN_CMD_LENGTH];
  2657. // position 0 retrieves the command name. Could be unctban or removectban.
  2658. GetCmdArg(ARG_ZERO_GET_COMMAND_NAME, sCommandName, sizeof(sCommandName));
  2659. StrCat(sCommandName, sizeof(sCommandName), " <player>");
  2660.  
  2661. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", sCommandName);
  2662. return Plugin_Handled;
  2663. }
  2664.  
  2665. if (!iArgs)
  2666. {
  2667. DisplayCTBannedPlayerMenu(iClient, e_RemoveCTBan);
  2668. }
  2669. else
  2670. {
  2671. char sTarget[MAX_NAME_LENGTH];
  2672. GetCmdArg(UNCTBAN_ARG_TARGET, sTarget, sizeof(sTarget));
  2673.  
  2674. char sClientName[MAX_TARGET_LENGTH];
  2675. int aiTargetList[MAXPLAYERS];
  2676. int iTargetCount;
  2677. bool b_tn_is_ml;
  2678. iTargetCount = ProcessTargetString(sTarget, iClient, aiTargetList, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sClientName, sizeof(sClientName), b_tn_is_ml);
  2679.  
  2680. if (iTargetCount < ONE)
  2681. {
  2682. ReplyToTargetError(iClient, iTargetCount);
  2683. }
  2684. else
  2685. {
  2686. int iTarget = aiTargetList[ZERO];
  2687. // check if the cookies are ready
  2688. if (AreClientCookiesCached(iTarget))
  2689. {
  2690. Remove_CTBan(iClient, iTarget);
  2691. }
  2692. else
  2693. {
  2694. ReplyToCommand(iClient, g_sChatBanner, "Cookie Status Unavailable");
  2695. }
  2696. }
  2697. }
  2698.  
  2699. return Plugin_Handled;
  2700. }
  2701.  
  2702. void Remove_CTBan(int iAdmin, int iTarget, bool bExpired=false)
  2703. {
  2704. if (GetCTBanStatus(iTarget))
  2705. {
  2706. char sTargetSteam[FIELD_AUTHID_MAXLENGTH];
  2707. GetClientAuthId(iTarget, AuthId_Steam2, sTargetSteam, sizeof(sTargetSteam));
  2708.  
  2709. char sQuery[QUERY_MAXLENGTH];
  2710. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_EXPIRE, g_sLogTableName, sTargetSteam);
  2711.  
  2712. #if defined CTBAN_DEBUG
  2713. LogMessage("log query: %s", sQuery);
  2714. #endif
  2715.  
  2716. SQL_TQuery(gH_BanDatabase, DB_Callback_RemoveCTBan, sQuery, iTarget);
  2717.  
  2718. LogMessage("%N has removed the CT ban on %N (%s).", iAdmin, iTarget, sTargetSteam);
  2719.  
  2720. if (!bExpired)
  2721. {
  2722. ShowActivity2(iAdmin, "", g_sChatBanner, "CT Ban Removed", iTarget);
  2723. }
  2724. else
  2725. {
  2726. ShowActivity2(iAdmin, "", g_sChatBanner, "CT Ban Auto Removed", iTarget);
  2727. }
  2728.  
  2729. // delete from the timedban database if there was one
  2730. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_DELETE, g_sTimesTableName, sTargetSteam);
  2731.  
  2732. SQL_TQuery(gH_BanDatabase, DB_Callback_RemoveCTBan, sQuery, iTarget);
  2733. }
  2734. else
  2735. {
  2736. ReplyToCommand(iAdmin, g_sChatBanner, "Not CT Banned", iTarget);
  2737. }
  2738.  
  2739. // error on side of caution and just set cookie to 0 regardless of what it was
  2740. SetClientCookie(iTarget, g_CT_Cookie, COOKIE_UNBANNED_STRING);
  2741.  
  2742. g_bA_Temp_CTBan_Override[iTarget] = false;
  2743.  
  2744. Call_StartForward(g_hFrwd_OnUnCTBan);
  2745. Call_PushCell(iTarget);
  2746. Call_PushCell(iAdmin);
  2747. Call_Finish();
  2748. }
  2749.  
  2750. public void DB_Callback_RemoveCTBan(Handle hOwner, Handle hCallback, const char[] sError, any iClient)
  2751. {
  2752. if (hCallback == INVALID_HANDLE)
  2753. {
  2754. LogError("Error handling steamID after CT ban removal: %s", sError);
  2755. }
  2756. else
  2757. {
  2758. #if defined CTBAN_DEBUG
  2759. if (iClient > ZERO && IsClientInGame(iClient))
  2760. {
  2761. LogMessage("CTBan on %N was removed in SQL", iClient);
  2762. }
  2763. else
  2764. {
  2765. LogMessage("CTBan on --- was removed in SQL");
  2766. }
  2767. #endif
  2768. }
  2769. }
  2770.  
  2771. public Action Command_CTBan(int iClient, int iArgs)
  2772. {
  2773. if (!iClient && (iArgs < (GetConVarBool(gH_Cvar_Force_Reason) ? CTBAN_ARG_REASON : CTBAN_ARG_TIME)))
  2774. {
  2775. if (GetConVarBool(gH_Cvar_Force_Reason))
  2776. {
  2777. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_ctban <player> <time> <reason>");
  2778. }
  2779. else
  2780. {
  2781. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_ctban <player> <time> <optional:reason>");
  2782. }
  2783.  
  2784. return Plugin_Handled;
  2785. }
  2786.  
  2787. if (!iArgs)
  2788. {
  2789. DisplayCTBanPlayerMenu(iClient);
  2790. return Plugin_Handled;
  2791. }
  2792.  
  2793. char sTarget[MAX_NAME_LENGTH];
  2794. GetCmdArg(CTBAN_ARG_PLAYER, sTarget, sizeof(sTarget));
  2795.  
  2796. char sClientName[MAX_TARGET_LENGTH];
  2797. int aiTargetList[MAXPLAYERS];
  2798. int iTargetCount;
  2799. bool b_tn_is_ml;
  2800. iTargetCount = ProcessTargetString(sTarget, iClient, aiTargetList, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sClientName, sizeof(sClientName), b_tn_is_ml);
  2801.  
  2802. // target count 0 or less is an error condition
  2803. if (iTargetCount < ONE)
  2804. {
  2805. ReplyToTargetError(iClient, iTargetCount);
  2806. }
  2807. else
  2808. {
  2809. int iTarget = aiTargetList[ZERO];
  2810.  
  2811. if(iTarget && IsClientInGame(iTarget))
  2812. {
  2813. if (GetCTBanStatus(iTarget, iClient))
  2814. {
  2815. ReplyToCommand(iClient, g_sChatBanner, "Already CT Banned", iTarget);
  2816. }
  2817. else
  2818. {
  2819. if (iArgs == CTBAN_ARG_PLAYER)
  2820. {
  2821. int iTargetUserId = GetClientUserId(iTarget);
  2822. DisplayCTBanTimeMenu(iClient, iTargetUserId);
  2823. return Plugin_Handled;
  2824. }
  2825.  
  2826. char sBanTime[MAX_TIME_ARG_LENGTH];
  2827. GetCmdArg(CTBAN_ARG_TIME, sBanTime, sizeof(sBanTime));
  2828. int iBanTime = StringToInt(sBanTime);
  2829.  
  2830. if (GetConVarBool(gH_Cvar_Force_Reason) && iArgs == CTBAN_ARG_TIME)
  2831. {
  2832. int iTargetUserId = GetClientUserId(iTarget);
  2833. DisplayCTBanReasonMenu(iClient, iTargetUserId, iBanTime);
  2834. return Plugin_Handled;
  2835. }
  2836.  
  2837. char sReasonStr[FIELD_REASON_MAXLENGTH];
  2838. char sArgPart[FIELD_REASON_MAXLENGTH];
  2839. for (int iArg = CTBAN_ARG_REASON; iArg <= iArgs; iArg++)
  2840. {
  2841. GetCmdArg(iArg, sArgPart, sizeof(sArgPart));
  2842. Format(sReasonStr, sizeof(sReasonStr), "%s %s", sReasonStr, sArgPart);
  2843. }
  2844. // Remove the space at the beginning
  2845. TrimString(sReasonStr);
  2846.  
  2847. if (GetConVarBool(gH_Cvar_Force_Reason) && !strlen(sReasonStr))
  2848. {
  2849. ReplyToCommand(iClient, g_sChatBanner, "Reason Required");
  2850. }
  2851. else
  2852. {
  2853. PerformCTBan(iTarget, iClient, iBanTime, _, sReasonStr);
  2854. }
  2855. }
  2856. }
  2857. }
  2858. return Plugin_Handled;
  2859. }
  2860.  
  2861. void PerformCTBan(int iClient, int iAdmin, int iBanTime = CTBAN_PERM_BAN_LENGTH, int iReason = CTBAN_NO_REASON_GIVEN, char[] sManualReason="")
  2862. {
  2863. // set cookie to ban
  2864. SetClientCookie(iClient, g_CT_Cookie, COOKIE_BANNED_STRING);
  2865.  
  2866. char sTargetAuthID[FIELD_AUTHID_MAXLENGTH];
  2867. GetClientAuthId(iClient, AuthId_Steam2, sTargetAuthID, sizeof(sTargetAuthID));
  2868.  
  2869. // check if they're on CT team
  2870. if (GetClientTeam(iClient) == CS_TEAM_CT)
  2871. {
  2872. EnforceCTBan(iClient);
  2873. }
  2874.  
  2875. char sReason[FIELD_REASON_MAXLENGTH];
  2876. if (strlen(sManualReason) > ZERO)
  2877. {
  2878. Format(sReason, sizeof(sReason), "%s", sManualReason);
  2879. }
  2880. // or else they picked a reason # from the admin menu
  2881. else
  2882. {
  2883. // Check if we are using the translated phrase reasons or the manual file reasons
  2884. int iNumManualReasons = GetArraySize(gH_DArray_Reasons);
  2885.  
  2886. // manual file reasons
  2887. if (iNumManualReasons > ZERO)
  2888. {
  2889. if (iReason == CTBAN_NO_REASON_GIVEN)
  2890. {
  2891. Format(sReason, sizeof(sReason), "No reason given.");
  2892. }
  2893. else
  2894. {
  2895. GetArrayString(gH_DArray_Reasons, iReason, sReason, sizeof(sReason));
  2896. }
  2897. }
  2898. // translated phrases reasons
  2899. else
  2900. {
  2901. switch (iReason)
  2902. {
  2903. case ONE:
  2904. {
  2905. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 1", iAdmin);
  2906. }
  2907. case TWO:
  2908. {
  2909. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 2", iAdmin);
  2910. }
  2911. case THREE:
  2912. {
  2913. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 3", iAdmin);
  2914. }
  2915. case FOUR:
  2916. {
  2917. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 4", iAdmin);
  2918. }
  2919. case FIVE:
  2920. {
  2921. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 5", iAdmin);
  2922. }
  2923. case SIX:
  2924. {
  2925. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 6", iAdmin);
  2926. }
  2927. case SEVEN:
  2928. {
  2929. Format(sReason, sizeof(sReason), "%T", "CT Ban Reason 7", iAdmin);
  2930. }
  2931. default:
  2932. {
  2933. Format(sReason, sizeof(sReason), "No reason given.");
  2934. }
  2935. }
  2936. }
  2937. }
  2938.  
  2939. int iTimeStamp = GetTime();
  2940.  
  2941. char sTempName[FIELD_NAME_MAXLENGTH];
  2942. char sQuery[QUERY_MAXLENGTH];
  2943.  
  2944. char sEscapedPerpName[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  2945. Format(sTempName, sizeof(sTempName), "%N", iClient);
  2946. SQL_EscapeString(gH_BanDatabase, sTempName, sEscapedPerpName, sizeof(sEscapedPerpName));
  2947.  
  2948. char sEscapedReason[MAX_SAFE_ESCAPE_QUERY(FIELD_REASON_MAXLENGTH)];
  2949. SQL_EscapeString(gH_BanDatabase, sReason, sEscapedReason, sizeof(sEscapedReason));
  2950.  
  2951. if(iAdmin && IsClientInGame(iAdmin))
  2952. {
  2953. char sAdminAuthID[FIELD_AUTHID_MAXLENGTH];
  2954. GetClientAuthId(iAdmin, AuthId_Steam2, sAdminAuthID, sizeof(sAdminAuthID));
  2955.  
  2956. char sEscapedAdminName[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  2957. Format(sTempName, sizeof(sTempName), "%N", iAdmin);
  2958. SQL_EscapeString(gH_BanDatabase, sTempName, sEscapedAdminName, sizeof(sEscapedAdminName));
  2959.  
  2960. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_INSERT, g_sLogTableName, iTimeStamp, sTargetAuthID, sEscapedPerpName, sAdminAuthID, sEscapedAdminName, iBanTime, iBanTime, sEscapedReason);
  2961.  
  2962. #if defined CTBAN_DEBUG
  2963. LogMessage("log query: %s", sQuery);
  2964. #endif
  2965.  
  2966. SQL_TQuery(gH_BanDatabase, DB_Callback_CTBan, sQuery, iClient);
  2967.  
  2968. LogMessage("%N (%s) has issued a CT ban on %N (%s) for %d minutes for %s.", iAdmin, sAdminAuthID, iClient, sTargetAuthID, iBanTime, sReason);
  2969. }
  2970. else
  2971. {
  2972. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_INSERT, g_sLogTableName, iTimeStamp, sTargetAuthID, sEscapedPerpName, CONSOLE_AUTHID, CONSOLE_USER_NAME, iBanTime, iBanTime, sEscapedReason);
  2973.  
  2974. #if defined CTBAN_DEBUG
  2975. LogMessage("log query: %s", sQuery);
  2976. #endif
  2977.  
  2978. SQL_TQuery(gH_BanDatabase, DB_Callback_CTBan, sQuery, iClient);
  2979.  
  2980. LogMessage("Console has issued a CT ban on %N (%s) for %d.", iClient, sTargetAuthID, iBanTime);
  2981. }
  2982.  
  2983. // check if there is a time
  2984. if (iBanTime > CTBAN_PERM_BAN_LENGTH)
  2985. {
  2986. ShowActivity2(iAdmin, "", g_sChatBanner, "Temporary CT Ban and Reason", iClient, iBanTime, sReason);
  2987. // save in local quick-access array
  2988. PushArrayCell(gA_TimedBanLocalList, iClient);
  2989. gA_LocalTimeRemaining[iClient] = iBanTime;
  2990.  
  2991. // save in long-term database (already guaranteed to run only once per steam ID)
  2992. switch (g_eDatabaseType)
  2993. {
  2994. case e_SQLite:
  2995. {
  2996. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_INSERT_SQLITE, g_sTimesTableName, sTargetAuthID, iBanTime);
  2997. }
  2998. default:
  2999. {
  3000. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_INSERT_MYSQL, g_sTimesTableName, sTargetAuthID, iBanTime, iBanTime);
  3001. }
  3002. }
  3003.  
  3004. #if defined CTBAN_DEBUG
  3005. LogMessage("ctban query: %s", sQuery);
  3006. #endif
  3007.  
  3008. SQL_TQuery(gH_BanDatabase, DB_Callback_CTBan, sQuery, iClient);
  3009. }
  3010. else
  3011. {
  3012. ShowActivity2(iAdmin, "", g_sChatBanner, "Permanent CT Ban and Reason", iClient, sReason);
  3013. }
  3014.  
  3015. Call_StartForward(g_hFrwd_OnCTBan);
  3016. Call_PushCell(iClient);
  3017. Call_PushCell(iAdmin);
  3018. Call_PushCell(iBanTime);
  3019. Call_PushString(sReason);
  3020. Call_Finish();
  3021. }
  3022.  
  3023. public void DB_Callback_CTBan(Handle hOwner, Handle hCallback, const char[] sError, any iClient)
  3024. {
  3025. if (hCallback == INVALID_HANDLE)
  3026. {
  3027. LogError("Error writing CTBan to Timed Ban database: %s", sError);
  3028. }
  3029. else
  3030. {
  3031. #if defined CTBAN_DEBUG
  3032. if (iClient > ZERO && IsClientInGame(iClient))
  3033. {
  3034. LogMessage("SQL CTBan: Updated database with CT Ban for %N", iClient);
  3035. }
  3036. #endif
  3037. }
  3038. }
  3039.  
  3040. public Action Command_Change_CTBan_Time(int iClient, int iArgs)
  3041. {
  3042. if (iArgs != CHANGE_TIME_ARG_TIME)
  3043. {
  3044. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_change_ctban_time <player> <time>");
  3045. return Plugin_Handled;
  3046. }
  3047.  
  3048. char sTarget[MAX_TARGET_LENGTH];
  3049. GetCmdArg(CHANGE_TIME_ARG_TARGET, sTarget, sizeof(sTarget));
  3050.  
  3051. char sClientName[MAX_TARGET_LENGTH];
  3052. int aiTargetList[MAXPLAYERS];
  3053. int iTargetCount;
  3054. bool b_tn_is_ml;
  3055. iTargetCount = ProcessTargetString(sTarget, iClient, aiTargetList, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sClientName, sizeof(sClientName), b_tn_is_ml);
  3056. if (iTargetCount < ONE)
  3057. {
  3058. ReplyToTargetError(iClient, iTargetCount);
  3059. }
  3060. else
  3061. {
  3062. int iTarget = aiTargetList[ZERO];
  3063. if (GetCTBanStatus(iTarget))
  3064. {
  3065. char sTime[MAX_TIME_ARG_LENGTH];
  3066. GetCmdArg(CHANGE_TIME_ARG_TIME, sTime, sizeof(sTime));
  3067.  
  3068. int iTime = StringToInt(sTime);
  3069.  
  3070. if (iTime < ZERO)
  3071. {
  3072. ReplyToCommand(iClient, g_sChatBanner, "Invalid Amount");
  3073. }
  3074. // check if time is not changing
  3075. else if (gA_LocalTimeRemaining[iTarget] == iTime || (gA_LocalTimeRemaining[iTarget] <= ZERO && iTime == ZERO))
  3076. {
  3077. ReplyToCommand(iClient, g_sChatBanner, "Invalid Amount");
  3078. }
  3079. else
  3080. {
  3081. PerformChangeCTBanTime(iTarget, iClient, iTime);
  3082. }
  3083. }
  3084. else
  3085. {
  3086. ReplyToCommand(iClient, g_sChatBanner, "Not CT Banned", iTarget);
  3087. }
  3088. }
  3089.  
  3090. return Plugin_Handled;
  3091. }
  3092.  
  3093. void PerformChangeCTBanTime(int iTarget, int iClient, int iTime)
  3094. {
  3095. // 3 types of possible actions depending on the existing and new ban type
  3096. // timed to timed
  3097. if (iTime > ZERO && gA_LocalTimeRemaining[iTarget] > ZERO)
  3098. {
  3099. gA_LocalTimeRemaining[iTarget] = iTime;
  3100.  
  3101. ShowActivity2(iClient, "", g_sChatBanner, "Temporary CT Ban", iTarget, iTime);
  3102.  
  3103. // if it is a timed to timed change then the values will be cached on client disconnect like normal
  3104. }
  3105. // timed to perm
  3106. else if (iTime == ZERO && gA_LocalTimeRemaining[iTarget] > ZERO)
  3107. {
  3108. gA_LocalTimeRemaining[iTarget] = iTime;
  3109.  
  3110. // check if they were in the timed array
  3111. int iBannedArrayIndex = FindValueInArray(gA_TimedBanLocalList, iTarget);
  3112. if (iBannedArrayIndex != VALUE_NOT_FOUND_IN_ARRAY)
  3113. {
  3114. // remove them from the local array
  3115. RemoveFromArray(gA_TimedBanLocalList, iBannedArrayIndex);
  3116.  
  3117. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  3118. GetClientAuthId(iTarget, AuthId_Steam2, sAuthId, sizeof(sAuthId));
  3119.  
  3120. // fix these tables so it will not reset on the next server join
  3121. char sQuery[QUERY_MAXLENGTH];
  3122. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_DELETE, g_sTimesTableName, sAuthId);
  3123. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  3124.  
  3125. switch (g_eDatabaseType)
  3126. {
  3127. case e_SQLite:
  3128. {
  3129. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_TIME_TO_PERM_SQLITE, g_sLogTableName, sAuthId);
  3130. }
  3131. default:
  3132. {
  3133. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_TIME_TO_PERM_MYSQL, g_sLogTableName, sAuthId);
  3134. }
  3135. }
  3136. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  3137. }
  3138.  
  3139. ShowActivity2(iClient, "", g_sChatBanner, "Permanent CT Ban", iTarget);
  3140. }
  3141. // perm to timed
  3142. else if (iTime > ZERO && gA_LocalTimeRemaining[iTarget] <= ZERO)
  3143. {
  3144. // save in local quick-access array
  3145. PushArrayCell(gA_TimedBanLocalList, iTarget);
  3146. gA_LocalTimeRemaining[iTarget] = iTime;
  3147.  
  3148. char sAuthId[FIELD_AUTHID_MAXLENGTH];
  3149. GetClientAuthId(iTarget, AuthId_Steam2, sAuthId, sizeof(sAuthId));
  3150.  
  3151. // save in long-term database (already guaranteed to run only once per steam ID)
  3152. char sQuery[QUERY_MAXLENGTH];
  3153. switch (g_eDatabaseType)
  3154. {
  3155. case e_SQLite:
  3156. {
  3157. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_INSERT_SQLITE, g_sTimesTableName, sAuthId, iTime);
  3158. }
  3159. default:
  3160. {
  3161. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_TIME_INSERT_MYSQL, g_sTimesTableName, sAuthId, iTime, iTime);
  3162. }
  3163. }
  3164. #if defined CTBAN_DEBUG
  3165. LogMessage("ctban query: %s", sQuery);
  3166. #endif
  3167. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  3168.  
  3169. switch (g_eDatabaseType)
  3170. {
  3171. case e_SQLite:
  3172. {
  3173. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_PERM_TO_TIME_SQLITE, g_sLogTableName, iTime, iTime, sAuthId);
  3174. }
  3175. default:
  3176. {
  3177. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_PERM_TO_TIME_MYSQL, g_sLogTableName, iTime, iTime, sAuthId);
  3178. }
  3179. }
  3180. SQL_TQuery(gH_BanDatabase, DB_Callback_DisconnectAction, sQuery);
  3181.  
  3182. ShowActivity2(iClient, "", g_sChatBanner, "Temporary CT Ban", iTarget, iTime);
  3183. }
  3184. }
  3185.  
  3186. public Action Command_CTBanList(int iClient, int iArgs)
  3187. {
  3188. // console user
  3189. if (!iClient)
  3190. {
  3191. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  3192. {
  3193. if (IsClientInGame(iIndex))
  3194. {
  3195. if (GetCTBanStatus(iIndex))
  3196. {
  3197. if (gA_LocalTimeRemaining[iIndex] <= ZERO)
  3198. {
  3199. ReplyToCommand(iClient, g_sChatBanner, "Permanent CT Ban", iIndex);
  3200. }
  3201. else
  3202. {
  3203. ReplyToCommand(iClient, g_sChatBanner, "Temporary CT Ban", iIndex, gA_LocalTimeRemaining[iIndex]);
  3204. }
  3205. }
  3206. }
  3207. }
  3208. }
  3209. // regular in-game player
  3210. else
  3211. {
  3212. // check if client is allowed to use the command
  3213. AdminId clientAdminId = GetUserAdmin(iClient);
  3214. char sFlags[MAX_ADMINFLAGS_LENGTH];
  3215. GetConVarString(gH_Cvar_CheckCTBans_Flags, sFlags, sizeof(sFlags));
  3216. int iAdminFlags = ReadFlagString(sFlags);
  3217.  
  3218. #if defined CTBAN_DEBUG
  3219. LogMessage("Flag string %s and value %d and client effective %d", sFlags, iAdminFlags, GetAdminFlags(clientAdminId, Access_Effective));
  3220. #endif
  3221.  
  3222. // length of 0 means they want everyone to have access to this
  3223. if (strlen(sFlags) == ZERO)
  3224. {
  3225. DisplayCTBannedPlayerMenu(iClient, e_CTBanList);
  3226. }
  3227. // if the player has no admin access
  3228. // iAdminFlags bitstring & client's bitstring will leave a logic TRUE if there is overlap
  3229. else if (clientAdminId == INVALID_ADMIN_ID || !(iAdminFlags & GetAdminFlags(clientAdminId, Access_Effective)))
  3230. {
  3231. ReplyToCommand(iClient, g_sChatBanner, "No Access");
  3232. }
  3233. // they are an admin and they have effective flag access
  3234. else
  3235. {
  3236. DisplayCTBannedPlayerMenu(iClient, e_CTBanList);
  3237. }
  3238. }
  3239.  
  3240. return Plugin_Handled;
  3241. }
  3242.  
  3243. public Action Command_IsBanned(int iClient, int iArgs)
  3244. {
  3245. char sTarget[MAX_TARGET_LENGTH];
  3246. GetCmdArg(ISBANNED_ARG_TARGET, sTarget, sizeof(sTarget));
  3247.  
  3248. char sClientName[MAX_TARGET_LENGTH];
  3249. int aiTargetList[MAXPLAYERS];
  3250. int iTargetCount;
  3251. bool b_tn_is_ml;
  3252. iTargetCount = ProcessTargetString(sTarget, iClient, aiTargetList, MAXPLAYERS, COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_IMMUNITY, sClientName, sizeof(sClientName), b_tn_is_ml);
  3253. int iTarget = aiTargetList[ZERO];
  3254.  
  3255. // Console
  3256. if (!iClient)
  3257. {
  3258. if (!iArgs)
  3259. {
  3260. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_isbanned <player>");
  3261. }
  3262. else
  3263. {
  3264. if (iTargetCount < ONE)
  3265. {
  3266. ReplyToTargetError(iClient, iTargetCount);
  3267. }
  3268. else
  3269. {
  3270. ProcessIsBannedTarget(iTarget, iClient);
  3271. }
  3272. }
  3273. return Plugin_Handled;
  3274. }
  3275.  
  3276. // check if client is allowed to use the command
  3277. AdminId clientAdminId = GetUserAdmin(iClient);
  3278. char sFlags[MAX_ADMINFLAGS_LENGTH];
  3279. GetConVarString(gH_Cvar_CheckCTBans_Flags, sFlags, sizeof(sFlags));
  3280.  
  3281. int iAdminFlags = ReadFlagString(sFlags);
  3282.  
  3283. #if defined CTBAN_DEBUG
  3284. LogMessage("Flag string %s and value %d and client effective %d", sFlags, iAdminFlags, GetAdminFlags(clientAdminId, Access_Effective));
  3285. #endif
  3286.  
  3287. // length of 0 means they want everyone to have access to this
  3288. if (strlen(sFlags) == ZERO)
  3289. {
  3290. if (!iArgs)
  3291. {
  3292. // automatically target self
  3293. ProcessIsBannedTarget(iClient, iClient);
  3294. }
  3295. else
  3296. {
  3297. if (iTargetCount < ONE)
  3298. {
  3299. ReplyToTargetError(iClient, iTargetCount);
  3300. }
  3301. else
  3302. {
  3303. ProcessIsBannedTarget(iTarget, iClient);
  3304. }
  3305. }
  3306. }
  3307. // if the player has no admin access
  3308. // iAdminFlags bitstring & client's bitstring will leave a logic TRUE if there is overlap
  3309. else if (clientAdminId == INVALID_ADMIN_ID || !(iAdminFlags & GetAdminFlags(clientAdminId, Access_Effective)))
  3310. {
  3311. // check if self-targeting allowed
  3312. if (GetConVarBool(gH_Cvar_IsBanned_Self))
  3313. {
  3314. if (!iArgs)
  3315. {
  3316. // automatically target self
  3317. ProcessIsBannedTarget(iClient, iClient);
  3318. }
  3319. else
  3320. {
  3321. // check if they target themselves
  3322. if (iTargetCount < ONE)
  3323. {
  3324. ReplyToTargetError(iClient, iTargetCount);
  3325. }
  3326. else if (iTarget != iClient)
  3327. {
  3328. ReplyToCommand(iClient, g_sChatBanner, "No Access");
  3329. }
  3330. // target is the calling client
  3331. else
  3332. {
  3333. ProcessIsBannedTarget(iTarget, iClient);
  3334. }
  3335. }
  3336. }
  3337. else
  3338. {
  3339. ReplyToCommand(iClient, g_sChatBanner, "No Access");
  3340. }
  3341. }
  3342. // they are an admin and they have effective flag access
  3343. else
  3344. {
  3345. if (!iArgs)
  3346. {
  3347. ReplyToCommand(iClient, g_sChatBanner, "Command Usage", "sm_isbanned <player>");
  3348. }
  3349. else
  3350. {
  3351. if (iTargetCount < ONE)
  3352. {
  3353. ReplyToTargetError(iClient, iTargetCount);
  3354. }
  3355. else
  3356. {
  3357. ProcessIsBannedTarget(iTarget, iClient);
  3358. }
  3359. }
  3360. }
  3361.  
  3362. return Plugin_Handled;
  3363. }
  3364.  
  3365. void ProcessIsBannedTarget(int iTarget, int iCaller)
  3366. {
  3367. #if defined CTBAN_DEBUG
  3368. LogMessage("Processing IsBanned on %N by %N", iTarget, iCaller);
  3369. #endif
  3370.  
  3371. if(iTarget > ZERO && iTarget <= MaxClients && IsClientInGame(iTarget))
  3372. {
  3373. if (GetCTBanStatus(iTarget, iCaller))
  3374. {
  3375. // grab perp steam id
  3376. char sPerpSteamID[FIELD_AUTHID_MAXLENGTH];
  3377. GetClientAuthId(iTarget, AuthId_Steam2, sPerpSteamID, sizeof(sPerpSteamID));
  3378.  
  3379. char sQuery[QUERY_MAXLENGTH];
  3380. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_ISBANNED, g_sLogTableName, sPerpSteamID);
  3381.  
  3382. #if defined CTBAN_DEBUG
  3383. LogMessage("isbanned query: %s", sQuery);
  3384. #endif
  3385.  
  3386. Handle hDataPack = CreateDataPack();
  3387. // perp SteamID
  3388. WritePackString(hDataPack, sPerpSteamID);
  3389. // current client who asked for isbanned info
  3390. WritePackCell(hDataPack, iCaller);
  3391. // target index
  3392. WritePackCell(hDataPack, iTarget);
  3393.  
  3394. SQL_TQuery(gH_BanDatabase, DB_Callback_IsBanned, sQuery, hDataPack);
  3395. }
  3396. else
  3397. {
  3398. if (iCaller != CALLER_NATIVE)
  3399. {
  3400. ReplyToCommand(iCaller, g_sChatBanner, "Not CT Banned", iTarget);
  3401. }
  3402. else
  3403. {
  3404. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Not CT Banned", iTarget);
  3405. }
  3406. }
  3407. }
  3408. else
  3409. {
  3410. if (iCaller != CALLER_NATIVE)
  3411. {
  3412. ReplyToCommand(iCaller, g_sChatBanner, "Unable to target");
  3413. }
  3414. else
  3415. {
  3416. ThrowNativeError(SP_ERROR_NATIVE, g_sChatBanner, "Unable to target");
  3417. }
  3418. }
  3419. }
  3420.  
  3421. public void DB_Callback_IsBanned(Handle hOwner, Handle hCallback, const char[] sError, any hDataPack)
  3422. {
  3423. if (hCallback == INVALID_HANDLE)
  3424. {
  3425. LogError("Error in IsBanned query: %s", sError);
  3426. CloseHandle(hDataPack);
  3427. }
  3428. else
  3429. {
  3430. ResetPack(hDataPack);
  3431. char sPerpAuthID[FIELD_AUTHID_MAXLENGTH];
  3432. ReadPackString(hDataPack, sPerpAuthID, sizeof(sPerpAuthID));
  3433. int iCaller = ReadPackCell(hDataPack);
  3434. int iTarget = ReadPackCell(hDataPack);
  3435. CloseHandle(hDataPack);
  3436.  
  3437. int iRowCount = SQL_GetRowCount(hCallback);
  3438. if (iRowCount > ONE || iRowCount < ZERO)
  3439. {
  3440. LogError("%d rows returned on LIMIT 1 query: %s", iRowCount, sError);
  3441. }
  3442. else if (!iRowCount)
  3443. {
  3444. #if defined CTBAN_DEBUG
  3445. LogMessage("Row count is 0 for IsBanned Query!");
  3446. #endif
  3447.  
  3448. if (iCaller == CALLER_NATIVE)
  3449. {
  3450. // Have to use incomplete information because the row is missing from the database table
  3451. Call_StartForward(g_hFrwd_CTBanInfo);
  3452. Call_PushCell(false);
  3453. Call_PushCell(iTarget);
  3454. Call_PushCell(gA_LocalTimeRemaining[iTarget]);
  3455. Call_PushCell(CALLER_NATIVE);
  3456. Call_PushString("Invalid");
  3457. Call_PushString("Invalid");
  3458. Call_Finish();
  3459. }
  3460. else if (gA_LocalTimeRemaining[iTarget] <= ZERO)
  3461. {
  3462. if (!iCaller)
  3463. {
  3464. PrintToServer(g_sChatBanner, "Permanent CT Ban", iTarget);
  3465. }
  3466. else
  3467. {
  3468. CPrintToChat(iCaller, g_sChatBanner, "Permanent CT Ban", iTarget);
  3469. }
  3470. }
  3471. else
  3472. {
  3473. if (!iCaller)
  3474. {
  3475. PrintToServer(g_sChatBanner, "Temporary CT Ban", iTarget, gA_LocalTimeRemaining[iTarget]);
  3476. }
  3477. else
  3478. {
  3479. CPrintToChat(iCaller, g_sChatBanner, "Temporary CT Ban", iTarget, gA_LocalTimeRemaining[iTarget]);
  3480. }
  3481. }
  3482. }
  3483. // Rows are exactly 1
  3484. else
  3485. {
  3486. SQL_FetchRow(hCallback);
  3487. int iTimeStamp = SQL_FetchInt(hCallback, ISBANNED_CB_FIELD_TIMESTAMP);
  3488. char sAdminName[FIELD_NAME_MAXLENGTH];
  3489. SQL_FetchString(hCallback, ISBANNED_CB_FIELD_ADMINNAME, sAdminName, sizeof(sAdminName));
  3490. char sReason[FIELD_REASON_MAXLENGTH];
  3491. SQL_FetchString(hCallback, ISBANNED_CB_FIELD_REASON, sReason, sizeof(sReason));
  3492. #if defined CTBAN_DEBUG
  3493. LogMessage("SQL ISBanned: admin %s banned with timestamp %d for reason %s", sAdminName, iTimeStamp, sReason);
  3494. #endif
  3495.  
  3496. char sTimeBanned[MAX_TIME_INFO_STR_LENGTH];
  3497. FormatTime(sTimeBanned, sizeof(sTimeBanned), NULL_STRING, iTimeStamp);
  3498.  
  3499. #if defined CTBAN_DEBUG
  3500. LogMessage("target %N, admin banning %s, when banned %s, timeleft %d", iTarget, sAdminName, sTimeBanned, gA_LocalTimeRemaining[iTarget]);
  3501. #endif
  3502.  
  3503. // check if we need to fire a forward from a native call
  3504. if (iCaller == CALLER_NATIVE)
  3505. {
  3506. Call_StartForward(g_hFrwd_CTBanInfo);
  3507. Call_PushCell(true);
  3508. Call_PushCell(iTarget);
  3509. Call_PushCell(gA_LocalTimeRemaining[iTarget]);
  3510. Call_PushCell(iTimeStamp);
  3511. Call_PushString(sAdminName);
  3512. Call_PushString(sReason);
  3513. Call_Finish();
  3514. }
  3515. // find the time if any
  3516. else if (gA_LocalTimeRemaining[iTarget] <= ZERO)
  3517. {
  3518. if (!iCaller)
  3519. {
  3520. PrintToServer(g_sChatBanner, "IsBanned Permanent", iTarget, sAdminName, sTimeBanned, sReason);
  3521. }
  3522. else
  3523. {
  3524. CPrintToChat(iCaller, g_sChatBanner, "IsBanned Permanent", iTarget, sAdminName, sTimeBanned, sReason);
  3525. }
  3526. }
  3527. else
  3528. {
  3529. if (!iCaller)
  3530. {
  3531. PrintToServer(g_sChatBanner, "IsBanned Temporary", iTarget, gA_LocalTimeRemaining[iTarget], sAdminName, sTimeBanned, sReason);
  3532. }
  3533. else
  3534. {
  3535. CPrintToChat(iCaller, g_sChatBanner, "IsBanned Temporary", iTarget, gA_LocalTimeRemaining[iTarget], sAdminName, sTimeBanned, sReason);
  3536. }
  3537. }
  3538. }
  3539. }
  3540. }
  3541.  
  3542. public Action Command_Offline_IsBanned(int iClient, int iArgs)
  3543. {
  3544. char sPerpSteamID[FIELD_AUTHID_MAXLENGTH];
  3545. GetCmdArgString(sPerpSteamID, sizeof(sPerpSteamID));
  3546. TrimString(sPerpSteamID);
  3547.  
  3548. if (IsAuthIdConnected(sPerpSteamID))
  3549. {
  3550. ReplyToCommand(iClient, g_sChatBanner, "Unable to target");
  3551. }
  3552. else
  3553. {
  3554. ProcessIsBannedOffline(iClient, sPerpSteamID);
  3555. }
  3556.  
  3557. return Plugin_Handled;
  3558. }
  3559.  
  3560. void ProcessIsBannedOffline(int iCaller, char[] sPerpAuthID)
  3561. {
  3562. char sEscapedPerpSteamID[MAX_SAFE_ESCAPE_QUERY(FIELD_NAME_MAXLENGTH)];
  3563. SQL_EscapeString(gH_BanDatabase, sPerpAuthID, sEscapedPerpSteamID, sizeof(sEscapedPerpSteamID));
  3564.  
  3565. char sQuery[QUERY_MAXLENGTH];
  3566. Format(sQuery, sizeof(sQuery), CTBAN_QUERY_LOG_ISBANNED_OFFLINE, g_sLogTableName, sEscapedPerpSteamID);
  3567.  
  3568. #if defined CTBAN_DEBUG
  3569. LogMessage("offline isbanned query: %s", sQuery);
  3570. #endif
  3571.  
  3572. Handle hDataPack = CreateDataPack();
  3573. // perp SteamID
  3574. WritePackString(hDataPack, sPerpAuthID);
  3575. // current client who asked for isbanned info
  3576. WritePackCell(hDataPack, iCaller);
  3577.  
  3578. SQL_TQuery(gH_BanDatabase, DB_Callback_Offline_IsBanned, sQuery, hDataPack);
  3579. }
  3580.  
  3581. public void DB_Callback_Offline_IsBanned(Handle hOwner, Handle hCallback, const char[] sError, any hOfflineIsBannedPack)
  3582. {
  3583. if (hCallback == INVALID_HANDLE)
  3584. {
  3585. LogError("Error in Offline IsBanned query: %s", sError);
  3586. }
  3587. else
  3588. {
  3589. ResetPack(hOfflineIsBannedPack);
  3590. char sPerpAuthID[FIELD_AUTHID_MAXLENGTH];
  3591. ReadPackString(hOfflineIsBannedPack, sPerpAuthID, sizeof(sPerpAuthID));
  3592. int iClient = ReadPackCell(hOfflineIsBannedPack);
  3593. CloseHandle(hOfflineIsBannedPack);
  3594.  
  3595. int iRowCount = SQL_GetRowCount(hCallback);
  3596. if (iRowCount != ONE)
  3597. {
  3598. if (iClient == CALLER_NATIVE)
  3599. {
  3600. Call_StartForward(g_hFrwd_CTBanInfoOffline);
  3601. Call_PushCell(false);
  3602. Call_PushString(sPerpAuthID);
  3603. Call_PushCell(CALLER_NATIVE);
  3604. Call_PushCell(CALLER_NATIVE);
  3605. Call_PushString("Invalid");
  3606. Call_PushString("Invalid");
  3607. Call_PushString("Invalid");
  3608. Call_Finish();
  3609. }
  3610. else if (!iClient)
  3611. {
  3612. PrintToServer(g_sChatBanner, "No matching client");
  3613. }
  3614. else
  3615. {
  3616. CPrintToChat(iClient, g_sChatBanner, "No matching client");
  3617. }
  3618. }
  3619. else
  3620. {
  3621. SQL_FetchRow(hCallback);
  3622. int timestamp = SQL_FetchInt(hCallback, ISBANNED_OFF_CB_FIELD_TIMESTAMP);
  3623. char sAdminName[FIELD_NAME_MAXLENGTH];
  3624. SQL_FetchString(hCallback, ISBANNED_OFF_CB_FIELD_ADMINNAME, sAdminName, sizeof(sAdminName));
  3625. char sReason[FIELD_REASON_MAXLENGTH];
  3626. SQL_FetchString(hCallback, ISBANNED_OFF_CB_FIELD_REASON, sReason, sizeof(sReason));
  3627. int timeleft = SQL_FetchInt(hCallback, ISBANNED_OFF_CB_FIELD_TIMELEFT);
  3628. char sPerpName[FIELD_NAME_MAXLENGTH];
  3629. SQL_FetchString(hCallback, ISBANNED_OFF_CB_FIELD_PERPNAME, sPerpName, sizeof(sPerpName));
  3630.  
  3631. char sTimeBanned[MAX_TIME_INFO_STR_LENGTH];
  3632. FormatTime(sTimeBanned, sizeof(sTimeBanned), NULL_STRING, timestamp);
  3633.  
  3634. #if defined CTBAN_DEBUG
  3635. LogMessage("target name %s, admin banning %s, when banned %s, timeleft %d", sPerpName, sAdminName, sTimeBanned, timeleft);
  3636. #endif
  3637.  
  3638. if (iClient == CALLER_NATIVE)
  3639. {
  3640. Call_StartForward(g_hFrwd_CTBanInfoOffline);
  3641. Call_PushCell(true);
  3642. Call_PushString(sPerpAuthID);
  3643. Call_PushCell(timeleft);
  3644. Call_PushCell(timestamp);
  3645. Call_PushString(sAdminName);
  3646. Call_PushString(sReason);
  3647. Call_PushString(sPerpName);
  3648. Call_Finish();
  3649. }
  3650. else if (timeleft <= ZERO)
  3651. {
  3652. if (!iClient)
  3653. {
  3654. PrintToServer(g_sChatBanner, "IsBanned Permanent String Name", sPerpName, sAdminName, sTimeBanned, sReason);
  3655. }
  3656. else
  3657. {
  3658. CPrintToChat(iClient, g_sChatBanner, "IsBanned Permanent String Name", sPerpName, sAdminName, sTimeBanned, sReason);
  3659. }
  3660. }
  3661. else
  3662. {
  3663. if (!iClient)
  3664. {
  3665. PrintToServer(g_sChatBanner, "IsBanned Temporary String Name", sPerpName, timeleft, sAdminName, sTimeBanned, sReason);
  3666. }
  3667. else
  3668. {
  3669. CPrintToChat(iClient, g_sChatBanner, "IsBanned Temporary String Name", sPerpName, timeleft, sAdminName, sTimeBanned, sReason);
  3670. }
  3671. }
  3672. }
  3673. }
  3674. }
  3675.  
  3676. public Action Command_CheckJoin(int iClient, const char[] sCommand, int iArgs)
  3677. {
  3678. // Check to see if we should continue (not a listen server, is in game, not a bot, if cookies are cached, and we're enabled)
  3679. if(!iClient || !IsClientInGame(iClient) || IsFakeClient(iClient) || !AreClientCookiesCached(iClient))
  3680. {
  3681. return Plugin_Continue;
  3682. }
  3683.  
  3684. // Get the target team
  3685. char sJoinTeamString[MAX_JOINTEAM_ARG_LENGTH];
  3686. GetCmdArg(JOINTEAM_ARG_TEAM_STRING, sJoinTeamString, sizeof(sJoinTeamString));
  3687. int iTargetTeam = StringToInt(sJoinTeamString);
  3688.  
  3689. int iBanStatus = GetCTBanStatus(iClient);
  3690.  
  3691. // check for an active ban to send a message
  3692. if ((iTargetTeam == CS_TEAM_SPECTATOR || iTargetTeam == CS_TEAM_T) && iBanStatus)
  3693. {
  3694. // display them a message about the ban
  3695. int iTimeBanned = GetClientCookieTime(iClient, g_CT_Cookie);
  3696. char sTimeBanned[MAX_TIME_INFO_STR_LENGTH];
  3697. FormatTime(sTimeBanned, sizeof(sTimeBanned), NULL_STRING, iTimeBanned);
  3698. char sJoinBanMsg[MAX_JOIN_BAN_MSG_LENGTH];
  3699. GetConVarString(gH_Cvar_JoinBanMessage, sJoinBanMsg, sizeof(sJoinBanMsg));
  3700. PrintHintText(iClient, "%t", "Last CT Banned On", sTimeBanned, sJoinBanMsg);
  3701.  
  3702. if (GetConVarBool(gH_Cvar_IsBanned_Self))
  3703. {
  3704. ProcessIsBannedTarget(iClient, iClient);
  3705. }
  3706. }
  3707. // otherwise they joined CT or auto-select and are banned
  3708. else if (iBanStatus)
  3709. {
  3710. if(strcmp(gS_SoundPath, ""))
  3711. {
  3712. char sPlayCommand[PLATFORM_MAX_PATH + PLAY_COMMAND_STRING_LENGTH];
  3713. Format(sPlayCommand, sizeof(sPlayCommand), "%s%s", PLAY_COMMAND_STRING, gS_SoundPath);
  3714. ClientCommand(iClient, sPlayCommand);
  3715. }
  3716. CPrintToChat(iClient, g_sChatBanner, "Enforcing CT Ban");
  3717.  
  3718. // if they are already on the Terrorist team then they don't need to pick anything again
  3719. if (GetClientTeam(iClient) != CS_TEAM_T)
  3720. {
  3721. UTIL_TeamMenu(iClient);
  3722. }
  3723.  
  3724. return Plugin_Stop;
  3725. }
  3726.  
  3727. return Plugin_Continue;
  3728. }
  3729.  
  3730. // This helper procedure will re-display the team join menu
  3731. // and is equivalent to what ClientCommand(client, "chooseteam") did in the past
  3732. void UTIL_TeamMenu(int iClient)
  3733. {
  3734. int aiClients[ONE];
  3735. Handle hBfWritePack;
  3736. aiClients[ZERO] = iClient;
  3737. hBfWritePack = StartMessage("VGUIMenu", aiClients, ONE);
  3738.  
  3739. if (GetUserMessageType() == UM_Protobuf)
  3740. {
  3741. PbSetString(hBfWritePack, "name", "team");
  3742. PbSetBool(hBfWritePack, "show", true);
  3743. }
  3744. else
  3745. {
  3746. BfWriteString(hBfWritePack, "team"); // panel name
  3747. BfWriteByte(hBfWritePack, ONE); // bShow
  3748. BfWriteByte(hBfWritePack, ZERO); // count
  3749. }
  3750.  
  3751. EndMessage();
  3752. }
  3753.  
  3754. // figure out if we can use the handy native SetAuthIdCookie
  3755. bool IsSetAuthIdNativePresent()
  3756. {
  3757. if (GetFeatureStatus(FeatureType_Native, "SetAuthIdCookie") == FeatureStatus_Available)
  3758. {
  3759. return true;
  3760. }
  3761. return false;
  3762. }
  3763.  
  3764. int GetCTBanStatus(int iClient, int iCaller = CALLER_DO_NOT_REPLY)
  3765. {
  3766. int iCTBanStatus = ZERO;
  3767.  
  3768. if (AreClientCookiesCached(iClient))
  3769. {
  3770. char sCookie[MAX_COOKIE_STR_LENGTH];
  3771. GetClientCookie(iClient, g_CT_Cookie, sCookie, sizeof(sCookie));
  3772. iCTBanStatus = StringToInt(sCookie);
  3773. }
  3774. else
  3775. {
  3776. if (iCaller >= ZERO)
  3777. {
  3778. ReplyToCommand(iCaller, g_sChatBanner, "Cookie Status Unavailable");
  3779. }
  3780. }
  3781.  
  3782. return iCTBanStatus;
  3783. }
  3784.  
  3785. void EnforceCTBan(int iClient)
  3786. {
  3787. if (IsPlayerAlive(iClient))
  3788. {
  3789. // strip their weapons so they cannot gunplant after death
  3790. StripAllWeapons(iClient);
  3791.  
  3792. ForcePlayerSuicide(iClient);
  3793. }
  3794.  
  3795. ChangeClientTeam(iClient, CS_TEAM_T);
  3796.  
  3797. if (GetConVarBool(gH_Cvar_Respawn))
  3798. {
  3799. CS_RespawnPlayer(iClient);
  3800. }
  3801.  
  3802. CPrintToChat(iClient, g_sChatBanner, "Enforcing CT Ban");
  3803. }
  3804.  
  3805. #if !defined _Hosties_Included_
  3806. // From hosties.inc on Beta branch (20 Aug 2017)
  3807. stock void StripAllWeapons(int iClient)
  3808. {
  3809. int iWeaponIndex = INVALID_WEAPON;
  3810. for (int iLoopIndex = CS_SLOT_PRIMARY; iLoopIndex < CS_SLOT_GRENADE + ONE; iLoopIndex++)
  3811. {
  3812. iWeaponIndex = INVALID_WEAPON;
  3813. while ((iWeaponIndex = GetPlayerWeaponSlot(iClient, iLoopIndex)) != INVALID_WEAPON)
  3814. {
  3815. RemovePlayerItem(iClient, iWeaponIndex);
  3816. AcceptEntityInput(iWeaponIndex, "Kill");
  3817. }
  3818. }
  3819. }
  3820. #endif
  3821.  
  3822. #if !defined _CTBan_Included_
  3823. stock int IsAuthIdConnected(char[] sAuthID)
  3824. {
  3825. char sIndexAuthID[FIELD_AUTHID_MAXLENGTH];
  3826. for (int iIndex = ONE; iIndex <= MaxClients; iIndex++)
  3827. {
  3828. if (IsClientInGame(iIndex))
  3829. {
  3830. GetClientAuthId(iIndex, AuthId_Steam2, sIndexAuthID, sizeof(sIndexAuthID));
  3831. if (StrEqual(sAuthID, sIndexAuthID))
  3832. {
  3833. return iIndex;
  3834. }
  3835. }
  3836. }
  3837.  
  3838. return ZERO;
  3839. }
  3840.  
  3841. stock void ParseCTBanReasonsFile(Handle hReasonsArray)
  3842. {
  3843. ClearArray(hReasonsArray);
  3844.  
  3845. char sPathReasons[PLATFORM_MAX_PATH];
  3846. BuildPath(Path_SM, sPathReasons, sizeof(sPathReasons), "configs/ctban_reasons.ini");
  3847. Handle hReasonsFile = OpenFile(sPathReasons, "r");
  3848.  
  3849. if (hReasonsFile != null)
  3850. {
  3851. char sReasonsLine[FIELD_REASON_MAXLENGTH];
  3852.  
  3853. while (ReadFileLine(hReasonsFile, sReasonsLine, sizeof(sReasonsLine)))
  3854. {
  3855. PushArrayString(hReasonsArray, sReasonsLine);
  3856. }
  3857. }
  3858.  
  3859. CloseHandle(hReasonsFile);
  3860. }
  3861.  
  3862. stock Handle ParseCTBanLengthsFile(Handle hKeyValues)
  3863. {
  3864. if (hKeyValues != INVALID_HANDLE)
  3865. {
  3866. CloseHandle(hKeyValues);
  3867. }
  3868.  
  3869. hKeyValues = CreateKeyValues("length");
  3870.  
  3871. char sPathLengths[PLATFORM_MAX_PATH];
  3872. BuildPath(Path_SM, sPathLengths, sizeof(sPathLengths), "configs/ctban_times.ini");
  3873.  
  3874. if (FileToKeyValues(hKeyValues, sPathLengths))
  3875. {
  3876. KvRewind(hKeyValues);
  3877. }
  3878. else
  3879. {
  3880. CloseHandle(hKeyValues);
  3881. return INVALID_HANDLE;
  3882. }
  3883.  
  3884. return hKeyValues;
  3885. }
  3886.  
  3887. stock void SetCTBanChatBanner(EngineVersion e_EngineVersion, char sChatBanner[MAX_CHAT_BANNER_LENGTH])
  3888. {
  3889. switch (e_EngineVersion)
  3890. {
  3891. case Engine_CSS, Engine_TF2:
  3892. {
  3893. sChatBanner = "[\x0799CCFFCTBAN\x01] \x07FFD700%t";
  3894. }
  3895. case Engine_CSGO:
  3896. {
  3897. sChatBanner = "[\x0BCTBAN\x01] \x10%t";
  3898. }
  3899. default:
  3900. {
  3901. SetFailState("Game engine is not supported.");
  3902. }
  3903. }
  3904. }
  3905. #endif
  3906.  
  3907. /*
  3908. [CS:S/CS:GO] CT Bans
  3909. by: databomb
  3910. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement