Store to be traded items in array based on item guid instead of item slot to prevent exploiting. Fixes #667.
--HG-- branch : trunk
This commit is contained in:
+1
-1
@@ -12435,7 +12435,7 @@ void Player::ClearTrade()
|
|||||||
tradeGold = 0;
|
tradeGold = 0;
|
||||||
acceptTrade = false;
|
acceptTrade = false;
|
||||||
for (uint8 i = 0; i < TRADE_SLOT_COUNT; i++)
|
for (uint8 i = 0; i < TRADE_SLOT_COUNT; i++)
|
||||||
tradeItems[i] = NULL_SLOT;
|
tradeItems[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::TradeCancel(bool sendback)
|
void Player::TradeCancel(bool sendback)
|
||||||
|
|||||||
+1
-2
@@ -1232,7 +1232,6 @@ class Player : public Unit, public GridObject<Player>
|
|||||||
Player* GetTrader() const { return pTrader; }
|
Player* GetTrader() const { return pTrader; }
|
||||||
void ClearTrade();
|
void ClearTrade();
|
||||||
void TradeCancel(bool sendback);
|
void TradeCancel(bool sendback);
|
||||||
uint16 GetItemPosByTradeSlot(uint32 slot) const { return tradeItems[slot]; }
|
|
||||||
|
|
||||||
void UpdateEnchantTime(uint32 time);
|
void UpdateEnchantTime(uint32 time);
|
||||||
void UpdateItemDuration(uint32 time, bool realtimeonly=false);
|
void UpdateItemDuration(uint32 time, bool realtimeonly=false);
|
||||||
@@ -2463,7 +2462,7 @@ Spell * m_spellModTakingSpell;
|
|||||||
|
|
||||||
Player *pTrader;
|
Player *pTrader;
|
||||||
bool acceptTrade;
|
bool acceptTrade;
|
||||||
uint16 tradeItems[TRADE_SLOT_COUNT];
|
uint64 tradeItems[TRADE_SLOT_COUNT];
|
||||||
uint32 tradeGold;
|
uint32 tradeGold;
|
||||||
|
|
||||||
bool m_DailyQuestChanged;
|
bool m_DailyQuestChanged;
|
||||||
|
|||||||
+1
-1
@@ -218,7 +218,7 @@ void SpellCastTargets::Update(Unit* caster)
|
|||||||
// here it is not guid but slot
|
// here it is not guid but slot
|
||||||
Player* pTrader = ((Player*)caster)->GetTrader();
|
Player* pTrader = ((Player*)caster)->GetTrader();
|
||||||
if(pTrader && m_itemTargetGUID < TRADE_SLOT_COUNT)
|
if(pTrader && m_itemTargetGUID < TRADE_SLOT_COUNT)
|
||||||
m_itemTarget = pTrader->GetItemByPos(pTrader->GetItemPosByTradeSlot(m_itemTargetGUID));
|
m_itemTarget = pTrader->GetItemByGuid(m_itemTargetGUID);
|
||||||
}
|
}
|
||||||
if(m_itemTarget)
|
if(m_itemTarget)
|
||||||
m_itemTargetEntry = m_itemTarget->GetEntry();
|
m_itemTargetEntry = m_itemTarget->GetEntry();
|
||||||
|
|||||||
+30
-23
@@ -136,7 +136,7 @@ void WorldSession::SendUpdateTrade()
|
|||||||
|
|
||||||
for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
|
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
|
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)
|
// not accept if some items now can't be trade (cheating)
|
||||||
for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
|
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);
|
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
||||||
return;
|
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);
|
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
||||||
return;
|
return;
|
||||||
@@ -313,21 +313,25 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
|
|||||||
// store items in local list and set 'in-trade' flag
|
// store items in local list and set 'in-trade' flag
|
||||||
for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
|
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
|
//Can return NULL
|
||||||
myItems[i]=_player->GetItemByPos( _player->tradeItems[i] );
|
myItems[i] = _player->GetItemByGuid( _player->tradeItems[i] );
|
||||||
if (myItems[i])
|
if (myItems[i])
|
||||||
|
{
|
||||||
myItems[i]->SetInTrade();
|
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
|
//Can return NULL
|
||||||
hisItems[i]=_player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i]);
|
hisItems[i]=_player->pTrader->GetItemByGuid( _player->pTrader->tradeItems[i]);
|
||||||
if(hisItems[i])
|
if (hisItems[i])
|
||||||
|
{
|
||||||
hisItems[i]->SetInTrade();
|
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
|
// execute trade: 1. remove
|
||||||
for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
|
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());
|
myItems[i]->SetUInt64Value( ITEM_FIELD_GIFTCREATOR, _player->GetGUID());
|
||||||
_player->MoveItemFromInventory(_player->tradeItems[i] >> 8, _player->tradeItems[i] & 255, true);
|
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());
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 pos = (bag << 8) | slot;
|
uint64 iGUID = item->GetGUID();
|
||||||
|
|
||||||
// prevent place single item into many trade slots using cheating and client bugs
|
// prevent place single item into many trade slots using cheating and client bugs
|
||||||
for (int i = 0; i < TRADE_SLOT_COUNT; ++i)
|
for (int i = 0; i < TRADE_SLOT_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if(_player->tradeItems[i]==pos)
|
if (_player->tradeItems[i] == iGUID)
|
||||||
{
|
{
|
||||||
// cheating attempt
|
// cheating attempt
|
||||||
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
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();
|
_player->pTrader->GetSession()->SendUpdateTrade();
|
||||||
}
|
}
|
||||||
@@ -630,7 +637,7 @@ void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket)
|
|||||||
if(tradeSlot >= TRADE_SLOT_COUNT)
|
if(tradeSlot >= TRADE_SLOT_COUNT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_player->tradeItems[tradeSlot] = NULL_SLOT;
|
_player->tradeItems[tradeSlot] = 0;
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendUpdateTrade();
|
_player->pTrader->GetSession()->SendUpdateTrade();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user