Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new CVar: sv_maxusrcmdprocessticks #844

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rehlds/engine/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ extern cvar_t sv_rehlds_attachedentities_playeranimationspeed_fix;
extern cvar_t sv_rehlds_local_gametime;
extern cvar_t sv_rehlds_send_mapcycle;
extern cvar_t sv_usercmd_custom_random_seed;
extern cvar_t sv_maxusrcmdprocessticks;
extern cvar_t sv_maxusrcmdprocessticks_warning;
#endif
extern int sv_playermodel;

Expand Down
4 changes: 4 additions & 0 deletions rehlds/engine/sv_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ cvar_t sv_rehlds_send_mapcycle = { "sv_rehlds_send_mapcycle", "0", 0, 0.0f, null
cvar_t sv_rehlds_maxclients_from_single_ip = { "sv_rehlds_maxclients_from_single_ip", "5", 0, 5.0f, nullptr };
cvar_t sv_use_entity_file = { "sv_use_entity_file", "0", 0, 0.0f, nullptr };
cvar_t sv_usercmd_custom_random_seed = { "sv_usercmd_custom_random_seed", "0", 0, 0.0f, nullptr };
cvar_t sv_maxusrcmdprocessticks = { "sv_maxusrcmdprocessticks", "16", 0, 0.0f, nullptr };
cvar_t sv_maxusrcmdprocessticks_warning = { "sv_maxusrcmdprocessticks_warning", "-1", 0, 0.0f, nullptr };
#endif

delta_t *SV_LookupDelta(char *name)
Expand Down Expand Up @@ -8300,6 +8302,8 @@ void SV_Init(void)
Cvar_RegisterVariable(&sv_rollangle);
Cvar_RegisterVariable(&sv_use_entity_file);
Cvar_RegisterVariable(&sv_usercmd_custom_random_seed);
Cvar_RegisterVariable(&sv_maxusrcmdprocessticks);
Cvar_RegisterVariable(&sv_maxusrcmdprocessticks_warning);
#endif

for (int i = 0; i < MAX_MODELS; i++)
Expand Down
48 changes: 48 additions & 0 deletions rehlds/engine/sv_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,54 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
}
#endif

#ifdef REHLDS_FIXES
#define TICK_INTERVAL (1.0f / sys_ticrate.value)

CGameClient* gameClient = g_GameClients[host_client - g_psvs.clients];
// bool bRunNullCmd = false;
if (int numUsrCmdProcessTicksMax = (int)sv_maxusrcmdprocessticks.value)
{
// Grant the client some time buffer to execute user commands
gameClient->m_flMovementTimeForUserCmdProcessingRemaining += TICK_INTERVAL;

// but never accumulate more than N ticks
if (gameClient->GetRemainingMovementTimeForUserCmdProcessing() > numUsrCmdProcessTicksMax * TICK_INTERVAL)
{
gameClient->m_flMovementTimeForUserCmdProcessingRemaining = numUsrCmdProcessTicksMax * TICK_INTERVAL;
// bRunNullCmd = true;
}
}
/*else
{
// Otherwise we don't care to track time
m_flMovementTimeForUserCmdProcessingRemaining = FLT_MAX;
}
*/

float playerFrameTime = TICK_INTERVAL;
float flTimeAllowedForProcessing = gameClient->ConsumeMovementTimeForUserCmdProcessing(playerFrameTime);
bool isBot = host_client->fakeclient;

if (!isBot && (flTimeAllowedForProcessing < playerFrameTime))
{
// Make sure that the activity in command is erased because player cheated or dropped too many packets
double dblWarningFrequencyThrottle = sv_maxusrcmdprocessticks_warning.value;
if (dblWarningFrequencyThrottle >= 0.0)
{
static double s_dblLastWarningTime = 0.0;
double dblTimeNow = Sys_FloatTime();
if (!s_dblLastWarningTime || (dblTimeNow - s_dblLastWarningTime >= dblWarningFrequencyThrottle))
{
s_dblLastWarningTime = dblTimeNow;
Con_Printf("sv_maxusrcmdprocessticks_warning at server tick %u: Ignored client %s usrcmd (%.6f < %.6f)!\n",
/* System::GetTick() */ 123, host_client->name, flTimeAllowedForProcessing, playerFrameTime);
}
}

return; // Don't process this command
}
#endif // REHLDS_FIXES

gEntityInterface.pfnCmdStart(sv_player, ucmd, random_seed);
frametime = float(ucmd->msec * 0.001);
host_client->svtimebase = frametime + host_client->svtimebase;
Expand Down
24 changes: 24 additions & 0 deletions rehlds/rehlds/rehlds_interfaces_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,30 @@ class CGameClient : public IGameClient
void SetupLocalGameTime() { m_localGameTimeBase = g_psv.time; }
double GetLocalGameTime() const { return g_psv.time - m_localGameTimeBase; }
double GetLocalGameTimeBase() const { return m_localGameTimeBase; }

// How much of a movement time buffer can we process from this user?
float m_flMovementTimeForUserCmdProcessingRemaining;

float GetRemainingMovementTimeForUserCmdProcessing() const { return m_flMovementTimeForUserCmdProcessingRemaining; }
float ConsumeMovementTimeForUserCmdProcessing( float flTimeNeeded )
{
float MOVE_EPSILON = 0.03125f;
if ( m_flMovementTimeForUserCmdProcessingRemaining <= 0.0f )
return 0.0f;
else if ( flTimeNeeded > m_flMovementTimeForUserCmdProcessingRemaining + MOVE_EPSILON )
{
float flResult = m_flMovementTimeForUserCmdProcessingRemaining;
m_flMovementTimeForUserCmdProcessingRemaining = 0.0f;
return flResult;
}
else
{
m_flMovementTimeForUserCmdProcessingRemaining -= flTimeNeeded;
if ( m_flMovementTimeForUserCmdProcessingRemaining < 0.0f )
m_flMovementTimeForUserCmdProcessingRemaining = 0.0f;
return flTimeNeeded;
}
}
#endif
};

Expand Down
Loading