diff options
author | Nay <dnpd.dd@gmail.com> | 2012-07-26 01:56:30 +0100 |
---|---|---|
committer | Nay <dnpd.dd@gmail.com> | 2012-07-26 01:56:30 +0100 |
commit | c6352171d7fce7908739e7d2b007d618126c840d (patch) | |
tree | e7e04b5ea3ff4c7f91715333e58b2917f74d5738 /src | |
parent | 32d17722d8be90f1e1f8addddd2d568df69ca9df (diff) |
Core/Player&PacketIO: Fix trading
Update some trade related packet structures
Enable missing trade opcode
Update TradeStatus enum
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Entities/Player/Player.h | 2 | ||||
-rwxr-xr-x | src/server/game/Handlers/TradeHandler.cpp | 181 | ||||
-rwxr-xr-x | src/server/game/Miscellaneous/SharedDefines.h | 56 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 6 |
4 files changed, 165 insertions, 80 deletions
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ded63b024b8..aba570c1d37 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1026,7 +1026,7 @@ class TradeData uint32 m_spell; // m_player apply spell to non-traded slot item uint64 m_spellCastItem; // applied spell casted by item use - uint64 m_items[TRADE_SLOT_COUNT]; // traded itmes from m_player side including non-traded slot + uint64 m_items[TRADE_SLOT_COUNT]; // traded items from m_player side including non-traded slot }; class KillRewarder 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); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 987876dd5e5..0b3dc884a1a 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3499,30 +3499,38 @@ enum SpellFamilyNames enum TradeStatus { - TRADE_STATUS_BUSY = 0, - TRADE_STATUS_BEGIN_TRADE = 1, - TRADE_STATUS_OPEN_WINDOW = 2, - TRADE_STATUS_TRADE_CANCELED = 3, - TRADE_STATUS_TRADE_ACCEPT = 4, - TRADE_STATUS_BUSY_2 = 5, - TRADE_STATUS_NO_TARGET = 6, - TRADE_STATUS_BACK_TO_TRADE = 7, - TRADE_STATUS_TRADE_COMPLETE = 8, - // 9? - TRADE_STATUS_TARGET_TO_FAR = 10, - TRADE_STATUS_WRONG_FACTION = 11, - TRADE_STATUS_CLOSE_WINDOW = 12, - // 13? - TRADE_STATUS_IGNORE_YOU = 14, - TRADE_STATUS_YOU_STUNNED = 15, - TRADE_STATUS_TARGET_STUNNED = 16, - TRADE_STATUS_YOU_DEAD = 17, - TRADE_STATUS_TARGET_DEAD = 18, - TRADE_STATUS_YOU_LOGOUT = 19, - TRADE_STATUS_TARGET_LOGOUT = 20, - TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action - TRADE_STATUS_ONLY_CONJURED = 22, // You can only trade conjured items... (cross realm BG related). - TRADE_STATUS_NOT_ELIGIBLE = 23 // Related to trading soulbound loot items + TRADE_STATUS_OPEN_WINDOW = 0, + // 1 - Related to EVENT_PLAYER_MONEY + TRADE_STATUS_NOT_ELIGIBLE = 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_ONLY_CONJURED = 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, }; enum XPColorChar diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index d2b18844242..301ebb12221 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -352,7 +352,7 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_KNOCKBACK_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_REQUIREMENTS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode ); DEFINE_OPCODE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode ); //DEFINE_OPCODE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode ); //DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse ); @@ -1349,8 +1349,8 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_TOGGLE_XP_GAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); |