diff options
| author | Shauren <shauren.trinity@gmail.com> | 2020-07-30 20:38:04 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-01-24 14:45:54 +0100 |
| commit | a9b4f9aca0d0b90e59e0ed26e9bb4cce7d0ceeab (patch) | |
| tree | c74e0a8e353302b085122869993ae0701a887d6d /src/server/game | |
| parent | 54a6e603ffc8b4913669cf0f189a966d25b620d8 (diff) | |
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)
(cherry picked from commit 57eaab80d9e1f6f25274f376da16e1f2f67ab4bc)
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 73 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 15 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 17 | ||||
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 29 | ||||
| -rw-r--r-- | src/server/game/Handlers/MailHandler.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Mails/Mail.cpp | 56 |
6 files changed, 79 insertions, 119 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f3798736082..b33e9b61cd1 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -247,7 +247,6 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this) m_oldpetspell = 0; m_lastpetnumber = 0; - m_mailsLoaded = false; m_mailsUpdated = false; unReadMails = 0; m_nextMailDelivereTime = 0; @@ -18525,7 +18524,13 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) _LoadActions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACTIONS)); // unread mails and next delivery time, actual mails not loaded - _LoadMailInit(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE)); + _LoadMail(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAILS), + holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS), + holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_ARTIFACT), + holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE), + holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_MILESTONE_POWER), + holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_UNLOCKED_ESSENCE), + holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_EMPOWERED)); m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID()); @@ -19399,34 +19404,18 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint return item; } -void Player::_LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery) -{ - //set a count of unread mails - //QueryResult* resultMails = CharacterDatabase.PQuery("SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(playerGuid), (uint64)cTime); - if (resultUnread) - unReadMails = uint8((*resultUnread)[0].GetUInt64()); - - // store nearest delivery time (it > 0 and if it < current then at next player update SendNewMaill will be called) - //resultMails = CharacterDatabase.PQuery("SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(playerGuid)); - if (resultDelivery) - m_nextMailDelivereTime = time_t((*resultDelivery)[0].GetUInt32()); -} - -void Player::_LoadMail() +void Player::_LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mailItemsResult, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult, + PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult, PreparedQueryResult azeriteEmpoweredItemResult) { m_mail.clear(); - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL); - stmt->setUInt64(0, GetGUID().GetCounter()); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - std::unordered_map<uint32, Mail*> mailById; - if (result) + if (mailsResult) { do { - Field* fields = result->Fetch(); + Field* fields = mailsResult->Fetch(); Mail* m = new Mail(); m->messageID = fields[0].GetUInt32(); @@ -19454,49 +19443,24 @@ void Player::_LoadMail() m_mail.push_back(m); mailById[m->messageID] = m; } - while (result->NextRow()); + while (mailsResult->NextRow()); } - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS); - stmt->setUInt64(0, GetGUID().GetCounter()); - result = CharacterDatabase.Query(stmt); - - if (result) + if (mailItemsResult) { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_ARTIFACT); - stmt->setUInt64(0, GetGUID().GetCounter()); - PreparedQueryResult artifactResult = CharacterDatabase.Query(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE); - stmt->setUInt64(0, GetGUID().GetCounter()); - PreparedQueryResult azeriteResult = CharacterDatabase.Query(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_MILESTONE_POWER); - stmt->setUInt64(0, GetGUID().GetCounter()); - PreparedQueryResult azeriteItemMilestonePowersResult = CharacterDatabase.Query(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE); - stmt->setUInt64(0, GetGUID().GetCounter()); - PreparedQueryResult azeriteItemUnlockedEssencesResult = CharacterDatabase.Query(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_EMPOWERED); - stmt->setUInt64(0, GetGUID().GetCounter()); - PreparedQueryResult azeriteEmpoweredItemResult = CharacterDatabase.Query(stmt); - std::unordered_map<ObjectGuid::LowType, ItemAdditionalLoadInfo> additionalData; - ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteResult, azeriteItemMilestonePowersResult, + ItemAdditionalLoadInfo::Init(&additionalData, artifactResult, azeriteItemResult, azeriteItemMilestonePowersResult, azeriteItemUnlockedEssencesResult, azeriteEmpoweredItemResult); do { - Field* fields = result->Fetch(); + Field* fields = mailItemsResult->Fetch(); uint32 mailId = fields[52].GetUInt32(); _LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], fields, Trinity::Containers::MapGetValuePtr(additionalData, fields[0].GetUInt64())); - } - while (result->NextRow()); + } while (mailItemsResult->NextRow()); } - m_mailsLoaded = true; + UpdateNextMailTimeAndUnreads(); } void Player::LoadPet() @@ -21190,9 +21154,6 @@ void Player::_SaveCUFProfiles(CharacterDatabaseTransaction& trans) void Player::_SaveMail(CharacterDatabaseTransaction& trans) { - if (!m_mailsLoaded) - return; - CharacterDatabasePreparedStatement* stmt; for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 965fbe7d00a..26e013d2b63 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -854,8 +854,13 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOAD_AZERITE_UNLOCKED_ESSENCES, PLAYER_LOGIN_QUERY_LOAD_AZERITE_EMPOWERED, PLAYER_LOGIN_QUERY_LOAD_ACTIONS, - PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT, - PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE, + PLAYER_LOGIN_QUERY_LOAD_MAILS, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_ARTIFACT, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_MILESTONE_POWER, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_UNLOCKED_ESSENCE, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_EMPOWERED, PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST, PLAYER_LOGIN_QUERY_LOAD_HOME_BIND, PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS, @@ -1684,7 +1689,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static void DeleteOldCharacters(); static void DeleteOldCharacters(uint32 keepDays); - bool m_mailsLoaded; bool m_mailsUpdated; void SetBindPoint(ObjectGuid guid) const; @@ -1717,7 +1721,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendNewMail() const; void UpdateNextMailTimeAndUnreads(); void AddNewMailDeliverTime(time_t deliver_time); - bool IsMailsLoaded() const { return m_mailsLoaded; } void RemoveMail(uint32 id); @@ -2804,8 +2807,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult, PreparedQueryResult azeriteEmpoweredItemResult, uint32 timeDiff); void _LoadVoidStorage(PreparedQueryResult result); - void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery); - void _LoadMail(); + void _LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mailItemsResult, PreparedQueryResult artifactResult, PreparedQueryResult azeriteItemResult, + PreparedQueryResult azeriteItemMilestonePowersResult, PreparedQueryResult azeriteItemUnlockedEssencesResult, PreparedQueryResult azeriteEmpoweredItemResult); static Item* _LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint32 mailId, Mail* mail, Field* fields, ItemAdditionalLoadInfo* addionalData); void _LoadQuestStatus(PreparedQueryResult result); void _LoadQuestStatusObjectives(PreparedQueryResult result); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 62ae41babdd..a82aae71be1 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6409,11 +6409,15 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) do { Field* fields = result->Fetch(); + ObjectGuid::LowType receiver = fields[3].GetUInt64(); + if (serverUp && ObjectAccessor::FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(receiver))) + continue; + Mail* m = new Mail; m->messageID = fields[0].GetUInt32(); m->messageType = fields[1].GetUInt8(); m->sender = fields[2].GetUInt64(); - m->receiver = fields[3].GetUInt64(); + m->receiver = receiver; bool has_items = fields[4].GetBool(); m->expire_time = fields[5].GetInt64(); m->deliver_time = 0; @@ -6421,17 +6425,6 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) m->checked = fields[7].GetUInt8(); m->mailTemplateId = fields[8].GetInt16(); - Player* player = nullptr; - if (serverUp) - player = ObjectAccessor::FindConnectedPlayer(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) - delete m; - continue; - } - // Delete or return mail if (has_items) { diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index b1359f1f064..ef67ac1b114 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -183,14 +183,33 @@ bool LoginQueryHolder::Initialize() stmt->setUInt64(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ACTIONS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILCOUNT); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL); stmt->setUInt64(0, lowGuid); - stmt->setUInt64(1, GameTime::GetGameTime()); - res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT, stmt); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAILS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILDATE); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS); stmt->setUInt64(0, lowGuid); - res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE, stmt); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS, stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_ARTIFACT); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_ARTIFACT, stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE, stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_MILESTONE_POWER); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_MILESTONE_POWER, stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_UNLOCKED_ESSENCE); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_UNLOCKED_ESSENCE, stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAILITEMS_AZERITE_EMPOWERED); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS_AZERITE_EMPOWERED, stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SOCIALLIST); stmt->setUInt64(0, lowGuid); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index f2c9a767dba..f2b4f4a79f4 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -572,10 +572,6 @@ void WorldSession::HandleGetMailList(WorldPackets::Mail::MailGetList& packet) Player* player = _player; - //load players mails, and mailed items - if (!player->m_mailsLoaded) - player->_LoadMail(); - WorldPackets::Mail::MailListResult response; time_t curTime = GameTime::GetGameTime(); @@ -655,14 +651,10 @@ void WorldSession::HandleMailCreateTextItem(WorldPackets::Mail::MailCreateTextIt } } -/// @todo Fix me! ... this void has probably bad condition, but good data are sent void WorldSession::HandleQueryNextMailTime(WorldPackets::Mail::MailQueryNextMailTime& /*packet*/) { WorldPackets::Mail::MailQueryNextTimeResult result; - if (!_player->m_mailsLoaded) - _player->_LoadMail(); - if (_player->unReadMails > 0) { result.NextMailTime = 0.0f; diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index c9ad975540b..731607645ae 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -252,43 +252,35 @@ void MailDraft::SendMailTo(CharacterDatabaseTransaction& trans, MailReceiver con { pReceiver->AddNewMailDeliverTime(deliver_time); - if (pReceiver->IsMailsLoaded()) + Mail* m = new Mail; + m->messageID = mailId; + m->mailTemplateId = GetMailTemplateId(); + m->subject = GetSubject(); + m->body = GetBody(); + m->money = GetMoney(); + m->COD = GetCOD(); + + for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) { - Mail* m = new Mail; - m->messageID = mailId; - m->mailTemplateId = GetMailTemplateId(); - m->subject = GetSubject(); - m->body = GetBody(); - m->money = GetMoney(); - m->COD = GetCOD(); - - for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) - { - Item* item = mailItemIter->second; - m->AddItem(item->GetGUID().GetCounter(), item->GetEntry()); - } + Item* item = mailItemIter->second; + 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->checked = checked; - m->state = MAIL_STATE_UNCHANGED; + 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->checked = checked; + m->state = MAIL_STATE_UNCHANGED; - pReceiver->AddMail(m); // to insert new mail to beginning of maillist + pReceiver->AddMail(m); // to insert new mail to beginning of maillist - if (!m_items.empty()) - { - for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) - pReceiver->AddMItem(mailItemIter->second); - } - } - else if (!m_items.empty()) + if (!m_items.empty()) { - CharacterDatabaseTransaction temp = CharacterDatabaseTransaction(nullptr); - deleteIncludedItems(temp); + for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) + pReceiver->AddMItem(mailItemIter->second); } } else if (!m_items.empty()) |
