TrinityCore
Loading...
Searching...
No Matches
Mail.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Mail.h"
19#include "AuctionHouseMgr.h"
20#include "BattlegroundMgr.h"
21#include "CalendarMgr.h"
22#include "CharacterCache.h"
23#include "DatabaseEnv.h"
24#include "GameTime.h"
25#include "Item.h"
26#include "Log.h"
27#include "LootMgr.h"
28#include "ObjectAccessor.h"
29#include "ObjectMgr.h"
30#include "Player.h"
31#include "World.h"
32
33MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery)
34{
35 switch (sender->GetTypeId())
36 {
37 case TYPEID_UNIT:
39 m_senderId = sender->GetEntry();
40 break;
43 m_senderId = sender->GetEntry();
44 break;
45 /*case TYPEID_ITEM:
46 m_messageType = MAIL_ITEM;
47 m_senderId = sender->GetEntry();
48 break;*/
49 case TYPEID_PLAYER:
51 m_senderId = sender->GetGUID().GetCounter();
52 break;
53 default:
55 m_senderId = 0; // will show mail from non-existing player
56 TC_LOG_ERROR("misc", "MailSender::MailSender - Mail message contains unexpected sender typeid ({}).", sender->GetTypeId());
57 break;
58 }
59}
60
62 : m_messageType(MAIL_CALENDAR), m_senderId(sender->GetEventId()), m_stationery(MAIL_STATIONERY_DEFAULT) // what stationery we should use here?
63{
64}
65
67 : m_messageType(MAIL_AUCTION), m_senderId(sender->GetHouseId()), m_stationery(MAIL_STATIONERY_AUCTION) { }
68
75
82
83MailReceiver::MailReceiver(Player* receiver) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUID().GetCounter()) { }
84
85MailReceiver::MailReceiver(Player* receiver, ObjectGuid::LowType receiver_lowguid) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid)
86{
87 ASSERT(!receiver || receiver->GetGUID().GetCounter() == receiver_lowguid);
88}
89
91{
92 m_items[item->GetGUID().GetCounter()] = item;
93 return *this;
94}
95
97{
99 return;
100
102
103 // The mail sent after turning in the quest The Good News and The Bad News contains 100g
104 if (m_mailTemplateId == 123)
105 m_money = 1000000;
106
107 Loot mailLoot;
108
109 // can be empty
110 mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver, true, true);
111
112 uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
113 for (uint32 i = 0; m_items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
114 {
115 if (LootItem* lootitem = mailLoot.LootItemInSlot(i, receiver))
116 {
117 if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, receiver))
118 {
119 item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
120 AddItem(item);
121 }
122 }
123 }
124}
125
127{
128 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
129 {
130 Item* item = mailItemIter->second;
131
132 if (inDB)
133 {
135 stmt->setUInt32(0, item->GetGUID().GetCounter());
136 trans->Append(stmt);
137 }
138
139 delete item;
140 }
141
142 m_items.clear();
143}
144
146{
147 ObjectGuid receiverGuid = ObjectGuid::Create<HighGuid::Player>(receiver_guid);
148 Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid);
149
150 uint32 rc_account = 0;
151 if (!receiver)
152 rc_account = sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
153
154 if (!receiver && !rc_account) // sender not exist
155 {
156 deleteIncludedItems(trans, true);
157 return;
158 }
159
160 // prepare mail and send in other case
161 bool needItemDelay = false;
162
163 if (!m_items.empty())
164 {
165 // if item send to character at another account, then apply item delivery delay
166 needItemDelay = sender_acc != rc_account;
167
168 // set owner to new receiver (to prevent delete item with sender char deleting)
169 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
170 {
171 Item* item = mailItemIter->second;
172 item->SaveToDB(trans); // item not in inventory and can be save standalone
173 // owner in data will set at mail receive and item extracting
175 stmt->setUInt32(0, receiver_guid);
176 stmt->setUInt32(1, item->GetGUID().GetCounter());
177 trans->Append(stmt);
178 }
179 }
180
181 // If theres is an item, there is a one hour delivery delay.
182 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
183
184 // will delete item or place to receiver mail list
185 SendMailTo(trans, MailReceiver(receiver, receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
186}
187
188void MailDraft::SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
189{
190 Player* pReceiver = receiver.GetPlayer(); // can be NULL
192
193 if (pReceiver)
194 prepareItems(pReceiver, trans); // generate mail template items
195
196 uint32 mailId = sObjectMgr->GenerateMailID();
197
198 time_t deliver_time = GameTime::GetGameTime() + deliver_delay;
199
200 //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour
201 uint32 expire_delay;
202
203 // auction mail without any items and money
204 if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money)
205 expire_delay = sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY);
206 // mail from battlemaster (rewardmarks) should last only one day
207 else if (sender.GetMailMessageType() == MAIL_CREATURE && sBattlegroundMgr->GetBattleMasterBG(sender.GetSenderId()) != BATTLEGROUND_TYPE_NONE)
208 expire_delay = DAY;
209 // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master)
210 else
211 {
212 if (m_COD)
213 expire_delay = 3 * DAY;
214 else
215 expire_delay = pSender && pSender->IsGameMaster() ? 90 * DAY : 30 * DAY;
216 }
217
218 time_t expire_time = deliver_time + expire_delay;
219
220 // Add to DB
221 uint8 index = 0;
223 stmt->setUInt32( index, mailId);
224 stmt->setUInt8 (++index, uint8(sender.GetMailMessageType()));
225 stmt->setInt8 (++index, int8(sender.GetStationery()));
226 stmt->setUInt16(++index, GetMailTemplateId());
227 stmt->setUInt32(++index, sender.GetSenderId());
228 stmt->setUInt32(++index, receiver.GetPlayerGUIDLow());
229 stmt->setString(++index, GetSubject());
230 stmt->setString(++index, GetBody());
231 stmt->setBool (++index, !m_items.empty());
232 stmt->setUInt64(++index, uint64(expire_time));
233 stmt->setUInt64(++index, uint64(deliver_time));
234 stmt->setUInt32(++index, m_money);
235 stmt->setUInt32(++index, m_COD);
236 stmt->setUInt8 (++index, uint8(checked));
237 trans->Append(stmt);
238
239 for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
240 {
241 Item* pItem = mailItemIter->second;
242 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL_ITEM);
243 stmt->setUInt32(0, mailId);
244 stmt->setUInt32(1, pItem->GetGUID().GetCounter());
245 stmt->setUInt32(2, receiver.GetPlayerGUIDLow());
246 trans->Append(stmt);
247 }
248
249 // For online receiver update in game mail status and data
250 if (pReceiver)
251 {
252 pReceiver->AddNewMailDeliverTime(deliver_time);
253
254 Mail* m = new Mail;
255 m->messageID = mailId;
257 m->subject = GetSubject();
258 m->body = GetBody();
259 m->money = GetMoney();
260 m->COD = GetCOD();
261
262 for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
263 {
264 Item* item = mailItemIter->second;
265 m->AddItem(item->GetGUID().GetCounter(), item->GetEntry());
266 }
267
268 m->messageType = sender.GetMailMessageType();
269 m->stationery = sender.GetStationery();
270 m->sender = sender.GetSenderId();
271 m->receiver = receiver.GetPlayerGUIDLow();
272 m->expire_time = expire_time;
273 m->deliver_time = deliver_time;
274 m->checked = checked;
276
277 pReceiver->AddMail(m); // to insert new mail to beginning of maillist
278
279 if (!m_items.empty())
280 {
281 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
282 pReceiver->AddMItem(mailItemIter->second);
283 }
284 }
285 else if (!m_items.empty())
286 {
289 }
290}
#define sBattlegroundMgr
#define sCharacterCache
@ CHAR_UPD_ITEM_OWNER
@ CHAR_DEL_ITEM_INSTANCE
@ CHAR_INS_MAIL_ITEM
@ CHAR_INS_MAIL
@ DAY
Definition Common.h:31
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
#define ASSERT
Definition Errors.h:68
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)
MailCheckMask
Definition Mail.h:45
@ MAIL_CHECK_MASK_RETURNED
Definition Mail.h:48
@ MAIL_STATE_UNCHANGED
Definition Mail.h:68
#define MAX_MAIL_ITEMS
Definition Mail.h:33
MailStationery
Definition Mail.h:56
@ MAIL_STATIONERY_GM
Definition Mail.h:59
@ MAIL_STATIONERY_DEFAULT
Definition Mail.h:58
@ MAIL_STATIONERY_AUCTION
Definition Mail.h:60
@ MAIL_AUCTION
Definition Mail.h:38
@ MAIL_GAMEOBJECT
Definition Mail.h:40
@ MAIL_CREATURE
Definition Mail.h:39
@ MAIL_CALENDAR
Definition Mail.h:41
@ MAIL_NORMAL
Definition Mail.h:37
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:40
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define sObjectMgr
Definition ObjectMgr.h:1721
@ BATTLEGROUND_TYPE_NONE
Definition Item.h:62
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:323
static Item * CreateItem(uint32 itemEntry, uint32 count, Player const *player=nullptr)
Definition Item.cpp:1044
void deleteIncludedItems(CharacterDatabaseTransaction trans, bool inDB=false)
Definition Mail.cpp:126
uint32 GetCOD() const
Definition Mail.h:132
uint32 GetMoney() const
Definition Mail.h:131
MailItemMap m_items
Definition Mail.h:153
std::string const & GetSubject() const
Definition Mail.h:130
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition Mail.cpp:188
uint32 m_COD
Definition Mail.h:156
uint32 m_money
Definition Mail.h:155
uint16 m_mailTemplateId
Definition Mail.h:148
bool m_mailTemplateItemsNeed
Definition Mail.h:149
void SendReturnToSender(uint32 sender_acc, ObjectGuid::LowType sender_guid, ObjectGuid::LowType receiver_guid, CharacterDatabaseTransaction trans)
Definition Mail.cpp:145
uint16 GetMailTemplateId() const
Definition Mail.h:129
void prepareItems(Player *receiver, CharacterDatabaseTransaction trans)
Definition Mail.cpp:96
MailDraft & AddItem(Item *item)
Definition Mail.cpp:90
std::string const & GetBody() const
Definition Mail.h:133
Player * GetPlayer() const
Definition Mail.h:111
ObjectGuid::LowType GetPlayerGUIDLow() const
Definition Mail.h:112
MailReceiver(ObjectGuid::LowType receiver_lowguid)
Definition Mail.h:107
MailStationery m_stationery
Definition Mail.h:101
ObjectGuid::LowType GetSenderId() const
Definition Mail.h:96
MailSender(MailMessageType messageType, ObjectGuid::LowType sender_guidlow_or_entry, MailStationery stationery=MAIL_STATIONERY_DEFAULT)
Definition Mail.h:85
MailMessageType m_messageType
Definition Mail.h:99
MailMessageType GetMailMessageType() const
Definition Mail.h:95
MailStationery GetStationery() const
Definition Mail.h:97
ObjectGuid::LowType m_senderId
Definition Mail.h:100
LowType GetCounter() const
Definition ObjectGuid.h:156
uint32 LowType
Definition ObjectGuid.h:142
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void AddNewMailDeliverTime(time_t deliver_time)
Definition Player.cpp:2840
void AddMItem(Item *it)
Definition Player.cpp:20578
void AddMail(Mail *mail)
Definition Player.h:1433
bool IsGameMaster() const
Definition Player.h:998
void setInt8(uint8 index, int8 value)
void setUInt16(uint8 index, uint16 value)
void setUInt32(uint8 index, uint32 value)
void setBool(uint8 index, bool value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
void setString(uint8 index, std::string const &value)
#define sWorld
Definition World.h:900
@ CONFIG_MAIL_DELIVERY_DELAY
Definition World.h:268
time_t GetGameTime()
Definition GameTime.cpp:42
TC_GAME_API Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
Definition Loot.h:207
uint32 GetMaxSlotInLootFor(Player *player) const
Definition Loot.cpp:541
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT)
Definition Loot.cpp:220
LootItem * LootItemInSlot(uint32 lootslot, Player *player, NotNormalLootItem **qitem=nullptr, NotNormalLootItem **ffaitem=nullptr, NotNormalLootItem **conditem=nullptr)
Definition Loot.cpp:478
Definition Mail.h:167
ObjectGuid::LowType receiver
Definition Mail.h:173
uint8 messageType
Definition Mail.h:169
uint32 messageID
Definition Mail.h:168
time_t expire_time
Definition Mail.h:178
uint8 stationery
Definition Mail.h:170
ObjectGuid::LowType sender
Definition Mail.h:172
std::string subject
Definition Mail.h:174
std::string body
Definition Mail.h:175
void AddItem(ObjectGuid::LowType itemGuidLow, uint32 item_template)
Definition Mail.h:185
time_t deliver_time
Definition Mail.h:179
uint32 COD
Definition Mail.h:181
uint32 checked
Definition Mail.h:182
MailState state
Definition Mail.h:183
uint32 money
Definition Mail.h:180
uint16 mailTemplateId
Definition Mail.h:171