mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[10048] Move trade data to dynamic created structure.
Also possible fix old bug with spam trade cancel after logout.
This commit is contained in:
parent
59c8741e9b
commit
9dd45d5cf0
4 changed files with 152 additions and 123 deletions
|
|
@ -381,8 +381,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
||||||
m_bHasDelayedTeleport = false;
|
m_bHasDelayedTeleport = false;
|
||||||
m_teleport_options = 0;
|
m_teleport_options = 0;
|
||||||
|
|
||||||
pTrader = 0;
|
m_trade = NULL;
|
||||||
ClearTrade();
|
|
||||||
|
|
||||||
m_cinematic = 0;
|
m_cinematic = 0;
|
||||||
|
|
||||||
|
|
@ -11989,33 +11988,23 @@ void Player::SendSellError( uint8 msg, Creature* pCreature, uint64 guid, uint32
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::ClearTrade()
|
|
||||||
{
|
|
||||||
tradeGold = 0;
|
|
||||||
acceptTrade = false;
|
|
||||||
for(int i = 0; i < TRADE_SLOT_COUNT; ++i)
|
|
||||||
m_tradeItems[i].Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::TradeCancel(bool sendback)
|
void Player::TradeCancel(bool sendback)
|
||||||
{
|
{
|
||||||
if (pTrader)
|
if (m_trade)
|
||||||
{
|
{
|
||||||
|
Player* trader = m_trade->m_tradeWith;
|
||||||
|
|
||||||
// send yellow "Trade canceled" message to both traders
|
// send yellow "Trade canceled" message to both traders
|
||||||
WorldSession* ws;
|
|
||||||
ws = GetSession();
|
|
||||||
if (sendback)
|
if (sendback)
|
||||||
ws->SendCancelTrade();
|
GetSession()->SendCancelTrade();
|
||||||
ws = pTrader->GetSession();
|
|
||||||
if (!ws->PlayerLogout())
|
trader->GetSession()->SendCancelTrade();
|
||||||
ws->SendCancelTrade();
|
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
ClearTrade();
|
delete m_trade;
|
||||||
pTrader->ClearTrade();
|
m_trade = NULL;
|
||||||
// prevent loss of reference
|
delete trader->m_trade;
|
||||||
pTrader->pTrader = NULL;
|
trader->m_trade = NULL;
|
||||||
pTrader = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1019,6 +1019,26 @@ struct BGData
|
||||||
bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; }
|
bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TradeData
|
||||||
|
{
|
||||||
|
explicit TradeData(Player* tradeWith)
|
||||||
|
: m_tradeWith(tradeWith), m_acceptedTrade(false), m_tradeGold(0), m_tradeSpell(0) {}
|
||||||
|
|
||||||
|
Player* m_tradeWith;
|
||||||
|
bool m_acceptedTrade;
|
||||||
|
uint32 m_tradeGold;
|
||||||
|
uint32 m_tradeSpell;
|
||||||
|
ObjectGuid m_tradeItems[TRADE_SLOT_COUNT];
|
||||||
|
|
||||||
|
bool HasItem(ObjectGuid item_guid) const
|
||||||
|
{
|
||||||
|
for(int i = 0; i < TRADE_SLOT_COUNT; ++i)
|
||||||
|
if (m_tradeItems[i] == item_guid)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC Player : public Unit
|
class MANGOS_DLL_SPEC Player : public Unit
|
||||||
{
|
{
|
||||||
friend class WorldSession;
|
friend class WorldSession;
|
||||||
|
|
@ -1280,10 +1300,9 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
|
bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
|
||||||
|
|
||||||
float GetReputationPriceDiscount( Creature const* pCreature ) const;
|
float GetReputationPriceDiscount( Creature const* pCreature ) const;
|
||||||
Player* GetTrader() const { return pTrader; }
|
Player* GetTrader() const { return m_trade ? m_trade->m_tradeWith : NULL; }
|
||||||
void ClearTrade();
|
|
||||||
void TradeCancel(bool sendback);
|
void TradeCancel(bool sendback);
|
||||||
Item* GetItemByTradeSlot(uint32 slot) const { return !m_tradeItems[slot].IsEmpty() ? GetItemByGuid(m_tradeItems[slot]) : NULL; }
|
Item* GetItemByTradeSlot(uint32 slot) const { return m_trade && !m_trade->m_tradeItems[slot].IsEmpty() ? GetItemByGuid(m_trade->m_tradeItems[slot]) : NULL; }
|
||||||
|
|
||||||
void UpdateEnchantTime(uint32 time);
|
void UpdateEnchantTime(uint32 time);
|
||||||
void UpdateItemDuration(uint32 time, bool realtimeonly=false);
|
void UpdateItemDuration(uint32 time, bool realtimeonly=false);
|
||||||
|
|
@ -2463,10 +2482,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
int m_cinematic;
|
int m_cinematic;
|
||||||
|
|
||||||
Player *pTrader;
|
TradeData* m_trade;
|
||||||
bool acceptTrade;
|
|
||||||
ObjectGuid m_tradeItems[TRADE_SLOT_COUNT];
|
|
||||||
uint32 tradeGold;
|
|
||||||
|
|
||||||
bool m_DailyQuestChanged;
|
bool m_DailyQuestChanged;
|
||||||
bool m_WeeklyQuestChanged;
|
bool m_WeeklyQuestChanged;
|
||||||
|
|
|
||||||
|
|
@ -106,20 +106,30 @@ void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/)
|
||||||
|
|
||||||
void WorldSession::SendUpdateTrade()
|
void WorldSession::SendUpdateTrade()
|
||||||
{
|
{
|
||||||
if( !_player || !_player->pTrader )
|
if (!_player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player* trader = my_trade->m_tradeWith;
|
||||||
|
|
||||||
|
TradeData* his_trade = trader->m_trade;
|
||||||
|
if (!his_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// reset trade status
|
// reset trade status
|
||||||
if (_player->acceptTrade)
|
if (my_trade->m_acceptedTrade)
|
||||||
{
|
{
|
||||||
_player->acceptTrade = false;
|
my_trade->m_acceptedTrade = false;
|
||||||
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_player->pTrader->acceptTrade)
|
if (his_trade->m_acceptedTrade)
|
||||||
{
|
{
|
||||||
_player->pTrader->acceptTrade = false;
|
his_trade->m_acceptedTrade = false;
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100)); // guess size
|
WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100)); // guess size
|
||||||
|
|
@ -127,14 +137,14 @@ void WorldSession::SendUpdateTrade()
|
||||||
data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
|
data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
|
||||||
data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
|
data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
|
||||||
data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
|
data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
|
||||||
data << uint32(_player->pTrader->tradeGold); // trader gold
|
data << uint32(his_trade->m_tradeGold); // trader gold
|
||||||
data << uint32(0); // spell casted on lowest slot item
|
data << uint32(his_trade->m_tradeSpell); // spell casted on lowest slot item
|
||||||
|
|
||||||
for(uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
|
for(uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
||||||
if (Item* item = _player->pTrader->GetItemByTradeSlot(i))
|
if (Item* item = trader->GetItemByTradeSlot(i))
|
||||||
{
|
{
|
||||||
data << uint32(item->GetProto()->ItemId); // entry
|
data << uint32(item->GetProto()->ItemId); // entry
|
||||||
data << uint32(item->GetProto()->DisplayInfoID);// display id
|
data << uint32(item->GetProto()->DisplayInfoID);// display id
|
||||||
|
|
@ -171,11 +181,16 @@ void WorldSession::SendUpdateTrade()
|
||||||
|
|
||||||
void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
|
void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
|
||||||
{
|
{
|
||||||
for(int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i)
|
if (!_player->m_trade)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player* trader = _player->m_trade->m_tradeWith;
|
||||||
|
|
||||||
|
for(int i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
|
||||||
{
|
{
|
||||||
ItemPosCountVec traderDst;
|
ItemPosCountVec traderDst;
|
||||||
ItemPosCountVec playerDst;
|
ItemPosCountVec playerDst;
|
||||||
bool traderCanTrade = (myItems[i]==NULL || _player->pTrader->CanStoreItem( NULL_BAG, NULL_SLOT, traderDst, myItems[i], false ) == EQUIP_ERR_OK);
|
bool traderCanTrade = (myItems[i]==NULL || trader->CanStoreItem( NULL_BAG, NULL_SLOT, traderDst, myItems[i], false ) == EQUIP_ERR_OK);
|
||||||
bool playerCanTrade = (hisItems[i]==NULL || _player->CanStoreItem( NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false ) == EQUIP_ERR_OK);
|
bool playerCanTrade = (hisItems[i]==NULL || _player->CanStoreItem( NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false ) == EQUIP_ERR_OK);
|
||||||
if (traderCanTrade && playerCanTrade )
|
if (traderCanTrade && playerCanTrade )
|
||||||
{
|
{
|
||||||
|
|
@ -189,25 +204,25 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
|
||||||
if (_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
if (_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
||||||
{
|
{
|
||||||
sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",
|
sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",
|
||||||
_player->GetName(),_player->GetSession()->GetAccountId(),
|
_player->GetName(), _player->GetSession()->GetAccountId(),
|
||||||
myItems[i]->GetProto()->Name1,myItems[i]->GetEntry(),myItems[i]->GetCount(),
|
myItems[i]->GetProto()->Name1, myItems[i]->GetEntry(), myItems[i]->GetCount(),
|
||||||
_player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId());
|
trader->GetName(), trader->GetSession()->GetAccountId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// store
|
// store
|
||||||
_player->pTrader->MoveItemToInventory( traderDst, myItems[i], true, true);
|
trader->MoveItemToInventory( traderDst, myItems[i], true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hisItems[i])
|
if (hisItems[i])
|
||||||
{
|
{
|
||||||
// logging
|
// logging
|
||||||
DEBUG_LOG("player storing: %s", hisItems[i]->GetObjectGuid().GetString().c_str());
|
DEBUG_LOG("player storing: %s", hisItems[i]->GetObjectGuid().GetString().c_str());
|
||||||
if (_player->pTrader->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
if (trader->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
||||||
{
|
{
|
||||||
sLog.outCommand(_player->pTrader->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",
|
sLog.outCommand(trader->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)",
|
||||||
_player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId(),
|
trader->GetName(), trader->GetSession()->GetAccountId(),
|
||||||
hisItems[i]->GetProto()->Name1,hisItems[i]->GetEntry(),hisItems[i]->GetCount(),
|
hisItems[i]->GetProto()->Name1, hisItems[i]->GetEntry(), hisItems[i]->GetCount(),
|
||||||
_player->GetName(),_player->GetSession()->GetAccountId());
|
_player->GetName(), _player->GetSession()->GetAccountId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// store
|
// store
|
||||||
|
|
@ -232,8 +247,8 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
|
||||||
{
|
{
|
||||||
if (!playerCanTrade)
|
if (!playerCanTrade)
|
||||||
sLog.outError("player can't store item: %s", hisItems[i]->GetObjectGuid().GetString().c_str());
|
sLog.outError("player can't store item: %s", hisItems[i]->GetObjectGuid().GetString().c_str());
|
||||||
if (_player->pTrader->CanStoreItem( NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false ) == EQUIP_ERR_OK)
|
if (trader->CanStoreItem( NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false ) == EQUIP_ERR_OK)
|
||||||
_player->pTrader->MoveItemToInventory(traderDst, hisItems[i], true, true);
|
trader->MoveItemToInventory(traderDst, hisItems[i], true, true);
|
||||||
else
|
else
|
||||||
sLog.outError("trader can't take item back: %s", hisItems[i]->GetObjectGuid().GetString().c_str());
|
sLog.outError("trader can't take item back: %s", hisItems[i]->GetObjectGuid().GetString().c_str());
|
||||||
}
|
}
|
||||||
|
|
@ -247,35 +262,42 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
recvPacket.read_skip<uint32>(); // 7, amount traded slots ?
|
recvPacket.read_skip<uint32>(); // 7, amount traded slots ?
|
||||||
|
|
||||||
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player* trader = my_trade->m_tradeWith;
|
||||||
|
|
||||||
|
TradeData* his_trade = trader->m_trade;
|
||||||
|
if (!his_trade)
|
||||||
|
return;
|
||||||
|
|
||||||
Item *myItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
Item *myItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
||||||
Item *hisItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
Item *hisItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
||||||
bool myCanCompleteTrade=true,hisCanCompleteTrade=true;
|
bool myCanCompleteTrade=true,hisCanCompleteTrade=true;
|
||||||
|
|
||||||
if (!GetPlayer()->pTrader)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// not accept case incorrect money amount
|
// not accept case incorrect money amount
|
||||||
if (_player->tradeGold > _player->GetMoney())
|
if (my_trade->m_tradeGold > _player->GetMoney())
|
||||||
{
|
{
|
||||||
SendNotification(LANG_NOT_ENOUGH_GOLD);
|
SendNotification(LANG_NOT_ENOUGH_GOLD);
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
_player->acceptTrade = false;
|
my_trade->m_acceptedTrade = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not accept case incorrect money amount
|
// not accept case incorrect money amount
|
||||||
if (_player->pTrader->tradeGold > _player->pTrader->GetMoney())
|
if (his_trade->m_tradeGold > trader->GetMoney())
|
||||||
{
|
{
|
||||||
_player->pTrader->GetSession( )->SendNotification(LANG_NOT_ENOUGH_GOLD);
|
trader->GetSession( )->SendNotification(LANG_NOT_ENOUGH_GOLD);
|
||||||
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
_player->pTrader->acceptTrade = false;
|
his_trade->m_acceptedTrade = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (Item* item =_player->GetItemByTradeSlot(i))
|
if (Item* item = _player->GetItemByTradeSlot(i))
|
||||||
{
|
{
|
||||||
if (!item->CanBeTraded())
|
if (!item->CanBeTraded())
|
||||||
{
|
{
|
||||||
|
|
@ -284,7 +306,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Item* item =_player->pTrader->GetItemByTradeSlot(i))
|
if (Item* item = trader->GetItemByTradeSlot(i))
|
||||||
{
|
{
|
||||||
if (!item->CanBeTraded())
|
if (!item->CanBeTraded())
|
||||||
{
|
{
|
||||||
|
|
@ -294,11 +316,11 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_player->acceptTrade = true;
|
my_trade->m_acceptedTrade = true;
|
||||||
if (_player->pTrader->acceptTrade )
|
if (his_trade->m_acceptedTrade)
|
||||||
{
|
{
|
||||||
// inform partner client
|
// inform partner client
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT);
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
@ -311,7 +333,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
myItems[i]->SetInTrade();
|
myItems[i]->SetInTrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Item* item = _player->pTrader->GetItemByTradeSlot(i))
|
if (Item* item = trader->GetItemByTradeSlot(i))
|
||||||
{
|
{
|
||||||
DEBUG_LOG("partner trade item %s bag: %u slot: %u", item->GetObjectGuid().GetString().c_str(), item->GetBagSlot(), item->GetSlot());
|
DEBUG_LOG("partner trade item %s bag: %u slot: %u", item->GetObjectGuid().GetString().c_str(), item->GetBagSlot(), item->GetSlot());
|
||||||
hisItems[i] = item;
|
hisItems[i] = item;
|
||||||
|
|
@ -320,7 +342,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if item will fit in each inventory
|
// test if item will fit in each inventory
|
||||||
hisCanCompleteTrade = (_player->pTrader->CanStoreItems( myItems,TRADE_SLOT_TRADED_COUNT )== EQUIP_ERR_OK);
|
hisCanCompleteTrade = (trader->CanStoreItems( myItems,TRADE_SLOT_TRADED_COUNT )== EQUIP_ERR_OK);
|
||||||
myCanCompleteTrade = (_player->CanStoreItems( hisItems,TRADE_SLOT_TRADED_COUNT ) == EQUIP_ERR_OK);
|
myCanCompleteTrade = (_player->CanStoreItems( hisItems,TRADE_SLOT_TRADED_COUNT ) == EQUIP_ERR_OK);
|
||||||
|
|
||||||
// clear 'in-trade' flag
|
// clear 'in-trade' flag
|
||||||
|
|
@ -336,17 +358,17 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
if(!myCanCompleteTrade)
|
if(!myCanCompleteTrade)
|
||||||
{
|
{
|
||||||
SendNotification(LANG_NOT_FREE_TRADE_SLOTS);
|
SendNotification(LANG_NOT_FREE_TRADE_SLOTS);
|
||||||
GetPlayer( )->pTrader->GetSession( )->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS);
|
trader->GetSession( )->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS);
|
||||||
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!hisCanCompleteTrade)
|
else if (!hisCanCompleteTrade)
|
||||||
{
|
{
|
||||||
SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS);
|
SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS);
|
||||||
GetPlayer()->pTrader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS);
|
trader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS);
|
||||||
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -360,8 +382,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
if (Item* item = hisItems[i])
|
if (Item* item = hisItems[i])
|
||||||
{
|
{
|
||||||
item->SetUInt64Value( ITEM_FIELD_GIFTCREATOR,_player->pTrader->GetGUID());
|
item->SetUInt64Value( ITEM_FIELD_GIFTCREATOR, trader->GetGUID());
|
||||||
_player->pTrader->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
|
trader->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,72 +393,74 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket)
|
||||||
// logging money
|
// logging money
|
||||||
if (sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
if (sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
||||||
{
|
{
|
||||||
if (_player->GetSession()->GetSecurity() > SEC_PLAYER && _player->tradeGold > 0)
|
if (_player->GetSession()->GetSecurity() > SEC_PLAYER && my_trade->m_tradeGold > 0)
|
||||||
{
|
{
|
||||||
sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
|
sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
|
||||||
_player->GetName(),_player->GetSession()->GetAccountId(),
|
_player->GetName(),_player->GetSession()->GetAccountId(),
|
||||||
_player->tradeGold,
|
my_trade->m_tradeGold,
|
||||||
_player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId());
|
trader->GetName(), trader->GetSession()->GetAccountId());
|
||||||
}
|
}
|
||||||
if (_player->pTrader->GetSession()->GetSecurity() > SEC_PLAYER && _player->pTrader->tradeGold > 0)
|
if (trader->GetSession()->GetSecurity() > SEC_PLAYER && his_trade->m_tradeGold > 0)
|
||||||
{
|
{
|
||||||
sLog.outCommand(_player->pTrader->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
|
sLog.outCommand(trader->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
|
||||||
_player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId(),
|
trader->GetName(), trader->GetSession()->GetAccountId(),
|
||||||
_player->pTrader->tradeGold,
|
his_trade->m_tradeGold,
|
||||||
_player->GetName(),_player->GetSession()->GetAccountId());
|
_player->GetName(),_player->GetSession()->GetAccountId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update money
|
// update money
|
||||||
_player->ModifyMoney( -int32(_player->tradeGold) );
|
_player->ModifyMoney( -int32(my_trade->m_tradeGold) );
|
||||||
_player->ModifyMoney(_player->pTrader->tradeGold );
|
_player->ModifyMoney(his_trade->m_tradeGold );
|
||||||
_player->pTrader->ModifyMoney( -int32(_player->pTrader->tradeGold) );
|
trader->ModifyMoney( -int32(his_trade->m_tradeGold) );
|
||||||
_player->pTrader->ModifyMoney(_player->tradeGold );
|
trader->ModifyMoney(my_trade->m_tradeGold );
|
||||||
|
|
||||||
_player->ClearTrade();
|
// cleanup
|
||||||
_player->pTrader->ClearTrade();
|
delete _player->m_trade;
|
||||||
|
_player->m_trade = NULL;
|
||||||
|
delete trader->m_trade;
|
||||||
|
trader->m_trade = NULL;
|
||||||
|
|
||||||
// desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
|
// desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
_player->SaveInventoryAndGoldToDB();
|
_player->SaveInventoryAndGoldToDB();
|
||||||
_player->pTrader->SaveInventoryAndGoldToDB();
|
trader->SaveInventoryAndGoldToDB();
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
|
||||||
SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
|
SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
|
||||||
|
|
||||||
_player->pTrader->pTrader = NULL;
|
|
||||||
_player->pTrader = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT);
|
trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/)
|
void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/)
|
||||||
{
|
{
|
||||||
if (!GetPlayer()->pTrader)
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
my_trade->m_tradeWith->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||||
_player->acceptTrade = false;
|
my_trade->m_acceptedTrade = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/)
|
void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/)
|
||||||
{
|
{
|
||||||
if (!_player->pTrader)
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW);
|
my_trade->m_tradeWith->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW);
|
||||||
_player->pTrader->ClearTrade();
|
|
||||||
|
|
||||||
SendTradeStatus(TRADE_STATUS_OPEN_WINDOW);
|
SendTradeStatus(TRADE_STATUS_OPEN_WINDOW);
|
||||||
_player->ClearTrade();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendCancelTrade()
|
void WorldSession::SendCancelTrade()
|
||||||
{
|
{
|
||||||
|
if (m_playerRecentlyLogout)
|
||||||
|
return;
|
||||||
|
|
||||||
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,7 +476,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
|
||||||
uint64 ID;
|
uint64 ID;
|
||||||
recvPacket >> ID;
|
recvPacket >> ID;
|
||||||
|
|
||||||
if (GetPlayer()->pTrader)
|
if (GetPlayer()->m_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!GetPlayer()->isAlive())
|
if (!GetPlayer()->isAlive())
|
||||||
|
|
@ -487,7 +511,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOther == GetPlayer() || pOther->pTrader)
|
if (pOther == GetPlayer() || pOther->m_trade)
|
||||||
{
|
{
|
||||||
SendTradeStatus(TRADE_STATUS_BUSY);
|
SendTradeStatus(TRADE_STATUS_BUSY);
|
||||||
return;
|
return;
|
||||||
|
|
@ -536,13 +560,13 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK start trade
|
// OK start trade
|
||||||
_player->pTrader = pOther;
|
_player->m_trade = new TradeData(pOther);
|
||||||
pOther->pTrader =_player;
|
pOther->m_trade = new TradeData(_player);
|
||||||
|
|
||||||
WorldPacket data(SMSG_TRADE_STATUS, 12);
|
WorldPacket data(SMSG_TRADE_STATUS, 12);
|
||||||
data << (uint32) TRADE_STATUS_BEGIN_TRADE;
|
data << (uint32) TRADE_STATUS_BEGIN_TRADE;
|
||||||
data << (uint64)_player->GetGUID();
|
data << (uint64)_player->GetGUID();
|
||||||
_player->pTrader->GetSession()->SendPacket(&data);
|
pOther->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket)
|
||||||
|
|
@ -551,13 +575,14 @@ void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket)
|
||||||
|
|
||||||
recvPacket >> gold;
|
recvPacket >> gold;
|
||||||
|
|
||||||
if(!_player->pTrader)
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// gold can be incorrect, but this is checked at trade finished.
|
// gold can be incorrect, but this is checked at trade finished.
|
||||||
_player->tradeGold = gold;
|
my_trade->m_tradeGold = gold;
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendUpdateTrade();
|
my_trade->m_tradeWith->GetSession()->SendUpdateTrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
|
||||||
|
|
@ -571,7 +596,8 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
|
||||||
recvPacket >> bag;
|
recvPacket >> bag;
|
||||||
recvPacket >> slot;
|
recvPacket >> slot;
|
||||||
|
|
||||||
if (!_player->pTrader)
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// invalid slot number
|
// invalid slot number
|
||||||
|
|
@ -582,7 +608,7 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check cheating, can't fail with correct client operations
|
// check cheating, can't fail with correct client operations
|
||||||
Item* item = _player->GetItemByPos(bag,slot);
|
Item* item = _player->GetItemByPos(bag, slot);
|
||||||
if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded()))
|
if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded()))
|
||||||
{
|
{
|
||||||
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
||||||
|
|
@ -590,19 +616,16 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
if (my_trade->HasItem(item->GetObjectGuid()))
|
||||||
{
|
{
|
||||||
if (_player->m_tradeItems[i]==item->GetObjectGuid())
|
// cheating attempt
|
||||||
{
|
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
||||||
// cheating attempt
|
return;
|
||||||
SendTradeStatus(TRADE_STATUS_TRADE_CANCELED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_player->m_tradeItems[tradeSlot] = item->GetObjectGuid();
|
my_trade->m_tradeItems[tradeSlot] = item->GetObjectGuid();
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendUpdateTrade();
|
my_trade->m_tradeWith->GetSession()->SendUpdateTrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket)
|
||||||
|
|
@ -610,14 +633,15 @@ void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket)
|
||||||
uint8 tradeSlot;
|
uint8 tradeSlot;
|
||||||
recvPacket >> tradeSlot;
|
recvPacket >> tradeSlot;
|
||||||
|
|
||||||
if (!_player->pTrader)
|
TradeData* my_trade = _player->m_trade;
|
||||||
|
if (!my_trade)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// invalid slot number
|
// invalid slot number
|
||||||
if (tradeSlot >= TRADE_SLOT_COUNT)
|
if (tradeSlot >= TRADE_SLOT_COUNT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_player->m_tradeItems[tradeSlot].Clear();
|
my_trade->m_tradeItems[tradeSlot].Clear();
|
||||||
|
|
||||||
_player->pTrader->GetSession()->SendUpdateTrade();
|
my_trade->m_tradeWith->GetSession()->SendUpdateTrade();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10047"
|
#define REVISION_NR "10048"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue