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
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
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));
|
||||
|
||||
itemData.WriteByteSeq(creatorGuid[1]);
|
||||
tradeItem.Unwrapped.HasValue = true;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user