slimmed down

This commit is contained in:
2026-08-10 14:23:20 +02:00
parent aed1ea6053
commit 4e9500f0ea
6 changed files with 67 additions and 928 deletions

View File

@@ -1,22 +1,16 @@
#include "detour.h"
#include "common.h"
#include "entity2/entitysystem.h"
#include "entity2/entityinstance.h"
#include "entityhandle.h"
#include "gameconfig.h"
#include "networksystem/inetworkserializer.h"
#include "overrides.h"
#include "playerslot.h"
#include "schema.h"
#include <cstring>
extern CGameConfig* g_gameConfig;
extern CGameEntitySystem* g_entitySystem;
extern bool g_enabled;
extern bool g_armed;
extern CGameEntitySystem* GameEntitySystem();
using SendSnapshotFn = void (*)(void*, void*);
using PackEntitiesFn = void (*)(void*, void*, int, void*, void*, void*, void*, void*, void*);
@@ -28,17 +22,9 @@ static funchook_t* g_snapshotHook = nullptr;
static funchook_t* g_packHook = nullptr;
static funchook_t* g_packEntityHook = nullptr;
static uint64_t g_snapshotCalls = 0;
static uint64_t g_snapshotApplied = 0;
static uint64_t g_snapshotChanged = 0;
static uint64_t g_packCalls = 0;
static uint64_t g_packApplied = 0;
static uint64_t g_packChanged = 0;
static uint64_t g_packEntityCalls = 0;
static uint64_t g_packEntitySpoofs = 0;
static uint64_t g_packEntityScopedWrites = 0;
static uint64_t g_packEntityGenericSpoofs = 0;
static uint64_t g_packEntitySelfSkips = 0;
static uint64_t g_packEntityNoRecipient = 0;
static uint64_t g_fullUpdateWrites = 0;
static int g_fullUpdateBudget = 0;
static thread_local CPlayerSlot g_currentRecipient(-1);
@@ -81,21 +67,7 @@ static void Detour_SendSnapshot(void* client, void* snapshot)
}
}
if (!g_enabled || !g_armed || !client || g_overrides.Empty())
{
g_sendSnapshot(client, snapshot);
return;
}
CPlayerSlot slot = SlotFromClient(client);
auto applied = g_overrides.ApplyForRecipient(slot);
if (!applied.empty())
{
++g_snapshotApplied;
g_snapshotChanged += applied.size();
}
g_sendSnapshot(client, snapshot);
g_overrides.Restore(applied);
}
static void Detour_PackEntities(void* self, void* arg1, int arg2, void* arg3, void* arg4, void* arg5, void* arg6, void* arg7, void* arg8)
@@ -104,61 +76,6 @@ static void Detour_PackEntities(void* self, void* arg1, int arg2, void* arg3, vo
g_packEntities(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
}
static CEntityIdentity* PlayerIdentityFromInstance(void* instance)
{
if (!instance)
return nullptr;
auto* entity = static_cast<CEntityInstance*>(instance);
CEntityIdentity* identity = entity->m_pEntity;
const char* designer = identity ? identity->m_designerName.String() : nullptr;
return designer && !V_stricmp(designer, "player") ? identity : nullptr;
}
static bool DesignerContains(CEntityIdentity* identity, const char* needle)
{
const char* designer = identity ? identity->m_designerName.String() : nullptr;
return designer && V_stristr(designer, needle);
}
static int EntityIndex(CEntityIdentity* identity)
{
return identity ? identity->m_EHandle.GetEntryIndex() : -1;
}
static int OwnerSlotForPawn(CEntityIdentity* pawnIdentity)
{
if (!pawnIdentity)
return -1;
if (!g_entitySystem)
g_entitySystem = GameEntitySystem();
if (!g_entitySystem)
return -1;
auto pawnField = schema::FindField("CBasePlayerController", "m_hPawn");
auto slotField = schema::FindField("CBasePlayerController", "m_nSplitScreenSlot");
if (!pawnField.found || !slotField.found)
return -1;
int pawnIndex = EntityIndex(pawnIdentity);
int visited = 0;
for (auto* identity = g_entitySystem->m_EntityList.m_pFirstActiveEntity; identity && visited < 16384; identity = identity->m_pNext, ++visited)
{
if (!identity->m_pInstance || !DesignerContains(identity, "controller"))
continue;
auto* entity = reinterpret_cast<uint8_t*>(identity->m_pInstance);
int controlledPawnIndex = reinterpret_cast<CEntityHandle*>(entity + pawnField.offset)->GetEntryIndex();
if (controlledPawnIndex != pawnIndex)
continue;
int slot = *reinterpret_cast<int*>(entity + slotField.offset);
return slot >= 0 && slot < 64 ? slot : -1;
}
return -1;
}
static void Detour_PackEntity(void* self, void* arg1, int entityIndex, void* entityData, void* arg4, void* arg5, void* arg6, void* arg7, void* arg8, void* arg9)
{
++g_packEntityCalls;
@@ -172,41 +89,7 @@ static void Detour_PackEntity(void* self, void* arg1, int entityIndex, void* ent
CPlayerSlot recipient = g_currentRecipient;
auto applied = g_overrides.ApplyForPackedEntity(recipient, entityIndex, entityData);
g_packEntityGenericSpoofs += applied.size();
bool spoofedHealth = false;
int savedHealth = 0;
int* healthAddress = nullptr;
int spoofHealth = 42;
if (g_overrides.TryGetHealth42Value(recipient, spoofHealth))
{
CEntityIdentity* identity = PlayerIdentityFromInstance(entityData);
if (identity)
{
if (recipient.Get() < 0)
++g_packEntityNoRecipient;
else if (OwnerSlotForPawn(identity) == recipient.Get())
{
++g_packEntitySelfSkips;
}
else
{
auto healthField = schema::FindField("CBaseEntity", "m_iHealth");
if (healthField.found && healthField.offset >= 0)
{
healthAddress = reinterpret_cast<int*>(reinterpret_cast<uint8_t*>(entityData) + healthField.offset);
savedHealth = *healthAddress;
*healthAddress = spoofHealth;
spoofedHealth = true;
++g_packEntitySpoofs;
++g_packEntityScopedWrites;
}
}
}
}
g_packEntity(self, arg1, entityIndex, entityData, arg4, arg5, arg6, arg7, arg8, arg9);
if (spoofedHealth)
*healthAddress = savedHealth;
g_overrides.Restore(applied);
}
@@ -215,7 +98,7 @@ static bool InitPackEntityDetour(CGameConfig* config)
void* packEntityTarget = config->ResolveSignature("CNetworkGameServer_PackEntity");
if (!packEntityTarget)
{
SPWarning("CNetworkGameServer_PackEntity signature missing; scoped health hook disabled\n");
SPWarning("CNetworkGameServer_PackEntity signature missing; override hook disabled\n");
return true;
}
@@ -257,7 +140,7 @@ bool InitSnapshotDetour(CGameConfig* config)
void* packTarget = config->ResolveSignature("CNetworkGameServer_PackEntities_Normal");
if (!packTarget)
{
SPWarning("CNetworkGameServer_PackEntities_Normal signature missing; pre-pack health_42 hook disabled\n");
SPWarning("CNetworkGameServer_PackEntities_Normal signature missing; pack counter hook disabled\n");
return true;
}
@@ -304,19 +187,11 @@ void ShutdownSnapshotDetour()
void DumpDetourStats()
{
SPMessage("hooks: snapshot calls=%llu applied=%llu changed=%llu; pack calls=%llu applied=%llu changed=%llu; pack_entity calls=%llu health_spoofs=%llu generic_spoofs=%llu scoped_writes=%llu self_skips=%llu no_recipient=%llu; fullupdate writes=%llu budget=%d\n",
SPMessage("hooks: snapshot calls=%llu; pack calls=%llu; pack_entity calls=%llu generic_spoofs=%llu; fullupdate writes=%llu budget=%d\n",
static_cast<unsigned long long>(g_snapshotCalls),
static_cast<unsigned long long>(g_snapshotApplied),
static_cast<unsigned long long>(g_snapshotChanged),
static_cast<unsigned long long>(g_packCalls),
static_cast<unsigned long long>(g_packApplied),
static_cast<unsigned long long>(g_packChanged),
static_cast<unsigned long long>(g_packEntityCalls),
static_cast<unsigned long long>(g_packEntitySpoofs),
static_cast<unsigned long long>(g_packEntityGenericSpoofs),
static_cast<unsigned long long>(g_packEntityScopedWrites),
static_cast<unsigned long long>(g_packEntitySelfSkips),
static_cast<unsigned long long>(g_packEntityNoRecipient),
static_cast<unsigned long long>(g_fullUpdateWrites),
g_fullUpdateBudget);
}