2004-08-23 00:15:46 +00:00
/*
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
2005-07-03 15:16:20 +00:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
2004-08-23 00:15:46 +00:00
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"
2004-11-29 01:21:00 +00:00
# ifndef CLIENTONLY
2007-10-25 07:29:59 +00:00
# ifndef INVALID_SOCKET
2005-12-21 03:07:33 +00:00
# define INVALID_SOCKET -1
# endif
2004-08-23 00:15:46 +00:00
qboolean sv_allow_cheats ;
extern cvar_t cl_warncmd ;
2006-02-11 02:09:43 +00:00
cvar_t sv_cheats = SCVARF ( " sv_cheats " , " 0 " , CVAR_LATCH ) ;
2004-08-23 00:15:46 +00:00
extern redirect_t sv_redirected ;
extern cvar_t sv_public ;
//generic helper function for naming players.
client_t * SV_GetClientForString ( char * name , int * id )
{
int i ;
char * s , * s2 ;
char nicename [ 80 ] ;
client_t * cl ;
int first = 0 ;
if ( id & & * id ! = - 1 )
first = * id ;
if ( ! strcmp ( name , " * " ) ) //match with all
{
for ( i = first , cl = svs . clients + first ; i < sv . allocated_client_slots ; i + + , cl + + )
{
if ( cl - > state < = cs_zombie )
continue ;
* id = i + 1 ;
return cl ;
}
* id = sv . allocated_client_slots ;
return NULL ;
}
//check to make sure it's all an int
for ( s = name ; * s ; s + + )
{
if ( * s < ' 0 ' | | * s > ' 9 ' )
break ;
}
//we got to the end of the string and found only numbers. - it's a uid.
if ( ! * s )
{
int uid = Q_atoi ( name ) ;
for ( i = first , cl = svs . clients ; i < sv . allocated_client_slots ; i + + , cl + + )
{
if ( cl - > state < = cs_zombie )
continue ;
if ( cl - > userid = = uid )
{
2006-04-02 23:47:27 +00:00
if ( id )
* id = sv . allocated_client_slots ;
2004-08-23 00:15:46 +00:00
return cl ;
}
}
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
return NULL ;
2005-07-03 15:16:20 +00:00
}
2004-08-23 00:15:46 +00:00
for ( i = first , cl = svs . clients + first ; i < sv . allocated_client_slots ; i + + , cl + + )
{
if ( cl - > state < = cs_zombie )
continue ;
s = nicename ;
s2 = cl - > name ;
while ( * s2 )
{
* s = * s2 & ~ 128 ;
s2 + + ;
if ( * s = = ' 3 ' )
* s = ' e ' ;
else if ( * s = = ' 4 ' )
* s = ' a ' ;
else if ( * s = = ' 1 ' | | * s = = ' 7 ' )
* s = ' l ' ;
else if ( * s > = 18 & & * s < 27 )
* s = * s - 18 + ' 0 ' ;
else if ( * s > = ' A ' & & * s < = ' Z ' )
* s = * s - ' A ' + ' a ' ;
else if ( * s < ' ' | | * s = = ' ~ ' )
continue ;
s + + ;
}
* s = ' \0 ' ;
if ( strstr ( nicename , name ) )
{
2006-04-02 23:47:27 +00:00
if ( id )
* id = i + 1 ;
2004-08-23 00:15:46 +00:00
return cl ;
}
}
return NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
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
= = = = = = = = = = = = = = = = = = = =
*/
2005-09-26 08:07:26 +00:00
void Master_ClearAll ( void ) ;
void Master_Add ( char * stringadr ) ;
2004-08-23 00:15:46 +00:00
void SV_SetMaster_f ( void )
{
int i ;
Cvar_Set ( & sv_public , " 1 " ) ; //go public.
2005-05-26 12:55:34 +00:00
Master_ClearAll ( ) ;
2004-08-23 00:15:46 +00:00
2005-05-26 12:55:34 +00:00
if ( ! strcmp ( Cmd_Argv ( 1 ) , " none " ) )
2004-08-23 00:15:46 +00:00
{
2005-05-26 12:55:34 +00:00
Con_Printf ( " Entering no-master mode \n " ) ;
return ;
}
2004-08-23 00:15:46 +00:00
2005-05-26 12:55:34 +00:00
for ( i = 1 ; i < Cmd_Argc ( ) ; i + + )
{
Master_Add ( Cmd_Argv ( i ) ) ;
2004-08-23 00:15:46 +00:00
}
svs . last_heartbeat = - 99999 ;
}
/*
= = = = = = = = = = = = = = = = = =
SV_Quit_f
= = = = = = = = = = = = = = = = = =
*/
void SV_Quit_f ( void )
{
SV_FinalMessage ( " server shutdown \n " ) ;
Con_TPrintf ( STL_SHUTTINGDOWN ) ;
SV_Shutdown ( ) ;
Sys_Quit ( ) ;
}
/*
= = = = = = = = = = = =
SV_Fraglogfile_f
= = = = = = = = = = = =
*/
void SV_Fraglogfile_f ( void )
{
char name [ MAX_OSPATH ] ;
int i ;
if ( sv_fraglogfile )
{
Con_TPrintf ( STL_FLOGGINGOFF ) ;
2005-12-21 03:07:33 +00:00
VFS_CLOSE ( sv_fraglogfile ) ;
2004-08-23 00:15:46 +00:00
sv_fraglogfile = NULL ;
return ;
}
// find an unused name
for ( i = 0 ; i < 1000 ; i + + )
{
2005-12-21 03:07:33 +00:00
sprintf ( name , " frag_%i.log " , i ) ;
2006-01-02 22:33:23 +00:00
sv_fraglogfile = FS_OpenVFS ( name , " rb " , FS_GAME ) ;
2004-08-23 00:15:46 +00:00
if ( ! sv_fraglogfile )
{ // can't read it, so create this one
2006-01-02 22:33:23 +00:00
sv_fraglogfile = FS_OpenVFS ( name , " wb " , FS_GAME ) ;
2004-08-23 00:15:46 +00:00
if ( ! sv_fraglogfile )
i = 1000 ; // give error
break ;
}
2005-12-21 03:07:33 +00:00
VFS_CLOSE ( sv_fraglogfile ) ;
2004-08-23 00:15:46 +00:00
}
if ( i = = 1000 )
{
Con_TPrintf ( STL_FLOGGINGFAILED ) ;
sv_fraglogfile = NULL ;
return ;
}
Con_TPrintf ( STL_FLOGGINGTO , 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_TPrintf ( STL_USERIDNOTONSERVER , idnum ) ;
return false ;
}
/*
= = = = = = = = = = = = = = = = = =
SV_God_f
Sets client to godmode
= = = = = = = = = = = = = = = = = =
*/
void SV_God_f ( void )
{
if ( ! sv_allow_cheats )
{
Con_TPrintf ( STL_NEEDCHEATPARM ) ;
return ;
}
if ( ! SV_SetPlayer ( ) )
return ;
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( host_client , " god cheat " ) ;
2005-03-28 00:11:59 +00:00
sv_player - > v - > flags = ( int ) sv_player - > v - > flags ^ FL_GODMODE ;
if ( ( int ) sv_player - > v - > flags & FL_GODMODE )
2004-08-23 00:15:46 +00:00
SV_ClientTPrintf ( host_client , PRINT_HIGH , STL_GODON ) ;
else
2005-07-03 15:16:20 +00:00
SV_ClientTPrintf ( host_client , PRINT_HIGH , STL_GODOFF ) ;
2004-08-23 00:15:46 +00:00
}
void SV_Noclip_f ( void )
{
if ( ! sv_allow_cheats )
{
Con_TPrintf ( STL_NEEDCHEATPARM ) ;
return ;
}
if ( ! SV_SetPlayer ( ) )
return ;
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( host_client , " noclip cheat " ) ;
2005-03-28 00:11:59 +00:00
if ( sv_player - > v - > movetype ! = MOVETYPE_NOCLIP )
2004-08-23 00:15:46 +00:00
{
2005-03-28 00:11:59 +00:00
sv_player - > v - > movetype = MOVETYPE_NOCLIP ;
2004-08-23 00:15:46 +00:00
SV_ClientTPrintf ( host_client , PRINT_HIGH , STL_NOCLIPON ) ;
}
else
{
2005-03-28 00:11:59 +00:00
sv_player - > v - > movetype = MOVETYPE_WALK ;
2004-08-23 00:15:46 +00:00
SV_ClientTPrintf ( host_client , PRINT_HIGH , STL_NOCLIPOFF ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
SV_Give_f
= = = = = = = = = = = = = = = = = =
*/
void SV_Give_f ( void )
{
char * t ;
int v ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
if ( ! sv_allow_cheats )
{
Con_TPrintf ( STL_NEEDCHEATPARM ) ;
return ;
}
2005-07-03 15:16:20 +00:00
2008-11-09 22:29:28 +00:00
if ( developer . value )
2005-01-04 08:01:03 +00:00
{
int oldself ;
oldself = pr_global_struct - > self ;
2008-11-09 22:29:28 +00:00
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , sv . edicts ) ;
2005-01-04 08:01:03 +00:00
Con_Printf ( " Result: %s \n " , svprogfuncs - > EvaluateDebugString ( svprogfuncs , Cmd_Args ( ) ) ) ;
pr_global_struct - > self = oldself ;
2008-11-09 22:29:28 +00:00
}
if ( ! SV_SetPlayer ( ) )
{
2004-08-23 00:15:46 +00:00
return ;
2005-01-04 08:01:03 +00:00
}
2004-08-23 00:15:46 +00:00
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( host_client , " give cheat " ) ;
2004-08-23 00:15:46 +00:00
if ( ! svprogfuncs )
return ;
t = Cmd_Argv ( 2 ) ;
v = atoi ( Cmd_Argv ( 3 ) ) ;
2005-07-03 15:16:20 +00:00
2008-11-09 22:29:28 +00:00
switch ( ( t [ 1 ] = = 0 ) ? t [ 0 ] : 0 )
2004-08-23 00:15:46 +00:00
{
case ' 2 ' :
case ' 3 ' :
case ' 4 ' :
case ' 5 ' :
case ' 6 ' :
case ' 7 ' :
case ' 8 ' :
case ' 9 ' :
2005-03-28 00:11:59 +00:00
sv_player - > v - > items = ( int ) sv_player - > v - > items | IT_SHOTGUN < < ( t [ 0 ] - ' 2 ' ) ;
2004-08-23 00:15:46 +00:00
break ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
case ' s ' :
2005-03-28 00:11:59 +00:00
sv_player - > v - > ammo_shells = v ;
2005-07-03 15:16:20 +00:00
break ;
2004-08-23 00:15:46 +00:00
case ' n ' :
2005-03-28 00:11:59 +00:00
sv_player - > v - > ammo_nails = v ;
2005-07-03 15:16:20 +00:00
break ;
2004-08-23 00:15:46 +00:00
case ' r ' :
2005-03-28 00:11:59 +00:00
sv_player - > v - > ammo_rockets = v ;
2005-07-03 15:16:20 +00:00
break ;
2004-08-23 00:15:46 +00:00
case ' h ' :
2005-03-28 00:11:59 +00:00
sv_player - > v - > health = v ;
2005-07-03 15:16:20 +00:00
break ;
2004-08-23 00:15:46 +00:00
case ' c ' :
2005-03-28 00:11:59 +00:00
sv_player - > v - > ammo_cells = v ;
2005-01-04 08:01:03 +00:00
break ;
default :
{
int oldself ;
oldself = pr_global_struct - > self ;
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , sv_player ) ;
2008-11-09 22:29:28 +00:00
Cmd_ShiftArgs ( 1 , false ) ;
2005-01-04 08:01:03 +00:00
Con_Printf ( " Result: %s \n " , svprogfuncs - > EvaluateDebugString ( svprogfuncs , Cmd_Args ( ) ) ) ;
pr_global_struct - > self = oldself ;
}
2004-08-23 00:15:46 +00:00
}
}
2009-04-01 22:03:56 +00:00
int ShowMapList ( const char * name , int flags , void * parm )
2004-08-23 00:15:46 +00:00
{
if ( name [ 5 ] = = ' b ' & & name [ 6 ] = = ' _ ' ) //skip box models
return true ;
Con_Printf ( " %s \n " , name + 5 ) ;
return true ;
}
void SV_MapList_f ( void )
{
COM_EnumerateFiles ( " maps/*.bsp " , ShowMapList , NULL ) ;
}
2007-02-23 00:21:33 +00:00
void gtcallback ( struct cvar_s * var , char * oldvalue )
{
Con_Printf ( " g_gametype changed \n " ) ;
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = =
SV_Map_f
2005-07-03 15:16:20 +00:00
handle a
2004-08-23 00:15:46 +00:00
map < mapname >
command from the console or progs .
= = = = = = = = = = = = = = = = = = = = = =
*/
void SV_Map_f ( void )
{
char level [ MAX_QPATH ] ;
char spot [ MAX_QPATH ] ;
char expanded [ MAX_QPATH ] ;
char * nextserver ;
qboolean issamelevel = false ;
qboolean newunit = false ;
qboolean cinematic = false ;
2005-05-13 10:42:48 +00:00
qboolean waschangelevel = false ;
2005-09-08 01:47:12 +00:00
qboolean wasspmap = false ;
2004-08-23 00:15:46 +00:00
int i ;
char * startspot ;
2007-12-03 11:40:18 +00:00
nextserver = 0 ;
2006-10-15 03:34:05 +00:00
# ifndef SERVERONLY
if ( qrenderer = = - 1 )
{
Cbuf_AddText ( va ( " wait;map %s \n " , Cmd_Args ( ) ) , Cmd_ExecLevel ) ;
return ;
}
# endif
2004-08-23 00:15:46 +00:00
if ( Cmd_Argc ( ) ! = 2 & & Cmd_Argc ( ) ! = 3 )
{
Con_TPrintf ( STL_MAPCOMMANDUSAGE ) ;
return ;
}
2005-03-18 06:13:11 +00:00
2007-03-04 19:17:16 +00:00
sv . mapchangelocked = false ;
2006-05-25 21:32:32 +00:00
Q_strncpyz ( level , Cmd_Argv ( 1 ) , sizeof ( level ) ) ;
2004-08-23 00:15:46 +00:00
startspot = ( ( Cmd_Argc ( ) = = 2 ) ? NULL : Cmd_Argv ( 2 ) ) ;
2005-05-13 10:42:48 +00:00
waschangelevel = ! strcmp ( Cmd_Argv ( 0 ) , " changelevel " ) ;
2005-09-08 01:47:12 +00:00
wasspmap = ! strcmp ( Cmd_Argv ( 0 ) , " spmap " ) ;
2005-05-13 10:42:48 +00:00
2009-04-01 22:03:56 +00:00
if ( strcmp ( level , " . " ) ) //restart current
2004-08-23 00:15:46 +00:00
{
2009-04-01 22:03:56 +00:00
snprintf ( expanded , sizeof ( expanded ) , " maps/%s.bsp " , level ) ; // this function and the if statement below, is a quake bugfix which stopped a map called "dm6++.bsp" from loading because of the + sign, quake2 map syntax interprets + character as "intro.cin+base1.bsp", to play a cinematic then load a map after
if ( ! COM_FCheckExists ( expanded ) )
2007-10-25 07:29:59 +00:00
{
2009-04-01 22:03:56 +00:00
nextserver = strchr ( level , ' + ' ) ;
if ( nextserver )
{
* nextserver = ' \0 ' ;
nextserver + + ;
}
2007-10-25 07:29:59 +00:00
}
2004-08-23 00:15:46 +00:00
}
if ( startspot )
{
strcpy ( spot , startspot ) ;
startspot = spot ;
}
else if ( ( startspot = strchr ( level , ' $ ' ) ) )
{
strcpy ( spot , startspot + 1 ) ;
* startspot = ' \0 ' ;
startspot = spot ;
}
else
startspot = NULL ;
if ( ! strcmp ( level , " . " ) ) //restart current
2005-07-03 15:16:20 +00:00
{
2009-04-01 22:03:56 +00:00
//grab the current map name
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( sv . modelname ) , level , sizeof ( level ) ) ;
2004-08-23 00:15:46 +00:00
issamelevel = true ;
2009-04-01 22:03:56 +00:00
if ( ! * level )
Q_strncpyz ( level , " start " , sizeof ( level ) ) ;
//override the startspot
2004-08-23 00:15:46 +00:00
Q_strncpyz ( spot , Info_ValueForKey ( svs . info , " *startspot " ) , sizeof ( spot ) ) ;
startspot = spot ;
}
// check to make sure the level exists
if ( * level = = ' * ' )
{
memmove ( level , level + 1 , strlen ( level ) ) ;
newunit = true ;
}
2006-09-17 00:59:22 +00:00
# ifndef SERVERONLY
SCR_ImageName ( level ) ;
# endif
COM_FlushFSCache ( ) ;
2004-08-23 00:15:46 +00:00
if ( strlen ( level ) > 4 & & ! strcmp ( level + strlen ( level ) - 4 , " .cin " ) )
{
cinematic = true ;
}
else
{
2006-05-18 02:24:38 +00:00
snprintf ( expanded , sizeof ( expanded ) , " maps/%s.bsp " , level ) ;
2004-08-23 00:15:46 +00:00
if ( ! COM_FCheckExists ( expanded ) )
{
2005-09-08 01:47:12 +00:00
//doesn't exist, so try lowercase. Q3 does this.
2007-09-22 19:29:24 +00:00
for ( i = 0 ; i < sizeof ( level ) & & level [ i ] ; i + + )
2005-09-08 01:47:12 +00:00
{
if ( level [ i ] > = ' A ' & & level [ i ] < = ' Z ' )
level [ i ] = level [ i ] - ' A ' + ' a ' ;
}
2006-05-18 02:24:38 +00:00
snprintf ( expanded , sizeof ( expanded ) , " maps/%s.bsp " , level ) ;
2005-09-08 01:47:12 +00:00
if ( ! COM_FCheckExists ( expanded ) )
{
Con_TPrintf ( STL_CANTFINDMAP , expanded ) ;
return ;
}
2004-08-23 00:15:46 +00:00
}
}
if ( sv . mvdrecording )
SV_MVDStop_f ( ) ;
# ifndef SERVERONLY
if ( ! isDedicated ) //otherwise, info used on map loading isn't present
2005-01-07 02:32:32 +00:00
Cmd_ExecuteString ( va ( " fullserverinfo \" %s \" \n " , svs . info ) , RESTRICT_SERVER ) ;
2004-08-23 00:15:46 +00:00
if ( ! sv . state & & cls . state )
CL_Disconnect ( ) ;
# endif
SV_SaveSpawnparms ( issamelevel ) ;
if ( startspot & & ! issamelevel & & ! newunit )
2005-03-18 06:13:11 +00:00
{
2005-07-03 15:16:20 +00:00
# ifdef Q2SERVER
2005-03-18 06:13:11 +00:00
if ( ge )
{
qboolean savedinuse [ MAX_CLIENTS ] ;
for ( i = 0 ; i < sv . allocated_client_slots ; i + + )
{
savedinuse [ i ] = svs . clients [ i ] . q2edict - > inuse ;
svs . clients [ i ] . q2edict - > inuse = false ;
}
SV_SaveLevelCache ( false ) ;
for ( i = 0 ; i < sv . allocated_client_slots ; i + + )
{
svs . clients [ i ] . q2edict - > inuse = savedinuse [ i ] ;
}
}
else
2005-07-03 15:16:20 +00:00
# endif
2005-03-18 06:13:11 +00:00
SV_SaveLevelCache ( false ) ;
}
2004-08-23 00:15:46 +00:00
2005-09-08 01:47:12 +00:00
# ifdef Q3SERVER
{
cvar_t * gametype ;
2007-02-23 00:21:33 +00:00
gametype = Cvar_Get ( " mapname " , " 0 " , CVAR_LATCH | CVAR_SERVERINFO , " Q3 compatability " ) ;
gametype - > flags | = CVAR_SERVERINFO ;
Cvar_ForceSet ( gametype , level ) ;
gametype = Cvar_Get ( " g_gametype " , " 0 " , CVAR_LATCH | CVAR_SERVERINFO , " Q3 compatability " ) ;
gametype - > callback = gtcallback ;
2005-09-08 01:47:12 +00:00
if ( wasspmap )
2007-03-04 19:17:16 +00:00
Cvar_ForceSet ( gametype , " 2 " ) ; //singleplayer
else if ( gametype - > value = = 2 )
Cvar_ForceSet ( gametype , " 0 " ) ; //force to ffa deathmatch
2005-09-08 01:47:12 +00:00
}
# endif
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + ) //we need to drop all q2 clients. We don't mix q1w with q2.
{
if ( svs . clients [ i ] . state > cs_connected ) //so that we don't send a datagram
svs . clients [ i ] . state = cs_connected ;
}
# ifndef SERVERONLY
S_StopAllSounds ( true ) ;
2006-09-17 00:59:22 +00:00
// SCR_BeginLoadingPlaque();
SCR_ImageName ( level ) ;
2004-08-23 00:15:46 +00:00
# endif
2006-09-17 00:59:22 +00:00
SV_BroadcastCommand ( " changing \" %s \" \n " , level ) ;
SV_SendMessagesToAll ( ) ;
2004-08-23 00:15:46 +00:00
if ( newunit | | ! startspot | | ! SV_LoadLevelCache ( level , startspot , false ) )
2005-05-13 10:42:48 +00:00
{
if ( waschangelevel & & ! startspot )
startspot = " " ;
2004-08-23 00:15:46 +00:00
SV_SpawnServer ( level , startspot , false , cinematic ) ;
2005-05-13 10:42:48 +00:00
}
2004-08-23 00:15:46 +00:00
2007-06-20 00:02:54 +00:00
//SV_BroadcastCommand ("cmd new\n");
for ( i = 0 , host_client = svs . clients ; i < MAX_CLIENTS ; i + + , host_client + + )
{ //this expanded code cuts out a packet when changing maps...
//but more usefully, it stops dp(and probably nq too) from timing out.
if ( host_client - > controller )
continue ;
if ( host_client - > state > = cs_connected )
{
2008-11-09 22:29:28 +00:00
if ( host_client - > protocol = = SCP_QUAKE3 )
continue ;
2007-06-20 00:02:54 +00:00
if ( ISNQCLIENT ( host_client ) )
SVNQ_New_f ( ) ;
else
SV_New_f ( ) ;
}
}
2004-08-23 00:15:46 +00:00
if ( ! issamelevel )
{
cvar_t * nsv ;
nsv = Cvar_Get ( " nextserver " , " " , 0 , " " ) ;
if ( nextserver )
2004-08-27 00:43:28 +00:00
Cvar_Set ( nsv , va ( " gamemap \" %s \" " , nextserver ) ) ;
2004-08-23 00:15:46 +00:00
else
Cvar_Set ( nsv , " " ) ;
}
}
void SV_KillServer_f ( void )
{
SV_UnspawnServer ( ) ;
}
/*
= = = = = = = = = = = = = = = = = =
SV_Kick_f
Kick a user off of the server
= = = = = = = = = = = = = = = = = =
*/
void SV_Kick_f ( void )
2005-07-03 15:16:20 +00:00
{
2004-08-23 00:15:46 +00:00
client_t * cl ;
int clnum = - 1 ;
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
{
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTWASKICKED , cl - > name ) ;
// print directly, because the dropped client won't get the
// SV_BroadcastPrintf message
SV_ClientTPrintf ( cl , PRINT_HIGH , STL_YOUWEREKICKED ) ;
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " kicked " ) ;
2005-07-03 15:16:20 +00:00
SV_DropClient ( cl ) ;
}
2004-08-23 00:15:46 +00:00
if ( clnum = = - 1 )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
2006-05-22 22:51:14 +00:00
void SV_BanName_f ( void )
2004-08-23 00:15:46 +00:00
{
client_t * cl ;
int clnum = - 1 ;
2006-05-25 04:47:03 +00:00
char * reason = NULL ;
int reasonsize = 0 ;
2004-08-23 00:15:46 +00:00
2006-05-22 22:51:14 +00:00
if ( Cmd_Argc ( ) < 2 )
{
2006-05-25 04:47:03 +00:00
Con_Printf ( " %s userid|nick [reason] \n " , Cmd_Argv ( 0 ) ) ;
2006-05-22 22:51:14 +00:00
return ;
}
2006-05-25 04:47:03 +00:00
if ( Cmd_Argc ( ) > 2 )
{
reason = Cmd_Argv ( 2 ) ;
reasonsize = strlen ( reason ) ;
}
2004-08-23 00:15:46 +00:00
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
if ( cl )
{
bannedips_t * nb ;
2006-05-22 22:51:14 +00:00
if ( NET_IsLoopBackAddress ( cl - > netchan . remote_address ) )
{
Con_Printf ( " You're not allowed to ban loopback! \n " ) ;
continue ;
}
2006-05-25 04:47:03 +00:00
nb = Z_Malloc ( sizeof ( bannedips_t ) + reasonsize ) ;
2004-08-23 00:15:46 +00:00
nb - > next = svs . bannedips ;
nb - > adr = cl - > netchan . remote_address ;
2006-05-22 22:51:14 +00:00
NET_IntegerToMask ( & nb - > adr , & nb - > adrmask , - 1 ) ; // fill mask
2004-08-23 00:15:46 +00:00
if ( * Cmd_Argv ( 2 ) ) //explicit blocking of all ports of a client ip
nb - > adr . port = 0 ;
svs . bannedips = nb ;
2006-05-25 04:47:03 +00:00
if ( reasonsize )
Q_strcpy ( nb - > reason , reason ) ;
2004-08-23 00:15:46 +00:00
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTWASBANNED , cl - > name ) ;
// print directly, because the dropped client won't get the
// SV_BroadcastPrintf message
SV_ClientTPrintf ( cl , PRINT_HIGH , STL_YOUWEREBANNED ) ;
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " banned name " ) ;
2004-08-23 00:15:46 +00:00
SV_DropClient ( cl ) ;
}
if ( clnum = = - 1 )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
2008-05-25 22:23:43 +00:00
void SV_KickBanIP ( netadr_t banadr , netadr_t banmask , char * reason )
{
qboolean shouldkick ;
client_t * cl ;
int i ;
unsigned int reasonsize ;
bannedips_t * nb ;
if ( reason )
reasonsize = strlen ( reason ) ;
else
reasonsize = 0 ;
// loop through clients and kick the ones that match
for ( i = 0 , cl = svs . clients ; i < sv . allocated_client_slots ; i + + , cl + + )
{
if ( cl - > state < = cs_zombie )
continue ;
shouldkick = false ;
if ( NET_CompareAdrMasked ( cl - > netchan . remote_address , banadr , banmask ) )
shouldkick = true ;
else if ( cl - > realip_status > = 1 )
if ( NET_CompareAdrMasked ( cl - > realip , banadr , banmask ) )
shouldkick = true ;
if ( shouldkick )
{
// match, so kick
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTWASBANNED , cl - > name ) ;
// print directly, because the dropped client won't get the
// SV_BroadcastPrintf message
SV_ClientTPrintf ( cl , PRINT_HIGH , STL_YOUWEREBANNED ) ;
SV_LogPlayer ( cl , " banned ip " ) ;
SV_DropClient ( cl ) ;
}
}
// add IP and mask to ban list
nb = Z_Malloc ( sizeof ( bannedips_t ) + reasonsize ) ;
nb - > next = svs . bannedips ;
nb - > adr = banadr ;
nb - > adrmask = banmask ;
svs . bannedips = nb ;
if ( reasonsize )
Q_strcpy ( nb - > reason , reason ) ;
}
2006-05-22 22:51:14 +00:00
void SV_BanIP_f ( void )
2004-08-23 00:15:46 +00:00
{
2006-05-22 22:51:14 +00:00
netadr_t banadr ;
netadr_t banmask ;
2006-05-25 04:47:03 +00:00
char * reason = NULL ;
int reasonsize = 0 ;
2004-08-23 00:15:46 +00:00
2006-05-22 22:51:14 +00:00
if ( Cmd_Argc ( ) < 2 )
{
2006-05-25 04:47:03 +00:00
Con_Printf ( " %s address/mask|adress/maskbits [reason] \n " , Cmd_Argv ( 0 ) ) ;
2006-05-22 22:51:14 +00:00
return ;
}
2004-08-23 00:15:46 +00:00
2006-05-22 22:51:14 +00:00
if ( ! NET_StringToAdrMasked ( Cmd_Argv ( 1 ) , & banadr , & banmask ) )
2004-08-23 00:15:46 +00:00
{
2006-05-22 22:51:14 +00:00
Con_Printf ( " invalid address or mask \n " ) ;
return ;
}
if ( NET_IsLoopBackAddress ( banadr ) )
{
Con_Printf ( " You're not allowed to ban loopback! \n " ) ;
return ;
}
2006-05-25 04:47:03 +00:00
if ( Cmd_Argc ( ) > 2 )
reason = Cmd_Argv ( 2 ) ;
2008-05-25 22:23:43 +00:00
SV_KickBanIP ( banadr , banmask , reason ) ;
}
void SV_BanClientIP_f ( void )
{
netadr_t banmask ;
client_t * cl ;
char * reason = NULL ;
int clnum = - 1 ;
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
2006-05-22 22:51:14 +00:00
{
2008-05-25 22:23:43 +00:00
if ( NET_IsLoopBackAddress ( cl - > netchan . remote_address ) )
{
Con_Printf ( " You're not allowed to ban loopback! \n " ) ;
2006-05-22 22:51:14 +00:00
continue ;
2008-05-25 22:23:43 +00:00
}
2006-05-22 22:51:14 +00:00
2008-05-25 22:23:43 +00:00
if ( cl - > realip_status > 0 )
2004-08-23 00:15:46 +00:00
{
2008-05-25 22:23:43 +00:00
memset ( & banmask . address , 0xff , sizeof ( banmask . address ) ) ;
banmask . type = cl - > netchan . remote_address . type ;
SV_KickBanIP ( cl - > realip , banmask , reason ) ;
}
else
{
memset ( & banmask . address , 0xff , sizeof ( banmask . address ) ) ;
banmask . type = cl - > netchan . remote_address . type ;
SV_KickBanIP ( cl - > netchan . remote_address , banmask , reason ) ;
2004-08-23 00:15:46 +00:00
}
}
2006-05-25 04:47:03 +00:00
}
void SV_FilterIP_f ( void )
{
netadr_t banadr ;
netadr_t banmask ;
int i ;
client_t * cl ;
filteredips_t * nb ;
extern cvar_t filterban ;
if ( Cmd_Argc ( ) < 2 )
{
Con_Printf ( " %s address/mask|adress/maskbits \n " , Cmd_Argv ( 0 ) ) ;
return ;
}
if ( ! NET_StringToAdrMasked ( Cmd_Argv ( 1 ) , & banadr , & banmask ) )
{
Con_Printf ( " invalid address or mask \n " ) ;
return ;
}
if ( NET_IsLoopBackAddress ( banadr ) )
{
Con_Printf ( " You're not allowed to filter loopback! \n " ) ;
return ;
}
// loop through clients and kick the ones that match
for ( i = 0 , cl = svs . clients ; i < sv . allocated_client_slots ; i + + , cl + + )
{
if ( cl - > state < = cs_zombie )
continue ;
if ( filterban . value & & NET_CompareAdrMasked ( cl - > netchan . remote_address , banadr , banmask ) )
SV_DropClient ( cl ) ;
}
// add IP and mask to filter list
nb = Z_Malloc ( sizeof ( filteredips_t ) ) ;
nb - > next = svs . filteredips ;
nb - > adr = banadr ;
nb - > adrmask = banmask ;
svs . filteredips = nb ;
2006-05-22 22:51:14 +00:00
}
void SV_BanList_f ( void )
{
int bancount = 0 ;
bannedips_t * nb = svs . bannedips ;
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2006-05-22 22:51:14 +00:00
while ( nb )
{
2006-05-25 04:47:03 +00:00
if ( nb - > reason [ 0 ] )
2008-06-08 14:37:57 +00:00
Con_Printf ( " %s, %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , nb - > adr , nb - > adrmask ) , nb - > reason ) ;
2006-05-25 04:47:03 +00:00
else
2008-06-08 14:37:57 +00:00
Con_Printf ( " %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , nb - > adr , nb - > adrmask ) ) ;
2006-05-22 22:51:14 +00:00
bancount + + ;
nb = nb - > next ;
}
Con_Printf ( " %i total entries in ban list \n " , bancount ) ;
}
2006-05-25 04:47:03 +00:00
void SV_FilterList_f ( void )
{
int filtercount = 0 ;
filteredips_t * nb = svs . filteredips ;
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2006-05-25 04:47:03 +00:00
while ( nb )
{
2008-06-08 14:37:57 +00:00
Con_Printf ( " %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , nb - > adr , nb - > adrmask ) ) ;
2006-05-25 04:47:03 +00:00
filtercount + + ;
nb = nb - > next ;
}
Con_Printf ( " %i total entries in filter list \n " , filtercount ) ;
}
2006-05-22 22:51:14 +00:00
void SV_Unban_f ( void )
{
qboolean all = false ;
bannedips_t * nb = svs . bannedips ;
bannedips_t * nbnext ;
netadr_t unbanadr = { 0 } ;
netadr_t unbanmask = { 0 } ;
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2006-05-22 22:51:14 +00:00
if ( Cmd_Argc ( ) < 2 )
{
Con_Printf ( " %s address/mask|address/maskbits|all \n " , Cmd_Argv ( 0 ) ) ;
return ;
}
if ( ! Q_strcasecmp ( Cmd_Argv ( 1 ) , " all " ) )
all = true ;
else if ( ! NET_StringToAdrMasked ( Cmd_Argv ( 1 ) , & unbanadr , & unbanmask ) )
{
Con_Printf ( " invalid address or mask \n " ) ;
return ;
}
while ( nb )
{
nbnext = nb - > next ;
2006-05-29 16:12:21 +00:00
if ( all | | ( NET_CompareAdr ( nb - > adr , unbanadr ) & & NET_CompareAdr ( nb - > adrmask , unbanmask ) ) )
2006-05-22 22:51:14 +00:00
{
if ( ! all )
2008-06-08 14:37:57 +00:00
Con_Printf ( " unbanned %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , nb - > adr , nb - > adrmask ) ) ;
2006-05-22 22:51:14 +00:00
if ( svs . bannedips = = nb )
svs . bannedips = nbnext ;
Z_Free ( nb ) ;
2006-05-29 16:12:21 +00:00
break ;
2006-05-22 22:51:14 +00:00
}
nb = nbnext ;
}
2004-08-23 00:15:46 +00:00
}
2006-05-25 04:47:03 +00:00
void SV_Unfilter_f ( void )
{
qboolean all = false ;
filteredips_t * nb = svs . filteredips ;
filteredips_t * nbnext ;
netadr_t unbanadr = { 0 } ;
netadr_t unbanmask = { 0 } ;
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2006-05-25 04:47:03 +00:00
if ( Cmd_Argc ( ) < 2 )
{
Con_Printf ( " %s address/mask|address/maskbits|all \n " , Cmd_Argv ( 0 ) ) ;
return ;
}
if ( ! Q_strcasecmp ( Cmd_Argv ( 1 ) , " all " ) )
all = true ;
else if ( ! NET_StringToAdrMasked ( Cmd_Argv ( 1 ) , & unbanadr , & unbanmask ) )
{
Con_Printf ( " invalid address or mask \n " ) ;
return ;
}
while ( nb )
{
nbnext = nb - > next ;
2006-05-29 16:12:21 +00:00
if ( all | | ( NET_CompareAdr ( nb - > adr , unbanadr ) & & NET_CompareAdr ( nb - > adrmask , unbanmask ) ) )
2006-05-25 04:47:03 +00:00
{
if ( ! all )
2008-06-08 14:37:57 +00:00
Con_Printf ( " unfiltered %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , nb - > adr , nb - > adrmask ) ) ;
2006-05-25 04:47:03 +00:00
if ( svs . filteredips = = nb )
svs . filteredips = nbnext ;
Z_Free ( nb ) ;
2006-05-29 16:12:21 +00:00
break ;
2006-05-25 04:47:03 +00:00
}
nb = nbnext ;
}
}
2006-05-29 16:12:21 +00:00
void SV_WriteIP_f ( void )
{
vfsfile_t * f ;
char name [ MAX_OSPATH ] ;
bannedips_t * bi ;
filteredips_t * fi ;
char * s ;
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2006-05-29 16:12:21 +00:00
strcpy ( name , " listip.cfg " ) ;
Con_Printf ( " Writing %s. \n " , name ) ;
f = FS_OpenVFS ( name , " wb " , FS_GAME ) ;
if ( ! f )
{
Con_Printf ( " Couldn't open %s \n " , name ) ;
return ;
}
s = " // banned ip addresses \n " ;
VFS_WRITE ( f , s , strlen ( s ) ) ;
bi = svs . bannedips ;
while ( bi )
{
if ( bi - > reason [ 0 ] )
2008-06-08 14:37:57 +00:00
s = va ( " banip %s \" %s \" \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , bi - > adr , bi - > adrmask ) , bi - > reason ) ;
2006-05-29 16:12:21 +00:00
else
2008-06-08 14:37:57 +00:00
s = va ( " banip %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , bi - > adr , bi - > adrmask ) ) ;
2006-05-29 16:12:21 +00:00
VFS_WRITE ( f , s , strlen ( s ) ) ;
bi = bi - > next ;
}
s = " \n // filtered ip addresses \n " ;
VFS_WRITE ( f , s , strlen ( s ) ) ;
fi = svs . filteredips ;
while ( fi )
{
2008-06-08 14:37:57 +00:00
s = va ( " addip %s \n " , NET_AdrToStringMasked ( adr , sizeof ( adr ) , fi - > adr , fi - > adrmask ) ) ;
2006-05-29 16:12:21 +00:00
VFS_WRITE ( f , s , strlen ( s ) ) ;
fi = fi - > next ;
}
VFS_CLOSE ( f ) ;
}
2004-08-23 00:15:46 +00:00
void SV_ForceName_f ( void )
{
client_t * cl ;
int clnum = - 1 ;
int i ;
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
{
Info_SetValueForKey ( cl - > userinfo , " name " , Cmd_Argv ( 2 ) , MAX_INFO_STRING ) ;
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " name forced " ) ;
2004-08-23 00:15:46 +00:00
SV_ExtractFromUserinfo ( cl ) ;
2005-09-27 05:53:31 +00:00
Q_strncpyz ( cl - > name , Cmd_Argv ( 2 ) , sizeof ( cl - > namebuf ) ) ;
2004-08-23 00:15:46 +00:00
i = cl - svs . clients ;
MSG_WriteByte ( & sv . reliable_datagram , svc_setinfo ) ;
MSG_WriteByte ( & sv . reliable_datagram , i ) ;
MSG_WriteString ( & sv . reliable_datagram , " name " ) ;
MSG_WriteString ( & sv . reliable_datagram , cl - > name ) ;
return ;
}
if ( clnum = = - 1 )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
void SV_CripplePlayer_f ( void )
{
client_t * cl ;
int clnum = - 1 ;
int persist = * Cmd_Argv ( 2 ) ;
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
{
if ( ! cl - > iscrippled )
{
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " crippled " ) ;
2004-08-23 00:15:46 +00:00
if ( persist )
{
cl - > iscrippled = 2 ;
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTISCRIPPLEDPERMANENTLY , cl - > name ) ;
}
else
{
cl - > iscrippled = true ;
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTISCRIPPLED , cl - > name ) ;
}
}
else
{
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " uncrippled " ) ;
2004-08-23 00:15:46 +00:00
cl - > iscrippled = false ;
SV_ClientTPrintf ( cl , PRINT_HIGH , STL_YOUARNTCRIPPLED ) ;
2005-07-03 15:16:20 +00:00
}
2004-08-23 00:15:46 +00:00
}
if ( clnum = = - 1 )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
void SV_Mute_f ( void )
{
client_t * cl ;
int clnum = - 1 ;
int persist = * Cmd_Argv ( 2 ) ;
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
{
if ( ! cl - > ismuted )
{
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " muted " ) ;
2004-08-23 00:15:46 +00:00
if ( persist )
{
cl - > ismuted = 2 ;
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTISMUTEDPERMANENTLY , cl - > name ) ;
}
else
{
cl - > ismuted = true ;
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTISMUTED , cl - > name ) ;
}
}
else
{
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " unmuted " ) ;
2004-08-23 00:15:46 +00:00
cl - > ismuted = false ;
SV_ClientTPrintf ( cl , PRINT_HIGH , STL_YOUARNTMUTED ) ;
}
}
if ( clnum = = - 1 )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
void SV_Cuff_f ( void )
{
client_t * cl ;
int clnum = - 1 ;
int persist = * Cmd_Argv ( 2 ) ;
while ( ( cl = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
{
if ( ! cl - > iscuffed )
{
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " cuffed " ) ;
2004-08-23 00:15:46 +00:00
if ( persist )
{
cl - > iscuffed = 2 ;
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTISCUFFEDPERMANENTLY , cl - > name ) ;
}
else
{
cl - > iscuffed = true ;
SV_BroadcastTPrintf ( PRINT_HIGH , STL_CLIENTISCUFFED , cl - > name ) ;
}
}
else
{
2007-07-27 21:24:31 +00:00
SV_LogPlayer ( cl , " uncuffed " ) ;
2004-08-23 00:15:46 +00:00
cl - > iscuffed = false ;
SV_ClientTPrintf ( cl , PRINT_HIGH , STL_YOUARNTCUFFED ) ;
}
return ;
}
if ( clnum = = - 1 )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
2006-05-30 04:00:24 +00:00
void SV_Floodprot_f ( void )
{
extern cvar_t sv_floodprotect ;
extern cvar_t sv_floodprotect_messages ;
extern cvar_t sv_floodprotect_interval ;
extern cvar_t sv_floodprotect_silencetime ;
if ( Cmd_Argc ( ) = = 1 )
{
if ( sv_floodprotect_messages . value < = 0 | | ! sv_floodprotect . value )
Con_Printf ( " Flood protection is off. \n " ) ;
else
Con_Printf ( " Current flood protection settings: \n After %g msgs for %g seconds, silence for %g seconds \n " ,
sv_floodprotect_messages . value ,
sv_floodprotect_interval . value ,
sv_floodprotect_silencetime . value ) ;
return ;
}
if ( Cmd_Argc ( ) ! = 4 )
{
Con_Printf ( " Usage: %s <messagerate> <ratepersecond> <silencetime> \n " , Cmd_Argv ( 0 ) ) ;
return ;
}
Cvar_SetValue ( & sv_floodprotect_messages , atof ( Cmd_Argv ( 1 ) ) ) ;
Cvar_SetValue ( & sv_floodprotect_interval , atof ( Cmd_Argv ( 2 ) ) ) ;
Cvar_SetValue ( & sv_floodprotect_silencetime , atof ( Cmd_Argv ( 3 ) ) ) ;
}
2004-08-23 00:15:46 +00:00
void SV_StuffToClient_f ( void )
{ //with this we emulate the progs 'stuffcmds' builtin
client_t * cl ;
int clnum = - 1 ;
char * clientname = Cmd_Argv ( 1 ) ;
char * str ;
char * c ;
char * key ;
2004-12-08 04:14:52 +00:00
Cmd_ShiftArgs ( 1 , Cmd_ExecLevel = = RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
if ( ! strcmp ( Cmd_Argv ( 1 ) , " bind " ) )
{
key = Z_Malloc ( strlen ( Cmd_Argv ( 2 ) ) + 1 ) ;
strcpy ( key , Cmd_Argv ( 2 ) ) ;
2004-12-08 04:14:52 +00:00
Cmd_ShiftArgs ( 2 , Cmd_ExecLevel = = RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
}
else
key = NULL ;
str = Cmd_Args ( ) ;
while ( * str < = ' ' ) //strim leading spaces
{
if ( ! * str )
break ;
str + + ;
}
//a list of safe, allowed commands. Allows any extention of this.
if ( strchr ( str , ' \n ' ) | | strchr ( str , ' ; ' ) | | (
2006-06-12 22:05:41 +00:00
! strncmp ( str , " setinfo " , 7 ) & &
! strncmp ( str , " quit " , 4 ) & &
! strncmp ( str , " gl_fb " , 5 ) & &
! strncmp ( str , " r_fb " , 4 ) & &
2006-06-15 21:40:54 +00:00
! strncmp ( str , " say " , 3 ) & & //note that the say parsing could be useful here.
2006-06-12 22:05:41 +00:00
! strncmp ( str , " echo " , 4 ) & &
! strncmp ( str , " name " , 4 ) & &
! strncmp ( str , " skin " , 4 ) & &
! strncmp ( str , " color " , 5 ) & &
! strncmp ( str , " cmd " , 3 ) & &
! strncmp ( str , " fov " , 3 ) & &
! strncmp ( str , " connect " , 7 ) & &
! strncmp ( str , " rate " , 4 ) & &
! strncmp ( str , " cd " , 2 ) & &
! strncmp ( str , " easyrecord " , 10 ) & &
! strncmp ( str , " leftisright " , 11 ) & &
! strncmp ( str , " menu_ " , 5 ) & &
! strncmp ( str , " r_fullbright " , 12 ) & &
! strncmp ( str , " toggleconsole " , 13 ) & &
! strncmp ( str , " v_i " , 3 ) & & //idlescale vars
! strncmp ( str , " bf " , 2 ) & &
! strncmp ( str , " + " , 1 ) & &
! strncmp ( str , " - " , 1 ) & &
! strncmp ( str , " impulse " , 7 ) & &
2004-08-23 00:15:46 +00:00
1 ) )
{
Con_Printf ( " You're not allowed to stuffcmd that \n " ) ;
if ( key )
Z_Free ( key ) ;
return ;
}
while ( ( cl = SV_GetClientForString ( clientname , & clnum ) ) )
{
2005-05-26 12:55:34 +00:00
if ( cl - > protocol = = SCP_QUAKE2 )
2004-08-23 00:15:46 +00:00
ClientReliableWrite_Begin ( cl , svcq2_stufftext , 3 + strlen ( str ) + ( key ? strlen ( key ) + 6 : 0 ) ) ;
else
ClientReliableWrite_Begin ( cl , svc_stufftext , 3 + strlen ( str ) + ( key ? strlen ( key ) + 6 : 0 ) ) ;
if ( key )
{
for ( c = " bind " ; * c ; c + + )
ClientReliableWrite_Byte ( cl , * c ) ;
for ( c = key ; * c ; c + + )
ClientReliableWrite_Byte ( cl , * c ) ;
ClientReliableWrite_Byte ( cl , ' ' ) ;
}
for ( c = str ; * c ; c + + )
ClientReliableWrite_Byte ( cl , * c ) ;
ClientReliableWrite_Byte ( cl , ' \n ' ) ;
ClientReliableWrite_Byte ( cl , ' \0 ' ) ;
}
if ( key )
Z_Free ( key ) ;
}
2009-04-01 22:03:56 +00:00
char * ShowTime ( unsigned int seconds )
{
char buf [ 1024 ] ;
char * b = buf ;
* b = 0 ;
if ( seconds > 60 )
{
if ( seconds > 60 * 60 )
{
if ( seconds > 24 * 60 * 60 )
{
strcpy ( b , va ( " %id " , seconds / ( 24 * 60 * 60 ) ) ) ;
b + = strlen ( b ) ;
seconds % = 24 * 60 * 60 ;
}
strcpy ( b , va ( " %ih " , seconds / ( 60 * 60 ) ) ) ;
b + = strlen ( b ) ;
seconds % = 60 * 60 ;
}
strcpy ( b , va ( " %im " , seconds / 60 ) ) ;
b + = strlen ( b ) ;
seconds % = 60 ;
}
strcpy ( b , va ( " %is " , seconds ) ) ;
b + = strlen ( b ) ;
return va ( " %s " , buf ) ;
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = =
SV_Status_f
= = = = = = = = = = = = = = = =
*/
void SV_Status_f ( void )
{
int i , j , l ;
client_t * cl ;
float cpu , avg , pak ;
char * s ;
2008-06-08 14:37:57 +00:00
char adr [ MAX_ADR_SIZE ] ;
2004-08-23 00:15:46 +00:00
int columns = 80 ;
if ( sv_redirected ! = RD_OBLIVION & & ( sv_redirected ! = RD_NONE
# ifndef SERVERONLY
| | ( vid . width < 68 * 8 & & qrenderer ! = QR_NONE )
# endif
) )
columns = 40 ;
if ( ! sv . state )
{
Con_Printf ( " Server is not running \n " ) ;
return ;
}
if ( Cmd_Argc ( ) > 1 )
columns = atoi ( Cmd_Argv ( 1 ) ) ;
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 ;
2008-11-09 22:29:28 +00:00
NET_PrintAddresses ( svs . sockets ) ;
2005-11-30 01:20:53 +00:00
2004-08-23 00:15:46 +00:00
Con_Printf ( " cpu utilization : %3i%% \n " , ( int ) cpu ) ;
Con_Printf ( " avg response time: %i ms \n " , ( int ) avg ) ;
Con_Printf ( " packets/frame : %5.2f \n " , pak ) ; //not relevent as a limit.
2005-01-04 08:01:03 +00:00
2009-04-01 22:03:56 +00:00
//show the current map+name (but hide name if its too long or would be ugly)
if ( columns > = 80 & & * sv . mapname & & strlen ( sv . mapname ) < 45 & & ! strchr ( sv . mapname , ' \n ' ) )
Con_Printf ( " current map : %s (%s) \n " , sv . name , sv . mapname ) ;
else
Con_Printf ( " current map : %s \n " , sv . name ) ;
Con_Printf ( " map uptime : %s \n " , ShowTime ( sv . physicstime ) ) ;
Con_Printf ( " server uptime : %s \n " , ShowTime ( realtime ) ) ;
if ( sv . csqcdebug )
Con_Printf ( " csqc debug : true \n " ) ;
Con_Printf ( " public : %s \n " , sv_public . value ? " yes " : " no " ) ;
2008-06-01 22:06:22 +00:00
2004-08-23 00:15:46 +00:00
// min fps lat drp
if ( columns < 80 )
{
// 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 - > old_frags ) ;
if ( cl - > spectator )
Con_Printf ( " (s) \n " ) ;
2005-07-03 15:16:20 +00:00
else
2004-08-23 00:15:46 +00:00
Con_Printf ( " \n " ) ;
2005-09-08 01:47:12 +00:00
if ( cl - > istobeloaded & & cl - > state = = cs_zombie )
s = " LoadZombie " ;
else if ( cl - > protocol = = SCP_BAD )
s = " bot " ;
else
2008-06-08 14:37:57 +00:00
s = NET_BaseAdrToString ( adr , sizeof ( adr ) , cl - > netchan . remote_address ) ;
2004-08-23 00:15:46 +00:00
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 dl%% dls \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 - > old_frags , cl - > userid ) ;
if ( cl - > istobeloaded & & cl - > state = = cs_zombie )
s = " LoadZombie " ;
2005-09-08 01:47:12 +00:00
else if ( cl - > protocol = = SCP_BAD )
s = " bot " ;
2004-08-23 00:15:46 +00:00
else
2008-06-08 14:37:57 +00:00
s = NET_BaseAdrToString ( adr , sizeof ( adr ) , cl - > netchan . remote_address ) ;
2004-08-23 00:15:46 +00:00
Con_Printf ( " %s " , s ) ;
l = 16 - strlen ( s ) ;
for ( j = 0 ; j < l ; j + + )
Con_Printf ( " " ) ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
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 " ) ;
}
else if ( cl - > state = = cs_zombie )
{
Con_Printf ( " ZOMBIE " ) ;
}
else
Con_Printf ( " %4i %4i %5.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 - > download )
{
Con_Printf ( " %3i %4i " , ( cl - > downloadcount * 100 ) / cl - > downloadsize , cl - > downloadsize / 1024 ) ;
}
if ( cl - > spectator )
Con_Printf ( " (s) \n " ) ;
2005-07-03 15:16:20 +00:00
else
2004-08-23 00:15:46 +00:00
Con_Printf ( " \n " ) ;
2005-07-03 15:16:20 +00:00
2004-08-23 00:15:46 +00:00
}
}
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_free )
continue ;
SV_ClientPrintf ( client , PRINT_CHAT , " %s \n " , text ) ;
}
if ( sv . mvdrecording )
{
MVDWrite_Begin ( dem_all , 0 , strlen ( text ) + 3 ) ;
MSG_WriteByte ( ( sizebuf_t * ) demo . dbuf , svc_print ) ;
MSG_WriteByte ( ( sizebuf_t * ) demo . dbuf , PRINT_CHAT ) ;
MSG_WriteString ( ( sizebuf_t * ) demo . dbuf , text ) ;
}
}
void SV_ConSayOne_f ( void )
{
char text [ 2048 ] ;
client_t * to ;
int i ;
char * s ;
int clnum = - 1 ;
if ( Cmd_Argc ( ) < 3 )
return ;
while ( ( to = SV_GetClientForString ( Cmd_Argv ( 1 ) , & clnum ) ) )
{
Q_strcpy ( text , " {console}: " ) ;
for ( i = 2 ; ; i + + )
{
s = Cmd_Argv ( i ) ;
if ( ! * s )
break ;
if ( strlen ( text ) + strlen ( s ) + 2 > = sizeof ( text ) - 1 )
break ;
strcat ( text , " " ) ;
strcat ( text , s ) ;
}
strcat ( text , " \n " ) ;
SV_ClientPrintf ( to , PRINT_CHAT , " %s " , text ) ;
}
if ( ! clnum )
Con_TPrintf ( STL_USERDOESNTEXIST , Cmd_Argv ( 1 ) ) ;
}
/*
= = = = = = = = = = = = = = = = = =
SV_Heartbeat_f
= = = = = = = = = = = = = = = = = =
*/
void SV_Heartbeat_f ( void )
{
2009-04-01 22:03:56 +00:00
Master_ReResolve ( ) ;
2004-08-23 00:15:46 +00:00
svs . last_heartbeat = - 9999 ;
}
2005-03-28 00:11:59 +00:00
void SV_SendServerInfoChange ( char * key , const char * value )
2004-08-23 00:15:46 +00:00
{
if ( ! sv . state )
return ;
# ifdef Q2SERVER
if ( ge )
return ; //FIXME!!!
# endif
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 ) ;
2005-10-05 02:44:40 +00:00
extern char * Info_KeyForNumber ( char * s , int num ) ;
2004-08-23 00:15:46 +00:00
void SV_Serverinfo_f ( void )
{
cvar_t * var ;
char value [ 512 ] ;
int i ;
if ( Cmd_Argc ( ) = = 1 )
{
Con_TPrintf ( STL_SERVERINFOSETTINGS ) ;
Info_Print ( svs . info ) ;
return ;
}
if ( Cmd_Argc ( ) < 3 )
{
Con_TPrintf ( STL_SERVERINFOSYNTAX ) ;
return ;
}
if ( Cmd_Argv ( 1 ) [ 0 ] = = ' * ' )
{
2005-10-01 03:09:17 +00:00
if ( ! strcmp ( Cmd_Argv ( 1 ) , " * " ) )
if ( ! strcmp ( Cmd_Argv ( 2 ) , " " ) )
{ //clear it out
char * k ;
for ( i = 0 ; ; )
{
k = Info_KeyForNumber ( svs . info , i ) ;
if ( ! * k )
break ; //no more.
else if ( * k = = ' * ' )
i + + ; //can't remove * keys
else if ( ( var = Cvar_FindVar ( k ) ) & & var - > flags & CVAR_SERVERINFO )
i + + ; //this one is a cvar.
else
Info_RemoveKey ( svs . info , k ) ; //we can remove this one though, so yay.
}
2005-11-03 23:40:51 +00:00
2005-10-01 03:09:17 +00:00
return ;
}
2004-08-23 00:15:46 +00:00
Con_TPrintf ( TL_STARKEYPROTECTED ) ;
return ;
}
Q_strncpyz ( value , Cmd_Argv ( 2 ) , sizeof ( value ) ) ;
value [ sizeof ( value ) - 1 ] = ' \0 ' ;
for ( i = 3 ; i < Cmd_Argc ( ) ; i + + )
{
strncat ( value , " " , sizeof ( value ) - 1 ) ;
strncat ( value , Cmd_Argv ( i ) , sizeof ( value ) - 1 ) ;
}
Info_SetValueForKey ( svs . info , Cmd_Argv ( 1 ) , value , MAX_SERVERINFO_STRING ) ;
2005-07-03 15:16:20 +00:00
// if this is a cvar, change it too
2004-08-23 00:15:46 +00:00
var = Cvar_FindVar ( Cmd_Argv ( 1 ) ) ;
if ( var )
{
Cvar_Set ( var , value ) ;
2005-07-03 15:16:20 +00:00
/* Z_Free (var->string); // free the old value string
2004-08-23 00:15:46 +00:00
var - > string = CopyString ( value ) ;
var - > value = Q_atof ( var - > string ) ;
*/ }
SV_SendServerInfoChange ( Cmd_Argv ( 1 ) , value ) ;
}
/*
= = = = = = = = = = =
SV_Serverinfo_f
Examine or change the serverinfo string
= = = = = = = = = = =
*/
char * CopyString ( char * s ) ;
void SV_Localinfo_f ( void )
{
char * old ;
if ( Cmd_Argc ( ) = = 1 )
{
Con_TPrintf ( STL_LOCALINFOSETTINGS ) ;
Info_Print ( localinfo ) ;
return ;
}
if ( Cmd_Argc ( ) ! = 3 )
{
Con_TPrintf ( STL_LOCALINFOSYNTAX ) ;
return ;
}
if ( Cmd_Argv ( 1 ) [ 0 ] = = ' * ' )
{
2005-10-01 03:09:17 +00:00
if ( ! strcmp ( Cmd_Argv ( 1 ) , " * " ) )
if ( ! strcmp ( Cmd_Argv ( 2 ) , " " ) )
{ //clear it out
Info_RemoveNonStarKeys ( localinfo ) ;
return ;
}
2004-08-23 00:15:46 +00:00
Con_TPrintf ( TL_STARKEYPROTECTED ) ;
return ;
}
old = Info_ValueForKey ( localinfo , Cmd_Argv ( 1 ) ) ;
Info_SetValueForKey ( localinfo , Cmd_Argv ( 1 ) , Cmd_Argv ( 2 ) , MAX_LOCALINFO_STRING ) ;
PR_LocalInfoChanged ( Cmd_Argv ( 1 ) , old , Cmd_Argv ( 2 ) ) ;
2005-07-01 19:23:00 +00:00
Con_DPrintf ( " Localinfo %s changed (%s -> %s) \n " , Cmd_Argv ( 1 ) , old , Cmd_Argv ( 2 ) ) ;
2004-08-23 00:15:46 +00:00
}
2005-12-21 03:07:33 +00:00
void SV_SaveInfos ( vfsfile_t * f )
2004-11-17 17:42:28 +00:00
{
2005-12-21 03:07:33 +00:00
VFS_WRITE ( f , " \n " , 1 ) ;
VFS_WRITE ( f , " serverinfo * \" \" \n " , 16 ) ;
2005-11-30 01:20:53 +00:00
Info_WriteToFile ( f , svs . info , " serverinfo " , CVAR_SERVERINFO ) ;
2005-12-21 03:07:33 +00:00
VFS_WRITE ( f , " \n " , 1 ) ;
VFS_WRITE ( f , " localinfo * \" \" \n " , 15 ) ;
2005-11-30 01:20:53 +00:00
Info_WriteToFile ( f , localinfo , " localinfo " , 0 ) ;
2004-11-17 17:42:28 +00:00
}
2004-08-23 00:15:46 +00:00
2005-09-26 08:07:26 +00:00
/*
void SV_ResetInfos ( void )
{
// TODO: add me
}
*/
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = =
SV_User_f
Examine a users info strings
= = = = = = = = = = =
*/
void SV_User_f ( void )
{
if ( Cmd_Argc ( ) ! = 2 )
{
Con_TPrintf ( STL_USERINFOSYNTAX ) ;
return ;
}
if ( ! SV_SetPlayer ( ) )
return ;
Info_Print ( host_client - > userinfo ) ;
}
/*
= = = = = = = = = = = = = = = =
SV_Floodport_f
Sets the gamedir and path to a different directory .
= = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
SV_Gamedir
Sets the fake * gamedir to a different directory .
= = = = = = = = = = = = = = = =
*/
void SV_Gamedir ( void )
{
char * dir ;
if ( Cmd_Argc ( ) = = 1 )
{
Con_TPrintf ( STL_CURRENTGAMEDIR , Info_ValueForKey ( svs . info , " *gamedir " ) ) ;
return ;
}
if ( Cmd_Argc ( ) ! = 2 )
{
Con_TPrintf ( STL_SVGAMEDIRUSAGE ) ;
return ;
}
dir = Cmd_Argv ( 1 ) ;
if ( strstr ( dir , " .. " ) | | strstr ( dir , " / " )
| | strstr ( dir , " \\ " ) | | strstr ( dir , " : " ) )
{
Con_TPrintf ( STL_GAMEDIRCANTBEPATH ) ;
return ;
}
Info_SetValueForStarKey ( svs . info , " *gamedir " , dir , MAX_SERVERINFO_STRING ) ;
}
/*
= = = = = = = = = = = = = = = =
SV_Gamedir_f
Sets the gamedir and path to a different directory .
= = = = = = = = = = = = = = = =
*/
void SV_Gamedir_f ( void )
{
char * dir ;
if ( Cmd_Argc ( ) = = 1 )
{
2009-04-01 22:03:56 +00:00
Con_TPrintf ( STL_CURRENTGAMEDIR , FS_GetGamedir ( ) ) ;
2004-08-23 00:15:46 +00:00
return ;
}
if ( Cmd_Argc ( ) ! = 2 )
{
Con_TPrintf ( STL_GAMEDIRUSAGE ) ;
return ;
}
dir = Cmd_Argv ( 1 ) ;
if ( strstr ( dir , " .. " ) | | strstr ( dir , " / " )
| | strstr ( dir , " \\ " ) | | strstr ( dir , " : " ) )
{
Con_TPrintf ( STL_GAMEDIRCANTBEPATH ) ;
return ;
}
COM_Gamedir ( dir ) ;
Info_SetValueForStarKey ( svs . info , " *gamedir " , dir , MAX_SERVERINFO_STRING ) ;
}
extern char gamedirfile [ MAX_OSPATH ] ;
/*
= = = = = = = = = = = = = = = =
SV_Snap
= = = = = = = = = = = = = = = =
*/
void SV_Snap ( int uid )
{
client_t * cl ;
2005-07-03 15:16:20 +00:00
char pcxname [ 80 ] ;
2004-08-23 00:15:46 +00:00
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_TPrintf ( STL_USERDOESNTEXIST ) ;
return ;
}
2005-07-01 19:23:00 +00:00
if ( ! ISQWCLIENT ( cl ) )
{
Con_Printf ( " Can only snap QW clients \n " ) ;
return ;
}
2004-08-23 00:15:46 +00:00
sprintf ( pcxname , " %d-00.pcx " , uid ) ;
sprintf ( checkname , " %s/snap " , gamedirfile ) ;
Sys_mkdir ( gamedirfile ) ;
Sys_mkdir ( checkname ) ;
2005-07-03 15:16:20 +00:00
for ( i = 0 ; i < = 99 ; i + + )
{
pcxname [ strlen ( pcxname ) - 6 ] = i / 10 + ' 0 ' ;
pcxname [ strlen ( pcxname ) - 5 ] = i % 10 + ' 0 ' ;
2004-08-23 00:15:46 +00:00
sprintf ( checkname , " %s/snap/%s " , gamedirfile , pcxname ) ;
if ( Sys_FileTime ( checkname ) = = - 1 )
break ; // file doesn't exist
2005-07-03 15:16:20 +00:00
}
if ( i = = 100 )
2004-08-23 00:15:46 +00:00
{
Con_TPrintf ( STL_SNAPTOOMANYFILES ) ;
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 ) ;
2005-07-01 19:23:00 +00:00
ClientReliableWrite_String ( cl , " cmd snap \n " ) ;
2004-08-23 00:15:46 +00:00
Con_TPrintf ( STL_SNAPREQUEST , uid ) ;
}
/*
= = = = = = = = = = = = = = = =
SV_Snap_f
= = = = = = = = = = = = = = = =
*/
void SV_Snap_f ( void )
{
int uid ;
if ( Cmd_Argc ( ) ! = 2 )
{
Con_TPrintf ( STL_SNAPUSAGE ) ;
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 ) ;
}
}
2005-11-29 11:30:13 +00:00
float mytimer ;
2004-08-23 00:15:46 +00:00
float lasttimer ;
int ticsleft ;
float timerinterval ;
int timerlevel ;
cvar_t * timercommand ;
void SV_CheckTimer ( void )
{
float ctime = Sys_DoubleTime ( ) ;
// if (ctime < lasttimer) //new map? (shouldn't happen)
2005-11-29 11:30:13 +00:00
// mytimer = ctime+5; //trigger in a few secs
2004-08-23 00:15:46 +00:00
lasttimer = ctime ;
if ( ticsleft )
{
2005-11-29 11:30:13 +00:00
if ( mytimer < ctime )
2004-08-23 00:15:46 +00:00
{
2005-11-29 11:30:13 +00:00
mytimer + = timerinterval ;
2004-08-23 00:15:46 +00:00
if ( ticsleft > 0 )
ticsleft - - ;
if ( timercommand )
{
Cbuf_AddText ( timercommand - > string , timerlevel ) ;
Cbuf_AddText ( " \n " , timerlevel ) ;
}
}
}
}
void SV_SetTimer_f ( void )
{
int count ;
float interval ;
char * command ;
if ( Cmd_Argc ( ) < 2 )
{
2004-12-21 04:39:47 +00:00
Con_Printf ( " %s <count> <interval> <command> \n " , Cmd_Argv ( 0 ) ) ;
2004-08-23 00:15:46 +00:00
return ;
}
count = atoi ( Cmd_Argv ( 1 ) ) ;
interval = atof ( Cmd_Argv ( 2 ) ) ;
if ( ! count & & Cmd_Argc ( ) = = 2 )
{
ticsleft = 0 ;
return ;
}
if ( interval < = 0 | | ( count < = 0 & & count ! = - 1 ) ) //makes sure the args are right. :)
{
Con_Printf ( " %s count interval command \n " , Cmd_Argv ( 0 ) ) ;
return ;
}
2004-12-08 04:14:52 +00:00
Cmd_ShiftArgs ( 2 , Cmd_ExecLevel = = RESTRICT_LOCAL ) ; //strip the two vars
2004-08-23 00:15:46 +00:00
command = Cmd_Args ( ) ;
timercommand = Cvar_Get ( " sv_timer " , " " , CVAR_NOSET , NULL ) ;
Cvar_ForceSet ( timercommand , command ) ;
2005-11-29 11:30:13 +00:00
mytimer = Sys_DoubleTime ( ) + interval ;
2004-08-23 00:15:46 +00:00
ticsleft = count ;
timerinterval = interval ;
timerlevel = Cmd_ExecLevel ;
}
void SV_SendGameCommand_f ( void )
{
2005-09-08 01:47:12 +00:00
# ifdef Q3SERVER
if ( SVQ3_ConsoleCommand ( ) )
return ;
# endif
2007-09-03 22:37:13 +00:00
# ifdef VM_Q1
if ( Q1QVM_GameConsoleCommand ( ) )
return ;
# endif
2004-08-23 00:15:46 +00:00
# ifdef Q2SERVER
if ( ge )
{
ge - > ServerCommand ( ) ;
}
else
# endif
Con_Printf ( " This command requires a Q2 sever \n " ) ;
}
2005-12-15 19:15:39 +00:00
void PIN_LoadMessages ( void ) ;
void PIN_SaveMessages ( void ) ;
void PIN_DeleteOldestMessage ( void ) ;
void PIN_MakeMessage ( char * from , char * msg ) ;
void SV_Pin_Save_f ( void )
{
PIN_SaveMessages ( ) ;
}
void SV_Pin_Reload_f ( void )
{
PIN_LoadMessages ( ) ;
}
void SV_Pin_Delete_f ( void )
{
PIN_DeleteOldestMessage ( ) ;
}
void SV_Pin_Add_f ( void )
{
2006-02-22 23:31:51 +00:00
PIN_MakeMessage ( Cmd_Argv ( 1 ) , Cmd_Argv ( 2 ) ) ;
2005-12-15 19:15:39 +00:00
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = = = =
SV_InitOperatorCommands
= = = = = = = = = = = = = = = = = =
*/
void SV_InitOperatorCommands ( void )
{
# ifndef SERVERONLY
if ( isDedicated )
# endif
{
Cmd_AddCommand ( " quit " , SV_Quit_f ) ;
Cmd_AddCommand ( " say " , SV_ConSay_f ) ;
Cmd_AddCommand ( " sayone " , SV_ConSayOne_f ) ;
Cmd_AddCommand ( " serverinfo " , SV_Serverinfo_f ) ; //commands that conflict with client commands.
Cmd_AddCommand ( " user " , SV_User_f ) ;
Cmd_AddCommand ( " god " , SV_God_f ) ;
Cmd_AddCommand ( " give " , SV_Give_f ) ;
Cmd_AddCommand ( " noclip " , SV_Noclip_f ) ;
}
Cvar_Register ( & sv_cheats , " Server Permissions " ) ;
if ( COM_CheckParm ( " -cheats " ) )
{
Cvar_Set ( & sv_cheats , " 1 " ) ;
}
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 ( " mute " , SV_Mute_f ) ;
Cmd_AddCommand ( " cuff " , SV_Cuff_f ) ;
Cmd_AddCommand ( " renameclient " , SV_ForceName_f ) ;
Cmd_AddCommand ( " cripple " , SV_CripplePlayer_f ) ;
Cmd_AddCommand ( " banname " , SV_BanName_f ) ;
2006-05-22 22:51:14 +00:00
Cmd_AddCommand ( " banlist " , SV_BanList_f ) ;
2004-08-23 00:15:46 +00:00
Cmd_AddCommand ( " banip " , SV_BanIP_f ) ;
2008-05-25 22:23:43 +00:00
Cmd_AddCommand ( " ban " , SV_BanClientIP_f ) ;
2006-05-22 22:51:14 +00:00
Cmd_AddCommand ( " unban " , SV_Unban_f ) ;
2004-08-23 00:15:46 +00:00
// Cmd_AddCommand ("ban", SV_BanName_f);
Cmd_AddCommand ( " status " , SV_Status_f ) ;
2006-05-25 04:47:03 +00:00
Cmd_AddCommand ( " addip " , SV_FilterIP_f ) ;
Cmd_AddCommand ( " removeip " , SV_Unfilter_f ) ;
Cmd_AddCommand ( " listip " , SV_FilterList_f ) ;
2006-05-29 16:12:21 +00:00
Cmd_AddCommand ( " writeip " , SV_WriteIP_f ) ;
2006-05-25 04:47:03 +00:00
2006-05-30 04:00:24 +00:00
Cmd_AddCommand ( " floodprot " , SV_Floodprot_f ) ;
2006-05-25 04:47:03 +00:00
// Cmd_AddCommand ("filterip", SV_FilterIP_f);
// Cmd_AddCommand ("unfilter", SV_Unfilter_f);
// Cmd_AddCommand ("filterlist", SV_FilterList_f);
// Cmd_AddCommand ("writeip", SV_WriteIP_f);
2004-08-23 00:15:46 +00:00
Cmd_AddCommand ( " sv " , SV_SendGameCommand_f ) ;
2007-09-03 22:37:13 +00:00
Cmd_AddCommand ( " mod " , SV_SendGameCommand_f ) ;
2004-08-23 00:15:46 +00:00
Cmd_AddCommand ( " killserver " , SV_KillServer_f ) ;
Cmd_AddCommand ( " map " , SV_Map_f ) ;
2005-09-08 01:47:12 +00:00
# ifdef Q3SERVER
Cmd_AddCommand ( " spmap " , SV_Map_f ) ;
# endif
2004-08-23 00:15:46 +00:00
Cmd_AddCommand ( " gamemap " , SV_Map_f ) ;
Cmd_AddCommand ( " changelevel " , SV_Map_f ) ;
Cmd_AddCommand ( " listmaps " , SV_MapList_f ) ;
Cmd_AddCommand ( " setmaster " , SV_SetMaster_f ) ;
Cmd_AddCommand ( " heartbeat " , SV_Heartbeat_f ) ;
2005-07-03 15:16:20 +00:00
Cmd_AddCommand ( " localinfo " , SV_Localinfo_f ) ;
2004-08-23 00:15:46 +00:00
Cmd_AddCommand ( " gamedir " , SV_Gamedir_f ) ;
Cmd_AddCommand ( " sv_gamedir " , SV_Gamedir ) ;
Cmd_AddCommand ( " sv_settimer " , SV_SetTimer_f ) ;
Cmd_AddCommand ( " stuffcmd " , SV_StuffToClient_f ) ;
2005-12-15 19:15:39 +00:00
Cmd_AddCommand ( " pin_save " , SV_Pin_Save_f ) ;
Cmd_AddCommand ( " pin_reload " , SV_Pin_Reload_f ) ;
Cmd_AddCommand ( " pin_delete " , SV_Pin_Delete_f ) ;
Cmd_AddCommand ( " pin_add " , SV_Pin_Add_f ) ;
2004-08-23 00:15:46 +00:00
cl_warncmd . value = 1 ;
}
2004-11-29 01:21:00 +00:00
# endif