aboutsummaryrefslogtreecommitdiffstats
path: root/QW/server/sv_ccmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'QW/server/sv_ccmds.c')
-rw-r--r--QW/server/sv_ccmds.c900
1 files changed, 900 insertions, 0 deletions
diff --git a/QW/server/sv_ccmds.c b/QW/server/sv_ccmds.c
new file mode 100644
index 0000000..14cec5d
--- /dev/null
+++ b/QW/server/sv_ccmds.c
@@ -0,0 +1,900 @@
+/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "qwsvdef.h"
+
+qboolean sv_allow_cheats;
+
+int fp_messages=4, fp_persecond=4, fp_secondsdead=10;
+char fp_msg[255] = { 0 };
+extern cvar_t cl_warncmd;
+ extern redirect_t sv_redirected;
+
+
+/*
+===============================================================================
+
+OPERATOR CONSOLE ONLY COMMANDS
+
+These commands can only be entered from stdin or by a remote operator datagram
+===============================================================================
+*/
+
+/*
+====================
+SV_SetMaster_f
+
+Make a master server current
+====================
+*/
+void SV_SetMaster_f (void)
+{
+ char data[2];
+ int i;
+
+ memset (&master_adr, 0, sizeof(master_adr));
+
+ for (i=1 ; i<Cmd_Argc() ; i++)
+ {
+ if (!strcmp(Cmd_Argv(i), "none") || !NET_StringToAdr (Cmd_Argv(i), &master_adr[i-1]))
+ {
+ Con_Printf ("Setting nomaster mode.\n");
+ return;
+ }
+ if (master_adr[i-1].port == 0)
+ master_adr[i-1].port = BigShort (27000);
+
+ Con_Printf ("Master server at %s\n", NET_AdrToString (master_adr[i-1]));
+
+ Con_Printf ("Sending a ping.\n");
+
+ data[0] = A2A_PING;
+ data[1] = 0;
+ NET_SendPacket (2, data, master_adr[i-1]);
+ }
+
+ svs.last_heartbeat = -99999;
+}
+
+
+/*
+==================
+SV_Quit_f
+==================
+*/
+void SV_Quit_f (void)
+{
+ SV_FinalMessage ("server shutdown\n");
+ Con_Printf ("Shutting down.\n");
+ SV_Shutdown ();
+ Sys_Quit ();
+}
+
+/*
+============
+SV_Logfile_f
+============
+*/
+void SV_Logfile_f (void)
+{
+ char name[MAX_OSPATH];
+
+ if (sv_logfile)
+ {
+ Con_Printf ("File logging off.\n");
+ fclose (sv_logfile);
+ sv_logfile = NULL;
+ return;
+ }
+
+ sprintf (name, "%s/qconsole.log", com_gamedir);
+ Con_Printf ("Logging text to %s.\n", name);
+ sv_logfile = fopen (name, "w");
+ if (!sv_logfile)
+ Con_Printf ("failed.\n");
+}
+
+
+/*
+============
+SV_Fraglogfile_f
+============
+*/
+void SV_Fraglogfile_f (void)
+{
+ char name[MAX_OSPATH];
+ int i;
+
+ if (sv_fraglogfile)
+ {
+ Con_Printf ("Frag file logging off.\n");
+ fclose (sv_fraglogfile);
+ sv_fraglogfile = NULL;
+ return;
+ }
+
+ // find an unused name
+ for (i=0 ; i<1000 ; i++)
+ {
+ sprintf (name, "%s/frag_%i.log", com_gamedir, i);
+ sv_fraglogfile = fopen (name, "r");
+ if (!sv_fraglogfile)
+ { // can't read it, so create this one
+ sv_fraglogfile = fopen (name, "w");
+ if (!sv_fraglogfile)
+ i=1000; // give error
+ break;
+ }
+ fclose (sv_fraglogfile);
+ }
+ if (i==1000)
+ {
+ Con_Printf ("Can't open any logfiles.\n");
+ sv_fraglogfile = NULL;
+ return;
+ }
+
+ Con_Printf ("Logging frags to %s.\n", name);
+}
+
+
+/*
+==================
+SV_SetPlayer
+
+Sets host_client and sv_player to the player with idnum Cmd_Argv(1)
+==================
+*/
+qboolean SV_SetPlayer (void)
+{
+ client_t *cl;
+ int i;
+ int idnum;
+
+ idnum = atoi(Cmd_Argv(1));
+
+ for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
+ {
+ if (!cl->state)
+ continue;
+ if (cl->userid == idnum)
+ {
+ host_client = cl;
+ sv_player = host_client->edict;
+ return true;
+ }
+ }
+ Con_Printf ("Userid %i is not on the server\n", idnum);
+ return false;
+}
+
+
+/*
+==================
+SV_God_f
+
+Sets client to godmode
+==================
+*/
+void SV_God_f (void)
+{
+ if (!sv_allow_cheats)
+ {
+ Con_Printf ("You must run the server with -cheats to enable this command.\n");
+ return;
+ }
+
+ if (!SV_SetPlayer ())
+ return;
+
+ sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE;
+ if (!((int)sv_player->v.flags & FL_GODMODE) )
+ SV_ClientPrintf (host_client, PRINT_HIGH, "godmode OFF\n");
+ else
+ SV_ClientPrintf (host_client, PRINT_HIGH, "godmode ON\n");
+}
+
+
+void SV_Noclip_f (void)
+{
+ if (!sv_allow_cheats)
+ {
+ Con_Printf ("You must run the server with -cheats to enable this command.\n");
+ return;
+ }
+
+ if (!SV_SetPlayer ())
+ return;
+
+ if (sv_player->v.movetype != MOVETYPE_NOCLIP)
+ {
+ sv_player->v.movetype = MOVETYPE_NOCLIP;
+ SV_ClientPrintf (host_client, PRINT_HIGH, "noclip ON\n");
+ }
+ else
+ {
+ sv_player->v.movetype = MOVETYPE_WALK;
+ SV_ClientPrintf (host_client, PRINT_HIGH, "noclip OFF\n");
+ }
+}
+
+
+/*
+==================
+SV_Give_f
+==================
+*/
+void SV_Give_f (void)
+{
+ char *t;
+ int v;
+
+ if (!sv_allow_cheats)
+ {
+ Con_Printf ("You must run the server with -cheats to enable this command.\n");
+ return;
+ }
+
+ if (!SV_SetPlayer ())
+ return;
+
+ t = Cmd_Argv(2);
+ v = atoi (Cmd_Argv(3));
+
+ switch (t[0])
+ {
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ sv_player->v.items = (int)sv_player->v.items | IT_SHOTGUN<< (t[0] - '2');
+ break;
+
+ case 's':
+ sv_player->v.ammo_shells = v;
+ break;
+ case 'n':
+ sv_player->v.ammo_nails = v;
+ break;
+ case 'r':
+ sv_player->v.ammo_rockets = v;
+ break;
+ case 'h':
+ sv_player->v.health = v;
+ break;
+ case 'c':
+ sv_player->v.ammo_cells = v;
+ break;
+ }
+}
+
+
+/*
+======================
+SV_Map_f
+
+handle a
+map <mapname>
+command from the console or progs.
+======================
+*/
+void SV_Map_f (void)
+{
+ char level[MAX_QPATH];
+ char expanded[MAX_QPATH];
+ FILE *f;
+
+ if (Cmd_Argc() != 2)
+ {
+ Con_Printf ("map <levelname> : continue game on a new level\n");
+ return;
+ }
+ strcpy (level, Cmd_Argv(1));
+
+#if 0
+ if (!strcmp (level, "e1m8"))
+ { // QuakeWorld can't go to e1m8
+ SV_BroadcastPrintf (PRINT_HIGH, "can't go to low grav level in QuakeWorld...\n");
+ strcpy (level, "e1m5");
+ }
+#endif
+
+ // check to make sure the level exists
+ sprintf (expanded, "maps/%s.bsp", level);
+ COM_FOpenFile (expanded, &f);
+ if (!f)
+ {
+ Con_Printf ("Can't find %s\n", expanded);
+ return;
+ }
+ fclose (f);
+
+ SV_BroadcastCommand ("changing\n");
+ SV_SendMessagesToAll ();
+
+ SV_SpawnServer (level);
+
+ SV_BroadcastCommand ("reconnect\n");
+}
+
+
+/*
+==================
+SV_Kick_f
+
+Kick a user off of the server
+==================
+*/
+void SV_Kick_f (void)
+{
+ int i;
+ client_t *cl;
+ int uid;
+
+ uid = atoi(Cmd_Argv(1));
+
+ for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
+ {
+ if (!cl->state)
+ continue;
+ if (cl->userid == uid)
+ {
+ SV_BroadcastPrintf (PRINT_HIGH, "%s was kicked\n", cl->name);
+ // print directly, because the dropped client won't get the
+ // SV_BroadcastPrintf message
+ SV_ClientPrintf (cl, PRINT_HIGH, "You were kicked from the game\n");
+ SV_DropClient (cl);
+ return;
+ }
+ }
+
+ Con_Printf ("Couldn't find user number %i\n", uid);
+}
+
+
+/*
+================
+SV_Status_f
+================
+*/
+void SV_Status_f (void)
+{
+ int i, j, l;
+ client_t *cl;
+ float cpu, avg, pak;
+ char *s;
+
+
+ cpu = (svs.stats.latched_active+svs.stats.latched_idle);
+ if (cpu)
+ cpu = 100*svs.stats.latched_active/cpu;
+ avg = 1000*svs.stats.latched_active / STATFRAMES;
+ pak = (float)svs.stats.latched_packets/ STATFRAMES;
+
+ Con_Printf ("net address : %s\n",NET_AdrToString (net_local_adr));
+ Con_Printf ("cpu utilization : %3i%%\n",(int)cpu);
+ Con_Printf ("avg response time: %i ms\n",(int)avg);
+ Con_Printf ("packets/frame : %5.2f (%d)\n", pak, num_prstr);
+
+// min fps lat drp
+ if (sv_redirected != RD_NONE) {
+ // most remote clients are 40 columns
+ // 0123456789012345678901234567890123456789
+ Con_Printf ("name userid frags\n");
+ Con_Printf (" address rate ping drop\n");
+ Con_Printf (" ---------------- ---- ---- -----\n");
+ for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
+ {
+ if (!cl->state)
+ continue;
+
+ Con_Printf ("%-16.16s ", cl->name);
+
+ Con_Printf ("%6i %5i", cl->userid, (int)cl->edict->v.frags);
+ if (cl->spectator)
+ Con_Printf(" (s)\n");
+ else
+ Con_Printf("\n");
+
+ s = NET_BaseAdrToString ( cl->netchan.remote_address);
+ Con_Printf (" %-16.16s", s);
+ if (cl->state == cs_connected)
+ {
+ Con_Printf ("CONNECTING\n");
+ continue;
+ }
+ if (cl->state == cs_zombie)
+ {
+ Con_Printf ("ZOMBIE\n");
+ continue;
+ }
+ Con_Printf ("%4i %4i %5.2f\n"
+ , (int)(1000*cl->netchan.frame_rate)
+ , (int)SV_CalcPing (cl)
+ , 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence);
+ }
+ } else {
+ Con_Printf ("frags userid address name rate ping drop qport\n");
+ Con_Printf ("----- ------ --------------- --------------- ---- ---- ----- -----\n");
+ for (i=0,cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
+ {
+ if (!cl->state)
+ continue;
+ Con_Printf ("%5i %6i ", (int)cl->edict->v.frags, cl->userid);
+
+ s = NET_BaseAdrToString ( cl->netchan.remote_address);
+ Con_Printf ("%s", s);
+ l = 16 - strlen(s);
+ for (j=0 ; j<l ; j++)
+ Con_Printf (" ");
+
+ Con_Printf ("%s", cl->name);
+ l = 16 - strlen(cl->name);
+ for (j=0 ; j<l ; j++)
+ Con_Printf (" ");
+ if (cl->state == cs_connected)
+ {
+ Con_Printf ("CONNECTING\n");
+ continue;
+ }
+ if (cl->state == cs_zombie)
+ {
+ Con_Printf ("ZOMBIE\n");
+ continue;
+ }
+ Con_Printf ("%4i %4i %3.1f %4i"
+ , (int)(1000*cl->netchan.frame_rate)
+ , (int)SV_CalcPing (cl)
+ , 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence
+ , cl->netchan.qport);
+ if (cl->spectator)
+ Con_Printf(" (s)\n");
+ else
+ Con_Printf("\n");
+
+
+ }
+ }
+ Con_Printf ("\n");
+}
+
+/*
+==================
+SV_ConSay_f
+==================
+*/
+void SV_ConSay_f(void)
+{
+ client_t *client;
+ int j;
+ char *p;
+ char text[1024];
+
+ if (Cmd_Argc () < 2)
+ return;
+
+ Q_strcpy (text, "console: ");
+ p = Cmd_Args();
+
+ if (*p == '"')
+ {
+ p++;
+ p[Q_strlen(p)-1] = 0;
+ }
+
+ Q_strcat(text, p);
+
+ for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
+ {
+ if (client->state != cs_spawned)
+ continue;
+ SV_ClientPrintf(client, PRINT_CHAT, "%s\n", text);
+ }
+}
+
+
+/*
+==================
+SV_Heartbeat_f
+==================
+*/
+void SV_Heartbeat_f (void)
+{
+ svs.last_heartbeat = -9999;
+}
+
+void SV_SendServerInfoChange(char *key, char *value)
+{
+ if (!sv.state)
+ return;
+
+ MSG_WriteByte (&sv.reliable_datagram, svc_serverinfo);
+ MSG_WriteString (&sv.reliable_datagram, key);
+ MSG_WriteString (&sv.reliable_datagram, value);
+}
+
+/*
+===========
+SV_Serverinfo_f
+
+ Examine or change the serverinfo string
+===========
+*/
+char *CopyString(char *s);
+void SV_Serverinfo_f (void)
+{
+ cvar_t *var;
+
+ if (Cmd_Argc() == 1)
+ {
+ Con_Printf ("Server info settings:\n");
+ Info_Print (svs.info);
+ return;
+ }
+
+ if (Cmd_Argc() != 3)
+ {
+ Con_Printf ("usage: serverinfo [ <key> <value> ]\n");
+ return;
+ }
+
+ if (Cmd_Argv(1)[0] == '*')
+ {
+ Con_Printf ("Star variables cannot be changed.\n");
+ return;
+ }
+ Info_SetValueForKey (svs.info, Cmd_Argv(1), Cmd_Argv(2), MAX_SERVERINFO_STRING);
+
+ // if this is a cvar, change it too
+ var = Cvar_FindVar (Cmd_Argv(1));
+ if (var)
+ {
+ Z_Free (var->string); // free the old value string
+ var->string = CopyString (Cmd_Argv(2));
+ var->value = Q_atof (var->string);
+ }
+
+ SV_SendServerInfoChange(Cmd_Argv(1), Cmd_Argv(2));
+}
+
+
+/*
+===========
+SV_Serverinfo_f
+
+ Examine or change the serverinfo string
+===========
+*/
+char *CopyString(char *s);
+void SV_Localinfo_f (void)
+{
+ if (Cmd_Argc() == 1)
+ {
+ Con_Printf ("Local info settings:\n");
+ Info_Print (localinfo);
+ return;
+ }
+
+ if (Cmd_Argc() != 3)
+ {
+ Con_Printf ("usage: localinfo [ <key> <value> ]\n");
+ return;
+ }
+
+ if (Cmd_Argv(1)[0] == '*')
+ {
+ Con_Printf ("Star variables cannot be changed.\n");
+ return;
+ }
+ Info_SetValueForKey (localinfo, Cmd_Argv(1), Cmd_Argv(2), MAX_LOCALINFO_STRING);
+}
+
+
+/*
+===========
+SV_User_f
+
+Examine a users info strings
+===========
+*/
+void SV_User_f (void)
+{
+ if (Cmd_Argc() != 2)
+ {
+ Con_Printf ("Usage: info <userid>\n");
+ return;
+ }
+
+ if (!SV_SetPlayer ())
+ return;
+
+ Info_Print (host_client->userinfo);
+}
+
+/*
+================
+SV_Gamedir
+
+Sets the fake *gamedir to a different directory.
+================
+*/
+void SV_Gamedir (void)
+{
+ char *dir;
+
+ if (Cmd_Argc() == 1)
+ {
+ Con_Printf ("Current *gamedir: %s\n", Info_ValueForKey (svs.info, "*gamedir"));
+ return;
+ }
+
+ if (Cmd_Argc() != 2)
+ {
+ Con_Printf ("Usage: sv_gamedir <newgamedir>\n");
+ return;
+ }
+
+ dir = Cmd_Argv(1);
+
+ if (strstr(dir, "..") || strstr(dir, "/")
+ || strstr(dir, "\\") || strstr(dir, ":") )
+ {
+ Con_Printf ("*Gamedir should be a single filename, not a path\n");
+ return;
+ }
+
+ Info_SetValueForStarKey (svs.info, "*gamedir", dir, MAX_SERVERINFO_STRING);
+}
+
+/*
+================
+SV_Floodport_f
+
+Sets the gamedir and path to a different directory.
+================
+*/
+
+void SV_Floodprot_f (void)
+{
+ int arg1, arg2, arg3;
+
+ if (Cmd_Argc() == 1)
+ {
+ if (fp_messages) {
+ Con_Printf ("Current floodprot settings: \nAfter %d msgs per %d seconds, silence for %d seconds\n",
+ fp_messages, fp_persecond, fp_secondsdead);
+ return;
+ } else
+ Con_Printf ("No floodprots enabled.\n");
+ }
+
+ if (Cmd_Argc() != 4)
+ {
+ Con_Printf ("Usage: floodprot <# of messages> <per # of seconds> <seconds to silence>\n");
+ Con_Printf ("Use floodprotmsg to set a custom message to say to the flooder.\n");
+ return;
+ }
+
+ arg1 = atoi(Cmd_Argv(1));
+ arg2 = atoi(Cmd_Argv(2));
+ arg3 = atoi(Cmd_Argv(3));
+
+ if (arg1<=0 || arg2 <= 0 || arg3<=0) {
+ Con_Printf ("All values must be positive numbers\n");
+ return;
+ }
+
+ if (arg1 > 10) {
+ Con_Printf ("Can only track up to 10 messages.\n");
+ return;
+ }
+
+ fp_messages = arg1;
+ fp_persecond = arg2;
+ fp_secondsdead = arg3;
+}
+
+void SV_Floodprotmsg_f (void)
+{
+ if (Cmd_Argc() == 1) {
+ Con_Printf("Current msg: %s\n", fp_msg);
+ return;
+ } else if (Cmd_Argc() != 2) {
+ Con_Printf("Usage: floodprotmsg \"<message>\"\n");
+ return;
+ }
+ sprintf(fp_msg, "%s", Cmd_Argv(1));
+}
+
+/*
+================
+SV_Gamedir_f
+
+Sets the gamedir and path to a different directory.
+================
+*/
+char gamedirfile[MAX_OSPATH];
+void SV_Gamedir_f (void)
+{
+ char *dir;
+
+ if (Cmd_Argc() == 1)
+ {
+ Con_Printf ("Current gamedir: %s\n", com_gamedir);
+ return;
+ }
+
+ if (Cmd_Argc() != 2)
+ {
+ Con_Printf ("Usage: gamedir <newdir>\n");
+ return;
+ }
+
+ dir = Cmd_Argv(1);
+
+ if (strstr(dir, "..") || strstr(dir, "/")
+ || strstr(dir, "\\") || strstr(dir, ":") )
+ {
+ Con_Printf ("Gamedir should be a single filename, not a path\n");
+ return;
+ }
+
+ COM_Gamedir (dir);
+ Info_SetValueForStarKey (svs.info, "*gamedir", dir, MAX_SERVERINFO_STRING);
+}
+
+/*
+================
+SV_Snap
+================
+*/
+void SV_Snap (int uid)
+{
+ client_t *cl;
+ char pcxname[80];
+ char checkname[MAX_OSPATH];
+ int i;
+
+ for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
+ {
+ if (!cl->state)
+ continue;
+ if (cl->userid == uid)
+ break;
+ }
+ if (i >= MAX_CLIENTS) {
+ Con_Printf ("userid not found\n");
+ return;
+ }
+
+ sprintf(pcxname, "%d-00.pcx", uid);
+
+ sprintf(checkname, "%s/snap", gamedirfile);
+ Sys_mkdir(gamedirfile);
+ Sys_mkdir(checkname);
+
+ for (i=0 ; i<=99 ; i++)
+ {
+ pcxname[strlen(pcxname) - 6] = i/10 + '0';
+ pcxname[strlen(pcxname) - 5] = i%10 + '0';
+ sprintf (checkname, "%s/snap/%s", gamedirfile, pcxname);
+ if (Sys_FileTime(checkname) == -1)
+ break; // file doesn't exist
+ }
+ if (i==100)
+ {
+ Con_Printf ("Snap: Couldn't create a file, clean some out.\n");
+ return;
+ }
+ strcpy(cl->uploadfn, checkname);
+
+ memcpy(&cl->snap_from, &net_from, sizeof(net_from));
+ if (sv_redirected != RD_NONE)
+ cl->remote_snap = true;
+ else
+ cl->remote_snap = false;
+
+ ClientReliableWrite_Begin (cl, svc_stufftext, 24);
+ ClientReliableWrite_String (cl, "cmd snap");
+ Con_Printf ("Requesting snap from user %d...\n", uid);
+}
+
+/*
+================
+SV_Snap_f
+================
+*/
+void SV_Snap_f (void)
+{
+ int uid;
+
+ if (Cmd_Argc() != 2)
+ {
+ Con_Printf ("Usage: snap <userid>\n");
+ return;
+ }
+
+ uid = atoi(Cmd_Argv(1));
+
+ SV_Snap(uid);
+}
+
+/*
+================
+SV_Snap
+================
+*/
+void SV_SnapAll_f (void)
+{
+ client_t *cl;
+ int i;
+
+ for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++)
+ {
+ if (cl->state < cs_connected || cl->spectator)
+ continue;
+ SV_Snap(cl->userid);
+ }
+}
+
+/*
+==================
+SV_InitOperatorCommands
+==================
+*/
+void SV_InitOperatorCommands (void)
+{
+ if (COM_CheckParm ("-cheats"))
+ {
+ sv_allow_cheats = true;
+ Info_SetValueForStarKey (svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING);
+ }
+
+ Cmd_AddCommand ("logfile", SV_Logfile_f);
+ Cmd_AddCommand ("fraglogfile", SV_Fraglogfile_f);
+
+ Cmd_AddCommand ("snap", SV_Snap_f);
+ Cmd_AddCommand ("snapall", SV_SnapAll_f);
+ Cmd_AddCommand ("kick", SV_Kick_f);
+ Cmd_AddCommand ("status", SV_Status_f);
+
+ Cmd_AddCommand ("map", SV_Map_f);
+ Cmd_AddCommand ("setmaster", SV_SetMaster_f);
+
+ Cmd_AddCommand ("say", SV_ConSay_f);
+ Cmd_AddCommand ("heartbeat", SV_Heartbeat_f);
+ Cmd_AddCommand ("quit", SV_Quit_f);
+ Cmd_AddCommand ("god", SV_God_f);
+ Cmd_AddCommand ("give", SV_Give_f);
+ Cmd_AddCommand ("noclip", SV_Noclip_f);
+ Cmd_AddCommand ("serverinfo", SV_Serverinfo_f);
+ Cmd_AddCommand ("localinfo", SV_Localinfo_f);
+ Cmd_AddCommand ("user", SV_User_f);
+ Cmd_AddCommand ("gamedir", SV_Gamedir_f);
+ Cmd_AddCommand ("sv_gamedir", SV_Gamedir);
+ Cmd_AddCommand ("floodprot", SV_Floodprot_f);
+ Cmd_AddCommand ("floodprotmsg", SV_Floodprotmsg_f);
+
+ cl_warncmd.value = 1;
+}