mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
Cstrike: Make CS_OnBuy forward more reliable - part 4
Added support for shield , which is a special case. Moved hashmap creation to OnPluginsLoaded.
This commit is contained in:
parent
884c5e9643
commit
0728fee706
@ -163,14 +163,17 @@
|
|||||||
* CS_OnBuy forward
|
* CS_OnBuy forward
|
||||||
*/
|
*/
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
#define CS_IDENT_GIVENSHIELD "_ZN11CBasePlayer10GiveShieldEb"
|
||||||
#define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc"
|
#define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc"
|
||||||
#define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib"
|
#define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib"
|
||||||
#define CS_IDENT_HIDDEN_STATE false
|
#define CS_IDENT_HIDDEN_STATE false
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
#define CS_IDENT_GIVENSHIELD "_ZN11CBasePlayer10GiveShieldEb"
|
||||||
#define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc"
|
#define CS_IDENT_GIVENAMEDITEM "_ZN11CBasePlayer13GiveNamedItemEPKc"
|
||||||
#define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib"
|
#define CS_IDENT_ADDACCOUNT "_ZN11CBasePlayer10AddAccountEib"
|
||||||
#define CS_IDENT_HIDDEN_STATE true
|
#define CS_IDENT_HIDDEN_STATE true
|
||||||
#elif defined(WIN32)
|
#elif defined(WIN32)
|
||||||
|
#define CS_IDENT_GIVENSHIELD "\\x56\\x8B\\x2A\\x57\\x33\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\xB0"
|
||||||
#define CS_IDENT_GIVENAMEDITEM "\\x8B\\x2A\\x2A\\x2A\\x56\\x57\\x8B\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x2B"
|
#define CS_IDENT_GIVENAMEDITEM "\\x8B\\x2A\\x2A\\x2A\\x56\\x57\\x8B\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x2B"
|
||||||
#define CS_IDENT_ADDACCOUNT "\\x8B\\x2A\\x2A\\x2A\\x56\\x8B\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x03"
|
#define CS_IDENT_ADDACCOUNT "\\x8B\\x2A\\x2A\\x2A\\x56\\x8B\\x2A\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x03"
|
||||||
#define CS_IDENT_HIDDEN_STATE false
|
#define CS_IDENT_HIDDEN_STATE false
|
||||||
|
@ -47,9 +47,7 @@ int *g_UseBotArgs = NULL;
|
|||||||
const char **g_BotArgs = NULL;
|
const char **g_BotArgs = NULL;
|
||||||
|
|
||||||
CDetour *g_ClientCommandDetour = NULL;
|
CDetour *g_ClientCommandDetour = NULL;
|
||||||
CDetour *g_CanBuyThisDetour = NULL;
|
CDetour *g_GiveShieldDetour = NULL;
|
||||||
CDetour *g_BuyItemDetour = NULL;
|
|
||||||
CDetour *g_BuyGunAmmoDetour = NULL;
|
|
||||||
CDetour *g_GiveNamedItemDetour = NULL;
|
CDetour *g_GiveNamedItemDetour = NULL;
|
||||||
CDetour *g_AddAccountDetour = NULL;
|
CDetour *g_AddAccountDetour = NULL;
|
||||||
|
|
||||||
@ -93,7 +91,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
|
|||||||
{
|
{
|
||||||
const char *command = CMD_ARGV(0);
|
const char *command = CMD_ARGV(0);
|
||||||
|
|
||||||
// A new command is triggered, reset current item.
|
// A new command is triggered, reset variable, always.
|
||||||
g_CurrentItemId = 0;
|
g_CurrentItemId = 0;
|
||||||
|
|
||||||
// Purpose is to retrieve an item id based on alias name or selected item from menu,
|
// Purpose is to retrieve an item id based on alias name or selected item from menu,
|
||||||
@ -102,7 +100,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
|
|||||||
{
|
{
|
||||||
int itemId = 0;
|
int itemId = 0;
|
||||||
|
|
||||||
// Handling via menu.
|
// Handling buy via menu.
|
||||||
if (!strcmp(command, "menuselect"))
|
if (!strcmp(command, "menuselect"))
|
||||||
{
|
{
|
||||||
int slot = atoi(CMD_ARGV(1));
|
int slot = atoi(CMD_ARGV(1));
|
||||||
@ -148,8 +146,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handling via alias
|
else // Handling buy via alias
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (g_ItemAliasList.retrieve(command, &itemId))
|
if (g_ItemAliasList.retrieve(command, &itemId))
|
||||||
{
|
{
|
||||||
@ -174,26 +171,47 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
|
|||||||
|
|
||||||
DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlayer::GiveNamedItem(const char *pszName)
|
DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlayer::GiveNamedItem(const char *pszName)
|
||||||
{
|
{
|
||||||
|
// If the current item id is not null, this means player has triggers a buy command.
|
||||||
if (g_CurrentItemId && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(PrivateToIndex(this)), static_cast<cell>(g_CurrentItemId)) > 0)
|
if (g_CurrentItemId && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(PrivateToIndex(this)), static_cast<cell>(g_CurrentItemId)) > 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From here, forward is not blocked, resetting this
|
||||||
|
// to ignore code in AddAccount which is called right after.
|
||||||
g_CurrentItemId = 0;
|
g_CurrentItemId = 0;
|
||||||
|
|
||||||
|
// Give me my item!
|
||||||
DETOUR_MEMBER_CALL(GiveNamedItem)(pszName);
|
DETOUR_MEMBER_CALL(GiveNamedItem)(pszName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DETOUR_DECL_MEMBER1(GiveShield, void, bool, bRetire) // void CBasePlayer::GiveShield(bool bRetire)
|
||||||
DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void CBasePlayer::AddAccount(int amount, bool bTrackChange)
|
|
||||||
{
|
{
|
||||||
if (g_CurrentItemId)
|
// Special case for shield. Game doesn't use GiveNamedItem() to give a shield.
|
||||||
|
if (g_CurrentItemId == CSI_SHIELDGUN && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(PrivateToIndex(this)), CSI_SHIELDGUN) > 0)
|
||||||
{
|
{
|
||||||
g_CurrentItemId = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From here, forward is not blocked, resetting this
|
||||||
|
// to ignore code in AddAccount which is called right after.
|
||||||
|
g_CurrentItemId = 0;
|
||||||
|
|
||||||
|
// Give me my shield!
|
||||||
|
DETOUR_MEMBER_CALL(GiveShield)(bRetire);
|
||||||
|
}
|
||||||
|
|
||||||
|
DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void CBasePlayer::AddAccount(int amount, bool bTrackChange)
|
||||||
|
{
|
||||||
|
// No buy command or forward not blocked.
|
||||||
|
// Resuming game flow.
|
||||||
|
if (!g_CurrentItemId)
|
||||||
|
{
|
||||||
DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange);
|
DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's reset this right away to avoid issues.
|
||||||
|
g_CurrentItemId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,9 +257,11 @@ void CtrlDetours_BuyCommands(bool set)
|
|||||||
{
|
{
|
||||||
if (set)
|
if (set)
|
||||||
{
|
{
|
||||||
|
void *giveShieldAddress = UTIL_FindAddressFromEntry(CS_IDENT_GIVENSHIELD , CS_IDENT_HIDDEN_STATE);
|
||||||
void *giveNamedItemAddress = UTIL_FindAddressFromEntry(CS_IDENT_GIVENAMEDITEM, CS_IDENT_HIDDEN_STATE);
|
void *giveNamedItemAddress = UTIL_FindAddressFromEntry(CS_IDENT_GIVENAMEDITEM, CS_IDENT_HIDDEN_STATE);
|
||||||
void *addAccountAddress = UTIL_FindAddressFromEntry(CS_IDENT_ADDACCOUNT , CS_IDENT_HIDDEN_STATE);
|
void *addAccountAddress = UTIL_FindAddressFromEntry(CS_IDENT_ADDACCOUNT , CS_IDENT_HIDDEN_STATE);
|
||||||
|
|
||||||
|
g_GiveShieldDetour = DETOUR_CREATE_MEMBER_FIXED(GiveShield, giveShieldAddress);
|
||||||
g_GiveNamedItemDetour = DETOUR_CREATE_MEMBER_FIXED(GiveNamedItem, giveNamedItemAddress);
|
g_GiveNamedItemDetour = DETOUR_CREATE_MEMBER_FIXED(GiveNamedItem, giveNamedItemAddress);
|
||||||
g_AddAccountDetour = DETOUR_CREATE_MEMBER_FIXED(AddAccount, addAccountAddress);
|
g_AddAccountDetour = DETOUR_CREATE_MEMBER_FIXED(AddAccount, addAccountAddress);
|
||||||
|
|
||||||
@ -249,9 +269,37 @@ void CtrlDetours_BuyCommands(bool set)
|
|||||||
{
|
{
|
||||||
MF_Log("No Buy Commands detours could be initialized - Disabled Buy forward.");
|
MF_Log("No Buy Commands detours could be initialized - Disabled Buy forward.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (g_GiveShieldDetour)
|
||||||
|
g_GiveShieldDetour->Destroy();
|
||||||
|
|
||||||
|
if (g_GiveNamedItemDetour)
|
||||||
|
g_GiveNamedItemDetour->Destroy();
|
||||||
|
|
||||||
|
if (g_AddAccountDetour)
|
||||||
|
g_AddAccountDetour->Destroy();
|
||||||
|
|
||||||
|
g_ItemAliasList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToggleDetour_BuyCommands(bool enable)
|
||||||
|
{
|
||||||
|
if (g_GiveShieldDetour)
|
||||||
|
(enable) ? g_GiveShieldDetour->EnableDetour() : g_GiveShieldDetour->DisableDetour();
|
||||||
|
|
||||||
|
if (g_GiveNamedItemDetour)
|
||||||
|
(enable) ? g_GiveNamedItemDetour->EnableDetour() : g_GiveNamedItemDetour->DisableDetour();
|
||||||
|
|
||||||
|
if (g_AddAccountDetour)
|
||||||
|
(enable) ? g_AddAccountDetour->EnableDetour() : g_AddAccountDetour->DisableDetour();
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
// Build the item alias list.
|
// Build the item alias list.
|
||||||
// Used in ClientCommand to check and get fastly item id from aiias name.
|
// Used in ClientCommand to check and get fastly item id from alias name.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *alias;
|
char *alias;
|
||||||
@ -298,21 +346,6 @@ void CtrlDetours_BuyCommands(bool set)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (g_GiveNamedItemDetour)
|
|
||||||
g_GiveNamedItemDetour->Destroy();
|
|
||||||
|
|
||||||
if (g_AddAccountDetour)
|
|
||||||
g_AddAccountDetour->Destroy();
|
|
||||||
|
|
||||||
g_ItemAliasList.clear();
|
g_ItemAliasList.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleDetour_BuyCommands(bool enable)
|
|
||||||
{
|
|
||||||
if (g_GiveNamedItemDetour)
|
|
||||||
(enable) ? g_GiveNamedItemDetour->EnableDetour() : g_GiveNamedItemDetour->DisableDetour();
|
|
||||||
|
|
||||||
if (g_AddAccountDetour)
|
|
||||||
(enable) ? g_AddAccountDetour->EnableDetour() : g_AddAccountDetour->DisableDetour();
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user