mirror of
https://github.com/rehlds/reapi.git
synced 2024-12-28 15:45:31 +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',
|
||||
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.extraLibs 'ws2_32.lib'
|
||||
} else if (cfg instanceof GccToolchainConfig) {
|
||||
@ -61,7 +61,7 @@ void setupToolchain(NativeBinarySpec b) {
|
||||
'_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)
|
||||
|
@ -361,6 +361,7 @@
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -494,7 +494,7 @@ extern amxxapi_t g_amxxapi;
|
||||
|
||||
void MF_Log(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);
|
||||
|
||||
inline cell* getAmxAddr(AMX *amx, cell amx_addr)
|
||||
@ -504,11 +504,16 @@ inline cell* getAmxAddr(AMX *amx, cell amx_addr)
|
||||
|
||||
struct getAmxString
|
||||
{
|
||||
getAmxString(cell* src, size_t* len)
|
||||
getAmxString(cell* src, size_t* len = nullptr)
|
||||
{
|
||||
getAmxStringTemp(src, temp, sizeof temp - 1, len);
|
||||
}
|
||||
|
||||
getAmxString(AMX* amx, cell addr, size_t* len = nullptr)
|
||||
{
|
||||
getAmxString(getAmxAddr(amx, addr), len);
|
||||
}
|
||||
|
||||
operator char *()
|
||||
{
|
||||
return temp;
|
||||
|
@ -246,6 +246,7 @@ void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain,
|
||||
{
|
||||
chain->callNext();
|
||||
};
|
||||
|
||||
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(CBaseEntity *) { return ATYPE_CLASSPTR; }
|
||||
|
||||
#define MAX_ARGS 12u
|
||||
|
||||
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>
|
||||
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)
|
||||
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
|
||||
{
|
||||
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_ptr = ptr;
|
||||
args_count = min(arg_count, MAX_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;
|
||||
size_t args_count;
|
||||
size_t args_ptr;
|
||||
@ -73,15 +78,26 @@ struct hookctx_t
|
||||
|
||||
extern hookctx_t* g_hookCtx;
|
||||
|
||||
template <typename original_t, typename ...f_args>
|
||||
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;
|
||||
#pragma optimize("ts", on)
|
||||
|
||||
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;
|
||||
auto hook = g_hookManager.getHook(func);
|
||||
|
||||
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...);
|
||||
|
||||
if (ret == HC_BREAK) {
|
||||
g_hookCtx = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -112,20 +127,29 @@ void callVoidForward(int func, original_t original, f_args... args)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hookCtx = nullptr;
|
||||
}
|
||||
|
||||
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...);
|
||||
hookCtx.retVal.set = false;
|
||||
hookCtx.retVal.type = getApiType(R());
|
||||
g_hookCtx = &hookCtx;
|
||||
#ifndef _WIN32
|
||||
static
|
||||
#endif
|
||||
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;
|
||||
auto hook = g_hookManager.getHook(func);
|
||||
|
||||
for (auto& fwd : hook->pre)
|
||||
{
|
||||
@ -136,15 +160,13 @@ R callForward(int func, original_t original, f_args... args)
|
||||
if (ret == HC_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");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret == HC_BREAK) {
|
||||
g_hookCtx = nullptr;
|
||||
return (R)hookCtx.retVal._interger;
|
||||
return *(R *)&hookCtx.retVal._interger;
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
@ -41,7 +41,7 @@ hook_t hooklist_player[] = {
|
||||
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;
|
||||
|
||||
@ -55,4 +55,8 @@ hook_t *hooklist_t::operator[](size_t hook) const
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -197,6 +230,3 @@ enum GamedllFunc_CBasePlayer
|
||||
// [...]
|
||||
RH_CBasePlayer_End
|
||||
};
|
||||
|
||||
extern hook_t hooklist_engine[];
|
||||
extern hook_t hooklist_player[];
|
||||
|
@ -3,7 +3,7 @@
|
||||
struct regmember
|
||||
{
|
||||
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.max_size = sizeof(T);
|
||||
|
@ -32,8 +32,8 @@ static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int funcid, len;
|
||||
const char *funcname = g_amxxapi.GetAmxString(amx, params[arg_handler], 0, &len);
|
||||
int funcid;
|
||||
const char *funcname = getAmxString(amx, params[arg_handler]);
|
||||
if (g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "EnableHookChain: invalid HookChain handle.");
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "DisableHookChain: invalid HookChain handle.");
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 };
|
||||
@ -125,7 +125,7 @@ static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params)
|
||||
if (params[arg_type] != retVal.type)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set incompatible return type.");
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
retVal.set = true;
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -174,7 +174,7 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
|
||||
if (!g_hookCtx)
|
||||
{
|
||||
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 };
|
||||
@ -191,7 +191,7 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
|
||||
case ATYPE_STRING:
|
||||
{
|
||||
if (params[arg_count] != 2)
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
setAmxString(dstAddr, retVal._string, params[arg_maxlen]);
|
||||
break;
|
||||
@ -200,10 +200,10 @@ static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
|
||||
*dstAddr = retVal._classptr->entindex();
|
||||
break;
|
||||
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)
|
||||
{
|
||||
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 };
|
||||
|
||||
size_t number = params[arg_number] - 1;
|
||||
|
||||
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);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: invalid argument type provided.");
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char temp_strings[MAX_ARGS][1024];
|
||||
@ -256,14 +255,14 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
||||
*(cell *)destAddr = *srcAddr;
|
||||
break;
|
||||
case ATYPE_STRING:
|
||||
*(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], 1023, nullptr);
|
||||
*(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], 1023);
|
||||
break;
|
||||
case ATYPE_CLASSPTR:
|
||||
*(CBaseEntity **)destAddr = CBaseEntity::Instance(INDEXENT(*srcAddr));
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO Func_Natives[] =
|
||||
|
@ -8,13 +8,13 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
||||
|
||||
if (member == nullptr) {
|
||||
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]);
|
||||
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
||||
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]);
|
||||
@ -23,7 +23,7 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
||||
switch (member->type)
|
||||
{
|
||||
case MEMBER_ENTITY:
|
||||
return -1;
|
||||
return FALSE;
|
||||
case MEMBER_CLASSPTR:
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
set_member<CBaseEntity *>(pEdict, member->offset, pEntity, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
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);
|
||||
edict_t *pEdictValue = INDEXENT(*value);
|
||||
ehandle.Set(pEdictValue);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_EVARS:
|
||||
return -1;
|
||||
return FALSE;
|
||||
case MEMBER_EDICT:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
edict_t *pEdictValue = INDEXENT(*value);
|
||||
set_member<edict_t *>(pEdict, member->offset, pEdictValue, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_VECTOR:
|
||||
{
|
||||
// native set_member(_index, any:_member, Float:_value[3], _elem);
|
||||
Vector *pSource = (Vector *)getAmxAddr(amx, params[arg_value]);
|
||||
set_member<Vector>(pEdict, member->offset, *pSource, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
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);
|
||||
strncpy(dest, source, member->max_size - 1);
|
||||
dest[member->max_size - 1] = '\0';
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_CHAR_POINTER:
|
||||
{
|
||||
@ -85,51 +85,51 @@ static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
||||
strcpy(dest, source);
|
||||
|
||||
set_member<char *>(pEdict, member->offset, dest);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
{
|
||||
// native set_member(_index, any:_member, any:_value, _elem);
|
||||
set_member<int>(pEdict, member->offset, *value, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_SHORT:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
set_member<short>(pEdict, member->offset, *value, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_BYTE:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
set_member<byte>(pEdict, member->offset, *value, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_BOOL:
|
||||
{
|
||||
// native set_member(_index, any:_member, bool:_value, _elem);
|
||||
set_member<bool>(pEdict, member->offset, *value != 0, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_SIGNALS:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value);
|
||||
CUnifiedSignals& signal = get_member<CUnifiedSignals>(pEdict, member->offset, element);
|
||||
signal.Signal(*value);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_DOUBLE:
|
||||
{
|
||||
// native set_member(_index, any:_member, any:_value, _elem);
|
||||
set_member<double>(pEdict, member->offset, *(float *)value, element);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
edict_t *pEdict = INDEXENT(params[arg_index]);
|
||||
|
||||
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
case MEMBER_ENTITY:
|
||||
return -1;
|
||||
return FALSE;
|
||||
case MEMBER_CLASSPTR:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
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) {
|
||||
return ((CBaseEntity *)ehandle)->entindex();
|
||||
}
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
case MEMBER_EVARS:
|
||||
return -1;
|
||||
@ -178,7 +178,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
||||
return indexOfEdict(pEntity);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
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]));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
@ -244,7 +244,7 @@ static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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]);
|
||||
@ -273,7 +273,7 @@ static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params)
|
||||
case MEMBER_BYTE:
|
||||
case MEMBER_SIGNALS:
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return -1;
|
||||
return FALSE;
|
||||
case MEMBER_CLASSPTR:
|
||||
{
|
||||
// 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:...);
|
||||
@ -324,7 +324,7 @@ static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params)
|
||||
|
||||
if (member == nullptr) {
|
||||
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]);
|
||||
@ -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[] =
|
||||
|
Loading…
Reference in New Issue
Block a user