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)
This commit is contained in:
hondacrx
2022-03-02 09:52:35 -05:00
parent 6e6ee2d694
commit 150b09205b
9 changed files with 95 additions and 126 deletions
@@ -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,
+1 -1
View File
@@ -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)
+30 -62
View File
@@ -1180,47 +1180,36 @@ namespace Game.Entities
}
while (result.NextRow());
}
void _LoadMailInit(SQLResult resultUnread, SQLResult resultDelivery)
{
if (!resultUnread.IsEmpty())
unReadMails = (byte)resultUnread.Read<ulong>(0);
if (!resultDelivery.IsEmpty())
m_nextMailDelivereTime = resultDelivery.Read<uint>(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<uint, Mail> mailById = new();
if (!result.IsEmpty())
if (!mailsResult.IsEmpty())
{
do
{
Mail m = new();
m.messageID = result.Read<uint>(0);
m.messageType = (MailMessageType)result.Read<byte>(1);
m.sender = result.Read<uint>(2);
m.receiver = result.Read<uint>(3);
m.subject = result.Read<string>(4);
m.body = result.Read<string>(5);
m.expire_time = result.Read<long>(6);
m.deliver_time = result.Read<long>(7);
m.money = result.Read<ulong>(8);
m.COD = result.Read<ulong>(9);
m.checkMask = (MailCheckMask)result.Read<byte>(10);
m.stationery = (MailStationery)result.Read<byte>(11);
m.mailTemplateId = result.Read<ushort>(12);
m.messageID = mailsResult.Read<uint>(0);
m.messageType = (MailMessageType)mailsResult.Read<byte>(1);
m.sender = mailsResult.Read<uint>(2);
m.receiver = mailsResult.Read<uint>(3);
m.subject = mailsResult.Read<string>(4);
m.body = mailsResult.Read<string>(5);
m.expire_time = mailsResult.Read<long>(6);
m.deliver_time = mailsResult.Read<long>(7);
m.money = mailsResult.Read<ulong>(8);
m.COD = mailsResult.Read<ulong>(9);
m.checkMask = (MailCheckMask)mailsResult.Read<byte>(10);
m.stationery = (MailStationery)mailsResult.Read<byte>(11);
m.mailTemplateId = mailsResult.Read<ushort>(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<ulong, ItemAdditionalLoadInfo> additionalData = new();
ItemAdditionalLoadInfo.Init(additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult);
ItemAdditionalLoadInfo.Init(additionalData, artifactResult, azeriteItemResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult);
do
{
uint mailId = result.Read<uint>(52);
_LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], result.GetFields(), additionalData.LookupByKey(result.Read<ulong>(0)));
uint mailId = mailItemsResult.Read<uint>(52);
_LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], mailItemsResult.GetFields(), additionalData.LookupByKey(mailItemsResult.Read<ulong>(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());
@@ -127,7 +127,6 @@ namespace Game.Entities
Dictionary<ulong, Item> mMitems = new();
public byte unReadMails;
long m_nextMailDelivereTime;
public bool m_mailsLoaded;
public bool m_mailsUpdated;
//Pets
-1
View File
@@ -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;
+5 -11
View File
@@ -9440,11 +9440,15 @@ namespace Game
uint returnedCount = 0;
do
{
ulong receiver = result.Read<ulong>(3);
if (serverUp && Global.ObjAccessor.FindConnectedPlayer(ObjectGuid.Create(HighGuid.Player, receiver)))
continue;
Mail m = new();
m.messageID = result.Read<uint>(0);
m.messageType = (MailMessageType)result.Read<byte>(1);
m.sender = result.Read<uint>(2);
m.receiver = result.Read<ulong>(3);
m.receiver = receiver;
bool has_items = result.Read<bool>(4);
m.expire_time = result.Read<long>(5);
m.deliver_time = 0;
@@ -9452,16 +9456,6 @@ namespace Game
m.checkMask = (MailCheckMask)result.Read<byte>(7);
m.mailTemplateId = result.Read<ushort>(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)
{
+31 -7
View File
@@ -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,
-7
View File
@@ -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;
+28 -32
View File
@@ -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);