mirror of
https://github.com/rehlds/reapi.git
synced 2024-12-29 08:05:36 +03:00
Callbacks refactoring
Implemented hookchain arguments changing
This commit is contained in:
parent
219071fb50
commit
59be98fb6a
@ -45,7 +45,7 @@ void setupToolchain(NativeBinarySpec b) {
|
|||||||
pchHeader: 'precompiled.h',
|
pchHeader: 'precompiled.h',
|
||||||
pchSourceSet: 'reapi_pch'
|
pchSourceSet: 'reapi_pch'
|
||||||
)
|
)
|
||||||
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF', '/GR-'
|
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF', '/GR-', '/GS-'
|
||||||
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
|
||||||
cfg.extraLibs 'ws2_32.lib'
|
cfg.extraLibs 'ws2_32.lib'
|
||||||
} else if (cfg instanceof GccToolchainConfig) {
|
} else if (cfg instanceof GccToolchainConfig) {
|
||||||
@ -61,7 +61,7 @@ void setupToolchain(NativeBinarySpec b) {
|
|||||||
'_snprintf': 'snprintf'
|
'_snprintf': 'snprintf'
|
||||||
])
|
])
|
||||||
|
|
||||||
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fp-model fast', '-fomit-frame-pointer', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s'
|
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fp-model fast=2', '-fomit-frame-pointer', '-inline-forceinline', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s'
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolchainConfigUtils.apply(project, cfg, b)
|
ToolchainConfigUtils.apply(project, cfg, b)
|
||||||
|
@ -361,6 +361,7 @@
|
|||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
|
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -494,7 +494,7 @@ extern amxxapi_t g_amxxapi;
|
|||||||
|
|
||||||
void MF_Log(const char *fmt, ...);
|
void MF_Log(const char *fmt, ...);
|
||||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
||||||
char* getAmxStringTemp(cell* src, char* dest, size_t max, size_t* len);
|
char* getAmxStringTemp(cell* src, char* dest, size_t max, size_t* len = nullptr);
|
||||||
void setAmxString(cell* dest, const char* string, size_t max);
|
void setAmxString(cell* dest, const char* string, size_t max);
|
||||||
|
|
||||||
inline cell* getAmxAddr(AMX *amx, cell amx_addr)
|
inline cell* getAmxAddr(AMX *amx, cell amx_addr)
|
||||||
@ -504,11 +504,16 @@ inline cell* getAmxAddr(AMX *amx, cell amx_addr)
|
|||||||
|
|
||||||
struct getAmxString
|
struct getAmxString
|
||||||
{
|
{
|
||||||
getAmxString(cell* src, size_t* len)
|
getAmxString(cell* src, size_t* len = nullptr)
|
||||||
{
|
{
|
||||||
getAmxStringTemp(src, temp, sizeof temp - 1, len);
|
getAmxStringTemp(src, temp, sizeof temp - 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAmxString(AMX* amx, cell addr, size_t* len = nullptr)
|
||||||
|
{
|
||||||
|
getAmxString(getAmxAddr(amx, addr), len);
|
||||||
|
}
|
||||||
|
|
||||||
operator char *()
|
operator char *()
|
||||||
{
|
{
|
||||||
return temp;
|
return temp;
|
||||||
|
@ -246,6 +246,7 @@ void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain,
|
|||||||
{
|
{
|
||||||
chain->callNext();
|
chain->callNext();
|
||||||
};
|
};
|
||||||
|
|
||||||
callVoidForward(RH_CBasePlayer_ImpulseCommands, original, pthis->entindex());
|
callVoidForward(RH_CBasePlayer_ImpulseCommands, original, pthis->entindex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,18 +39,17 @@ inline AType getApiType(float) { return ATYPE_FLOAT; }
|
|||||||
inline AType getApiType(const char *) { return ATYPE_STRING; }
|
inline AType getApiType(const char *) { return ATYPE_STRING; }
|
||||||
inline AType getApiType(CBaseEntity *) { return ATYPE_CLASSPTR; }
|
inline AType getApiType(CBaseEntity *) { return ATYPE_CLASSPTR; }
|
||||||
|
|
||||||
|
#define MAX_ARGS 12u
|
||||||
|
|
||||||
template<size_t current>
|
template<size_t current>
|
||||||
void setupArgTypes(AType args_type[])
|
void setupArgTypes(AType args_type[MAX_ARGS])
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_ARGS 10u
|
|
||||||
|
|
||||||
template<size_t current = 0, typename T, typename ...t_args>
|
template<size_t current = 0, typename T, typename ...t_args>
|
||||||
void setupArgTypes(AType args_type[MAX_ARGS], T arg, t_args... args)
|
void setupArgTypes(AType args_type[MAX_ARGS], T arg, t_args... args)
|
||||||
{
|
{
|
||||||
args_type[current] = getApiType(arg);
|
args_type[current] = getApiType(T());
|
||||||
if (sizeof...(args) && current + 1 < MAX_ARGS)
|
if (sizeof...(args) && current + 1 < MAX_ARGS)
|
||||||
setupArgTypes<current + 1>(args_type, args...);
|
setupArgTypes<current + 1>(args_type, args...);
|
||||||
}
|
}
|
||||||
@ -58,13 +57,19 @@ void setupArgTypes(AType args_type[MAX_ARGS], T arg, t_args... args)
|
|||||||
struct hookctx_t
|
struct hookctx_t
|
||||||
{
|
{
|
||||||
template<typename ...t_args>
|
template<typename ...t_args>
|
||||||
hookctx_t(size_t count, size_t ptr, t_args... args)
|
hookctx_t(size_t arg_count, t_args... args) : args_ptr()
|
||||||
{
|
{
|
||||||
args_count = min(count, MAX_ARGS);
|
args_count = min(arg_count, MAX_ARGS);
|
||||||
args_ptr = ptr;
|
|
||||||
setupArgTypes(args_type, args...);
|
setupArgTypes(args_type, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset(size_t arg_ptr, AType ret_type = ATYPE_INTEGER)
|
||||||
|
{
|
||||||
|
retVal.set = false;
|
||||||
|
retVal.type = ret_type;
|
||||||
|
args_ptr = arg_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
retval_t retVal;
|
retval_t retVal;
|
||||||
size_t args_count;
|
size_t args_count;
|
||||||
size_t args_ptr;
|
size_t args_ptr;
|
||||||
@ -73,15 +78,26 @@ struct hookctx_t
|
|||||||
|
|
||||||
extern hookctx_t* g_hookCtx;
|
extern hookctx_t* g_hookCtx;
|
||||||
|
|
||||||
template <typename original_t, typename ...f_args>
|
#pragma optimize("ts", on)
|
||||||
void callVoidForward(int func, original_t original, f_args... args)
|
|
||||||
{
|
|
||||||
hookctx_t hookCtx(sizeof...(args), size_t(&original) + sizeof(original), args...);
|
|
||||||
hookCtx.retVal.set = false;
|
|
||||||
g_hookCtx = &hookCtx;
|
|
||||||
|
|
||||||
|
template <typename original_t, typename ...f_args>
|
||||||
|
void callVoidForward(size_t func, original_t original, f_args... args)
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
static
|
||||||
|
#endif
|
||||||
|
hookctx_t hookCtx(sizeof...(args), args...);
|
||||||
|
|
||||||
|
g_hookCtx = &hookCtx;
|
||||||
|
_callVoidForward(g_hookManager.getHook(func), original, args...);
|
||||||
|
g_hookCtx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename original_t, typename ...f_args>
|
||||||
|
NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original, volatile f_args... args)
|
||||||
|
{
|
||||||
|
g_hookCtx->reset(size_t(&original) + sizeof(original));
|
||||||
int hc_state = HC_CONTINUE;
|
int hc_state = HC_CONTINUE;
|
||||||
auto hook = g_hookManager.getHook(func);
|
|
||||||
|
|
||||||
for (auto& fwd : hook->pre)
|
for (auto& fwd : hook->pre)
|
||||||
{
|
{
|
||||||
@ -90,7 +106,6 @@ void callVoidForward(int func, original_t original, f_args... args)
|
|||||||
auto ret = g_amxxapi.ExecuteForward(fwd->m_forward, args...);
|
auto ret = g_amxxapi.ExecuteForward(fwd->m_forward, args...);
|
||||||
|
|
||||||
if (ret == HC_BREAK) {
|
if (ret == HC_BREAK) {
|
||||||
g_hookCtx = nullptr;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,20 +127,29 @@ void callVoidForward(int func, original_t original, f_args... args)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hookCtx = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename original_t, typename ...f_args>
|
template <typename R, typename original_t, typename ...f_args>
|
||||||
R callForward(int func, original_t original, f_args... args)
|
R callForward(size_t func, original_t original, f_args... args)
|
||||||
{
|
{
|
||||||
hookctx_t hookCtx(sizeof...(args), size_t(&original) + sizeof(original), args...);
|
#ifndef _WIN32
|
||||||
hookCtx.retVal.set = false;
|
static
|
||||||
hookCtx.retVal.type = getApiType(R());
|
#endif
|
||||||
g_hookCtx = &hookCtx;
|
hookctx_t hookCtx(sizeof...(args), args...);
|
||||||
|
|
||||||
|
g_hookCtx = &hookCtx;
|
||||||
|
auto ret = _callForward<R>(g_hookManager.getHook(func), original, args...);
|
||||||
|
g_hookCtx = nullptr;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename R, typename original_t, typename ...f_args>
|
||||||
|
NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volatile f_args... args)
|
||||||
|
{
|
||||||
|
auto& hookCtx = *g_hookCtx;
|
||||||
|
hookCtx.reset(size_t(&original) + sizeof(original), getApiType(R()));
|
||||||
int hc_state = HC_CONTINUE;
|
int hc_state = HC_CONTINUE;
|
||||||
auto hook = g_hookManager.getHook(func);
|
|
||||||
|
|
||||||
for (auto& fwd : hook->pre)
|
for (auto& fwd : hook->pre)
|
||||||
{
|
{
|
||||||
@ -136,15 +160,13 @@ R callForward(int func, original_t original, f_args... args)
|
|||||||
if (ret == HC_CONTINUE)
|
if (ret == HC_CONTINUE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!hookCtx.retVal.set)
|
if (!hookCtx.retVal.set) {
|
||||||
{
|
|
||||||
g_amxxapi.LogError(fwd->GetAmx(), AMX_ERR_CALLBACK, "%s", "can't suppress original function call without new return value set");
|
g_amxxapi.LogError(fwd->GetAmx(), AMX_ERR_CALLBACK, "%s", "can't suppress original function call without new return value set");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == HC_BREAK) {
|
if (ret == HC_BREAK) {
|
||||||
g_hookCtx = nullptr;
|
return *(R *)&hookCtx.retVal._interger;
|
||||||
return (R)hookCtx.retVal._interger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret > hc_state)
|
if (ret > hc_state)
|
||||||
@ -169,10 +191,11 @@ R callForward(int func, original_t original, f_args... args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hookCtx = nullptr;
|
return *(R *)&hookCtx.retVal._interger;
|
||||||
return (R)hookCtx.retVal._interger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma optimize("", on)
|
||||||
|
|
||||||
// rehlds functions
|
// rehlds functions
|
||||||
void SV_StartSound(IRehldsHook_SV_StartSound *chain, int recipients, edict_t *entity, int channel, const char *sample, int volume, float attenuation, int fFlags, int pitch);
|
void SV_StartSound(IRehldsHook_SV_StartSound *chain, int recipients, edict_t *entity, int channel, const char *sample, int volume, float attenuation, int fFlags, int pitch);
|
||||||
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt);
|
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt);
|
||||||
|
@ -41,7 +41,7 @@ hook_t hooklist_player[] = {
|
|||||||
DLL(CBasePlayer_Observer_IsValidTarget),
|
DLL(CBasePlayer_Observer_IsValidTarget),
|
||||||
};
|
};
|
||||||
|
|
||||||
hook_t *hooklist_t::operator[](size_t hook) const
|
/*hook_t *hooklist_t::getHook(size_t hook)
|
||||||
{
|
{
|
||||||
#define CASE(h) case ht_##h: if (index < arraysize(hooklist_##h)) return &hooklist_##h[index]; else break;
|
#define CASE(h) case ht_##h: if (index < arraysize(hooklist_##h)) return &hooklist_##h[index]; else break;
|
||||||
|
|
||||||
@ -55,4 +55,8 @@ hook_t *hooklist_t::operator[](size_t hook) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
const size_t hooklist_engine_size = arraysize(hooklist_engine);
|
||||||
|
const size_t hooklist_gamedll_size = arraysize(hooklist_gamedll);
|
||||||
|
const size_t hooklist_player_size = arraysize(hooklist_player);
|
||||||
|
@ -101,9 +101,42 @@ struct hook_t
|
|||||||
regchain_t unregisterHookchain; // unregister re* API hook
|
regchain_t unregisterHookchain; // unregister re* API hook
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern hook_t hooklist_engine[];
|
||||||
|
extern hook_t hooklist_gamedll[];
|
||||||
|
extern hook_t hooklist_player[];
|
||||||
|
extern const size_t hooklist_engine_size;
|
||||||
|
extern const size_t hooklist_gamedll_size;
|
||||||
|
extern const size_t hooklist_player_size;
|
||||||
|
|
||||||
struct hooklist_t
|
struct hooklist_t
|
||||||
{
|
{
|
||||||
hook_t *operator[](size_t hook) const;
|
hook_t *operator[](size_t hook) const
|
||||||
|
{
|
||||||
|
#define CASE(h) case ht_##h: if (index < hooklist_##h##_size) return &hooklist_##h[index]; else break;
|
||||||
|
|
||||||
|
const auto table = hooks_tables_e(hook / MAX_REGION_RANGE);
|
||||||
|
const auto index = hook & (MAX_REGION_RANGE - 1);
|
||||||
|
|
||||||
|
switch (table) {
|
||||||
|
CASE(engine)
|
||||||
|
CASE(gamedll)
|
||||||
|
CASE(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
/*const auto table = hooks_tables_e(hook / MAX_REGION_RANGE);
|
||||||
|
const auto index = hook & (MAX_REGION_RANGE - 1);
|
||||||
|
|
||||||
|
switch (table) {
|
||||||
|
case ht_engine: return &hooklist_engine[index];
|
||||||
|
case ht_gamedll: return &hooklist_gamedll[index];
|
||||||
|
case ht_player: return &hooklist_player[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//static hook_t *getHook(size_t hook);
|
||||||
|
|
||||||
enum hooks_tables_e
|
enum hooks_tables_e
|
||||||
{
|
{
|
||||||
@ -197,6 +230,3 @@ enum GamedllFunc_CBasePlayer
|
|||||||
// [...]
|
// [...]
|
||||||
RH_CBasePlayer_End
|
RH_CBasePlayer_End
|
||||||
};
|
};
|
||||||
|
|
||||||
extern hook_t hooklist_engine[];
|
|
||||||
extern hook_t hooklist_player[];
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
struct regmember
|
struct regmember
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
regmember(T &type, size_t maxsize, size_t offset, enum_membertypes member_type)
|
regmember(T& type, size_t maxsize, size_t offset, enum_membertypes member_type)
|
||||||
{
|
{
|
||||||
member.size = sizeof(T);
|
member.size = sizeof(T);
|
||||||
member.max_size = sizeof(T);
|
member.max_size = sizeof(T);
|
||||||
|
@ -32,8 +32,8 @@ static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int funcid, len;
|
int funcid;
|
||||||
const char *funcname = g_amxxapi.GetAmxString(amx, params[arg_handler], 0, &len);
|
const char *funcname = getAmxString(amx, params[arg_handler]);
|
||||||
if (g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)
|
if (g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: public function \"%s\" not found.", funcname);
|
MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: public function \"%s\" not found.", funcname);
|
||||||
@ -69,11 +69,11 @@ static cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params)
|
|||||||
if (hook == nullptr)
|
if (hook == nullptr)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "EnableHookChain: invalid HookChain handle.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "EnableHookChain: invalid HookChain handle.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->m_state = FSTATE_ENABLED;
|
hook->m_state = FSTATE_ENABLED;
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -94,11 +94,11 @@ static cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params)
|
|||||||
if (hook == nullptr)
|
if (hook == nullptr)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "DisableHookChain: invalid HookChain handle.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "DisableHookChain: invalid HookChain handle.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->m_state = FSTATE_STOPPED;
|
hook->m_state = FSTATE_STOPPED;
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -116,7 +116,7 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params)
|
|||||||
if (!g_hookCtx)
|
if (!g_hookCtx)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set return value without active hook.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set return value without active hook.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum args_e { arg_count, arg_type, arg_value };
|
enum args_e { arg_count, arg_type, arg_value };
|
||||||
@ -125,7 +125,7 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params)
|
|||||||
if (params[arg_type] != retVal.type)
|
if (params[arg_type] != retVal.type)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set incompatible return type.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set incompatible return type.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
||||||
@ -151,11 +151,11 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params)
|
|||||||
retVal._classptr = CBaseEntity::Instance(INDEXENT(*srcAddr));
|
retVal._classptr = CBaseEntity::Instance(INDEXENT(*srcAddr));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal.set = true;
|
retVal.set = true;
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -174,7 +174,7 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
|
|||||||
if (!g_hookCtx)
|
if (!g_hookCtx)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum args_e { arg_count, arg_value, arg_maxlen };
|
enum args_e { arg_count, arg_value, arg_maxlen };
|
||||||
@ -191,7 +191,7 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
|
|||||||
case ATYPE_STRING:
|
case ATYPE_STRING:
|
||||||
{
|
{
|
||||||
if (params[arg_count] != 2)
|
if (params[arg_count] != 2)
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
setAmxString(dstAddr, retVal._string, params[arg_maxlen]);
|
setAmxString(dstAddr, retVal._string, params[arg_maxlen]);
|
||||||
break;
|
break;
|
||||||
@ -200,10 +200,10 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
|
|||||||
*dstAddr = retVal._classptr->entindex();
|
*dstAddr = retVal._classptr->entindex();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -223,17 +223,16 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
if (!g_hookCtx)
|
if (!g_hookCtx)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum args_e { arg_count, arg_number, arg_type, arg_value };
|
enum args_e { arg_count, arg_number, arg_type, arg_value };
|
||||||
|
|
||||||
size_t number = params[arg_number] - 1;
|
size_t number = params[arg_number] - 1;
|
||||||
|
|
||||||
if (number >= g_hookCtx->args_count)
|
if (number >= g_hookCtx->args_count)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: can't set argument %i of hookchain with %i args.", params[arg_number], g_hookCtx->args_count);
|
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: can't set argument %i of hookchain with %i args.", params[arg_number], g_hookCtx->args_count);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
AType type = g_hookCtx->args_type[number];
|
AType type = g_hookCtx->args_type[number];
|
||||||
@ -241,7 +240,7 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
if (params[arg_type] != type)
|
if (params[arg_type] != type)
|
||||||
{
|
{
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: invalid argument type provided.");
|
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: invalid argument type provided.");
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char temp_strings[MAX_ARGS][1024];
|
static char temp_strings[MAX_ARGS][1024];
|
||||||
@ -256,14 +255,14 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
*(cell *)destAddr = *srcAddr;
|
*(cell *)destAddr = *srcAddr;
|
||||||
break;
|
break;
|
||||||
case ATYPE_STRING:
|
case ATYPE_STRING:
|
||||||
*(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], 1023, nullptr);
|
*(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], 1023);
|
||||||
break;
|
break;
|
||||||
case ATYPE_CLASSPTR:
|
case ATYPE_CLASSPTR:
|
||||||
*(CBaseEntity **)destAddr = CBaseEntity::Instance(INDEXENT(*srcAddr));
|
*(CBaseEntity **)destAddr = CBaseEntity::Instance(INDEXENT(*srcAddr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO Func_Natives[] =
|
AMX_NATIVE_INFO Func_Natives[] =
|
||||||
|
@ -8,13 +8,13 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
|||||||
|
|
||||||
if (member == nullptr) {
|
if (member == nullptr) {
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "set_member: unknown member id %i", params[arg_member]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "set_member: unknown member id %i", params[arg_member]);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
edict_t *pEdict = INDEXENT(params[arg_index]);
|
edict_t *pEdict = INDEXENT(params[arg_index]);
|
||||||
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "set_member: invalid or uninitialized entity", params[arg_member]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "set_member: invalid or uninitialized entity", params[arg_member]);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell* value = getAmxAddr(amx, params[arg_value]);
|
cell* value = getAmxAddr(amx, params[arg_value]);
|
||||||
@ -23,7 +23,7 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
|||||||
switch (member->type)
|
switch (member->type)
|
||||||
{
|
{
|
||||||
case MEMBER_ENTITY:
|
case MEMBER_ENTITY:
|
||||||
return -1;
|
return FALSE;
|
||||||
case MEMBER_CLASSPTR:
|
case MEMBER_CLASSPTR:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, _value, _elem);
|
// native set_member(_index, any:_member, _value, _elem);
|
||||||
@ -34,7 +34,7 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
|||||||
pEntity = CBaseEntity::Instance(pEdictValue);
|
pEntity = CBaseEntity::Instance(pEdictValue);
|
||||||
}
|
}
|
||||||
set_member<CBaseEntity *>(pEdict, member->offset, pEntity, element);
|
set_member<CBaseEntity *>(pEdict, member->offset, pEntity, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_EHANDLE:
|
case MEMBER_EHANDLE:
|
||||||
{
|
{
|
||||||
@ -42,23 +42,23 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
|||||||
EHANDLE& ehandle = get_member<EHANDLE>(pEdict, member->offset, element);
|
EHANDLE& ehandle = get_member<EHANDLE>(pEdict, member->offset, element);
|
||||||
edict_t *pEdictValue = INDEXENT(*value);
|
edict_t *pEdictValue = INDEXENT(*value);
|
||||||
ehandle.Set(pEdictValue);
|
ehandle.Set(pEdictValue);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_EVARS:
|
case MEMBER_EVARS:
|
||||||
return -1;
|
return FALSE;
|
||||||
case MEMBER_EDICT:
|
case MEMBER_EDICT:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, _value, _elem);
|
// native set_member(_index, any:_member, _value, _elem);
|
||||||
edict_t *pEdictValue = INDEXENT(*value);
|
edict_t *pEdictValue = INDEXENT(*value);
|
||||||
set_member<edict_t *>(pEdict, member->offset, pEdictValue, element);
|
set_member<edict_t *>(pEdict, member->offset, pEdictValue, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_VECTOR:
|
case MEMBER_VECTOR:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, Float:_value[3], _elem);
|
// native set_member(_index, any:_member, Float:_value[3], _elem);
|
||||||
Vector *pSource = (Vector *)getAmxAddr(amx, params[arg_value]);
|
Vector *pSource = (Vector *)getAmxAddr(amx, params[arg_value]);
|
||||||
set_member<Vector>(pEdict, member->offset, *pSource, element);
|
set_member<Vector>(pEdict, member->offset, *pSource, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_CHAR_ARRAY:
|
case MEMBER_CHAR_ARRAY:
|
||||||
{
|
{
|
||||||
@ -68,7 +68,7 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
|||||||
char *dest = get_member_direct<char *>(pEdict, member->offset);
|
char *dest = get_member_direct<char *>(pEdict, member->offset);
|
||||||
strncpy(dest, source, member->max_size - 1);
|
strncpy(dest, source, member->max_size - 1);
|
||||||
dest[member->max_size - 1] = '\0';
|
dest[member->max_size - 1] = '\0';
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_CHAR_POINTER:
|
case MEMBER_CHAR_POINTER:
|
||||||
{
|
{
|
||||||
@ -85,51 +85,51 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
|||||||
strcpy(dest, source);
|
strcpy(dest, source);
|
||||||
|
|
||||||
set_member<char *>(pEdict, member->offset, dest);
|
set_member<char *>(pEdict, member->offset, dest);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_FLOAT:
|
case MEMBER_FLOAT:
|
||||||
case MEMBER_INTEGER:
|
case MEMBER_INTEGER:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, any:_value, _elem);
|
// native set_member(_index, any:_member, any:_value, _elem);
|
||||||
set_member<int>(pEdict, member->offset, *value, element);
|
set_member<int>(pEdict, member->offset, *value, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_SHORT:
|
case MEMBER_SHORT:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, _value, _elem);
|
// native set_member(_index, any:_member, _value, _elem);
|
||||||
set_member<short>(pEdict, member->offset, *value, element);
|
set_member<short>(pEdict, member->offset, *value, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_BYTE:
|
case MEMBER_BYTE:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, _value, _elem);
|
// native set_member(_index, any:_member, _value, _elem);
|
||||||
set_member<byte>(pEdict, member->offset, *value, element);
|
set_member<byte>(pEdict, member->offset, *value, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_BOOL:
|
case MEMBER_BOOL:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, bool:_value, _elem);
|
// native set_member(_index, any:_member, bool:_value, _elem);
|
||||||
set_member<bool>(pEdict, member->offset, *value != 0, element);
|
set_member<bool>(pEdict, member->offset, *value != 0, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_SIGNALS:
|
case MEMBER_SIGNALS:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, _value);
|
// native set_member(_index, any:_member, _value);
|
||||||
CUnifiedSignals& signal = get_member<CUnifiedSignals>(pEdict, member->offset, element);
|
CUnifiedSignals& signal = get_member<CUnifiedSignals>(pEdict, member->offset, element);
|
||||||
signal.Signal(*value);
|
signal.Signal(*value);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEMBER_DOUBLE:
|
case MEMBER_DOUBLE:
|
||||||
{
|
{
|
||||||
// native set_member(_index, any:_member, any:_value, _elem);
|
// native set_member(_index, any:_member, any:_value, _elem);
|
||||||
set_member<double>(pEdict, member->offset, *(float *)value, element);
|
set_member<double>(pEdict, member->offset, *(float *)value, element);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case MEBMER_REBUYSTRUCT:
|
case MEBMER_REBUYSTRUCT:
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// native any:get_member(_index = 0, any:_member, any:...);
|
// native any:get_member(_index = 0, any:_member, any:...);
|
||||||
@ -140,13 +140,13 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
|||||||
|
|
||||||
if (member == nullptr) {
|
if (member == nullptr) {
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
edict_t *pEdict = INDEXENT(params[arg_index]);
|
edict_t *pEdict = INDEXENT(params[arg_index]);
|
||||||
|
|
||||||
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
||||||
@ -154,7 +154,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
|||||||
switch (member->type)
|
switch (member->type)
|
||||||
{
|
{
|
||||||
case MEMBER_ENTITY:
|
case MEMBER_ENTITY:
|
||||||
return -1;
|
return FALSE;
|
||||||
case MEMBER_CLASSPTR:
|
case MEMBER_CLASSPTR:
|
||||||
// native any:get_member(_index, any:_member, element);
|
// native any:get_member(_index, any:_member, element);
|
||||||
return get_member<CBaseEntity *>(pEdict, member->offset, element)->entindex();
|
return get_member<CBaseEntity *>(pEdict, member->offset, element)->entindex();
|
||||||
@ -166,7 +166,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
|||||||
if (pEntity != nullptr) {
|
if (pEntity != nullptr) {
|
||||||
return ((CBaseEntity *)ehandle)->entindex();
|
return ((CBaseEntity *)ehandle)->entindex();
|
||||||
}
|
}
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
case MEMBER_EVARS:
|
case MEMBER_EVARS:
|
||||||
return -1;
|
return -1;
|
||||||
@ -178,7 +178,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
|||||||
return indexOfEdict(pEntity);
|
return indexOfEdict(pEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
case MEMBER_VECTOR:
|
case MEMBER_VECTOR:
|
||||||
{
|
{
|
||||||
@ -207,7 +207,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
|||||||
g_amxxapi.SetAmxString(amx, params[3], dest, *g_amxxapi.GetAmxAddr(amx, params[4]));
|
g_amxxapi.SetAmxString(amx, params[3], dest, *g_amxxapi.GetAmxAddr(amx, params[4]));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
case MEMBER_FLOAT:
|
case MEMBER_FLOAT:
|
||||||
case MEMBER_INTEGER:
|
case MEMBER_INTEGER:
|
||||||
@ -244,7 +244,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// native set_member_game(any:_member, any:...);
|
// native set_member_game(any:_member, any:...);
|
||||||
@ -255,7 +255,7 @@ static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params)
|
|||||||
|
|
||||||
if (member == nullptr) {
|
if (member == nullptr) {
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t value = *g_amxxapi.GetAmxAddr(amx, params[arg_value]);
|
size_t value = *g_amxxapi.GetAmxAddr(amx, params[arg_value]);
|
||||||
@ -273,7 +273,7 @@ static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params)
|
|||||||
case MEMBER_BYTE:
|
case MEMBER_BYTE:
|
||||||
case MEMBER_SIGNALS:
|
case MEMBER_SIGNALS:
|
||||||
case MEBMER_REBUYSTRUCT:
|
case MEBMER_REBUYSTRUCT:
|
||||||
return -1;
|
return FALSE;
|
||||||
case MEMBER_CLASSPTR:
|
case MEMBER_CLASSPTR:
|
||||||
{
|
{
|
||||||
// native set_member_game(any:_member, _value, _elem);
|
// native set_member_game(any:_member, _value, _elem);
|
||||||
@ -313,7 +313,7 @@ static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// native get_member_game(any:_member, any:...);
|
// native get_member_game(any:_member, any:...);
|
||||||
@ -324,7 +324,7 @@ static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params)
|
|||||||
|
|
||||||
if (member == nullptr) {
|
if (member == nullptr) {
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
||||||
@ -370,7 +370,7 @@ static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO Member_Natives[] =
|
AMX_NATIVE_INFO Member_Natives[] =
|
||||||
|
Loading…
Reference in New Issue
Block a user