[10862] Fixed not show and lost mail items in returned expire mails.

Also
* Use typename for mail item info vector.
* Include tools/characters_mail_items_cleanup.sql for cleanup lost mail items.
  It also included as sql update part. Sql update also fix receiver for stored
  in DB expired mail items.

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
Quriq14 2010-12-12 09:02:43 +03:00 committed by VladimirMangos
parent f72e2ccee8
commit c7205a6837
10 changed files with 44 additions and 13 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` (
`required_10664_01_characters_arena_team_stats` bit(1) default NULL
`required_10862_01_characters_mail` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--

View file

@ -0,0 +1,7 @@
DROP TABLE IF EXISTS item_test;
CREATE TABLE item_test
SELECT mi.mail_id, mi.item_guid FROM mail_items as mi WHERE mi.mail_id NOT IN (SELECT id FROM mail);
DELETE item_instance FROM item_instance, item_test WHERE item_instance.guid = item_test.item_guid;
DELETE mail_items FROM mail_items, item_test WHERE mail_items.mail_id = item_test.mail_id;
DROP TABLE IF EXISTS item_test;

View file

@ -0,0 +1,12 @@
ALTER TABLE character_db_version CHANGE COLUMN required_10664_01_characters_arena_team_stats required_10862_01_characters_mail bit;
UPDATE mail_items, mail
SET mail_items.receiver = mail.receiver WHERE mail.id = mail_items.mail_id;
DROP TABLE IF EXISTS item_test;
CREATE TABLE item_test
SELECT mi.mail_id, mi.item_guid FROM mail_items as mi WHERE mi.mail_id NOT IN (SELECT id FROM mail);
DELETE item_instance FROM item_instance, item_test WHERE item_instance.guid = item_test.item_guid;
DELETE mail_items FROM mail_items, item_test WHERE mail_items.mail_id = item_test.mail_id;
DROP TABLE IF EXISTS item_test;

View file

@ -130,6 +130,7 @@ pkgdata_DATA = \
10788_01_mangos_creature_addon.sql \
10788_02_mangos_creature_template_addon.sql \
10835_01_mangos_spell_proc_event.sql \
10862_01_characters_mail.sql \
README
## Additional files to include when running 'make dist'
@ -240,4 +241,5 @@ EXTRA_DIST = \
10788_01_mangos_creature_addon.sql \
10788_02_mangos_creature_template_addon.sql \
10835_01_mangos_spell_proc_event.sql \
10862_01_characters_mail.sql \
README

View file

@ -395,7 +395,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
if(m->HasItems())
{
for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
for(MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
{
if(Item *item = pl->GetMItem(itr2->item_guid))
draft.AddItem(item);

View file

@ -255,6 +255,8 @@ struct MailItemInfo
uint32 item_guid; ///< the GUID of the item.
uint32 item_template; ///< the ID of the template of the item.
};
typedef std::vector<MailItemInfo> MailItemInfoVec;
/**
* Structure that holds an actual mail.
*/
@ -277,7 +279,7 @@ struct Mail
/// the body of the mail
std::string body;
/// A vector containing Information about the items in this mail.
std::vector<MailItemInfo> items;
MailItemInfoVec items;
/// A vector containing Information about the items that where already take from this mail.
std::vector<uint32> removedItems;
/// The time at which this mail will expire
@ -323,7 +325,7 @@ struct Mail
*/
bool RemoveItem(uint32 item_guid)
{
for(std::vector<MailItemInfo>::iterator itr = items.begin(); itr != items.end(); ++itr)
for(MailItemInfoVec::iterator itr = items.begin(); itr != items.end(); ++itr)
{
if(itr->item_guid == item_guid)
{

View file

@ -5508,25 +5508,31 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
delete resultItems;
}
//if it is mail from AH, it shouldn't be returned, but deleted
if (m->messageType != MAIL_NORMAL || m->messageType == MAIL_AUCTION || (m->checked & (MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED)))
// if it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
if (m->messageType != MAIL_NORMAL || (m->checked & (MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED)))
{
// mail open and then not returned
for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
for(MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
}
else
{
//mail will be returned:
// mail will be returned:
CharacterDatabase.PExecute("UPDATE mail SET sender = '%u', receiver = '%u', expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',cod = '0', checked = '%u' WHERE id = '%u'",
m->receiverGuid.GetCounter(), m->sender, (uint64)(basetime + 30*DAY), (uint64)basetime, MAIL_CHECK_MASK_RETURNED, m->messageID);
for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
{
// update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
CharacterDatabase.PExecute("UPDATE mail_items SET receiver = %u WHERE item_guid = '%u'", m->sender, itr2->item_guid);
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = %u WHERE guid = '%u'", m->sender, itr2->item_guid);
}
delete m;
continue;
}
}
//deletemail = true;
//delmails << m->messageID << ", ";
// deletemail = true;
// delmails << m->messageID << ", ";
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
delete m;
++count;

View file

@ -15171,6 +15171,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder *holder )
SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[47].GetUInt64());
SetUInt32Value(PLAYER_AMMO_ID, fields[62].GetUInt32());
// Action bars state
SetByteValue(PLAYER_FIELD_BYTES, 2, fields[64].GetUInt8());
// cleanup inventory related item value fields (its will be filled correctly in _LoadInventory)
@ -17293,7 +17295,7 @@ void Player::_SaveMail()
else if (m->state == MAIL_STATE_DELETED)
{
if (m->HasItems())
for(std::vector<MailItemInfo>::const_iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
for(MailItemInfoVec::const_iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10861"
#define REVISION_NR "10862"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_10664_01_characters_arena_team_stats"
#define REVISION_DB_CHARACTERS "required_10862_01_characters_mail"
#define REVISION_DB_MANGOS "required_10835_01_mangos_spell_proc_event"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__