| /*
|
| 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; |
| } |