From 0cf39307e071b6965e291551b60bc960c36757a5 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 3 Jul 2014 19:40:30 +0200 Subject: [PATCH] Cstrike: Make CS_OnBuy forward more reliable - part 2 Purpose is to have the forward be called only on actual buying. This has been requested on the forum. --- dlls/cstrike/cstrike/AMBuilder | 4 + dlls/cstrike/cstrike/CstrikeDatas.h | 21 +++ dlls/cstrike/cstrike/CstrikeHacks.cpp | 163 +++++++++++++++++++- dlls/cstrike/cstrike/CstrikePlayer.cpp | 8 - dlls/cstrike/cstrike/msvc10/cstrike.vcxproj | 4 +- 5 files changed, 182 insertions(+), 18 deletions(-) diff --git a/dlls/cstrike/cstrike/AMBuilder b/dlls/cstrike/cstrike/AMBuilder index fc243e71..ec1ac464 100644 --- a/dlls/cstrike/cstrike/AMBuilder +++ b/dlls/cstrike/cstrike/AMBuilder @@ -3,6 +3,10 @@ import os.path binary = AMXX.MetaModule(builder, 'cstrike') +binary.compiler.defines += [ + 'HAVE_STDINT_H', +] + binary.sources = [ 'sdk/amxxmodule.cpp', 'amxx_api.cpp', diff --git a/dlls/cstrike/cstrike/CstrikeDatas.h b/dlls/cstrike/cstrike/CstrikeDatas.h index 85a61d50..be68adf2 100644 --- a/dlls/cstrike/cstrike/CstrikeDatas.h +++ b/dlls/cstrike/cstrike/CstrikeDatas.h @@ -64,6 +64,7 @@ #define OFFSET_INTERNALMODEL 126 + EXTRAOFFSET #define OFFSET_NVGOGGLES 129 + EXTRAOFFSET #define OFFSET_DEFUSE_PLANT 193 + EXTRAOFFSET + #define OFFSET_MENU 205 + EXTRAOFFSET #define OFFSET_VIP 209 + EXTRAOFFSET #define OFFSET_TK 216 + EXTRAOFFSET // 040926 #define OFFSET_HOSTAGEKILLS 217 + EXTRAOFFSET @@ -353,4 +354,24 @@ enum CS_SET_AUGSG552_ZOOM, }; +typedef enum +{ + Menu_OFF, + Menu_ChooseTeam, + Menu_IGChooseTeam, + Menu_ChooseAppearance, + Menu_Buy, + Menu_BuyPistol, + Menu_BuyRifle, + Menu_BuyMachineGun, + Menu_BuyShotgun, + Menu_BuySubMachineGun, + Menu_BuyItem, + Menu_Radio1, + Menu_Radio2, + Menu_Radio3, + Menu_ClientBuy + +} Menu; + #endif // CSTRIKE_DATA_H \ No newline at end of file diff --git a/dlls/cstrike/cstrike/CstrikeHacks.cpp b/dlls/cstrike/cstrike/CstrikeHacks.cpp index 01f5f4c4..25673cc1 100644 --- a/dlls/cstrike/cstrike/CstrikeHacks.cpp +++ b/dlls/cstrike/cstrike/CstrikeHacks.cpp @@ -33,6 +33,9 @@ #include "CstrikeDatas.h" #include "CstrikeUtils.h" #include "CDetour/detours.h" +#include + +using namespace SourceMod; // hashmap void CtrlDetours_ClientCommand(bool set); void CtrlDetours_BuyCommands(bool set); @@ -50,6 +53,9 @@ CDetour *g_BuyGunAmmoDetour = NULL; CDetour *g_GiveNamedItemDetour = NULL; CDetour *g_AddAccountDetour = NULL; +int g_CurrentItemId = 0; +StringHashMap g_ItemAliasList; + void InitializeHacks() { #if defined AMD64 @@ -66,9 +72,92 @@ void ShutdownHacks() CtrlDetours_BuyCommands(false); } +#undef CMD_ARGV + +const char *CMD_ARGV(int i) +{ + if (*g_UseBotArgs) + { + if (i < 4) + { + return g_BotArgs[i]; + } + + return NULL; + } + + return g_engfuncs.pfnCmd_Argv(i); +} DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientCommand(edict_t *pEntity) { + const char *command = CMD_ARGV(0); + + // A new command is triggered, reset current item. + g_CurrentItemId = 0; + + // Purpose is to retrieve an item id based on alias name or selected item from menu, + // to be used in OnBuy* forwards. + if (command && *command) + { + int itemId = 0; + + // Handling via menu. + if (!strcmp(command, "menuselect")) + { + int slot = atoi(CMD_ARGV(1)); + + if (slot > 0 && slot < 9) + { + static const int menuItemsTe[][9] = + { + /* Menu_Buy */ { 0, 0, 0, 0, 0, 0, CSI_PRIMAMMO, CSI_SECAMMO, 0 }, + /* Menu_BuyPistol */ { 0, CSI_GLOCK18, CSI_USP, CSI_P228, CSI_DEAGLE, CSI_ELITE, 0, 0, 0 }, + /* Menu_BuyRifle */ { 0, CSI_GALI, CSI_AK47, CSI_SCOUT, CSI_SG552, CSI_AWP, CSI_G3SG1, 0, 0 }, + /* Menu_BuyMachineGun */ { 0, CSI_M249, 0, 0, 0, 0, 0, 0, 0 }, + /* Menu_BuyShotgun */ { 0, CSI_M3, CSI_XM1014, 0, 0, 0, 0, 0, 0 }, + /* Menu_BuySubMachineGun */ { 0, CSI_MAC10, CSI_MP5NAVY, CSI_UMP45, CSI_P90, 0, 0, 0, 0 }, + /* Menu_BuyItem */ { 0, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, 0, 0 } + }; + + static const int menuItemsCt[][9] = + { + /* Menu_Buy */ { 0, 0, 0, 0, 0, 0, CSI_PRIMAMMO, CSI_SECAMMO, 0 }, + /* Menu_BuyPistol */ { 0, CSI_GLOCK18, CSI_USP, CSI_P228, CSI_DEAGLE, CSI_FIVESEVEN, 0, 0, 0 }, + /* Menu_BuyRifle */ { 0, CSI_FAMAS, CSI_SCOUT, CSI_M4A1, CSI_AUG, CSI_SG550, CSI_AWP, 0, 0 }, + /* Menu_BuyMachineGun */ { 0, CSI_M249, 0, 0, 0, 0, 0, 0, 0 }, + /* Menu_BuyShotgun */ { 0, CSI_M3, CSI_XM1014, 0, 0, 0, 0, 0, 0 }, + /* Menu_BuySubMachineGun */ { 0, CSI_TMP, CSI_MP5NAVY, CSI_UMP45, CSI_P90, 0, 0, 0, 0 }, + /* Menu_BuyItem */ { 0, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, CSI_DEFUSER, CSI_SHIELDGUN } + }; + + int menuId = *((int *)pEdict->pvPrivateData + OFFSET_MENU); + if (menuId >= Menu_Buy && menuId <= Menu_BuyItem) + { + int team = *((int *)pEdict->pvPrivateData + OFFSET_TEAM); + switch (team) + { + case TEAM_T: itemId = menuItemsTe[menuId - 4][slot]; break; // -4 because array is zero-based and Menu_Buy* constants starts from 4. + case TEAM_CT:itemId = menuItemsCt[menuId - 4][slot]; break; + } + + if (itemId) + { + g_CurrentItemId = itemId; + } + } + } + } + // Handling via alias + else + { + if (g_ItemAliasList.retrieve(command, &itemId)) + { + g_CurrentItemId = itemId; + } + } + } + if (*g_UseBotArgs) { int client = ENTINDEX(pEdict); @@ -89,9 +178,9 @@ DETOUR_DECL_STATIC2(CanBuyThis, bool, void*, pvPlayer, int, weaponId) // bool Ca { int player = PrivateToIndex(pvPlayer); - if (MF_IsPlayerAlive(player) && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast(player), static_cast(weaponId)) > 0) + if (MF_IsPlayerAlive(player)) { - return false; + g_CurrentItemId = weaponId; } } @@ -106,9 +195,9 @@ DETOUR_DECL_STATIC2(BuyItem, void, void*, pvPlayer, int, iSlot) // void BuyItem( { 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(player), static_cast(itemSlotToWeaponId[iSlot])) > 0) + if (iSlot >= 1 && iSlot <= 8) { - return; + g_CurrentItemId = itemSlotToWeaponId[iSlot]; } } @@ -128,10 +217,7 @@ DETOUR_DECL_STATIC3(BuyGunAmmo, bool, void*, pvPlayer, void*, pvWeapon, bool, bB int weaponId = *((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE); int ammoId = (1<(player), static_cast(ammoId)) > 0) - { - return false; - } + g_CurrentItemId = ammoId; } } @@ -140,12 +226,25 @@ DETOUR_DECL_STATIC3(BuyGunAmmo, bool, void*, pvPlayer, void*, pvWeapon, bool, bB DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlayer::GiveNamedItem(const char *pszName) { + if (g_CurrentItemId && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast(PrivateToIndex(this)), static_cast(g_CurrentItemId)) > 0) + { + return; + } + + g_CurrentItemId = 0; + DETOUR_MEMBER_CALL(GiveNamedItem)(pszName); } DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void CBasePlayer::AddAccount(int amount, bool bTrackChange) { + if (g_CurrentItemId) + { + g_CurrentItemId = 0; + return; + } + DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange); } @@ -212,6 +311,52 @@ void CtrlDetours_BuyCommands(bool set) { MF_Log("No Buy Commands detours could be initialized - Disabled Buy forward."); } + + // Build the item alias list. + // Used in ClientCommand to check and get fastly item id from aiias name. + typedef struct + { + char *alias; + int id; + + } itemBuyAliasInfo; + + itemBuyAliasInfo aliasToId[] = + { + { "p228" , CSI_P228 }, { "228compact" , CSI_P228 }, + { "scout" , CSI_SCOUT }, { "hegren" , CSI_HEGRENADE }, + { "xm1014" , CSI_XM1014 }, { "autoshotgun", CSI_XM1014 }, + { "mac10" , CSI_MAC10 }, { "aug" , CSI_AUG }, + { "bullpup" , CSI_AUG }, { "sgren" , CSI_SMOKEGRENADE }, + { "elites" , CSI_ELITE }, { "fn57" , CSI_FIVESEVEN }, + { "fiveseven" , CSI_FIVESEVEN }, { "ump45" , CSI_UMP45 }, + { "sg550" , CSI_SG550 }, { "krieg550" , CSI_SG550 }, + { "galil" , CSI_GALI }, { "defender" , CSI_GALI }, + { "famas" , CSI_FAMAS }, { "clarion" , CSI_FAMAS }, + { "usp" , CSI_USP }, { "km45" , CSI_USP }, + { "glock" , CSI_GLOCK18 }, { "9x19mm" , CSI_GLOCK18 }, + { "awp" , CSI_AWP }, { "magnum" , CSI_AWP }, + { "mp5" , CSI_MP5NAVY }, { "smg" , CSI_MP5NAVY }, + { "m249" , CSI_M249 }, { "m3" , CSI_M3 }, + { "12gauge" , CSI_M3 }, { "m4a1" , CSI_M4A1 }, + { "tmp" , CSI_TMP }, { "mp" , CSI_TMP }, + { "g3sg1" , CSI_G3SG1 }, { "d3au1" , CSI_G3SG1 }, + { "flash" , CSI_FLASHBANG }, { "deagle" , CSI_DEAGLE }, + { "nighthawk" , CSI_DEAGLE }, { "sg552" , CSI_SG552 }, + { "krieg552" , CSI_SG552 }, { "ak47" , CSI_AK47 }, + { "cv47" , CSI_AK47 }, { "p90" , CSI_P90 }, + { "c90" , CSI_P90 }, { "vest" , CSI_VEST }, + { "vesthelm" , CSI_VESTHELM }, { "defuser" , CSI_DEFUSER }, + { "nvgs" , CSI_NVGS }, { "shield" , CSI_SHIELDGUN }, + { "buyammo1" , CSI_PRIMAMMO }, { "primammo" , CSI_PRIMAMMO }, + { "buyammo2" , CSI_SECAMMO }, { "secammo" , CSI_SECAMMO }, + { NULL , 0 } + }; + + for (size_t i = 0; aliasToId[i].alias != NULL; ++i) + { + g_ItemAliasList.insert(aliasToId[i].alias, aliasToId[i].id); + } } else { @@ -229,6 +374,8 @@ void CtrlDetours_BuyCommands(bool set) if (g_AddAccountDetour) g_AddAccountDetour->Destroy(); + + g_ItemAliasList.clear(); } } diff --git a/dlls/cstrike/cstrike/CstrikePlayer.cpp b/dlls/cstrike/cstrike/CstrikePlayer.cpp index 72cee51e..cd72d55f 100755 --- a/dlls/cstrike/cstrike/CstrikePlayer.cpp +++ b/dlls/cstrike/cstrike/CstrikePlayer.cpp @@ -3,14 +3,6 @@ ////////////////////////////////////////////////////////////////////// #include "CstrikePlayer.h" - -#if defined _MSC_VER - #if _MSC_VER >= 1400 - // MSVC8 - disable deprecation warnings for "unsafe" CRT functions - #define _CRT_SECURE_NO_DEPRECATE - #endif -#endif - #include // strcpy() ////////////////////////////////////////////////////////////////////// diff --git a/dlls/cstrike/cstrike/msvc10/cstrike.vcxproj b/dlls/cstrike/cstrike/msvc10/cstrike.vcxproj index c19e1bda..2e39589c 100644 --- a/dlls/cstrike/cstrike/msvc10/cstrike.vcxproj +++ b/dlls/cstrike/cstrike/msvc10/cstrike.vcxproj @@ -63,7 +63,7 @@ Disabled ..\;..\..\..\..\public; ..\..\..\..\public\amtl;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;CSTRIKE_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug false @@ -106,7 +106,7 @@ MaxSpeed OnlyExplicitInline ..\;..\..\..\..\public; ..\..\..\..\public\amtl;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;CSTRIKE_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions) true MultiThreaded true