Files
TCPlayerbotCore/src/server/game/Mails/Mail.cpp
T

256 lines
9.5 KiB
C++
Raw Normal View History

2008-10-02 16:23:55 -05:00
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2010-01-16 20:19:18 +03:00
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
#include "DatabaseEnv.h"
2008-10-02 16:23:55 -05:00
#include "Mail.h"
#include "Log.h"
#include "World.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "Unit.h"
2010-08-08 04:37:24 +02:00
#include "BattlegroundMgr.h"
2009-12-16 18:58:36 +02:00
#include "Item.h"
#include "AuctionHouseMgr.h"
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery)
2009-12-16 18:58:36 +02:00
{
switch(sender->GetTypeId())
{
case TYPEID_UNIT:
m_messageType = MAIL_CREATURE;
m_senderId = sender->GetEntry();
break;
case TYPEID_GAMEOBJECT:
m_messageType = MAIL_GAMEOBJECT;
m_senderId = sender->GetEntry();
break;
case TYPEID_ITEM:
m_messageType = MAIL_ITEM;
m_senderId = sender->GetEntry();
break;
case TYPEID_PLAYER:
m_messageType = MAIL_NORMAL;
m_senderId = sender->GetGUIDLow();
break;
default:
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;
}
}
2010-04-07 22:59:46 +02:00
MailSender::MailSender(AuctionEntry* sender)
2009-12-16 18:58:36 +02:00
: m_messageType(MAIL_AUCTION), m_senderId(sender->GetHouseId()), m_stationery(MAIL_STATIONERY_AUCTION)
{
}
2010-04-07 22:59:46 +02:00
MailReceiver::MailReceiver(Player* receiver) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUIDLow())
2009-12-16 18:58:36 +02:00
{
}
2010-04-07 22:59:46 +02:00
MailReceiver::MailReceiver(Player* receiver,uint32 receiver_lowguid) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid)
2009-12-16 18:58:36 +02:00
{
ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid);
}
2010-04-07 22:59:46 +02:00
MailDraft& MailDraft::AddItem(Item* item)
2009-12-16 18:58:36 +02:00
{
m_items[item->GetGUIDLow()] = item; return *this;
}
2010-08-21 03:19:25 +02:00
void MailDraft::prepareItems(Player* receiver, SQLTransaction& trans)
2008-10-02 16:23:55 -05:00
{
2009-12-16 18:58:36 +02:00
if (!m_mailTemplateId || !m_mailTemplateItemsNeed)
return;
m_mailTemplateItemsNeed = false;
Loot mailLoot;
// can be empty
mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver, true, true);
uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
for (uint32 i = 0; m_items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
{
2009-12-16 18:58:36 +02:00
if (LootItem* lootitem = mailLoot.LootItemInSlot(i,receiver))
{
2009-12-16 18:58:36 +02:00
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,receiver))
{
2010-08-21 03:19:25 +02:00
item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
2009-12-16 18:58:36 +02:00
AddItem(item);
}
}
2009-12-16 18:58:36 +02:00
}
}
void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/ )
2009-12-16 18:58:36 +02:00
{
for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
Item* item = mailItemIter->second;
if (inDB)
2010-08-21 03:19:25 +02:00
trans->PAppend("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
2009-12-16 18:58:36 +02:00
delete item;
}
m_items.clear();
}
2010-04-07 22:59:46 +02:00
void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid)
2009-12-16 18:58:36 +02:00
{
2010-08-08 05:25:45 +02:00
Player *receiver = sObjectMgr.GetPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
2009-12-16 18:58:36 +02:00
uint32 rc_account = 0;
if (!receiver)
2010-08-08 05:25:45 +02:00
rc_account = sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
2009-12-16 18:58:36 +02:00
2010-08-21 03:19:25 +02:00
SQLTransaction trans = CharacterDatabase.BeginTransaction();
2009-12-16 18:58:36 +02:00
if (!receiver && !rc_account) // sender not exist
{
deleteIncludedItems(trans, true);
return;
}
2009-12-16 18:58:36 +02:00
// 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)
for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
Item* item = mailItemIter->second;
2010-08-21 03:19:25 +02:00
item->SaveToDB(trans); // item not in inventory and can be save standalone
2009-12-16 18:58:36 +02:00
// owner in data will set at mail receive and item extracting
2010-08-21 03:19:25 +02:00
trans->PAppend("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, item->GetGUIDLow());
2009-12-16 18:58:36 +02:00
}
}
// If theres is an item, there is a one hour delivery delay.
uint32 deliver_delay = needItemDelay ? sWorld.getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
2009-12-16 18:58:36 +02:00
// will delete item or place to receiver mail list
2010-08-21 03:19:25 +02:00
SendMailTo(trans,MailReceiver(receiver,receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
CharacterDatabase.CommitTransaction(trans);
2009-12-16 18:58:36 +02:00
}
2010-08-21 03:19:25 +02:00
void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
2009-12-16 18:58:36 +02:00
{
Player* pReceiver = receiver.GetPlayer(); // can be NULL
2009-12-16 18:58:36 +02:00
if (pReceiver)
2010-08-21 03:19:25 +02:00
prepareItems(pReceiver, trans); // generate mail template items
2009-12-16 18:58:36 +02:00
2010-08-08 05:25:45 +02:00
uint32 mailId = sObjectMgr.GenerateMailID();
2009-10-17 15:51:44 -07:00
time_t deliver_time = time(NULL) + deliver_delay;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
//expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour
uint32 expire_delay;
2009-12-16 18:58:36 +02:00
// auction mail without any items and money
if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money)
expire_delay = sWorld.getIntConfig(CONFIG_MAIL_DELIVERY_DELAY);
2009-12-16 18:58:36 +02:00
// mail from battlemaster (rewardmarks) should last only one day
2010-08-08 04:37:24 +02:00
else if (sender.GetMailMessageType() == MAIL_CREATURE && sBattlegroundMgr.GetBattleMasterBG(sender.GetSenderId()) != BATTLEGROUND_TYPE_NONE)
2009-12-16 18:58:36 +02:00
expire_delay = DAY;
// default case: expire time if COD 3 days, if no COD 30 days
2008-10-02 16:23:55 -05:00
else
2009-12-16 18:58:36 +02:00
expire_delay = (m_COD > 0) ? 3 * DAY : 30 * DAY;
2009-10-17 15:51:44 -07:00
2008-10-02 16:23:55 -05:00
time_t expire_time = deliver_time + expire_delay;
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
// Add to DB
std::string safe_subject = GetSubject();
2010-04-11 20:20:38 +02:00
std::string safe_body = GetBody();
2010-08-21 03:19:25 +02:00
CharacterDatabase.escape_string(safe_subject);
2010-04-11 20:20:38 +02:00
CharacterDatabase.escape_string(safe_body);
2010-08-21 03:19:25 +02:00
trans->PAppend("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%s', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), safe_body.c_str(),(m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
2009-12-16 18:58:36 +02:00
for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
2008-10-02 16:23:55 -05:00
{
2009-12-16 18:58:36 +02:00
Item* item = mailItemIter->second;
2010-08-21 03:19:25 +02:00
trans->PAppend("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, item->GetGUIDLow(), item->GetEntry(), receiver.GetPlayerGUIDLow());
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
// For online receiver update in game mail status and data
if (pReceiver)
2008-10-02 16:23:55 -05:00
{
2009-12-16 18:58:36 +02:00
pReceiver->AddNewMailDeliverTime(deliver_time);
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
if (pReceiver->IsMailsLoaded())
2008-10-02 16:23:55 -05:00
{
Mail * m = new Mail;
m->messageID = mailId;
2009-12-16 18:58:36 +02:00
m->mailTemplateId = GetMailTemplateId();
m->subject = GetSubject();
m->body = GetBody();
2009-12-16 18:58:36 +02:00
m->money = GetMoney();
m->COD = GetCOD();
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
Item* item = mailItemIter->second;
m->AddItem(item->GetGUIDLow(), item->GetEntry());
}
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
m->messageType = sender.GetMailMessageType();
m->stationery = sender.GetStationery();
m->sender = sender.GetSenderId();
m->receiver = receiver.GetPlayerGUIDLow();
2008-10-02 16:23:55 -05:00
m->expire_time = expire_time;
m->deliver_time = deliver_time;
m->checked = checked;
m->state = MAIL_STATE_UNCHANGED;
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
pReceiver->AddMail(m); // to insert new mail to beginning of maillist
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
if (!m_items.empty())
2008-10-02 16:23:55 -05:00
{
2009-12-16 18:58:36 +02:00
for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
pReceiver->AddMItem(mailItemIter->second);
2008-10-02 16:23:55 -05:00
}
}
2009-12-16 18:58:36 +02:00
else if (!m_items.empty())
{
SQLTransaction temp = SQLTransaction(NULL);
deleteIncludedItems(temp);
}
2008-10-02 16:23:55 -05:00
}
2009-12-16 18:58:36 +02:00
else if (!m_items.empty())
{
SQLTransaction temp = SQLTransaction(NULL);
deleteIncludedItems(temp);
}
2008-10-02 16:23:55 -05:00
}