From da2abb9c3b7d68e5a6e926a4fcc58f4fe1345561 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 25 Feb 2016 22:17:25 +0100 Subject: [PATCH] Fix a bcompat issue with cs_s/get_user_backpackammo() by not relying on m_rgpPlayerItems to get ammo index --- modules/cstrike/cstrike/CstrikeItemsInfos.cpp | 4 +- modules/cstrike/cstrike/CstrikeItemsInfos.h | 33 +++++++++- modules/cstrike/cstrike/CstrikeNatives.cpp | 65 +++++-------------- .../cstrike/cstrike/CstrikeUserMessages.cpp | 42 +++++++++--- 4 files changed, 82 insertions(+), 62 deletions(-) diff --git a/modules/cstrike/cstrike/CstrikeItemsInfos.cpp b/modules/cstrike/cstrike/CstrikeItemsInfos.cpp index 36018e8c..715aece7 100644 --- a/modules/cstrike/cstrike/CstrikeItemsInfos.cpp +++ b/modules/cstrike/cstrike/CstrikeItemsInfos.cpp @@ -15,7 +15,7 @@ #include "CstrikeHacks.h" CsItemInfo ItemsManager; -char WeaponNameList[MAX_WEAPONS][64]; +ItemInfo WeaponsList[MAX_WEAPONS]; #define PSTATE_ALIASES_TYPE 0 #define PSTATE_ALIASES_ALIAS 1 @@ -202,7 +202,7 @@ bool CsItemInfo::GetAliasInfosFromName(const char *name, AliasInfo *info) for (size_t id = 0; id < ARRAYSIZE(WeaponNameList); ++id) { - const char *weapon = WeaponNameList[id]; + const char *weapon = WeaponsList[id].name.chars(); if (weapon[prefix_weapon_length] == '_' && !strncmp(weapon, prefix_weapon, prefix_weapon_length)) { diff --git a/modules/cstrike/cstrike/CstrikeItemsInfos.h b/modules/cstrike/cstrike/CstrikeItemsInfos.h index e3d886e9..294843a9 100644 --- a/modules/cstrike/cstrike/CstrikeItemsInfos.h +++ b/modules/cstrike/cstrike/CstrikeItemsInfos.h @@ -20,6 +20,37 @@ #include #include +struct ItemInfo +{ + ItemInfo() : name("Empty"), ammoIndex1(-1), maxAmmo1(0), ammoIndex2(-1), maxAmmo2(0), slot(0), position(0), id(0), flags(0) + {} + + ItemInfo &operator = (ItemInfo &other) + { + name = other.name; + ammoIndex1 = other.ammoIndex1; + maxAmmo1 = other.maxAmmo1; + ammoIndex2 = other.ammoIndex2; + maxAmmo2 = other.maxAmmo2; + slot = other.slot; + position = other.position; + id = other.id; + flags = other.flags; + + return *this; + } + + ke::AString name; + int ammoIndex1; + int maxAmmo1; + int ammoIndex2; + int maxAmmo2; + int slot; + int position; + int id; + int flags; +}; + struct AliasInfo { AliasInfo() @@ -102,7 +133,7 @@ class CsItemInfo : public ITextListener_SMC int m_EquipmentsPrice[static_cast(Equipments::Count)]; }; -extern char WeaponNameList[MAX_WEAPONS][64]; +extern ItemInfo WeaponsList[MAX_WEAPONS]; extern CsItemInfo ItemsManager; #endif // _CSTRIKE_WEAPONS_INFOS_H_ diff --git a/modules/cstrike/cstrike/CstrikeNatives.cpp b/modules/cstrike/cstrike/CstrikeNatives.cpp index 47b3386c..363ff784 100644 --- a/modules/cstrike/cstrike/CstrikeNatives.cpp +++ b/modules/cstrike/cstrike/CstrikeNatives.cpp @@ -731,81 +731,46 @@ static cell AMX_NATIVE_CALL cs_set_user_defusekit(AMX *amx, cell *params) // native cs_get_user_bpammo(index, weapon); static cell AMX_NATIVE_CALL cs_get_user_backpackammo(AMX *amx, cell *params) { - GET_OFFSET("CBasePlayer" , m_rgpPlayerItems ); - GET_OFFSET("CBasePlayer" , m_rgAmmo ); - GET_OFFSET("CBasePlayerItem" , m_pNext ); - GET_OFFSET("CBasePlayerItem" , m_iId ); - GET_OFFSET("CBasePlayerWeapon", m_iPrimaryAmmoType); + GET_OFFSET("CBasePlayer", m_rgAmmo); - int index = params[1]; + int index = params[1]; int weaponId = params[2]; CHECK_PLAYER(index); - edict_t *pPlayer = MF_GetPlayerEdict(index); - if (weaponId < CSW_P228 || weaponId > CSW_P90 || weaponId == CSW_KNIFE) + int ammoIndex; + + if (weaponId <= CSW_NONE || weaponId >= MAX_WEAPONS || (ammoIndex = WeaponsList[weaponId].ammoIndex1) < 0) { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", params[2]); + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", weaponId); return 0; } - for (size_t i = 0; i < MAX_WEAPON_SLOTS; ++i) - { - uintptr_t *pItem = get_pdata(pPlayer, m_rgpPlayerItems, i); - - while (pItem) - { - if (weaponId == get_pdata(pItem, m_iId)) - { - return get_pdata(pPlayer, m_rgAmmo, get_pdata(pItem, m_iPrimaryAmmoType)); - } - - pItem = get_pdata(pItem, m_pNext); - } - } - - return 0; + return get_pdata(MF_GetPlayerEdict(index), m_rgAmmo, ammoIndex); } // native cs_set_user_bpammo(index, weapon, amount); static cell AMX_NATIVE_CALL cs_set_user_backpackammo(AMX *amx, cell *params) { - GET_OFFSET("CBasePlayer" , m_rgpPlayerItems ); - GET_OFFSET("CBasePlayer" , m_rgAmmo ); - GET_OFFSET("CBasePlayerItem" , m_pNext ); - GET_OFFSET("CBasePlayerItem" , m_iId ); - GET_OFFSET("CBasePlayerWeapon", m_iPrimaryAmmoType); + GET_OFFSET("CBasePlayer", m_rgAmmo); int index = params[1]; int weaponId = params[2]; int amount = params[3]; CHECK_PLAYER(index); - edict_t *pPlayer = MF_GetPlayerEdict(index); - if (weaponId < CSW_P228 || weaponId > CSW_P90 || weaponId == CSW_KNIFE) + int ammoIndex; + + if (weaponId <= CSW_NONE || weaponId >= MAX_WEAPONS || (ammoIndex = WeaponsList[weaponId].ammoIndex1) < 0) { - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", params[2]); + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", weaponId); return 0; } - for (size_t i = 0; i < MAX_WEAPON_SLOTS; ++i) - { - uintptr_t *pItem = get_pdata(pPlayer, m_rgpPlayerItems, i); + set_pdata(MF_GetPlayerEdict(index), m_rgAmmo, amount, ammoIndex); - while (pItem) - { - if (weaponId == get_pdata(pItem, m_iId)) - { - set_pdata(pPlayer, m_rgAmmo, amount, get_pdata(pItem, m_iPrimaryAmmoType)); - return 1; - } - - pItem = get_pdata(pItem, m_pNext); - } - } - - return 0; + return 1; } // native cs_get_user_nvg(index); @@ -1903,7 +1868,7 @@ static cell AMX_NATIVE_CALL cs_get_translated_item_alias(AMX* amx, cell* params) default: { // weapon_* retrieved from WeaponList messages at map change. - name = WeaponNameList[info.itemid]; + name = WeaponsList[info.itemid].name.chars(); break; } } diff --git a/modules/cstrike/cstrike/CstrikeUserMessages.cpp b/modules/cstrike/cstrike/CstrikeUserMessages.cpp index 4d646765..75a57e5c 100644 --- a/modules/cstrike/cstrike/CstrikeUserMessages.cpp +++ b/modules/cstrike/cstrike/CstrikeUserMessages.cpp @@ -21,8 +21,8 @@ bool ShouldBlock; bool ShouldBlockHLTV; bool ShouldDisableHooks; -bool RetrieveWeaponName; -ke::AString CurrentWeaponName; +bool RetrieveWeaponList; +ItemInfo CurrentWeaponList; int ArgPosition; int MessageIdArmorType; @@ -132,7 +132,19 @@ void OnMessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *p { if (msg_type == MessageIdWeaponList) { - RetrieveWeaponName = true; + // MESSAGE_BEGIN(MSG_INIT, gmsgWeaponList); + // WRITE_STRING(pszName); + // WRITE_BYTE(CBasePlayer::GetAmmoIndex(II.pszAmmo1)); + // WRITE_BYTE(II.iMaxAmmo1); + // WRITE_BYTE(CBasePlayer::GetAmmoIndex(II.pszAmmo2)); + // WRITE_BYTE(II.iMaxAmmo2); + // WRITE_BYTE(II.iSlot); + // WRITE_BYTE(II.iPosition); + // WRITE_BYTE(II.iId); + // WRITE_BYTE(II.iFlags); + // MESSAGE_END(); + // + RetrieveWeaponList = true; } } } @@ -152,9 +164,19 @@ void OnWriteByte(int value) RETURN_META(MRES_SUPERCEDE); } - if (RetrieveWeaponName && ++ArgPosition == 7 && value >= 0 && value < MAX_WEAPONS) + if (RetrieveWeaponList) { - strncopy(WeaponNameList[value], CurrentWeaponName.chars(), sizeof(WeaponNameList[value])); + switch (++ArgPosition) + { + case 1: CurrentWeaponList.ammoIndex1 = value; + case 2: CurrentWeaponList.maxAmmo1 = value; + case 3: CurrentWeaponList.ammoIndex2 = value; + case 4: CurrentWeaponList.maxAmmo2 = value; + case 5: CurrentWeaponList.slot = value; + case 6: CurrentWeaponList.position = value; + case 7: CurrentWeaponList.id = value; + case 8: CurrentWeaponList.flags = value; + } } RETURN_META(MRES_IGNORED); @@ -167,9 +189,9 @@ void OnWriteString(const char *value) RETURN_META(MRES_SUPERCEDE); } - if (RetrieveWeaponName) + if (RetrieveWeaponList) { - CurrentWeaponName = value; + CurrentWeaponList.name = value; } RETURN_META(MRES_IGNORED); @@ -190,10 +212,12 @@ void OnMessageEnd(void) RETURN_META(MRES_SUPERCEDE); } - if (RetrieveWeaponName) + if (RetrieveWeaponList) { - RetrieveWeaponName = false; + RetrieveWeaponList = false; ArgPosition = 0; + + WeaponsList[CurrentWeaponList.id] = CurrentWeaponList; } RETURN_META(MRES_IGNORED);