Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Mail.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "AuctionHouseMgr.h"
7#include "BattlegroundMgr.h"
8#include "BlackMarketMgr.h"
9#include "CalendarMgr.h"
10#include "DatabaseEnv.h"
11#include "Item.h"
12#include "Log.h"
13#include "Mail.h"
14#include "ObjectMgr.h"
15#include "Player.h"
16#include "Unit.h"
17#include "World.h"
18
19MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery)
20{
21 switch (sender->GetTypeId())
22 {
23 case TypeID::TYPEID_UNIT:
24 m_messageType = MAIL_CREATURE;
25 m_senderId = sender->GetEntry();
26 break;
27 case TypeID::TYPEID_GAMEOBJECT:
28 m_messageType = MAIL_GAMEOBJECT;
29 m_senderId = sender->GetEntry();
30 break;
31 /*case TYPEID_ITEM:
32 m_messageType = MAIL_ITEM;
33 m_senderId = sender->GetEntry();
34 break;*/
35 case TypeID::TYPEID_PLAYER:
36 m_messageType = MAIL_NORMAL;
37 m_senderId = sender->GetGUIDLow();
38 break;
39 default:
40 m_messageType = MAIL_NORMAL;
41 m_senderId = 0; // will show mail from not existed player
42 SF_LOG_ERROR("misc", "MailSender::MailSender - Mail have unexpected sender typeid (%u)", uint8(sender->GetTypeId()));
43 break;
44 }
45}
46
48 : m_messageType(MAIL_CALENDAR), m_senderId(sender->GetEventId()), m_stationery(MAIL_STATIONERY_DEFAULT) { } // what stationery we should use here?
49
52
55
62
63MailReceiver::MailReceiver(Player* receiver) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUIDLow()) { }
64
65MailReceiver::MailReceiver(Player* receiver, uint32 receiver_lowguid) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid)
66{
67 ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid);
68}
69
71{
72 m_items[item->GetGUIDLow()] = item; return *this;
73}
74
76{
78 return;
79
81
82 Loot mailLoot;
83
84 // can be empty
85 mailLoot.FillLoot(m_mailTemplateId, LootTemplates_Mail, receiver, true, true);
86
87 uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
88 for (uint32 i = 0; m_items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
89 {
90 if (LootItem* lootitem = mailLoot.LootItemInSlot(i, receiver))
91 {
92 if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, receiver))
93 {
94 item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
95 AddItem(item);
96 }
97 }
98 }
99}
100
101void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/)
102{
103 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
104 {
105 Item* item = mailItemIter->second;
106
107 if (inDB)
108 {
109 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
110 stmt->setUInt32(0, item->GetGUIDLow());
111 trans->Append(stmt);
112 }
113
114 delete item;
115 }
116
117 m_items.clear();
118}
119
120void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction& trans)
121{
122 Player* receiver = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
123
124 uint32 rc_account = 0;
125 if (!receiver)
126 rc_account = sObjectMgr->GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
127
128 if (!receiver && !rc_account) // sender not exist
129 {
130 deleteIncludedItems(trans, true);
131 return;
132 }
133
134 // prepare mail and send in other case
135 bool needItemDelay = false;
136
137 if (!m_items.empty())
138 {
139 // if item send to character at another account, then apply item delivery delay
140 needItemDelay = sender_acc != rc_account;
141
142 // set owner to new receiver (to prevent delete item with sender char deleting)
143 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
144 {
145 Item* item = mailItemIter->second;
146 item->SaveToDB(trans); // item not in inventory and can be save standalone
147 // owner in data will set at mail receive and item extracting
148 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER);
149 stmt->setUInt32(0, receiver_guid);
150 stmt->setUInt32(1, item->GetGUIDLow());
151 trans->Append(stmt);
152 }
153 }
154
155 // If theres is an item, there is a one hour delivery delay.
156 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(WorldIntConfigs::CONFIG_MAIL_DELIVERY_DELAY) : 0;
157
158 // will delete item or place to receiver mail list
159 SendMailTo(trans, MailReceiver(receiver, receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
160}
161
162void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
163{
164 Player* pReceiver = receiver.GetPlayer(); // can be NULL
165 Player* pSender = sObjectMgr->GetPlayerByLowGUID(sender.GetSenderId());
166
167 if (pReceiver)
168 prepareItems(pReceiver, trans); // generate mail template items
169
170 uint32 mailId = sObjectMgr->GenerateMailID();
171
172 time_t deliver_time = time(NULL) + deliver_delay;
173
174 //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour
175 uint32 expire_delay;
176
177 // auction mail without any items and money
178 if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money)
179 expire_delay = sWorld->getIntConfig(WorldIntConfigs::CONFIG_MAIL_DELIVERY_DELAY);
180 // mail from battlemaster (rewardmarks) should last only one day
182 expire_delay = DAY;
183 // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master)
184 else
185 if (m_COD)
186 expire_delay = 3 * DAY;
187 else
188 expire_delay = pSender && pSender->IsGameMaster() ? 90 * DAY : 30 * DAY;
189
190 time_t expire_time = deliver_time + expire_delay;
191
192 // Add to DB
193 uint8 index = 0;
194 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL);
195 stmt->setUInt32(index, mailId);
196 stmt->setUInt8(++index, uint8(sender.GetMailMessageType()));
197 stmt->setInt8(++index, int8(sender.GetStationery()));
198 stmt->setUInt16(++index, GetMailTemplateId());
199 stmt->setUInt32(++index, sender.GetSenderId());
200 stmt->setUInt32(++index, receiver.GetPlayerGUIDLow());
201 stmt->setString(++index, GetSubject());
202 stmt->setString(++index, GetBody());
203 stmt->setBool(++index, !m_items.empty());
204 stmt->setUInt64(++index, uint64(expire_time));
205 stmt->setUInt64(++index, uint64(deliver_time));
206 stmt->setUInt32(++index, m_money);
207 stmt->setUInt32(++index, m_COD);
208 stmt->setUInt8(++index, uint8(checked));
209 trans->Append(stmt);
210
211 for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
212 {
213 Item* pItem = mailItemIter->second;
214 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL_ITEM);
215 stmt->setUInt32(0, mailId);
216 stmt->setUInt32(1, pItem->GetGUIDLow());
217 stmt->setUInt32(2, receiver.GetPlayerGUIDLow());
218 trans->Append(stmt);
219 }
220
221 // For online receiver update in game mail status and data
222 if (pReceiver)
223 {
224 pReceiver->AddNewMailDeliverTime(deliver_time);
225
226 if (pReceiver->IsMailsLoaded())
227 {
228 Mail* m = new Mail;
229 m->messageID = mailId;
231 m->subject = GetSubject();
232 m->body = GetBody();
233 m->money = GetMoney();
234 m->COD = GetCOD();
235
236 for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
237 {
238 Item* item = mailItemIter->second;
239 m->AddItem(item->GetGUIDLow(), item->GetEntry());
240 }
241
242 m->messageType = sender.GetMailMessageType();
243 m->stationery = sender.GetStationery();
244 m->sender = sender.GetSenderId();
245 m->receiver = receiver.GetPlayerGUIDLow();
246 m->expire_time = expire_time;
247 m->deliver_time = deliver_time;
248 m->checked = checked;
250
251 pReceiver->AddMail(m); // to insert new mail to beginning of maillist
252
253 if (!m_items.empty())
254 {
255 for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
256 pReceiver->AddMItem(mailItemIter->second);
257 }
258 }
259 else if (!m_items.empty())
260 {
261 SQLTransaction temp = SQLTransaction(NULL);
263 }
264 }
265 else if (!m_items.empty())
266 {
267 SQLTransaction temp = SQLTransaction(NULL);
269 }
270}
#define sBattlegroundMgr
@ CHAR_UPD_ITEM_OWNER
@ CHAR_DEL_ITEM_INSTANCE
@ CHAR_INS_MAIL_ITEM
@ CHAR_INS_MAIL
@ DAY
Definition Common.h:121
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)
MailCheckMask
Definition Mail.h:33
@ MAIL_CHECK_MASK_RETURNED
Definition Mail.h:36
@ MAIL_STATE_UNCHANGED
Definition Mail.h:57
#define MAX_MAIL_ITEMS
Definition Mail.h:20
MailStationery
Definition Mail.h:44
@ MAIL_STATIONERY_GM
Definition Mail.h:47
@ MAIL_STATIONERY_DEFAULT
Definition Mail.h:46
@ MAIL_STATIONERY_AUCTION
Definition Mail.h:48
@ MAIL_AUCTION
Definition Mail.h:25
@ MAIL_BLACKMARKET
Definition Mail.h:29
@ MAIL_CREATURE
Definition Mail.h:26
@ MAIL_CALENDAR
Definition Mail.h:28
@ MAIL_NORMAL
Definition Mail.h:24
@ HIGHGUID_PLAYER
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
#define sObjectMgr
Definition ObjectMgr.h:1617
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
Definition Item.h:202
virtual void SaveToDB(SQLTransaction &trans)
Definition Item.cpp:305
static Item * CreateItem(uint32 itemEntry, uint32 count, Player const *player=NULL)
Definition Item.cpp:1012
uint64 GetCOD() const
Definition Mail.h:121
uint64 m_money
Definition Mail.h:144
MailItemMap m_items
Definition Mail.h:142
std::string const & GetSubject() const
Definition Mail.h:119
void deleteIncludedItems(SQLTransaction &trans, bool inDB=false)
Definition Mail.cpp:101
uint16 m_mailTemplateId
Definition Mail.h:137
MailDraft(uint16 mailTemplateId, bool need_items=true)
Definition Mail.h:112
void SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction &trans)
Definition Mail.cpp:120
void SendMailTo(SQLTransaction &trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition Mail.cpp:162
bool m_mailTemplateItemsNeed
Definition Mail.h:138
uint16 GetMailTemplateId() const
Definition Mail.h:118
uint64 m_COD
Definition Mail.h:145
void prepareItems(Player *receiver, SQLTransaction &trans)
Definition Mail.cpp:75
MailDraft & AddItem(Item *item)
Definition Mail.cpp:70
std::string const & GetBody() const
Definition Mail.h:122
uint64 GetMoney() const
Definition Mail.h:120
Player * GetPlayer() const
Definition Mail.h:100
Player * m_receiver
Definition Mail.h:103
MailReceiver(uint32 receiver_lowguid)
Definition Mail.h:96
uint32 GetPlayerGUIDLow() const
Definition Mail.h:101
uint32 m_receiver_lowguid
Definition Mail.h:104
uint32 GetSenderId() const
Definition Mail.h:85
uint32 m_senderId
Definition Mail.h:89
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery=MAIL_STATIONERY_DEFAULT)
Definition Mail.h:74
MailStationery m_stationery
Definition Mail.h:90
MailMessageType m_messageType
Definition Mail.h:88
MailMessageType GetMailMessageType() const
Definition Mail.h:84
MailStationery GetStationery() const
Definition Mail.h:86
static Player * FindPlayer(uint64)
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:125
void AddNewMailDeliverTime(time_t deliver_time)
void AddMItem(Item *it)
void AddMail(Mail *mail)
Definition Player.h:2001
bool IsMailsLoaded() const
Definition Player.h:1994
bool IsGameMaster() const
Definition Player.h:1369
void setBool(const uint8 index, const bool value)
void setString(const uint8 index, const std::string &value)
void setUInt16(const uint8 index, const uint16 value)
void setUInt64(const uint8 index, const uint64 value)
void setInt8(const uint8 index, const int8 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
#define sWorld
Definition World.h:910
@ CONFIG_MAIL_DELIVERY_DELAY
Definition World.h:255
uint32 GetMaxSlotInLootFor(Player *player) const
Definition LootMgr.cpp:776
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT)
Definition LootMgr.cpp:418
LootItem * LootItemInSlot(uint32 lootslot, Player *player, QuestItem **qitem=NULL, QuestItem **ffaitem=NULL, QuestItem **conditem=NULL)
Definition LootMgr.cpp:713
Definition Mail.h:156
uint8 messageType
Definition Mail.h:161
uint32 messageID
Definition Mail.h:160
uint64 money
Definition Mail.h:172
uint64 COD
Definition Mail.h:173
time_t expire_time
Definition Mail.h:170
uint32 sender
Definition Mail.h:164
uint32 receiver
Definition Mail.h:165
uint8 stationery
Definition Mail.h:162
std::string subject
Definition Mail.h:166
std::string body
Definition Mail.h:167
time_t deliver_time
Definition Mail.h:171
uint32 checked
Definition Mail.h:174
MailState state
Definition Mail.h:175
void AddItem(uint32 itemGuidLow, uint32 item_template)
Definition Mail.h:177
uint16 mailTemplateId
Definition Mail.h:163