Skip to content

Commit 9738302

Browse files
committed
Add option to not bypass hooks with TakeDamage and DropWeapon natives.
1 parent 4a6d263 commit 9738302

File tree

4 files changed

+105
-10
lines changed

4 files changed

+105
-10
lines changed

extensions/sdkhooks/extension.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "natives.h"
3838
#include <sm_platform.h>
3939
#include <const.h>
40-
40+
#include <IBinTools.h>
4141

4242
//#define SDKHOOKSDEBUG
4343

@@ -317,6 +317,23 @@ void SDKHooks::SDK_OnAllLoaded()
317317
#endif
318318
}
319319

320+
bool SDKHooks::QueryRunning(char* error, size_t maxlength)
321+
{
322+
SM_CHECK_IFACE(BINTOOLS, g_pBinTools);
323+
324+
return true;
325+
}
326+
327+
bool SDKHooks::QueryInterfaceDrop(SMInterface* pInterface)
328+
{
329+
if (pInterface == g_pBinTools)
330+
{
331+
return false;
332+
}
333+
334+
return IExtensionInterface::QueryInterfaceDrop(pInterface);
335+
}
336+
320337
#define KILL_HOOK_IF_ACTIVE(hook) \
321338
if (hook != 0) \
322339
{ \

extensions/sdkhooks/extension.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include "smsdk_ext.h"
55
#include <ISDKHooks.h>
6-
#include <IBinTools.h>
76
#include <convar.h>
87
#include <sh_list.h>
98
#include <am-vector.h>
@@ -107,6 +106,10 @@ class IPhysicsObject;
107106
class CDmgAccumulator;
108107
typedef CBaseEntity CBaseCombatWeapon;
109108

109+
namespace SourceMod {
110+
class IBinTools;
111+
}
112+
110113
struct HookList
111114
{
112115
public:
@@ -184,7 +187,9 @@ class SDKHooks :
184187
* @param maxlength Size of error message buffer.
185188
* @return True if working, false otherwise.
186189
*/
187-
//virtual bool QueryRunning(char *error, size_t maxlength);
190+
virtual bool QueryRunning(char *error, size_t maxlength);
191+
192+
virtual bool QueryInterfaceDrop(SMInterface* pInterface);
188193

189194
/** Returns version string */
190195
virtual const char *GetExtensionVerString();
@@ -350,5 +355,7 @@ extern ICvar *icvar;
350355
#if SOURCE_ENGINE >= SE_ORANGEBOX
351356
extern IServerTools *servertools;
352357
#endif
358+
extern SourceMod::IBinTools *g_pBinTools;
359+
extern IGameConfig *g_pGameConf;
353360

354361
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

extensions/sdkhooks/natives.cpp

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "extension.h"
3434
#include "natives.h"
3535
#include <compat_wrappers.h>
36+
#include <IBinTools.h>
37+
#include <sm_argbuffer.h>
38+
39+
using namespace SourceMod;
3640

3741
SH_DECL_MANUALEXTERN1(OnTakeDamage, int, CTakeDamageInfoHack &);
3842
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)
170174
}
171175

172176
CTakeDamageInfoHack info(pInflictor, pAttacker, flDamage, iDamageType, pWeapon, vecDamageForce, vecDamagePosition);
173-
SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack &)info);
177+
178+
if (params[0] < 9 || params[9] != 0)
179+
{
180+
SH_MCALL(pVictim, OnTakeDamage)((CTakeDamageInfoHack&)info);
181+
}
182+
else
183+
{
184+
static ICallWrapper *pCall = nullptr;
185+
if (!pCall)
186+
{
187+
int offset;
188+
if (!g_pGameConf->GetOffset("OnTakeDamage", &offset))
189+
{
190+
return pContext->ThrowNativeError("Could not find OnTakeDamage offset");
191+
}
192+
193+
PassInfo pass[2];
194+
pass[0].type = PassType_Object;
195+
pass[0].size = sizeof(CTakeDamageInfoHack &);
196+
pass[0].flags = PASSFLAG_BYREF | PASSFLAG_OCTOR;
197+
pass[1].type = PassType_Basic;
198+
pass[1].size = sizeof(int);
199+
pass[1].flags = PASSFLAG_BYVAL;
200+
201+
pCall = g_pBinTools->CreateVCall(offset, 0, 0, &pass[1], &pass[0], 1);
202+
}
203+
204+
// Can't ArgBuffer here until we upgrade our Clang version on the Linux builder
205+
unsigned char vstk[sizeof(CBaseEntity *) + sizeof(CTakeDamageInfoHack &)];
206+
unsigned char* vptr = vstk;
207+
208+
*(CBaseEntity **)vptr = pVictim;
209+
vptr += sizeof(CBaseEntity *);
210+
*(CTakeDamageInfoHack *&)vptr = info;
211+
212+
int ret;
213+
pCall->Execute(vstk, &ret);
214+
}
174215

175216
return 0;
176217
}
@@ -225,6 +266,7 @@ cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
225266
}
226267

227268
Vector vecVelocity;
269+
Vector *pVecVelocity = nullptr;
228270
if ((err = pContext->LocalToPhysAddr(params[4], &addr)) != SP_ERROR_NONE)
229271
{
230272
return pContext->ThrowNativeError("Could not read vecVelocity vector");
@@ -236,14 +278,40 @@ cell_t Native_DropWeapon(IPluginContext *pContext, const cell_t *params)
236278
sp_ctof(addr[0]),
237279
sp_ctof(addr[1]),
238280
sp_ctof(addr[2]));
281+
pVecVelocity = &vecVelocity;
239282
}
240-
else
283+
284+
if (params[0] < 5 || params[5] != 0)
241285
{
242-
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, NULL);
243-
return 0;
286+
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon*)pWeapon, &vecTarget, pVecVelocity);
244287
}
288+
else
289+
{
290+
static ICallWrapper* pCall = nullptr;
291+
if (!pCall)
292+
{
293+
int offset;
294+
if (!g_pGameConf->GetOffset("Weapon_Drop", &offset))
295+
{
296+
return pContext->ThrowNativeError("Could not find Weapon_Drop offset");
297+
}
298+
299+
PassInfo pass[2];
300+
pass[0].type = PassType_Basic;
301+
pass[0].size = sizeof(CBaseEntity *);
302+
pass[0].flags = PASSFLAG_BYVAL;
303+
pass[1].type = PassType_Basic;
304+
pass[1].size = sizeof(Vector *);
305+
pass[1].flags = PASSFLAG_BYVAL;
306+
pass[2].type = PassType_Basic;
307+
pass[2].size = sizeof(Vector *);
308+
pass[2].flags = PASSFLAG_BYVAL;
245309

246-
SH_MCALL(pPlayer, Weapon_Drop)((CBaseCombatWeapon *)pWeapon, &vecTarget, &vecVelocity);
310+
pCall = g_pBinTools->CreateVCall(offset, 0, 0, nullptr, pass, 3);
311+
}
312+
313+
pCall->Execute(ArgBuffer<CBaseEntity *, CBaseEntity *, Vector *, Vector *>(pPlayer, pWeapon, &vecTarget, pVecVelocity), nullptr);
314+
}
247315

248316
return 0;
249317
}

plugins/include/sdkhooks.inc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,11 +416,13 @@ native void SDKUnhook(int entity, SDKHookType type, SDKHookCB callback);
416416
* @param weapon Weapon index (orangebox and later) or -1 for unspecified
417417
* @param damageForce Velocity of damage force
418418
* @param damagePosition Origin of damage
419+
* @param bypassHooks If true, bypass SDK hooks on OnTakeDamage
419420
* @error Invalid entity, attacker, inflictor, or weapon entity.
420421
*/
421422
native void SDKHooks_TakeDamage(int entity, int inflictor, int attacker,
422423
float damage, int damageType=DMG_GENERIC, int weapon=-1,
423-
const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR);
424+
const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR,
425+
bool bypassHooks = true);
424426

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

437440
/**
438441
* Do not edit below this line!

0 commit comments

Comments
 (0)