2
0
mirror of https://github.com/rehlds/reapi.git synced 2025-01-16 08:38:08 +03:00

Merge pull request #4 from s1lentq/refactoring

Refactoring
This commit is contained in:
theAsmodai 2016-04-22 00:35:14 +03:00
commit b7c2c22cbb
37 changed files with 2386 additions and 1277 deletions

View File

@ -45,7 +45,7 @@ void setupToolchain(NativeBinarySpec b) {
pchHeader: 'precompiled.h', pchHeader: 'precompiled.h',
pchSourceSet: 'reapi_pch' pchSourceSet: 'reapi_pch'
) )
cfg.compilerOptions.args '/Ob2', '/Oi', '/GF', '/GR-' cfg.compilerOptions.args '/Ob2', '/Oi', '/GF', '/GR-', '/GS-'
cfg.singleDefines('_CRT_SECURE_NO_WARNINGS') cfg.singleDefines('_CRT_SECURE_NO_WARNINGS')
cfg.extraLibs 'ws2_32.lib' cfg.extraLibs 'ws2_32.lib'
} else if (cfg instanceof GccToolchainConfig) { } else if (cfg instanceof GccToolchainConfig) {
@ -61,7 +61,7 @@ void setupToolchain(NativeBinarySpec b) {
'_snprintf': 'snprintf' '_snprintf': 'snprintf'
]) ])
cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fp-model fast', '-fomit-frame-pointer', '-fvisibility=hidden', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s' cfg.compilerOptions.args '-Qoption,cpp,--treat_func_as_string_literal_cpp', '-msse2', '-fp-model fast=2', '-fomit-frame-pointer', '-inline-forceinline', '-fvisibility=default', '-fvisibility-inlines-hidden', '-fno-rtti', '-g0', '-s'
} }
ToolchainConfigUtils.apply(project, cfg, b) ToolchainConfigUtils.apply(project, cfg, b)

View File

@ -17,22 +17,27 @@
#include <reapi_engine.inc> // NOTE: only for ReHLDS #include <reapi_engine.inc> // NOTE: only for ReHLDS
#include <reapi_gamedll.inc> // NOTE: only for gamedll Counter-Strike (ReGameDLL_CS) #include <reapi_gamedll.inc> // NOTE: only for gamedll Counter-Strike (ReGameDLL_CS)
// return constants
enum enum
{ {
RH_UNSET = 0, HC_CONTINUE = 0,
RH_IGNORED, // plugin didn't take any action HC_OVERRIDE,
RH_HANDLED, // plugin did something, but real function should still be called HC_SUPERCEDE,
RH_OVERRIDE, // call real function, but use my return value HC_BREAK
RH_SUPERCEDE // skip real function; use my return value
}; };
// for hookchain return // hookchain types
enum HookChainReturn enum AType
{ {
RHV_STRING = 0, // string ATYPE_INTEGER = 0,
RHV_FLOAT, // float ATYPE_FLOAT,
RHV_INTEGER, // returns an integer or boolean ATYPE_STRING,
RHV_CLASSPTR // for CBaseEntity *, CBasePlayer * etc ATYPE_CLASSPTR
};
enum HookChain
{
INVALID_HOOKCHAIN = 0
}; };
/* /*
@ -45,7 +50,6 @@ enum HookChainReturn
* @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off. * @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off.
* *
*/ */
native HookChain:RegisterHookChain(any:function_id, const callback[], post = 0); native HookChain:RegisterHookChain(any:function_id, const callback[], post = 0);
/* /*
@ -55,7 +59,6 @@ native HookChain:RegisterHookChain(any:function_id, const callback[], post = 0);
* @param hook The hook to stop. * @param hook The hook to stop.
* *
*/ */
native bool:DisableHookChain(HookChain:hook); native bool:DisableHookChain(HookChain:hook);
/* /*
@ -66,7 +69,6 @@ native bool:DisableHookChain(HookChain:hook);
* @return Returns if the function is successful executed true otherwise false * @return Returns if the function is successful executed true otherwise false
* *
*/ */
native bool:EnableHookChain(HookChain:hook); native bool:EnableHookChain(HookChain:hook);
/* /*
@ -76,11 +78,34 @@ native bool:EnableHookChain(HookChain:hook);
* @param type To specify the type RHV_*, look at the enum HookChainReturn * @param type To specify the type RHV_*, look at the enum HookChainReturn
* @param value The value to set the return to. * @param value The value to set the return to.
* *
* native SetHookChainReturn(HookChainReturn:type, any:...); * native SetHookChainReturn(AType:type, any:...);
*/ */
native SetHookChainReturn(HookChainReturn:type, any:...); native SetHookChainReturn(HookChainReturn:type, any:...);
/*
* Gets the return value of a hookchain.
* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE.
*
* @param type To specify the type RHV_*, look at the enum HookChainReturn
* @param value The value to set the return to.
*
* native GetHookChainReturn(AType:type, any:...);
*/
native GetHookChainReturn(AType:type, any:...);
/*
* Set hookchain argument.
* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE.
*
* @param number Number of argument
* @param value New value
* @param [maxlen] Max length of string (optional)
* @return Returns if the function is successful executed true otherwise false
*
* native SetHookChainArg(number, AType:type, any:...);
*/
native SetHookChainArg(number, AType:type, any:...);
/* /*
* This is the callback from the module that gives major/minor versions for verifying compatibility reapi API versions * This is the callback from the module that gives major/minor versions for verifying compatibility reapi API versions
* If will be amxx plugin a failure, then you do need to upgrade to the latest version of the module reapi or do update files included for amxx plugins * If will be amxx plugin a failure, then you do need to upgrade to the latest version of the module reapi or do update files included for amxx plugins
@ -90,13 +115,17 @@ public __reapi_version_check(const majorVersion, const minorVersion)
{ {
if (majorVersion != REAPI_VERISON_MAJOR) if (majorVersion != REAPI_VERISON_MAJOR)
{ {
set_fail_state("[ReAPI]: Api major version mismatch; expected %d, real %d", REAPI_VERISON_MAJOR, majorVersion); new temp[512];
formatex(temp, sizeof temp - 1, "[ReAPI]: Api major version mismatch; expected %d, real %d", REAPI_VERISON_MAJOR, majorVersion);
set_fail_state(temp);
return; return;
} }
if (minorVersion < REAPI_VERISON_MINOR) if (minorVersion < REAPI_VERISON_MINOR)
{ {
set_fail_state("[ReAPI]: Api minor version mismatch; expected at least %d, real %d", REAPI_VERISON_MINOR, minorVersion); new temp[512];
formatex(temp, sizeof temp - 1, "[ReAPI]: Api minor version mismatch; expected at least %d, real %d", REAPI_VERISON_MINOR, minorVersion);
set_fail_state(temp);
return; return;
} }
} }

View File

@ -52,3 +52,16 @@ native set_member(index, any:member, any:...);
* *
*/ */
native any:get_member(index, any:member, any:...); native any:get_member(index, any:member, any:...);
native rg_set_animation(index, PLAYER_ANIM:playerAnim);
native rg_add_account(index, amount, bool:bTrackChange = true);
native rg_give_item(index, const pszName[]);
native rg_give_default_items(index);
native rg_give_shield(index, bool:bDeploy = true);
native rg_dmg_radius(Float:vecSrc[3], inflictor, attacker, Float:flDamage, Float:flRadius, iClassIgnore, bitsDamageType);
native rg_multidmg_clear();
native rg_multidmg_apply(inflictor, attacker);
native rg_multidmg_add(inflictor, victim, Float:flDamage, bitsDamageType);
native rg_fire_bullets(inflictor, attacker, shots, Float:vecSrc[3], Float:vecDirShooting[3], Float:vecSpread[3], Float:flDistance, iBulletType, iTracerFreq, iDamage);
native Float:[3] rg_fire_bullets3(inflictor, attacker, Float:vecSrc[3], Float:vecDirShooting[3], Float:vecSpread, Float:flDistance, iPenetration, iBulletType, iDamage, Float:flRangeModifier, bool:bPistol, shared_rand);

View File

@ -11,6 +11,21 @@
#define SIGNAL_ESCAPE (1<<3) #define SIGNAL_ESCAPE (1<<3)
#define SIGNAL_VIPSAFETY (1<<4) #define SIGNAL_VIPSAFETY (1<<4)
enum PLAYER_ANIM
{
PLAYER_IDLE,
PLAYER_WALK,
PLAYER_JUMP,
PLAYER_SUPERJUMP,
PLAYER_DIE,
PLAYER_ATTACK1,
PLAYER_ATTACK2,
PLAYER_FLINCH,
PLAYER_LARGE_FLINCH,
PLAYER_RELOAD,
PLAYER_HOLDBOMB
};
enum GamedllFunc enum GamedllFunc
{ {
/** /**
@ -20,17 +35,41 @@ enum GamedllFunc
*/ */
RH_GetForceCamera = 1024, RH_GetForceCamera = 1024,
/**
* Description: -
* Params: (const index, const inflictor, const attacker, const Float:fadeTime, const Float:fadeHold, const alpha, Float:color[3])
*/
RH_PlayerBlind,
/**
* Description: -
* Params: (const index, inflictor, attacker, Float:vecSrc[3], Float:vecSpot[3], tracehandle)
*/
RH_RadiusFlash_TraceLine,
// [...] // [...]
RH_GameDLL_End RH_GameDLL_End
}; };
enum GamedllFunc_CBaseAnimating
{
/**
* Description: -
* Params: (const this)
*/
RH_CBaseAnimating_ResetSequenceInfo = 2048,
// [...]
RH_CBaseAnimating_End
};
enum GamedllFunc_CBasePlayer enum GamedllFunc_CBasePlayer
{ {
/** /**
* Description: - * Description: -
* Params: (const this) * Params: (const this)
*/ */
RH_CBasePlayer_Spawn = 2048, RH_CBasePlayer_Spawn = 3072,
/** /**
* Description: - * Description: -
@ -820,6 +859,254 @@ enum CSGameRules_Members
m_bSkipSpawn m_bSkipSpawn
}; };
// CBaseEntity
enum CBaseEntity_Members
{
/**
* Description: -
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
*/
currentammo = 1024,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_buckshot,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_buckshot,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_9mm,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_9mm,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_556nato,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_556nato,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_556natobox,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_556natobox,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_762nato,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_762nato,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_45acp,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_45acp,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_50ae,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_50ae,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_338mag,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_338mag,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_57mm,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_57mm,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
maxammo_357sig,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
ammo_357sig,
/**
* Description: -
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
*/
m_flStartThrow,
/**
* Description: -
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
*/
m_flReleaseThrow,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
m_iSwing,
/**
* Description: -
* Member type: bool
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
has_disconnected,
};
// CBaseAnimating
enum CBaseAnimating_Members
{
/**
* Description: -
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
*/
m_flFrameRate = 2048,
/**
* Description: -
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
*/
m_flGroundSpeed,
/**
* Description: -
* Member type: float
* Get params: Float:get_member(index, member);
* Set params: set_member(index, member, Float:value);
*/
m_flLastEventCheck,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
m_fSequenceFinished,
/**
* Description: -
* Member type: int
* Get params: get_member(index, member);
* Set params: set_member(index, member, value);
*/
m_fSequenceLoops,
};
// CBasePlayer // CBasePlayer
enum CBasePlayer_Members enum CBasePlayer_Members
{ {
@ -829,7 +1116,7 @@ enum CBasePlayer_Members
* Get params: get_member(index, member); * Get params: get_member(index, member);
* Set params: set_member(index, member, value); * Set params: set_member(index, member, value);
*/ */
random_seed = 1024, random_seed = 3072,
/** /**
* Description: - * Description: -
@ -1370,8 +1657,8 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [32] * Member type: char [32]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_szNewName, m_szNewName,
@ -1394,7 +1681,7 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: class CUnifiedSignals * Member type: class CUnifiedSignals
* Get params: get_member(index, member, &signal, &state); * Get params: get_member(index, member, signals[2]); (0 - signal, 1 - state)
* Set params: set_member(index, member, value); * Set params: set_member(index, member, value);
*/ */
m_signals, m_signals,
@ -1690,8 +1977,8 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [17] * Member type: char [17]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_szTextureName, m_szTextureName,
@ -1970,8 +2257,8 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [128] * Member type: char [128]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_SbarString0, m_SbarString0,
@ -2010,8 +2297,8 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [16] * Member type: char [16]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_szTeamName, m_szTeamName,
@ -2026,8 +2313,8 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [32] * Member type: char [32]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_szAnimExtention, m_szAnimExtention,
@ -2202,16 +2489,16 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [256] * Member type: char [256]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_autoBuyString, m_autoBuyString,
/** /**
* Description: - * Description: -
* Member type: char * * Member type: char *
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_rebuyString, m_rebuyString,
@ -2242,8 +2529,8 @@ enum CBasePlayer_Members
/** /**
* Description: - * Description: -
* Member type: char [32] * Member type: char [32]
* Get params: Float:get_member(index, member, const dest[], const lenght); * Get params: get_member(index, member, dest[], const lenght);
* Set params: set_member(index, member, const dest[]); * Set params: set_member(index, member, const source[]);
*/ */
m_lastLocation, m_lastLocation,

View File

@ -29,8 +29,6 @@
#include "voice_gamemgr.h" #include "voice_gamemgr.h"
#define COM_TOKEN_LEN 1500
#define MAX_RULE_BUFFER 1024 #define MAX_RULE_BUFFER 1024
#define MAX_VOTE_MAPS 100 #define MAX_VOTE_MAPS 100
#define MAX_VIP_QUEUES 5 #define MAX_VIP_QUEUES 5

View File

@ -151,6 +151,11 @@
// It's usually defined to something like "__stdcall". // It's usually defined to something like "__stdcall".
#else // _WIN32 #else // _WIN32
#ifdef __FUNCTION__
#undef __FUNCTION__
#endif
#define __FUNCTION__ __func__
#ifndef PAGESIZE #ifndef PAGESIZE
#define PAGESIZE 4096 #define PAGESIZE 4096
#endif #endif

View File

@ -51,8 +51,8 @@ typedef IHookChain<int> IReGameHook_CBasePlayer_Classify;
typedef IHookChainRegistryClass<int, class CBasePlayer> IReGameHookRegistry_CBasePlayer_Classify; typedef IHookChainRegistryClass<int, class CBasePlayer> IReGameHookRegistry_CBasePlayer_Classify;
// CBasePlayer::TraceAttack hook // CBasePlayer::TraceAttack hook
typedef IVoidHookChain<struct entvars_s *, float, Vector, struct TraceResult *, int> IReGameHook_CBasePlayer_TraceAttack; typedef IVoidHookChain<struct entvars_s *, float, Vector &, struct TraceResult *, int> IReGameHook_CBasePlayer_TraceAttack;
typedef IVoidHookChainRegistryClass<class CBasePlayer, struct entvars_s *, float, Vector, struct TraceResult *, int> IReGameHookRegistry_CBasePlayer_TraceAttack; typedef IVoidHookChainRegistryClass<class CBasePlayer, struct entvars_s *, float, Vector &, struct TraceResult *, int> IReGameHookRegistry_CBasePlayer_TraceAttack;
// CBasePlayer::TakeDamage hook // CBasePlayer::TakeDamage hook
typedef IHookChain<int, struct entvars_s *, struct entvars_s *, float, int> IReGameHook_CBasePlayer_TakeDamage; typedef IHookChain<int, struct entvars_s *, struct entvars_s *, float, int> IReGameHook_CBasePlayer_TakeDamage;
@ -123,20 +123,53 @@ typedef IVoidHookChain<float, float, float, int> IReGameHook_CBasePlayer_Blind;
typedef IVoidHookChainRegistryClass<class CBasePlayer, float, float, float, int> IReGameHookRegistry_CBasePlayer_Blind; typedef IVoidHookChainRegistryClass<class CBasePlayer, float, float, float, int> IReGameHookRegistry_CBasePlayer_Blind;
// CBasePlayer::Observer_IsValidTarget hook
// Observer_IsValidTarget hook
typedef IHookChain<class CBaseEntity *, int, bool> IReGameHook_CBasePlayer_Observer_IsValidTarget; typedef IHookChain<class CBaseEntity *, int, bool> IReGameHook_CBasePlayer_Observer_IsValidTarget;
typedef IHookChainRegistryClass<class CBaseEntity *, class CBasePlayer, int, bool> IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget; typedef IHookChainRegistryClass<class CBaseEntity *, class CBasePlayer, int, bool> IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget;
// CBasePlayer::SetAnimation hook
typedef IVoidHookChain<PLAYER_ANIM> IReGameHook_CBasePlayer_SetAnimation;
typedef IVoidHookChainRegistryClass<class CBasePlayer, PLAYER_ANIM> IReGameHookRegistry_CBasePlayer_SetAnimation;
// CBasePlayer::GiveDefaultItems hook
typedef IVoidHookChain<> IReGameHook_CBasePlayer_GiveDefaultItems;
typedef IVoidHookChainRegistryClass<class CBasePlayer> IReGameHookRegistry_CBasePlayer_GiveDefaultItems;
// CBasePlayer::GiveNamedItem hook
typedef IVoidHookChain<const char *> IReGameHook_CBasePlayer_GiveNamedItem;
typedef IVoidHookChainRegistryClass<class CBasePlayer, const char *> IReGameHookRegistry_CBasePlayer_GiveNamedItem;
// CBasePlayer::AddAccount hook
typedef IVoidHookChain<int, bool> IReGameHook_CBasePlayer_AddAccount;
typedef IVoidHookChainRegistryClass<class CBasePlayer, int, bool> IReGameHookRegistry_CBasePlayer_AddAccount;
// CBasePlayer::GiveShield hook
typedef IVoidHookChain<bool> IReGameHook_CBasePlayer_GiveShield;
typedef IVoidHookChainRegistryClass<class CBasePlayer, bool> IReGameHookRegistry_CBasePlayer_GiveShield;
// CBaseAnimating::ResetSequenceInfo hook
typedef IVoidHookChain<> IReGameHook_CBaseAnimating_ResetSequenceInfo;
typedef IVoidHookChainRegistryClass<class CBaseAnimating> IReGameHookRegistry_CBaseAnimating_ResetSequenceInfo;
// GetForceCamera hook // GetForceCamera hook
typedef IHookChain<int, class CBasePlayer *> IReGameHook_GetForceCamera; typedef IHookChain<int, class CBasePlayer *> IReGameHook_GetForceCamera;
typedef IHookChainRegistry<int, class CBasePlayer *> IReGameHookRegistry_GetForceCamera; typedef IHookChainRegistry<int, class CBasePlayer *> IReGameHookRegistry_GetForceCamera;
// PlayerBlind hook
typedef IVoidHookChain<class CBasePlayer *, struct entvars_s *, struct entvars_s *, float, float, int, Vector &> IReGameHook_PlayerBlind;
typedef IVoidHookChainRegistry<class CBasePlayer *, struct entvars_s *, struct entvars_s *, float, float, int, Vector &> IReGameHookRegistry_PlayerBlind;
// RadiusFlash_TraceLine hook
typedef IVoidHookChain<class CBasePlayer *, struct entvars_s *, struct entvars_s *, Vector &, Vector &, struct TraceResult *> IReGameHook_RadiusFlash_TraceLine;
typedef IVoidHookChainRegistry<class CBasePlayer *, struct entvars_s *, struct entvars_s *, Vector &, Vector &, struct TraceResult *> IReGameHookRegistry_RadiusFlash_TraceLine;
class IReGameHookchains { class IReGameHookchains {
public: public:
virtual ~IReGameHookchains() {} virtual ~IReGameHookchains() {}
@ -164,23 +197,38 @@ public:
virtual IReGameHookRegistry_CBasePlayer_RoundRespawn* CBasePlayer_RoundRespawn() = 0; virtual IReGameHookRegistry_CBasePlayer_RoundRespawn* CBasePlayer_RoundRespawn() = 0;
virtual IReGameHookRegistry_CBasePlayer_Blind* CBasePlayer_Blind() = 0; virtual IReGameHookRegistry_CBasePlayer_Blind* CBasePlayer_Blind() = 0;
virtual IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget* CBasePlayer_Observer_IsValidTarget() = 0; virtual IReGameHookRegistry_CBasePlayer_Observer_IsValidTarget* CBasePlayer_Observer_IsValidTarget() = 0;
virtual IReGameHookRegistry_CBasePlayer_SetAnimation* CBasePlayer_SetAnimation() = 0;
virtual IReGameHookRegistry_CBasePlayer_GiveDefaultItems* CBasePlayer_GiveDefaultItems() = 0;
virtual IReGameHookRegistry_CBasePlayer_GiveNamedItem* CBasePlayer_GiveNamedItem() = 0;
virtual IReGameHookRegistry_CBasePlayer_AddAccount* CBasePlayer_AddAccount() = 0;
virtual IReGameHookRegistry_CBasePlayer_GiveShield* CBasePlayer_GiveShield() = 0;
virtual IReGameHookRegistry_CBaseAnimating_ResetSequenceInfo* CBaseAnimating_ResetSequenceInfo() = 0;
virtual IReGameHookRegistry_GetForceCamera* GetForceCamera() = 0; virtual IReGameHookRegistry_GetForceCamera* GetForceCamera() = 0;
virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0;
virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0;
}; };
struct ReGameFuncs_t { struct ReGameFuncs_t {
class CBaseEntity *(*UTIL_PlayerByIndex)(int playerIndex); class CBaseEntity *(*UTIL_PlayerByIndex)(int playerIndex);
class ICSPlayer *(*CBASE_TO_CSPLAYER)(class CBaseEntity *pEntity); class ICSPlayer *(*CBASE_TO_CSPLAYER)(class CBaseEntity *pEntity);
class ICSEntity *(*CBASE_TO_CSENTITY)(CBaseEntity *pEntity); class ICSEntity *(*CBASE_TO_CSENTITY)(class CBaseEntity *pEntity);
class ICSPlayer *(*INDEX_TO_CSPLAYER)(int iPlayerIndex); class ICSPlayer *(*INDEX_TO_CSPLAYER)(int iPlayerIndex);
class ICSEntity *(*INDEX_TO_CSENTITY)(int iEntityIndex); class ICSEntity *(*INDEX_TO_CSENTITY)(int iEntityIndex);
struct edict_s *(*CREATE_NAMED_ENTITY2)(string_t iClass); struct edict_s *(*CREATE_NAMED_ENTITY2)(string_t iClass);
void (*ChangeString)(char *&dest, const char *source);
void (*RadiusDamage)(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
void (*ClearMultiDamage)();
void (*ApplyMultiDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker);
void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType);
}; };
class IReGameApi { class IReGameApi {

File diff suppressed because it is too large Load Diff

View File

@ -202,7 +202,9 @@
<ClInclude Include="..\src\member_list.h" /> <ClInclude Include="..\src\member_list.h" />
<ClInclude Include="..\src\mod_regamedll_api.h" /> <ClInclude Include="..\src\mod_regamedll_api.h" />
<ClInclude Include="..\src\mod_rehlds_api.h" /> <ClInclude Include="..\src\mod_rehlds_api.h" />
<ClInclude Include="..\src\natives.h" /> <ClInclude Include="..\src\natives_misc.h" />
<ClInclude Include="..\src\natives_hookchains.h" />
<ClInclude Include="..\src\natives_members.h" />
<ClInclude Include="..\src\precompiled.h" /> <ClInclude Include="..\src\precompiled.h" />
<ClInclude Include="..\src\reapi_utils.h" /> <ClInclude Include="..\src\reapi_utils.h" />
</ItemGroup> </ItemGroup>
@ -236,8 +238,9 @@
<ClCompile Include="..\src\main.cpp" /> <ClCompile Include="..\src\main.cpp" />
<ClCompile Include="..\src\meta_api.cpp" /> <ClCompile Include="..\src\meta_api.cpp" />
<ClCompile Include="..\src\mod_rehlds_api.cpp" /> <ClCompile Include="..\src\mod_rehlds_api.cpp" />
<ClCompile Include="..\src\natives.cpp" /> <ClCompile Include="..\src\natives_misc.cpp" />
<ClCompile Include="..\src\natives_member.cpp" /> <ClCompile Include="..\src\natives_hookchains.cpp" />
<ClCompile Include="..\src\natives_members.cpp" />
<ClCompile Include="..\src\precompiled.cpp"> <ClCompile Include="..\src\precompiled.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@ -358,6 +361,10 @@
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<OmitFramePointers>true</OmitFramePointers>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -49,6 +49,9 @@
<Filter Include="amxmodx\scripting\include"> <Filter Include="amxmodx\scripting\include">
<UniqueIdentifier>{c4bfa412-f9f4-4b90-9f02-3c1531e2ac23}</UniqueIdentifier> <UniqueIdentifier>{c4bfa412-f9f4-4b90-9f02-3c1531e2ac23}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="src\natives">
<UniqueIdentifier>{1e41b4f5-768c-437f-af6d-51432194e332}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\include\metamod\dllapi.h"> <ClInclude Include="..\include\metamod\dllapi.h">
@ -591,9 +594,6 @@
<ClInclude Include="..\src\amxxmodule.h"> <ClInclude Include="..\src\amxxmodule.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\natives.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\src\precompiled.h"> <ClInclude Include="..\src\precompiled.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
@ -621,6 +621,15 @@
<ClInclude Include="..\src\hook_manager.h"> <ClInclude Include="..\src\hook_manager.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\src\natives_hookchains.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\natives_members.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\natives_misc.h">
<Filter>src\natives</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp"> <ClCompile Include="..\include\cssdk\common\parsemsg.cpp">
@ -644,9 +653,6 @@
<ClCompile Include="..\src\meta_api.cpp"> <ClCompile Include="..\src\meta_api.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\natives.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\precompiled.cpp"> <ClCompile Include="..\src\precompiled.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
@ -671,9 +677,6 @@
<ClCompile Include="..\src\member_list.cpp"> <ClCompile Include="..\src\member_list.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\natives_member.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\hook_manager.cpp"> <ClCompile Include="..\src\hook_manager.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
@ -686,6 +689,15 @@
<ClCompile Include="..\src\h_export.cpp"> <ClCompile Include="..\src\h_export.cpp">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\natives_hookchains.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\src\natives_members.cpp">
<Filter>src\natives</Filter>
</ClCompile>
<ClCompile Include="..\src\natives_misc.cpp">
<Filter>src\natives</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\extra\amxmodx\scripting\include\reapi.inc"> <None Include="..\extra\amxmodx\scripting\include\reapi.inc">

View File

@ -159,7 +159,10 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
*(void **)((unsigned long)&g_amxxapi + g_funcrequests[i].offset) = fptr; *(void **)((unsigned long)&g_amxxapi + g_funcrequests[i].offset) = fptr;
} }
RegisterNatives(); RegisterNatives_HookChains();
RegisterNatives_Members();
RegisterNatives_Misc();
return AMXX_OK; return AMXX_OK;
} }
@ -206,3 +209,25 @@ NOINLINE void MF_LogError(AMX *amx, int err, const char *fmt, ...)
g_amxxapi.LogError(amx, err, "[%s] %s", g_ModuleInfo.logtag, msg); g_amxxapi.LogError(amx, err, "[%s] %s", g_ModuleInfo.logtag, msg);
} }
char* getAmxStringTemp(cell* src, char* dest, size_t max, size_t* len)
{
char* start = dest;
while (*src && --max)
*dest++ = (char)*src++;
*dest = '\0';
if (len)
*len = dest - start;
return start;
}
void setAmxString(cell* dest, const char* string, size_t max)
{
while (*string && max--)
*dest++ = (cell)*string++;
*dest = 0;
}

View File

@ -378,15 +378,6 @@ typedef edict_t * ( *PFN_GET_PLAYER_EDICT ) ( int /*id*/ );
typedef void * ( *PFN_GET_PLAYER_EDICT ) ( int /*id*/ ); typedef void * ( *PFN_GET_PLAYER_EDICT ) ( int /*id*/ );
#endif #endif
typedef void * ( *PFN_PLAYER_PROP_ADDR ) ( int /*id*/, int /*prop*/ ); typedef void * ( *PFN_PLAYER_PROP_ADDR ) ( int /*id*/, int /*prop*/ );
#ifdef MEMORY_TEST
typedef void * ( *PFN_ALLOCATOR ) ( const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const size_t /*size*/ );
typedef void * ( *PFN_REALLOCATOR ) ( const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
typedef void(*PFN_DEALLOCATOR) ( const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const void* /*addr*/ );
#endif
typedef int(*PFN_AMX_EXEC) ( AMX* /*amx*/, cell* /*return val*/, int /*index*/ ); typedef int(*PFN_AMX_EXEC) ( AMX* /*amx*/, cell* /*return val*/, int /*index*/ );
typedef int(*PFN_AMX_EXECV) ( AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/ ); typedef int(*PFN_AMX_EXECV) ( AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/ );
typedef int(*PFN_AMX_ALLOT) ( AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/ ); typedef int(*PFN_AMX_ALLOT) ( AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/ );
@ -503,5 +494,32 @@ extern amxxapi_t g_amxxapi;
void MF_Log(const char *fmt, ...); void MF_Log(const char *fmt, ...);
void MF_LogError(AMX *amx, int err, const char *fmt, ...); void MF_LogError(AMX *amx, int err, const char *fmt, ...);
char* getAmxStringTemp(cell* src, char* dest, size_t max, size_t* len = nullptr);
void setAmxString(cell* dest, const char* string, size_t max);
inline cell* getAmxAddr(AMX *amx, cell amx_addr)
{
return (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
}
struct getAmxString
{
getAmxString(cell* src, size_t* len = nullptr)
{
getAmxStringTemp(src, temp, sizeof temp - 1, len);
}
getAmxString(AMX* amx, cell addr, size_t* len = nullptr)
{
getAmxStringTemp(getAmxAddr(amx, addr), temp, sizeof temp - 1, len);
}
operator char *()
{
return temp;
}
char temp[1024];
};
#endif // __AMXXMODULE_H__ #endif // __AMXXMODULE_H__

View File

@ -2,6 +2,11 @@
CAPI_Config api_cfg; CAPI_Config api_cfg;
CAPI_Config::CAPI_Config() : m_api_rehlds(false), m_api_regame(false)
{
}
bool CAPI_Config::Init() bool CAPI_Config::Init()
{ {
m_api_rehlds = RehldsApi_Init(); m_api_rehlds = RehldsApi_Init();
@ -9,3 +14,17 @@ bool CAPI_Config::Init()
return true; return true;
} }
void CAPI_Config::ServerActivate() const
{
if (m_api_regame) {
g_pCSGameRules = (CHalfLifeMultiplay **)g_ReGameApi->GetGameData()->GetGameRules();
}
}
void CAPI_Config::ServerDeactivate() const
{
if (m_api_regame) {
g_pCSGameRules = nullptr;
}
}

View File

@ -5,11 +5,15 @@
class CAPI_Config { class CAPI_Config {
public: public:
CAPI_Config();
bool Init(); bool Init();
bool hasReHLDS() const { return m_api_rehlds; } bool hasReHLDS() const { return m_api_rehlds; }
bool hasReGameDLL() const { return m_api_regame; } bool hasReGameDLL() const { return m_api_regame; }
void ServerActivate() const;
void ServerDeactivate() const;
private: private:
// to provide API functions // to provide API functions
bool m_api_rehlds; // some useful functions bool m_api_rehlds; // some useful functions

View File

@ -1,5 +1,6 @@
#include "precompiled.h" #include "precompiled.h"
extern void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
extern void ServerDeactivate_Post(); extern void ServerDeactivate_Post();
DLL_FUNCTIONS gFunctionTable = DLL_FUNCTIONS gFunctionTable =
@ -25,7 +26,7 @@ DLL_FUNCTIONS gFunctionTable =
NULL, // pfnClientPutInServer NULL, // pfnClientPutInServer
NULL, // pfnClientCommand NULL, // pfnClientCommand
NULL, // pfnClientUserInfoChanged NULL, // pfnClientUserInfoChanged
NULL, // pfnServerActivate &ServerActivate, // pfnServerActivate
NULL, // pfnServerDeactivate NULL, // pfnServerDeactivate
NULL, // pfnPlayerPreThink NULL, // pfnPlayerPreThink
NULL, // pfnPlayerPostThink NULL, // pfnPlayerPostThink

View File

@ -1,36 +1,48 @@
#include "precompiled.h" #include "precompiled.h"
CHook *g_currentHookChain = nullptr; hookctx_t* g_hookCtx;
/* /*
* ReHLDS functions * 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) 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)
{ {
if (callVoidForward_Pre(RH_SV_StartSound, recipients, ENTINDEX(entity), channel, sample, volume, attenuation, fFlags, pitch)) { auto original = [chain](int _recipients, int _entity, int _channel, const char *_sample, int _volume, float _attenuation, int _fFlags, int _pitch)
chain->callNext(recipients, entity, channel, sample, volume, attenuation, fFlags, pitch); {
} chain->callNext(_recipients, INDEXENT(_entity), _channel, _sample, _volume, _attenuation, _fFlags, _pitch);
};
callVoidForward_Post(RH_SV_StartSound, recipients, ENTINDEX(entity), channel, sample, volume, attenuation, fFlags, pitch); callVoidForward(RH_SV_StartSound, original, recipients, indexOfEdict(entity), channel, sample, volume, attenuation, fFlags, pitch);
} }
void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt) void SV_DropClient(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *fmt)
{ {
if (callVoidForward_Pre(RH_SV_DropClient, cl->GetId(), crash, fmt)) { auto original = [chain](int _cl, bool _crash, const char *_fmt)
chain->callNext(cl, crash, fmt); {
} chain->callNext(g_RehldsSvs->GetClient(_cl), _crash, _fmt);
};
callVoidForward_Post(RH_SV_DropClient, cl->GetId(), crash, fmt); callVoidForward(RH_SV_DropClient, original, cl->GetId(), crash, fmt);
} }
void SV_ActivateServer(IRehldsHook_SV_ActivateServer *chain, int runPhysics) void SV_ActivateServer(IRehldsHook_SV_ActivateServer *chain, int runPhysics)
{ {
callVoidForward(chain, RH_SV_ActivateServer, runPhysics); auto original = [chain](int _runPhysics)
{
chain->callNext(_runPhysics);
};
callVoidForward(RH_SV_ActivateServer, original, runPhysics);
} }
void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value) void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value)
{ {
callVoidForward(chain, RH_Cvar_DirectSet, var, value); auto original = [chain](cvar_t *_var, const char *_value)
{
chain->callNext(_var, _value);
};
callVoidForward(RH_Cvar_DirectSet, original, var, value);
} }
/* /*
@ -38,297 +50,326 @@ void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *
*/ */
void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis) void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_Spawn, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_Spawn, pthis->entindex()); callVoidForward(RH_CBasePlayer_Spawn, original, pthis->entindex());
} }
void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer *pthis) void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_Precache, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_Precache, pthis->entindex()); callVoidForward(RH_CBasePlayer_Precache, original, pthis->entindex());
} }
int CBasePlayer_ObjectCaps(IReGameHook_CBasePlayer_ObjectCaps *chain, CBasePlayer *pthis) int CBasePlayer_ObjectCaps(IReGameHook_CBasePlayer_ObjectCaps *chain, CBasePlayer *pthis)
{ {
int ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis)
int origresult = 0; // return by call original function {
return chain->callNext();
};
if (callForward_Pre(RH_CBasePlayer_ObjectCaps, pthis->entindex())) { return callForward<int>(RH_CBasePlayer_ObjectCaps, original, pthis->entindex());
origresult = chain->callNext();
}
if (callForward_Post(RH_CBasePlayer_ObjectCaps, pthis->entindex())) {
// return original
return origresult;
}
// return from override
return g_currentHookChain->m_data.m_interger;
} }
int CBasePlayer_Classify(IReGameHook_CBasePlayer_Classify *chain, CBasePlayer *pthis) int CBasePlayer_Classify(IReGameHook_CBasePlayer_Classify *chain, CBasePlayer *pthis)
{ {
//int ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis)
int origresult = 0; // return by call original function
if (callForward_Pre(RH_CBasePlayer_Classify, pthis->entindex())) {
origresult = chain->callNext();
}
if (callForward_Post(RH_CBasePlayer_Classify, pthis->entindex())) {
// return original
return origresult;
}
// return from override
return g_currentHookChain->m_data.m_interger;
}
void CBasePlayer_TraceAttack(IReGameHook_CBasePlayer_TraceAttack *chain, CBasePlayer *pthis, entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_TraceAttack, pthis->entindex(), ENTINDEX(pevAttacker), flDamage, g_amxxapi.PrepareCellArrayA(reinterpret_cast<cell *>(&vecDir), 3, false), ptr, bitsDamageType)) { return chain->callNext();
chain->callNext(pevAttacker, flDamage, vecDir, ptr, bitsDamageType); };
return callForward<int>(RH_CBasePlayer_Classify, original, pthis->entindex());
} }
callVoidForward_Post(RH_CBasePlayer_TraceAttack, pthis->entindex(), ENTINDEX(pevAttacker), flDamage, g_amxxapi.PrepareCellArrayA(reinterpret_cast<cell *>(&vecDir), 3, false), ptr, bitsDamageType); void CBasePlayer_TraceAttack(IReGameHook_CBasePlayer_TraceAttack *chain, CBasePlayer *pthis, entvars_t *pevAttacker, float flDamage, Vector& vecDir, TraceResult *ptr, int bitsDamageType)
{
Vector vecDirCopy(vecDir);
auto original = [chain, &vecDirCopy](int _pthis, int _pevAttacker, float _flDamage, cell _vecDir, int _ptr, int _bitsDamageType)
{
chain->callNext(PEV(_pevAttacker), _flDamage, vecDirCopy, (TraceResult *)_ptr, _bitsDamageType);
};
callVoidForward(RH_CBasePlayer_TraceAttack, original, pthis->entindex(), indexOfEdict(pevAttacker), flDamage, g_amxxapi.PrepareCellArrayA(reinterpret_cast<cell *>(&vecDirCopy), 3, true), int(ptr), bitsDamageType);
} }
int CBasePlayer_TakeDamage(IReGameHook_CBasePlayer_TakeDamage *chain, CBasePlayer *pthis, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) int CBasePlayer_TakeDamage(IReGameHook_CBasePlayer_TakeDamage *chain, CBasePlayer *pthis, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{ {
//int ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis, int _pevInflictor, int _pevAttacker, float _flDamage, int _bitsDamageType)
int origresult = 0; // return by call original function {
return chain->callNext(PEV(_pevInflictor), PEV(_pevAttacker), _flDamage, _bitsDamageType);
};
if (callForward_Pre(RH_CBasePlayer_TakeDamage, pthis->entindex(), ENTINDEX(pevInflictor), ENTINDEX(pevAttacker), flDamage, bitsDamageType)) { return callForward<int>(RH_CBasePlayer_TakeDamage, original, pthis->entindex(), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), flDamage, bitsDamageType);
origresult = chain->callNext(pevInflictor, pevAttacker, flDamage, bitsDamageType);
}
if (callForward_Post(RH_CBasePlayer_TakeDamage, pthis->entindex(), ENTINDEX(pevInflictor), ENTINDEX(pevAttacker), flDamage, bitsDamageType)) {
// return original
return origresult;
}
// return from override
return g_currentHookChain->m_data.m_interger;
} }
int CBasePlayer_TakeHealth(IReGameHook_CBasePlayer_TakeHealth *chain, CBasePlayer *pthis, float flHealth, int bitsDamageType) int CBasePlayer_TakeHealth(IReGameHook_CBasePlayer_TakeHealth *chain, CBasePlayer *pthis, float flHealth, int bitsDamageType)
{ {
//int ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis, float _flHealth, int _bitsDamageType)
int origresult = 0; // return by call original function {
return chain->callNext(_flHealth, _bitsDamageType);
};
if (callForward_Pre(RH_CBasePlayer_TakeHealth, pthis->entindex(), flHealth, bitsDamageType)) { return callForward<int>(RH_CBasePlayer_TakeHealth, original, pthis->entindex(), flHealth, bitsDamageType);
origresult = chain->callNext(flHealth, bitsDamageType);
}
if (callForward_Post(RH_CBasePlayer_TakeHealth, pthis->entindex(), flHealth, bitsDamageType)) {
// return original
return origresult;
}
// return from override
return g_currentHookChain->m_data.m_interger;
} }
void CBasePlayer_Killed(IReGameHook_CBasePlayer_Killed *chain, CBasePlayer *pthis, entvars_t *pevAttacker, int iGib) void CBasePlayer_Killed(IReGameHook_CBasePlayer_Killed *chain, CBasePlayer *pthis, entvars_t *pevAttacker, int iGib)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_Killed, pthis->entindex(), ENTINDEX(pevAttacker), iGib)) { auto original = [chain](int _pthis, int _pevAttacker, int _iGib)
chain->callNext(pevAttacker, iGib); {
} chain->callNext(PEV(_pevAttacker), _iGib);
};
callVoidForward_Post(RH_CBasePlayer_Killed, pthis->entindex(), ENTINDEX(pevAttacker), iGib); callVoidForward(RH_CBasePlayer_Killed, original, pthis->entindex(), indexOfEdict(pevAttacker), iGib);
} }
void CBasePlayer_AddPoints(IReGameHook_CBasePlayer_AddPoints *chain, CBasePlayer *pthis, int score, BOOL bAllowNegativeScore) void CBasePlayer_AddPoints(IReGameHook_CBasePlayer_AddPoints *chain, CBasePlayer *pthis, int score, BOOL bAllowNegativeScore)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_AddPoints, pthis->entindex(), score, bAllowNegativeScore)) { auto original = [chain](int _pthis, int _score, BOOL _bAllowNegativeScore)
chain->callNext(score, bAllowNegativeScore); {
} chain->callNext(_score, _bAllowNegativeScore);
};
callVoidForward_Post(RH_CBasePlayer_AddPoints, pthis->entindex(), score, bAllowNegativeScore); callVoidForward(RH_CBasePlayer_AddPoints, original, pthis->entindex(), score, bAllowNegativeScore);
} }
void CBasePlayer_AddPointsToTeam(IReGameHook_CBasePlayer_AddPointsToTeam *chain, CBasePlayer *pthis, int score, BOOL bAllowNegativeScore) void CBasePlayer_AddPointsToTeam(IReGameHook_CBasePlayer_AddPointsToTeam *chain, CBasePlayer *pthis, int score, BOOL bAllowNegativeScore)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_AddPointsToTeam, pthis->entindex(), score, bAllowNegativeScore)) { auto original = [chain](int _pthis, int _score, BOOL _bAllowNegativeScore)
chain->callNext(score, bAllowNegativeScore); {
} chain->callNext(_score, _bAllowNegativeScore);
};
callVoidForward_Post(RH_CBasePlayer_AddPointsToTeam, pthis->entindex(), score, bAllowNegativeScore); callVoidForward(RH_CBasePlayer_AddPointsToTeam, original, pthis->entindex(), score, bAllowNegativeScore);
} }
BOOL CBasePlayer_AddPlayerItem(IReGameHook_CBasePlayer_AddPlayerItem *chain, CBasePlayer *pthis, CBasePlayerItem *pItem) BOOL CBasePlayer_AddPlayerItem(IReGameHook_CBasePlayer_AddPlayerItem *chain, CBasePlayer *pthis, CBasePlayerItem *pItem)
{ {
//BOOL ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis, int _pItem)
BOOL origresult = 0; // return by call original function {
return chain->callNext(getPrivate<CBasePlayerItem>(_pItem));
};
if (callForward_Pre(RH_CBasePlayer_AddPlayerItem, pthis->entindex(), pItem->entindex())) { return callForward<BOOL>(RH_CBasePlayer_AddPlayerItem, original, pthis->entindex(), pItem->entindex());
origresult = chain->callNext(pItem);
}
if (callForward_Post(RH_CBasePlayer_AddPlayerItem, pthis->entindex(), pItem->entindex())) {
// return original
return origresult;
}
// return from override
return (BOOL)g_currentHookChain->m_data.m_interger;
} }
BOOL CBasePlayer_RemovePlayerItem(IReGameHook_CBasePlayer_RemovePlayerItem *chain, CBasePlayer *pthis, CBasePlayerItem *pItem) BOOL CBasePlayer_RemovePlayerItem(IReGameHook_CBasePlayer_RemovePlayerItem *chain, CBasePlayer *pthis, CBasePlayerItem *pItem)
{ {
//BOOL ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis, int _pItem)
BOOL origresult = 0; // return by call original function {
return chain->callNext(getPrivate<CBasePlayerItem>(_pItem));
};
if (callForward_Pre(RH_CBasePlayer_RemovePlayerItem, pthis->entindex(), pItem->entindex())) { return callForward<BOOL>(RH_CBasePlayer_RemovePlayerItem, original, pthis->entindex(), pItem->entindex());
origresult = chain->callNext(pItem);
}
if (callForward_Post(RH_CBasePlayer_RemovePlayerItem, pthis->entindex(), pItem->entindex())) {
// return original
return origresult;
}
// return from override
return (BOOL)g_currentHookChain->m_data.m_interger;
} }
int CBasePlayer_GiveAmmo(IReGameHook_CBasePlayer_GiveAmmo *chain, CBasePlayer *pthis, int iAmount, char *szName, int iMax) int CBasePlayer_GiveAmmo(IReGameHook_CBasePlayer_GiveAmmo *chain, CBasePlayer *pthis, int iAmount, char *szName, int iMax)
{ {
//int ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pthis, int _iAmount, char *_szName, int _iMax)
int origresult = 0; // return by call original function {
return chain->callNext(_iAmount, _szName, _iMax);
};
if (callForward_Pre(RH_CBasePlayer_GiveAmmo, pthis->entindex(), iAmount, szName, iMax)) { return callForward<int>(RH_CBasePlayer_GiveAmmo, original, pthis->entindex(), iAmount, szName, iMax);
origresult = chain->callNext(iAmount, szName, iMax);
}
if (callForward_Post(RH_CBasePlayer_GiveAmmo, pthis->entindex(), iAmount, szName, iMax)) {
// return original
return origresult;
}
// return from override
return g_currentHookChain->m_data.m_interger;
} }
void CBasePlayer_ResetMaxSpeed(IReGameHook_CBasePlayer_ResetMaxSpeed *chain, CBasePlayer *pthis) void CBasePlayer_ResetMaxSpeed(IReGameHook_CBasePlayer_ResetMaxSpeed *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_ResetMaxSpeed, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_ResetMaxSpeed, pthis->entindex()); callVoidForward(RH_CBasePlayer_ResetMaxSpeed, original, pthis->entindex());
} }
void CBasePlayer_Jump(IReGameHook_CBasePlayer_Jump *chain, CBasePlayer *pthis) void CBasePlayer_Jump(IReGameHook_CBasePlayer_Jump *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_Jump, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_Jump, pthis->entindex()); callVoidForward(RH_CBasePlayer_Jump, original, pthis->entindex());
} }
void CBasePlayer_Duck(IReGameHook_CBasePlayer_Duck *chain, CBasePlayer *pthis) void CBasePlayer_Duck(IReGameHook_CBasePlayer_Duck *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_Duck, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_Duck, pthis->entindex()); callVoidForward(RH_CBasePlayer_Duck, original, pthis->entindex());
} }
void CBasePlayer_PreThink(IReGameHook_CBasePlayer_PreThink *chain, CBasePlayer *pthis) void CBasePlayer_PreThink(IReGameHook_CBasePlayer_PreThink *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_PreThink, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_PreThink, pthis->entindex()); callVoidForward(RH_CBasePlayer_PreThink, original, pthis->entindex());
} }
void CBasePlayer_PostThink(IReGameHook_CBasePlayer_PostThink *chain, CBasePlayer *pthis) void CBasePlayer_PostThink(IReGameHook_CBasePlayer_PostThink *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_PostThink, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_PostThink, pthis->entindex()); callVoidForward(RH_CBasePlayer_PostThink, original, pthis->entindex());
} }
void CBasePlayer_UpdateClientData(IReGameHook_CBasePlayer_UpdateClientData *chain, CBasePlayer *pthis) void CBasePlayer_UpdateClientData(IReGameHook_CBasePlayer_UpdateClientData *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_UpdateClientData, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_UpdateClientData, pthis->entindex()); callVoidForward(RH_CBasePlayer_UpdateClientData, original, pthis->entindex());
} }
void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain, CBasePlayer *pthis) void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_ImpulseCommands, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_ImpulseCommands, pthis->entindex()); callVoidForward(RH_CBasePlayer_ImpulseCommands, original, pthis->entindex());
} }
void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBasePlayer *pthis) void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBasePlayer *pthis)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_RoundRespawn, pthis->entindex())) { auto original = [chain](int _pthis)
{
chain->callNext(); chain->callNext();
} };
callVoidForward_Post(RH_CBasePlayer_RoundRespawn, pthis->entindex()); callVoidForward(RH_CBasePlayer_RoundRespawn, original, pthis->entindex());
} }
void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha) void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha)
{ {
if (callVoidForward_Pre(RH_CBasePlayer_Blind, pthis->entindex(), flUntilTime, flHoldTime, flFadeTime, iAlpha)) { auto original = [chain](int _pthis, float _flUntilTime, float _flHoldTime, float _flFadeTime, int _iAlpha)
chain->callNext(flUntilTime, flHoldTime, flFadeTime, iAlpha); {
} chain->callNext(_flUntilTime, _flHoldTime, _flFadeTime, _iAlpha);
};
callVoidForward_Post(RH_CBasePlayer_Blind, pthis->entindex(), flUntilTime, flHoldTime, flFadeTime, iAlpha); callVoidForward(RH_CBasePlayer_Blind, original, pthis->entindex(), flUntilTime, flHoldTime, flFadeTime, iAlpha);
} }
CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam) CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam)
{ {
//CBaseEntity *ownresult = nullptr; // return own for OVERRIDE auto original = [chain](int _pthis, int _iPlayerIndex, bool _bSameTeam)
CBaseEntity *origresult = nullptr; // return by call original function {
return chain->callNext(_iPlayerIndex, _bSameTeam);
};
if (callForward_Pre(RH_CBasePlayer_Observer_IsValidTarget, pthis->entindex(), iPlayerIndex, bSameTeam)) { return callForward<CBaseEntity *>(RH_CBasePlayer_Observer_IsValidTarget, original, pthis->entindex(), iPlayerIndex, bSameTeam);
origresult = chain->callNext(iPlayerIndex, bSameTeam);
} }
if (callForward_Post(RH_CBasePlayer_Observer_IsValidTarget, pthis->entindex(), iPlayerIndex, bSameTeam)) { void CBasePlayer_SetAnimation(IReGameHook_CBasePlayer_SetAnimation *chain, CBasePlayer *pthis, PLAYER_ANIM playerAnim)
// return original {
return origresult; auto original = [chain](int _pthis, PLAYER_ANIM _playerAnim)
{
chain->callNext(_playerAnim);
};
callVoidForward(RH_CBasePlayer_SetAnimation, original, pthis->entindex(), playerAnim);
} }
// return from override void CBasePlayer_GiveDefaultItems(IReGameHook_CBasePlayer_GiveDefaultItems *chain, CBasePlayer *pthis)
return g_currentHookChain->m_data.m_classptr; {
auto original = [chain](int _pthis)
{
chain->callNext();
};
callVoidForward(RH_CBasePlayer_GiveDefaultItems, original, pthis->entindex());
}
void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBasePlayer *pthis, const char *pszName)
{
auto original = [chain](int _pthis, const char *_pszName)
{
chain->callNext(_pszName);
};
callVoidForward(RH_CBasePlayer_GiveNamedItem, original, pthis->entindex(), pszName);
}
void CBasePlayer_AddAccount(IReGameHook_CBasePlayer_AddAccount *chain, CBasePlayer *pthis, int amount, bool bTrackChange)
{
auto original = [chain](int _pthis, int _amount, bool _bTrackChange)
{
chain->callNext(_amount, _bTrackChange);
};
callVoidForward(RH_CBasePlayer_AddAccount, original, pthis->entindex(), amount, bTrackChange);
}
void CBasePlayer_GiveShield(IReGameHook_CBasePlayer_GiveShield *chain, CBasePlayer *pthis, bool bDeploy)
{
auto original = [chain](int _pthis, bool _bDeploy)
{
chain->callNext(_bDeploy);
};
callVoidForward(RH_CBasePlayer_GiveShield, original, pthis->entindex(), bDeploy);
}
void CBaseAnimating_ResetSequenceInfo(IReGameHook_CBaseAnimating_ResetSequenceInfo *chain, CBaseAnimating *pthis)
{
auto original = [chain](int _pthis)
{
chain->callNext();
};
callVoidForward(RH_CBaseAnimating_ResetSequenceInfo, original, pthis->entindex());
} }
int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver) int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver)
{ {
//int ownresult = 0; // return own for OVERRIDE auto original = [chain](int _pObserver)
int origresult = 0; // return by call original function {
return chain->callNext(getPrivate<CBasePlayer>(_pObserver));
};
if (callForward_Pre(RH_GetForceCamera, pObserver->entindex())) { return callForward<int>(RH_GetForceCamera, original, pObserver->entindex());
origresult = chain->callNext(pObserver);
} }
if (callForward_Post(RH_GetForceCamera, pObserver->entindex())) { void PlayerBlind(IReGameHook_PlayerBlind *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, float fadeTime, float fadeHold, int alpha, Vector& color)
// return original {
return origresult; Vector colorCopy(color);
auto original = [chain, &colorCopy](int _pPlayer, int _pevInflictor, int _pevAttacker, float _fadeTime, float _fadeHold, int _alpha, cell _color)
{
chain->callNext(getPrivate<CBasePlayer>(_pPlayer), PEV(_pevInflictor), PEV(_pevAttacker), _fadeTime, _fadeHold, _alpha, colorCopy);
};
callVoidForward(RH_PlayerBlind, original, pPlayer->entindex(), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), fadeTime, fadeHold, alpha, g_amxxapi.PrepareCellArrayA(reinterpret_cast<cell *>(&colorCopy), 3, true));
} }
// return from override void RadiusFlash_TraceLine(IReGameHook_RadiusFlash_TraceLine *chain, CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector& vecSrc, Vector& vecSpot, TraceResult *ptr)
return g_currentHookChain->m_data.m_interger; {
Vector vecSrcCopy(vecSrc), vecSpotCopy(vecSpot);
auto original = [chain, &vecSrcCopy, &vecSpotCopy](int _pPlayer, int _pevInflictor, int _pevAttacker, cell _vecSrc, cell _vecSpot, int _ptr)
{
chain->callNext(getPrivate<CBasePlayer>(_pPlayer), PEV(_pevInflictor), PEV(_pevAttacker), vecSrcCopy, vecSpotCopy, (TraceResult *)_ptr);
};
callVoidForward(RH_RadiusFlash_TraceLine, original, pPlayer->entindex(), indexOfEdict(pevInflictor), indexOfEdict(pevAttacker), g_amxxapi.PrepareCellArrayA(reinterpret_cast<cell *>(&vecSrcCopy), 3, true), g_amxxapi.PrepareCellArrayA(reinterpret_cast<cell *>(&vecSpotCopy), 3, true), int(ptr));
} }

View File

@ -1,119 +1,193 @@
#pragma once #pragma once
enum // hookchain return type
enum HookChainState
{ {
RH_UNSET = 0, HC_CONTINUE = 0,
RH_IGNORED, // plugin didn't take any action HC_OVERRIDE,
RH_HANDLED, // plugin did something, but real function should still be called HC_SUPERCEDE,
RH_OVERRIDE, // call real function, but use my return value HC_BREAK
RH_SUPERCEDE // skip real function; use my return value
}; };
// for hookchain return // api types
enum HookChainReturn enum AType : uint8
{ {
RHV_STRING = 0, ATYPE_INTEGER = 0,
RHV_FLOAT, ATYPE_FLOAT,
RHV_INTEGER, ATYPE_STRING,
RHV_CLASSPTR ATYPE_CLASSPTR
}; };
extern CHook *g_currentHookChain; struct retval_t
{
bool set;
AType type;
union
{
char* _string;
float _float;
int _interger;
CBaseEntity* _classptr;
};
};
inline AType getApiType(int) { return ATYPE_INTEGER; }
inline AType getApiType(unsigned) { return ATYPE_INTEGER; }
inline AType getApiType(cvar_s *) { return ATYPE_INTEGER; }
inline AType getApiType(float) { return ATYPE_FLOAT; }
inline AType getApiType(const char *) { return ATYPE_STRING; }
inline AType getApiType(CBaseEntity *) { return ATYPE_CLASSPTR; }
#define MAX_ARGS 12u
template<size_t current>
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, t_args... args)
{
args_type[current] = getApiType(T());
if (sizeof...(args) && current + 1 < MAX_ARGS)
setupArgTypes<current + 1>(args_type, args...);
}
struct hookctx_t
{
template<typename ...t_args> template<typename ...t_args>
inline bool callVoidForward_Pre(int func, t_args... args) hookctx_t(size_t arg_count, t_args... args) : args_ptr()
{ {
auto hook = hooklist[func]; args_count = min(arg_count, MAX_ARGS);
register int ret = RH_UNSET; setupArgTypes(args_type, args...);
for (auto it = hook->pre.begin(), end = hook->pre.end(); it != end; ++it) }
void reset(size_t arg_ptr, AType ret_type = ATYPE_INTEGER)
{ {
if ((*it)->GetState() == FSTATE_OK) retVal.set = false;
retVal.type = ret_type;
args_ptr = arg_ptr;
}
retval_t retVal;
size_t args_count;
size_t args_ptr;
AType args_type[MAX_ARGS];
};
extern hookctx_t* g_hookCtx;
template <typename original_t, typename ...f_args>
NOINLINE void DLLEXPORT _callVoidForward(const hook_t* hook, original_t original, volatile f_args... args)
{ {
ret = g_amxxapi.ExecuteForward((*it)->GetForwardID(), args...); g_hookCtx->reset(size_t(&original) + sizeof(original));
int hc_state = HC_CONTINUE;
for (auto& fwd : hook->pre)
{
if (fwd->GetState() == FSTATE_ENABLED)
{
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
if (ret == HC_BREAK) {
return;
}
if (ret > hc_state)
hc_state = ret;
} }
} }
// no supercede, continue to call original func if (hc_state != HC_SUPERCEDE)
return (ret < RH_SUPERCEDE); original(args...);
}
template <typename ...t_args> for (auto& fwd : hook->post) {
inline void callVoidForward_Post(int func, t_args... args) if (fwd->GetState() == FSTATE_ENABLED) {
{ auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
auto hook = hooklist[func];
for (auto it = hook->post.begin(), end = hook->post.end(); it != end; ++it) if (ret == HC_BREAK)
{ break;
if ((*it)->GetState() == FSTATE_OK)
{
g_currentHookChain = (*it);
g_amxxapi.ExecuteForward((*it)->GetForwardID(), args...);
} }
} }
} }
template <typename t_chain, typename ...t_args> template <typename original_t, typename ...f_args>
inline void callVoidForward(t_chain chain, int func, t_args... args) void callVoidForward(size_t func, original_t original, f_args... args)
{ {
auto hook = hooklist[func]; #ifndef _WIN32
register int ret = RH_UNSET; static
for (auto it = hook->pre.begin(), end = hook->pre.end(); it != end; ++it) #endif
hookctx_t hookCtx(sizeof...(args), args...);
g_hookCtx = &hookCtx;
_callVoidForward(g_hookManager.getHookFast(func), original, args...);
g_hookCtx = nullptr;
}
template <typename R, typename original_t, typename ...f_args>
NOINLINE R DLLEXPORT _callForward(const hook_t* hook, original_t original, volatile f_args... args)
{ {
if ((*it)->GetState() == FSTATE_OK) auto& hookCtx = *g_hookCtx;
hookCtx.reset(size_t(&original) + sizeof(original), getApiType(R()));
int hc_state = HC_CONTINUE;
for (auto& fwd : hook->pre)
{ {
ret = g_amxxapi.ExecuteForward((*it)->GetForwardID(), args...); if (fwd->GetState() == FSTATE_ENABLED)
{
auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
if (ret == HC_CONTINUE)
continue;
if (!hookCtx.retVal.set) {
g_amxxapi.LogError(fwd->GetAmx(), AMX_ERR_CALLBACK, "%s", "can't suppress original function call without new return value set");
continue;
}
if (ret == HC_BREAK) {
return *(R *)&hookCtx.retVal._interger;
}
if (ret > hc_state)
hc_state = ret;
} }
} }
// no supercede, continue to call original func if (hc_state != HC_SUPERCEDE)
if (ret < RH_SUPERCEDE)
{ {
chain->callNext(args...); auto retVal = original(args...);
if (hc_state != HC_OVERRIDE)
hookCtx.retVal._interger = *(int *)&retVal;
} }
// Post for (auto& fwd : hook->post) {
for (auto it = hook->post.begin(), end = hook->post.end(); it != end; ++it) if (fwd->GetState() == FSTATE_ENABLED) {
{ auto ret = g_amxxapi.ExecuteForward(fwd->GetIndex(), args...);
if ((*it)->GetState() == FSTATE_OK)
{ if (ret == HC_BREAK)
g_currentHookChain = (*it); break;
g_amxxapi.ExecuteForward((*it)->GetForwardID(), args...);
}
} }
} }
template <typename ...t_args> return *(R *)&hookCtx.retVal._interger;
inline bool callForward_Pre(int func, t_args... args)
{
auto hook = hooklist[func];
register int ret = RH_UNSET;
for (auto it = hook->pre.begin(), end = hook->pre.end(); it != end; ++it)
{
if ((*it)->GetState() == FSTATE_OK)
{
ret = g_amxxapi.ExecuteForward((*it)->GetForwardID(), args...);
}
} }
// no supercede, continue to call original func template <typename R, typename original_t, typename ...f_args>
return (ret < RH_SUPERCEDE); R callForward(size_t func, original_t original, f_args... args)
} {
#ifndef _WIN32
static
#endif
hookctx_t hookCtx(sizeof...(args), args...);
template <typename ...t_args> g_hookCtx = &hookCtx;
inline bool callForward_Post(int func, t_args... args) auto ret = _callForward<R>(g_hookManager.getHookFast(func), original, args...);
{ g_hookCtx = nullptr;
auto hook = hooklist[func];
register int ret = RH_UNSET;
for (auto it = hook->post.begin(), end = hook->post.end(); it != end; ++it)
{
if ((*it)->GetState() == FSTATE_OK)
{
g_currentHookChain = (*it);
ret = g_amxxapi.ExecuteForward((*it)->GetForwardID(), args...);
}
}
// no override return ret;
return (ret < RH_OVERRIDE);
} }
// rehlds functions // rehlds functions
@ -124,13 +198,15 @@ void Cvar_DirectSet(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *
// regamedll functions // regamedll functions
int GetForceCamera(IReGameHook_GetForceCamera *chain, CBasePlayer *pObserver); 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 // regamedll functions - player
void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis); void CBasePlayer_Spawn(IReGameHook_CBasePlayer_Spawn *chain, CBasePlayer *pthis);
void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer *pthis); void CBasePlayer_Precache(IReGameHook_CBasePlayer_Precache *chain, CBasePlayer *pthis);
int CBasePlayer_ObjectCaps(IReGameHook_CBasePlayer_ObjectCaps *chain, CBasePlayer *pthis); int CBasePlayer_ObjectCaps(IReGameHook_CBasePlayer_ObjectCaps *chain, CBasePlayer *pthis);
int CBasePlayer_Classify(IReGameHook_CBasePlayer_Classify *chain, CBasePlayer *pthis); int CBasePlayer_Classify(IReGameHook_CBasePlayer_Classify *chain, CBasePlayer *pthis);
void CBasePlayer_TraceAttack(IReGameHook_CBasePlayer_TraceAttack *chain, CBasePlayer *pthis, entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); void CBasePlayer_TraceAttack(IReGameHook_CBasePlayer_TraceAttack *chain, CBasePlayer *pthis, entvars_t *pevAttacker, float flDamage, Vector& vecDir, TraceResult *ptr, int bitsDamageType);
int CBasePlayer_TakeDamage(IReGameHook_CBasePlayer_TakeDamage *chain, CBasePlayer *pthis, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType); int CBasePlayer_TakeDamage(IReGameHook_CBasePlayer_TakeDamage *chain, CBasePlayer *pthis, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
int CBasePlayer_TakeHealth(IReGameHook_CBasePlayer_TakeHealth *chain, CBasePlayer *pthis, float flHealth, int bitsDamageType); int CBasePlayer_TakeHealth(IReGameHook_CBasePlayer_TakeHealth *chain, CBasePlayer *pthis, float flHealth, int bitsDamageType);
void CBasePlayer_Killed(IReGameHook_CBasePlayer_Killed *chain, CBasePlayer *pthis, entvars_t *pevAttacker, int iGib); void CBasePlayer_Killed(IReGameHook_CBasePlayer_Killed *chain, CBasePlayer *pthis, entvars_t *pevAttacker, int iGib);
@ -148,4 +224,12 @@ void CBasePlayer_UpdateClientData(IReGameHook_CBasePlayer_UpdateClientData *chai
void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain, CBasePlayer *pthis); void CBasePlayer_ImpulseCommands(IReGameHook_CBasePlayer_ImpulseCommands *chain, CBasePlayer *pthis);
void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBasePlayer *pthis); void CBasePlayer_RoundRespawn(IReGameHook_CBasePlayer_RoundRespawn *chain, CBasePlayer *pthis);
void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha); void CBasePlayer_Blind(IReGameHook_CBasePlayer_Blind *chain, CBasePlayer *pthis, float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha);
CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam); CBaseEntity *CBasePlayer_Observer_IsValidTarget(IReGameHook_CBasePlayer_Observer_IsValidTarget *chain, CBasePlayer *pthis, int iPlayerIndex, bool bSameTeam);
void CBasePlayer_SetAnimation(IReGameHook_CBasePlayer_SetAnimation *chain, CBasePlayer *pthis, PLAYER_ANIM playerAnim);
void CBasePlayer_GiveDefaultItems(IReGameHook_CBasePlayer_GiveDefaultItems *chain, CBasePlayer *pthis);
void CBasePlayer_GiveNamedItem(IReGameHook_CBasePlayer_GiveNamedItem *chain, CBasePlayer *pthis, const char *pszName);
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,8 +1,64 @@
#include "precompiled.h" #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; int regfunc::current_cell = 1;
#define ENG(h) { {}, {}, #h, "ReHLDS", [](){ return api_cfg.hasReHLDS(); }, ((!(RH_##h & 1023) ? regfunc::current_cell = 1, true : false) || (RH_##h & 1023) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h " doesn't match hook definition"), [](){ g_RehldsHookchains->##h##()->registerHook(&##h); }, [](){ g_RehldsHookchains->##h##()->unregisterHook(&##h); }} #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); }}
hook_t hooklist_engine[] = { hook_t hooklist_engine[] = {
ENG(SV_StartSound), ENG(SV_StartSound),
ENG(SV_DropClient), ENG(SV_DropClient),
@ -10,9 +66,15 @@ hook_t hooklist_engine[] = {
ENG(Cvar_DirectSet) ENG(Cvar_DirectSet)
}; };
#define DLL(h) { {}, {}, #h, "ReGameDLL", [](){ return api_cfg.hasReGameDLL(); }, ((!(RH_##h & 1023) ? regfunc::current_cell = 1, true : false) || (RH_##h & 1023) == regfunc::current_cell++) ? regfunc(h) : regfunc(#h " doesn't match hook definition"), [](){ g_ReGameHookchains->##h##()->registerHook(&##h); }, [](){ g_ReGameHookchains->##h##()->unregisterHook(&##h); }} #define DLL(h) { {}, {}, #h, "ReGameDLL", [](){ return api_cfg.hasReGameDLL(); }, ((!(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_ReGameHookchains->##h##()->registerHook(&##h); }, [](){ g_ReGameHookchains->##h##()->unregisterHook(&##h); }}
hook_t hooklist_gamedll[] = { hook_t hooklist_gamedll[] = {
DLL(GetForceCamera) DLL(GetForceCamera),
DLL(PlayerBlind),
DLL(RadiusFlash_TraceLine)
};
hook_t hooklist_animating[] = {
DLL(CBaseAnimating_ResetSequenceInfo)
}; };
hook_t hooklist_player[] = { hook_t hooklist_player[] = {
@ -38,23 +100,41 @@ hook_t hooklist_player[] = {
DLL(CBasePlayer_ImpulseCommands), DLL(CBasePlayer_ImpulseCommands),
DLL(CBasePlayer_RoundRespawn), DLL(CBasePlayer_RoundRespawn),
DLL(CBasePlayer_Blind), DLL(CBasePlayer_Blind),
DLL(CBasePlayer_Observer_IsValidTarget), DLL(CBasePlayer_Observer_IsValidTarget),
DLL(CBasePlayer_SetAnimation),
DLL(CBasePlayer_GiveDefaultItems),
DLL(CBasePlayer_GiveNamedItem),
DLL(CBasePlayer_AddAccount),
DLL(CBasePlayer_GiveShield),
}; };
hooklist_t hooklist; hook_t* hooklist_t::getHookSafe(size_t hook)
hook_t *hooklist_t::operator[](size_t hook) const
{ {
#define CASE(h) case ht_##h: if (index < arraysize(hooklist_##h)) return &hooklist_##h[index]; else break; #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_RANGE_REGION); const auto table = hooks_tables_e(hook / MAX_REGION_RANGE);
const auto index = hook & (MAX_RANGE_REGION - 1); const auto index = hook & (MAX_REGION_RANGE - 1);
switch (table) { switch (table) {
CASE(engine) CASE(engine)
CASE(gamedll) CASE(gamedll)
CASE(animating)
CASE(player) CASE(player)
} }
return nullptr; 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

@ -1,114 +1,60 @@
#pragma once #pragma once
#include "reapi_utils.h"
#define MAX_RANGE_REGION 1024 #define MAX_REGION_RANGE 1024
#define BEGIN_FUNC_REGION(x) (MAX_RANGE_REGION * hooklist_t::hooks_tables_e::ht_##x) #define BEGIN_FUNC_REGION(x) (MAX_REGION_RANGE * hooklist_t::hooks_tables_e::ht_##x)
#define MAX_HOOK_FORWARDS 1024
typedef bool (*ablfunc_t)(); typedef bool (*reqfunc_t)();
typedef int (*regfunc_t)(AMX *, const char *); typedef int (*regfunc_t)(AMX *, const char *);
typedef void (*regchain_t)(); 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 *, 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 *, 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_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_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_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 struct hook_t
{ {
std::vector<class CHook *> pre; // array pre forward std::vector<class CAmxxHook *> pre; // pre forwards
std::vector<class CHook *> post; // array post forward std::vector<class CAmxxHook *> post; // post forwards
const char *func_name; // name functions const char *func_name; // function name
const char *depend_name; // platform dependency const char *depend_name; // platform dependency
ablfunc_t availableFunc; reqfunc_t checkRequirements;
regfunc_t registerForward; // register AMXX forward and get ID regfunc_t registerForward; // AMXX forward registration function
regchain_t registerHookchain; // register function-hook API regchain_t registerHookchain; // register re* API hook
regchain_t unregisterHookchain; // unregister function-hook API regchain_t unregisterHookchain; // unregister re* API hook
void clear();
}; };
extern hook_t hooklist_engine[];
extern hook_t hooklist_gamedll[];
extern hook_t hooklist_animating[];
extern hook_t hooklist_player[];
struct hooklist_t struct hooklist_t
{ {
hook_t *operator[](size_t hook) const; hook_t *operator[](size_t hook) const
{
#define CASE(h) case ht_##h: return &hooklist_##h[index];
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(animating)
CASE(player)
}
return nullptr;
}
static hook_t *getHookSafe(size_t hook);
enum hooks_tables_e enum hooks_tables_e
{ {
ht_engine, ht_engine,
ht_gamedll, ht_gamedll,
ht_animating,
ht_player, ht_player,
ht_end ht_end
@ -161,11 +107,21 @@ enum EngineFunc
enum GamedllFunc enum GamedllFunc
{ {
RH_GetForceCamera = BEGIN_FUNC_REGION(gamedll), RH_GetForceCamera = BEGIN_FUNC_REGION(gamedll),
RH_PlayerBlind,
RH_RadiusFlash_TraceLine,
// [...] // [...]
RH_GameDLL_End RH_GameDLL_End
}; };
enum GamedllFunc_CBaseAnimating
{
RH_CBaseAnimating_ResetSequenceInfo = BEGIN_FUNC_REGION(animating),
// [...]
RH_CBaseAnimating_End
};
enum GamedllFunc_CBasePlayer enum GamedllFunc_CBasePlayer
{ {
// CBasePlayer virtual // CBasePlayer virtual
@ -193,11 +149,12 @@ enum GamedllFunc_CBasePlayer
RH_CBasePlayer_Blind, RH_CBasePlayer_Blind,
RH_CBasePlayer_Observer_IsValidTarget, RH_CBasePlayer_Observer_IsValidTarget,
RH_CBasePlayer_SetAnimation,
RH_CBasePlayer_GiveDefaultItems,
RH_CBasePlayer_GiveNamedItem,
RH_CBasePlayer_AddAccount,
RH_CBasePlayer_GiveShield,
// [...] // [...]
RH_CBasePlayer_End RH_CBasePlayer_End
}; };
extern hook_t hooklist_engine[];
extern hook_t hooklist_player[];
extern hooklist_t hooklist;

View File

@ -2,39 +2,79 @@
CHookManager g_hookManager; CHookManager g_hookManager;
CHook *CHookManager::addHandler(int func, int forward, bool post) int CHookManager::addHandler(AMX* amx, int func, int forward, bool post) const
{ {
if (!hooklist[func]->post.size() && !hooklist[func]->pre.size()) auto hook = m_hooklist.getHookSafe(func);
if (!hook->post.size() && !hook->pre.size())
{ {
// register API hookchain // API hookchain
hooklist[func]->registerHookchain(); hook->registerHookchain();
} }
CHook *hook = new CHook(forward); auto& dest = post ? hook->post : hook->pre;
if (post) dest.push_back(new CAmxxHook(amx, forward));
{ int id = func * MAX_HOOK_FORWARDS + dest.size();
hooklist[func]->post.push_back(hook); return post ? -id : id; // use unsigned ids for post hooks
}
else
{
hooklist[func]->pre.push_back(hook);
} }
return hook; AMX* CAmxxHook::GetAmx() const
{
return m_amx;
} }
void CHookManager::clearHandlers() int CAmxxHook::GetIndex() const
{
return m_index;
}
fwdstate CAmxxHook::GetState() const
{
return m_state;
}
void CAmxxHook::SetState(fwdstate st)
{
m_state = st;
}
void CHookManager::clearHandlers() const
{ {
#define CLEAR_HOOKLIST(__END__, __START__)\ #define CLEAR_HOOKLIST(__END__, __START__)\
for (size_t i = BEGIN_FUNC_REGION(__START__); i < RH_##__END__##_End; ++i) {\ for (size_t i = BEGIN_FUNC_REGION(__START__); i < RH_##__END__##_End; ++i) {\
if (hooklist[i] == nullptr)\ if (m_hooklist[i])\
continue;\ m_hooklist[i]->clear();\
hooklist[i]->pre.clear();\
hooklist[i]->post.clear();\
hooklist[i]->unregisterHookchain();\
} }
CLEAR_HOOKLIST(EngineFunc, engine); CLEAR_HOOKLIST(EngineFunc, engine);
CLEAR_HOOKLIST(GameDLL, gamedll); CLEAR_HOOKLIST(GameDLL, gamedll);
CLEAR_HOOKLIST(CBasePlayer, player); CLEAR_HOOKLIST(CBasePlayer, player);
} }
hook_t* CHookManager::getHook(size_t func) const
{
return m_hooklist.getHookSafe(func);
}
CAmxxHook* CHookManager::getAmxxHook(cell handle) const
{
bool post = handle < 0;
if (post)
handle = ~handle;
else
handle--;
const size_t func = handle / MAX_HOOK_FORWARDS;
const size_t id = handle & (MAX_HOOK_FORWARDS - 1);
auto hook = m_hooklist.getHookSafe(func);
if (hook)
{
auto& forwards = post ? hook->post : hook->pre;
if (id < forwards.size())
return forwards[id];
}
return nullptr;
}

View File

@ -1,43 +1,44 @@
#pragma once #pragma once
#include "hook_list.h" #include "hook_list.h"
//#define MAX_RANGE_HOOKS RH_EngineFunc_End + RH_GameDLL_End + RH_CBasePlayer_End
enum fwdstate enum fwdstate
{ {
FSTATE_INVALID = 0, FSTATE_INVALID = 0,
FSTATE_OK, FSTATE_ENABLED,
FSTATE_PAUSE, FSTATE_PAUSED,
FSTATE_STOP FSTATE_STOPPED
}; };
class CHook class CAmxxHook
{ {
public: public:
CHook(int forward_index) : m_forward(forward_index), m_state(FSTATE_OK) {}; CAmxxHook(AMX* amx, int index) : m_index(index), m_state(FSTATE_ENABLED), m_amx(amx) {};
int GetForwardID() const { return m_forward; } int GetIndex() const;
fwdstate GetState() const { return m_state; } fwdstate GetState() const;
AMX* GetAmx() const;
void SetState(fwdstate st);
public: private:
int m_forward; int m_index;
fwdstate m_state; fwdstate m_state;
AMX* m_amx;
struct data_return_t
{
char* m_string;
float m_float;
int m_interger;
CBaseEntity* m_classptr;
};
data_return_t m_data;
}; };
class CHookManager class CHookManager
{ {
public: public:
void clearHandlers(); void clearHandlers() const;
CHook *addHandler(int func, int forward, bool post); cell addHandler(AMX* amx, int func, int forward, bool post) const;
hook_t* getHook(size_t func) const;
CAmxxHook* getAmxxHook(cell hook) const;
hook_t* getHookFast(size_t func) const {
return m_hooklist[func];
}
private:
hooklist_t m_hooklist;
}; };
extern CHookManager g_hookManager; extern CHookManager g_hookManager;

View File

@ -1,5 +1,7 @@
#include "precompiled.h" #include "precompiled.h"
edict_t* g_pEdicts;
bool OnMetaAttach() bool OnMetaAttach()
{ {
// initialize API // initialize API
@ -15,7 +17,18 @@ void OnMetaDetach()
g_hookManager.clearHandlers(); g_hookManager.clearHandlers();
} }
void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
g_pEdicts = pEdictList;
api_cfg.ServerActivate();
SET_META_RESULT(MRES_IGNORED);
}
void ServerDeactivate_Post() void ServerDeactivate_Post()
{ {
api_cfg.ServerActivate();
g_hookManager.clearHandlers(); g_hookManager.clearHandlers();
SET_META_RESULT(MRES_IGNORED);
} }

View File

@ -3,7 +3,7 @@
struct regmember struct regmember
{ {
template<typename T> 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.size = sizeof(T);
member.max_size = sizeof(T); member.max_size = sizeof(T);
@ -11,7 +11,7 @@ struct regmember
member.type = member_type; member.type = member_type;
} }
template<typename T> 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.size = sizeof(T);
member.max_size = maxsize; member.max_size = maxsize;
@ -19,10 +19,7 @@ struct regmember
member.type = member_type; member.type = member_type;
} }
regmember(const char *error) regmember(const char *error) { UTIL_SysError(error); } // to cause a amxx module failure.
{
UTIL_SysError("%s", error);
} // to cause a amxx module failure.
operator member_t() const { return member; } operator member_t() const { return member; }
member_t member; member_t member;
@ -32,9 +29,8 @@ struct regmember
static char mem_dummy[0xffff]; static char mem_dummy[0xffff];
int regmember::current_cell = 1; int regmember::current_cell = 1;
#define GM_MEMBERS(mx, mtype) ((!(mx & 1023) ? regmember::current_cell = 1, true : false) || (mx & 1023) == regmember::current_cell++) ? regmember(((CHalfLifeMultiplay *)&mem_dummy)->##mx, sizeof(((CHalfLifeMultiplay *)&mem_dummy)->##mx), offsetof(CHalfLifeMultiplay, mx), mtype) : regmember(#mx " doesn't match hook definition") #define GM_MEMBERS(mx, mtype) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember(((CHalfLifeMultiplay *)&mem_dummy)->##mx, sizeof(((CHalfLifeMultiplay *)&mem_dummy)->##mx), offsetof(CHalfLifeMultiplay, mx), mtype) : regmember(#mx " doesn't match member definition")
#define GM_VOICE_MEMBERS(mx, mtype) ((!(mx & 1023) ? regmember::current_cell = 1, true : false) || (mx & 1023) == regmember::current_cell++) ? regmember(((CVoiceGameMgr *)&mem_dummy)->##mx, sizeof(((CVoiceGameMgr *)&mem_dummy)->##mx), offsetof(CVoiceGameMgr, mx), mtype) : regmember(#mx " doesn't match hook definition") #define GM_VOICE_MEMBERS(mx, mtype) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember(((CVoiceGameMgr *)&mem_dummy)->##mx, sizeof(((CVoiceGameMgr *)&mem_dummy)->##mx), offsetof(CVoiceGameMgr, mx), mtype) : regmember(#mx " doesn't match member definition")
member_t memberlist_gamerules[] = { member_t memberlist_gamerules[] = {
GM_MEMBERS(m_bFreezePeriod, MEMBER_INTEGER), GM_MEMBERS(m_bFreezePeriod, MEMBER_INTEGER),
GM_MEMBERS(m_bBombDropped, MEMBER_INTEGER), GM_MEMBERS(m_bBombDropped, MEMBER_INTEGER),
@ -94,7 +90,7 @@ member_t memberlist_gamerules[] = {
GM_MEMBERS(m_iTotalArmourCount, MEMBER_INTEGER), GM_MEMBERS(m_iTotalArmourCount, MEMBER_INTEGER),
GM_MEMBERS(m_iUnBalancedRounds, MEMBER_INTEGER), GM_MEMBERS(m_iUnBalancedRounds, MEMBER_INTEGER),
GM_MEMBERS(m_iNumEscapeRounds, MEMBER_INTEGER), GM_MEMBERS(m_iNumEscapeRounds, MEMBER_INTEGER),
GM_MEMBERS(m_iMapVotes, MEMBER_INTEGER), // ARRAY 100 GM_MEMBERS(m_iMapVotes, MEMBER_INTEGER),
GM_MEMBERS(m_iLastPick, MEMBER_INTEGER), GM_MEMBERS(m_iLastPick, MEMBER_INTEGER),
GM_MEMBERS(m_iMaxMapTime, MEMBER_INTEGER), GM_MEMBERS(m_iMaxMapTime, MEMBER_INTEGER),
GM_MEMBERS(m_iMaxRounds, MEMBER_INTEGER), GM_MEMBERS(m_iMaxRounds, MEMBER_INTEGER),
@ -105,7 +101,7 @@ member_t memberlist_gamerules[] = {
GM_MEMBERS(m_flForceChaseCamValue, MEMBER_FLOAT), GM_MEMBERS(m_flForceChaseCamValue, MEMBER_FLOAT),
GM_MEMBERS(m_flFadeToBlackValue, MEMBER_FLOAT), GM_MEMBERS(m_flFadeToBlackValue, MEMBER_FLOAT),
GM_MEMBERS(m_pVIP, MEMBER_CLASSPTR), GM_MEMBERS(m_pVIP, MEMBER_CLASSPTR),
GM_MEMBERS(VIPQueue, MEMBER_CLASSPTR), // ARRAY [5] GM_MEMBERS(VIPQueue, MEMBER_CLASSPTR),
GM_MEMBERS(m_flIntermissionEndTime, MEMBER_FLOAT), GM_MEMBERS(m_flIntermissionEndTime, MEMBER_FLOAT),
GM_MEMBERS(m_flIntermissionStartTime, MEMBER_FLOAT), GM_MEMBERS(m_flIntermissionStartTime, MEMBER_FLOAT),
GM_MEMBERS(m_iEndIntermissionButtonHit, MEMBER_INTEGER), GM_MEMBERS(m_iEndIntermissionButtonHit, MEMBER_INTEGER),
@ -119,8 +115,45 @@ member_t memberlist_gamerules[] = {
GM_MEMBERS(m_bSkipSpawn, MEMBER_BOOL), GM_MEMBERS(m_bSkipSpawn, MEMBER_BOOL),
}; };
#define PL_MEMBERS(mx, mtype) ((!(mx & 1023) ? regmember::current_cell = 1, true : false) || (mx & 1023) == regmember::current_cell++) ? regmember(((CBasePlayer *)&mem_dummy)->##mx, sizeof(((CBasePlayer *)&mem_dummy)->##mx), offsetof(CBasePlayer, mx), mtype) : regmember(#mx " doesn't match hook definition") #define BASE_MEMBERS(mx, mtype) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember(((CBaseEntity *)&mem_dummy)->##mx, sizeof(((CBaseEntity *)&mem_dummy)->##mx), offsetof(CBaseEntity, mx), mtype) : regmember(#mx " doesn't match member definition")
member_t memberlist_base[] = {
BASE_MEMBERS(currentammo, MEMBER_FLOAT),
BASE_MEMBERS(maxammo_buckshot, MEMBER_INTEGER),
BASE_MEMBERS(ammo_buckshot, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_9mm, MEMBER_INTEGER),
BASE_MEMBERS(ammo_9mm, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_556nato, MEMBER_INTEGER),
BASE_MEMBERS(ammo_556nato, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_556natobox, MEMBER_INTEGER),
BASE_MEMBERS(ammo_556natobox, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_762nato, MEMBER_INTEGER),
BASE_MEMBERS(ammo_762nato, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_45acp, MEMBER_INTEGER),
BASE_MEMBERS(ammo_45acp, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_50ae, MEMBER_INTEGER),
BASE_MEMBERS(ammo_50ae, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_338mag, MEMBER_INTEGER),
BASE_MEMBERS(ammo_338mag, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_57mm, MEMBER_INTEGER),
BASE_MEMBERS(ammo_57mm, MEMBER_INTEGER),
BASE_MEMBERS(maxammo_357sig, MEMBER_INTEGER),
BASE_MEMBERS(ammo_357sig, MEMBER_INTEGER),
BASE_MEMBERS(m_flStartThrow, MEMBER_FLOAT),
BASE_MEMBERS(m_flReleaseThrow, MEMBER_FLOAT),
BASE_MEMBERS(m_iSwing, MEMBER_INTEGER),
BASE_MEMBERS(has_disconnected, MEMBER_BOOL),
};
#define ANIM_MEMBERS(mx, mtype) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember(((CBaseAnimating *)&mem_dummy)->##mx, sizeof(((CBaseAnimating *)&mem_dummy)->##mx), offsetof(CBaseAnimating, mx), mtype) : regmember(#mx " doesn't match member definition")
member_t memberlist_animating[] = {
ANIM_MEMBERS(m_flFrameRate, MEMBER_FLOAT),
ANIM_MEMBERS(m_flGroundSpeed, MEMBER_FLOAT),
ANIM_MEMBERS(m_flLastEventCheck, MEMBER_FLOAT),
ANIM_MEMBERS(m_fSequenceFinished, MEMBER_INTEGER),
ANIM_MEMBERS(m_fSequenceLoops, MEMBER_INTEGER),
};
#define PL_MEMBERS(mx, mtype) ((!(mx & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (mx & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember(((CBasePlayer *)&mem_dummy)->##mx, sizeof(((CBasePlayer *)&mem_dummy)->##mx), offsetof(CBasePlayer, mx), mtype) : regmember(#mx " doesn't match member definition")
member_t memberlist_player[] = { member_t memberlist_player[] = {
PL_MEMBERS(random_seed, MEMBER_INTEGER), PL_MEMBERS(random_seed, MEMBER_INTEGER),
PL_MEMBERS(m_usPlayerBleed, MEMBER_SHORT), PL_MEMBERS(m_usPlayerBleed, MEMBER_SHORT),
@ -158,7 +191,7 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_iIgnoreGlobalChat, MEMBER_INTEGER), PL_MEMBERS(m_iIgnoreGlobalChat, MEMBER_INTEGER),
PL_MEMBERS(m_bHasNightVision, MEMBER_BOOL), PL_MEMBERS(m_bHasNightVision, MEMBER_BOOL),
PL_MEMBERS(m_bNightVisionOn, MEMBER_BOOL), PL_MEMBERS(m_bNightVisionOn, MEMBER_BOOL),
PL_MEMBERS(m_vRecentPath, MEMBER_VECTOR), // ARRAY [20] PL_MEMBERS(m_vRecentPath, MEMBER_VECTOR),
PL_MEMBERS(m_flIdleCheckTime, MEMBER_FLOAT), PL_MEMBERS(m_flIdleCheckTime, MEMBER_FLOAT),
PL_MEMBERS(m_flRadioTime, MEMBER_FLOAT), PL_MEMBERS(m_flRadioTime, MEMBER_FLOAT),
PL_MEMBERS(m_iRadioMessages, MEMBER_INTEGER), PL_MEMBERS(m_iRadioMessages, MEMBER_INTEGER),
@ -191,7 +224,7 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_bReceivesNoMoneyNextRound, MEMBER_BOOL), PL_MEMBERS(m_bReceivesNoMoneyNextRound, MEMBER_BOOL),
PL_MEMBERS(m_iTimeCheckAllowed, MEMBER_INTEGER), PL_MEMBERS(m_iTimeCheckAllowed, MEMBER_INTEGER),
PL_MEMBERS(m_bHasChangedName, MEMBER_BOOL), PL_MEMBERS(m_bHasChangedName, MEMBER_BOOL),
PL_MEMBERS(m_szNewName, MEMBER_CHAR_ARRAY), // ARRAY [32] PL_MEMBERS(m_szNewName, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_bIsDefusing, MEMBER_BOOL), PL_MEMBERS(m_bIsDefusing, MEMBER_BOOL),
PL_MEMBERS(m_tmHandleSignals, MEMBER_FLOAT), PL_MEMBERS(m_tmHandleSignals, MEMBER_FLOAT),
PL_MEMBERS(m_signals, MEMBER_SIGNALS), PL_MEMBERS(m_signals, MEMBER_SIGNALS),
@ -211,7 +244,7 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_flSndRoomtype, MEMBER_FLOAT), PL_MEMBERS(m_flSndRoomtype, MEMBER_FLOAT),
PL_MEMBERS(m_flSndRange, MEMBER_FLOAT), PL_MEMBERS(m_flSndRange, MEMBER_FLOAT),
PL_MEMBERS(m_flFallVelocity, MEMBER_FLOAT), PL_MEMBERS(m_flFallVelocity, MEMBER_FLOAT),
PL_MEMBERS(m_rgItems, MEMBER_INTEGER), // ARRAY [4] PL_MEMBERS(m_rgItems, MEMBER_INTEGER),
PL_MEMBERS(m_fNewAmmo, MEMBER_INTEGER), PL_MEMBERS(m_fNewAmmo, MEMBER_INTEGER),
PL_MEMBERS(m_afPhysicsFlags, MEMBER_INTEGER), PL_MEMBERS(m_afPhysicsFlags, MEMBER_INTEGER),
PL_MEMBERS(m_fNextSuicideTime, MEMBER_FLOAT), PL_MEMBERS(m_fNextSuicideTime, MEMBER_FLOAT),
@ -221,17 +254,17 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_flDuckTime, MEMBER_FLOAT), PL_MEMBERS(m_flDuckTime, MEMBER_FLOAT),
PL_MEMBERS(m_flWallJumpTime, MEMBER_FLOAT), PL_MEMBERS(m_flWallJumpTime, MEMBER_FLOAT),
PL_MEMBERS(m_flSuitUpdate, MEMBER_FLOAT), PL_MEMBERS(m_flSuitUpdate, MEMBER_FLOAT),
PL_MEMBERS(m_rgSuitPlayList, MEMBER_INTEGER), // ARRAY [4] PL_MEMBERS(m_rgSuitPlayList, MEMBER_INTEGER),
PL_MEMBERS(m_iSuitPlayNext, MEMBER_INTEGER), PL_MEMBERS(m_iSuitPlayNext, MEMBER_INTEGER),
PL_MEMBERS(m_rgiSuitNoRepeat, MEMBER_INTEGER), // ARRAY [32] PL_MEMBERS(m_rgiSuitNoRepeat, MEMBER_INTEGER),
PL_MEMBERS(m_rgflSuitNoRepeatTime, MEMBER_FLOAT), // ARRAY [32] PL_MEMBERS(m_rgflSuitNoRepeatTime, MEMBER_FLOAT),
PL_MEMBERS(m_lastDamageAmount, MEMBER_INTEGER), PL_MEMBERS(m_lastDamageAmount, MEMBER_INTEGER),
PL_MEMBERS(m_tbdPrev, MEMBER_FLOAT), PL_MEMBERS(m_tbdPrev, MEMBER_FLOAT),
PL_MEMBERS(m_flgeigerRange, MEMBER_FLOAT), PL_MEMBERS(m_flgeigerRange, MEMBER_FLOAT),
PL_MEMBERS(m_flgeigerDelay, MEMBER_FLOAT), PL_MEMBERS(m_flgeigerDelay, MEMBER_FLOAT),
PL_MEMBERS(m_igeigerRangePrev, MEMBER_INTEGER), PL_MEMBERS(m_igeigerRangePrev, MEMBER_INTEGER),
PL_MEMBERS(m_iStepLeft, MEMBER_INTEGER), PL_MEMBERS(m_iStepLeft, MEMBER_INTEGER),
PL_MEMBERS(m_szTextureName, MEMBER_CHAR_ARRAY), // ARRAY [17] PL_MEMBERS(m_szTextureName, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_chTextureType, MEMBER_BYTE), PL_MEMBERS(m_chTextureType, MEMBER_BYTE),
PL_MEMBERS(m_idrowndmg, MEMBER_INTEGER), PL_MEMBERS(m_idrowndmg, MEMBER_INTEGER),
PL_MEMBERS(m_idrownrestored, MEMBER_INTEGER), PL_MEMBERS(m_idrownrestored, MEMBER_INTEGER),
@ -258,22 +291,22 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_pActiveItem, MEMBER_CLASSPTR), PL_MEMBERS(m_pActiveItem, MEMBER_CLASSPTR),
PL_MEMBERS(m_pClientActiveItem, MEMBER_CLASSPTR), PL_MEMBERS(m_pClientActiveItem, MEMBER_CLASSPTR),
PL_MEMBERS(m_pLastItem, MEMBER_CLASSPTR), PL_MEMBERS(m_pLastItem, MEMBER_CLASSPTR),
PL_MEMBERS(m_rgAmmo, MEMBER_INTEGER), // ARRAY [32] PL_MEMBERS(m_rgAmmo, MEMBER_INTEGER),
PL_MEMBERS(m_rgAmmoLast, MEMBER_INTEGER), // ARRAY [32] PL_MEMBERS(m_rgAmmoLast, MEMBER_INTEGER),
PL_MEMBERS(m_vecAutoAim, MEMBER_VECTOR), PL_MEMBERS(m_vecAutoAim, MEMBER_VECTOR),
PL_MEMBERS(m_fOnTarget, MEMBER_INTEGER), PL_MEMBERS(m_fOnTarget, MEMBER_INTEGER),
PL_MEMBERS(m_iDeaths, MEMBER_INTEGER), PL_MEMBERS(m_iDeaths, MEMBER_INTEGER),
PL_MEMBERS(m_izSBarState, MEMBER_INTEGER), // ARRAY [4] PL_MEMBERS(m_izSBarState, MEMBER_INTEGER),
PL_MEMBERS(m_flNextSBarUpdateTime, MEMBER_FLOAT), PL_MEMBERS(m_flNextSBarUpdateTime, MEMBER_FLOAT),
PL_MEMBERS(m_flStatusBarDisappearDelay, MEMBER_FLOAT), PL_MEMBERS(m_flStatusBarDisappearDelay, MEMBER_FLOAT),
PL_MEMBERS(m_SbarString0, MEMBER_CHAR_ARRAY), // ARRAY [128] PL_MEMBERS(m_SbarString0, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_lastx, MEMBER_INTEGER), PL_MEMBERS(m_lastx, MEMBER_INTEGER),
PL_MEMBERS(m_lasty, MEMBER_INTEGER), PL_MEMBERS(m_lasty, MEMBER_INTEGER),
PL_MEMBERS(m_nCustomSprayFrames, MEMBER_INTEGER), PL_MEMBERS(m_nCustomSprayFrames, MEMBER_INTEGER),
PL_MEMBERS(m_flNextDecalTime, MEMBER_FLOAT), PL_MEMBERS(m_flNextDecalTime, MEMBER_FLOAT),
PL_MEMBERS(m_szTeamName, MEMBER_CHAR_ARRAY), // ARRAY [16] PL_MEMBERS(m_szTeamName, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_modelIndexPlayer, MEMBER_INTEGER), PL_MEMBERS(m_modelIndexPlayer, MEMBER_INTEGER),
PL_MEMBERS(m_szAnimExtention, MEMBER_CHAR_ARRAY), // ARRAY [32] PL_MEMBERS(m_szAnimExtention, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_iGaitsequence, MEMBER_INTEGER), PL_MEMBERS(m_iGaitsequence, MEMBER_INTEGER),
PL_MEMBERS(m_flGaitframe, MEMBER_FLOAT), PL_MEMBERS(m_flGaitframe, MEMBER_FLOAT),
PL_MEMBERS(m_flGaityaw, MEMBER_FLOAT), PL_MEMBERS(m_flGaityaw, MEMBER_FLOAT),
@ -295,12 +328,12 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_blindFadeTime, MEMBER_FLOAT), PL_MEMBERS(m_blindFadeTime, MEMBER_FLOAT),
PL_MEMBERS(m_blindAlpha, MEMBER_INTEGER), PL_MEMBERS(m_blindAlpha, MEMBER_INTEGER),
PL_MEMBERS(m_allowAutoFollowTime, MEMBER_FLOAT), PL_MEMBERS(m_allowAutoFollowTime, MEMBER_FLOAT),
PL_MEMBERS(m_autoBuyString, MEMBER_CHAR_ARRAY), // ARRAY 256 PL_MEMBERS(m_autoBuyString, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_rebuyString, MEMBER_CHAR_POINTER), PL_MEMBERS(m_rebuyString, MEMBER_CHAR_POINTER),
PL_MEMBERS(m_rebuyStruct, MEBMER_REBUYSTRUCT), PL_MEMBERS(m_rebuyStruct, MEBMER_REBUYSTRUCT),
PL_MEMBERS(m_bIsInRebuy, MEMBER_BOOL), PL_MEMBERS(m_bIsInRebuy, MEMBER_BOOL),
PL_MEMBERS(m_flLastUpdateTime, MEMBER_FLOAT), PL_MEMBERS(m_flLastUpdateTime, MEMBER_FLOAT),
PL_MEMBERS(m_lastLocation, MEMBER_CHAR_ARRAY), // ARRAY [32] PL_MEMBERS(m_lastLocation, MEMBER_CHAR_ARRAY),
PL_MEMBERS(m_progressStart, MEMBER_FLOAT), PL_MEMBERS(m_progressStart, MEMBER_FLOAT),
PL_MEMBERS(m_progressEnd, MEMBER_FLOAT), PL_MEMBERS(m_progressEnd, MEMBER_FLOAT),
PL_MEMBERS(m_bObserverAutoDirector, MEMBER_BOOL), PL_MEMBERS(m_bObserverAutoDirector, MEMBER_BOOL),
@ -309,7 +342,7 @@ member_t memberlist_player[] = {
PL_MEMBERS(m_intenseTimestamp, MEMBER_FLOAT), PL_MEMBERS(m_intenseTimestamp, MEMBER_FLOAT),
PL_MEMBERS(m_silentTimestamp, MEMBER_FLOAT), PL_MEMBERS(m_silentTimestamp, MEMBER_FLOAT),
PL_MEMBERS(m_musicState, MEMBER_INTEGER), PL_MEMBERS(m_musicState, MEMBER_INTEGER),
PL_MEMBERS(m_flLastCommandTime, MEMBER_FLOAT), // ARRAY [8] PL_MEMBERS(m_flLastCommandTime, MEMBER_FLOAT),
}; };
memberlist_t memberlist; memberlist_t memberlist;
@ -318,11 +351,13 @@ member_t *memberlist_t::operator[](size_t members) const
{ {
#define CASE(h) case ht_##h: if (index < arraysize(memberlist_##h)) return &memberlist_##h[index]; else break; #define CASE(h) case ht_##h: if (index < arraysize(memberlist_##h)) return &memberlist_##h[index]; else break;
const auto table = members_tables_e(members / MAX_RANGE_REGION); const auto table = members_tables_e(members / MAX_REGION_RANGE);
const auto index = members & (MAX_RANGE_REGION - 1); const auto index = members & (MAX_REGION_RANGE - 1);
switch (table) { switch (table) {
CASE(gamerules) CASE(gamerules)
CASE(base)
CASE(animating)
CASE(player) CASE(player)
} }

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#define BEGIN_MEMBER_REGION(x) (MAX_RANGE_REGION * memberlist_t::members_tables_e::ht_##x) #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_FLOAT = 0, // Any floating point value
MEMBER_DOUBLE, // double value MEMBER_DOUBLE, // double value
@ -27,7 +28,7 @@ struct member_t
uint16 size; uint16 size;
uint16 max_size; uint16 max_size;
uint32 offset; uint32 offset;
enum_membertypes type; MType type;
}; };
struct memberlist_t struct memberlist_t
@ -37,6 +38,8 @@ struct memberlist_t
enum members_tables_e enum members_tables_e
{ {
ht_gamerules, ht_gamerules,
ht_base,
ht_animating,
ht_player ht_player
}; };
}; };
@ -132,6 +135,46 @@ enum CSGameRules_Members
m_bSkipSpawn m_bSkipSpawn
}; };
// CBasePlayer
enum CBaseEntity_Members
{
currentammo = BEGIN_MEMBER_REGION(base),
maxammo_buckshot,
ammo_buckshot,
maxammo_9mm,
ammo_9mm,
maxammo_556nato,
ammo_556nato,
maxammo_556natobox,
ammo_556natobox,
maxammo_762nato,
ammo_762nato,
maxammo_45acp,
ammo_45acp,
maxammo_50ae,
ammo_50ae,
maxammo_338mag,
ammo_338mag,
maxammo_57mm,
ammo_57mm,
maxammo_357sig,
ammo_357sig,
m_flStartThrow,
m_flReleaseThrow,
m_iSwing,
has_disconnected,
};
// CBaseAnimating
enum CBaseAnimating_Members
{
m_flFrameRate = BEGIN_MEMBER_REGION(animating),
m_flGroundSpeed,
m_flLastEventCheck,
m_fSequenceFinished,
m_fSequenceLoops,
};
// CBasePlayer // CBasePlayer
enum CBasePlayer_Members enum CBasePlayer_Members
{ {

View File

@ -11,7 +11,7 @@ plugin_info_t Plugin_info =
"ReAPI", // name "ReAPI", // name
APP_VERSION_STRD, // version APP_VERSION_STRD, // version
APP_VERSION_YMD_STR, // date APP_VERSION_YMD_STR, // date
"s1lent", // author "Asmodai & s1lent", // author
"https://github.com/s1lentq/reapi/", // url "https://github.com/s1lentq/reapi/", // url
"ReAPI", // logtag, all caps please "ReAPI", // logtag, all caps please
PT_ANYTIME, // (when) loadable PT_ANYTIME, // (when) loadable
@ -33,7 +33,7 @@ META_FUNCTIONS gMetaFunctionTable =
{ {
NULL, // pfnGetEntityAPI HL SDK; called before game DLL NULL, // pfnGetEntityAPI HL SDK; called before game DLL
NULL, // pfnGetEntityAPI_Post META; called after game DLL NULL, // pfnGetEntityAPI_Post META; called after game DLL
NULL, // pfnGetEntityAPI2 HL SDK2; called before game DLL GetEntityAPI2, // pfnGetEntityAPI2 HL SDK2; called before game DLL
GetEntityAPI2_Post, // pfnGetEntityAPI2_Post META; called after game DLL GetEntityAPI2_Post, // pfnGetEntityAPI2_Post META; called after game DLL
NULL, // pfnGetNewDLLFunctions HL SDK2; called before game DLL NULL, // pfnGetNewDLLFunctions HL SDK2; called before game DLL
NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL

View File

@ -52,7 +52,6 @@ bool RegamedllApi_Init()
g_ReGameFuncs = g_ReGameApi->GetFuncs(); g_ReGameFuncs = g_ReGameApi->GetFuncs();
g_ReGameHookchains = g_ReGameApi->GetHookchains(); g_ReGameHookchains = g_ReGameApi->GetHookchains();
g_pCSGameRules = (CHalfLifeMultiplay **)g_ReGameApi->GetGameData()->GetGameRules();
return true; return true;
} }

View File

@ -1,169 +0,0 @@
#include "precompiled.h"
/*
* Hook API function that are available into enum
* Look at the enum's for parameter lists.
*
* @param function The function to hook.
* @param callback The forward to call.
* @param post Whether or not to forward this in post.
* @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off.
*
* native RegisterHookChain(any:function_id, const callback[], post = 0);
*/
static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_func, arg_handler, arg_post };
int func = params[arg_func];
int post = params[arg_post];
if (hooklist[func] == nullptr)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Function (%d) doesn't match hook definition.", func);
return 0;
}
if (!hooklist[func]->availableFunc())
{
MF_LogError(amx, AMX_ERR_NATIVE, "Function (%s) is not available, required %s", hooklist[func]->func_name, hooklist[func]->depend_name);
return 0;
}
int funcid, len;
const char *funcname = g_amxxapi.GetAmxString(amx, params[arg_handler], 0, &len);
if (g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Public function \"%s\" not found.", funcname);
return 0;
}
int fwid = hooklist[func]->registerForward(amx, funcname);
if (fwid == -1)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Public function \"%s\" not found.", funcname);
return 0;
}
return (cell)g_hookManager.addHandler(func, fwid, post != 0);
}
/*
* Starts a hook back up.
* Use the return value from RegisterHookChain as the parameter here!
*
* @param fwd The hook to re-enable.
* @return Returns if the function is successful executed true otherwise false
*
* native bool:EnableHookChain(any:fwd);
*/
static cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_handle_hook };
CHook *hook = reinterpret_cast<CHook *>(params[arg_handle_hook]);
if (hook == nullptr)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid HookChain handle.");
return 0;
}
hook->m_state = FSTATE_OK;
return 1;
}
/*
* Stops a hook from triggering.
* Use the return value from RegisterHookChain as the parameter here!
*
* @param fwd The hook to stop.
*
* native bool:DisableHookChain(any:fwd);
*/
static cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_handle_hook };
CHook *hook = reinterpret_cast<CHook *>(params[arg_handle_hook]);
if (hook == nullptr)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid HookChain handle.");
return 0;
}
hook->m_state = FSTATE_STOP;
return 1;
}
/*
* Sets the return value of a hookchain.
* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE.
*
* @param type To specify the type RHV_*, look at the enum HookChainReturn
* @param value The value to set the return to.
*
* native SetHookChainReturn(HookChainReturn:type, any:...);
*/
static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params)
{
if (!g_currentHookChain)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Trying get return value without active hook.");
return 0;
}
enum args_e { arg_count, arg_type, arg_value };
switch (params[arg_type])
{
case RHV_STRING:
{
if (g_currentHookChain->m_data.m_string != NULL) {
delete [] g_currentHookChain->m_data.m_string;
}
int len;
char *dest = g_amxxapi.GetAmxString(amx, params[arg_value], 0, &len);
g_currentHookChain->m_data.m_string = new char [len + 1];
strcpy(g_currentHookChain->m_data.m_string, dest);
break;
}
case RHV_FLOAT:
g_currentHookChain->m_data.m_float = *(float *)g_amxxapi.GetAmxAddr(amx, params[arg_value]);
break;
case RHV_INTEGER:
g_currentHookChain->m_data.m_interger = *g_amxxapi.GetAmxAddr(amx, params[arg_value]);
break;
case RHV_CLASSPTR:
g_currentHookChain->m_data.m_classptr = CBaseEntity::Instance(INDEXENT(*g_amxxapi.GetAmxAddr(amx, params[arg_value])));
break;
default:
return 0;
}
return 1;
}
AMX_NATIVE_INFO Func_Natives[] =
{
{ "RegisterHookChain", RegisterHookChain },
{ "EnableHookChain", EnableHookChain },
{ "DisableHookChain", DisableHookChain },
{ "SetHookChainReturn", SetHookChainReturn },
{ nullptr, nullptr }
};
void RegisterNatives()
{
g_amxxapi.AddNatives(Func_Natives);
g_amxxapi.AddNatives(Member_Natives);
}

View File

@ -0,0 +1,286 @@
#include "precompiled.h"
/*
* Hook API function that are available into enum
* Look at the enum's for parameter lists.
*
* @param function The function to hook.
* @param callback The forward to call.
* @param post Whether or not to forward this in post.
* @return Returns a handle to the hook. Use EnableHookChain/DisableHookChain to toggle the forward on or off.
*
* native RegisterHookChain(any:function_id, const callback[], post = 0);
*/
static cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_func, arg_handler, arg_post };
int func = params[arg_func];
int post = params[arg_post];
auto hook = g_hookManager.getHook(func);
if (hook == nullptr)
{
MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: function with id (%d) doesn't exist in current API version.", func);
return 0;
}
if (!hook->checkRequirements())
{
MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: function (%s) is not available, %s required", hook->func_name, hook->depend_name);
return 0;
}
int funcid;
const char *funcname = getAmxString(amx, params[arg_handler]);
if (g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)
{
MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: public function \"%s\" not found.", funcname);
return 0;
}
int fwid = hook->registerForward(amx, funcname);
if (fwid == -1)
{
MF_LogError(amx, AMX_ERR_NATIVE, "RegisterHookChain: register forward failed.");
return 0;
}
return g_hookManager.addHandler(amx, func, fwid, post != 0);
}
/*
* Enable hook by handle.
* Use the return value from RegisterHookChain as the parameter here!
*
* @param fwd The hook to re-enable.
* @return Returns if the function is successful executed true otherwise false
*
* native bool:EnableHookChain(any:fwd);
*/
static cell AMX_NATIVE_CALL EnableHookChain(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_handle_hook };
auto hook = g_hookManager.getAmxxHook(params[arg_handle_hook]);
if (hook == nullptr)
{
MF_LogError(amx, AMX_ERR_NATIVE, "EnableHookChain: invalid HookChain handle.");
return FALSE;
}
hook->SetState(FSTATE_ENABLED);
return TRUE;
}
/*
* Disable hook by handle.
* Use the return value from RegisterHookChain as the parameter here!
*
* @param fwd The hook to stop.
*
* native bool:DisableHookChain(any:fwd);
*/
static cell AMX_NATIVE_CALL DisableHookChain(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_handle_hook };
auto hook = g_hookManager.getAmxxHook(params[arg_handle_hook]);
if (hook == nullptr)
{
MF_LogError(amx, AMX_ERR_NATIVE, "DisableHookChain: invalid HookChain handle.");
return FALSE;
}
hook->SetState(FSTATE_STOPPED);
return TRUE;
}
/*
* Sets the return value of a hookchain.
* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE.
*
* @param type To specify the type RHV_*, look at the enum AType
* @param value The value to set the return to.
*
* native SetHookChainReturn(AType:type, any:...);
*/
static cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params)
{
if (!g_hookCtx)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set return value without active hook.");
return FALSE;
}
enum args_e { arg_count, arg_type, arg_value };
auto& retVal = g_hookCtx->retVal;
if (params[arg_type] != retVal.type)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to set incompatible return type.");
return FALSE;
}
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
switch (retVal.type)
{
case ATYPE_INTEGER:
case ATYPE_FLOAT:
retVal._interger = *srcAddr;
break;
case ATYPE_STRING:
{
if (retVal._string != nullptr)
delete[] retVal._string;
size_t len;
const char *dest = getAmxString(srcAddr, &len);
retVal._string = strcpy(new char[len + 1], dest);
break;
}
case ATYPE_CLASSPTR:
retVal._classptr = CBaseEntity::Instance(INDEXENT(*srcAddr));
break;
default:
return FALSE;
}
retVal.set = true;
return TRUE;
}
/*
* Get the return value of a hookchain.
* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE.
*
* @param value The value to set the return to.
* @param [maxlen] Max length of string (optional)
* @return Returns if the function is successful executed true otherwise false
*
* native GetHookChainReturn(AType:type, any:...);
*/
static cell AMX_NATIVE_CALL GetHookChainReturn(AMX *amx, cell *params)
{
if (!g_hookCtx)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook.");
return FALSE;
}
enum args_e { arg_count, arg_value, arg_maxlen };
auto& retVal = g_hookCtx->retVal;
cell* dstAddr = getAmxAddr(amx, params[arg_value]);
switch (retVal.type)
{
case ATYPE_INTEGER:
case ATYPE_FLOAT:
*dstAddr = retVal._interger;
break;
case ATYPE_STRING:
{
if (PARAMS_COUNT != 2)
return FALSE;
setAmxString(dstAddr, retVal._string, params[arg_maxlen]);
break;
}
case ATYPE_CLASSPTR:
*dstAddr = retVal._classptr->entindex();
break;
default:
return FALSE;
}
return TRUE;
}
/*
* Set hookchain argument.
* This needs to be used in conjunction with RH_OVERRIDE or RH_SUPERCEDE.
*
* @param number Number of argument
* @param value New value
* @param [maxlen] Max length of string (optional)
* @return Returns if the function is successful executed true otherwise false
*
* native SetHookChainArg(number, AType:type, any:...);
*/
static cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params)
{
if (!g_hookCtx)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Trying to get return value without active hook.");
return FALSE;
}
enum args_e { arg_count, arg_number, arg_type, arg_value };
size_t number = params[arg_number] - 1;
if (number >= g_hookCtx->args_count)
{
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: can't set argument %i of hookchain with %i args.", params[arg_number], g_hookCtx->args_count);
return FALSE;
}
AType type = g_hookCtx->args_type[number];
if (params[arg_type] != type)
{
MF_LogError(amx, AMX_ERR_NATIVE, "SetHookChainArg: invalid argument type provided.");
return FALSE;
}
static char temp_strings[MAX_ARGS][1024];
cell* srcAddr = getAmxAddr(amx, params[arg_value]);
size_t destAddr = g_hookCtx->args_ptr + number * sizeof(int);
switch (type)
{
case ATYPE_INTEGER:
case ATYPE_FLOAT:
*(cell *)destAddr = *srcAddr;
break;
case ATYPE_STRING:
*(char **)destAddr = getAmxStringTemp(srcAddr, temp_strings[number], sizeof temp_strings[0] - 1);
break;
case ATYPE_CLASSPTR:
*(CBaseEntity **)destAddr = CBaseEntity::Instance(INDEXENT(*srcAddr));
break;
}
return TRUE;
}
AMX_NATIVE_INFO HookChain_Natives[] =
{
{ "RegisterHookChain", RegisterHookChain },
{ "EnableHookChain", EnableHookChain },
{ "DisableHookChain", DisableHookChain },
{ "SetHookChainReturn", SetHookChainReturn },
{ "GetHookChainReturn", GetHookChainReturn },
{ "SetHookChainArg", SetHookChainArg },
{ nullptr, nullptr }
};
void RegisterNatives_HookChains()
{
g_amxxapi.AddNatives(HookChain_Natives);
}

View File

@ -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 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; } #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_HookChains();
void RegisterNatives();

View File

@ -1,378 +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, "Member (%d) is unknown", params[arg_member]);
return 0;
}
edict_t *pEdict = INDEXENT(params[arg_index]);
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
return 0;
}
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:
return -1;
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 1;
}
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 1;
}
case MEMBER_EVARS:
return -1;
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 1;
}
case MEMBER_VECTOR:
{
// native set_member(_index, any:_member, Float:_value[3], _elem);
cell *pSource = g_amxxapi.GetAmxAddr(amx, params[arg_value]);
Vector vecDest;
vecDest.x = *(vec_t *)&pSource[0];
vecDest.y = *(vec_t *)&pSource[1];
vecDest.z = *(vec_t *)&pSource[2];
set_member<Vector>(pEdict, member->offset, vecDest, element);
return 1;
}
case MEMBER_CHAR_ARRAY:
{
// native set_member(_index, any:_member, const source[]);
int len;
char *source = g_amxxapi.GetAmxString(amx, params[arg_value], 0, &len);
char *dest = get_member_direct<char *>(pEdict, member->offset);
strcpy(dest, source);
return 1;
}
case MEMBER_CHAR_POINTER:
{
// native set_member(_index, any:_member, const source[]);
int len;
char *source = g_amxxapi.GetAmxString(amx, params[arg_value], 0, &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 1;
}
case MEMBER_FLOAT:
case MEMBER_INTEGER:
{
// native set_member(_index, any:_member, any:_value, _elem);
set_member<int>(pEdict, member->offset, value, element);
return 1;
}
case MEMBER_SHORT:
{
// native set_member(_index, any:_member, _value, _elem);
set_member<short>(pEdict, member->offset, value, element);
return 1;
}
case MEMBER_BYTE:
{
// native set_member(_index, any:_member, _value, _elem);
set_member<byte>(pEdict, member->offset, value, element);
return 1;
}
case MEMBER_BOOL:
{
// native set_member(_index, any:_member, bool:_value, _elem);
set_member<bool>(pEdict, member->offset, value != 0, element);
return 1;
}
case MEMBER_SIGNALS:
{
// native set_member(_index, any:_member, _value);
CUnifiedSignals signal = get_member<CUnifiedSignals>(pEdict, member->offset, element);
signal.Signal(value);
return 1;
}
case MEBMER_REBUYSTRUCT:
return -1;
}
return 0;
}
// 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 0;
}
edict_t *pEdict = INDEXENT(params[arg_index]);
if (pEdict == nullptr || pEdict->pvPrivateData == nullptr) {
return 0;
}
size_t element = *g_amxxapi.GetAmxAddr(amx, params[arg_elem]);
switch (member->type)
{
case MEMBER_ENTITY:
return -1;
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 0;
}
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 ENTINDEX(pEntity);
}
return 0;
}
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 0;
}
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 MEBMER_REBUYSTRUCT:
return -1;
}
return 0;
}
// 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 0;
}
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 -1;
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 0;
}
// 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 0;
}
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 0;
}
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 }
};

View File

@ -0,0 +1,371 @@
#include "precompiled.h"
// native set_member(_index, any:_member, any:...);
static cell AMX_NATIVE_CALL set_member(AMX *amx, cell *params)
{
enum args_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");
return FALSE;
}
cell* value = getAmxAddr(amx, params[arg_value]);
size_t element = (PARAMS_COUNT == 4) ? *getAmxAddr(amx, params[arg_elem]) : 0;
return set_member(pEdict->pvPrivateData, member, element, value);
}
// native any:get_member(_index, any:_member, any:...);
static cell AMX_NATIVE_CALL get_member(AMX *amx, cell *params)
{
enum args_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");
return FALSE;
}
cell* dest;
size_t element;
if (PARAMS_COUNT == 4) {
dest = getAmxAddr(amx, params[arg_3]);
element = *getAmxAddr(amx, params[arg_4]);
}
else if (PARAMS_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_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;
}
if (g_pCSGameRules == nullptr || *g_pCSGameRules == nullptr) {
MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: gamerules not initialized");
return 0;
}
cell* value = getAmxAddr(amx, params[arg_value]);
size_t element = (PARAMS_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_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;
}
if (g_pCSGameRules == nullptr || *g_pCSGameRules == nullptr) {
MF_LogError(amx, AMX_ERR_NATIVE, "get_member_game: gamerules not initialized");
return 0;
}
cell* dest;
size_t element;
if (PARAMS_COUNT == 4) {
dest = getAmxAddr(amx, params[arg_3]);
element = *getAmxAddr(amx, params[arg_4]);
}
else if (PARAMS_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[]);
char *source = getAmxString(value);
char *&dest = get_member<char *>(pdata, member->offset);
g_ReGameFuncs->ChangeString(dest, source);
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;
}
}

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

189
reapi/src/natives_misc.cpp Normal file
View File

@ -0,0 +1,189 @@
#include "precompiled.h"
// native rg_set_animation(index, PLAYER_ANIM:playerAnim);
static cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_anim };
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
return FALSE;
}
pPlayer->SetAnimation(static_cast<PLAYER_ANIM>(params[arg_anim]));
return TRUE;
}
// native rg_add_account(index, amount, bool:bTrackChange = true);
static cell AMX_NATIVE_CALL rg_add_account(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_amount, arg_track_change };
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
return FALSE;
}
pPlayer->AddAccount(params[arg_amount], params[arg_track_change] != 0);
return TRUE;
}
// native rg_give_item(index, const pszName[]);
static cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_item };
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
return FALSE;
}
const char *itemName = getAmxString(amx, params[arg_item]);
pPlayer->GiveNamedItem(itemName);
return TRUE;
}
// native rg_give_default_items(index);
static cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
return FALSE;
}
pPlayer->GiveDefaultItems();
return TRUE;
}
// native rg_give_shield(index, bool:bDeploy = true);
static cell AMX_NATIVE_CALL rg_give_shield(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_deploy };
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
return FALSE;
}
pPlayer->GiveShield(params[arg_deploy] != 0);
return TRUE;
}
// native rg_dmg_radius(Float:vecSrc[3], inflictor, attacker, Float:flDamage, Float:flRadius, iClassIgnore, bitsDamageType);
static cell AMX_NATIVE_CALL rg_dmg_radius(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_vec, arg_inflictor, arg_attacker, arg_damage, arg_radius, arg_ignore_class, arg_dmg_type };
cell *pSrc = getAmxAddr(amx, params[arg_vec]);
entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor]));
entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker]));
Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]);
g_ReGameFuncs->RadiusDamage(vecSrc, pevInflictor, pevAttacker, *(float *)&params[arg_damage], *(float *)&params[arg_radius], params[arg_ignore_class], params[arg_dmg_type]);
return TRUE;
}
// native rg_multidmg_clear();
static cell AMX_NATIVE_CALL rg_multidmg_clear(AMX *amx, cell *params)
{
g_ReGameFuncs->ClearMultiDamage();
return TRUE;
}
// native rg_multidmg_apply(inflictor, attacker);
static cell AMX_NATIVE_CALL rg_multidmg_apply(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_inflictor, arg_attacker };
entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor]));
entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker]));
g_ReGameFuncs->ApplyMultiDamage(pevInflictor, pevAttacker);
return TRUE;
}
// native rg_multidmg_add(inflictor, victim, Float:flDamage, bitsDamageType);
static cell AMX_NATIVE_CALL rg_multidmg_add(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_inflictor, arg_victim, arg_damage, arg_dmg_type };
entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor]));
CBaseEntity *pVictim = g_ReGameFuncs->UTIL_PlayerByIndex(params[arg_inflictor]);
if (pVictim == nullptr) {
return FALSE;
}
g_ReGameFuncs->AddMultiDamage(pevInflictor, pVictim, *(float *)&params[arg_damage], params[arg_dmg_type]);
return TRUE;
}
// native rg_fire_bullets(inflictor, attacker, shots, Float:vecSrc[3], Float:vecDirShooting[3], Float::vecSpread[3], Float:flDistance, iBulletType, iTracerFreq, iDamage);
static cell AMX_NATIVE_CALL rg_fire_bullets(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_inflictor, arg_attacker, arg_shots, arg_vecSrc, arg_dir, arg_spread, arg_dist, arg_bullet_type, arg_tracefrq, arg_dmg };
ICSEntity *pInflictor = g_ReGameFuncs->INDEX_TO_CSENTITY(params[arg_inflictor]);
cell *pSrc = getAmxAddr(amx, params[arg_vecSrc]);
Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]);
cell *pDir = getAmxAddr(amx, params[arg_dir]);
Vector vecDirShooting(*(float *)&pDir[0], *(float *)&pDir[1], *(float *)&pDir[2]);
cell *pSpread = getAmxAddr(amx, params[arg_spread]);
Vector vecSpread(*(float *)&pSpread[0], *(float *)&pSpread[1], *(float *)&pSpread[2]);
entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker]));
pInflictor->FireBullets(params[arg_shots], vecSrc, vecDirShooting, vecSpread, *(float *)&params[arg_dist], params[arg_bullet_type], params[arg_tracefrq], params[arg_dmg], pevAttacker);
return TRUE;
}
// native Float:[3] rg_fire_bullets3(inflictor, attacker, Float:vecSrc[3], Float:vecDirShooting[3], Float:vecSpread, Float:flDistance, iPenetration, iBulletType, iDamage, Float:flRangeModifier, bool:bPistol, shared_rand);
static cell AMX_NATIVE_CALL rg_fire_bullets3(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_inflictor, arg_attacker, arg_vecSrc, arg_dir, arg_spread, arg_dist, arg_penetration, arg_bullet_type, arg_dmg, arg_range_mod, arg_pistol, arg_rand, arg_out };
ICSEntity *pInflictor = g_ReGameFuncs->INDEX_TO_CSENTITY(params[arg_inflictor]);
cell *pSrc = getAmxAddr(amx, params[arg_vecSrc]);
Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]);
cell *pDir = getAmxAddr(amx, params[arg_dir]);
Vector vecDirShooting(*(float *)&pDir[0], *(float *)&pDir[1], *(float *)&pDir[2]);
entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker]));
Vector *pOut = (Vector *)getAmxAddr(amx, params[arg_out]);
*pOut = pInflictor->FireBullets3(vecSrc, vecDirShooting, *(float *)&params[arg_spread], *(float *)&params[arg_dist], params[arg_penetration], params[arg_bullet_type], params[arg_dmg], *(float *)&params[arg_range_mod], pevAttacker, params[arg_pistol] != 0, params[arg_rand]);
return TRUE;
}
AMX_NATIVE_INFO Misc_Natives[] =
{
{ "rg_set_animation", rg_set_animation },
{ "rg_add_account", rg_add_account },
{ "rg_give_item", rg_give_item },
{ "rg_give_default_items", rg_give_default_items },
{ "rg_give_shield", rg_give_shield },
{ "rg_dmg_radius", rg_dmg_radius },
{ "rg_multidmg_clear", rg_multidmg_clear },
{ "rg_multidmg_apply", rg_multidmg_apply },
{ "rg_multidmg_add", rg_multidmg_add },
{ "rg_fire_bullets", rg_fire_bullets },
{ "rg_fire_bullets3", rg_fire_bullets3 },
{ nullptr, nullptr }
};
void RegisterNatives_Misc()
{
g_amxxapi.AddNatives(Misc_Natives);
}

3
reapi/src/natives_misc.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void RegisterNatives_Misc();

View File

@ -10,6 +10,7 @@
#include <vector> // std::vector #include <vector> // std::vector
#include <extdll.h> #include <extdll.h>
#include "reapi_utils.h"
#include <cbase.h> #include <cbase.h>
#include "osdep.h" // win32 vsnprintf, etc #include "osdep.h" // win32 vsnprintf, etc
@ -35,7 +36,9 @@
#include "hook_manager.h" #include "hook_manager.h"
#include "hook_callback.h" #include "hook_callback.h"
#include "member_list.h" #include "member_list.h"
#include "natives.h" #include "natives_hookchains.h"
#include "natives_members.h"
#include "natives_misc.h"
#undef DLLEXPORT #undef DLLEXPORT
#ifdef _WIN32 #ifdef _WIN32

View File

@ -4,6 +4,37 @@ template <typename T, size_t N>
char(&ArraySizeHelper(T(&array)[N]))[N]; char(&ArraySizeHelper(T(&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array))) #define arraysize(array) (sizeof(ArraySizeHelper(array)))
#define INDEXENT edictByIndex
#define ENTINDEX indexOfEdict
extern edict_t* g_pEdicts;
inline size_t indexOfEdict(edict_t* ed)
{
return ed - g_pEdicts;
}
inline size_t indexOfEdict(entvars_t* pev)
{
return indexOfEdict(pev->pContainingEntity);
}
inline edict_t* edictByIndex(size_t index)
{
return g_pEdicts + index;
}
template<typename T>
T* getPrivate(int index)
{
return (T *)edictByIndex(index)->pvPrivateData;
}
inline entvars_t* PEV(int index)
{
return &edictByIndex(index)->v;
}
// HLTypeConversion.h -> AMXModX // HLTypeConversion.h -> AMXModX
template <typename T> template <typename T>
inline T &ref_member(void *ptr, int offset, int element = 0) inline T &ref_member(void *ptr, int offset, int element = 0)