fix(Core/Mails): mails containing items not being returned if they were read and ensure mails sent by GMs are not returned (#8095)

This commit is contained in:
Skjalf
2021-10-04 10:45:33 -03:00
committed by GitHub
parent e094c1ae78
commit 9330df59da
3 changed files with 13 additions and 9 deletions

View File

@@ -126,7 +126,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_MAIL_ITEM, "INSERT INTO mail_items(mail_id, item_guid, receiver) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_EXPIRED_MAIL, "SELECT id, messageType, sender, receiver, has_items, expire_time, cod, checked, mailTemplateId, auctionId FROM mail WHERE expire_time < ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_EXPIRED_MAIL, "SELECT id, messageType, sender, receiver, has_items, expire_time, stationery, checked, mailTemplateId, auctionId FROM mail WHERE expire_time < ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS, "SELECT item_guid, itemEntry, mail_id FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid LEFT JOIN mail mm ON mi.mail_id = mm.id WHERE mm.id IS NOT NULL AND mm.expire_time < ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_UPD_MAIL_RETURNED, "UPDATE mail SET sender = ?, receiver = ?, expire_time = ?, deliver_time = ?, cod = 0, checked = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_MAIL_ITEM_RECEIVER, "UPDATE mail_items SET receiver = ? WHERE item_guid = ?", CONNECTION_ASYNC);

View File

@@ -5731,7 +5731,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
bool has_items = fields[4].GetBool();
m->expire_time = time_t(fields[5].GetUInt32());
m->deliver_time = time_t(0);
m->COD = fields[6].GetUInt32();
m->stationery = fields[6].GetUInt8();
m->checked = fields[7].GetUInt8();
m->mailTemplateId = fields[8].GetInt16();
m->auctionId = fields[9].GetInt32();
@@ -5752,13 +5752,13 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
// read items from cache
m->items.swap(itemsCache[m->messageID]);
// don't return if: is mail from non-player, or sent to self, or already returned, or read and isn't COD
if (m->messageType != MAIL_NORMAL || m->receiver == m->sender || (m->checked & (MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED)) || ((m->checked & MAIL_CHECK_MASK_READ) && !m->COD))
// If it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
if (!m->IsSentByPlayer() || m->IsSentByGM() || (m->IsCODPayment() || m->IsReturnedMail()))
{
for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
for (auto const& mailedItem : m->items)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
stmt->setUInt32(0, itr2->item_guid);
stmt->setUInt32(0, mailedItem.item_guid);
CharacterDatabase.Execute(stmt);
}
@@ -5777,17 +5777,17 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
stmt->setUInt8 (4, uint8(MAIL_CHECK_MASK_RETURNED));
stmt->setUInt32(5, m->messageID);
CharacterDatabase.Execute(stmt);
for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
for (auto const& mailedItem : m->items)
{
// Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_ITEM_RECEIVER);
stmt->setUInt32(0, m->sender);
stmt->setUInt32(1, itr2->item_guid);
stmt->setUInt32(1, mailedItem.item_guid);
CharacterDatabase.Execute(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
stmt->setUInt32(0, m->sender);
stmt->setUInt32(1, itr2->item_guid);
stmt->setUInt32(1, mailedItem.item_guid);
CharacterDatabase.Execute(stmt);
}

View File

@@ -207,6 +207,10 @@ struct Mail
}
[[nodiscard]] bool HasItems() const { return !items.empty(); }
[[nodiscard]] bool IsSentByPlayer() const { return messageType == MAIL_NORMAL; }
[[nodiscard]] bool IsSentByGM() const { return stationery == MAIL_STATIONERY_GM; }
[[nodiscard]] bool IsCODPayment() const { return checked & MAIL_CHECK_MASK_COD_PAYMENT; }
[[nodiscard]] bool IsReturnedMail() const { return checked & MAIL_CHECK_MASK_RETURNED; }
};
#endif