1 // ====================================================
2 // Shared code for server commands, written by Samual
3 // Last updated: December 13th, 2011
4 // ====================================================
6 string GetCommandPrefix(entity caller)
14 string GetCallerName(entity caller)
17 return caller.netname;
19 return ((autocvar_sv_adminnick != "") ? autocvar_sv_adminnick : autocvar_hostname);
22 // find a player which matches the input string, and return their entity number
23 float GetFilteredNumber(string input)
25 entity tmp_player, selection;
26 float output, matches;
28 // check and see if we can get a number from input like "#3" or "3"
29 if(substring(input, 0, 1) == "#")
30 output = stof(substring(input, 1, -1));
34 // if we can't, check and see if we can match the input to the netname of any player in the game
37 FOR_EACH_CLIENT(tmp_player)
38 if (strdecolorize(tmp_player.netname) == strdecolorize(input))
39 selection = tmp_player;
41 if (selection) { output = num_for_edict(selection); }
44 print(strcat("input: ", input, ", output: ", ftos(output), ",\n"));
48 // switch between sprint and print depending on whether the reciever is the server or a player
49 void print_to(entity to, string input)
52 sprint(to, strcat(input, "\n"));
58 // ===================================================
59 // Common commands used in both sv_cmd.qc and cmd.qc
60 // ===================================================
62 void CommonCommand_cvar_changes(float request)
66 case CMD_REQUEST_COMMAND:
68 print_to(self, cvar_changes);
69 return; // never fall through to usage
73 case CMD_REQUEST_USAGE:
75 print_to(self, "\nUsage:^3 sv_cmd cvar_changes");
76 print_to(self, " No arguments required.");
77 print_to(self, "See also: ^2cvar_purechanges^7");
83 void CommonCommand_cvar_purechanges(float request)
87 case CMD_REQUEST_COMMAND:
89 print_to(self, cvar_purechanges);
90 return; // never fall through to usage
94 case CMD_REQUEST_USAGE:
96 print_to(self, "\nUsage:^3 sv_cmd cvar_purechanges");
97 print_to(self, " No arguments required.");
98 print_to(self, "See also: ^2cvar_changes^7");
104 void CommonCommand_info(float request, float argc) // todo: figure out how this works?
108 case CMD_REQUEST_COMMAND:
112 command = builtin_cvar_string(strcat("sv_info_", argv(1)));
114 wordwrap_sprint(command, 1111); // why 1111?
116 print_to(self, "ERROR: unsupported info command");
118 return; // never fall through to usage
122 case CMD_REQUEST_USAGE:
124 print_to(self, "\nUsage:^3 cmd info request");
125 print_to(self, " Where 'request' is the suffixed string appended onto the request for cvar.");
131 void CommonCommand_ladder(float request)
135 case CMD_REQUEST_COMMAND:
137 print_to(self, ladder_reply);
138 return; // never fall through to usage
142 case CMD_REQUEST_USAGE:
144 print_to(self, "\nUsage:^3 cmd ladder");
145 print_to(self, " No arguments required.");
151 void CommonCommand_lsmaps(float request)
155 case CMD_REQUEST_COMMAND:
157 print_to(self, lsmaps_reply);
158 return; // never fall through to usage
162 case CMD_REQUEST_USAGE:
164 print_to(self, "\nUsage:^3 cmd lsmaps");
165 print_to(self, " No arguments required.");
171 void CommonCommand_lsnewmaps(float request)
175 case CMD_REQUEST_COMMAND:
177 print_to(self, lsnewmaps_reply);
178 return; // never fall through to usage
182 case CMD_REQUEST_USAGE:
184 print_to(self, "\nUsage:^3 cmd lsnewmaps");
185 print_to(self, " No arguments required.");
191 void CommonCommand_maplist(float request)
195 case CMD_REQUEST_COMMAND:
197 print_to(self, maplist_reply);
198 return; // never fall through to usage
202 case CMD_REQUEST_USAGE:
204 print_to(self, "\nUsage:^3 cmd maplist");
205 print_to(self, " No arguments required.");
211 void GameCommand_rankings(float request) // this is OLD.... jeez.
215 case CMD_REQUEST_COMMAND:
217 strunzone(rankings_reply);
218 rankings_reply = strzone(getrankings());
219 print(rankings_reply);
224 case CMD_REQUEST_USAGE:
226 print("\nUsage:^3 sv_cmd rankings");
227 print(" No arguments required.");
233 void CommonCommand_rankings(float request)
237 case CMD_REQUEST_COMMAND:
239 print_to(self, rankings_reply);
240 return; // never fall through to usage
244 case CMD_REQUEST_USAGE:
246 print_to(self, "\nUsage:^3 cmd rankings");
247 print_to(self, " No arguments required.");
253 void CommonCommand_records(float request) // TODO: Isn't this flooding with the sprint messages? Old code, but perhaps bad?
257 case CMD_REQUEST_COMMAND:
261 for(i = 0; i < 10; ++i)
262 print_to(self, records_reply[i]);
264 return; // never fall through to usage
268 case CMD_REQUEST_USAGE:
270 print_to(self, "\nUsage:^3 cmd records");
271 print_to(self, " No arguments required.");
277 void CommonCommand_teamstatus(float request)
281 case CMD_REQUEST_COMMAND:
283 Score_NicePrint(self);
284 return; // never fall through to usage
288 case CMD_REQUEST_USAGE:
290 print_to(self, "\nUsage:^3 cmd teamstatus");
291 print_to(self, " No arguments required.");
298 void CommonCommand_timein(float request)
302 case CMD_REQUEST_COMMAND:
304 if(self.flags & FL_CLIENT)
306 if(autocvar_sv_timeout)
309 return print_to(self, "^7Error: There is no active timeout which could be aborted!");
310 if (self != timeoutInitiator)
311 return print_to(self, "^7Error: You may not abort the active timeout. Only the player who called it can do that!");
313 if (timeoutStatus == 1)
315 remainingTimeoutTime = timeoutStatus = 0;
316 timeoutHandler.nextthink = time; //timeoutHandler has to take care of it immediately
317 bprint(strcat("^7The timeout was aborted by ", self.netname, " !\n"));
319 else if (timeoutStatus == 2)
321 //only shorten the remainingTimeoutTime if it makes sense
322 if( remainingTimeoutTime > (autocvar_sv_timeout_resumetime + 1) )
324 bprint(strcat("^1Attention: ^7", self.netname, " resumed the game! Prepare for battle!\n"));
325 remainingTimeoutTime = autocvar_sv_timeout_resumetime;
326 timeoutHandler.nextthink = time; //timeoutHandler has to take care of it immediately
329 print_to(self, "^7Error: Your resumegame call was discarded!");
333 return; // never fall through to usage
337 case CMD_REQUEST_USAGE:
339 print_to(self, "\nUsage:^3 cmd timein");
340 print_to(self, " No arguments required.");
346 void CommonCommand_timeout(float request) // DEAR GOD THIS COMMAND IS TERRIBLE.
350 case CMD_REQUEST_COMMAND:
352 if(self.flags & FL_CLIENT)
354 if(autocvar_sv_timeout)
356 if(self.classname == "player")
359 print_to(self, "^7Error: you can not call a timeout while a vote is active!");
362 if (inWarmupStage && !g_warmup_allow_timeout)
363 return print_to(self, "^7Error: You can not call a timeout in warmup-stage!");
364 if (time < game_starttime )
365 return print_to(self, "^7Error: You can not call a timeout while the map is being restarted!");
367 if (timeoutStatus != 2) {
368 //if the map uses a timelimit make sure that timeout cannot be called right before the map ends
369 if (autocvar_timelimit) {
370 //a timelimit was used
372 myTl = autocvar_timelimit;
374 float lastPossibleTimeout;
375 lastPossibleTimeout = (myTl*60) - autocvar_sv_timeout_leadtime - 1;
377 if (lastPossibleTimeout < time - game_starttime)
378 return print_to(self, "^7Error: It is too late to call a timeout now!");
382 //player may not call a timeout if he has no calls left
383 if (self.allowedTimeouts < 1)
384 return print_to(self, "^7Error: You already used all your timeout calls for this map!");
387 //now all required checks are passed
388 self.allowedTimeouts -= 1;
389 bprint(self.netname, " ^7called a timeout (", ftos(self.allowedTimeouts), " timeouts left)!\n"); //write a bprint who started the timeout (and how many he has left)
390 remainingTimeoutTime = autocvar_sv_timeout_length;
391 remainingLeadTime = autocvar_sv_timeout_leadtime;
392 timeoutInitiator = self;
393 if (timeoutStatus == 0) { //if another timeout was already active, don't change its status (which was 1 or 2) to 1, only change it to 1 if no timeout was active yet
395 //create the timeout indicator which centerprints the information to all players and takes care of pausing/unpausing
396 timeoutHandler = spawn();
397 timeoutHandler.think = timeoutHandler_Think;
399 timeoutHandler.nextthink = time; //always let the entity think asap
401 //inform all connected clients about the timeout call
402 Announce("timeoutcalled");
406 print_to(self, "^7Error: only players can call a timeout!");
409 return; // never fall through to usage
413 case CMD_REQUEST_USAGE:
415 print_to(self, "\nUsage:^3 cmd timeout");
416 print_to(self, " No arguments required.");
422 void CommonCommand_who(float request)
426 case CMD_REQUEST_COMMAND:
428 float total_listed_players, tmp_hours, tmp_minutes, tmp_seconds;
430 //string tmp_player_name;
432 print_to(self, strcat("List of client information", (autocvar_sv_status_privacy ? " (some data is hidden for privacy)" : string_null), ":\n"));
433 print_to(self, sprintf(" %-4s %-20s %-5s %-3s %-9s %-16s %s\n", "ent", "nickname", "ping", "pl", "time", "ip", "crypto_id"));
435 FOR_EACH_CLIENT(tmp_player)
437 //tmp_player_name = strlimitedlen(tmp_player.netname, "...", TRUE, 20);
439 tmp_hours = tmp_minutes = tmp_seconds = 0;
441 tmp_seconds = (time - tmp_player.jointime);
442 tmp_minutes = (tmp_seconds / 60);
446 tmp_seconds -= (tmp_minutes * 60);
447 tmp_hours = (tmp_minutes / 60);
449 if(tmp_hours) { tmp_minutes -= (tmp_hours * 60); }
452 print_to(self, sprintf(" %-4s %-20s %-5d %-3d %-9s %-16s %s\n",
453 strcat("#", ftos(num_for_edict(tmp_player))),
454 tmp_player.netname, //strcat(tmp_player_name, sprintf("%*s", (20 - strlen(strdecolorize(tmp_player_name))), "")),
455 tmp_player.ping, tmp_player.ping_packetloss,
456 sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds),
457 (autocvar_sv_status_privacy ? "hidden" : tmp_player.netaddress),
458 (autocvar_sv_status_privacy ? "hidden" : tmp_player.crypto_idfp)));
460 ++total_listed_players;
463 print_to(self, strcat("Finished listing ", ftos(total_listed_players), " client(s). \n"));
465 return; // never fall through to usage
469 case CMD_REQUEST_USAGE:
471 print_to(self, "\nUsage:^3 cmd who");
472 print_to(self, " No arguments required.");
478 /* use this when creating a new command, making sure to place it in alphabetical order.
479 void CommonCommand_(float request)
483 case CMD_REQUEST_COMMAND:
486 return; // never fall through to usage
490 case CMD_REQUEST_USAGE:
492 print_to(self, "\nUsage:^3 cmd ");
493 print_to(self, " No arguments required.");