From 6a44399852f746883d39a17e34670e1f5c8c10a6 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Tue, 17 Jan 2012 18:51:04 +0100 Subject: [PATCH] Core/Items: Fix a trading spoof exploit. Closes #4713 --- src/server/game/Entities/Player/Player.cpp | 20 ++++++++++++++++++-- src/server/game/Entities/Player/Player.h | 6 ++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bed3c0cb1a..5ba80caaaf 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -296,15 +296,24 @@ Item* TradeData::GetItem(TradeSlots slot) const return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : NULL; } -bool TradeData::HasItem(uint64 item_guid) const +bool TradeData::HasItem(uint64 itemGuid) const { for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) - if (m_items[i] == item_guid) + if (m_items[i] == itemGuid) return true; return false; } +TradeSlots const TradeData::GetTradeSlotForItem(uint64 itemGuid) +{ + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (m_items[i] == itemGuid) + return TradeSlots(i); + + return TRADE_SLOT_INVALID; +} + Item* TradeData::GetSpellCastItem() const { return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : NULL; @@ -12874,6 +12883,13 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) EquipItem(dest, pNewItem, true); AutoUnequipOffhandIfNeed(); } + + //! Update item count in trade window, prevent spoofing + //! Since pSrcItem has its count updated (see above), Item::GetCount() will return the new count + //! in the underlying packet builder function + TradeSlots const slot = GetTradeData()->GetTradeSlotForItem(pSrcItem->GetGUID()); + if (slot != TRADE_SLOT_INVALID) + GetTradeData()->SetItem(slot, pSrcItem); } void Player::SwapItem(uint16 src, uint16 dst) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7a45559050..fccd380bd2 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -686,7 +686,8 @@ enum TradeSlots { TRADE_SLOT_COUNT = 7, TRADE_SLOT_TRADED_COUNT = 6, - TRADE_SLOT_NONTRADED = 6 + TRADE_SLOT_NONTRADED = 6, + TRADE_SLOT_INVALID = -1, }; enum TransferAbortReason @@ -1001,7 +1002,8 @@ class TradeData TradeData* GetTraderData() const; Item* GetItem(TradeSlots slot) const; - bool HasItem(uint64 item_guid) const; + bool HasItem(uint64 itemGuid) const; + TradeSlots const GetTradeSlotForItem(uint64 itemGuid); void SetItem(TradeSlots slot, Item* item); uint32 GetSpell() const { return m_spell; }