aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/TradeHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/TradeHandler.cpp')
-rwxr-xr-xsrc/server/game/Handlers/TradeHandler.cpp181
1 files changed, 129 insertions, 52 deletions
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 318325b4e57..b20b7e1730a 100755
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -36,32 +36,30 @@ void WorldSession::SendTradeStatus(TradeStatus status)
switch (status)
{
+ data.Initialize(SMSG_TRADE_STATUS, 1+4+4);
+ data.WriteBit(0); // unk bit, usually 0
+ data.WriteBits(status, 5);
+
case TRADE_STATUS_BEGIN_TRADE:
- data.Initialize(SMSG_TRADE_STATUS, 4+8);
- data << uint32(status);
- data << uint64(0);
+ data.WriteBits(0, 8); // zero guid
break;
case TRADE_STATUS_OPEN_WINDOW:
- data.Initialize(SMSG_TRADE_STATUS, 4+4);
- data << uint32(status);
- data << uint32(0); // added in 2.4.0
+ data << uint32(0); // unk
break;
case TRADE_STATUS_CLOSE_WINDOW:
- data.Initialize(SMSG_TRADE_STATUS, 4+4+1+4);
- data << uint32(status);
- data << uint32(0);
- data << uint8(0);
- data << uint32(0);
+ data.WriteBit(0); // unk
+ data << uint32(0); // unk
+ data << uint32(0); // unk
break;
case TRADE_STATUS_ONLY_CONJURED:
case TRADE_STATUS_NOT_ELIGIBLE:
- data.Initialize(SMSG_TRADE_STATUS, 4+1);
- data << uint32(status);
- data << uint8(0);
+ data << uint8(0); // unk
break;
+ case TRADE_STATUS_CURRENCY: // Not implemented
+ case TRADE_STATUS_CURRENCY_NOT_TRADABLE: // Not implemented
+ data << uint32(0); // unk
+ data << uint32(0); // unk
default:
- data.Initialize(SMSG_TRADE_STATUS, 4);
- data << uint32(status);
break;
}
@@ -71,13 +69,11 @@ void WorldSession::SendTradeStatus(TradeStatus status)
void WorldSession::HandleIgnoreTradeOpcode(WorldPacket& /*recvPacket*/)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Ignore Trade %u", _player->GetGUIDLow());
- // recvPacket.print_storage();
}
void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Busy Trade %u", _player->GetGUIDLow());
- // recvPacket.print_storage();
}
void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
@@ -85,46 +81,106 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1+4+4+4+4+4+7*(1+4+4+4+4+8+4+4+4+4+8+4+4+4+4+4+4));
- data << uint8(trader_data); // 1 means traders data, 0 means own
- data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
- data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
- data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
+
+ data << uint32(0); // this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
+ data << uint32(0); // unk 2
data << uint32(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
+
+ ByteBuffer itemData;
+ ByteBuffer bitData;
+ uint8 count = 0;
for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
{
- data << uint8(i); // trade slot number, if not specified, then end of packet
+ Item* item = view_trade->GetItem(TradeSlots(i));
+ if (!item)
+ continue;
+ ++count;
- if (Item* item = view_trade->GetItem(TradeSlots(i)))
- {
- data << uint32(item->GetTemplate()->ItemId); // entry
- data << uint32(item->GetTemplate()->DisplayInfoID);// display id
- data << uint32(item->GetCount()); // stack count
- // wrapped: hide stats but show giftcreator name
- data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED) ? 1 : 0);
- data << uint64(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR));
- // perm. enchantment and gems
- data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
- data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
- // creator
- data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR));
- data << uint32(item->GetSpellCharges()); // charges
- data << uint32(item->GetItemSuffixFactor()); // SuffixFactor
- data << uint32(item->GetItemRandomPropertyId());// random properties id
- data << uint32(item->GetTemplate()->LockID); // lock id
- // max durability
- data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
- // durability
- data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
- }
- else
+ ObjectGuid giftCreatorGuid = item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR);
+ ObjectGuid creatorGuid = item->GetUInt64Value(ITEM_FIELD_CREATOR);
+
+ bitData.WriteBit(giftCreatorGuid[7]);
+ bitData.WriteBit(giftCreatorGuid[1]);
+ bool notWrapped = bitData.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED));
+ bitData.WriteBit(giftCreatorGuid[3]);
+
+ if (notWrapped)
{
- for (uint8 j = 0; j < 18; ++j)
- data << uint32(0);
+ bitData.WriteBit(creatorGuid[7]);
+ bitData.WriteBit(creatorGuid[1]);
+ bitData.WriteBit(creatorGuid[4]);
+ bitData.WriteBit(creatorGuid[6]);
+ bitData.WriteBit(creatorGuid[2]);
+ bitData.WriteBit(creatorGuid[3]);
+ bitData.WriteBit(creatorGuid[5]);
+ bitData.WriteBit(item->GetTemplate()->LockID != 0);
+ bitData.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(0); // reforge id, FIXME: not implemented
+ 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]);
}
+
+ bitData.WriteBit(giftCreatorGuid[6]);
+ bitData.WriteBit(giftCreatorGuid[4]);
+ bitData.WriteBit(giftCreatorGuid[2]);
+ bitData.WriteBit(giftCreatorGuid[0]);
+ bitData.WriteBit(giftCreatorGuid[5]);
+
+ itemData.WriteByteSeq(giftCreatorGuid[6]);
+ itemData.WriteByteSeq(giftCreatorGuid[1]);
+ itemData.WriteByteSeq(giftCreatorGuid[7]);
+ itemData.WriteByteSeq(giftCreatorGuid[4]);
+
+ itemData << uint32(item->GetTemplate()->ItemId);
+
+ itemData.WriteByteSeq(giftCreatorGuid[0]);
+
+ itemData << uint32(item->GetCount());
+
+ itemData.WriteByteSeq(giftCreatorGuid[5]);
+
+ itemData << uint8(i);
+
+ itemData.WriteByteSeq(giftCreatorGuid[2]);
+ itemData.WriteByteSeq(giftCreatorGuid[3]);
}
+
+ data.WriteBits(count, 22);
+ data.FlushBits();
+ data.append(bitData);
+ data.FlushBits();
+ data.append(itemData);
+
SendPacket(&data);
}
@@ -665,9 +721,30 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
_player->m_trade = new TradeData(_player, pOther);
pOther->m_trade = new TradeData(pOther, _player);
- WorldPacket data(SMSG_TRADE_STATUS, 12);
- data << uint32(TRADE_STATUS_BEGIN_TRADE);
- data << uint64(_player->GetGUID());
+ WorldPacket data(SMSG_TRADE_STATUS, 2+7);
+ data.WriteBit(0); // unk bit, usually 0
+ data.WriteBits(TRADE_STATUS_BEGIN_TRADE, 5);
+
+ ObjectGuid playerGuid = _player->GetGUID();
+ // WTB StartBitStream...
+ data.WriteBit(playerGuid[2]);
+ data.WriteBit(playerGuid[4]);
+ data.WriteBit(playerGuid[6]);
+ data.WriteBit(playerGuid[0]);
+ data.WriteBit(playerGuid[1]);
+ data.WriteBit(playerGuid[3]);
+ data.WriteBit(playerGuid[7]);
+ data.WriteBit(playerGuid[5]);
+
+ data.WriteByteSeq(playerGuid[4]);
+ data.WriteByteSeq(playerGuid[1]);
+ data.WriteByteSeq(playerGuid[2]);
+ data.WriteByteSeq(playerGuid[3]);
+ data.WriteByteSeq(playerGuid[0]);
+ data.WriteByteSeq(playerGuid[7]);
+ data.WriteByteSeq(playerGuid[6]);
+ data.WriteByteSeq(playerGuid[5]);
+
pOther->GetSession()->SendPacket(&data);
}