mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2025-01-11 02:45:46 +01:00
engine: add stuffcmd filtering, not wired to ClientCmd yet
This commit is contained in:
parent
6c9321e50c
commit
1a1d81de62
@ -30,11 +30,15 @@ typedef struct
|
||||
} cmdbuf_t;
|
||||
|
||||
qboolean cmd_wait;
|
||||
cmdbuf_t cmd_text;
|
||||
cmdbuf_t cmd_text, filteredcmd_text;
|
||||
byte cmd_text_buf[MAX_CMD_BUFFER];
|
||||
byte filteredcmd_text_buf[MAX_CMD_BUFFER];
|
||||
cmdalias_t *cmd_alias;
|
||||
uint cmd_condition;
|
||||
int cmd_condlevel;
|
||||
static qboolean cmd_currentCommandIsPrivileged;
|
||||
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
@ -52,8 +56,10 @@ Cbuf_Init
|
||||
void Cbuf_Init( void )
|
||||
{
|
||||
cmd_text.data = cmd_text_buf;
|
||||
cmd_text.maxsize = MAX_CMD_BUFFER;
|
||||
cmd_text.cursize = 0;
|
||||
filteredcmd_text.data = filteredcmd_text_buf;
|
||||
|
||||
filteredcmd_text.maxsize = cmd_text.maxsize = MAX_CMD_BUFFER;
|
||||
filteredcmd_text.cursize = cmd_text.cursize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -63,8 +69,9 @@ Cbuf_Clear
|
||||
*/
|
||||
void Cbuf_Clear( void )
|
||||
{
|
||||
memset( cmd_text.data, 0, sizeof( cmd_text_buf ));
|
||||
cmd_text.cursize = 0;
|
||||
memset( cmd_text.data, 0, cmd_text.maxsize );
|
||||
memset( filteredcmd_text.data, 0, filteredcmd_text.maxsize );
|
||||
cmd_text.cursize = filteredcmd_text.cursize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -88,6 +95,19 @@ void *Cbuf_GetSpace( cmdbuf_t *buf, int length )
|
||||
return data;
|
||||
}
|
||||
|
||||
static void Cbuf_AddTextToBuffer( cmdbuf_t *buf, const char *text )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
|
||||
if(( buf->cursize + l ) >= buf->maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "%s: overflow\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy( Cbuf_GetSpace( buf, l ), text, l );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_AddText
|
||||
@ -97,16 +117,17 @@ Adds command text at the end of the buffer
|
||||
*/
|
||||
void Cbuf_AddText( const char *text )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
Cbuf_AddTextToBuffer( &cmd_text, text );
|
||||
}
|
||||
|
||||
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "Cbuf_AddText: overflow\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( Cbuf_GetSpace( &cmd_text, l ), text, l );
|
||||
}
|
||||
/*
|
||||
============
|
||||
Cbuf_AddFilteredText
|
||||
============
|
||||
*/
|
||||
void Cbuf_AddFilteredText( const char *text )
|
||||
{
|
||||
Cbuf_AddTextToBuffer( &filteredcmd_text, text );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -117,43 +138,55 @@ Adds command text immediately after the current command
|
||||
Adds a \n to the text
|
||||
============
|
||||
*/
|
||||
void Cbuf_InsertText( const char *text )
|
||||
static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
|
||||
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
|
||||
if(( buf->cursize + l ) >= buf->maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "Cbuf_InsertText: overflow\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove( cmd_text.data + l, cmd_text.data, cmd_text.cursize );
|
||||
memcpy( cmd_text.data, text, l );
|
||||
cmd_text.cursize += l;
|
||||
memmove( buf->data + l, buf->data, buf->cursize );
|
||||
memcpy( buf->data, text, l );
|
||||
buf->cursize += l;
|
||||
}
|
||||
}
|
||||
|
||||
void Cbuf_InsertText( const char *text )
|
||||
{
|
||||
Cbuf_InsertTextToBuffer( &cmd_text, text );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Execute
|
||||
============
|
||||
*/
|
||||
void Cbuf_Execute( void )
|
||||
void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int cmdsToExecute )
|
||||
{
|
||||
char *text;
|
||||
char line[MAX_CMD_LINE];
|
||||
int i, quotes;
|
||||
char *comment;
|
||||
|
||||
while( cmd_text.cursize )
|
||||
while( buf->cursize )
|
||||
{
|
||||
// limit amount of commands that can be issued
|
||||
if( cmdsToExecute >= 0 )
|
||||
{
|
||||
if( !cmdsToExecute-- )
|
||||
break;
|
||||
}
|
||||
|
||||
// find a \n or ; line break
|
||||
text = (char *)cmd_text.data;
|
||||
text = (char *)buf->data;
|
||||
|
||||
quotes = false;
|
||||
comment = NULL;
|
||||
|
||||
for( i = 0; i < cmd_text.cursize; i++ )
|
||||
for( i = 0; i < buf->cursize; i++ )
|
||||
{
|
||||
if( !comment )
|
||||
{
|
||||
@ -162,7 +195,7 @@ void Cbuf_Execute( void )
|
||||
if( quotes )
|
||||
{
|
||||
// make sure i doesn't get > cursize which causes a negative size in memmove, which is fatal --blub
|
||||
if( i < ( cmd_text.cursize - 1 ) && ( text[i+0] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
|
||||
if( i < ( buf->cursize - 1 ) && ( text[i+0] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
|
||||
i++;
|
||||
}
|
||||
else
|
||||
@ -191,19 +224,19 @@ void Cbuf_Execute( void )
|
||||
// delete the text from the command buffer and move remaining commands down
|
||||
// this is necessary because commands (exec) can insert data at the
|
||||
// beginning of the text buffer
|
||||
if( i == cmd_text.cursize )
|
||||
if( i == buf->cursize )
|
||||
{
|
||||
cmd_text.cursize = 0;
|
||||
buf->cursize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
cmd_text.cursize -= i;
|
||||
memmove( cmd_text.data, text + i, cmd_text.cursize );
|
||||
buf->cursize -= i;
|
||||
memmove( buf->data, text + i, buf->cursize );
|
||||
}
|
||||
|
||||
// execute the command line
|
||||
Cmd_ExecuteString( line );
|
||||
Cmd_ExecuteStringWithPrivilegeCheck( line, isPrivileged );
|
||||
|
||||
if( cmd_wait )
|
||||
{
|
||||
@ -215,6 +248,17 @@ void Cbuf_Execute( void )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Execute
|
||||
============
|
||||
*/
|
||||
void Cbuf_Execute( void )
|
||||
{
|
||||
Cbuf_ExecuteCommandsFromBuffer( &cmd_text, true, -1 );
|
||||
Cbuf_ExecuteCommandsFromBuffer( &filteredcmd_text, false, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cbuf_ExecStuffCmds
|
||||
@ -282,6 +326,11 @@ void Cbuf_ExecStuffCmds( void )
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
qboolean Cmd_CurrentCommandIsPrivileged( void )
|
||||
{
|
||||
return cmd_currentCommandIsPrivileged;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_StuffCmds_f
|
||||
@ -876,6 +925,32 @@ void Cmd_Else_f( void )
|
||||
cmd_condition ^= BIT( cmd_condlevel );
|
||||
}
|
||||
|
||||
static qboolean Cmd_ShouldAllowCommand( cmd_t *cmd, qboolean isPrivileged )
|
||||
{
|
||||
const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_" };
|
||||
int i;
|
||||
|
||||
// always allow local commands
|
||||
if( isPrivileged )
|
||||
return true;
|
||||
|
||||
// never allow local only commands from remote
|
||||
if( FBitSet( cmd->flags, CMD_LOCALONLY ))
|
||||
return false;
|
||||
|
||||
// allow engine commands if user don't mind
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( prefixes ); i++ )
|
||||
{
|
||||
if( !Q_stricmp( cmd->name, prefixes[i] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_ExecuteString
|
||||
@ -883,7 +958,7 @@ Cmd_ExecuteString
|
||||
A complete command line has been parsed, so try to execute it
|
||||
============
|
||||
*/
|
||||
void Cmd_ExecuteString( const char *text )
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged )
|
||||
{
|
||||
cmd_t *cmd = NULL;
|
||||
cmdalias_t *a = NULL;
|
||||
@ -952,44 +1027,56 @@ void Cmd_ExecuteString( const char *text )
|
||||
if( !host.apply_game_config )
|
||||
{
|
||||
// check aliases
|
||||
if( a ) // already found in basecmd
|
||||
if( !a ) // if not found in basecmd
|
||||
{
|
||||
Cbuf_InsertText( a->value );
|
||||
return;
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
if( a )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
{
|
||||
Cbuf_InsertText( a->value );
|
||||
return;
|
||||
}
|
||||
Cbuf_InsertTextToBuffer(
|
||||
isPrivileged ? &cmd_text : &filteredcmd_text,
|
||||
a->value );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// special mode for restore game.dll archived cvars
|
||||
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
|
||||
{
|
||||
// check functions
|
||||
if( cmd && cmd->function ) // already found in basecmd
|
||||
if( !cmd || !cmd->function ) // if not found in basecmd
|
||||
{
|
||||
cmd->function();
|
||||
return;
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
// check functions
|
||||
if( cmd && cmd->function )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
if( Cmd_ShouldAllowCommand( cmd, isPrivileged ))
|
||||
{
|
||||
cmd_currentCommandIsPrivileged = isPrivileged;
|
||||
cmd->function();
|
||||
return;
|
||||
cmd_currentCommandIsPrivileged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "Could not execute privileged command %s\n", cmd->name );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check cvars
|
||||
if( Cvar_Command( cvar )) return;
|
||||
if( Cvar_CommandWithPrivilegeCheck( cvar, isPrivileged )) return;
|
||||
|
||||
if( host.apply_game_config )
|
||||
return; // don't send nothing to server: we is a server!
|
||||
@ -1011,6 +1098,11 @@ void Cmd_ExecuteString( const char *text )
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_ExecuteString( const char *text )
|
||||
{
|
||||
Cmd_ExecuteStringWithPrivilegeCheck( text, true );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Cmd_ForwardToServer
|
||||
|
@ -184,6 +184,7 @@ extern convar_t host_developer;
|
||||
extern convar_t *host_limitlocal;
|
||||
extern convar_t *host_framerate;
|
||||
extern convar_t *host_maxfps;
|
||||
extern convar_t cl_filterstuffcmd;
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
@ -465,7 +466,7 @@ extern sysinfo_t SI;
|
||||
#define CMD_CLIENTDLL BIT( 1 ) // added by client.dll
|
||||
#define CMD_GAMEUIDLL BIT( 2 ) // added by GameUI.dll
|
||||
#define CMD_LOCALONLY BIT( 3 ) // restricted from server commands
|
||||
#define CMD_REFDLL BIT( 4 ) // added by ref.dll
|
||||
#define CMD_REFDLL BIT( 4 ) // added by ref.dll
|
||||
|
||||
typedef void (*xcommand_t)( void );
|
||||
|
||||
|
@ -16,6 +16,7 @@ GNU General Public License for more details.
|
||||
#include <math.h> // fabs...
|
||||
#include "common.h"
|
||||
#include "base_cmd.h"
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cmd_scripting;
|
||||
@ -754,6 +755,38 @@ static void Cvar_SetGL( const char *name, const char *value )
|
||||
Cvar_FullSet( name, value, FCVAR_GLCONFIG );
|
||||
}
|
||||
|
||||
static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
{
|
||||
const char *prefixes[] = { "cl_", "gl_", "m_", "r_", "hud_" };
|
||||
int i;
|
||||
|
||||
if( isPrivileged )
|
||||
return true;
|
||||
|
||||
// TODO: figure this out
|
||||
//if( v->flags & FCVAR_SERVER )
|
||||
// return false;
|
||||
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
// TODO: figure this out too
|
||||
//if( v->flags & FCVAR_EXTDLL )
|
||||
// return false;
|
||||
|
||||
// a1ba: xash3d-fwgs extension
|
||||
if( v->flags & FCVAR_LOCALONLY )
|
||||
return false;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( prefixes ); i++ )
|
||||
{
|
||||
if( Q_stricmp( v->name, prefixes[i] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Command
|
||||
@ -761,7 +794,7 @@ Cvar_Command
|
||||
Handles variable inspection and changing from the console
|
||||
============
|
||||
*/
|
||||
qboolean Cvar_Command( convar_t *v )
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
|
||||
{
|
||||
// special case for setup opengl configuration
|
||||
if( host.apply_opengl_config )
|
||||
@ -773,7 +806,8 @@ qboolean Cvar_Command( convar_t *v )
|
||||
// check variables
|
||||
if( !v ) // already found in basecmd
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
if( !v ) return false;
|
||||
if( !v )
|
||||
return false;
|
||||
|
||||
// perform a variable print or set
|
||||
if( Cmd_Argc() == 1 )
|
||||
@ -796,6 +830,11 @@ qboolean Cvar_Command( convar_t *v )
|
||||
Con_Printf( "can't set \"%s\" in multiplayer\n", v->name );
|
||||
return false;
|
||||
}
|
||||
else if( !Cvar_ShouldSetCvar( v, isPrivileged ))
|
||||
{
|
||||
Con_Printf( "%s is a privileged variable\n", v->name );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_DirectSet( v, Cmd_Argv( 1 ));
|
||||
|
@ -75,7 +75,7 @@ void Cvar_WriteVariables( file_t *f, int group );
|
||||
qboolean Cvar_Exists( const char *var_name );
|
||||
void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_Command( convar_t *v );
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
|
@ -52,6 +52,7 @@ struct tests_stats_s tests_stats;
|
||||
|
||||
CVAR_DEFINE( host_developer, "developer", "0", 0, "engine is in development-mode" );
|
||||
CVAR_DEFINE_AUTO( sys_ticrate, "100", 0, "framerate in dedicated mode" );
|
||||
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_LOCALONLY, "filter commands coming from server" );
|
||||
|
||||
convar_t *host_serverstate;
|
||||
convar_t *host_gameloaded;
|
||||
@ -1051,6 +1052,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cmd_AddCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
|
||||
}
|
||||
|
||||
Cvar_RegisterVariable( &cl_filterstuffcmd );
|
||||
host_serverstate = Cvar_Get( "host_serverstate", "0", FCVAR_READ_ONLY, "displays current server state" );
|
||||
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE, "host fps upper limit" );
|
||||
host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" );
|
||||
|
Loading…
Reference in New Issue
Block a user