From 5fa5020af5686dcfe89d952ddcc3a1cd34d09bb2 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 14 Mar 2026 07:11:18 -0700 Subject: [PATCH] fix(mail): use attachment item guid for WotLK take item --- include/game/game_handler.hpp | 2 +- include/game/packet_parsers.hpp | 6 +++--- include/game/world_packets.hpp | 2 +- src/game/game_handler.cpp | 4 ++-- src/game/world_packets.cpp | 5 +++-- src/ui/game_screen.cpp | 4 ++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 7ce07326..2513083f 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1978,7 +1978,7 @@ public: const std::array& getMailAttachments() const { return mailAttachments_; } int getMailAttachmentCount() const; void mailTakeMoney(uint32_t mailId); - void mailTakeItem(uint32_t mailId, uint32_t itemIndex); + void mailTakeItem(uint32_t mailId, uint32_t itemGuidLow); void mailDelete(uint32_t mailId); void mailMarkAsRead(uint32_t mailId); void refreshMailList(); diff --git a/include/game/packet_parsers.hpp b/include/game/packet_parsers.hpp index 40655045..38560cc7 100644 --- a/include/game/packet_parsers.hpp +++ b/include/game/packet_parsers.hpp @@ -266,8 +266,8 @@ public: virtual bool parseMailList(network::Packet& packet, std::vector& inbox); /** Build CMSG_MAIL_TAKE_ITEM */ - virtual network::Packet buildMailTakeItem(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemSlot) { - return MailTakeItemPacket::build(mailboxGuid, mailId, itemSlot); + virtual network::Packet buildMailTakeItem(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemGuidLow) { + return MailTakeItemPacket::build(mailboxGuid, mailId, itemGuidLow); } /** Build CMSG_MAIL_DELETE */ @@ -404,7 +404,7 @@ public: uint32_t money, uint32_t cod, const std::vector& itemGuids = {}) override; bool parseMailList(network::Packet& packet, std::vector& inbox) override; - network::Packet buildMailTakeItem(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemSlot) override; + network::Packet buildMailTakeItem(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemGuidLow) override; network::Packet buildMailDelete(uint64_t mailboxGuid, uint32_t mailId, uint32_t mailTemplateId) override; network::Packet buildItemQuery(uint32_t entry, uint64_t guid) override; bool parseItemQueryResponse(network::Packet& packet, ItemQueryResponseData& data) override; diff --git a/include/game/world_packets.hpp b/include/game/world_packets.hpp index 61266b2f..15b8f8ff 100644 --- a/include/game/world_packets.hpp +++ b/include/game/world_packets.hpp @@ -2517,7 +2517,7 @@ public: /** CMSG_MAIL_TAKE_ITEM packet builder */ class MailTakeItemPacket { public: - static network::Packet build(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemIndex); + static network::Packet build(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemGuidLow); }; /** CMSG_MAIL_DELETE packet builder */ diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index caf67b73..ae28aad7 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -22136,9 +22136,9 @@ void GameHandler::mailTakeMoney(uint32_t mailId) { socket->send(packet); } -void GameHandler::mailTakeItem(uint32_t mailId, uint32_t itemIndex) { +void GameHandler::mailTakeItem(uint32_t mailId, uint32_t itemGuidLow) { if (state != WorldState::IN_WORLD || !socket || mailboxGuid_ == 0) return; - auto packet = packetParsers_->buildMailTakeItem(mailboxGuid_, mailId, itemIndex); + auto packet = packetParsers_->buildMailTakeItem(mailboxGuid_, mailId, itemGuidLow); socket->send(packet); } diff --git a/src/game/world_packets.cpp b/src/game/world_packets.cpp index de9f1df4..398cfb2a 100644 --- a/src/game/world_packets.cpp +++ b/src/game/world_packets.cpp @@ -5069,11 +5069,12 @@ network::Packet MailTakeMoneyPacket::build(uint64_t mailboxGuid, uint32_t mailId return packet; } -network::Packet MailTakeItemPacket::build(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemIndex) { +network::Packet MailTakeItemPacket::build(uint64_t mailboxGuid, uint32_t mailId, uint32_t itemGuidLow) { network::Packet packet(wireOpcode(Opcode::CMSG_MAIL_TAKE_ITEM)); packet.writeUInt64(mailboxGuid); packet.writeUInt32(mailId); - packet.writeUInt32(itemIndex); + // WotLK expects attachment item GUID low, not attachment slot index. + packet.writeUInt32(itemGuidLow); return packet; } diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 18860f94..77d136ec 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -17716,7 +17716,7 @@ void GameScreen::renderMailWindow(game::GameHandler& gameHandler) { } ImGui::SameLine(); if (ImGui::SmallButton("Take")) { - gameHandler.mailTakeItem(mail.messageId, att.slot); + gameHandler.mailTakeItem(mail.messageId, att.itemGuidLow); } ImGui::PopID(); @@ -17725,7 +17725,7 @@ void GameScreen::renderMailWindow(game::GameHandler& gameHandler) { if (mail.attachments.size() > 1) { if (ImGui::SmallButton("Take All")) { for (const auto& att2 : mail.attachments) { - gameHandler.mailTakeItem(mail.messageId, att2.slot); + gameHandler.mailTakeItem(mail.messageId, att2.itemGuidLow); } } }