diff options
| author | Shauren <shauren.trinity@gmail.com> | 2020-09-27 15:29:05 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2020-09-27 15:29:32 +0200 |
| commit | 93f6e7431a73acc2047739ddf6ec006f9ccb59ec (patch) | |
| tree | 4f37410e3d5e7c3e57b97eda4865730eadc60c63 /src/server/game/Server | |
| parent | 24c798ddaceac603901e5fa9dec96a276166cb5b (diff) | |
Core/PacketIO: Convert mail packets to classes
Diffstat (limited to 'src/server/game/Server')
| -rw-r--r-- | src/server/game/Server/Packets/AllPackets.h | 1 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/MailPackets.cpp | 300 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/MailPackets.h | 269 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.h | 40 |
4 files changed, 598 insertions, 12 deletions
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 1b3d2006854..12f1fb37973 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -26,6 +26,7 @@ #include "GuildPackets.h" #include "LFGPackets.h" #include "NPCPackets.h" +#include "MailPackets.h" #include "MiscPackets.h" #include "PetPackets.h" #include "QueryPackets.h" diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp new file mode 100644 index 00000000000..ffb85167ead --- /dev/null +++ b/src/server/game/Server/Packets/MailPackets.cpp @@ -0,0 +1,300 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "MailPackets.h" +#include "Item.h" +#include "Mail.h" +#include "Player.h" +#include "World.h" + +WorldPackets::Mail::MailAttachedItem::MailAttachedItem(::Item const* item, uint8 pos) +{ + Position = pos; + AttachID = item->GetGUID().GetCounter(); + ItemID = item->GetEntry(); + RandomPropertiesID = item->GetItemRandomPropertyId(); + RandomPropertiesSeed = item->GetItemSuffixFactor(); + Count = item->GetCount(); + Charges = item->GetSpellCharges(); + MaxDurability = item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); + Durability = item->GetInt32Value(ITEM_FIELD_DURABILITY); + Unlocked = !item->IsLocked(); + + for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; j++) + { + EnchantmentSlot slot = EnchantmentSlot(j); + EnchantmentID[slot] = item->GetEnchantmentId(slot); + EnchantmentDuration[slot] = item->GetEnchantmentDuration(slot); + EnchantmentCharges[slot] = item->GetEnchantmentCharges(slot); + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailAttachedItem const& att) +{ + data << uint8(att.Position); + data << int32(att.AttachID); + data << int32(att.ItemID); + for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) + { + data << int32(att.EnchantmentID[i]); + data << int32(att.EnchantmentDuration[i]); + data << int32(att.EnchantmentCharges[i]); + } + data << int32(att.RandomPropertiesID); + data << int32(att.RandomPropertiesSeed); + data << int32(att.Count); + data << int32(att.Charges); + data << uint32(att.MaxDurability); + data << int32(att.Durability); + data << bool(att.Unlocked); + + return data; +} + +WorldPackets::Mail::MailListEntry::MailListEntry(::Mail const* mail, ::Player* player) +{ + MailID = mail->messageID; + SenderType = mail->messageType; + + switch (mail->messageType) + { + case MAIL_NORMAL: + SenderCharacter = ObjectGuid::Create<HighGuid::Player>(mail->sender); + break; + case MAIL_CREATURE: + case MAIL_GAMEOBJECT: + case MAIL_AUCTION: + case MAIL_CALENDAR: + AltSenderID = mail->sender; + break; + } + + Cod = mail->COD; + StationeryID = mail->stationery; + SentMoney = mail->money; + Flags = mail->checked; + DaysLeft = float(mail->expire_time - time(nullptr)) / DAY; + MailTemplateID = mail->mailTemplateId; + Subject = mail->subject; + Body = mail->body; + + for (uint8 i = 0; i < mail->items.size(); i++) + if (::Item* item = player->GetMItem(mail->items[i].item_guid)) + Attachments.emplace_back(item, i); +} + +std::size_t WorldPackets::Mail::MailListEntry::GetPacketSize() const +{ + return sizeof(uint16) + sizeof(int32) + sizeof(uint8) + (SenderCharacter ? sizeof(uint64) : 0) + (AltSenderID ? sizeof(int32) : 0) + + sizeof(uint32) + sizeof(int32) + sizeof(int32) + sizeof(uint32) + sizeof(int32) + sizeof(float) + sizeof(int32) + + Subject.length() + 1 + Body.length() + 1 + sizeof(uint8) + Attachments.size() * MailAttachedItem::GetPacketSize(); +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailListEntry const& entry) +{ + data << uint16(entry.GetPacketSize()); + data << int32(entry.MailID); + data << uint8(entry.SenderType); + if (entry.SenderCharacter) + data << *entry.SenderCharacter; + else if (entry.AltSenderID) + data << int32(*entry.AltSenderID); + + data << uint32(entry.Cod); + data << int32(entry.PackageID); + data << int32(entry.StationeryID); + data << uint32(entry.SentMoney); + data << int32(entry.Flags); + data << float(entry.DaysLeft); + data << int32(entry.MailTemplateID); + data << entry.Subject; + data << entry.Body; + data << uint8(entry.Attachments.size()); + + for (WorldPackets::Mail::MailAttachedItem const& att : entry.Attachments) + data << att; + + return data; +} + +void WorldPackets::Mail::MailGetList::Read() +{ + _worldPacket >> Mailbox; +} + +WorldPackets::Mail::MailListResult::MailListResult() : ServerPacket(SMSG_MAIL_LIST_RESULT, 8) +{ + _worldPacket << int32(0); // TotalNumRecords + _worldPacket << uint8(0); // Mails.size() +} + +WorldPacket const* WorldPackets::Mail::MailListResult::Write() +{ + _worldPacket.put<int32>(0, TotalNumRecords); + _worldPacket.put<uint8>(4, Mails.size()); + + return &_worldPacket; +} + +void WorldPackets::Mail::MailListResult::AddMail(::Mail const* mail, Player* player) +{ + ++TotalNumRecords; + if (Mails.size() >= 50 || _maxPacketSizeReached) + return; + + MailListEntry packetEntry(mail, player); + if (_worldPacket.size() + packetEntry.GetPacketSize() >= std::numeric_limits<int16>::max()) + { + _maxPacketSizeReached = true; + return; + } + + _worldPacket << Mails.emplace_back(std::move(packetEntry)); +} + +void WorldPackets::Mail::MailCreateTextItem::Read() +{ + _worldPacket >> Mailbox; + _worldPacket >> MailID; +} + +void WorldPackets::Mail::SendMail::Read() +{ + _worldPacket >> Info.Mailbox; + _worldPacket >> Info.Target; + _worldPacket >> Info.Subject; + _worldPacket >> Info.Body; + _worldPacket >> Info.StationeryID; + _worldPacket >> Info.PackageID; + Info.Attachments.resize(_worldPacket.read<uint8>()); + + for (auto& att : Info.Attachments) + { + _worldPacket >> att.AttachPosition; + _worldPacket >> att.ItemGUID; + } + + _worldPacket >> Info.SendMoney; + _worldPacket >> Info.Cod; + _worldPacket.read_skip<uint64>(); + _worldPacket.read_skip<uint8>(); +} + +void WorldPackets::Mail::MailReturnToSender::Read() +{ + _worldPacket >> Mailbox; + _worldPacket >> MailID; + _worldPacket >> SenderGUID; +} + +WorldPacket const* WorldPackets::Mail::MailCommandResult::Write() +{ + _worldPacket << uint32(MailID); + _worldPacket << uint32(Command); + _worldPacket << uint32(ErrorCode); + + if (ErrorCode == MAIL_ERR_EQUIP_ERROR) + _worldPacket << uint32(BagResult); + + if (Command == MAIL_ITEM_TAKEN) + { + if (ErrorCode == MAIL_OK || ErrorCode == MAIL_ERR_ITEM_HAS_EXPIRED) + { + _worldPacket << uint32(AttachID); + _worldPacket << uint32(QtyInInventory); + } + } + + return &_worldPacket; +} + +void WorldPackets::Mail::MailMarkAsRead::Read() +{ + _worldPacket >> Mailbox; + _worldPacket >> MailID; +} + +void WorldPackets::Mail::MailDelete::Read() +{ + _worldPacket >> Mailbox; + _worldPacket >> MailID; + _worldPacket >> DeleteReason; +} + +void WorldPackets::Mail::MailTakeItem::Read() +{ + _worldPacket >> Mailbox; + _worldPacket >> MailID; + _worldPacket >> AttachID; +} + +void WorldPackets::Mail::MailTakeMoney::Read() +{ + _worldPacket >> Mailbox; + _worldPacket >> MailID; +} + +WorldPackets::Mail::MailQueryNextTimeResult::MailNextTimeEntry::MailNextTimeEntry(::Mail const* mail) +{ + switch (mail->messageType) + { + case MAIL_NORMAL: + SenderGuid = ObjectGuid::Create<HighGuid::Player>(mail->sender); + break; + case MAIL_AUCTION: + case MAIL_CREATURE: + case MAIL_GAMEOBJECT: + case MAIL_CALENDAR: + AltSenderID = mail->sender; + break; + } + + TimeLeft = mail->deliver_time - time(nullptr); + AltSenderType = mail->messageType; + StationeryID = mail->stationery; +} + +WorldPacket const* WorldPackets::Mail::MailQueryNextTimeResult::Write() +{ + _worldPacket << float(NextMailTime); + _worldPacket << int32(Next.size()); + + for (auto const& entry : Next) + { + _worldPacket << entry.SenderGuid; + _worldPacket << int32(entry.AltSenderID); + _worldPacket << int32(entry.AltSenderType); + _worldPacket << int32(entry.StationeryID); + _worldPacket << float(entry.TimeLeft); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Mail::NotifyReceivedMail::Write() +{ + _worldPacket << float(Delay); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Mail::ShowMailbox::Write() +{ + _worldPacket << PostmasterGUID; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MailPackets.h b/src/server/game/Server/Packets/MailPackets.h new file mode 100644 index 00000000000..855cb459ca6 --- /dev/null +++ b/src/server/game/Server/Packets/MailPackets.h @@ -0,0 +1,269 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MailPackets_h__ +#define MailPackets_h__ + +#include "Packet.h" +#include "ItemDefines.h" +#include "Mail.h" +#include "Optional.h" +#include "PacketUtilities.h" + +namespace WorldPackets +{ + namespace Mail + { + struct MailAttachedItem + { + MailAttachedItem(::Item const* item, uint8 pos); + + static constexpr std::size_t GetPacketSize() + { + return sizeof(uint8) + sizeof(int32) + sizeof(int32) + MAX_INSPECTED_ENCHANTMENT_SLOT * (sizeof(int32) + sizeof(int32) + sizeof(int32)) + + sizeof(int32) + sizeof(int32) + sizeof(int32) + sizeof(int32) + sizeof(uint32) + sizeof(int32) + sizeof(bool); + } + + uint8 Position = 0; + int32 AttachID = 0; + int32 ItemID = 0; + int32 RandomPropertiesSeed = 0; + int32 RandomPropertiesID = 0; + int32 Count = 0; + int32 Charges = 0; + uint32 MaxDurability = 0; + int32 Durability = 0; + bool Unlocked = false; + std::array<uint32, MAX_INSPECTED_ENCHANTMENT_SLOT> EnchantmentID = { }; + std::array<uint32, MAX_INSPECTED_ENCHANTMENT_SLOT> EnchantmentDuration = { }; + std::array<uint32, MAX_INSPECTED_ENCHANTMENT_SLOT> EnchantmentCharges = { }; + }; + + struct MailListEntry + { + MailListEntry(::Mail const* mail, ::Player* player); + + std::size_t GetPacketSize() const; + + int32 MailID = 0; + uint8 SenderType = 0; + Optional<ObjectGuid> SenderCharacter; + Optional<uint32> AltSenderID; + uint32 Cod = 0; + int32 PackageID = 0; + int32 StationeryID = 0; + uint32 SentMoney = 0; + int32 Flags = 0; + float DaysLeft = 0.0f; + int32 MailTemplateID = 0; + std::string_view Subject; + std::string_view Body; + std::vector<MailAttachedItem> Attachments; + }; + + class MailGetList final : public ClientPacket + { + public: + MailGetList(WorldPacket&& packet) : ClientPacket(CMSG_GET_MAIL_LIST, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + }; + + class MailListResult final : public ServerPacket + { + public: + MailListResult(); + + WorldPacket const* Write() override; + + void AddMail(::Mail const* mail, Player* player); + + int32 TotalNumRecords = 0; + std::vector<MailListEntry> Mails; + + private: + bool _maxPacketSizeReached = false; + }; + + class MailCreateTextItem final : public ClientPacket + { + public: + MailCreateTextItem(WorldPacket&& packet) : ClientPacket(CMSG_MAIL_CREATE_TEXT_ITEM, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + uint32 MailID = 0; + }; + + class SendMail final : public ClientPacket + { + public: + struct StructSendMail + { + struct MailAttachment + { + uint8 AttachPosition = 0; + ObjectGuid ItemGUID; + }; + + ObjectGuid Mailbox; + int32 StationeryID = 0; + int32 PackageID = 0; + int32 SendMoney = 0; + int32 Cod = 0; + std::string Target; + String<255, Strings::NoHyperlinks> Subject; + String<7999, Strings::NoHyperlinks> Body; + Array<MailAttachment, MAX_MAIL_ITEMS> Attachments; + }; + + SendMail(WorldPacket&& packet) : ClientPacket(CMSG_SEND_MAIL, std::move(packet)) { } + + void Read() override; + + StructSendMail Info; + }; + + class MailCommandResult final : public ServerPacket + { + public: + MailCommandResult() : ServerPacket(SMSG_SEND_MAIL_RESULT) { } + + WorldPacket const* Write() override; + + uint32 MailID = 0; + uint32 Command = 0; + uint32 ErrorCode = 0; + uint32 BagResult = 0; + uint32 AttachID = 0; + uint32 QtyInInventory = 0; + }; + + class MailReturnToSender final : public ClientPacket + { + public: + MailReturnToSender(WorldPacket&& packet) : ClientPacket(CMSG_MAIL_RETURN_TO_SENDER, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + int32 MailID = 0; + ObjectGuid SenderGUID; + }; + + class MailMarkAsRead final : public ClientPacket + { + public: + MailMarkAsRead(WorldPacket&& packet) : ClientPacket(CMSG_MAIL_MARK_AS_READ, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + int32 MailID = 0; + }; + + class MailDelete final : public ClientPacket + { + public: + MailDelete(WorldPacket&& packet) : ClientPacket(CMSG_MAIL_DELETE, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + int32 MailID = 0; + int32 DeleteReason = 0; + }; + + class MailTakeItem final : public ClientPacket + { + public: + MailTakeItem(WorldPacket&& packet) : ClientPacket(CMSG_MAIL_TAKE_ITEM, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + int32 MailID = 0; + int32 AttachID = 0; + }; + + class MailTakeMoney final : public ClientPacket + { + public: + MailTakeMoney(WorldPacket&& packet) : ClientPacket(CMSG_MAIL_TAKE_MONEY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Mailbox; + int32 MailID = 0; + }; + + class MailQueryNextMailTime final : public ClientPacket + { + public: + MailQueryNextMailTime(WorldPacket&& packet) : ClientPacket(MSG_QUERY_NEXT_MAIL_TIME, std::move(packet)) { } + + void Read() override { } + }; + + class MailQueryNextTimeResult final : public ServerPacket + { + public: + struct MailNextTimeEntry + { + MailNextTimeEntry(::Mail const* mail); + + ObjectGuid SenderGuid; + float TimeLeft = 0.0f; + int32 AltSenderID = 0; + int32 AltSenderType = 0; + int32 StationeryID = 0; + }; + + MailQueryNextTimeResult() : ServerPacket(MSG_QUERY_NEXT_MAIL_TIME, 8) { } + + WorldPacket const* Write() override; + + float NextMailTime = 0.0f; + std::vector<MailNextTimeEntry> Next; + }; + + class NotifyReceivedMail : ServerPacket + { + public: + NotifyReceivedMail() : ServerPacket(SMSG_RECEIVED_MAIL, 4) { } + + WorldPacket const* Write() override; + + float Delay = 0.0f; + }; + + class ShowMailbox final : public ServerPacket + { + public: + ShowMailbox() : ServerPacket(SMSG_SHOW_MAILBOX, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid PostmasterGUID; + }; + } +} + +#endif // MailPackets_h__ diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index e19c81b54db..1a3917dd325 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -142,16 +142,26 @@ namespace WorldPackets class GuildSetGuildMaster; class SaveGuildEmblem; } + namespace LFG { class LFGJoin; class LFGLeave; } - namespace NPC + + namespace Mail { - class Hello; - class TrainerBuySpell; + class MailCreateTextItem; + class MailDelete; + class MailGetList; + class MailMarkAsRead; + class MailQueryNextMailTime; + class MailReturnToSender; + class MailTakeItem; + class MailTakeMoney; + class SendMail; } + namespace Misc { class CompleteCinematic; @@ -166,6 +176,12 @@ namespace WorldPackets class ResurrectResponse; } + namespace NPC + { + class Hello; + class TrainerBuySpell; + } + namespace Pet { class DismissCritter; @@ -816,16 +832,16 @@ class TC_GAME_API WorldSession void HandleAutoStoreBankItemOpcode(WorldPackets::Bank::AutoStoreBankItem& packet); void HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& buyBankSlot); - void HandleGetMailList(WorldPacket& recvData); - void HandleSendMail(WorldPacket& recvData); - void HandleMailTakeMoney(WorldPacket& recvData); - void HandleMailTakeItem(WorldPacket& recvData); - void HandleMailMarkAsRead(WorldPacket& recvData); - void HandleMailReturnToSender(WorldPacket& recvData); - void HandleMailDelete(WorldPacket& recvData); + void HandleGetMailList(WorldPackets::Mail::MailGetList& getList); + void HandleSendMail(WorldPackets::Mail::SendMail& sendMail); + void HandleMailTakeMoney(WorldPackets::Mail::MailTakeMoney& takeMoney); + void HandleMailTakeItem(WorldPackets::Mail::MailTakeItem& takeItem); + void HandleMailMarkAsRead(WorldPackets::Mail::MailMarkAsRead& markAsRead); + void HandleMailReturnToSender(WorldPackets::Mail::MailReturnToSender& returnToSender); + void HandleMailDelete(WorldPackets::Mail::MailDelete& mailDelete); void HandleItemTextQuery(WorldPacket& recvData); - void HandleMailCreateTextItem(WorldPacket& recvData); - void HandleQueryNextMailTime(WorldPacket& recvData); + void HandleMailCreateTextItem(WorldPackets::Mail::MailCreateTextItem& createTextItem); + void HandleQueryNextMailTime(WorldPackets::Mail::MailQueryNextMailTime& queryNextMailTime); void HandleSplitItemOpcode(WorldPacket& recvPacket); void HandleSwapInvItemOpcode(WorldPacket& recvPacket); |
