mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[8764] Simplify code for mail items send. Avoid packet unread spam at errors.
This commit is contained in:
parent
132aed0f0b
commit
d5dad82f3d
9 changed files with 86 additions and 126 deletions
|
|
@ -1713,7 +1713,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
||||||
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||||
|
|
||||||
// item
|
// item
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
mi.AddItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
|
int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
|
||||||
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
|
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
|
||||||
|
|
||||||
MailItemsInfo mi;
|
MailItemsInfo mi;
|
||||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
mi.AddItem(pItem);
|
||||||
|
|
||||||
// item will deleted or added to received mail list
|
// item will deleted or added to received mail list
|
||||||
WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction )
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
MailItemsInfo mi;
|
MailItemsInfo mi;
|
||||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
mi.AddItem(pItem);
|
||||||
|
|
||||||
if (bidder)
|
if (bidder)
|
||||||
bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
|
bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
|
||||||
|
|
@ -262,7 +262,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
|
||||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||||
|
|
||||||
MailItemsInfo mi;
|
MailItemsInfo mi;
|
||||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
mi.AddItem(pItem);
|
||||||
|
|
||||||
// will delete item or place to receiver mail list
|
// will delete item or place to receiver mail list
|
||||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||||
|
|
|
||||||
|
|
@ -935,7 +935,7 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
|
||||||
|
|
||||||
// item
|
// item
|
||||||
MailItemsInfo mi;
|
MailItemsInfo mi;
|
||||||
mi.AddItem(markItem->GetGUIDLow(), markItem->GetEntry(), markItem);
|
mi.AddItem(markItem);
|
||||||
|
|
||||||
// subject: item name
|
// subject: item name
|
||||||
std::string subject = markProto->Name1;
|
std::string subject = markProto->Name1;
|
||||||
|
|
|
||||||
|
|
@ -6230,7 +6230,7 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
|
||||||
if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
|
if(Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
|
||||||
{
|
{
|
||||||
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
mi.AddItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,18 +39,6 @@ enum MailShowFlags
|
||||||
MAIL_SHOW_RETURN = 0x0010,
|
MAIL_SHOW_RETURN = 0x0010,
|
||||||
};
|
};
|
||||||
|
|
||||||
void MailItem::deleteItem( bool inDB )
|
|
||||||
{
|
|
||||||
if(item)
|
|
||||||
{
|
|
||||||
if(inDB)
|
|
||||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
|
|
||||||
|
|
||||||
delete item;
|
|
||||||
item = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
uint64 mailbox, unk3;
|
uint64 mailbox, unk3;
|
||||||
|
|
@ -70,39 +58,35 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
recv_data >> unk1; // stationery?
|
recv_data >> unk1; // stationery?
|
||||||
recv_data >> unk2; // 0x00000000
|
recv_data >> unk2; // 0x00000000
|
||||||
|
|
||||||
MailItemsInfo mi;
|
|
||||||
|
|
||||||
uint8 items_count;
|
uint8 items_count;
|
||||||
recv_data >> items_count; // attached items count
|
recv_data >> items_count; // attached items count
|
||||||
|
|
||||||
if(items_count > 12) // client limit
|
if (items_count > MAX_MAIL_ITEMS) // client limit
|
||||||
{
|
{
|
||||||
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
|
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
|
||||||
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64 itemGUIDs[MAX_MAIL_ITEMS];
|
||||||
|
|
||||||
for(uint8 i = 0; i < items_count; ++i)
|
for(uint8 i = 0; i < items_count; ++i)
|
||||||
{
|
{
|
||||||
uint64 item_guid;
|
|
||||||
recv_data.read_skip<uint8>(); // item slot in mail, not used
|
recv_data.read_skip<uint8>(); // item slot in mail, not used
|
||||||
recv_data >> item_guid;
|
recv_data >> itemGUIDs[i];
|
||||||
mi.AddItem(GUID_LOPART(item_guid));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_data >> money >> COD; // money and cod
|
recv_data >> money >> COD; // money and cod
|
||||||
recv_data >> unk3; // const 0
|
recv_data >> unk3; // const 0
|
||||||
recv_data >> unk4; // const 0
|
recv_data >> unk4; // const 0
|
||||||
|
|
||||||
items_count = mi.size(); // this is the real size after the duplicates have been removed
|
|
||||||
|
|
||||||
if (receiver.empty())
|
if (receiver.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player* pl = _player;
|
Player* pl = _player;
|
||||||
|
|
||||||
uint64 rc = 0;
|
uint64 rc = 0;
|
||||||
if(normalizePlayerName(receiver))
|
if (normalizePlayerName(receiver))
|
||||||
rc = objmgr.GetPlayerGUIDByName(receiver);
|
rc = objmgr.GetPlayerGUIDByName(receiver);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
|
|
@ -115,7 +99,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
|
|
||||||
sLog.outDetail("Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
|
sLog.outDetail("Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
|
||||||
|
|
||||||
if(pl->GetGUID() == rc)
|
if (pl->GetGUID() == rc)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF);
|
||||||
return;
|
return;
|
||||||
|
|
@ -136,7 +120,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
uint32 rc_team = 0;
|
uint32 rc_team = 0;
|
||||||
uint8 mails_count = 0; // do not allow to send to one player more than 100 mails
|
uint8 mails_count = 0; // do not allow to send to one player more than 100 mails
|
||||||
|
|
||||||
if(receive)
|
if (receive)
|
||||||
{
|
{
|
||||||
rc_team = receive->GetTeam();
|
rc_team = receive->GetTeam();
|
||||||
mails_count = receive->GetMailSize();
|
mails_count = receive->GetMailSize();
|
||||||
|
|
@ -144,8 +128,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc_team = objmgr.GetPlayerTeamByGUID(rc);
|
rc_team = objmgr.GetPlayerTeamByGUID(rc);
|
||||||
QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc));
|
if (QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc)))
|
||||||
if(result)
|
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
mails_count = fields[0].GetUInt32();
|
mails_count = fields[0].GetUInt32();
|
||||||
|
|
@ -167,100 +150,95 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 rc_account = 0;
|
uint32 rc_account = receive
|
||||||
if(receive)
|
? receive->GetSession()->GetAccountId()
|
||||||
rc_account = receive->GetSession()->GetAccountId();
|
: objmgr.GetPlayerAccountIdByGUID(rc);
|
||||||
else
|
|
||||||
rc_account = objmgr.GetPlayerAccountIdByGUID(rc);
|
|
||||||
|
|
||||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
Item* items[MAX_MAIL_ITEMS];
|
||||||
|
|
||||||
|
for(uint8 i = 0; i < items_count; ++i)
|
||||||
{
|
{
|
||||||
MailItem& mailItem = mailItemIter->second;
|
if (!itemGUIDs[i])
|
||||||
|
|
||||||
if(!mailItem.item_guidlow)
|
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mailItem.item = pl->GetItemByGuid(MAKE_NEW_GUID(mailItem.item_guidlow, 0, HIGHGUID_ITEM));
|
Item* item = pl->GetItemByGuid(itemGUIDs[i]);
|
||||||
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
||||||
if(!mailItem.item)
|
if (!item)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mailItem.item->CanBeTraded(true))
|
if (!item->CanBeTraded(true))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mailItem.item->IsBoundAccountWide() && mailItem.item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account)
|
if (item->IsBoundAccountWide() && item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION))
|
if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
|
if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items[i] = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
||||||
|
|
||||||
uint32 itemTextId = 0;
|
uint32 itemTextId = !body.empty() ? itemTextId = objmgr.CreateItemText( body ) : 0;
|
||||||
if (!body.empty())
|
|
||||||
{
|
|
||||||
itemTextId = objmgr.CreateItemText( body );
|
|
||||||
}
|
|
||||||
|
|
||||||
pl->ModifyMoney( -int32(reqmoney) );
|
pl->ModifyMoney( -int32(reqmoney) );
|
||||||
pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
|
pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
|
||||||
|
|
||||||
bool needItemDelay = false;
|
bool needItemDelay = false;
|
||||||
|
|
||||||
if(items_count > 0 || money > 0)
|
MailItemsInfo mi;
|
||||||
|
|
||||||
|
if (items_count > 0 || money > 0)
|
||||||
{
|
{
|
||||||
if (items_count > 0)
|
if (items_count > 0)
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
for(uint8 i = 0; i < items_count; ++i)
|
||||||
{
|
{
|
||||||
MailItem& mailItem = mailItemIter->second;
|
Item* item = items[i];
|
||||||
if(!mailItem.item)
|
if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
||||||
continue;
|
|
||||||
|
|
||||||
mailItem.item_template = mailItem.item ? mailItem.item->GetEntry() : 0;
|
|
||||||
|
|
||||||
if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
|
|
||||||
{
|
{
|
||||||
sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)",
|
sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)",
|
||||||
GetPlayerName(), GetAccountId(), mailItem.item->GetProto()->Name1, mailItem.item->GetEntry(), mailItem.item->GetCount(), receiver.c_str(), rc_account);
|
GetPlayerName(), GetAccountId(), item->GetProto()->Name1, item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account);
|
||||||
}
|
}
|
||||||
|
|
||||||
pl->MoveItemFromInventory(mailItem.item->GetBagSlot(), mailItem.item->GetSlot(), true);
|
pl->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
mailItem.item->DeleteFromInventoryDB(); // deletes item from character's inventory
|
item->DeleteFromInventoryDB(); // deletes item from character's inventory
|
||||||
mailItem.item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
|
item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
|
||||||
// owner in data will set at mail receive and item extracting
|
// owner in data will set at mail receive and item extracting
|
||||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), mailItem.item->GetGUIDLow());
|
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), item->GetGUIDLow());
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
|
mi.AddItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if item send to character at another account, then apply item delivery delay
|
// if item send to character at another account, then apply item delivery delay
|
||||||
needItemDelay = pl->GetSession()->GetAccountId() != rc_account;
|
needItemDelay = pl->GetSession()->GetAccountId() != rc_account;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
if (money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
|
||||||
{
|
{
|
||||||
sLog.outCommand(GetAccountId(),"GM %s (Account: %u) mail money: %u to player: %s (Account: %u)",
|
sLog.outCommand(GetAccountId(),"GM %s (Account: %u) mail money: %u to player: %s (Account: %u)",
|
||||||
GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account);
|
GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account);
|
||||||
|
|
@ -365,7 +343,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
Item *item = pl->GetMItem(itr2->item_guid);
|
Item *item = pl->GetMItem(itr2->item_guid);
|
||||||
if(item)
|
if(item)
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
mi.AddItem(item);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//WTF?
|
//WTF?
|
||||||
|
|
@ -413,10 +391,10 @@ void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
||||||
{
|
{
|
||||||
MailItem& mailItem = mailItemIter->second;
|
Item* item = mailItemIter->second;
|
||||||
mailItem.item->SaveToDB(); // item not in inventory and can be save standalone
|
item->SaveToDB(); // item not in inventory and can be save standalone
|
||||||
// owner in data will set at mail receive and item extracting
|
// owner in data will set at mail receive and item extracting
|
||||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, mailItem.item->GetGUIDLow());
|
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, item->GetGUIDLow());
|
||||||
}
|
}
|
||||||
CharacterDatabase.CommitTransaction();
|
CharacterDatabase.CommitTransaction();
|
||||||
}
|
}
|
||||||
|
|
@ -852,6 +830,24 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station
|
||||||
mailTemplateId = 0;
|
mailTemplateId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to DB
|
||||||
|
CharacterDatabase.BeginTransaction();
|
||||||
|
CharacterDatabase.escape_string(subject);
|
||||||
|
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) "
|
||||||
|
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
|
||||||
|
mailId, messageType, stationery, mailTemplateId, sender_guidlow_or_entry, receiver_guidlow, subject.c_str(), itemTextId, (mi && !mi->empty() ? 1 : 0), (uint64)expire_time, (uint64)deliver_time, money, COD, checked);
|
||||||
|
|
||||||
|
if (mi)
|
||||||
|
{
|
||||||
|
for(MailItemMap::const_iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
||||||
|
{
|
||||||
|
Item* item = mailItemIter->second;
|
||||||
|
CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, item->GetGUIDLow(), item->GetEntry(), item->GetGUIDLow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CharacterDatabase.CommitTransaction();
|
||||||
|
|
||||||
|
// For online receiver update in game mail status and data
|
||||||
if (receiver)
|
if (receiver)
|
||||||
{
|
{
|
||||||
receiver->AddNewMailDeliverTime(deliver_time);
|
receiver->AddNewMailDeliverTime(deliver_time);
|
||||||
|
|
@ -883,11 +879,7 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station
|
||||||
if (mi)
|
if (mi)
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
||||||
{
|
receiver->AddMItem(mailItemIter->second);
|
||||||
MailItem& mailItem = mailItemIter->second;
|
|
||||||
if (mailItem.item)
|
|
||||||
receiver->AddMItem(mailItem.item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mi)
|
else if (mi)
|
||||||
|
|
@ -895,22 +887,6 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station
|
||||||
}
|
}
|
||||||
else if (mi)
|
else if (mi)
|
||||||
mi->deleteIncludedItems();
|
mi->deleteIncludedItems();
|
||||||
|
|
||||||
CharacterDatabase.BeginTransaction();
|
|
||||||
CharacterDatabase.escape_string(subject);
|
|
||||||
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) "
|
|
||||||
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
|
|
||||||
mailId, messageType, stationery, mailTemplateId, sender_guidlow_or_entry, receiver_guidlow, subject.c_str(), itemTextId, (mi && !mi->empty() ? 1 : 0), (uint64)expire_time, (uint64)deliver_time, money, COD, checked);
|
|
||||||
|
|
||||||
if (mi)
|
|
||||||
{
|
|
||||||
for(MailItemMap::const_iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
|
||||||
{
|
|
||||||
MailItem const& mailItem = mailItemIter->second;
|
|
||||||
CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, mailItem.item_guidlow, mailItem.item_template, receiver_guidlow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CharacterDatabase.CommitTransaction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendMailTo(Player* receiver, Object* sender, uint8 stationery, uint32 receiver_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay, uint16 mailTemplateId)
|
void WorldSession::SendMailTo(Player* receiver, Object* sender, uint8 stationery, uint32 receiver_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay, uint16 mailTemplateId)
|
||||||
|
|
@ -962,7 +938,7 @@ void WorldSession::SendMailTemplateTo(Player* receiver, Object* sender, uint8 st
|
||||||
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,receiver))
|
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,receiver))
|
||||||
{
|
{
|
||||||
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
mi.AddItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,18 +80,7 @@ struct MailItemInfo
|
||||||
uint32 item_template;
|
uint32 item_template;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MailItem
|
typedef std::map<uint32, Item*> MailItemMap;
|
||||||
{
|
|
||||||
MailItem() : item_guidlow(0), item_template(0), item(NULL) {}
|
|
||||||
|
|
||||||
uint32 item_guidlow; // item guid (low part)
|
|
||||||
uint32 item_template; // item entry
|
|
||||||
Item *item; // item pointer
|
|
||||||
|
|
||||||
void deleteItem(bool inDB = false);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<uint32, MailItem> MailItemMap;
|
|
||||||
|
|
||||||
class MailItemsInfo
|
class MailItemsInfo
|
||||||
{
|
{
|
||||||
|
|
@ -101,20 +90,9 @@ class MailItemsInfo
|
||||||
MailItemMap::iterator begin() { return i_MailItemMap.begin(); }
|
MailItemMap::iterator begin() { return i_MailItemMap.begin(); }
|
||||||
MailItemMap::iterator end() { return i_MailItemMap.end(); }
|
MailItemMap::iterator end() { return i_MailItemMap.end(); }
|
||||||
|
|
||||||
void AddItem(uint32 guidlow, uint32 _template, Item *item)
|
void AddItem(Item *item)
|
||||||
{
|
{
|
||||||
MailItem mailItem;
|
i_MailItemMap[item->GetGUIDLow()] = item;
|
||||||
mailItem.item_guidlow = guidlow;
|
|
||||||
mailItem.item_template = _template;
|
|
||||||
mailItem.item = item;
|
|
||||||
i_MailItemMap[guidlow] = mailItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddItem(uint32 guidlow)
|
|
||||||
{
|
|
||||||
MailItem mailItem;
|
|
||||||
mailItem.item_guidlow = guidlow;
|
|
||||||
i_MailItemMap[guidlow] = mailItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 size() const { return i_MailItemMap.size(); }
|
uint8 size() const { return i_MailItemMap.size(); }
|
||||||
|
|
@ -124,9 +102,15 @@ class MailItemsInfo
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = begin(); mailItemIter != end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = begin(); mailItemIter != end(); ++mailItemIter)
|
||||||
{
|
{
|
||||||
MailItem& mailItem = mailItemIter->second;
|
Item* item = mailItemIter->second;
|
||||||
mailItem.deleteItem(inDB);
|
|
||||||
|
if(inDB)
|
||||||
|
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
|
||||||
|
|
||||||
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i_MailItemMap.clear();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
MailItemMap i_MailItemMap; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
|
MailItemMap i_MailItemMap; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
|
||||||
|
|
@ -163,8 +147,8 @@ struct Mail
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = pMailItemsInfo.begin(); mailItemIter != pMailItemsInfo.end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = pMailItemsInfo.begin(); mailItemIter != pMailItemsInfo.end(); ++mailItemIter)
|
||||||
{
|
{
|
||||||
MailItem& mailItem = mailItemIter->second;
|
Item* item = mailItemIter->second;
|
||||||
AddItem(mailItem.item_guidlow, mailItem.item_template);
|
AddItem(item->GetGUIDLow(), item->GetEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3963,7 +3963,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mi.AddItem(item_guidlow, item_template, pItem);
|
mi.AddItem(pItem);
|
||||||
}
|
}
|
||||||
while (resultItems->NextRow());
|
while (resultItems->NextRow());
|
||||||
|
|
||||||
|
|
@ -14949,7 +14949,7 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
|
||||||
Item* item = problematicItems.front();
|
Item* item = problematicItems.front();
|
||||||
problematicItems.pop_front();
|
problematicItems.pop_front();
|
||||||
|
|
||||||
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
|
mi.AddItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
||||||
|
|
@ -18823,7 +18823,7 @@ void Player::AutoUnequipOffhandIfNeed()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MailItemsInfo mi;
|
MailItemsInfo mi;
|
||||||
mi.AddItem(offItem->GetGUIDLow(), offItem->GetEntry(), offItem);
|
mi.AddItem(offItem);
|
||||||
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
|
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
|
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8763"
|
#define REVISION_NR "8764"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue