mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
engine: server: refactoring, better validation of cl_updaterate and rate values. Allow sv_min/maxupdaterate to be set to 0 for unlimited powah
This commit is contained in:
@@ -233,7 +233,7 @@ typedef struct sv_client_s
|
||||
double next_messagetime; // time when we should send next world state update
|
||||
double next_checkpingtime; // time to send all players pings to client
|
||||
double next_sendinfotime; // time to send info about all players
|
||||
double cl_updaterate; // client requested updaterate
|
||||
double next_messageinterval; // update rate, clamped
|
||||
double timebase; // client timebase
|
||||
double connection_started;
|
||||
|
||||
|
||||
@@ -38,15 +38,13 @@ SV_GetPlayerCount
|
||||
*/
|
||||
void SV_GetPlayerCount( int *players, int *bots )
|
||||
{
|
||||
int i;
|
||||
|
||||
*players = 0;
|
||||
*bots = 0;
|
||||
|
||||
if( !svs.clients )
|
||||
return;
|
||||
|
||||
for( i = 0; i < svs.maxclients; i++ )
|
||||
for( int i = 0; i < svs.maxclients; i++ )
|
||||
{
|
||||
if( svs.clients[i].state >= cs_connected )
|
||||
{
|
||||
@@ -55,7 +53,6 @@ void SV_GetPlayerCount( int *players, int *bots )
|
||||
else
|
||||
(*players)++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,7 +440,7 @@ static void SV_ConnectClient( netadr_t from )
|
||||
|
||||
newcl->upstate = us_inactive;
|
||||
newcl->connection_started = host.realtime;
|
||||
newcl->cl_updaterate = 0.05; // 20 fps as default
|
||||
newcl->next_messageinterval = 0.05; // 20 fps as default
|
||||
newcl->delta_sequence = -1;
|
||||
|
||||
// parse some info from the info strings (this can override cl_updaterate)
|
||||
@@ -451,7 +448,7 @@ static void SV_ConnectClient( netadr_t from )
|
||||
|
||||
SV_UserinfoChanged( newcl );
|
||||
|
||||
newcl->next_messagetime = host.realtime + newcl->cl_updaterate;
|
||||
newcl->next_messagetime = host.realtime + sv.frametime + newcl->next_messageinterval;
|
||||
|
||||
// reset stats
|
||||
newcl->next_checkpingtime = -1.0;
|
||||
@@ -1774,6 +1771,40 @@ static qboolean SV_ShouldUpdateUserinfo( sv_client_t *cl )
|
||||
return allow;
|
||||
}
|
||||
|
||||
static double SV_CheckUpdateRate( double rate )
|
||||
{
|
||||
if( sv_maxupdaterate.value )
|
||||
{
|
||||
if( rate < 1.0f / sv_maxupdaterate.value )
|
||||
return 1.0f / sv_maxupdaterate.value;
|
||||
}
|
||||
|
||||
if( sv_minupdaterate.value )
|
||||
{
|
||||
if( rate > 1.0f / sv_minupdaterate.value )
|
||||
return 1.0f / sv_minupdaterate.value;
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static double SV_CheckRate( double rate )
|
||||
{
|
||||
if( sv_maxrate.value )
|
||||
{
|
||||
if( rate > sv_maxrate.value )
|
||||
return rate;
|
||||
}
|
||||
|
||||
if( sv_minrate.value )
|
||||
{
|
||||
if( rate < sv_minrate.value )
|
||||
return rate;
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_UserinfoChanged
|
||||
@@ -1789,6 +1820,7 @@ static void SV_UserinfoChanged( sv_client_t *cl )
|
||||
string name1, name2;
|
||||
sv_client_t *current;
|
||||
const char *val;
|
||||
int ival;
|
||||
|
||||
if( !COM_CheckString( cl->userinfo ))
|
||||
return;
|
||||
@@ -1852,9 +1884,10 @@ static void SV_UserinfoChanged( sv_client_t *cl )
|
||||
|
||||
// rate command
|
||||
val = Info_ValueForKey( cl->userinfo, "rate" );
|
||||
if( COM_CheckString( val ) )
|
||||
cl->netchan.rate = bound( sv_minrate.value, Q_atoi( val ), sv_maxrate.value );
|
||||
else cl->netchan.rate = DEFAULT_RATE;
|
||||
cl->netchan.rate = Q_atoi( Info_ValueForKey( cl->userinfo, "rate" ));
|
||||
if( cl->netchan.rate <= 0 )
|
||||
cl->netchan.rate = DEFAULT_RATE;
|
||||
cl->netchan.rate = bound( MIN_RATE, cl->netchan.rate, MAX_RATE );
|
||||
|
||||
// movement prediction
|
||||
if( Q_atoi( Info_ValueForKey( cl->userinfo, "cl_nopred" )))
|
||||
@@ -1871,13 +1904,13 @@ static void SV_UserinfoChanged( sv_client_t *cl )
|
||||
SetBits( cl->flags, FCL_LOCAL_WEAPONS );
|
||||
else ClearBits( cl->flags, FCL_LOCAL_WEAPONS );
|
||||
|
||||
val = Info_ValueForKey( cl->userinfo, "cl_updaterate" );
|
||||
ival = Q_atoi( Info_ValueForKey( cl->userinfo, "cl_updaterate" ));
|
||||
|
||||
if( COM_CheckString( val ))
|
||||
{
|
||||
float rate = Q_atoi( val );
|
||||
cl->cl_updaterate = 1.0 / bound( sv_minupdaterate.value, rate, sv_maxupdaterate.value );
|
||||
}
|
||||
if( ival <= 0 )
|
||||
ival = 20; // 20 fps as default
|
||||
|
||||
cl->next_messageinterval = SV_CheckUpdateRate( 1.0 / ival );
|
||||
cl->netchan.rate = SV_CheckRate( cl->netchan.rate );
|
||||
|
||||
// call prog code to allow overrides
|
||||
svgame.dllFuncs.pfnClientUserInfoChanged( cl->edict, cl->userinfo );
|
||||
@@ -3602,7 +3635,7 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
||||
frame = &cl->frames[cl->netchan.incoming_acknowledged & SV_UPDATE_MASK];
|
||||
|
||||
// ping time doesn't factor in message interval, either
|
||||
frame->ping_time = host.realtime - frame->senttime - cl->cl_updaterate;
|
||||
frame->ping_time = host.realtime - frame->senttime - cl->next_messageinterval;
|
||||
|
||||
// on first frame ( no senttime ) don't skew ping
|
||||
if( frame->senttime == 0.0f ) frame->ping_time = 0.0f;
|
||||
|
||||
@@ -892,8 +892,7 @@ void SV_SendClientMessages( void )
|
||||
|
||||
// now that we were able to send, reset timer to point to next possible send time.
|
||||
// check here also because sv_max/minupdaterate could been changed in runtime
|
||||
updaterate_time = bound( 1.0 / sv_maxupdaterate.value, cl->cl_updaterate, 1.0 / sv_minupdaterate.value );
|
||||
cl->next_messagetime = host.realtime + sv.frametime + updaterate_time;
|
||||
cl->next_messagetime = host.realtime + sv.frametime + cl->next_messageinterval;
|
||||
ClearBits( cl->flags, FCL_SEND_NET_MESSAGE );
|
||||
|
||||
// NOTE: we should send frame even if server is not simulated to prevent overflow
|
||||
|
||||
@@ -34,10 +34,10 @@ CVAR_DEFINE_AUTO( rcon_enable, "1", FCVAR_PROTECTED, "enable accepting remote co
|
||||
CVAR_DEFINE_AUTO( sv_cheats, "0", FCVAR_SERVER, "allow cheats on server" );
|
||||
CVAR_DEFINE_AUTO( sv_instancedbaseline, "1", 0, "allow to use instanced baselines to saves network overhead" );
|
||||
static CVAR_DEFINE_AUTO( sv_contact, "", FCVAR_ARCHIVE|FCVAR_SERVER, "server techincal support contact address or web-page" );
|
||||
CVAR_DEFINE_AUTO( sv_minupdaterate, "25.0", FCVAR_ARCHIVE, "minimal value for 'cl_updaterate' window" );
|
||||
CVAR_DEFINE_AUTO( sv_maxupdaterate, "60.0", FCVAR_ARCHIVE, "maximal value for 'cl_updaterate' window" );
|
||||
CVAR_DEFINE_AUTO( sv_minupdaterate, "10.0", FCVAR_ARCHIVE, "minimal value for 'cl_updaterate' window, 0 == unlimited" );
|
||||
CVAR_DEFINE_AUTO( sv_maxupdaterate, "60.0", FCVAR_ARCHIVE, "maximal value for 'cl_updaterate' window, 0 == unlimited" );
|
||||
CVAR_DEFINE_AUTO( sv_minrate, "5000", FCVAR_SERVER, "min bandwidth rate allowed on server, 0 == unlimited" );
|
||||
CVAR_DEFINE_AUTO( sv_maxrate, "50000", FCVAR_SERVER, "max bandwidth rate allowed on server, 0 == unlimited" );
|
||||
CVAR_DEFINE_AUTO( sv_maxrate, "0", FCVAR_SERVER, "max bandwidth rate allowed on server, 0 == unlimited" );
|
||||
// TODO: CVAR_DEFINE_AUTO( sv_logrelay, "0", FCVAR_ARCHIVE, "allow log messages from remote machines to be logged on this server" );
|
||||
CVAR_DEFINE_AUTO( sv_newunit, "0", 0, "clear level-saves from previous SP game chapter to help keep .sav file size as minimum" );
|
||||
CVAR_DEFINE_AUTO( sv_clienttrace, "1", FCVAR_SERVER, "0 = big box(Quake), 0.5 = halfsize, 1 = normal (100%), otherwise it's a scaling factor" );
|
||||
|
||||
@@ -727,16 +727,19 @@ static void SV_SetupMoveInterpolant( sv_client_t *cl )
|
||||
|
||||
if( sv_maxunlag.value != 0.0f )
|
||||
{
|
||||
if (sv_maxunlag.value < 0.0f )
|
||||
Cvar_SetValue( "sv_maxunlag", 0.0f );
|
||||
if( sv_maxunlag.value < 0.0f )
|
||||
Cvar_DirectSetValue( &sv_maxunlag, 0.0f );
|
||||
|
||||
latency = Q_min( latency, sv_maxunlag.value );
|
||||
}
|
||||
|
||||
lerp_msec = cl->lastcmd.lerp_msec * 0.001f;
|
||||
if( lerp_msec > 0.1f ) lerp_msec = 0.1f;
|
||||
|
||||
if( lerp_msec < cl->cl_updaterate )
|
||||
lerp_msec = cl->cl_updaterate;
|
||||
if( lerp_msec > 0.1f )
|
||||
lerp_msec = 0.1f;
|
||||
|
||||
if( lerp_msec < cl->next_messageinterval )
|
||||
lerp_msec = cl->next_messageinterval;
|
||||
|
||||
finalpush = ( host.realtime - latency - lerp_msec ) + sv_unlagpush.value;
|
||||
if( finalpush > host.realtime ) finalpush = host.realtime; // pushed too much ?
|
||||
|
||||
Reference in New Issue
Block a user