Merge branch 'master' into terencehill/string_prefixes_cleanup
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / command / banning.qc
1 #if defined(CSQC)
2 #elif defined(MENUQC)
3 #elif defined(SVQC)
4         #include "../../dpdefs/dpextensions.qh"
5     #include "../../common/util.qh"
6     #include "../../common/command/shared_defs.qh"
7     #include "../autocvars.qh"
8     #include "common.qh"
9     #include "banning.qh"
10     #include "../ipban.qh"
11 #endif
12 // =====================================================
13 //  Banning and kicking command code, written by Samual
14 //  Last updated: December 29th, 2011
15 // =====================================================
16
17 void BanCommand_ban(float request, float argc, string command)
18 {
19         switch(request)
20         {
21                 case CMD_REQUEST_COMMAND:
22                 {
23                         if(argc >= 2)
24                         {
25                                 string ip = argv(1);
26                                 float reason_arg, bantime;
27                                 string reason;
28
29                                 reason_arg = 2;
30
31                                 GET_BAN_ARG(bantime, autocvar_g_ban_default_bantime);
32                                 GET_BAN_REASON(reason, "No reason provided");
33
34                                 Ban_Insert(ip, bantime, reason, 1);
35                                 return;
36                         }
37                 }
38
39                 default:
40                         print("Incorrect parameters for ^2ban^7\n");
41                 case CMD_REQUEST_USAGE:
42                 {
43                         print("\nUsage:^3 sv_cmd ban address [bantime] [reason]\n");
44                         print("  'address' is the IP address or range of the player to ban,\n");
45                         print("  'bantime' is the amount of time that the ban is active (default if not provided),\n");
46                         print("  and 'reason' is the string to label the ban with as reason for banning.\n");
47                         print("See also: ^2banlist, kickban, unban^7\n");
48                         return;
49                 }
50         }
51 }
52
53 void BanCommand_banlist(float request)
54 {
55         switch(request)
56         {
57                 case CMD_REQUEST_COMMAND:
58                 {
59                         Ban_View();
60                         return;
61                 }
62
63                 default:
64                 case CMD_REQUEST_USAGE:
65                 {
66                         print("\nUsage:^3 sv_cmd banlist\n");
67                         print("  No arguments required.\n");
68                         print("See also: ^2ban, kickban, unban^7\n");
69                         return;
70                 }
71         }
72 }
73
74 void BanCommand_kickban(float request, float argc, string command)
75 {
76         switch(request)
77         {
78                 case CMD_REQUEST_COMMAND:
79                 {
80                         if(argc >= 2)
81                         {
82                                 entity client = GetIndexedEntity(argc, 1);
83                                 float accepted = VerifyKickableEntity(client);
84                                 float reason_arg, bantime, masksize;
85                                 string reason;
86
87                                 if(accepted > 0)
88                                 {
89                                         reason_arg = next_token;
90
91                                         GET_BAN_ARG(bantime, autocvar_g_ban_default_bantime);
92                                         GET_BAN_ARG(masksize, autocvar_g_ban_default_masksize);
93                                         GET_BAN_REASON(reason, "No reason provided");
94
95                                         Ban_KickBanClient(client, bantime, masksize, reason);
96
97                                         return;
98                                 }
99                                 else
100                                 {
101                                         print("kickban: ", GetClientErrorString(accepted, argv(1)), ".\n");
102                                 }
103                         }
104                 }
105
106                 default:
107                         print("Incorrect parameters for ^2kickban^7\n");
108                 case CMD_REQUEST_USAGE:
109                 {
110                         print("\nUsage:^3 sv_cmd kickban client [bantime] [masksize] [reason]\n");
111                         print("  'client' is the entity number or name of the player to ban,\n");
112                         print("  'bantime' is the amount of time that the ban is active (default if not provided),\n");
113                         print("  'masksize' is the range of the IP address (1-thru-4, default if not provided),\n");
114                         print("  and 'reason' is the string to label the ban with as reason for banning.\n");
115                         print("See also: ^2ban, banlist, unban^7\n");
116                         return;
117                 }
118         }
119 }
120
121 void BanCommand_mute(float request, float argc, string command) // TODO: Add a sort of mute-"ban" which allows players to be muted based on IP/cryptokey
122 {
123         switch(request)
124         {
125                 case CMD_REQUEST_COMMAND:
126                 {
127                         if(argc >= 2)
128                         {
129                                 entity client = GetFilteredEntity(argv(1));
130                                 float accepted = VerifyClientEntity(client, true, false);
131
132                                 if(accepted > 0)
133                                 {
134                                         client.muted = true;
135                                         return;
136                                 }
137                                 else
138                                 {
139                                         print("mute: ", GetClientErrorString(accepted, argv(1)), ".\n");
140                                 }
141                         }
142                 }
143
144                 default:
145                         print("Incorrect parameters for ^2mute^7\n");
146                 case CMD_REQUEST_USAGE:
147                 {
148                         print("\nUsage:^3 sv_cmd mute client\n");
149                         print("  'client' is the entity number or name of the player to mute.\n");
150                         print("See also: ^2unmute^7\n");
151                         return;
152                 }
153         }
154 }
155
156 void BanCommand_unban(float request, float argc)
157 {
158         switch(request)
159         {
160                 case CMD_REQUEST_COMMAND:
161                 {
162                         if(argv(1))
163                         {
164                                 float tmp_number = -1;
165                                 string tmp_string;
166
167                                 if(substring(argv(1), 0, 1) == "#")
168                                 {
169                                         tmp_string = substring(argv(1), 1, -1);
170
171                                         if(tmp_string != "") // is it all one token? like #1
172                                         {
173                                                 tmp_number = stof(tmp_string);
174                                         }
175                                         else if(argc > 2) // no, it's two tokens? # 1
176                                         {
177                                                 tmp_number = stof(argv(2));
178                                         }
179                                         else
180                                                 tmp_number = -1;
181                                 }
182                                 else // maybe it's ONLY a number?
183                                 {
184                                         tmp_number = stof(argv(1));
185
186                                         if((tmp_number == 0) && (argv(1) != "0"))
187                                                 { tmp_number = -1; }
188                                 }
189
190                                 if(tmp_number >= 0)
191                                 {
192                                         Ban_Delete(tmp_number);
193                                         return;
194                                 }
195                         }
196                 }
197
198                 default:
199                 case CMD_REQUEST_USAGE:
200                 {
201                         print("\nUsage:^3 sv_cmd unban banid\n");
202                         print("  Where 'banid' is the ID of the ban of which to remove.\n");
203                         print("See also: ^2ban, banlist, kickban^7\n");
204                         return;
205                 }
206         }
207 }
208
209 void BanCommand_unmute(float request, float argc)
210 {
211         switch(request)
212         {
213                 case CMD_REQUEST_COMMAND:
214                 {
215                         if(argc >= 2)
216                         {
217                                 entity client = GetFilteredEntity(argv(1));
218                                 float accepted = VerifyClientEntity(client, true, false);
219
220                                 if(accepted > 0)
221                                 {
222                                         client.muted = false;
223                                         return;
224                                 }
225                                 else
226                                 {
227                                         print("unmute: ", GetClientErrorString(accepted, argv(1)), ".\n");
228                                 }
229                         }
230                 }
231
232                 default:
233                         print("Incorrect parameters for ^2mute^7\n");
234                 case CMD_REQUEST_USAGE:
235                 {
236                         print("\nUsage:^3 sv_cmd unmute client\n");
237                         print("  'client' is the entity number or name of the player to unmute.\n");
238                         print("See also: ^2mute^7\n");
239                         return;
240                 }
241         }
242 }
243
244 /* use this when creating a new command, making sure to place it in alphabetical order... also,
245 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
246 void BanCommand_(float request)
247 {
248         switch(request)
249         {
250                 case CMD_REQUEST_COMMAND:
251                 {
252
253                         return;
254                 }
255
256                 default:
257                 case CMD_REQUEST_USAGE:
258                 {
259                         print("\nUsage:^3 sv_cmd \n");
260                         print("  No arguments required.\n");
261                         return;
262                 }
263         }
264 }
265 */
266
267
268 // ==================================
269 //  Macro system for server commands
270 // ==================================
271
272 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
273 #define BAN_COMMANDS(request,arguments,command) \
274         BAN_COMMAND("ban", BanCommand_ban(request, arguments, command), "Ban an IP address or a range of addresses (like 1.2.3)") \
275         BAN_COMMAND("banlist", BanCommand_banlist(request), "List all existing bans") \
276         BAN_COMMAND("kickban", BanCommand_kickban(request, arguments, command), "Disconnect a client and ban it at the same time") \
277         BAN_COMMAND("mute", BanCommand_mute(request, arguments, command), "Disallow a client from talking by muting them") \
278         BAN_COMMAND("unban", BanCommand_unban(request, arguments), "Remove an existing ban") \
279         BAN_COMMAND("unmute", BanCommand_unmute(request, arguments), "Unmute a client") \
280         /* nothing */
281
282 void BanCommand_macro_help()
283 {
284         #define BAN_COMMAND(name,function,description) \
285                 { if(strtolower(description) != "") { print("  ^2", name, "^7: ", description, "\n"); } }
286
287         BAN_COMMANDS(0, 0, "");
288         #undef BAN_COMMAND
289
290         return;
291 }
292
293 float BanCommand_macro_command(float argc, string command)
294 {
295         #define BAN_COMMAND(name,function,description) \
296                 { if(name == strtolower(argv(0))) { function; return true; } }
297
298         BAN_COMMANDS(CMD_REQUEST_COMMAND, argc, command);
299         #undef BAN_COMMAND
300
301         return false;
302 }
303
304 float BanCommand_macro_usage(float argc)
305 {
306         #define BAN_COMMAND(name,function,description) \
307                 { if(name == strtolower(argv(1))) { function; return true; } }
308
309         BAN_COMMANDS(CMD_REQUEST_USAGE, argc, "");
310         #undef BAN_COMMAND
311
312         return false;
313 }
314
315 void BanCommand_macro_write_aliases(float fh)
316 {
317         #define BAN_COMMAND(name,function,description) \
318                 { if(strtolower(description) != "") { CMD_Write_Alias("qc_cmd_sv", name, description); } }
319
320         BAN_COMMANDS(0, 0, "");
321         #undef BAN_COMMAND
322
323         return;
324 }
325
326 float BanCommand(string command)
327 {
328         float argc = tokenize_console(command);
329
330         // Guide for working with argc arguments by example:
331         // argc:   1    - 2      - 3     - 4
332         // argv:   0    - 1      - 2     - 3
333         // cmd     vote - master - login - password
334
335         if(BanCommand_macro_command(argc, command)) // continue as usual and scan for normal commands
336         {
337                 return true; // handled by one of the above GenericCommand_* functions
338         }
339
340         return false;
341 }