AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
MailMgr Class Reference

Owns the mail lifecycle bookkeeping that lives outside a single player session: the per-character mail count mirrored in CharacterCache and the cleanup of expired mail. More...

#include "MailMgr.h"

Public Member Functions

void OnMailSent (ObjectGuid::LowType receiverLow)
 Reports a mail row inserted for a character.
 
void OnMailDeleted (ObjectGuid::LowType receiverLow)
 Reports a mail row deleted from a character's mailbox.
 
void OnMailReturned (ObjectGuid::LowType oldReceiverLow, ObjectGuid::LowType newReceiverLow)
 Reports a mail row handed to a new receiver (return to sender).
 
void LoadMailCounts ()
 Recounts the mail of all characters from the database. Called once at startup after the character cache is filled.
 
void RecountMailCount (ObjectGuid::LowType receiverLow)
 Recounts one character's mail from the database, overwriting the cached value.
 
void DeleteEmptyExpiredMail (uint32 mailId, ObjectGuid::LowType receiverLow)
 Deletes an expired mail row that has no items, money or COD attached. Used at login for mail that would otherwise stay invisible in the DB until ReturnOrDeleteOldMails catches the receiver offline.
 
void ReturnOrDeleteOldMails (bool serverUp)
 Returns expired mail with items to the sender and deletes the rest.
 

Static Public Member Functions

static MailMgrinstance ()
 

Detailed Description

Owns the mail lifecycle bookkeeping that lives outside a single player session: the per-character mail count mirrored in CharacterCache and the cleanup of expired mail.

Every code path that inserts or deletes a row in the characters mail table must report it here, otherwise the cached count drifts until the next recount.

Member Function Documentation

◆ DeleteEmptyExpiredMail()

void MailMgr::DeleteEmptyExpiredMail ( uint32  mailId,
ObjectGuid::LowType  receiverLow 
)

Deletes an expired mail row that has no items, money or COD attached. Used at login for mail that would otherwise stay invisible in the DB until ReturnOrDeleteOldMails catches the receiver offline.

Parameters
mailIdId of the mail row to delete
receiverLowLow GUID of the mail receiver
74{
76 stmt->SetData(0, mailId);
77 CharacterDatabase.Execute(stmt);
78
79 OnMailDeleted(receiverLow);
80}
@ CHAR_DEL_MAIL_BY_ID
Definition CharacterDatabase.h:110
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
void OnMailDeleted(ObjectGuid::LowType receiverLow)
Reports a mail row deleted from a character's mailbox.
Definition MailMgr.cpp:40
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157

References CHAR_DEL_MAIL_BY_ID, CharacterDatabase, OnMailDeleted(), and PreparedStatementBase::SetData().

◆ instance()

MailMgr * MailMgr::instance ( )
static
30{
31 static MailMgr instance;
32 return &instance;
33}
Owns the mail lifecycle bookkeeping that lives outside a single player session: the per-character mai...
Definition MailMgr.h:33
static MailMgr * instance()
Definition MailMgr.cpp:29

References instance().

Referenced by instance().

◆ LoadMailCounts()

void MailMgr::LoadMailCounts ( )

Recounts the mail of all characters from the database. Called once at startup after the character cache is filled.

52{
53 QueryResult result = CharacterDatabase.Query("SELECT receiver, COUNT(receiver) FROM mail GROUP BY receiver");
54 if (!result)
55 return;
56
57 do
58 {
59 Field* fields = result->Fetch();
60 sCharacterCache->UpdateCharacterMailCount(ObjectGuid(HighGuid::Player, fields[0].Get<uint32>()), static_cast<int32>(fields[1].Get<uint64>()), true);
61 } while (result->NextRow());
62}
#define sCharacterCache
Definition CharacterCache.h:88
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
std::int32_t int32
Definition Define.h:103
Class used to access individual fields of database query result.
Definition Field.h:98
Definition ObjectGuid.h:118

References CharacterDatabase, Player, and sCharacterCache.

◆ OnMailDeleted()

void MailMgr::OnMailDeleted ( ObjectGuid::LowType  receiverLow)

Reports a mail row deleted from a character's mailbox.

Parameters
receiverLowLow GUID of the mail receiver
41{
42 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, receiverLow));
43}

References Player, and sCharacterCache.

Referenced by DeleteEmptyExpiredMail(), and ReturnOrDeleteOldMails().

◆ OnMailReturned()

void MailMgr::OnMailReturned ( ObjectGuid::LowType  oldReceiverLow,
ObjectGuid::LowType  newReceiverLow 
)

Reports a mail row handed to a new receiver (return to sender).

Parameters
oldReceiverLowLow GUID of the previous receiver
newReceiverLowLow GUID of the new receiver
46{
47 sCharacterCache->DecreaseCharacterMailCount(ObjectGuid(HighGuid::Player, oldReceiverLow));
48 sCharacterCache->IncreaseCharacterMailCount(ObjectGuid(HighGuid::Player, newReceiverLow));
49}

References Player, and sCharacterCache.

Referenced by ReturnOrDeleteOldMails().

◆ OnMailSent()

void MailMgr::OnMailSent ( ObjectGuid::LowType  receiverLow)

Reports a mail row inserted for a character.

Parameters
receiverLowLow GUID of the mail receiver
36{
37 sCharacterCache->IncreaseCharacterMailCount(ObjectGuid(HighGuid::Player, receiverLow));
38}

References Player, and sCharacterCache.

◆ RecountMailCount()

void MailMgr::RecountMailCount ( ObjectGuid::LowType  receiverLow)

Recounts one character's mail from the database, overwriting the cached value.

Parameters
receiverLowLow GUID of the character to recount
65{
66 int32 count = 0;
67 if (QueryResult result = CharacterDatabase.Query("SELECT COUNT(*) FROM mail WHERE receiver = {}", receiverLow))
68 count = static_cast<int32>((*result)[0].Get<uint64>());
69
70 sCharacterCache->UpdateCharacterMailCount(ObjectGuid(HighGuid::Player, receiverLow), count, true);
71}
std::uint64_t uint64
Definition Define.h:106

References CharacterDatabase, Player, and sCharacterCache.

◆ ReturnOrDeleteOldMails()

void MailMgr::ReturnOrDeleteOldMails ( bool  serverUp)

Returns expired mail with items to the sender and deletes the rest.

Parameters
serverUpWhen true, receivers that are currently online are skipped.
83{
84 uint32 oldMSTime = getMSTime();
85
86 time_t curTime = GameTime::GetGameTime().count();
87
89 stmt->SetData(0, uint32(curTime));
90 PreparedQueryResult result = CharacterDatabase.Query(stmt);
91 if (!result)
92 return;
93
94 std::map<uint32 /*messageId*/, MailItemInfoVec> itemsCache;
95 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS);
96 stmt->SetData(0, uint32(curTime));
97 if (PreparedQueryResult items = CharacterDatabase.Query(stmt))
98 {
99 MailItemInfo item;
100 do
101 {
102 Field* fields = items->Fetch();
103 item.item_guid = fields[0].Get<uint32>();
104 item.item_template = fields[1].Get<uint32>();
105 uint32 mailId = fields[2].Get<uint32>();
106 itemsCache[mailId].push_back(item);
107 } while (items->NextRow());
108 }
109
110 uint32 deletedCount = 0;
111 uint32 returnedCount = 0;
112 do
113 {
114 Field* fields = result->Fetch();
115 Mail* m = new Mail;
116 m->messageID = fields[0].Get<uint32>();
117 m->messageType = fields[1].Get<uint8>();
118 m->sender = fields[2].Get<uint32>();
119 m->receiver = fields[3].Get<uint32>();
120 bool has_items = fields[4].Get<bool>();
121 m->expire_time = time_t(fields[5].Get<uint32>());
122 m->deliver_time = time_t(0);
123 m->stationery = fields[6].Get<uint8>();
124 m->checked = fields[7].Get<uint8>();
125 m->mailTemplateId = fields[8].Get<int16>();
126
127 Player* player = nullptr;
128 if (serverUp)
130
131 if (player) // don't modify mails of a logged in player
132 {
133 delete m;
134 continue;
135 }
136
137 // Keep each mail's correlated writes atomic
138 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
139
140 // Delete or return mail
141 if (has_items)
142 {
143 // read items from cache
144 m->items.swap(itemsCache[m->messageID]);
145
146 // If it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
147 if (!m->IsSentByPlayer() || m->IsSentByGM() || (m->IsCODPayment() || m->IsReturnedMail()))
148 {
149 for (auto const& mailedItem : m->items)
150 {
151 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
152 stmt->SetData(0, mailedItem.item_guid);
153 trans->Append(stmt);
154 }
155
156 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
157 stmt->SetData(0, m->messageID);
158 trans->Append(stmt);
159 }
160 else
161 {
162 // Mail will be returned
163 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_RETURNED);
164 stmt->SetData(0, m->receiver);
165 stmt->SetData(1, m->sender);
166 stmt->SetData(2, uint32(curTime + 30 * DAY));
167 stmt->SetData(3, uint32(curTime));
169 stmt->SetData(5, m->messageID);
170 trans->Append(stmt);
171 for (auto const& mailedItem : m->items)
172 {
173 // Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
174 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_ITEM_RECEIVER);
175 stmt->SetData(0, m->sender);
176 stmt->SetData(1, mailedItem.item_guid);
177 trans->Append(stmt);
178
179 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
180 stmt->SetData(0, m->sender);
181 stmt->SetData(1, mailedItem.item_guid);
182 trans->Append(stmt);
183 }
184
185 CharacterDatabase.CommitTransaction(trans);
186
188
189 delete m;
190 ++returnedCount;
191 continue;
192 }
193 }
194
195 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
196 stmt->SetData(0, m->messageID);
197 trans->Append(stmt);
198
199 CharacterDatabase.CommitTransaction(trans);
200
202
203 delete m;
204 ++deletedCount;
205 } while (result->NextRow());
206
207 LOG_INFO("server.loading", ">> Processed {} expired mails: {} deleted and {} returned in {} ms", deletedCount + returnedCount, deletedCount, returnedCount, GetMSTimeDiffToNow(oldMSTime));
208 LOG_INFO("server.loading", " ");
209}
@ CHAR_UPD_ITEM_OWNER
Definition CharacterDatabase.h:118
@ CHAR_DEL_ITEM_INSTANCE
Definition CharacterDatabase.h:127
@ CHAR_UPD_MAIL_RETURNED
Definition CharacterDatabase.h:116
@ CHAR_SEL_EXPIRED_MAIL
Definition CharacterDatabase.h:114
@ CHAR_SEL_EXPIRED_MAIL_ITEMS
Definition CharacterDatabase.h:115
@ CHAR_DEL_MAIL_ITEM_BY_ID
Definition CharacterDatabase.h:384
@ CHAR_UPD_MAIL_ITEM_RECEIVER
Definition CharacterDatabase.h:117
constexpr auto DAY
Definition Common.h:49
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
std::int16_t int16
Definition Define.h:104
#define LOG_INFO(filterType__,...)
Definition Log.h:153
std::vector< MailItemInfo > MailItemInfoVec
Definition Mail.h:164
@ MAIL_CHECK_MASK_RETURNED
Definition Mail.h:48
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
void OnMailReturned(ObjectGuid::LowType oldReceiverLow, ObjectGuid::LowType newReceiverLow)
Reports a mail row handed to a new receiver (return to sender).
Definition MailMgr.cpp:45
Definition Player.h:1085
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
Definition ObjectAccessor.cpp:251
Definition Mail.h:160
ObjectGuid::LowType item_guid
Definition Mail.h:161
uint32 item_template
Definition Mail.h:162
Definition Mail.h:167
bool IsSentByGM() const
Definition Mail.h:208
bool IsCODPayment() const
Definition Mail.h:209
ObjectGuid::LowType receiver
Definition Mail.h:173
uint8 messageType
Definition Mail.h:169
bool IsSentByPlayer() const
Definition Mail.h:207
uint32 messageID
Definition Mail.h:168
time_t expire_time
Definition Mail.h:178
uint32 sender
Definition Mail.h:172
uint8 stationery
Definition Mail.h:170
std::vector< MailItemInfo > items
Definition Mail.h:176
time_t deliver_time
Definition Mail.h:179
bool IsReturnedMail() const
Definition Mail.h:210
uint32 checked
Definition Mail.h:182
uint16 mailTemplateId
Definition Mail.h:171

References CHAR_DEL_ITEM_INSTANCE, CHAR_DEL_MAIL_BY_ID, CHAR_DEL_MAIL_ITEM_BY_ID, CHAR_SEL_EXPIRED_MAIL, CHAR_SEL_EXPIRED_MAIL_ITEMS, CHAR_UPD_ITEM_OWNER, CHAR_UPD_MAIL_ITEM_RECEIVER, CHAR_UPD_MAIL_RETURNED, CharacterDatabase, Mail::checked, DAY, Mail::deliver_time, Mail::expire_time, ObjectAccessor::FindPlayerByLowGUID(), Field::Get(), GameTime::GetGameTime(), getMSTime(), GetMSTimeDiffToNow(), Mail::IsCODPayment(), Mail::IsReturnedMail(), Mail::IsSentByGM(), Mail::IsSentByPlayer(), MailItemInfo::item_guid, MailItemInfo::item_template, Mail::items, LOG_INFO, MAIL_CHECK_MASK_RETURNED, Mail::mailTemplateId, Mail::messageID, Mail::messageType, OnMailDeleted(), OnMailReturned(), Mail::receiver, Mail::sender, PreparedStatementBase::SetData(), and Mail::stationery.


The documentation for this class was generated from the following files: