aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-04-04 00:07:16 +0200
committerShauren <shauren.trinity@gmail.com>2015-04-04 00:07:16 +0200
commit89007ac1d08228c106c17cc8f51b4530531fa059 (patch)
treeae4178bfcdb4c3bc164a98aa0a63333508a4712e /src
parentbe016b94aa4b6df7bef1b21cbf6df80dbb3a7bcd (diff)
Core/Players: Updated trading
* Use special Uniq ObjectGuid::TradeItem for enchanting trade items * Added additional validation of trade state * Fixed an ancient bug in trade display causing pending enchantment to never update clientside if too many operations were done in a trading session
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp27
-rw-r--r--src/server/game/Entities/Player/Player.h32
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp361
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h58
-rw-r--r--src/server/game/Server/Packets/TradePackets.cpp129
-rw-r--r--src/server/game/Server/Packets/TradePackets.h187
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp24
-rw-r--r--src/server/game/Server/WorldSession.h33
-rw-r--r--src/server/game/Spells/Spell.cpp10
9 files changed, 511 insertions, 350 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 1730b1d2eee..5968c7453c3 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -97,6 +97,7 @@
#include "ItemPackets.h"
#include "QuestPackets.h"
#include "LootPackets.h"
+#include "TradePackets.h"
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
@@ -315,6 +316,8 @@ void TradeData::SetItem(TradeSlots slot, Item* item)
SetAccepted(false);
GetTraderData()->SetAccepted(false);
+ UpdateServerStateIndex();
+
Update();
// need remove possible trader spell applied to changed item
@@ -338,6 +341,8 @@ void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/)
SetAccepted(false);
GetTraderData()->SetAccepted(false);
+ UpdateServerStateIndex();
+
Update(true); // send spell info to item owner
Update(false); // send spell info to caster self
}
@@ -349,9 +354,9 @@ void TradeData::SetMoney(uint64 money)
if (!m_player->HasEnoughMoney(money))
{
- TradeStatusInfo info;
- info.Status = TRADE_STATUS_CLOSE_WINDOW;
- info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY;
+ WorldPackets::Trade::TradeStatus info;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_NOT_ENOUGH_MONEY;
m_player->GetSession()->SendTradeStatus(info);
return;
}
@@ -361,6 +366,8 @@ void TradeData::SetMoney(uint64 money)
SetAccepted(false);
GetTraderData()->SetAccepted(false);
+ UpdateServerStateIndex();
+
Update(true);
}
@@ -378,8 +385,8 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
if (!state)
{
- TradeStatusInfo info;
- info.Status = TRADE_STATUS_BACK_TO_TRADE;
+ WorldPackets::Trade::TradeStatus info;
+ info.Status = TRADE_STATUS_UNACCEPTED;
if (crosssend)
m_trader->GetSession()->SendTradeStatus(info);
else
@@ -10157,7 +10164,7 @@ bool Player::HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32
return false;
}
-InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count /*= NULL*/, uint32* itemLimitCategory /*= NULL*/) const
+InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count /*= nullptr*/, uint32* offendingItemId /*= nullptr*/) const
{
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(entry);
if (!pProto)
@@ -10203,8 +10210,8 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
{
if (no_space_count)
*no_space_count = count + curcount - limitEntry->Quantity;
- if (itemLimitCategory)
- *itemLimitCategory = pProto->GetItemLimitCategory();
+ if (offendingItemId)
+ *offendingItemId = pProto->GetId();
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS;
}
}
@@ -10735,7 +10742,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
}
//////////////////////////////////////////////////////////////////////////
-InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimitCategory) const
+InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offendingItemId) const
{
Item* item2;
@@ -10789,7 +10796,7 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimit
ItemTemplate const* pBagProto;
// item is 'one item only'
- InventoryResult res = CanTakeMoreSimilarItems(item, itemLimitCategory);
+ InventoryResult res = CanTakeMoreSimilarItems(item, offendingItemId);
if (res != EQUIP_ERR_OK)
return res;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 3f94fc23fa9..83627ede64f 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1148,19 +1148,6 @@ struct BGData
bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; }
};
-struct TradeStatusInfo
-{
- TradeStatusInfo() : Status(TRADE_STATUS_BUSY), TraderGuid(), Result(EQUIP_ERR_OK),
- IsTargetResult(false), ItemLimitCategoryId(0), Slot(0) { }
-
- TradeStatus Status;
- ObjectGuid TraderGuid;
- InventoryResult Result;
- bool IsTargetResult;
- uint32 ItemLimitCategoryId;
- uint8 Slot;
-};
-
struct VoidStorageItem
{
VoidStorageItem()
@@ -1192,7 +1179,7 @@ class TradeData
public: // constructors
TradeData(Player* player, Player* trader) :
m_player(player), m_trader(trader), m_accepted(false), m_acceptProccess(false),
- m_money(0), m_spell(0), m_spellCastItem() { }
+ m_money(0), m_spell(0), m_spellCastItem(), m_clientStateIndex(1), m_serverStateIndex(1) { }
Player* GetTrader() const { return m_trader; }
TradeData* GetTraderData() const;
@@ -1217,6 +1204,12 @@ class TradeData
bool IsInAcceptProcess() const { return m_acceptProccess; }
void SetInAcceptProcess(bool state) { m_acceptProccess = state; }
+ uint32 GetClientStateIndex() const { return m_clientStateIndex; }
+ void UpdateClientStateIndex() { ++m_clientStateIndex; }
+
+ uint32 GetServerStateIndex() const { return m_serverStateIndex; }
+ void UpdateServerStateIndex() { m_serverStateIndex = rand32(); }
+
private: // internal functions
void Update(bool for_trader = true);
@@ -1235,6 +1228,9 @@ class TradeData
ObjectGuid m_spellCastItem; // applied spell cast by item use
ObjectGuid m_items[TRADE_SLOT_COUNT]; // traded items from m_player side including non-traded slot
+
+ uint32 m_clientStateIndex;
+ uint32 m_serverStateIndex;
};
struct ResurrectionData
@@ -1480,11 +1476,11 @@ class Player : public Unit, public GridObject<Player>
bool CanNoReagentCast(SpellInfo const* spellInfo) const;
bool HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const;
bool HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const;
- InventoryResult CanTakeMoreSimilarItems(Item* pItem, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem, NULL, itemLimitCategory); }
- InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(entry, count, NULL, NULL, itemLimitCategory); }
+ InventoryResult CanTakeMoreSimilarItems(Item* pItem, uint32* offendingItemId = nullptr) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem, nullptr, offendingItemId); }
+ InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* offendingItemId = nullptr) const { return CanTakeMoreSimilarItems(entry, count, nullptr, nullptr, offendingItemId); }
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL) const;
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const;
- InventoryResult CanStoreItems(Item** items, int count, uint32* itemLimitCategory) const;
+ InventoryResult CanStoreItems(Item** items, int count, uint32* offendingItemId) const;
InventoryResult CanEquipNewItem(uint8 slot, uint16& dest, uint32 item, bool swap) const;
InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const;
@@ -1508,7 +1504,7 @@ class Player : public Unit, public GridObject<Player>
void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false) { AutoStoreLoot(NULL_BAG, NULL_SLOT, loot_id, store, broadcast); }
void StoreLootItem(uint8 lootSlot, Loot* loot);
- InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL, uint32* itemLimitCategory = NULL) const;
+ InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = nullptr, uint32* offendingItemId = nullptr) const;
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const;
void AddRefundReference(ObjectGuid it);
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index b06f89797cf..517d02f852a 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -31,65 +31,19 @@
#include "AccountMgr.h"
#include "TradePackets.h"
-void WorldSession::SendTradeStatus(TradeStatusInfo const& info)
+void WorldSession::SendTradeStatus(WorldPackets::Trade::TradeStatus& info)
{
- Player* trader = GetPlayer()->GetTrader();
-
- WorldPacket data(SMSG_TRADE_STATUS, 13);
- data.WriteBit(trader ? (trader->GetSession()->GetBattlenetAccountId() == GetBattlenetAccountId()) : 0); // IsSameBnetAccount, used for trading heirlooms and other battle.net bound items with your other accounts
- data.WriteBits(info.Status, 5);
-
- switch (info.Status)
- {
- case TRADE_STATUS_BEGIN_TRADE:
- data.WriteBit(info.TraderGuid[2]);
- data.WriteBit(info.TraderGuid[4]);
- data.WriteBit(info.TraderGuid[6]);
- data.WriteBit(info.TraderGuid[0]);
- data.WriteBit(info.TraderGuid[1]);
- data.WriteBit(info.TraderGuid[3]);
- data.WriteBit(info.TraderGuid[7]);
- data.WriteBit(info.TraderGuid[5]);
-
- data.WriteByteSeq(info.TraderGuid[4]);
- data.WriteByteSeq(info.TraderGuid[1]);
- data.WriteByteSeq(info.TraderGuid[2]);
- data.WriteByteSeq(info.TraderGuid[3]);
- data.WriteByteSeq(info.TraderGuid[0]);
- data.WriteByteSeq(info.TraderGuid[7]);
- data.WriteByteSeq(info.TraderGuid[6]);
- data.WriteByteSeq(info.TraderGuid[5]);
- break;
- case TRADE_STATUS_OPEN_WINDOW:
- data << uint32(0); // CGTradeInfo::m_tradeID
- break;
- case TRADE_STATUS_CLOSE_WINDOW:
- data.WriteBit(info.IsTargetResult); // bool isTargetError; used for: EQUIP_ERR_BAG_FULL, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_MISSING_REAGENT, EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED
- data << uint32(info.Result); // InventoryResult
- data << uint32(info.ItemLimitCategoryId); // ItemLimitCategory.dbc entry
- break;
- case TRADE_STATUS_WRONG_REALM:
- case TRADE_STATUS_NOT_ON_TAPLIST:
- data << uint8(info.Slot); // Trade slot; -1 here clears CGTradeInfo::m_tradeMoney
- break;
- case TRADE_STATUS_CURRENCY: // Not implemented
- case TRADE_STATUS_CURRENCY_NOT_TRADABLE: // Not implemented
- // Blizzard never implemented these, you can only trade currency with the field9 & 1 in CurrencyTypes.DBC, and only two test currencies have that flag
- data << uint32(0); // Trading Currency Id
- data << uint32(0); // Trading Currency Amount
- default:
- data.FlushBits();
- break;
- }
-
- SendPacket(&data);
+ info.Clear(); // reuse packet
+ Player* trader = _player->GetTrader();
+ info.PartnerIsSameBnetAccount = trader && trader->GetSession()->GetBattlenetAccountId() == GetBattlenetAccountId();
+ SendPacket(info.Write());
}
-void WorldSession::HandleIgnoreTradeOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleIgnoreTradeOpcode(WorldPackets::Trade::IgnoreTrade& /*ignoreTrade*/)
{
}
-void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleBusyTradeOpcode(WorldPackets::Trade::BusyTrade& /*busyTrade*/)
{
}
@@ -97,106 +51,44 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
{
TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
- ByteBuffer itemData(7*2 + 7*4 + 3*4 + 3*4 + 1);
-
- uint8 count = 0;
- for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
- if (view_trade->GetItem(TradeSlots(i)))
- ++count;
-
- WorldPacket data(SMSG_TRADE_UPDATED, 4*6 + 8 + 1 + 3 + count * 70);
- data << uint32(0); // CGTradeInfo::m_tradeID
- data << uint32(0); // unk 2
- data << uint64(view_trade->GetMoney()); // trader gold
- data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item
- data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
- data << uint32(0); // unk 5
- data << uint8(trader_data); // 1 means traders data, 0 means own
- data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
- data.WriteBits(count, 22);
+ WorldPackets::Trade::TradeUpdated tradeUpdated;
+ tradeUpdated.WhichPlayer = trader_data;
+ tradeUpdated.ClientStateIndex = view_trade->GetClientStateIndex();
+ tradeUpdated.CurrentStateIndex = view_trade->GetServerStateIndex();
+ tradeUpdated.Gold = view_trade->GetMoney();
+ tradeUpdated.ProposedEnchantment = view_trade->GetSpell();
for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
{
- Item* item = view_trade->GetItem(TradeSlots(i));
- if (!item)
- continue;
-
- ObjectGuid giftCreatorGuid = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
- ObjectGuid creatorGuid = item->GetGuidValue(ITEM_FIELD_CREATOR);
-
- data.WriteBit(giftCreatorGuid[7]);
- data.WriteBit(giftCreatorGuid[1]);
- bool notWrapped = data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED));
- data.WriteBit(giftCreatorGuid[3]);
-
- if (notWrapped)
+ if (Item* item = view_trade->GetItem(TradeSlots(i)))
{
- data.WriteBit(creatorGuid[7]);
- data.WriteBit(creatorGuid[1]);
- data.WriteBit(creatorGuid[4]);
- data.WriteBit(creatorGuid[6]);
- data.WriteBit(creatorGuid[2]);
- data.WriteBit(creatorGuid[3]);
- data.WriteBit(creatorGuid[5]);
- data.WriteBit(item->GetTemplate()->GetLockID() != 0);
- data.WriteBit(creatorGuid[0]);
-
- itemData.WriteByteSeq(creatorGuid[1]);
-
- itemData << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS /*3*/; ++enchant_slot)
- itemData << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
- itemData << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
-
- itemData.WriteByteSeq(creatorGuid[6]);
- itemData.WriteByteSeq(creatorGuid[2]);
- itemData.WriteByteSeq(creatorGuid[7]);
- itemData.WriteByteSeq(creatorGuid[4]);
-
- itemData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
- itemData << uint32(item->GetItemRandomPropertyId());
-
- itemData.WriteByteSeq(creatorGuid[3]);
-
- itemData << uint32(0); // unk7
-
- itemData.WriteByteSeq(creatorGuid[0]);
-
- itemData << uint32(item->GetSpellCharges());
- itemData << uint32(item->GetItemSuffixFactor());
+ WorldPackets::Trade::TradeUpdated::TradeItem tradeItem;
+ tradeItem.Slot = i;
+ tradeItem.EntryID = item->GetEntry();
+ tradeItem.StackCount = item->GetCount();
+ tradeItem.GiftCreator = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
+ if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
+ {
+ WorldPackets::Trade::TradeUpdated::UnwrappedTradeItem* unwrappedItem = &tradeItem.Unwrapped.Value;
+ unwrappedItem->Item.Initalize(item);
+ unwrappedItem->EnchantID = item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT);
+ unwrappedItem->OnUseEnchantmentID = item->GetEnchantmentId(USE_ENCHANTMENT_SLOT);
+ unwrappedItem->Creator = item->GetGuidValue(ITEM_FIELD_CREATOR);
+ unwrappedItem->Charges = item->GetSpellCharges();
+ unwrappedItem->Lock = item->GetTemplate()->GetLockID() && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED);
+ unwrappedItem->MaxDurability = item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY);
+ unwrappedItem->Durability = item->GetUInt32Value(ITEM_FIELD_DURABILITY);
+ for (uint32 s = SOCK_ENCHANTMENT_SLOT; s < MAX_GEM_SOCKETS; ++s)
+ unwrappedItem->SocketEnchant[s] = item->GetEnchantmentId(EnchantmentSlot(s + SOCK_ENCHANTMENT_SLOT));
+
+ tradeItem.Unwrapped.HasValue = true;
+ }
- itemData.WriteByteSeq(creatorGuid[5]);
+ tradeUpdated.Items.push_back(tradeItem);
}
-
- data.WriteBit(giftCreatorGuid[6]);
- data.WriteBit(giftCreatorGuid[4]);
- data.WriteBit(giftCreatorGuid[2]);
- data.WriteBit(giftCreatorGuid[0]);
- data.WriteBit(giftCreatorGuid[5]);
-
- itemData.WriteByteSeq(giftCreatorGuid[6]);
- itemData.WriteByteSeq(giftCreatorGuid[1]);
- itemData.WriteByteSeq(giftCreatorGuid[7]);
- itemData.WriteByteSeq(giftCreatorGuid[4]);
-
- itemData << uint32(item->GetTemplate()->GetId());
-
- itemData.WriteByteSeq(giftCreatorGuid[0]);
-
- itemData << uint32(item->GetCount());
-
- itemData.WriteByteSeq(giftCreatorGuid[5]);
-
- itemData << uint8(i);
-
- itemData.WriteByteSeq(giftCreatorGuid[2]);
- itemData.WriteByteSeq(giftCreatorGuid[3]);
}
- data.FlushBits();
- data.append(itemData);
-
- SendPacket(&data);
+ SendPacket(tradeUpdated.Write());
}
//==============================================================
@@ -328,7 +220,7 @@ static void clearAcceptTradeMode(Item* *myItems, Item* *hisItems)
}
}
-void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleAcceptTradeOpcode(WorldPackets::Trade::AcceptTrade& acceptTrade)
{
TradeData* my_trade = _player->m_trade;
if (!my_trade)
@@ -346,10 +238,18 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
// set before checks for propertly undo at problems (it already set in to client)
my_trade->SetAccepted(true);
- TradeStatusInfo info;
+ WorldPackets::Trade::TradeStatus info;
+ if (his_trade->GetServerStateIndex() != acceptTrade.StateIndex)
+ {
+ info.Status = TRADE_STATUS_STATE_CHANGED;
+ SendTradeStatus(info);
+ my_trade->SetAccepted(false);
+ return;
+ }
+
if (!_player->IsWithinDistInMap(trader, TRADE_DISTANCE, false))
{
- info.Status = TRADE_STATUS_TARGET_TO_FAR;
+ info.Status = TRADE_STATUS_TOO_FAR_AWAY;
SendTradeStatus(info);
my_trade->SetAccepted(false);
return;
@@ -358,8 +258,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
// not accept case incorrect money amount
if (!_player->HasEnoughMoney(my_trade->GetMoney()))
{
- info.Status = TRADE_STATUS_CLOSE_WINDOW;
- info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_NOT_ENOUGH_MONEY;
SendTradeStatus(info);
my_trade->SetAccepted(false, true);
return;
@@ -368,8 +268,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
// not accept case incorrect money amount
if (!trader->HasEnoughMoney(his_trade->GetMoney()))
{
- info.Status = TRADE_STATUS_CLOSE_WINDOW;
- info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_NOT_ENOUGH_MONEY;
trader->GetSession()->SendTradeStatus(info);
his_trade->SetAccepted(false, true);
return;
@@ -377,8 +277,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
if (_player->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - his_trade->GetMoney())
{
- info.Status = TRADE_STATUS_CLOSE_WINDOW;
- info.Result = EQUIP_ERR_TOO_MUCH_GOLD;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_TOO_MUCH_GOLD;
SendTradeStatus(info);
my_trade->SetAccepted(false, true);
return;
@@ -386,8 +286,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
if (trader->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - my_trade->GetMoney())
{
- info.Status = TRADE_STATUS_CLOSE_WINDOW;
- info.Result = EQUIP_ERR_TOO_MUCH_GOLD;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_TOO_MUCH_GOLD;
trader->GetSession()->SendTradeStatus(info);
his_trade->SetAccepted(false, true);
return;
@@ -400,15 +300,15 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
{
if (!item->CanBeTraded(false, true))
{
- info.Status = TRADE_STATUS_TRADE_CANCELED;
+ info.Status = TRADE_STATUS_CANCELLED;
SendTradeStatus(info);
return;
}
if (item->IsBindedNotWith(trader))
{
- info.Status = TRADE_STATUS_CLOSE_WINDOW;
- info.Result = EQUIP_ERR_TRADE_BOUND_ITEM;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_TRADE_BOUND_ITEM;
SendTradeStatus(info);
return;
}
@@ -418,7 +318,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
{
if (!item->CanBeTraded(false, true))
{
- info.Status = TRADE_STATUS_TRADE_CANCELED;
+ info.Status = TRADE_STATUS_CANCELLED;
SendTradeStatus(info);
return;
}
@@ -514,36 +414,36 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
}
// inform partner client
- info.Status = TRADE_STATUS_TRADE_ACCEPT;
+ info.Status = TRADE_STATUS_ACCEPTED;
trader->GetSession()->SendTradeStatus(info);
// test if item will fit in each inventory
- TradeStatusInfo myCanCompleteInfo, hisCanCompleteInfo;
- hisCanCompleteInfo.Result = trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT, &hisCanCompleteInfo.ItemLimitCategoryId);
- myCanCompleteInfo.Result = _player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT, &myCanCompleteInfo.ItemLimitCategoryId);
+ WorldPackets::Trade::TradeStatus myCanCompleteInfo, hisCanCompleteInfo;
+ hisCanCompleteInfo.BagResult = trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT, &hisCanCompleteInfo.ItemID);
+ myCanCompleteInfo.BagResult = _player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT, &myCanCompleteInfo.ItemID);
clearAcceptTradeMode(myItems, hisItems);
// in case of missing space report error
- if (myCanCompleteInfo.Result != EQUIP_ERR_OK)
+ if (myCanCompleteInfo.BagResult != EQUIP_ERR_OK)
{
clearAcceptTradeMode(my_trade, his_trade);
- myCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW;
+ myCanCompleteInfo.Status = TRADE_STATUS_FAILED;
trader->GetSession()->SendTradeStatus(myCanCompleteInfo);
- myCanCompleteInfo.IsTargetResult = true;
+ myCanCompleteInfo.FailureForYou = true;
SendTradeStatus(myCanCompleteInfo);
my_trade->SetAccepted(false);
his_trade->SetAccepted(false);
return;
}
- else if (hisCanCompleteInfo.Result != EQUIP_ERR_OK)
+ else if (hisCanCompleteInfo.BagResult != EQUIP_ERR_OK)
{
clearAcceptTradeMode(my_trade, his_trade);
- hisCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW;
+ hisCanCompleteInfo.Status = TRADE_STATUS_FAILED;
SendTradeStatus(hisCanCompleteInfo);
- hisCanCompleteInfo.IsTargetResult = true;
+ hisCanCompleteInfo.FailureForYou = true;
trader->GetSession()->SendTradeStatus(hisCanCompleteInfo);
my_trade->SetAccepted(false);
his_trade->SetAccepted(false);
@@ -613,18 +513,18 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
trader->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
- info.Status = TRADE_STATUS_TRADE_COMPLETE;
+ info.Status = TRADE_STATUS_COMPLETE;
trader->GetSession()->SendTradeStatus(info);
SendTradeStatus(info);
}
else
{
- info.Status = TRADE_STATUS_TRADE_ACCEPT;
+ info.Status = TRADE_STATUS_ACCEPTED;
trader->GetSession()->SendTradeStatus(info);
}
}
-void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleUnacceptTradeOpcode(WorldPackets::Trade::UnacceptTrade& /*unacceptTrade*/)
{
TradeData* my_trade = _player->GetTradeData();
if (!my_trade)
@@ -633,14 +533,14 @@ void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/)
my_trade->SetAccepted(false, true);
}
-void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleBeginTradeOpcode(WorldPackets::Trade::BeginTrade& /*beginTrade*/)
{
TradeData* my_trade = _player->m_trade;
if (!my_trade)
return;
- TradeStatusInfo info;
- info.Status = TRADE_STATUS_OPEN_WINDOW;
+ WorldPackets::Trade::TradeStatus info;
+ info.Status = TRADE_STATUS_INITIATED;
my_trade->GetTrader()->GetSession()->SendTradeStatus(info);
SendTradeStatus(info);
}
@@ -650,8 +550,8 @@ void WorldSession::SendCancelTrade()
if (PlayerRecentlyLoggedOut() || PlayerLogout())
return;
- TradeStatusInfo info;
- info.Status = TRADE_STATUS_TRADE_CANCELED;
+ WorldPackets::Trade::TradeStatus info;
+ info.Status = TRADE_STATUS_CANCELLED;
SendTradeStatus(info);
}
@@ -662,56 +562,36 @@ void WorldSession::HandleCancelTradeOpcode(WorldPackets::Trade::CancelTrade& /*c
_player->TradeCancel(true);
}
-void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleInitiateTradeOpcode(WorldPackets::Trade::InitiateTrade& initiateTrade)
{
- ObjectGuid guid;
-
- guid[0] = recvPacket.ReadBit();
- guid[3] = recvPacket.ReadBit();
- guid[5] = recvPacket.ReadBit();
- guid[1] = recvPacket.ReadBit();
- guid[4] = recvPacket.ReadBit();
- guid[6] = recvPacket.ReadBit();
- guid[7] = recvPacket.ReadBit();
- guid[2] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guid[7]);
- recvPacket.ReadByteSeq(guid[4]);
- recvPacket.ReadByteSeq(guid[3]);
- recvPacket.ReadByteSeq(guid[5]);
- recvPacket.ReadByteSeq(guid[1]);
- recvPacket.ReadByteSeq(guid[2]);
- recvPacket.ReadByteSeq(guid[6]);
- recvPacket.ReadByteSeq(guid[0]);
-
if (GetPlayer()->m_trade)
return;
- TradeStatusInfo info;
+ WorldPackets::Trade::TradeStatus info;
if (!GetPlayer()->IsAlive())
{
- info.Status = TRADE_STATUS_YOU_DEAD;
+ info.Status = TRADE_STATUS_DEAD;
SendTradeStatus(info);
return;
}
if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED))
{
- info.Status = TRADE_STATUS_YOU_STUNNED;
+ info.Status = TRADE_STATUS_STUNNED;
SendTradeStatus(info);
return;
}
if (isLogingOut())
{
- info.Status = TRADE_STATUS_YOU_LOGOUT;
+ info.Status = TRADE_STATUS_LOGGING_OUT;
SendTradeStatus(info);
return;
}
if (GetPlayer()->IsInFlight())
{
- info.Status = TRADE_STATUS_TARGET_TO_FAR;
+ info.Status = TRADE_STATUS_TOO_FAR_AWAY;
SendTradeStatus(info);
return;
}
@@ -722,8 +602,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return;
}
- Player* pOther = ObjectAccessor::FindPlayer(guid);
-
+ Player* pOther = ObjectAccessor::FindPlayer(initiateTrade.Guid);
if (!pOther)
{
info.Status = TRADE_STATUS_NO_TARGET;
@@ -733,7 +612,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
if (pOther == GetPlayer() || pOther->m_trade)
{
- info.Status = TRADE_STATUS_BUSY;
+ info.Status = TRADE_STATUS_PLAYER_BUSY;
SendTradeStatus(info);
return;
}
@@ -747,7 +626,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
if (pOther->IsInFlight())
{
- info.Status = TRADE_STATUS_TARGET_TO_FAR;
+ info.Status = TRADE_STATUS_TOO_FAR_AWAY;
SendTradeStatus(info);
return;
}
@@ -761,14 +640,14 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
if (pOther->GetSession()->isLogingOut())
{
- info.Status = TRADE_STATUS_TARGET_LOGOUT;
+ info.Status = TRADE_STATUS_TARGET_LOGGING_OUT;
SendTradeStatus(info);
return;
}
if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
{
- info.Status = TRADE_STATUS_IGNORE_YOU;
+ info.Status = TRADE_STATUS_PLAYER_IGNORED;
SendTradeStatus(info);
return;
}
@@ -784,7 +663,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false))
{
- info.Status = TRADE_STATUS_TARGET_TO_FAR;
+ info.Status = TRADE_STATUS_TOO_FAR_AWAY;
SendTradeStatus(info);
return;
}
@@ -799,52 +678,41 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
_player->m_trade = new TradeData(_player, pOther);
pOther->m_trade = new TradeData(pOther, _player);
- info.Status = TRADE_STATUS_BEGIN_TRADE;
- info.TraderGuid = _player->GetGUID();
+ info.Status = TRADE_STATUS_PROPOSED;
+ info.Partner = _player->GetGUID();
pOther->GetSession()->SendTradeStatus(info);
}
-void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleSetTradeGoldOpcode(WorldPackets::Trade::SetTradeGold& setTradeGold)
{
- uint64 gold;
- recvPacket >> gold;
-
TradeData* my_trade = _player->GetTradeData();
if (!my_trade)
return;
- my_trade->SetMoney(gold);
+ my_trade->UpdateClientStateIndex();
+ my_trade->SetMoney(setTradeGold.Coinage);
}
-void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleSetTradeItemOpcode(WorldPackets::Trade::SetTradeItem& setTradeItem)
{
- // send update
- uint8 tradeSlot;
- uint8 bag;
- uint8 slot;
-
- recvPacket >> slot;
- recvPacket >> tradeSlot;
- recvPacket >> bag;
-
TradeData* my_trade = _player->GetTradeData();
if (!my_trade)
return;
- TradeStatusInfo info;
+ WorldPackets::Trade::TradeStatus info;
// invalid slot number
- if (tradeSlot >= TRADE_SLOT_COUNT)
+ if (setTradeItem.TradeSlot >= TRADE_SLOT_COUNT)
{
- info.Status = TRADE_STATUS_TRADE_CANCELED;
+ info.Status = TRADE_STATUS_CANCELLED;
SendTradeStatus(info);
return;
}
// check cheating, can't fail with correct client operations
- Item* item = _player->GetItemByPos(bag, slot);
- if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true)))
+ Item* item = _player->GetItemByPos(setTradeItem.PackSlot, setTradeItem.ItemSlotInPack);
+ if (!item || (setTradeItem.TradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true)))
{
- info.Status = TRADE_STATUS_TRADE_CANCELED;
+ info.Status = TRADE_STATUS_CANCELLED;
SendTradeStatus(info);
return;
}
@@ -855,34 +723,39 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
if (my_trade->HasItem(iGUID))
{
// cheating attempt
- info.Status = TRADE_STATUS_TRADE_CANCELED;
+ info.Status = TRADE_STATUS_CANCELLED;
SendTradeStatus(info);
return;
}
- if (tradeSlot != TRADE_SLOT_NONTRADED && item->IsBindedNotWith(my_trade->GetTrader()))
+ my_trade->UpdateClientStateIndex();
+
+ if (setTradeItem.TradeSlot != TRADE_SLOT_NONTRADED && item->IsBindedNotWith(my_trade->GetTrader()))
{
info.Status = TRADE_STATUS_NOT_ON_TAPLIST;
- info.Slot = tradeSlot;
+ info.TradeSlot = setTradeItem.TradeSlot;
SendTradeStatus(info);
return;
}
- my_trade->SetItem(TradeSlots(tradeSlot), item);
+ my_trade->SetItem(TradeSlots(setTradeItem.TradeSlot), item);
}
-void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleClearTradeItemOpcode(WorldPackets::Trade::ClearTradeItem& clearTradeItem)
{
- uint8 tradeSlot;
- recvPacket >> tradeSlot;
-
TradeData* my_trade = _player->m_trade;
if (!my_trade)
return;
+ my_trade->UpdateClientStateIndex();
+
// invalid slot number
- if (tradeSlot >= TRADE_SLOT_COUNT)
+ if (clearTradeItem.TradeSlot >= TRADE_SLOT_COUNT)
return;
- my_trade->SetItem(TradeSlots(tradeSlot), NULL);
+ my_trade->SetItem(TradeSlots(clearTradeItem.TradeSlot), NULL);
+}
+
+void WorldSession::HandleSetTradeCurrencyOpcode(WorldPackets::Trade::SetTradeCurrency& /*setTradeCurrency*/)
+{
}
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 9a0714b105a..894e7624ca5 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -4659,38 +4659,32 @@ enum SpellFamilyNames
enum TradeStatus
{
- TRADE_STATUS_OPEN_WINDOW = 0,
- // 1 - Related to EVENT_PLAYER_MONEY
- TRADE_STATUS_NOT_ON_TAPLIST = 2, // Related to trading soulbound loot items
- TRADE_STATUS_YOU_LOGOUT = 3,
- TRADE_STATUS_IGNORE_YOU = 4,
- TRADE_STATUS_TARGET_DEAD = 5,
- TRADE_STATUS_TRADE_ACCEPT = 6,
- TRADE_STATUS_TARGET_LOGOUT = 7,
- // 8 - nonexistent
- TRADE_STATUS_TRADE_COMPLETE = 9,
- TRADE_STATUS_TRIAL_ACCOUNT = 10, // Trial accounts can not perform that action
- // 11 - nonexistent
- TRADE_STATUS_BEGIN_TRADE = 12,
- TRADE_STATUS_YOU_DEAD = 13,
- // 14 - nonexistent
- // 15 - nonexistent
- TRADE_STATUS_TARGET_TO_FAR = 16,
- TRADE_STATUS_NO_TARGET = 17,
- TRADE_STATUS_BUSY_2 = 18,
- TRADE_STATUS_CURRENCY_NOT_TRADABLE = 19, // new 4.x
- TRADE_STATUS_WRONG_FACTION = 20,
- TRADE_STATUS_BUSY = 21,
- // 22 - equivalent to 335 unk status 9
- TRADE_STATUS_TRADE_CANCELED = 23,
- TRADE_STATUS_CURRENCY = 24, // new 4.x
- TRADE_STATUS_BACK_TO_TRADE = 25,
- TRADE_STATUS_WRONG_REALM = 26, // You can only trade conjured items... (cross realm BG related).
- TRADE_STATUS_YOU_STUNNED = 27,
- // 28 - nonexistent
- TRADE_STATUS_TARGET_STUNNED = 29,
- // 30 - nonexistent
- TRADE_STATUS_CLOSE_WINDOW = 31,
+ TRADE_STATUS_STUNNED = 0,
+ TRADE_STATUS_TARGET_DEAD = 2,
+ TRADE_STATUS_PLAYER_IGNORED = 3,
+ TRADE_STATUS_STATE_CHANGED = 4,
+ TRADE_STATUS_PETITION = 5,
+ TRADE_STATUS_FAILED = 6,
+ TRADE_STATUS_NOT_ENOUGH_CURRENCY = 7,
+ TRADE_STATUS_TARGET_LOGGING_OUT = 8,
+ TRADE_STATUS_PROPOSED = 9,
+ TRADE_STATUS_RESTRICTED_ACCOUNT = 10,
+ TRADE_STATUS_WRONG_REALM = 12,
+ TRADE_STATUS_ALREADY_TRADING = 14,
+ TRADE_STATUS_COMPLETE = 15,
+ TRADE_STATUS_TARGET_STUNNED = 16,
+ TRADE_STATUS_ACCEPTED = 17,
+ TRADE_STATUS_NO_TARGET = 18,
+ TRADE_STATUS_CURRENCY_NOT_TRADABLE = 19,
+ TRADE_STATUS_WRONG_FACTION = 20,
+ TRADE_STATUS_NOT_ON_TAPLIST = 21,
+ TRADE_STATUS_UNACCEPTED = 23,
+ TRADE_STATUS_LOGGING_OUT = 24,
+ TRADE_STATUS_CANCELLED = 26,
+ TRADE_STATUS_TOO_FAR_AWAY = 27,
+ TRADE_STATUS_DEAD = 28,
+ TRADE_STATUS_INITIATED = 29,
+ TRADE_STATUS_PLAYER_BUSY = 30
};
enum XPColorChar
diff --git a/src/server/game/Server/Packets/TradePackets.cpp b/src/server/game/Server/Packets/TradePackets.cpp
new file mode 100644
index 00000000000..ef5ebb13e20
--- /dev/null
+++ b/src/server/game/Server/Packets/TradePackets.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TradePackets.h"
+
+void WorldPackets::Trade::AcceptTrade::Read()
+{
+ _worldPacket >> StateIndex;
+}
+
+void WorldPackets::Trade::ClearTradeItem::Read()
+{
+ _worldPacket >> TradeSlot;
+}
+
+void WorldPackets::Trade::InitiateTrade::Read()
+{
+ _worldPacket >> Guid;
+}
+
+void WorldPackets::Trade::SetTradeCurrency::Read()
+{
+ _worldPacket >> Type >> Quantity;
+}
+
+void WorldPackets::Trade::SetTradeGold::Read()
+{
+ _worldPacket >> Coinage;
+}
+
+void WorldPackets::Trade::SetTradeItem::Read()
+{
+ _worldPacket >> TradeSlot >> PackSlot >> ItemSlotInPack;
+}
+
+WorldPacket const* WorldPackets::Trade::TradeStatus::Write()
+{
+ _worldPacket.WriteBit(PartnerIsSameBnetAccount);
+ _worldPacket.WriteBits(Status, 5);
+ switch (Status)
+ {
+ case TRADE_STATUS_FAILED:
+ _worldPacket.WriteBit(FailureForYou);
+ _worldPacket << int32(BagResult);
+ _worldPacket << int32(ItemID);
+ break;
+ case TRADE_STATUS_INITIATED:
+ _worldPacket << uint32(ID);
+ break;
+ case TRADE_STATUS_PROPOSED:
+ _worldPacket << Partner;
+ _worldPacket << PartnerAccount;
+ break;
+ case TRADE_STATUS_WRONG_REALM:
+ case TRADE_STATUS_NOT_ON_TAPLIST:
+ _worldPacket << uint8(TradeSlot);
+ break;
+ case TRADE_STATUS_NOT_ENOUGH_CURRENCY:
+ case TRADE_STATUS_CURRENCY_NOT_TRADABLE:
+ _worldPacket << int32(CurrencyType);
+ _worldPacket << int32(CurrencyQuantity);
+ break;
+ default:
+ _worldPacket.FlushBits();
+ break;
+ }
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& buffer, WorldPackets::Trade::TradeUpdated::UnwrappedTradeItem const& unwrappedTradeItem)
+{
+ buffer << unwrappedTradeItem.Item;
+ buffer << int32(unwrappedTradeItem.EnchantID);
+ buffer << int32(unwrappedTradeItem.OnUseEnchantmentID);
+ buffer.append(unwrappedTradeItem.SocketEnchant, MAX_GEM_SOCKETS);
+ buffer << unwrappedTradeItem.Creator;
+ buffer << int32(unwrappedTradeItem.Charges);
+ buffer << uint32(unwrappedTradeItem.MaxDurability);
+ buffer << uint32(unwrappedTradeItem.Durability);
+ buffer.WriteBit(unwrappedTradeItem.Lock);
+ buffer.FlushBits();
+
+ return buffer;
+}
+
+ByteBuffer& operator<<(ByteBuffer& buffer, WorldPackets::Trade::TradeUpdated::TradeItem const& tradeItem)
+{
+ buffer << uint8(tradeItem.Slot);
+ buffer << uint32(tradeItem.EntryID);
+ buffer << uint32(tradeItem.StackCount);
+ buffer << tradeItem.GiftCreator;
+ if (buffer.WriteBit(tradeItem.Unwrapped.HasValue))
+ buffer << tradeItem.Unwrapped.Value;
+
+ return buffer;
+}
+
+WorldPacket const* WorldPackets::Trade::TradeUpdated::Write()
+{
+ _worldPacket << uint8(WhichPlayer);
+ _worldPacket << uint32(ID);
+ _worldPacket << uint32(ClientStateIndex);
+ _worldPacket << uint32(CurrentStateIndex);
+ _worldPacket << uint64(Gold);
+ _worldPacket << int32(CurrencyType);
+ _worldPacket << int32(CurrencyQuantity);
+ _worldPacket << int32(ProposedEnchantment);
+ _worldPacket << uint32(Items.size());
+
+ for (TradeItem const& item : Items)
+ _worldPacket << item;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/TradePackets.h b/src/server/game/Server/Packets/TradePackets.h
index b964a24e6fe..8831135f4e5 100644
--- a/src/server/game/Server/Packets/TradePackets.h
+++ b/src/server/game/Server/Packets/TradePackets.h
@@ -1,29 +1,55 @@
/*
-* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of the GNU General Public License as published by the
-* Free Software Foundation; either version 2 of the License, or (at your
-* option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#ifndef TradePackets_h__
#define TradePackets_h__
-#include "Packet.h"
+#include "ItemPackets.h"
namespace WorldPackets
{
namespace Trade
{
+ class AcceptTrade final : public ClientPacket
+ {
+ public:
+ AcceptTrade(WorldPacket&& packet) : ClientPacket(CMSG_ACCEPT_TRADE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 StateIndex = 0;
+ };
+
+ class BeginTrade final : public ClientPacket
+ {
+ public:
+ BeginTrade(WorldPacket&& packet) : ClientPacket(CMSG_BEGIN_TRADE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class BusyTrade final : public ClientPacket
+ {
+ public:
+ BusyTrade(WorldPacket&& packet) : ClientPacket(CMSG_BUSY_TRADE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
class CancelTrade final : public ClientPacket
{
public:
@@ -31,6 +57,135 @@ namespace WorldPackets
void Read() override { }
};
+
+ class ClearTradeItem final : public ClientPacket
+ {
+ public:
+ ClearTradeItem(WorldPacket&& packet) : ClientPacket(CMSG_CLEAR_TRADE_ITEM, std::move(packet)) { }
+
+ void Read() override;
+
+ uint8 TradeSlot = 0;
+ };
+
+ class IgnoreTrade final : public ClientPacket
+ {
+ public:
+ IgnoreTrade(WorldPacket&& packet) : ClientPacket(CMSG_IGNORE_TRADE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class InitiateTrade final : public ClientPacket
+ {
+ public:
+ InitiateTrade(WorldPacket&& packet) : ClientPacket(CMSG_INITIATE_TRADE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Guid;
+ };
+
+ class SetTradeCurrency final : public ClientPacket
+ {
+ public:
+ SetTradeCurrency(WorldPacket&& packet) : ClientPacket(CMSG_SET_TRADE_CURRENCY, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 Type = 0;
+ uint32 Quantity = 0;
+ };
+
+ class SetTradeGold final : public ClientPacket
+ {
+ public:
+ SetTradeGold(WorldPacket&& packet) : ClientPacket(CMSG_SET_TRADE_GOLD, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 Coinage = 0;
+ };
+
+ class SetTradeItem final : public ClientPacket
+ {
+ public:
+ SetTradeItem(WorldPacket&& packet) : ClientPacket(CMSG_SET_TRADE_ITEM, std::move(packet)) { }
+
+ void Read() override;
+
+ uint8 TradeSlot = 0;
+ uint8 PackSlot = 0;
+ uint8 ItemSlotInPack = 0;
+ };
+
+ class UnacceptTrade final : public ClientPacket
+ {
+ public:
+ UnacceptTrade(WorldPacket&& packet) : ClientPacket(CMSG_UNACCEPT_TRADE, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class TradeStatus final : public ServerPacket
+ {
+ public:
+ TradeStatus() : ServerPacket(SMSG_TRADE_STATUS, 1 + 1 + 16 + 4 + 4 + 1 + 4 + 4 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ::TradeStatus Status = TRADE_STATUS_INITIATED;
+ uint8 TradeSlot = 0;
+ ObjectGuid PartnerAccount;
+ ObjectGuid Partner;
+ int32 CurrencyType = 0;
+ int32 CurrencyQuantity = 0;
+ bool FailureForYou = false;
+ int32 BagResult = 0;
+ uint32 ItemID = 0;
+ uint32 ID = 0;
+ bool PartnerIsSameBnetAccount = false;
+ };
+
+ class TradeUpdated final : public ServerPacket
+ {
+ public:
+ TradeUpdated() : ServerPacket(SMSG_TRADE_UPDATED) { }
+
+ WorldPacket const* Write() override;
+
+ struct UnwrappedTradeItem
+ {
+ WorldPackets::Item::ItemInstance Item;
+ int32 EnchantID = 0;
+ int32 OnUseEnchantmentID = 0;
+ ObjectGuid Creator;
+ int32 Charges = 0;
+ bool Lock = false;
+ uint32 MaxDurability = 0;
+ uint32 Durability = 0;
+ int32 SocketEnchant[MAX_GEM_SOCKETS] = { };
+ };
+
+ struct TradeItem
+ {
+ uint8 Slot = 0;
+ int32 EntryID = 0;
+ int32 StackCount = 0;
+ ObjectGuid GiftCreator;
+ Optional<UnwrappedTradeItem> Unwrapped;
+ };
+
+ uint64 Gold = 0;
+ uint32 CurrentStateIndex = 0;
+ uint8 WhichPlayer = 0;
+ uint32 ClientStateIndex = 0;
+ std::vector<TradeItem> Items;
+ int32 CurrencyType = 0;
+ uint32 ID = 0;
+ int32 ProposedEnchantment = 0;
+ int32 CurrencyQuantity = 0;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index b000e29a15f..a637e8f8966 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -145,7 +145,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_ACCEPT_GUILD_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::AcceptGuildInvite, &WorldSession::HandleGuildAcceptInvite);
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_LEVEL_GRANT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode );
+ DEFINE_HANDLER(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::AcceptTrade, &WorldSession::HandleAcceptTradeOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_WARGAME_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACTIVATE_TAXI, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ADD_BATTLENET_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -200,7 +200,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SET_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SUMMON, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_UPDATE_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BEGIN_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode );
+ DEFINE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BeginTrade, &WorldSession::HandleBeginTradeOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_EXIT_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfExitRequest);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse );
@@ -210,7 +210,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_BLACK_MARKET_OPEN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::BlackMarket::BlackMarketOpen, &WorldSession::HandleBlackMarketOpen);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BLACK_MARKET_REQUEST_ITEMS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG_REPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugReportOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode );
+ DEFINE_HANDLER(CMSG_BUSY_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BusyTrade, &WorldSession::HandleBusyTradeOpcode);
DEFINE_HANDLER(CMSG_BUY_BACK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyBackItem, &WorldSession::HandleBuybackItem);
DEFINE_HANDLER(CMSG_BUY_BANK_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Bank::BuyBankSlot, &WorldSession::HandleBuyBankSlotOpcode);
DEFINE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyItem, &WorldSession::HandleBuyItemOpcode);
@@ -307,7 +307,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHECK_WOW_TOKEN_VETERAN_ELIGIBILITY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHOICE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CLEAR_RAID_MARKER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CLEAR_TRADE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode );
+ DEFINE_HANDLER(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::ClearTradeItem, &WorldSession::HandleClearTradeItemOpcode);
DEFINE_HANDLER(CMSG_CLIENT_PORT_GRAVEYARD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Misc::PortGraveyard, &WorldSession::HandlePortGraveyard);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CLOSE_INTERACTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_COMMENTATOR_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -447,10 +447,10 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_GUILD_UPDATE_INFO_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateInfoText, &WorldSession::HandleGuildUpdateInfoText);
DEFINE_HANDLER(CMSG_GUILD_UPDATE_MOTD_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateMotdText, &WorldSession::HandleGuildUpdateMotdText);
DEFINE_OPCODE_HANDLER_OLD(CMSG_HEARTH_AND_RESURRECT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_IGNORE_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode );
+ DEFINE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::IgnoreTrade, &WorldSession::HandleIgnoreTradeOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_INCREASE_CAST_TIME_FOR_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_INITIATE_ROLE_POLL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRolePollBeginOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_INITIATE_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode );
+ DEFINE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::InitiateTrade, &WorldSession::HandleInitiateTradeOpcode);
DEFINE_HANDLER(CMSG_INSPECT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::Inspect, &WorldSession::HandleInspectOpcode);
DEFINE_HANDLER(CMSG_INSPECT_PVP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::InspectPVPRequest, &WorldSession::HandleInspectPVP);
DEFINE_OPCODE_HANDLER_OLD(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse);
@@ -738,9 +738,9 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SET_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Talent::SetSpecialization, &WorldSession::HandleSetSpecializationOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode );
DEFINE_HANDLER(CMSG_SET_TITLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Character::SetTitle, &WorldSession::HandleSetTitleOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TRADE_CURRENCY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TRADE_GOLD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TRADE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode );
+ DEFINE_HANDLER(CMSG_SET_TRADE_CURRENCY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::SetTradeCurrency, &WorldSession::HandleSetTradeCurrencyOpcode);
+ DEFINE_HANDLER(CMSG_SET_TRADE_GOLD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::SetTradeGold, &WorldSession::HandleSetTradeGoldOpcode);
+ DEFINE_HANDLER(CMSG_SET_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::SetTradeItem, &WorldSession::HandleSetTradeItemOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_USING_PARTY_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_WATCHED_FACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetWatchedFactionOpcode );
DEFINE_HANDLER(CMSG_SHOWING_CLOAK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Character::ShowingCloak, &WorldSession::HandleShowingCloakOpcode);
@@ -792,7 +792,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_DISCONNECT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_POST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_UI_TIME_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::UITimeRequest, &WorldSession::HandleUITimeRequest);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode );
+ DEFINE_HANDLER(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Trade::UnacceptTrade, &WorldSession::HandleUnacceptTradeOpcode);
DEFINE_HANDLER(CMSG_UNDELETE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::UndeleteCharacter, &WorldSession::HandleCharUndeleteOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SKILL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -1675,8 +1675,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOKEN_UNK1, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOTEM_MOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_UPDATED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 8ec5af98db7..9c2457e7b5e 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -55,7 +55,6 @@ struct AuctionEntry;
struct DeclinedName;
struct ItemTemplate;
struct MovementInfo;
-struct TradeStatusInfo;
namespace lfg
{
@@ -393,7 +392,18 @@ namespace WorldPackets
namespace Trade
{
+ class AcceptTrade;
+ class BeginTrade;
+ class BusyTrade;
class CancelTrade;
+ class ClearTradeItem;
+ class IgnoreTrade;
+ class InitiateTrade;
+ class SetTradeCurrency;
+ class SetTradeGold;
+ class SetTradeItem;
+ class UnacceptTrade;
+ class TradeStatus;
}
namespace Who
@@ -658,7 +668,7 @@ class WorldSession
void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId = BATTLEGROUND_RB);
- void SendTradeStatus(TradeStatusInfo const& status);
+ void SendTradeStatus(WorldPackets::Trade::TradeStatus& status);
void SendUpdateTrade(bool trader_data = true);
void SendCancelTrade();
@@ -1033,16 +1043,17 @@ class WorldSession
void HandleDuelAccepted();
void HandleDuelCancelled();
- void HandleAcceptTradeOpcode(WorldPacket& recvPacket);
- void HandleBeginTradeOpcode(WorldPacket& recvPacket);
- void HandleBusyTradeOpcode(WorldPacket& recvPacket);
+ void HandleAcceptTradeOpcode(WorldPackets::Trade::AcceptTrade& acceptTrade);
+ void HandleBeginTradeOpcode(WorldPackets::Trade::BeginTrade& beginTrade);
+ void HandleBusyTradeOpcode(WorldPackets::Trade::BusyTrade& busyTrade);
void HandleCancelTradeOpcode(WorldPackets::Trade::CancelTrade& cancelTrade);
- void HandleClearTradeItemOpcode(WorldPacket& recvPacket);
- void HandleIgnoreTradeOpcode(WorldPacket& recvPacket);
- void HandleInitiateTradeOpcode(WorldPacket& recvPacket);
- void HandleSetTradeGoldOpcode(WorldPacket& recvPacket);
- void HandleSetTradeItemOpcode(WorldPacket& recvPacket);
- void HandleUnacceptTradeOpcode(WorldPacket& recvPacket);
+ void HandleClearTradeItemOpcode(WorldPackets::Trade::ClearTradeItem& clearTradeItem);
+ void HandleIgnoreTradeOpcode(WorldPackets::Trade::IgnoreTrade& ignoreTrade);
+ void HandleInitiateTradeOpcode(WorldPackets::Trade::InitiateTrade& initiateTrade);
+ void HandleSetTradeCurrencyOpcode(WorldPackets::Trade::SetTradeCurrency& setTradeCurrency);
+ void HandleSetTradeGoldOpcode(WorldPackets::Trade::SetTradeGold& setTradeGold);
+ void HandleSetTradeItemOpcode(WorldPackets::Trade::SetTradeItem& setTradeItem);
+ void HandleUnacceptTradeOpcode(WorldPackets::Trade::UnacceptTrade& unacceptTrade);
void HandleAuctionHelloOpcode(WorldPackets::AuctionHouse::AuctionHelloRequest& packet);
void HandleAuctionListItems(WorldPacket& recvData);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index a5c143f1c63..a4b84e6a2eb 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -365,7 +365,7 @@ void SpellCastTargets::SetItemTarget(Item* item)
void SpellCastTargets::SetTradeItemTarget(Player* caster)
{
- m_itemTargetGUID.SetRawValue({ uint8(TRADE_SLOT_NONTRADED), 0, 0, 0, 0, 0, 0, 0 });
+ m_itemTargetGUID = ObjectGuid::TradeItem;
m_itemTargetEntry = 0;
m_targetMask |= TARGET_FLAG_TRADE_ITEM;
@@ -489,9 +489,7 @@ void SpellCastTargets::Update(Unit* caster)
m_itemTarget = player->GetItemByGuid(m_itemTargetGUID);
else if (m_targetMask & TARGET_FLAG_TRADE_ITEM)
{
- ObjectGuid nonTradedGuid;
- nonTradedGuid.SetRawValue(uint64(0), uint64(TRADE_SLOT_NONTRADED));
- if (m_itemTargetGUID == nonTradedGuid) // here it is not guid but slot. Also prevents hacking slots
+ if (m_itemTargetGUID == ObjectGuid::TradeItem)
if (TradeData* pTrade = player->GetTradeData())
m_itemTarget = pTrade->GetTraderData()->GetItem(TRADE_SLOT_NONTRADED);
}
@@ -5543,9 +5541,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!my_trade)
return SPELL_FAILED_NOT_TRADING;
- // Item target guid contains trade slot until m_targets.UpdateTradeSlotItem() is called
- TradeSlots slot = TradeSlots(m_targets.GetItemTargetGUID().GetRawValue().at(0));
- if (slot != TRADE_SLOT_NONTRADED)
+ if (m_targets.GetItemTargetGUID() != ObjectGuid::TradeItem)
return SPELL_FAILED_BAD_TARGETS;
if (!IsTriggered())