Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
banning.qc
Go to the documentation of this file.
1#include "banning.qh"
2
5#include <common/state.qh>
6#include <common/stats.qh>
7#include <common/util.qh>
11#include <server/ipban.qh>
12#include <server/player.qh>
13
14// =====================================================
15// Banning and kicking command code, written by Samual
16// Last updated: December 29th, 2011
17// =====================================================
18
19void BanCommand_ban(int request, int argc, string command)
20{
21 switch (request)
22 {
24 {
25 if (argc >= 2)
26 {
27 string ip = argv(1);
28 float reason_arg, bantime;
29 string reason;
30
31 reason_arg = 2;
32
34 GET_BAN_REASON(reason, "No reason provided");
35
36 Ban_Insert(ip, bantime, reason, 1);
37 return;
38 }
39 }
40
41 default:
42 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
44 {
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");
50 return;
51 }
52 }
53}
54
55void BanCommand_banlist(int request)
56{
57 switch (request)
58 {
60 {
61 Ban_View();
62 return;
63 }
64
65 default:
67 {
68 LOG_HELP("Usage:^3 sv_cmd banlist");
69 LOG_HELP(" No arguments required.");
70 LOG_HELP("See also: ^2ban, kickban, unban^7");
71 return;
72 }
73 }
74}
75
76void BanCommand_kickban(int request, int argc, string command)
77{
78 switch (request)
79 {
81 {
82 if (argc >= 2)
83 {
84 entity client = GetIndexedEntity(argc, 1);
85 float accepted = VerifyKickableEntity(client);
86 float reason_arg, bantime, masksize;
87 string reason;
88
89 if (accepted > 0)
90 {
91 reason_arg = next_token;
92
95 GET_BAN_REASON(reason, "No reason provided");
96
97 Ban_KickBanClient(client, bantime, masksize, reason);
98
99 return;
100 }
101 else
102 {
103 LOG_INFO("kickban: ", GetClientErrorString(accepted, argv(1)), ".");
104 }
105 }
106 }
107
108 default:
109 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
111 {
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");
118 return;
119 }
120 }
121}
122
123void BanCommand_mute(int request, int argc, string command)
124{
125 switch (request)
126 {
128 {
129 if (argc >= 2)
130 {
131 entity client = GetIndexedEntity(argc, 1);
132 float accepted = VerifyClientEntity(client, true, false);
133
134 if (accepted > 0)
135 {
136 string theid = "";
138 theid = cons(theid, client.netaddress);
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));
144
145 return;
146 }
147 else
148 {
149 LOG_INFO("mute: ", GetClientErrorString(accepted, argv(1)), ".");
150 }
151 }
152 }
153
154 default:
155 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
157 {
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");
161 return;
162 }
163 }
164}
165
166void BanCommand_playban(int request, int argc, string command)
167{
168 switch (request)
169 {
171 {
172 if (argc >= 2)
173 {
174 entity client = GetIndexedEntity(argc, 1);
175 float accepted = VerifyClientEntity(client, true, false);
176
177 if (accepted > 0)
178 {
179 string theid = "";
181 theid = cons(theid, client.netaddress);
183 theid = cons(theid, client.crypto_idfp);
184
185 LOG_INFO(strcat("Play-banning player ", GetCallerName(client), " (", argv(1), ")."));
186 PutObserverInServer(client, true, true);
188 part_minigame(client);
189 cvar_set("g_playban_list", cons(autocvar_g_playban_list, theid));
190
191 return;
192 }
193 else
194 {
195 LOG_INFO("playban: ", GetClientErrorString(accepted, argv(1)), ".");
196 }
197 }
198 }
199
200 default:
201 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
203 {
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");
207 return;
208 }
209 }
210}
211
212void BanCommand_unban(int request, int argc)
213{
214 switch (request)
215 {
217 {
218 if (argv(1))
219 {
220 float tmp_number = -1;
221 string tmp_string;
222
223 if (substring(argv(1), 0, 1) == "#")
224 {
225 tmp_string = substring(argv(1), 1, -1);
226
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;
232 }
233 else // maybe it's ONLY a number?
234 {
235 tmp_number = stof(argv(1));
236
237 if ((tmp_number == 0) && (argv(1) != "0")) tmp_number = -1; }
238
239 if (tmp_number >= 0)
240 {
241 Ban_Delete(tmp_number);
242 return;
243 }
244 }
245 }
246
247 default:
249 {
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");
253 return;
254 }
255 }
256}
257
258void BanCommand_unmute(int request, int argc)
259{
260 switch (request)
261 {
263 {
264 if (argc >= 2)
265 {
266 entity client = GetIndexedEntity(argc, 1);
267 float accepted = VerifyClientEntity(client, true, false);
268 string original_arg = argv(1);
269
270 if (accepted > 0)
271 {
272 string tmp_string = "";
273 FOREACH_WORD(autocvar_g_chatban_list, it != client.netaddress,
274 {
275 if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
276 continue;
277 tmp_string = cons(tmp_string, it);
278 });
279
280 cvar_set("g_chatban_list", tmp_string);
281 LOG_INFO(strcat("Unmuting player ", GetCallerName(client), " (", original_arg, ")."));
282 CS(client).muted = false;
283
284 return;
285 }
286 else
287 {
288 LOG_INFO("unmute: ", GetClientErrorString(accepted, argv(1)), ".");
289 }
290 }
291 }
292
293 default:
294 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
296 {
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");
300 return;
301 }
302 }
303}
304
305void BanCommand_unplayban(int request, int argc)
306{
307 switch (request)
308 {
310 {
311 if (argv(1))
312 {
313 entity client = GetIndexedEntity(argc, 1);
314 float accepted = VerifyClientEntity(client, true, false);
315 string original_arg = argv(1);
316
317 if (accepted > 0)
318 {
319 string tmp_string = "";
320 FOREACH_WORD(autocvar_g_playban_list, it != client.netaddress,
321 {
322 if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
323 continue;
324 tmp_string = cons(tmp_string, it);
325 });
326
327 cvar_set("g_playban_list", tmp_string);
328 LOG_INFO(strcat("Releasing forced to spectate player ", GetCallerName(client), " (", original_arg, ")."));
329
330 return;
331 }
332 else
333 {
334 LOG_INFO("unplayban: ", GetClientErrorString(accepted, argv(1)), ".");
335 }
336 }
337 }
338
339 default:
341 {
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");
345 return;
346 }
347 }
348}
349
350void BanCommand_unvoteban(int request, int argc)
351{
352 switch (request)
353 {
355 {
356 if (argv(1))
357 {
358 entity client = GetIndexedEntity(argc, 1);
359 float accepted = VerifyClientEntity(client, true, false);
360 string original_arg = argv(1);
361
362 if (accepted > 0)
363 {
364 string tmp_string = "";
365 FOREACH_WORD(autocvar_g_voteban_list, it != client.netaddress,
366 {
367 if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
368 continue;
369 tmp_string = cons(tmp_string, it);
370 });
371
372 cvar_set("g_voteban_list", tmp_string);
373 LOG_INFO(strcat("Unvote-banning player ", GetCallerName(client), " (", original_arg, ")."));
374
375 return;
376 }
377 else
378 {
379 LOG_INFO("unvoteban: ", GetClientErrorString(accepted, argv(1)), ".");
380 }
381 }
382 }
383
384 default:
386 {
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");
390 return;
391 }
392 }
393}
394
395void BanCommand_voteban(int request, int argc, string command)
396{
397 switch (request)
398 {
400 {
401 if (argc >= 2)
402 {
403 entity client = GetIndexedEntity(argc, 1);
404 float accepted = VerifyClientEntity(client, true, false);
405
406 if (accepted > 0)
407 {
408 string theid = "";
410 theid = cons(theid, client.netaddress);
412 theid = cons(theid, client.crypto_idfp);
413
414 LOG_INFO(strcat("Vote-banning player ", GetCallerName(client), " (", argv(1), ")."));
415 cvar_set("g_voteban_list", cons(autocvar_g_voteban_list, theid));
416
417 return;
418 }
419 else
420 {
421 LOG_INFO("voteban: ", GetClientErrorString(accepted, argv(1)), ".");
422 }
423 }
424 }
425
426 default:
427 LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
429 {
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");
433 return;
434 }
435 }
436}
437
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!
440void BanCommand_(int request)
441{
442 switch(request)
443 {
444 case CMD_REQUEST_COMMAND:
445 {
446
447 return;
448 }
449
450 default:
451 case CMD_REQUEST_USAGE:
452 {
453 LOG_HELP("Usage:^3 sv_cmd ");
454 LOG_HELP(" No arguments required.");
455 return;
456 }
457 }
458}
459*/
460
461
462// ==================================
463// Macro system for server commands
464// ==================================
465
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") \
478 /* nothing */
479
481{
482 #define BAN_COMMAND(name, function, description) \
483 { if (strtolower(description) != "") { LOG_INFO(" ^2", name, "^7: ", description); } }
484
485 BAN_COMMANDS(0, 0, "");
486#undef BAN_COMMAND
487}
488
489float BanCommand_macro_command(int argc, string command)
490{
491 #define BAN_COMMAND(name, function, description) \
492 { if (name == strtolower(argv(0))) { function; return true; } }
493
494 BAN_COMMANDS(CMD_REQUEST_COMMAND, argc, command);
495#undef BAN_COMMAND
496
497 return false;
498}
499
501{
502 #define BAN_COMMAND(name, function, description) \
503 { if (name == strtolower(argv(1))) { function; return true; } }
504
506#undef BAN_COMMAND
507
508 return false;
509}
510
512{
513 #define BAN_COMMAND(name, function, description) \
514 { if (strtolower(description) != "") { CMD_Write_Alias("qc_cmd_sv", name, description); } }
515
516 BAN_COMMANDS(0, 0, "");
517#undef BAN_COMMAND
518}
519
520float BanCommand(string command)
521{
522 int argc = tokenize_console(command);
523
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
528
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
531
532 return false;
533}
void BanCommand_banlist(int request)
Definition banning.qc:55
void BanCommand_kickban(int request, int argc, string command)
Definition banning.qc:76
void BanCommand_macro_help()
Definition banning.qc:480
void BanCommand_ban(int request, int argc, string command)
Definition banning.qc:19
#define BAN_COMMANDS(request, arguments, command)
Definition banning.qc:467
void BanCommand_playban(int request, int argc, string command)
Definition banning.qc:166
void BanCommand_unplayban(int request, int argc)
Definition banning.qc:305
void BanCommand_voteban(int request, int argc, string command)
Definition banning.qc:395
void BanCommand_unban(int request, int argc)
Definition banning.qc:212
void BanCommand_unvoteban(int request, int argc)
Definition banning.qc:350
float BanCommand_macro_command(int argc, string command)
Definition banning.qc:489
void BanCommand_mute(int request, int argc, string command)
Definition banning.qc:123
void BanCommand_unmute(int request, int argc)
Definition banning.qc:258
void BanCommand_macro_write_aliases(float fh)
Definition banning.qc:511
float BanCommand_macro_usage(int argc)
Definition banning.qc:500
float BanCommand(string command)
Definition banning.qc:520
#define GET_BAN_ARG(v, d)
Definition banning.qh:18
string autocvar_g_playban_list
Definition banning.qh:14
bool autocvar_g_playban_minigames
Definition banning.qh:15
string autocvar_g_voteban_list
Definition banning.qh:16
#define GET_BAN_REASON(v, d)
Definition banning.qh:19
string autocvar_g_chatban_list
Definition banning.qh:13
float autocvar_g_ban_default_bantime
Definition banning.qh:3
float autocvar_g_ban_default_masksize
Definition banning.qh:4
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
const int CMD_REQUEST_COMMAND
Definition command.qh:3
const int CMD_REQUEST_USAGE
Definition command.qh:4
#define tokenize_console
void Ban_View()
Definition ipban.qc:328
float Ban_Insert(string ip, float bantime, string reason, float dosync)
Definition ipban.qc:505
float Ban_Delete(float i)
Definition ipban.qc:286
void Ban_KickBanClient(entity client, float bantime, float masksize, string reason)
Definition ipban.qc:582
#define FOREACH_WORD(words, cond, body)
Definition iter.qh:33
#define LOG_HELP(...)
Definition log.qh:85
#define LOG_INFO(...)
Definition log.qh:65
#define LOG_INFOF(...)
Definition log.qh:66
void cvar_set(string name, string value)
float stof(string val,...)
string substring(string s, float start, float length)
string argv(float n)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
bool PlayerInIDList(entity p, string idlist)
Definition client.qc:1036
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
putting a client as observer in the server
Definition client.qc:261
bool PlayerInIPList(entity p, string iplist)
Definition client.qc:1027
entity GetIndexedEntity(int argc, int start_index)
Definition common.qc:82
int VerifyClientEntity(entity client, bool must_be_real, bool must_be_bots)
Definition common.qc:47
string GetCallerName(entity caller)
Definition common.qc:33
int VerifyKickableEntity(entity client)
Definition common.qc:40
#define GetClientErrorString(clienterror, original_input)
Definition common.qh:87
int next_token
Definition common.qh:71
ClientState CS(Client this)
Definition state.qh:47
ERASEABLE string cons(string a, string b)
Definition string.qh:276
void part_minigame(entity player)