mirror of
https://github.com/rehlds/reapi.git
synced 2025-01-16 00:28:17 +03:00
Refactored string arguments changing
This commit is contained in:
parent
727cf3c01d
commit
9fc7607368
@ -1,6 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
hookctx_t* g_hookCtx = nullptr;
|
||||
CTempStrings hookctx_t::s_temp_strings;
|
||||
|
||||
/*
|
||||
* ReHLDS functions
|
||||
|
@ -40,7 +40,7 @@ inline AType getApiType(int) { return ATYPE_INTEGER; }
|
||||
inline AType getApiType(unsigned) { return ATYPE_INTEGER; }
|
||||
inline AType getApiType(float) { return ATYPE_FLOAT; }
|
||||
inline AType getApiType(const char *) { return ATYPE_STRING; }
|
||||
inline AType getApiType(char[]) { return ATYPE_STRING; }
|
||||
inline AType getApiType(char[]) { return ATYPE_STRING; }
|
||||
inline AType getApiType(CBaseEntity *) { return ATYPE_CLASSPTR; }
|
||||
inline AType getApiType(edict_t *) { return ATYPE_EDICT; }
|
||||
inline AType getApiType(entvars_t *) { return ATYPE_EVARS; }
|
||||
@ -48,6 +48,15 @@ inline AType getApiType(entvars_t *) { return ATYPE_EVARS; }
|
||||
template<typename T>
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
args_count = min(arg_count, MAX_HOOKCHAIN_ARGS);
|
||||
|
||||
if (hasStringArgs(args...)) {
|
||||
tempstrings_used = 0;
|
||||
}
|
||||
|
||||
setupArgTypes(args_type, args...);
|
||||
}
|
||||
|
||||
@ -105,10 +119,28 @@ struct hookctx_t
|
||||
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;
|
||||
size_t args_count;
|
||||
size_t args_ptr;
|
||||
size_t tempstrings_used;
|
||||
AType args_type[MAX_HOOKCHAIN_ARGS];
|
||||
|
||||
static CTempStrings s_temp_strings;
|
||||
};
|
||||
|
||||
extern hookctx_t* g_hookCtx;
|
||||
@ -160,6 +192,10 @@ void callVoidForward(size_t func, original_t original, f_args... args)
|
||||
g_hookCtx = &hookCtx;
|
||||
_callVoidForward(g_hookManager.getHookFast(func), original, args...);
|
||||
g_hookCtx = save;
|
||||
|
||||
if (hasStringArgs(args...)) {
|
||||
hookCtx.clear_temp_strings();
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
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* 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...);
|
||||
g_hookCtx = save;
|
||||
|
||||
if (hasStringArgs(args...)) {
|
||||
hookCtx.clear_temp_strings();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -250,8 +250,6 @@ cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char temp_strings[MAX_HOOKCHAIN_ARGS][1024];
|
||||
|
||||
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
|
||||
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;
|
||||
break;
|
||||
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;
|
||||
case ATYPE_CLASSPTR:
|
||||
*(CBaseEntity **)destAddr = getPrivate<CBaseEntity>(*srcAddr);
|
||||
|
@ -42,3 +42,24 @@ ModelName GetModelAuto(TeamName team)
|
||||
|
||||
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, ...);
|
||||
|
||||
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