2
0
mirror of https://github.com/rehlds/reapi.git synced 2024-12-29 08:05:36 +03:00

Increased automation of hookchains registration

This commit is contained in:
asmodai 2016-04-21 16:15:21 +03:00
parent df8cab66f4
commit 170f67bdf2
9 changed files with 91 additions and 134 deletions

View File

@ -4,5 +4,5 @@
#define _reapi_const_included
// reapi version
#define REAPI_VERISON_MAJOR 2
#define REAPI_VERISON_MAJOR 1
#define REAPI_VERISON_MINOR 0

View File

@ -15,14 +15,14 @@ bool CAPI_Config::Init()
return true;
}
void CAPI_Config::ServerActivate()
void CAPI_Config::ServerActivate() const
{
if (m_api_regame) {
g_pCSGameRules = (CHalfLifeMultiplay **)g_ReGameApi->GetGameData()->GetGameRules();
}
}
void CAPI_Config::ServerDeactivate()
void CAPI_Config::ServerDeactivate() const
{
if (m_api_regame) {
g_pCSGameRules = nullptr;

View File

@ -11,8 +11,8 @@ public:
bool hasReHLDS() const { return m_api_rehlds; }
bool hasReGameDLL() const { return m_api_regame; }
void ServerActivate();
void ServerDeactivate();
void ServerActivate() const;
void ServerDeactivate() const;
private:
// to provide API functions

View File

@ -47,7 +47,7 @@ void setupArgTypes(AType args_type[MAX_ARGS])
}
template<size_t current = 0, typename T, typename ...t_args>
void setupArgTypes(AType args_type[MAX_ARGS], T arg, t_args... args)
void setupArgTypes(AType args_type[MAX_ARGS], T, t_args... args)
{
args_type[current] = getApiType(T());
if (sizeof...(args) && current + 1 < MAX_ARGS)
@ -201,7 +201,6 @@ int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver);
void PlayerBlind(IReGameHook_PlayerBlind *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, float fadeTime, float fadeHold, int alpha, Vector& color);
void RadiusFlash_TraceLine(IReGameHook_RadiusFlash_TraceLine *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector& vecSrc, Vector& vecSpot, TraceResult *ptr);
// regamedll functions - player
void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis);
void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer *pthis);
@ -233,5 +232,4 @@ void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBa
void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, bool bTrackChange);
void CBasePlayer_GiveShield(IReGameHook_CBasePlayer_GiveShield *chain, CBasePlayer *pthis, bool bDeploy);
void CBaseAnimating_ResetSequenceInfo(IReGameHook_CBaseAnimating_ResetSequenceInfo *chain, CBaseAnimating *pthis);

View File

@ -1,5 +1,61 @@
#include "precompiled.h"
inline size_t getFwdParamType(void(*)(int)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(bool)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(Vector&)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(PLAYER_ANIM)) { return FP_CELL; }
inline size_t getFwdParamType(void(*)(float)) { return FP_FLOAT; }
inline size_t getFwdParamType(void(*)(const char *)) { return FP_STRING; }
template<typename T>
inline size_t getFwdParamType(void(*)(T *)) { return FP_CELL; }
template<size_t current = 0>
void setupParamTypes(size_t param_types[], void (*)())
{
param_types[current] = FP_DONE;
}
template<size_t current = 0, typename T, typename ...t_args>
void setupParamTypes(size_t param_types[], void(*)(T, t_args...))
{
void (*func)(T) = nullptr;
param_types[current] = getFwdParamType(func);
void (*next)(t_args...) = nullptr;
setupParamTypes<current + 1>(param_types, next);
}
template<typename... f_args>
struct regargs
{
regargs(void (*)(f_args...))
{
void (*func)(f_args...) = nullptr;
setupParamTypes(types, func);
}
size_t types[sizeof...(f_args) + 1]; // + FP_DONE
};
struct regfunc
{
template<typename R, typename T, typename... f_args>
regfunc(R (*)(T, f_args...))
{
func = [](AMX *amx, const char *name) {
void(*func)(f_args...) = nullptr;
regargs<f_args...> args(func);
return g_amxxapi.RegisterSPForwardByName(amx, name, args);
};
}
regfunc(const char *error) { UTIL_SysError(error); } // to cause a amxx module failure.
operator regfunc_t() const { return func; }
regfunc_t func;
static int current_cell; // the counter of cells
};
int regfunc::current_cell = 1;
#define ENG(h) { {}, {}, #h, "ReHLDS", [](){ return api_cfg.hasReHLDS(); }, ((!(RH_##h & (MAX_REGION_RANGE - 1)) ? regfunc::current_cell = 1, true : false) || (RH_##h & (MAX_REGION_RANGE - 1)) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h " doesn't match hook definition"), [](){ g_RehldsHookchains->##h##()->registerHook(&##h); }, [](){ g_RehldsHookchains->##h##()->unregisterHook(&##h); }}
@ -69,3 +125,16 @@ hook_t* hooklist_t::getHookSafe(size_t hook)
return nullptr;
}
void hook_t::clear()
{
for (auto h : pre)
delete h;
pre.clear();
for (auto h : post)
delete h;
post.clear();
unregisterHookchain();
}

View File

@ -8,115 +8,6 @@ typedef bool (*reqfunc_t)();
typedef int (*regfunc_t)(AMX *, const char *);
typedef void (*regchain_t)();
struct regfunc
{
template<typename T, typename R>
regfunc(R (*)(T *, int, edict_t *, int, const char *, int, float, int, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_FLOAT, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, IGameClient *, bool, const char *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_STRING, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, struct cvar_s *, const char *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_STRING, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBaseAnimating *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, const char *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_STRING, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, bool)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, PLAYER_ANIM)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, entvars_t *, float, Vector&, TraceResult *, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_FLOAT, FP_ARRAY, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, entvars_t *, entvars_t *, float, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, float, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_FLOAT, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, entvars_t *, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, int, BOOL)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, CBasePlayerItem *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, int, char *, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, float, float, float, int)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_FLOAT, FP_FLOAT, FP_FLOAT, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, int, bool)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, entvars_t *, entvars_t *, float, float, int, Vector&)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_FLOAT, FP_CELL, FP_ARRAY, FP_DONE); };
}
template<typename T, typename R>
regfunc(R (*)(T *, CBasePlayer *, entvars_t *, entvars_t *, Vector&, Vector&, TraceResult *)) {
func = [](AMX *amx, const char *name) { return g_amxxapi.RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_ARRAY, FP_ARRAY, FP_CELL, FP_DONE); };
}
regfunc(const char *error) { UTIL_SysError(error); } // to cause a amxx module failure.
operator regfunc_t() const { return func; }
regfunc_t func;
static int current_cell; // the counter of cells
};
struct hook_t
{
std::vector<class CAmxxHook *> pre; // pre forwards
@ -129,6 +20,8 @@ struct hook_t
regfunc_t registerForward; // AMXX forward registration function
regchain_t registerHookchain; // register re* API hook
regchain_t unregisterHookchain; // unregister re* API hook
void clear();
};
extern hook_t hooklist_engine[];

View File

@ -4,13 +4,15 @@ CHookManager g_hookManager;
int CHookManager::addHandler(AMX* amx, int func, int forward, bool post) const
{
if (!m_hooklist[func]->post.size() && !m_hooklist[func]->pre.size())
auto hook = m_hooklist.getHookSafe(func);
if (!hook->post.size() && !hook->pre.size())
{
// API hookchain
m_hooklist[func]->registerHookchain();
hook->registerHookchain();
}
auto& dest = post ? m_hooklist[func]->post : m_hooklist[func]->pre;
auto& dest = post ? hook->post : hook->pre;
dest.push_back(new CAmxxHook(amx, forward));
int id = func * MAX_HOOK_FORWARDS + dest.size();
return post ? -id : id; // use unsigned ids for post hooks
@ -40,11 +42,8 @@ void CHookManager::clearHandlers() const
{
#define CLEAR_HOOKLIST(__END__, __START__)\
for (size_t i = BEGIN_FUNC_REGION(__START__); i < RH_##__END__##_End; ++i) {\
if (m_hooklist[i] == nullptr)\
continue;\
m_hooklist[i]->pre.clear();\
m_hooklist[i]->post.clear();\
m_hooklist[i]->unregisterHookchain();\
if (m_hooklist[i])\
m_hooklist[i]->clear();\
}
CLEAR_HOOKLIST(EngineFunc, engine);
@ -59,18 +58,16 @@ hook_t* CHookManager::getHook(size_t func) const
CAmxxHook* CHookManager::getAmxxHook(cell handle) const
{
bool post = false;
bool post = handle < 0;
if (handle < 0) // post
{
if (post)
handle = ~handle;
post = true;
}
else handle--;
else
handle--;
const size_t func = handle / MAX_HOOK_FORWARDS;
const size_t id = handle & (MAX_HOOK_FORWARDS - 1);
auto hook = m_hooklist[func];
auto hook = m_hooklist.getHookSafe(func);
if (hook)
{

View File

@ -255,7 +255,7 @@ 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);
*(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], sizeof temp_strings[0] - 1);
break;
case ATYPE_CLASSPTR:
*(CBaseEntity **)destAddr = CBaseEntity::Instance(INDEXENT(*srcAddr));

View File

@ -4,5 +4,5 @@
#define _reapi_const_included
// reapi version
#define REAPI_VERISON_MAJOR 2
#define REAPI_VERISON_MAJOR 1
#define REAPI_VERISON_MINOR 0