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 "BlackMarketMgr.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 "Loot.h"
28#include "LootMgr.h"
29#include "ObjectAccessor.h"
30#include "ObjectMgr.h"
31#include "Player.h"
32#include "World.h"
33
34MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery)
35{
36 switch (sender->GetTypeId())
37 {
38 case TYPEID_UNIT:
40 m_senderId = uint64(sender->GetEntry());
41 break;
44 m_senderId = uint64(sender->GetEntry());
45 break;
46 /*case TYPEID_ITEM:
47 m_messageType = MAIL_ITEM;
48 m_senderId = sender->GetEntry();
49 break;*/
50 case TYPEID_PLAYER:
52 m_senderId = sender->GetGUID().GetCounter();
53 break;
54 default:
56 m_senderId = UI64LIT(0); // will show mail from non-existing player
57 TC_LOG_ERROR("misc", "MailSender::MailSender - Mail message contains unexpected sender typeid ({}).", sender->GetTypeId());
58 break;
59 }
60}
61
63 : m_messageType(MAIL_CALENDAR), m_senderId(sender->GetEventId()), m_stationery(MAIL_STATIONERY_DEFAULT) // what stationery we should use here?
64{
65}
66
68 : m_messageType(MAIL_AUCTION), m_senderId(uint64(sender->GetAuctionHouseId())), m_stationery(MAIL_STATIONERY_AUCTION) { }
69
71 : m_messageType(MAIL_BLACKMARKET), m_senderId(sender->GetTemplate()->SellerNPC), m_stationery(MAIL_STATIONERY_AUCTION) { }
72
79
86
87MailReceiver::MailReceiver(Player* receiver) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUID().GetCounter()) { }
88
89MailReceiver::MailReceiver(Player* receiver, ObjectGuid::LowType receiver_lowguid) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid)
90{
91 ASSERT(!receiver || receiver->GetGUID().GetCounter() == receiver_lowguid);
92}
93
94MailReceiver::MailReceiver(Player* receiver, ObjectGuid receiverGuid) : m_receiver(receiver), m_receiver_lowguid(receiverGuid.GetCounter())
95{
96 ASSERT(!receiver || receiver->GetGUID() == receiverGuid);
97}
98
100{
101 m_items[item->GetGUID().GetCounter()] = item;
102 return *this;
103}
104
106{
108 return;
109
111
112 // The mail sent after turning in the quest The Good News and The Bad News contains 100g
113 if (m_mailTemplateId == 123)
114 m_money = 1000000;
115
116 Loot mailLoot(nullptr, ObjectGuid::Empty, LOOT_NONE, nullptr);
117
118 // can be empty
120
121 for (uint32 i = 0; m_items.size() < MAX_MAIL_ITEMS && i < mailLoot.items.size(); ++i)
122 {
123 if (LootItem const* lootitem = mailLoot.LootItemInSlot(i, receiver))
124 {
125 if (lootitem->type != LootItemType::Item)
126 continue;
127
128 if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, lootitem->context, receiver))
129 {
130 item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
131 AddItem(item);
132 }
133 }
134 }
135}
136
138{
139 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
140 {
141 Item* item = mailItemIter->second;
142
143 if (inDB)
144 item->DeleteFromDB(trans);
145
146 delete item;
147 }
148
149 m_items.clear();
150}
151
153{
154 ObjectGuid receiverGuid = ObjectGuid::Create<HighGuid::Player>(receiver_guid);
155 Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid);
156
157 uint32 rc_account = 0;
158 if (!receiver)
159 rc_account = sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
160
161 if (!receiver && !rc_account) // sender not exist
162 {
163 deleteIncludedItems(trans, true);
164 return;
165 }
166
167 // prepare mail and send in other case
168 bool needItemDelay = false;
169
170 if (!m_items.empty())
171 {
172 // if item send to character at another account, then apply item delivery delay
173 needItemDelay = sender_acc != rc_account;
174
175 // set owner to new receiver (to prevent delete item with sender char deleting)
176 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
177 {
178 Item* item = mailItemIter->second;
179 item->SaveToDB(trans); // item not in inventory and can be save standalone
180 // owner in data will set at mail receive and item extracting
182 stmt->setUInt64(0, receiver_guid);
183 stmt->setUInt64(1, item->GetGUID().GetCounter());
184 trans->Append(stmt);
185 }
186 }
187
188 // If theres is an item, there is a one hour delivery delay.
189 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
190
191 // will delete item or place to receiver mail list
192 SendMailTo(trans, MailReceiver(receiver, receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
193}
194
195void MailDraft::SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
196{
197 Player* pReceiver = receiver.GetPlayer(); // can be NULL
198 Player* pSender = sender.GetMailMessageType() == MAIL_NORMAL ? ObjectAccessor::FindPlayer(ObjectGuid::Create<HighGuid::Player>(sender.GetSenderId())) : nullptr;
199
200 if (pReceiver)
201 prepareItems(pReceiver, trans); // generate mail template items
202
203 uint64 mailId = sObjectMgr->GenerateMailID();
204
205 time_t deliver_time = GameTime::GetGameTime() + deliver_delay;
206
207 //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour
208 uint32 expire_delay;
209
210 // auction mail without any items and money
211 if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money)
212 expire_delay = sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY);
213 // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master)
214 else
215 {
216 if (m_COD)
217 expire_delay = 3 * DAY;
218 else
219 expire_delay = pSender && pSender->IsGameMaster() ? 90 * DAY : 30 * DAY;
220 }
221
222 time_t expire_time = deliver_time + expire_delay;
223
224 // Add to DB
225 uint8 index = 0;
227 stmt->setUInt64( index, mailId);
228 stmt->setUInt8 (++index, uint8(sender.GetMailMessageType()));
229 stmt->setInt8 (++index, int8(sender.GetStationery()));
230 stmt->setUInt16(++index, GetMailTemplateId());
231 stmt->setUInt64(++index, sender.GetSenderId());
232 stmt->setUInt64(++index, receiver.GetPlayerGUIDLow());
233 stmt->setString(++index, GetSubject());
234 stmt->setString(++index, GetBody());
235 stmt->setBool (++index, !m_items.empty());
236 stmt->setInt64 (++index, expire_time);
237 stmt->setInt64 (++index, deliver_time);
238 stmt->setUInt64(++index, m_money);
239 stmt->setUInt64(++index, m_COD);
240 stmt->setUInt8 (++index, uint8(checked));
241 trans->Append(stmt);
242
243 for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
244 {
245 Item* pItem = mailItemIter->second;
246 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL_ITEM);
247 stmt->setUInt64(0, mailId);
248 stmt->setUInt64(1, pItem->GetGUID().GetCounter());
249 stmt->setUInt64(2, receiver.GetPlayerGUIDLow());
250 trans->Append(stmt);
251 }
252
253 // For online receiver update in game mail status and data
254 if (pReceiver)
255 {
256 pReceiver->AddNewMailDeliverTime(deliver_time);
257
258 Mail* m = new Mail;
259 m->messageID = mailId;
261 m->subject = GetSubject();
262 m->body = GetBody();
263 m->money = GetMoney();
264 m->COD = GetCOD();
265
266 for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
267 {
268 Item* item = mailItemIter->second;
269 m->AddItem(item->GetGUID().GetCounter(), item->GetEntry());
270 }
271
272 m->messageType = sender.GetMailMessageType();
273 m->stationery = sender.GetStationery();
274 m->sender = sender.GetSenderId();
275 m->receiver = receiver.GetPlayerGUIDLow();
276 m->expire_time = expire_time;
277 m->deliver_time = deliver_time;
278 m->checked = checked;
280
281 pReceiver->AddMail(m); // to insert new mail to beginning of maillist
282
283 if (!m_items.empty())
284 {
285 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
286 pReceiver->AddMItem(mailItemIter->second);
287 }
288 }
289 else if (!m_items.empty())
290 {
293 }
294}
#define sCharacterCache
@ CHAR_UPD_ITEM_OWNER
@ CHAR_INS_MAIL_ITEM
@ CHAR_INS_MAIL
@ DAY
Definition Common.h:34
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
uint64_t uint64
Definition Define.h:153
#define UI64LIT(N)
Definition Define.h:139
uint32_t uint32
Definition Define.h:154
#define ASSERT
Definition Errors.h:80
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)
@ LOOT_NONE
Definition Loot.h:100
MailCheckMask
Definition Mail.h:51
@ MAIL_CHECK_MASK_RETURNED
Definition Mail.h:54
@ MAIL_STATE_UNCHANGED
Definition Mail.h:74
#define MAX_MAIL_ITEMS
Definition Mail.h:35
MailStationery
Definition Mail.h:62
@ MAIL_STATIONERY_GM
Definition Mail.h:65
@ MAIL_STATIONERY_DEFAULT
Definition Mail.h:64
@ MAIL_STATIONERY_AUCTION
Definition Mail.h:66
@ MAIL_AUCTION
Definition Mail.h:40
@ MAIL_BLACKMARKET
Definition Mail.h:44
@ MAIL_GAMEOBJECT
Definition Mail.h:42
@ MAIL_CREATURE
Definition Mail.h:41
@ MAIL_CALENDAR
Definition Mail.h:43
@ MAIL_NORMAL
Definition Mail.h:39
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:46
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
#define sObjectMgr
Definition ObjectMgr.h:1885
@ LOOT_MODE_DEFAULT
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
Definition Item.h:179
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition Item.cpp:639
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition Item.cpp:1180
static Item * CreateItem(uint32 itemEntry, uint32 count, ItemContext context, Player const *player=nullptr, bool addDefaultBonuses=true)
Definition Item.cpp:1721
uint64 GetCOD() const
Definition Mail.h:140
void deleteIncludedItems(CharacterDatabaseTransaction trans, bool inDB=false)
Definition Mail.cpp:137
uint64 m_money
Definition Mail.h:163
MailItemMap m_items
Definition Mail.h:161
std::string const & GetSubject() const
Definition Mail.h:138
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition Mail.cpp:195
uint16 m_mailTemplateId
Definition Mail.h:156
bool m_mailTemplateItemsNeed
Definition Mail.h:157
void SendReturnToSender(uint32 sender_acc, ObjectGuid::LowType sender_guid, ObjectGuid::LowType receiver_guid, CharacterDatabaseTransaction trans)
Definition Mail.cpp:152
uint16 GetMailTemplateId() const
Definition Mail.h:137
void prepareItems(Player *receiver, CharacterDatabaseTransaction trans)
Definition Mail.cpp:105
uint64 m_COD
Definition Mail.h:164
MailDraft & AddItem(Item *item)
Definition Mail.cpp:99
std::string const & GetBody() const
Definition Mail.h:141
uint64 GetMoney() const
Definition Mail.h:139
Player * GetPlayer() const
Definition Mail.h:119
ObjectGuid::LowType GetPlayerGUIDLow() const
Definition Mail.h:120
MailReceiver(ObjectGuid::LowType receiver_lowguid)
Definition Mail.h:114
MailStationery m_stationery
Definition Mail.h:108
ObjectGuid::LowType GetSenderId() const
Definition Mail.h:103
MailSender(MailMessageType messageType, ObjectGuid::LowType sender_guidlow_or_entry, MailStationery stationery=MAIL_STATIONERY_DEFAULT)
Definition Mail.h:91
MailMessageType m_messageType
Definition Mail.h:106
MailMessageType GetMailMessageType() const
Definition Mail.h:102
MailStationery GetStationery() const
Definition Mail.h:104
ObjectGuid::LowType m_senderId
Definition Mail.h:107
LowType GetCounter() const
Definition ObjectGuid.h:336
static ObjectGuid const Empty
Definition ObjectGuid.h:314
uint64 LowType
Definition ObjectGuid.h:321
uint32 GetEntry() const
Definition Object.h:89
void AddNewMailDeliverTime(time_t deliver_time)
Definition Player.cpp:2664
void AddMItem(Item *it)
Definition Player.cpp:22454
void AddMail(Mail *mail)
Definition Player.cpp:2613
bool IsGameMaster() const
Definition Player.h:1309
void setInt8(uint8 index, int8 value)
void setUInt16(uint8 index, uint16 value)
void setString(uint8 index, std::string &&value)
void setInt64(uint8 index, int64 value)
void setBool(uint8 index, bool value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
#define sWorld
Definition World.h:916
@ CONFIG_MAIL_DELIVERY_DELAY
Definition World.h:294
time_t GetGameTime()
Definition GameTime.cpp:52
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
Definition Loot.h:286
LootItem * LootItemInSlot(uint32 lootListId, Player const *player, NotNormalLootItem **ffaItem=nullptr)
Definition Loot.cpp:1074
std::vector< LootItem > items
Definition Loot.h:289
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT, ItemContext context=ItemContext::NONE)
Definition Loot.cpp:859
Definition Mail.h:175
uint64 messageID
Definition Mail.h:176
ObjectGuid::LowType receiver
Definition Mail.h:181
uint8 messageType
Definition Mail.h:177
uint64 money
Definition Mail.h:188
uint64 COD
Definition Mail.h:189
time_t expire_time
Definition Mail.h:186
uint8 stationery
Definition Mail.h:178
ObjectGuid::LowType sender
Definition Mail.h:180
std::string subject
Definition Mail.h:182
std::string body
Definition Mail.h:183
void AddItem(ObjectGuid::LowType itemGuidLow, uint32 item_template)
Definition Mail.h:193
time_t deliver_time
Definition Mail.h:187
uint32 checked
Definition Mail.h:190
MailState state
Definition Mail.h:191
uint16 mailTemplateId
Definition Mail.h:179