· 6 years ago · Aug 14, 2019, 12:40 PM
1#include <amxmodx>
2#include <hamsandwich>
3#include <colorchat>
4#include <unixtime>
5#include <fakemeta>
6#include <sqlx>
7
8#define ForArray(%1,%2) for(new %1 = 0; %1 < sizeof %2; %1++)
9#define ForPlayers(%1) for(new %1 = 1; %1 <= 32; %1++)
10
11#define maxNameLength 33
12#define maxSafeNameLength 50
13#define maxIpLength 25
14#define maxSidLength 36
15
16new const listReasonsMenu[][] =
17{
18 "Brak mutacji",
19 "Brak mikrofonu",
20 "Nieogarnianie",
21 "Przeszkadzanie",
22 "Nieumiejetne prowadzenie",
23 "Nieznajomosc regulaminu"
24};
25
26new const banPlayerCommands[][] =
27{
28 "/ban",
29 "/banct",
30 "/zbanuj",
31 "/banowaniect"
32};
33
34new const mysqlData[][] =
35{
36 "145.239.236.240",
37 "srv56345",
38 "v9SwMWlvUb",
39 "srv56345"
40};
41
42enum _:mysqlEnumerator (+= 1)
43{
44 mysqlHost,
45 mysqlUser,
46 mysqlPass,
47 mysqlDBase
48};
49
50enum _:playerData (+= 1)
51{
52 bool:userBan,
53 userName[maxNameLength],
54 userSafeName[maxSafeNameLength],
55 userIp[maxIpLength],
56 userSid[maxSidLength],
57 userManyBan
58};
59
60new const menuAccessFlag = ADMIN_KICK;
61
62new const chatPrefix[] = "^x04[BAN CT]";
63
64
65new Handle:sqlHandle,
66 userData[33][playerData];
67
68
69public plugin_init()
70{
71 register_plugin("BanCT", "v2.0", "K@MILOVVSKY");
72
73 registerCommands(banPlayerCommands, sizeof(banPlayerCommands), "banCT");
74
75 RegisterHam(Ham_Spawn, "player", "playerSpawned", true);
76
77 register_forward(FM_ClientUserInfoChanged, "clientInfoChanged");
78}
79
80public plugin_natives()
81{
82 register_native("letPlayCt", "nativeLetPlay", true);
83}
84
85public plugin_precache()
86{
87 new errorMessage[512],
88 errorCode,
89 queryRequest[256],
90 Handle:temporaryHandle,
91 Handle:query;
92
93 sqlHandle = SQL_MakeDbTuple(mysqlData[mysqlHost], mysqlData[mysqlUser], mysqlData[mysqlPass], mysqlData[mysqlDBase]);
94
95 temporaryHandle = SQL_Connect(sqlHandle, errorCode, errorMessage, charsmax(errorMessage));
96
97 formatex(queryRequest, charsmax(queryRequest),
98 "CREATE TABLE IF NOT EXISTS `banyct`\
99 (`id` int(5) NOT NULL auto_increment, \
100 `name` VARCHAR(35) NOT NULL, \
101 `steam_id` VARCHAR(35) NOT NULL, \
102 `ip` VARCHAR(35) NOT NULL, \
103 `banned` INT NOT NULL, \
104 `admin_name` VARCHAR(35), \
105 `timestamp` INT NOT NULL, \
106 `date` VARCHAR(33), \
107 `reason` VARCHAR(35) NOT NULL, \
108 `admin_ub_name` VARCHAR(35) NOT NULL, \
109 `manyBan` INT NOT NULL, \
110 PRIMARY KEY(`id`))");
111
112 query = SQL_PrepareQuery(temporaryHandle, queryRequest);
113
114 SQL_FreeHandle(query);
115}
116
117public plugin_end()
118{
119 SQL_FreeHandle(sqlHandle);
120}
121
122public client_putinserver(index)
123{
124 getVariablesData(index);
125
126 loadUserBanData(index);
127}
128
129public banCT(index)
130{
131 if(!(get_user_flags(index) & menuAccessFlag))
132 {
133 return PLUGIN_HANDLED;
134 }
135
136 new menuIndex = menu_create("Wybierz gracza do zbanowania na CT:", "banCtHandlec"),
137 userId[2];
138
139 ForPlayers(i)
140 {
141 if(!is_user_connected(i))
142 {
143 continue;
144 }
145
146 formatex(userId, charsmax(userId), "%i", i);
147
148 menu_additem(menuIndex, userData[i][userName], userId);
149 }
150
151 menu_display(index, menuIndex);
152
153 return PLUGIN_HANDLED;
154}
155
156public banCtHandlec(index, menuIndex, item)
157{
158 if(item == MENU_EXIT)
159 {
160 menu_destroy(menuIndex);
161
162 return PLUGIN_HANDLED;
163 }
164
165 new menuData[2],
166 blank,
167 chosenPlayer;
168
169 menu_item_getinfo(menuIndex, item, blank, menuData, charsmax(menuData), _, _, blank);
170
171 menu_destroy(menuIndex);
172
173 chosenPlayer = str_to_num(menuData);
174
175 if(!is_user_connected(chosenPlayer))
176 {
177 return PLUGIN_HANDLED;
178 }
179
180 banCTstepTwo(index, chosenPlayer);
181
182 return PLUGIN_HANDLED;
183}
184
185public banCTstepTwo(admin, target)
186{
187 new menuTitle[128],
188 menuIndex = menu_create("", "banCTstepTwoHandle"),
189 menuCallback = menu_makecallback("banCTstepTwoCallback"),
190 menuData[2];
191
192 formatex(menuData, charsmax(menuData), "%i", target);
193
194 formatex(menuTitle, charsmax(menuTitle), "Czy jestes pewien, ze chcesz zbanowac gracza\r %s\w?^nJesli tak, przejdziesz do listy powodow.", userData[target][userName]);
195
196 menu_additem(menuIndex, isBanned(target) ? "\rTak \d(\yma bana!\d)" : "\rTak", menuData);
197 menu_additem(menuIndex, "\wNie", menuData);
198
199 if(isBanned(target))
200 {
201 menu_additem(menuIndex, "Daj UB", menuData, _, menuCallback);
202 }
203
204 menu_setprop(menuIndex, MPROP_TITLE, menuTitle);
205
206 menu_display(admin, menuIndex);
207}
208
209public banCTstepTwoCallback(index, menuIndex, item)
210{
211 new menuData[2],
212 blank,
213 target;
214
215 menu_item_getinfo(menuIndex, item, blank, menuData, charsmax(menuData), _, _, blank);
216
217 target = str_to_num(menuData);
218
219 switch(item)
220 {
221 case 0:
222 {
223 if(isBanned(target))
224 {
225 return ITEM_DISABLED;
226 }
227 }
228
229 case 2:
230 {
231 if(!isBanned(target))
232 {
233 return ITEM_DISABLED;
234 }
235 }
236 }
237
238 return ITEM_ENABLED;
239}
240
241public banCTstepTwoHandle(index, menuIndex, item)
242{
243 if(item == MENU_EXIT)
244 {
245 menu_destroy(menuIndex);
246
247 return PLUGIN_HANDLED;
248 }
249
250 new menuData[2],
251 blank,
252 target;
253
254 menu_item_getinfo(menuIndex, item, blank, menuData, charsmax(menuData), _, _, blank);
255
256 menu_destroy(menuIndex);
257
258 target = str_to_num(menuData);
259
260 switch(item)
261 {
262 case 0:
263 {
264 listReasons(index, target);
265 }
266
267 case 1:
268 {
269 banCT(index);
270 }
271
272 case 2:
273 {
274 unbanMenu(index, target);
275 }
276 }
277
278 return PLUGIN_HANDLED;
279}
280
281public listReasons(index, target)
282{
283 new menuIndex = menu_create("Wybierz powod bana:", "listReasonsHandle"),
284 menuData[2];
285
286 formatex(menuData, charsmax(menuData), "%i", target);
287
288 ForArray(i, listReasonsMenu)
289 {
290 menu_additem(menuIndex, listReasonsMenu[i], menuData);
291 }
292
293 menu_display(index, menuIndex);
294}
295
296public listReasonsHandle(index, menuIndex, item)
297{
298 if(item == MENU_EXIT)
299 {
300 menu_destroy(menuIndex);
301
302 return PLUGIN_HANDLED;
303 }
304
305 new menuData[2],
306 blank,
307 target;
308
309 menu_item_getinfo(menuIndex, item, blank, menuData, charsmax(menuData), _, _, blank);
310
311 menu_destroy(menuIndex);
312
313 target = str_to_num(menuData);
314
315 banPlayer(index, target, listReasonsMenu[item]);
316
317 return PLUGIN_HANDLED;
318}
319
320public unbanMenu(index, target)
321{
322 new menuTitle[128],
323 menuIndex,
324 menuData[2];
325
326 formatex(menuTitle, charsmax(menuTitle), "Jestes pewien, ze chcesz dac UB graczowi\r %s\w?", userData[target][userName]);
327 formatex(menuData, charsmax(menuData), "%i", target);
328
329 menuIndex = menu_create(menuTitle, "unbanMenuHandle");
330
331 menu_additem(menuIndex, "Tak", menuData);
332 menu_additem(menuIndex, "Nie", menuData);
333
334 menu_display(index, menuIndex)
335}
336
337public unbanMenuHandle(index, menuIndex, item)
338{
339 if(item == MENU_EXIT)
340 {
341 menu_destroy(menuIndex);
342
343 return PLUGIN_HANDLED;
344 }
345
346 new menuData[2],
347 blank,
348 target;
349
350 menu_item_getinfo(menuIndex, item, blank, menuData, charsmax(menuData), _, _, blank);
351
352 menu_destroy(menuIndex);
353
354 target = str_to_num(menuData);
355
356 if(!item)
357 {
358 unbanPlayer(index, target);
359 }
360 else
361 {
362 banCT(index);
363 }
364
365 return PLUGIN_HANDLED;
366}
367
368public loadUserBanData(index)
369{
370 new queryRequest[512],
371 queryData[1];
372
373 queryData[0] = index;
374
375 formatex(queryRequest, charsmax(queryRequest),
376 "SELECT * FROM `banyct` WHERE \
377 `name` = '%s' OR \
378 `steam_id` = '%s' OR \
379 `ip` = '%s'",
380 userData[index][userSafeName], userData[index][userSid], userData[index][userIp]);
381
382 SQL_ThreadQuery(sqlHandle, "loadUserBanDataHandler", queryRequest, queryData, sizeof(queryData));
383}
384
385public loadUserBanDataHandler(failState, Handle:query, errorMessage[], errorCode, queryData[], dataSize)
386{
387 new index = queryData[0];
388
389 if(errorCode)
390 {
391 log_amx("Blad w zapytaniu: %s [LoadHandler]", errorMessage);
392 }
393
394 if(failState == TQUERY_CONNECT_FAILED)
395 {
396 log_amx("Nie mozna podlaczyc sie do bazy danych.");
397
398 return PLUGIN_CONTINUE;
399 }
400
401 else if(failState == TQUERY_QUERY_FAILED)
402 {
403 log_amx("Zapytanie anulowane [LoadHandler]");
404
405 return PLUGIN_CONTINUE;
406 }
407
408 if(SQL_MoreResults(query))
409 {
410 userData[index][userBan] = bool:SQL_ReadResult(query, SQL_FieldNameToNum(query, "banned"));
411 userData[index][userManyBan] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "manyBan"));
412 }
413 else
414 {
415 new queryRequest[192];
416
417 formatex(queryRequest, charsmax(queryRequest),
418 "INSERT INTO `banyct` \
419 (`name`, \
420 `steam_id`, \
421 `ip`, \
422 `banned`, \
423 `manyBan`) \
424 VALUES ('%s', '%s', '%s', 0, 0);", userData[index][userSafeName], userData[index][userSid], userData[index][userIp]);
425
426 SQL_ThreadQuery(sqlHandle, "ignore_handle", queryRequest);
427 }
428
429 return PLUGIN_CONTINUE;
430}
431
432public ignore_handle(failState, Handle:query, error[], errorNum, data[], dataSize)
433{
434 if(failState)
435 {
436 if(failState == TQUERY_CONNECT_FAILED)
437 {
438 log_amx("[BANY] Could not connect to SQL database. [%d] %s", errorNum, error);
439 }
440
441 else if(failState == TQUERY_QUERY_FAILED)
442 {
443 log_amx("[BANY] Query failed. [%d] %s query: %d", errorNum, error, query);
444 }
445 }
446
447 return PLUGIN_CONTINUE;
448}
449
450public playerSpawned(index)
451{
452 if(!isBanned(index))
453 {
454 return;
455 }
456
457 if(get_user_team(index) == 2)
458 kickPlayer(index);
459}
460
461public clientInfoChanged(index)
462{
463 getVariablesData(index);
464}
465
466
467
468public nativeLetPlay(index)
469{
470 return isBanned(index);
471}
472
473
474formatDate(unix, output[], outputSize)
475{
476 new timeData[6];
477
478 UnixToTime(unix, timeData[0], timeData[1], timeData[2], timeData[3], timeData[4], timeData[5]);
479
480 formatex(output, outputSize, "%d/%02d/%02d %02d:%02d:%02d", timeData[0], timeData[1], timeData[2], timeData[3], timeData[4], timeData[5]);
481}
482
483bool:isBanned(index)
484{
485 if(userData[index][userBan] && userData[index][userManyBan])
486 {
487 return 1;
488 }
489 else
490 return 0;
491}
492
493escapeString(string[], length)
494{
495 new const unsafeCharacters[][][] =
496 {
497 { "\\", "\\\\" },
498 { "\0", "\\0" },
499 { "\n", "\\n" },
500 { "\r", "\\r" },
501 { "\x1a", "\Z" },
502 { "'", "\'" },
503 { "`", "\`" },
504 { "^"", "\^"" }
505 };
506
507 ForArray(i, unsafeCharacters)
508 {
509 replace_all(string, length, unsafeCharacters[i][0], unsafeCharacters[i][1]);
510 }
511}
512
513getVariablesData(index)
514{
515 get_user_name(index, userData[index][userName], maxNameLength);
516 get_user_authid(index, userData[index][userSid], maxSidLength);
517 get_user_ip(index, userData[index][userIp], maxIpLength);
518
519 copy(userData[index][userSafeName], maxSafeNameLength, userData[index][userName]);
520
521 escapeString(userData[index][userSafeName], maxSafeNameLength);
522}
523
524banPlayer(admin, target, reason[])
525{
526 if(!is_user_connected(admin) || !is_user_connected(target))
527 {
528 return;
529 }
530
531 if(isBanned(target))
532 {
533 printMessage(admin, _, "Gracz^x04 %s^x01 ma juz bana.", userData[target][userName]);
534 }
535
536 printMessage(admin, _, "Zbanowales^x04 %s^x01 na CT z powodu:^x03 %s^x01.", userData[target][userName], reason);
537
538 userData[target][userBan] = true;
539 userData[target][userManyBan]++;
540
541 saveBanToDatabase(admin, target, reason);
542}
543
544unbanPlayer(admin, target)
545{
546 if(!is_user_connected(admin) || !is_user_connected(target))
547 {
548 return;
549 }
550
551 printMessage(admin, _, "Dales UB graczowi^x04 %s^x01.", userData[target][userName]);
552 printMessage(target, _, "Dostales UB od admina^x04 %s^x01.", userData[admin][userName]);
553
554 userData[target][userBan] = false;
555
556 unbanFromDatabase(admin, target);
557}
558
559unbanFromDatabase(admin, target)
560{
561 new queryCommand[512];
562
563 formatex(queryCommand, charsmax(queryCommand), "UPDATE `banyct` SET `banned` = '%i', `admin_ub_name` = ^"%s^" WHERE `name` = '%s';", userData[target][userBan], userData[admin][userSafeName], userData[target][userSafeName]);
564
565 SQL_ThreadQuery(sqlHandle, "ignore_handle", queryCommand);
566}
567
568saveBanToDatabase(admin, target, const reason[])
569{
570 new queryRequest[512],
571 banDate[33],
572 currentUnix = get_systime();
573
574 formatDate(currentUnix, banDate, charsmax(banDate));
575
576 formatex(queryRequest, charsmax(queryRequest),
577 "UPDATE `banyct` SET \
578 `ip` = '%s', \
579 `banned` = '%i', \
580 `date` = '%s', \
581 `admin_name` = '%s', \
582 `timestamp` = '%i', \
583 `reason` = '%s', \
584 `manyBan` = '%i' \
585 WHERE `name` = '%s';", userData[target][userIp], userData[target][userBan], banDate, userData[admin][userSafeName], currentUnix, reason, userData[target][userManyBan], userData[target][userSafeName]);
586
587
588 SQL_ThreadQuery(sqlHandle, "ignore_handle", queryRequest);
589}
590
591kickPlayer(index)
592{
593 if(!is_user_connected(index))
594 {
595 return;
596 }
597
598 server_cmd("kick #%d ^"Nie mozesz grac w CT, poniewaz dostales bana!^"", get_user_userid(index));
599}
600
601/*
602 Prints message to a player or all players with prefix and proper formating.
603*/
604printMessage(index, Color:messageColor = NORMAL, const initialMessage[], any:...)
605{
606 new newMessage[191];
607
608 // Add additional arguments to the message.
609 vformat(newMessage, charsmax(newMessage), initialMessage, 4);
610
611 // Check if we go above the character limit if we add the prefix.
612 // ReHLDS and its sub-modules (like safenameandchat for example), do not work 100% properly.
613 if(strlen(newMessage) + strlen(chatPrefix) > 191)
614 {
615 ColorChat(index, messageColor, newMessage);
616
617 return;
618 }
619
620 new colorIdentificator[5];
621
622 // Format color-identificator-prefix thingy.
623 formatex(colorIdentificator, charsmax(colorIdentificator),
624 messageColor == NORMAL ? "^x01" :
625 (messageColor == TEAM_COLOR ? "^x03" :
626 (messageColor == GREEN ? "^x04" : "^x01")));
627
628 // Format new message with proper colors and prefix.
629 format(newMessage, charsmax(newMessage), "^x03%s %s%s", chatPrefix, colorIdentificator, newMessage);
630
631 // Display new message.
632 ColorChat(index, messageColor, newMessage);
633}
634
635stock registerCommands(const array[][], arraySize, function[])
636{
637 #if !defined ForRange
638
639 #define ForRange(%1,%2,%3) for(new %1 = %2; %1 <= %3; %1++)
640
641 #endif
642
643 #if AMXX_VERSION_NUM >= 183
644
645 ForRange(i, 0, arraySize - 1)
646 {
647 ForRange(j, 0, 1)
648 {
649 register_clcmd(fmt("%s %s", !j ? "say" : "say_team", array[i]), function);
650 }
651 }
652
653 #else
654
655 new newCommand[33];
656
657 ForRange(i, 0, arraySize - 1)
658 {
659 ForRange(j, 0, 1)
660 {
661 formatex(newCommand, charsmax(newCommand), "%s %s", !j ? "say" : "say_team", array[i]);
662 register_clcmd(newCommand, function);
663 }
664 }
665
666 #endif
667}