Xonotic
sv_cmd.qc
Go to the documentation of this file.
1 #include "sv_cmd.qh"
2 
3 #include <common/constants.qh>
4 #include <common/effects/all.qh>
6 #include <common/mapinfo.qh>
8 #include <common/net_linked.qh>
10 #include <common/teams.qh>
11 #include <common/util.qh>
12 #include <server/anticheat.qh>
13 #include <server/bot/api.qh>
14 #include <server/campaign.qh>
15 #include <server/client.qh>
16 #include <server/command/_mod.qh>
18 #include <server/command/cmd.qh>
19 #include <server/command/common.qh>
22 #include <server/intermission.qh>
23 #include <server/ipban.qh>
24 #include <server/mutators/_mod.qh>
25 #include <server/player.qh>
26 #include <server/scores_rules.qh>
27 #include <server/teamplay.qh>
28 #include <server/world.qh>
29 
30 // used by GameCommand_make_mapinfo()
32 {
34  {
35  LOG_INFO("Done rebuiling mapinfos.");
37  delete(this);
38  }
39  else
40  {
42  this.nextthink = time;
43  }
44 }
45 
46 // used by GameCommand_extendmatchtime() and GameCommand_reducematchtime()
47 void changematchtime(float delta, float mi, float ma)
48 {
49  float cur;
50  float update;
51  float lim;
52 
53  if (delta == 0) return;
54  if (autocvar_timelimit < 0) return;
55 
56  if (mi <= 10) mi = 10; // at least ten sec in the future
57  cur = time - game_starttime;
58  if (cur > 0) mi += cur; // from current time!
59 
60  lim = autocvar_timelimit * 60;
61 
62  if (delta > 0)
63  {
64  if (lim == 0) return; // cannot increase any further
65  else if (lim < ma) update = min(ma, lim + delta);
66  else // already above maximum: FAIL
67  return;
68  }
69  else
70  {
71  if (lim == 0) // infinite: try reducing to max, if we are allowed to
72  update = max(mi, ma);
73  else if (lim > mi) // above minimum: decrease
74  update = max(mi, lim + delta);
75  else // already below minimum: FAIL
76  return;
77  }
78 
79  cvar_set("timelimit", ftos(update / 60));
80 }
81 
82 
83 // =======================
84 // Command Sub-Functions
85 // =======================
86 
87 void GameCommand_adminmsg(int request, int argc)
88 {
89  switch (request)
90  {
92  {
93  entity client;
94  float accepted;
95 
96  string targets = strreplace(",", " ", argv(1));
97  string original_targets = strreplace(" ", ", ", targets);
98  string admin_message = argv(2);
99  float infobartime = stof(argv(3));
100 
101  string successful, t;
102  successful = string_null;
103 
104  if ((targets) && (admin_message))
105  {
106  for ( ; targets; )
107  {
108  t = car(targets);
109  targets = cdr(targets);
110 
111  // Check to see if the player is a valid target
112  client = GetFilteredEntity(t);
113  accepted = VerifyClientEntity(client, true, false);
114 
115  if (accepted <= 0)
116  {
117  LOG_INFO("adminmsg: ", GetClientErrorString(accepted, t), (targets ? ", skipping to next player.\n" : "."));
118  continue;
119  }
120 
121  // send the centerprint/console print or infomessage
122  if (infobartime)
123  {
124  stuffcmd(client, sprintf("\ninfobar %f \"%s\"\n", infobartime, MakeConsoleSafe(admin_message)));
125  }
126  else
127  {
128  centerprint(client, strcat("^3", GetCallerName(NULL), ":\n^7", admin_message));
129  sprint(client, strcat("\{1}\{13}^3", GetCallerName(NULL), "^7: ", admin_message, "\n"));
130  }
131 
132  successful = strcat(successful, (successful ? ", " : ""), playername(client.netname, client.team, false));
133  LOG_TRACE("Message sent to ", playername(client.netname, client.team, false));
134  continue;
135  }
136 
137  if (successful) bprint("Successfully sent message '", admin_message, "' to ", successful, ".\n");
138  else LOG_INFO("No players given (", original_targets, ") could receive the message.");
139 
140  return;
141  }
142  }
143 
144  default:
145  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
146  case CMD_REQUEST_USAGE:
147  {
148  LOG_HELP("Usage:^3 sv_cmd adminmsg <clients> \"<message>\" [<infobartime>]");
149  LOG_HELP(" <clients> is a list (separated by commas) of player entity ID's or nicknames");
150  LOG_HELP(" If <infobartime> is provided, the message will be sent to infobar.");
151  LOG_HELP(" Otherwise, it will just be sent as a centerprint message.");
152  LOG_HELP("Examples: adminmsg 2,4 \"this infomessage will last for ten seconds\" 10");
153  LOG_HELP(" adminmsg 2,5 \"this message will be a centerprint\"");
154  return;
155  }
156  }
157 }
158 
159 void GameCommand_allready(int request)
160 {
161  switch (request)
162  {
163  case CMD_REQUEST_COMMAND:
164  {
165  if(warmup_stage)
166  {
167  ReadyRestart(true);
168  }
169  else
170  LOG_INFO("Not in warmup.");
171 
172  return;
173  }
174 
175  default:
176  case CMD_REQUEST_USAGE:
177  {
178  LOG_HELP("Usage:^3 sv_cmd allready");
179  LOG_HELP(" No arguments required.");
180  return;
181  }
182  }
183 }
184 
185 void GameCommand_allspec(int request, int argc)
186 {
187  switch (request)
188  {
189  case CMD_REQUEST_COMMAND:
190  {
191  string reason = argv(1);
192  int n = 0;
194  PutObserverInServer(it, true, true);
195  ++n;
196  });
197  if (n) bprint(strcat("Successfully forced all (", ftos(n), ") players to spectate", (reason ? strcat(" for reason: '", reason, "'") : ""), ".\n"));
198  else LOG_INFO("No players found to spectate.");
199  return;
200  }
201 
202  default:
203  case CMD_REQUEST_USAGE:
204  {
205  LOG_HELP("Usage:^3 sv_cmd allspec [<reason>]");
206  LOG_HELP(" Where <reason> is an optional argument for explanation of allspec command.");
207  LOG_HELP("See also: ^2moveplayer, shuffleteams^7");
208  return;
209  }
210  }
211 }
212 
213 void GameCommand_anticheat(int request, int argc)
214 {
215  switch (request)
216  {
217  case CMD_REQUEST_COMMAND:
218  {
219  entity client = GetIndexedEntity(argc, 1);
220  float accepted = VerifyClientEntity(client, false, false);
221 
222  if (accepted > 0)
223  {
225  return;
226  }
227  else
228  {
229  LOG_INFO("anticheat: ", GetClientErrorString(accepted, argv(1)), ".");
230  }
231  }
232 
233  default:
234  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
235  case CMD_REQUEST_USAGE:
236  {
237  LOG_HELP("Usage:^3 sv_cmd anticheat <client>");
238  LOG_HELP(" <client> is the entity number or name of the player.");
239  return;
240  }
241  }
242 }
243 
244 void GameCommand_bbox(int request)
245 {
246  switch (request)
247  {
248  case CMD_REQUEST_COMMAND:
249  {
250  vector size_min = '0 0 0';
251  vector size_max = '0 0 0';
252  tracebox('1 0 0' * world.absmin.x,
253  '0 1 0' * world.absmin.y + '0 0 1' * world.absmin.z,
254  '0 1 0' * world.absmax.y + '0 0 1' * world.absmax.z,
255  '1 0 0' * world.absmax.x,
257  NULL);
258  size_min.x = (trace_startsolid) ? world.absmin.x : trace_endpos.x;
259 
260  tracebox('0 1 0' * world.absmin.y,
261  '1 0 0' * world.absmin.x + '0 0 1' * world.absmin.z,
262  '1 0 0' * world.absmax.x + '0 0 1' * world.absmax.z,
263  '0 1 0' * world.absmax.y,
265  NULL);
266  size_min.y = (trace_startsolid) ? world.absmin.y : trace_endpos.y;
267 
268  tracebox('0 0 1' * world.absmin.z,
269  '1 0 0' * world.absmin.x + '0 1 0' * world.absmin.y,
270  '1 0 0' * world.absmax.x + '0 1 0' * world.absmax.y,
271  '0 0 1' * world.absmax.z,
273  NULL);
274  size_min.z = (trace_startsolid) ? world.absmin.z : trace_endpos.z;
275 
276  tracebox('1 0 0' * world.absmax.x,
277  '0 1 0' * world.absmin.y + '0 0 1' * world.absmin.z,
278  '0 1 0' * world.absmax.y + '0 0 1' * world.absmax.z,
279  '1 0 0' * world.absmin.x,
281  NULL);
282  size_max.x = (trace_startsolid) ? world.absmax.x : trace_endpos.x;
283 
284  tracebox('0 1 0' * world.absmax.y,
285  '1 0 0' * world.absmin.x + '0 0 1' * world.absmin.z,
286  '1 0 0' * world.absmax.x + '0 0 1' * world.absmax.z,
287  '0 1 0' * world.absmin.y,
289  NULL);
290  size_max.y = (trace_startsolid) ? world.absmax.y : trace_endpos.y;
291 
292  tracebox('0 0 1' * world.absmax.z,
293  '1 0 0' * world.absmin.x + '0 1 0' * world.absmin.y,
294  '1 0 0' * world.absmax.x + '0 1 0' * world.absmax.y,
295  '0 0 1' * world.absmin.z,
297  NULL);
298  size_max.z = (trace_startsolid) ? world.absmax.z : trace_endpos.z;
299 
300  LOG_INFOF("Original size: %v %v", world.absmin, world.absmax);
301  LOG_INFOF("Currently set size: %v %v", world.mins, world.maxs);
302  LOG_INFOF("Solid bounding box size: %v %v", size_min, size_max);
303  return;
304  }
305 
306  default:
307  case CMD_REQUEST_USAGE:
308  {
309  LOG_HELP("Usage:^3 sv_cmd bbox");
310  LOG_HELP(" No arguments required.");
311  LOG_HELP("See also: ^2gettaginfo, trace^7");
312  return;
313  }
314  }
315 }
316 
317 void GameCommand_bot_cmd(int request, int argc, string command)
318 {
319  switch (request)
320  {
321  case CMD_REQUEST_COMMAND:
322  {
323  entity bot;
324 
325  if (argv(1) == "reset")
326  {
327  bot_resetqueues();
328  return;
329  }
330  else if (argv(1) == "setbots")
331  {
332  cvar_settemp("bot_vs_human", "0");
333  cvar_settemp("minplayers", "0");
334  cvar_settemp("minplayers_per_team", "0");
335  cvar_settemp("bot_number", "0");
336  bot_fixcount(false); // Kill all bots.
337  cvar_settemp("bot_number", argv(2));
338  if (!bot_fixcount(true)) LOG_INFO("Sorry, could not set requested bot count");
339  return;
340  }
341  else if (argv(1) == "load" && argc == 3)
342  {
343  float fh, i;
344  string s;
345  fh = fopen(argv(2), FILE_READ);
346  if (fh < 0)
347  {
348  LOG_INFO("cannot open the file");
349  return;
350  }
351 
352  i = 0;
353  while ((s = fgets(fh)))
354  {
355  argc = tokenize_console(s);
356 
357  if (argc >= 3 && argv(0) == "sv_cmd" && argv(1) == "bot_cmd")
358  {
359  if (argv(2) == "reset")
360  {
361  bot_resetqueues();
362  }
363  else if (argv(2) == "setbots")
364  {
365  cvar_settemp("bot_vs_human", "0");
366  cvar_settemp("minplayers", "0");
367  cvar_settemp("minplayers_per_team", "0");
368  cvar_settemp("bot_number", "0");
369  bot_fixcount(false); // Kill all bots.
370  cvar_settemp("bot_number", argv(3));
371  if (!bot_fixcount(true)) LOG_INFO("Sorry, could not set requested bot count");
372  }
373  else
374  {
375  if(argv(2) == "*" || argv(2) == "all")
378  });
379  else
380  {
381  bot = find_bot_by_number(stof(argv(2)));
382  if (bot == NULL) bot = find_bot_by_name(argv(2));
383  if (bot) bot_queuecommand(bot, substring(s, argv_start_index(3), -1));
384  }
385  }
386  }
387  else
388  {
389  localcmd(strcat(s, "\n"));
390  }
391 
392  ++i;
393  }
394  LOG_INFO(ftos(i), " commands read");
395  fclose(fh);
396  return;
397  }
398  else if (argv(1) == "help")
399  {
400  if (argv(2)) bot_cmdhelp(argv(2));
401  else bot_list_commands();
402  return;
403  }
404  else if (argc >= 3) // this comes last
405  {
406  if(argv(1) == "*" || argv(1) == "all")
407  {
408  int bot_num = 0;
410  bot_queuecommand(it, substring(command, argv_start_index(2), -1));
411  bot_num++;
412  });
413  if(bot_num)
414  LOG_INFO("Command '", substring(command, argv_start_index(2), -1), "' sent to all bots (", ftos(bot_num), ")");
415  return;
416  }
417  else
418  {
419  bot = find_bot_by_number(stof(argv(1)));
420  if (bot == NULL) bot = find_bot_by_name(argv(1));
421  if (bot)
422  {
423  LOG_INFO("Command '", substring(command, argv_start_index(2), -1), "' sent to bot ", bot.netname);
424  bot_queuecommand(bot, substring(command, argv_start_index(2), -1));
425  return;
426  }
427  else
428  {
429  LOG_INFO("Error: Can't find bot with the name or id '", argv(1), "' - Did you mistype the command?"); // don't return so that usage is shown
430  }
431  }
432  }
433  }
434 
435  default:
436  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
437  case CMD_REQUEST_USAGE:
438  {
439  LOG_HELP("Usage:^3 sv_cmd bot_cmd <client> <command> [<arguments>]");
440  LOG_HELP(" <client> can be either the name of the bot or a progressive number (not the entity number!)");
441  LOG_HELP(" can also be '*' or 'all' to allow sending the command to all the bots");
442  LOG_HELP(" For full list of commands, see bot_cmd help [<command>].");
443  LOG_HELP("Examples: sv_cmd bot_cmd 1 cc \"say something\"");
444  LOG_HELP(" sv_cmd bot_cmd 1 presskey jump");
445  LOG_HELP(" sv_cmd bot_cmd * pause");
446  return;
447  }
448  }
449 }
450 
451 void GameCommand_cointoss(int request, int argc)
452 {
453  switch (request)
454  {
455  case CMD_REQUEST_COMMAND:
456  {
457  string result1 = (argv(2) ? strcat("^7", argv(1)) : "^1HEADS");
458  string result2 = (argv(2) ? strcat("^7", argv(2)) : "^4TAILS");
459  string choice = ((random() > 0.5) ? result1 : result2);
460 
461  Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, MULTI_COINTOSS, choice);
462  return;
463  }
464 
465  default:
466  case CMD_REQUEST_USAGE:
467  {
468  LOG_HELP("Usage:^3 sv_cmd cointoss [<result1> <result2>]");
469  LOG_HELP(" Where <result1> and <result2> are user created options.");
470  return;
471  }
472  }
473 }
474 
475 void GameCommand_database(int request, int argc)
476 {
477  switch (request)
478  {
479  case CMD_REQUEST_COMMAND:
480  {
481  if (argc == 3)
482  {
483  if (argv(1) == "save")
484  {
486  LOG_INFO("Copied serverprogs database to '", argv(2), "' in the data directory.");
487  return;
488  }
489  else if (argv(1) == "dump")
490  {
492  LOG_INFO("DB dumped."); // wtf does this do?
493  return;
494  }
495  else if (argv(1) == "load")
496  {
498  ServerProgsDB = db_load(argv(2));
499  LOG_INFO("Loaded '", argv(2), "' as new serverprogs database.");
500  return;
501  }
502  }
503  }
504 
505  default:
506  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
507  case CMD_REQUEST_USAGE:
508  {
509  LOG_HELP("Usage:^3 sv_cmd database <action> <filename>");
510  LOG_HELP(" Where <action> is the command to complete,");
511  LOG_HELP(" and <filename> is what it acts upon.");
512  LOG_HELP(" Full list of commands here: save, dump, load.");
513  return;
514  }
515  }
516 }
517 
518 void GameCommand_defer_clear(int request, int argc)
519 {
520  switch (request)
521  {
522  case CMD_REQUEST_COMMAND:
523  {
524  entity client;
525  float accepted;
526 
527  if (argc >= 2)
528  {
529  client = GetIndexedEntity(argc, 1);
530  accepted = VerifyClientEntity(client, true, false);
531 
532  if (accepted > 0)
533  {
534  stuffcmd(client, "defer clear\n");
535  LOG_INFO("defer clear stuffed to ", playername(client.netname, client.team, false));
536  }
537  else { LOG_INFO("defer_clear: ", GetClientErrorString(accepted, argv(1)), "."); }
538 
539  return;
540  }
541  }
542 
543  default:
544  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
545  case CMD_REQUEST_USAGE:
546  {
547  LOG_HELP("Usage:^3 sv_cmd defer_clear <client>");
548  LOG_HELP(" <client> is the entity number or name of the player.");
549  LOG_HELP("See also: ^2defer_clear_all^7");
550  return;
551  }
552  }
553 }
554 
556 {
557  switch (request)
558  {
559  case CMD_REQUEST_COMMAND:
560  {
561  int n = 0;
562  int argc;
563 
564  FOREACH_CLIENT(true, {
565  argc = tokenize_console(strcat("defer_clear ", ftos(etof(it))));
567  ++n;
568  });
569  if (n) LOG_INFO("Successfully stuffed defer clear to all clients (", ftos(n), ")"); // should a message be added if no players were found?
570  return;
571  }
572 
573  default:
574  case CMD_REQUEST_USAGE:
575  {
576  LOG_HELP("Usage:^3 sv_cmd defer_clear_all");
577  LOG_HELP(" No arguments required.");
578  LOG_HELP("See also: ^2defer_clear^7");
579  return;
580  }
581  }
582 }
583 
584 void GameCommand_delrec(int request, int argc) // perhaps merge later with records and printstats and such?
585 {
586  switch (request)
587  {
588  case CMD_REQUEST_COMMAND:
589  {
590  if (argv(1))
591  {
592  if (argv(2)) race_deleteTime(argv(2), stof(argv(1)));
593  else race_deleteTime(GetMapname(), stof(argv(1)));
594  return;
595  }
596  }
597 
598  default:
599  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
600  case CMD_REQUEST_USAGE:
601  {
602  LOG_HELP("Usage:^3 sv_cmd delrec <ranking> [<map>]");
603  LOG_HELP(" <ranking> is which ranking level to clear up to, ");
604  LOG_HELP(" it will clear all records up to nth place.");
605  LOG_HELP(" if <map> is not provided it will use current map.");
606  return;
607  }
608  }
609 }
610 
611 void print_Effect_Index(int d, string effect_name)
612 {
613  // this is inside a function to avoid expanding it on compilation everytime
614  LOG_INFO("effect ", effect_name, " is ", ftos(_particleeffectnum(effect_name)), "\n");
615  db_put(d, effect_name, "1");
616 }
617 
619 {
620  switch (request)
621  {
622  case CMD_REQUEST_COMMAND:
623  {
624  float fh, d;
625  string s;
626 
627  d = db_create();
628  LOG_INFO("begin of effects list");
629 
630  print_Effect_Index(d, "TE_GUNSHOT");
631  print_Effect_Index(d, "TE_GUNSHOTQUAD");
632  print_Effect_Index(d, "TE_SPIKE");
633  print_Effect_Index(d, "TE_SPIKEQUAD");
634  print_Effect_Index(d, "TE_SUPERSPIKE");
635  print_Effect_Index(d, "TE_SUPERSPIKEQUAD");
636  print_Effect_Index(d, "TE_WIZSPIKE");
637  print_Effect_Index(d, "TE_KNIGHTSPIKE");
638  print_Effect_Index(d, "TE_EXPLOSION");
639  print_Effect_Index(d, "TE_EXPLOSIONQUAD");
640  print_Effect_Index(d, "TE_TAREXPLOSION");
641  print_Effect_Index(d, "TE_TELEPORT");
642  print_Effect_Index(d, "TE_LAVASPLASH");
643  print_Effect_Index(d, "TE_SMALLFLASH");
644  print_Effect_Index(d, "TE_FLAMEJET");
645  print_Effect_Index(d, "EF_FLAME");
646  print_Effect_Index(d, "TE_BLOOD");
647  print_Effect_Index(d, "TE_SPARK");
648  print_Effect_Index(d, "TE_PLASMABURN");
649  print_Effect_Index(d, "TE_TEI_G3");
650  print_Effect_Index(d, "TE_TEI_SMOKE");
651  print_Effect_Index(d, "TE_TEI_BIGEXPLOSION");
652  print_Effect_Index(d, "TE_TEI_PLASMAHIT");
653  print_Effect_Index(d, "EF_STARDUST");
654  print_Effect_Index(d, "TR_ROCKET");
655  print_Effect_Index(d, "TR_GRENADE");
656  print_Effect_Index(d, "TR_BLOOD");
657  print_Effect_Index(d, "TR_WIZSPIKE");
658  print_Effect_Index(d, "TR_SLIGHTBLOOD");
659  print_Effect_Index(d, "TR_KNIGHTSPIKE");
660  print_Effect_Index(d, "TR_VORESPIKE");
661  print_Effect_Index(d, "TR_NEHAHRASMOKE");
662  print_Effect_Index(d, "TR_NEXUIZPLASMA");
663  print_Effect_Index(d, "TR_GLOWTRAIL");
664  print_Effect_Index(d, "TR_SEEKER");
665  print_Effect_Index(d, "SVC_PARTICLE");
666 
667  fh = fopen("effectinfo.txt", FILE_READ);
668  while ((s = fgets(fh)))
669  {
670  tokenize_console(s);
671  if (argv(0) == "effect")
672  {
673  if (db_get(d, argv(1)) != "1")
674  {
675  int i = _particleeffectnum(argv(1));
676  if (i >= 0) LOG_INFO("effect ", argv(1), " is ", ftos(i));
677  db_put(d, argv(1), "1");
678  }
679  }
680  }
681  LOG_INFO("end of effects list");
682 
683  db_close(d);
684  return;
685  }
686 
687  default:
688  case CMD_REQUEST_USAGE:
689  {
690  LOG_HELP("Usage:^3 sv_cmd effectindexdump");
691  LOG_HELP(" No arguments required.");
692  return;
693  }
694  }
695 }
696 
698 {
699  switch (request)
700  {
701  case CMD_REQUEST_COMMAND:
702  {
704  return;
705  }
706 
707  default:
708  case CMD_REQUEST_USAGE:
709  {
710  LOG_HELP("Usage:^3 sv_cmd extendmatchtime");
711  LOG_HELP(" No arguments required.");
712  LOG_HELP("See also: ^2reducematchtime^7");
713  return;
714  }
715  }
716 }
717 
718 void GameCommand_gametype(int request, int argc)
719 {
720  switch (request)
721  {
722  case CMD_REQUEST_COMMAND:
723  {
724  if (!world_initialized)
725  {
726  LOG_INFOF("This command works only when the server is running.");
727  return;
728  }
729  if (argv(1) != "")
730  {
731  string s = argv(1);
733 
734  if (t)
735  {
738  if (MapInfo_count > 0)
739  {
740  // update lsmaps in case the gametype changed, this way people can easily list maps for it
741  if (lsmaps_reply != "") strunzone(lsmaps_reply);
742  lsmaps_reply = strzone(getlsmaps());
743  bprint("Game type successfully switched to ", s, "\n");
744  }
745  else
746  {
747  bprint("Cannot use this game type: no map for it found\n");
748  MapInfo_SwitchGameType(tsave);
750  }
751  }
752  else
753  {
754  bprint("Failed to switch to ", s, ": this game type does not exist!\n");
755  }
756 
757  return;
758  }
759  }
760 
761  default:
762  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
763  case CMD_REQUEST_USAGE:
764  {
765  LOG_HELP("Usage:^3 sv_cmd gametype <mode>");
766  LOG_HELP(" Where <mode> is the gametype mode to switch to.");
767  LOG_HELP("See also: ^2gotomap^7");
768  return;
769  }
770  }
771 }
772 
773 void GameCommand_gettaginfo(int request, int argc)
774 {
775  switch (request)
776  {
777  case CMD_REQUEST_COMMAND:
778  {
779  entity tmp_entity;
780  float i;
781  vector v;
782 
783  if (argc >= 4)
784  {
785  tmp_entity = spawn();
786  if (argv(1) == "w")
787  {
788  .entity weaponentity = weaponentities[0];
789  _setmodel(tmp_entity, (nextent(NULL)).(weaponentity).model);
790  }
791  else
792  {
793  precache_model(argv(1));
794  _setmodel(tmp_entity, argv(1));
795  }
796  tmp_entity.frame = stof(argv(2));
797  if (substring(argv(3), 0, 1) == "#") i = stof(substring(argv(3), 1, -1));
798  else i = gettagindex(tmp_entity, argv(3));
799  if (i)
800  {
801  v = gettaginfo(tmp_entity, i);
802  LOG_HELPF("model %s frame %s tag %s index %s parent %s",
803  tmp_entity.model, ftos(tmp_entity.frame), gettaginfo_name, ftos(i), ftos(gettaginfo_parent)
804  );
805  LOG_HELPF(" vector = %s %s %s", ftos(v.x), ftos(v.y), ftos(v.z));
806  LOG_HELPF(" offset = %s %s %s", ftos(gettaginfo_offset.x), ftos(gettaginfo_offset.y), ftos(gettaginfo_offset.z));
808  LOG_HELPF(" right = %s %s %s", ftos(gettaginfo_right.x), ftos(gettaginfo_right.y), ftos(gettaginfo_right.z));
809  LOG_HELPF(" up = %s %s %s", ftos(gettaginfo_up.x), ftos(gettaginfo_up.y), ftos(gettaginfo_up.z));
810  if (argc >= 6)
811  {
812  v.y = -v.y;
813  localcmd(strcat(argv(4), vtos(v), argv(5), "\n"));
814  }
815  }
816  else
817  {
818  LOG_INFO("bone not found");
819  }
820 
821  delete(tmp_entity);
822  return;
823  }
824  }
825 
826  default:
827  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
828  case CMD_REQUEST_USAGE:
829  {
830  LOG_HELP("Usage:^3 sv_cmd gettaginfo <model> <frame> <index> [<command1>] [<command2>]");
831  LOG_HELP("See also: ^2bbox, trace^7");
832  return;
833  }
834  }
835 }
836 
837 void GameCommand_animbench(int request, int argc)
838 {
839  switch (request)
840  {
841  case CMD_REQUEST_COMMAND:
842  {
843  entity tmp_entity;
844 
845  if (argc >= 4)
846  {
847  tmp_entity = spawn();
848  if (argv(1) == "w")
849  {
850  .entity weaponentity = weaponentities[0];
851  _setmodel(tmp_entity, (nextent(NULL)).(weaponentity).model);
852  }
853  else
854  {
855  precache_model(argv(1));
856  _setmodel(tmp_entity, argv(1));
857  }
858  float f1 = stof(argv(2));
859  float f2 = stof(argv(3));
860  float t0;
861  float t1 = 0;
862  float t2 = 0;
863  float n = 0;
864 
865  while (t1 + t2 < 1)
866  {
867  tmp_entity.frame = f1;
868  t0 = gettime(GETTIME_HIRES);
869  getsurfacepoint(tmp_entity, 0, 0);
870  t1 += gettime(GETTIME_HIRES) - t0;
871  tmp_entity.frame = f2;
872  t0 = gettime(GETTIME_HIRES);
873  getsurfacepoint(tmp_entity, 0, 0);
874  t2 += gettime(GETTIME_HIRES) - t0;
875  n += 1;
876  }
877  LOG_INFO("model ", tmp_entity.model, " frame ", ftos(f1), " animtime ", ftos(n / t1), "/s");
878  LOG_INFO("model ", tmp_entity.model, " frame ", ftos(f2), " animtime ", ftos(n / t2), "/s");
879 
880  delete(tmp_entity);
881  return;
882  }
883  }
884 
885  default:
886  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
887  case CMD_REQUEST_USAGE:
888  {
889  LOG_HELP("Usage:^3 sv_cmd animbench <model> <frame1> <frame2>");
890  LOG_HELP("See also: ^2bbox, trace^7");
891  return;
892  }
893  }
894 }
895 
896 void GameCommand_gotomap(int request, int argc)
897 {
898  switch (request)
899  {
900  case CMD_REQUEST_COMMAND:
901  {
902  if (!world_initialized)
903  {
904  LOG_INFOF("This command works only when the server is running.");
905  return;
906  }
907  if (argv(1))
908  {
909  LOG_INFO(GotoMap(argv(1)));
910  return;
911  }
912  }
913 
914  default:
915  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
916  case CMD_REQUEST_USAGE:
917  {
918  LOG_HELP("Usage:^3 sv_cmd gotomap <map>");
919  LOG_HELP(" Where <map> is the *.bsp file to change to.");
920  LOG_HELP("See also: ^2gametype^7");
921  return;
922  }
923  }
924 }
925 
926 void GameCommand_lockteams(int request)
927 {
928  switch (request)
929  {
930  case CMD_REQUEST_COMMAND:
931  {
932  if (teamplay)
933  {
934  lockteams = 1;
935  bprint("^1The teams are now locked.\n");
936  }
937  else
938  {
939  bprint("lockteams command can only be used in a team-based gamemode.\n");
940  }
941  return;
942  }
943 
944  default:
945  case CMD_REQUEST_USAGE:
946  {
947  LOG_HELP("Usage:^3 sv_cmd lockteams");
948  LOG_HELP(" No arguments required.");
949  LOG_HELP("See also: ^2unlockteams^7");
950  return;
951  }
952  }
953 }
954 
955 void GameCommand_make_mapinfo(int request)
956 {
957  switch (request)
958  {
959  case CMD_REQUEST_COMMAND:
960  {
961  entity tmp_entity;
962 
963  tmp_entity = new(make_mapinfo);
964  setthink(tmp_entity, make_mapinfo_Think);
965  tmp_entity.nextthink = time;
967  return;
968  }
969 
970  default:
971  case CMD_REQUEST_USAGE:
972  {
973  LOG_HELP("Usage:^3 sv_cmd make_mapinfo");
974  LOG_HELP(" No arguments required.");
975  LOG_HELP("See also: ^2radarmap^7");
976  return;
977  }
978  }
979 }
980 
981 void GameCommand_moveplayer(int request, int argc)
982 {
983  switch (request)
984  {
985  case CMD_REQUEST_COMMAND:
986  {
987  float accepted;
988  entity client;
989 
990  string targets = strreplace(",", " ", argv(1));
991  string original_targets = strreplace(" ", ", ", targets);
992  string destination = argv(2);
993  if (destination == "spec")
994  destination = "spectator";
995 
996  if ((targets) && (destination))
997  {
998  string successful = string_null;
999  string t;
1000  for ( ; targets; )
1001  {
1002  t = car(targets);
1003  targets = cdr(targets);
1004 
1005  // Check to see if the player is a valid target
1006  client = GetFilteredEntity(t);
1007  accepted = VerifyClientEntity(client, false, false);
1008  string client_num_str = ftos(etof(client));
1009 
1010  if (accepted <= 0)
1011  {
1012  LOG_INFO("moveplayer: ", GetClientErrorString(accepted, t), ".");
1013  }
1014  else if (destination == "spectator")
1015  {
1016  string pl_name = playername(client.netname, client.team, false);
1017  if (!IS_SPEC(client) && !IS_OBSERVER(client))
1018  {
1019  PutObserverInServer(client, true, true);
1020 
1021  successful = strcat(successful, (successful ? ", " : ""), pl_name);
1022  }
1023  else
1024  {
1025  LOG_INFO("Player #", client_num_str, " (", pl_name, ") is already spectating.");
1026  }
1027  }
1028  else
1029  {
1030  if (!teamplay)
1031  {
1032  LOG_INFO("Can't change teams when currently not playing a team game.");
1033  return;
1034  }
1035 
1036  string pl_name = playername(client.netname, client.team, false);
1037  if (IS_SPEC(client) || IS_OBSERVER(client))
1038  {
1039  // well technically we could, but should we allow that? :P
1040  LOG_INFO("Player #", client_num_str, " (", pl_name, ") is not in the game.");
1041  continue;
1042  }
1043 
1044  // set up
1045  int save = Player_GetForcedTeamIndex(client);
1047 
1048  // find the team to move the player to
1049  int team_num = Team_ColorToTeam(destination);
1050  entity balance;
1051  if (team_num == client.team) // already on the destination team
1052  {
1053  // keep the forcing undone
1054  LOG_INFO("Player #", client_num_str, " (", pl_name, ") is already on the ", Team_ColoredFullName(team_num), "^7.");
1055  continue;
1056  }
1057  else if (team_num == 0) // auto team
1058  {
1059  balance = TeamBalance_CheckAllowedTeams(client);
1060  team_num = Team_IndexToTeam(TeamBalance_FindBestTeam(balance, client, false));
1061  }
1062  else
1063  {
1064  balance = TeamBalance_CheckAllowedTeams(client);
1065  }
1066  Player_SetForcedTeamIndex(client, save);
1067 
1068  // Check to see if the destination team is even available
1069  int team_id = Team_TeamToIndex(team_num);
1070  if (team_id == -1)
1071  {
1072  LOG_INFO("Can't move player to ", destination, " team because it doesn't exist.");
1073  TeamBalance_Destroy(balance);
1074  return;
1075  }
1076  if (!IsTeamAvailable(team_num))
1077  {
1078  LOG_INFO("Can't move player to ", destination, " team because it isn't available.");
1079  TeamBalance_Destroy(balance);
1080  return;
1081  }
1082  if (!TeamBalance_IsTeamAllowed(balance, team_id))
1083  {
1084  LOG_INFO("Player #", client_num_str, " (", pl_name, ") is not allowed to join the ", Team_ColoredFullName(team_num), "^7.");
1085  TeamBalance_Destroy(balance);
1086  continue;
1087  }
1088  TeamBalance_Destroy(balance);
1089 
1090  // If so, lets continue and finally move the player
1092  if (MoveToTeam(client, team_id, 6))
1093  {
1094  successful = strcat(successful, (successful ? ", " : ""), pl_name);
1095  LOG_INFO("Player #", client_num_str, " (", pl_name, ") has been moved to the ", Team_ColoredFullName(team_num), "^7.");
1096  }
1097  else
1098  {
1099  LOG_INFO("Unable to move player #", client_num_str, " (", pl_name, ")");
1100  }
1101  }
1102  } // loop end
1103 
1104  if (successful) bprint("Successfully moved players ", successful, " to destination ", destination, ".\n");
1105  else LOG_INFO("No players given (", original_targets, ") are able to move.");
1106 
1107  return; // still correct parameters so return to avoid usage print
1108  }
1109  }
1110 
1111  default:
1112  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
1113  case CMD_REQUEST_USAGE:
1114  {
1115  LOG_HELP("Usage:^3 sv_cmd moveplayer <clients> <destination>");
1116  LOG_HELP(" <clients> is a list (separated by commas) of player entity ID's or nicknames");
1117  LOG_HELP(" <destination> is what to send the player to, be it team or spectating");
1118  LOG_HELP(" Full list of destinations here: spec, spectator, red, blue, yellow, pink, auto.");
1119  LOG_HELP("Examples: sv_cmd moveplayer 1,3,5 red");
1120  LOG_HELP(" sv_cmd moveplayer 2 spec");
1121  LOG_HELP("See also: ^2allspec, shuffleteams^7");
1122  return;
1123  }
1124  }
1125 }
1126 
1127 void GameCommand_nospectators(int request)
1128 {
1129  switch (request)
1130  {
1131  case CMD_REQUEST_COMMAND:
1132  {
1133  blockSpectators = 1;
1134  // give every spectator <g_maxplayers_spectator_blocktime> seconds time to become a player
1135  FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)) && !INGAME(it), {
1136  CS(it).spectatortime = time;
1137  Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
1138  });
1139  bprint(strcat("^7All spectators will be automatically kicked when not joining the game after ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds!\n"));
1140  return;
1141  }
1142 
1143  default:
1144  case CMD_REQUEST_USAGE:
1145  {
1146  LOG_HELP("Usage:^3 sv_cmd nospectators");
1147  LOG_HELP(" No arguments required.");
1148  return;
1149  }
1150  }
1151 }
1152 
1153 void GameCommand_printstats(int request)
1154 {
1155  switch (request)
1156  {
1157  case CMD_REQUEST_COMMAND:
1158  {
1159  DumpStats(false);
1160  LOG_INFO("stats dumped.");
1161  return;
1162  }
1163 
1164  default:
1165  case CMD_REQUEST_USAGE:
1166  {
1167  LOG_HELP("Usage:^3 sv_cmd printstats");
1168  LOG_HELP(" No arguments required.");
1169  return;
1170  }
1171  }
1172 }
1173 
1174 void GameCommand_radarmap(int request, int argc)
1175 {
1176  switch (request)
1177  {
1178  case CMD_REQUEST_COMMAND:
1179  {
1180  if (RadarMap_Make(argc)) return;
1181  }
1182 
1183  default:
1184  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
1185  case CMD_REQUEST_USAGE:
1186  {
1187  LOG_HELP("Usage:^3 sv_cmd radarmap [--force] [--loop] [--quit] [--block | --trace | --sample | --lineblock] [--sharpen N] [--res W H] [--qual Q]");
1188  LOG_HELP(" The quality factor Q is roughly proportional to the time taken.");
1189  LOG_HELP(" trace supports no quality factor; its result should look like --block with infinite quality factor.");
1190  LOG_HELP("See also: ^2make_mapinfo^7");
1191  return;
1192  }
1193  }
1194 }
1195 
1197 {
1198  switch (request)
1199  {
1200  case CMD_REQUEST_COMMAND:
1201  {
1203  return;
1204  }
1205 
1206  default:
1207  case CMD_REQUEST_USAGE:
1208  {
1209  LOG_HELP("Usage:^3 sv_cmd reducematchtime");
1210  LOG_HELP(" No arguments required.");
1211  LOG_HELP("See also: ^2extendmatchtime^7");
1212  return;
1213  }
1214  }
1215 }
1216 
1217 void GameCommand_setbots(int request, int argc)
1218 {
1219  switch (request)
1220  {
1221  case CMD_REQUEST_COMMAND:
1222  {
1223  if (argc >= 2)
1224  {
1225  cvar_settemp("minplayers", "0");
1226  cvar_settemp("minplayers_per_team", "0");
1227  cvar_settemp("bot_number", argv(1));
1228  bot_fixcount(true);
1229  return;
1230  }
1231  }
1232 
1233  default:
1234  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
1235  case CMD_REQUEST_USAGE:
1236  {
1237  LOG_HELP("Usage:^3 sv_cmd setbots <botnumber>");
1238  LOG_HELP(" Where <botnumber> is the amount of bots to set bot_number cvar to.");
1239  LOG_HELP("See also: ^2bot_cmd^7");
1240  return;
1241  }
1242  }
1243 }
1244 
1246 {
1247  if (!teamplay)
1248  {
1249  LOG_INFO("Can't shuffle teams when currently not playing a team game.");
1250  return;
1251  }
1252 
1253  FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), {
1254  if (Player_HasRealForcedTeam(it)) {
1255  // we could theoretically assign forced players to their teams
1256  // and shuffle the rest to fill the empty spots but in practise
1257  // either all players or none are gonna have forced teams
1258  LOG_INFO("Can't shuffle teams because at least one player has a forced team.");
1259  return;
1260  }
1261  });
1262 
1263  int number_of_teams = 0;
1265  for (int i = 1; i <= NUM_TEAMS; ++i)
1266  {
1267  if (TeamBalance_IsTeamAllowed(balance, i))
1268  {
1269  number_of_teams = max(i, number_of_teams);
1270  }
1271  }
1272  TeamBalance_Destroy(balance);
1273 
1274  int team_index = 0;
1275  FOREACH_CLIENT_RANDOM(IS_PLAYER(it) || INGAME(it), {
1276  int target_team_index = team_index + 1;
1277  if (Entity_GetTeamIndex(it) != target_team_index)
1278  {
1279  MoveToTeam(it, target_team_index, 6);
1280  }
1281  team_index = (team_index + 1) % number_of_teams;
1282  });
1283 
1284  bprint("Successfully shuffled the players around randomly.\n");
1285 }
1286 
1287 void GameCommand_shuffleteams(int request)
1288 {
1289  switch (request)
1290  {
1291  case CMD_REQUEST_COMMAND:
1292  {
1294  {
1295  bprint("Players will be shuffled when this round is over.\n");
1297  }
1298  else
1299  shuffleteams();
1300  return;
1301  }
1302 
1303  default:
1304  case CMD_REQUEST_USAGE:
1305  {
1306  LOG_HELP("Usage:^3 sv_cmd shuffleteams");
1307  LOG_HELP(" No arguments required.");
1308  LOG_HELP("See also: ^2moveplayer, allspec^7");
1309  return;
1310  }
1311  }
1312 }
1313 
1314 void GameCommand_resetmatch(int request)
1315 {
1316  switch (request)
1317  {
1318  case CMD_REQUEST_COMMAND:
1319  {
1320  ReadyRestart(false);
1321  return;
1322  }
1323 
1324  default:
1325  case CMD_REQUEST_USAGE:
1326  {
1327  LOG_HELP("Usage:^3 sv_cmd resetmatch");
1328  LOG_HELP(" No arguments required.");
1329  return;
1330  }
1331  }
1332 }
1333 
1334 void GameCommand_stuffto(int request, int argc)
1335 {
1336  // This... is a fairly dangerous and powerful command... - It allows any arguments to be sent to a client via rcon.
1337  // Because of this, it is disabled by default and must be enabled by the server owner when doing compilation. That way,
1338  // we can be certain they understand the risks of it... So to enable, compile server with -DSTUFFTO_ENABLED argument.
1339 
1340 #ifdef STUFFTO_ENABLED
1341  switch (request)
1342  {
1343  case CMD_REQUEST_COMMAND:
1344  {
1345  if (argv(2))
1346  {
1347  entity client = GetIndexedEntity(argc, 1);
1348  float accepted = VerifyClientEntity(client, true, false);
1349 
1350  if (accepted > 0)
1351  {
1352  stuffcmd(client, strcat("\n", argv(next_token), "\n"));
1353  LOG_INFO("Command: \"", argv(next_token), "\" sent to ", GetCallerName(client), " (", argv(1), ").");
1354  }
1355  else
1356  {
1357  LOG_INFO("stuffto: ", GetClientErrorString(accepted, argv(1)), ".");
1358  }
1359 
1360  return;
1361  }
1362  }
1363 
1364  default:
1365  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
1366  case CMD_REQUEST_USAGE:
1367  {
1368  LOG_HELP("Usage:^3 sv_cmd stuffto <client> \"<command>\"");
1369  LOG_HELP(" <client> is the entity number or name of the player,");
1370  LOG_HELP(" and <command> is the command to be sent to that player.");
1371  return;
1372  }
1373  }
1374 #else
1375  if (request)
1376  {
1377  LOG_HELP("stuffto command is not enabled on this server.");
1378  return;
1379  }
1380 #endif
1381 }
1382 
1383 void GameCommand_trace(int request, int argc)
1384 {
1385  switch (request)
1386  {
1387  case CMD_REQUEST_COMMAND:
1388  {
1389  entity e;
1390  vector org, delta, start, end, p, q, q0, pos, vv, dv;
1391  float i, f, safe, unsafe, dq, dqf;
1392 
1393  switch (argv(1))
1394  {
1395  case "debug":
1396  {
1397  float hitcount = 0;
1398  LOG_INFO("TEST CASE. If this returns the runaway loop counter error, possibly everything is oaky.");
1399  float worst_endpos_bug = 0;
1400  for ( ; ; )
1401  {
1402  org = world.mins;
1403  delta = world.maxs - world.mins;
1404 
1405  start.x = org.x + random() * delta.x;
1406  start.y = org.y + random() * delta.y;
1407  start.z = org.z + random() * delta.z;
1408 
1409  end.x = org.x + random() * delta.x;
1410  end.y = org.y + random() * delta.y;
1411  end.z = org.z + random() * delta.z;
1412 
1413  start = stov(vtos(start));
1414  end = stov(vtos(end));
1415 
1416  tracebox(start, PL_MIN_CONST, PL_MAX_CONST, end, MOVE_NOMONSTERS, NULL);
1417  if (!trace_startsolid && trace_fraction < 1)
1418  {
1419  p = trace_endpos;
1420  tracebox(p, PL_MIN_CONST, PL_MAX_CONST, p, MOVE_NOMONSTERS, NULL);
1421  if (trace_startsolid)
1422  {
1423  rint(42); // do an engine breakpoint on VM_rint so you can get the trace that errnoeously returns startsolid
1424  tracebox(start, PL_MIN_CONST, PL_MAX_CONST, end, MOVE_NOMONSTERS, NULL);
1425 
1426  // how much do we need to back off?
1427  safe = 1;
1428  unsafe = 0;
1429  for ( ; ; )
1430  {
1431  pos = p * (1 - (safe + unsafe) * 0.5) + start * ((safe + unsafe) * 0.5);
1432  tracebox(pos, PL_MIN_CONST, PL_MAX_CONST, pos, MOVE_NOMONSTERS, NULL);
1433  if (trace_startsolid)
1434  {
1435  if ((safe + unsafe) * 0.5 == unsafe) break;
1436  unsafe = (safe + unsafe) * 0.5;
1437  }
1438  else
1439  {
1440  if ((safe + unsafe) * 0.5 == safe) break;
1441  safe = (safe + unsafe) * 0.5;
1442  }
1443  }
1444 
1445  LOG_INFO("safe distance to back off: ", ftos(safe * vlen(p - start)), "qu");
1446  LOG_INFO("unsafe distance to back off: ", ftos(unsafe * vlen(p - start)), "qu");
1447 
1448  tracebox(p, PL_MIN_CONST + '0.1 0.1 0.1', PL_MAX_CONST - '0.1 0.1 0.1', p, MOVE_NOMONSTERS, NULL);
1449  if (trace_startsolid) LOG_INFO("trace_endpos much in solid when tracing from ", vtos(start), " to ", vtos(end), " endpos ", vtos(p));
1450  else LOG_INFO("trace_endpos just in solid when tracing from ", vtos(start), " to ", vtos(end), " endpos ", vtos(p));
1451  if (++hitcount >= 10) break;
1452  }
1453  else
1454  {
1455  q0 = p;
1456  dq = 0;
1457  dqf = 1;
1458  for ( ; ; )
1459  {
1460  q = p + normalize(end - p) * (dq + dqf);
1461  if (q == q0) break;
1462  tracebox(p, PL_MIN_CONST, PL_MAX_CONST, q, MOVE_NOMONSTERS, NULL);
1463  if (trace_startsolid) error("THIS ONE cannot happen");
1464  if (trace_fraction > 0) dq += dqf * trace_fraction;
1465  dqf *= 0.5;
1466  q0 = q;
1467  }
1468  if (dq > worst_endpos_bug)
1469  {
1470  worst_endpos_bug = dq;
1471  LOG_INFO("trace_endpos still before solid when tracing from ", vtos(start), " to ", vtos(end), " endpos ", vtos(p));
1472  LOG_INFO("could go ", ftos(dq), " units further to ", vtos(q));
1473  if (++hitcount >= 10) break;
1474  }
1475  }
1476  }
1477  }
1478  return;
1479  }
1480 
1481  case "debug2":
1482  {
1483  e = nextent(NULL);
1484  tracebox(e.origin + '0 0 32', e.mins, e.maxs, e.origin + '0 0 -1024', MOVE_NORMAL, e);
1485  vv = trace_endpos;
1486  if (trace_fraction == 1)
1487  {
1488  LOG_INFO("not above ground, aborting");
1489  return;
1490  }
1491  f = 0;
1492  for (i = 0; i < 100000; ++i)
1493  {
1494  dv = randomvec();
1495  if (dv.z > 0) dv = -1 * dv;
1496  tracebox(vv, e.mins, e.maxs, vv + dv, MOVE_NORMAL, e);
1497  if (trace_startsolid) LOG_INFO("bug 1");
1498  if (trace_fraction == 1)
1499  {
1500  if (dv.z < f)
1501  {
1502  LOG_INFO("bug 2: ", ftos(dv.x), " ", ftos(dv.y), " ", ftos(dv.z));
1503  LOG_INFO(" (", ftos(asin(dv.z / vlen(dv)) * 180 / M_PI), " degrees)");
1504  f = dv.z;
1505  }
1506  }
1507  }
1508  LOG_INFO("highest possible dist: ", ftos(f));
1509  return;
1510  }
1511 
1512  case "walk":
1513  {
1514  if (argc == 4 || argc == 5)
1515  {
1516  e = nextent(NULL);
1517  int dphitcontentsmask_save = e.dphitcontentsmask;
1519  if (tracewalk(e, stov(argv(2)), e.mins, e.maxs, stov(argv(3)), stof(argv(4)), MOVE_NORMAL))
1520  LOG_INFO("can walk");
1521  else
1522  LOG_INFO("cannot walk");
1523  e.dphitcontentsmask = dphitcontentsmask_save;
1524  return;
1525  }
1526  }
1527 
1528  case "showline":
1529  {
1530  if (argc == 4)
1531  {
1532  vv = stov(argv(2));
1533  dv = stov(argv(3));
1534  traceline(vv, dv, MOVE_NORMAL, NULL);
1535  __trailparticles(NULL, particleeffectnum(EFFECT_TR_NEXUIZPLASMA), vv, trace_endpos);
1536  __trailparticles(NULL, particleeffectnum(EFFECT_TR_CRYLINKPLASMA), trace_endpos, dv);
1537  return;
1538  }
1539  }
1540 
1541  // no default case, just go straight to invalid
1542  }
1543  }
1544 
1545  default:
1546  LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
1547  case CMD_REQUEST_USAGE:
1548  {
1549  LOG_HELP("Usage:^3 sv_cmd trace <command> [<startpos> <endpos>] [<endpos_height>]");
1550  LOG_HELP(" Where <startpos> and <endpos> are parameters for the 'walk' and 'showline' commands,");
1551  LOG_HELP(" <endpos_height> is an optional parameter for the 'walk' command,");
1552  LOG_HELP(" Full list of commands here: debug, debug2, walk, showline.");
1553  LOG_HELP("See also: ^2bbox, gettaginfo^7");
1554  return;
1555  }
1556  }
1557 }
1558 
1559 void GameCommand_unlockteams(int request)
1560 {
1561  switch (request)
1562  {
1563  case CMD_REQUEST_COMMAND:
1564  {
1565  if (teamplay)
1566  {
1567  lockteams = 0;
1568  bprint("^1The teams are now unlocked.\n");
1569  }
1570  else
1571  {
1572  bprint("unlockteams command can only be used in a team-based gamemode.\n");
1573  }
1574  return;
1575  }
1576 
1577  default:
1578  case CMD_REQUEST_USAGE:
1579  {
1580  LOG_HELP("Usage:^3 sv_cmd unlockteams");
1581  LOG_HELP(" No arguments required.");
1582  LOG_HELP("See also: ^2lockteams^7");
1583  return;
1584  }
1585  }
1586 }
1587 
1588 void GameCommand_warp(int request, int argc)
1589 {
1590  switch (request)
1591  {
1592  case CMD_REQUEST_COMMAND:
1593  {
1594  if (autocvar_g_campaign)
1595  {
1596  if (argc >= 2)
1597  {
1599  LOG_INFO("Successfully warped to campaign level ", argv(1), ".");
1600  }
1601  else
1602  {
1603  CampaignLevelWarp(-1);
1604  LOG_INFO("Successfully warped to next campaign level.");
1605  }
1606  }
1607  else
1608  {
1609  LOG_INFO("Not in campaign, can't level warp");
1610  }
1611  return;
1612  }
1613 
1614  default:
1615  case CMD_REQUEST_USAGE:
1616  {
1617  LOG_HELP("Usage:^3 sv_cmd warp [<level>]");
1618  LOG_HELP(" <level> is the level to change campaign mode to.");
1619  LOG_HELP(" if <level> is not provided it will change to the next level.");
1620  return;
1621  }
1622  }
1623 }
1624 
1625 /* use this when creating a new command, making sure to place it in alphabetical order... also,
1626 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
1627 void GameCommand_(int request)
1628 {
1629  switch(request)
1630  {
1631  case CMD_REQUEST_COMMAND:
1632  {
1633 
1634  return;
1635  }
1636 
1637  default:
1638  case CMD_REQUEST_USAGE:
1639  {
1640  LOG_HELP("Usage:^3 sv_cmd ");
1641  LOG_HELP(" No arguments required.");
1642  return;
1643  }
1644  }
1645 }
1646 */
1647 
1648 
1649 // ==================================
1650 // Macro system for server commands
1651 // ==================================
1652 
1653 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
1654 SERVER_COMMAND(adminmsg, "Send an admin message to a client directly") { GameCommand_adminmsg(request, arguments); }
1655 SERVER_COMMAND(allready, "Ends warmup and starts the match") { GameCommand_allready(request); }
1656 SERVER_COMMAND(allspec, "Force all players to spectate") { GameCommand_allspec(request, arguments); }
1657 SERVER_COMMAND(anticheat, "Create an anticheat report for a client") { GameCommand_anticheat(request, arguments); }
1658 SERVER_COMMAND(animbench, "Benchmark model animation (LAGS)") { GameCommand_animbench(request, arguments); }
1659 SERVER_COMMAND(bbox, "Print detailed information about world size") { GameCommand_bbox(request); }
1660 SERVER_COMMAND(bot_cmd, "Control and send commands to bots") { GameCommand_bot_cmd(request, arguments, command); }
1661 SERVER_COMMAND(cointoss, "Flip a virtual coin and give random result") { GameCommand_cointoss(request, arguments); }
1662 SERVER_COMMAND(database, "Extra controls of the serverprogs database") { GameCommand_database(request, arguments); }
1663 SERVER_COMMAND(defer_clear, "Clear all queued defer commands for a specific client") { GameCommand_defer_clear(request, arguments); }
1664 SERVER_COMMAND(defer_clear_all, "Clear all queued defer commands for all clients") { GameCommand_defer_clear_all(request); }
1665 SERVER_COMMAND(delrec, "Delete race time record for a map") { GameCommand_delrec(request, arguments); }
1666 SERVER_COMMAND(effectindexdump, "Dump list of effects from code and effectinfo.txt") { GameCommand_effectindexdump(request); }
1667 SERVER_COMMAND(extendmatchtime, "Increase the timelimit value incrementally") { GameCommand_extendmatchtime(request); }
1668 SERVER_COMMAND(gametype, "Simple command to change the active gametype") { GameCommand_gametype(request, arguments); }
1669 SERVER_COMMAND(gettaginfo, "Get specific information about a weapon model") { GameCommand_gettaginfo(request, arguments); }
1670 SERVER_COMMAND(gotomap, "Simple command to switch to another map") { GameCommand_gotomap(request, arguments); }
1671 SERVER_COMMAND(lockteams, "Disable the ability for players to switch or enter teams") { GameCommand_lockteams(request); }
1672 SERVER_COMMAND(make_mapinfo, "Automatically rebuild mapinfo files") { GameCommand_make_mapinfo(request); }
1673 SERVER_COMMAND(moveplayer, "Change the team/status of a player") { GameCommand_moveplayer(request, arguments); }
1674 SERVER_COMMAND(nospectators, "Automatically remove spectators from a match") { GameCommand_nospectators(request); }
1675 SERVER_COMMAND(printstats, "Dump eventlog player stats and other score information") { GameCommand_printstats(request); }
1676 SERVER_COMMAND(radarmap, "Generate a radar image of the map") { GameCommand_radarmap(request, arguments); }
1677 SERVER_COMMAND(reducematchtime, "Decrease the timelimit value incrementally") { GameCommand_reducematchtime(request); }
1678 SERVER_COMMAND(resetmatch, "Soft restart the game without changing teams; goes back to warmup if enabled") { GameCommand_resetmatch(request); }
1679 SERVER_COMMAND(setbots, "Adjust how many bots are in the match") { GameCommand_setbots(request, arguments); }
1680 SERVER_COMMAND(shuffleteams, "Randomly move players to different teams") { GameCommand_shuffleteams(request); }
1681 SERVER_COMMAND(stuffto, "Send a command to be executed on a client") { GameCommand_stuffto(request, arguments); }
1682 SERVER_COMMAND(trace, "Various debugging tools with tracing") { GameCommand_trace(request, arguments); }
1683 SERVER_COMMAND(unlockteams, "Enable the ability for players to switch or enter teams") { GameCommand_unlockteams(request); }
1684 SERVER_COMMAND(warp, "Choose different level in campaign") { GameCommand_warp(request, arguments); }
1685 
1687 {
1688  FOREACH(SERVER_COMMANDS, true, { LOG_HELPF(" ^2%s^7: %s", it.m_name, it.m_description); });
1689 }
1690 
1691 float GameCommand_macro_command(int argc, string command)
1692 {
1693  string c = strtolower(argv(0));
1694  FOREACH(SERVER_COMMANDS, it.m_name == c, {
1695  it.m_invokecmd(it, CMD_REQUEST_COMMAND, NULL, argc, command);
1696  return true;
1697  });
1698  return false;
1699 }
1700 
1702 {
1703  string c = strtolower(argv(1));
1704  FOREACH(SERVER_COMMANDS, it.m_name == c, {
1705  it.m_invokecmd(it, CMD_REQUEST_USAGE, NULL, argc, "");
1706  return true;
1707  });
1708  return false;
1709 }
1710 
1712 {
1713  FOREACH(SERVER_COMMANDS, true, { CMD_Write_Alias("qc_cmd_sv", it.m_name, it.m_description); });
1714 }
1715 
1716 
1717 // =========================================
1718 // Main Function Called By Engine (sv_cmd)
1719 // =========================================
1720 // If this function exists, game code handles gamecommand instead of the engine code.
1721 
1722 void GameCommand(string command)
1723 {
1724  int argc = tokenize_console(command);
1725 
1726  // Guide for working with argc arguments by example:
1727  // argc: 1 - 2 - 3 - 4
1728  // argv: 0 - 1 - 2 - 3
1729  // cmd vote - master - login - password
1730 
1731  if (strtolower(argv(0)) == "help")
1732  {
1733  if (argc == 1)
1734  {
1735  LOG_HELP("Server console commands:");
1737 
1738  LOG_HELP("\nBanning commands:");
1740 
1741  LOG_HELP("\nCommon networked commands:");
1743 
1744  LOG_HELP("\nGeneric commands shared by all programs:");
1746 
1747  LOG_HELP("\nUsage:^3 sv_cmd <command>^7, where possible commands are listed above.\n"
1748  "For help about a specific command, type sv_cmd help <command>");
1749 
1750  return;
1751  }
1752  else if (BanCommand_macro_usage(argc)) // Instead of trying to call a command, we're going to see detailed information about it
1753  {
1754  return;
1755  }
1756  else if (CommonCommand_macro_usage(argc, NULL)) // same here, but for common commands instead
1757  {
1758  return;
1759  }
1760  else if (GenericCommand_macro_usage(argc)) // same here, but for generic commands instead
1761  {
1762  return;
1763  }
1764  else if (GameCommand_macro_usage(argc)) // finally try for normal commands too
1765  {
1766  return;
1767  }
1768  }
1769  else if (MUTATOR_CALLHOOK(SV_ParseServerCommand, strtolower(argv(0)), argc, command))
1770  {
1771  return; // handled by a mutator
1772  }
1773  else if (BanCommand(command))
1774  {
1775  return; // handled by server/command/ipban.qc
1776  }
1777  else if (CommonCommand_macro_command(argc, NULL, command))
1778  {
1779  return; // handled by server/command/common.qc
1780  }
1781  else if (GenericCommand(command))
1782  {
1783  return; // handled by common/command/generic.qc
1784  }
1785  else if (GameCommand_macro_command(argc, command)) // continue as usual and scan for normal commands
1786  {
1787  return; // handled by one of the above GameCommand_* functions
1788  }
1789 
1790  // nothing above caught the command, must be invalid
1791  LOG_INFO(((command != "") ? strcat("Unknown server command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try sv_cmd help.");
1792 }
#define INGAME(it)
Definition: sv_rules.qh:20
const int NUM_TEAMS
Number of teams in the game.
Definition: teams.qh:3
void GameCommand_allready(int request)
Definition: sv_cmd.qc:159
float gettaginfo_parent
#define LOG_HELPF(...)
Definition: log.qh:96
void GameCommand_macro_write_aliases(float fh)
Definition: sv_cmd.qc:1711
int MapInfo_RequiredFlags()
Definition: mapinfo.qc:1339
ERASEABLE int db_create()
Definition: map.qh:25
ERASEABLE void db_put(int db, string key, string value)
Definition: map.qh:101
void GameCommand_gettaginfo(int request, int argc)
Definition: sv_cmd.qc:773
string gettaginfo_name
bool MoveToTeam(entity client, int team_index, int type)
Moves player to the specified team.
Definition: teamplay.qc:327
void GameCommand_bbox(int request)
Definition: sv_cmd.qc:244
entity GetIndexedEntity(int argc, float start_index)
Definition: common.qc:83
string string_null
Definition: nil.qh:9
entity world
Definition: csprogsdefs.qc:15
void GameCommand_macro_help()
Definition: sv_cmd.qc:1686
void GameCommand_animbench(int request, int argc)
Definition: sv_cmd.qc:837
float CommonCommand_macro_usage(int argc, entity caller)
Definition: common.qh:178
void print_Effect_Index(int d, string effect_name)
Definition: sv_cmd.qc:611
void GameCommand_gametype(int request, int argc)
Definition: sv_cmd.qc:718
void GameCommand_printstats(int request)
Definition: sv_cmd.qc:1153
ERASEABLE int db_load(string filename)
Definition: map.qh:35
void changematchtime(float delta, float mi, float ma)
Definition: sv_cmd.qc:47
float blockSpectators
Definition: client.qh:334
float cvar_settemp(string tmp_cvar, string tmp_value)
Definition: util.qc:696
vector gettaginfo_offset
const int CMD_REQUEST_USAGE
Definition: command.qh:4
string GetMapname()
Definition: intermission.qc:18
int MAPINFO_TYPE_ALL
Definition: mapinfo.qh:26
void TeamBalance_Destroy(entity balance)
Destroy the team balance entity.
Definition: teamplay.qc:627
vector gettaginfo_up
void bot_cmdhelp(string scmd)
Definition: scripting.qc:331
float ServerProgsDB
Definition: world.qh:131
entity() spawn
void anticheat_report_to_eventlog(entity this)
Definition: anticheat.qc:195
float GenericCommand(string command)
Definition: generic.qc:582
void CommonCommand_macro_help(entity caller)
Definition: common.qh:163
void GameCommand(string command)
Definition: sv_cmd.qc:1722
float BanCommand_macro_usage(int argc)
Definition: banning.qc:296
const float MOVE_NORMAL
Definition: csprogsdefs.qc:252
void GameCommand_stuffto(int request, int argc)
Definition: sv_cmd.qc:1334
ClientState CS(Client this)
Definition: state.qh:47
#define FOREACH_CLIENT(cond, body)
Definition: utils.qh:49
entity find_bot_by_name(string name)
Definition: scripting.qc:235
ERASEABLE string cdr(string s)
returns all but first word
Definition: string.qh:249
#define IS_OBSERVER(v)
Definition: utils.qh:11
void GameCommand_defer_clear_all(int request)
Definition: sv_cmd.qc:555
ERASEABLE void db_close(int db)
Definition: map.qh:84
float VerifyClientEntity(entity client, float must_be_real, float must_be_bots)
Definition: common.qc:47
float DPCONTENTS_BOTCLIP
bool warmup_stage
Definition: main.qh:103
const float FILE_READ
Definition: csprogsdefs.qc:231
ERASEABLE string MakeConsoleSafe(string input)
escape the string to make it safe for consoles
Definition: cvar.qh:24
int world_initialized
Definition: world.qh:39
float DPCONTENTS_PLAYERCLIP
void GameCommand_adminmsg(int request, int argc)
Definition: sv_cmd.qc:87
int MapInfo_ForbiddenFlags()
Definition: mapinfo.qc:1324
#define gettaginfo
Definition: post.qh:32
bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float end_height, float movemode)
Definition: navigation.qc:273
int Entity_GetTeamIndex(entity this)
Returns the team index of the given entity.
Definition: teamplay.qc:176
void GameCommand_nospectators(int request)
Definition: sv_cmd.qc:1127
ERASEABLE string car(string s)
returns first word
Definition: string.qh:240
#define LOG_HELP(...)
Definition: log.qh:95
string model
Definition: csprogsdefs.qc:108
void shuffleteams()
Definition: sv_cmd.qc:1245
#define gettagindex
Definition: dpextensions.qh:16
entity GetFilteredEntity(string input)
Definition: common.qc:144
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1
Definition: all.inc:654
float autocvar_timelimit_max
Definition: world.qh:26
void GameCommand_reducematchtime(int request)
Definition: sv_cmd.qc:1196
#define IS_REAL_CLIENT(v)
Definition: utils.qh:17
void bot_list_commands()
Definition: scripting.qc:444
float next_token
Definition: common.qh:71
void GenericCommand_macro_help()
Definition: generic.qc:546
entity find_bot_by_number(float number)
Definition: scripting.qc:246
void GameCommand_radarmap(int request, int argc)
Definition: sv_cmd.qc:1174
void GameCommand_make_mapinfo(int request)
Definition: sv_cmd.qc:955
#define IS_SPEC(v)
Definition: utils.qh:10
void GameCommand_resetmatch(int request)
Definition: sv_cmd.qc:1314
float MapInfo_count
Definition: mapinfo.qh:144
Gametype MapInfo_Type_FromString(string gtype, bool dowarn)
Definition: mapinfo.qc:589
void race_deleteTime(string map, float pos)
Definition: race.qc:452
Gametype MapInfo_CurrentGametype()
Definition: mapinfo.qc:1150
const float MOVE_NOMONSTERS
Definition: csprogsdefs.qc:253
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1 f1points f2
Definition: all.inc:348
bool IsTeamAvailable(int team_num)
Definition: scores_rules.qc:12
vector gettaginfo_right
int Player_GetForcedTeamIndex(entity player)
Returns the index of the forced team of the given player.
Definition: teamplay.qc:346
int MapInfo_CurrentFeatures()
Definition: mapinfo.qc:1140
void GameCommand_gotomap(int request, int argc)
Definition: sv_cmd.qc:896
float GenericCommand_macro_usage(int argc)
Definition: generic.qc:561
#define LOG_INFOF(...)
Definition: log.qh:71
void GameCommand_extendmatchtime(int request)
Definition: sv_cmd.qc:697
#define argv_start_index
Definition: dpextensions.qh:27
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
entity bot_cmd
Definition: scripting.qh:59
void Player_SetForcedTeamIndex(entity player, int team_index)
Sets the index of the forced team of the given player.
Definition: teamplay.qc:351
int TeamBalance_FindBestTeam(entity balance, entity player, bool ignore_player)
Finds the team that will make the game most balanced if the player joins it.
Definition: teamplay.qc:783
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
putting a client as observer in the server
Definition: client.qc:238
float GameCommand_macro_command(int argc, string command)
Definition: sv_cmd.qc:1691
void GameCommand_warp(int request, int argc)
Definition: sv_cmd.qc:1588
ERASEABLE void db_save(int db, string filename)
Definition: map.qh:8
ERASEABLE void db_dump(int db, string filename)
Definition: map.qh:69
#define NULL
Definition: post.qh:17
const int CMD_REQUEST_COMMAND
Definition: command.qh:3
#define CMD_Write_Alias(execute, command, description)
Definition: generic.qh:34
#define LOG_INFO(...)
Definition: log.qh:70
void GameCommand_lockteams(int request)
Definition: sv_cmd.qc:926
float DPCONTENTS_SOLID
entity gametype
Definition: main.qh:30
void GameCommand_unlockteams(int request)
Definition: sv_cmd.qc:1559
vector trace_endpos
Definition: csprogsdefs.qc:37
ERASEABLE string db_get(int db, string key)
Definition: map.qh:91
void GameCommand_bot_cmd(int request, int argc, string command)
Definition: sv_cmd.qc:317
void DumpStats(float final)
Definition: world.qc:1170
string GetCallerName(entity caller)
Definition: common.qc:33
float teamplay
Definition: progsdefs.qc:31
float GameCommand_macro_usage(int argc)
Definition: sv_cmd.qc:1701
float nextthink
Definition: csprogsdefs.qc:121
bool lockteams
Definition: teamplay.qh:13
float BanCommand(string command)
Definition: banning.qc:316
#define GetClientErrorString(clienterror, original_input)
Definition: common.qh:87
void GameCommand_delrec(int request, int argc)
Definition: sv_cmd.qc:584
int Team_TeamToIndex(int team_num)
Converts team value into team index.
Definition: teams.qh:184
#define stuffcmd(cl,...)
Definition: progsdefs.qh:23
vector(float skel, float bonenum) _skel_get_boneabs_hidden
float GETTIME_HIRES
#define tokenize_console
Definition: dpextensions.qh:24
const float M_PI
Definition: csprogsdefs.qc:269
void ReadyRestart(bool forceWarmupEnd)
Definition: vote.qc:484
float Team_ColorToTeam(string team_color)
Definition: teams.qh:116
bool shuffleteams_on_reset_map
Definition: sv_cmd.qh:7
vector v
Definition: ent_cs.qc:116
void GameCommand_anticheat(int request, int argc)
Definition: sv_cmd.qc:213
float DPCONTENTS_BODY
bool TeamBalance_IsTeamAllowed(entity balance, int index)
Returns whether the team change to the specified team is allowed.
Definition: teamplay.qc:662
Don&#39;t force any team.
Definition: teamplay.qh:138
#define LOG_TRACE(...)
Definition: log.qh:81
void GameCommand_effectindexdump(int request)
Definition: sv_cmd.qc:618
float autocvar_g_maxplayers_spectator_blocktime
Definition: client.qh:44
void CampaignLevelWarp(float n)
Definition: campaign.qc:266
void GameCommand_trace(int request, int argc)
Definition: sv_cmd.qc:1383
float autocvar_timelimit_increment
Definition: world.qh:23
#define FOREACH_CLIENT_RANDOM(cond, body)
Definition: utils.qh:55
#define MUTATOR_CALLHOOK(id,...)
Definition: base.qh:140
void BanCommand_macro_help()
Definition: banning.qc:276
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition: utils.qh:15
entity weaponentities[MAX_WEAPONSLOTS]
Definition: weapon.qh:14
bool Player_HasRealForcedTeam(entity player)
Returns whether player has real forced team.
Definition: teamplay.qc:341
#define setthink(e, f)
bool RadarMap_Make(int argc)
Definition: radarmap.qh:3
int Team_IndexToTeam(int index)
Converts team index into team value.
Definition: teams.qh:169
void GameCommand_allspec(int request, int argc)
Definition: sv_cmd.qc:185
void GameCommand_defer_clear(int request, int argc)
Definition: sv_cmd.qc:518
bool autocvar_g_campaign
Definition: campaign.qh:6
float trace_startsolid
Definition: csprogsdefs.qc:35
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings...
Definition: teamplay.qc:487
string GotoMap(string m)
void bot_queuecommand(entity bot, string cmdstring)
Definition: scripting.qc:30
void bot_resetqueues()
Definition: scripting.qc:1165
void GameCommand_shuffleteams(int request)
Definition: sv_cmd.qc:1287
float _MapInfo_FilterGametype(int pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
Definition: mapinfo.qc:162
float MOVE_WORLDONLY
SERVER_COMMAND(adminmsg, "Send an admin message to a client directly")
Definition: sv_cmd.qc:1654
float MapInfo_FilterGametype(Gametype pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
Definition: mapinfo.qc:158
float time
Definition: csprogsdefs.qc:16
void MapInfo_Enumerate()
Definition: mapinfo.qc:115
#define Team_ColoredFullName(teamid)
Definition: teams.qh:230
void GameCommand_database(int request, int argc)
Definition: sv_cmd.qc:475
void GameCommand_moveplayer(int request, int argc)
Definition: sv_cmd.qc:981
string getlsmaps()
Definition: getreplies.qc:253
void MapInfo_SwitchGameType(Gametype t)
Definition: mapinfo.qc:1178
float trace_fraction
Definition: csprogsdefs.qc:36
#define FOREACH(list, cond, body)
Definition: iter.qh:19
bool bot_fixcount(bool multiple_per_frame)
Definition: bot.qc:591
void GameCommand_setbots(int request, int argc)
Definition: sv_cmd.qc:1217
float autocvar_timelimit_min
Definition: world.qh:25
#define IS_PLAYER(v)
Definition: utils.qh:9
vector gettaginfo_forward
void GameCommand_cointoss(int request, int argc)
Definition: sv_cmd.qc:451
float CommonCommand_macro_command(int argc, entity caller, string command)
Definition: common.qh:168
void make_mapinfo_Think(entity this)
Definition: sv_cmd.qc:31
#define particleeffectnum(e)
Definition: effect.qh:3
float autocvar_timelimit_decrement
Definition: world.qh:24