/* ============ Cvar_Command Handles variable inspection and changing from the console ============ */ qboolean Cvar_Command( void ) { cvar_t *v; // check variables v = Cvar_FindVar( Cmd_Argv( 0 ) ); if ( !v ) { return qfalse; } // perform a variable print or set if ( Cmd_Argc() == 1 ) { Com_Printf( _("\"%s\" is \"%s^7\" default: \"%s^7\"\n"), v->name, v->string, v->resetString ); if ( v->latchedString ) { Com_Printf( _("latched: \"%s\"\n"), v->latchedString ); } return qtrue; } // set the value if forcing isn't required Cvar_Set2( v->name, Cmd_UnquoteString( Cmd_Args() ), qfalse ); return qtrue; }
/* ================= SV_SendServerCommand Sends a reliable command string to be interpreted by the client game module: "cp", "print", "chat", etc A nullptr client will broadcast to all clients ================= */ void QDECL PRINTF_LIKE(2) SV_SendServerCommand( client_t *cl, const char *fmt, ... ) { va_list argptr; byte message[ MAX_MSGLEN ]; client_t *client; int j; va_start( argptr, fmt ); Q_vsnprintf( ( char * ) message, sizeof( message ), fmt, argptr ); va_end( argptr ); // do not forward server command messages that would be too big to clients // ( q3infoboom / q3msgboom stuff ) if ( strlen( ( char * ) message ) > 1022 ) { return; } if ( cl != nullptr ) { SV_AddServerCommand( cl, ( char * ) message ); return; } if ( Com_IsDedicatedServer() ) { if ( !strncmp( ( char * ) message, "print_tr_p ", 11 ) ) { SV_PrintTranslatedText( ( const char * ) message, true, true ); } else if ( !strncmp( ( char * ) message, "print_tr ", 9 ) ) { SV_PrintTranslatedText( ( const char * ) message, true, false ); } // hack to echo broadcast prints to console else if ( !strncmp( ( char * ) message, "print ", 6 ) ) { Com_Printf( "Broadcast: %s", Cmd_UnquoteString( ( char * ) message + 6 ) ); } } // send the data to all relevent clients for ( j = 0, client = svs.clients; j < sv_maxclients->integer; j++, client++ ) { if ( client->state < CS_PRIMED ) { continue; } // Ridah, don't need to send messages to AI if ( SV_IsBot(client) ) { continue; } // done. SV_AddServerCommand( client, ( char * ) message ); } }
/* ================== SV_Map_f Restart the server on a different map ================== */ static void SV_Map_f( void ) { char *cmd; char *map; const char *layouts; char mapname[ MAX_QPATH ]; qboolean cheat; char expanded[ MAX_QPATH ]; char layout[ MAX_CVAR_VALUE_STRING ]; map = Cmd_Argv( 1 ); if ( !map ) { return; } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game Com_sprintf( expanded, sizeof( expanded ), "maps/%s.bsp", map ); if ( FS_ReadFile( expanded, NULL ) == -1 ) { Com_Printf(_( "Can't find map %s\n"), expanded ); return; } // layout(s) - note that ArgsFrom adds quoting which we don't want here // Also, if empty, don't override layouts = Cmd_UnquoteString( Cmd_ArgsFrom( 2 ) ); if ( *layouts ) { Cvar_Set( "g_layouts", layouts ); } cheat = !Q_stricmp( Cmd_Argv( 0 ), "devmap" ); // save the map name here cause on a map restart we reload the q3config.cfg // and thus nuke the arguments of the map command Q_strncpyz( mapname, map, sizeof( mapname ) ); // start up the map SV_SpawnServer( mapname ); // set the cheat value // if the level was started with "map <levelname>", then // cheats will not be allowed. If started with "devmap <levelname>" // then cheats will be allowed Cvar_Set( "sv_cheats", cheat ? "1" : "0" ); }
/* ============ Cvar_Set_f Allows setting and defining of arbitrary cvars from console, even if they weren't declared in C code. ============ */ void Cvar_Set_f( void ) { int c, unsafe = 0; char *value; c = Cmd_Argc(); if ( c < 3 ) { Cmd_PrintUsage(_("<variable> <value> [unsafe]"), NULL); return; } // ydnar: handle unsafe vars if ( c >= 4 && !strcmp( Cmd_Argv( c - 1 ), "unsafe" ) ) { c--; unsafe = 1; if ( com_crashed != NULL && com_crashed->integer ) { Com_Printf(_( "%s is unsafe. Check com_crashed.\n"), Cmd_Argv( 1 ) ); return; } } value = strdup( Cmd_Cmd_FromNth( 2 ) ); // 3rd arg onwards, raw if ( unsafe ) { char *end = value + strlen( value ); // skip spaces while ( --end > value ) { if ( *end != ' ' ) { break; } } ++end; // skip "unsafe" (may be quoted, so just scan it) while ( --end > value ) { if ( *end == ' ' ) { break; } } ++end; // skip spaces while ( --end > value ) { if ( *end != ' ' ) { break; } } end[ 1 ] = 0; // end of string :-) } Cvar_Set2( Cmd_Argv( 1 ), Cmd_UnquoteString( value ), qfalse ); free( value ); }