mirror of
https://github.com/mangosfour/server.git
synced 2025-12-25 22:37:04 +00:00
It expected to be used in 2 case: some gameevent must send mails at start/end,
and this can be useful in game commands. Both case wil implemented in later commits.
* New MassMailMgr can accept tasks for send mass mails in safe way for map update threads context/etc.
* It work in way:
- By provided race mask or more generic SQL query string in async query selected affected characters
- At query result ready at next world tick update in safe common part of tick code some from mails
from queued mas mail tasks send.
- Amount mails limited MassMailer.SendPerTick confir option (10 by default). This done for prevent
high server load/lags at send too many mails in one tick (mail send all existed characters in DB
who match to seelction criteria)
- Manager not persistant for server shutdowns so any not send mails in queue lost at shutdown.
But with default setting 10K mail send in 20 secs (10000/50/10). Adding more safe execution
for this case will make related code lot more slow and req. many DB tables and code support.
370 lines
14 KiB
C++
370 lines
14 KiB
C++
/*
|
|
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
|
*
|
|
* 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
|
|
* 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
|
|
*/
|
|
|
|
/**
|
|
* @addtogroup mailing The mail system
|
|
* The mailing system in MaNGOS consists of mostly 4 files:
|
|
* - Mail.h
|
|
* - Mail.cpp
|
|
* - MassMailMgr.h
|
|
* - MassMailMgr.cpp
|
|
*
|
|
* @{
|
|
*
|
|
* @file Mail.h
|
|
* This file contains the the headers needed for MaNGOS to handle mails.
|
|
*
|
|
*/
|
|
|
|
#ifndef MANGOS_MAIL_H
|
|
#define MANGOS_MAIL_H
|
|
|
|
#include "Common.h"
|
|
#include "ObjectGuid.h"
|
|
#include <map>
|
|
|
|
struct AuctionEntry;
|
|
class Item;
|
|
class Object;
|
|
class Player;
|
|
|
|
#define MAIL_BODY_ITEM_TEMPLATE 8383 ///< - plain letter, A Dusty Unsent Letter: 889
|
|
/// The maximal amount of items a mail can contain.
|
|
#define MAX_MAIL_ITEMS 12
|
|
/**
|
|
* The type of the mail.
|
|
* A mail can have 5 Different Types.
|
|
*/
|
|
enum MailMessageType
|
|
{
|
|
MAIL_NORMAL = 0,
|
|
MAIL_AUCTION = 2,
|
|
MAIL_CREATURE = 3, /// client send CMSG_CREATURE_QUERY on this mailmessagetype
|
|
MAIL_GAMEOBJECT = 4, /// client send CMSG_GAMEOBJECT_QUERY on this mailmessagetype
|
|
MAIL_ITEM = 5, /// client send CMSG_ITEM_QUERY on this mailmessagetype
|
|
};
|
|
/**
|
|
* A Mask representing the status of the mail.
|
|
*/
|
|
enum MailCheckMask
|
|
{
|
|
MAIL_CHECK_MASK_NONE = 0x00, /// Nothing.
|
|
MAIL_CHECK_MASK_READ = 0x01, /// This mail was read.
|
|
MAIL_CHECK_MASK_RETURNED = 0x02, /// This mail was returned. No allow return mail.
|
|
MAIL_CHECK_MASK_COPIED = 0x04, /// This mail was copied. No allow make item copy from mail text.
|
|
MAIL_CHECK_MASK_COD_PAYMENT = 0x08, /// This mail is payable on delivery.
|
|
MAIL_CHECK_MASK_HAS_BODY = 0x10, /// This mail has body text.
|
|
};
|
|
|
|
/**
|
|
* The different types of Stationaries that exist for mails.
|
|
* They have been gathered from Stationery.dbc
|
|
*/
|
|
enum MailStationery
|
|
{
|
|
MAIL_STATIONERY_TEST = 1,
|
|
MAIL_STATIONERY_DEFAULT = 41,
|
|
MAIL_STATIONERY_GM = 61,
|
|
MAIL_STATIONERY_AUCTION = 62,
|
|
MAIL_STATIONERY_VAL = 64,
|
|
MAIL_STATIONERY_CHR = 65,
|
|
MAIL_STATIONERY_ORP = 67, // new in 3.2.2
|
|
};
|
|
/**
|
|
* Representation of the State of a mail.
|
|
*/
|
|
enum MailState
|
|
{
|
|
MAIL_STATE_UNCHANGED = 1,
|
|
MAIL_STATE_CHANGED = 2,
|
|
MAIL_STATE_DELETED = 3
|
|
};
|
|
/**
|
|
* Answers contained in mails from auctionhouses.
|
|
*/
|
|
enum MailAuctionAnswers
|
|
{
|
|
AUCTION_OUTBIDDED = 0,
|
|
AUCTION_WON = 1,
|
|
AUCTION_SUCCESSFUL = 2,
|
|
AUCTION_EXPIRED = 3,
|
|
AUCTION_CANCELLED_TO_BIDDER = 4,
|
|
AUCTION_CANCELED = 5,
|
|
AUCTION_SALE_PENDING = 6
|
|
};
|
|
/**
|
|
* A class to represent the sender of a mail.
|
|
*/
|
|
class MailSender
|
|
{
|
|
public: // Constructors
|
|
MailSender() : m_messageType(MAIL_NORMAL), m_senderId(0), m_stationery(MAIL_STATIONERY_DEFAULT) {}
|
|
|
|
/**
|
|
* Creates a new MailSender object.
|
|
*
|
|
* @param messageType the type of the mail.
|
|
* @param sender_guidlow_or_entry The lower part of the GUID of the player sending
|
|
* this mail, or the Entry of the non-player object.
|
|
* @param stationery The stationary associated with this MailSender.
|
|
*
|
|
*/
|
|
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_DEFAULT)
|
|
: m_messageType(messageType), m_senderId(sender_guidlow_or_entry), m_stationery(stationery)
|
|
{
|
|
}
|
|
MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_DEFAULT);
|
|
MailSender(AuctionEntry* sender);
|
|
public: // Accessors
|
|
/// The Messagetype of this MailSender.
|
|
MailMessageType GetMailMessageType() const { return m_messageType; }
|
|
/// The GUID of the player represented by this MailSender, or the Entry of the non-player object.
|
|
uint32 GetSenderId() const { return m_senderId; }
|
|
/// The stationary associated with this MailSender
|
|
MailStationery GetStationery() const { return m_stationery; }
|
|
private:
|
|
// Trap for wrong used guid as low guid, no body
|
|
MailSender(MailMessageType messageType, uint64 wrong_guid, MailStationery stationery = MAIL_STATIONERY_DEFAULT);
|
|
|
|
MailMessageType m_messageType;
|
|
uint32 m_senderId; // player low guid or other object entry
|
|
MailStationery m_stationery;
|
|
};
|
|
/**
|
|
* A class to represent the receiver of a mail.
|
|
*/
|
|
class MailReceiver
|
|
{
|
|
public: // Constructors
|
|
explicit MailReceiver(ObjectGuid receiver_guid) : m_receiver(NULL), m_receiver_guid(receiver_guid) {}
|
|
MailReceiver(Player* receiver);
|
|
MailReceiver(Player* receiver, ObjectGuid receiver_guid);
|
|
public: // Accessors
|
|
/**
|
|
* Gets the player associated with this MailReciever
|
|
*
|
|
* @see Player
|
|
*
|
|
* @returns a pointer to the Player this mail is for.
|
|
*
|
|
*/
|
|
Player* GetPlayer() const { return m_receiver; }
|
|
/**
|
|
* Gets the low part of the recievers GUID.
|
|
*
|
|
* @returns the low part of the GUID of the player associated with this MailReciever
|
|
*/
|
|
ObjectGuid const& GetPlayerGuid() const { return m_receiver_guid; }
|
|
private:
|
|
Player* m_receiver;
|
|
ObjectGuid m_receiver_guid;
|
|
};
|
|
/**
|
|
* The class to represent the draft of a mail.
|
|
*/
|
|
class MailDraft
|
|
{
|
|
/**
|
|
* Holds a Map of GUIDs of items and pointers to the items.
|
|
*/
|
|
typedef std::map<uint32, Item*> MailItemMap;
|
|
|
|
public: // Constructors
|
|
/**
|
|
* Creates a new blank MailDraft object
|
|
*
|
|
*/
|
|
MailDraft()
|
|
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_money(0), m_COD(0) {}
|
|
/**
|
|
* Creates a new MailDraft object using mail template id.
|
|
*
|
|
* @param mailTemplateId The ID of the Template to be used.
|
|
* @param a boolean specifying whether the mail needs items or not.
|
|
*
|
|
*/
|
|
explicit MailDraft(uint16 mailTemplateId, bool need_items = true)
|
|
: m_mailTemplateId(mailTemplateId), m_mailTemplateItemsNeed(need_items), m_money(0), m_COD(0)
|
|
{}
|
|
/**
|
|
* Creates a new MailDraft object using subject and content texts.
|
|
*
|
|
* @param subject The subject of the mail.
|
|
* @param itemText The text of the body of the mail.
|
|
*/
|
|
MailDraft(std::string subject, std::string body)
|
|
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_body(body), m_money(0), m_COD(0) {}
|
|
public: // Accessors
|
|
/// Returns the template ID used for this MailDraft.
|
|
uint16 GetMailTemplateId() const { return m_mailTemplateId; }
|
|
/// Returns the subject of this MailDraft.
|
|
std::string const& GetSubject() const { return m_subject; }
|
|
/// Returns the subject of this MailDraft.
|
|
std::string const& GetBody() const { return m_body; }
|
|
/// Returns the amount of money in this MailDraft.
|
|
uint32 GetMoney() const { return m_money; }
|
|
/// Returns the Cost of delivery of this MailDraft.
|
|
uint32 GetCOD() const { return m_COD; }
|
|
public: // modifiers
|
|
|
|
// this two modifiers expected to be applied in normal case to blank draft and exclusively, it will work and with mixed cases but this will be not normal way use.
|
|
MailDraft& SetSubjectAndBody(std::string subject, std::string body) { m_subject = subject; m_body = body; return *this; }
|
|
MailDraft& SetMailTemplate(uint16 mailTemplateId, bool need_items = true) { m_mailTemplateId = mailTemplateId, m_mailTemplateItemsNeed = need_items; return *this; }
|
|
|
|
MailDraft& AddItem(Item* item);
|
|
/**
|
|
* Modifies the amount of money in a MailDraft.
|
|
*
|
|
* @param money The amount of money included in this MailDraft.
|
|
*/
|
|
MailDraft& SetMoney(uint32 money) { m_money = money; return *this; }
|
|
/**
|
|
* Modifies the cost of delivery of the MailDraft.
|
|
*
|
|
* @param COD the amount to which the cod should be set.
|
|
*/
|
|
MailDraft& SetCOD(uint32 COD) { m_COD = COD; return *this; }
|
|
|
|
void CloneFrom(MailDraft const& draft);
|
|
public: // finishers
|
|
void SendReturnToSender(uint32 sender_acc, ObjectGuid sender_guid, ObjectGuid receiver_guid);
|
|
void SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked = MAIL_CHECK_MASK_NONE, uint32 deliver_delay = 0);
|
|
private:
|
|
MailDraft(MailDraft const&); // trap decl, no body, mail draft must cloned only explicitly...
|
|
MailDraft& operator=(MailDraft const&); // trap decl, no body, ...because items clone is high price operation
|
|
|
|
void deleteIncludedItems(bool inDB = false);
|
|
void prepareItems(Player* receiver); ///< called from SendMailTo for generate mailTemplateBase items
|
|
|
|
/// The ID of the template associated with this MailDraft.
|
|
uint16 m_mailTemplateId;
|
|
/// Boolean specifying whether items are required or not.
|
|
bool m_mailTemplateItemsNeed;
|
|
/// The subject of the MailDraft.
|
|
std::string m_subject;
|
|
/// The body of the MailDraft.
|
|
std::string m_body;
|
|
/// A map of items in this MailDraft.
|
|
MailItemMap m_items; ///< Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
|
|
|
|
/// The amount of money in this MailDraft.
|
|
uint32 m_money;
|
|
/// The cod amount of this MailDraft.
|
|
uint32 m_COD;
|
|
};
|
|
/**
|
|
* Structure holding information about an item in the mail.
|
|
*/
|
|
struct MailItemInfo
|
|
{
|
|
uint32 item_guid; ///< the GUID of the item.
|
|
uint32 item_template; ///< the ID of the template of the item.
|
|
};
|
|
|
|
typedef std::vector<MailItemInfo> MailItemInfoVec;
|
|
/**
|
|
* Structure that holds an actual mail.
|
|
*/
|
|
struct Mail
|
|
{
|
|
/// the ID of the message contained in the mail.
|
|
uint32 messageID;
|
|
/// the type of the message
|
|
uint8 messageType;
|
|
/// the stationary used in this mail.
|
|
uint8 stationery;
|
|
/// the ID of the template this mail is based on.
|
|
uint16 mailTemplateId;
|
|
/// the LowGUID of the player that sent this mail, or creature low guid, or other id
|
|
uint32 sender;
|
|
/// the GUID of the player that this mail is sent to.
|
|
ObjectGuid receiverGuid;
|
|
/// the subject of the mail
|
|
std::string subject;
|
|
/// the body of the mail
|
|
std::string body;
|
|
/// A vector containing Information about the items in this mail.
|
|
MailItemInfoVec items;
|
|
/// A vector containing Information about the items that where already take from this mail.
|
|
std::vector<uint32> removedItems;
|
|
/// The time at which this mail will expire
|
|
time_t expire_time;
|
|
/// The time at which this mail (was/will be) delivered
|
|
time_t deliver_time;
|
|
/// The amount of money contained in this mail.
|
|
uint32 money;
|
|
/// The amount of money the receiver has to pay to get this mail.
|
|
uint32 COD;
|
|
/// The time at which this mail was read.
|
|
uint32 checked;
|
|
/// The state of this mail.
|
|
MailState state;
|
|
|
|
/**
|
|
* Adds an item to the mail.
|
|
* This method adds an item to mail represented by this structure.
|
|
* There is no checking done whether this is a legal action or not; it is up
|
|
* to the caller to make sure there is still room for more items in the mail.
|
|
*
|
|
* @param itemGuidLow the GUID(low) of the item added to the mail.
|
|
* @param item_template the ID of the template of the item.
|
|
*
|
|
*/
|
|
void AddItem(uint32 itemGuidLow, uint32 item_template)
|
|
{
|
|
MailItemInfo mii;
|
|
mii.item_guid = itemGuidLow;
|
|
mii.item_template = item_template;
|
|
items.push_back(mii);
|
|
}
|
|
|
|
/**
|
|
* Removes an item from the mail.
|
|
* This method removes an item from the mail.
|
|
*
|
|
* @see MailItemInfo
|
|
*
|
|
* @param item_guid The GUID of the item to be removed.
|
|
* @returns true if the item was removed, or false if no item with that GUID was found.
|
|
*
|
|
*/
|
|
bool RemoveItem(uint32 item_guid)
|
|
{
|
|
for(MailItemInfoVec::iterator itr = items.begin(); itr != items.end(); ++itr)
|
|
{
|
|
if(itr->item_guid == item_guid)
|
|
{
|
|
items.erase(itr);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Checks whether a mail contains items or not.
|
|
* HasItems() checks whether the mail contains items or not.
|
|
*
|
|
* @returns true if the mail contains items, false otherwise.
|
|
*
|
|
*/
|
|
bool HasItems() const { return !items.empty(); }
|
|
};
|
|
|
|
#endif
|
|
/*! @} */
|