mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Finish unlag exploit fix
- Make sure cmdTime is never lower than last. - Make sure delta doesn't exceed maxUnlag. - Make sure latency gets clamped to maxUnlag (clamp appears to be missing in the engine). - Only check for cmdTime if we are not discarding the cmd; previously, already processed queued cmd's got checked before being discarded.
This commit is contained in:
parent
631e6d9e17
commit
3ff85c174a
@ -104,7 +104,7 @@ ConVar* sv_forceChatToTeamOnly = nullptr;
|
||||
|
||||
ConVar* sv_single_core_dedi = nullptr;
|
||||
|
||||
ConVar* sv_maxunlag_delta = nullptr;
|
||||
ConVar* sv_maxunlag = nullptr;
|
||||
|
||||
ConVar* sv_updaterate_sp = nullptr;
|
||||
ConVar* sv_updaterate_mp = nullptr;
|
||||
@ -328,8 +328,6 @@ void ConVar_StaticInit(void)
|
||||
sv_autoReloadRate = ConVar::StaticCreate("sv_autoReloadRate" , "0" , FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null).", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_simulateBots = ConVar::StaticCreate("sv_simulateBots", "1", FCVAR_RELEASE, "Simulate user commands for bots on the server.", true, 0.f, false, 0.f, nullptr, nullptr);
|
||||
|
||||
sv_maxunlag_delta = ConVar::StaticCreate("sv_maxunlag_delta", "0.3", FCVAR_RELEASE, "Maximum amount of deviation in seconds between server and UserCmd's issue time for unlag (excludes latency).", true, 0.f, true, 1.f, nullptr, nullptr);
|
||||
|
||||
sv_rcon_debug = ConVar::StaticCreate("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
sv_rcon_sendlogs = ConVar::StaticCreate("sv_rcon_sendlogs" , "0" , FCVAR_RELEASE, "Network console logs to connected and authenticated sockets.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
//sv_rcon_banpenalty = ConVar::StaticCreate("sv_rcon_banpenalty" , "10", FCVAR_RELEASE, "Number of minutes to ban users who fail rcon authentication.", false, 0.f, false, 0.f, nullptr, nullptr);
|
||||
@ -520,6 +518,8 @@ void ConVar_InitShipped(void)
|
||||
#ifndef CLIENT_DLL
|
||||
sv_stats = g_pCVar->FindVar("sv_stats");
|
||||
|
||||
sv_maxunlag = g_pCVar->FindVar("sv_maxunlag");
|
||||
|
||||
sv_updaterate_sp = g_pCVar->FindVar("sv_updaterate_sp");
|
||||
sv_updaterate_mp = g_pCVar->FindVar("sv_updaterate_mp");
|
||||
|
||||
|
@ -93,7 +93,7 @@ extern ConVar* sv_forceChatToTeamOnly;
|
||||
|
||||
extern ConVar* sv_single_core_dedi;
|
||||
|
||||
extern ConVar* sv_maxunlag_delta;
|
||||
extern ConVar* sv_maxunlag;
|
||||
|
||||
extern ConVar* sv_updaterate_sp;
|
||||
extern ConVar* sv_updaterate_mp;
|
||||
|
@ -125,49 +125,64 @@ void CPlayer::ProcessUserCmds(CUserCmd* cmds, int numCmds, int totalCmds,
|
||||
|
||||
CUserCmd* lastCmd = &m_Commands[MAX_QUEUED_COMMANDS_PROCESS];
|
||||
|
||||
const float latencyAmount = chan->GetLatency(FLOW_OUTGOING);
|
||||
const float maxCommandDelta = sv_maxunlag_delta->GetFloat();
|
||||
const float maxUnlag = sv_maxunlag->GetFloat();
|
||||
const float latencyAmount = Clamp(chan->GetLatency(FLOW_OUTGOING), 0.0f, maxUnlag);
|
||||
const float localCurTime = (*g_pGlobals)->m_flCurTime;
|
||||
const float lastCommandTime = m_LastCmd.command_time;
|
||||
|
||||
for (int i = totalCmds - 1; i >= 0; i--)
|
||||
{
|
||||
CUserCmd* cmd = &cmds[i];
|
||||
const int commandNumber = cmd->command_number;
|
||||
|
||||
if (commandNumber <= m_latestCommandQueued)
|
||||
continue;
|
||||
|
||||
m_latestCommandQueued = commandNumber;
|
||||
const int lastCommandNumber = lastCmd->command_number;
|
||||
|
||||
if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS)
|
||||
return;
|
||||
|
||||
// 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 commandDelta = fabs(commandTime - localCurTime) - latencyAmount;
|
||||
const float lastCommandTime = m_LastCmd.command_time;
|
||||
|
||||
if (/*commandTime < lastCommandTime ||*/ commandDelta > maxCommandDelta)
|
||||
if (commandTime < lastCommandTime) // Can never be lower than last !!!
|
||||
{
|
||||
cmd->command_time = localCurTime - latencyAmount;
|
||||
|
||||
if (IsDebug())
|
||||
{
|
||||
Warning(eDLL_T::SERVER, "%s: Command delta of %f exceeded maximum of %f; commandTime=%f, lastCommandTime=%f, localCurTime=%f, latencyAmount=%f\n",
|
||||
__FUNCTION__, commandDelta, maxCommandDelta, commandTime, lastCommandTime, localCurTime, latencyAmount);
|
||||
Warning(eDLL_T::SERVER, "%s: cmd->command_time( %f ) < m_LastCmd.command_time( %f ); clamped to %f !!!\n",
|
||||
__FUNCTION__, commandTime, lastCommandTime, cmd->command_time);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const float commandDelta = fabs(commandTime - localCurTime);
|
||||
|
||||
if (commandDelta > maxUnlag) // Too much to unlag, clamp to max !!!
|
||||
{
|
||||
cmd->command_time = localCurTime - latencyAmount;
|
||||
|
||||
if (IsDebug())
|
||||
{
|
||||
Warning(eDLL_T::SERVER, "%s: commandDelta( %f ) > maxUnlag( %f ); clamped to %f !!!\n",
|
||||
__FUNCTION__, commandDelta, maxUnlag, cmd->command_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int commandNumber = cmd->command_number;
|
||||
CUserCmd* queuedCmd = &m_Commands[lastCommandNumber];
|
||||
queuedCmd->Copy(cmd);
|
||||
|
||||
if (commandNumber > m_latestCommandQueued)
|
||||
if (++lastCmd->command_number > player_userCmdsQueueWarning->GetInt())
|
||||
{
|
||||
m_latestCommandQueued = commandNumber;
|
||||
const int lastCommandNumber = lastCmd->command_number;
|
||||
const float curTime = float(Plat_FloatTime());
|
||||
|
||||
if (lastCommandNumber == MAX_QUEUED_COMMANDS_PROCESS)
|
||||
return;
|
||||
|
||||
CUserCmd* queuedCmd = &m_Commands[lastCommandNumber];
|
||||
queuedCmd->Copy(cmd);
|
||||
|
||||
if (++lastCmd->command_number > player_userCmdsQueueWarning->GetInt())
|
||||
{
|
||||
const float curTime = float(Plat_FloatTime());
|
||||
|
||||
if ((curTime - m_lastCommandCountWarnTime) > 0.5f)
|
||||
m_lastCommandCountWarnTime = curTime;
|
||||
}
|
||||
if ((curTime - m_lastCommandCountWarnTime) > 0.5f)
|
||||
m_lastCommandCountWarnTime = curTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user