diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index 9b38fcc19..15cf25996 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -345,18 +345,18 @@ void InitializeOpcodes() OPCODE(SMSG_OPEN_CONTAINER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode ); //OPCODE(SMSG_INSPECT_RESULTS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode ); - //OPCODE(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode ); - //OPCODE(CMSG_BUSY_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode ); - //OPCODE(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode ); - //OPCODE(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode ); - //OPCODE(CMSG_UNACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode ); - //OPCODE(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode); - //OPCODE(CMSG_SET_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode ); - //OPCODE(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode ); - //OPCODE(CMSG_SET_TRADE_GOLD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode ); - //OPCODE(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + OPCODE(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode ); + OPCODE(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode ); + OPCODE(CMSG_BUSY_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode ); + OPCODE(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode ); + OPCODE(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode ); + OPCODE(CMSG_UNACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode ); + OPCODE(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode); + OPCODE(CMSG_SET_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode ); + OPCODE(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode ); + OPCODE(CMSG_SET_TRADE_GOLD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode ); + OPCODE(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + OPCODE(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_SET_FACTION_VISIBLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_SET_FACTION_STANDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index d77b939d1..ffe0a646c 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -330,18 +330,18 @@ enum Opcodes SMSG_OPEN_CONTAINER = 0x4714, // 4.3.4 15595 CMSG_INSPECT = 0x0927, // 4.3.4 15595 SMSG_INSPECT_RESULTS_UPDATE = 0x1116, - CMSG_INITIATE_TRADE = 0x1117, - CMSG_BEGIN_TRADE = 0x1118, - CMSG_BUSY_TRADE = 0x1119, - CMSG_IGNORE_TRADE = 0x111A, - CMSG_ACCEPT_TRADE = 0x111B, - CMSG_UNACCEPT_TRADE = 0x111C, - CMSG_CANCEL_TRADE = 0x111D, - CMSG_SET_TRADE_ITEM = 0x111E, - CMSG_CLEAR_TRADE_ITEM = 0x111F, - CMSG_SET_TRADE_GOLD = 0x1120, - SMSG_TRADE_STATUS = 0x1121, - SMSG_TRADE_STATUS_EXTENDED = 0x1122, + CMSG_INITIATE_TRADE = 0x7916, // 4.3.4 15595 + CMSG_BEGIN_TRADE = 0x721E, // 4.3.4 15595 + CMSG_BUSY_TRADE = 0x331C, // 4.3.4 15595 + CMSG_IGNORE_TRADE = 0x7112, // 4.3.4 15595 + CMSG_ACCEPT_TRADE = 0x7110, // 4.3.4 15595 + CMSG_UNACCEPT_TRADE = 0x391A, // 4.3.4 15595 + CMSG_CANCEL_TRADE = 0x731E, // 4.3.4 15595 + CMSG_SET_TRADE_ITEM = 0x7B0C, // 4.3.4 15595 + CMSG_CLEAR_TRADE_ITEM = 0x7018, // 4.3.4 15595 + CMSG_SET_TRADE_GOLD = 0x3008, // 4.3.4 15595 + SMSG_TRADE_STATUS = 0x5CA3, // 4.3.4 15595 + SMSG_TRADE_STATUS_EXTENDED = 0x70A2, // 4.3.4 15595 SMSG_INITIALIZE_FACTIONS = 0x4634, // 4.3.4 15595 SMSG_SET_FACTION_VISIBLE = 0x1124, SMSG_SET_FACTION_STANDING = 0x1125, diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a93a72b15..9d8d9a5da 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -350,7 +350,7 @@ void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/) Update(false); // send spell info to caster self } -void TradeData::SetMoney(uint32 money) +void TradeData::SetMoney(uint64 money) { if (m_money == money) return; diff --git a/src/game/Player.h b/src/game/Player.h index 61fe69f90..c0830ba41 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1002,7 +1002,7 @@ class TradeData Item* GetSpellCastItem() const; bool HasSpellCastItem() const { return !m_spellCastItem.IsEmpty(); } - uint32 GetMoney() const { return m_money; } + uint64 GetMoney() const { return m_money; } bool IsAccepted() const { return m_accepted; } bool IsInAcceptProcess() const { return m_acceptProccess; } @@ -1010,7 +1010,7 @@ class TradeData void SetItem(TradeSlots slot, Item* item); void SetSpell(uint32 spell_id, Item* castItem = NULL); - void SetMoney(uint32 money); + void SetMoney(uint64 money); void SetAccepted(bool state, bool crosssend = false); @@ -1029,7 +1029,7 @@ class TradeData bool m_accepted; // m_player press accept for trade list bool m_acceptProccess; // one from player/trader press accept and this processed - uint32 m_money; // m_player place money to trade + uint64 m_money; // m_player place money to trade uint32 m_spell; // m_player apply spell to non-traded slot item ObjectGuid m_spellCastItem; // applied spell casted by item use @@ -1515,7 +1515,7 @@ class MANGOS_DLL_SPEC Player : public Unit void setRegenTimer(uint32 time) {m_regenTimer = time;} void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;} - uint32 GetMoney() const { return GetUInt32Value(PLAYER_FIELD_COINAGE); } + uint64 GetMoney() const { return GetUInt64Value(PLAYER_FIELD_COINAGE); } void ModifyMoney(int32 d) { if (d < 0) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index fe9945e41..0f1c217c6 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -3139,29 +3139,31 @@ enum TotemSlot 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_OPEN_WINDOW = 0, + //TRADE_STATUS_TRADE_CANCELED_NO_REPORT = 1, + TRADE_STATUS_NOT_ON_TAPLIST = 2, // You may only trade bound items to players that were originally eligible to loot them + 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, + TRADE_STATUS_TRADE_COMPLETE = 9, + //TRADE_STATUS_TRIAL_ACCOUNT = 10, // Trial accounts can not perform that action + TRADE_STATUS_BEGIN_TRADE = 12, + TRADE_STATUS_YOU_DEAD = 13, + TRADE_STATUS_TARGET_TO_FAR = 16, + TRADE_STATUS_NO_TARGET = 17, + //TRADE_STATUS_BUSY_2 = 18, + TRADE_STATUS_CURRENCY_NOT_TRADEABLE = 19, // guessed + TRADE_STATUS_WRONG_FACTION = 20, + TRADE_STATUS_BUSY = 21, + TRADE_STATUS_TRADE_CANCELED = 23, + TRADE_STATUS_CLOSE_WINDOW = 24, // guessed + TRADE_STATUS_BACK_TO_TRADE = 25, + TRADE_STATUS_ONLY_CONJURED = 26, // You can only trade conjured items to players from other realms + TRADE_STATUS_YOU_STUNNED = 27, + TRADE_STATUS_TARGET_STUNNED = 29, + // item related = 31 // closes trade }; enum EncounterCreditType diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp index 6e8a7c170..c94828133 100644 --- a/src/game/TradeHandler.cpp +++ b/src/game/TradeHandler.cpp @@ -32,35 +32,45 @@ void WorldSession::SendTradeStatus(TradeStatus status) { - WorldPacket data; + WorldPacket data(SMSG_TRADE_STATUS, 4 + 8); - switch (status) + data.WriteBit(false); + data.WriteBits(status, 5); + + switch(status) { - case TRADE_STATUS_BEGIN_TRADE: - data.Initialize(SMSG_TRADE_STATUS, 4 + 8); - data << uint32(status); - data << uint64(0); - break; case TRADE_STATUS_OPEN_WINDOW: - data.Initialize(SMSG_TRADE_STATUS, 4 + 4); - data << uint32(status); - data << uint32(0); // added in 2.4.0 - 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); break; + } + case TRADE_STATUS_NOT_ON_TAPLIST: case TRADE_STATUS_ONLY_CONJURED: - data.Initialize(SMSG_TRADE_STATUS, 4 + 1); - data << uint32(status); + { data << uint8(0); break; + } + case TRADE_STATUS_BEGIN_TRADE: + { + data.WriteGuidMask<2, 4, 6, 0, 1, 3, 7, 5>(ObjectGuid()); + data.WriteGuidBytes<4, 1, 2, 3, 0, 7, 6, 5>(ObjectGuid()); + break; + } + case TRADE_STATUS_CURRENCY_NOT_TRADEABLE: + case TRADE_STATUS_CLOSE_WINDOW: + { + data << uint32(0); + data << uint32(0); + break; + } + case 31: + { + data.WriteBit(false); + data << uint32(0); + data << uint32(0); + break; + } default: - data.Initialize(SMSG_TRADE_STATUS, 4); - data << uint32(status); break; } @@ -84,46 +94,78 @@ void WorldSession::SendUpdateTrade(bool trader_state /*= true*/) TradeData* view_trade = trader_state ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData(); WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100)); // guess size - data << uint8(trader_state ? 1 : 0); // send trader or own trade windows state (last need for proper show spell apply to non-trade slot) 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(view_trade->GetMoney()); // trader gold + 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? + data << uint32(0); // unk 5 + data << uint8(trader_state ? 1 : 0); // send trader or own trade windows state (last need for proper show spell apply to non-trade slot) + data << uint32(TRADE_SLOT_COUNT); // trade slots count/number? + + uint8 itemCount = 0; + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (Item* item = view_trade->GetItem(TradeSlots(i))) + ++itemCount; + + data.WriteBits(itemCount, 22); for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) { - data << uint8(i); // trade slot number, if not specified, then end of packet - if (Item* item = view_trade->GetItem(TradeSlots(i))) { - data << uint32(item->GetProto()->ItemId); // entry - data << uint32(item->GetProto()->DisplayInfoID);// display id - data << uint32(item->GetCount()); // stack count - // wrapped: hide stats but show giftcreator name - data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED) ? 1 : 0); - data << item->GetGuidValue(ITEM_FIELD_GIFTCREATOR); + ObjectGuid creatorGuid = item->GetGuidValue(ITEM_FIELD_CREATOR); + ObjectGuid giftCreatorGuid = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR); - 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 << item->GetGuidValue(ITEM_FIELD_CREATOR); - data << uint32(item->GetSpellCharges()); // charges - data << uint32(item->GetItemSuffixFactor()); // SuffixFactor - data << uint32(item->GetItemRandomPropertyId());// random properties id - data << uint32(item->GetProto()->LockID); // lock id - // max durability - data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); - // durability - data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); - } - else - { - for (uint8 j = 0; j < 18; ++j) - data << uint32(0); + data.WriteGuidMask<7, 1>(giftCreatorGuid); + data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)); + data.WriteGuidMask<3>(giftCreatorGuid); + if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) + { + data.WriteGuidMask<7, 1, 4, 6, 2, 3, 5>(creatorGuid); + data.WriteBit(item->GetProto()->LockID && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_UNLOCKED)); + data.WriteGuidMask<0>(creatorGuid); + } + data.WriteGuidMask<6, 4, 2, 0, 5>(giftCreatorGuid); } } + + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + { + if (Item* item = view_trade->GetItem(TradeSlots(i))) + { + ObjectGuid creatorGuid = item->GetGuidValue(ITEM_FIELD_CREATOR); + ObjectGuid giftCreatorGuid = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR); + + if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) + { + data.WriteGuidBytes<1>(creatorGuid); + 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))); + data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); + data.WriteGuidBytes<6, 2, 7, 4>(creatorGuid); + data << uint32(0); // reforge Id + data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); + data << uint32(item->GetItemRandomPropertyId()); + data.WriteGuidBytes<3>(creatorGuid); + data << uint32(0); // unk + data.WriteGuidBytes<0>(creatorGuid); + data << uint32(item->GetSpellCharges()); // charges + data << uint32(item->GetItemSuffixFactor()); + data.WriteGuidBytes<5>(creatorGuid); + } + + data.WriteGuidBytes<6, 1, 7, 4>(giftCreatorGuid); + data << uint32(item->GetProto()->ItemId); // entry + data.WriteGuidBytes<0>(giftCreatorGuid); + data << uint32(item->GetCount()); // stack count + data.WriteGuidBytes<5>(giftCreatorGuid); + data << uint8(i); // slot id + data.WriteGuidBytes<2, 3>(giftCreatorGuid); + } + } + SendPacket(&data); } @@ -531,7 +573,8 @@ void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { ObjectGuid otherGuid; - recvPacket >> otherGuid; + recvPacket.ReadGuidMask<0, 3, 5, 1, 4, 6, 7, 2>(otherGuid); + recvPacket.ReadGuidBytes<7, 4, 3, 5, 1, 2, 6, 0>(otherGuid); if (GetPlayer()->m_trade) return; @@ -621,14 +664,18 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) pOther->m_trade = new TradeData(pOther, _player); WorldPacket data(SMSG_TRADE_STATUS, 12); - data << uint32(TRADE_STATUS_BEGIN_TRADE); - data << ObjectGuid(_player->GetObjectGuid()); + data.WriteBit(false); + data.WriteBits(TRADE_STATUS_BEGIN_TRADE, 5); + data.WriteGuidMask<2, 4, 6, 0, 1, 3, 7, 5>(_player->GetObjectGuid()); + data.WriteGuidBytes<4, 1, 2, 3, 0, 7, 6, 5>(_player->GetObjectGuid()); + data << uint32(0); + pOther->GetSession()->SendPacket(&data); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) { - uint32 gold; + uint64 gold; recvPacket >> gold; @@ -647,9 +694,9 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) uint8 bag; uint8 slot; + recvPacket >> slot; recvPacket >> tradeSlot; recvPacket >> bag; - recvPacket >> slot; TradeData* my_trade = _player->m_trade; if (!my_trade) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 17a35ec52..ae1004ccb 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12174" + #define REVISION_NR "12175" #endif // __REVISION_NR_H__