· 8 years ago · Aug 26, 2018, 05:06 PM
1/**
2 * @file ct_restrict.sp
3 * @author 1Swat2KillThemAll
4 *
5 * @brief Counter Strike: Source SourceMod Plugin
6 * @version 2.0./**
7 * @file ct_restrict.sp
8 * @author 1Swat2KillThemAll
9 *
10 * @brief Counter Strike: Source SourceMod Plugin
11 * @version 2.0.0
12 *
13 * CT Restrict SourceMod Plugin
14 * Copyright (C) 2010 - 2011 B.D.A.K. Koch
15 * This program is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 */
28#pragma semicolon 1
29
30#include <sourcemod>
31#include <sdktools>
32
33#define YELLOW 0x01
34#define TEAMCOLOR 0x02
35#define LIGHTGREEN 0x03
36#define GREEN 0x04
37
38#define SQLITE__ 0
39#define MYSQL__ 1
40#define SQLMAX__ 2
41
42new g_iDatabaseId[MAXPLAYERS+1] = { -1, ... },
43 Handle:g_hDatabase = INVALID_HANDLE,
44 g_DatabaseType = SQLITE__,
45 Handle:g_hCvEnabled = INVALID_HANDLE;
46
47new const stock g_c_banned_team = 3;
48
49enum EQueries
50{
51 E_QCreate = 0,
52 E_QInsert,
53 E_QConnect,
54 E_QDelete,
55 E_QUpdate,
56 E_QMax
57};
58new stock const String:SQLQueries[SQLMAX__][E_QMax][] =
59{
60 { // SQLite
61 "CREATE TABLE IF NOT EXISTS ct_restrict ( id INTEGER PRIMARY KEY, name VARCHAR(65), steam VARCHAR(32) UNIQUE, ban_time DATE DEFAULT (DATE('now')), admin_steam VARCHAR(32) );",
62 "INSERT OR IGNORE INTO ct_restrict (name, steam, admin_steam) VALUES ('%s', '%s', '%s');",
63 "SELECT id FROM ct_restrict WHERE steam = '%s';",
64 "DELETE FROM ct_restrict WHERE id = '%i';",
65 "UPDATE ct_restrict SET name = '%s' WHERE id = '%i';"
66 },
67 { // MySQL
68 "CREATE TABLE IF NOT EXISTS ct_restrict ( id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, name VARCHAR(65), steam VARCHAR(32) UNIQUE, ban_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, admin_steam VARCHAR(32), status INT(11), unbanned_by VARCHAR(32) );",
69 "INSERT INTO ct_restrict (name, steam, admin_steam, status, unbanned_by) VALUES ('%s', '%s', '%s', '0', '0');",
70 "SELECT id FROM ct_restrict WHERE steam = '%s' AND status = '0';",
71 "DELETE FROM ct_restrict WHERE id = '%i';",
72 "UPDATE ct_restrict SET name = '%s' WHERE id = '%i';"
73 }
74};
75
76#define PLUGIN_NAME "CT Restrict"
77#define PLUGIN_AUTHOR "1Swat2KillThemAll"
78#define PLUGIN_DESCR "Ban players from using the CT team."
79#define PLUGIN_VERSION "1.000.000"
80#define PLUGIN_URL ""
81public Plugin:myinfo =
82{
83 name = PLUGIN_NAME,
84 author = PLUGIN_AUTHOR,
85 description = PLUGIN_DESCR,
86 version = PLUGIN_VERSION,
87 url = PLUGIN_URL
88};
89
90public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) {
91 CreateNative("CTR_IsClientCTBanned", Native_IsClientCTBanned);
92 RegPluginLibrary("ct_restrict");
93
94 return APLRes_Success;
95}
96
97#define ASSERT_NATIVE_ERROR_PARAMS(%1) if (numParams != (%1)) { ThrowNativeError(SP_ERROR_PARAM, "wrong number of parameters supplied: got (%i), expected (%i)", numParams, (%1)); }
98#define ASSERT_NATIVE_ERROR_CLIENT(%1) decl client; if (!(client = GetNativeCell(%1)) || !IsClientInGame(client) || !IsClientConnected(client)) { ThrowNativeError(SP_ERROR_INDEX, "client index %i is invalid", client); }
99public Native_IsClientCTBanned(Handle:plugin, numParams)
100{
101 ASSERT_NATIVE_ERROR_PARAMS(1)
102 ASSERT_NATIVE_ERROR_CLIENT(1)
103
104 return g_iDatabaseId[client] != -1;
105}
106#undef ASSERT_NATIVE_ERROR_PARAMS
107#undef ASSERT_NATIVE_ERROR_CLIENT
108
109public OnPluginStart()
110{
111 CreateConVar("sm_ctrestrict_version", PLUGIN_VERSION, "Version Console Variable", FCVAR_CHEAT | FCVAR_DONTRECORD | FCVAR_NOTIFY);
112 g_hCvEnabled = CreateConVar("sm_ctrestrict_enabled", "1", "Enable plugin?1:0", FCVAR_DONTRECORD, true, 0.0, true, 1.0);
113
114 RegAdminCmd("sm_ctban", Command_CtBan, ADMFLAG_KICK, "sm_ctban <player> | Bans a player from joining CT.");
115 RegAdminCmd("sm_ctunban", Command_CtUnban, ADMFLAG_KICK, "sm_ctunban <player> | Unbans a player from joining CT.");
116 RegAdminCmd("sm_reloadctban", Command_ReloadCtBan, ADMFLAG_ROOT, "sm_reloadctban <player(s)> | Reload bans");
117
118 AddCommandListener(CListener_JoinTeam, "jointeam");
119 HookEvent("player_team", Event_PlayerTeam);
120
121 LoadTranslations("common.phrases");
122
123 decl String:buff[255], String:db_config[128];
124 new use_sqlite = 1;
125
126 new Handle:kv = CreateKeyValues("CTRestrict");
127
128 if (!FileToKeyValues(kv, "cfg/ct_restrict.kv") || !KvGotoFirstSubKey(kv))
129 {
130 LogMessage("Couldn\'t open keyvalue file!");
131 }
132 else
133 {
134 do
135 {
136 KvGetSectionName(kv, buff, sizeof(buff));
137
138 if (StrEqual(buff, "Options"))
139 {
140 if (KvGotoFirstSubKey(kv))
141 {
142 do
143 {
144 KvGetSectionName(kv, buff, sizeof(buff));
145
146 if (StrEqual(buff, "Database"))
147 {
148 if (!(use_sqlite = KvGetNum(kv, "use_sqlite", 0)))
149 {
150 KvGetString(kv, "database_config", db_config, sizeof(db_config), "default");
151 }
152 }
153 } while (KvGotoNextKey(kv));
154
155 KvGoBack(kv);
156 }
157 }
158 } while (KvGotoNextKey(kv));
159 }
160
161 CloseHandle(kv);
162
163 if (!use_sqlite)
164 {
165 if (SQL_CheckConfig(db_config))
166 {
167 if ((g_hDatabase = SQL_Connect(db_config, true, buff, sizeof(buff))) == INVALID_HANDLE)
168 {
169 LogMessage("Couldn't connect to database using configuration \"%s\": %s", db_config, buff);
170 use_sqlite = 1;
171 }
172 else
173 {
174 g_DatabaseType = -1;
175
176 decl String:type[32];
177 new Handle:driver = SQL_ReadDriver(g_hDatabase);
178
179 SQL_GetDriverProduct(driver, type, sizeof(type));
180
181 if (StrEqual(type, "MySQL", false))
182 {
183 g_DatabaseType = MYSQL__;
184 }
185 else if (StrEqual(type, "SQLite", false))
186 {
187 g_DatabaseType = SQLITE__;
188 }
189
190 if (g_DatabaseType < 0)
191 {
192 LogError("Unrecognized Database-type \"%s\".", type);
193 use_sqlite = true;
194 CloseHandle(g_hDatabase);
195 g_hDatabase = INVALID_HANDLE;
196 }
197 }
198 }
199 else
200 {
201 LogMessage("Couldn't find named configuration \"%s\" in databases.cfg.", db_config);
202 use_sqlite = true;
203 }
204 }
205 if (use_sqlite)
206 {
207 if ((g_hDatabase = SQLite_UseDatabase("ct_restrict", buff, sizeof(buff))) == INVALID_HANDLE)
208 {
209 SetFailState(buff);
210 }
211 }
212
213 SQL_TQuery(g_hDatabase, T_NoAction, SQLQueries[g_DatabaseType][E_QCreate], DBPrio_High);
214}
215
216public OnClientAuthorized(client, const String:auth[])
217{
218 g_iDatabaseId[client] = -1;
219
220 if (IsFakeClient(client))
221 {
222 return;
223 }
224
225 decl String:query[255];
226 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QConnect], auth);
227 SQL_TQuery(g_hDatabase, T_ClientConnected, query, GetClientUserId(client));
228}
229public T_ClientConnected(Handle:owner, Handle:hndl, const String:error[], any:uid_client)
230{
231 new client = GetClientOfUserId(uid_client);
232
233 if (!client || !IsClientConnected(client))
234 {
235 return;
236 }
237
238 if (hndl == INVALID_HANDLE)
239 {
240 SetFailState(error);
241 }
242 else if (SQL_FetchRow(hndl))
243 {
244 g_iDatabaseId[client] = SQL_FetchInt(hndl, 0);
245 if (IsClientInGame(client) && GetClientTeam(client) != (g_c_banned_team==3?2:3))
246 {
247 ChangeClientTeam(client, g_c_banned_team==3?2:3);
248 }
249 }
250}
251
252public Action:Command_CtBan(client, argc)
253{
254 if (argc != 1)
255 {
256 ReplyToCommand(client, "[SM] sm_ctban <player> | Bans a player from joining CT.");
257 }
258 else
259 {
260 decl String:arg[128];
261 GetCmdArg(1, arg, sizeof(arg));
262
263 decl reason, targets[1], String:target_name[1], bool:tn_is_ml;
264 if ((reason = ProcessTargetString(arg, client, targets, sizeof(targets),
265 COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_BOTS,
266 target_name, sizeof(target_name), tn_is_ml)) <= 0)
267 {
268 ReplyToTargetError(client, reason);
269
270 return Plugin_Handled;
271 }
272
273 if (reason != 1)
274 {
275 return Plugin_Handled;
276 }
277
278 if (g_iDatabaseId[targets[0]] == -1)
279 {
280 ShowActivity2(client, "[SM]", "%N banned %N from playing on CT.", client, targets[0]);
281
282 if (GetClientTeam(targets[0]) == g_c_banned_team && GetConVarInt(g_hCvEnabled))
283 {
284 ChangeClientTeam(targets[0], g_c_banned_team==3?2:3);
285 PrintToChat(targets[0], "%c[CTBan]%c You've been banned from playing on that team!", GREEN, LIGHTGREEN);
286 }
287
288 decl String:player_authid[32];
289 GetClientAuthString(targets[0], player_authid, sizeof(player_authid));
290 decl String:admin_authid[32];
291 if (client != 0)
292 {
293 GetClientAuthString(client, admin_authid, sizeof(admin_authid));
294 }
295 else
296 {
297 strcopy(admin_authid, sizeof(admin_authid), "SERVER");
298 }
299
300 decl String:query[255],
301 String:name[MAX_NAME_LENGTH],
302 String:name2[2*(MAX_NAME_LENGTH)+1];
303 GetClientName(targets[0], name, sizeof(name));
304 SQL_EscapeString(g_hDatabase, name, name2, sizeof(name2));
305 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QInsert], name2, player_authid, admin_authid);
306
307
308 SQL_TQuery(g_hDatabase, T_Insert, query, GetClientUserId(targets[0]), DBPrio_High);
309 }
310 else
311 {
312 ReplyToCommand(client, "[SM] %N was already banned from playing as CT.", targets[0]);
313 }
314 }
315
316 return Plugin_Handled;
317}
318public T_Insert(Handle:owner, Handle:hndl, const String:error[], any:uid_client)
319{
320 new client = GetClientOfUserId(uid_client);
321
322 if (!IsClientConnected(client))
323 {
324 return;
325 }
326
327 if (hndl == INVALID_HANDLE)
328 {
329 SetFailState(error);
330 }
331 else
332 {
333 decl String:query[255], String:authid[32];
334 GetClientAuthString(client, authid, sizeof(authid));
335
336 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QConnect], authid);
337 SQL_TQuery(g_hDatabase, T_ClientConnected, query, GetClientUserId(client), DBPrio_High);
338 }
339}
340
341public Action:Command_CtUnban(client, argc)
342{
343 if (argc != 1)
344 {
345 ReplyToCommand(client, "[SM] sm_ctunban <player> | Unbans a player from joining CT.");
346 }
347 else
348 {
349 decl String:arg[128];
350 GetCmdArg(1, arg, sizeof(arg));
351
352 decl reason, targets[1], String:target_name[1], bool:tn_is_ml;
353 if ((reason = ProcessTargetString(arg, client, targets, sizeof(targets),
354 COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_BOTS,
355 target_name, sizeof(target_name), tn_is_ml)) <= 0)
356 {
357 ReplyToTargetError(client, reason);
358
359 return Plugin_Handled;
360 }
361
362 if (reason != 1)
363 {
364 return Plugin_Handled;
365 }
366
367 if (g_iDatabaseId[targets[0]] != -1)
368 {
369 ShowActivity2(client, "[SM]", "%N unbanned %N from playing on CT.", client, targets[0]);
370
371 decl String:query[255];
372 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QDelete], g_iDatabaseId[targets[0]]);
373
374 SQL_TQuery(g_hDatabase, T_NoAction, query);
375
376 g_iDatabaseId[targets[0]] = -1;
377 }
378 else
379 {
380 ReplyToCommand(client, "[SM] %N wasn't banned from playing as CT to begin with.", targets[0]);
381 }
382 }
383
384 return Plugin_Handled;
385}
386
387public OnClientDisconnect(client)
388{
389 if (g_iDatabaseId[client] != -1 && IsClientConnected(client))
390 {
391 decl String:query[255],
392 String:name[MAX_NAME_LENGTH],
393 String:name2[2*(MAX_NAME_LENGTH)+1];
394 GetClientName(client, name, sizeof(name));
395 SQL_EscapeString(g_hDatabase, name, name2, sizeof(name2));
396
397 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QUpdate], name2, g_iDatabaseId[client], DBPrio_Low);
398 SQL_TQuery(g_hDatabase, T_NoAction, query);
399 }
400
401 g_iDatabaseId[client] = -1;
402}
403
404public T_NoAction(Handle:owner, Handle:hndl, const String:error[], any:data)
405{
406 if (hndl == INVALID_HANDLE)
407 {
408 SetFailState(error);
409 }
410}
411
412public Action:CListener_JoinTeam(client, const String:command[], argc)
413{
414 if (g_iDatabaseId[client] != -1)
415 {
416 decl String:buff[8], Action:ret, team;
417
418 GetCmdArg(1, buff, sizeof(buff));
419 StripQuotes(buff);
420 TrimString(buff);
421
422 if (!strlen(buff))
423 {
424 return Plugin_Handled;
425 }
426
427 team = StringToInt(buff);
428
429 if (team)
430 {
431 if (team == g_c_banned_team)
432 {
433 ret = Plugin_Handled;
434 PrintRejectionMessage(client);
435 }
436 else
437 {
438 ret = Plugin_Continue;
439 }
440 }
441 else
442 {
443 if (GetClientTeam(client) != (g_c_banned_team==3?2:3))
444 {
445 ChangeClientTeam(client, g_c_banned_team==3?2:3);
446 }
447
448 ret = Plugin_Handled;
449 }
450
451 return ret;
452 }
453
454 return Plugin_Continue;
455}
456
457public Action:Event_PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
458{
459 if (GetConVarInt(g_hCvEnabled))
460 {
461 new client = GetClientOfUserId(GetEventInt(event, "userid"));
462
463 if (client && IsClientConnected(client) && IsClientInGame(client) && !GetEventInt(event, "disconnect") &&
464 !IsFakeClient(client) && g_iDatabaseId[client] != -1 && GetEventInt(event, "team") == g_c_banned_team)
465 {
466 CreateTimer(0.1, Timer_ChangeTeam, client, TIMER_FLAG_NO_MAPCHANGE);
467 PrintRejectionMessage(client);
468 }
469 }
470}
471public Action:Timer_ChangeTeam(Handle:timer, any:client)
472{
473 ChangeClientTeam(client, g_c_banned_team==3?2:3);
474}
475
476PrintRejectionMessage(client)
477{
478 PrintToChat(client, "%c[CTBan]%c You're banned from joining that team!", GREEN, LIGHTGREEN);
479 for (new i = 1; i <= MaxClients; i++)
480 {
481 if (i != client && IsClientConnected(i) && IsClientInGame(i))
482 {
483 PrintToChat(i, "%c[CTBan]%c %N tried to join CT, but was rejected", GREEN, LIGHTGREEN, client);
484 }
485 }
486}
487
488public Action:Command_ReloadCtBan(client, argc)
489{
490 if (argc != 1)
491 {
492 ReplyToCommand(client, "[SM] sm_reloadctban <player(s)> | Reload bans");
493
494 return Plugin_Handled;
495 }
496
497 new cClients = MaxClients;
498
499 decl String:arg[32],
500 cTargets,
501 targets[cClients],
502 String:target_name[1],
503 bool:tn_is_ml;
504
505 GetCmdArg(1, arg, sizeof(arg));
506 if ((cTargets = ProcessTargetString(arg, client, targets, cClients,
507 COMMAND_FILTER_NO_IMMUNITY | COMMAND_FILTER_NO_BOTS,
508 target_name, sizeof(target_name), tn_is_ml)) <= 0)
509 {
510 ReplyToTargetError(client, cTargets);
511
512 return Plugin_Handled;
513 }
514
515 decl String:authid[32];
516 for (new i = 0; i < cTargets; i++)
517 {
518 GetClientAuthString(targets[i], authid, sizeof(authid));
519 OnClientAuthorized(targets[i], authid);
520 }
521
522 ReplyToCommand(client, "[SM] Reloading CT Ban(s)");
523
524 return Plugin_Handled;
525}
526
527 *
528 * CT Restrict SourceMod Plugin
529 * Copyright (C) 2010 - 2011 B.D.A.K. Koch
530 * This program is free software: you can redistribute it and/or modify
531 * it under the terms of the GNU General Public License as published by
532 * the Free Software Foundation, either version 3 of the License, or
533 * (at your option) any later version.
534 *
535 * This program is distributed in the hope that it will be useful,
536 * but WITHOUT ANY WARRANTY; without even the implied warranty of
537 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
538 * GNU General Public License for more details.
539 *
540 * You should have received a copy of the GNU General Public License
541 * along with this program. If not, see <http://www.gnu.org/licenses/>.
542 */
543#pragma semicolon 1
544
545#include <sourcemod>
546#include <sdktools>
547
548#define YELLOW 0x01
549#define TEAMCOLOR 0x02
550#define LIGHTGREEN 0x03
551#define GREEN 0x04
552
553#define SQLITE__ 0
554#define MYSQL__ 1
555#define SQLMAX__ 2
556
557new g_iDatabaseId[MAXPLAYERS+1] = { -1, ... },
558 Handle:g_hDatabase = INVALID_HANDLE,
559 g_DatabaseType = SQLITE__,
560 Handle:g_hCvEnabled = INVALID_HANDLE;
561
562new const stock g_c_banned_team = 3;
563
564enum EQueries
565{
566 E_QCreate = 0,
567 E_QInsert,
568 E_QConnect,
569 E_QDelete,
570 E_QUpdate,
571 E_QMax
572};
573new stock const String:SQLQueries[SQLMAX__][E_QMax][] =
574{
575 { // SQLite
576 "CREATE TABLE IF NOT EXISTS ct_restrict ( id INTEGER PRIMARY KEY, name VARCHAR(65), steam VARCHAR(32) UNIQUE, ban_time DATE DEFAULT (DATE('now')), admin_steam VARCHAR(32) );",
577 "INSERT OR IGNORE INTO ct_restrict (name, steam, admin_steam) VALUES ('%s', '%s', '%s');",
578 "SELECT id FROM ct_restrict WHERE steam = '%s';",
579 "DELETE FROM ct_restrict WHERE id = '%i';",
580 "UPDATE ct_restrict SET name = '%s' WHERE id = '%i';"
581 },
582 { // MySQL
583 "CREATE TABLE IF NOT EXISTS ct_restrict ( id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, name VARCHAR(65), steam VARCHAR(32) UNIQUE, ban_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, admin_steam VARCHAR(32), status INT(11), unbanned_by VARCHAR(32) );",
584 "INSERT INTO ct_restrict (name, steam, admin_steam, status, unbanned_by) VALUES ('%s', '%s', '%s', '0', '0');",
585 "SELECT id FROM ct_restrict WHERE steam = '%s' AND status = '0';",
586 "DELETE FROM ct_restrict WHERE id = '%i';",
587 "UPDATE ct_restrict SET name = '%s' WHERE id = '%i';"
588 }
589};
590
591#define PLUGIN_NAME "CT Restrict"
592#define PLUGIN_AUTHOR "1Swat2KillThemAll"
593#define PLUGIN_DESCR "Ban players from using the CT team."
594#define PLUGIN_VERSION "1.000.000"
595#define PLUGIN_URL ""
596public Plugin:myinfo =
597{
598 name = PLUGIN_NAME,
599 author = PLUGIN_AUTHOR,
600 description = PLUGIN_DESCR,
601 version = PLUGIN_VERSION,
602 url = PLUGIN_URL
603};
604
605public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) {
606 CreateNative("CTR_IsClientCTBanned", Native_IsClientCTBanned);
607 RegPluginLibrary("ct_restrict");
608
609 return APLRes_Success;
610}
611
612#define ASSERT_NATIVE_ERROR_PARAMS(%1) if (numParams != (%1)) { ThrowNativeError(SP_ERROR_PARAM, "wrong number of parameters supplied: got (%i), expected (%i)", numParams, (%1)); }
613#define ASSERT_NATIVE_ERROR_CLIENT(%1) decl client; if (!(client = GetNativeCell(%1)) || !IsClientInGame(client) || !IsClientConnected(client)) { ThrowNativeError(SP_ERROR_INDEX, "client index %i is invalid", client); }
614public Native_IsClientCTBanned(Handle:plugin, numParams)
615{
616 ASSERT_NATIVE_ERROR_PARAMS(1)
617 ASSERT_NATIVE_ERROR_CLIENT(1)
618
619 return g_iDatabaseId[client] != -1;
620}
621#undef ASSERT_NATIVE_ERROR_PARAMS
622#undef ASSERT_NATIVE_ERROR_CLIENT
623
624public OnPluginStart()
625{
626 CreateConVar("sm_ctrestrict_version", PLUGIN_VERSION, "Version Console Variable", FCVAR_CHEAT | FCVAR_DONTRECORD | FCVAR_NOTIFY);
627 g_hCvEnabled = CreateConVar("sm_ctrestrict_enabled", "1", "Enable plugin?1:0", FCVAR_DONTRECORD, true, 0.0, true, 1.0);
628
629 RegAdminCmd("sm_ctban", Command_CtBan, ADMFLAG_KICK, "sm_ctban <player> | Bans a player from joining CT.");
630 RegAdminCmd("sm_ctunban", Command_CtUnban, ADMFLAG_KICK, "sm_ctunban <player> | Unbans a player from joining CT.");
631 RegAdminCmd("sm_reloadctban", Command_ReloadCtBan, ADMFLAG_ROOT, "sm_reloadctban <player(s)> | Reload bans");
632
633 AddCommandListener(CListener_JoinTeam, "jointeam");
634 HookEvent("player_team", Event_PlayerTeam);
635
636 LoadTranslations("common.phrases");
637
638 decl String:buff[255], String:db_config[128];
639 new use_sqlite = 1;
640
641 new Handle:kv = CreateKeyValues("CTRestrict");
642
643 if (!FileToKeyValues(kv, "cfg/ct_restrict.kv") || !KvGotoFirstSubKey(kv))
644 {
645 LogMessage("Couldn\'t open keyvalue file!");
646 }
647 else
648 {
649 do
650 {
651 KvGetSectionName(kv, buff, sizeof(buff));
652
653 if (StrEqual(buff, "Options"))
654 {
655 if (KvGotoFirstSubKey(kv))
656 {
657 do
658 {
659 KvGetSectionName(kv, buff, sizeof(buff));
660
661 if (StrEqual(buff, "Database"))
662 {
663 if (!(use_sqlite = KvGetNum(kv, "use_sqlite", 0)))
664 {
665 KvGetString(kv, "database_config", db_config, sizeof(db_config), "default");
666 }
667 }
668 } while (KvGotoNextKey(kv));
669
670 KvGoBack(kv);
671 }
672 }
673 } while (KvGotoNextKey(kv));
674 }
675
676 CloseHandle(kv);
677
678 if (!use_sqlite)
679 {
680 if (SQL_CheckConfig(db_config))
681 {
682 if ((g_hDatabase = SQL_Connect(db_config, true, buff, sizeof(buff))) == INVALID_HANDLE)
683 {
684 LogMessage("Couldn't connect to database using configuration \"%s\": %s", db_config, buff);
685 use_sqlite = 1;
686 }
687 else
688 {
689 g_DatabaseType = -1;
690
691 decl String:type[32];
692 new Handle:driver = SQL_ReadDriver(g_hDatabase);
693
694 SQL_GetDriverProduct(driver, type, sizeof(type));
695
696 if (StrEqual(type, "MySQL", false))
697 {
698 g_DatabaseType = MYSQL__;
699 }
700 else if (StrEqual(type, "SQLite", false))
701 {
702 g_DatabaseType = SQLITE__;
703 }
704
705 if (g_DatabaseType < 0)
706 {
707 LogError("Unrecognized Database-type \"%s\".", type);
708 use_sqlite = true;
709 CloseHandle(g_hDatabase);
710 g_hDatabase = INVALID_HANDLE;
711 }
712 }
713 }
714 else
715 {
716 LogMessage("Couldn't find named configuration \"%s\" in databases.cfg.", db_config);
717 use_sqlite = true;
718 }
719 }
720 if (use_sqlite)
721 {
722 if ((g_hDatabase = SQLite_UseDatabase("ct_restrict", buff, sizeof(buff))) == INVALID_HANDLE)
723 {
724 SetFailState(buff);
725 }
726 }
727
728 SQL_TQuery(g_hDatabase, T_NoAction, SQLQueries[g_DatabaseType][E_QCreate], DBPrio_High);
729}
730
731public OnClientAuthorized(client, const String:auth[])
732{
733 g_iDatabaseId[client] = -1;
734
735 if (IsFakeClient(client))
736 {
737 return;
738 }
739
740 decl String:query[255];
741 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QConnect], auth);
742 SQL_TQuery(g_hDatabase, T_ClientConnected, query, GetClientUserId(client));
743}
744public T_ClientConnected(Handle:owner, Handle:hndl, const String:error[], any:uid_client)
745{
746 new client = GetClientOfUserId(uid_client);
747
748 if (!client || !IsClientConnected(client))
749 {
750 return;
751 }
752
753 if (hndl == INVALID_HANDLE)
754 {
755 SetFailState(error);
756 }
757 else if (SQL_FetchRow(hndl))
758 {
759 g_iDatabaseId[client] = SQL_FetchInt(hndl, 0);
760 if (IsClientInGame(client) && GetClientTeam(client) != (g_c_banned_team==3?2:3))
761 {
762 ChangeClientTeam(client, g_c_banned_team==3?2:3);
763 }
764 }
765}
766
767public Action:Command_CtBan(client, argc)
768{
769 if (argc != 1)
770 {
771 ReplyToCommand(client, "[SM] sm_ctban <player> | Bans a player from joining CT.");
772 }
773 else
774 {
775 decl String:arg[128];
776 GetCmdArg(1, arg, sizeof(arg));
777
778 decl reason, targets[1], String:target_name[1], bool:tn_is_ml;
779 if ((reason = ProcessTargetString(arg, client, targets, sizeof(targets),
780 COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_BOTS,
781 target_name, sizeof(target_name), tn_is_ml)) <= 0)
782 {
783 ReplyToTargetError(client, reason);
784
785 return Plugin_Handled;
786 }
787
788 if (reason != 1)
789 {
790 return Plugin_Handled;
791 }
792
793 if (g_iDatabaseId[targets[0]] == -1)
794 {
795 ShowActivity2(client, "[SM]", "%N banned %N from playing on CT.", client, targets[0]);
796
797 if (GetClientTeam(targets[0]) == g_c_banned_team && GetConVarInt(g_hCvEnabled))
798 {
799 ChangeClientTeam(targets[0], g_c_banned_team==3?2:3);
800 PrintToChat(targets[0], "%c[CTBan]%c You've been banned from playing on that team!", GREEN, LIGHTGREEN);
801 }
802
803 decl String:player_authid[32];
804 GetClientAuthString(targets[0], player_authid, sizeof(player_authid));
805 decl String:admin_authid[32];
806 if (client != 0)
807 {
808 GetClientAuthString(client, admin_authid, sizeof(admin_authid));
809 }
810 else
811 {
812 strcopy(admin_authid, sizeof(admin_authid), "SERVER");
813 }
814
815 decl String:query[255],
816 String:name[MAX_NAME_LENGTH],
817 String:name2[2*(MAX_NAME_LENGTH)+1];
818 GetClientName(targets[0], name, sizeof(name));
819 SQL_EscapeString(g_hDatabase, name, name2, sizeof(name2));
820 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QInsert], name2, player_authid, admin_authid);
821
822
823 SQL_TQuery(g_hDatabase, T_Insert, query, GetClientUserId(targets[0]), DBPrio_High);
824 }
825 else
826 {
827 ReplyToCommand(client, "[SM] %N was already banned from playing as CT.", targets[0]);
828 }
829 }
830
831 return Plugin_Handled;
832}
833public T_Insert(Handle:owner, Handle:hndl, const String:error[], any:uid_client)
834{
835 new client = GetClientOfUserId(uid_client);
836
837 if (!IsClientConnected(client))
838 {
839 return;
840 }
841
842 if (hndl == INVALID_HANDLE)
843 {
844 SetFailState(error);
845 }
846 else
847 {
848 decl String:query[255], String:authid[32];
849 GetClientAuthString(client, authid, sizeof(authid));
850
851 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QConnect], authid);
852 SQL_TQuery(g_hDatabase, T_ClientConnected, query, GetClientUserId(client), DBPrio_High);
853 }
854}
855
856public Action:Command_CtUnban(client, argc)
857{
858 if (argc != 1)
859 {
860 ReplyToCommand(client, "[SM] sm_ctunban <player> | Unbans a player from joining CT.");
861 }
862 else
863 {
864 decl String:arg[128];
865 GetCmdArg(1, arg, sizeof(arg));
866
867 decl reason, targets[1], String:target_name[1], bool:tn_is_ml;
868 if ((reason = ProcessTargetString(arg, client, targets, sizeof(targets),
869 COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_BOTS,
870 target_name, sizeof(target_name), tn_is_ml)) <= 0)
871 {
872 ReplyToTargetError(client, reason);
873
874 return Plugin_Handled;
875 }
876
877 if (reason != 1)
878 {
879 return Plugin_Handled;
880 }
881
882 if (g_iDatabaseId[targets[0]] != -1)
883 {
884 ShowActivity2(client, "[SM]", "%N unbanned %N from playing on CT.", client, targets[0]);
885
886 decl String:query[255];
887 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QDelete], g_iDatabaseId[targets[0]]);
888
889 SQL_TQuery(g_hDatabase, T_NoAction, query);
890
891 g_iDatabaseId[targets[0]] = -1;
892 }
893 else
894 {
895 ReplyToCommand(client, "[SM] %N wasn't banned from playing as CT to begin with.", targets[0]);
896 }
897 }
898
899 return Plugin_Handled;
900}
901
902public OnClientDisconnect(client)
903{
904 if (g_iDatabaseId[client] != -1 && IsClientConnected(client))
905 {
906 decl String:query[255],
907 String:name[MAX_NAME_LENGTH],
908 String:name2[2*(MAX_NAME_LENGTH)+1];
909 GetClientName(client, name, sizeof(name));
910 SQL_EscapeString(g_hDatabase, name, name2, sizeof(name2));
911
912 Format(query, sizeof(query), SQLQueries[g_DatabaseType][E_QUpdate], name2, g_iDatabaseId[client], DBPrio_Low);
913 SQL_TQuery(g_hDatabase, T_NoAction, query);
914 }
915
916 g_iDatabaseId[client] = -1;
917}
918
919public T_NoAction(Handle:owner, Handle:hndl, const String:error[], any:data)
920{
921 if (hndl == INVALID_HANDLE)
922 {
923 SetFailState(error);
924 }
925}
926
927public Action:CListener_JoinTeam(client, const String:command[], argc)
928{
929 if (g_iDatabaseId[client] != -1)
930 {
931 decl String:buff[8], Action:ret, team;
932
933 GetCmdArg(1, buff, sizeof(buff));
934 StripQuotes(buff);
935 TrimString(buff);
936
937 if (!strlen(buff))
938 {
939 return Plugin_Handled;
940 }
941
942 team = StringToInt(buff);
943
944 if (team)
945 {
946 if (team == g_c_banned_team)
947 {
948 ret = Plugin_Handled;
949 PrintRejectionMessage(client);
950 }
951 else
952 {
953 ret = Plugin_Continue;
954 }
955 }
956 else
957 {
958 if (GetClientTeam(client) != (g_c_banned_team==3?2:3))
959 {
960 ChangeClientTeam(client, g_c_banned_team==3?2:3);
961 }
962
963 ret = Plugin_Handled;
964 }
965
966 return ret;
967 }
968
969 return Plugin_Continue;
970}
971
972public Action:Event_PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
973{
974 if (GetConVarInt(g_hCvEnabled))
975 {
976 new client = GetClientOfUserId(GetEventInt(event, "userid"));
977
978 if (client && IsClientConnected(client) && IsClientInGame(client) && !GetEventInt(event, "disconnect") &&
979 !IsFakeClient(client) && g_iDatabaseId[client] != -1 && GetEventInt(event, "team") == g_c_banned_team)
980 {
981 CreateTimer(0.1, Timer_ChangeTeam, client, TIMER_FLAG_NO_MAPCHANGE);
982 PrintRejectionMessage(client);
983 }
984 }
985}
986public Action:Timer_ChangeTeam(Handle:timer, any:client)
987{
988 ChangeClientTeam(client, g_c_banned_team==3?2:3);
989}
990
991PrintRejectionMessage(client)
992{
993 PrintToChat(client, "%c[CTBan]%c You're banned from joining that team!", GREEN, LIGHTGREEN);
994 for (new i = 1; i <= MaxClients; i++)
995 {
996 if (i != client && IsClientConnected(i) && IsClientInGame(i))
997 {
998 PrintToChat(i, "%c[CTBan]%c %N tried to join CT, but was rejected", GREEN, LIGHTGREEN, client);
999 }
1000 }
1001}
1002
1003public Action:Command_ReloadCtBan(client, argc)
1004{
1005 if (argc != 1)
1006 {
1007 ReplyToCommand(client, "[SM] sm_reloadctban <player(s)> | Reload bans");
1008
1009 return Plugin_Handled;
1010 }
1011
1012 new cClients = MaxClients;
1013
1014 decl String:arg[32],
1015 cTargets,
1016 targets[cClients],
1017 String:target_name[1],
1018 bool:tn_is_ml;
1019
1020 GetCmdArg(1, arg, sizeof(arg));
1021 if ((cTargets = ProcessTargetString(arg, client, targets, cClients,
1022 COMMAND_FILTER_NO_IMMUNITY | COMMAND_FILTER_NO_BOTS,
1023 target_name, sizeof(target_name), tn_is_ml)) <= 0)
1024 {
1025 ReplyToTargetError(client, cTargets);
1026
1027 return Plugin_Handled;
1028 }
1029
1030 decl String:authid[32];
1031 for (new i = 0; i < cTargets; i++)
1032 {
1033 GetClientAuthString(targets[i], authid, sizeof(authid));
1034 OnClientAuthorized(targets[i], authid);
1035 }
1036
1037 ReplyToCommand(client, "[SM] Reloading CT Ban(s)");
1038
1039 return Plugin_Handled;
1040}