Skip to content

Commit

Permalink
Add option to not bypass hooks with TakeDamage and DropWeapon natives.
Browse files Browse the repository at this point in the history
  • Loading branch information
psychonic committed Oct 13, 2021
1 parent 4a6d263 commit 9738302
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 10 deletions.
19 changes: 18 additions & 1 deletion extensions/sdkhooks/extension.cpp
Expand Up @@ -37,7 +37,7 @@
#include "natives.h"
#include <sm_platform.h>
#include <const.h>

#include <IBinTools.h>

//#define SDKHOOKSDEBUG

Expand Down Expand Up @@ -317,6 +317,23 @@ void SDKHooks::SDK_OnAllLoaded()
#endif
}

bool SDKHooks::QueryRunning(char* error, size_t maxlength)
{
SM_CHECK_IFACE(BINTOOLS, g_pBinTools);

return true;
}

bool SDKHooks::QueryInterfaceDrop(SMInterface* pInterface)
{
if (pInterface == g_pBinTools)
{
return false;
}

return IExtensionInterface::QueryInterfaceDrop(pInterface);
}

#define KILL_HOOK_IF_ACTIVE(hook) \
if (hook != 0) \
{ \
Expand Down
11 changes: 9 additions & 2 deletions extensions/sdkhooks/extension.h
Expand Up @@ -3,7 +3,6 @@

#include "smsdk_ext.h"
#include <ISDKHooks.h>
#include <IBinTools.h>
#include <convar.h>
#include <sh_list.h>
#include <am-vector.h>
Expand Down Expand Up @@ -107,6 +106,10 @@ class IPhysicsObject;
class CDmgAccumulator;
typedef CBaseEntity CBaseCombatWeapon;

namespace SourceMod {
class IBinTools;
}

struct HookList
{
public:
Expand Down Expand Up @@ -184,7 +187,9 @@ class SDKHooks :
* @param maxlength Size of error message buffer.
* @return True if working, false otherwise.
*/
//virtual bool QueryRunning(char *error, size_t maxlength);
virtual bool QueryRunning(char *error, size_t maxlength);

virtual bool QueryInterfaceDrop(SMInterface* pInterface);

/** Returns version string */
virtual const char *GetExtensionVerString();
Expand Down Expand Up @@ -350,5 +355,7 @@ extern ICvar *icvar;
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools;
#endif
extern SourceMod::IBinTools *g_pBinTools;
extern IGameConfig *g_pGameConf;

#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
78 changes: 73 additions & 5 deletions extensions/sdkhooks/natives.cpp
Expand Up @@ -33,6 +33,10 @@
#include "extension.h"
#include "natives.h"
#include <compat_wrappers.h>
#include <IBinTools.h>
#include <sm_argbuffer.h>

using namespace SourceMod;

SH_DECL_MANUALEXTERN1(OnTakeDamage, int, CTakeDamageInfoHack &);
SH_DECL_MANUALEXTERN3_void(Weapon_Drop, CBaseCombatWeapon *, const Vector *, const Vector *);
Expand Down Expand Up @@ -170,7 +174,44 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
}

CTakeDamageInfoHack info(pInflictor, pAttacker, flDamage, iDamageType, pWeapon, vecDamageForce, vecDamagePosition);
SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack &)info);

if (params[0] < 9 || params[9] != 0)
{
SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack&)info);
}
else
{
static ICallWrapper *pCall = nullptr;
if (!pCall)
{
int offset;
if (!g_pGameConf->GetOffset("OnTakeDamage", &offset))
{
return pContext->ThrowNativeError("Could not find OnTakeDamage offset");
}

PassInfo pass[2];
pass[0].type = PassType_Object;
pass[0].size = sizeof(CTakeDamageInfoHack &);
pass[0].flags = PASSFLAG_BYREF | PASSFLAG_OCTOR;
pass[1].type = PassType_Basic;
pass[1].size = sizeof(int);
pass[1].flags = PASSFLAG_BYVAL;

pCall = g_pBinTools->CreateVCall(offset, 0, 0, &pass[1], &pass[0], 1);
}

// Can't ArgBuffer here until we upgrade our Clang version on the Linux builder
unsigned char vstk[sizeof(CBaseEntity *) + sizeof(CTakeDamageInfoHack &)];
unsigned char* vptr = vstk;

*(CBaseEntity **)vptr = pVictim;
vptr += sizeof(CBaseEntity *);
*(CTakeDamageInfoHack *&)vptr = info;

int ret;
pCall->Execute(vstk, &ret);
}

return 0;
}
Expand Down Expand Up @@ -225,6 +266,7 @@ cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
}

Vector vecVelocity;
Vector *pVecVelocity = nullptr;
if ((err = pContext->LocalToPhysAddr(params[4], &addr)) != SP_ERROR_NONE)
{
return pContext->ThrowNativeError("Could not read vecVelocity vector");
Expand All @@ -236,14 +278,40 @@ cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
sp_ctof(addr[0]),
sp_ctof(addr[1]),
sp_ctof(addr[2]));
pVecVelocity = &vecVelocity;
}
else

if (params[0] < 5 || params[5] != 0)
{
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, NULL);
return 0;
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon*)pWeapon, &vecTarget, 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[2];
pass[0].type = PassType_Basic;
pass[0].size = sizeof(CBaseEntity *);
pass[0].flags = PASSFLAG_BYVAL;
pass[1].type = PassType_Basic;
pass[1].size = sizeof(Vector *);
pass[1].flags = PASSFLAG_BYVAL;
pass[2].type = PassType_Basic;
pass[2].size = sizeof(Vector *);
pass[2].flags = PASSFLAG_BYVAL;

SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, &vecVelocity);
pCall = g_pBinTools->CreateVCall(offset, 0, 0, nullptr, pass, 3);
}

pCall->Execute(ArgBuffer<CBaseEntity *, CBaseEntity *, Vector *, Vector *>(pPlayer, pWeapon, &vecTarget, pVecVelocity), nullptr);
}

return 0;
}
7 changes: 5 additions & 2 deletions plugins/include/sdkhooks.inc
Expand Up @@ -416,11 +416,13 @@ native void SDKUnhook(int entity, SDKHookType type, SDKHookCB callback);
* @param weapon Weapon index (orangebox and later) or -1 for unspecified
* @param damageForce Velocity of damage force
* @param damagePosition Origin of damage
* @param bypassHooks If true, bypass SDK hooks on OnTakeDamage
* @error Invalid entity, attacker, inflictor, or weapon entity.
*/
native void SDKHooks_TakeDamage(int entity, int inflictor, int attacker,
float damage, int damageType=DMG_GENERIC, int weapon=-1,
const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR);
const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR,
bool bypassHooks = true);

/**
* Forces a client to drop the specified weapon
Expand All @@ -429,10 +431,11 @@ native void SDKHooks_TakeDamage(int entity, int inflictor, int attacker,
* @param weapon Weapon entity index.
* @param vecTarget Location to toss weapon to, or NULL_VECTOR for default.
* @param vecVelocity Velocity at which to toss weapon, or NULL_VECTOR for default.
* @param bypassHooks If true, bypass SDK hooks on Weapon Drop
* @error Invalid client or weapon entity, weapon not owned by client.
*/
native void SDKHooks_DropWeapon(int client, int weapon, const float vecTarget[3]=NULL_VECTOR,
const float vecVelocity[3]=NULL_VECTOR);
const float vecVelocity[3]=NULL_VECTOR, bool bypassHooks = true);

/**
* Do not edit below this line!
Expand Down

0 comments on commit 9738302

Please sign in to comment.