diff --git a/src/engine/client/cl_cgame.cpp b/src/engine/client/cl_cgame.cpp index b5d30a389f..74a668f417 100644 --- a/src/engine/client/cl_cgame.cpp +++ b/src/engine/client/cl_cgame.cpp @@ -694,7 +694,7 @@ void CL_AdjustTimeDelta() // if the current time is WAY off, just correct to the current value /* - if(com_sv_running->integer) + if(com_sv_running.Get()) { resetTime = 100; } diff --git a/src/engine/client/cl_main.cpp b/src/engine/client/cl_main.cpp index c073c081d0..e8f2f6c379 100644 --- a/src/engine/client/cl_main.cpp +++ b/src/engine/client/cl_main.cpp @@ -689,7 +689,7 @@ void CL_ShutdownAll() // Gordon: stop recording on map change etc, demos aren't valid over map changes anyway CL_StopRecord(); - if ( !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { void SV_ShutdownGameProgs(); SV_ShutdownGameProgs(); @@ -1014,7 +1014,7 @@ void CL_Connect_f() // clear any previous "server full" type messages clc.serverMessage[ 0 ] = 0; - if ( com_sv_running->integer && !strcmp( server, "loopback" ) ) + if ( com_sv_running.Get() && !strcmp( server, "loopback" ) ) { // if running a local server, kill it SV_Shutdown( "Server quit" ); @@ -2376,7 +2376,7 @@ void CL_Init() cl_altTab = Cvar_Get( "cl_altTab", "1", 0 ); // userinfo - cl_rate = Cvar_Get( "rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE ); + cl_rate = Cvar_Get( "rate", XSTRING(NETWORK_DEFAULT_RATE), CVAR_USERINFO | CVAR_ARCHIVE); #if defined(USE_MUMBLE) cl_useMumble = Cvar_Get( "cl_useMumble", "0", CVAR_LATCH ); diff --git a/src/engine/client/cl_parse.cpp b/src/engine/client/cl_parse.cpp index abb8b40a3c..bc47793be0 100644 --- a/src/engine/client/cl_parse.cpp +++ b/src/engine/client/cl_parse.cpp @@ -352,7 +352,7 @@ void CL_SystemInfoChanged() cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); // load paks sent by the server, but not if we are running a local server - if (!com_sv_running->integer) { + if (!com_sv_running.Get()) { FS::PakPath::ClearPaks(); if (!FS_LoadServerPaks(Info_ValueForKey(systemInfo, "sv_paks"), clc.demoplaying)) { if (!cl_allowDownload->integer) { diff --git a/src/engine/client/cl_scrn.cpp b/src/engine/client/cl_scrn.cpp index 4b4035315d..66b50a646e 100644 --- a/src/engine/client/cl_scrn.cpp +++ b/src/engine/client/cl_scrn.cpp @@ -255,7 +255,7 @@ void SCR_DrawScreenField() // also draw the connection information, so it doesn't // flash away too briefly on local or LAN games - //if (!com_sv_running->value || Cvar_VariableIntegerValue("sv_cheats")) // Ridah, don't draw useless text if not in dev mode + //if (!com_sv_running.Get() || Cvar_VariableIntegerValue("sv_cheats")) // Ridah, don't draw useless text if not in dev mode break; case connstate_t::CA_ACTIVE: diff --git a/src/engine/qcommon/common.cpp b/src/engine/qcommon/common.cpp index 7793f7610c..1d22e3ff5e 100644 --- a/src/engine/qcommon/common.cpp +++ b/src/engine/qcommon/common.cpp @@ -61,7 +61,7 @@ Cvar::Cvar cvar_demo_timedemo( Cvar::CHEAT | Cvar::TEMPORARY, false ); -cvar_t *com_sv_running; +Cvar::Cvar com_sv_running("sv_running", "do we have a server running?", Cvar::ROM, false); cvar_t *com_cl_running; cvar_t *com_version; @@ -183,7 +183,7 @@ bool Com_IsDedicatedServer() bool Com_ServerRunning() { - return com_sv_running->integer; + return com_sv_running.Get(); } /* @@ -384,7 +384,7 @@ static void HandlePacketEvent(const Sys::PacketEvent& event) buf.cursize = event.data.size(); memcpy( buf.data, event.data.data(), buf.cursize ); - if ( com_sv_running->integer ) + if ( com_sv_running.Get() ) { Com_RunAndTimeServerPacket( &event.adr, &buf ); } @@ -432,7 +432,7 @@ void Com_EventLoop() while ( NET_GetLoopPacket( netsrc_t::NS_SERVER, &evFrom, &buf ) ) { // if the server just shut down, flush the events - if ( com_sv_running->integer ) + if ( com_sv_running.Get() ) { Com_RunAndTimeServerPacket( &evFrom, &buf ); } @@ -560,7 +560,6 @@ void Com_Init() com_dropsim = Cvar_Get( "com_dropsim", "0", CVAR_CHEAT ); com_speeds = Cvar_Get( "com_speeds", "0", 0 ); - com_sv_running = Cvar_Get( "sv_running", "0", CVAR_ROM ); com_cl_running = Cvar_Get( "cl_running", "0", CVAR_ROM ); com_unfocused = Cvar_Get( "com_unfocused", "0", CVAR_ROM ); diff --git a/src/engine/qcommon/net_ip.cpp b/src/engine/qcommon/net_ip.cpp index 286ca5845e..ffaadbb3b3 100644 --- a/src/engine/qcommon/net_ip.cpp +++ b/src/engine/qcommon/net_ip.cpp @@ -1882,6 +1882,6 @@ void NET_Restart_f() #ifdef BUILD_SERVER NET_EnableNetworking( true ); #else - NET_EnableNetworking( !!com_sv_running->integer ); + NET_EnableNetworking( com_sv_running.Get() ); #endif } diff --git a/src/engine/qcommon/qcommon.h b/src/engine/qcommon/qcommon.h index dc01323ef2..c591a169d5 100644 --- a/src/engine/qcommon/qcommon.h +++ b/src/engine/qcommon/qcommon.h @@ -530,7 +530,7 @@ bool Com_ServerRunning(); extern cvar_t *com_speeds; extern cvar_t *com_timescale; -extern cvar_t *com_sv_running; +extern Cvar::Cvar com_sv_running; extern cvar_t *com_cl_running; extern cvar_t *com_version; diff --git a/src/engine/qcommon/sys.h b/src/engine/qcommon/sys.h index 47eb44bca0..dd6823c7bf 100644 --- a/src/engine/qcommon/sys.h +++ b/src/engine/qcommon/sys.h @@ -37,6 +37,12 @@ Maryland 20850 USA. #include "engine/qcommon/net_types.h" +// server->client bandwidth limits in bytes/sec +#define NETWORK_MIN_RATE 1000 +#define NETWORK_DEFAULT_RATE 25000 +#define NETWORK_MAX_RATE 90000 +#define NETWORK_LAN_RATE 99999 + void Sys_SendPacket(int length, const void *data, const netadr_t& to); bool Sys_GetPacket(netadr_t *net_from, msg_t *net_message); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 7dede81ad3..25a25a4925 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -179,7 +179,6 @@ struct client_t // note: this is one-shot, multiple downloads would cause a www download to be attempted again int deltaMessage; // frame last client usercmd message - int nextReliableTime; // svs.time when another reliable command will be allowed int lastPacketTime; // svs.time when packet was last received int lastConnectTime; // svs.time when connection started int nextSnapshotTime; // send another snapshot when svs.time >= nextSnapshotTime @@ -291,34 +290,31 @@ extern serverStatic_t svs; // persistent server info across maps extern server_t sv; // cleared each map extern GameVM gvm; // game virtual machine -extern cvar_t *sv_fps; -extern cvar_t *sv_timeout; -extern cvar_t *sv_zombietime; -extern cvar_t *sv_privatePassword; -extern cvar_t *sv_allowDownload; +extern Cvar::Range> sv_fps; +extern Cvar::Cvar sv_timeout; +extern Cvar::Cvar sv_zombietime; +extern Cvar::Cvar sv_privatePassword; +extern Cvar::Cvar sv_allowDownload; extern Cvar::Range> sv_maxClients; extern Cvar::Range> sv_privateClients; -extern cvar_t *sv_hostname; -extern cvar_t *sv_statsURL; -extern cvar_t *sv_reconnectlimit; -extern cvar_t *sv_padPackets; +extern Cvar::Cvar sv_hostname; +extern Cvar::Cvar sv_statsURL; +extern Cvar::Cvar sv_reconnectlimit; +extern Cvar::Cvar sv_padPackets; extern cvar_t *sv_killserver; -extern cvar_t *sv_mapname; +extern Cvar::Cvar sv_mapname; extern cvar_t *sv_mapChecksum; -extern cvar_t *sv_serverid; -extern cvar_t *sv_maxRate; +extern Cvar::Cvar sv_serverid; +extern Cvar::Cvar sv_maxRate; -extern cvar_t *sv_floodProtect; -extern cvar_t *sv_lanForceRate; - -extern cvar_t *sv_showAverageBPS; // NERVE - SMF - net debugging +extern Cvar::Cvar sv_lanForceRate; // TTimo - autodl -extern cvar_t *sv_dl_maxRate; +extern Cvar::Cvar sv_dl_maxRate; //fretn -extern cvar_t *sv_fullmsg; +extern Cvar::Cvar sv_fullmsg; extern Cvar::Range> sv_networkScope; @@ -372,7 +368,7 @@ void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd ); void SV_FreeClient( client_t *client ); void SV_DropClient( client_t *drop, const char *reason ); -void SV_ExecuteClientCommand( client_t *cl, const char *s, bool clientOK, bool premaprestart ); +void SV_ExecuteClientCommand( client_t *cl, const char *s, bool premaprestart ); void SV_ClientThink( client_t *cl, usercmd_t *cmd ); void SV_WriteDownloadToClient( client_t *cl, msg_t *msg ); diff --git a/src/engine/server/sv_bot.cpp b/src/engine/server/sv_bot.cpp index 0e77f9a908..c5b5fe616b 100644 --- a/src/engine/server/sv_bot.cpp +++ b/src/engine/server/sv_bot.cpp @@ -35,6 +35,7 @@ Maryland 20850 USA. // sv_bot.c #include "server.h" +#include "qcommon/sys.h" /* ================== @@ -60,7 +61,7 @@ int SV_BotAllocateClient() cl->state = clientState_t::CS_ACTIVE; cl->lastPacketTime = svs.time; cl->netchan.remoteAddress.type = netadrtype_t::NA_BOT; - cl->rate = 16384; + cl->rate = NETWORK_DEFAULT_RATE; return i; } diff --git a/src/engine/server/sv_ccmds.cpp b/src/engine/server/sv_ccmds.cpp index 09128f3180..a98eeecced 100644 --- a/src/engine/server/sv_ccmds.cpp +++ b/src/engine/server/sv_ccmds.cpp @@ -153,7 +153,7 @@ static void SV_MapRestart_f() } // make sure server is running - if ( !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { Log::Notice( "Server is not running." ); return; @@ -166,7 +166,7 @@ static void SV_MapRestart_f() // generate a new serverid // TTimo - don't update restartedserverId there, otherwise we won't deal correctly with multiple map_restart sv.serverId = com_frameTime; - Cvar_Set( "sv_serverid", va( "%i", sv.serverId ) ); + Cvar::SetValueForce( "sv_serverid", va( "%i", sv.serverId ) ); // reset all the VM data in place without changing memory allocation // note that we do NOT set sv.state = SS_LOADING, so configstrings that @@ -245,7 +245,7 @@ class StatusCmd: public Cmd::StaticCmd void Run(const Cmd::Args&) const override { // make sure server is running - if ( !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { Log::Notice( "Server is not running." ); return; @@ -286,12 +286,12 @@ class StatusCmd: public Cmd::StaticCmd "players: %d / %d\n" "num score connection address port name\n" "--- ----- ---------- ---------------------- ------ ----", - sv_hostname->string, + sv_hostname.Get(), Q3_VERSION " on " Q3_ENGINE, PROTOCOL_VERSION, cpu, time_string, - sv_mapname->string, + sv_mapname.Get(), players, sv_maxClients.Get() ); @@ -352,7 +352,7 @@ Examine the serverinfo string static void SV_Serverinfo_f() { // make sure server is running - if ( !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { Log::Notice( "Server is not running." ); return; @@ -372,7 +372,7 @@ Examine the systeminfo string static void SV_Systeminfo_f() { // make sure server is running - if ( !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { Log::Notice( "Server is not running." ); return; @@ -413,7 +413,7 @@ SV_AddOperatorCommands */ void SV_AddOperatorCommands() { - if ( com_sv_running->integer ) + if ( com_sv_running.Get() ) { // These commands should only be available while the server is running. Cmd_AddCommand( "fieldinfo", SV_FieldInfo_f ); diff --git a/src/engine/server/sv_client.cpp b/src/engine/server/sv_client.cpp index 7e718ccade..b7441f423e 100644 --- a/src/engine/server/sv_client.cpp +++ b/src/engine/server/sv_client.cpp @@ -96,7 +96,7 @@ void SV_DirectConnect( const netadr_t& from, const Cmd::Args& args ) ); if ( reconnecting != clients_end && - svs.time - reconnecting->lastConnectTime < sv_reconnectlimit->integer * 1000 ) + svs.time - reconnecting->lastConnectTime < sv_reconnectlimit.Get() * 1000 ) { Log::Debug( "%s: reconnect rejected: too soon", NET_AdrToString( from ) ); return; @@ -142,7 +142,7 @@ void SV_DirectConnect( const netadr_t& from, const Cmd::Args& args ) // check for privateClient password auto allowed_clients_begin = clients_begin; - if ( userinfo["password"] != sv_privatePassword->string ) + if ( userinfo["password"] != sv_privatePassword.Get() ) { // skip past the reserved slots allowed_clients_begin += std::min(sv_privateClients.Get(), sv_maxClients.Get()); @@ -175,7 +175,7 @@ void SV_DirectConnect( const netadr_t& from, const Cmd::Args& args ) } else { - Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n%s", sv_fullmsg->string ); + Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n%s", sv_fullmsg.Get() ); Log::Debug( "Rejected a connection." ); return; } @@ -713,7 +713,7 @@ void SV_WriteDownloadToClient( client_t *cl, msg_t *msg ) Log::Notice( "clientDownload: %d : beginning \"%s\"", ( int )( cl - svs.clients ), cl->downloadName ); } - if ( !sv_allowDownload->integer ) + if ( !sv_allowDownload.Get() ) { Log::Notice( "clientDownload: %d : \"%s\" download disabled", ( int )( cl - svs.clients ), cl->downloadName ); @@ -907,13 +907,13 @@ void SV_WriteDownloadToClient( client_t *cl, msg_t *msg ) // show_bug.cgi?id=509 // for autodownload, we use a separate max rate value // we do this every time because the client might change its rate during the download - if ( sv_dl_maxRate->integer < rate ) + if ( sv_dl_maxRate.Get() < rate ) { - rate = sv_dl_maxRate->integer; + rate = sv_dl_maxRate.Get(); if ( bTellRate ) { - Log::Notice( "'%s' downloading at sv_dl_maxrate (%d)", cl->name, sv_dl_maxRate->integer ); + Log::Notice( "'%s' downloading at sv_dl_maxrate (%d)", cl->name, sv_dl_maxRate.Get() ); } } else if ( bTellRate ) @@ -1025,31 +1025,22 @@ void SV_UserinfoChanged( client_t *cl ) // Internet server, assume that they don't need a rate choke if ( Sys_IsLANAddress( cl->netchan.remoteAddress ) && sv_networkScope.Get() <= 1 - && sv_lanForceRate->integer == 1 ) + && sv_lanForceRate.Get() ) { - cl->rate = 99999; // lans should not rate limit + cl->rate = NETWORK_LAN_RATE; // lans should not rate limit (though sv_maxRate still applies?) } else { val = Info_ValueForKey( cl->userinfo, "rate" ); - if ( strlen( val ) ) + int rate; + if ( Str::ParseInt( rate, val ) ) { - i = atoi( val ); - cl->rate = i; - - if ( cl->rate < 1000 ) - { - cl->rate = 1000; - } - else if ( cl->rate > 90000 ) - { - cl->rate = 90000; - } + cl->rate = Math::Clamp( rate, NETWORK_MIN_RATE, NETWORK_MAX_RATE ); } else { - cl->rate = 5000; + cl->rate = NETWORK_DEFAULT_RATE; } } @@ -1064,9 +1055,9 @@ void SV_UserinfoChanged( client_t *cl ) { i = 1; } - else if ( i > sv_fps->integer ) + else if ( i > sv_fps.Get() ) { - i = sv_fps->integer; + i = sv_fps.Get(); } cl->snapshotMsec = 1000 / i; @@ -1132,10 +1123,9 @@ Also called by bot code */ Log::Logger clientCommands("server.clientCommands"); -void SV_ExecuteClientCommand( client_t *cl, const char *s, bool clientOK, bool premaprestart ) +void SV_ExecuteClientCommand( client_t *cl, const char *s, bool premaprestart ) { ucmd_t *u; - bool bProcessed = false; Log::Debug( "EXCL: %s", s ); Cmd::Args args(s); @@ -1152,22 +1142,14 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, bool clientOK, bool p } u->func(cl, args); - bProcessed = true; break; } } - if ( clientOK ) - { - // pass unknown strings to the game - if ( !u->name && sv.state == serverState_t::SS_GAME ) - { - gvm.GameClientCommand( cl - svs.clients, s ); - } - } - else if ( !bProcessed ) + // pass unknown strings to the game + if ( !u->name && sv.state == serverState_t::SS_GAME ) { - Log::Debug( "client text ignored for %s^*: %s", cl->name, args.Argv(0).c_str()); + gvm.GameClientCommand( cl - svs.clients, s ); } } @@ -1178,9 +1160,6 @@ SV_ClientCommand */ static bool SV_ClientCommand( client_t *cl, msg_t *msg, bool premaprestart ) { - bool clientOk = true; - bool floodprotect = true; - auto seq = MSG_ReadLong( msg ); auto s = MSG_ReadString( msg ); @@ -1200,36 +1179,7 @@ static bool SV_ClientCommand( client_t *cl, msg_t *msg, bool premaprestart ) return false; } - // Gordon: AHA! Need to steal this for some other stuff BOOKMARK - // NERVE - SMF - some server game-only commands we cannot have flood protect - if ( !Q_strncmp( "team", s, 4 ) || !Q_strncmp( "setspawnpt", s, 10 ) || !Q_strncmp( "score", s, 5 ) || !Q_stricmp( "forcetapout", s ) ) - { -// Log::Debug( "Skipping flood protection for: %s", s ); - floodprotect = false; - } - - // malicious users may try using too many string commands - // to lag other players. If we decide that we want to stall - // the command, we will stop processing the rest of the packet, - // including the usercmd. This causes flooders to lag themselves - // but not other people - // We don't do this when the client hasn't been active yet, since it is - // by protocol to spam a lot of commands when downloading - if ( !com_cl_running->integer && cl->state >= clientState_t::CS_ACTIVE && // (SA) this was commented out in Wolf. Did we do that? - sv_floodProtect->integer && svs.time < cl->nextReliableTime && floodprotect ) - { - // ignore any other text messages from this client but let them keep playing - // TTimo - moved the ignored verbose to the actual processing in SV_ExecuteClientCommand, only printing if the core doesn't intercept - clientOk = false; - } - - // don't allow another command for 800 msec - if ( floodprotect && svs.time >= cl->nextReliableTime ) - { - cl->nextReliableTime = svs.time + 800; - } - - SV_ExecuteClientCommand( cl, s, clientOk, premaprestart ); + SV_ExecuteClientCommand( cl, s, premaprestart ); cl->lastClientCommand = seq; Com_sprintf( cl->lastClientCommandString, sizeof( cl->lastClientCommandString ), "%s", s ); diff --git a/src/engine/server/sv_init.cpp b/src/engine/server/sv_init.cpp index dcce7679a7..0b917c0ccb 100644 --- a/src/engine/server/sv_init.cpp +++ b/src/engine/server/sv_init.cpp @@ -320,7 +320,7 @@ void SV_Startup() svs.initialized = true; - Cvar_Set( "sv_running", "1" ); + Cvar::SetValueForce( "sv_running", "1" ); #ifndef BUILD_SERVER // For clients, reconfigure to open server ports. NET_EnableNetworking( true ); @@ -419,7 +419,6 @@ SV_SpawnServer Change the server to a new map, taking all connected clients along with it. -This is NOT called for map_restart, UNLESS the number of client slots changed ================ */ void SV_SpawnServer(std::string pakname, std::string mapname) @@ -488,13 +487,13 @@ void SV_SpawnServer(std::string pakname, std::string mapname) CM_LoadMap(mapname); // set serverinfo visible name - Cvar_Set( "mapname", mapname.c_str() ); + Cvar::SetValueForce( "mapname", mapname ); Cvar::SetValueForce( cvar_pakname.Name(), pakname ); // serverid should be different each time sv.serverId = com_frameTime; sv.restartedServerId = sv.serverId; - Cvar_Set( "sv_serverid", va( "%i", sv.serverId ) ); + Cvar::SetValueForce( "sv_serverid", va( "%i", sv.serverId ) ); // media configstring setting should be done during // the loading stage, so connected clients don't have @@ -606,40 +605,13 @@ void SV_Init() SV_AddOperatorCommands(); // serverinfo vars - sv_mapname = Cvar_Get( "mapname", "nomap", CVAR_SERVERINFO | CVAR_ROM ); - sv_hostname = Cvar_Get( "sv_hostname", UNNAMED_SERVER, CVAR_SERVERINFO ); Cvar::Latch( sv_maxClients ); - sv_maxRate = Cvar_Get( "sv_maxRate", "0", CVAR_SERVERINFO ); - sv_floodProtect = Cvar_Get( "sv_floodProtect", "0", CVAR_SERVERINFO ); Cvar::SetValue( "layout", "" ); // TODO: declare in sgame Cvar::AddFlags( "layout", Cvar::SERVERINFO ); - sv_statsURL = Cvar_Get( "sv_statsURL", "", CVAR_SERVERINFO ); - - // systeminfo - sv_serverid = Cvar_Get( "sv_serverid", "0", CVAR_SYSTEMINFO | CVAR_ROM ); - // server vars - sv_privatePassword = Cvar_Get( "sv_privatePassword", "", CVAR_TEMP ); - sv_fps = Cvar_Get( "sv_fps", "40", CVAR_TEMP ); - sv_timeout = Cvar_Get( "sv_timeout", "240", CVAR_TEMP ); - sv_zombietime = Cvar_Get( "sv_zombietime", "2", CVAR_TEMP ); - - sv_allowDownload = Cvar_Get( "sv_allowDownload", "1", 0 ); - sv_reconnectlimit = Cvar_Get( "sv_reconnectlimit", "3", 0 ); - sv_padPackets = Cvar_Get( "sv_padPackets", "0", 0 ); - sv_killserver = Cvar_Get( "sv_killserver", "0", 0 ); - - sv_lanForceRate = Cvar_Get( "sv_lanForceRate", "1", 0 ); - sv_showAverageBPS = Cvar_Get( "sv_showAverageBPS", "0", 0 ); // NERVE - SMF - net debugging - - // the download netcode tops at 18/20 kb/s, no need to make you think you can go above - sv_dl_maxRate = Cvar_Get( "sv_dl_maxRate", "42000", 0 ); - - // fretn - note: redirecting of clients to other servers relies on this, - // ET://someserver.com - sv_fullmsg = Cvar_Get( "sv_fullmsg", "Server is full.", 0 ); + sv_killserver = Cvar_Get( "sv_killserver", "0", 0 ); svs.serverLoad = -1; } @@ -693,7 +665,7 @@ void SV_FinalCommand( char *cmd, bool disconnect ) // Used instead of SV_Shutdown when Daemon is exiting void SV_QuickShutdown( const char *finalmsg ) { - if ( !com_sv_running || !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { return; } @@ -718,7 +690,7 @@ Called to shut down the sgame VM, or to clean up after the VM shut down on its o */ void SV_Shutdown( const char *finalmsg ) { - if ( !com_sv_running || !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { return; } @@ -753,7 +725,7 @@ void SV_Shutdown( const char *finalmsg ) svs.serverLoad = -1; ChallengeManager::Clear(); - Cvar_Set( "sv_running", "0" ); + Cvar::SetValueForce( "sv_running", "0" ); #ifndef BUILD_SERVER // For clients, reconfigure to close server ports. NET_EnableNetworking( false ); diff --git a/src/engine/server/sv_main.cpp b/src/engine/server/sv_main.cpp index 7b2af156e2..14fdeec358 100644 --- a/src/engine/server/sv_main.cpp +++ b/src/engine/server/sv_main.cpp @@ -56,35 +56,32 @@ GameVM gvm; // game virtual machine // timescale 5, the number of gamelogic frames per wall second will be 200. // For the dedicated server this also controls the engine frame rate. The engine framerate // is based on real time, disregarding timescale. -cvar_t *sv_fps; +Cvar::Range> sv_fps("sv_fps", "sgame and dedicated server frame rate", Cvar::NONE, 40, 1, 1000); -cvar_t *sv_timeout; // seconds without any message -cvar_t *sv_zombietime; // seconds to sink messages after disconnect -cvar_t *sv_privatePassword; // password for the privateClient slots -cvar_t *sv_allowDownload; +Cvar::Cvar sv_timeout("sv_timeout", "seconds without connectivity after which to drop a client", Cvar::NONE, 240); +Cvar::Cvar sv_zombietime("sv_zombietime", "seconds without messages after which to recycle client slot", Cvar::NONE, 2); +Cvar::Cvar sv_privatePassword("sv_privatePassword", "password guarding private server slots", Cvar::NONE, ""); +Cvar::Cvar sv_allowDownload("sv_allowDownload", "let clients download missing paks", Cvar::NONE, true); Cvar::Range> sv_maxClients("sv_maxclients", "max number of players on the server", Cvar::SERVERINFO, 20, 1, MAX_CLIENTS); Cvar::Range> sv_privateClients("sv_privateClients", "number of password-protected client slots", Cvar::SERVERINFO, 0, 0, MAX_CLIENTS); -cvar_t *sv_hostname; -cvar_t *sv_statsURL; -cvar_t *sv_reconnectlimit; // minimum seconds between connect messages -cvar_t *sv_padPackets; // add nop bytes to messages +Cvar::Cvar sv_hostname("sv_hostname", "server name for server list", Cvar::SERVERINFO, UNNAMED_SERVER); +Cvar::Cvar sv_statsURL("sv_statsURL", "URL for server's gameplay statistics", Cvar::SERVERINFO, ""); +Cvar::Cvar sv_reconnectlimit("sv_reconnectlimit", "minimum time (seconds) before client can reconnect", Cvar::NONE, 3); +Cvar::Cvar sv_padPackets("sv_padPackets", "(debugging) add n NOP bytes to each snapshot packet", Cvar::NONE, 0); cvar_t *sv_killserver; // menu system can set to 1 to shut server down -cvar_t *sv_mapname; -cvar_t *sv_serverid; -cvar_t *sv_maxRate; +Cvar::Cvar sv_mapname("mapname", "current map on this server", Cvar::SERVERINFO | Cvar::ROM, "nomap"); +Cvar::Cvar sv_serverid("sv_serverid", "match ID", Cvar::SYSTEMINFO | Cvar::ROM, 0); +Cvar::Cvar sv_maxRate("sv_maxRate", "max bytes/sec to send to a client (0 = unlimited)", Cvar::SERVERINFO, 0); -cvar_t *sv_floodProtect; -cvar_t *sv_lanForceRate; // TTimo - dedicated 1 (LAN) server forces local client rates to 99999 (bug #491) +Cvar::Cvar sv_lanForceRate("sv_lanForceRate", "make LAN clients use max network rate", Cvar::NONE, true); -cvar_t *sv_dl_maxRate; - -cvar_t *sv_showAverageBPS; // NERVE - SMF - net debugging +Cvar::Cvar sv_dl_maxRate("sv_dl_maxRate", "max bytes/sec for UDP pak download", Cvar::NONE, 42000); // fretn -cvar_t *sv_fullmsg; +Cvar::Cvar sv_fullmsg("sv_fullmsg", "message for clients attempting to join full server", Cvar::NONE, "Server is full."); Cvar::Range> sv_networkScope( "sv_networkScope", @@ -516,7 +513,7 @@ if a user is interested in a server to do a full status */ static void SVC_Info( const netadr_t& from, const Cmd::Args& args ) { - if ( SV_Private(ServerPrivate::NoStatus) || !com_sv_running || !com_sv_running->integer ) + if ( SV_Private(ServerPrivate::NoStatus) || !com_sv_running.Get() ) { return; } @@ -584,18 +581,18 @@ static void SVC_Info( const netadr_t& from, const Cmd::Args& args ) } info_map["protocol"] = std::to_string( PROTOCOL_VERSION ); - info_map["hostname"] = sv_hostname->string; + info_map["hostname"] = sv_hostname.Get(); info_map["serverload"] = std::to_string( svs.serverLoad ); - info_map["mapname"] = sv_mapname->string; + info_map["mapname"] = sv_mapname.Get(); info_map["clients"] = std::to_string( publicSlotHumans + privateSlotHumans ); info_map["bots"] = std::to_string( bots ); // Satisfies (number of open public slots) = (displayed max clients) - (number of clients). info_map["sv_maxclients"] = std::to_string( std::max( 0, sv_maxClients.Get() - sv_privateClients.Get() ) + privateSlotHumans ); - if ( sv_statsURL->string[0] ) + if ( !sv_statsURL.Get().empty() ) { - info_map["stats"] = sv_statsURL->string; + info_map["stats"] = sv_statsURL.Get().c_str(); } info_map["gamename"] = GAMENAME_STRING; // Arnout: to be able to filter out Quake servers @@ -1238,8 +1235,8 @@ void SV_CheckTimeouts() int droppoint; int zombiepoint; - droppoint = svs.time - 1000 * sv_timeout->integer; - zombiepoint = svs.time - 1000 * sv_zombietime->integer; + droppoint = svs.time - 1000 * sv_timeout.Get(); + zombiepoint = svs.time - 1000 * sv_zombietime.Get(); for ( i = 0, cl = svs.clients; i < sv_maxClients.Get(); i++, cl++ ) { @@ -1288,23 +1285,16 @@ Return time in milliseconds until processing of the next server frame. */ int SV_FrameMsec() { - if( sv_fps ) - { - const int frameMsec = static_cast(1000.0f / sv_fps->value); - int scaledResidual = static_cast( sv.timeResidual / com_timescale->value ); + const int frameMsec = 1000 / sv_fps.Get(); + int scaledResidual = static_cast( sv.timeResidual / com_timescale->value ); - if ( frameMsec < scaledResidual ) - { - return 0; - } - else - { - return frameMsec - scaledResidual; - } + if ( frameMsec < scaledResidual ) + { + return 0; } else { - return 1; + return frameMsec - scaledResidual; } } @@ -1335,7 +1325,7 @@ void SV_Frame( int msec ) return; } - if ( !com_sv_running->integer ) + if ( !com_sv_running.Get() ) { return; } @@ -1343,12 +1333,7 @@ void SV_Frame( int msec ) frameStartTime = Sys::Milliseconds(); // if it isn't time for the next frame, do nothing - if ( sv_fps->integer < 1 ) - { - Cvar_Set( "sv_fps", "10" ); - } - - frameMsec = 1000 / sv_fps->integer; + frameMsec = 1000 / sv_fps.Get(); sv.timeResidual += msec; @@ -1372,7 +1357,7 @@ void SV_Frame( int msec ) // there won't be a map_restart if you have shut down the server // since it doesn't restart a non-running server // instead, re-run the current map - Cmd::BufferCommandText(Str::Format("map %s", Cmd::Escape(sv_mapname->string))); + Cmd::BufferCommandText(Str::Format("map %s", Cmd::Escape(sv_mapname.Get()))); Sys::Drop( "Restarting server due to time wrapping" ); } @@ -1381,7 +1366,7 @@ void SV_Frame( int msec ) if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) { // TTimo see above - Cmd::BufferCommandText(Str::Format("map %s", Cmd::Escape(sv_mapname->string))); + Cmd::BufferCommandText(Str::Format("map %s", Cmd::Escape(sv_mapname.Get()))); Sys::Drop( "Restarting server due to numSnapshotEntities wrapping" ); } diff --git a/src/engine/server/sv_snapshot.cpp b/src/engine/server/sv_snapshot.cpp index 81523c201d..6408ace628 100644 --- a/src/engine/server/sv_snapshot.cpp +++ b/src/engine/server/sv_snapshot.cpp @@ -59,6 +59,8 @@ A server packet will look something like: static Cvar::Cvar sv_novis("sv_novis", "skip PVS check when transmitting entities", 0, false); +static Log::Logger bandwidthLog("server.bandwidth"); + /* ============= SV_EmitPacketEntities @@ -237,9 +239,9 @@ static void SV_WriteSnapshotToClient( client_t *client, msg_t *msg ) SV_EmitPacketEntities( oldframe, frame, msg ); // padding for rate debugging - if ( sv_padPackets->integer ) + if ( sv_padPackets.Get() ) { - for ( i = 0; i < sv_padPackets->integer; i++ ) + for ( i = 0; i < sv_padPackets.Get(); i++ ) { MSG_WriteByte( msg, svc_nop ); } @@ -780,9 +782,10 @@ static int SV_RateMsec( client_t *client, int messageSize ) } // low watermark for sv_maxRate, never 0 < sv_maxRate < 1000 (0 is no limitation) - if ( sv_maxRate->integer && sv_maxRate->integer < 1000 ) + if ( sv_maxRate.Get() > 0 && sv_maxRate.Get() < NETWORK_MIN_RATE ) { - Cvar_Set( "sv_MaxRate", "1000" ); + Log::Warn( "sv_maxRate too low, increasing to %d", NETWORK_MIN_RATE ); + sv_maxRate.Set( NETWORK_MIN_RATE ); } rate = client->rate; @@ -790,19 +793,16 @@ static int SV_RateMsec( client_t *client, int messageSize ) // work on the appropriate max rate (client or download) if ( !*client->downloadName ) { - maxRate = sv_maxRate->integer; + maxRate = sv_maxRate.Get(); } else { - maxRate = sv_dl_maxRate->integer; + maxRate = sv_dl_maxRate.Get(); } - if ( maxRate ) + if ( maxRate > 0 ) { - if ( maxRate < rate ) - { - rate = maxRate; - } + rate = std::min( rate, maxRate ); } rateMsec = ( messageSize + HEADER_RATE_BYTES ) * 1000 / rate; @@ -835,7 +835,7 @@ void SV_SendMessageToClient( msg_t *msg, client_t *client ) // TTimo - show_bug.cgi?id=491 // added sv_lanForceRate check if ( client->netchan.remoteAddress.type == netadrtype_t::NA_LOOPBACK || - ( sv_lanForceRate->integer && Sys_IsLANAddress( client->netchan.remoteAddress ) ) ) + ( sv_lanForceRate.Get() && Sys_IsLANAddress( client->netchan.remoteAddress ) ) ) { client->nextSnapshotTime = svs.time - 1; return; @@ -995,7 +995,6 @@ SV_SendClientMessages void SV_SendClientMessages() { - int i; client_t *c; int numclients = 0; // NERVE - SMF - net debugging @@ -1006,7 +1005,7 @@ void SV_SendClientMessages() SV_UpdateConfigStrings(); // send a message to each connected client - for ( i = 0; i < sv_maxClients.Get(); i++ ) + for ( int i = 0; i < sv_maxClients.Get(); i++ ) { c = &svs.clients[ i ]; @@ -1045,11 +1044,15 @@ void SV_SendClientMessages() } // NERVE - SMF - net debugging - if ( sv_showAverageBPS->integer && numclients > 0 ) - { + bandwidthLog.DoDebugCode( [numclients] { + if ( numclients <= 0 ) + { + return; + } + float ave = 0, uave = 0; - for ( i = 0; i < MAX_BPS_WINDOW - 1; i++ ) + for ( int i = 0; i < MAX_BPS_WINDOW - 1; i++ ) { sv.bpsWindow[ i ] = sv.bpsWindow[ i + 1 ]; ave += sv.bpsWindow[ i ]; @@ -1089,11 +1092,11 @@ void SV_SendClientMessages() sv.ucompAve += comp_ratio; sv.ucompNum++; - Log::Debug( "bpspc(%2.0f) bps(%2.0f) pk(%i) ubps(%2.0f) upk(%i) cr(%2.2f) acr(%2.2f)", + bandwidthLog.Debug( "bpspc(%2.0f) bps(%2.0f) pk(%i) ubps(%2.0f) upk(%i) cr(%2.2f) acr(%2.2f)", ave / ( float ) numclients, ave, sv.bpsMaxBytes, uave, sv.ubpsMaxBytes, comp_ratio, sv.ucompAve / sv.ucompNum ); } - } + }); // -NERVE - SMF }