Files
WoWee/tests/test_mail_packets.cpp
2026-07-14 22:47:57 -07:00

162 lines
6.9 KiB
C++

#include <catch_amalgamated.hpp>
#include "core/application.hpp"
#include "game/packet_parsers.hpp"
#include "game/world_packets.hpp"
namespace wowee::core {
Application* Application::instance = nullptr;
}
using namespace wowee::game;
TEST_CASE("WotLK mail list parses uint32 attached money and inclusive entry size", "[mail]") {
wowee::network::Packet entry;
entry.writeUInt32(0x12345678); // message id
entry.writeUInt8(0); // normal player mail
entry.writeUInt64(0x1122334455667788); // sender
entry.writeUInt32(54321); // COD
entry.writeUInt32(0); // pre-3.3.3 item text field
entry.writeUInt32(41); // stationery
entry.writeUInt32(1234567); // attached money
entry.writeUInt32(1); // read flag
entry.writeFloat(12.5f); // days remaining
entry.writeUInt32(0); // mail template
entry.writeString("Test subject");
entry.writeString("Test body");
entry.writeUInt8(0); // attachments
wowee::network::Packet packet;
packet.writeUInt32(1); // total count
packet.writeUInt8(1); // shown count
packet.writeUInt16(static_cast<uint16_t>(entry.getSize() + 2));
packet.writeBytes(entry.getData().data(), entry.getSize());
WotlkPacketParsers parsers;
std::vector<MailMessage> inbox;
REQUIRE(parsers.parseMailList(packet, inbox));
REQUIRE(inbox.size() == 1);
CHECK(inbox[0].messageId == 0x12345678);
CHECK(inbox[0].senderGuid == 0x1122334455667788);
CHECK(inbox[0].cod == 54321);
CHECK(inbox[0].stationeryId == 41);
CHECK(inbox[0].money == 1234567);
CHECK(inbox[0].flags == 1);
CHECK(inbox[0].expirationTime == Catch::Approx(12.5f));
CHECK(inbox[0].subject == "Test subject");
CHECK(inbox[0].body == "Test body");
CHECK(packet.getRemainingSize() == 0);
}
TEST_CASE("WotLK send mail writes uint32 money and COD plus legacy zeros", "[mail]") {
auto built = SendMailPacket::build(0x1020304050607080, "Receiver", "Subject", "Body",
1234567, 7654321, {});
wowee::network::Packet packet(built.getOpcode(), built.getData());
CHECK(packet.readUInt64() == 0x1020304050607080);
CHECK(packet.readString() == "Receiver");
CHECK(packet.readString() == "Subject");
CHECK(packet.readString() == "Body");
CHECK(packet.readUInt32() == 0);
CHECK(packet.readUInt32() == 0);
CHECK(packet.readUInt8() == 0);
CHECK(packet.readUInt32() == 1234567);
CHECK(packet.readUInt32() == 7654321);
CHECK(packet.readUInt64() == 0);
CHECK(packet.readUInt8() == 0);
CHECK(packet.getRemainingSize() == 0);
}
TEST_CASE("TBC mail list parses attached money and item wire layout", "[mail][tbc]") {
wowee::network::Packet entry;
entry.writeUInt32(0x87654321); // message id
entry.writeUInt8(0); // normal player mail
entry.writeUInt64(0x8877665544332211); // sender
entry.writeUInt32(24680); // COD
entry.writeUInt32(13579); // item text id
entry.writeUInt32(0); // package
entry.writeUInt32(41); // stationery
entry.writeUInt32(765432); // attached money
entry.writeUInt32(0); // flags
entry.writeFloat(7.25f); // days remaining
entry.writeUInt32(0); // mail template
entry.writeString("TBC subject");
entry.writeUInt8(1); // attachment count
entry.writeUInt8(3); // attachment slot
entry.writeUInt32(0x10203040); // item GUID low
entry.writeUInt32(19019); // item entry
for (uint32_t enchantSlot = 0; enchantSlot < 6; ++enchantSlot) {
entry.writeUInt32(enchantSlot + 10); // charges
entry.writeUInt32(enchantSlot + 20); // duration
entry.writeUInt32(enchantSlot == 0 ? 2673 : 0); // enchant id
}
entry.writeUInt32(44); // random property
entry.writeUInt32(55); // suffix factor
entry.writeUInt8(7); // stack count
entry.writeUInt32(6); // spell charges
entry.writeUInt32(100); // max durability
entry.writeUInt32(83); // current durability
wowee::network::Packet packet;
packet.writeUInt8(1);
packet.writeUInt16(static_cast<uint16_t>(entry.getSize() + 2));
packet.writeBytes(entry.getData().data(), entry.getSize());
TbcPacketParsers parsers;
std::vector<MailMessage> inbox;
REQUIRE(parsers.parseMailList(packet, inbox));
REQUIRE(inbox.size() == 1);
CHECK(inbox[0].messageId == 0x87654321);
CHECK(inbox[0].senderGuid == 0x8877665544332211);
CHECK(inbox[0].cod == 24680);
CHECK(inbox[0].stationeryId == 41);
CHECK(inbox[0].money == 765432);
CHECK(inbox[0].expirationTime == Catch::Approx(7.25f));
CHECK(inbox[0].subject == "TBC subject");
REQUIRE(inbox[0].attachments.size() == 1);
CHECK(inbox[0].attachments[0].slot == 3);
CHECK(inbox[0].attachments[0].itemGuidLow == 0x10203040);
CHECK(inbox[0].attachments[0].itemId == 19019);
CHECK(inbox[0].attachments[0].enchantId == 2673);
CHECK(inbox[0].attachments[0].randomPropertyId == 44);
CHECK(inbox[0].attachments[0].randomSuffix == 55);
CHECK(inbox[0].attachments[0].stackCount == 7);
CHECK(inbox[0].attachments[0].chargesOrDurability == 6);
CHECK(inbox[0].attachments[0].maxDurability == 100);
CHECK(packet.getRemainingSize() == 0);
}
TEST_CASE("TBC mail list accepts overstated non-player sender size", "[mail][tbc]") {
wowee::network::Packet entry;
entry.writeUInt32(99); // message id
entry.writeUInt8(2); // auction mail
entry.writeUInt32(1234); // auction sender id
entry.writeUInt32(0); // COD
entry.writeUInt32(0); // item text id
entry.writeUInt32(0); // package
entry.writeUInt32(62); // auction stationery
entry.writeUInt32(40000); // attached money
entry.writeUInt32(0); // flags
entry.writeFloat(30.0f); // days remaining
entry.writeUInt32(0); // template
entry.writeString("Auction successful");
entry.writeUInt8(0); // attachments
wowee::network::Packet packet;
packet.writeUInt8(1);
// CMaNGOS budgets an 8-byte sender here but emits the uint32 above.
packet.writeUInt16(static_cast<uint16_t>(entry.getSize() + 2 + 4));
packet.writeBytes(entry.getData().data(), entry.getSize());
TbcPacketParsers parsers;
std::vector<MailMessage> inbox;
REQUIRE(parsers.parseMailList(packet, inbox));
REQUIRE(inbox.size() == 1);
CHECK(inbox[0].messageType == 2);
CHECK(inbox[0].senderEntry == 1234);
CHECK(inbox[0].money == 40000);
CHECK(inbox[0].stationeryId == 62);
CHECK(inbox[0].subject == "Auction successful");
CHECK(packet.getRemainingSize() == 0);
}