mirror of
https://github.com/rehlds/reapi.git
synced 2025-01-27 22:17:55 +03:00
Refactored member natives code
Fixed compilation under linux
This commit is contained in:
parent
59be98fb6a
commit
0dd99aaf6d
@ -202,7 +202,8 @@
|
||||
<ClInclude Include="..\src\member_list.h" />
|
||||
<ClInclude Include="..\src\mod_regamedll_api.h" />
|
||||
<ClInclude Include="..\src\mod_rehlds_api.h" />
|
||||
<ClInclude Include="..\src\natives.h" />
|
||||
<ClInclude Include="..\src\natives_hookchains.h" />
|
||||
<ClInclude Include="..\src\natives_members.h" />
|
||||
<ClInclude Include="..\src\precompiled.h" />
|
||||
<ClInclude Include="..\src\reapi_utils.h" />
|
||||
</ItemGroup>
|
||||
@ -236,8 +237,8 @@
|
||||
<ClCompile Include="..\src\main.cpp" />
|
||||
<ClCompile Include="..\src\meta_api.cpp" />
|
||||
<ClCompile Include="..\src\mod_rehlds_api.cpp" />
|
||||
<ClCompile Include="..\src\natives.cpp" />
|
||||
<ClCompile Include="..\src\natives_member.cpp" />
|
||||
<ClCompile Include="..\src\natives_hookchains.cpp" />
|
||||
<ClCompile Include="..\src\natives_members.cpp" />
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
|
@ -591,9 +591,6 @@
|
||||
<ClInclude Include="..\src\amxxmodule.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\natives.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\precompiled.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
@ -621,6 +618,12 @@
|
||||
<ClInclude Include="..\src\hook_manager.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\natives_hookchains.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\natives_members.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
|
||||
@ -644,9 +647,6 @@
|
||||
<ClCompile Include="..\src\meta_api.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\natives.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\precompiled.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
@ -671,9 +671,6 @@
|
||||
<ClCompile Include="..\src\member_list.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\natives_member.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\hook_manager.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
@ -686,6 +683,12 @@
|
||||
<ClCompile Include="..\src\h_export.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\natives_hookchains.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\natives_members.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\extra\amxmodx\scripting\include\reapi.inc">
|
||||
|
@ -159,7 +159,8 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
*(void **)((unsigned long)&g_amxxapi + g_funcrequests[i].offset) = fptr;
|
||||
}
|
||||
|
||||
RegisterNatives();
|
||||
RegisterNatives_HookChains();
|
||||
RegisterNatives_Members();
|
||||
return AMXX_OK;
|
||||
}
|
||||
|
||||
|
@ -78,21 +78,6 @@ struct hookctx_t
|
||||
|
||||
extern hookctx_t* g_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)
|
||||
{
|
||||
@ -129,8 +114,8 @@ NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original
|
||||
}
|
||||
}
|
||||
|
||||
template <typename R, typename original_t, typename ...f_args>
|
||||
R callForward(size_t func, original_t original, f_args... args)
|
||||
template <typename original_t, typename ...f_args>
|
||||
void callVoidForward(size_t func, original_t original, f_args... args)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
static
|
||||
@ -138,10 +123,8 @@ R callForward(size_t func, original_t original, f_args... args)
|
||||
hookctx_t hookCtx(sizeof...(args), args...);
|
||||
|
||||
g_hookCtx = &hookCtx;
|
||||
auto ret = _callForward<R>(g_hookManager.getHook(func), original, args...);
|
||||
_callVoidForward(g_hookManager.getHook(func), original, args...);
|
||||
g_hookCtx = nullptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename R, typename original_t, typename ...f_args>
|
||||
@ -194,7 +177,20 @@ NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volat
|
||||
return *(R *)&hookCtx.retVal._interger;
|
||||
}
|
||||
|
||||
#pragma optimize("", on)
|
||||
template <typename R, typename original_t, typename ...f_args>
|
||||
R callForward(size_t func, original_t original, f_args... args)
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
@ -41,22 +41,6 @@ hook_t hooklist_player[] = {
|
||||
DLL(CBasePlayer_Observer_IsValidTarget),
|
||||
};
|
||||
|
||||
/*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;
|
||||
|
||||
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 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);
|
||||
|
@ -124,20 +124,8 @@ struct hooklist_t
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
ht_engine,
|
||||
|
@ -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, MType member_type)
|
||||
{
|
||||
member.size = sizeof(T);
|
||||
member.max_size = sizeof(T);
|
||||
@ -11,7 +11,7 @@ struct regmember
|
||||
member.type = member_type;
|
||||
}
|
||||
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, MType member_type)
|
||||
{
|
||||
member.size = sizeof(T);
|
||||
member.max_size = maxsize;
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
#define BEGIN_MEMBER_REGION(x) (MAX_REGION_RANGE * memberlist_t::members_tables_e::ht_##x)
|
||||
|
||||
enum enum_membertypes
|
||||
// member types
|
||||
enum MType
|
||||
{
|
||||
MEMBER_FLOAT = 0, // Any floating point value
|
||||
MEMBER_DOUBLE, // double value
|
||||
@ -27,7 +28,7 @@ struct member_t
|
||||
uint16 size;
|
||||
uint16 max_size;
|
||||
uint32 offset;
|
||||
enum_membertypes type;
|
||||
MType type;
|
||||
};
|
||||
|
||||
struct memberlist_t
|
||||
|
@ -265,7 +265,7 @@ static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO Func_Natives[] =
|
||||
AMX_NATIVE_INFO HookChain_Natives[] =
|
||||
{
|
||||
{ "RegisterHookChain", RegisterHookChain },
|
||||
|
||||
@ -280,8 +280,7 @@ AMX_NATIVE_INFO Func_Natives[] =
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
void RegisterNatives()
|
||||
void RegisterNatives_HookChains()
|
||||
{
|
||||
g_amxxapi.AddNatives(Func_Natives);
|
||||
g_amxxapi.AddNatives(Member_Natives);
|
||||
g_amxxapi.AddNatives(HookChain_Natives);
|
||||
}
|
@ -4,6 +4,4 @@
|
||||
#define PARAMS_REQUIRE(x) if (params[0] != x * sizeof(cell)) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid parameters count in %s", __FUNCTION__); return nullptr; }
|
||||
#define NATIVE_MEMBER_REQUIRE(a,x) if (!api_cfg.has##x()) { MF_LogError(amx, AMX_ERR_NATIVE, "Member (%s) is not available, required %s", memberlist[a]->member_name, #x); return 0; }
|
||||
|
||||
extern AMX_NATIVE_INFO Member_Natives[];
|
||||
|
||||
void RegisterNatives();
|
||||
void RegisterNatives_HookChains();
|
@ -1,385 +0,0 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// native set_member(_index, any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_index, arg_member, arg_value, arg_elem };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "set_member: unknown member id %i", params[arg_member]);
|
||||
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 FALSE;
|
||||
}
|
||||
|
||||
cell* value = getAmxAddr(amx, params[arg_value]);
|
||||
size_t element = (params[arg_count] == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0;
|
||||
|
||||
switch (member->type)
|
||||
{
|
||||
case MEMBER_ENTITY:
|
||||
return FALSE;
|
||||
case MEMBER_CLASSPTR:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
CBaseEntity *pEntity = nullptr;
|
||||
edict_t *pEdictValue = INDEXENT(*value);
|
||||
|
||||
if (pEdictValue != nullptr) {
|
||||
pEntity = CBaseEntity::Instance(pEdictValue);
|
||||
}
|
||||
set_member<CBaseEntity *>(pEdict, member->offset, pEntity, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_EHANDLE:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
EHANDLE& ehandle = get_member<EHANDLE>(pEdict, member->offset, element);
|
||||
edict_t *pEdictValue = INDEXENT(*value);
|
||||
ehandle.Set(pEdictValue);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_EVARS:
|
||||
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 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 TRUE;
|
||||
}
|
||||
case MEMBER_CHAR_ARRAY:
|
||||
{
|
||||
// native set_member(_index, any:_member, const source[]);
|
||||
size_t len;
|
||||
char *source = getAmxString(value, &len);
|
||||
char *dest = get_member_direct<char *>(pEdict, member->offset);
|
||||
strncpy(dest, source, member->max_size - 1);
|
||||
dest[member->max_size - 1] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_CHAR_POINTER:
|
||||
{
|
||||
// native set_member(_index, any:_member, const source[]);
|
||||
size_t len;
|
||||
char *source = getAmxString(value, &len);
|
||||
char *&dest = get_member<char *>(pEdict, member->offset);
|
||||
|
||||
if (dest != nullptr) {
|
||||
delete [] dest;
|
||||
}
|
||||
|
||||
dest = new char[len + 1];
|
||||
strcpy(dest, source);
|
||||
|
||||
set_member<char *>(pEdict, member->offset, dest);
|
||||
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 TRUE;
|
||||
}
|
||||
case MEMBER_SHORT:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
set_member<short>(pEdict, member->offset, *value, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_BYTE:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
set_member<byte>(pEdict, member->offset, *value, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_BOOL:
|
||||
{
|
||||
// native set_member(_index, any:_member, bool:_value, _elem);
|
||||
set_member<bool>(pEdict, member->offset, *value != 0, element);
|
||||
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 TRUE;
|
||||
}
|
||||
case MEMBER_DOUBLE:
|
||||
{
|
||||
// native set_member(_index, any:_member, any:_value, _elem);
|
||||
set_member<double>(pEdict, member->offset, *(float *)value, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// native any:get_member(_index = 0, any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_index, arg_member, arg_elem };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
edict_t *pEdict = INDEXENT(params[arg_index]);
|
||||
|
||||
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
||||
|
||||
switch (member->type)
|
||||
{
|
||||
case MEMBER_ENTITY:
|
||||
return FALSE;
|
||||
case MEMBER_CLASSPTR:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<CBaseEntity *>(pEdict, member->offset, element)->entindex();
|
||||
case MEMBER_EHANDLE:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
EHANDLE ehandle = get_member<EHANDLE>(pEdict, member->offset, element);
|
||||
edict_t *pEntity = ehandle.Get();
|
||||
if (pEntity != nullptr) {
|
||||
return ((CBaseEntity *)ehandle)->entindex();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
case MEMBER_EVARS:
|
||||
return -1;
|
||||
case MEMBER_EDICT:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
edict_t *pEntity = get_member<edict_t *>(pEdict, member->offset, element);
|
||||
if (pEntity != nullptr) {
|
||||
return indexOfEdict(pEntity);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
case MEMBER_VECTOR:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, any:output[], element);
|
||||
cell *pOutput = g_amxxapi.GetAmxAddr(amx, params[3]);
|
||||
Vector vecDest = get_member<Vector>(pEdict, member->offset, *g_amxxapi.GetAmxAddr(amx, params[4]));
|
||||
|
||||
pOutput[0] = *(cell *)&vecDest.x;
|
||||
pOutput[1] = *(cell *)&vecDest.y;
|
||||
pOutput[2] = *(cell *)&vecDest.z;
|
||||
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_CHAR_ARRAY:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, any:output[], maxlength);
|
||||
char *dest = get_member_direct<char *>(pEdict, member->offset);
|
||||
g_amxxapi.SetAmxString(amx, params[3], dest, *g_amxxapi.GetAmxAddr(amx, params[4]));
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_CHAR_POINTER:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, any:output[], maxlength);
|
||||
char *dest = get_member<char *>(pEdict, member->offset);
|
||||
if (dest != nullptr) {
|
||||
g_amxxapi.SetAmxString(amx, params[3], dest, *g_amxxapi.GetAmxAddr(amx, params[4]));
|
||||
return 1;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<int>(pEdict, member->offset, element);
|
||||
}
|
||||
case MEMBER_SHORT:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<short>(pEdict, member->offset, element);
|
||||
case MEMBER_BYTE:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<byte>(pEdict, member->offset, element);
|
||||
case MEMBER_BOOL:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<bool>(pEdict, member->offset, element);
|
||||
case MEMBER_SIGNALS:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, &_signal = 0, &_state = 0);
|
||||
CUnifiedSignals signal = get_member<CUnifiedSignals>(pEdict, member->offset);
|
||||
cell *pSignal = g_amxxapi.GetAmxAddr(amx, params[3]);
|
||||
cell *pState = g_amxxapi.GetAmxAddr(amx, params[4]);
|
||||
|
||||
*pSignal = signal.GetSignal();
|
||||
*pState = signal.GetState();
|
||||
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_DOUBLE:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// native set_member_game(any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_member, arg_value, arg_elem };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t value = *g_amxxapi.GetAmxAddr(amx, params[arg_value]);
|
||||
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
||||
|
||||
switch (member->type)
|
||||
{
|
||||
case MEMBER_ENTITY:
|
||||
case MEMBER_EHANDLE:
|
||||
case MEMBER_EVARS:
|
||||
case MEMBER_EDICT:
|
||||
case MEMBER_VECTOR:
|
||||
case MEMBER_CHAR_ARRAY:
|
||||
case MEMBER_CHAR_POINTER:
|
||||
case MEMBER_BYTE:
|
||||
case MEMBER_SIGNALS:
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return FALSE;
|
||||
case MEMBER_CLASSPTR:
|
||||
{
|
||||
// native set_member_game(any:_member, _value, _elem);
|
||||
CBaseEntity *pEntity = NULL;
|
||||
edict_t *pEdictValue = INDEXENT(value);
|
||||
|
||||
if (pEdictValue != nullptr) {
|
||||
pEntity = CBaseEntity::Instance(pEdictValue);
|
||||
}
|
||||
set_member<CBaseEntity *>((*g_pCSGameRules), member->offset, pEntity, element);
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
{
|
||||
// native set_member_game(any:_member, any:_value, _elem);
|
||||
set_member<int>((*g_pCSGameRules), member->offset, value, element);
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_SHORT:
|
||||
{
|
||||
// native set_member_game(any:_member, _value, _elem);
|
||||
set_member<short>((*g_pCSGameRules), member->offset, value, element);
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_BOOL:
|
||||
{
|
||||
// native set_member_game(any:_member, bool:_value, _elem);
|
||||
set_member<bool>((*g_pCSGameRules), member->offset, value != 0, element);
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_DOUBLE:
|
||||
{
|
||||
// native set_member_game(any:_member, _value);
|
||||
set_member<double>((*g_pCSGameRules), member->offset, value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// native get_member_game(any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_member, arg_elem };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Member (%d) is unknown", params[arg_member]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
|
||||
|
||||
switch (member->type)
|
||||
{
|
||||
case MEMBER_ENTITY:
|
||||
case MEMBER_EHANDLE:
|
||||
case MEMBER_EVARS:
|
||||
case MEMBER_EDICT:
|
||||
case MEMBER_VECTOR:
|
||||
case MEMBER_CHAR_ARRAY:
|
||||
case MEMBER_CHAR_POINTER:
|
||||
case MEMBER_BYTE:
|
||||
case MEMBER_SIGNALS:
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return -1;
|
||||
case MEMBER_CLASSPTR:
|
||||
// native any:get_member_game(any:_member, element);
|
||||
return get_member<CBaseEntity *>((*g_pCSGameRules), member->offset, element)->entindex();
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
{
|
||||
// native any:get_member_game(any:_member, element);
|
||||
// members for m_VoiceGameMgr
|
||||
if (params[arg_member] >= m_msgPlayerVoiceMask && params[arg_member] <= m_nMaxPlayers) {
|
||||
return get_member<int>(&((*g_pCSGameRules)->m_VoiceGameMgr), member->offset);
|
||||
}
|
||||
(*g_pCSGameRules)->m_iMapVotes[5] = 1337;
|
||||
return get_member<int>((*g_pCSGameRules), member->offset, element);
|
||||
}
|
||||
case MEMBER_SHORT:
|
||||
// native any:get_member_game(any:_member);
|
||||
return get_member<short>((*g_pCSGameRules), member->offset);
|
||||
case MEMBER_BOOL:
|
||||
// native any:get_member_game(any:_member);
|
||||
return get_member<bool>((*g_pCSGameRules), member->offset);
|
||||
case MEMBER_DOUBLE:
|
||||
{
|
||||
// native get_member_game(any:_member, _value);
|
||||
float flRet = (float)get_member<double>(&((*g_pCSGameRules)->m_VoiceGameMgr), member->offset);
|
||||
return *(cell *)&flRet;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO Member_Natives[] =
|
||||
{
|
||||
{ "set_member", set_member },
|
||||
{ "get_member", get_member },
|
||||
|
||||
{ "set_member_game", set_member_game },
|
||||
{ "get_member_game", get_member_game },
|
||||
|
||||
{ nullptr, nullptr }
|
||||
};
|
370
reapi/src/natives_members.cpp
Normal file
370
reapi/src/natives_members.cpp
Normal file
@ -0,0 +1,370 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// native set_member(_index, any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_index, arg_member, arg_value, arg_elem };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "set_member: unknown member id %i", params[arg_member]);
|
||||
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 FALSE;
|
||||
}
|
||||
|
||||
cell* value = getAmxAddr(amx, params[arg_value]);
|
||||
size_t element = (params[arg_count] == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0;
|
||||
|
||||
return set_member(pEdict->pvPrivateData, member, element, value);
|
||||
}
|
||||
|
||||
// native any:get_member(_index = 0, any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_index, arg_member, arg_3, arg_4 };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "get_member: unknown member id %i", params[arg_member]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
edict_t *pEdict = INDEXENT(params[arg_index]);
|
||||
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "get_member: invalid or uninitialized entity", params[arg_member]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cell* dest;
|
||||
size_t element;
|
||||
|
||||
if (params[arg_count] == 4) {
|
||||
dest = getAmxAddr(amx, params[arg_3]);
|
||||
element = *getAmxAddr(amx, params[arg_4]);
|
||||
}
|
||||
else if (params[arg_count] == 3) {
|
||||
cell* arg3 = getAmxAddr(amx, params[arg_3]);
|
||||
|
||||
if (isTypeReturnable(member->type)) {
|
||||
dest = nullptr;
|
||||
element = *arg3;
|
||||
}
|
||||
else {
|
||||
dest = arg3;
|
||||
element = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dest = nullptr;
|
||||
element = 0;
|
||||
}
|
||||
|
||||
return get_member(pEdict->pvPrivateData, member, element, dest);
|
||||
}
|
||||
|
||||
// native set_member_game(any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL set_member_game(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_member, arg_value, arg_elem };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "set_member_game: unknown member id %i", params[arg_member]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cell* value = getAmxAddr(amx, params[arg_value]);
|
||||
size_t element = (params[arg_count] == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0;
|
||||
|
||||
return set_member(*g_pCSGameRules, member, element, value);
|
||||
}
|
||||
|
||||
// native get_member_game(any:_member, any:...);
|
||||
static cell AMX_NATIVE_CALL get_member_game(AMX *amx, cell *params)
|
||||
{
|
||||
enum args_member_e { arg_count, arg_member, arg_3, arg_4 };
|
||||
member_t *member = memberlist[params[arg_member]];
|
||||
|
||||
if (member == nullptr) {
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: unknown member id %i", params[arg_member]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell* dest;
|
||||
size_t element;
|
||||
|
||||
if (params[arg_count] == 4) {
|
||||
dest = getAmxAddr(amx, params[arg_3]);
|
||||
element = *getAmxAddr(amx, params[arg_4]);
|
||||
}
|
||||
else if (params[arg_count] == 3) {
|
||||
cell* arg3 = getAmxAddr(amx, params[arg_3]);
|
||||
|
||||
if (isTypeReturnable(member->type)) {
|
||||
dest = nullptr;
|
||||
element = *arg3;
|
||||
}
|
||||
else {
|
||||
dest = arg3;
|
||||
element = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dest = nullptr;
|
||||
element = 0;
|
||||
}
|
||||
|
||||
return get_member(*g_pCSGameRules, member, element, dest);
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO Member_Natives[] =
|
||||
{
|
||||
{ "set_member", set_member },
|
||||
{ "get_member", get_member },
|
||||
|
||||
{ "set_member_game", set_member_game },
|
||||
{ "get_member_game", get_member_game },
|
||||
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
void RegisterNatives_Members()
|
||||
{
|
||||
g_amxxapi.AddNatives(Member_Natives);
|
||||
}
|
||||
|
||||
BOOL set_member(void* pdata, const member_t *member, size_t element, cell* value)
|
||||
{
|
||||
switch (member->type) {
|
||||
case MEMBER_CLASSPTR:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
CBaseEntity *pEntity = CBaseEntity::Instance(INDEXENT(*value));
|
||||
set_member<CBaseEntity *>(pdata, member->offset, pEntity, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_EHANDLE:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
EHANDLE& ehandle = get_member<EHANDLE>(pdata, member->offset, element);
|
||||
edict_t *pEdictValue = INDEXENT(*value);
|
||||
ehandle.Set(pEdictValue);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_EDICT:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
edict_t *pEdictValue = INDEXENT(*value);
|
||||
set_member<edict_t *>(pdata, member->offset, pEdictValue, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_VECTOR:
|
||||
{
|
||||
// native set_member(_index, any:_member, Float:_value[3], _elem);
|
||||
Vector *pSource = (Vector *)value;
|
||||
set_member<Vector>(pdata, member->offset, *pSource, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_CHAR_ARRAY:
|
||||
{
|
||||
// native set_member(_index, any:_member, const source[]);
|
||||
size_t len;
|
||||
char *source = getAmxString(value, &len);
|
||||
char *dest = get_member_direct<char *>(pdata, member->offset);
|
||||
strncpy(dest, source, member->max_size - 1);
|
||||
dest[member->max_size - 1] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_CHAR_POINTER:
|
||||
{
|
||||
// native set_member(_index, any:_member, const source[]);
|
||||
size_t len;
|
||||
char *source = getAmxString(value, &len);
|
||||
char *&dest = get_member<char *>(pdata, member->offset);
|
||||
|
||||
if (dest != nullptr) {
|
||||
delete[] dest;
|
||||
}
|
||||
|
||||
dest = new char[len + 1];
|
||||
strcpy(dest, source);
|
||||
|
||||
set_member<char *>(pdata, member->offset, dest);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
{
|
||||
// native set_member(_index, any:_member, any:_value, _elem);
|
||||
set_member<int>(pdata, member->offset, *value, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_SHORT:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
set_member<short>(pdata, member->offset, *value, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_BYTE:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value, _elem);
|
||||
set_member<byte>(pdata, member->offset, *value, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_BOOL:
|
||||
{
|
||||
// native set_member(_index, any:_member, bool:_value, _elem);
|
||||
set_member<bool>(pdata, member->offset, *value != 0, element);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_SIGNALS:
|
||||
{
|
||||
// native set_member(_index, any:_member, _value);
|
||||
CUnifiedSignals& signal = get_member<CUnifiedSignals>(pdata, member->offset, element);
|
||||
signal.Signal(*value);
|
||||
return TRUE;
|
||||
}
|
||||
case MEMBER_DOUBLE:
|
||||
{
|
||||
// native set_member(_index, any:_member, any:_value, _elem);
|
||||
set_member<double>(pdata, member->offset, *(float *)value, element);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case MEMBER_ENTITY:
|
||||
case MEMBER_EVARS:
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cell get_member(void* pdata, const member_t *member, size_t element, cell* dest)
|
||||
{
|
||||
switch (member->type)
|
||||
{
|
||||
case MEMBER_CLASSPTR:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<CBaseEntity *>(pdata, member->offset, element)->entindex();
|
||||
case MEMBER_EHANDLE:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
EHANDLE ehandle = get_member<EHANDLE>(pdata, member->offset, element);
|
||||
edict_t *pEntity = ehandle.Get();
|
||||
if (pEntity != nullptr) {
|
||||
return ENTINDEX(pEntity);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
case MEMBER_EDICT:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
edict_t *pEntity = get_member<edict_t *>(pdata, member->offset, element);
|
||||
if (pEntity != nullptr) {
|
||||
return ENTINDEX(pEntity);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
case MEMBER_VECTOR:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, any:output[], element);
|
||||
if (!dest)
|
||||
return 0;
|
||||
|
||||
cell* vecSrc = get_member_direct<cell *>(pdata, member->offset, element);
|
||||
|
||||
dest[0] = vecSrc[0];
|
||||
dest[1] = vecSrc[1];
|
||||
dest[2] = vecSrc[2];
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_CHAR_ARRAY:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, any:output[], maxlength);
|
||||
if (!dest)
|
||||
return 0;
|
||||
|
||||
const char *src = get_member_direct<const char *>(pdata, member->offset);
|
||||
setAmxString(dest, src, element);
|
||||
return 1;
|
||||
}
|
||||
case MEMBER_CHAR_POINTER:
|
||||
{
|
||||
// native any:get_member(_index, any:_member, any:output[], maxlength);
|
||||
if (!dest)
|
||||
return 0;
|
||||
|
||||
const char *src = get_member<const char *>(pdata, member->offset);
|
||||
if (src != nullptr) {
|
||||
setAmxString(dest, src, element);
|
||||
return 1;
|
||||
}
|
||||
setAmxString(dest, "", 1);
|
||||
return 0;
|
||||
}
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_INTEGER:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<int>(pdata, member->offset, element);
|
||||
case MEMBER_SHORT:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<short>(pdata, member->offset, element);
|
||||
case MEMBER_BYTE:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<byte>(pdata, member->offset, element);
|
||||
case MEMBER_BOOL:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<bool>(pdata, member->offset, element);
|
||||
case MEMBER_DOUBLE:
|
||||
// native any:get_member(_index, any:_member, element);
|
||||
return get_member<double>(pdata, member->offset, element);
|
||||
case MEMBER_SIGNALS:
|
||||
{
|
||||
enum {_Signal, _State};
|
||||
|
||||
// native any:get_member(_index, any:_member, signals[2]);
|
||||
if (!dest)
|
||||
return 0;
|
||||
|
||||
CUnifiedSignals& signal = get_member<CUnifiedSignals>(pdata, member->offset);
|
||||
|
||||
int *pSignals = dest;
|
||||
pSignals[_Signal] = signal.GetSignal();
|
||||
pSignals[_State] = signal.GetState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
case MEMBER_ENTITY:
|
||||
case MEMBER_EVARS:
|
||||
case MEBMER_REBUYSTRUCT:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isTypeReturnable(MType type)
|
||||
{
|
||||
switch (type) {
|
||||
case MEMBER_FLOAT:
|
||||
case MEMBER_DOUBLE:
|
||||
case MEMBER_ENTITY:
|
||||
case MEMBER_CLASSPTR:
|
||||
case MEMBER_EDICT:
|
||||
case MEMBER_INTEGER:
|
||||
case MEMBER_SHORT:
|
||||
case MEMBER_BYTE:
|
||||
case MEMBER_BOOL:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
8
reapi/src/natives_members.h
Normal file
8
reapi/src/natives_members.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
void RegisterNatives_Members();
|
||||
|
||||
BOOL set_member(void* pdata, const member_t *member, size_t element, cell* value);
|
||||
cell get_member(void* pdata, const member_t *member, size_t element, cell* dest);
|
||||
|
||||
bool isTypeReturnable(MType type);
|
@ -36,7 +36,8 @@
|
||||
#include "hook_manager.h"
|
||||
#include "hook_callback.h"
|
||||
#include "member_list.h"
|
||||
#include "natives.h"
|
||||
#include "natives_hookchains.h"
|
||||
#include "natives_members.h"
|
||||
|
||||
#undef DLLEXPORT
|
||||
#ifdef _WIN32
|
||||
|
Loading…
x
Reference in New Issue
Block a user