LagCompensation, best version so far.
This commit is contained in:
parent
d74cb89848
commit
6496076cef
@ -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++)
|
||||||
|
Loading…
Reference in New Issue
Block a user