From a9c6a5e733fdd35f191a64a3966823818afd50b1 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 30 Jul 2024 01:12:35 +0200 Subject: [PATCH] Game: properly setup interface classes Member m_RefEHandle is always at offset 8 for Server and Client BaseEntity class. The onyl way to achieve this is to put this into the IHandleEntity interface, as otherwise it will be placed after the interface pointers in C_BaseEntity for client. This also eliminates the need of padding at the beginning of both the server and client's version of the BaseEntity class. The IClientEntity interface has also been properly reversed and applied to the SDK now, the unknown vftable entries have now been identified correctly and moved to IClientUnknown . --- src/game/client/c_baseentity.h | 10 ++++++---- src/game/server/baseentity.h | 2 -- src/public/icliententity.h | 23 ++++------------------- src/public/iclientnetworkable.h | 3 +-- src/public/iclientrenderable.h | 12 +++++++++--- src/public/iclientthinkable.h | 5 ++++- src/public/iclientunknown.h | 31 +++++++++++++++++++++++++++---- src/public/ihandleentity.h | 3 +++ 8 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/game/client/c_baseentity.h b/src/game/client/c_baseentity.h index 5afaf5ab..d8e8cdc0 100644 --- a/src/game/client/c_baseentity.h +++ b/src/game/client/c_baseentity.h @@ -3,6 +3,7 @@ #include "game/shared/collisionproperty.h" #include "game/shared/particleproperty.h" +#include "game/shared/predictioncopy.h" #include "vscript/ivscript.h" #include "icliententity.h" @@ -12,9 +13,10 @@ // How many data slots to use when in multiplayer. #define MULTIPLAYER_BACKUP 750 -class C_BaseEntity : public IClientEntity +class C_BaseEntity : public IClientEntity, public IClientModelRenderable { - char pad0[8]; +protected: + char pad0[16]; void* unkHandle; char pad1[16]; int m_iEFlags; @@ -45,7 +47,7 @@ class C_BaseEntity : public IClientEntity float m_flGravity; float m_flProxyRandomValue; Vector3D m_vecBaseVelocity; - int m_hGroundEntity; + EHANDLE m_hGroundEntity; char gap_3e0[4]; float m_flMaxspeed; int m_visibilityFlags; @@ -60,7 +62,7 @@ class C_BaseEntity : public IClientEntity Vector3D m_angNetworkAngles; float m_flFriction; char gap_438[4]; - int m_hOwnerEntity; + EHANDLE m_hOwnerEntity; bool m_bRenderWithViewModels; unsigned __int8 m_nRenderFX; char gap_442[15]; diff --git a/src/game/server/baseentity.h b/src/game/server/baseentity.h index 36a3984f..c8b42b37 100644 --- a/src/game/server/baseentity.h +++ b/src/game/server/baseentity.h @@ -59,8 +59,6 @@ public: inline int GetFlags(void) const { return m_fFlags; } protected: - CBaseHandle m_RefEHandle; - char gap_c[4]; void* m_collideable; void* m_networkable; int genericKeyValueCount; diff --git a/src/public/icliententity.h b/src/public/icliententity.h index 66bacb4c..c8952dab 100644 --- a/src/public/icliententity.h +++ b/src/public/icliententity.h @@ -9,28 +9,13 @@ #include "mathlib/vector.h" abstract_class IClientEntity : public IClientUnknown, - public IHandleEntity, public IClientRenderable, public IClientNetworkable, - public IClientThinkable, - public IClientModelRenderable + public IClientThinkable { - // NOTE: commented because the compiler optimizes this away, but that causes - // out class members to misalign. Once usage is made from this interface, - // remove the '__vftable' alignment member. -//public: -// virtual __int64 sub_1405A82B0() = 0; -// virtual __int64 sub_14096B640(char a2) = 0; -// virtual __int64 sub_1405A9330() = 0; -// virtual __int64 sub_1405A9340() = 0; -// virtual __int64 sub_1405A9350() = 0; -// virtual __int64 sub_1401F8F80() = 0; -// virtual __int64 sub_1401F8F81() = 0; -// virtual __int64 sub_1405A9360() = 0; -// virtual const Vector3D& GetAbsOrigin(void) const = 0; -// virtual const QAngle& GetAbsAngles(void) const = 0; - - void* __vftable; +public: + virtual const Vector3D& GetAbsOrigin(void) const = 0; + virtual const QAngle& GetAbsAngles(void) const = 0; }; #endif // ICLIENTENTITY_H \ No newline at end of file diff --git a/src/public/iclientnetworkable.h b/src/public/iclientnetworkable.h index 8db83f78..6eed1dc9 100644 --- a/src/public/iclientnetworkable.h +++ b/src/public/iclientnetworkable.h @@ -4,8 +4,7 @@ class IClientNetworkable { public: - void* __vftable /*VFT*/; - //virtual ~IClientNetworkable(void) = 0; + virtual ~IClientNetworkable(void) = 0; // !TODO! }; diff --git a/src/public/iclientrenderable.h b/src/public/iclientrenderable.h index 68f0f9d1..1fb77da4 100644 --- a/src/public/iclientrenderable.h +++ b/src/public/iclientrenderable.h @@ -11,14 +11,20 @@ enum INVALID_CLIENT_RENDER_HANDLE = (ClientRenderHandle_t)0xffff, }; -class IClientRenderable +//----------------------------------------------------------------------------- +// Purpose: All client entities must implement this interface. +//----------------------------------------------------------------------------- +abstract_class IClientRenderable { - void* __vftable /*VFT*/; + // Gets at the containing class... + virtual IClientUnknown* GetIClientUnknown() = 0; + // TODO: }; class IClientModelRenderable { - void* __vftable /*VFT*/; + // TODO: + virtual void InterfaceNeedsRebuild() = 0; }; diff --git a/src/public/iclientthinkable.h b/src/public/iclientthinkable.h index 026f5a60..3a38068d 100644 --- a/src/public/iclientthinkable.h +++ b/src/public/iclientthinkable.h @@ -3,7 +3,10 @@ class IClientThinkable { - void* __vftable /*VFT*/; +public: + // Gets at the containing class... + virtual IClientUnknown* GetIClientUnknown() = 0; + // TODO: }; #endif // ICLIENTTHINKABLE_H \ No newline at end of file diff --git a/src/public/iclientunknown.h b/src/public/iclientunknown.h index cbaf419e..8379fffd 100644 --- a/src/public/iclientunknown.h +++ b/src/public/iclientunknown.h @@ -1,10 +1,33 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// #ifndef ICLIENTUNKNOWN_H #define ICLIENTUNKNOWN_H -class IClientUnknown +#include "tier0/platform.h" +#include "ihandleentity.h" + +class ICollideable; +class IClientNetworkable; +class IClientRenderable; +class IClientEntity; +class IClientThinkable; +class C_BaseEntity; + +// This is the client's version of IUnknown. We may want to use a QueryInterface-like +// mechanism if this gets big. +abstract_class IClientUnknown : public IHandleEntity { - void* __vftable /*VFT*/; +public: + virtual ICollideable* GetCollideable() = 0; + virtual IClientNetworkable* GetClientNetworkable() = 0; + virtual IClientRenderable* GetClientRenderable() = 0; + virtual IClientEntity* GetIClientEntity() = 0; + virtual C_BaseEntity* GetBaseEntity() = 0; + virtual IClientThinkable* GetClientThinkable() = 0; }; - -#endif // ICLIENTUNKNOWN_H \ No newline at end of file +#endif // ICLIENTUNKNOWN_H diff --git a/src/public/ihandleentity.h b/src/public/ihandleentity.h index 76458c96..3d6ec2ea 100644 --- a/src/public/ihandleentity.h +++ b/src/public/ihandleentity.h @@ -7,6 +7,9 @@ class IHandleEntity public: virtual void SetRefEHandle(const CBaseHandle& handle) = 0; virtual ~IHandleEntity() {} + +protected: + CBaseHandle m_RefEHandle; // Reference ehandle. Used to generate ehandles off this entity. }; #endif // IHANDLEENTITY_H \ No newline at end of file