· 6 years ago · Nov 05, 2019, 08:40 AM
1/*
2 Advanced Bans
3
4 Version 0.8.1
5
6 by Exolent
7
8
9
10 Plugin Thread:
11
12 - http://forums.alliedmods.net/showthread.php?t=80858
13
14
15
16 Description:
17
18 - This plugin revamps the current amx_ban, amx_banip, amx_banid, amx_unban admin commands.
19
20 - It uses Real Time on the server
21 (Eg. Banned for 10 minutes, you will be unbanned 10 minutes later, regardless of map changing).
22
23 - It includes a list of who is banned.
24
25 - It does not use the banned.cfg or listip.cfg. It uses its own file where bans are stored.
26
27 - It saves what admin banned the player (name), the admin's steamid, the reason, the ban time,
28 the banned player's name, the banned player's steamid (or IP), and the estimated time of unban.
29
30 - It will load your currently banned players from the banned.cfg and listip.cfg files.
31 (Only if the #define below is uncommented)
32
33 - If you use the menu to ban players, you will have to type a reason after you choose a player.
34
35 - If you use the vote system to ban players, you will have to type a reason after you execute the amx_voteban command.
36
37 - You can limit the ban time for admins based on their admin flags.
38
39 - You can monitor all ban history (admins banning, unbanning, and when ban times are up) in
40 the addons/amxmodx/logs/BAN_HISTORY_MMDDYYYY.log (MM = month, DD = day, YYYY = year)
41
42 - If you wish to have only 1 file for ban history, uncomment the line at the top of the .sma file and recompile.
43
44 - Supports SQL for banning.
45
46
47
48 Commands:
49
50 - amx_ban <nick, #userid, authid> <time in minutes> <reason>
51
52 - amx_banip <nick, #userid, authid> <time in minutes> <reason>
53
54 - amx_addban <name> <authid or ip> <time in minutes> <reason>
55
56 - amx_unban <authid or ip>
57
58 - amx_banlist
59 - Shows a list of who is banned
60
61 - amx_addbanlimit <flags> <time in minutes>
62 - Adds a max ban time to the list
63 - Note: Use this command in the amxx.cfg
64
65
66
67 Cvars:
68
69 - ab_website <website>
70 - This is the website displayed to the banned player if you have an unban request section on your website.
71 - Leave blank to not show a website.
72 - Default: blank
73
74 - ab_immunity <0|1|2>
75 - 0 - Any admin can ban an immunity admin (flag 'a').
76 - 1 - Immunity admins (flag 'a') cannot be banned.
77 - 2 - Immunity admins (flag 'a') can only be banned by other immunity admins (flag 'a').
78 - Default: 1
79
80 - ab_bandelay <seconds>
81 - Delay of banned players being disconnected.
82 - Default: 1
83
84 - ab_unbancheck <seconds>
85 - Interval of checking if a player is unbanned.
86 - Default: 5
87
88
89
90 Requirements:
91
92 - AMX Mod X version 1.8.0 or higher
93
94
95
96 Changelog:
97
98 - Version 0.1 (with updates included)
99 - Initial Release
100 - Changed to dynamic arrays to hold ban information
101 - Added option #2 for ab_immunity
102 - Added support for banning by IP
103 - Added compatability for banned.cfg and listip.cfg
104 - Added menu support (plmenu.amxx)
105 - Added ML support
106
107 - Version 0.2
108 - Added simple max ban time feature
109
110 - Version 0.3
111 - Added more cvars for max ban times
112 - Added cvar for delay of player to disconenct after being banned
113 - Added cvar for interval of checking for unban time of banned players
114 - Added more translations
115
116 - Version 0.4
117 - Fixed the possible infinite loop, causing servers to crash
118 - Added ban history
119 - Removed max ban time cvars
120 - Added max ban times per admin flags
121 - Added more translations
122
123 - Version 0.5
124 - Fixed information not being printed into console
125 - Fixed "amx_addban" using the admin's name as the SteamID when saving the ban
126 - Added option for ban history to be one file
127 - Added translations
128
129 - Version 0.5b
130 - Fixed players not being unbanned
131 - Added translations
132
133 - Version 0.6
134 - Added small optimization for unban checking
135 - Changed "UnBan Time" in the logs and chat messages to "Ban Length"
136 - Fixed small code error where unban time was generated was used when length was 0
137 - Changed IsValidIP() method to use regex (Thanks to arkshine)
138 - Added plugin information inside the .sma file
139 - Added a #define option to use maximum bans for compatability for AMXX < 1.8.0
140 - Changed admin messages in chat to work with amx_show_activity cvar
141 - Added translations
142
143 - Version 0.6b
144 - Fixed a small bug
145
146 - Version 0.6c
147 - Fixed amx_banlist for server consoles
148 - Changed IsValidAuthid() method to use regex
149
150 - Version 0.6d
151 - Fixed ban limit for permanent bans
152
153 - Version 0.7
154 - Changed the "unlimited bans" version to be faster (Thanks to joaquimandrade)
155 - Added check when adding bans if the player is already banned.
156
157 - Version 0.8
158 - Added SQL support.
159
160 - Version 0.8.1
161 - Added unban logging for non-SQL version
162
163
164
165 Notes:
166
167 - If you plan to use this plugin, go to the plugin's thread.
168
169 - The plugin's thread has more information about the plugin, along with the multilingual file.
170
171 - It also has a modified plmenu.amxx plugin that adds the ban reason to the menu.
172
173 - And it has a modified adminvote.amxx plugin that adds the ban reason to amx_voteban.
174*/
175
176
177
178#include <amxmodx>
179#include <amxmisc>
180#include <engine>
181#include <regex>
182
183#define PLUGIN_NAME "Advanced Bans"
184#define PLUGIN_VERSION "0.8.1"
185#define PLUGIN_AUTHOR "Exolent"
186
187#pragma semicolon 1
188
189
190
191// ===============================================
192// CUSTOMIZATION STARTS HERE
193// ===============================================
194
195
196// uncomment the line below if you want this plugin to
197// load old bans from the banned.cfg and listip.cfg files
198//#define KEEP_DEFAULT_BANS
199
200
201// uncomment the line below if you want the history to be in one file
202//#define HISTORY_ONE_FILE
203
204
205// if you must have a maximum amount of bans to be compatible with AMXX versions before 1.8.0
206// change this number to your maximum amount
207// if you would rather have unlimited (requires AMXX 1.8.0 or higher) then set it to 0
208#define MAX_BANS 0
209
210
211// if you want to use SQL for your server, then uncomment the line below
212//#define USING_SQL
213
214
215// ===============================================
216// CUSTOMIZATION ENDS HERE
217// ===============================================
218
219
220
221#if defined USING_SQL
222#include <sqlx>
223
224#define TABLE_NAME "advanced_bans"
225#define KEY_NAME "name"
226#define KEY_STEAMID "steamid"
227#define KEY_BANLENGTH "banlength"
228#define KEY_UNBANTIME "unbantime"
229#define KEY_REASON "reason"
230#define KEY_ADMIN_NAME "admin_name"
231#define KEY_ADMIN_STEAMID "admin_steamid"
232
233#define RELOAD_BANS_INTERVAL 60.0
234#endif
235
236#define REGEX_IP_PATTERN "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"
237// OLD Metod #define REGEX_STEAMID_PATTERN "^^STEAM_0:(0|1):\d+$"
238#define REGEX_STEAMID_PATTERN "^^STEAM_(0|1):(0|1):\d+$" // Modificat pentru a lua in considerare STEAM_1/0
239
240new Regex:g_IP_pattern;
241new Regex:g_SteamID_pattern;
242new g_regex_return;
243
244/*bool:IsValidIP(const ip[])
245{
246 return regex_match_c(ip, g_IP_pattern, g_regex_return) > 0;
247}*/
248
249#define IsValidIP(%1) (regex_match_c(%1, g_IP_pattern, g_regex_return) > 0)
250
251/*bool:IsValidAuthid(const authid[])
252{
253 return regex_match_c(authid, g_SteamID_pattern, g_regex_return) > 0;
254}*/
255
256#define IsValidAuthid(%1) (regex_match_c(%1, g_SteamID_pattern, g_regex_return) > 0)
257
258
259enum // for name displaying
260{
261 ACTIVITY_NONE, // nothing is shown
262 ACTIVITY_HIDE, // admin name is hidden
263 ACTIVITY_SHOW // admin name is shown
264};
265new const g_admin_activity[] =
266{
267 ACTIVITY_NONE, // amx_show_activity 0 = show nothing to everyone
268 ACTIVITY_HIDE, // amx_show_activity 1 = hide admin name from everyone
269 ACTIVITY_SHOW, // amx_show_activity 2 = show admin name to everyone
270 ACTIVITY_SHOW, // amx_show_activity 3 = show name to admins but hide it from normal users
271 ACTIVITY_SHOW, // amx_show_activity 4 = show name to admins but show nothing to normal users
272 ACTIVITY_HIDE // amx_show_activity 5 = hide name from admins but show nothing to normal users
273};
274new const g_normal_activity[] =
275{
276 ACTIVITY_NONE, // amx_show_activity 0 = show nothing to everyone
277 ACTIVITY_HIDE, // amx_show_activity 1 = hide admin name from everyone
278 ACTIVITY_SHOW, // amx_show_activity 2 = show admin name to everyone
279 ACTIVITY_HIDE, // amx_show_activity 3 = show name to admins but hide it from normal users
280 ACTIVITY_NONE, // amx_show_activity 4 = show name to admins but show nothing to normal users
281 ACTIVITY_NONE // amx_show_activity 5 = hide name from admins but show nothing to normal users
282};
283
284
285#if MAX_BANS <= 0
286enum _:BannedData
287{
288 bd_name[32],
289 bd_steamid[35],
290 bd_banlength,
291 bd_unbantime[32],
292 bd_reason[128],
293 bd_admin_name[64],
294 bd_admin_steamid[35]
295};
296
297new Trie:g_trie;
298new Array:g_array;
299#else
300new g_names[MAX_BANS][32];
301new g_steamids[MAX_BANS][35];
302new g_banlengths[MAX_BANS];
303new g_unbantimes[MAX_BANS][32];
304new g_reasons[MAX_BANS][128];
305new g_admin_names[MAX_BANS][64];
306new g_admin_steamids[MAX_BANS][35];
307#endif
308new g_total_bans;
309
310#if !defined USING_SQL
311new g_ban_file[64];
312#else
313new Handle:g_sql_tuple;
314new bool:g_loading_bans = true;
315#endif
316
317new ab_website;
318new ab_immunity;
319new ab_bandelay;
320new ab_unbancheck;
321
322new amx_show_activity;
323
324#if MAX_BANS <= 0
325new Array:g_maxban_times;
326new Array:g_maxban_flags;
327#else
328#define MAX_BANLIMITS 30
329new g_maxban_times[MAX_BANLIMITS];
330new g_maxban_flags[MAX_BANLIMITS];
331#endif
332new g_total_maxban_times;
333
334new g_unban_entity;
335
336new g_max_clients;
337
338new g_msgid_SayText;
339
340public plugin_init()
341{
342 register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
343 register_cvar("advanced_bans", PLUGIN_VERSION, FCVAR_SPONLY);
344
345 register_dictionary("advanced_bans.txt");
346
347 register_concmd("amx_ban", "CmdBan", ADMIN_BAN, "<nick, #userid, authid> <time in minutes> <reason>");
348 register_concmd("amx_banip", "CmdBanIp", ADMIN_BAN, "<nick, #userid, authid> <time in minutes> <reason>");
349 register_concmd("amx_addban", "CmdAddBan", ADMIN_BAN, "<name> <authid or ip> <time in minutes> <reason>");
350 register_concmd("amx_unban", "CmdUnban", ADMIN_BAN, "<authid or ip>");
351 register_concmd("amx_banlist", "CmdBanList", ADMIN_BAN, "[start] -- shows everyone who is banned");
352 register_srvcmd("amx_addbanlimit", "CmdAddBanLimit", -1, "<flag> <time in minutes>");
353
354 ab_website = register_cvar("ab_website", "Site sectiunea Server");
355 ab_immunity = register_cvar("ab_immunity", "0");
356 ab_bandelay = register_cvar("ab_bandelay", "1.0");
357 ab_unbancheck = register_cvar("ab_unbancheck", "5.0");
358
359 amx_show_activity = register_cvar("amx_show_activity", "2");
360
361 #if MAX_BANS <= 0
362 g_trie = TrieCreate();
363 g_array = ArrayCreate(BannedData);
364 #endif
365
366 #if !defined MAX_BANLIMITS
367 g_maxban_times = ArrayCreate(1);
368 g_maxban_flags = ArrayCreate(1);
369 #endif
370
371 #if !defined USING_SQL
372 get_datadir(g_ban_file, sizeof(g_ban_file) - 1);
373 add(g_ban_file, sizeof(g_ban_file) - 1, "/advanced_bans.txt");
374
375 LoadBans();
376 #else
377 g_sql_tuple = SQL_MakeStdTuple();
378 PrepareTable();
379 #endif
380
381 new error[2];
382 g_IP_pattern = regex_compile(REGEX_IP_PATTERN, g_regex_return, error, sizeof(error) - 1);
383 g_SteamID_pattern = regex_compile(REGEX_STEAMID_PATTERN, g_regex_return, error, sizeof(error) - 1);
384
385 g_max_clients = get_maxplayers();
386
387 g_msgid_SayText = get_user_msgid("SayText");
388}
389
390#if defined USING_SQL
391PrepareTable()
392{
393 new query[128];
394 formatex(query, sizeof(query) - 1,\
395 "CREATE TABLE IF NOT EXISTS `%s` (`%s` varchar(32) NOT NULL, `%s` varchar(35) NOT NULL, `%s` int(10) NOT NULL, `%s` varchar(32) NOT NULL, `%s` varchar(128) NOT NULL, `%s` varchar(64) NOT NULL, `%s` varchar(35) NOT NULL);",\
396 TABLE_NAME, KEY_NAME, KEY_STEAMID, KEY_BANLENGTH, KEY_UNBANTIME, KEY_REASON, KEY_ADMIN_NAME, KEY_ADMIN_STEAMID
397 );
398
399 SQL_ThreadQuery(g_sql_tuple, "QueryCreateTable", query);
400}
401
402public QueryCreateTable(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
403{
404 if( failstate == TQUERY_CONNECT_FAILED )
405 {
406 set_fail_state("Could not connect to database.");
407 }
408 else if( failstate == TQUERY_QUERY_FAILED )
409 {
410 set_fail_state("Query failed.");
411 }
412 else if( errcode )
413 {
414 log_amx("Error on query: %s", error);
415 }
416 else
417 {
418 LoadBans();
419 }
420}
421#endif
422
423public plugin_cfg()
424{
425 CreateUnbanEntity();
426}
427
428public CreateUnbanEntity()
429{
430 static failtimes;
431
432 g_unban_entity = create_entity("info_target");
433
434 if( !is_valid_ent(g_unban_entity) )
435 {
436 ++failtimes;
437
438 log_amx("[ERROR] Failed to create unban entity (%i/10)", failtimes);
439
440 if( failtimes < 10 )
441 {
442 set_task(1.0, "CreateUnbanEntity");
443 }
444 else
445 {
446 log_amx("[ERROR] Could not create unban entity!");
447 }
448
449 return;
450 }
451
452 entity_set_string(g_unban_entity, EV_SZ_classname, "unban_entity");
453 entity_set_float(g_unban_entity, EV_FL_nextthink, get_gametime() + 1.0);
454
455 register_think("unban_entity", "FwdThink");
456}
457
458public client_authorized(client)
459{
460 static authid[35];
461 get_user_authid(client, authid, sizeof(authid) - 1);
462
463 static ip[35];
464 get_user_ip(client, ip, sizeof(ip) - 1, 1);
465
466 #if MAX_BANS > 0
467 static banned_authid[35], bool:is_ip;
468 for( new i = 0; i < g_total_bans; i++ )
469 {
470 copy(banned_authid, sizeof(banned_authid) - 1, g_steamids[i]);
471
472 is_ip = bool:(containi(banned_authid, ".") != -1);
473
474 if( is_ip && equal(ip, banned_authid) || !is_ip && equal(authid, banned_authid) )
475 {
476 static name[32], reason[128], unbantime[32], admin_name[32], admin_steamid[64];
477 copy(name, sizeof(name) - 1, g_names[i]);
478 copy(reason, sizeof(reason) - 1, g_reasons[i]);
479 new banlength = g_banlengths[i];
480 copy(unbantime, sizeof(unbantime) - 1, g_unbantimes[i]);
481 copy(admin_name, sizeof(admin_name) - 1, g_admin_names[i]);
482 copy(admin_steamid, sizeof(admin_steamid) - 1, g_admin_steamids[i]);
483
484 PrintBanInformation(client, name, banned_authid, reason, banlength, unbantime, admin_name, admin_steamid, true, true);
485
486 set_task(get_pcvar_float(ab_bandelay), "TaskDisconnectPlayer", client);
487 break;
488 }
489 }
490 #else
491 static array_pos;
492
493 if( TrieGetCell(g_trie, authid, array_pos) || TrieGetCell(g_trie, ip, array_pos) )
494 {
495 static data[BannedData];
496 ArrayGetArray(g_array, array_pos, data);
497
498 PrintBanInformation(client, data[bd_name], data[bd_steamid], data[bd_reason], data[bd_banlength], data[bd_unbantime], data[bd_admin_name], data[bd_admin_steamid], true, true);
499
500 set_task(get_pcvar_float(ab_bandelay), "TaskDisconnectPlayer", client);
501 }
502 #endif
503}
504
505public CmdBan(client, level, cid)
506{
507 if( !cmd_access(client, level, cid, 4) ) return PLUGIN_HANDLED;
508
509 static arg[128];
510 read_argv(1, arg, sizeof(arg) - 1);
511
512 new target = cmd_target(client, arg, GetTargetFlags(client));
513 if( !target ) return PLUGIN_HANDLED;
514
515 static target_authid[35];
516 get_user_authid(target, target_authid, sizeof(target_authid) - 1);
517
518 if( !IsValidAuthid(target_authid) )
519 {
520 console_print(client, "[Advanced Bans] %L", client, "AB_NOT_AUTHORIZED");
521 return PLUGIN_HANDLED;
522 }
523
524 #if MAX_BANS <= 0
525 if( TrieKeyExists(g_trie, target_authid) )
526 {
527 console_print(client, "[Advanced Bans] %L", client, "AB_ALREADY_BANNED_STEAMID");
528 return PLUGIN_HANDLED;
529 }
530 #else
531 for( new i = 0; i < g_total_bans; i++ )
532 {
533 if( !strcmp(target_authid, g_steamids[i], 1) )
534 {
535 console_print(client, "[Advanced Bans] %L", client, "AB_ALREADY_BANNED_STEAMID");
536 return PLUGIN_HANDLED;
537 }
538 }
539 #endif
540
541 read_argv(2, arg, sizeof(arg) - 1);
542
543 new length = str_to_num(arg);
544 new maxlength = GetMaxBanTime(client);
545
546 if( maxlength && (!length || length > maxlength) )
547 {
548 console_print(client, "[Advanced Bans] %L", client, "AB_MAX_BAN_TIME", maxlength);
549 return PLUGIN_HANDLED;
550 }
551
552 static unban_time[64];
553 if( length == 0 )
554 {
555 formatex(unban_time, sizeof(unban_time) - 1, "%L", client, "AB_PERMANENT_BAN");
556 }
557 else
558 {
559 GenerateUnbanTime(length, unban_time, sizeof(unban_time) - 1);
560 }
561
562 read_argv(3, arg, sizeof(arg) - 1);
563
564 static admin_name[64], target_name[32];
565 get_user_name(client, admin_name, sizeof(admin_name) - 1);
566 get_user_name(target, target_name, sizeof(target_name) - 1);
567
568 static admin_authid[35];
569 get_user_authid(client, admin_authid, sizeof(admin_authid) - 1);
570
571 AddBan(target_name, target_authid, arg, length, unban_time, admin_name, admin_authid);
572
573 PrintBanInformation(target, target_name, target_authid, arg, length, unban_time, admin_name, admin_authid, true, true);
574 PrintBanInformation(client, target_name, target_authid, arg, length, unban_time, admin_name, admin_authid, false, false);
575
576 set_task(get_pcvar_float(ab_bandelay), "TaskDisconnectPlayer", target);
577
578 GetBanTime(length, unban_time, sizeof(unban_time) - 1);
579
580 PrintActivity(admin_name, "^x03[Advanced Bans] $name^x01 : Ban ^x03%s^x01. Motiv: ^x03%s^x01. Timp unban: ^x03%s^x01", target_name, arg, unban_time);
581
582 Log("%s <%s> banned %s <%s> || Reason: ^"%s^" || Ban Length: %s", admin_name, admin_authid, target_name, target_authid, arg, unban_time);
583
584 return PLUGIN_HANDLED;
585}
586
587public CmdBanIp(client, level, cid)
588{
589 if( !cmd_access(client, level, cid, 4) ) return PLUGIN_HANDLED;
590
591 static arg[128];
592 read_argv(1, arg, sizeof(arg) - 1);
593
594 new target = cmd_target(client, arg, GetTargetFlags(client));
595 if( !target ) return PLUGIN_HANDLED;
596
597 static target_ip[35];
598 get_user_ip(target, target_ip, sizeof(target_ip) - 1, 1);
599
600 #if MAX_BANS <= 0
601 if( TrieKeyExists(g_trie, target_ip) )
602 {
603 console_print(client, "[Advanced Bans] %L", client, "AB_ALREADY_BANNED_IP");
604 return PLUGIN_HANDLED;
605 }
606 #else
607 for( new i = 0; i < g_total_bans; i++ )
608 {
609 if( !strcmp(target_ip, g_steamids[i], 1) )
610 {
611 console_print(client, "[Advanced Bans] %L", client, "AB_ALREADY_BANNED_IP");
612 return PLUGIN_HANDLED;
613 }
614 }
615 #endif
616
617 read_argv(2, arg, sizeof(arg) - 1);
618
619 new length = str_to_num(arg);
620 new maxlength = GetMaxBanTime(client);
621
622 if( maxlength && (!length || length > maxlength) )
623 {
624 console_print(client, "[Advanced Bans] %L", client, "AB_MAX_BAN_TIME", maxlength);
625 return PLUGIN_HANDLED;
626 }
627
628 static unban_time[32];
629
630 if( length == 0 )
631 {
632 formatex(unban_time, sizeof(unban_time) - 1, "%L", client, "AB_PERMANENT_BAN");
633 }
634 else
635 {
636 GenerateUnbanTime(length, unban_time, sizeof(unban_time) - 1);
637 }
638
639 read_argv(3, arg, sizeof(arg) - 1);
640
641 static admin_name[64], target_name[32];
642 get_user_name(client, admin_name, sizeof(admin_name) - 1);
643 get_user_name(target, target_name, sizeof(target_name) - 1);
644
645 static admin_authid[35];
646 get_user_authid(client, admin_authid, sizeof(admin_authid) - 1);
647
648 AddBan(target_name, target_ip, arg, length, unban_time, admin_name, admin_authid);
649
650 PrintBanInformation(target, target_name, target_ip, arg, length, unban_time, admin_name, admin_authid, true, true);
651 PrintBanInformation(client, target_name, target_ip, arg, length, unban_time, admin_name, admin_authid, false, false);
652
653 set_task(get_pcvar_float(ab_bandelay), "TaskDisconnectPlayer", target);
654
655 GetBanTime(length, unban_time, sizeof(unban_time) - 1);
656
657
658 PrintActivity(admin_name, "^x03[Advanced Bans] $name^x01 : Ban ^x03%s^x01. Motiv: ^x03%s^x01. Timp unban: ^x03%s^x01", target_name, arg, unban_time);
659 //PrintActivity(admin_name, "^x04[Advanced Bans] $name^x01 :^x03 banned %s. Reason: %s. Ban Length: %s", target_name, arg, unban_time);
660
661 Log("%s <%s> banned %s <%s> || Reason: ^"%s^" || Ban Length: %s", admin_name, admin_authid, target_name, target_ip, arg, unban_time);
662
663 return PLUGIN_HANDLED;
664}
665
666public CmdAddBan(client, level, cid)
667{
668 if( !cmd_access(client, level, cid, 5) ) return PLUGIN_HANDLED;
669
670 static target_name[32], target_authid[35], bantime[10], reason[128];
671 read_argv(1, target_name, sizeof(target_name) - 1);
672 read_argv(2, target_authid, sizeof(target_authid) - 1);
673 read_argv(3, bantime, sizeof(bantime) - 1);
674 read_argv(4, reason, sizeof(reason) - 1);
675
676 new bool:is_ip = bool:(containi(target_authid, ".") != -1);
677
678 if( !is_ip && !IsValidAuthid(target_authid) )
679 {
680 console_print(client, "[Advanced Bans] %L", client, "AB_INVALID_STEAMID");
681 console_print(client, "[Advanced Bans] %L", client, "AB_VALID_STEAMID_FORMAT");
682
683 return PLUGIN_HANDLED;
684 }
685 else if( is_ip )
686 {
687 new pos = contain(target_authid, ":");
688 if( pos > 0 )
689 {
690 target_authid[pos] = 0;
691 }
692
693 if( !IsValidIP(target_authid) )
694 {
695 console_print(client, "[Advanced Bans] %L", client, "AB_INVALID_IP");
696
697 return PLUGIN_HANDLED;
698 }
699 }
700
701 #if MAX_BANS <= 0
702 if( TrieKeyExists(g_trie, target_authid) )
703 {
704 console_print(client, "[Advanced Bans] %L", client, is_ip ? "AB_ALREADY_BANNED_IP" : "AB_ALREADY_BANNED_STEAMID");
705 return PLUGIN_HANDLED;
706 }
707 #else
708 for( new i = 0; i < g_total_bans; i++ )
709 {
710 if( !strcmp(target_authid, g_steamids[i], 1) )
711 {
712 console_print(client, "[Advanced Bans] %L", client, is_ip ? "AB_ALREADY_BANNED_IP" : "AB_ALREADY_BANNED_STEAMID");
713 return PLUGIN_HANDLED;
714 }
715 }
716 #endif
717
718 new length = str_to_num(bantime);
719 new maxlength = GetMaxBanTime(client);
720
721 if( maxlength && (!length || length > maxlength) )
722 {
723 console_print(client, "[Advanced Bans] %L", client, "AB_MAX_BAN_TIME", maxlength);
724 return PLUGIN_HANDLED;
725 }
726
727 if( is_user_connected(find_player(is_ip ? "d" : "c", target_authid)) )
728 {
729 client_cmd(client, "amx_ban ^"%s^" %i ^"%s^"", target_authid, length, reason);
730 return PLUGIN_HANDLED;
731 }
732
733 static unban_time[32];
734 if( length == 0 )
735 {
736 formatex(unban_time, sizeof(unban_time) - 1, "%L", client, "AB_PERMANENT_BAN");
737 }
738 else
739 {
740 GenerateUnbanTime(length, unban_time, sizeof(unban_time) - 1);
741 }
742
743 static admin_name[64], admin_authid[35];
744 get_user_name(client, admin_name, sizeof(admin_name) - 1);
745 get_user_authid(client, admin_authid, sizeof(admin_authid) - 1);
746
747 AddBan(target_name, target_authid, reason, length, unban_time, admin_name, admin_authid);
748
749 PrintBanInformation(client, target_name, target_authid, reason, length, unban_time, "", "", false, false);
750
751 GetBanTime(length, unban_time, sizeof(unban_time) - 1);
752
753 PrintActivity(admin_name, "^x03[Advanced Bans] $name^x01 : Ban ^x03%s^x01. Motiv: ^x03%s^x01. Timp unban: ^x03%s^x01", is_ip ? "IP" : "SteamID", target_authid, reason, unban_time);
754 //PrintActivity(admin_name, "^x04[Advanced Bans] $name^x01 :^x03 banned %s %s. Reason: %s. Ban Length: %s", is_ip ? "IP" : "SteamID", target_authid, reason, unban_time);
755
756 Log("%s <%s> banned %s <%s> || Reason: ^"%s^" || Ban Length: %s", admin_name, admin_authid, target_name, target_authid, reason, unban_time);
757
758 return PLUGIN_HANDLED;
759}
760
761public CmdUnban(client, level, cid)
762{
763 if( !cmd_access(client, level, cid, 2) ) return PLUGIN_HANDLED;
764
765 static arg[35];
766 read_argv(1, arg, sizeof(arg) - 1);
767
768 #if MAX_BANS > 0
769 static banned_authid[35];
770 for( new i = 0; i < g_total_bans; i++ )
771 {
772 copy(banned_authid, sizeof(banned_authid) - 1, g_steamids[i]);
773
774 if( equal(arg, banned_authid) )
775 {
776 static admin_name[64];
777 get_user_name(client, admin_name, sizeof(admin_name) - 1);
778
779 static name[32], reason[128];
780 copy(name, sizeof(name) - 1, g_names[i]);
781 copy(reason, sizeof(reason) - 1, g_reasons[i]);
782
783 PrintActivity(admin_name, "^x04[Advanced Bans] $name^x01 : Unbanned^x03 %s^x01 [^x03%s^x01] [Motiv: ^x03%s^x01]", name, arg, reason);
784
785 //PrintActivity(admin_name, "^x04[Advanced Bans] $name^x01 :^x03 unbanned %s^x01 [%s] [Ban Reason: %s]", name, arg, reason);
786
787 static authid[35];
788 get_user_authid(client, authid, sizeof(authid) - 1);
789
790 Log("%s <%s> unbanned %s <%s> || Ban Reason: ^"%s^"", admin_name, authid, name, arg, reason);
791
792 RemoveBan(i);
793
794 return PLUGIN_HANDLED;
795 }
796 }
797 #else
798 if( TrieKeyExists(g_trie, arg) )
799 {
800 static array_pos;
801 TrieGetCell(g_trie, arg, array_pos);
802
803 static data[BannedData];
804 ArrayGetArray(g_array, array_pos, data);
805
806 static unban_name[32];
807 get_user_name(client, unban_name, sizeof(unban_name) - 1);
808
809 PrintActivity(unban_name, "^x04[Advanced Bans] $name^x01 : Unbanned^x03 %s^x01 [^x03%s^x01] [Motiv: ^x03%s^x01]", data[bd_name], data[bd_steamid], data[bd_reason]);
810 //PrintActivity(unban_name, "^x04[Advanced Bans] $name^x01 :^x03 unbanned %s^x01 [%s] [Ban Reason: %s]", data[bd_name], data[bd_steamid], data[bd_reason]);
811
812 static admin_name[64];
813 get_user_name(client, admin_name, sizeof(admin_name) - 1);
814
815 static authid[35];
816 get_user_authid(client, authid, sizeof(authid) - 1);
817
818 Log("%s <%s> unbanned %s <%s> || Ban Reason: ^"%s^"", admin_name, authid, data[bd_name], data[bd_steamid], data[bd_reason]);
819
820 RemoveBan(array_pos, data[bd_steamid]);
821
822 return PLUGIN_HANDLED;
823 }
824 #endif
825
826 console_print(client, "[Advanced Bans] %L", client, "AB_NOT_IN_BAN_LIST", arg);
827
828 return PLUGIN_HANDLED;
829}
830
831public CmdBanList(client, level, cid)
832{
833 if( !cmd_access(client, level, cid, 1) ) return PLUGIN_HANDLED;
834
835 if( !g_total_bans )
836 {
837 console_print(client, "[Advanced Bans] %L", client, "AB_NO_BANS");
838 return PLUGIN_HANDLED;
839 }
840
841 static start;
842
843 if( read_argc() > 1 )
844 {
845 static arg[5];
846 read_argv(1, arg, sizeof(arg) - 1);
847
848 start = min(str_to_num(arg), g_total_bans) - 1;
849 }
850 else
851 {
852 start = 0;
853 }
854
855 new last = min(start + 10, g_total_bans);
856
857 if( client == 0 )
858 {
859 server_cmd("echo ^"%L^"", client, "AB_BAN_LIST_NUM", start + 1, last);
860 }
861 else
862 {
863 client_cmd(client, "echo ^"%L^"", client, "AB_BAN_LIST_NUM", start + 1, last);
864 }
865
866 for( new i = start; i < last; i++ )
867 {
868 #if MAX_BANS <= 0
869 static data[BannedData];
870 ArrayGetArray(g_array, i, data);
871
872 PrintBanInformation(client, data[bd_name], data[bd_steamid], data[bd_reason], data[bd_banlength], data[bd_unbantime], data[bd_admin_name], data[bd_admin_steamid], true, false);
873 #else
874 static name[32], steamid[35], reason[128], banlength, unbantime[32], admin_name[32], admin_steamid[35];
875
876 copy(name, sizeof(name) - 1, g_names[i]);
877 copy(steamid, sizeof(steamid) - 1, g_steamids[i]);
878 copy(reason, sizeof(reason) - 1, g_reasons[i]);
879 banlength = g_banlengths[i];
880 copy(unbantime, sizeof(unbantime) - 1, g_unbantimes[i]);
881 copy(admin_name, sizeof(admin_name) - 1, g_admin_names[i]);
882 copy(admin_steamid, sizeof(admin_steamid) - 1, g_admin_steamids[i]);
883
884 PrintBanInformation(client, name, steamid, reason, banlength, unbantime, admin_name, admin_steamid, true, false);
885 #endif
886 }
887
888 if( ++last < g_total_bans )
889 {
890 if( client == 0 )
891 {
892 server_cmd("echo ^"%L^"", client, "AB_BAN_LIST_NEXT", last);
893 }
894 else
895 {
896 client_cmd(client, "echo ^"%L^"", client, "AB_BAN_LIST_NEXT", last);
897 }
898 }
899
900 return PLUGIN_HANDLED;
901}
902
903public CmdAddBanLimit()
904{
905 if( read_argc() != 3 )
906 {
907 log_amx("amx_addbanlimit was used with incorrect parameters!");
908 log_amx("Usage: amx_addbanlimit <flags> <time in minutes>");
909 return PLUGIN_HANDLED;
910 }
911
912 static arg[16];
913
914 read_argv(1, arg, sizeof(arg) - 1);
915 new flags = read_flags(arg);
916
917 read_argv(2, arg, sizeof(arg) - 1);
918 new minutes = str_to_num(arg);
919
920 #if !defined MAX_BANLIMITS
921 ArrayPushCell(g_maxban_flags, flags);
922 ArrayPushCell(g_maxban_times, minutes);
923 #else
924 if( g_total_maxban_times >= MAX_BANLIMITS )
925 {
926 static notified;
927 if( !notified )
928 {
929 log_amx("The amx_addbanlimit has reached its maximum!");
930 notified = 1;
931 }
932 return PLUGIN_HANDLED;
933 }
934
935 g_maxban_flags[g_total_maxban_times] = flags;
936 g_maxban_times[g_total_maxban_times] = minutes;
937 #endif
938 g_total_maxban_times++;
939
940 return PLUGIN_HANDLED;
941}
942
943public FwdThink(entity)
944{
945 if( entity != g_unban_entity ) return;
946
947 #if defined USING_SQL
948 if( g_total_bans > 0 && !g_loading_bans )
949 #else
950 if( g_total_bans > 0 )
951 #endif
952 {
953 static _hours[5], _minutes[5], _seconds[5], _month[5], _day[5], _year[7];
954 format_time(_hours, sizeof(_hours) - 1, "%H");
955 format_time(_minutes, sizeof(_minutes) - 1, "%M");
956 format_time(_seconds, sizeof(_seconds) - 1, "%S");
957 format_time(_month, sizeof(_month) - 1, "%m");
958 format_time(_day, sizeof(_day) - 1, "%d");
959 format_time(_year, sizeof(_year) - 1, "%Y");
960
961 // c = current
962 // u = unban
963
964 new c_hours = str_to_num(_hours);
965 new c_minutes = str_to_num(_minutes);
966 new c_seconds = str_to_num(_seconds);
967 new c_month = str_to_num(_month);
968 new c_day = str_to_num(_day);
969 new c_year = str_to_num(_year);
970
971 static unban_time[32];
972 static u_hours, u_minutes, u_seconds, u_month, u_day, u_year;
973
974 for( new i = 0; i < g_total_bans; i++ )
975 {
976 #if MAX_BANS <= 0
977 static data[BannedData];
978 ArrayGetArray(g_array, i, data);
979
980 if( data[bd_banlength] == 0 ) continue;
981 #else
982 if( g_banlengths[i] == 0 ) continue;
983 #endif
984
985 #if MAX_BANS <= 0
986 copy(unban_time, sizeof(unban_time) - 1, data[bd_unbantime]);
987 #else
988 copy(unban_time, sizeof(unban_time) - 1, g_unbantimes[i]);
989 #endif
990 replace_all(unban_time, sizeof(unban_time) - 1, ":", " ");
991 replace_all(unban_time, sizeof(unban_time) - 1, "/", " ");
992
993 parse(unban_time,\
994 _hours, sizeof(_hours) - 1,\
995 _minutes, sizeof(_minutes) - 1,\
996 _seconds, sizeof(_seconds) - 1,\
997 _month, sizeof(_month) - 1,\
998 _day, sizeof(_day) - 1,\
999 _year, sizeof(_year) - 1
1000 );
1001
1002 u_hours = str_to_num(_hours);
1003 u_minutes = str_to_num(_minutes);
1004 u_seconds = str_to_num(_seconds);
1005 u_month = str_to_num(_month);
1006 u_day = str_to_num(_day);
1007 u_year = str_to_num(_year);
1008
1009 if( u_year < c_year
1010 || u_year == c_year && u_month < c_month
1011 || u_year == c_year && u_month == c_month && u_day < c_day
1012 || u_year == c_year && u_month == c_month && u_day == c_day && u_hours < c_hours
1013 || u_year == c_year && u_month == c_month && u_day == c_day && u_hours == c_hours && u_minutes < c_minutes
1014 || u_year == c_year && u_month == c_month && u_day == c_day && u_hours == c_hours && u_minutes == c_minutes && u_seconds <= c_seconds )
1015 {
1016 #if MAX_BANS <= 0
1017 Log("Ban time is up for: %s [%s]", data[bd_name], data[bd_steamid]);
1018
1019 Print("^x04[Advanced Bans]^x03 %s^x01[^x04%s^x01]^x03 ban time is up!^x01 [Ban Reason: %s]", data[bd_name], data[bd_steamid], data[bd_reason]);
1020
1021 RemoveBan(i, data[bd_steamid]);
1022 #else
1023 Log("Ban time is up for: %s [%s]", g_names[i], g_steamids[i]);
1024
1025 Print("^x04[Advanced Bans]^x03 %s^x01[^x04%s^x01]^x03 ban time is up!^x01 [Ban Reason: %s]", g_names[i], g_steamids[i], g_reasons[i]);
1026
1027 RemoveBan(i);
1028 #endif
1029
1030 i--; // current pos was replaced with another ban, so we need to check it again.
1031 }
1032 }
1033 }
1034
1035 entity_set_float(g_unban_entity, EV_FL_nextthink, get_gametime() + get_pcvar_float(ab_unbancheck));
1036}
1037
1038public TaskDisconnectPlayer(client)
1039{
1040 server_cmd("kick #%i ^"You are banned from this server. Check your console^"", get_user_userid(client));
1041}
1042
1043AddBan(const target_name[], const target_steamid[], const reason[], const length, const unban_time[], const admin_name[], const admin_steamid[])
1044{
1045 #if MAX_BANS > 0
1046 if( g_total_bans == MAX_BANS )
1047 {
1048 log_amx("Ban list is full! (%i)", g_total_bans);
1049 return;
1050 }
1051 #endif
1052
1053 #if defined USING_SQL
1054 static target_name2[32], reason2[128], admin_name2[32];
1055 MakeStringSQLSafe(target_name, target_name2, sizeof(target_name2) - 1);
1056 MakeStringSQLSafe(reason, reason2, sizeof(reason2) - 1);
1057 MakeStringSQLSafe(admin_name, admin_name2, sizeof(admin_name2) - 1);
1058
1059 static query[512];
1060 formatex(query, sizeof(query) - 1,\
1061 "INSERT INTO `%s` (`%s`, `%s`, `%s`, `%s`, `%s`, `%s`, `%s`) VALUES ('%s', '%s', '%i', '%s', '%s', '%s', '%s');",\
1062 TABLE_NAME, KEY_NAME, KEY_STEAMID, KEY_BANLENGTH, KEY_UNBANTIME, KEY_REASON, KEY_ADMIN_NAME, KEY_ADMIN_STEAMID,\
1063 target_name2, target_steamid, length, unban_time, reason2, admin_name2, admin_steamid
1064 );
1065
1066 SQL_ThreadQuery(g_sql_tuple, "QueryAddBan", query);
1067 #else
1068 new f = fopen(g_ban_file, "a+");
1069
1070 fprintf(f, "^"%s^" ^"%s^" %i ^"%s^" ^"%s^" ^"%s^" ^"%s^"^n",\
1071 target_steamid,\
1072 target_name,\
1073 length,\
1074 unban_time,\
1075 reason,\
1076 admin_name,\
1077 admin_steamid
1078 );
1079
1080 fclose(f);
1081 #endif
1082
1083 #if MAX_BANS <= 0
1084 static data[BannedData];
1085 copy(data[bd_name], sizeof(data[bd_name]) - 1, target_name);
1086 copy(data[bd_steamid], sizeof(data[bd_steamid]) - 1, target_steamid);
1087 data[bd_banlength] = length;
1088 copy(data[bd_unbantime], sizeof(data[bd_unbantime]) - 1, unban_time);
1089 copy(data[bd_reason], sizeof(data[bd_reason]) - 1, reason);
1090 copy(data[bd_admin_name], sizeof(data[bd_admin_name]) - 1, admin_name);
1091 copy(data[bd_admin_steamid], sizeof(data[bd_admin_steamid]) - 1, admin_steamid);
1092
1093 TrieSetCell(g_trie, target_steamid, g_total_bans);
1094 ArrayPushArray(g_array, data);
1095 #else
1096 copy(g_names[g_total_bans], sizeof(g_names[]) - 1, target_name);
1097 copy(g_steamids[g_total_bans], sizeof(g_steamids[]) - 1, target_steamid);
1098 g_banlengths[g_total_bans] = length;
1099 copy(g_unbantimes[g_total_bans], sizeof(g_unbantimes[]) - 1, unban_time);
1100 copy(g_reasons[g_total_bans], sizeof(g_reasons[]) - 1, reason);
1101 copy(g_admin_names[g_total_bans], sizeof(g_admin_names[]) - 1, admin_name);
1102 copy(g_admin_steamids[g_total_bans], sizeof(g_admin_steamids[]) - 1, admin_steamid);
1103 #endif
1104
1105 g_total_bans++;
1106
1107 #if MAX_BANS > 0
1108 if( g_total_bans == MAX_BANS )
1109 {
1110 log_amx("Ban list is full! (%i)", g_total_bans);
1111 }
1112 #endif
1113}
1114
1115#if defined USING_SQL
1116public QueryAddBan(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
1117{
1118 if( failstate == TQUERY_CONNECT_FAILED )
1119 {
1120 set_fail_state("Could not connect to database.");
1121 }
1122 else if( failstate == TQUERY_QUERY_FAILED )
1123 {
1124 set_fail_state("Query failed.");
1125 }
1126 else if( errcode )
1127 {
1128 log_amx("Error on query: %s", error);
1129 }
1130 else
1131 {
1132 // Yay, ban was added! We can all rejoice!
1133 }
1134}
1135
1136public QueryDeleteBan(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
1137{
1138 if( failstate == TQUERY_CONNECT_FAILED )
1139 {
1140 set_fail_state("Could not connect to database.");
1141 }
1142 else if( failstate == TQUERY_QUERY_FAILED )
1143 {
1144 set_fail_state("Query failed.");
1145 }
1146 else if( errcode )
1147 {
1148 log_amx("Error on query: %s", error);
1149 }
1150 else
1151 {
1152 // Yay, ban was deleted! We can all rejoice!
1153 }
1154}
1155
1156public QueryLoadBans(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
1157{
1158 if( failstate == TQUERY_CONNECT_FAILED )
1159 {
1160 set_fail_state("Could not connect to database.");
1161 }
1162 else if( failstate == TQUERY_QUERY_FAILED )
1163 {
1164 set_fail_state("Query failed.");
1165 }
1166 else if( errcode )
1167 {
1168 log_amx("Error on query: %s", error);
1169 }
1170 else
1171 {
1172 if( SQL_NumResults(query) )
1173 {
1174 #if MAX_BANS <= 0
1175 static data[BannedData];
1176 while( SQL_MoreResults(query) )
1177 #else
1178 while( SQL_MoreResults(query) && g_total_bans < MAX_BANS )
1179 #endif
1180 {
1181 #if MAX_BANS <= 0
1182 SQL_ReadResult(query, 0, data[bd_name], sizeof(data[bd_name]) - 1);
1183 SQL_ReadResult(query, 1, data[bd_steamid], sizeof(data[bd_steamid]) - 1);
1184 data[bd_banlength] = SQL_ReadResult(query, 2);
1185 SQL_ReadResult(query, 3, data[bd_unbantime], sizeof(data[bd_unbantime]) - 1);
1186 SQL_ReadResult(query, 4, data[bd_reason], sizeof(data[bd_reason]) - 1);
1187 SQL_ReadResult(query, 5, data[bd_admin_name], sizeof(data[bd_admin_name]) - 1);
1188 SQL_ReadResult(query, 6, data[bd_admin_steamid], sizeof(data[bd_admin_steamid]) - 1);
1189
1190 ArrayPushArray(g_array, data);
1191 TrieSetCell(g_trie, data[bd_steamid], g_total_bans);
1192 #else
1193 SQL_ReadResult(query, 0, g_names[g_total_bans], sizeof(g_names[]) - 1);
1194 SQL_ReadResult(query, 1, g_steamids[g_total_bans], sizeof(g_steamids[]) - 1);
1195 g_banlengths[g_total_bans] = SQL_ReadResult(query, 2);
1196 SQL_ReadResult(query, 3, g_unbantimes[g_total_bans], sizeof(g_unbantimes[]) - 1);
1197 SQL_ReadResult(query, 4, g_reasons[g_total_bans], sizeof(g_reasons[]) - 1);
1198 SQL_ReadResult(query, 5, g_admin_names[g_total_bans], sizeof(g_admin_names[]) - 1);
1199 SQL_ReadResult(query, 6, g_admin_steamids[g_total_bans], sizeof(g_admin_steamids[]) - 1);
1200 #endif
1201
1202 g_total_bans++;
1203
1204 SQL_NextRow(query);
1205 }
1206 }
1207
1208 set_task(RELOAD_BANS_INTERVAL, "LoadBans");
1209
1210 g_loading_bans = false;
1211 }
1212}
1213#endif
1214
1215#if MAX_BANS > 0
1216RemoveBan(remove)
1217{
1218 #if defined USING_SQL
1219 static query[128];
1220 formatex(query, sizeof(query) - 1,\
1221 "DELETE FROM `%s` WHERE `%s` = '%s';",\
1222 TABLE_NAME, KEY_STEAMID, g_steamids[remove]
1223 );
1224
1225 SQL_ThreadQuery(g_sql_tuple, "QueryDeleteBan", query);
1226 #endif
1227
1228 for( new i = remove; i < g_total_bans; i++ )
1229 {
1230 if( (i + 1) == g_total_bans )
1231 {
1232 copy(g_names[i], sizeof(g_names[]) - 1, "");
1233 copy(g_steamids[i], sizeof(g_steamids[]) - 1, "");
1234 g_banlengths[i] = 0;
1235 copy(g_unbantimes[i], sizeof(g_unbantimes[]) - 1, "");
1236 copy(g_reasons[i], sizeof(g_reasons[]) - 1, "");
1237 copy(g_admin_names[i], sizeof(g_admin_names[]) - 1, "");
1238 copy(g_admin_steamids[i], sizeof(g_admin_steamids[]) - 1, "");
1239 }
1240 else
1241 {
1242 copy(g_names[i], sizeof(g_names[]) - 1, g_names[i + 1]);
1243 copy(g_steamids[i], sizeof(g_steamids[]) - 1, g_steamids[i + 1]);
1244 g_banlengths[i] = g_banlengths[i + 1];
1245 copy(g_unbantimes[i], sizeof(g_unbantimes[]) - 1, g_unbantimes[i + 1]);
1246 copy(g_reasons[i], sizeof(g_reasons[]) - 1, g_reasons[i + 1]);
1247 copy(g_admin_names[i], sizeof(g_admin_names[]) - 1, g_admin_names[i + 1]);
1248 copy(g_admin_steamids[i], sizeof(g_admin_steamids[]) - 1, g_admin_steamids[i + 1]);
1249 }
1250 }
1251
1252 g_total_bans--;
1253
1254 #if !defined USING_SQL
1255 new f = fopen(g_ban_file, "wt");
1256
1257 static name[32], steamid[35], banlength, unbantime[32], reason[128], admin_name[32], admin_steamid[35];
1258 for( new i = 0; i < g_total_bans; i++ )
1259 {
1260 copy(name, sizeof(name) - 1, g_names[i]);
1261 copy(steamid, sizeof(steamid) - 1, g_steamids[i]);
1262 banlength = g_banlengths[i];
1263 copy(unbantime, sizeof(unbantime) - 1, g_unbantimes[i]);
1264 copy(reason, sizeof(reason) - 1, g_reasons[i]);
1265 copy(admin_name, sizeof(admin_name) - 1, g_admin_names[i]);
1266 copy(admin_steamid, sizeof(admin_steamid) - 1, g_admin_steamids[i]);
1267
1268 fprintf(f, "^"%s^" ^"%s^" %i ^"%s^" ^"%s^" ^"%s^" ^"%s^"^n",\
1269 steamid,\
1270 name,\
1271 banlength,\
1272 unbantime,\
1273 reason,\
1274 admin_name,\
1275 admin_steamid
1276 );
1277 }
1278
1279 fclose(f);
1280 #endif
1281}
1282#else
1283RemoveBan(pos, const authid[])
1284{
1285 TrieDeleteKey(g_trie, authid);
1286 ArrayDeleteItem(g_array, pos);
1287
1288 g_total_bans--;
1289
1290 #if defined USING_SQL
1291 static query[128];
1292 formatex(query, sizeof(query) - 1,\
1293 "DELETE FROM `%s` WHERE `%s` = '%s';",\
1294 TABLE_NAME, KEY_STEAMID, authid
1295 );
1296
1297 SQL_ThreadQuery(g_sql_tuple, "QueryDeleteBan", query);
1298
1299 new data[BannedData];
1300 for( new i = 0; i < g_total_bans; i++ )
1301 {
1302 ArrayGetArray(g_array, i, data);
1303 TrieSetCell(g_trie, data[bd_steamid], i);
1304 }
1305 #else
1306 new f = fopen(g_ban_file, "wt");
1307
1308 new data[BannedData];
1309 for( new i = 0; i < g_total_bans; i++ )
1310 {
1311 ArrayGetArray(g_array, i, data);
1312 TrieSetCell(g_trie, data[bd_steamid], i);
1313
1314 fprintf(f, "^"%s^" ^"%s^" %i ^"%s^" ^"%s^" ^"%s^" ^"%s^"^n",\
1315 data[bd_steamid],\
1316 data[bd_name],\
1317 data[bd_banlength],\
1318 data[bd_unbantime],\
1319 data[bd_reason],\
1320 data[bd_admin_name],\
1321 data[bd_admin_steamid]
1322 );
1323 }
1324
1325 fclose(f);
1326 #endif
1327}
1328#endif
1329
1330#if defined KEEP_DEFAULT_BANS
1331LoadOldBans(filename[])
1332{
1333 if( file_exists(filename) )
1334 {
1335 new f = fopen(filename, "rt");
1336
1337 static data[96];
1338 static command[10], minutes[10], steamid[35], length, unban_time[32];
1339
1340 while( !feof(f) )
1341 {
1342 fgets(f, data, sizeof(data) - 1);
1343 if( !data[0] ) continue;
1344
1345 parse(data, command, sizeof(command) - 1, minutes, sizeof(minutes) - 1, steamid, sizeof(steamid) - 1);
1346 if( filename[0] == 'b' && !equali(command, "banid") || filename[0] == 'l' && !equali(command, "addip") ) continue;
1347
1348 length = str_to_num(minutes);
1349 GenerateUnbanTime(length, unban_time, sizeof(unban_time) - 1);
1350
1351 AddBan("", steamid, "", length, unban_time, "", "");
1352 }
1353
1354 fclose(f);
1355
1356 static filename2[32];
1357
1358 // copy current
1359 copy(filename2, sizeof(filename2) - 1, filename);
1360
1361 // cut off at the "."
1362 // banned.cfg = banned
1363 // listip.cfg = listip
1364 filename2[containi(filename2, ".")] = 0;
1365
1366 // add 2.cfg
1367 // banned = banned2.cfg
1368 // listip = listip2.cfg
1369 add(filename2, sizeof(filename2) - 1, "2.cfg");
1370
1371 // rename file so that it isnt loaded again
1372 while( !rename_file(filename, filename2, 1) ) { }
1373 }
1374}
1375#endif
1376
1377public LoadBans()
1378{
1379 if( g_total_bans )
1380 {
1381 #if MAX_BANS <= 0
1382 TrieClear(g_trie);
1383 ArrayClear(g_array);
1384 #endif
1385
1386 g_total_bans = 0;
1387 }
1388
1389 #if defined USING_SQL
1390 static query[128];
1391 formatex(query, sizeof(query) - 1,\
1392 "SELECT * FROM `%s`;",\
1393 TABLE_NAME
1394 );
1395
1396 SQL_ThreadQuery(g_sql_tuple, "QueryLoadBans", query);
1397
1398 g_loading_bans = true;
1399 #else
1400 if( file_exists(g_ban_file) )
1401 {
1402 new f = fopen(g_ban_file, "rt");
1403
1404 static filedata[512], length[10];
1405
1406 #if MAX_BANS <= 0
1407 static data[BannedData];
1408 while( !feof(f) )
1409 #else
1410 while( !feof(f) && g_total_bans < MAX_BANS )
1411 #endif
1412 {
1413 fgets(f, filedata, sizeof(filedata) - 1);
1414
1415 if( !filedata[0] ) continue;
1416
1417 #if MAX_BANS <= 0
1418 parse(filedata,\
1419 data[bd_steamid], sizeof(data[bd_steamid]) - 1,\
1420 data[bd_name], sizeof(data[bd_name]) - 1,\
1421 length, sizeof(length) - 1,\
1422 data[bd_unbantime], sizeof(data[bd_unbantime]) - 1,\
1423 data[bd_reason], sizeof(data[bd_reason]) - 1,\
1424 data[bd_admin_name], sizeof(data[bd_admin_name]) - 1,\
1425 data[bd_admin_steamid], sizeof(data[bd_admin_steamid]) - 1
1426 );
1427
1428 data[bd_banlength] = str_to_num(length);
1429
1430 ArrayPushArray(g_array, data);
1431 TrieSetCell(g_trie, data[bd_steamid], g_total_bans);
1432 #else
1433 static steamid[35], name[32], unbantime[32], reason[128], admin_name[32], admin_steamid[35];
1434
1435 parse(filedata,\
1436 steamid, sizeof(steamid) - 1,\
1437 name, sizeof(name) - 1,\
1438 length, sizeof(length) - 1,\
1439 unbantime, sizeof(unbantime) - 1,\
1440 reason, sizeof(reason) - 1,\
1441 admin_name, sizeof(admin_name) - 1,\
1442 admin_steamid, sizeof(admin_steamid) - 1
1443 );
1444
1445 copy(g_names[g_total_bans], sizeof(g_names[]) - 1, name);
1446 copy(g_steamids[g_total_bans], sizeof(g_steamids[]) - 1, steamid);
1447 g_banlengths[g_total_bans] = str_to_num(length);
1448 copy(g_unbantimes[g_total_bans], sizeof(g_unbantimes[]) - 1, unbantime);
1449 copy(g_reasons[g_total_bans], sizeof(g_reasons[]) - 1, reason);
1450 copy(g_admin_names[g_total_bans], sizeof(g_admin_names[]) - 1, admin_name);
1451 copy(g_admin_steamids[g_total_bans], sizeof(g_admin_steamids[]) - 1, admin_steamid);
1452 #endif
1453
1454 g_total_bans++;
1455 }
1456
1457 fclose(f);
1458 }
1459 #endif
1460
1461 // load these after, so when they are added to the file with AddBan(), they aren't loaded again from above.
1462
1463 #if defined KEEP_DEFAULT_BANS
1464 LoadOldBans("banned.cfg");
1465 LoadOldBans("listip.cfg");
1466 #endif
1467}
1468
1469#if defined USING_SQL
1470MakeStringSQLSafe(const input[], output[], len)
1471{
1472 copy(output, len, input);
1473 replace_all(output, len, "'", "*");
1474 replace_all(output, len, "^"", "*");
1475 replace_all(output, len, "`", "*");
1476}
1477#endif
1478
1479GetBanTime(const bantime, length[], len)
1480{
1481 new minutes = bantime;
1482 new hours = 0;
1483 new days = 0;
1484
1485 while( minutes >= 60 )
1486 {
1487 minutes -= 60;
1488 hours++;
1489 }
1490
1491 while( hours >= 24 )
1492 {
1493 hours -= 24;
1494 days++;
1495 }
1496
1497 new bool:add_before;
1498 if( minutes )
1499 {
1500 formatex(length, len, "%i minute%s", minutes, minutes == 1 ? "" : "s");
1501
1502 add_before = true;
1503 }
1504 if( hours )
1505 {
1506 if( add_before )
1507 {
1508 format(length, len, "%i hour%s, %s", hours, hours == 1 ? "" : "s", length);
1509 }
1510 else
1511 {
1512 formatex(length, len, "%i hour%s", hours, hours == 1 ? "" : "s");
1513
1514 add_before = true;
1515 }
1516 }
1517 if( days )
1518 {
1519 if( add_before )
1520 {
1521 format(length, len, "%i day%s, %s", days, days == 1 ? "" : "s", length);
1522 }
1523 else
1524 {
1525 formatex(length, len, "%i day%s", days, days == 1 ? "" : "s");
1526
1527 add_before = true;
1528 }
1529 }
1530 if( !add_before )
1531 {
1532 // minutes, hours, and days = 0
1533 // assume permanent ban
1534 copy(length, len, "Permanent Ban");
1535 }
1536}
1537
1538GenerateUnbanTime(const bantime, unban_time[], len)
1539{
1540 static _hours[5], _minutes[5], _seconds[5], _month[5], _day[5], _year[7];
1541 format_time(_hours, sizeof(_hours) - 1, "%H");
1542 format_time(_minutes, sizeof(_minutes) - 1, "%M");
1543 format_time(_seconds, sizeof(_seconds) - 1, "%S");
1544 format_time(_month, sizeof(_month) - 1, "%m");
1545 format_time(_day, sizeof(_day) - 1, "%d");
1546 format_time(_year, sizeof(_year) - 1, "%Y");
1547
1548 new hours = str_to_num(_hours);
1549 new minutes = str_to_num(_minutes);
1550 new seconds = str_to_num(_seconds);
1551 new month = str_to_num(_month);
1552 new day = str_to_num(_day);
1553 new year = str_to_num(_year);
1554
1555 minutes += bantime;
1556
1557 while( minutes >= 60 )
1558 {
1559 minutes -= 60;
1560 hours++;
1561 }
1562
1563 while( hours >= 24 )
1564 {
1565 hours -= 24;
1566 day++;
1567 }
1568
1569 new max_days = GetDaysInMonth(month, year);
1570 while( day > max_days )
1571 {
1572 day -= max_days;
1573 month++;
1574 }
1575
1576 while( month > 12 )
1577 {
1578 month -= 12;
1579 year++;
1580 }
1581
1582 formatex(unban_time, len, "%i:%02i:%02i %i/%i/%i", hours, minutes, seconds, month, day, year);
1583}
1584
1585GetDaysInMonth(month, year=0)
1586{
1587 switch( month )
1588 {
1589 case 1: return 31; // january
1590 case 2: return ((year % 4) == 0) ? 29 : 28; // february
1591 case 3: return 31; // march
1592 case 4: return 30; // april
1593 case 5: return 31; // may
1594 case 6: return 30; // june
1595 case 7: return 31; // july
1596 case 8: return 31; // august
1597 case 9: return 30; // september
1598 case 10: return 31; // october
1599 case 11: return 30; // november
1600 case 12: return 31; // december
1601 }
1602
1603 return 30;
1604}
1605
1606GetTargetFlags(client)
1607{
1608 static const flags_no_immunity = (CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS);
1609 static const flags_immunity = (CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS|CMDTARGET_OBEY_IMMUNITY);
1610
1611 switch( get_pcvar_num(ab_immunity) )
1612 {
1613 case 1: return flags_immunity;
1614 case 2: return access(client, ADMIN_IMMUNITY) ? flags_no_immunity : flags_immunity;
1615 }
1616
1617 return flags_no_immunity;
1618}
1619
1620GetMaxBanTime(client)
1621{
1622 if( !g_total_maxban_times ) return 0;
1623
1624 new flags = get_user_flags(client);
1625
1626 for( new i = 0; i < g_total_maxban_times; i++ )
1627 {
1628 #if !defined MAX_BANLIMITS
1629 if( flags & ArrayGetCell(g_maxban_flags, i) )
1630 {
1631 return ArrayGetCell(g_maxban_times, i);
1632 }
1633 #else
1634 if( flags & g_maxban_flags[i] )
1635 {
1636 return g_maxban_times[i];
1637 }
1638 #endif
1639 }
1640
1641 return 0;
1642}
1643
1644PrintBanInformation(client, const target_name[], const target_authid[], const reason[], const length, const unban_time[], const admin_name[], const admin_authid[], bool:show_admin, bool:show_website)
1645{
1646 static website[64], ban_length[64];
1647 if( client == 0 )
1648 {
1649 server_print("************************************************");
1650 server_print("%L", client, "AB_BAN_INFORMATION");
1651 server_print("%L: %s", client, "AB_NAME", target_name);
1652 server_print("%L: %s", client, IsValidAuthid(target_authid) ? "AB_STEAMID" : "AB_IP", target_authid);
1653 server_print("%L: %s", client, "AB_REASON", reason);
1654 if( length > 0 )
1655 {
1656 GetBanTime(length, ban_length, sizeof(ban_length) - 1);
1657 server_print("%L: %s", client, "AB_BAN_LENGTH", ban_length);
1658 }
1659 server_print("%L: %s", client, "AB_UNBAN_TIME", unban_time);
1660 if( show_admin )
1661 {
1662 server_print("%L: %s", client, "AB_ADMIN_NAME", admin_name);
1663 server_print("%L: %s", client, "AB_ADMIN_STEAMID", admin_authid);
1664 }
1665 if( show_website )
1666 {
1667 get_pcvar_string(ab_website, website, sizeof(website) - 1);
1668 if( website[0] )
1669 {
1670 server_print("");
1671 server_print("%L", client, "AB_WEBSITE");
1672 server_print("%s", website);
1673 }
1674 }
1675 server_print("************************************************");
1676 }
1677 else
1678 {
1679 client_cmd(client, "echo ^"************************************************^"");
1680 client_cmd(client, "echo ^"%L^"", client, "AB_BAN_INFORMATION");
1681 client_cmd(client, "echo ^"%L: %s^"", client, "AB_NAME", target_name);
1682 client_cmd(client, "echo ^"%L: %s^"", client, IsValidAuthid(target_authid) ? "AB_STEAMID" : "AB_IP", target_authid);
1683 client_cmd(client, "echo ^"%L: %s^"", client, "AB_REASON", reason);
1684 if( length > 0 )
1685 {
1686 GetBanTime(length, ban_length, sizeof(ban_length) - 1);
1687 client_cmd(client, "echo ^"%L: %s^"", client, "AB_BAN_LENGTH", ban_length);
1688 }
1689 client_cmd(client, "echo ^"%L: %s^"", client, "AB_UNBAN_TIME", unban_time);
1690 if( show_admin )
1691 {
1692 client_cmd(client, "echo ^"%L: %s^"", client, "AB_ADMIN_NAME", admin_name);
1693 client_cmd(client, "echo ^"%L: %s^"", client, "AB_ADMIN_STEAMID", admin_authid);
1694 }
1695 if( show_website )
1696 {
1697 get_pcvar_string(ab_website, website, sizeof(website) - 1);
1698 if( website[0] )
1699 {
1700 client_cmd(client, "echo ^"^"");
1701 client_cmd(client, "echo ^"%L^"", client, "AB_WEBSITE");
1702 client_cmd(client, "echo ^"%s^"", website);
1703 }
1704 }
1705 client_cmd(client, "echo ^"************************************************^"");
1706 }
1707}
1708
1709PrintActivity(const admin_name[], const message_fmt[], any:...)
1710{
1711 if( !get_playersnum() ) return;
1712
1713 new activity = get_pcvar_num(amx_show_activity);
1714 if( !(0 <= activity <= 5) )
1715 {
1716 set_pcvar_num(amx_show_activity, (activity = 2));
1717 }
1718
1719 static message[192], temp[192];
1720 vformat(message, sizeof(message) - 1, message_fmt, 3);
1721
1722 for( new client = 1; client <= g_max_clients; client++ )
1723 {
1724 if( !is_user_connected(client) ) continue;
1725
1726 switch( is_user_admin(client) ? g_admin_activity[activity] : g_normal_activity[activity] )
1727 {
1728 case ACTIVITY_NONE:
1729 {
1730
1731 }
1732 case ACTIVITY_HIDE:
1733 {
1734 copy(temp, sizeof(temp) - 1, message);
1735 replace(temp, sizeof(temp) - 1, "$name", "ADMIN");
1736
1737 message_begin(MSG_ONE_UNRELIABLE, g_msgid_SayText, _, client);
1738 write_byte(client);
1739 write_string(temp);
1740 message_end();
1741 }
1742 case ACTIVITY_SHOW:
1743 {
1744 copy(temp, sizeof(temp) - 1, message);
1745 replace(temp, sizeof(temp) - 1, "$name", admin_name);
1746
1747 message_begin(MSG_ONE_UNRELIABLE, g_msgid_SayText, _, client);
1748 write_byte(client);
1749 write_string(temp);
1750 message_end();
1751 }
1752 }
1753 }
1754}
1755
1756Print(const message_fmt[], any:...)
1757{
1758 if( !get_playersnum() ) return;
1759
1760 static message[192];
1761 vformat(message, sizeof(message) - 1, message_fmt, 2);
1762
1763 for( new client = 1; client <= g_max_clients; client++ )
1764 {
1765 if( !is_user_connected(client) ) continue;
1766
1767 message_begin(MSG_ONE_UNRELIABLE, g_msgid_SayText, _, client);
1768 write_byte(client);
1769 write_string(message);
1770 message_end();
1771 }
1772}
1773
1774Log(const message_fmt[], any:...)
1775{
1776 static message[256];
1777 vformat(message, sizeof(message) - 1, message_fmt, 2);
1778
1779 static filename[96];
1780 #if defined HISTORY_ONE_FILE
1781 if( !filename[0] )
1782 {
1783 get_basedir(filename, sizeof(filename) - 1);
1784 add(filename, sizeof(filename) - 1, "/logs/ban_history.log");
1785 }
1786 #else
1787 static dir[64];
1788 if( !dir[0] )
1789 {
1790 get_basedir(dir, sizeof(dir) - 1);
1791 add(dir, sizeof(dir) - 1, "/logs");
1792 }
1793
1794 format_time(filename, sizeof(filename) - 1, "%m%d%Y");
1795 format(filename, sizeof(filename) - 1, "%s/BAN_HISTORY_%s.log", dir, filename);
1796 #endif
1797
1798 log_amx("%s", message);
1799 log_to_file(filename, "%s", message);
1800}