mirror of
https://github.com/rehlds/reapi.git
synced 2025-01-16 08:38:08 +03:00
Refactored string arguments changing
This commit is contained in:
parent
727cf3c01d
commit
9fc7607368
@ -1,6 +1,7 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
hookctx_t* g_hookCtx = nullptr;
|
hookctx_t* g_hookCtx = nullptr;
|
||||||
|
CTempStrings hookctx_t::s_temp_strings;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ReHLDS functions
|
* ReHLDS functions
|
||||||
|
@ -48,6 +48,15 @@ inline AType getApiType(entvars_t *) { return ATYPE_EVARS; }
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
inline AType getApiType(T *) { return ATYPE_INTEGER; }
|
inline AType getApiType(T *) { return ATYPE_INTEGER; }
|
||||||
|
|
||||||
|
inline bool hasStringArgs() { return false; }
|
||||||
|
|
||||||
|
template <typename T, typename ...f_args>
|
||||||
|
bool hasStringArgs(T, f_args... args)
|
||||||
|
{
|
||||||
|
if (getApiType(T()) == ATYPE_STRING) return true;
|
||||||
|
return hasStringArgs(args...);
|
||||||
|
}
|
||||||
|
|
||||||
#define MAX_HOOKCHAIN_ARGS 12u
|
#define MAX_HOOKCHAIN_ARGS 12u
|
||||||
|
|
||||||
template<size_t current = 0, typename T1, typename T2, typename T3, typename T4, typename ...t_args>
|
template<size_t current = 0, typename T1, typename T2, typename T3, typename T4, typename ...t_args>
|
||||||
@ -95,6 +104,11 @@ struct hookctx_t
|
|||||||
hookctx_t(size_t arg_count, t_args... args)
|
hookctx_t(size_t arg_count, t_args... args)
|
||||||
{
|
{
|
||||||
args_count = min(arg_count, MAX_HOOKCHAIN_ARGS);
|
args_count = min(arg_count, MAX_HOOKCHAIN_ARGS);
|
||||||
|
|
||||||
|
if (hasStringArgs(args...)) {
|
||||||
|
tempstrings_used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
setupArgTypes(args_type, args...);
|
setupArgTypes(args_type, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,10 +119,28 @@ struct hookctx_t
|
|||||||
args_ptr = arg_ptr;
|
args_ptr = arg_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* get_temp_string(AMX* amx)
|
||||||
|
{
|
||||||
|
auto ptr = s_temp_strings.push(amx);
|
||||||
|
if (ptr) {
|
||||||
|
tempstrings_used++;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
return "<reapi error>";
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_temp_strings() const
|
||||||
|
{
|
||||||
|
s_temp_strings.pop(tempstrings_used);
|
||||||
|
}
|
||||||
|
|
||||||
retval_t retVal;
|
retval_t retVal;
|
||||||
size_t args_count;
|
size_t args_count;
|
||||||
size_t args_ptr;
|
size_t args_ptr;
|
||||||
|
size_t tempstrings_used;
|
||||||
AType args_type[MAX_HOOKCHAIN_ARGS];
|
AType args_type[MAX_HOOKCHAIN_ARGS];
|
||||||
|
|
||||||
|
static CTempStrings s_temp_strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern hookctx_t* g_hookCtx;
|
extern hookctx_t* g_hookCtx;
|
||||||
@ -160,6 +192,10 @@ void callVoidForward(size_t func, original_t original, f_args... args)
|
|||||||
g_hookCtx = &hookCtx;
|
g_hookCtx = &hookCtx;
|
||||||
_callVoidForward(g_hookManager.getHookFast(func), original, args...);
|
_callVoidForward(g_hookManager.getHookFast(func), original, args...);
|
||||||
g_hookCtx = save;
|
g_hookCtx = save;
|
||||||
|
|
||||||
|
if (hasStringArgs(args...)) {
|
||||||
|
hookCtx.clear_temp_strings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename original_t, typename ...f_args>
|
template <typename R, typename original_t, typename ...f_args>
|
||||||
@ -220,6 +256,10 @@ NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volat
|
|||||||
template <typename R, typename original_t, typename ...f_args>
|
template <typename R, typename original_t, typename ...f_args>
|
||||||
R callForward(size_t func, original_t original, f_args... args)
|
R callForward(size_t func, original_t original, f_args... args)
|
||||||
{
|
{
|
||||||
|
if (sizeof(R) > sizeof(int)) {
|
||||||
|
UTIL_SysError("%s: invalid return type size (%i)", __FUNCTION__, sizeof(R));
|
||||||
|
}
|
||||||
|
|
||||||
hookctx_t hookCtx(sizeof...(args), args...);
|
hookctx_t hookCtx(sizeof...(args), args...);
|
||||||
hookctx_t* save = g_hookCtx;
|
hookctx_t* save = g_hookCtx;
|
||||||
|
|
||||||
@ -227,6 +267,10 @@ R callForward(size_t func, original_t original, f_args... args)
|
|||||||
auto ret = _callForward<R>(g_hookManager.getHookFast(func), original, args...);
|
auto ret = _callForward<R>(g_hookManager.getHookFast(func), original, args...);
|
||||||
g_hookCtx = save;
|
g_hookCtx = save;
|
||||||
|
|
||||||
|
if (hasStringArgs(args...)) {
|
||||||
|
hookCtx.clear_temp_strings();
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +250,6 @@ cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char temp_strings[MAX_HOOKCHAIN_ARGS][1024];
|
|
||||||
|
|
||||||
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
||||||
size_t destAddr = g_hookCtx->args_ptr + number * sizeof(int);
|
size_t destAddr = g_hookCtx->args_ptr + number * sizeof(int);
|
||||||
|
|
||||||
@ -262,7 +260,7 @@ 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], sizeof temp_strings[0] - 1);
|
*(char **)destAddr = getAmxStringTemp(srcAddr, g_hookCtx->get_temp_string(amx), CTempStrings::STRING_LEN);
|
||||||
break;
|
break;
|
||||||
case ATYPE_CLASSPTR:
|
case ATYPE_CLASSPTR:
|
||||||
*(CBaseEntity **)destAddr = getPrivate<CBaseEntity>(*srcAddr);
|
*(CBaseEntity **)destAddr = getPrivate<CBaseEntity>(*srcAddr);
|
||||||
|
@ -42,3 +42,24 @@ ModelName GetModelAuto(TeamName team)
|
|||||||
|
|
||||||
return MODEL_UNASSIGNED;
|
return MODEL_UNASSIGNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTempStrings::CTempStrings()
|
||||||
|
{
|
||||||
|
m_current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* CTempStrings::push(AMX* amx)
|
||||||
|
{
|
||||||
|
if (m_current == STRINGS_MAX) {
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "temp strings limit exceeded, contact reapi authors");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_strings[m_current++];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTempStrings::pop(size_t count)
|
||||||
|
{
|
||||||
|
m_current -= count;
|
||||||
|
}
|
||||||
|
@ -134,3 +134,22 @@ ModelName GetModelAuto(TeamName team);
|
|||||||
void UTIL_ServerPrint(const char *fmt, ...);
|
void UTIL_ServerPrint(const char *fmt, ...);
|
||||||
|
|
||||||
extern void __declspec(noreturn) UTIL_SysError(const char *fmt, ...);
|
extern void __declspec(noreturn) UTIL_SysError(const char *fmt, ...);
|
||||||
|
|
||||||
|
class CTempStrings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTempStrings();
|
||||||
|
char* push(AMX* amx);
|
||||||
|
void pop(size_t count);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STRINGS_MAX = 16,
|
||||||
|
STRING_SIZE = 1024,
|
||||||
|
STRING_LEN = STRING_SIZE - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_current;
|
||||||
|
char m_strings[STRINGS_MAX][STRING_SIZE];
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user