diff options
-rw-r--r-- | src/game/g_admin.c | 2 | ||||
-rw-r--r-- | src/game/g_cmds.c | 47 | ||||
-rw-r--r-- | src/game/g_local.h | 1 | ||||
-rw-r--r-- | src/game/g_svcmds.c | 24 |
4 files changed, 73 insertions, 1 deletions
diff --git a/src/game/g_admin.c b/src/game/g_admin.c index 59d89dc4..badf49aa 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -707,7 +707,7 @@ static void admin_log( gentity_t *admin, char *cmd ) ( admin && admin->client->pers.admin ) ? admin->client->pers.admin->level : 0, cmd, - ConcatArgs( args ) ); + ConcatArgsPrintable( args ) ); } struct llist diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 68a251b9..c0476dae 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -332,6 +332,53 @@ char *ConcatArgs( int start ) return line; } +/* +================== +ConcatArgsPrintable +Duplicate of concatargs but enquotes things that need to be +Used to log command arguments in a way that preserves user intended tokenizing +================== +*/ +char *ConcatArgsPrintable( int start ) +{ + int i, c, tlen; + static char line[ MAX_STRING_CHARS ]; + int len; + char arg[ MAX_STRING_CHARS + 2 ]; + char *printArg; + + len = 0; + c = trap_Argc( ); + + for( i = start; i < c; i++ ) + { + printArg = arg; + trap_Argv( i, arg, sizeof( arg ) ); + if( strchr( arg, ' ' ) ) + printArg = va( "\"%s\"", arg ); + tlen = strlen( printArg ); + + if( len + tlen >= MAX_STRING_CHARS - 1 ) + break; + + memcpy( line + len, printArg, tlen ); + len += tlen; + + if( len == MAX_STRING_CHARS - 1 ) + break; + + if( i != c - 1 ) + { + line[ len ] = ' '; + len++; + } + } + + line[ len ] = 0; + + return line; +} + /* ================== diff --git a/src/game/g_local.h b/src/game/g_local.h index 52f4cb11..703e305e 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -719,6 +719,7 @@ void G_ToggleFollow( gentity_t *ent ); int G_ClientNumberFromString( char *s, char *err, int len ); int G_ClientNumbersFromString( char *s, int *plist, int max ); char *ConcatArgs( int start ); +char *ConcatArgsPrintable( int start ); void G_Say( gentity_t *ent, saymode_t mode, const char *chatText ); void G_DecolorString( char *in, char *out, int len ); void G_UnEscapeString( char *in, char *out, int len ); diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c index 9338766f..382b7c47 100644 --- a/src/game/g_svcmds.c +++ b/src/game/g_svcmds.c @@ -449,6 +449,29 @@ static void Svcmd_DumpUser_f( void ) } } +static void Svcmd_Pr_f( void ) +{ + char targ[ 4 ]; + int cl; + + if( trap_Argc( ) < 3 ) + { + G_Printf( "usage: <clientnum|-1> <message>\n" ); + return; + } + + trap_Argv( 1, targ, sizeof( targ ) ); + cl = atoi( targ ); + + if( cl >= MAX_CLIENTS || cl < -1 ) + { + G_Printf( "invalid clientnum %d\n", cl ); + return; + } + + trap_SendServerCommand( cl, va( "print \"%s\n\"", ConcatArgs( 2 ) ) ); +} + static void Svcmd_PrintQueue_f( void ) { char team[ MAX_STRING_CHARS ]; @@ -540,6 +563,7 @@ struct svcmd { "loadcensors", qfalse, G_LoadCensors }, { "m", qtrue, Svcmd_MessageWrapper }, { "mapRotation", qfalse, Svcmd_MapRotation_f }, + { "pr", qfalse, Svcmd_Pr_f }, { "printqueue", qfalse, Svcmd_PrintQueue_f }, { "say", qtrue, Svcmd_MessageWrapper }, { "say_team", qtrue, Svcmd_TeamMessage_f }, |