mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Server: simplify lagcomp clamping code and add technical notes
Clamp to +- sv_maxunlag delta from server time base. Also added notes to possibly rework the system in the future.
This commit is contained in:
parent
c3f66e748f
commit
1fe74fe727
@ -112,65 +112,6 @@ void CPlayer::SetTotalExtraClientCmdTimeAttempted(float flAttemptedTime)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: clamps the unlag amount to sv_unlag + clockdrift
|
||||
// Input : *cmd -
|
||||
//------------------------------------------------------------------------------
|
||||
void CPlayer::ClampUnlag(CUserCmd* cmd)
|
||||
{
|
||||
const CClient* client = g_pServer->GetClient(GetEdict() - 1);
|
||||
const CNetChan* chan = client->GetNetChan();
|
||||
|
||||
const float clockDriftMsecs = sv_clockcorrection_msecs->GetFloat() / 1000.0f;
|
||||
const float maxUnlag = sv_maxunlag->GetFloat();
|
||||
const float latencyAmount = Clamp(chan->GetLatency(FLOW_OUTGOING), 0.0f, maxUnlag);
|
||||
const float serverTime = (*g_pGlobals)->m_flCurTime;
|
||||
|
||||
// Command issue time from client, note that this value can be altered
|
||||
// from the client, and therefore be used to exploit lag compensation.
|
||||
const float commandTime = cmd->command_time;
|
||||
const float lastCommandTime = m_LastCmd.command_time;
|
||||
const float commandDelta = fabs(commandTime - serverTime);
|
||||
|
||||
bool recomputeUnlag = false;
|
||||
|
||||
// Check delta first, otherwise player could set commandTime to a fixed
|
||||
// time and circumvent the system, as commandTime < lastCommandTime or
|
||||
// commandTime > localCurTime will always fail.
|
||||
if (commandDelta > maxUnlag)
|
||||
{
|
||||
// Too much to unlag, clamp to max !!!
|
||||
recomputeUnlag = true;
|
||||
DevWarning(eDLL_T::SERVER, "%s: commandDelta( %f ) > maxUnlag( %f ) !!!\n",
|
||||
__FUNCTION__, commandDelta, maxUnlag);
|
||||
}
|
||||
else if (commandTime < (lastCommandTime - clockDriftMsecs))
|
||||
{
|
||||
// Can never be lower than last !!!
|
||||
recomputeUnlag = true;
|
||||
DevWarning(eDLL_T::SERVER, "%s: cmd->command_time( %f ) < (m_LastCmd.command_time( %f ) - clockDriftMsecs( %f )) !!!\n",
|
||||
__FUNCTION__, commandTime, lastCommandTime, clockDriftMsecs);
|
||||
}
|
||||
else if (commandTime > (serverTime + clockDriftMsecs))
|
||||
{
|
||||
// Too far in the future, clamp to max !!!
|
||||
recomputeUnlag = true;
|
||||
DevWarning(eDLL_T::SERVER, "%s: cmd->command_time( %f ) > (g_pGlobals->m_flCurTime( %f ) + clockDriftMsecs( %f )) !!!\n",
|
||||
__FUNCTION__, commandTime, serverTime, clockDriftMsecs);
|
||||
}
|
||||
|
||||
if (recomputeUnlag)
|
||||
{
|
||||
// Clamp it to server time minus latency. Note that it could still
|
||||
// be lower than previous, hence the clamp on the recomputation.
|
||||
float newCommandTime = Clamp(serverTime - latencyAmount, lastCommandTime, serverTime);
|
||||
cmd->command_time = newCommandTime;
|
||||
|
||||
DevWarning(eDLL_T::SERVER, "%s: Clamped cmd->command_time( %f ) to %f !!!\n",
|
||||
__FUNCTION__, commandTime, newCommandTime);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose: processes user cmd's for this player
|
||||
// Input : *cmds -
|
||||
@ -182,7 +123,7 @@ void CPlayer::ClampUnlag(CUserCmd* cmd)
|
||||
// TODO: this code is experimental and has reported problems from players with
|
||||
// high latency, needs to be debugged or a different approach needs to be taken!
|
||||
// Defaulted to OFF for now
|
||||
static ConVar sv_unlag_clamp("sv_unlag_clamp", "0", FCVAR_RELEASE, "Clamp the difference between the current time and received command time to sv_maxunlag + sv_clockcorrection_msecs.");
|
||||
static ConVar sv_unlag_clamp("sv_unlag_clamp", "0", FCVAR_RELEASE, "Clamp the difference between the current time and received command time to sv_maxunlag.");
|
||||
|
||||
void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
||||
int droppedPackets, bool paused)
|
||||
@ -192,6 +133,9 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
||||
|
||||
CUserCmd* lastCmd = &m_Commands[MAX_QUEUED_COMMANDS_PROCESS];
|
||||
|
||||
const float maxUnlag = sv_maxunlag->GetFloat();
|
||||
const float currTime = (*g_pGlobals)->m_flCurTime;
|
||||
|
||||
for (int i = totalCmds - 1; i >= 0; i--)
|
||||
{
|
||||
CUserCmd* cmd = &cmds[i];
|
||||
@ -206,8 +150,22 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
||||
if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS)
|
||||
return;
|
||||
|
||||
// TODO: why are grenades not clamped to sv_maxunlag ???
|
||||
// TODO: the command_time is set from the client itself in CInput::CreateMove
|
||||
// to gpGlobals->curtime in the ucmd packet, perhaps just calculate it from
|
||||
// the server based on ucmd ticks ???
|
||||
//
|
||||
// Possible solutions that need to be explored and worked out further:
|
||||
//
|
||||
// cmd->command_time = TICKS_TO_TIME(cmd->command_number + cmd->tick_count) // seems to be the closest, but also still manipulatable from the client.
|
||||
// cmd->command_time = TICKS_TO_TIME(client->GetDeltaTick() + cmd->command_number) // delta tick is not necessarily the same as actual ucmd tick, and will be -1 on baseline request.
|
||||
// cmd->command_time = TICKS_TO_TIME(m_lastUCmdSimulationRemainderTime) + m_totalExtraClientCmdTimeAttempted; // player timebase; also up to 100ms difference between orig sent value.
|
||||
//
|
||||
// ... reverse more ticks and floats in CClient since there seem to be a
|
||||
// bunch still in the padded bytes, possibly one of them is what we could
|
||||
// and should actually use to get the remote client time since ucmd was sent.
|
||||
if (sv_unlag_clamp.GetBool())
|
||||
ClampUnlag(cmd);
|
||||
cmd->command_time = Min(Max(cmd->command_time, Max(currTime - maxUnlag, 0.0f)), currTime + maxUnlag);
|
||||
|
||||
CUserCmd* queuedCmd = &m_Commands[lastCommandNumber];
|
||||
queuedCmd->Copy(cmd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user