mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 10:05:32 +01:00
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)
This commit is contained in:
@@ -103,8 +103,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, creationTime, 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);
|
||||
@@ -128,7 +126,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, creationTime, 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, creationTime, 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, creationTime, 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);
|
||||
@@ -467,7 +465,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);
|
||||
|
||||
@@ -92,8 +92,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,
|
||||
|
||||
@@ -266,7 +266,6 @@ Player::Player(WorldSession* session): Unit(true)
|
||||
_restFlagMask = 0;
|
||||
////////////////////Rest System/////////////////////
|
||||
|
||||
m_mailsLoaded = false;
|
||||
m_mailsUpdated = false;
|
||||
unReadMails = 0;
|
||||
m_nextMailDelivereTime = 0;
|
||||
@@ -17631,7 +17630,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());
|
||||
|
||||
@@ -18365,34 +18364,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();
|
||||
@@ -18419,24 +18401,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()
|
||||
@@ -20134,9 +20112,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)
|
||||
|
||||
@@ -756,8 +756,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,
|
||||
@@ -1510,7 +1510,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;
|
||||
@@ -1551,7 +1550,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);
|
||||
|
||||
@@ -2465,8 +2463,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void _LoadBoundInstances(PreparedQueryResult result);
|
||||
void _LoadInventory(PreparedQueryResult result, uint32 timeDiff);
|
||||
void _LoadVoidStorage(PreparedQueryResult result);
|
||||
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);
|
||||
|
||||
@@ -5839,11 +5839,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;
|
||||
@@ -5851,17 +5855,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)
|
||||
{
|
||||
|
||||
@@ -135,14 +135,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);
|
||||
|
||||
@@ -662,10 +662,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;
|
||||
|
||||
@@ -839,14 +835,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
|
||||
|
||||
@@ -245,43 +245,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());
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (!m_items.empty())
|
||||
{
|
||||
for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||
pReceiver->AddMItem(mailItemIter->second);
|
||||
}
|
||||
Item* item = mailItemIter->second;
|
||||
m->AddItem(item->GetGUID().GetCounter(), item->GetEntry());
|
||||
}
|
||||
else if (!m_items.empty())
|
||||
|
||||
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
|
||||
|
||||
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())
|
||||
|
||||
Reference in New Issue
Block a user