Advertisement
Guest User

Untitled

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