From c0c5cf2f6b48271f31ac0e171fac8caec4092a8a Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Wed, 24 Jun 2026 18:43:59 +0200 Subject: [PATCH] feat(Core/ServerMail): Allow mail sender to be a creature (#26302) --- .../rev_1782050272664632800.sql | 2 ++ src/server/game/Mails/ServerMailMgr.cpp | 27 ++++++++++++------- src/server/game/Mails/ServerMailMgr.h | 4 ++- src/server/scripts/World/server_mail.cpp | 1 + 4 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 data/sql/updates/pending_db_characters/rev_1782050272664632800.sql diff --git a/data/sql/updates/pending_db_characters/rev_1782050272664632800.sql b/data/sql/updates/pending_db_characters/rev_1782050272664632800.sql new file mode 100644 index 0000000000..6164b1f900 --- /dev/null +++ b/data/sql/updates/pending_db_characters/rev_1782050272664632800.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mail_server_template` + ADD COLUMN `senderEntry` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Entry from creature_template. 0 for default "Customer Support" sender.' AFTER `id`; diff --git a/src/server/game/Mails/ServerMailMgr.cpp b/src/server/game/Mails/ServerMailMgr.cpp index 571e1ab443..32c8c425a2 100644 --- a/src/server/game/Mails/ServerMailMgr.cpp +++ b/src/server/game/Mails/ServerMailMgr.cpp @@ -41,8 +41,8 @@ void ServerMailMgr::LoadMailServerTemplates() _serverMailStore.clear(); // for reload case - // 0 1 2 3 4 5 - QueryResult result = CharacterDatabase.Query("SELECT `id`, `moneyA`, `moneyH`, `subject`, `body`, `active` FROM `mail_server_template`"); + // 0 1 2 3 4 5 6 + QueryResult result = CharacterDatabase.Query("SELECT `id`, `senderEntry`, `moneyA`, `moneyH`, `subject`, `body`, `active` FROM `mail_server_template`"); if (!result) { LOG_INFO("server.loading", ">> Loaded 0 server mail rewards. DB table `mail_server_template` is empty."); @@ -60,11 +60,12 @@ void ServerMailMgr::LoadMailServerTemplates() ServerMail& servMail = _serverMailStore[id]; servMail.id = id; - servMail.moneyA = fields[1].Get(); - servMail.moneyH = fields[2].Get(); - servMail.subject = fields[3].Get(); - servMail.body = fields[4].Get(); - servMail.active = fields[5].Get(); + servMail.senderEntry = fields[1].Get(); + servMail.moneyA = fields[2].Get(); + servMail.moneyH = fields[3].Get(); + servMail.subject = fields[4].Get(); + servMail.body = fields[5].Get(); + servMail.active = fields[6].Get(); // Skip non-activated entries if (!servMail.active) @@ -75,6 +76,12 @@ void ServerMailMgr::LoadMailServerTemplates() 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); continue; } + + if (servMail.senderEntry && !sObjectMgr->GetCreatureTemplate(servMail.senderEntry)) + { + LOG_ERROR("sql.sql", "Table `mail_server_template` has invalid senderEntry {} (no matching creature_template) for id {}, falling back to default sender.", servMail.senderEntry, servMail.id); + servMail.senderEntry = 0; + } } while (result->NextRow()); LoadMailServerTemplatesItems(); @@ -281,7 +288,7 @@ void ServerMailMgr::LoadMailServerTemplatesConditions() } while (result->NextRow()); } -void ServerMailMgr::SendServerMail(Player* player, uint32 id, uint32 money, +void ServerMailMgr::SendServerMail(Player* player, uint32 id, uint32 senderEntry, uint32 money, std::vector const& items, std::vector const& conditions, std::string const& subject, std::string const& body) const @@ -292,7 +299,9 @@ void ServerMailMgr::SendServerMail(Player* player, uint32 id, uint32 money, CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); - MailSender sender(MAIL_NORMAL, player->GetGUID().GetCounter(), MAIL_STATIONERY_GM); + MailSender sender = senderEntry + ? MailSender(MAIL_CREATURE, senderEntry, MAIL_STATIONERY_DEFAULT) + : MailSender(MAIL_NORMAL, player->GetGUID().GetCounter(), MAIL_STATIONERY_GM); MailDraft draft(subject, body); draft.AddMoney(money); diff --git a/src/server/game/Mails/ServerMailMgr.h b/src/server/game/Mails/ServerMailMgr.h index 73092d5467..892dfd4a0f 100644 --- a/src/server/game/Mails/ServerMailMgr.h +++ b/src/server/game/Mails/ServerMailMgr.h @@ -128,6 +128,7 @@ struct ServerMail { ServerMail() = default; uint32 id{ 0 }; + uint32 senderEntry{ 0 }; ///< Entry from creature_template. 0 for default "Customer Support" sender. uint32 moneyA{ 0 }; uint32 moneyH{ 0 }; std::string subject; @@ -205,6 +206,7 @@ public: * * @param player The recipient player. * @param id The template ID. + * @param senderEntry Entry from creature_template. 0 for default "Customer Support" sender. * @param money Money reward. * @param items List of items to include in the mail. * @param conditions List of the conditions for the mail. @@ -212,7 +214,7 @@ public: * @param body Mail body. * @param active Whether the mail template is active. */ - void SendServerMail(Player* player, uint32 id, uint32 money, std::vector const& items, std::vector const& conditions, std::string const& subject, std::string const& body) const; + void SendServerMail(Player* player, uint32 id, uint32 senderEntry, uint32 money, std::vector const& items, std::vector const& conditions, std::string const& subject, std::string const& body) const; /** * @brief Retrieves the entire server mail store. diff --git a/src/server/scripts/World/server_mail.cpp b/src/server/scripts/World/server_mail.cpp index 3a40f74923..59d40372de 100644 --- a/src/server/scripts/World/server_mail.cpp +++ b/src/server/scripts/World/server_mail.cpp @@ -58,6 +58,7 @@ public: sServerMailMgr->SendServerMail( session->GetPlayer(), servMail.id, + servMail.senderEntry, money, items, conditions,