mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
fix(mail): new mail notices in live's form
Live filled a NewMail notice with the mail it was about: the mail ID, the player, the attachment (LOT -1 without one) and a count of 1, and at load sent one notice per unread mail. DLU sent one notice with every field 0 and the unread total as the count. The answer to NotificationRequest names the player and no mail, with LOT -1 and the unread count, as live's did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -129,23 +129,40 @@ TEST(MailPacketTests, NoAttachmentIsLotNull) {
|
||||
EXPECT_EQ(lot, -1);
|
||||
}
|
||||
|
||||
// Answer to NotificationRequest: 56 bytes, the unread count at offset 48 (live sent 2 there for two unread mails).
|
||||
TEST(MailPacketTests, NotificationResponseLayout) {
|
||||
// The answer to NotificationRequest names no mail: the player, no attachment (LOT -1) and the unread count at
|
||||
// offset 48. Live capture (its padding held stale memory; zero here).
|
||||
TEST(MailPacketTests, NotificationRequestAnswerMatchesLive) {
|
||||
Mail::NotificationResponse response;
|
||||
response.status = Mail::eNotificationResponse::NewMail;
|
||||
response.receiverID = 0x100000015b7b141f;
|
||||
response.mailCount = 2;
|
||||
const auto actual = Write(response);
|
||||
ASSERT_EQ(actual.bytes.size(), 56u);
|
||||
Bytes expected;
|
||||
PutClientMailHeader(expected, Mail::eMessageID::NotificationResponse);
|
||||
expected.Put<uint32_t>(0); // NewMail
|
||||
expected.Put<uint64_t>(0);
|
||||
expected.Put<uint64_t>(0);
|
||||
expected.Put<uint64_t>(0);
|
||||
expected.Put<uint64_t>(0);
|
||||
expected.Put<uint32_t>(2); // mail count
|
||||
expected.Put<uint32_t>(0);
|
||||
EXPECT_TRUE(PacketsEqual(expected.Packet(), actual));
|
||||
EXPECT_TRUE(PacketsEqual(
|
||||
FromHex("530500310000000002000000000000000000000000000000""1f147b5b010000100000000000000000ffffffff0000000002000000""00000000"),
|
||||
Write(response)));
|
||||
}
|
||||
|
||||
// A new mail notice: the mail, the player, the attachment and a count of 1. Live capture (padding zeroed).
|
||||
TEST(MailPacketTests, NewMailNoticeMatchesLive) {
|
||||
MailInfo mail;
|
||||
mail.id = 0x10000001733377d7;
|
||||
mail.itemID = 0x10000001733377d6;
|
||||
mail.itemLOT = 0x3e6c;
|
||||
mail.itemCount = 1;
|
||||
EXPECT_TRUE(PacketsEqual(
|
||||
FromHex("53050031000000000200000000000000d7773373010000105e7dea8e00000010d6773373010000106c3e00000100000001000000""00000000"),
|
||||
Write(Mail::NewMailNotice(mail, 0x100000008eea7d5e))));
|
||||
}
|
||||
|
||||
// Without an attachment the notice carries LOT -1, as live did for mission mail.
|
||||
TEST(MailPacketTests, NewMailNoticeWithoutAttachment) {
|
||||
MailInfo mail;
|
||||
mail.id = 7;
|
||||
mail.itemLOT = 0;
|
||||
mail.itemCount = 1;
|
||||
const auto notice = Mail::NewMailNotice(mail, 0x100000015b7b141f);
|
||||
EXPECT_EQ(notice.attachmentLOT, LOT_NULL);
|
||||
EXPECT_EQ(notice.mailCount, 1u);
|
||||
EXPECT_EQ(Write(notice).bytes.size(), 56u);
|
||||
}
|
||||
|
||||
// The mailbox opens the Mail UI with pushGameState {state: "Mail"}; bytes from a live capture.
|
||||
|
||||
@@ -65,18 +65,34 @@ TEST_F(LoadSequenceTests, SavedCheckpointIsSentUnrotated) {
|
||||
EXPECT_EQ(checkpoints[0].rot, QuatUtils::IDENTITY);
|
||||
}
|
||||
|
||||
// Unread mail is announced during the load without the client asking; nothing is sent without unread mail.
|
||||
// Live's packet (56 bytes) also fills the three fields DLU leaves 0 with object IDs the client does not use here.
|
||||
// Unread mail is announced during the load without the client asking, one NewMail notice per unread mail (oldest
|
||||
// first, a count of 1 each, as live sent two notices for two mails); nothing is sent without unread mail.
|
||||
TEST_F(LoadSequenceTests, UnreadMailIsAnnouncedOnLoad) {
|
||||
auto sent = Capture([&] { Mail::NotifyUnreadMailOnLoad(0, ClientAddress()); });
|
||||
EXPECT_TRUE(sent.empty());
|
||||
EXPECT_TRUE(Mail::UnreadMailNotices({}, PLAYER).empty());
|
||||
|
||||
sent = Capture([&] { Mail::NotifyUnreadMailOnLoad(1, ClientAddress()); });
|
||||
ASSERT_EQ(sent.size(), 1u);
|
||||
EXPECT_EQ(sent[0].sysAddr, ClientAddress());
|
||||
EXPECT_PACKET_EQ(FromHex(
|
||||
"53 05 00 31 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
|
||||
"00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00"), FromCapture(sent[0]));
|
||||
MailInfo read;
|
||||
read.id = 1;
|
||||
read.wasRead = true;
|
||||
MailInfo newer;
|
||||
newer.id = 9;
|
||||
newer.itemLOT = 0;
|
||||
newer.itemCount = 1;
|
||||
MailInfo older;
|
||||
older.id = 4;
|
||||
older.itemID = 0x1000000000000123;
|
||||
older.itemLOT = 3038;
|
||||
older.itemCount = 100;
|
||||
const auto notices = Mail::UnreadMailNotices({ read, newer, older }, PLAYER);
|
||||
ASSERT_EQ(notices.size(), 2u);
|
||||
EXPECT_EQ(notices[0].mailID, 4u);
|
||||
EXPECT_EQ(notices[0].attachmentLOT, 3038);
|
||||
EXPECT_EQ(notices[1].mailID, 9u);
|
||||
EXPECT_EQ(notices[1].attachmentLOT, LOT_NULL);
|
||||
for (const auto& notice : notices) {
|
||||
EXPECT_EQ(notice.status, Mail::eNotificationResponse::NewMail);
|
||||
EXPECT_EQ(notice.receiverID, PLAYER);
|
||||
EXPECT_EQ(notice.mailCount, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
// Live, right before TRANSFER_TO_WORLD on a rocket launch to Nimbus Station (spawn point MedPropLand): flag 32 on,
|
||||
|
||||
Reference in New Issue
Block a user