Skip to content

Commit df3b84b

Browse files
committed
Slight cleanup of CL_GetServerCommand
* Check the accesses to the args more * Comments to explain what it actually does * Make a recursive function instead of an unnecessary goto
1 parent 18c7d57 commit df3b84b

File tree

1 file changed

+95
-97
lines changed

1 file changed

+95
-97
lines changed

src/engine/client/cl_cgame.cpp

Lines changed: 95 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -329,159 +329,157 @@ void CL_ConfigstringModified( Cmd::Args& csCmd )
329329

330330
/*
331331
===================
332+
CL_HandleServerCommand
332333
CL_GetServerCommand
333-
334-
Set up argc/argv for the given command
335334
===================
336335
*/
337-
qboolean CL_GetServerCommand( int serverCommandNumber )
338-
{
339-
const char *s;
340-
const char *cmd;
336+
bool CL_HandleServerCommand(Str::StringRef text) {
341337
static char bigConfigString[ BIG_INFO_STRING ];
342-
int argc;
343-
344-
// if we have irretrievably lost a reliable command, drop the connection
345-
if ( serverCommandNumber <= clc.serverCommandSequence - MAX_RELIABLE_COMMANDS )
346-
{
347-
// when a demo record was started after the client got a whole bunch of
348-
// reliable commands then the client never got those first reliable commands
349-
if ( clc.demoplaying )
350-
{
351-
return qfalse;
352-
}
353-
354-
Com_Error( ERR_DROP, "CL_GetServerCommand: a reliable command was cycled out" );
355-
}
356-
357-
if ( serverCommandNumber > clc.serverCommandSequence )
358-
{
359-
Com_Error( ERR_DROP, "CL_GetServerCommand: requested a command not received" );
360-
}
361-
362-
s = clc.serverCommands[ serverCommandNumber & ( MAX_RELIABLE_COMMANDS - 1 ) ];
363-
clc.lastExecutedServerCommand = serverCommandNumber;
364-
365-
if ( cl_showServerCommands->integer )
366-
{
367-
// NERVE - SMF
368-
Com_Printf( "serverCommand: %i : %s\n", serverCommandNumber, s );
369-
}
370-
371-
rescan:
372-
Cmd_TokenizeString( s );
373-
Cmd::Args args(s);
338+
Cmd::Args args(text);
374339

375340
if (args.Argc() == 0) {
376341
return qfalse;
377342
}
378343

379-
cmd = args[0].c_str();
380-
argc = args.size();
344+
auto cmd = args.Argv(0);
345+
int argc = args.Argc();
381346

382-
if ( !strcmp( cmd, "disconnect" ) )
383-
{
347+
if (cmd == "disconnect") {
384348
// NERVE - SMF - allow server to indicate why they were disconnected
385-
if ( argc >= 2 )
386-
{
387-
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected: %s", args[1].c_str() );
388-
}
389-
else
390-
{
391-
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected" );
349+
if (argc >= 2) {
350+
Com_Error(ERR_SERVERDISCONNECT, "Server disconnected: %s", args.Argv(1).c_str());
351+
} else {
352+
Com_Error(ERR_SERVERDISCONNECT, "Server disconnected");
392353
}
393354
}
394355

395-
if ( !strcmp( cmd, "bcs0" ) )
396-
{
397-
Com_sprintf( bigConfigString, BIG_INFO_STRING, "cs %s %s", args[1].c_str(), Cmd_QuoteString( args[2].c_str() ) );
356+
// bcs0 to bcs2 are used by the server to send info strings that are bigger than the size of a packet.
357+
// See also SV_UpdateConfigStrings
358+
// bcs0 starts a new big config string
359+
// bcs1 continues it
360+
// bcs2 finishes it and feeds it back as a new command sent by the server (bcs0 makes it a cs command)
361+
if (cmd == "bcs0") {
362+
if (argc >= 3) {
363+
Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s %s", args.Argv(1).c_str(), args.EscapedArgs(2).c_str());
364+
}
398365
return qfalse;
399366
}
400367

401-
if ( !strcmp( cmd, "bcs1" ) )
402-
{
403-
s = Cmd_QuoteString( args[2].c_str() );
368+
if (cmd == "bcs1") {
369+
if (argc >= 3) {
370+
const char* s = Cmd_QuoteString( args[2].c_str() );
404371

405-
if ( strlen( bigConfigString ) + strlen( s ) >= BIG_INFO_STRING )
406-
{
407-
Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" );
408-
}
372+
if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) {
373+
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
374+
}
409375

410-
Q_strcat( bigConfigString, sizeof( bigConfigString ), s );
376+
Q_strcat(bigConfigString, sizeof(bigConfigString), s);
377+
}
411378
return qfalse;
412379
}
413380

414-
if ( !strcmp( cmd, "bcs2" ) )
415-
{
416-
s = Cmd_QuoteString( args[2].c_str() );
381+
if (cmd == "bcs2") {
382+
if (argc >= 3) {
383+
const char* s = Cmd_QuoteString( args[2].c_str() );
417384

418-
if ( strlen( bigConfigString ) + strlen( s ) + 1 >= BIG_INFO_STRING )
419-
{
420-
Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" );
421-
}
385+
if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) {
386+
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
387+
}
422388

423-
Q_strcat( bigConfigString, sizeof( bigConfigString ), s );
424-
Q_strcat( bigConfigString, sizeof( bigConfigString ), "\"" );
425-
s = bigConfigString;
426-
goto rescan;
389+
Q_strcat(bigConfigString, sizeof(bigConfigString), s);
390+
Q_strcat(bigConfigString, sizeof(bigConfigString), "\"");
391+
return CL_HandleServerCommand(bigConfigString);
392+
}
393+
return qfalse;
427394
}
428395

429-
if ( !strcmp( cmd, "cs" ) )
430-
{
396+
if (cmd == "cs") {
431397
CL_ConfigstringModified(args);
432-
Cmd_TokenizeString( s );
398+
Cmd_TokenizeString(text.c_str());
433399
return qtrue;
434400
}
435401

436-
if ( !strcmp( cmd, "map_restart" ) )
437-
{
402+
if (cmd == "map_restart") {
438403
// clear outgoing commands before passing
439404
// the restart to the cgame
440-
memset( cl.cmds, 0, sizeof( cl.cmds ) );
405+
memset(cl.cmds, 0, sizeof(cl.cmds));
406+
Cmd_TokenizeString(text.c_str());
441407
return qtrue;
442408
}
443409

444-
if ( !strcmp( cmd, "popup" ) )
445-
{
410+
if (cmd == "popup") {
446411
// direct server to client popup request, bypassing cgame
447-
if ( cls.state == CA_ACTIVE && !clc.demoplaying )
448-
{
449-
Rocket_DocumentAction( Cmd_Argv(1), "open" );
412+
if (cls.state == CA_ACTIVE && !clc.demoplaying && argc >=1) {
413+
Rocket_DocumentAction(args.Argv(1).c_str(), "open");
450414
}
451415
return qfalse;
452416
}
453417

454-
if ( !strcmp( cmd, "pubkey_decrypt" ) )
455-
{
418+
if (cmd == "pubkey_decrypt") {
456419
char buffer[ MAX_STRING_CHARS ] = "pubkey_identify ";
457420
unsigned int msg_len = MAX_STRING_CHARS - 16;
458421
mpz_t message;
459422

460-
if ( argc == 1 )
461-
{
462-
Com_Printf("%s", _( "^3Server sent a pubkey_decrypt command, but sent nothing to decrypt!\n" ));
423+
if (argc == 1) {
424+
Com_Printf("%s", _("^3Server sent a pubkey_decrypt command, but sent nothing to decrypt!\n"));
463425
return qfalse;
464426
}
465427

466-
mpz_init_set_str( message, Cmd_Argv( 1 ), 16 );
428+
mpz_init_set_str(message, args.Argv(1).c_str(), 16);
467429

468-
if ( rsa_decrypt( &private_key, &msg_len, ( unsigned char * ) buffer + 16, message ) )
469-
{
470-
nettle_mpz_set_str_256_u( message, msg_len, ( unsigned char * ) buffer + 16 );
471-
mpz_get_str( buffer + 16, 16, message );
472-
CL_AddReliableCommand( buffer );
430+
if (rsa_decrypt(&private_key, &msg_len, (unsigned char *) buffer + 16, message)) {
431+
nettle_mpz_set_str_256_u(message, msg_len, (unsigned char *) buffer + 16);
432+
mpz_get_str(buffer + 16, 16, message);
433+
CL_AddReliableCommand(buffer);
473434
}
474435

475-
mpz_clear( message );
436+
mpz_clear(message);
476437
return qfalse;
477438
}
478439

479-
// we may want to put a "connect to other server" command here
480-
481-
// cgame can now act on the command
440+
Cmd_TokenizeString(text.c_str());
482441
return qtrue;
483442
}
484443

444+
// Get the server command, does client-specific handling
445+
// that may block the propagation of the command to cgame.
446+
// If the propagation is not blocked then it tokenizes the
447+
// command.
448+
// Returns false if the command was blacked.
449+
qboolean CL_GetServerCommand( int serverCommandNumber )
450+
{
451+
const char *s;
452+
453+
// if we have irretrievably lost a reliable command, drop the connection
454+
if ( serverCommandNumber <= clc.serverCommandSequence - MAX_RELIABLE_COMMANDS )
455+
{
456+
// when a demo record was started after the client got a whole bunch of
457+
// reliable commands then the client never got those first reliable commands
458+
if ( clc.demoplaying )
459+
{
460+
return qfalse;
461+
}
462+
463+
Com_Error( ERR_DROP, "CL_GetServerCommand: a reliable command was cycled out" );
464+
}
465+
466+
if ( serverCommandNumber > clc.serverCommandSequence )
467+
{
468+
Com_Error( ERR_DROP, "CL_GetServerCommand: requested a command not received" );
469+
}
470+
471+
s = clc.serverCommands[ serverCommandNumber & ( MAX_RELIABLE_COMMANDS - 1 ) ];
472+
clc.lastExecutedServerCommand = serverCommandNumber;
473+
474+
if ( cl_showServerCommands->integer )
475+
{
476+
// NERVE - SMF
477+
Com_Printf( "serverCommand: %i : %s\n", serverCommandNumber, s );
478+
}
479+
480+
return CL_HandleServerCommand(s);
481+
}
482+
485483
// DHM - Nerve :: Copied from server to here
486484

487485
/*

0 commit comments

Comments
 (0)