Cstrike: Implement CS_OnBuy forward.
This commit is contained in:
parent
38e2e3e393
commit
f130a8ea89
|
@ -1,3 +1,35 @@
|
|||
/* AMX Mod X
|
||||
* Counter-Strike Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
#ifndef CSTRIKE_DATA_H
|
||||
#define CSTRIKE_DATA_H
|
||||
|
||||
|
@ -123,10 +155,64 @@
|
|||
#define CS_CLICMD_OFFS_BOTARGS 22
|
||||
#endif
|
||||
|
||||
/**
|
||||
* CS_OnBuy forward
|
||||
*/
|
||||
#if defined(__linux__)
|
||||
#define CS_SYM_CANBUYTHIS "_Z10CanBuyThisP11CBasePlayeri"
|
||||
#define CS_SYM_BUYITEM "_Z7BuyItemP11CBasePlayeri"
|
||||
#define CS_SYM_BUYGUNAMMO "_Z10BuyGunAmmoR11CBasePlayerR15CBasePlayerItemb"
|
||||
#elif defined(__APPLE__)
|
||||
#define CS_SYM_CANBUYTHIS "__Z10CanBuyThisP11CBasePlayeri"
|
||||
#define CS_SYM_BUYITEM "__Z7BuyItemP11CBasePlayeri"
|
||||
#define CS_SYM_BUYGUNAMMO "__Z10BuyGunAmmoR11CBasePlayerR15CBasePlayerItemb"
|
||||
#elif defined(WIN32)
|
||||
#define CS_SIG_CANBUYTHIS "\x53\x8B\x2A\x2A\x2A\x2A\x2A\x56\x8B\x2A\x2A\x2A\x57"
|
||||
#define CS_SIG_BUYITEM "\x53\x56\x8B\x2A\x2A\x2A\xBB\x2A\x2A\x2A\x2A\x57\x53"
|
||||
#define CS_SIG_BUYGUNAMMO "\x56\x57\x8B\x2A\x2A\x2A\x6A\x2A\x8B\x2A\xE8\x2A\x2A\x2A\x2A\x84\x2A\x0F"
|
||||
#endif
|
||||
|
||||
#define CSI_P228 CSW_P228
|
||||
#define CSI_SCOUT CSW_SCOUT
|
||||
#define CSI_HEGRENADE CSW_HEGRENADE
|
||||
#define CSI_XM1014 CSW_XM1014
|
||||
#define CSI_C4 CSW_C4
|
||||
#define CSI_MAC10 CSW_MAC10
|
||||
#define CSI_AUG CSW_AUG
|
||||
#define CSI_SMOKEGRENADE CSW_SMOKEGRENADE
|
||||
#define CSI_ELITE CSW_ELITE
|
||||
#define CSI_FIVESEVEN CSW_FIVESEVEN
|
||||
#define CSI_UMP45 CSW_UMP45
|
||||
#define CSI_SG550 CSW_SG550
|
||||
#define CSI_GALI CSW_GALI
|
||||
#define CSI_FAMAS CSW_FAMAS
|
||||
#define CSI_USP CSW_USP
|
||||
#define CSI_GLOCK18 CSW_GLOCK18
|
||||
#define CSI_AWP CSW_AWP
|
||||
#define CSI_MP5NAVY CSW_MP5NAVY
|
||||
#define CSI_M249 CSW_M249
|
||||
#define CSI_M3 CSW_M3
|
||||
#define CSI_M4A1 CSW_M4A1
|
||||
#define CSI_TMP CSW_TMP
|
||||
#define CSI_G3SG1 CSW_G3SG1
|
||||
#define CSI_FLASHBANG CSW_FLASHBANG
|
||||
#define CSI_DEAGLE CSW_DEAGLE
|
||||
#define CSI_SG552 CSW_SG552
|
||||
#define CSI_AK47 CSW_AK47
|
||||
#define CSI_KNIFE CSW_KNIFE
|
||||
#define CSI_P90 CSW_P90
|
||||
#define CSI_SHIELDGUN CSW_SHIELDGUN
|
||||
#define CSI_VEST CSW_VEST // Custom
|
||||
#define CSI_VESTHELM CSW_VESTHELM // Custom
|
||||
#define CSI_DEFUSER 33 // Custom
|
||||
#define CSI_NVGS 34 // Custom
|
||||
#define CSI_PRIMAMMO 36 // Custom
|
||||
#define CSI_SECAMMO 37 // Custom
|
||||
|
||||
#define BITS_PISTOLS (1<<CSI_GLOCK18 | 1<<CSI_USP | 1<<CSI_P228 | 1<<CSI_DEAGLE | 1<<CSI_ELITE | 1<<CSI_FIVESEVEN)
|
||||
|
||||
// Ids of weapons in CS
|
||||
#define CSW_P228 1
|
||||
//#define CSW_SHIELD 2
|
||||
#define CSW_SCOUT 3
|
||||
#define CSW_HEGRENADE 4
|
||||
#define CSW_XM1014 5
|
||||
|
@ -157,6 +243,7 @@
|
|||
#define CSW_P90 30
|
||||
#define CSW_VEST 31 // Brand new invention!
|
||||
#define CSW_VESTHELM 32 // Brand new invention!
|
||||
#define CSW_SHIELDGUN 99
|
||||
|
||||
// These are used with armoury_entity:s.
|
||||
#define CSA_MP5NAVY 0
|
||||
|
|
|
@ -1,4 +1,37 @@
|
|||
/* AMX Mod X
|
||||
* Counter-Strike Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
#include "CstrikeDatas.h"
|
||||
#include "CstrikeUtils.h"
|
||||
#include <MemoryUtils.h>
|
||||
#include "CDetour/detours.h"
|
||||
|
||||
|
@ -6,24 +39,32 @@
|
|||
#include <mach-o/nlist.h>
|
||||
#endif
|
||||
|
||||
void CtrlDetour_ClientCommand(bool set);
|
||||
void CtrlDetours(bool set);
|
||||
|
||||
int g_CSCliCmdFwd = -1;
|
||||
int g_CSBuyCmdFwd = -1;
|
||||
|
||||
int *g_UseBotArgs = NULL;
|
||||
const char **g_BotArgs = NULL;
|
||||
|
||||
CDetour *g_ClientCommandDetour = NULL;
|
||||
CDetour *g_CanBuyThisDetour = NULL;
|
||||
CDetour *g_BuyItemDetour = NULL;
|
||||
CDetour *g_BuyGunAmmoDetour = NULL;
|
||||
|
||||
|
||||
void InitializeHacks()
|
||||
{
|
||||
CtrlDetour_ClientCommand(true);
|
||||
CtrlDetours(true);
|
||||
}
|
||||
|
||||
void ShutdownHacks()
|
||||
{
|
||||
CtrlDetour_ClientCommand(false);
|
||||
CtrlDetours(false);
|
||||
}
|
||||
|
||||
DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict)
|
||||
|
||||
DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientCommand(edict_t *pEntity)
|
||||
{
|
||||
if (*g_UseBotArgs)
|
||||
{
|
||||
|
@ -39,58 +80,146 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict)
|
|||
DETOUR_STATIC_CALL(C_ClientCommand)(pEdict);
|
||||
}
|
||||
|
||||
void CtrlDetour_ClientCommand(bool set)
|
||||
DETOUR_DECL_STATIC2(CanBuyThis, bool, void*, pvPlayer, int, weaponId) // bool CanBuyThis(CBasePlayer *pPlayer, int weaponId)
|
||||
{
|
||||
if (weaponId != CSI_SHIELDGUN) // This will be handled before with BuyItem. Avoiding duplicated call.
|
||||
{
|
||||
int player = PrivateToIndex(pvPlayer);
|
||||
|
||||
if (MF_IsPlayerAlive(player) && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(player), static_cast<cell>(weaponId)) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return DETOUR_STATIC_CALL(CanBuyThis)(pvPlayer, weaponId);
|
||||
}
|
||||
|
||||
DETOUR_DECL_STATIC2(BuyItem, void, void*, pvPlayer, int, iSlot) // void BuyItem(CBasePlayer *pPlayer, int iSlot)
|
||||
{
|
||||
int player = PrivateToIndex(pvPlayer);
|
||||
|
||||
if (MF_IsPlayerAlive(player))
|
||||
{
|
||||
static const int itemSlotToWeaponId[] = {-1, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, CSI_DEFUSER, CSI_SHIELDGUN};
|
||||
|
||||
if (iSlot >= 1 && iSlot <= 8 && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(player), static_cast<cell>(itemSlotToWeaponId[iSlot])) > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DETOUR_STATIC_CALL(BuyItem)(pvPlayer, iSlot);
|
||||
}
|
||||
|
||||
DETOUR_DECL_STATIC3(BuyGunAmmo, bool, void*, pvPlayer, void*, pvWeapon, bool, bBlinkMoney) // bool BuyGunAmmo(CBasePlayer *player, CBasePlayerItem *weapon, bool bBlinkMoney)
|
||||
{
|
||||
int player = PrivateToIndex(pvPlayer);
|
||||
|
||||
if (MF_IsPlayerAlive(player))
|
||||
{
|
||||
edict_t *pWeapon = PrivateToEdict(pvWeapon);
|
||||
|
||||
if (pWeapon)
|
||||
{
|
||||
int weaponId = *((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
|
||||
int ammoId = (1<<weaponId & BITS_PISTOLS) ? CSI_SECAMMO : CSI_PRIMAMMO;
|
||||
|
||||
if (MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(player), static_cast<cell>(ammoId)) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DETOUR_STATIC_CALL(BuyGunAmmo)(pvPlayer, pvWeapon, bBlinkMoney);
|
||||
}
|
||||
|
||||
|
||||
void CtrlDetours(bool set)
|
||||
{
|
||||
#if defined AMD64
|
||||
#error UNSUPPORTED
|
||||
#endif
|
||||
|
||||
void *target = (void *)MDLL_ClientCommand;
|
||||
|
||||
if (!g_UseBotArgs)
|
||||
if (set)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
char libName[256];
|
||||
uintptr_t base;
|
||||
|
||||
void *target = (void *)MDLL_ClientCommand;
|
||||
|
||||
if (!g_MemUtils.GetLibraryOfAddress(target, libName, sizeof(libName), &base))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
void *canBuyThisAddress = g_MemUtils.DecodeAndFindPattern(target, CS_SIG_CANBUYTHIS);
|
||||
void *buyItemAddress = g_MemUtils.DecodeAndFindPattern(target, CS_SIG_BUYITEM);
|
||||
void *buyGunAmmoAddress = g_MemUtils.DecodeAndFindPattern(target, CS_SIG_BUYGUNAMMO);
|
||||
|
||||
g_UseBotArgs = *(int **)((unsigned char *)target + CS_CLICMD_OFFS_USEBOTARGS);
|
||||
g_BotArgs = (const char **)*(const char **)((unsigned char *)target + CS_CLICMD_OFFS_BOTARGS);
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
void *canBuyThisAddress = g_MemUtils.ResolveSymbol(target, CS_SYM_CANBUYTHIS);
|
||||
void *buyItemAddress = g_MemUtils.ResolveSymbol(target, CS_SYM_BUYITEM);
|
||||
void *buyGunAmmoAddress = g_MemUtils.ResolveSymbol(target, CS_SYM_BUYGUNAMMO);
|
||||
|
||||
g_UseBotArgs = (int *)g_MemUtils.ResolveSymbol(target, "UseBotArgs");
|
||||
g_BotArgs = (const char **)g_MemUtils.ResolveSymbol(target, "BotArgs");
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
/* Using dlsym on OS X won't work because the symbols are hidden */
|
||||
char dll[256];
|
||||
uintptr_t base;
|
||||
g_MemUtils.GetLibraryOfAddress(target, dll, sizeof(dll), &base);
|
||||
|
||||
struct nlist symbols[3];
|
||||
struct nlist symbols[6];
|
||||
memset(symbols, 0, sizeof(symbols));
|
||||
symbols[0].n_un.n_name = (char *)"_UseBotArgs";
|
||||
symbols[1].n_un.n_name = (char *)"_BotArgs";
|
||||
if (nlist(dll, symbols) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_UseBotArgs = (int *)(base + symbols[0].n_value);
|
||||
g_BotArgs = (const char **)(base + symbols[1].n_value);
|
||||
|
||||
#elif defined(WIN32)
|
||||
symbols[0].n_un.n_name = (char *)CS_SYM_CANBUYTHIS;
|
||||
symbols[1].n_un.n_name = (char *)CS_SYM_BUYITEM;
|
||||
symbols[2].n_un.n_name = (char *)CS_SYM_BUYGUNAMMO;
|
||||
symbols[3].n_un.n_name = (char *)"_UseBotArgs";
|
||||
symbols[4].n_un.n_name = (char *)"_BotArgs";
|
||||
|
||||
g_UseBotArgs = *(int **)((unsigned char *)target + CS_CLICMD_OFFS_USEBOTARGS);
|
||||
g_BotArgs = (const char **)*(const char **)((unsigned char *)target + CS_CLICMD_OFFS_BOTARGS);
|
||||
if (nlist(libName, symbols) != 0) { return; }
|
||||
|
||||
void *canBuyThisAddress = (void *)(base + symbols[0].n_value);
|
||||
void *buyItemAddress = (void *)(base + symbols[1].n_value);
|
||||
void *buyGunAmmoAddress = (void *)(base + symbols[2].n_value);
|
||||
void *g_UseBotArgs = (void *)(base + symbols[3].n_value);
|
||||
void *g_BotArgs = (void *)(base + symbols[4].n_value);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if (set)
|
||||
{
|
||||
g_ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, target);
|
||||
g_ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, target);
|
||||
g_CanBuyThisDetour = DETOUR_CREATE_STATIC_FIXED(CanBuyThis, canBuyThisAddress);
|
||||
g_BuyItemDetour = DETOUR_CREATE_STATIC_FIXED(BuyItem, buyItemAddress);
|
||||
g_BuyGunAmmoDetour = DETOUR_CREATE_STATIC_FIXED(BuyGunAmmo, buyGunAmmoAddress);
|
||||
|
||||
if (g_ClientCommandDetour != NULL)
|
||||
{
|
||||
g_ClientCommandDetour->EnableDetour();
|
||||
else
|
||||
{
|
||||
MF_Log("No Client Commands detours could be initialized - Disabled Client Command forward.");
|
||||
}
|
||||
|
||||
if (g_CanBuyThisDetour != NULL && g_BuyItemDetour != NULL && g_BuyGunAmmoDetour != NULL)
|
||||
{
|
||||
g_CanBuyThisDetour->EnableDetour();
|
||||
g_BuyItemDetour->EnableDetour();
|
||||
g_BuyGunAmmoDetour->EnableDetour();
|
||||
}
|
||||
else
|
||||
{
|
||||
MF_Log("No Buy Commands detours could be initialized - Disabled Buy forward.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_CanBuyThisDetour->Destroy();
|
||||
g_BuyItemDetour->Destroy();
|
||||
g_BuyGunAmmoDetour->Destroy();
|
||||
g_ClientCommandDetour->Destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,4 +84,36 @@ void UTIL_TextMsg_Generic(edict_t* pPlayer, const char* message);
|
|||
#define GETEDICT(n) \
|
||||
((n >= 1 && n <= gpGlobals->maxClients) ? MF_GetPlayerEdict(n) : INDEXENT(n))
|
||||
|
||||
|
||||
inline edict_t *PrivateToEdict(const void *pdata)
|
||||
{
|
||||
if (!pdata)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ptr = (char*)pdata;
|
||||
ptr += 4;
|
||||
entvars_t *pev = *(entvars_t **)ptr;
|
||||
|
||||
if (!pev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pev->pContainingEntity;
|
||||
};
|
||||
|
||||
inline int PrivateToIndex(const void *pdata)
|
||||
{
|
||||
edict_t *pEntity = PrivateToEdict(pdata);
|
||||
|
||||
if (!pEntity)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ENTINDEX(pEntity);
|
||||
};
|
||||
|
||||
#endif // CSTRIKE_UTILS_H
|
|
@ -33,7 +33,9 @@
|
|||
#include "amxxmodule.h"
|
||||
|
||||
extern AMX_NATIVE_INFO cstrikeNatives[];
|
||||
|
||||
extern int g_CSCliCmdFwd;
|
||||
extern int g_CSBuyCmdFwd;
|
||||
|
||||
void InitializeHacks();
|
||||
void ShutdownHacks();
|
||||
|
@ -57,6 +59,7 @@ void OnAmxxAttach()
|
|||
void OnPluginsLoaded()
|
||||
{
|
||||
g_CSCliCmdFwd = MF_RegisterForward("CS_InternalCommand", ET_STOP, FP_CELL, FP_STRING, FP_DONE);
|
||||
g_CSBuyCmdFwd = MF_RegisterForward("CS_OnBuy", ET_STOP, FP_CELL, FP_CELL, FP_DONE);
|
||||
}
|
||||
|
||||
void OnAmxxDetach()
|
||||
|
|
|
@ -343,6 +343,7 @@ native cs_set_c4_explode_time(index, Float:value);
|
|||
native bool:cs_get_c4_defusing(c4index);
|
||||
|
||||
native cs_set_c4_defusing(c4index, bool:defusing);
|
||||
|
||||
/**
|
||||
* Called when CS internally fires a command to a player. It does this for a few
|
||||
* functions, most notably rebuy/autobuy functionality. This is also used to pass
|
||||
|
@ -353,3 +354,52 @@ native cs_set_c4_defusing(c4index, bool:defusing);
|
|||
* @return PLUGIN_HANDLED to block, PLUGIN_CONTINUE for normal operation.
|
||||
*/
|
||||
forward CS_InternalCommand(id, const cmd[]);
|
||||
|
||||
|
||||
/**
|
||||
* The following constants are used with CS_OnBuy forward.
|
||||
*/
|
||||
#define CSI_P228 CSW_P228
|
||||
#define CSI_SCOUT CSW_SCOUT
|
||||
#define CSI_HEGRENADE CSW_HEGRENADE
|
||||
#define CSI_XM1014 CSW_XM1014
|
||||
#define CSI_C4 CSW_C4
|
||||
#define CSI_MAC10 CSW_MAC10
|
||||
#define CSI_AUG CSW_AUG
|
||||
#define CSI_SMOKEGRENADE CSW_SMOKEGRENADE
|
||||
#define CSI_ELITE CSW_ELITE
|
||||
#define CSI_FIVESEVEN CSW_FIVESEVEN
|
||||
#define CSI_UMP45 CSW_UMP45
|
||||
#define CSI_SG550 CSW_SG550
|
||||
#define CSI_GALI CSW_GALI
|
||||
#define CSI_FAMAS CSW_FAMAS
|
||||
#define CSI_USP CSW_USP
|
||||
#define CSI_GLOCK18 CSW_GLOCK18
|
||||
#define CSI_AWP CSW_AWP
|
||||
#define CSI_MP5NAVY CSW_MP5NAVY
|
||||
#define CSI_M249 CSW_M249
|
||||
#define CSI_M3 CSW_M3
|
||||
#define CSI_M4A1 CSW_M4A1
|
||||
#define CSI_TMP CSW_TMP
|
||||
#define CSI_G3SG1 CSW_G3SG1
|
||||
#define CSI_FLASHBANG CSW_FLASHBANG
|
||||
#define CSI_DEAGLE CSW_DEAGLE
|
||||
#define CSI_SG552 CSW_SG552
|
||||
#define CSI_AK47 CSW_AK47
|
||||
#define CSI_P90 CSW_P90
|
||||
#define CSI_SHIELDGUN CSW_SHIELDGUN
|
||||
#define CSI_VEST CSW_VEST // Custom
|
||||
#define CSI_VESTHELM CSW_VESTHELM // Custom
|
||||
#define CSI_DEFUSER 33 // Custom
|
||||
#define CSI_NVGS 34 // Custom
|
||||
#define CSI_PRIMAMMO 36 // Custom
|
||||
#define CSI_SECAMMO 37 // Custom
|
||||
|
||||
/**
|
||||
* Called when a player attempts to purchase an item.
|
||||
* Return PLUGIN_CONTINUE to allow the purchase or return a higher action to deny.
|
||||
*
|
||||
* @param id Player index.
|
||||
* @param item Item index, see CSI_* constants.
|
||||
*/
|
||||
forward CS_OnBuy(index, item);
|
||||
|
|
|
@ -56,6 +56,14 @@ ret name(void)
|
|||
ret (*name##_Actual)(p1type) = NULL; \
|
||||
ret name(p1type p1name)
|
||||
|
||||
#define DETOUR_DECL_STATIC2(name, ret, p1type, p1name, p2type, p2name) \
|
||||
ret (*name##_Actual)(p1type, p2type) = NULL; \
|
||||
ret name(p1type p1name, p2type p2name)
|
||||
|
||||
#define DETOUR_DECL_STATIC3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \
|
||||
ret (*name##_Actual)(p1type, p2type, p3type) = NULL; \
|
||||
ret name(p1type p1name, p2type p2name, p3type p3name)
|
||||
|
||||
#define DETOUR_DECL_STATIC4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \
|
||||
ret (*name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \
|
||||
ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name)
|
||||
|
@ -127,9 +135,9 @@ ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name
|
|||
#define GET_STATIC_CALLBACK(name) (void *)&name
|
||||
#define GET_STATIC_TRAMPOLINE(name) (void **)&name##_Actual
|
||||
|
||||
#define DETOUR_CREATE_MEMBER(name, gamedata, target) CDetourManager::CreateDetour(GET_MEMBER_CALLBACK(name), GET_MEMBER_TRAMPOLINE(name), gamedata, target);
|
||||
#define DETOUR_CREATE_STATIC(name, gamedata, target) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), gamedata, target);
|
||||
#define DETOUR_CREATE_STATIC_FIXED(name, address) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), address);
|
||||
#define DETOUR_CREATE_MEMBER(name, gamedata, target) CDetourManager::CreateDetour(GET_MEMBER_CALLBACK(name), GET_MEMBER_TRAMPOLINE(name), gamedata, target);
|
||||
#define DETOUR_CREATE_STATIC(name, gamedata, target) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), gamedata, target);
|
||||
#define DETOUR_CREATE_STATIC_FIXED(name, address) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), address);
|
||||
|
||||
class GenericClass {};
|
||||
typedef void (GenericClass::*VoidFunc)();
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "MemoryUtils.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <fcntl.h>
|
||||
|
@ -63,8 +64,6 @@
|
|||
#endif // MAC_OS_X_VERSION_10_6
|
||||
#endif // __APPLE__
|
||||
|
||||
|
||||
|
||||
MemoryUtils g_MemUtils;
|
||||
|
||||
MemoryUtils::MemoryUtils()
|
||||
|
@ -103,6 +102,19 @@ MemoryUtils::~MemoryUtils()
|
|||
#endif
|
||||
}
|
||||
|
||||
void *MemoryUtils::DecodeAndFindPattern(const void *libPtr, const char *pattern)
|
||||
{
|
||||
unsigned char real_sig[511];
|
||||
size_t real_bytes = DecodeHexString(real_sig, sizeof(real_sig), pattern);
|
||||
|
||||
if (real_bytes >= 1)
|
||||
{
|
||||
return FindPattern(libPtr, (char*)real_sig, real_bytes);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t len)
|
||||
{
|
||||
DynLibInfo lib;
|
||||
|
@ -655,3 +667,39 @@ bool MemoryUtils::GetLibraryOfAddress(const void *libPtr, char *buffer, size_t m
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t MemoryUtils::DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr)
|
||||
{
|
||||
size_t written = 0;
|
||||
size_t length = strlen(hexstr);
|
||||
|
||||
for (size_t i = 0; i < length; i++)
|
||||
{
|
||||
if (written >= maxlength)
|
||||
break;
|
||||
|
||||
buffer[written++] = hexstr[i];
|
||||
if (hexstr[i] == '\\' && hexstr[i + 1] == 'x')
|
||||
{
|
||||
if (i + 3 >= length)
|
||||
continue;
|
||||
|
||||
/* Get the hex part. */
|
||||
char s_byte[3];
|
||||
int r_byte;
|
||||
s_byte[0] = hexstr[i + 2];
|
||||
s_byte[1] = hexstr[i + 3];
|
||||
s_byte[2] = '\0';
|
||||
|
||||
/* Read it as an integer */
|
||||
sscanf(s_byte, "%x", &r_byte);
|
||||
|
||||
/* Save the value */
|
||||
buffer[written - 1] = r_byte;
|
||||
|
||||
/* Adjust index */
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
|
@ -44,6 +44,10 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1400
|
||||
#pragma warning (disable:4996) /* Disable deprecation warnings */
|
||||
#endif
|
||||
|
||||
struct DynLibInfo
|
||||
{
|
||||
void *baseAddress;
|
||||
|
@ -66,6 +70,7 @@ class MemoryUtils
|
|||
~MemoryUtils();
|
||||
|
||||
public:
|
||||
void *DecodeAndFindPattern(const void *libPtr, const char *pattern);
|
||||
void *FindPattern(const void *libPtr, const char *pattern, size_t len);
|
||||
void *ResolveSymbol(void *handle, const char *symbol);
|
||||
|
||||
|
@ -73,6 +78,9 @@ class MemoryUtils
|
|||
bool GetLibraryInfo(const void *libPtr, DynLibInfo &lib);
|
||||
bool GetLibraryOfAddress(const void *libPtr, char *buffer, size_t maxlength, uintptr_t *base);
|
||||
|
||||
public:
|
||||
size_t DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr);
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
private:
|
||||
ke::Vector<LibSymbolTable *> m_SymTables;
|
||||
|
|
Loading…
Reference in New Issue
Block a user