3#include <CS2Kit/Sdk/Entity.hpp>
4#include <CS2Kit/Sdk/GameData.hpp>
5#include <CS2Kit/Sdk/GameInterfaces.hpp>
6#include <CS2Kit/Utils/Log.hpp>
7#include <entity2/concreteentitylist.h>
8#include <entity2/entityidentity.h>
9#include <entity2/entityinstance.h>
10#include <entity2/entitysystem.h>
16void EntitySystem::ResolveSchemaOffsets()
18 if (_schemaOffsetsResolved)
21 auto& schema = SchemaService::Instance();
23 _offsetPlayerPawn = schema.GetOffset(
"CBasePlayerController",
"m_hPawn");
24 _offsetMovementServices = schema.GetOffset(
"CBasePlayerPawn",
"m_pMovementServices");
25 _offsetButtons = schema.GetOffset(
"CPlayer_MovementServices",
"m_nButtons");
26 _offsetButtonStates = schema.GetOffset(
"CInButtonState",
"m_pButtonStates");
28 _schemaOffsetsResolved =
true;
31bool EntitySystem::Initialize()
33 auto& interfaces = GameInterfaces::Instance();
35 if (!interfaces.GameResourceService)
37 Log::Warn(
"IGameResourceService not available.");
40 int offsetGameEntitySystem = GameData::Instance().GetOffset(
"GameEntitySystem");
42 if (offsetGameEntitySystem < 0)
44 Log::Warn(
"GameEntitySystem offset not found in gamedata.");
48 Log::Info(
"Gamedata loaded (entity system offset: {}).", offsetGameEntitySystem);
51 if (interfaces.GameResourceService && offsetGameEntitySystem >= 0)
53 interfaces.EntitySystem = *
reinterpret_cast<CGameEntitySystem**
>(
54 reinterpret_cast<uintptr_t
>(interfaces.GameResourceService) + offsetGameEntitySystem);
57 if (interfaces.EntitySystem)
59 Log::Info(
"Entity system initialized.");
65CGameEntitySystem* EntitySystem::GetEntitySystem()
67 auto& interfaces = GameInterfaces::Instance();
69 if (!interfaces.EntitySystem && interfaces.GameResourceService)
71 int offsetGameEntitySystem = GameData::Instance().GetOffset(
"GameEntitySystem");
72 if (offsetGameEntitySystem >= 0)
74 interfaces.EntitySystem = *
reinterpret_cast<CGameEntitySystem**
>(
75 reinterpret_cast<uintptr_t
>(interfaces.GameResourceService) + offsetGameEntitySystem);
78 return interfaces.EntitySystem;
81CEntityIdentity* EntitySystem::GetEntityIdentityByIndex(CGameEntitySystem* pSys,
int index)
83 if (!pSys || index < 0 || index >= MAX_TOTAL_ENTITIES)
86 int chunk = index / MAX_ENTITIES_IN_LIST;
87 int offset = index % MAX_ENTITIES_IN_LIST;
89 CEntityIdentity* pChunk = pSys->m_EntityList.m_pIdentityChunks[chunk];
93 return &pChunk[offset];
96CEntityInstance* EntitySystem::ResolveEntityHandle(uint32_t handle)
98 if (handle == 0xFFFFFFFF)
101 int entryIndex = handle & 0x7FFF;
103 auto* pSys = GetEntitySystem();
107 CEntityIdentity* pIdentity = GetEntityIdentityByIndex(pSys, entryIndex);
111 return pIdentity->m_pInstance;
114CEntityInstance* EntitySystem::GetPlayerController(
int slot)
116 auto* pSys = GetEntitySystem();
117 if (!pSys || slot < 0 || slot >= MaxPlayers)
120 CEntityIdentity* pIdentity = GetEntityIdentityByIndex(pSys, slot + 1);
124 return pIdentity->m_pInstance;
127uint64_t EntitySystem::GetPlayerButtons(
int slot)
129 if (!_schemaOffsetsResolved)
130 ResolveSchemaOffsets();
132 if (_offsetPlayerPawn < 0 || _offsetMovementServices < 0 || _offsetButtons < 0 || _offsetButtonStates < 0)
135 CEntityInstance* pController = GetPlayerController(slot);
139 auto* pCtrlBase =
reinterpret_cast<uint8_t*
>(pController);
141 uint32_t hPawn = *
reinterpret_cast<uint32_t*
>(pCtrlBase + _offsetPlayerPawn);
142 CEntityInstance* pPawn = ResolveEntityHandle(hPawn);
146 auto* pPawnBase =
reinterpret_cast<uint8_t*
>(pPawn);
148 auto* pMovementServices = *
reinterpret_cast<uint8_t**
>(pPawnBase + _offsetMovementServices);
149 if (!pMovementServices)
152 auto* pButtonStates =
reinterpret_cast<uint64_t*
>(pMovementServices + _offsetButtons + _offsetButtonStates);
154 return pButtonStates[0];
157bool EntitySystem::IsPlayerSlotValid(
int slot)
159 return GetPlayerController(slot) !=
nullptr;