Fix CS_GetWeaponPrice returning incorrect weapon prices.

This commit is contained in:
Ruben Gonzalez 2017-08-25 10:19:19 -04:00
parent d705f6a2e1
commit 22033c21f2
4 changed files with 55 additions and 16 deletions
extensions/cstrike
gamedata/sm-cstrike.games

View File

@ -459,7 +459,7 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
if (!IsValidWeaponID(params[2])) if (!IsValidWeaponID(params[2]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game"); return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
static int iLoadoutSlotOffset = -1; /*static int iLoadoutSlotOffset = -1;
if (iLoadoutSlotOffset == -1) if (iLoadoutSlotOffset == -1)
{ {
@ -468,7 +468,7 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
iLoadoutSlotOffset = -1; iLoadoutSlotOffset = -1;
return pContext->ThrowNativeError("Failed to get LoadoutSlotOffset offset."); return pContext->ThrowNativeError("Failed to get LoadoutSlotOffset offset.");
} }
} }*/
if (g_iPriceOffset == -1) if (g_iPriceOffset == -1)
{ {
@ -497,16 +497,7 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
void *pDef = GetItemDefintionByName(classname); void *pDef = GetItemDefintionByName(classname);
int iLoadoutSlot = *(int *)((intptr_t)pDef + iLoadoutSlotOffset); void *pWpnData = GetCCSWpnDataFromItemDef(pDef);
CEconItemView *pView = GetEconItemView(pEntity, iLoadoutSlot);
if (!pView)
{
return pContext->ThrowNativeError("Failed to get CEconItemVIiew for %s", classname);
}
void *pWpnData = GetCCSWeaponData(pView);
if (!pWpnData) if (!pWpnData)
{ {
@ -618,6 +609,10 @@ static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params)
{ {
return SMCSWeapon_M4A1; return SMCSWeapon_M4A1;
} }
else if (strstr(weapon, "revolver") != NULL)
{
return SMCSWeapon_DEAGLE;
}
#endif #endif
int id = GetFakeWeaponID(AliasToWeaponID(weapon)); int id = GetFakeWeaponID(AliasToWeaponID(weapon));

View File

@ -161,16 +161,16 @@ void *GetCCSWeaponData(CEconItemView *view)
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &retpass, pass, 1)) pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &retpass, pass, 1))
} }
unsigned char vstk[sizeof(const char *)]; unsigned char vstk[sizeof(void *)];
unsigned char *vptr = vstk; unsigned char *vptr = vstk;
*(CEconItemView **)vptr = view; *(CEconItemView **)vptr = view;
void *pDef = NULL; void *pWpnData = NULL;
pWrapper->Execute(vstk, &pDef); pWrapper->Execute(vstk, &pWpnData);
return pDef; return pWpnData;
} }
void *GetItemSchema() void *GetItemSchema()
@ -244,6 +244,40 @@ void *GetItemDefintionByName(const char *classname)
return pItemDef; return pItemDef;
} }
void *GetCCSWpnDataFromItemDef(void *pItemDef)
{
if (!pItemDef)
return NULL;
static ICallWrapper *pWrapper = NULL;
if (!pWrapper)
{
// In windows this is a sig to the inlined code in GetCCSWeaponData
// We abuse the fact that the ItemDef is stored in ecx
REGISTER_ADDR("GetCCSWeaponDataFromDef", NULL,
PassInfo pass[1]; \
PassInfo retpass; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(void *); \
retpass.flags = PASSFLAG_BYVAL; \
retpass.type = PassType_Basic; \
retpass.size = sizeof(void *); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &retpass, pass, 1))
}
unsigned char vstk[sizeof(void *)];
unsigned char *vptr = vstk;
*(void **)vptr = pItemDef;
void *pWpnData = NULL;
pWrapper->Execute(vstk, &pWpnData);
return pWpnData;
}
#endif #endif
#if SOURCE_ENGINE != SE_CSGO #if SOURCE_ENGINE != SE_CSGO

View File

@ -39,6 +39,7 @@ CEconItemView *GetEconItemView(void *pEntity, int iSlot);
void *GetCCSWeaponData(CEconItemView *view); void *GetCCSWeaponData(CEconItemView *view);
void *GetItemSchema(); void *GetItemSchema();
void *GetItemDefintionByName(const char *classname); void *GetItemDefintionByName(const char *classname);
void *GetCCSWpnDataFromItemDef(void *pItemDef);
static const char *szWeaponInfo[] = static const char *szWeaponInfo[] =
{ {

View File

@ -143,12 +143,21 @@
"linux" "\x55\x89\xE5\x83\xEC\x28\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x89\x7D\xFC\x89\x1C\x24\xE8\x2A\x2A\x2A\x2A\x83\xF8\x02" "linux" "\x55\x89\xE5\x83\xEC\x28\x89\x5D\xF4\x8B\x5D\x08\x89\x75\xF8\x89\x7D\xFC\x89\x1C\x24\xE8\x2A\x2A\x2A\x2A\x83\xF8\x02"
} }
//GetCCSWeaponData Found in HandleCommand_Buy_Internal //GetCCSWeaponData Found in HandleCommand_Buy_Internal
//Uses an econitemview
"GetCCSWeaponData" "GetCCSWeaponData"
{ {
"library" "server" "library" "server"
"windows" "\x85\xC9\x75\x2A\x33\xC0\xC3\xE8\x2A\x2A\x2A\x2A\x8B" "windows" "\x85\xC9\x75\x2A\x33\xC0\xC3\xE8\x2A\x2A\x2A\x2A\x8B"
"linux" "\x55\x89\xE5\x83\xEC\x18\x8B\x45\x08\x85\xC0\x74\x2A\x89\x04\x24" "linux" "\x55\x89\xE5\x83\xEC\x18\x8B\x45\x08\x85\xC0\x74\x2A\x89\x04\x24"
} }
//In windows this is to inlined code.
//It is within GetCCSWeaponData
"GetCCSWeaponDataFromDef"
{
"library" "server"
"windows" "\x8B\x01\x56\x8B\x35\x2A\x2A\x2A\x2A\xFF\x10\x0F\xB7\xC0\xB9\x2A\x2A\x2A\x2A\x50\xFF\x56\x08\x5E\xC3"
"linux" "\x55\x31\xC0\x89\xE5\x53\x83\xEC\x14\x8B\x55\x08\x85\xD2"
}
} }
} }