3 #include <common/command/_mod.qh>
4 #include <common/minigames/sv_minigames.qh>
5 #include <common/state.qh>
6 #include <common/stats.qh>
7 #include <common/util.qh>
8 #include <common/weapons/_all.qh>
9 #include <server/command/banning.qh>
10 #include <server/command/common.qh>
11 #include <server/ipban.qh>
12 #include <server/player.qh>
14 // =====================================================
15 // Banning and kicking command code, written by Samual
16 // Last updated: December 29th, 2011
17 // =====================================================
19 void BanCommand_ban(int request, int argc, string command)
23 case CMD_REQUEST_COMMAND:
28 float reason_arg, bantime;
33 GET_BAN_ARG(bantime, autocvar_g_ban_default_bantime);
34 GET_BAN_REASON(reason, "No reason provided");
36 Ban_Insert(ip, bantime, reason, 1);
42 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
43 case CMD_REQUEST_USAGE:
45 LOG_HELP("Usage:^3 sv_cmd ban <address> [<bantime>] [<reason>]");
46 LOG_HELP(" <address> is the IP address or range of the player to ban,");
47 LOG_HELP(" <bantime> is the amount of time that the ban is active (default if not provided),");
48 LOG_HELP(" and <reason> is the string to label the ban with as reason for banning.");
49 LOG_HELP("See also: ^2banlist, kickban, unban^7");
55 void BanCommand_banlist(int request)
59 case CMD_REQUEST_COMMAND:
66 case CMD_REQUEST_USAGE:
68 LOG_HELP("Usage:^3 sv_cmd banlist");
69 LOG_HELP(" No arguments required.");
70 LOG_HELP("See also: ^2ban, kickban, unban^7");
76 void BanCommand_kickban(int request, int argc, string command)
80 case CMD_REQUEST_COMMAND:
84 entity client = GetIndexedEntity(argc, 1);
85 float accepted = VerifyKickableEntity(client);
86 float reason_arg, bantime, masksize;
91 reason_arg = next_token;
93 GET_BAN_ARG(bantime, autocvar_g_ban_default_bantime);
94 GET_BAN_ARG(masksize, autocvar_g_ban_default_masksize);
95 GET_BAN_REASON(reason, "No reason provided");
97 Ban_KickBanClient(client, bantime, masksize, reason);
103 LOG_INFO("kickban: ", GetClientErrorString(accepted, argv(1)), ".");
109 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
110 case CMD_REQUEST_USAGE:
112 LOG_HELP("Usage:^3 sv_cmd kickban <client> [<bantime>] [<masksize>] [<reason>]");
113 LOG_HELP(" <client> is the entity number or name of the player to ban,");
114 LOG_HELP(" <bantime> is the amount of time that the ban is active (default if not provided),");
115 LOG_HELP(" <masksize> is the range of the IP address (1-thru-4, default if not provided),");
116 LOG_HELP(" and <reason> is the string to label the ban with as reason for banning.");
117 LOG_HELP("See also: ^2ban, banlist, unban^7");
123 void BanCommand_mute(int request, int argc, string command)
127 case CMD_REQUEST_COMMAND:
131 entity client = GetIndexedEntity(argc, 1);
132 float accepted = VerifyClientEntity(client, true, false);
137 if(!PlayerInIPList(client, autocvar_g_chatban_list))
138 theid = cons(theid, client.netaddress);
139 if(!PlayerInIDList(client, autocvar_g_chatban_list))
140 theid = cons(theid, client.crypto_idfp);
141 CS(client).muted = true;
142 LOG_INFO(strcat("Mute-banning player ", GetCallerName(client), " (", argv(1), ")."));
143 cvar_set("g_chatban_list", cons(autocvar_g_chatban_list, theid));
149 LOG_INFO("mute: ", GetClientErrorString(accepted, argv(1)), ".");
155 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
156 case CMD_REQUEST_USAGE:
158 LOG_HELP("Usage:^3 sv_cmd mute <client>");
159 LOG_HELP(" <client> is the entity number or name of the player to mute.");
160 LOG_HELP("See also: ^2unmute, g_chatban_list^7");
166 void BanCommand_playban(int request, int argc, string command)
170 case CMD_REQUEST_COMMAND:
174 entity client = GetIndexedEntity(argc, 1);
175 float accepted = VerifyClientEntity(client, true, false);
180 if(!PlayerInIPList(client, autocvar_g_playban_list))
181 theid = cons(theid, client.netaddress);
182 if(!PlayerInIDList(client, autocvar_g_playban_list))
183 theid = cons(theid, client.crypto_idfp);
185 LOG_INFO(strcat("Play-banning player ", GetCallerName(client), " (", argv(1), ")."));
186 PutObserverInServer(client, true, true);
187 if (autocvar_g_playban_minigames)
188 part_minigame(client);
189 cvar_set("g_playban_list", cons(autocvar_g_playban_list, theid));
195 LOG_INFO("playban: ", GetClientErrorString(accepted, argv(1)), ".");
201 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
202 case CMD_REQUEST_USAGE:
204 LOG_HELP("Usage:^3 sv_cmd playban <client>");
205 LOG_HELP(" <client> is the entity number or name of the player to ban being forced to spectate permanently,");
206 LOG_HELP("See also: ^2g_playban_list, unplayban^7");
212 void BanCommand_unban(int request, int argc)
216 case CMD_REQUEST_COMMAND:
220 float tmp_number = -1;
223 if (substring(argv(1), 0, 1) == "#")
225 tmp_string = substring(argv(1), 1, -1);
227 if (tmp_string != "") // is it all one token? like #1
228 tmp_number = stof(tmp_string);
229 else if (argc > 2) // no, it's two tokens? # 1
230 tmp_number = stof(argv(2));
231 else tmp_number = -1;
233 else // maybe it's ONLY a number?
235 tmp_number = stof(argv(1));
237 if ((tmp_number == 0) && (argv(1) != "0")) tmp_number = -1; }
241 Ban_Delete(tmp_number);
248 case CMD_REQUEST_USAGE:
250 LOG_HELP("Usage:^3 sv_cmd unban <banid>");
251 LOG_HELP(" Where <banid> is the ID of the ban of which to remove.");
252 LOG_HELP("See also: ^2ban, banlist, kickban^7");
258 void BanCommand_unmute(int request, int argc)
262 case CMD_REQUEST_COMMAND:
266 entity client = GetIndexedEntity(argc, 1);
267 float accepted = VerifyClientEntity(client, true, false);
268 string original_arg = argv(1);
272 string tmp_string = "";
273 FOREACH_WORD(autocvar_g_chatban_list, it != client.netaddress,
275 if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
277 tmp_string = cons(tmp_string, it);
280 cvar_set("g_chatban_list", tmp_string);
281 LOG_INFO(strcat("Unmuting player ", GetCallerName(client), " (", original_arg, ")."));
282 CS(client).muted = false;
288 LOG_INFO("unmute: ", GetClientErrorString(accepted, argv(1)), ".");
294 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
295 case CMD_REQUEST_USAGE:
297 LOG_HELP("Usage:^3 sv_cmd unmute <client>");
298 LOG_HELP(" <client> is the entity number or name of the player to unmute.");
299 LOG_HELP("See also: ^2mute, g_chatban_list^7");
305 void BanCommand_unplayban(int request, int argc)
309 case CMD_REQUEST_COMMAND:
313 entity client = GetIndexedEntity(argc, 1);
314 float accepted = VerifyClientEntity(client, true, false);
315 string original_arg = argv(1);
319 string tmp_string = "";
320 FOREACH_WORD(autocvar_g_playban_list, it != client.netaddress,
322 if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
324 tmp_string = cons(tmp_string, it);
327 cvar_set("g_playban_list", tmp_string);
328 LOG_INFO(strcat("Releasing forced to spectate player ", GetCallerName(client), " (", original_arg, ")."));
334 LOG_INFO("unplayban: ", GetClientErrorString(accepted, argv(1)), ".");
340 case CMD_REQUEST_USAGE:
342 LOG_HELP("Usage:^3 sv_cmd unplayban <banid>");
343 LOG_HELP(" Where <banid> is the ID of the forced to spectate ban of which to remove.");
344 LOG_HELP("See also: ^2playban, g_playban_list^7");
350 void BanCommand_unvoteban(int request, int argc)
354 case CMD_REQUEST_COMMAND:
358 entity client = GetIndexedEntity(argc, 1);
359 float accepted = VerifyClientEntity(client, true, false);
360 string original_arg = argv(1);
364 string tmp_string = "";
365 FOREACH_WORD(autocvar_g_voteban_list, it != client.netaddress,
367 if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
369 tmp_string = cons(tmp_string, it);
372 cvar_set("g_voteban_list", tmp_string);
373 LOG_INFO(strcat("Unvote-banning player ", GetCallerName(client), " (", original_arg, ")."));
379 LOG_INFO("unvoteban: ", GetClientErrorString(accepted, argv(1)), ".");
385 case CMD_REQUEST_USAGE:
387 LOG_HELP("Usage:^3 sv_cmd unvoteban <banid>");
388 LOG_HELP(" Where <banid> is the ID of the ban from voting of which to remove.");
389 LOG_HELP("See also: ^2voteban, g_voteban_list^7");
395 void BanCommand_voteban(int request, int argc, string command)
399 case CMD_REQUEST_COMMAND:
403 entity client = GetIndexedEntity(argc, 1);
404 float accepted = VerifyClientEntity(client, true, false);
409 if(!PlayerInIPList(client, autocvar_g_voteban_list))
410 theid = cons(theid, client.netaddress);
411 if(!PlayerInIDList(client, autocvar_g_voteban_list))
412 theid = cons(theid, client.crypto_idfp);
414 LOG_INFO(strcat("Vote-banning player ", GetCallerName(client), " (", argv(1), ")."));
415 cvar_set("g_voteban_list", cons(autocvar_g_voteban_list, theid));
421 LOG_INFO("voteban: ", GetClientErrorString(accepted, argv(1)), ".");
427 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
428 case CMD_REQUEST_USAGE:
430 LOG_HELP("Usage:^3 sv_cmd voteban <client>");
431 LOG_HELP(" <client> is the entity number or name of the player to ban from voting,");
432 LOG_HELP("See also: ^2g_voteban_list, unvoteban^7");
438 /* use this when creating a new command, making sure to place it in alphabetical order... also,
439 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
440 void BanCommand_(int request)
444 case CMD_REQUEST_COMMAND:
451 case CMD_REQUEST_USAGE:
453 LOG_HELP("Usage:^3 sv_cmd ");
454 LOG_HELP(" No arguments required.");
462 // ==================================
463 // Macro system for server commands
464 // ==================================
466 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
467 #define BAN_COMMANDS(request, arguments, command) \
468 BAN_COMMAND("ban", BanCommand_ban(request, arguments, command), "Ban an IP address or a range of addresses (like 1.2.3)") \
469 BAN_COMMAND("banlist", BanCommand_banlist(request), "List all existing bans") \
470 BAN_COMMAND("kickban", BanCommand_kickban(request, arguments, command), "Disconnect a client and ban it at the same time") \
471 BAN_COMMAND("mute", BanCommand_mute(request, arguments, command), "Disallow a client from talking by muting them") \
472 BAN_COMMAND("playban", BanCommand_playban(request, arguments, command), "Force to spectate a client permanently") \
473 BAN_COMMAND("unban", BanCommand_unban(request, arguments), "Remove an existing ban") \
474 BAN_COMMAND("unmute", BanCommand_unmute(request, arguments), "Unmute a client") \
475 BAN_COMMAND("unvoteban", BanCommand_unvoteban(request, arguments), "Remove an existing voting ban") \
476 BAN_COMMAND("unplayban", BanCommand_unplayban(request, arguments), "Remove an existing forced to spectate ban") \
477 BAN_COMMAND("voteban", BanCommand_voteban(request, arguments, command), "Disallow a client from voting") \
480 void BanCommand_macro_help()
482 #define BAN_COMMAND(name, function, description) \
483 { if (strtolower(description) != "") { LOG_INFO(" ^2", name, "^7: ", description); } }
485 BAN_COMMANDS(0, 0, "");
489 float BanCommand_macro_command(int argc, string command)
491 #define BAN_COMMAND(name, function, description) \
492 { if (name == strtolower(argv(0))) { function; return true; } }
494 BAN_COMMANDS(CMD_REQUEST_COMMAND, argc, command);
500 float BanCommand_macro_usage(int argc)
502 #define BAN_COMMAND(name, function, description) \
503 { if (name == strtolower(argv(1))) { function; return true; } }
505 BAN_COMMANDS(CMD_REQUEST_USAGE, argc, "");
511 void BanCommand_macro_write_aliases(float fh)
513 #define BAN_COMMAND(name, function, description) \
514 { if (strtolower(description) != "") { CMD_Write_Alias("qc_cmd_sv", name, description); } }
516 BAN_COMMANDS(0, 0, "");
520 float BanCommand(string command)
522 int argc = tokenize_console(command);
524 // Guide for working with argc arguments by example:
525 // argc: 1 - 2 - 3 - 4
526 // argv: 0 - 1 - 2 - 3
527 // cmd vote - master - login - password
529 if (BanCommand_macro_command(argc, command)) // continue as usual and scan for normal commands
530 return true; // handled by one of the above GenericCommand_* functions