From 892f4154252f444583cc1d7a10a31717434917d5 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:44:30 +0200 Subject: [PATCH] Server: reverse server entity list class Fully reversed. --- src/core/init.cpp | 3 +- src/game/CMakeLists.txt | 3 +- src/game/client/cliententitylist.h | 1 - src/game/client/entitylist_clientbase.h | 54 +++++++++++++++---- src/game/server/baseentity.h | 25 +-------- src/game/server/entitylist.h | 60 +++++++++++++++++++-- src/game/server/entitylist_serverbase.h | 69 +++++++++++++++++++++++++ src/game/shared/ehandle.h | 2 +- src/game/shared/entitylist_base.cpp | 24 --------- src/game/shared/entitylist_base.h | 51 ------------------ 10 files changed, 174 insertions(+), 118 deletions(-) create mode 100644 src/game/server/entitylist_serverbase.h delete mode 100644 src/game/shared/entitylist_base.cpp delete mode 100644 src/game/shared/entitylist_base.h diff --git a/src/core/init.cpp b/src/core/init.cpp index 5c14b349..bff65e82 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -141,6 +141,7 @@ #include "game/server/ai_basenpc.h" #include "game/server/physics_main.h" #include "game/server/vscript_server.h" +#include "game/server/entitylist.h" #endif // !CLIENT_DLL #ifndef DEDICATED #include "game/client/viewrender.h" @@ -667,11 +668,11 @@ void DetourRegister() // Register detour classes to be searched and hooked. REGISTER(VServerGameDLL); REGISTER(VMoveHelperServer); REGISTER(VPhysics_Main); // REGISTER SERVER ONLY - REGISTER(VBaseEntity); REGISTER(VBaseAnimating); REGISTER(VPlayer); REGISTER(VAI_BaseNPC); REGISTER(VPlayerMove); + REGISTER(VServerEntityList); #endif // !CLIENT_DLL diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index e4c7f6dc..1515bff1 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -14,8 +14,6 @@ add_sources( SOURCE_GROUP "AI" add_sources( SOURCE_GROUP "Entity" "shared/ehandle.h" - "shared/entitylist_base.cpp" - "shared/entitylist_base.h" ) add_sources( SOURCE_GROUP "Simulation" @@ -138,6 +136,7 @@ add_sources( SOURCE_GROUP "Entity" "server/entityoutput.h" "server/soundent.cpp" "server/soundent.h" + "server/entitylist_serverbase.h" ) add_sources( SOURCE_GROUP "Network" diff --git a/src/game/client/cliententitylist.h b/src/game/client/cliententitylist.h index 72e43333..97fbb5ee 100644 --- a/src/game/client/cliententitylist.h +++ b/src/game/client/cliententitylist.h @@ -16,7 +16,6 @@ #include "public/icliententitylist.h" -#include "entitylist_clientbase.h" #include "icliententityinternal.h" #include "entitylist_clientbase.h" #include "c_baseplayer.h" diff --git a/src/game/client/entitylist_clientbase.h b/src/game/client/entitylist_clientbase.h index b619800c..c83ed889 100644 --- a/src/game/client/entitylist_clientbase.h +++ b/src/game/client/entitylist_clientbase.h @@ -1,9 +1,19 @@ #ifndef ENTITYLIST_CLIENTBASE_H #define ENTITYLIST_CLIENTBASE_H -#include -#include -#include +#include "tier0/threadtools.h" +#include "game/shared/ehandle.h" + +class C_EntInfo +{ +public: + IHandleEntity* m_pEntity; + int m_SerialNumber; + C_EntInfo* m_pPrev; + C_EntInfo* m_pNext; + + inline void ClearLinks() { m_pPrev = m_pNext = this; } +}; class C_BaseEntityList { @@ -20,15 +30,37 @@ protected: virtual void OnRemoveEntity(IHandleEntity* pEnt, const CBaseHandle& handle) = 0; // NOTE: implemented in engine! private: - // The first MAX_EDICTS entities are networkable. The rest are client-only or server-only. - CEntInfo m_EntPtrArray[NUM_ENT_ENTRIES]; - CEntInfoList m_activeList; - CEntInfoList m_freeNonNetworkableList; + class C_EntInfoList + { + public: + C_EntInfoList(); - // Client Sound (Miles) entities. - CThreadMutex m_clientSoundEntsMutex; - IHandleEntity* m_pClientSoundEnts[NUM_ENT_ENTRIES]; - ssize_t m_clientSoundEntCount; + const C_EntInfo* Head() const { return m_pHead; } + const C_EntInfo* Tail() const { return m_pTail; } + C_EntInfo* Head() { return m_pHead; } + C_EntInfo* Tail() { return m_pTail; } + //void AddToHead( C_EntInfo *pElement ) { LinkAfter( NULL, pElement ); } + //void AddToTail( C_EntInfo *pElement ) { LinkBefore( NULL, pElement ); } + + //void LinkBefore( C_EntInfo *pBefore, C_EntInfo *pElement ); + //void LinkAfter( C_EntInfo *pBefore, C_EntInfo *pElement ); + //void Unlink( C_EntInfo *pElement ); + //bool IsInList( C_EntInfo *pElement ); + + private: + C_EntInfo* m_pHead; + C_EntInfo* m_pTail; + }; + + // The first MAX_EDICTS entities are networkable. The rest are client-only. + C_EntInfo m_EntPtrArray[NUM_ENT_ENTRIES]; + C_EntInfoList m_activeList; + C_EntInfoList m_freeNonNetworkableList; + + // Sound entities. + CThreadMutex m_soundEntsMutex; + IHandleEntity* m_pSoundEnts[NUM_ENT_ENTRIES]; + ssize_t m_soundEntCount; }; #endif // ENTITYLIST_CLIENTBASE_H diff --git a/src/game/server/baseentity.h b/src/game/server/baseentity.h index 2993424b..246ca378 100644 --- a/src/game/server/baseentity.h +++ b/src/game/server/baseentity.h @@ -19,7 +19,7 @@ #include "game/shared/collisionproperty.h" #include "game/shared/shareddefs.h" #include "networkproperty.h" -#include "entitylist.h" +//#include "entitylist.h" #include "entityoutput.h" //----------------------------------------------------------------------------- @@ -277,27 +277,4 @@ protected: }; static_assert(sizeof(CBaseEntity) == 0xB08); -inline CBaseEntity*(*CBaseEntity__GetBaseEntity)(CBaseEntity* thisp); - -/////////////////////////////////////////////////////////////////////////////// -class VBaseEntity : public IDetour -{ - virtual void GetAdr(void) const - { - LogFunAdr("CBaseEntity::GetBaseEntity", CBaseEntity__GetBaseEntity); - LogVarAdr("g_pEntityList", g_pEntityList); - } - virtual void GetFun(void) const - { - g_GameDll.FindPatternSIMD("8B 91 ?? ?? ?? ?? 83 FA FF 74 1F 0F B7 C2 48 8D 0D ?? ?? ?? ?? C1 EA 10 48 8D 04 40 48 03 C0 39 54 C1 08 75 05 48 8B 04 C1 C3 33 C0 C3 CC CC CC 48 8B 41 30").GetPtr(CBaseEntity__GetBaseEntity); - } - virtual void GetVar(void) const - { - g_pEntityList = CMemory(CBaseEntity__GetBaseEntity).FindPattern("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - } - virtual void GetCon(void) const { } - virtual void Detour(const bool bAttach) const { } -}; -/////////////////////////////////////////////////////////////////////////////// - #endif // BASEENTITY_H diff --git a/src/game/server/entitylist.h b/src/game/server/entitylist.h index f0ec8cc0..78f189a3 100644 --- a/src/game/server/entitylist.h +++ b/src/game/server/entitylist.h @@ -1,14 +1,68 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // +// $Workfile: $ +// $Date: $ // $NoKeywords: $ //===========================================================================// -#ifndef ENTITYLIST_H +#if !defined( ENTITYLIST_H ) #define ENTITYLIST_H -#include "game/shared/entitylist_base.h" +#include "entitylist_serverbase.h" + +//------------------------------------------------------------------------------------- +// Forward declarations +//------------------------------------------------------------------------------------- +class CBaseEntity; + +// Implement this class and register with gEntList to receive entity create/delete notification +class IEntityListener +{ +public: + virtual void OnEntityCreated(CBaseEntity* pEntity) {}; + virtual void OnEntityDeleted(CBaseEntity* pEntity) {}; +}; + +//----------------------------------------------------------------------------- +// Purpose: a global list of all the entities in the game. All iteration through +// entities is done through this object. +//----------------------------------------------------------------------------- +class CGlobalEntityList : public CBaseEntityList +{ +private: + int m_iHighestEnt; // the topmost used array index + int m_iNumEnts; + int m_iNumEdicts; + + bool m_bClearingEntities; + CUtlVector m_entityListeners; +}; + IHandleEntity* LookupEntityByIndex(int iEntity); + + + extern CEntInfo** g_pEntityList; + +/////////////////////////////////////////////////////////////////////////////// +class VServerEntityList : public IDetour +{ + virtual void GetAdr(void) const + { + LogVarAdr("g_serverEntityList", g_pEntityList); + } + virtual void GetFun(void) const { } + virtual void GetVar(void) const + { + void* CBaseEntity__GetBaseEntity; + g_GameDll.FindPatternSIMD("8B 91 ?? ?? ?? ?? 83 FA FF 74 1F 0F B7 C2 48 8D 0D ?? ?? ?? ?? C1 EA 10 48 8D 04 40 48 03 C0 39 54 C1 08 75 05 48 8B 04 C1 C3 33 C0 C3 CC CC CC 48 8B 41 30").GetPtr(CBaseEntity__GetBaseEntity); + g_pEntityList = CMemory(CBaseEntity__GetBaseEntity).FindPattern("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + } + virtual void GetCon(void) const { } + virtual void Detour(const bool bAttach) const { } +}; +/////////////////////////////////////////////////////////////////////////////// + #endif // ENTITYLIST_H diff --git a/src/game/server/entitylist_serverbase.h b/src/game/server/entitylist_serverbase.h new file mode 100644 index 00000000..c2fe99be --- /dev/null +++ b/src/game/server/entitylist_serverbase.h @@ -0,0 +1,69 @@ +#ifndef ENTITYLIST_SERVERBASE_H +#define ENTITYLIST_SERVERBASE_H + +#include "tier0/threadtools.h" +#include "tier1/string_t.h" +#include "game/shared/ehandle.h" + +class CEntInfo +{ +public: + IHandleEntity* m_pEntity; + int m_SerialNumber; + CEntInfo* m_pPrev; + CEntInfo* m_pNext; + string_t m_iName; + string_t m_iClassName; + + inline void ClearLinks() { m_pPrev = m_pNext = this; } +}; + +class CBaseEntityList +{ +public: + + // Overridables. +protected: + + // These are notifications to the derived class. It can cache info here if it wants. + virtual void OnAddEntity(IHandleEntity* pEnt, const CBaseHandle& handle) = 0; // NOTE: implemented in engine! + + // It is safe to delete the entity here. We won't be accessing the pointer after + // calling OnRemoveEntity. + virtual void OnRemoveEntity(IHandleEntity* pEnt, const CBaseHandle& handle) = 0; // NOTE: implemented in engine! + +private: + class CEntInfoList + { + public: + CEntInfoList(); + + const CEntInfo* Head() const { return m_pHead; } + const CEntInfo* Tail() const { return m_pTail; } + CEntInfo* Head() { return m_pHead; } + CEntInfo* Tail() { return m_pTail; } + //void AddToHead( CEntInfo *pElement ) { LinkAfter( NULL, pElement ); } + //void AddToTail( CEntInfo *pElement ) { LinkBefore( NULL, pElement ); } + + //void LinkBefore( CEntInfo *pBefore, CEntInfo *pElement ); + //void LinkAfter( CEntInfo *pBefore, CEntInfo *pElement ); + //void Unlink( CEntInfo *pElement ); + //bool IsInList( CEntInfo *pElement ); + + private: + CEntInfo* m_pHead; + CEntInfo* m_pTail; + }; + + // The first MAX_EDICTS entities are networkable. The rest are server-only. + CEntInfo m_EntPtrArray[NUM_ENT_ENTRIES]; + CEntInfoList m_activeList; + CEntInfoList m_freeNonNetworkableList; + + // Sound entities. + CThreadMutex m_soundEntsMutex; + IHandleEntity* m_pSoundEnts[NUM_ENT_ENTRIES]; + ssize_t m_soundEntCount; +}; + +#endif // ENTITYLIST_SERVERBASE_H diff --git a/src/game/shared/ehandle.h b/src/game/shared/ehandle.h index 1caa06a5..b20ca97d 100644 --- a/src/game/shared/ehandle.h +++ b/src/game/shared/ehandle.h @@ -34,7 +34,7 @@ inline IHandleEntity* CBaseHandle::Get() const extern CBaseEntityList *g_pEntityList; return g_pEntityList->LookupEntity( *this ); } -*/ // !TODO: Obtain ptr. +*/ // !TODO: Obtain ptr. TODO: Move this out of shared code as the server's structure of BaseEntityList is different! // -------------------------------------------------------------------------------------------------- // // CHandle. diff --git a/src/game/shared/entitylist_base.cpp b/src/game/shared/entitylist_base.cpp deleted file mode 100644 index 98cef5ac..00000000 --- a/src/game/shared/entitylist_base.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -//=============================================================================// - -#include "core/stdafx.h" -#include "entitylist_base.h" -#include "public/ihandleentity.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -enum -{ - SERIAL_MASK = 0x7fff // the max value of a serial number, rolls back to 0 when it hits this limit -}; - -void CEntInfo::ClearLinks() -{ - m_pPrev = m_pNext = this; -} - -// !TODO: entity list. diff --git a/src/game/shared/entitylist_base.h b/src/game/shared/entitylist_base.h deleted file mode 100644 index acbaae37..00000000 --- a/src/game/shared/entitylist_base.h +++ /dev/null @@ -1,51 +0,0 @@ -//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// -// -// Purpose: -// -//=============================================================================// - -#ifndef ENTITYLIST_BASE_H -#define ENTITYLIST_BASE_H -#ifdef _WIN32 -#pragma once -#endif -#include "public/ihandleentity.h" - -class CEntInfo -{ -public: - IHandleEntity* m_pEntity; - int m_SerialNumber; - CEntInfo* m_pPrev; - CEntInfo* m_pNext; -#ifdef GAME_DLL - string_t m_iName; - string_t m_iClassName; -#endif - - void ClearLinks(); -}; - -class CEntInfoList -{ -public: - CEntInfoList(); - - const CEntInfo *Head() const { return m_pHead; } - const CEntInfo *Tail() const { return m_pTail; } - CEntInfo *Head() { return m_pHead; } - CEntInfo *Tail() { return m_pTail; } - //void AddToHead( CEntInfo *pElement ) { LinkAfter( NULL, pElement ); } - //void AddToTail( CEntInfo *pElement ) { LinkBefore( NULL, pElement ); } - - //void LinkBefore( CEntInfo *pBefore, CEntInfo *pElement ); - //void LinkAfter( CEntInfo *pBefore, CEntInfo *pElement ); - //void Unlink( CEntInfo *pElement ); - //bool IsInList( CEntInfo *pElement ); - -private: - CEntInfo *m_pHead; - CEntInfo *m_pTail; -}; - -#endif // ENTITYLIST_BASE_H