1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "qwsvdef.h"
22
23 qboolean sv_allow_cheats;
24
25 int fp_messages=4, fp_persecond=4, fp_secondsdead=10;
26 char fp_msg[255] = { 0 };
27 extern cvar_t cl_warncmd;
28 extern redirect_t sv_redirected;
29
30
31 /*
32 ===============================================================================
33
34 OPERATOR CONSOLE ONLY COMMANDS
35
36 These commands can only be entered from stdin or by a remote operator datagram
37 ===============================================================================
38 */
39
40 /*
41 ====================
42 SV_SetMaster_f
43
44 Make a master server current
45 ====================
46 */
SV_SetMaster_f(void)47 void SV_SetMaster_f (void)
48 {
49 char data[2];
50 int i;
51
52 memset (&master_adr, 0, sizeof(master_adr));
53
54 for (i=1 ; i<Cmd_Argc() ; i++)
55 {
56 if (!strcmp(Cmd_Argv(i), "none") || !NET_StringToAdr (Cmd_Argv(i), &master_adr[i-1]))
57 {
58 Con_Printf ("Setting nomaster mode.\n");
59 return;
60 }
61 if (master_adr[i-1].port == 0)
62 master_adr[i-1].port = BigShort (27000);
63
64 Con_Printf ("Master server at %s\n", NET_AdrToString (master_adr[i-1]));
65
66 Con_Printf ("Sending a ping.\n");
67
68 data[0] = A2A_PING;
69 data[1] = 0;
70 NET_SendPacket (2, data, master_adr[i-1]);
71 }
72
73 svs.last_heartbeat = -99999;
74 }
75
76
77 /*
78 ==================
79 SV_Quit_f
80 ==================
81 */
SV_Quit_f(void)82 void SV_Quit_f (void)
83 {
84 SV_FinalMessage ("server shutdown\n");
85 Con_Printf ("Shutting down.\n");
86 SV_Shutdown ();
87 Sys_Quit ();
88 }
89
90 /*
91 ============
92 SV_Logfile_f
93 ============
94 */
SV_Logfile_f(void)95 void SV_Logfile_f (void)
96 {
97 char name[MAX_OSPATH];
98
99 if (sv_logfile)
100 {
101 Con_Printf ("File logging off.\n");
102 fclose (sv_logfile);
103 sv_logfile = NULL;
104 return;
105 }
106
107 sprintf (name, "%s/qconsole.log", com_gamedir);
108 Con_Printf ("Logging text to %s.\n", name);
109 sv_logfile = fopen (name, "w");
110 if (!sv_logfile)
111 Con_Printf ("failed.\n");
112 }
113
114
115 /*
116 ============
117 SV_Fraglogfile_f
118 ============
119 */
SV_Fraglogfile_f(void)120 void SV_Fraglogfile_f (void)
121 {
122 char name[MAX_OSPATH];
123 int i;
124
125 if (sv_fraglogfile)
126 {
127 Con_Printf ("Frag file logging off.\n");
128 fclose (sv_fraglogfile);
129 sv_fraglogfile = NULL;
130 return;
131 }
132
133 // find an unused name
134 for (i=0 ; i<1000 ; i++)
135 {
136 sprintf (name, "%s/frag_%i.log", com_gamedir, i);
137 sv_fraglogfile = fopen (name, "r");
138 if (!sv_fraglogfile)
139 { // can't read it, so create this one
140 sv_fraglogfile = fopen (name, "w");
141 if (!sv_fraglogfile)
142 i=1000; // give error
143 break;
144 }
145 fclose (sv_fraglogfile);
146 }
147 if (i==1000)
148 {
149 Con_Printf ("Can't open any logfiles.\n");
150 sv_fraglogfile = NULL;
151 return;
152 }
153
154 Con_Printf ("Logging frags to %s.\n", name);
155 }
156
157
158 /*
159 ==================
160 SV_SetPlayer
161
162 Sets host_client and sv_player to the player with idnum Cmd_Argv(1)
163 ==================
164 */
SV_SetPlayer(void)165 qboolean SV_SetPlayer (void)
166 {
167 client_t *cl;
168 int i;
169 int idnum;
170
171 idnum = atoi(Cmd_Argv(1));
172
173 for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
174 {
175 if (!cl->state)
176 continue;
177 if (cl->userid == idnum)
178 {
179 host_client = cl;
180 sv_player = host_client->edict;
181 return true;
182 }
183 }
184 Con_Printf ("Userid %i is not on the server\n", idnum);
185 return false;
186 }
187
188
189 /*
190 ==================
191 SV_God_f
192
193 Sets client to godmode
194 ==================
195 */
SV_God_f(void)196 void SV_God_f (void)
197 {
198 if (!sv_allow_cheats)
199 {
200 Con_Printf ("You must run the server with -cheats to enable this command.\n");
201 return;
202 }
203
204 if (!SV_SetPlayer ())
205 return;
206
207 sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE;
208 if (!((int)sv_player->v.flags & FL_GODMODE) )
209 SV_ClientPrintf (host_client, PRINT_HIGH, "godmode OFF\n");
210 else
211 SV_ClientPrintf (host_client, PRINT_HIGH, "godmode ON\n");
212 }
213
214
SV_Noclip_f(void)215 void SV_Noclip_f (void)
216 {
217 if (!sv_allow_cheats)
218 {
219 Con_Printf ("You must run the server with -cheats to enable this command.\n");
220 return;
221 }
222
223 if (!SV_SetPlayer ())
224 return;
225
226 if (sv_player->v.movetype != MOVETYPE_NOCLIP)
227 {
228 sv_player->v.movetype = MOVETYPE_NOCLIP;
229 SV_ClientPrintf (host_client, PRINT_HIGH, "noclip ON\n");
230 }
231 else
232 {
233 sv_player->v.movetype = MOVETYPE_WALK;
234 SV_ClientPrintf (host_client, PRINT_HIGH, "noclip OFF\n");
235 }
236 }
237
238
239 /*
240 ==================
241 SV_Give_f
242 ==================
243 */
SV_Give_f(void)244 void SV_Give_f (void)
245 {
246 char *t;
247 int v;
248
249 if (!sv_allow_cheats)
250 {
251 Con_Printf ("You must run the server with -cheats to enable this command.\n");
252 return;
253 }
254
255 if (!SV_SetPlayer ())
256 return;
257
258 t = Cmd_Argv(2);
259 v = atoi (Cmd_Argv(3));
260
261 switch (t[0])
262 {
263 case '2':
264 case '3':
265 case '4':
266 case '5':
267 case '6':
268 case '7':
269 case '8':
270 case '9':
271 sv_player->v.items = (int)sv_player->v.items | IT_SHOTGUN<< (t[0] - '2');
272 break;
273
274 case 's':
275 sv_player->v.ammo_shells = v;
276 break;
277 case 'n':
278 sv_player->v.ammo_nails = v;
279 break;
280 case 'r':
281 sv_player->v.ammo_rockets = v;
282 break;
283 case 'h':
284 sv_player->v.health = v;
285 break;
286 case 'c':
287 sv_player->v.ammo_cells = v;
288 break;
289 }
290 }
291
292
293 /*
294 ======================
295 SV_Map_f
296
297 handle a
298 map <mapname>
299 command from the console or progs.
300 ======================
301 */
SV_Map_f(void)302 void SV_Map_f (void)
303 {
304 char level[MAX_QPATH];
305 char expanded[MAX_QPATH];
306 FILE *f;
307
308 if (Cmd_Argc() != 2)
309 {
310 Con_Printf ("map <levelname> : continue game on a new level\n");
311 return;
312 }
313 strcpy (level, Cmd_Argv(1));
314
315 #if 0
316 if (!strcmp (level, "e1m8"))
317 { // QuakeWorld can't go to e1m8
318 SV_BroadcastPrintf (PRINT_HIGH, "can't go to low grav level in QuakeWorld...\n");
319 strcpy (level, "e1m5");
320 }
321 #endif
322
323 // check to make sure the level exists
324 sprintf (expanded, "maps/%s.bsp", level);
325 COM_FOpenFile (expanded, &f);
326 if (!f)
327 {
328 Con_Printf ("Can't find %s\n", expanded);
329 return;
330 }
331 fclose (f);
332
333 SV_BroadcastCommand ("changing\n");
334 SV_SendMessagesToAll ();
335
336 SV_SpawnServer (level);
337
338 SV_BroadcastCommand ("reconnect\n");
339 }
340
341
342 /*
343 ==================
344 SV_Kick_f
345
346 Kick a user off of the server
347 ==================
348 */
SV_Kick_f(void)349 void SV_Kick_f (void)
350 {
351 int i;
352 client_t *cl;
353 int uid;
354
355 uid = atoi(Cmd_Argv(1));
356
357 for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
358 {
359 if (!cl->state)
360 continue;
361 if (cl->userid == uid)
362 {
363 SV_BroadcastPrintf (PRINT_HIGH, "%s was kicked\n", cl->name);
364 // print directly, because the dropped client won't get the
365 // SV_BroadcastPrintf message
366 SV_ClientPrintf (cl, PRINT_HIGH, "You were kicked from the game\n");
367 SV_DropClient (cl);
368 return;
369 }
370 }
371
372 Con_Printf ("Couldn't find user number %i\n", uid);
373 }
374
375
376 /*
377 ================
378 SV_Status_f
379 ================
380 */
SV_Status_f(void)381 void SV_Status_f (void)
382 {
383 int i, j, l;
384 client_t *cl;
385 float cpu, avg, pak;
386 char *s;
387
388
389 cpu = (svs.stats.latched_active+svs.stats.latched_idle);
390 if (cpu)
391 cpu = 100*svs.stats.latched_active/cpu;
392 avg = 1000*svs.stats.latched_active / STATFRAMES;
393 pak = (float)svs.stats.latched_packets/ STATFRAMES;
394
395 Con_Printf ("net address : %s\n",NET_AdrToString (net_local_adr));
396 Con_Printf ("cpu utilization : %3i%%\n",(int)cpu);
397 Con_Printf ("avg response time: %i ms\n",(int)avg);
398 Con_Printf ("packets/frame : %5.2f (%d)\n", pak, num_prstr);
399
400 // min fps lat drp
401 if (sv_redirected != RD_NONE) {
402 // most remote clients are 40 columns
403 // 0123456789012345678901234567890123456789
404 Con_Printf ("name userid frags\n");
405 Con_Printf (" address rate ping drop\n");
406 Con_Printf (" ---------------- ---- ---- -----\n");
407 for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
408 {
409 if (!cl->state)
410 continue;
411
412 Con_Printf ("%-16.16s ", cl->name);
413
414 Con_Printf ("%6i %5i", cl->userid, (int)cl->edict->v.frags);
415 if (cl->spectator)
416 Con_Printf(" (s)\n");
417 else
418 Con_Printf("\n");
419
420 s = NET_BaseAdrToString ( cl->netchan.remote_address);
421 Con_Printf (" %-16.16s", s);
422 if (cl->state == cs_connected)
423 {
424 Con_Printf ("CONNECTING\n");
425 continue;
426 }
427 if (cl->state == cs_zombie)
428 {
429 Con_Printf ("ZOMBIE\n");
430 continue;
431 }
432 Con_Printf ("%4i %4i %5.2f\n"
433 , (int)(1000*cl->netchan.frame_rate)
434 , (int)SV_CalcPing (cl)
435 , 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence);
436 }
437 } else {
438 Con_Printf ("frags userid address name rate ping drop qport\n");
439 Con_Printf ("----- ------ --------------- --------------- ---- ---- ----- -----\n");
440 for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
441 {
442 if (!cl->state)
443 continue;
444 Con_Printf ("%5i %6i ", (int)cl->edict->v.frags, cl->userid);
445
446 s = NET_BaseAdrToString ( cl->netchan.remote_address);
447 Con_Printf ("%s", s);
448 l = 16 - strlen(s);
449 for (j=0 ; j<l ; j++)
450 Con_Printf (" ");
451
452 Con_Printf ("%s", cl->name);
453 l = 16 - strlen(cl->name);
454 for (j=0 ; j<l ; j++)
455 Con_Printf (" ");
456 if (cl->state == cs_connected)
457 {
458 Con_Printf ("CONNECTING\n");
459 continue;
460 }
461 if (cl->state == cs_zombie)
462 {
463 Con_Printf ("ZOMBIE\n");
464 continue;
465 }
466 Con_Printf ("%4i %4i %3.1f %4i"
467 , (int)(1000*cl->netchan.frame_rate)
468 , (int)SV_CalcPing (cl)
469 , 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence
470 , cl->netchan.qport);
471 if (cl->spectator)
472 Con_Printf(" (s)\n");
473 else
474 Con_Printf("\n");
475
476
477 }
478 }
479 Con_Printf ("\n");
480 }
481
482 /*
483 ==================
484 SV_ConSay_f
485 ==================
486 */
SV_ConSay_f(void)487 void SV_ConSay_f(void)
488 {
489 client_t *client;
490 int j;
491 char *p;
492 char text[1024];
493
494 if (Cmd_Argc () < 2)
495 return;
496
497 Q_strcpy (text, "console: ");
498 p = Cmd_Args();
499
500 if (*p == '"')
501 {
502 p++;
503 p[Q_strlen(p)-1] = 0;
504 }
505
506 Q_strcat(text, p);
507
508 for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
509 {
510 if (client->state != cs_spawned)
511 continue;
512 SV_ClientPrintf(client, PRINT_CHAT, "%s\n", text);
513 }
514 }
515
516
517 /*
518 ==================
519 SV_Heartbeat_f
520 ==================
521 */
SV_Heartbeat_f(void)522 void SV_Heartbeat_f (void)
523 {
524 svs.last_heartbeat = -9999;
525 }
526
SV_SendServerInfoChange(char * key,char * value)527 void SV_SendServerInfoChange(char *key, char *value)
528 {
529 if (!sv.state)
530 return;
531
532 MSG_WriteByte (&sv.reliable_datagram, svc_serverinfo);
533 MSG_WriteString (&sv.reliable_datagram, key);
534 MSG_WriteString (&sv.reliable_datagram, value);
535 }
536
537 /*
538 ===========
539 SV_Serverinfo_f
540
541 Examine or change the serverinfo string
542 ===========
543 */
544 char *CopyString(char *s);
SV_Serverinfo_f(void)545 void SV_Serverinfo_f (void)
546 {
547 cvar_t *var;
548
549 if (Cmd_Argc() == 1)
550 {
551 Con_Printf ("Server info settings:\n");
552 Info_Print (svs.info);
553 return;
554 }
555
556 if (Cmd_Argc() != 3)
557 {
558 Con_Printf ("usage: serverinfo [ <key> <value> ]\n");
559 return;
560 }
561
562 if (Cmd_Argv(1)[0] == '*')
563 {
564 Con_Printf ("Star variables cannot be changed.\n");
565 return;
566 }
567 Info_SetValueForKey (svs.info, Cmd_Argv(1), Cmd_Argv(2), MAX_SERVERINFO_STRING);
568
569 // if this is a cvar, change it too
570 var = Cvar_FindVar (Cmd_Argv(1));
571 if (var)
572 {
573 Z_Free (var->string); // free the old value string
574 var->string = CopyString (Cmd_Argv(2));
575 var->value = Q_atof (var->string);
576 }
577
578 SV_SendServerInfoChange(Cmd_Argv(1), Cmd_Argv(2));
579 }
580
581
582 /*
583 ===========
584 SV_Serverinfo_f
585
586 Examine or change the serverinfo string
587 ===========
588 */
589 char *CopyString(char *s);
SV_Localinfo_f(void)590 void SV_Localinfo_f (void)
591 {
592 if (Cmd_Argc() == 1)
593 {
594 Con_Printf ("Local info settings:\n");
595 Info_Print (localinfo);
596 return;
597 }
598
599 if (Cmd_Argc() != 3)
600 {
601 Con_Printf ("usage: localinfo [ <key> <value> ]\n");
602 return;
603 }
604
605 if (Cmd_Argv(1)[0] == '*')
606 {
607 Con_Printf ("Star variables cannot be changed.\n");
608 return;
609 }
610 Info_SetValueForKey (localinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_LOCALINFO_STRING);
611 }
612
613
614 /*
615 ===========
616 SV_User_f
617
618 Examine a users info strings
619 ===========
620 */
SV_User_f(void)621 void SV_User_f (void)
622 {
623 if (Cmd_Argc() != 2)
624 {
625 Con_Printf ("Usage: info <userid>\n");
626 return;
627 }
628
629 if (!SV_SetPlayer ())
630 return;
631
632 Info_Print (host_client->userinfo);
633 }
634
635 /*
636 ================
637 SV_Gamedir
638
639 Sets the fake *gamedir to a different directory.
640 ================
641 */
SV_Gamedir(void)642 void SV_Gamedir (void)
643 {
644 char *dir;
645
646 if (Cmd_Argc() == 1)
647 {
648 Con_Printf ("Current *gamedir: %s\n", Info_ValueForKey (svs.info, "*gamedir"));
649 return;
650 }
651
652 if (Cmd_Argc() != 2)
653 {
654 Con_Printf ("Usage: sv_gamedir <newgamedir>\n");
655 return;
656 }
657
658 dir = Cmd_Argv(1);
659
660 if (strstr(dir, "..") || strstr(dir, "/")
661 || strstr(dir, "\\") || strstr(dir, ":") )
662 {
663 Con_Printf ("*Gamedir should be a single filename, not a path\n");
664 return;
665 }
666
667 Info_SetValueForStarKey (svs.info, "*gamedir", dir, MAX_SERVERINFO_STRING);
668 }
669
670 /*
671 ================
672 SV_Floodport_f
673
674 Sets the gamedir and path to a different directory.
675 ================
676 */
677
SV_Floodprot_f(void)678 void SV_Floodprot_f (void)
679 {
680 int arg1, arg2, arg3;
681
682 if (Cmd_Argc() == 1)
683 {
684 if (fp_messages) {
685 Con_Printf ("Current floodprot settings: \nAfter %d msgs per %d seconds, silence for %d seconds\n",
686 fp_messages, fp_persecond, fp_secondsdead);
687 return;
688 } else
689 Con_Printf ("No floodprots enabled.\n");
690 }
691
692 if (Cmd_Argc() != 4)
693 {
694 Con_Printf ("Usage: floodprot <# of messages> <per # of seconds> <seconds to silence>\n");
695 Con_Printf ("Use floodprotmsg to set a custom message to say to the flooder.\n");
696 return;
697 }
698
699 arg1 = atoi(Cmd_Argv(1));
700 arg2 = atoi(Cmd_Argv(2));
701 arg3 = atoi(Cmd_Argv(3));
702
703 if (arg1<=0 || arg2 <= 0 || arg3<=0) {
704 Con_Printf ("All values must be positive numbers\n");
705 return;
706 }
707
708 if (arg1 > 10) {
709 Con_Printf ("Can only track up to 10 messages.\n");
710 return;
711 }
712
713 fp_messages = arg1;
714 fp_persecond = arg2;
715 fp_secondsdead = arg3;
716 }
717
SV_Floodprotmsg_f(void)718 void SV_Floodprotmsg_f (void)
719 {
720 if (Cmd_Argc() == 1) {
721 Con_Printf("Current msg: %s\n", fp_msg);
722 return;
723 } else if (Cmd_Argc() != 2) {
724 Con_Printf("Usage: floodprotmsg \"<message>\"\n");
725 return;
726 }
727 sprintf(fp_msg, "%s", Cmd_Argv(1));
728 }
729
730 /*
731 ================
732 SV_Gamedir_f
733
734 Sets the gamedir and path to a different directory.
735 ================
736 */
737 char gamedirfile[MAX_OSPATH];
SV_Gamedir_f(void)738 void SV_Gamedir_f (void)
739 {
740 char *dir;
741
742 if (Cmd_Argc() == 1)
743 {
744 Con_Printf ("Current gamedir: %s\n", com_gamedir);
745 return;
746 }
747
748 if (Cmd_Argc() != 2)
749 {
750 Con_Printf ("Usage: gamedir <newdir>\n");
751 return;
752 }
753
754 dir = Cmd_Argv(1);
755
756 if (strstr(dir, "..") || strstr(dir, "/")
757 || strstr(dir, "\\") || strstr(dir, ":") )
758 {
759 Con_Printf ("Gamedir should be a single filename, not a path\n");
760 return;
761 }
762
763 COM_Gamedir (dir);
764 Info_SetValueForStarKey (svs.info, "*gamedir", dir, MAX_SERVERINFO_STRING);
765 }
766
767 /*
768 ================
769 SV_Snap
770 ================
771 */
SV_Snap(int uid)772 void SV_Snap (int uid)
773 {
774 client_t *cl;
775 char pcxname[80];
776 char checkname[MAX_OSPATH];
777 int i;
778
779 for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
780 {
781 if (!cl->state)
782 continue;
783 if (cl->userid == uid)
784 break;
785 }
786 if (i >= MAX_CLIENTS) {
787 Con_Printf ("userid not found\n");
788 return;
789 }
790
791 sprintf(pcxname, "%d-00.pcx", uid);
792
793 sprintf(checkname, "%s/snap", gamedirfile);
794 Sys_mkdir(gamedirfile);
795 Sys_mkdir(checkname);
796
797 for (i=0 ; i<=99 ; i++)
798 {
799 pcxname[strlen(pcxname) - 6] = i/10 + '0';
800 pcxname[strlen(pcxname) - 5] = i%10 + '0';
801 sprintf (checkname, "%s/snap/%s", gamedirfile, pcxname);
802 if (Sys_FileTime(checkname) == -1)
803 break; // file doesn't exist
804 }
805 if (i==100)
806 {
807 Con_Printf ("Snap: Couldn't create a file, clean some out.\n");
808 return;
809 }
810 strcpy(cl->uploadfn, checkname);
811
812 memcpy(&cl->snap_from, &net_from, sizeof(net_from));
813 if (sv_redirected != RD_NONE)
814 cl->remote_snap = true;
815 else
816 cl->remote_snap = false;
817
818 ClientReliableWrite_Begin (cl, svc_stufftext, 24);
819 ClientReliableWrite_String (cl, "cmd snap");
820 Con_Printf ("Requesting snap from user %d...\n", uid);
821 }
822
823 /*
824 ================
825 SV_Snap_f
826 ================
827 */
SV_Snap_f(void)828 void SV_Snap_f (void)
829 {
830 int uid;
831
832 if (Cmd_Argc() != 2)
833 {
834 Con_Printf ("Usage: snap <userid>\n");
835 return;
836 }
837
838 uid = atoi(Cmd_Argv(1));
839
840 SV_Snap(uid);
841 }
842
843 /*
844 ================
845 SV_Snap
846 ================
847 */
SV_SnapAll_f(void)848 void SV_SnapAll_f (void)
849 {
850 client_t *cl;
851 int i;
852
853 for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
854 {
855 if (cl->state < cs_connected || cl->spectator)
856 continue;
857 SV_Snap(cl->userid);
858 }
859 }
860
861 /*
862 ==================
863 SV_InitOperatorCommands
864 ==================
865 */
SV_InitOperatorCommands(void)866 void SV_InitOperatorCommands (void)
867 {
868 if (COM_CheckParm ("-cheats"))
869 {
870 sv_allow_cheats = true;
871 Info_SetValueForStarKey (svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING);
872 }
873
874 Cmd_AddCommand ("logfile", SV_Logfile_f);
875 Cmd_AddCommand ("fraglogfile", SV_Fraglogfile_f);
876
877 Cmd_AddCommand ("snap", SV_Snap_f);
878 Cmd_AddCommand ("snapall", SV_SnapAll_f);
879 Cmd_AddCommand ("kick", SV_Kick_f);
880 Cmd_AddCommand ("status", SV_Status_f);
881
882 Cmd_AddCommand ("map", SV_Map_f);
883 Cmd_AddCommand ("setmaster", SV_SetMaster_f);
884
885 Cmd_AddCommand ("say", SV_ConSay_f);
886 Cmd_AddCommand ("heartbeat", SV_Heartbeat_f);
887 Cmd_AddCommand ("quit", SV_Quit_f);
888 Cmd_AddCommand ("god", SV_God_f);
889 Cmd_AddCommand ("give", SV_Give_f);
890 Cmd_AddCommand ("noclip", SV_Noclip_f);
891 Cmd_AddCommand ("serverinfo", SV_Serverinfo_f);
892 Cmd_AddCommand ("localinfo", SV_Localinfo_f);
893 Cmd_AddCommand ("user", SV_User_f);
894 Cmd_AddCommand ("gamedir", SV_Gamedir_f);
895 Cmd_AddCommand ("sv_gamedir", SV_Gamedir);
896 Cmd_AddCommand ("floodprot", SV_Floodprot_f);
897 Cmd_AddCommand ("floodprotmsg", SV_Floodprotmsg_f);
898
899 cl_warncmd.value = 1;
900 }
901