Add option to not bypass hooks with TakeDamage and DropWeapon natives.

This commit is contained in:
Nick Hastings 2021-10-12 20:34:55 -04:00 committed by Nicholas Hastings
parent 4a6d263dad
commit 97383028e5
4 changed files with 105 additions and 10 deletions

View File

@ -37,7 +37,7 @@
#include "natives.h"
#include <sm_platform.h>
#include <const.h>
#include <IBinTools.h>
//#define SDKHOOKSDEBUG
@ -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) \
{ \

View File

@ -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>
@ -107,6 +106,10 @@ class IPhysicsObject;
class CDmgAccumulator;
typedef CBaseEntity CBaseCombatWeapon;
namespace SourceMod {
class IBinTools;
}
struct HookList
{
public:
@ -184,7 +187,9 @@ public:
* @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();
@ -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_

View File

@ -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 *);
@ -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;
}
@ -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");
@ -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;
}
if (params[0] < 5 || params[5] != 0)
{
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon*)pWeapon, &vecTarget, pVecVelocity);
}
else
{
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, NULL);
return 0;
}
static ICallWrapper* pCall = nullptr;
if (!pCall)
{
int offset;
if (!g_pGameConf->GetOffset("Weapon_Drop", &offset))
{
return pContext->ThrowNativeError("Could not find Weapon_Drop offset");
}
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, &vecVelocity);
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;
pCall = g_pBinTools->CreateVCall(offset, 0, 0, nullptr, pass, 3);
}
pCall->Execute(ArgBuffer<CBaseEntity *, CBaseEntity *, Vector *, Vector *>(pPlayer, pWeapon, &vecTarget, pVecVelocity), nullptr);
}
return 0;
}

View File

@ -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
@ -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!