2
0
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:
asmodai 2016-10-16 21:35:11 +03:00
parent 727cf3c01d
commit 9fc7607368
5 changed files with 87 additions and 4 deletions

View File

@ -1,6 +1,7 @@
#include "precompiled.h"
hookctx_t* g_hookCtx = nullptr;
CTempStrings hookctx_t::s_temp_strings;
/*
* ReHLDS functions

View File

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

View File

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

View File

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

View File

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