diff --git a/reapi/extra/amxmodx/scripting/include/reapi.inc b/reapi/extra/amxmodx/scripting/include/reapi.inc index d3c0dec..2a796c3 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi.inc @@ -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); +/* +* Returns the current hookchain handle. +* +* @return Returns the hook handle +*/ +native HookChain:GetCurrentHookChainHandle(); + /* * Compares the entity to a specified classname. * @note This native also checks the validity of an entity. diff --git a/reapi/src/amx_hook.cpp b/reapi/src/amx_hook.cpp index 59fbb26..29c29c9 100644 --- a/reapi/src/amx_hook.cpp +++ b/reapi/src/amx_hook.cpp @@ -1,6 +1,7 @@ #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_state(FSTATE_ENABLED), m_amx(amx) @@ -10,10 +11,10 @@ CAmxxHookBase::CAmxxHookBase(AMX *amx, const char *funcname, int index) : CAmxxHookBase::~CAmxxHookBase() { - if (m_index != -1) + if (m_fwdindex != -1) { - g_amxxapi.UnregisterSPForward(m_index); - m_index = -1; + g_amxxapi.UnregisterSPForward(m_fwdindex); + m_fwdindex = -1; } } diff --git a/reapi/src/amx_hook.h b/reapi/src/amx_hook.h index a43fae3..8b84a35 100644 --- a/reapi/src/amx_hook.h +++ b/reapi/src/amx_hook.h @@ -12,8 +12,9 @@ class CAmxxHookBase { public: ~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; } fwdstate GetState() const { return m_state; } AMX *GetAmx() const { return m_amx; } @@ -23,7 +24,7 @@ public: void Error(int error, const char *fmt, ...); private: - int m_index; + int m_fwdindex, m_index; char m_CallbackName[64]; fwdstate m_state; AMX *m_amx; @@ -43,7 +44,7 @@ public: } CAmxxHookUnique(AMX *amx, const char *funcname, int index, T *data = nullptr) : - CAmxxHookBase(amx, funcname, index), + CAmxxHookBase(amx, funcname, index, -1), m_uniqueData(data) { diff --git a/reapi/src/entity_callback.h b/reapi/src/entity_callback.h index b9fb720..6220259 100644 --- a/reapi/src/entity_callback.h +++ b/reapi/src/entity_callback.h @@ -30,9 +30,9 @@ public: if (data->m_entity == pEntity && data->m_callbackType == type) { 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 { - g_amxxapi.ExecuteForward(fwd->GetIndex(), args...); + g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), args...); } } } diff --git a/reapi/src/hook_callback.h b/reapi/src/hook_callback.h index bd8860d..348a50a 100644 --- a/reapi/src/hook_callback.h +++ b/reapi/src/hook_callback.h @@ -122,11 +122,15 @@ struct hookctx_t return fatalErr; } + void SetId(int id) { index = id; } + void ResetId() { index = 0; } + void clear_temp_strings() const { s_temp_strings.pop(tempstrings_used); } + int index = 0; retval_t retVal = {false,ATYPE_INTEGER}; 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)) { - auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward(args)...); + hookCtx->SetId(fwd->GetIndex()); // set current handler hook + auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward(args)...); + hookCtx->ResetId(); if (unlikely(ret == HC_BREAK)) { return; @@ -178,7 +184,9 @@ NOINLINE void DLLEXPORT _callVoidForward(hook_t* hook, original_t original, f_ar { if (likely(fwd->GetState() == FSTATE_ENABLED)) { - auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward(args)...); + hookCtx->SetId(fwd->GetIndex()); // set current handler hook + auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward(args)...); + hookCtx->ResetId(); if (unlikely(ret == HC_BREAK)) break; @@ -217,7 +225,9 @@ NOINLINE R DLLEXPORT _callForward(hook_t* hook, original_t original, f_args&&... { if (likely(fwd->GetState() == FSTATE_ENABLED)) { - auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward(args)...); + hookCtx->SetId(fwd->GetIndex()); // set current handler hook + auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward(args)...); + hookCtx->ResetId(); if (unlikely(ret != HC_SUPERCEDE && ret != HC_BREAK)) { continue; @@ -264,7 +274,9 @@ NOINLINE R DLLEXPORT _callForward(hook_t* hook, original_t original, f_args&&... { if (likely(fwd->GetState() == FSTATE_ENABLED)) { - auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), std::forward(args)...); + hookCtx->SetId(fwd->GetIndex()); // set current handler hook + auto ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), std::forward(args)...); + hookCtx->ResetId(); if (unlikely(ret == HC_BREAK)) break; diff --git a/reapi/src/hook_manager.cpp b/reapi/src/hook_manager.cpp index 4476ccb..a34f959 100644 --- a/reapi/src/hook_manager.cpp +++ b/reapi/src/hook_manager.cpp @@ -13,9 +13,11 @@ int CHookManager::addHandler(AMX *amx, int func, const char *funcname, int forwa } auto& dest = post ? hook->post : hook->pre; - dest.push_back(new CAmxxHookBase(amx, funcname, forward)); - int id = func * MAX_HOOK_FORWARDS + dest.size(); - return post ? -id : id; // use unsigned ids for post hooks + int i = func * MAX_HOOK_FORWARDS + dest.size() + 1; + int index = post ? -i : i; // use unsigned ids for post hooks + + dest.push_back(new CAmxxHookBase(amx, funcname, forward, index)); + return index; } void CHookManager::Clear() const diff --git a/reapi/src/natives/natives_hookchains.cpp b/reapi/src/natives/natives_hookchains.cpp index 4d0aa9a..bb212bc 100644 --- a/reapi/src/natives/natives_hookchains.cpp +++ b/reapi/src/natives/natives_hookchains.cpp @@ -346,6 +346,24 @@ cell AMX_NATIVE_CALL IsReapiHookOriginalWasCalled(AMX* amx, cell* params) 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[] = { { "RegisterHookChain", RegisterHookChain }, @@ -360,6 +378,8 @@ AMX_NATIVE_INFO HookChain_Natives[] = { "IsReapiHookOriginalWasCalled", IsReapiHookOriginalWasCalled }, + { "GetCurrentHookChainHandle", GetCurrentHookChainHandle }, + { nullptr, nullptr } };