diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-07-30 20:38:04 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-07-30 20:38:04 +0200 |
commit | 57eaab80d9e1f6f25274f376da16e1f2f67ab4bc (patch) | |
tree | d0031051d676b956283fddc191bbfea9fe866572 /src | |
parent | e94350fcc31cedb5a8140a71e2b2a03ab4125927 (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)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 6 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 9 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Handlers/MailHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Mails/Mail.cpp | 56 |
8 files changed, 47 insertions, 103 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index dd161ef98cc..ab0d938d434 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -97,8 +97,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, bag, slot, " "item, itemEntry FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC); PrepareStatement(CHAR_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", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_MAIL_COUNT, "SELECT COUNT(*) FROM mail WHERE receiver = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHARACTER_SOCIALLIST, "SELECT friend, flags, note FROM character_social JOIN characters ON characters.guid = character_social.friend WHERE character_social.guid = ? AND deleteinfos_name IS NULL LIMIT 255", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC); @@ -122,7 +120,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, item_guid, itemEntry, ii.owner_guid, m.id FROM mail_items mi INNER JOIN mail m ON mi.mail_id = m.id LEFT JOIN item_instance ii ON mi.item_guid = ii.guid WHERE m.receiver = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, item_guid, itemEntry, ii.owner_guid, m.id FROM mail_items mi INNER JOIN mail m ON mi.mail_id = m.id LEFT JOIN item_instance ii ON mi.item_guid = ii.guid WHERE m.receiver = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, itemguid, itemEntry FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, houseid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH); PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, houseid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); @@ -428,7 +426,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH); + PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index f5c5c909f8a..98a40671671 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -86,8 +86,6 @@ enum CharacterDatabaseStatements : uint32 CHAR_SEL_CHARACTER_INVENTORY, CHAR_SEL_CHARACTER_ACTIONS, CHAR_SEL_CHARACTER_ACTIONS_SPEC, - CHAR_SEL_CHARACTER_MAILCOUNT, - CHAR_SEL_CHARACTER_MAILDATE, CHAR_SEL_MAIL_COUNT, CHAR_SEL_CHARACTER_SOCIALLIST, CHAR_SEL_CHARACTER_HOMEBIND, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 80ac886585d..123f9886cb3 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -297,7 +297,6 @@ Player::Player(WorldSession* session): Unit(true) _restFlagMask = 0; ////////////////////Rest System///////////////////// - m_mailsLoaded = false; m_mailsUpdated = false; unReadMails = 0; m_nextMailDelivereTime = 0; @@ -17807,7 +17806,7 @@ 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)); m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID()); @@ -18444,34 +18443,17 @@ 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) { m_mail.clear(); - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL); - stmt->setUInt32(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(); @@ -18499,24 +18481,20 @@ 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->setUInt32(0, GetGUID().GetCounter()); - result = CharacterDatabase.Query(stmt); - - if (result) + if (mailItemsResult) { do { - Field* fields = result->Fetch(); + Field* fields = mailItemsResult->Fetch(); uint32 mailId = fields[14].GetUInt32(); _LoadMailedItem(GetGUID(), this, mailId, mailById[mailId], fields); - } while (result->NextRow()); + } while (mailItemsResult->NextRow()); } - m_mailsLoaded = true; + UpdateNextMailTimeAndUnreads(); } void Player::LoadPet() @@ -19923,9 +19901,6 @@ void Player::_SaveInventory(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 542cca2f29f..a1d191b48e3 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -709,8 +709,8 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7, PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8, PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9, - PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT = 10, - PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE = 11, + PLAYER_LOGIN_QUERY_LOAD_MAILS = 10, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11, PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 12, PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 13, PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 14, @@ -1346,7 +1346,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; @@ -1380,7 +1379,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); @@ -2227,8 +2225,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void _LoadGlyphAuras(); void _LoadBoundInstances(PreparedQueryResult result); void _LoadInventory(PreparedQueryResult result, uint32 timeDiff); - void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery); - void _LoadMail(); + void _LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mailItemsResult); static Item* _LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint32 mailId, Mail* mail, Field* fields); void _LoadQuestStatus(PreparedQueryResult result); void _LoadQuestStatusRewarded(PreparedQueryResult result); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 52eca422e6c..57a773eab2b 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6274,11 +6274,15 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) do { Field* fields = result->Fetch(); + ObjectGuid::LowType receiver = fields[3].GetUInt32(); + if (serverUp && ObjectAccessor::FindConnectedPlayer(ObjectGuid(HighGuid::Player, receiver))) + continue; + Mail* m = new Mail; m->messageID = fields[0].GetUInt32(); m->messageType = fields[1].GetUInt8(); m->sender = fields[2].GetUInt32(); - m->receiver = fields[3].GetUInt32(); + m->receiver = receiver; bool has_items = fields[4].GetBool(); m->expire_time = time_t(fields[5].GetUInt32()); m->deliver_time = 0; @@ -6286,17 +6290,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(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 e935fb8847e..fbb7c4213cb 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -124,14 +124,13 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ACTIONS, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILCOUNT); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL); stmt->setUInt32(0, lowGuid); - stmt->setUInt64(1, uint64(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->setUInt32(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_CHARACTER_SOCIALLIST); stmt->setUInt32(0, lowGuid); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 7e2963a93fa..cca8f2b0c67 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -604,10 +604,6 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData) Player* player = _player; - //load players mails, and mailed items - if (!player->m_mailsLoaded) - player->_LoadMail(); - // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; @@ -776,14 +772,10 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) } } -/// @todo Fix me! ... this void has probably bad condition, but good data are sent void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recvData*/) { WorldPacket data(MSG_QUERY_NEXT_MAIL_TIME, 8); - if (!_player->m_mailsLoaded) - _player->_LoadMail(); - if (_player->unReadMails > 0) { data << float(0); // float diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index c42bd2a8e63..3233123c11a 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -250,43 +250,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()) |