feat(Core/Mail): add Mail.PushInboxOnDelivery to refresh stale mailboxes (#27508)

This commit is contained in:
Axel Cocat
2026-09-13 11:16:23 -03:00
committed by GitHub
parent 67317e09df
commit cd8dc5775b
7 changed files with 40 additions and 5 deletions
@@ -4245,6 +4245,22 @@ MaxAllowedMMRDrop = 500
MailDeliveryDelay = 3600
#
# Mail.PushInboxOnDelivery
# Description: Send the receiver's inbox to the client whenever mail is delivered to them
# while they are online.
# The client caches its mailbox and will not ask the server for it again for
# about a minute, so a player who opens a mailbox shortly after checking it
# sees a stale list until that minute is up, or until they /reload or relog.
# Pushing the inbox refreshes it in place and works around that.
# This is not something a retail server does, and every delivery then costs
# one inbox packet (up to ~32KB for characters holding many mails), so leave
# it off unless the stale mailbox is a problem on your realm.
# Default: 0 - (Disabled)
# 1 - (Enabled)
Mail.PushInboxOnDelivery = 0
#
# LevelReq.Mail
# Description: Level requirement for characters to be able to send and receive mails.
@@ -2977,6 +2977,13 @@ void Player::SendNewMail()
WorldPacket data(SMSG_RECEIVED_MAIL, 4);
data << (uint32) 0;
SendDirectMessage(&data);
// The client caches its inbox and refuses to re-query it more than once a minute, so a mailbox
// opened inside that window still shows the old list. Pushing the inbox refreshes it in place.
// Only when in world: _LoadInventory mails problematic items during login, and that must not
// push a mail list to a client that has not finished logging in yet.
if (IsInWorld() && sWorld->getBoolConfig(CONFIG_MAIL_PUSH_INBOX_ON_DELIVERY))
GetSession()->SendMailList();
}
void Player::AddNewMailDeliverTime(time_t deliver_time)
+11 -3
View File
@@ -686,6 +686,17 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData)
if (!CanOpenMailBox(mailbox))
return;
SendMailList();
// recalculate m_nextMailDelivereTime and unReadMails
_player->UpdateNextMailTimeAndUnreads();
}
// Builds and sends the inbox. Normally a reply to CMSG_GET_MAIL_LIST, but it is also pushed
// unsolicited on delivery when Mail.PushInboxOnDelivery is on, because the client refuses to
// re-query its inbox more than once a minute and would otherwise show a stale mailbox
void WorldSession::SendMailList()
{
Player* player = _player;
uint8 mailsCount = 0;
@@ -807,9 +818,6 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData)
data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount
data.put<uint8>(4, mailsCount); // set real send mails to client
SendPacket(&data);
// recalculate m_nextMailDelivereTime and unReadMails
_player->UpdateNextMailTimeAndUnreads();
}
//used when player copies mail body to his inventory
+3 -2
View File
@@ -264,8 +264,6 @@ void MailDraft::SendMailTo(CharacterDatabaseTransaction trans, MailReceiver cons
// For online receiver update in game mail status and data
if (pReceiver)
{
pReceiver->AddNewMailDeliverTime(deliver_time);
Mail* m = new Mail;
m->messageID = mailId;
m->mailTemplateId = GetMailTemplateId();
@@ -303,6 +301,9 @@ void MailDraft::SendMailTo(CharacterDatabaseTransaction trans, MailReceiver cons
// for another receiver must not attach them a second time
m_items.clear();
}
// Announce last: the notification may push the inbox, which has to contain this mail already
pReceiver->AddNewMailDeliverTime(deliver_time);
}
else if (!m_items.empty())
{
+1
View File
@@ -549,6 +549,7 @@ public:
void SendShowBank(ObjectGuid guid);
bool CanOpenMailBox(ObjectGuid guid);
void SendShowMailBox(ObjectGuid guid);
void SendMailList();
void SendTabardVendorActivate(ObjectGuid guid);
void SendSpiritResurrect();
void SendBindPoint(Creature* npc);
+1
View File
@@ -301,6 +301,7 @@ void WorldConfig::BuildConfigCache()
SetConfigValue<bool>(CONFIG_OBJECT_QUEST_MARKERS, "Visibility.ObjectQuestMarkers", true);
SetConfigValue<uint32>(CONFIG_MAIL_DELIVERY_DELAY, "MailDeliveryDelay", HOUR);
SetConfigValue<bool>(CONFIG_MAIL_PUSH_INBOX_ON_DELIVERY, "Mail.PushInboxOnDelivery", false);
SetConfigValue<uint32>(CONFIG_UPTIME_UPDATE, "UpdateUptimeInterval", 10, ConfigValueCache::Reloadable::Yes, [](uint32 const& value) { return value > 0; }, "> 0");
+1
View File
@@ -218,6 +218,7 @@ enum ServerConfigs
CONFIG_START_GM_LEVEL,
CONFIG_GROUP_VISIBILITY,
CONFIG_MAIL_DELIVERY_DELAY,
CONFIG_MAIL_PUSH_INBOX_ON_DELIVERY,
CONFIG_UPTIME_UPDATE,
CONFIG_SKILL_CHANCE_ORANGE,
CONFIG_SKILL_CHANCE_YELLOW,