From 150b09205bbdf6a01be4aa5ba2e2859eb1b77a87 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 2 Mar 2022 09:52:35 -0500 Subject: [PATCH] Core/Mail: Load mails at login instead of on demand when queried by packets (logging in always sends one of the packets that cause mail loading anyway) Port From (https://github.com/TrinityCore/TrinityCore/commit/a9b4f9aca0d0b90e59e0ed26e9bb4cce7d0ceeab) --- .../Database/Databases/CharacterDatabase.cs | 4 - Source/Game/Chat/CommandHandler.cs | 2 +- Source/Game/Entities/Player/Player.DB.cs | 92 ++++++------------- Source/Game/Entities/Player/Player.Fields.cs | 1 - Source/Game/Entities/Player/Player.cs | 1 - Source/Game/Globals/ObjectManager.cs | 16 +--- Source/Game/Handlers/CharacterHandler.cs | 38 ++++++-- Source/Game/Handlers/MailHandler.cs | 7 -- Source/Game/Mails/MailDraft.cs | 60 ++++++------ 9 files changed, 95 insertions(+), 126 deletions(-) diff --git a/Source/Framework/Database/Databases/CharacterDatabase.cs b/Source/Framework/Database/Databases/CharacterDatabase.cs index 2ed759e59..4a76d2cf7 100644 --- a/Source/Framework/Database/Databases/CharacterDatabase.cs +++ b/Source/Framework/Database/Databases/CharacterDatabase.cs @@ -118,8 +118,6 @@ namespace Framework.Database PrepareStatement(CharStatements.SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?"); PrepareStatement(CharStatements.SEL_CHARACTER_INVENTORY, "SELECT " + SelectItemInstanceContent + ", bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid LEFT JOIN item_instance_transmog iit ON ii.guid = iit.itemGuid LEFT JOIN item_instance_modifiers im ON ii.guid = im.itemGuid WHERE ci.guid = ? ORDER BY (ii.flags & 0x80000) ASC, bag ASC, slot ASC"); PrepareStatement(CharStatements.SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activeTalentGroup AND a.guid = ? ORDER BY button"); - PrepareStatement(CharStatements.SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?"); - PrepareStatement(CharStatements.SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0"); PrepareStatement(CharStatements.SEL_MAIL_COUNT, "SELECT COUNT(*) FROM mail WHERE receiver = ?"); PrepareStatement(CharStatements.SEL_CHARACTER_SOCIALLIST, "SELECT cs.friend, c.account, cs.flags, cs.note FROM character_social cs JOIN characters c ON c.guid = cs.friend WHERE cs.guid = ? AND c.deleteinfos_name IS NULL LIMIT 255"); PrepareStatement(CharStatements.SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ, orientation FROM character_homebind WHERE guid = ?"); @@ -860,8 +858,6 @@ namespace Framework.Database SEL_CHARACTER_INVENTORY, SEL_CHARACTER_ACTIONS, SEL_CHARACTER_ACTIONS_SPEC, - SEL_CHARACTER_MAILCOUNT, - SEL_CHARACTER_MAILDATE, SEL_MAIL_COUNT, SEL_CHARACTER_SOCIALLIST, SEL_CHARACTER_HOMEBIND, diff --git a/Source/Game/Chat/CommandHandler.cs b/Source/Game/Chat/CommandHandler.cs index 9b8eafbab..01e49061a 100644 --- a/Source/Game/Chat/CommandHandler.cs +++ b/Source/Game/Chat/CommandHandler.cs @@ -680,7 +680,7 @@ namespace Game.Chat if (target != null) target_ac_sec = target.GetSecurity(); else if (target_account != 0) - target_ac_sec = Global.AccountMgr.GetSecurity(target_account); + target_ac_sec = Global.AccountMgr.GetSecurity(target_account, (int)Global.WorldMgr.GetRealmId().Index); else return true; // caller must report error for (target == NULL && target_account == 0) diff --git a/Source/Game/Entities/Player/Player.DB.cs b/Source/Game/Entities/Player/Player.DB.cs index 16d59b898..b71b7fd5f 100644 --- a/Source/Game/Entities/Player/Player.DB.cs +++ b/Source/Game/Entities/Player/Player.DB.cs @@ -1180,47 +1180,36 @@ namespace Game.Entities } while (result.NextRow()); } - void _LoadMailInit(SQLResult resultUnread, SQLResult resultDelivery) - { - if (!resultUnread.IsEmpty()) - unReadMails = (byte)resultUnread.Read(0); - if (!resultDelivery.IsEmpty()) - m_nextMailDelivereTime = resultDelivery.Read(0); - } - public void _LoadMail() + public void _LoadMail(SQLResult mailsResult, SQLResult mailItemsResult, SQLResult artifactResult, SQLResult azeriteItemResult, SQLResult azeriteItemMilestonePowersResult, SQLResult azeriteItemUnlockedEssencesResult, SQLResult azeriteEmpoweredItemResult) { m_mail.Clear(); - PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL); - stmt.AddValue(0, GetGUID().GetCounter()); - SQLResult result = DB.Characters.Query(stmt); - Dictionary mailById = new(); - if (!result.IsEmpty()) + if (!mailsResult.IsEmpty()) { do { Mail m = new(); - m.messageID = result.Read(0); - m.messageType = (MailMessageType)result.Read(1); - m.sender = result.Read(2); - m.receiver = result.Read(3); - m.subject = result.Read(4); - m.body = result.Read(5); - m.expire_time = result.Read(6); - m.deliver_time = result.Read(7); - m.money = result.Read(8); - m.COD = result.Read(9); - m.checkMask = (MailCheckMask)result.Read(10); - m.stationery = (MailStationery)result.Read(11); - m.mailTemplateId = result.Read(12); + m.messageID = mailsResult.Read(0); + m.messageType = (MailMessageType)mailsResult.Read(1); + m.sender = mailsResult.Read(2); + m.receiver = mailsResult.Read(3); + m.subject = mailsResult.Read(4); + m.body = mailsResult.Read(5); + m.expire_time = mailsResult.Read(6); + m.deliver_time = mailsResult.Read(7); + m.money = mailsResult.Read(8); + m.COD = mailsResult.Read(9); + m.checkMask = (MailCheckMask)mailsResult.Read(10); + m.stationery = (MailStationery)mailsResult.Read(11); + m.mailTemplateId = mailsResult.Read(12); if (m.mailTemplateId != 0 && !CliDB.MailTemplateStorage.ContainsKey(m.mailTemplateId)) { - Log.outError(LogFilter.Player, "Player:_LoadMail - Mail ({0}) have not existed MailTemplateId ({1}), remove at load", m.messageID, m.mailTemplateId); + Log.outError(LogFilter.Player, $"Player:_LoadMail - Mail ({m.messageID}) have not existed MailTemplateId ({m.mailTemplateId}), remove at load"); m.mailTemplateId = 0; } @@ -1229,47 +1218,23 @@ namespace Game.Entities m_mail.Add(m); mailById[m.messageID] = m; } - while (result.NextRow()); + while (mailsResult.NextRow()); } - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS); - stmt.AddValue(0, GetGUID().GetCounter()); - result = DB.Characters.Query(stmt); - - if (!result.IsEmpty()) + if (!mailItemsResult.IsEmpty()) { - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_ARTIFACT); - stmt.AddValue(0, GetGUID().GetCounter()); - SQLResult artifactResult = DB.Characters.Query(stmt); - - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE); - stmt.AddValue(0, GetGUID().GetCounter()); - SQLResult azeriteResult = DB.Characters.Query(stmt); - - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_MILESTONE_POWER); - stmt.AddValue(0, GetGUID().GetCounter()); - SQLResult azeriteItemMilestonePowersResult = DB.Characters.Query(stmt); - - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE); - stmt.AddValue(0, GetGUID().GetCounter()); - SQLResult azeriteItemUnlockedEssencesResult = DB.Characters.Query(stmt); - - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_EMPOWERED); - stmt.AddValue(0, GetGUID().GetCounter()); - SQLResult azeriteEmpoweredItemResult = DB.Characters.Query(stmt); - Dictionary additionalData = new(); - ItemAdditionalLoadInfo.Init(additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult); + ItemAdditionalLoadInfo.Init(additionalData, artifactResult, azeriteItemResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult); do { - uint mailId = result.Read(52); - _LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], result.GetFields(), additionalData.LookupByKey(result.Read(0))); + uint mailId = mailItemsResult.Read(52); + _LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], mailItemsResult.GetFields(), additionalData.LookupByKey(mailItemsResult.Read(0))); } - while (result.NextRow()); + while (mailItemsResult.NextRow()); } - m_mailsLoaded = true; + UpdateNextMailTimeAndUnreads(); } static Item _LoadMailedItem(ObjectGuid playerGuid, Player player, uint mailId, Mail mail, SQLFields fields, ItemAdditionalLoadInfo addionalData) @@ -2199,9 +2164,6 @@ namespace Game.Entities } public void _SaveMail(SQLTransaction trans) { - if (!m_mailsLoaded) - return; - PreparedStatement stmt; foreach (var m in m_mail) @@ -3174,7 +3136,13 @@ namespace Game.Entities _LoadActions(holder.GetResult(PlayerLoginQueryLoad.Actions)); // unread mails and next delivery time, actual mails not loaded - _LoadMailInit(holder.GetResult(PlayerLoginQueryLoad.MailCount), holder.GetResult(PlayerLoginQueryLoad.MailDate)); + _LoadMail(holder.GetResult(PlayerLoginQueryLoad.Mails), + holder.GetResult(PlayerLoginQueryLoad.MailItems), + holder.GetResult(PlayerLoginQueryLoad.MailItemsArtifact), + holder.GetResult(PlayerLoginQueryLoad.MailItemsAzerite), + holder.GetResult(PlayerLoginQueryLoad.MailItemsAzeriteMilestonePower), + holder.GetResult(PlayerLoginQueryLoad.MailItemsAzeriteUnlockedEssence), + holder.GetResult(PlayerLoginQueryLoad.MailItemsAzeriteEmpowered)); m_social = Global.SocialMgr.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.SocialList), GetGUID()); diff --git a/Source/Game/Entities/Player/Player.Fields.cs b/Source/Game/Entities/Player/Player.Fields.cs index 67124fd82..0092cd991 100644 --- a/Source/Game/Entities/Player/Player.Fields.cs +++ b/Source/Game/Entities/Player/Player.Fields.cs @@ -127,7 +127,6 @@ namespace Game.Entities Dictionary mMitems = new(); public byte unReadMails; long m_nextMailDelivereTime; - public bool m_mailsLoaded; public bool m_mailsUpdated; //Pets diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index c607589c4..8df1f0669 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -2751,7 +2751,6 @@ namespace Game.Entities m_nextMailDelivereTime = deliver_time; } } - public bool IsMailsLoaded() { return m_mailsLoaded; } public void AddMItem(Item it) { mMitems[it.GetGUID().GetCounter()] = it; diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 44f2af5e5..3783b0f9e 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -9440,11 +9440,15 @@ namespace Game uint returnedCount = 0; do { + ulong receiver = result.Read(3); + if (serverUp && Global.ObjAccessor.FindConnectedPlayer(ObjectGuid.Create(HighGuid.Player, receiver))) + continue; + Mail m = new(); m.messageID = result.Read(0); m.messageType = (MailMessageType)result.Read(1); m.sender = result.Read(2); - m.receiver = result.Read(3); + m.receiver = receiver; bool has_items = result.Read(4); m.expire_time = result.Read(5); m.deliver_time = 0; @@ -9452,16 +9456,6 @@ namespace Game m.checkMask = (MailCheckMask)result.Read(7); m.mailTemplateId = result.Read(8); - Player player = null; - if (serverUp) - player = Global.ObjAccessor.FindPlayer(ObjectGuid.Create(HighGuid.Player, m.receiver)); - - if (player && player.m_mailsLoaded) - { // this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail - // his in mailbox and he has already listed his mails) - continue; - } - // Delete or return mail if (has_items) { diff --git a/Source/Game/Handlers/CharacterHandler.cs b/Source/Game/Handlers/CharacterHandler.cs index ea3c4ba0d..0a7581cf7 100644 --- a/Source/Game/Handlers/CharacterHandler.cs +++ b/Source/Game/Handlers/CharacterHandler.cs @@ -2693,14 +2693,33 @@ namespace Game stmt.AddValue(0, lowGuid); SetQuery(PlayerLoginQueryLoad.Actions, stmt); - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_MAILCOUNT); + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAIL); stmt.AddValue(0, lowGuid); - stmt.AddValue(1, GameTime.GetGameTime()); - SetQuery(PlayerLoginQueryLoad.MailCount, stmt); + SetQuery(PlayerLoginQueryLoad.Mails, stmt); - stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_MAILDATE); + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS); stmt.AddValue(0, lowGuid); - SetQuery(PlayerLoginQueryLoad.MailDate, stmt); + SetQuery(PlayerLoginQueryLoad.MailItems, stmt); + + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_ARTIFACT); + stmt.AddValue(0, lowGuid); + SetQuery(PlayerLoginQueryLoad.MailItemsArtifact, stmt); + + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE); + stmt.AddValue(0, lowGuid); + SetQuery(PlayerLoginQueryLoad.MailItemsAzerite, stmt); + + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_MILESTONE_POWER); + stmt.AddValue(0, lowGuid); + SetQuery(PlayerLoginQueryLoad.MailItemsAzeriteMilestonePower, stmt); + + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE); + stmt.AddValue(0, lowGuid); + SetQuery(PlayerLoginQueryLoad.MailItemsAzeriteUnlockedEssence, stmt); + + stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_MAILITEMS_AZERITE_EMPOWERED); + stmt.AddValue(0, lowGuid); + SetQuery(PlayerLoginQueryLoad.MailItemsAzeriteEmpowered, stmt); stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_SOCIALLIST); stmt.AddValue(0, lowGuid); @@ -2884,8 +2903,13 @@ namespace Game AzeriteUnlockedEssences, AzeriteEmpowered, Actions, - MailCount, - MailDate, + Mails, + MailItems, + MailItemsArtifact, + MailItemsAzerite, + MailItemsAzeriteMilestonePower, + MailItemsAzeriteUnlockedEssence, + MailItemsAzeriteEmpowered, SocialList, HomeBind, SpellCooldowns, diff --git a/Source/Game/Handlers/MailHandler.cs b/Source/Game/Handlers/MailHandler.cs index 87fc95324..c20873e37 100644 --- a/Source/Game/Handlers/MailHandler.cs +++ b/Source/Game/Handlers/MailHandler.cs @@ -568,10 +568,6 @@ namespace Game Player player = GetPlayer(); - //load players mails, and mailed items - if (!player.m_mailsLoaded) - player._LoadMail(); - var mails = player.GetMails(); MailListResult response = new(); @@ -658,9 +654,6 @@ namespace Game { MailQueryNextTimeResult result = new(); - if (!GetPlayer().m_mailsLoaded) - GetPlayer()._LoadMail(); - if (GetPlayer().unReadMails > 0) { result.NextMailTime = 0.0f; diff --git a/Source/Game/Mails/MailDraft.cs b/Source/Game/Mails/MailDraft.cs index a2153529b..5b693d920 100644 --- a/Source/Game/Mails/MailDraft.cs +++ b/Source/Game/Mails/MailDraft.cs @@ -159,9 +159,9 @@ namespace Game.Mails // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master) else if (m_COD != 0) - expire_delay = 3 * Time.Day; - else - expire_delay = (uint)(pSender != null && pSender.IsGameMaster() ? 90 * Time.Day : 30 * Time.Day); + expire_delay = 3 * Time.Day; + else + expire_delay = (uint)(pSender != null && pSender.IsGameMaster() ? 90 * Time.Day : 30 * Time.Day); long expire_time = deliver_time + expire_delay; @@ -198,38 +198,34 @@ namespace Game.Mails { pReceiver.AddNewMailDeliverTime(deliver_time); - if (pReceiver.IsMailsLoaded()) + + Mail m = new(); + m.messageID = mailId; + m.mailTemplateId = GetMailTemplateId(); + m.subject = GetSubject(); + m.body = GetBody(); + m.money = GetMoney(); + m.COD = GetCOD(); + + foreach (var item in m_items.Values) + m.AddItem(item.GetGUID().GetCounter(), item.GetEntry()); + + m.messageType = sender.GetMailMessageType(); + m.stationery = sender.GetStationery(); + m.sender = sender.GetSenderId(); + m.receiver = receiver.GetPlayerGUIDLow(); + m.expire_time = expire_time; + m.deliver_time = deliver_time; + m.checkMask = checkMask; + m.state = MailState.Unchanged; + + pReceiver.AddMail(m); // to insert new mail to beginning of maillist + + if (!m_items.Empty()) { - Mail m = new(); - m.messageID = mailId; - m.mailTemplateId = GetMailTemplateId(); - m.subject = GetSubject(); - m.body = GetBody(); - m.money = GetMoney(); - m.COD = GetCOD(); - foreach (var item in m_items.Values) - m.AddItem(item.GetGUID().GetCounter(), item.GetEntry()); - - m.messageType = sender.GetMailMessageType(); - m.stationery = sender.GetStationery(); - m.sender = sender.GetSenderId(); - m.receiver = receiver.GetPlayerGUIDLow(); - m.expire_time = expire_time; - m.deliver_time = deliver_time; - m.checkMask = checkMask; - m.state = MailState.Unchanged; - - pReceiver.AddMail(m); // to insert new mail to beginning of maillist - - if (!m_items.Empty()) - { - foreach (var item in m_items.Values) - pReceiver.AddMItem(item); - } + pReceiver.AddMItem(item); } - else if (!m_items.Empty()) - DeleteIncludedItems(null); } else if (!m_items.Empty()) DeleteIncludedItems(null);