Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 11 commits into from
Oct 25, 2020
7 changes: 7 additions & 0 deletions reapi/extra/amxmodx/scripting/include/reapi.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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 a current hookchain handle.
afwn90cj93201nixr2e1re marked this conversation as resolved.
Show resolved Hide resolved
*
* @return Returns a hook handle
*/
native HookChain:GetHookChainHandle();

/*
* Compares the entity to a specified classname.
* @note This native also checks the validity of an entity.
Expand Down
9 changes: 5 additions & 4 deletions reapi/src/amx_hook.cpp
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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;
}
}

Expand Down
7 changes: 4 additions & 3 deletions reapi/src/amx_hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -23,7 +24,7 @@ class CAmxxHookBase
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;
Expand All @@ -43,7 +44,7 @@ class CAmxxHookUnique: public CAmxxHookBase
}

CAmxxHookUnique(AMX *amx, const char *funcname, int index, T *data = nullptr) :
CAmxxHookBase(amx, funcname, index),
CAmxxHookBase(amx, funcname, index, -1),
m_uniqueData(data)
{

Expand Down
4 changes: 2 additions & 2 deletions reapi/src/entity_callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ class CEntityCallback
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...);
}
}
}
Expand Down
20 changes: 16 additions & 4 deletions reapi/src/hook_callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<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)) {
return;
Expand All @@ -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<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))
break;
Expand Down Expand Up @@ -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<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)) {
continue;
Expand Down Expand Up @@ -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<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))
break;
Expand Down
8 changes: 5 additions & 3 deletions reapi/src/hook_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions reapi/src/natives/natives_hookchains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,24 @@ cell AMX_NATIVE_CALL IsReapiHookOriginalWasCalled(AMX* amx, cell* params)
return hook->wasCalled ? TRUE : FALSE;
}

/*
* Returns a current hookchain handle.
*
* @return Returns a hook handle
*
* native HookChain:GetHookChainHandle();
*/
cell AMX_NATIVE_CALL GetHookChainHandle(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 },
Expand All @@ -360,6 +378,8 @@ AMX_NATIVE_INFO HookChain_Natives[] =

{ "IsReapiHookOriginalWasCalled", IsReapiHookOriginalWasCalled },

{ "GetHookChainHandle", GetHookChainHandle },

{ nullptr, nullptr }
};

Expand Down