29 std::string receiverName;
37struct MailDeleteRequest
42struct MailboxMailRequest
48struct MailTakeItemRequest
55struct MailTakeMoneyRequest
67bool ReadSendMailRequest(
WorldPacket& recvData, SendMailRequest& request)
73 recvData >> request.unk1 >> request.unk2;
74 recvData >> request.COD >> request.money;
76 request.mailbox[0] = recvData.
ReadBit();
77 request.mailbox[6] = recvData.
ReadBit();
78 request.mailbox[4] = recvData.
ReadBit();
79 request.mailbox[1] = recvData.
ReadBit();
81 request.mailbox[3] = recvData.
ReadBit();
82 receiverLength = recvData.
ReadBits(9);
83 request.mailbox[7] = recvData.
ReadBit();
84 request.mailbox[5] = recvData.
ReadBit();
90 request.itemCount =
uint8(itemCount);
92 for (
uint8 i = 0; i < request.itemCount; ++i)
94 request.itemGuids[i][1] = recvData.
ReadBit();
95 request.itemGuids[i][7] = recvData.
ReadBit();
96 request.itemGuids[i][2] = recvData.
ReadBit();
97 request.itemGuids[i][5] = recvData.
ReadBit();
98 request.itemGuids[i][0] = recvData.
ReadBit();
99 request.itemGuids[i][6] = recvData.
ReadBit();
100 request.itemGuids[i][3] = recvData.
ReadBit();
101 request.itemGuids[i][4] = recvData.
ReadBit();
104 subjectLength = recvData.
ReadBits(9);
105 request.mailbox[2] = recvData.
ReadBit();
107 for (
uint8 i = 0; i < request.itemCount; ++i)
121 request.body = recvData.
ReadString(bodyLength);
123 request.subject = recvData.
ReadString(subjectLength);
130 request.receiverName = recvData.
ReadString(receiverLength);
135MailboxMailRequest ReadMailMarkAsReadRequest(
WorldPacket& recvData)
137 MailboxMailRequest request;
138 recvData >> request.mailId;
140 request.mailbox[0] = recvData.
ReadBit();
141 request.mailbox[2] = recvData.
ReadBit();
142 request.mailbox[3] = recvData.
ReadBit();
144 request.mailbox[4] = recvData.
ReadBit();
145 request.mailbox[6] = recvData.
ReadBit();
146 request.mailbox[7] = recvData.
ReadBit();
147 request.mailbox[1] = recvData.
ReadBit();
148 request.mailbox[5] = recvData.
ReadBit();
163MailDeleteRequest ReadMailDeleteRequest(
WorldPacket& recvData)
165 MailDeleteRequest request;
166 recvData >> request.mailId;
171MailboxMailRequest ReadMailReturnToSenderRequest(
WorldPacket& recvData)
173 MailboxMailRequest request;
174 recvData >> request.mailId;
176 request.mailbox[2] = recvData.
ReadBit();
177 request.mailbox[0] = recvData.
ReadBit();
178 request.mailbox[4] = recvData.
ReadBit();
179 request.mailbox[6] = recvData.
ReadBit();
180 request.mailbox[3] = recvData.
ReadBit();
181 request.mailbox[1] = recvData.
ReadBit();
182 request.mailbox[7] = recvData.
ReadBit();
183 request.mailbox[5] = recvData.
ReadBit();
197MailTakeItemRequest ReadMailTakeItemRequest(
WorldPacket& recvData)
199 MailTakeItemRequest request;
200 recvData >> request.mailId;
201 recvData >> request.itemId;
203 request.mailbox[6] = recvData.
ReadBit();
204 request.mailbox[5] = recvData.
ReadBit();
205 request.mailbox[2] = recvData.
ReadBit();
206 request.mailbox[3] = recvData.
ReadBit();
207 request.mailbox[0] = recvData.
ReadBit();
208 request.mailbox[1] = recvData.
ReadBit();
209 request.mailbox[4] = recvData.
ReadBit();
210 request.mailbox[7] = recvData.
ReadBit();
224MailTakeMoneyRequest ReadMailTakeMoneyRequest(
WorldPacket& recvData)
226 MailTakeMoneyRequest request;
227 recvData >> request.mailId;
228 recvData >> request.money;
230 request.mailbox[7] = recvData.
ReadBit();
231 request.mailbox[6] = recvData.
ReadBit();
232 request.mailbox[3] = recvData.
ReadBit();
233 request.mailbox[2] = recvData.
ReadBit();
234 request.mailbox[4] = recvData.
ReadBit();
235 request.mailbox[5] = recvData.
ReadBit();
236 request.mailbox[0] = recvData.
ReadBit();
237 request.mailbox[1] = recvData.
ReadBit();
251MailboxRequest ReadGetMailListRequest(
WorldPacket& recvData)
253 MailboxRequest request;
255 request.mailbox[6] = recvData.
ReadBit();
256 request.mailbox[3] = recvData.
ReadBit();
257 request.mailbox[7] = recvData.
ReadBit();
258 request.mailbox[5] = recvData.
ReadBit();
259 request.mailbox[4] = recvData.
ReadBit();
260 request.mailbox[1] = recvData.
ReadBit();
261 request.mailbox[2] = recvData.
ReadBit();
262 request.mailbox[0] = recvData.
ReadBit();
276MailboxMailRequest ReadMailCreateTextItemRequest(
WorldPacket& recvData)
278 MailboxMailRequest request;
279 recvData >> request.mailId;
281 request.mailbox[4] = recvData.
ReadBit();
282 request.mailbox[1] = recvData.
ReadBit();
283 request.mailbox[6] = recvData.
ReadBit();
284 request.mailbox[2] = recvData.
ReadBit();
285 request.mailbox[5] = recvData.
ReadBit();
286 request.mailbox[3] = recvData.
ReadBit();
287 request.mailbox[0] = recvData.
ReadBit();
288 request.mailbox[7] = recvData.
ReadBit();
307bool IsDeliveredMail(
Mail const* mail)
315 if (!IsDeliveredMail(mail))
327 if (!IsDeliveredMail(mail) || (money > 0 && mail->
money != money))
350 if (mail && mail->
COD)
359bool ValidateSendMailCost(
Player* player,
uint64 requiredMoney)
368bool ValidateReceiverMailboxCapacity(
Player* player,
uint8 mailsCount)
371 if (mailsCount <= 100)
383 for (
uint8 i = 0; i < itemCount; ++i)
396bool ValidateReceiverFaction(
Player* player,
uint32 receiverTeam,
bool accountBound,
bool allowTwoSideMail)
398 if (accountBound || player->
GetTeam() == receiverTeam || allowTwoSideMail)
407 for (
uint8 i = 0; i < itemCount; ++i)
472 SendMailRequest request;
473 if (!ReadSendMailRequest(recvData, request))
482 uint64 money = request.money;
484 std::string& receiverName = request.receiverName;
485 std::string
const& subject = request.subject;
486 std::string
const& body = request.body;
487 uint32 unk1 = request.unk1;
488 uint32 unk2 = request.unk2;
489 uint8 itemCount = request.itemCount;
495 if (!HasMailboxAccess(player, mailbox))
498 if (receiverName.empty())
509 receiverGuid =
sObjectMgr->GetPlayerGUIDByName(receiverName);
513 SF_LOG_INFO(
"network",
"Player %u is sending mail to %s (GUID: not existed!) with subject %s "
514 "and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u",
515 player->
GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(),
516 itemCount, money, COD, unk1, unk2);
521 SF_LOG_INFO(
"network",
"Player %u is sending mail to %s (GUID: %u) with subject %s and body %s "
522 "includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u",
524 body.c_str(), itemCount, money, COD, unk1, unk2);
526 if (player->
GetGUID() == receiverGuid)
532 uint32 cost = itemCount ? 30 * itemCount : 30;
534 uint64 reqmoney = cost + money;
536 if (!ValidateSendMailCost(player, reqmoney))
542 uint8 mailsCount = 0;
543 uint8 receiverLevel = 0;
544 uint32 receiverAccountId = 0;
548 receiverTeam = receiver->
GetTeam();
550 receiverLevel = receiver->
getLevel();
555 receiverTeam =
sObjectMgr->GetPlayerTeamByGUID(receiverGuid);
563 Field* fields = result->Fetch();
573 Field* fields = result->Fetch();
574 receiverLevel = fields[0].
GetUInt8();
577 receiverAccountId =
sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid);
581 if (!ValidateReceiverMailboxCapacity(player, mailsCount))
585 bool accountBound = AreAttachedItemsAccountBound(player, itemGuids, itemCount);
597 if (!ValidateSendMailAttachments(player, itemGuids, itemCount, COD, receiverAccountId, items))
605 bool needItemDelay =
false;
611 if (itemCount > 0 || money > 0)
616 for (
uint8 i = 0; i < itemCount; ++i)
618 Item* item = items[i];
621 sLog->outCommand(
GetAccountId(),
"GM %s (GUID: %u) (Account: %u) mail item: %s (Entry: %u Count: %u) "
624 receiverName.c_str(),
GUID_LOPART(receiverGuid), receiverAccountId);
641 if (log && money > 0)
643 sLog->outCommand(
GetAccountId(),
"GM %s (GUID: %u) (Account: %u) mail money: " UI64FMTD " to player: %s (GUID: %u) (Account: %u)",
653 if (guild->GetLevel() >= 17 && guild->IsMember(receiverGuid))
669 MailboxMailRequest request = ReadMailMarkAsReadRequest(recvData);
671 uint32 mailId = request.mailId;
673 if (!HasMailboxAccess(
_player, mailbox))
684 _player->m_mailsUpdated =
true;
691 MailDeleteRequest request = ReadMailDeleteRequest(recvData);
692 uint32 mailId = request.mailId;
697 if (!ValidateMailDelete(
_player, mailId, mail))
703 _player->m_mailsUpdated =
true;
709 MailboxMailRequest request = ReadMailReturnToSenderRequest(recvData);
711 uint32 mailId = request.mailId;
713 if (!HasMailboxAccess(
_player, mailbox))
742 for (MailItemInfoVec::iterator itr2 = m->
items.begin(); itr2 != m->
items.end(); ++itr2)
744 if (
Item*
const item = player->
GetMItem(itr2->item_guid))
761 MailTakeItemRequest request = ReadMailTakeItemRequest(recvData);
763 uint32 mailId = request.mailId;
764 uint32 itemId = request.itemId;
766 if (!HasMailboxAccess(
_player, mailbox))
776 if (!ValidateMailCODPayment(player, mailId, m))
798 std::string sender_name;
802 sender_name = receiver->
GetName();
807 sender_accId =
sObjectMgr->GetPlayerAccountIdByGUID(sender_guid);
809 if (!
sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name))
812 sLog->outCommand(
GetAccountId(),
"GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: " UI64FMTD " to player: %s (Account: %u)",
816 sender_accId =
sObjectMgr->GetPlayerAccountIdByGUID(sender_guid);
819 if (receiver || sender_accId)
849 MailTakeMoneyRequest request = ReadMailTakeMoneyRequest(recvData);
851 uint64 money = request.money;
852 uint32 mailId = request.mailId;
854 if (!HasMailboxAccess(
_player, mailbox))
859 Mail* m = GetMoneyMailOrSendResult(player, mailId, money);
885 MailboxRequest request = ReadGetMailListRequest(recvData);
888 if (!HasMailboxAccess(
_player, mailbox))
898 const uint32 maxPacketSize = 32767;
902 time_t cur_time = time(NULL);
908 size_t mailCountPos = data.
bitwpos();
936 4 + 4 + 4 + 4 + 1 + 4) + mail->
body.size() + mail->
subject.size() + 4 + 4 + 8 + 4 + 8 + 4 + 4 + 1 + 4;
938 if (data.
wpos() + nextMailSize > maxPacketSize)
950 size_t itemCountPos = data.
bitwpos();
965 uint8 trueItemCount = 0;
966 for (
uint8 i = 0; i < itemCount; i++)
991 mailData <<
uint8(i);
997 data.
PutBits(itemCountPos, trueItemCount, 17);
1013 mailData << float(
float(mail->
expire_time - time(NULL)) /
float(
DAY));
1031 data.
PutBits(mailCountPos, mailCount, 18);
1036 _player->UpdateNextMailTimeAndUnreads();
1042 MailboxMailRequest request = ReadMailCreateTextItemRequest(recvData);
1044 uint32 mailId = request.mailId;
1046 if (!HasMailboxAccess(
_player, mailbox))
1051 Mail* m = GetTextMailOrSendResult(player, mailId);
1066 if (!mailTemplateEntry)
1080 SF_LOG_INFO(
"network",
"HandleMailCreateTextItem mailid=%u", mailId);
1090 player->
StoreItem(dest, bodyItem,
true);
1112 time_t now = time(NULL);
1113 bool hasVirtualRealmAddress =
false, hasNativeRealmAddress =
false;
1118 for (PlayerMails::iterator itr =
_player->GetMailBegin(); itr !=
_player->GetMailEnd(); ++itr)
1126 if (now < m->deliver_time)
1132 data.
WriteBit(hasVirtualRealmAddress);
1134 data.
WriteBit(hasNativeRealmAddress);
1150 if (hasNativeRealmAddress)
1155 if (hasVirtualRealmAddress)
@ CHAR_DEL_MAIL_ITEM_BY_ID
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
@ MAX_INSPECTED_ENCHANTMENT_SLOT
@ EQUIP_ERR_TOO_MUCH_GOLD
@ EQUIP_ERR_MAIL_BOUND_ITEM
@ EQUIP_ERR_DESTROY_NONEMPTY_BAG
@ EQUIP_ERR_NOT_SAME_ACCOUNT
@ ITEM_PROTO_FLAG_CONJURED
@ ITEM_PROTO_FLAG_BIND_TO_ACCOUNT
@ ITEM_FLAG_MAIL_TEXT_MASK
#define SF_LOG_INFO(filterType__,...)
@ MAIL_CHECK_MASK_HAS_BODY
@ MAIL_CHECK_MASK_COD_PAYMENT
This mail was copied. Do not allow making a copy of items in mail.
@ MAIL_CHECK_MASK_COPIED
This mail was returned. Do not allow returning mail back again.
#define MAIL_BODY_ITEM_TEMPLATE
uint32 GUID_LOPART(uint64 x)
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
bool normalizePlayerName(std::string &name)
std::vector< ItemPosCount > ItemPosCountVec
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
@ GAMEOBJECT_TYPE_MAILBOX
@ MAIL_RETURNED_TO_SENDER
@ MAIL_ERR_NOT_ENOUGH_MONEY
@ MAIL_ERR_CANT_SEND_WRAPPED_COD
@ MAIL_ERR_RECIPIENT_CAP_REACHED
@ MAIL_ERR_RECIPIENT_NOT_FOUND
@ MAIL_ERR_TOO_MANY_ATTACHMENTS
@ MAIL_ERR_MAIL_ATTACHMENT_INVALID
@ MAIL_ERR_INTERNAL_ERROR
@ MAIL_ERR_CANNOT_SEND_TO_SELF
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
@ ITEM_FIELD_MAX_DURABILITY
@ ITEM_FIELD_DYNAMIC_FLAGS
bool WriteBit(uint32 bit)
void put(size_t pos, T value)
size_t bitwpos() const
Returns position of last written bit.
void WriteString(std::string const &str)
uint32 ReadBits(size_t bits)
void ReadByteSeq(uint8 &b)
std::string ReadString(size_t length)
void PutBits(size_t pos, T value, uint32 bitCount)
void WriteBits(T value, size_t bits)
void WriteByteSeq(uint8 b)
void SetNotRefundable(Player *owner, bool changestate=true, SQLTransaction *trans=NULL)
void SetText(std::string const &text)
void SetState(ItemUpdateState state, Player *forplayer=NULL)
uint32 GetEnchantmentId(EnchantmentSlot slot) const
int32 GetSpellCharges(uint8 index=0) const
void SetOwnerGUID(uint64 guid)
bool IsBoundAccountWide() const
bool CanBeTraded(bool mail=false, bool trade=false) const
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
virtual void SaveToDB(SQLTransaction &trans)
int32 GetItemRandomPropertyId() const
ItemTemplate const * GetTemplate() const
uint32 GetItemSuffixFactor() const
static void DeleteFromInventoryDB(SQLTransaction &trans, uint32 itemGuid)
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
bool IsNotEmptyBag() const
virtual bool Create(uint32 guidlow, uint32 itemid, Player const *owner)
MailDraft & AddCOD(uint32 COD)
void SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction &trans)
void SendMailTo(SQLTransaction &trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
MailDraft & AddItem(Item *item)
MailDraft & AddMoney(uint64 money)
static Player * FindPlayer(uint64)
uint32 GetUInt32Value(uint16 index) const
uint32 GetGUIDLow() const
void SetFlag(uint16 index, uint32 newFlag)
bool HasFlag(uint16 index, uint32 flag) const
void SetUInt32Value(uint16 index, uint32 value)
void SaveInventoryAndGoldToDB(SQLTransaction &trans)
void _SaveMail(SQLTransaction &trans)
bool ModifyMoney(int64 amount, bool sendError=true)
uint32 GetGuildId() const
bool RemoveMItem(uint32 id)
void RemoveMail(uint32 id)
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError=0, uint32 item_guid=0, uint32 item_count=0)
PlayerMails::iterator GetMailBegin()
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
WorldSession * GetSession() const
Item * GetItemByGuid(uint64 guid) const
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update)
GameObject * GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const
void MoveItemToInventory(ItemPosCountVec const &dest, Item *pItem, bool update, bool in_characterInventoryDB=false)
bool IsGameMaster() const
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, Unit *unit=NULL)
PlayerMails::iterator GetMailEnd()
Item * GetMItem(uint32 id)
void SaveGoldToDB(SQLTransaction &trans)
Mail * GetMail(uint32 id)
bool HasEnoughMoney(uint64 amount) const
void setUInt32(const uint8 index, const uint32 value)
std::string const & GetName() const
void HandleMailCreateTextItem(WorldPacket &recvData)
void HandleMailReturnToSender(WorldPacket &recvData)
const char * GetSkyFireString(int32 entry) const
void HandleSendMail(WorldPacket &recvData)
void SendNotification(const char *format,...) ATTR_PRINTF(2
uint32 GetGuidLow() const
Get player guid if available. Use for logging purposes only.
Player * GetPlayer() const
void HandleMailTakeItem(WorldPacket &recvData)
void HandleMailTakeMoney(WorldPacket &recvData)
void HandleGetMailList(WorldPacket &recvData)
void HandleMailMarkAsRead(WorldPacket &recvData)
bool HasPermission(uint32 permissionId)
void HandleQueryNextMailTime(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetAccountId() const
std::string const & GetPlayerName() const
void HandleMailDelete(WorldPacket &recvData)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
@ SMSG_MAIL_QUERY_NEXT_TIME_RESULT
uint32 realmID
Id of the realm.
@ CONFIG_MAIL_DELIVERY_DELAY
@ RBAC_PERM_TWO_SIDE_INTERACTION_MAIL
std::vector< uint32 > removedItems
std::vector< MailItemInfo > items
bool RemoveItem(uint32 item_guid)