home *** CD-ROM | disk | FTP | other *** search
- /*
- 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;
- }
-