2
0
mirror of https://github.com/rehlds/reapi.git synced 2024-12-28 15:45:31 +03:00

Added missed safety checks

A more clean design of natives_misc
This commit is contained in:
asmodai 2016-04-28 00:28:17 +03:00
parent e51d1442a2
commit 7a3992e960
20 changed files with 211 additions and 117 deletions

View File

@ -200,10 +200,12 @@
<ClInclude Include="..\src\hook_manager.h" />
<ClInclude Include="..\src\hook_callback.h" />
<ClInclude Include="..\src\hook_list.h" />
<ClInclude Include="..\src\main.h" />
<ClInclude Include="..\src\member_list.h" />
<ClInclude Include="..\src\mods\mod_regamedll_api.h" />
<ClInclude Include="..\src\mods\mod_rehlds_api.h" />
<ClInclude Include="..\src\mods\mod_vtc_api.h" />
<ClInclude Include="..\src\natives\natives_helper.h" />
<ClInclude Include="..\src\natives\natives_hookchains.h" />
<ClInclude Include="..\src\natives\natives_members.h" />
<ClInclude Include="..\src\natives\natives_misc.h" />

View File

@ -642,6 +642,12 @@
<ClInclude Include="..\include\vtc_api.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\src\natives\natives_helper.h">
<Filter>src\natives</Filter>
</ClInclude>
<ClInclude Include="..\src\main.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\include\cssdk\common\parsemsg.cpp">

View File

@ -159,6 +159,8 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
*(void **)((unsigned long)&g_amxxapi + g_funcrequests[i].offset) = fptr;
}
OnAmxxAttach();
RegisterNatives_HookChains();
RegisterNatives_Members();
RegisterNatives_Misc();

View File

@ -7,13 +7,11 @@ CAPI_Config::CAPI_Config() : m_api_rehlds(false), m_api_regame(false), m_api_vtc
}
bool CAPI_Config::Init()
void CAPI_Config::Init()
{
m_api_rehlds = RehldsApi_Init();
m_api_regame = RegamedllApi_Init();
m_api_vtc = VTC_Api_Init();
return true;
}
void CAPI_Config::ServerActivate() const

View File

@ -6,7 +6,7 @@
class CAPI_Config {
public:
CAPI_Config();
bool Init();
void Init();
bool hasReHLDS() const { return m_api_rehlds; }
bool hasReGameDLL() const { return m_api_regame; }

View File

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

View File

@ -129,15 +129,30 @@ hook_t* hooklist_t::getHookSafe(size_t hook)
return nullptr;
}
void hooklist_t::clear()
{
for (auto& h : hooklist_engine)
h.clear();
for (auto& h : hooklist_gamedll)
h.clear();
for (auto& h : hooklist_animating)
h.clear();
for (auto& h : hooklist_player)
h.clear();
}
void hook_t::clear()
{
for (auto h : pre)
delete h;
pre.clear();
if (pre.size() || post.size()) {
for (auto h : pre)
delete h;
pre.clear();
for (auto h : post)
delete h;
post.clear();
for (auto h : post)
delete h;
post.clear();
unregisterHookchain();
unregisterHookchain();
}
}

View File

@ -49,6 +49,7 @@ struct hooklist_t
}
static hook_t *getHookSafe(size_t hook);
static void clear();
enum hooks_tables_e
{

View File

@ -40,17 +40,7 @@ void CAmxxHook::SetState(fwdstate st)
void CHookManager::clearHandlers() const
{
#define CLEAR_HOOKLIST(__END__, __START__)\
for (size_t i = BEGIN_FUNC_REGION(__START__); i < ##__END__; ++i) {\
if (m_hooklist[i])\
m_hooklist[i]->clear();\
}
CLEAR_HOOKLIST(RH_EngineFunc_End, engine);
CLEAR_HOOKLIST(RG_End, gamedll);
CLEAR_HOOKLIST(RG_CBaseAnimating_End, animating);
CLEAR_HOOKLIST(RG_CBasePlayer_End, player);
m_hooklist.clear();
}
hook_t* CHookManager::getHook(size_t func) const

View File

@ -1,13 +1,17 @@
#include "precompiled.h"
edict_t* g_pEdicts;
int gmsgSendAudio;
int gmsgTeamScore;
void OnAmxxAttach()
{
// initialize API
api_cfg.Init();
}
bool OnMetaAttach()
{
// initialize API
if (!api_cfg.Init())
return false;
return true;
}
@ -22,9 +26,11 @@ void OnMetaDetach()
}
}
void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
{
g_pEdicts = pEdictList;
gmsgSendAudio = GET_USER_MSG_ID(PLID, "SendAudio", NULL);
gmsgTeamScore = GET_USER_MSG_ID(PLID, "TeamScore", NULL);
api_cfg.ServerActivate();
SET_META_RESULT(MRES_IGNORED);

12
reapi/src/main.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
extern edict_t* g_pEdicts;
extern int gmsgSendAudio;
extern int gmsgTeamScore;
void OnAmxxAttach();
bool OnMetaAttach();
void OnMetaDetach();
void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax);
void ServerDeactivate_Post();

View File

@ -19,9 +19,6 @@ plugin_info_t Plugin_info =
PT_NEVER, // (when) unloadable
};
extern bool OnMetaAttach();
extern void OnMetaDetach();
C_DLLEXPORT int Meta_Query(char *interfaceVersion, plugin_info_t* *plinfo, mutil_funcs_t *pMetaUtilFuncs)
{
*plinfo = &Plugin_info;
@ -34,7 +31,7 @@ META_FUNCTIONS gMetaFunctionTable =
{
NULL, // pfnGetEntityAPI HL SDK; called before game DLL
NULL, // pfnGetEntityAPI_Post META; called after game DLL
GetEntityAPI2, // pfnGetEntityAPI2 HL SDK2; called before game DLL
NULL, // pfnGetEntityAPI2 HL SDK2; called before game DLL
GetEntityAPI2_Post, // pfnGetEntityAPI2_Post META; called after game DLL
NULL, // pfnGetNewDLLFunctions HL SDK2; called before game DLL
NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL

View File

@ -0,0 +1,67 @@
#pragma once
#define CHECK_ISPLAYER(x) if (x <= 0 || x > gpGlobals->maxClients) { MF_LogError(amx, AMX_ERR_NATIVE, "invalid player index %i", x); return FALSE; }
#define CHECK_ISENTITY(x) if (x > gpGlobals->maxEntities) { MF_LogError(amx, AMX_ERR_NATIVE, "invalid entity index %i", x); return FALSE; }
class CAmxArg
{
public:
CAmxArg(AMX* amx, cell value) : m_amx(amx), m_value(value) {}
operator float() const
{
return *(float *)m_value;
}
operator Vector&() const
{
return *(Vector *)getAmxAddr(m_amx, m_value);
}
operator entvars_s*() const
{
if (m_value < 0)
return nullptr;
return PEV(m_value);
}
operator int() const
{
return m_value;
}
operator size_t() const
{
return size_t(m_value);
}
operator bool() const
{
return m_value != 0;
}
operator CBaseEntity*() const
{
return g_ReGameFuncs->UTIL_PlayerByIndex(m_value);
}
operator PLAYER_ANIM() const
{
return static_cast<PLAYER_ANIM>(m_value);
}
Vector& vector() const
{
return operator Vector&();
}
private:
AMX* m_amx;
cell m_value;
};
class CAmxArgs
{
public:
CAmxArgs(AMX* amx, cell* params) : m_amx(amx), m_params(params) {}
CAmxArg operator[](size_t index) const
{
return CAmxArg(m_amx, m_params[index]);
}
private:
AMX* m_amx;
cell* m_params;
};

View File

@ -282,5 +282,6 @@ AMX_NATIVE_INFO HookChain_Natives[] =
void RegisterNatives_HookChains()
{
g_amxxapi.AddNatives(HookChain_Natives);
if (api_cfg.hasReHLDS() || api_cfg.hasReGameDLL())
g_amxxapi.AddNatives(HookChain_Natives);
}

View File

@ -145,7 +145,8 @@ AMX_NATIVE_INFO Member_Natives[] =
void RegisterNatives_Members()
{
g_amxxapi.AddNatives(Member_Natives);
if (api_cfg.hasReGameDLL())
g_amxxapi.AddNatives(Member_Natives);
}
BOOL set_member(void* pdata, const member_t *member, size_t element, cell* value)
@ -300,14 +301,14 @@ cell get_member(void* pdata, const member_t *member, size_t element, cell* dest)
} else {
// char *
const char *src = get_member<const char *>(pdata, member->offset);
if (src != nullptr) {
setAmxString(dest, src, element);
return 1;
if (src == nullptr) {
setAmxString(dest, "", 1);
return 0;
}
setAmxString(dest, "", 1);
setAmxString(dest, src, element);
}
return 0;
return 1;
}
case MEMBER_FLOAT:
case MEMBER_INTEGER:

View File

@ -14,12 +14,15 @@ static cell AMX_NATIVE_CALL rg_set_animation(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_anim };
CHECK_ISPLAYER(params[arg_index]);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]);
return FALSE;
}
pPlayer->SetAnimation(static_cast<PLAYER_ANIM>(params[arg_anim]));
pPlayer->SetAnimation(CAmxArg(amx, params[arg_anim]));
return TRUE;
}
@ -38,8 +41,11 @@ static cell AMX_NATIVE_CALL rg_add_account(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_amount, arg_track_change };
CHECK_ISPLAYER(params[arg_index]);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]);
return FALSE;
}
@ -61,9 +67,11 @@ 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]);
CHECK_ISPLAYER(params[arg_index]);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]);
return FALSE;
}
@ -85,8 +93,11 @@ static cell AMX_NATIVE_CALL rg_give_default_items(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index };
CHECK_ISPLAYER(params[arg_index]);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]);
return FALSE;
}
@ -108,8 +119,11 @@ static cell AMX_NATIVE_CALL rg_give_shield(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_deploy };
CHECK_ISPLAYER(params[arg_index]);
ICSPlayer *pPlayer = g_ReGameFuncs->INDEX_TO_CSPLAYER(params[arg_index]);
if (pPlayer == nullptr || !pPlayer->IsConnected()) {
MF_LogError(amx, AMX_ERR_NATIVE, "player %i is not connected", params[arg_index]);
return FALSE;
}
@ -136,13 +150,12 @@ 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]);
CHECK_ISENTITY(params[arg_inflictor]);
CHECK_ISENTITY(params[arg_attacker]);
entvars_t *pevInflictor = VARS(INDEXENT(params[arg_inflictor]));
entvars_t *pevAttacker = VARS(INDEXENT(params[arg_attacker]));
CAmxArgs args(amx, params);
g_ReGameFuncs->RadiusDamage(args[arg_vec], args[arg_inflictor], args[arg_attacker], args[arg_damage], args[arg_radius], args[arg_ignore_class], args[arg_dmg_type]);
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;
}
@ -173,10 +186,12 @@ 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]));
CHECK_ISENTITY(params[arg_inflictor]);
CHECK_ISENTITY(params[arg_attacker]);
CAmxArgs args(amx, params);
g_ReGameFuncs->ApplyMultiDamage(args[arg_inflictor], args[arg_attacker]);
g_ReGameFuncs->ApplyMultiDamage(pevInflictor, pevAttacker);
return TRUE;
}
@ -196,14 +211,17 @@ 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]);
CHECK_ISENTITY(params[arg_inflictor]);
CHECK_ISENTITY(params[arg_victim]);
if (pVictim == nullptr) {
CAmxArgs args(amx, params);
if (params[arg_victim] < 0) { // null
MF_LogError(amx, AMX_ERR_NATIVE, "rg_multidmg_add: victim == null");
return FALSE;
}
g_ReGameFuncs->AddMultiDamage(pevInflictor, pVictim, *(float *)&params[arg_damage], params[arg_dmg_type]);
g_ReGameFuncs->AddMultiDamage(args[arg_inflictor], args[arg_victim], args[arg_damage], args[arg_dmg_type]);
return TRUE;
}
@ -229,29 +247,23 @@ 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 };
CHECK_ISENTITY(params[arg_inflictor]);
CHECK_ISENTITY(params[arg_attacker]);
CAmxArgs args(amx, params);
ICSEntity *pInflictor = g_ReGameFuncs->INDEX_TO_CSENTITY(params[arg_inflictor]);
cell *pSrc = getAmxAddr(amx, params[arg_vecSrc]);
cell *pDir = getAmxAddr(amx, params[arg_dir]);
cell *pSpread = getAmxAddr(amx, params[arg_spread]);
Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]);
Vector vecDirShooting(*(float *)&pDir[0], *(float *)&pDir[1], *(float *)&pDir[2]);
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
args[arg_shots],
args[arg_vecSrc],
args[arg_dir],
args[arg_spread],
args[arg_dist],
args[arg_bullet_type],
args[arg_tracefrq],
args[arg_dmg],
args[arg_attacker]
);
return TRUE;
@ -281,31 +293,25 @@ 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 };
CHECK_ISENTITY(params[arg_inflictor]);
CHECK_ISENTITY(params[arg_attacker]);
CAmxArgs args(amx, params);
ICSEntity *pInflictor = g_ReGameFuncs->INDEX_TO_CSENTITY(params[arg_inflictor]);
cell *pSrc = getAmxAddr(amx, params[arg_vecSrc]);
cell *pDir = getAmxAddr(amx, params[arg_dir]);
Vector vecSrc(*(float *)&pSrc[0], *(float *)&pSrc[1], *(float *)&pSrc[2]);
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
args[arg_out].vector() = 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]
args[arg_vecSrc],
args[arg_dir],
args[arg_spread],
args[arg_dist],
args[arg_penetration],
args[arg_bullet_type],
args[arg_dmg],
args[arg_range_mod],
args[arg_attacker],
args[arg_pistol],
args[arg_rand]
);
return TRUE;
@ -378,7 +384,7 @@ static cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params)
if (_message[0])
g_ReGameFuncs->EndRoundMessage(_message, event);
(*g_pCSGameRules)->TerminateRound(*(float *)&params[arg_delay], winstatus);
(*g_pCSGameRules)->TerminateRound(CAmxArg(amx, params[arg_delay]), winstatus);
return TRUE;
}
@ -404,7 +410,7 @@ static cell AMX_NATIVE_CALL rg_update_teamscores(AMX *amx, cell *params)
return TRUE;
}
AMX_NATIVE_INFO Misc_Natives[] =
AMX_NATIVE_INFO Misc_Natives_RG[] =
{
{ "rg_set_animation", rg_set_animation },
{ "rg_add_account", rg_add_account },
@ -428,5 +434,6 @@ AMX_NATIVE_INFO Misc_Natives[] =
void RegisterNatives_Misc()
{
g_amxxapi.AddNatives(Misc_Natives);
if (api_cfg.hasReGameDLL())
g_amxxapi.AddNatives(Misc_Natives_RG);
}

View File

@ -57,5 +57,6 @@ AMX_NATIVE_INFO Vtc_Natives[] =
void RegisterNatives_Vtc()
{
g_amxxapi.AddNatives(Vtc_Natives);
if (api_cfg.hasVTC())
g_amxxapi.AddNatives(Vtc_Natives);
}

View File

@ -10,6 +10,7 @@
#include <vector> // std::vector
#include <extdll.h>
#include "main.h"
#include "reapi_utils.h"
#include <cbase.h>
@ -43,6 +44,7 @@
#include "natives_members.h"
#include "natives_misc.h"
#include "natives_vtc.h"
#include "natives_helper.h"
#undef DLLEXPORT
#ifdef _WIN32

View File

@ -2,16 +2,10 @@
void Broadcast(const char *sentence)
{
char text[32];
char text[128];
snprintf(text, sizeof text, "%!MRAD_%s", sentence);
strcpy(text, "%!MRAD_");
strcat(text, UTIL_VarArgs("%s", sentence));
static int gmsgSendAudio = 0;
if (gmsgSendAudio == 0 && !(gmsgSendAudio = REG_USER_MSG("SendAudio", -1)))
return;
g_pengfuncsTable->pfnMessageBegin(MSG_BROADCAST, REG_USER_MSG("SendAudio", -1), NULL, NULL);
g_pengfuncsTable->pfnMessageBegin(MSG_BROADCAST, gmsgSendAudio, NULL, NULL);
g_pengfuncsTable->pfnWriteByte(0);
g_pengfuncsTable->pfnWriteString(text);
g_pengfuncsTable->pfnWriteShort(100);
@ -20,10 +14,6 @@ void Broadcast(const char *sentence)
void UpdateTeamScores()
{
static int gmsgTeamScore = 0;
if (gmsgTeamScore == 0 && !(gmsgTeamScore = REG_USER_MSG("TeamScore", -1)))
return;
g_pengfuncsTable->pfnMessageBegin(MSG_ALL, gmsgTeamScore, NULL, NULL);
g_pengfuncsTable->pfnWriteString("CT");
g_pengfuncsTable->pfnWriteShort((*g_pCSGameRules)->m_iNumCTWins);

View File

@ -7,7 +7,6 @@ char(&ArraySizeHelper(T(&array)[N]))[N];
#define INDEXENT edictByIndex
#define ENTINDEX indexOfEdict
extern edict_t* g_pEdicts;
extern enginefuncs_t* g_pengfuncsTable;
inline size_t indexOfEdict(edict_t* ed)