From 45cabd756c6313b9cafab59a38520aaf39b4e58c Mon Sep 17 00:00:00 2001 From: Drifter Date: Thu, 15 Aug 2013 14:40:30 -0400 Subject: [PATCH] Fix CS:GO GetWeaponPrice and OnGetWeaponPrice using outdated method (r=psychonic). --- extensions/cstrike/forwards.cpp | 131 +++--------------------- extensions/cstrike/forwards.h | 8 -- extensions/cstrike/natives.cpp | 59 +++++++++-- extensions/cstrike/util_cstrike.h | 2 + gamedata/sm-cstrike.games/game.csgo.txt | 8 ++ 5 files changed, 73 insertions(+), 135 deletions(-) diff --git a/extensions/cstrike/forwards.cpp b/extensions/cstrike/forwards.cpp index 8c0d3dc0..83375a4b 100644 --- a/extensions/cstrike/forwards.cpp +++ b/extensions/cstrike/forwards.cpp @@ -44,23 +44,10 @@ DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon) } #if SOURCE_ENGINE == SE_CSGO - int defaultprice = -1; - if (g_iPriceOffset != -1 && g_PriceDetoured) - { - defaultprice = CallPriceForwardCSGO(client, weapon); - } - int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon, iUnknown, bRebuy); #else int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon); #endif - - -#if SOURCE_ENGINE == SE_CSGO - if (defaultprice != -1) - SetWeaponPrice(weapon, defaultprice); -#endif - lastclient = -1; return val; } @@ -77,6 +64,18 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int) return CallPriceForward(lastclient, weapon_name, price); } +#else +DETOUR_DECL_MEMBER2(DetourWeaponPrice, int, const char *, szAttribute, CEconItemView *, pEconItem) +{ + int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(szAttribute, pEconItem); + + if(lastclient == -1 || strcmp(szAttribute, "in_game_price") != 0) + return price; + + const char *weapon_name = reinterpret_cast(this+weaponNameOffset); + + return CallPriceForward(lastclient, weapon_name, price); +} #endif DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason) @@ -141,29 +140,10 @@ bool CreateWeaponPriceDetour() } #if SOURCE_ENGINE == SE_CSGO - if (g_iPriceOffset == -1) - { - if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset)) - { - g_iPriceOffset = -1; - g_pSM->LogError(myself, "Failed to get WeaponPrice offset - Disabled OnGetWeaponPrice forward"); - return false; - } - } - if (!CreateHandleBuyDetour()) - { - g_pSM->LogError(myself, "HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward."); - return false; - } - else - { - g_PriceDetoured = true; - return true; - } + DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetAttributeInt"); #else - DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice"); - +#endif if (DWeaponPrice != NULL) { if (!CreateHandleBuyDetour()) @@ -179,7 +159,6 @@ bool CreateWeaponPriceDetour() g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward."); return false; -#endif } bool CreateTerminateRoundDetour() @@ -230,14 +209,12 @@ bool CreateCSWeaponDropDetour() void RemoveWeaponPriceDetour() { -#if SOURCE_ENGINE != SE_CSGO if (DWeaponPrice != NULL) { DWeaponPrice->Destroy(); DWeaponPrice = NULL; } g_PriceDetoured = false; -#endif } void RemoveHandleBuyDetour() @@ -272,85 +249,6 @@ void RemoveCSWeaponDropDetour() } g_pCSWeaponDropDetoured = false; } - -#if SOURCE_ENGINE == SE_CSGO -bool SetWeaponPrice(int weaponID, int price) -{ - void *info = GetWeaponInfo(weaponID); - if (!info) - { - return false; - } - *(int *)((intptr_t)info+g_iPriceOffset) = price; - return true; -} - -bool SetWeaponPrice(const char *weapon, int price) -{ - const char *weaponalias = GetTranslatedWeaponAlias(weapon); - int weaponID = AliasToWeaponID(weaponalias); - if (weaponID <= 0) - { - return false; - } - void *info = GetWeaponInfo(weaponID); - if (!info) - { - return false; - } - *(int *)((intptr_t)info+g_iPriceOffset) = price; - return true; - -} - -int CallPriceForwardCSGO(int client, const char *weapon, int price) -{ - int changedprice = price; - cell_t result = Pl_Continue; - - g_pPriceForward->PushCell(client); - g_pPriceForward->PushString(weapon); - g_pPriceForward->PushCellByRef(&changedprice); - g_pPriceForward->Execute(&result); - - if (result == Pl_Continue) - return price; - - return changedprice; -} - -int CallPriceForwardCSGO(int client, const char *weapon) -{ - const char *weaponalias = GetTranslatedWeaponAlias(weapon); - int weaponID = AliasToWeaponID(weaponalias); - if (weaponID <= 0) - { - return -1; - } - void *info = GetWeaponInfo(weaponID); - if (!info) - { - return -1; - } - const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset); - int price = *(int *)((intptr_t)info + g_iPriceOffset); - int changedprice = price; - cell_t result = Pl_Continue; - - g_pPriceForward->PushCell(client); - g_pPriceForward->PushString(weapon_name); - g_pPriceForward->PushCellByRef(&changedprice); - g_pPriceForward->Execute(&result); - - if (result == Pl_Continue) - return -1; - if (SetWeaponPrice(weaponID, changedprice)) - return price; - else - return -1; -} -#else - int CallPriceForward(int client, const char *weapon_name, int price) { int changedprice = price; @@ -367,4 +265,3 @@ int CallPriceForward(int client, const char *weapon_name, int price) return changedprice; } -#endif diff --git a/extensions/cstrike/forwards.h b/extensions/cstrike/forwards.h index 3cd8161e..785c3224 100644 --- a/extensions/cstrike/forwards.h +++ b/extensions/cstrike/forwards.h @@ -9,17 +9,9 @@ void RemoveHandleBuyDetour(); void RemoveTerminateRoundDetour(); void RemoveCSWeaponDropDetour(); -#if SOURCE_ENGINE == SE_CSGO -bool SetWeaponPrice(int weaponID, int price); -bool SetWeaponPrice(const char *weapon, int price); -int CallPriceForwardCSGO(int client, const char *weapon); -int CallPriceForwardCSGO(int client, const char *weapon, int price); -#endif - extern IServerGameEnts *gameents; extern IForward *g_pHandleBuyForward; extern IForward *g_pPriceForward; extern IForward *g_pTerminateRoundForward; extern IForward *g_pCSWeaponDropForward; -extern int g_iPriceOffset; #endif //_INCLUDE_CSTRIKE_FORWARDS_H_ diff --git a/extensions/cstrike/natives.cpp b/extensions/cstrike/natives.cpp index d649fefa..815328b2 100644 --- a/extensions/cstrike/natives.cpp +++ b/extensions/cstrike/natives.cpp @@ -353,6 +353,45 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params) return 400; #endif + void *info = GetWeaponInfo(id); + + if (!info) + { + return pContext->ThrowNativeError("Failed to get weaponinfo"); + } + +#if SOURCE_ENGINE == SE_CSGO + static ICallWrapper *pWrapper = NULL; + + if (!pWrapper) + { + REGISTER_NATIVE_ADDR("GetAttributeInt", + PassInfo pass[2]; \ + PassInfo ret; \ + pass[0].flags = PASSFLAG_BYVAL; \ + pass[0].type = PassType_Basic; \ + pass[0].size = sizeof(char *); \ + pass[1].flags = PASSFLAG_BYVAL; \ + pass[1].type = PassType_Basic; \ + pass[1].size = sizeof(CEconItemView *); \ + ret.flags = PASSFLAG_BYVAL; \ + ret.type = PassType_Basic; \ + ret.size = sizeof(int); \ + pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 2)) + } + + unsigned char vstk[sizeof(void *) * 2 + sizeof(char *)]; + unsigned char *vptr = vstk; + + *(void **)vptr = info; + vptr += sizeof(void *); + *(char **)vptr = "in_game_price"; + vptr += sizeof(char **); + *(CEconItemView **)vptr = NULL; + + int price = 0; + pWrapper->Execute(vstk, &price); +#else if (g_iPriceOffset == -1) { if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset)) @@ -362,28 +401,21 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params) } } + int price = *(int *)((intptr_t)info + g_iPriceOffset); +#endif + CBaseEntity *pEntity; if (!(pEntity = GetCBaseEntity(params[1], true))) { return pContext->ThrowNativeError("Client index %d is not valid", params[1]); } - void *info = GetWeaponInfo(id); - if (!info) - return pContext->ThrowNativeError("Failed to get weaponinfo"); - - int price = *(int *)((intptr_t)info + g_iPriceOffset); - if (params[3] || weaponNameOffset == -1) return price; const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset); -#if SOURCE_ENGINE == SE_CSGO - return CallPriceForwardCSGO(params[1], weapon_name, price); -#else return CallPriceForward(params[1], weapon_name, price); -#endif } static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params) @@ -469,6 +501,13 @@ static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params) pContext->LocalToString(params[1], &weapon); +#if SOURCE_ENGINE == SE_CSGO + if (strstr(weapon, "usp_silencer") != NULL) + { + return SMCSWeapon_HKP2000; + } +#endif + int id = GetFakeWeaponID(AliasToWeaponID(weapon)); if (!IsValidWeaponID(id)) diff --git a/extensions/cstrike/util_cstrike.h b/extensions/cstrike/util_cstrike.h index 1a77ad39..9f5445d4 100644 --- a/extensions/cstrike/util_cstrike.h +++ b/extensions/cstrike/util_cstrike.h @@ -33,6 +33,8 @@ #define _INCLUDE_CSTRIKE_UTIL_H_ #if SOURCE_ENGINE == SE_CSGO +class CEconItemView; + enum CSGOWeapon { CSGOWeapon_NONE, diff --git a/gamedata/sm-cstrike.games/game.csgo.txt b/gamedata/sm-cstrike.games/game.csgo.txt index 16feb8c3..548ce3e2 100644 --- a/gamedata/sm-cstrike.games/game.csgo.txt +++ b/gamedata/sm-cstrike.games/game.csgo.txt @@ -130,6 +130,14 @@ "linux" "@_ZN9CCSPlayer10SetClanTagEPKc" "mac" "@_ZN9CCSPlayer10SetClanTagEPKc" } + //Wild card first 6 bytes since we call it and detour it. + "GetAttributeInt" + { + "library" "server" + "windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x08\x56\x57\x8B\xF1\x50\x8D\x4D\xFC\x51\xE8\x2A\x2A\x2A\x2A\x8B\x4D\x0C\x0F\x57\xC0\x8B\x7D\xFC\x83\xC4\x08\xF3\x0F\x11\x45\x08\x85\xC9\x74\x2A\x80\x2A\x2A\x00\x74\x2A\x57\x8D\x55\x08\x52\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75\x2A\x57\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x83\xF8\xFF\x74\x2A\x83\xF8\xFF\x7E\x2A\x8B\x0D\x2A\x2A\x2A\x2A\x8B\x04\x81\x83\x2A\x2A\x05" + "linux" "@_ZNK16FileWeaponInfo_t15GetAttributeIntEPKcPK13CEconItemView" + "mac" "@_ZNK16FileWeaponInfo_t15GetAttributeIntEPKcPK13CEconItemView" + } } }