mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[8768] Rewrite code for prepare and send mails.
* Move send functions to new MailDraft class from WorldSession * Simplify use different args combinations used in SendMailTo by groupping its by functionality in Helper classes. This also will prevent wrong way use args combinations.
This commit is contained in:
parent
50e80d67f9
commit
d009994f59
12 changed files with 381 additions and 317 deletions
|
|
@ -1706,16 +1706,6 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
|||
{
|
||||
Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL;
|
||||
|
||||
MailItemsInfo mi;
|
||||
if(item)
|
||||
{
|
||||
// save new item before send
|
||||
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||
|
||||
// item
|
||||
mi.AddItem(item);
|
||||
}
|
||||
|
||||
int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
|
||||
|
||||
// subject and text
|
||||
|
|
@ -1734,7 +1724,18 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
|||
|
||||
uint32 itemTextId = objmgr.CreateItemText( text );
|
||||
|
||||
WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft draft(subject, itemTextId);
|
||||
|
||||
if(item)
|
||||
{
|
||||
// save new item before send
|
||||
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||
|
||||
// item
|
||||
draft.AddItem(item);
|
||||
}
|
||||
|
||||
draft.SendMailTo(GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,9 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri
|
|||
if (oldBidder)
|
||||
oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
|
||||
|
||||
WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft(msgAuctionOutbiddedSubject.str())
|
||||
.AddMoney(auction->bid)
|
||||
.SendMailTo(MailReceiver(oldBidder, auction->bidder), auction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +144,9 @@ void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction )
|
|||
std::ostringstream msgAuctionCancelledSubject;
|
||||
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER;
|
||||
|
||||
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft(msgAuctionCancelledSubject.str())
|
||||
.AddMoney(auction->bid)
|
||||
.SendMailTo(MailReceiver(bidder, auction->bidder), auction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -443,11 +447,10 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
|
|||
std::ostringstream msgAuctionCanceledOwner;
|
||||
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(pItem);
|
||||
|
||||
// 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);
|
||||
MailDraft(msgAuctionCanceledOwner.str())
|
||||
.AddItem(pItem)
|
||||
.SendMailTo(pl, auction);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,16 +141,15 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction )
|
|||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(pItem);
|
||||
|
||||
if (bidder)
|
||||
bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
|
||||
else
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
|
||||
MailDraft(msgAuctionWonSubject.str(), itemTextId)
|
||||
.AddItem(pItem)
|
||||
.SendMailTo(MailReceiver(bidder,auction->bidder), auction, MAIL_CHECK_MASK_AUCTION);
|
||||
}
|
||||
// receiver not exist
|
||||
else
|
||||
|
|
@ -187,7 +186,8 @@ void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
|
|||
|
||||
uint32 itemTextId = objmgr.CreateItemText( msgAuctionSalePendingBody.str() );
|
||||
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
|
||||
MailDraft(msgAuctionSalePendingSubject.str(), itemTextId)
|
||||
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +229,9 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
|
|||
owner->GetSession()->SendAuctionOwnerNotification( auction );
|
||||
}
|
||||
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR);
|
||||
MailDraft(msgAuctionSuccessfulSubject.str(), itemTextId)
|
||||
.AddMoney(profit)
|
||||
.SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_AUCTION, HOUR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -261,11 +263,10 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
|
|||
else
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(pItem);
|
||||
|
||||
// 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);
|
||||
MailDraft(subject.str())
|
||||
.AddItem(pItem)
|
||||
.SendMailTo(MailReceiver(owner,auction->owner), auction);
|
||||
}
|
||||
// owner not found
|
||||
else
|
||||
|
|
|
|||
|
|
@ -933,10 +933,6 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
|
|||
// save new item before send
|
||||
markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
|
||||
|
||||
// item
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(markItem);
|
||||
|
||||
// subject: item name
|
||||
std::string subject = markProto->Name1;
|
||||
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
|
||||
|
|
@ -951,7 +947,9 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
|
|||
snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName());
|
||||
uint32 itemTextId = objmgr.CreateItemText( textBuf );
|
||||
|
||||
WorldSession::SendMailTo(plr, MAIL_CREATURE, MAIL_STATIONERY_NORMAL, bmEntry, plr->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft(subject, itemTextId)
|
||||
.AddItem(markItem)
|
||||
.SendMailTo(plr, MailSender(MAIL_CREATURE, bmEntry));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2003,13 +2003,12 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
|
|||
std::string text = msgText;
|
||||
|
||||
// from console show not existed sender
|
||||
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
|
||||
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
|
||||
|
||||
uint32 messagetype = MAIL_NORMAL;
|
||||
uint32 stationery = MAIL_STATIONERY_GM;
|
||||
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
|
||||
|
||||
WorldSession::SendMailTo(target,messagetype, stationery, sender_guidlo, GUID_LOPART(target_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft(subject, itemTextId)
|
||||
.SendMailTo(MailReceiver(target,GUID_LOPART(target_guid)),sender);
|
||||
|
||||
std::string nameLink = playerLink(target_name);
|
||||
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
||||
|
|
|
|||
|
|
@ -6216,25 +6216,23 @@ bool ChatHandler::HandleSendItemsCommand(const char* args)
|
|||
}
|
||||
|
||||
// from console show not existed sender
|
||||
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
|
||||
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
|
||||
|
||||
uint32 messagetype = MAIL_NORMAL;
|
||||
uint32 stationery = MAIL_STATIONERY_GM;
|
||||
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
|
||||
|
||||
// fill mail
|
||||
MailItemsInfo mi; // item list preparing
|
||||
MailDraft draft(subject, itemTextId);
|
||||
|
||||
for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
|
||||
{
|
||||
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
|
||||
mi.AddItem(item);
|
||||
draft.AddItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
|
||||
|
||||
std::string nameLink = playerLink(receiver_name);
|
||||
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
||||
|
|
@ -6278,13 +6276,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
|
|||
std::string text = msgText;
|
||||
|
||||
// from console show not existed sender
|
||||
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
|
||||
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
|
||||
|
||||
uint32 messagetype = MAIL_NORMAL;
|
||||
uint32 stationery = MAIL_STATIONERY_GM;
|
||||
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
|
||||
|
||||
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft(subject, itemTextId)
|
||||
.AddMoney(money)
|
||||
.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
|
||||
|
||||
std::string nameLink = playerLink(receiver_name);
|
||||
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "DBCStores.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "Item.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
|
||||
enum MailShowFlags
|
||||
{
|
||||
|
|
@ -40,36 +41,6 @@ enum MailShowFlags
|
|||
MAIL_SHOW_RETURN = 0x0010,
|
||||
};
|
||||
|
||||
|
||||
void MailItemsInfo::deleteIncludedItems( bool inDB /*= false*/ )
|
||||
{
|
||||
for(MailItemMap::iterator mailItemIter = begin(); mailItemIter != end(); ++mailItemIter)
|
||||
{
|
||||
Item* item = mailItemIter->second;
|
||||
|
||||
if(inDB)
|
||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
i_MailItemMap.clear();
|
||||
}
|
||||
|
||||
void MailItemsInfo::AddItem( Item *item )
|
||||
{
|
||||
i_MailItemMap[item->GetGUIDLow()] = item;
|
||||
}
|
||||
|
||||
void Mail::AddAllItems( MailItemsInfo& pMailItemsInfo )
|
||||
{
|
||||
for(MailItemMap::iterator mailItemIter = pMailItemsInfo.begin(); mailItemIter != pMailItemsInfo.end(); ++mailItemIter)
|
||||
{
|
||||
Item* item = mailItemIter->second;
|
||||
AddItem(item->GetGUIDLow(), item->GetEntry());
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||
{
|
||||
uint64 mailbox, unk3;
|
||||
|
|
@ -79,9 +50,6 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
recv_data >> mailbox;
|
||||
recv_data >> receiver;
|
||||
|
||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||
return;
|
||||
|
||||
recv_data >> subject;
|
||||
|
||||
recv_data >> body;
|
||||
|
|
@ -111,6 +79,11 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
recv_data >> unk3; // const 0
|
||||
recv_data >> unk4; // const 0
|
||||
|
||||
// packet read complete, now do check
|
||||
|
||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||
return;
|
||||
|
||||
if (receiver.empty())
|
||||
return;
|
||||
|
||||
|
|
@ -196,8 +169,9 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
}
|
||||
|
||||
Item* item = pl->GetItemByGuid(itemGUIDs[i]);
|
||||
|
||||
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
||||
if (!item)
|
||||
if(!item)
|
||||
{
|
||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||
return;
|
||||
|
|
@ -239,7 +213,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
|
||||
bool needItemDelay = false;
|
||||
|
||||
MailItemsInfo mi;
|
||||
MailDraft draft(subject, itemTextId);
|
||||
|
||||
if (items_count > 0 || money > 0)
|
||||
{
|
||||
|
|
@ -262,7 +236,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), item->GetGUIDLow());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
mi.AddItem(item);
|
||||
draft.AddItem(item);
|
||||
}
|
||||
|
||||
// if item send to character at another account, then apply item delivery delay
|
||||
|
|
@ -280,7 +254,10 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, pl->GetGUIDLow(), GUID_LOPART(rc), subject, itemTextId, &mi, money, COD, MAIL_CHECK_MASK_NONE, deliver_delay);
|
||||
draft
|
||||
.AddMoney(money)
|
||||
.AddCOD(COD)
|
||||
.SendMailTo(MailReceiver(receive, GUID_LOPART(rc)), pl, MAIL_CHECK_MASK_NONE, deliver_delay);
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
pl->SaveInventoryAndGoldToDB();
|
||||
|
|
@ -345,11 +322,12 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
|||
uint64 mailbox;
|
||||
uint32 mailId;
|
||||
recv_data >> mailbox;
|
||||
recv_data >> mailId;
|
||||
recv_data.read_skip<uint64>(); // original sender GUID for return to, not used
|
||||
|
||||
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
|
||||
return;
|
||||
|
||||
recv_data >> mailId;
|
||||
Player *pl = _player;
|
||||
Mail *m = pl->GetMail(mailId);
|
||||
if(!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL))
|
||||
|
|
@ -366,7 +344,12 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
|||
CharacterDatabase.CommitTransaction();
|
||||
pl->RemoveMail(mailId);
|
||||
|
||||
MailItemsInfo mi;
|
||||
// send back only to players and simple drop for other cases
|
||||
if (m->messageType == MAIL_NORMAL)
|
||||
{
|
||||
MailDraft draft(m->subject, m->itemTextId);
|
||||
if (m->mailTemplateId)
|
||||
draft = MailDraft(m->mailTemplateId,false); // items already included
|
||||
|
||||
if(m->HasItems())
|
||||
{
|
||||
|
|
@ -374,7 +357,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
|||
{
|
||||
Item *item = pl->GetMItem(itr2->item_guid);
|
||||
if(item)
|
||||
mi.AddItem(item);
|
||||
draft.AddItem(item);
|
||||
else
|
||||
{
|
||||
//WTF?
|
||||
|
|
@ -384,59 +367,13 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
|||
}
|
||||
}
|
||||
|
||||
SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
|
||||
draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender);
|
||||
}
|
||||
|
||||
delete m; // we can deallocate old mail
|
||||
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_OK);
|
||||
}
|
||||
|
||||
void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, const std::string& subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint16 mailTemplateId )
|
||||
{
|
||||
if(messageType != MAIL_NORMAL) // return only to players
|
||||
{
|
||||
mi->deleteIncludedItems(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Player *receiver = objmgr.GetPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
||||
|
||||
uint32 rc_account = 0;
|
||||
if(!receiver)
|
||||
rc_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
||||
|
||||
if(!receiver && !rc_account) // sender not exist
|
||||
{
|
||||
mi->deleteIncludedItems(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare mail and send in other case
|
||||
bool needItemDelay = false;
|
||||
|
||||
if(mi && !mi->empty())
|
||||
{
|
||||
// if item send to character at another account, then apply item delivery delay
|
||||
needItemDelay = sender_acc != rc_account;
|
||||
|
||||
// set owner to new receiver (to prevent delete item with sender char deleting)
|
||||
CharacterDatabase.BeginTransaction();
|
||||
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
||||
{
|
||||
Item* item = mailItemIter->second;
|
||||
item->SaveToDB(); // item not in inventory and can be save standalone
|
||||
// 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, item->GetGUIDLow());
|
||||
}
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
// If theres is an item, there is a one hour delivery delay.
|
||||
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(receiver, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, sender_guid, receiver_guid, subject, itemTextId, mi, money, 0, MAIL_CHECK_MASK_RETURNED, deliver_delay, mailTemplateId);
|
||||
}
|
||||
|
||||
//called when player takes item attached in mail
|
||||
void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
||||
{
|
||||
|
|
@ -507,7 +444,9 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
|||
// check player existence
|
||||
if(receive || sender_accId)
|
||||
{
|
||||
WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, m->receiver, m->sender, m->subject, 0, NULL, m->COD, 0, MAIL_CHECK_MASK_COD_PAYMENT);
|
||||
MailDraft(m->subject)
|
||||
.AddMoney(m->COD)
|
||||
.SendMailTo(MailReceiver(receive,m->sender),MailSender(MAIL_NORMAL,m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
|
||||
}
|
||||
|
||||
pl->ModifyMoney( -int32(m->COD) );
|
||||
|
|
@ -612,7 +551,7 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
|
|||
if ((*itr)->HasItems() && (*itr)->messageType == MAIL_NORMAL)
|
||||
show_flags |= MAIL_SHOW_RETURN;
|
||||
|
||||
data << uint16(0x0040); // unknown 2.3.0, different values
|
||||
data << uint16(next_mail_size); // Message size
|
||||
data << uint32((*itr)->messageID); // Message ID
|
||||
data << uint8((*itr)->messageType); // Message Type
|
||||
|
||||
|
|
@ -834,145 +773,217 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recv_data*/ )
|
|||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 receiver_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay, uint16 mailTemplateId)
|
||||
MailSender::MailSender( Object* sender, MailStationery stationery ) : m_stationery(stationery)
|
||||
{
|
||||
uint32 mailId = objmgr.GenerateMailID();
|
||||
|
||||
time_t deliver_time = time(NULL) + deliver_delay;
|
||||
|
||||
uint32 expire_delay;
|
||||
// auction mail without any items and money (auction sale note) pending 1 hour
|
||||
if (messageType == MAIL_AUCTION && !mi && !money)
|
||||
expire_delay = HOUR;
|
||||
// mail from battlemaster (rewardmarks) should last only one day
|
||||
else if (messageType == MAIL_CREATURE && sBattleGroundMgr.GetBattleMasterBG(sender_guidlow_or_entry) != BATTLEGROUND_TYPE_NONE)
|
||||
expire_delay = DAY;
|
||||
// default case: expire time if COD 3 days, if no COD 30 days
|
||||
else
|
||||
expire_delay = (COD > 0) ? 3 * DAY : 30 * DAY;
|
||||
|
||||
|
||||
|
||||
time_t expire_time = deliver_time + expire_delay;
|
||||
|
||||
if (mailTemplateId && !sMailTemplateStore.LookupEntry(mailTemplateId))
|
||||
{
|
||||
sLog.outError( "WorldSession::SendMailTo - Mail have not existed MailTemplateId (%u), remove at send", mailTemplateId);
|
||||
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(), receiver_guidlow);
|
||||
}
|
||||
}
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
// For online receiver update in game mail status and data
|
||||
if (receiver)
|
||||
{
|
||||
receiver->AddNewMailDeliverTime(deliver_time);
|
||||
|
||||
if (receiver->IsMailsLoaded())
|
||||
{
|
||||
Mail *m = new Mail;
|
||||
m->messageID = mailId;
|
||||
m->messageType = messageType;
|
||||
m->stationery = stationery;
|
||||
m->mailTemplateId = mailTemplateId;
|
||||
m->sender = sender_guidlow_or_entry;
|
||||
m->receiver = receiver->GetGUIDLow();
|
||||
m->subject = subject;
|
||||
m->itemTextId = itemTextId;
|
||||
|
||||
if (mi)
|
||||
m->AddAllItems(*mi);
|
||||
|
||||
m->expire_time = expire_time;
|
||||
m->deliver_time = deliver_time;
|
||||
m->money = money;
|
||||
m->COD = COD;
|
||||
m->checked = checked;
|
||||
m->state = MAIL_STATE_UNCHANGED;
|
||||
|
||||
receiver->AddMail(m); // to insert new mail to beginning of maillist
|
||||
|
||||
if (mi)
|
||||
{
|
||||
for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter)
|
||||
receiver->AddMItem(mailItemIter->second);
|
||||
}
|
||||
}
|
||||
else if (mi)
|
||||
mi->deleteIncludedItems();
|
||||
}
|
||||
else if (mi)
|
||||
mi->deleteIncludedItems();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
MailMessageType mailType;
|
||||
uint32 senderGuidOrEntry;
|
||||
switch(sender->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
mailType = MAIL_CREATURE;
|
||||
senderGuidOrEntry = sender->GetEntry();
|
||||
m_messageType = MAIL_CREATURE;
|
||||
m_senderId = sender->GetEntry();
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
mailType = MAIL_GAMEOBJECT;
|
||||
senderGuidOrEntry = sender->GetEntry();
|
||||
m_messageType = MAIL_GAMEOBJECT;
|
||||
m_senderId = sender->GetEntry();
|
||||
break;
|
||||
case TYPEID_ITEM:
|
||||
mailType = MAIL_ITEM;
|
||||
senderGuidOrEntry = sender->GetEntry();
|
||||
m_messageType = MAIL_ITEM;
|
||||
m_senderId = sender->GetEntry();
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
mailType = MAIL_NORMAL;
|
||||
senderGuidOrEntry = sender->GetGUIDLow();
|
||||
m_messageType = MAIL_NORMAL;
|
||||
m_senderId = sender->GetGUIDLow();
|
||||
break;
|
||||
default:
|
||||
mailType = MAIL_NORMAL;
|
||||
senderGuidOrEntry = receiver_guidlow;
|
||||
sLog.outError( "WorldSession::SendMailTo - Mail have unexpected sender typeid (%u), sent from receiver to self", sender->GetTypeId());
|
||||
m_messageType = MAIL_NORMAL;
|
||||
m_senderId = 0; // will show mail from not existed player
|
||||
sLog.outError( "MailSender::MailSender - Mail have unexpected sender typeid (%u)", sender->GetTypeId());
|
||||
break;
|
||||
}
|
||||
|
||||
SendMailTo(receiver, mailType, stationery, senderGuidOrEntry, receiver_guidlow, subject, itemTextId, mi, money, COD, checked,deliver_delay,mailTemplateId);
|
||||
}
|
||||
|
||||
void WorldSession::SendMailTemplateTo(Player* receiver, Object* sender, uint8 stationery, uint16 mailTemplateId, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay)
|
||||
MailSender::MailSender( AuctionEntry* sender )
|
||||
: m_messageType(MAIL_AUCTION), m_senderId(sender->GetHouseId()), m_stationery(MAIL_STATIONERY_AUCTION)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MailReceiver::MailReceiver( Player* receiver ) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUIDLow())
|
||||
{
|
||||
}
|
||||
|
||||
MailReceiver::MailReceiver( Player* receiver,uint32 receiver_lowguid ) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid)
|
||||
{
|
||||
ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid);
|
||||
}
|
||||
|
||||
MailDraft& MailDraft::AddItem( Item* item )
|
||||
{
|
||||
m_items[item->GetGUIDLow()] = item; return *this;
|
||||
}
|
||||
|
||||
void MailDraft::prepareItems(Player* receiver)
|
||||
{
|
||||
if (!m_mailTemplateId || !m_mailTemplateItemsNeed)
|
||||
return;
|
||||
|
||||
m_mailTemplateItemsNeed = false;
|
||||
|
||||
Loot mailLoot;
|
||||
|
||||
mailLoot.FillLoot(mailTemplateId, LootTemplates_Mail, receiver,true);
|
||||
|
||||
// fill mail
|
||||
MailItemsInfo mi; // item list preparing
|
||||
mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver,true);
|
||||
|
||||
uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
|
||||
for(uint32 i = 0; mi.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
|
||||
for(uint32 i = 0; m_items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
|
||||
{
|
||||
if (LootItem* lootitem = mailLoot.LootItemInSlot(i,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
|
||||
mi.AddItem(item);
|
||||
AddItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MailDraft::deleteIncludedItems( bool inDB /*= false*/ )
|
||||
{
|
||||
for(MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||
{
|
||||
Item* item = mailItemIter->second;
|
||||
|
||||
if(inDB)
|
||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
WorldSession::SendMailTo(receiver, sender, stationery, receiver->GetGUIDLow(), "", 0, &mi, money, COD, checked,deliver_delay,mailTemplateId);
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid )
|
||||
{
|
||||
Player *receiver = objmgr.GetPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
||||
|
||||
uint32 rc_account = 0;
|
||||
if(!receiver)
|
||||
rc_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
|
||||
|
||||
if(!receiver && !rc_account) // sender not exist
|
||||
{
|
||||
deleteIncludedItems(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare mail and send in other case
|
||||
bool needItemDelay = false;
|
||||
|
||||
if(!m_items.empty())
|
||||
{
|
||||
// if item send to character at another account, then apply item delivery delay
|
||||
needItemDelay = sender_acc != rc_account;
|
||||
|
||||
// set owner to new receiver (to prevent delete item with sender char deleting)
|
||||
CharacterDatabase.BeginTransaction();
|
||||
for(MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
|
||||
{
|
||||
Item* item = mailItemIter->second;
|
||||
item->SaveToDB(); // item not in inventory and can be save standalone
|
||||
// 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, item->GetGUIDLow());
|
||||
}
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
// If theres is an item, there is a one hour delivery delay.
|
||||
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
SendMailTo(MailReceiver(receiver,receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
|
||||
}
|
||||
|
||||
void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
|
||||
{
|
||||
Player* pReceiver = receiver.GetPlayer(); // can be NULL
|
||||
|
||||
if (pReceiver)
|
||||
prepareItems(pReceiver); // generate mail template items
|
||||
|
||||
|
||||
uint32 mailId = objmgr.GenerateMailID();
|
||||
|
||||
time_t deliver_time = time(NULL) + deliver_delay;
|
||||
|
||||
uint32 expire_delay;
|
||||
// auction mail without any items and money (auction sale note) pending 1 hour
|
||||
if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money)
|
||||
expire_delay = HOUR;
|
||||
// mail from battlemaster (rewardmarks) should last only one day
|
||||
else if (sender.GetMailMessageType() == MAIL_CREATURE && sBattleGroundMgr.GetBattleMasterBG(sender.GetSenderId()) != BATTLEGROUND_TYPE_NONE)
|
||||
expire_delay = DAY;
|
||||
// default case: expire time if COD 3 days, if no COD 30 days
|
||||
else
|
||||
expire_delay = (m_COD > 0) ? 3 * DAY : 30 * DAY;
|
||||
|
||||
time_t expire_time = deliver_time + expire_delay;
|
||||
|
||||
// Add to DB
|
||||
std::string safe_subject = GetSubject();
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.escape_string(safe_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, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), GetBodyId(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
|
||||
|
||||
for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.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(), receiver.GetPlayerGUIDLow());
|
||||
}
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
// For online receiver update in game mail status and data
|
||||
if (pReceiver)
|
||||
{
|
||||
pReceiver->AddNewMailDeliverTime(deliver_time);
|
||||
|
||||
if (pReceiver->IsMailsLoaded())
|
||||
{
|
||||
Mail *m = new Mail;
|
||||
m->messageID = mailId;
|
||||
m->mailTemplateId = GetMailTemplateId();
|
||||
m->subject = GetSubject();
|
||||
m->itemTextId = GetBodyId();
|
||||
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->GetGUIDLow(), 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);
|
||||
}
|
||||
}
|
||||
else if (!m_items.empty())
|
||||
deleteIncludedItems();
|
||||
}
|
||||
else if (!m_items.empty())
|
||||
deleteIncludedItems();
|
||||
}
|
||||
|
|
|
|||
110
src/game/Mail.h
110
src/game/Mail.h
|
|
@ -21,20 +21,12 @@
|
|||
#include "Common.h"
|
||||
#include <map>
|
||||
|
||||
struct AuctionEntry;
|
||||
class Item;
|
||||
|
||||
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
||||
#define MAX_MAIL_ITEMS 12
|
||||
|
||||
enum MailCheckMask
|
||||
{
|
||||
MAIL_CHECK_MASK_NONE = 0,
|
||||
MAIL_CHECK_MASK_READ = 1,
|
||||
MAIL_CHECK_MASK_AUCTION = 4,
|
||||
MAIL_CHECK_MASK_COD_PAYMENT = 8,
|
||||
MAIL_CHECK_MASK_RETURNED = 16
|
||||
};
|
||||
|
||||
enum MailMessageType
|
||||
{
|
||||
MAIL_NORMAL = 0,
|
||||
|
|
@ -62,16 +54,75 @@ enum MailAuctionAnswers
|
|||
AUCTION_SALE_PENDING = 6
|
||||
};
|
||||
|
||||
// gathered from Stationery.dbc
|
||||
enum MailStationery
|
||||
class MailSender
|
||||
{
|
||||
MAIL_STATIONERY_UNKNOWN = 1,
|
||||
MAIL_STATIONERY_NORMAL = 41,
|
||||
MAIL_STATIONERY_GM = 61,
|
||||
MAIL_STATIONERY_AUCTION = 62,
|
||||
MAIL_STATIONERY_VAL = 64,
|
||||
MAIL_STATIONERY_CHR = 65,
|
||||
MAIL_STATIONERY_ORP = 67, // new in 3.2.2
|
||||
public: // Constructors
|
||||
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_NORMAL)
|
||||
: m_messageType(messageType), m_senderId(sender_guidlow_or_entry), m_stationery(stationery)
|
||||
{
|
||||
}
|
||||
MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_NORMAL);
|
||||
MailSender(AuctionEntry* sender);
|
||||
public: // Accessors
|
||||
MailMessageType GetMailMessageType() const { return m_messageType; }
|
||||
uint32 GetSenderId() const { return m_senderId; }
|
||||
MailStationery GetStationery() const { return m_stationery; }
|
||||
private:
|
||||
MailMessageType m_messageType;
|
||||
uint32 m_senderId; // player low guid or other object entry
|
||||
MailStationery m_stationery;
|
||||
};
|
||||
|
||||
class MailReceiver
|
||||
{
|
||||
public: // Constructors
|
||||
explicit MailReceiver(uint32 receiver_lowguid) : m_receiver(NULL), m_receiver_lowguid(receiver_lowguid) {}
|
||||
MailReceiver(Player* receiver);
|
||||
MailReceiver(Player* receiver,uint32 receiver_lowguid);
|
||||
public: // Accessors
|
||||
Player* GetPlayer() const { return m_receiver; }
|
||||
uint32 GetPlayerGUIDLow() const { return m_receiver_lowguid; }
|
||||
private:
|
||||
Player* m_receiver;
|
||||
uint32 m_receiver_lowguid;
|
||||
};
|
||||
|
||||
class MailDraft
|
||||
{
|
||||
typedef std::map<uint32, Item*> MailItemMap;
|
||||
|
||||
public: // Constructors
|
||||
explicit MailDraft(uint16 mailTemplateId, bool need_items = true)
|
||||
: m_mailTemplateId(mailTemplateId), m_mailTemplateItemsNeed(need_items), m_bodyId(0), m_money(0), m_COD(0)
|
||||
{}
|
||||
MailDraft(std::string subject, uint32 itemTextId = 0)
|
||||
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_bodyId(itemTextId), m_money(0), m_COD(0) {}
|
||||
public: // Accessors
|
||||
uint16 GetMailTemplateId() const { return m_mailTemplateId; }
|
||||
std::string const& GetSubject() const { return m_subject; }
|
||||
uint32 GetBodyId() const { return m_bodyId; }
|
||||
uint32 GetMoney() const { return m_money; }
|
||||
uint32 GetCOD() const { return m_COD; }
|
||||
public: // modifiers
|
||||
MailDraft& AddItem(Item* item);
|
||||
MailDraft& AddMoney(uint32 money) { m_money = money; return *this; }
|
||||
MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; }
|
||||
public: // finishers
|
||||
void SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid);
|
||||
void SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked = MAIL_CHECK_MASK_NONE, uint32 deliver_delay = 0);
|
||||
private:
|
||||
void deleteIncludedItems(bool inDB = false);
|
||||
void prepareItems(Player* receiver); // called from SendMailTo for generate mailTemplateBase items
|
||||
|
||||
uint16 m_mailTemplateId;
|
||||
bool m_mailTemplateItemsNeed;
|
||||
std::string m_subject;
|
||||
uint32 m_bodyId;
|
||||
|
||||
MailItemMap m_items; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
|
||||
|
||||
uint32 m_money;
|
||||
uint32 m_COD;
|
||||
};
|
||||
|
||||
struct MailItemInfo
|
||||
|
|
@ -80,26 +131,6 @@ struct MailItemInfo
|
|||
uint32 item_template;
|
||||
};
|
||||
|
||||
typedef std::map<uint32, Item*> MailItemMap;
|
||||
|
||||
class MailItemsInfo
|
||||
{
|
||||
public:
|
||||
MailItemMap::const_iterator begin() const { return i_MailItemMap.begin(); }
|
||||
MailItemMap::const_iterator end() const { return i_MailItemMap.end(); }
|
||||
MailItemMap::iterator begin() { return i_MailItemMap.begin(); }
|
||||
MailItemMap::iterator end() { return i_MailItemMap.end(); }
|
||||
|
||||
void AddItem(Item *item);
|
||||
|
||||
uint8 size() const { return i_MailItemMap.size(); }
|
||||
bool empty() const { return i_MailItemMap.empty(); }
|
||||
|
||||
void deleteIncludedItems(bool inDB = false);
|
||||
private:
|
||||
MailItemMap i_MailItemMap; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
|
||||
};
|
||||
|
||||
struct Mail
|
||||
{
|
||||
uint32 messageID;
|
||||
|
|
@ -127,8 +158,6 @@ struct Mail
|
|||
items.push_back(mii);
|
||||
}
|
||||
|
||||
void AddAllItems(MailItemsInfo& pMailItemsInfo);
|
||||
|
||||
bool RemoveItem(uint32 item_guid)
|
||||
{
|
||||
for(std::vector<MailItemInfo>::iterator itr = items.begin(); itr != items.end(); ++itr)
|
||||
|
|
@ -144,4 +173,5 @@ struct Mail
|
|||
|
||||
bool HasItems() const { return !items.empty(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3914,8 +3914,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
// remove signs from petitions (also remove petitions if owner);
|
||||
RemovePetitionsAndSigns(playerguid, 10);
|
||||
|
||||
// return back all mails with COD and Item 0 1 2 3 4 5 6
|
||||
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,mailTemplateId,sender,subject,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
|
||||
// return back all mails with COD and Item 0 1 2 3 4 5 6 7
|
||||
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
|
||||
if(resultMail)
|
||||
{
|
||||
do
|
||||
|
|
@ -3923,18 +3923,30 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
Field *fields = resultMail->Fetch();
|
||||
|
||||
uint32 mail_id = fields[0].GetUInt32();
|
||||
uint16 mailTemplateId= fields[1].GetUInt16();
|
||||
uint32 sender = fields[2].GetUInt32();
|
||||
std::string subject = fields[3].GetCppString();
|
||||
uint32 itemTextId = fields[4].GetUInt32();
|
||||
uint32 money = fields[5].GetUInt32();
|
||||
bool has_items = fields[6].GetBool();
|
||||
uint16 mailType = fields[1].GetUInt16();
|
||||
uint16 mailTemplateId= fields[2].GetUInt16();
|
||||
uint32 sender = fields[3].GetUInt32();
|
||||
std::string subject = fields[4].GetCppString();
|
||||
uint32 itemTextId = fields[5].GetUInt32();
|
||||
uint32 money = fields[6].GetUInt32();
|
||||
bool has_items = fields[7].GetBool();
|
||||
|
||||
//we can return mail now
|
||||
//so firstly delete the old one
|
||||
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mail_id);
|
||||
|
||||
MailItemsInfo mi;
|
||||
// mail not from player
|
||||
if (mailType != MAIL_NORMAL)
|
||||
{
|
||||
if(has_items)
|
||||
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
MailDraft draft(subject, itemTextId);
|
||||
if (mailTemplateId)
|
||||
draft = MailDraft(mailTemplateId,false); // itesm already included
|
||||
|
||||
if(has_items)
|
||||
{
|
||||
// data needs to be at first place for Item::LoadFromDB
|
||||
|
|
@ -3963,7 +3975,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
continue;
|
||||
}
|
||||
|
||||
mi.AddItem(pItem);
|
||||
draft.AddItem(pItem);
|
||||
}
|
||||
while (resultItems->NextRow());
|
||||
|
||||
|
|
@ -3975,7 +3987,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
|
||||
uint32 pl_account = objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
|
||||
|
||||
WorldSession::SendReturnToSender(MAIL_NORMAL, pl_account, guid, sender, subject, itemTextId, &mi, money, mailTemplateId);
|
||||
draft.AddMoney(money).SendReturnToSender(pl_account, guid, sender);
|
||||
}
|
||||
while (resultMail->NextRow());
|
||||
|
||||
|
|
@ -12715,7 +12727,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
|
|||
|
||||
// Send reward mail
|
||||
if (uint32 mail_template_id = pQuest->GetRewMailTemplateId())
|
||||
WorldSession::SendMailTemplateTo(this, questGiver, MAIL_STATIONERY_NORMAL, mail_template_id, 0, 0, MAIL_CHECK_MASK_NONE, pQuest->GetRewMailDelaySecs());
|
||||
MailDraft(mail_template_id).SendMailTo(this, questGiver, MAIL_CHECK_MASK_NONE, pQuest->GetRewMailDelaySecs());
|
||||
|
||||
if (pQuest->IsDaily())
|
||||
{
|
||||
|
|
@ -14941,20 +14953,20 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
|
|||
// send by mail problematic items
|
||||
while(!problematicItems.empty())
|
||||
{
|
||||
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
||||
|
||||
// fill mail
|
||||
MailItemsInfo mi; // item list preparing
|
||||
MailDraft draft(subject);
|
||||
|
||||
for(int i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i)
|
||||
{
|
||||
Item* item = problematicItems.front();
|
||||
problematicItems.pop_front();
|
||||
|
||||
mi.AddItem(item);
|
||||
draft.AddItem(item);
|
||||
}
|
||||
|
||||
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
||||
|
||||
WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
draft.SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
|
||||
}
|
||||
}
|
||||
//if(isAlive())
|
||||
|
|
@ -18822,8 +18834,6 @@ void Player::AutoUnequipOffhandIfNeed()
|
|||
}
|
||||
else
|
||||
{
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(offItem);
|
||||
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
|
||||
CharacterDatabase.BeginTransaction();
|
||||
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
|
||||
|
|
@ -18831,7 +18841,7 @@ void Player::AutoUnequipOffhandIfNeed()
|
|||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
|
||||
WorldSession::SendMailTo(this, MAIL_NORMAL, MAIL_STATIONERY_GM, GetGUIDLow(), GetGUIDLow(), subject, 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
MailDraft(subject).AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2620,6 +2620,27 @@ enum BattleGroundTypeId
|
|||
};
|
||||
#define MAX_BATTLEGROUND_TYPE_ID 33
|
||||
|
||||
enum MailCheckMask
|
||||
{
|
||||
MAIL_CHECK_MASK_NONE = 0x00,
|
||||
MAIL_CHECK_MASK_READ = 0x01,
|
||||
MAIL_CHECK_MASK_AUCTION = 0x04,
|
||||
MAIL_CHECK_MASK_COD_PAYMENT = 0x08,
|
||||
MAIL_CHECK_MASK_RETURNED = 0x10
|
||||
};
|
||||
|
||||
// gathered from Stationery.dbc
|
||||
enum MailStationery
|
||||
{
|
||||
MAIL_STATIONERY_UNKNOWN = 1,
|
||||
MAIL_STATIONERY_NORMAL = 41,
|
||||
MAIL_STATIONERY_GM = 61,
|
||||
MAIL_STATIONERY_AUCTION = 62,
|
||||
MAIL_STATIONERY_VAL = 64,
|
||||
MAIL_STATIONERY_CHR = 65,
|
||||
MAIL_STATIONERY_ORP = 67, // new in 3.2.2
|
||||
};
|
||||
|
||||
enum MailResponseType
|
||||
{
|
||||
MAIL_SEND = 0,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "Common.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class MailItemsInfo;
|
||||
struct ItemPrototype;
|
||||
struct AuctionEntry;
|
||||
struct DeclinedName;
|
||||
|
|
@ -39,7 +38,6 @@ class Player;
|
|||
class Unit;
|
||||
class WorldPacket;
|
||||
class WorldSocket;
|
||||
class WorldSession;
|
||||
class QueryResult;
|
||||
class LoginQueryHolder;
|
||||
class CharacterHandler;
|
||||
|
|
@ -220,14 +218,8 @@ class MANGOS_DLL_SPEC WorldSession
|
|||
m_TutorialsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
//mail
|
||||
//used with item_page table
|
||||
bool SendItemInfo( uint32 itemid, WorldPacket data );
|
||||
static void SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, const std::string& subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint16 mailTemplateId = 0);
|
||||
static void SendMailTo(Player* receiver, uint8 messageType, uint8 stationery, uint32 sender_guidlow_or_entry, uint32 received_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay = 0, uint16 mailTemplateId = 0);
|
||||
static void SendMailTo(Player* receiver, Object* sender, uint8 stationery, uint32 received_guidlow, std::string subject, uint32 itemTextId, MailItemsInfo* mi, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay = 0, uint16 mailTemplateId = 0);
|
||||
static void SendMailTemplateTo(Player* receiver, Object* sender, uint8 stationery, uint16 mailTemplateId, uint32 money, uint32 COD, uint32 checked, uint32 deliver_delay = 0);
|
||||
|
||||
//auction
|
||||
void SendAuctionHello( uint64 guid, Creature * unit );
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "8767"
|
||||
#define REVISION_NR "8768"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue