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

#include "ServerMailMgr.h"

Public Member Functions

void LoadMailServerTemplates ()
 Loads all server mail templates from the database into memory.
 
void LoadMailServerTemplatesItems ()
 Loads all items associated with server mail templates.
 
void LoadMailServerTemplatesConditions ()
 Loads all conditions associated with server mail templates.
 
ServerMailConditionType GetServerMailConditionType (std::string_view conditionTypeStr) const
 Convert DB value of conditionType to ServerMailConditionType.
 
bool ConditionTypeUsesConditionState (ServerMailConditionType type) const
 Check if ConditionType should use ConditionState.
 
void SendServerMail (Player *player, uint32 id, uint32 money, std::vector< ServerMailItems > const &items, std::vector< ServerMailCondition > const &conditions, std::string const &subject, std::string const &body) const
 Sends a server mail to a player if the template is active and the player is eligible.
 
ServerMailContainer const & GetAllServerMailStore () const
 Retrieves the entire server mail store.
 

Static Public Member Functions

static ServerMailMgrinstance ()
 

Private Member Functions

 ServerMailMgr ()=default
 
 ~ServerMailMgr ()=default
 

Private Attributes

ServerMailContainer _serverMailStore
 

Detailed Description

Constructor & Destructor Documentation

◆ ServerMailMgr()

ServerMailMgr::ServerMailMgr ( )
privatedefault

◆ ~ServerMailMgr()

ServerMailMgr::~ServerMailMgr ( )
privatedefault

Member Function Documentation

◆ ConditionTypeUsesConditionState()

bool ServerMailMgr::ConditionTypeUsesConditionState ( ServerMailConditionType  type) const

Check if ConditionType should use ConditionState.

Returns
True if the ConditionType is allowed to use ConditionState, otherwise False.
326{
327 switch (type)
328 {
331 return true;
332 default:
333 return false;
334 }
335}
@ Quest
Requires the player to have completed a specific quest.
@ Reputation
Requires the player to have earned reputation with a specific faction.

References Quest, and Reputation.

Referenced by LoadMailServerTemplatesConditions().

◆ GetAllServerMailStore()

ServerMailContainer const & ServerMailMgr::GetAllServerMailStore ( ) const
inline

Retrieves the entire server mail store.

This function returns a constant reference to the internal _serverMailStore container, which holds all server mail data.

Returns
A constant reference to the ServerMailContainer containing all stored server mail.
225{ return _serverMailStore; }
ServerMailContainer _serverMailStore
Definition ServerMailMgr.h:228

References _serverMailStore.

◆ GetServerMailConditionType()

ServerMailConditionType ServerMailMgr::GetServerMailConditionType ( std::string_view  conditionTypeStr) const

Convert DB value of conditionType to ServerMailConditionType.

Lookup the corresponding SeverMailConditionType enum for the provided string by DB. If the string is not found we return internal default value ServerMailConditionType::Invalid

Parameters
conditionTypeStrstring value from DB of conditionType
Returns
ServerMailConditionType The corresponding value (see ServerMailConditionType) or default to ServerMailConditionType::Invalid
317{
318 for (auto const& pair : ServerMailConditionTypePairs)
319 if (pair.first == conditionTypeStr)
320 return pair.second;
321
323}
@ Invalid
Internal use, not used in DB.
constexpr std::pair< std::string_view, ServerMailConditionType > ServerMailConditionTypePairs[]
Assign string condition to corresponding ServerMailConditionType enum value.
Definition ServerMailMgr.h:62

References Invalid, and ServerMailConditionTypePairs.

Referenced by LoadMailServerTemplatesConditions().

◆ instance()

ServerMailMgr * ServerMailMgr::instance ( )
static
33{
35 return &instance;
36}
Definition ServerMailMgr.h:148
static ServerMailMgr * instance()
Definition ServerMailMgr.cpp:32

References instance().

Referenced by instance().

◆ LoadMailServerTemplates()

void ServerMailMgr::LoadMailServerTemplates ( )

Loads all server mail templates from the database into memory.

Queries the mail_server_template table and loads all rows into memory. This method is intended to be called during server startup.

39{
40 uint32 oldMSTime = getMSTime();
41
42 _serverMailStore.clear(); // for reload case
43
44 // 0 1 2 3 4 5
45 QueryResult result = CharacterDatabase.Query("SELECT `id`, `moneyA`, `moneyH`, `subject`, `body`, `active` FROM `mail_server_template`");
46 if (!result)
47 {
48 LOG_INFO("server.loading", ">> Loaded 0 server mail rewards. DB table `mail_server_template` is empty.");
49 LOG_INFO("server.loading", " ");
50 return;
51 }
52
53 _serverMailStore.reserve(result->GetRowCount());
54
55 do
56 {
57 Field* fields = result->Fetch();
58
59 uint32 id = fields[0].Get<uint32>();
60
61 ServerMail& servMail = _serverMailStore[id];
62 servMail.id = id;
63 servMail.moneyA = fields[1].Get<uint32>();
64 servMail.moneyH = fields[2].Get<uint32>();
65 servMail.subject = fields[3].Get<std::string>();
66 servMail.body = fields[4].Get<std::string>();
67 servMail.active = fields[5].Get<uint8>();
68
69 // Skip non-activated entries
70 if (!servMail.active)
71 continue;
72
73 if (servMail.moneyA > MAX_MONEY_AMOUNT || servMail.moneyH > MAX_MONEY_AMOUNT)
74 {
75 LOG_ERROR("sql.sql", "Table `mail_server_template` has moneyA {} or moneyH {} larger than MAX_MONEY_AMOUNT {} for id {}, skipped.", servMail.moneyA, servMail.moneyH, MAX_MONEY_AMOUNT, servMail.id);
76 continue;
77 }
78 } while (result->NextRow());
79
82
83 LOG_INFO("server.loading", ">> Loaded {} Mail Server definitions in {} ms", _serverMailStore.size(), GetMSTimeDiffToNow(oldMSTime));
84 LOG_INFO("server.loading", " ");
85}
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
#define LOG_INFO(filterType__,...)
Definition Log.h:166
#define LOG_ERROR(filterType__,...)
Definition Log.h:158
#define MAX_MONEY_AMOUNT
Definition Player.h:923
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
Class used to access individual fields of database query result.
Definition Field.h:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
void LoadMailServerTemplatesItems()
Loads all items associated with server mail templates.
Definition ServerMailMgr.cpp:87
void LoadMailServerTemplatesConditions()
Loads all conditions associated with server mail templates.
Definition ServerMailMgr.cpp:156
Represents a server mail template, including rewards, conditions, and metadata.
Definition ServerMailMgr.h:128
uint32 id
Definition ServerMailMgr.h:130

References _serverMailStore, CharacterDatabase, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), ServerMail::id, LoadMailServerTemplatesConditions(), LoadMailServerTemplatesItems(), LOG_ERROR, LOG_INFO, and MAX_MONEY_AMOUNT.

◆ LoadMailServerTemplatesConditions()

void ServerMailMgr::LoadMailServerTemplatesConditions ( )

Loads all conditions associated with server mail templates.

Queries the mail_server_template_conditions table and loads all conditions into memory, linking them to their corresponding templates by template ID. This method is intended to be called during server startup.

157{
158 // 0 1 2 3
159 QueryResult result = CharacterDatabase.Query("SELECT `templateID`, `conditionType`, `conditionValue`, `conditionState` FROM `mail_server_template_conditions`");
160 if (!result)
161 {
162 LOG_WARN("server.loading", ">> Loaded 0 server mail conditions. DB table `mail_server_template_conditions` is empty.");
163 return;
164 }
165
166 do
167 {
168 Field* fields = result->Fetch();
169
170 uint32 templateID = fields[0].Get<uint32>();
171 std::string_view conditionTypeStr = fields[1].Get<std::string_view>();
172 uint32 conditionValue = fields[2].Get<uint32>();
173 uint32 conditionState = fields[3].Get<uint32>();
174
175 if (_serverMailStore.find(templateID) == _serverMailStore.end())
176 {
177 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has an invalid templateID {}, skipped.", templateID);
178 continue;
179 }
180
181 // Get conditiontype from ServerMailConditionTypePairs
182 ServerMailConditionType conditionType;
183 conditionType = GetServerMailConditionType(conditionTypeStr);
184 if (conditionType == ServerMailConditionType::Invalid) [[unlikely]]
185 {
186 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has unknown conditionType '{}', skipped.", conditionTypeStr);
187 continue;
188 }
189
190 if (conditionState && !ConditionTypeUsesConditionState(conditionType))
191 LOG_WARN("sql.sql", "Table `mail_server_template_conditions` has conditionState value ({}) for conditionType ({}) which does not use conditionState.", conditionState, conditionTypeStr);
192
193 switch (conditionType)
194 {
196 if (conditionValue > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
197 {
198 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Level' with invalid conditionValue ({}), max level is ({}) for templateID {}, skipped.", conditionValue, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL), templateID);
199 continue;
200 }
201 break;
203 {
204 Quest const* qInfo = sObjectMgr->GetQuestTemplate(conditionValue);
205 if (!qInfo)
206 {
207 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Quest' with invalid quest in conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
208 continue;
209 }
210 if (conditionState < QUEST_STATUS_NONE || conditionState >= MAX_QUEST_STATUS ||
211 /*2 and 4 not defined and should not be used*/ conditionState == 2 || conditionState == 4)
212 {
213 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Quest' with invalid conditionState ({}) for templateID {}, skipped.", conditionState, templateID);
214 continue;
215 }
216 break;
217 }
219 {
220 AchievementEntry const* achievement = sAchievementStore.LookupEntry(conditionValue);
221 if (!achievement)
222 {
223 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Achievement' with invalid achievement in conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
224 continue;
225 }
226 break;
227 }
229 {
230 FactionEntry const* faction = sFactionStore.LookupEntry(conditionValue);
231 if (!faction)
232 {
233 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Reputation' with invalid faction in conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
234 continue;
235 }
236 if (conditionState < REP_HATED || conditionState > REP_EXALTED)
237 {
238 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Reputation' with invalid conditionState ({}) for templateID {}, skipped.", conditionState, templateID);
239 continue;
240 }
241 break;
242 }
244 if (conditionValue < TEAM_ALLIANCE || conditionValue > TEAM_HORDE)
245 {
246 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Faction' with invalid conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
247 continue;
248 }
249 break;
251 if (conditionValue & ~sRaceMgr->GetPlayableRaceMask())
252 {
253 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Race' with invalid conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
254 continue;
255 }
256 break;
258 if (conditionValue & ~CLASSMASK_ALL_PLAYABLE)
259 {
260 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'Class' with invalid conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
261 continue;
262 }
263 break;
265 if ((conditionValue & ~ACCOUNT_FLAGS_ALL) != 0)
266 {
267 LOG_ERROR("sql.sql", "Table `mail_server_template_conditions` has conditionType 'AccountFlags' with invalid conditionValue ({}) for templateID {}, skipped.", conditionValue, templateID);
268 continue;
269 }
270 break;
271 default:
272 break;
273 }
274
275 ServerMailCondition condition;
276 condition.type = conditionType;
277 condition.value = conditionValue;
278 condition.state = conditionState;
279 _serverMailStore[templateID].conditions.push_back(condition);
280
281 } while (result->NextRow());
282}
constexpr uint32 ACCOUNT_FLAGS_ALL
Definition Common.h:103
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
DBCStorage< AchievementEntry > sAchievementStore(Achievementfmt)
#define LOG_WARN(filterType__,...)
Definition Log.h:162
#define sObjectMgr
Definition ObjectMgr.h:1712
@ MAX_QUEST_STATUS
Definition QuestDef.h:107
#define sRaceMgr
Definition RaceMgr.h:52
ServerMailConditionType
Represents the type of conditions that can be applied to server mail.
Definition ServerMailMgr.h:46
@ AccountFlags
Requires the player to have a specific AccountFlag (bit)
@ Faction
Requires the player to be a part of a specific faction. Horde/Alliance.
@ Race
Requires the player to be a specific race.
@ Class
Requires the player to be a specific class.
@ Level
Requires the player to be at least a specific level.
@ Achievement
Requires the player to have earned a specific achievement.
@ REP_EXALTED
Definition SharedDefines.h:164
#define CLASSMASK_ALL_PLAYABLE
Definition SharedDefines.h:142
@ TEAM_HORDE
Definition SharedDefines.h:749
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:193
Definition QuestDef.h:210
bool ConditionTypeUsesConditionState(ServerMailConditionType type) const
Check if ConditionType should use ConditionState.
Definition ServerMailMgr.cpp:325
ServerMailConditionType GetServerMailConditionType(std::string_view conditionTypeStr) const
Convert DB value of conditionType to ServerMailConditionType.
Definition ServerMailMgr.cpp:316
#define sWorld
Definition World.h:316
Definition DBCStructure.h:40
Definition DBCStructure.h:907
Represents a condition that must be met for a player to receive a server mail.
Definition ServerMailMgr.h:88
uint32 state
Definition ServerMailMgr.h:93
ServerMailConditionType type
Definition ServerMailMgr.h:91
uint32 value
Definition ServerMailMgr.h:92

References _serverMailStore, ACCOUNT_FLAGS_ALL, AccountFlags, Achievement, CharacterDatabase, Class, CLASSMASK_ALL_PLAYABLE, ConditionTypeUsesConditionState(), CONFIG_MAX_PLAYER_LEVEL, Faction, Field::Get(), GetServerMailConditionType(), Invalid, Level, LOG_ERROR, LOG_WARN, MAX_QUEST_STATUS, Quest, Race, REP_EXALTED, Reputation, sAchievementStore, sFactionStore, sObjectMgr, sRaceMgr, ServerMailCondition::state, sWorld, TEAM_HORDE, ServerMailCondition::type, and ServerMailCondition::value.

Referenced by LoadMailServerTemplates().

◆ LoadMailServerTemplatesItems()

void ServerMailMgr::LoadMailServerTemplatesItems ( )

Loads all items associated with server mail templates.

Queries the mail_server_template_items table and loads all items into memory, linking them to their corresponding templates by template ID. This method is intended to be called during server startup.

88{
89 // 0 1 2 3
90 QueryResult result = CharacterDatabase.Query("SELECT `templateID`, `faction`, `item`, `itemCount` FROM `mail_server_template_items`");
91 if (!result)
92 {
93 LOG_WARN("server.loading", ">> Loaded 0 server mail items. DB table `mail_server_template_items` is empty.");
94 return;
95 }
96
97 do
98 {
99 Field* fields = result->Fetch();
100
101 uint32 templateID = fields[0].Get<uint32>();
102 std::string_view faction = fields[1].Get<std::string_view>();
103 uint32 item = fields[2].Get<uint32>();
104 uint32 itemCount = fields[3].Get<uint32>();
105
106 if (_serverMailStore.find(templateID) == _serverMailStore.end())
107 {
108 LOG_ERROR("sql.sql", "Table `mail_server_template_items` has an invalid templateID {}, skipped.", templateID);
109 continue;
110 }
111
112 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item);
113 if (!itemTemplate)
114 {
115 LOG_ERROR("sql.sql", "Table `mail_server_template_items` has an invalid item {} for templateID {}, skipped.", item, templateID);
116 continue;
117 }
118
119 if (!itemCount)
120 {
121 LOG_ERROR("sql.sql", "Table `mail_server_template_items` has itemCount 0 for item {}, skipped.", item);
122 continue;
123 }
124
125 uint32 stackable = itemTemplate->Stackable;
126 if (itemCount > stackable)
127 {
128 LOG_ERROR("sql.sql", "Table `mail_server_template_items` has itemCount {} exceeding item_template.Stackable {} for item {}, skipped.", itemCount, stackable, item);
129 continue;
130 }
131
132 uint32 maxCount = itemTemplate->MaxCount;
133 if (maxCount && itemCount > maxCount)
134 {
135 LOG_ERROR("sql.sql", "Table `mail_server_template_items` has itemCount {} exceeding item_template.MaxCount {} for item {}, skipped", itemCount, maxCount, item);
136 continue;
137 }
138
139 ServerMailItems mailItem;
140 mailItem.item = item;
141 mailItem.itemCount = itemCount;
142
143 if (faction == "Alliance")
144 _serverMailStore[templateID].itemsA.push_back(mailItem);
145 else if (faction == "Horde")
146 _serverMailStore[templateID].itemsH.push_back(mailItem);
147 else [[unlikely]]
148 {
149 LOG_ERROR("sql.sql", "Table `mail_server_template_items` has invalid faction value '{}' for templateID {}, skipped.", faction, templateID);
150 continue;
151 }
152
153 } while (result->NextRow());
154}
Definition ItemTemplate.h:619
int32 MaxCount
Definition ItemTemplate.h:644
int32 Stackable
Definition ItemTemplate.h:645
Represents an item reward associated with a server mail template.
Definition ServerMailMgr.h:114
uint32 itemCount
Definition ServerMailMgr.h:117
uint32 item
Definition ServerMailMgr.h:116

References _serverMailStore, CharacterDatabase, Field::Get(), ServerMailItems::item, ServerMailItems::itemCount, LOG_ERROR, LOG_WARN, ItemTemplate::MaxCount, sObjectMgr, and ItemTemplate::Stackable.

Referenced by LoadMailServerTemplates().

◆ SendServerMail()

void ServerMailMgr::SendServerMail ( Player player,
uint32  id,
uint32  money,
std::vector< ServerMailItems > const &  items,
std::vector< ServerMailCondition > const &  conditions,
std::string const &  subject,
std::string const &  body 
) const

Sends a server mail to a player if the template is active and the player is eligible.

This method handles the creation of the mail, adding money and items, and saving the mail to the database. It also records that the player received the mail to prevent duplicate delivery.

Parameters
playerThe recipient player.
idThe template ID.
moneyMoney reward.
itemsList of items to include in the mail.
conditionsList of the conditions for the mail.
subjectMail subject.
bodyMail body.
activeWhether the mail template is active.
288{
289 for (ServerMailCondition const& condition : conditions)
290 if (!condition.CheckCondition(player))
291 return;
292
293 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
294
296 MailDraft draft(subject, body);
297
298 draft.AddMoney(money);
299 // Loop through all items and attach them to the mail
300 for (auto const& mailItem : items)
301 if (Item* newItem = Item::CreateItem(mailItem.item, mailItem.itemCount))
302 {
303 newItem->SaveToDB(trans);
304 draft.AddItem(newItem);
305 }
306
307 draft.SendMailTo(trans, MailReceiver(player), sender);
308 CharacterDatabase.CommitTransaction(trans);
309
311 stmt->SetData(0, player->GetGUID().GetCounter());
312 stmt->SetData(1, id);
313 CharacterDatabase.Execute(stmt);
314}
@ CHAR_REP_MAIL_SERVER_CHARACTER
Definition CharacterDatabase.h:85
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
@ MAIL_STATIONERY_GM
Definition Mail.h:59
@ MAIL_NORMAL
Definition Mail.h:37
Definition Item.h:220
Definition Mail.h:119
Definition Mail.h:105
Definition Mail.h:83
LowType GetCounter() const
Definition ObjectGuid.h:145
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:114
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157

References MailDraft::AddItem(), MailDraft::AddMoney(), CHAR_REP_MAIL_SERVER_CHARACTER, CharacterDatabase, Item::CreateItem(), ObjectGuid::GetCounter(), Object::GetGUID(), MAIL_NORMAL, MAIL_STATIONERY_GM, MailDraft::SendMailTo(), and PreparedStatementBase::SetData().

Member Data Documentation

◆ _serverMailStore


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