mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Put lag compensation clamping in a separate method, under a cvar that is disabled for now
There have been reports of hit registration issues, this is most likely caused by the clamping system to mitigate an exploit. Put behind a convar and disabled for now until debugged.
This commit is contained in:
parent
fa76747baa
commit
6bc15b50b5
@ -121,6 +121,7 @@ ConVar* sv_forceChatToTeamOnly = nullptr;
|
|||||||
ConVar* sv_single_core_dedi = nullptr;
|
ConVar* sv_single_core_dedi = nullptr;
|
||||||
|
|
||||||
ConVar* sv_maxunlag = nullptr;
|
ConVar* sv_maxunlag = nullptr;
|
||||||
|
ConVar* sv_unlag_clamp = nullptr;
|
||||||
ConVar* sv_clockcorrection_msecs = nullptr;
|
ConVar* sv_clockcorrection_msecs = nullptr;
|
||||||
|
|
||||||
ConVar* sv_updaterate_sp = nullptr;
|
ConVar* sv_updaterate_sp = nullptr;
|
||||||
@ -364,6 +365,9 @@ void ConVar_StaticInit(void)
|
|||||||
#endif // !DEDICATED
|
#endif // !DEDICATED
|
||||||
|
|
||||||
sv_language = ConVar::StaticCreate("sv_language", "english", FCVAR_RELEASE, "Language of the server. Sent to MasterServer for localising error messages.", false, 0.f, false, 0.f, LanguageChanged_f, nullptr);
|
sv_language = ConVar::StaticCreate("sv_language", "english", FCVAR_RELEASE, "Language of the server. Sent to MasterServer for localising error messages.", false, 0.f, false, 0.f, LanguageChanged_f, nullptr);
|
||||||
|
|
||||||
|
sv_unlag_clamp = ConVar::StaticCreate("sv_unlag_clamp", "0", FCVAR_RELEASE, "Clamp the difference between the current time and received command time to sv_maxunlag + sv_clockcorrection_msecs.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||||
|
|
||||||
sv_showconnecting = ConVar::StaticCreate("sv_showconnecting" , "1", FCVAR_RELEASE, "Logs information about the connecting client to the console.", false, 0.f, false, 0.f, nullptr, nullptr);
|
sv_showconnecting = ConVar::StaticCreate("sv_showconnecting" , "1", FCVAR_RELEASE, "Logs information about the connecting client to the console.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||||
sv_globalBanlist = ConVar::StaticCreate("sv_globalBanlist" , "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, nullptr, "0 = Disable, 1 = Enable.");
|
sv_globalBanlist = ConVar::StaticCreate("sv_globalBanlist" , "1", FCVAR_RELEASE, "Determines whether or not to use the global banned list.", false, 0.f, false, 0.f, nullptr, "0 = Disable, 1 = Enable.");
|
||||||
sv_pylonVisibility = ConVar::StaticCreate("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", false, 0.f, false, 0.f, nullptr, "0 = Offline, 1 = Hidden, 2 = Public.");
|
sv_pylonVisibility = ConVar::StaticCreate("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", false, 0.f, false, 0.f, nullptr, "0 = Offline, 1 = Hidden, 2 = Public.");
|
||||||
|
@ -110,6 +110,7 @@ extern ConVar* sv_forceChatToTeamOnly;
|
|||||||
extern ConVar* sv_single_core_dedi;
|
extern ConVar* sv_single_core_dedi;
|
||||||
|
|
||||||
extern ConVar* sv_maxunlag;
|
extern ConVar* sv_maxunlag;
|
||||||
|
extern ConVar* sv_unlag_clamp;
|
||||||
extern ConVar* sv_clockcorrection_msecs;
|
extern ConVar* sv_clockcorrection_msecs;
|
||||||
|
|
||||||
extern ConVar* sv_updaterate_sp;
|
extern ConVar* sv_updaterate_sp;
|
||||||
|
@ -109,6 +109,65 @@ 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
|
// Purpose: processes user cmd's for this player
|
||||||
// Input : *cmds -
|
// Input : *cmds -
|
||||||
@ -123,16 +182,8 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
|||||||
if (totalCmds <= 0)
|
if (totalCmds <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CClient* client = g_pServer->GetClient(GetEdict() - 1);
|
|
||||||
const CNetChan* chan = client->GetNetChan();
|
|
||||||
|
|
||||||
CUserCmd* lastCmd = &m_Commands[MAX_QUEUED_COMMANDS_PROCESS];
|
CUserCmd* lastCmd = &m_Commands[MAX_QUEUED_COMMANDS_PROCESS];
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
for (int i = totalCmds - 1; i >= 0; i--)
|
for (int i = totalCmds - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
CUserCmd* cmd = &cmds[i];
|
CUserCmd* cmd = &cmds[i];
|
||||||
@ -147,49 +198,8 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
|||||||
if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS)
|
if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Command issue time from client, note that this value can be altered
|
if (sv_unlag_clamp->GetBool())
|
||||||
// from the client, and therefore be used to exploit lag compensation.
|
ClampUnlag(cmd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
CUserCmd* queuedCmd = &m_Commands[lastCommandNumber];
|
CUserCmd* queuedCmd = &m_Commands[lastCommandNumber];
|
||||||
queuedCmd->Copy(cmd);
|
queuedCmd->Copy(cmd);
|
||||||
|
@ -251,6 +251,9 @@ public:
|
|||||||
|
|
||||||
void ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
void ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
||||||
int droppedPackets, bool paused);
|
int droppedPackets, bool paused);
|
||||||
|
|
||||||
|
void ClampUnlag(CUserCmd* cmd);
|
||||||
|
|
||||||
void PlayerRunCommand(CUserCmd* pUserCmd, IMoveHelper* pMover);
|
void PlayerRunCommand(CUserCmd* pUserCmd, IMoveHelper* pMover);
|
||||||
void SetLastUserCommand(CUserCmd* pUserCmd);
|
void SetLastUserCommand(CUserCmd* pUserCmd);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user