diff options
author | Shauren <shauren.trinity@gmail.com> | 2013-03-15 20:09:48 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2013-03-15 20:09:48 +0100 |
commit | e58e05d9d5da894447b81ded17c3b8fd9f4820a8 (patch) | |
tree | e41b9ed702da6dc1063e8bddd0f270c2d47f0d7b /src/server/game/Handlers/TradeHandler.cpp | |
parent | 51b9e6d2c947d2151af09d7a25af45ff75b0d530 (diff) | |
parent | 11846f5990f5af421ff2fc087925245f61b4ac84 (diff) |
Merge branch '4.3.4' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src/server/game/Handlers/TradeHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/TradeHandler.cpp | 229 |
1 files changed, 164 insertions, 65 deletions
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 8155dacf1d8..aa41e3bb391 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -34,34 +34,38 @@ void WorldSession::SendTradeStatus(TradeStatus status) { WorldPacket data; + data.Initialize(SMSG_TRADE_STATUS, 1+4+4); + data.WriteBit(0); // unk bit, usually 0 + data.WriteBits(status, 5); + switch (status) { case TRADE_STATUS_BEGIN_TRADE: - data.Initialize(SMSG_TRADE_STATUS, 4+8); - data << uint32(status); - data << uint64(0); + data.WriteBits(0, 8); // zero guid + data.FlushBits(); 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.FlushBits(); + 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.FlushBits(); + 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.FlushBits(); + data << uint8(0); // unk break; + case TRADE_STATUS_CURRENCY: // Not implemented + case TRADE_STATUS_CURRENCY_NOT_TRADABLE: // Not implemented + data.FlushBits(); + data << uint32(0); // unk + data << uint32(0); // unk default: - data.Initialize(SMSG_TRADE_STATUS, 4); - data << uint32(status); + data.FlushBits(); break; } @@ -71,60 +75,117 @@ 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*/) { 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?) + 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_STATUS_EXTENDED, 4*6 + 8 + 1 + 3 + count * 70); + 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 << 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 << uint32(view_trade->GetMoney()); // trader gold - data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item + data.WriteBits(count, 22); 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; - 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); + + 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) { - for (uint8 j = 0; j < 18; ++j) - data << uint32(0); + 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()->LockID != 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(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]); } + + 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()->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.FlushBits(); + data.append(itemData); + SendPacket(&data); } @@ -292,14 +353,14 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) return; } - if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney()) + if (_player->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - his_trade->GetMoney()) { _player->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); my_trade->SetAccepted(false, true); return; } - if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney()) + if (trader->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - my_trade->GetMoney()) { trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); his_trade->SetAccepted(false, true); @@ -477,7 +538,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { if (my_trade->GetMoney() > 0) { - sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", + sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: " UI64FMTD ") to player: %s (Account: %u)", _player->GetName().c_str(), _player->GetSession()->GetAccountId(), my_trade->GetMoney(), trader->GetName().c_str(), trader->GetSession()->GetAccountId()); @@ -485,7 +546,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) if (his_trade->GetMoney() > 0) { - sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", + sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: " UI64FMTD ") to player: %s (Account: %u)", trader->GetName().c_str(), trader->GetSession()->GetAccountId(), his_trade->GetMoney(), _player->GetName().c_str(), _player->GetSession()->GetAccountId()); @@ -493,9 +554,9 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) } // update money - _player->ModifyMoney(-int32(my_trade->GetMoney())); + _player->ModifyMoney(-int64(my_trade->GetMoney())); _player->ModifyMoney(his_trade->GetMoney()); - trader->ModifyMoney(-int32(his_trade->GetMoney())); + trader->ModifyMoney(-int64(his_trade->GetMoney())); trader->ModifyMoney(my_trade->GetMoney()); if (my_spell) @@ -555,15 +616,32 @@ void WorldSession::SendCancelTrade() void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) { - // sended also after LOGOUT COMPLETE + // sent also after LOGOUT COMPLETE if (_player) // needed because STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT _player->TradeCancel(true); } void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { - uint64 ID; - recvPacket >> ID; + 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; @@ -598,7 +676,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) return; } - Player* pOther = ObjectAccessor::FindPlayer(ID); + Player* pOther = ObjectAccessor::FindPlayer(guid); if (!pOther) { @@ -664,15 +742,36 @@ 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); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) { - uint32 gold; + uint64 gold; recvPacket >> gold; TradeData* my_trade = _player->GetTradeData(); @@ -690,9 +789,9 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) uint8 bag; uint8 slot; + recvPacket >> slot; recvPacket >> tradeSlot; recvPacket >> bag; - recvPacket >> slot; TradeData* my_trade = _player->GetTradeData(); if (!my_trade) |