Rewrite much of the GM ticket system

* Extract storage and manipulation of tickets to TicketMgr (from ObjectMgr)
* Extract ticket commands to TicketCommands.cpp
* Adds support for sending GM responses and GM surveys.
* Fix structure of several ticket-related packets.
* Add support for understanding lag reports.
* Thanks Zor for some of the packet structures, and Cyrax for some sniffs
* Please report any issues encountered via the tracker.

--HG--
branch : trunk
This commit is contained in:
silinoron
2010-08-29 20:28:14 -07:00
parent 1f9936399c
commit 08205afcc9
23 changed files with 1311 additions and 624 deletions
-123
View File
@@ -8816,129 +8816,6 @@ Quest const* GetQuestTemplateStore(uint32 entry)
return sObjectMgr.GetQuestTemplate(entry);
}
uint64 ObjectMgr::GenerateGMTicketId()
{
return ++m_GMticketid;
}
void ObjectMgr::LoadGMTickets()
{
if (!m_GMTicketList.empty())
{
for (GmTicketList::const_iterator itr = m_GMTicketList.begin(); itr != m_GMTicketList.end(); ++itr)
delete *itr;
}
m_GMTicketList.clear();
m_GMticketid = 0;
QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT guid, playerGuid, name, message, createtime, map, posX, posY, posZ, timestamp, closed, assignedto, comment FROM gm_tickets");
if (!result)
{
barGoLink bar(1);
bar.step();
sLog.outString();
sLog.outString(">> GM Tickets table is empty, no tickets were loaded.");
return;
}
uint16 count = 0;
barGoLink bar ((*result).GetRowCount());
GM_Ticket *ticket;
do
{
Field *fields = result->Fetch();
ticket = new GM_Ticket;
ticket->guid = fields[0].GetUInt64();
ticket->playerGuid = fields[1].GetUInt64();
ticket->name = fields[2].GetCppString();
ticket->message = fields[3].GetCppString();
ticket->createtime = fields[4].GetUInt64();
ticket->map = fields[5].GetUInt32();
ticket->pos_x = fields[6].GetFloat();
ticket->pos_y = fields[7].GetFloat();
ticket->pos_z = fields[8].GetFloat();
ticket->timestamp = fields[9].GetUInt64();
ticket->closed = fields[10].GetUInt64();
ticket->assignedToGM = fields[11].GetUInt64();
ticket->comment = fields[12].GetCppString();
++count;
bar.step();
m_GMTicketList.push_back(ticket);
} while (result->NextRow());
result = CharacterDatabase.Query("SELECT MAX(guid) from gm_tickets");
if (result)
{
Field *fields = result->Fetch();
m_GMticketid = fields[0].GetUInt64();
}
sLog.outString(">> Loaded %u GM Tickets from the database.", count);
}
void ObjectMgr::AddOrUpdateGMTicket(GM_Ticket &ticket, bool create)
{
if (create)
m_GMTicketList.push_back(&ticket);
_AddOrUpdateGMTicket(ticket);
}
void ObjectMgr::_AddOrUpdateGMTicket(GM_Ticket &ticket)
{
std::string msg(ticket.message), name(ticket.name), comment(ticket.comment);
CharacterDatabase.escape_string(msg);
CharacterDatabase.escape_string(name);
CharacterDatabase.escape_string(comment);
std::ostringstream ss;
ss << "REPLACE INTO gm_tickets (guid, playerGuid, name, message, createtime, map, posX, posY, posZ, timestamp, closed, assignedto, comment) VALUES('";
ss << ticket.guid << "', '";
ss << ticket.playerGuid << "', '";
ss << name << "', '";
ss << msg << "', '" ;
ss << ticket.createtime << "', '";
ss << ticket.map << "', '";
ss << ticket.pos_x << "', '";
ss << ticket.pos_y << "', '";
ss << ticket.pos_z << "', '";
ss << ticket.timestamp << "', '";
ss << ticket.closed << "', '";
ss << ticket.assignedToGM << "', '";
ss << comment << "');";
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(trans);
}
void ObjectMgr::RemoveGMTicket(GM_Ticket *ticket, int64 source, bool permanently)
{
for (GmTicketList::iterator i = m_GMTicketList.begin(); i != m_GMTicketList.end(); ++i)
if ((*i)->guid == ticket->guid)
{
if (permanently)
{
CharacterDatabase.PExecute("DELETE FROM gm_tickets WHERE guid = '%u'", ticket->guid);
i = m_GMTicketList.erase(i);
ticket = NULL;
return;
}
(*i)->closed = source;
_AddOrUpdateGMTicket(*(*i));
}
}
void ObjectMgr::RemoveGMTicket(uint64 ticketGuid, int64 source, bool permanently)
{
GM_Ticket *ticket = GetGMTicket(ticketGuid);
ASSERT(ticket);
RemoveGMTicket(ticket, source, permanently);
}
CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unitClass)
{
CreatureBaseStatsMap::const_iterator it = m_creatureBaseStatsMap.find(MAKE_PAIR16(level,unitClass));
-43
View File
@@ -337,23 +337,6 @@ enum SkillRangeType
SKILL_RANGE_NONE, // 0..0 always
};
struct GM_Ticket
{
uint64 guid;
uint64 playerGuid;
std::string name;
float pos_x;
float pos_y;
float pos_z;
uint32 map;
std::string message;
uint64 createtime;
uint64 timestamp;
int64 closed; // 0 = Open, -1 = Console, playerGuid = player abandoned ticket, other = GM who closed it.
uint64 assignedToGM;
std::string comment;
};
typedef std::list<GM_Ticket*> GmTicketList;
SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial);
#define MAX_PLAYER_NAME 12 // max allowed by client name length
@@ -713,7 +696,6 @@ class ObjectMgr
void LoadTrainerSpell();
bool AddSpellToTrainer(uint32 entry, uint32 spell, Field *fields, std::set<uint32> *skip_trainers, std::set<uint32> *talentIds);
int LoadReferenceTrainer(uint32 trainer, int32 spell, std::set<uint32> *skip_trainers, std::set<uint32> *talentIds);
void LoadGMTickets();
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint8 level);
@@ -950,23 +932,6 @@ class ObjectMgr
return SpellClickInfoMapBounds(mSpellClickInfoMap.lower_bound(creature_id),mSpellClickInfoMap.upper_bound(creature_id));
}
GM_Ticket *GetGMTicket(uint64 ticketGuid)
{
for (GmTicketList::const_iterator i = m_GMTicketList.begin(); i != m_GMTicketList.end(); ++i)
if ((*i) && (*i)->guid == ticketGuid)
return (*i);
return NULL;
}
GM_Ticket *GetGMTicketByPlayer(uint64 playerGuid)
{
for (GmTicketList::const_iterator i = m_GMTicketList.begin(); i != m_GMTicketList.end(); ++i)
if ((*i) && (*i)->playerGuid == playerGuid && (*i)->closed == 0)
return (*i);
return NULL;
}
GossipMenusMapBounds GetGossipMenusMapBounds(uint32 uiMenuId) const
{
return GossipMenusMapBounds(m_mGossipMenusMap.lower_bound(uiMenuId),m_mGossipMenusMap.upper_bound(uiMenuId));
@@ -986,13 +951,6 @@ class ObjectMgr
return GossipMenuItemsMapBoundsNonConst(m_mGossipMenuItemsMap.lower_bound(uiMenuId),m_mGossipMenuItemsMap.upper_bound(uiMenuId));
}
void AddOrUpdateGMTicket(GM_Ticket &ticket, bool create = false);
void _AddOrUpdateGMTicket(GM_Ticket &ticket);
void RemoveGMTicket(uint64 ticketGuid, int64 source = -1, bool permanently = false);
void RemoveGMTicket(GM_Ticket *ticket, int64 source = -1, bool permanently = false);
GmTicketList m_GMTicketList;
uint64 GenerateGMTicketId();
// for wintergrasp only
GraveYardMap mGraveYardMap;
@@ -1013,7 +971,6 @@ class ObjectMgr
uint32 m_ItemTextId;
uint32 m_mailid;
uint32 m_hiPetNumber;
uint64 m_GMticketid;
// first free low guid for seelcted guid type
uint32 m_hiCharGuid;