2
0
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:
asmodai 2016-04-13 19:55:25 +03:00
parent 219071fb50
commit 59be98fb6a
10 changed files with 154 additions and 91 deletions

View File

@ -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)

View File

@ -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>

View File

@ -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;

View File

@ -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());
} }

View File

@ -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);

View File

@ -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);

View File

@ -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[];

View File

@ -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);

View File

@ -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[] =

View File

@ -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[] =