LagCompensation 1.0.1: CSGO support, lerp, clientprefs, remove deprecated touchstamp code
This commit is contained in:
parent
58a85c4e9f
commit
a07d889cca
@ -7,7 +7,7 @@
|
|||||||
"::UTIL_Remove"
|
"::UTIL_Remove"
|
||||||
{
|
{
|
||||||
"library" "server"
|
"library" "server"
|
||||||
"linux" "@_Z11UTIL_RemoveP11CBaseEntity"
|
"linux" "@_Z11UTIL_RemoveP18IServerNetworkable"
|
||||||
}
|
}
|
||||||
|
|
||||||
"CCSGameRules::RestartRound"
|
"CCSGameRules::RestartRound"
|
||||||
@ -46,13 +46,13 @@
|
|||||||
"UTIL_Remove"
|
"UTIL_Remove"
|
||||||
{
|
{
|
||||||
"signature" "::UTIL_Remove"
|
"signature" "::UTIL_Remove"
|
||||||
"callconv" "cdecl"
|
|
||||||
"return" "void"
|
"return" "void"
|
||||||
|
"callconv" "cdecl"
|
||||||
"arguments"
|
"arguments"
|
||||||
{
|
{
|
||||||
"oldObj"
|
"oldObj"
|
||||||
{
|
{
|
||||||
"type" "cbaseentity"
|
"type" "objectptr"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,9 +68,8 @@
|
|||||||
"CEntityTouchManager__FrameUpdatePostEntityThink"
|
"CEntityTouchManager__FrameUpdatePostEntityThink"
|
||||||
{
|
{
|
||||||
"signature" "CEntityTouchManager::FrameUpdatePostEntityThink"
|
"signature" "CEntityTouchManager::FrameUpdatePostEntityThink"
|
||||||
"callconv" "thiscall"
|
"callconv" "cdecl"
|
||||||
"return" "void"
|
"return" "void"
|
||||||
"this" "ignore"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"CLogicMeasureMovement__SetTarget"
|
"CLogicMeasureMovement__SetTarget"
|
||||||
@ -83,7 +82,7 @@
|
|||||||
{
|
{
|
||||||
"pName"
|
"pName"
|
||||||
{
|
{
|
||||||
"type" "charptr"
|
"type" "charptr"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,10 +97,141 @@
|
|||||||
{
|
{
|
||||||
"pName"
|
"pName"
|
||||||
{
|
{
|
||||||
"type" "charptr"
|
"type" "charptr"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Offsets"
|
||||||
|
{
|
||||||
|
"CServerNetworkableProperty::m_pOuter"
|
||||||
|
{
|
||||||
|
"linux" "8"
|
||||||
|
"windows" "8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"csgo"
|
||||||
|
{
|
||||||
|
"Signatures"
|
||||||
|
{
|
||||||
|
"::UTIL_Remove"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"linux" "\x55\x89\xE5\x83\xEC\x48\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x89\x7D\xFC\x85\xDB"
|
||||||
|
"windows" "\x55\x8B\xEC\x51\x56\x8B\xF1\x85\xF6\x0F\x84\x2A\x2A\x2A\x2A"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CCSGameRules::RestartRound"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"linux" "\x55\x89\xE5\x57\x56\x53\x81\xEC\x3C\x03\x00\x00"
|
||||||
|
"windows" "\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\xD8\x01\x00\x00"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CLogicMeasureMovement::SetTarget"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"linux" "\x55\x89\xE5\x56\x53\x83\xEC\x20\x8B\x5D\x0C\xC7\x44\x24\x18\x00\x00\x00\x00\x8B\x75\x08\xC7\x44\x24\x14\x00\x00\x00\x00\xC7\x44\x24\x10\x00\x00\x00\x00\xC7\x44\x24\x0C\x00\x00\x00\x00\x89\x5C\x24\x08\xC7\x44\x24\x04\x00\x00\x00\x00\xC7\x04\x24\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\x10\x89\x04\x24\xFF\x52\x0C\x8B\x0D\x2A\x2A\x2A\x2A\x8B\x00\x83\xF8\xFF\x89\x86\xBC\x03\x00\x00"
|
||||||
|
"windows" "\x55\x8B\xEC\x51\x53\x8B\x5D\x08\x56\x8B\xF1\x89\x75\xFC\x57\x85\xDB\x74\x2A\x8A\x03\x84\xC0\x74\x2A\x3C\x21\x75\x2A\x6A\x00\x6A\x00\x6A\x00\x53\xE8\x2A\x2A\x2A\x2A\x8B\xF8\xEB\x2A\x8B\x35\x2A\x2A\x2A\x2A\x85\xF6\x74\x2A\x8B\x3E\x85\xFF\x75\x2A\x68\x2A\x2A\x2A\x2A\xFF\x15\x2A\x2A\x2A\x2A\x83\xC4\x04\xEB\x2A\x8B\x56\x10\x85\xD2\x74\x2A\x3B\xD3\x74\x2A\x8B\xCB\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75\x2A\x8B\x76\x0C\x85\xF6\x75\x2A\x8B\x75\xFC\x33\xFF\x85\xFF\x74\x2A\x8B\x07\x8B\xCF\xFF\x50\x08\x8B\x00\x89\x86\xA4\x03\x00\x00"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CEntityTouchManager::FrameUpdatePostEntityThink"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x3C\xA1\x2A\x2A\x2A\x2A\x8B\x5D\x08\x85\xC0"
|
||||||
|
"windows" "\x55\x8B\xEC\x53\x56\x57\x8B\x3D\x2A\x2A\x2A\x2A\x85\xFF"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CalcAbsolutePosition"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"linux" "\x55\x89\xE5\x81\xEC\x98\x00\x00\x00\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x89\x7D\xFC\x8B\x83\xDC\x00\x00\x00"
|
||||||
|
"windows" "\x55\x8B\xEC\x83\xE4\xF0\x83\xEC\x68\x56\x8B\xF1"
|
||||||
|
}
|
||||||
|
|
||||||
|
"MarkPartitionHandleDirty"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"linux" "\x55\x89\xE5\x53\x83\xEC\x14\x8B\x5D\x08\x8B\x43\x04\xF6\x80\xDD\x00\x00\x00\x80"
|
||||||
|
"windows" "\x56\x8B\xF1\x8B\x4E\x04\x8B\x51\x1C"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Functions"
|
||||||
|
{
|
||||||
|
"UTIL_Remove"
|
||||||
|
{
|
||||||
|
"signature" "::UTIL_Remove"
|
||||||
|
"return" "void"
|
||||||
|
"callconv" "cdecl"
|
||||||
|
"arguments"
|
||||||
|
{
|
||||||
|
"oldObj"
|
||||||
|
{
|
||||||
|
"type" "objectptr"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"windows"
|
||||||
|
{
|
||||||
|
"callconv" "fastcall"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"CCSGameRules__RestartRound"
|
||||||
|
{
|
||||||
|
"signature" "CCSGameRules::RestartRound"
|
||||||
|
"callconv" "thiscall"
|
||||||
|
"return" "void"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CEntityTouchManager__FrameUpdatePostEntityThink"
|
||||||
|
{
|
||||||
|
"signature" "CEntityTouchManager::FrameUpdatePostEntityThink"
|
||||||
|
"callconv" "cdecl"
|
||||||
|
"return" "void"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CLogicMeasureMovement__SetTarget"
|
||||||
|
{
|
||||||
|
"signature" "CLogicMeasureMovement::SetTarget"
|
||||||
|
"callconv" "thiscall"
|
||||||
|
"return" "void"
|
||||||
|
"this" "entity"
|
||||||
|
"arguments"
|
||||||
|
{
|
||||||
|
"pName"
|
||||||
|
{
|
||||||
|
"type" "charptr"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"CLogicMeasureMovement__SetTarget_post"
|
||||||
|
{
|
||||||
|
"signature" "CLogicMeasureMovement::SetTarget"
|
||||||
|
"callconv" "thiscall"
|
||||||
|
"return" "void"
|
||||||
|
"this" "ignore"
|
||||||
|
"arguments"
|
||||||
|
{
|
||||||
|
"pName"
|
||||||
|
{
|
||||||
|
"type" "charptr"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"Offsets"
|
||||||
|
{
|
||||||
|
"CServerNetworkableProperty::m_pOuter"
|
||||||
|
{
|
||||||
|
"linux" "8"
|
||||||
|
"windows" "8"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include <sdktools>
|
#include <sdktools>
|
||||||
#include <PhysHooks>
|
#include <PhysHooks>
|
||||||
#include <dhooks>
|
#include <dhooks>
|
||||||
|
#include <clientprefs>
|
||||||
|
|
||||||
|
#define PLUGIN_VERSION "1.0.1"
|
||||||
|
|
||||||
#define SetBit(%1,%2) ((%1)[(%2) >> 5] |= (1 << ((%2) & 31)))
|
#define SetBit(%1,%2) ((%1)[(%2) >> 5] |= (1 << ((%2) & 31)))
|
||||||
#define ClearBit(%1,%2) ((%1)[(%2) >> 5] &= ~(1 << ((%2) & 31)))
|
#define ClearBit(%1,%2) ((%1)[(%2) >> 5] &= ~(1 << ((%2) & 31)))
|
||||||
@ -16,7 +19,7 @@ public Plugin myinfo =
|
|||||||
name = "LagCompensation",
|
name = "LagCompensation",
|
||||||
author = "BotoX",
|
author = "BotoX",
|
||||||
description = "",
|
description = "",
|
||||||
version = "1.0",
|
version = PLUGIN_VERSION,
|
||||||
url = ""
|
url = ""
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,7 +78,6 @@ enum
|
|||||||
|
|
||||||
#define MAX_RECORDS 32
|
#define MAX_RECORDS 32
|
||||||
#define MAX_ENTITIES 256
|
#define MAX_ENTITIES 256
|
||||||
//#define DEBUG
|
|
||||||
|
|
||||||
enum struct LagRecord
|
enum struct LagRecord
|
||||||
{
|
{
|
||||||
@ -96,7 +98,6 @@ enum struct EntityLagData
|
|||||||
int iSpawned;
|
int iSpawned;
|
||||||
int iDeleted;
|
int iDeleted;
|
||||||
int iNotMoving;
|
int iNotMoving;
|
||||||
int iTouchStamp;
|
|
||||||
bool bRestore;
|
bool bRestore;
|
||||||
bool bLateKill;
|
bool bLateKill;
|
||||||
LagRecord RestoreData;
|
LagRecord RestoreData;
|
||||||
@ -107,6 +108,8 @@ EntityLagData g_aEntityLagData[MAX_ENTITIES];
|
|||||||
int g_iNumEntities = 0;
|
int g_iNumEntities = 0;
|
||||||
bool g_bCleaningUp = true;
|
bool g_bCleaningUp = true;
|
||||||
|
|
||||||
|
bool g_bHasOnEntitySpawned = false;
|
||||||
|
|
||||||
Handle g_hCalcAbsolutePosition;
|
Handle g_hCalcAbsolutePosition;
|
||||||
Handle g_hMarkPartitionHandleDirty;
|
Handle g_hMarkPartitionHandleDirty;
|
||||||
|
|
||||||
@ -118,14 +121,16 @@ Handle g_hFrameUpdatePostEntityThink;
|
|||||||
Handle g_hActivate;
|
Handle g_hActivate;
|
||||||
Handle g_hAcceptInput;
|
Handle g_hAcceptInput;
|
||||||
|
|
||||||
|
int g_iNetworkableOuter;
|
||||||
int g_iParent;
|
int g_iParent;
|
||||||
int g_iSpawnFlags;
|
int g_iSpawnFlags;
|
||||||
int g_iTouchStamp;
|
|
||||||
int g_iCollision;
|
int g_iCollision;
|
||||||
int g_iSolidFlags;
|
int g_iSolidFlags;
|
||||||
int g_iSolidType;
|
int g_iSolidType;
|
||||||
int g_iSurroundType;
|
int g_iSurroundType;
|
||||||
int g_iEFlags;
|
int g_iEFlags;
|
||||||
|
int g_iLerpTime = -1;
|
||||||
|
|
||||||
int g_iVecOrigin;
|
int g_iVecOrigin;
|
||||||
int g_iVecAbsOrigin;
|
int g_iVecAbsOrigin;
|
||||||
int g_iAngRotation;
|
int g_iAngRotation;
|
||||||
@ -139,8 +144,14 @@ int g_aaFilterClientSolidTouch[((MAXPLAYERS + 1) * MAX_EDICTS) / 32];
|
|||||||
int g_aBlockTriggerMoved[MAX_EDICTS / 32];
|
int g_aBlockTriggerMoved[MAX_EDICTS / 32];
|
||||||
int g_aBlacklisted[MAX_EDICTS / 32];
|
int g_aBlacklisted[MAX_EDICTS / 32];
|
||||||
|
|
||||||
|
Handle g_hCookie_DisableLagComp;
|
||||||
|
bool g_bDisableLagComp[MAXPLAYERS+1];
|
||||||
|
int g_iDisableLagComp[MAXPLAYERS+1];
|
||||||
|
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
{
|
{
|
||||||
|
CreateConVar("sm_lagcomp_version", PLUGIN_VERSION, "LagCompensation Version", FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD).SetString(PLUGIN_VERSION);
|
||||||
|
|
||||||
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.");
|
||||||
@ -234,6 +245,14 @@ public void OnPluginStart()
|
|||||||
SetFailState("Failed to detour CEntityTouchManager__FrameUpdatePostEntityThink.");
|
SetFailState("Failed to detour CEntityTouchManager__FrameUpdatePostEntityThink.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
g_iNetworkableOuter = GameConfGetOffset(hGameData, "CServerNetworkableProperty::m_pOuter");
|
||||||
|
if(g_iNetworkableOuter == -1)
|
||||||
|
{
|
||||||
|
delete hGameData;
|
||||||
|
SetFailState("GameConfGetOffset(hGameData, \"CServerNetworkableProperty::m_pOuter\") failed!");
|
||||||
|
}
|
||||||
|
|
||||||
delete hGameData;
|
delete hGameData;
|
||||||
|
|
||||||
|
|
||||||
@ -267,6 +286,14 @@ public void OnPluginStart()
|
|||||||
|
|
||||||
delete hGameData;
|
delete hGameData;
|
||||||
|
|
||||||
|
g_bHasOnEntitySpawned = GetFeatureStatus(FeatureType_Capability, "SDKHook_OnEntitySpawned") == FeatureStatus_Available;
|
||||||
|
|
||||||
|
g_hCookie_DisableLagComp = RegClientCookie("disable_lagcomp", "", CookieAccess_Private);
|
||||||
|
RegConsoleCmd("sm_lagcomp", OnToggleLagCompSettings);
|
||||||
|
RegConsoleCmd("sm_0ping", OnToggleLagCompSettings);
|
||||||
|
SetCookieMenuItem(MenuHandler_CookieMenu, 0, "LagCompensation");
|
||||||
|
|
||||||
|
CreateTimer(0.1, DisableLagCompTimer, _, TIMER_REPEAT);
|
||||||
|
|
||||||
RegAdminCmd("sm_unlag", Command_AddLagCompensation, ADMFLAG_RCON, "sm_unlag <entidx>");
|
RegAdminCmd("sm_unlag", Command_AddLagCompensation, ADMFLAG_RCON, "sm_unlag <entidx>");
|
||||||
RegAdminCmd("sm_lagged", Command_CheckLagCompensated, ADMFLAG_GENERIC, "sm_lagged");
|
RegAdminCmd("sm_lagged", Command_CheckLagCompensated, ADMFLAG_GENERIC, "sm_lagged");
|
||||||
@ -319,7 +346,6 @@ public void OnMapStart()
|
|||||||
|
|
||||||
g_iParent = FindDataMapInfo(0, "m_pParent");
|
g_iParent = FindDataMapInfo(0, "m_pParent");
|
||||||
g_iSpawnFlags = FindDataMapInfo(0, "m_spawnflags");
|
g_iSpawnFlags = FindDataMapInfo(0, "m_spawnflags");
|
||||||
g_iTouchStamp = FindDataMapInfo(0, "touchStamp");
|
|
||||||
g_iCollision = FindDataMapInfo(0, "m_Collision");
|
g_iCollision = FindDataMapInfo(0, "m_Collision");
|
||||||
g_iSolidFlags = FindDataMapInfo(0, "m_usSolidFlags");
|
g_iSolidFlags = FindDataMapInfo(0, "m_usSolidFlags");
|
||||||
g_iSolidType = FindDataMapInfo(0, "m_nSolidType");
|
g_iSolidType = FindDataMapInfo(0, "m_nSolidType");
|
||||||
@ -336,6 +362,17 @@ public void OnMapStart()
|
|||||||
/* Late Load */
|
/* Late Load */
|
||||||
if(bLate)
|
if(bLate)
|
||||||
{
|
{
|
||||||
|
for (int client = 1; client <= MaxClients; client++)
|
||||||
|
{
|
||||||
|
if(IsClientInGame(client))
|
||||||
|
{
|
||||||
|
OnClientConnected(client);
|
||||||
|
if(AreClientCookiesCached(client))
|
||||||
|
OnClientCookiesCached(client);
|
||||||
|
OnClientPutInServer(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
int entity = INVALID_ENT_REFERENCE;
|
||||||
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
|
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
|
||||||
{
|
{
|
||||||
@ -356,6 +393,42 @@ public void OnMapStart()
|
|||||||
g_bLateLoad = false;
|
g_bLateLoad = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnMapEnd()
|
||||||
|
{
|
||||||
|
Detour_OnRestartRound();
|
||||||
|
g_bCleaningUp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientConnected(int client)
|
||||||
|
{
|
||||||
|
g_bDisableLagComp[client] = false;
|
||||||
|
g_iDisableLagComp[client] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientCookiesCached(int client)
|
||||||
|
{
|
||||||
|
char sBuffer[16];
|
||||||
|
GetClientCookie(client, g_hCookie_DisableLagComp, sBuffer, sizeof(sBuffer));
|
||||||
|
if(sBuffer[0])
|
||||||
|
g_bDisableLagComp[client] = true;
|
||||||
|
else
|
||||||
|
g_bDisableLagComp[client] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientPutInServer(int client)
|
||||||
|
{
|
||||||
|
if(g_iLerpTime == -1)
|
||||||
|
{
|
||||||
|
g_iLerpTime = FindDataMapInfo(client, "m_fLerpTime");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientDisconnect(int client)
|
||||||
|
{
|
||||||
|
g_bDisableLagComp[client] = false;
|
||||||
|
g_iDisableLagComp[client] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
public void OnEntityCreated(int entity, const char[] classname)
|
||||||
{
|
{
|
||||||
if(g_bCleaningUp)
|
if(g_bCleaningUp)
|
||||||
@ -369,6 +442,19 @@ public void OnEntityCreated(int entity, const char[] classname)
|
|||||||
{
|
{
|
||||||
DHookEntity(g_hAcceptInput, true, entity);
|
DHookEntity(g_hAcceptInput, true, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!g_bHasOnEntitySpawned)
|
||||||
|
{
|
||||||
|
SDKHook(entity, SDKHook_SpawnPost, OnSDKHookEntitySpawnPost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSDKHookEntitySpawnPost(int entity)
|
||||||
|
{
|
||||||
|
char classname[64];
|
||||||
|
GetEntityClassname(entity, classname, sizeof(classname));
|
||||||
|
|
||||||
|
OnEntitySpawned(entity, classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEntitySpawned(int entity, const char[] classname)
|
public void OnEntitySpawned(int entity, const char[] classname)
|
||||||
@ -488,7 +574,7 @@ bool CheckEntityForLagComp(int entity, const char[] classname, bool bRecursive=f
|
|||||||
iParent = iTmp;
|
iParent = iTmp;
|
||||||
GetEntityClassname(iParent, sParentClassname, sizeof(sParentClassname));
|
GetEntityClassname(iParent, sParentClassname, sizeof(sParentClassname));
|
||||||
|
|
||||||
if(StrEqual(sParentClassname, "player") ||
|
if((iParent >= 1 && iParent <= MaxClients) ||
|
||||||
!strncmp(sParentClassname, "weapon_", 7))
|
!strncmp(sParentClassname, "weapon_", 7))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -580,7 +666,10 @@ public MRESReturn Detour_OnUTIL_Remove(Handle hParams)
|
|||||||
if(g_bCleaningUp)
|
if(g_bCleaningUp)
|
||||||
return MRES_Ignored;
|
return MRES_Ignored;
|
||||||
|
|
||||||
int entity = DHookGetParam(hParams, 1);
|
if(DHookIsNullParam(hParams, 1))
|
||||||
|
return MRES_Ignored;
|
||||||
|
|
||||||
|
int entity = DHookGetParamObjectPtrVar(hParams, 1, g_iNetworkableOuter, ObjectValueType_CBaseEntityPtr);
|
||||||
if(entity < 0 || entity > MAX_EDICTS)
|
if(entity < 0 || entity > MAX_EDICTS)
|
||||||
return MRES_Ignored;
|
return MRES_Ignored;
|
||||||
|
|
||||||
@ -704,22 +793,6 @@ public void OnRunThinkFunctions(bool simulating)
|
|||||||
i--; continue;
|
i--; continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save old touchStamp
|
|
||||||
int touchStamp = GetEntData(g_aEntityLagData[i].iEntity, g_iTouchStamp);
|
|
||||||
g_aEntityLagData[i].iTouchStamp = touchStamp;
|
|
||||||
// We have to increase the touchStamp by 1 here to avoid breaking the touchlink.
|
|
||||||
// The touchStamp is incremented by 1 every time an entities physics are simulated.
|
|
||||||
// When two entities touch then a touchlink is created on both entities with the touchStamp of either entity.
|
|
||||||
// Usually the player would touch the trigger first and then the trigger would touch the player later on in the same frame.
|
|
||||||
// The trigger touching the player would fix up the touchStamp (which was increased by 1 by the trigger physics simulate)
|
|
||||||
// But since we're blocking the trigger from ever touching a player outside of here we need to manually increase it by 1 up front
|
|
||||||
// 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++;
|
|
||||||
SetEntData(g_aEntityLagData[i].iEntity, g_iTouchStamp, touchStamp);
|
|
||||||
|
|
||||||
if(g_aEntityLagData[i].iDeleted)
|
if(g_aEntityLagData[i].iDeleted)
|
||||||
{
|
{
|
||||||
if(g_aEntityLagData[i].iDeleted + MAX_RECORDS <= GetGameTickCount())
|
if(g_aEntityLagData[i].iDeleted + MAX_RECORDS <= GetGameTickCount())
|
||||||
@ -749,11 +822,34 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
// this is because we simulate players first
|
// this is because we simulate players first
|
||||||
// hence no new entity record was inserted on the current tick
|
// hence no new entity record was inserted on the current tick
|
||||||
int iGameTick = GetGameTickCount() - 1;
|
int iGameTick = GetGameTickCount() - 1;
|
||||||
|
float fTickInterval = GetTickInterval();
|
||||||
|
|
||||||
|
float fLerpTime = GetEntDataFloat(client, g_iLerpTime);
|
||||||
|
// -1 lerp ticks was determined by analyzing hits visually at host_timescale 0.01 and debug_touchlinks 1
|
||||||
|
int iLerpTicks = RoundToFloor(0.5 + (fLerpTime / fTickInterval)) - 1;
|
||||||
|
|
||||||
|
int iTargetTick = tickcount - iLerpTicks;
|
||||||
|
int iDelta = iGameTick - iTargetTick;
|
||||||
|
|
||||||
|
float fCorrect = 0.0;
|
||||||
|
fCorrect += GetClientLatency(client, NetFlow_Outgoing);
|
||||||
|
fCorrect += iLerpTicks * fTickInterval;
|
||||||
|
|
||||||
|
float fDeltaTime = fCorrect - iDelta * fTickInterval;
|
||||||
|
if(FloatAbs(fDeltaTime) > 0.2)
|
||||||
|
{
|
||||||
|
// difference between cmd time and latency is too big > 200ms, use time correction based on latency
|
||||||
|
iDelta = RoundToFloor(0.5 + (fCorrect / fTickInterval));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The player is stupid and doesn't want lag compensation.
|
||||||
|
// To get the original behavior back lets assume they actually have 0 latency.
|
||||||
|
// To avoid abusing toggling lagcomp we increase/decrease this var by 1 every 100ms.
|
||||||
|
// This is so we only skip single ticks at a time. Fully ON = 0, Fully OFF = MAX_RECORDS
|
||||||
|
iDelta -= g_iDisableLagComp[client];
|
||||||
|
|
||||||
int iDelta = iGameTick - tickcount;
|
|
||||||
if(iDelta < 0)
|
if(iDelta < 0)
|
||||||
iDelta = 0;
|
iDelta = 0;
|
||||||
|
|
||||||
if(iDelta > MAX_RECORDS)
|
if(iDelta > MAX_RECORDS)
|
||||||
iDelta = MAX_RECORDS;
|
iDelta = MAX_RECORDS;
|
||||||
|
|
||||||
@ -769,10 +865,6 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
SetBit(g_aaFilterClientSolidTouch, client * MAX_EDICTS + iEntity);
|
SetBit(g_aaFilterClientSolidTouch, client * MAX_EDICTS + iEntity);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if(g_aEntityLagData[i].iSpawned == iPlayerSimTick)
|
|
||||||
{
|
|
||||||
ClearBit(g_aaFilterClientSolidTouch, client * MAX_EDICTS + iEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_aEntityLagData[i].iDeleted)
|
if(g_aEntityLagData[i].iDeleted)
|
||||||
{
|
{
|
||||||
@ -782,6 +874,10 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClearBit(g_aaFilterClientSolidTouch, client * MAX_EDICTS + iEntity);
|
||||||
|
}
|
||||||
|
|
||||||
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
|
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
|
||||||
continue;
|
continue;
|
||||||
@ -805,9 +901,6 @@ public void OnPostPlayerThinkFunctions()
|
|||||||
{
|
{
|
||||||
for(int i = 0; i < g_iNumEntities; i++)
|
for(int i = 0; i < g_iNumEntities; i++)
|
||||||
{
|
{
|
||||||
// Restore original touchStamp
|
|
||||||
SetEntData(g_aEntityLagData[i].iEntity, g_iTouchStamp, g_aEntityLagData[i].iTouchStamp);
|
|
||||||
|
|
||||||
if(!g_aEntityLagData[i].bRestore)
|
if(!g_aEntityLagData[i].bRestore)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -995,7 +1088,6 @@ bool AddEntityForLagCompensation(int iEntity, bool bLateKill)
|
|||||||
g_aEntityLagData[i].iNotMoving = MAX_RECORDS;
|
g_aEntityLagData[i].iNotMoving = MAX_RECORDS;
|
||||||
g_aEntityLagData[i].bRestore = false;
|
g_aEntityLagData[i].bRestore = false;
|
||||||
g_aEntityLagData[i].bLateKill = bLateKill;
|
g_aEntityLagData[i].bLateKill = bLateKill;
|
||||||
g_aEntityLagData[i].iTouchStamp = GetEntData(iEntity, g_iTouchStamp);
|
|
||||||
|
|
||||||
if(bLateKill)
|
if(bLateKill)
|
||||||
{
|
{
|
||||||
@ -1087,7 +1179,6 @@ void EntityLagData_Copy(EntityLagData obj, const EntityLagData other)
|
|||||||
obj.iSpawned = other.iSpawned;
|
obj.iSpawned = other.iSpawned;
|
||||||
obj.iDeleted = other.iDeleted;
|
obj.iDeleted = other.iDeleted;
|
||||||
obj.iNotMoving = other.iNotMoving;
|
obj.iNotMoving = other.iNotMoving;
|
||||||
obj.iTouchStamp = other.iTouchStamp;
|
|
||||||
obj.bRestore = other.bRestore;
|
obj.bRestore = other.bRestore;
|
||||||
obj.bLateKill = other.bLateKill;
|
obj.bLateKill = other.bLateKill;
|
||||||
|
|
||||||
@ -1217,11 +1308,100 @@ stock void PrintToBoth(const char[] format, any ...)
|
|||||||
VFormat(buffer, sizeof(buffer), format, 2);
|
VFormat(buffer, sizeof(buffer), format, 2);
|
||||||
LogMessage(buffer);
|
LogMessage(buffer);
|
||||||
|
|
||||||
for (int i = 1; i <= MaxClients; i++)
|
for(int client = 1; client <= MaxClients; client++)
|
||||||
{
|
{
|
||||||
if (IsClientInGame(i))
|
if(IsClientInGame(client))
|
||||||
{
|
{
|
||||||
PrintToConsole(i, "%s", buffer);
|
PrintToConsole(client, "%s", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action DisableLagCompTimer(Handle timer)
|
||||||
|
{
|
||||||
|
for(int client = 1; client <= MaxClients; client++)
|
||||||
|
{
|
||||||
|
if(g_bDisableLagComp[client] && g_iDisableLagComp[client] < MAX_RECORDS)
|
||||||
|
{
|
||||||
|
g_iDisableLagComp[client]++;
|
||||||
|
}
|
||||||
|
else if(!g_bDisableLagComp[client] && g_iDisableLagComp[client] > 0)
|
||||||
|
{
|
||||||
|
g_iDisableLagComp[client]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnLagCompSettings(int client, int args)
|
||||||
|
{
|
||||||
|
ShowSettingsMenu(client);
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnToggleLagCompSettings(int client, int args)
|
||||||
|
{
|
||||||
|
ToggleLagCompSettings(client);
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleLagCompSettings(int client)
|
||||||
|
{
|
||||||
|
g_bDisableLagComp[client] = !g_bDisableLagComp[client];
|
||||||
|
SetClientCookie(client, g_hCookie_DisableLagComp, g_bDisableLagComp[client] ? "1" : "");
|
||||||
|
|
||||||
|
PrintToChat(client, "\x04[LagCompensation]\x01 LagCompensation has been %s.", g_bDisableLagComp[client] ? "disabled" : "enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowSettingsMenu(int client)
|
||||||
|
{
|
||||||
|
Menu menu = new Menu(MenuHandler_MainMenu);
|
||||||
|
menu.SetTitle("LagCompensation Settings", client);
|
||||||
|
menu.ExitBackButton = true;
|
||||||
|
|
||||||
|
char sBuffer[128];
|
||||||
|
Format(sBuffer, sizeof(sBuffer), "LagCompensation: %s", g_bDisableLagComp[client] ? "Disabled" : "Enabled");
|
||||||
|
menu.AddItem("0", sBuffer);
|
||||||
|
|
||||||
|
menu.Display(client, MENU_TIME_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MenuHandler_CookieMenu(int client, CookieMenuAction action, any info, char[] buffer, int maxlen)
|
||||||
|
{
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case(CookieMenuAction_DisplayOption):
|
||||||
|
{
|
||||||
|
Format(buffer, maxlen, "LagCompensation", client);
|
||||||
|
}
|
||||||
|
case(CookieMenuAction_SelectOption):
|
||||||
|
{
|
||||||
|
ShowSettingsMenu(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MenuHandler_MainMenu(Menu menu, MenuAction action, int client, int selection)
|
||||||
|
{
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case(MenuAction_Select):
|
||||||
|
{
|
||||||
|
switch(selection)
|
||||||
|
{
|
||||||
|
case(0): ToggleLagCompSettings(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowSettingsMenu(client);
|
||||||
|
}
|
||||||
|
case(MenuAction_Cancel):
|
||||||
|
{
|
||||||
|
ShowCookieMenu(client);
|
||||||
|
}
|
||||||
|
case(MenuAction_End):
|
||||||
|
{
|
||||||
|
delete menu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user