LagCompensation: fixes and improvements

This commit is contained in:
BotoX 2019-10-20 12:44:34 +02:00
parent 699deab40a
commit 9b22f87169
1 changed files with 62 additions and 28 deletions

View File

@ -22,7 +22,7 @@ bool g_bLateLoad = false;
#define MAX_EDICTS 2048
#define MAX_RECORDS 32
#define MAX_ENTITIES 64
#define MAX_ENTITIES 128
//#define DEBUG
enum struct LagRecord
@ -43,6 +43,7 @@ enum struct EntityLagData
int iNotMoving;
int iTouchStamp;
bool bRestore;
bool bLateKill;
LagRecord RestoreData;
}
@ -59,7 +60,7 @@ Handle g_hUTIL_Remove;
Handle g_hRestartRound;
char g_aBlockTriggerTouch[MAX_EDICTS] = {0, ...};
char g_aaDeleted[MAXPLAYERS + 1][MAX_EDICTS];
char g_aaBlockTouch[MAXPLAYERS + 1][MAX_EDICTS];
public void OnPluginStart()
{
@ -131,14 +132,14 @@ public void OnPluginStart()
RegAdminCmd("sm_unlag", Command_AddLagCompensation, ADMFLAG_RCON, "sm_unlag <entidx>");
RegAdminCmd("sm_lagged", Command_CheckLagCompensated, ADMFLAG_GENERIC, "sm_lagged");
FilterClientEntityMap(g_aaDeleted, true);
FilterClientEntityMap(g_aaBlockTouch, true);
}
public Action Command_AddLagCompensation(int client, int argc)
{
if(argc < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_unlag <entidx>");
ReplyToCommand(client, "[SM] Usage: sm_unlag <entidx> [late]");
return Plugin_Handled;
}
@ -147,7 +148,14 @@ public Action Command_AddLagCompensation(int client, int argc)
int entity = StringToInt(sArgs);
AddEntityForLagCompensation(entity);
bool late = false;
if(argc >= 2)
{
GetCmdArg(2, sArgs, sizeof(sArgs));
late = view_as<bool>(StringToInt(sArgs));
}
AddEntityForLagCompensation(entity, late);
g_aBlockTriggerTouch[entity] = 1;
return Plugin_Handled;
@ -173,7 +181,7 @@ public Action Command_CheckLagCompensated(int client, int argc)
bool bDeleted = false;
for(int j = 1; j <= MaxClients; j++)
{
if(g_aaDeleted[j][i])
if(g_aaBlockTouch[j][i])
{
bDeleted = true;
break;
@ -214,7 +222,7 @@ public Action Command_CheckLagCompensated(int client, int argc)
public void OnPluginEnd()
{
g_bCleaningUp = true;
FilterClientEntityMap(g_aaDeleted, false);
FilterClientEntityMap(g_aaBlockTouch, false);
FilterTriggerTouchPlayers(g_aBlockTriggerTouch, false);
DHookDisableDetour(g_hUTIL_Remove, false, Detour_OnUTIL_Remove);
@ -251,6 +259,14 @@ public MRESReturn Detour_OnUTIL_Remove(Handle hParams)
if(g_aEntityLagData[i].iEntity != entity)
continue;
// let it die
if(!g_aEntityLagData[i].bLateKill)
break;
// ignore sleeping entities
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
break;
if(!g_aEntityLagData[i].iDeleted)
{
g_aEntityLagData[i].iDeleted = GetGameTickCount();
@ -271,13 +287,13 @@ public MRESReturn Detour_OnRestartRound()
{
g_aBlockTriggerTouch[g_aEntityLagData[i].iEntity] = 0;
for(int client = 1; client <= MaxClients; client++)
{
g_aaBlockTouch[client][g_aEntityLagData[i].iEntity] = 0;
}
if(g_aEntityLagData[i].iDeleted)
{
for(int client = 1; client <= MaxClients; client++)
{
g_aaDeleted[client][g_aEntityLagData[i].iEntity] = 0;
}
if(IsValidEntity(g_aEntityLagData[i].iEntity))
RemoveEdict(g_aEntityLagData[i].iEntity);
}
@ -342,6 +358,7 @@ public void OnRunThinkFunctions(bool simulating)
// so the correct +1'd touchStamp is stored in the touchlink.
// After simulating the players we restore the old touchStamp (-1) and when the entity is simulated it will increase it again by 1
// Thus both touchlinks will have the correct touchStamp value.
// The touchStamp doesn't increase when the entity is idle, however it also doesn't check untouch so we're fine.
touchStamp++;
SetEntProp(g_aEntityLagData[i].iEntity, Prop_Data, "touchStamp", touchStamp);
@ -380,22 +397,33 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
if(!IsPlayerAlive(client))
return Plugin_Continue;
int iDelta = GetGameTickCount() - tickcount;
int iGameTick = GetGameTickCount();
int iDelta = iGameTick - tickcount;
if(iDelta < 0)
iDelta = 0;
if(iDelta > MAX_RECORDS)
iDelta = MAX_RECORDS;
int iPlayerSimTick = GetGameTickCount() + iDelta;
int iPlayerSimTick = iGameTick + iDelta;
for(int i = 0; i < g_iNumEntities; i++)
{
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
continue;
int iEntity = g_aEntityLagData[i].iEntity;
// Entity too new, the client couldn't even see it yet.
if(g_aEntityLagData[i].iSpawned < iPlayerSimTick)
{
g_aaBlockTouch[client][iEntity] = 1;
continue;
}
else if(g_aEntityLagData[i].iSpawned == iPlayerSimTick)
{
g_aaBlockTouch[client][iEntity] = 0;
}
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
continue;
if(iDelta >= g_aEntityLagData[i].iNumRecords)
@ -403,10 +431,10 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
if(g_aEntityLagData[i].iDeleted)
{
int iEntitySimTick = GetGameTickCount() - iDelta;
int iEntitySimTick = iGameTick - iDelta;
if(iEntitySimTick > g_aEntityLagData[i].iDeleted)
{
g_aaDeleted[client][g_aEntityLagData[i].iEntity] = 1;
g_aaBlockTouch[client][iEntity] = 1;
continue;
}
}
@ -415,11 +443,11 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
if(iRecordIndex < 0)
iRecordIndex += MAX_RECORDS;
RestoreEntityFromRecord(g_aEntityLagData[i].iEntity, g_aaLagRecords[i][iRecordIndex]);
RestoreEntityFromRecord(iEntity, g_aaLagRecords[i][iRecordIndex]);
g_aEntityLagData[i].bRestore = !g_aEntityLagData[i].iDeleted;
#if defined DEBUG
LogMessage("2 [%d] index %d, Entity %d -> iDelta = %d | Record = %d", GetGameTickCount(), i, g_aEntityLagData[i].iEntity, iDelta, iRecordIndex);
LogMessage("2 [%d] index %d, Entity %d -> iDelta = %d | Record = %d", iGameTick, i, iEntity, iDelta, iRecordIndex);
LogMessage("%f %f %f",
g_aaLagRecords[i][iRecordIndex].vecOrigin[0],
g_aaLagRecords[i][iRecordIndex].vecOrigin[1],
@ -487,6 +515,8 @@ public void OnRunThinkFunctionsPost(bool simulating)
g_aaLagRecords[i][iOldRecord].vecOrigin[2] == TmpRecord.vecOrigin[2])
{
g_aEntityLagData[i].iNotMoving++;
#if defined DEBUG
if(g_aEntityLagData[i].iNotMoving == MAX_RECORDS)
{
char sClassname[64];
@ -499,9 +529,11 @@ public void OnRunThinkFunctionsPost(bool simulating)
PrintToBoth("[%d] entity %d (%s)\"%s\"(#%d) index %d GOING TO SLEEP", GetGameTickCount(), g_aEntityLagData[i].iEntity, sClassname, sTargetname, iHammerID, i);
}
#endif
}
else
{
#if defined DEBUG
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
{
char sClassname[64];
@ -514,6 +546,8 @@ public void OnRunThinkFunctionsPost(bool simulating)
PrintToBoth("[%d] entity %d (%s)\"%s\"(#%d) index %d WAKING UP", GetGameTickCount(), g_aEntityLagData[i].iEntity, sClassname, sTargetname, iHammerID, i);
}
#endif
g_aEntityLagData[i].iNotMoving = 0;
}
@ -558,7 +592,7 @@ void RestoreEntityFromRecord(int iEntity, LagRecord Record)
SetEntPropFloat(iEntity, Prop_Data, "m_flSimulationTime", Record.flSimulationTime);
}
bool AddEntityForLagCompensation(int iEntity)
bool AddEntityForLagCompensation(int iEntity, bool bLateKill)
{
if(g_bCleaningUp)
return false;
@ -594,6 +628,7 @@ bool AddEntityForLagCompensation(int iEntity)
g_aEntityLagData[i].iDeleted = 0;
g_aEntityLagData[i].iNotMoving = MAX_RECORDS;
g_aEntityLagData[i].bRestore = false;
g_aEntityLagData[i].bLateKill = bLateKill;
RecordDataIntoRecord(iEntity, g_aaLagRecords[i][0]);
@ -625,7 +660,7 @@ public void OnEntitySpawned(int entity, const char[] classname)
if(!strncmp(classname, "func_physbox", 12))
{
AddEntityForLagCompensation(entity);
AddEntityForLagCompensation(entity, false);
return;
}
@ -648,6 +683,7 @@ public void OnEntitySpawned(int entity, const char[] classname)
if(StrEqual(sParentClassname[5], "movelinear") ||
StrEqual(sParentClassname[5], "door") ||
StrEqual(sParentClassname[5], "rotating") ||
StrEqual(sParentClassname[5], "tracktrain") ||
!strncmp(sParentClassname[5], "physbox", 7))
{
@ -662,7 +698,7 @@ public void OnEntitySpawned(int entity, const char[] classname)
if(!bGoodParents)
return;
if(!AddEntityForLagCompensation(entity))
if(!AddEntityForLagCompensation(entity, true))
return;
g_aBlockTriggerTouch[entity] = 1;
@ -708,12 +744,9 @@ void RemoveRecord(int index)
g_aBlockTriggerTouch[g_aEntityLagData[index].iEntity] = 0;
if(g_aEntityLagData[index].iDeleted)
for(int client = 1; client <= MaxClients; client++)
{
for(int client = 1; client <= MaxClients; client++)
{
g_aaDeleted[client][g_aEntityLagData[index].iEntity] = 0;
}
g_aaBlockTouch[client][g_aEntityLagData[index].iEntity] = 0;
}
g_aEntityLagData[index].iEntity = INVALID_ENT_REFERENCE;
@ -746,6 +779,7 @@ void EntityLagData_Copy(EntityLagData obj, const EntityLagData other)
obj.iNotMoving = other.iNotMoving;
obj.iTouchStamp = other.iTouchStamp;
obj.bRestore = other.bRestore;
obj.bLateKill = other.bLateKill;
LagRecord_Copy(obj.RestoreData, other.RestoreData);
}