2
0
mirror of https://github.com/rehlds/reapi.git synced 2025-04-22 22:33:35 +03:00

Implement native to get the current hookchain handle in amxx callback (#173)

This commit is contained in:
shel 2020-10-25 18:14:46 +04:00 committed by GitHub
parent fb5ec01319
commit 623a4f2236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 16 deletions

View File

@ -202,6 +202,13 @@ native SetHookChainArg(number, AType:type, any:...);
*/ */
native bool:IsReapiHookOriginalWasCalled({EngineFunc, GamedllFunc, GamedllFunc_CBaseAnimating, GamedllFunc_CBasePlayer, GamedllFunc_CSGameRules, GamedllFunc_CGrenade, GamedllFunc_CWeaponBox, ReCheckerFunc, GamedllFunc_CBasePlayerWeapon, GamedllFunc_CGib}:function_id); native bool:IsReapiHookOriginalWasCalled({EngineFunc, GamedllFunc, GamedllFunc_CBaseAnimating, GamedllFunc_CBasePlayer, GamedllFunc_CSGameRules, GamedllFunc_CGrenade, GamedllFunc_CWeaponBox, ReCheckerFunc, GamedllFunc_CBasePlayerWeapon, GamedllFunc_CGib}:function_id);
/*
* Returns the current hookchain handle.
*
* @return Returns the hook handle
*/
native HookChain:GetCurrentHookChainHandle();
/* /*
* Compares the entity to a specified classname. * Compares the entity to a specified classname.
* @note This native also checks the validity of an entity. * @note This native also checks the validity of an entity.

View File

@ -1,6 +1,7 @@
#include "precompiled.h" #include "precompiled.h"
CAmxxHookBase::CAmxxHookBase(AMX *amx, const char *funcname, int index) : CAmxxHookBase::CAmxxHookBase(AMX *amx, const char *funcname, int forwardIndex, int index) :
m_fwdindex(forwardIndex),
m_index(index), m_index(index),
m_state(FSTATE_ENABLED), m_state(FSTATE_ENABLED),
m_amx(amx) m_amx(amx)
@ -10,10 +11,10 @@ CAmxxHookBase::CAmxxHookBase(AMX *amx, const char *funcname, int index) :
CAmxxHookBase::~CAmxxHookBase() CAmxxHookBase::~CAmxxHookBase()
{ {
if (m_index != -1) if (m_fwdindex != -1)
{ {
g_amxxapi.UnregisterSPForward(m_index); g_amxxapi.UnregisterSPForward(m_fwdindex);
m_index = -1; m_fwdindex = -1;
} }
} }

View File

@ -12,8 +12,9 @@ class CAmxxHookBase
{ {
public: public:
~CAmxxHookBase(); ~CAmxxHookBase();
CAmxxHookBase(AMX *amx, const char *funcname, int index); CAmxxHookBase(AMX *amx, const char *funcname, int forwardIndex, int index);
int GetFwdIndex() const { return m_fwdindex; }
int GetIndex() const { return m_index; } int GetIndex() const { return m_index; }
fwdstate GetState() const { return m_state; } fwdstate GetState() const { return m_state; }
AMX *GetAmx() const { return m_amx; } AMX *GetAmx() const { return m_amx; }
@ -23,7 +24,7 @@ public:
void Error(int error, const char *fmt, ...); void Error(int error, const char *fmt, ...);
private: private:
int m_index; int m_fwdindex, m_index;
char m_CallbackName[64]; char m_CallbackName[64];
fwdstate m_state; fwdstate m_state;
AMX *m_amx; AMX *m_amx;
@ -43,7 +44,7 @@ public:
} }
CAmxxHookUnique(AMX *amx, const char *funcname, int index, T *data = nullptr) : CAmxxHookUnique(AMX *amx, const char *funcname, int index, T *data = nullptr) :
CAmxxHookBase(amx, funcname, index), CAmxxHookBase(amx, funcname, index, -1),
m_uniqueData(data) m_uniqueData(data)
{ {

View File

@ -30,9 +30,9 @@ public:
if (data->m_entity == pEntity && data->m_callbackType == type) if (data->m_entity == pEntity && data->m_callbackType == type)
{ {
if (data->m_iParamLen > 0) { if (data->m_iParamLen > 0) {
g_amxxapi.ExecuteForward(fwd->GetIndex(), args..., g_amxxapi.PrepareCellArrayA(data->m_pParams, data->m_iParamLen, true)); g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), args..., g_amxxapi.PrepareCellArrayA(data->m_pParams, data->m_iParamLen, true));
} else { } else {
g_amxxapi.ExecuteForward(fwd->GetIndex(), args...); g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), args...);
} }
} }
} }

View File

@ -122,11 +122,15 @@ struct hookctx_t
return fatalErr; return fatalErr;
} }
void SetId(int id) { index = id; }
void ResetId() { index = 0; }
void clear_temp_strings() const void clear_temp_strings() const
{ {
s_temp_strings.pop(tempstrings_used); s_temp_strings.pop(tempstrings_used);
} }
int index = 0;
retval_t retVal = {false,ATYPE_INTEGER}; retval_t retVal = {false,ATYPE_INTEGER};
size_t tempstrings_used = 0; size_t tempstrings_used = 0;
@ -156,7 +160,9 @@ NOINLINE void DLLEXPORT _callVoidForward(hook_t* hook, original_t original, f_ar
{ {
if (likely(fwd->GetState() == FSTATE_ENABLED)) if (likely(fwd->GetState() == FSTATE_ENABLED))
{ {
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...); hookCtx->SetId(fwd->GetIndex()); // set current handler hook
auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward<f_args &&>(args)...);
hookCtx->ResetId();
if (unlikely(ret == HC_BREAK)) { if (unlikely(ret == HC_BREAK)) {
return; return;
@ -178,7 +184,9 @@ NOINLINE void DLLEXPORT _callVoidForward(hook_t* hook, original_t original, f_ar
{ {
if (likely(fwd->GetState() == FSTATE_ENABLED)) if (likely(fwd->GetState() == FSTATE_ENABLED))
{ {
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...); hookCtx->SetId(fwd->GetIndex()); // set current handler hook
auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward<f_args &&>(args)...);
hookCtx->ResetId();
if (unlikely(ret == HC_BREAK)) if (unlikely(ret == HC_BREAK))
break; break;
@ -217,7 +225,9 @@ NOINLINE R DLLEXPORT _callForward(hook_t* hook, original_t original, f_args&&...
{ {
if (likely(fwd->GetState() == FSTATE_ENABLED)) if (likely(fwd->GetState() == FSTATE_ENABLED))
{ {
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...); hookCtx->SetId(fwd->GetIndex()); // set current handler hook
auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward<f_args &&>(args)...);
hookCtx->ResetId();
if (unlikely(ret != HC_SUPERCEDE && ret != HC_BREAK)) { if (unlikely(ret != HC_SUPERCEDE && ret != HC_BREAK)) {
continue; continue;
@ -264,7 +274,9 @@ NOINLINE R DLLEXPORT _callForward(hook_t* hook, original_t original, f_args&&...
{ {
if (likely(fwd->GetState() == FSTATE_ENABLED)) if (likely(fwd->GetState() == FSTATE_ENABLED))
{ {
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward<f_args &&>(args)...); hookCtx->SetId(fwd->GetIndex()); // set current handler hook
auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward<f_args &&>(args)...);
hookCtx->ResetId();
if (unlikely(ret == HC_BREAK)) if (unlikely(ret == HC_BREAK))
break; break;

View File

@ -13,9 +13,11 @@ int CHookManager::addHandler(AMX *amx, int func, const char *funcname, int forwa
} }
auto& dest = post ? hook->post : hook->pre; auto& dest = post ? hook->post : hook->pre;
dest.push_back(new CAmxxHookBase(amx, funcname, forward)); int i = func * MAX_HOOK_FORWARDS + dest.size() + 1;
int id = func * MAX_HOOK_FORWARDS + dest.size(); int index = post ? -i : i; // use unsigned ids for post hooks
return post ? -id : id; // use unsigned ids for post hooks
dest.push_back(new CAmxxHookBase(amx, funcname, forward, index));
return index;
} }
void CHookManager::Clear() const void CHookManager::Clear() const

View File

@ -346,6 +346,24 @@ cell AMX_NATIVE_CALL IsReapiHookOriginalWasCalled(AMX* amx, cell* params)
return hook->wasCalled ? TRUE : FALSE; return hook->wasCalled ? TRUE : FALSE;
} }
/*
* Returns the current hookchain handle.
*
* @return Returns the hook handle
*
* native HookChain:GetCurrentHookChainHandle();
*/
cell AMX_NATIVE_CALL GetCurrentHookChainHandle(AMX* amx, cell* params)
{
if (unlikely(!g_hookCtx))
{
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get handle without active hook.", __FUNCTION__);
return FALSE;
}
return g_hookCtx->index;
}
AMX_NATIVE_INFO HookChain_Natives[] = AMX_NATIVE_INFO HookChain_Natives[] =
{ {
{ "RegisterHookChain", RegisterHookChain }, { "RegisterHookChain", RegisterHookChain },
@ -360,6 +378,8 @@ AMX_NATIVE_INFO HookChain_Natives[] =
{ "IsReapiHookOriginalWasCalled", IsReapiHookOriginalWasCalled }, { "IsReapiHookOriginalWasCalled", IsReapiHookOriginalWasCalled },
{ "GetCurrentHookChainHandle", GetCurrentHookChainHandle },
{ nullptr, nullptr } { nullptr, nullptr }
}; };