diff options
author | Machiavelli <none@none> | 2010-02-15 13:55:16 +0100 |
---|---|---|
committer | Machiavelli <none@none> | 2010-02-15 13:55:16 +0100 |
commit | a5585ceb3cc18d22c6353f0b22db7f2574055635 (patch) | |
tree | 27380f0ae86f5282daa476da07f191a9f01360f6 | |
parent | 9fe3a501cc0f2d272e40e1319ba19eaf1c527173 (diff) |
Store to be traded items in array based on item guid instead of item slot to prevent exploiting. Fixes #667.
--HG--
branch : trunk
-rw-r--r-- | src/game/Player.cpp | 2 | ||||
-rw-r--r-- | src/game/Player.h | 3 | ||||
-rw-r--r-- | src/game/Spell.cpp | 2 | ||||
-rw-r--r-- | src/game/TradeHandler.cpp | 53 |
4 files changed, 33 insertions, 27 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 46906a03e94..8bf3371fb98 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12435,7 +12435,7 @@ void Player::ClearTrade() tradeGold = 0; acceptTrade = false; for (uint8 i = 0; i < TRADE_SLOT_COUNT; i++) - tradeItems[i] = NULL_SLOT; + tradeItems[i] = 0; } void Player::TradeCancel(bool sendback) diff --git a/src/game/Player.h b/src/game/Player.h index 4236b3a29c0..34d3c01152a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1232,7 +1232,6 @@ class Player : public Unit, public GridObject<Player> Player* GetTrader() const { return pTrader; } void ClearTrade(); void TradeCancel(bool sendback); - uint16 GetItemPosByTradeSlot(uint32 slot) const { return tradeItems[slot]; } void UpdateEnchantTime(uint32 time); void UpdateItemDuration(uint32 time, bool realtimeonly=false); @@ -2463,7 +2462,7 @@ Spell * m_spellModTakingSpell; Player *pTrader; bool acceptTrade; - uint16 tradeItems[TRADE_SLOT_COUNT]; + uint64 tradeItems[TRADE_SLOT_COUNT]; uint32 tradeGold; bool m_DailyQuestChanged; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9bcb0751252..4dec156dfbd 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -218,7 +218,7 @@ void SpellCastTargets::Update(Unit* caster) // here it is not guid but slot Player* pTrader = ((Player*)caster)->GetTrader(); if(pTrader && m_itemTargetGUID < TRADE_SLOT_COUNT) - m_itemTarget = pTrader->GetItemByPos(pTrader->GetItemPosByTradeSlot(m_itemTargetGUID)); + m_itemTarget = pTrader->GetItemByGuid(m_itemTargetGUID); } if(m_itemTarget) m_itemTargetEntry = m_itemTarget->GetEntry(); diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp index 0d4e53a1d3f..eebbaf0c2a5 100644 --- a/src/game/TradeHandler.cpp +++ b/src/game/TradeHandler.cpp @@ -136,7 +136,7 @@ void WorldSession::SendUpdateTrade() for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) { - item = (_player->pTrader->tradeItems[i] != NULL_SLOT ? _player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i] ) : NULL); + item = (_player->pTrader->tradeItems[i] != 0 ? _player->pTrader->GetItemByGuid( _player->pTrader->tradeItems[i] ) : NULL); data << (uint8) i; // trade slot number, if not specified, then end of packet @@ -280,22 +280,22 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // not accept if some items now can't be trade (cheating) for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) { - if(_player->tradeItems[i] != NULL_SLOT ) + if (_player->tradeItems[i] != 0 ) { - if(Item* item =_player->GetItemByPos( _player->tradeItems[i] )) + if (Item* item =_player->GetItemByGuid( _player->tradeItems[i] )) { - if(!item->CanBeTraded()) + if (!item->CanBeTraded()) { SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); return; } } } - if(_player->pTrader->tradeItems[i] != NULL_SLOT) + if (_player->pTrader->tradeItems[i] != 0) { - if(Item* item =_player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i]) ) + if (Item* item =_player->pTrader->GetItemByGuid( _player->pTrader->tradeItems[i]) ) { - if(!item->CanBeTraded()) + if (!item->CanBeTraded()) { SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); return; @@ -313,21 +313,25 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // store items in local list and set 'in-trade' flag for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) { - if(_player->tradeItems[i] != NULL_SLOT ) + if (_player->tradeItems[i] != 0) { - sLog.outDebug("player trade item bag: %u slot: %u",_player->tradeItems[i] >> 8, _player->tradeItems[i] & 255 ); //Can return NULL - myItems[i]=_player->GetItemByPos( _player->tradeItems[i] ); + myItems[i] = _player->GetItemByGuid( _player->tradeItems[i] ); if (myItems[i]) + { myItems[i]->SetInTrade(); + sLog.outDebug("Player trade item bag: %u slot: %u", myItems[i]->GetBagSlot(), myItems[i]->GetSlot()); + } } - if(_player->pTrader->tradeItems[i] != NULL_SLOT) + if (_player->pTrader->tradeItems[i] != 0) { - sLog.outDebug("partner trade item bag: %u slot: %u",_player->pTrader->tradeItems[i] >> 8,_player->pTrader->tradeItems[i] & 255); //Can return NULL - hisItems[i]=_player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i]); - if(hisItems[i]) + hisItems[i]=_player->pTrader->GetItemByGuid( _player->pTrader->tradeItems[i]); + if (hisItems[i]) + { hisItems[i]->SetInTrade(); + sLog.outDebug("Player trade item bag: %u slot: %u", hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot()); + } } } @@ -363,15 +367,18 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // execute trade: 1. remove for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) { - if(myItems[i]) + Item* iPtr = NULL; + if (myItems[i]) { - myItems[i]->SetUInt64Value( ITEM_FIELD_GIFTCREATOR,_player->GetGUID()); - _player->MoveItemFromInventory(_player->tradeItems[i] >> 8, _player->tradeItems[i] & 255, true); + myItems[i]->SetUInt64Value( ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); + iPtr = _player->GetItemByGuid(_player->tradeItems[i]); + _player->MoveItemFromInventory(iPtr->GetBagSlot(), iPtr->GetSlot(), true); } - if(hisItems[i]) + if (hisItems[i]) { hisItems[i]->SetUInt64Value( ITEM_FIELD_GIFTCREATOR,_player->pTrader->GetGUID()); - _player->pTrader->MoveItemFromInventory(_player->pTrader->tradeItems[i] >> 8, _player->pTrader->tradeItems[i] & 255, true); + iPtr = _player->pTrader->GetItemByGuid(_player->pTrader->tradeItems[i]); + _player->pTrader->MoveItemFromInventory(iPtr->GetBagSlot(), iPtr->GetSlot(), true); } } @@ -600,12 +607,12 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) return; } - uint16 pos = (bag << 8) | slot; + uint64 iGUID = item->GetGUID(); // prevent place single item into many trade slots using cheating and client bugs for (int i = 0; i < TRADE_SLOT_COUNT; ++i) { - if(_player->tradeItems[i]==pos) + if (_player->tradeItems[i] == iGUID) { // cheating attempt SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); @@ -613,7 +620,7 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) } } - _player->tradeItems[tradeSlot] = pos; + _player->tradeItems[tradeSlot] = iGUID; _player->pTrader->GetSession()->SendUpdateTrade(); } @@ -630,7 +637,7 @@ void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket) if(tradeSlot >= TRADE_SLOT_COUNT) return; - _player->tradeItems[tradeSlot] = NULL_SLOT; + _player->tradeItems[tradeSlot] = 0; _player->pTrader->GetSession()->SendUpdateTrade(); } |