Strip sourcehook from SDKHooks

This commit is contained in:
Kenzzer 2025-08-18 19:09:27 +00:00
parent d03827e965
commit 290cf2ab96
No known key found for this signature in database
GPG Key ID: 64C3FD4332686DC1
7 changed files with 428 additions and 513 deletions

View File

@ -672,7 +672,7 @@ else:
#'extensions/mysql/AMBuilder',
'extensions/pgsql/AMBuilder',
'extensions/regex/AMBuilder',
#'extensions/sdkhooks/AMBuilder',
'extensions/sdkhooks/AMBuilder',
#'extensions/sdktools/AMBuilder',
'extensions/sqlite/AMBuilder',
#'extensions/tf2/AMBuilder',

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#include "smsdk_ext.h"
#include <ISDKHooks.h>
#include <convar.h>
#include <sh_list.h>
#include <list>
#include <am-vector.h>
#include <vtable_hook_helper.h>
@ -36,6 +36,7 @@ struct HookTypeData
const char *name;
const char *dtReq;
bool supported;
unsigned int offset;
};
enum SDKHookType
@ -87,6 +88,8 @@ enum SDKHookType
SDKHook_MAXHOOKS
};
extern HookTypeData g_HookTypes[SDKHook_MAXHOOKS];
enum HookReturn
{
HookRet_Successful,
@ -130,6 +133,9 @@ public:
{
delete vtablehook;
};
CVTableList(const CVTableList&) = delete;
CVTableList& operator= (const CVTableList&) = delete;
public:
CVTableHook *vtablehook;
std::vector<HookList> hooks;
@ -160,6 +166,8 @@ class SDKHooks :
public ISDKHooks
{
public:
SDKHooks();
/**
* @brief This is called after the initial loading sequence has been processed.
*
@ -260,9 +268,10 @@ public: // ISDKHooks
virtual void RemoveEntityListener(ISMEntityListener *listener);
public: // IServerGameDLL
void LevelShutdown();
KHook::Return<void> LevelShutdown(IServerGameDLL*);
KHook::Virtual<IServerGameDLL, void> m_HookLevelShutdown;
private:
SourceHook::List<ISMEntityListener *> m_EntListeners;
std::list<ISMEntityListener *> m_EntListeners;
public:
/**
@ -280,65 +289,67 @@ public:
* IServerGameDLL & IVEngineServer Hook Handlers
*/
#ifdef GAMEDESC_CAN_CHANGE
const char *Hook_GetGameDescription();
KHook::Return<const char*> Hook_GetGameDescription(IServerGameDLL*);
KHook::Virtual<IServerGameDLL, const char*> m_HookGetGameDescription;
#endif
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
KHook::Return<bool> Hook_LevelInit(IServerGameDLL*, char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
KHook::Virtual<IServerGameDLL, bool, char const*, char const*, char const*, char const*, bool, bool> m_HookLevelInit;
/**
* CBaseEntity Hook Handlers
*/
bool Hook_CanBeAutobalanced();
void Hook_EndTouch(CBaseEntity *pOther);
void Hook_EndTouchPost(CBaseEntity *pOther);
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
KHook::Return<bool> Hook_CanBeAutobalanced(CBaseEntity*);
KHook::Return<void> Hook_EndTouch(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<void> Hook_EndTouchPost(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<void> Hook_FireBulletsPost(CBaseEntity*, const FireBulletsInfo_t &info);
#ifdef GETMAXHEALTH_IS_VIRTUAL
int Hook_GetMaxHealth();
KHook::Return<int> Hook_GetMaxHealth(CBaseEntity*);
#endif
void Hook_GroundEntChangedPost(void *pVar);
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
int Hook_OnTakeDamage_Alive(CTakeDamageInfoHack &info);
int Hook_OnTakeDamage_AlivePost(CTakeDamageInfoHack &info);
void Hook_PreThink();
void Hook_PreThinkPost();
void Hook_PostThink();
void Hook_PostThinkPost();
bool Hook_Reload();
bool Hook_ReloadPost();
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
void Hook_Spawn();
void Hook_SpawnPost();
void Hook_StartTouch(CBaseEntity *pOther);
void Hook_StartTouchPost(CBaseEntity *pOther);
void Hook_Think();
void Hook_ThinkPost();
void Hook_Touch(CBaseEntity *pOther);
void Hook_TouchPost(CBaseEntity *pOther);
KHook::Return<void> Hook_GroundEntChangedPost(CBaseEntity*, void *pVar);
KHook::Return<int> Hook_OnTakeDamage(CBaseEntity*, CTakeDamageInfoHack &info);
KHook::Return<int> Hook_OnTakeDamagePost(CBaseEntity*, CTakeDamageInfoHack &info);
KHook::Return<int> Hook_OnTakeDamage_Alive(CBaseEntity*, CTakeDamageInfoHack &info);
KHook::Return<int> Hook_OnTakeDamage_AlivePost(CBaseEntity*, CTakeDamageInfoHack &info);
KHook::Return<void> Hook_PreThink(CBaseEntity*);
KHook::Return<void> Hook_PreThinkPost(CBaseEntity*);
KHook::Return<void> Hook_PostThink(CBaseEntity*);
KHook::Return<void> Hook_PostThinkPost(CBaseEntity*);
KHook::Return<bool> Hook_Reload(CBaseEntity*);
KHook::Return<bool> Hook_ReloadPost(CBaseEntity*);
KHook::Return<void> Hook_SetTransmit(CBaseEntity*, CCheckTransmitInfo *pInfo, bool bAlways);
KHook::Return<bool> Hook_ShouldCollide(CBaseEntity*, int collisonGroup, int contentsMask);
KHook::Return<void> Hook_Spawn(CBaseEntity*);
KHook::Return<void> Hook_SpawnPost(CBaseEntity*);
KHook::Return<void> Hook_StartTouch(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<void> Hook_StartTouchPost(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<void> Hook_Think(CBaseEntity*);
KHook::Return<void> Hook_ThinkPost(CBaseEntity*);
KHook::Return<void> Hook_Touch(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<void> Hook_TouchPost(CBaseEntity*, CBaseEntity *pOther);
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_PVKII
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
KHook::Return<void> Hook_TraceAttack(CBaseEntity*, CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
KHook::Return<void> Hook_TraceAttackPost(CBaseEntity*, CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
#else
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
KHook::Return<void> Hook_TraceAttack(CBaseEntity*, CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
KHook::Return<void> Hook_TraceAttackPost(CBaseEntity*, CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
#endif
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
void Hook_Blocked(CBaseEntity *pOther);
void Hook_BlockedPost(CBaseEntity *pOther);
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
KHook::Return<void> Hook_Use(CBaseEntity*, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
KHook::Return<void> Hook_UsePost(CBaseEntity*, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
KHook::Return<void> Hook_VPhysicsUpdate(CBaseEntity*, IPhysicsObject *pPhysics);
KHook::Return<void> Hook_VPhysicsUpdatePost(CBaseEntity*, IPhysicsObject *pPhysics);
KHook::Return<void> Hook_Blocked(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<void> Hook_BlockedPost(CBaseEntity*, CBaseEntity *pOther);
KHook::Return<bool> Hook_WeaponCanSwitchTo(CBaseEntity*, CBaseCombatWeapon *pWeapon);
KHook::Return<bool> Hook_WeaponCanSwitchToPost(CBaseEntity*, CBaseCombatWeapon *pWeapon);
KHook::Return<bool> Hook_WeaponCanUse(CBaseEntity*, CBaseCombatWeapon *pWeapon);
KHook::Return<bool> Hook_WeaponCanUsePost(CBaseEntity*, CBaseCombatWeapon *pWeapon);
KHook::Return<void> Hook_WeaponDrop(CBaseEntity*, CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
KHook::Return<void> Hook_WeaponDropPost(CBaseEntity*, CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
KHook::Return<void> Hook_WeaponEquip(CBaseEntity*, CBaseCombatWeapon *pWeapon);
KHook::Return<void> Hook_WeaponEquipPost(CBaseEntity*, CBaseCombatWeapon *pWeapon);
KHook::Return<bool> Hook_WeaponSwitch(CBaseEntity*, CBaseCombatWeapon *pWeapon, int viewmodelindex);
KHook::Return<bool> Hook_WeaponSwitchPost(CBaseEntity*, CBaseCombatWeapon *pWeapon, int viewmodelindex);
private:
void HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref);
@ -347,8 +358,8 @@ private:
void Unhook(IPluginContext *pContext);
private:
int HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType);
int HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType);
KHook::Return<int> HandleOnTakeDamageHook(CBaseEntity*, CTakeDamageInfoHack &info, SDKHookType hookType);
KHook::Return<int> HandleOnTakeDamageHookPost(CBaseEntity*, CTakeDamageInfoHack &info, SDKHookType hookType);
private:
inline bool IsEntityIndexInRange(int i) { return i >= 0 && i < NUM_ENT_ENTRIES; }

View File

@ -30,19 +30,23 @@
* Version: $Id$
*/
#define SET_PRE_true(gamedataname) g_HookTypes[SDKHook_##gamedataname].supported = true;
#define SET_PRE_false(gamedataname)
#define SET_POST_true(gamedataname) g_HookTypes[SDKHook_##gamedataname##Post].supported = true;
#define SET_POST_false(gamedataname)
#define SET_PRE_true(gamedataname, index) g_HookTypes[SDKHook_##gamedataname].supported = true; \
g_HookTypes[SDKHook_##gamedataname].offset = index;
#define SET_PRE_false(gamedataname, index)
#define SET_POST_true(gamedataname, index) g_HookTypes[SDKHook_##gamedataname##Post].supported = true; \
g_HookTypes[SDKHook_##gamedataname##Post].offset = index;
#define SET_POST_false(gamedataname, index)
#define CHECKOFFSET(gamedataname, supportsPre, supportsPost) \
offset = 0; \
g_pGameConf->GetOffset(#gamedataname, &offset); \
if (offset > 0) \
{ \
SH_MANUALHOOK_RECONFIGURE(gamedataname, offset, 0, 0); \
SET_PRE_##supportsPre(gamedataname) \
SET_POST_##supportsPost(gamedataname) \
SET_PRE_##supportsPre(gamedataname, offset) \
SET_POST_##supportsPost(gamedataname, offset) \
}
#define CHECKOFFSET_W(gamedataname, supportsPre, supportsPost) \
@ -50,9 +54,8 @@
g_pGameConf->GetOffset("Weapon_"#gamedataname, &offset); \
if (offset > 0) \
{ \
SH_MANUALHOOK_RECONFIGURE(Weapon_##gamedataname, offset, 0, 0); \
SET_PRE_##supportsPre(Weapon##gamedataname) \
SET_POST_##supportsPost(Weapon##gamedataname) \
SET_PRE_##supportsPre(Weapon##gamedataname, offset) \
SET_POST_##supportsPost(Weapon##gamedataname, offset) \
}
#define HOOKLOOP \

View File

@ -38,9 +38,6 @@
using namespace SourceMod;
SH_DECL_MANUALEXTERN1(OnTakeDamage, int, CTakeDamageInfoHack &);
SH_DECL_MANUALEXTERN3_void(Weapon_Drop, CBaseCombatWeapon *, const Vector *, const Vector *);
cell_t Native_Hook(IPluginContext *pContext, const cell_t *params)
{
int entity = (int)params[1];
@ -102,6 +99,9 @@ cell_t Native_Unhook(IPluginContext *pContext, const cell_t *params)
cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
{
if (g_HookTypes[SDKHook_OnTakeDamage].supported == false)
return pContext->ThrowNativeError("SDKHooks_DropWeapon isn't supported by this mod.");
CBaseEntity *pVictim = gamehelpers->ReferenceToEntity(params[1]);
if (!pVictim)
return pContext->ThrowNativeError("Invalid entity index %d for victim", params[1]);
@ -177,7 +177,9 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
if (params[0] < 9 || params[9] != 0)
{
SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack&)info);
auto func = KHook::GetOriginal((*(void***)pVictim)[g_HookTypes[SDKHook_OnTakeDamage].offset]);
auto mfp = KHook::BuildMFP<CBaseEntity, int, const CTakeDamageInfoHack&>(func);
(pVictim->*mfp)(info);
}
else
{
@ -198,7 +200,7 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
pass[1].size = sizeof(int);
pass[1].flags = PASSFLAG_BYVAL;
pCall = g_pBinTools->CreateVCall(offset, 0, 0, &pass[1], &pass[0], 1);
pCall = g_pBinTools->CreateVCall(g_HookTypes[SDKHook_OnTakeDamage].offset, 0, 0, &pass[1], &pass[0], 1);
}
// Can't ArgBuffer here until we upgrade our Clang version on the Linux builder
@ -218,6 +220,9 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
{
if (g_HookTypes[SDKHook_WeaponDrop].supported == false)
return pContext->ThrowNativeError("SDKHooks_DropWeapon isn't supported by this mod.");
CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(params[1]);
if (!pPlayer)
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
@ -286,19 +291,15 @@ cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
if (params[0] < 5 || params[5] != 0)
{
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon*)pWeapon, pVecTarget, pVecVelocity);
auto func = KHook::GetOriginal((*(void***)pPlayer)[g_HookTypes[SDKHook_WeaponDrop].offset]);
auto mfp = KHook::BuildMFP<CBaseEntity, void, CBaseCombatWeapon*, const Vector*, const Vector*>(func);
(pPlayer->*mfp)((CBaseCombatWeapon*)pWeapon, pVecTarget, pVecVelocity);
}
else
{
static ICallWrapper* pCall = nullptr;
if (!pCall)
{
int offset;
if (!g_pGameConf->GetOffset("Weapon_Drop", &offset))
{
return pContext->ThrowNativeError("Could not find Weapon_Drop offset");
}
PassInfo pass[3];
pass[0].type = PassType_Basic;
pass[0].size = sizeof(CBaseEntity *);
@ -310,7 +311,7 @@ cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
pass[2].size = sizeof(Vector *);
pass[2].flags = PASSFLAG_BYVAL;
pCall = g_pBinTools->CreateVCall(offset, 0, 0, nullptr, pass, 3);
pCall = g_pBinTools->CreateVCall(g_HookTypes[SDKHook_WeaponDrop].offset, 0, 0, nullptr, pass, 3);
}
pCall->Execute(ArgBuffer<CBaseEntity *, CBaseEntity *, Vector *, Vector *>(pPlayer, pWeapon, pVecTarget, pVecVelocity), nullptr);

View File

@ -305,7 +305,7 @@ void SDKExtension::SDK_OnDependenciesDropped()
PluginId g_PLID = 0; /**< Metamod plugin ID */
ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */
SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */
class KHook::IKHook* __exported__khook = NULL; /**< KHook pointer */
ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */
#ifndef META_NO_HL2SDK

View File

@ -32,83 +32,26 @@
#ifndef _INCLUDE_VTABLE_HOOK_HELPER_H_
#define _INCLUDE_VTABLE_HOOK_HELPER_H_
#include <memory>
class CVTableHook
{
public:
CVTableHook(void *takenclass)
{
this->vtableptr = *reinterpret_cast<void ***>(takenclass);
this->hookid = 0;
}
CVTableHook(void *vtable, int hook)
CVTableHook(void** vtable, KHook::__Hook* hook) : vtableptr(vtable), _khook(hook)
{
this->vtableptr = vtable;
this->hookid = hook;
}
CVTableHook(CVTableHook &other)
{
this->vtableptr = other.vtableptr;
this->hookid = other.hookid;
other.hookid = 0;
}
CVTableHook(CVTableHook *other)
{
this->vtableptr = other->vtableptr;
this->hookid = other->hookid;
other->hookid = 0;
}
~CVTableHook()
{
if (this->hookid)
{
SH_REMOVE_HOOK_ID(this->hookid);
this->hookid = 0;
}
}
CVTableHook(const CVTableHook&) = delete;
CVTableHook& operator= (const CVTableHook&) = delete;
public:
void *GetVTablePtr(void)
void** GetVTablePtr(void)
{
return this->vtableptr;
}
void SetHookID(int hook)
{
this->hookid = hook;
}
bool IsHooked(void)
{
return (this->hookid != 0);
}
public:
bool operator == (CVTableHook &other)
{
return (this->GetVTablePtr() == other.GetVTablePtr());
}
bool operator == (CVTableHook *other)
{
return (this->GetVTablePtr() == other->GetVTablePtr());
}
bool operator != (CVTableHook &other)
{
return (this->GetVTablePtr() != other.GetVTablePtr());
}
bool operator != (CVTableHook *other)
{
return (this->GetVTablePtr() != other->GetVTablePtr());
}
private:
void *vtableptr;
int hookid;
void** vtableptr;
std::unique_ptr<KHook::__Hook> _khook;
};
#endif //_INCLUDE_VTABLE_HOOK_HELPER_H_