From 73db0277f19e1fc78d2a7c378b9586f04909d56a Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Sat, 8 May 2021 18:42:27 +1000 Subject: [PATCH 1/1] test b --- server.h | 1 + sv_main.c | 2 ++ sv_user.c | 14 ++++++++------ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/server.h b/server.h index 79fce3b1..094f3b65 100644 --- a/server.h +++ b/server.h @@ -418,6 +418,7 @@ extern cvar_t sv_allowdownloads_inarchive; extern cvar_t sv_areagrid_mingridsize; extern cvar_t sv_checkforpacketsduringsleep; extern cvar_t sv_clmovement_enable; +extern cvar_t sv_clmovement_maxping; extern cvar_t sv_clmovement_minping; extern cvar_t sv_clmovement_minping_disabletime; extern cvar_t sv_clmovement_inputtimeout; diff --git a/sv_main.c b/sv_main.c index 107551c4..e971da00 100644 --- a/sv_main.c +++ b/sv_main.c @@ -74,6 +74,7 @@ cvar_t sv_allowdownloads_inarchive = {CF_SERVER, "sv_allowdownloads_inarchive", cvar_t sv_areagrid_mingridsize = {CF_SERVER | CF_NOTIFY, "sv_areagrid_mingridsize", "128", "minimum areagrid cell size, smaller values work better for lots of small objects, higher values for large objects"}; cvar_t sv_checkforpacketsduringsleep = {CF_SERVER, "sv_checkforpacketsduringsleep", "0", "uses select() function to wait between frames which can be interrupted by packets being received, instead of Sleep()/usleep()/SDL_Sleep() functions which do not check for packets"}; cvar_t sv_clmovement_enable = {CF_SERVER, "sv_clmovement_enable", "1", "whether to allow clients to use cl_movement prediction, which can cause choppy movement on the server which may annoy other players"}; +cvar_t sv_clmovement_maxping = {CF_SERVER, "sv_clmovement_maxping", "1000", "if client ping is above this time in milliseconds, then their ability to use cl_movement prediction is disabled for a while"}; cvar_t sv_clmovement_minping = {CF_SERVER, "sv_clmovement_minping", "0", "if client ping is below this time in milliseconds, then their ability to use cl_movement prediction is disabled for a while (as they don't need it)"}; cvar_t sv_clmovement_minping_disabletime = {CF_SERVER, "sv_clmovement_minping_disabletime", "1000", "when client falls below minping, disable their prediction for this many milliseconds (should be at least 1000 or else their prediction may turn on/off frequently)"}; cvar_t sv_clmovement_inputtimeout = {CF_SERVER, "sv_clmovement_inputtimeout", "0.1", "when a client does not send input for this many seconds (max 0.1), force them to move anyway (unlike QuakeWorld)"}; @@ -573,6 +574,7 @@ void SV_Init (void) Cvar_RegisterVariable (&sv_areagrid_mingridsize); Cvar_RegisterVariable (&sv_checkforpacketsduringsleep); Cvar_RegisterVariable (&sv_clmovement_enable); + Cvar_RegisterVariable (&sv_clmovement_maxping); Cvar_RegisterVariable (&sv_clmovement_minping); Cvar_RegisterVariable (&sv_clmovement_minping_disabletime); Cvar_RegisterVariable (&sv_clmovement_inputtimeout); diff --git a/sv_user.c b/sv_user.c index 1cb5a3f0..6af9d1a3 100644 --- a/sv_user.c +++ b/sv_user.c @@ -788,9 +788,14 @@ static void SV_ExecuteClientMoves(void) #if DEBUGMOVES Con_Printf("SV_ExecuteClientMoves: read %i moves at sv.time %f\n", sv_numreadmoves, (float)sv.time); #endif + + // update ping time + host_client->ping = max(sv_readmoves[sv_numreadmoves-1].receivetime - sv_readmoves[sv_numreadmoves-1].time, 0); + // disable clientside movement prediction in some cases - if (ceil(max(sv_readmoves[sv_numreadmoves-1].receivetime - sv_readmoves[sv_numreadmoves-1].time, 0) * 1000.0) < sv_clmovement_minping.integer) + if (host_client->ping * 1000.0 < sv_clmovement_minping.value || host_client->ping * 1000.0 > sv_clmovement_maxping.value) host_client->clmovement_disabletimeout = host.realtime + sv_clmovement_minping_disabletime.value / 1000.0; + // several conditions govern whether clientside movement prediction is allowed if (sv_readmoves[sv_numreadmoves-1].sequence && sv_clmovement_enable.integer && sv_clmovement_inputtimeout.value > 0 && host_client->clmovement_disabletimeout <= host.realtime && (PRVM_serveredictfloat(host_client->edict, disableclientprediction) == -1 || (PRVM_serveredictfloat(host_client->edict, movetype) == MOVETYPE_WALK && (!PRVM_serveredictfloat(host_client->edict, disableclientprediction))))) { @@ -808,12 +813,11 @@ static void SV_ExecuteClientMoves(void) Con_Printf("%smove #%u %ims (%ims) %i %i '%i %i %i' '%i %i %i'\n", (move->time - host_client->cmd.time) > sv.frametime * 1.01 ? "^1" : "^2", move->sequence, (int)floor((move->time - host_client->cmd.time) * 1000.0 + 0.5), (int)floor(move->time * 1000.0 + 0.5), move->impulse, move->buttons, (int)move->viewangles[0], (int)move->viewangles[1], (int)move->viewangles[2], (int)move->forwardmove, (int)move->sidemove, (int)move->upmove); #endif // this is a new move - move->time = bound(sv.time - 1, move->time, sv.time); // prevent slowhack/speedhack combos - move->time = max(move->time, host_client->cmd.time); // prevent backstepping of time + // prevent backstepping of time and slowhack/speedhack combos + move->time = bound(host_client->cmd.time, move->time, sv.time); // bones_was_here: limit moveframetime to a multiple of sv.frametime to match inputtimeout behaviour moveframetime = min(move->time - host_client->cmd.time, min(0.1, sys_ticrate.value > 0.0 && sv.frametime > 0.0 ? sv.frametime * ceil(sv_clmovement_inputtimeout.value / sv.frametime) : sv_clmovement_inputtimeout.value)); - // discard (treat like lost) moves with too low distance from // the previous one to prevent hacks using float inaccuracy // clients will see this as packet loss in the netgraph @@ -885,8 +889,6 @@ static void SV_ExecuteClientMoves(void) host_client->movesequence = 0; // make sure that normal physics takes over immediately host_client->clmovement_inputtimeout = 0; - // update ping time - host_client->ping = host_client->cmd.receivetime - sv_readmoves[sv_numreadmoves-1].time; } } -- 2.39.2