LagCompensation, best version so far.

This commit is contained in:
BotoX 2019-10-05 15:17:10 +02:00
parent d74cb89848
commit 6496076cef
1 changed files with 108 additions and 30 deletions

View File

@ -43,25 +43,38 @@ enum struct EntityLagData
LagRecord g_aaLagRecords[MAX_ENTITIES][MAX_RECORDS]; LagRecord g_aaLagRecords[MAX_ENTITIES][MAX_RECORDS];
EntityLagData g_aEntityLagData[MAX_ENTITIES]; EntityLagData g_aEntityLagData[MAX_ENTITIES];
int g_iNumEntities = 0; int g_iNumEntities = 0;
bool g_bCleaningUp = false;
Handle g_hPhysicsTouchTriggers;
Handle g_hGetAbsOrigin; Handle g_hGetAbsOrigin;
Handle g_hSetAbsOrigin; Handle g_hSetAbsOrigin;
Handle g_hGetAbsAngles; Handle g_hGetAbsAngles;
Handle g_hSetAbsAngles; Handle g_hSetAbsAngles;
bool g_bBlockPhysics = false; Handle g_hPhysicsTouchTriggersDetour;
bool g_bNoPhysics[2048];
Handle g_hPhysicsTouchTriggers;
Handle g_hUTIL_Remove; Handle g_hUTIL_Remove;
Handle g_hRestartRound; Handle g_hRestartRound;
bool g_bBlockPhysics = false;
char g_aBlockPhysics[2048];
char g_aaDeleted[MAXPLAYERS + 1][2048];
public void OnPluginStart() public void OnPluginStart()
{ {
PrintToServer("MAXPLAYERS = %d / MaxClients = %d", MAXPLAYERS, MaxClients);
Handle hGameData = LoadGameConfigFile("LagCompensation.games"); Handle hGameData = LoadGameConfigFile("LagCompensation.games");
if(!hGameData) if(!hGameData)
SetFailState("Failed to load LagCompensation gamedata."); SetFailState("Failed to load LagCompensation gamedata.");
// CBaseEntity::PhysicsTouchTriggers
StartPrepSDKCall(SDKCall_Entity);
if(!PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, "CBaseEntity::PhysicsTouchTriggers"))
{
delete hGameData;
SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, \"CBaseEntity::PhysicsTouchTriggers\") failed!");
}
PrepSDKCall_AddParameter(SDKType_Vector, SDKPass_ByRef);
g_hPhysicsTouchTriggers = EndPrepSDKCall();
// CBaseEntity::GetAbsOrigin // CBaseEntity::GetAbsOrigin
StartPrepSDKCall(SDKCall_Entity); StartPrepSDKCall(SDKCall_Entity);
@ -106,14 +119,14 @@ public void OnPluginStart()
// CBaseEntity::PhysicsTouchTriggers // CBaseEntity::PhysicsTouchTriggers
g_hPhysicsTouchTriggers = DHookCreateFromConf(hGameData, "CBaseEntity__PhysicsTouchTriggers"); g_hPhysicsTouchTriggersDetour = DHookCreateFromConf(hGameData, "CBaseEntity__PhysicsTouchTriggers");
if(!g_hPhysicsTouchTriggers) if(!g_hPhysicsTouchTriggersDetour)
{ {
delete hGameData; delete hGameData;
SetFailState("Failed to setup detour for CBaseEntity__PhysicsTouchTriggers"); SetFailState("Failed to setup detour for CBaseEntity__PhysicsTouchTriggers");
} }
if(!DHookEnableDetour(g_hPhysicsTouchTriggers, false, Detour_OnPhysicsTouchTriggers)) if(!DHookEnableDetour(g_hPhysicsTouchTriggersDetour, false, Detour_OnPhysicsTouchTriggers))
{ {
delete hGameData; delete hGameData;
SetFailState("Failed to detour CBaseEntity__PhysicsTouchTriggers."); SetFailState("Failed to detour CBaseEntity__PhysicsTouchTriggers.");
@ -140,16 +153,44 @@ public void OnPluginStart()
delete hGameData; delete hGameData;
SetFailState("Failed to setup detour for CCSGameRules__RestartRound"); SetFailState("Failed to setup detour for CCSGameRules__RestartRound");
} }
delete hGameData;
if(!DHookEnableDetour(g_hRestartRound, false, Detour_OnRestartRound)) if(!DHookEnableDetour(g_hRestartRound, false, Detour_OnRestartRound))
{
delete hGameData;
SetFailState("Failed to detour CCSGameRules__RestartRound."); SetFailState("Failed to detour CCSGameRules__RestartRound.");
}
delete hGameData;
RegAdminCmd("sm_unlag", Command_AddLagCompensation, ADMFLAG_GENERIC, "sm_unlag <entidx>");
FilterClientEntityMap(g_aaDeleted, true);
} }
public Action Command_AddLagCompensation(int client, int argc)
{
if(argc < 1)
{
ReplyToCommand(client, "[SM] Usage: sm_unlag <entidx>");
return Plugin_Handled;
}
char sArgs[32];
GetCmdArg(1, sArgs, sizeof(sArgs));
int entity = StringToInt(sArgs);
AddEntityForLagCompensation(entity);
g_aBlockPhysics[entity] = 1;
return Plugin_Handled;
}
public void OnPluginEnd() public void OnPluginEnd()
{ {
FilterSolidMoved(g_bNoPhysics, 0); g_bCleaningUp = true;
FilterClientEntityMap(g_aaDeleted, false);
DHookDisableDetour(g_hUTIL_Remove, false, Detour_OnUTIL_Remove); DHookDisableDetour(g_hUTIL_Remove, false, Detour_OnUTIL_Remove);
@ -160,12 +201,7 @@ public void OnPluginEnd()
if(g_aEntityLagData[i].iDeleted) if(g_aEntityLagData[i].iDeleted)
{ {
PrintToBoth("[%d] !!!!!!!!!!! RemoveEdict: %d / ent: %d", GetGameTickCount(), i, g_aEntityLagData[i].iEntity);
// calls OnEntityDestroyed right away
// which calls RemoveRecord
// which moves the next element to our current position
RemoveEdict(g_aEntityLagData[i].iEntity); RemoveEdict(g_aEntityLagData[i].iEntity);
i--; continue;
} }
} }
} }
@ -181,10 +217,10 @@ public MRESReturn Detour_OnPhysicsTouchTriggers(int entity, Handle hReturn, Hand
if(!g_bBlockPhysics) if(!g_bBlockPhysics)
return MRES_Ignored; return MRES_Ignored;
if(entity < 0 || entity > sizeof(g_bNoPhysics)) if(entity < 0 || entity > sizeof(g_aBlockPhysics))
return MRES_Ignored; return MRES_Ignored;
if(g_bNoPhysics[entity]) if(g_aBlockPhysics[entity])
{ {
//LogMessage("blocked physics on %d", entity); //LogMessage("blocked physics on %d", entity);
return MRES_Supercede; return MRES_Supercede;
@ -194,8 +230,11 @@ public MRESReturn Detour_OnPhysicsTouchTriggers(int entity, Handle hReturn, Hand
public MRESReturn Detour_OnUTIL_Remove(Handle hParams) public MRESReturn Detour_OnUTIL_Remove(Handle hParams)
{ {
if(g_bCleaningUp)
return MRES_Ignored;
int entity = DHookGetParam(hParams, 1); int entity = DHookGetParam(hParams, 1);
if(entity < 0 || entity > sizeof(g_bNoPhysics)) if(entity < 0 || entity > sizeof(g_aBlockPhysics))
return MRES_Ignored; return MRES_Ignored;
for(int i = 0; i < g_iNumEntities; i++) for(int i = 0; i < g_iNumEntities; i++)
@ -203,10 +242,10 @@ public MRESReturn Detour_OnUTIL_Remove(Handle hParams)
if(g_aEntityLagData[i].iEntity != entity) if(g_aEntityLagData[i].iEntity != entity)
continue; continue;
SetEntPropEnt(entity, Prop_Data, "m_pParent", 0);
if(!g_aEntityLagData[i].iDeleted) if(!g_aEntityLagData[i].iDeleted)
{
g_aEntityLagData[i].iDeleted = GetGameTickCount(); g_aEntityLagData[i].iDeleted = GetGameTickCount();
}
PrintToBoth("[%d] !!!!!!!!!!! Detour_OnUTIL_Remove: %d / ent: %d", GetGameTickCount(), i, entity); PrintToBoth("[%d] !!!!!!!!!!! Detour_OnUTIL_Remove: %d / ent: %d", GetGameTickCount(), i, entity);
return MRES_Supercede; return MRES_Supercede;
@ -217,14 +256,29 @@ public MRESReturn Detour_OnUTIL_Remove(Handle hParams)
public MRESReturn Detour_OnRestartRound() public MRESReturn Detour_OnRestartRound()
{ {
g_bCleaningUp = true;
PrintToBoth("Detour_OnRestartRound with %d entries.", g_iNumEntities); PrintToBoth("Detour_OnRestartRound with %d entries.", g_iNumEntities);
for(int i = 0; i < g_iNumEntities; i++) for(int i = 0; i < g_iNumEntities; i++)
{ {
g_aBlockPhysics[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);
}
g_aEntityLagData[i].iEntity = -1; g_aEntityLagData[i].iEntity = -1;
} }
g_iNumEntities = 0; g_iNumEntities = 0;
g_bCleaningUp = false;
return MRES_Ignored; return MRES_Ignored;
} }
@ -260,12 +314,9 @@ public void OnRunThinkFunctions(bool simulating)
{ {
for(int i = 0; i < g_iNumEntities; i++) for(int i = 0; i < g_iNumEntities; i++)
{ {
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
continue;
if(!IsValidEntity(g_aEntityLagData[i].iEntity)) if(!IsValidEntity(g_aEntityLagData[i].iEntity))
{ {
PrintToBoth("!!!!!!!!!!! OnRunThinkFunctions SHIT deleted: %d / %d", i, g_aEntityLagData[i].iEntity); //PrintToBoth("!!!!!!!!!!! OnRunThinkFunctions SHIT deleted: %d / %d", i, g_aEntityLagData[i].iEntity);
RemoveRecord(i); RemoveRecord(i);
i--; continue; i--; continue;
} }
@ -284,6 +335,9 @@ public void OnRunThinkFunctions(bool simulating)
continue; continue;
} }
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
continue;
RecordDataIntoRecord(g_aEntityLagData[i].iEntity, g_aEntityLagData[i].RestoreData); RecordDataIntoRecord(g_aEntityLagData[i].iEntity, g_aEntityLagData[i].RestoreData);
#if defined DEBUG #if defined DEBUG
@ -295,8 +349,6 @@ public void OnRunThinkFunctions(bool simulating)
); );
#endif #endif
} }
FilterSolidMoved(g_bNoPhysics, sizeof(g_bNoPhysics));
} }
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
@ -320,7 +372,10 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
{ {
int simtick = GetGameTickCount() - delta; int simtick = GetGameTickCount() - delta;
if(simtick > g_aEntityLagData[i].iDeleted) if(simtick > g_aEntityLagData[i].iDeleted)
{
g_aaDeleted[client][g_aEntityLagData[i].iEntity] = 1;
continue; continue;
}
} }
int iRecordIndex = g_aEntityLagData[i].iRecordIndex - delta; int iRecordIndex = g_aEntityLagData[i].iRecordIndex - delta;
@ -345,8 +400,6 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
public void OnPostPlayerThinkFunctions() public void OnPostPlayerThinkFunctions()
{ {
FilterSolidMoved(g_bNoPhysics, 0);
for(int i = 0; i < g_iNumEntities; i++) for(int i = 0; i < g_iNumEntities; i++)
{ {
if(!g_aEntityLagData[i].bRestore) if(!g_aEntityLagData[i].bRestore)
@ -470,12 +523,20 @@ void RestoreEntityFromRecord(int iEntity, int iFilter, LagRecord Record)
SDKCall(g_hSetAbsAngles, iEntity, Record.vecAngles); SDKCall(g_hSetAbsAngles, iEntity, Record.vecAngles);
SDKCall(g_hSetAbsOrigin, iEntity, Record.vecOrigin); SDKCall(g_hSetAbsOrigin, iEntity, Record.vecOrigin);
if(iFilter)
{
SDKCall(g_hPhysicsTouchTriggers, iEntity, Record.vecOrigin);
}
BlockSolidMoved(-1); BlockSolidMoved(-1);
FilterTriggerMoved(-1); FilterTriggerMoved(-1);
} }
bool AddEntityForLagCompensation(int iEntity) bool AddEntityForLagCompensation(int iEntity)
{ {
if(g_bCleaningUp)
return false;
if(g_iNumEntities == MAX_ENTITIES) if(g_iNumEntities == MAX_ENTITIES)
return false; return false;
@ -515,7 +576,10 @@ bool AddEntityForLagCompensation(int iEntity)
public void OnEntitySpawned(int entity, const char[] classname) public void OnEntitySpawned(int entity, const char[] classname)
{ {
if(entity < 0 || entity > sizeof(g_bNoPhysics)) if(g_bCleaningUp)
return;
if(entity < 0 || entity > sizeof(g_aBlockPhysics))
return; return;
if(!strncmp(classname, "func_physbox", 12)) if(!strncmp(classname, "func_physbox", 12))
@ -559,7 +623,7 @@ public void OnEntitySpawned(int entity, const char[] classname)
if(!AddEntityForLagCompensation(entity)) if(!AddEntityForLagCompensation(entity))
return; return;
g_bNoPhysics[entity] = true; g_aBlockPhysics[entity] = 1;
{ {
char sTargetname[64]; char sTargetname[64];
@ -574,10 +638,11 @@ public void OnEntitySpawned(int entity, const char[] classname)
public void OnEntityDestroyed(int entity) public void OnEntityDestroyed(int entity)
{ {
if(entity < 0 || entity > sizeof(g_bNoPhysics)) if(g_bCleaningUp)
return; return;
g_bNoPhysics[entity] = false; if(entity < 0 || entity > sizeof(g_aBlockPhysics))
return;
for(int i = 0; i < g_iNumEntities; i++) for(int i = 0; i < g_iNumEntities; i++)
{ {
@ -591,6 +656,9 @@ public void OnEntityDestroyed(int entity)
void RemoveRecord(int index) void RemoveRecord(int index)
{ {
if(g_bCleaningUp)
return;
{ {
char sClassname[64]; char sClassname[64];
GetEntityClassname(g_aEntityLagData[index].iEntity, sClassname, sizeof(sClassname)); GetEntityClassname(g_aEntityLagData[index].iEntity, sClassname, sizeof(sClassname));
@ -603,6 +671,16 @@ void RemoveRecord(int index)
PrintToBoth("[%d] RemoveRecord %d / %d (%s)\"%s\"(#%d), num: %d", GetGameTickCount(), index, g_aEntityLagData[index].iEntity, sClassname, sTargetname, iHammerID, g_iNumEntities); PrintToBoth("[%d] RemoveRecord %d / %d (%s)\"%s\"(#%d), num: %d", GetGameTickCount(), index, g_aEntityLagData[index].iEntity, sClassname, sTargetname, iHammerID, g_iNumEntities);
} }
g_aBlockPhysics[g_aEntityLagData[index].iEntity] = 0;
if(g_aEntityLagData[index].iDeleted)
{
for(int client = 1; client <= MaxClients; client++)
{
g_aaDeleted[client][g_aEntityLagData[index].iEntity] = 0;
}
}
g_aEntityLagData[index].iEntity = -1; g_aEntityLagData[index].iEntity = -1;
for(int src = index + 1; src < g_iNumEntities; src++) for(int src = index + 1; src < g_iNumEntities; src++)