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
+1 -371
View File
@@ -24,6 +24,7 @@
#include "WorldSession.h"
#include "World.h"
#include "ObjectMgr.h"
#include "TicketMgr.h"
#include "Player.h"
#include "AccountMgr.h"
#include "Opcodes.h"
@@ -288,377 +289,6 @@ bool ChatHandler::HandleGMChatCommand(const char* args)
return false;
}
std::string ChatHandler::PGetParseString(int32 entry, ...)
{
const char *format = GetTrinityString(entry);
va_list ap;
char str [1024];
va_start(ap, entry);
vsnprintf(str,1024,format, ap);
va_end(ap);
return (std::string)str;
}
bool ChatHandler::HandleGMTicketListCommand(const char* /*args*/)
{
SendSysMessage(LANG_COMMAND_TICKETSHOWLIST);
for (GmTicketList::iterator itr = sObjectMgr.m_GMTicketList.begin(); itr != sObjectMgr.m_GMTicketList.end(); ++itr)
{
if ((*itr)->closed != 0)
continue;
std::string gmname;
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
if (sObjectMgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
}
SendSysMessage(ss.str().c_str());
}
return true;
}
bool ChatHandler::HandleGMTicketListOnlineCommand(const char* /*args*/)
{
SendSysMessage(LANG_COMMAND_TICKETSHOWONLINELIST);
for (GmTicketList::iterator itr = sObjectMgr.m_GMTicketList.begin(); itr != sObjectMgr.m_GMTicketList.end(); ++itr)
{
if ((*itr)->closed != 0 || !sObjectMgr.GetPlayer((*itr)->playerGuid))
continue;
std::string gmname;
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
if (sObjectMgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
}
SendSysMessage(ss.str().c_str());
}
return true;
}
bool ChatHandler::HandleGMTicketListClosedCommand(const char* /*args*/)
{
SendSysMessage(LANG_COMMAND_TICKETSHOWCLOSEDLIST);
for (GmTicketList::iterator itr = sObjectMgr.m_GMTicketList.begin(); itr != sObjectMgr.m_GMTicketList.end(); ++itr)
{
if ((*itr)->closed == 0)
continue;
std::string gmname;
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
if (sObjectMgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
}
SendSysMessage(ss.str().c_str());
}
return true;
}
bool ChatHandler::HandleGMTicketGetByIdCommand(const char* args)
{
if (!*args)
return false;
uint64 tguid = atoi(args);
GM_Ticket *ticket = sObjectMgr.GetGMTicket(tguid);
if (!ticket || ticket->closed != 0)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
std::string gmname;
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - ticket->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - ticket->timestamp, true, false)).c_str());
if (sObjectMgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
}
ss << PGetParseString(LANG_COMMAND_TICKETLISTMESSAGE, ticket->message.c_str());
if (ticket->comment != "")
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, ticket->comment.c_str());
}
SendSysMessage(ss.str().c_str());
return true;
}
bool ChatHandler::HandleGMTicketGetByNameCommand(const char* args)
{
if (!*args)
return false;
std::string name = (char*)args;
normalizePlayerName(name);
Player *plr = sObjectMgr.GetPlayer(name.c_str());
if (!plr)
{
SendSysMessage(LANG_NO_PLAYERS_FOUND);
return true;
}
GM_Ticket *ticket = sObjectMgr.GetGMTicketByPlayer(plr->GetGUID());
if (!ticket)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
std::string gmname;
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - ticket->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - ticket->timestamp, true, false)).c_str());
if (sObjectMgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
}
ss << PGetParseString(LANG_COMMAND_TICKETLISTMESSAGE, ticket->message.c_str());
if (ticket->comment != "")
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, ticket->comment.c_str());
}
SendSysMessage(ss.str().c_str());
return true;
}
bool ChatHandler::HandleGMTicketCloseByIdCommand(const char* args)
{
if (!*args)
return false;
uint64 tguid = atoi(args);
GM_Ticket *ticket = sObjectMgr.GetGMTicket(tguid);
if (!ticket || ticket->closed != 0)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
if (ticket && ticket->assignedToGM != 0 && ticket->assignedToGM != m_session->GetPlayer()->GetGUID())
{
PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->guid);
return true;
}
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETCLOSED, m_session->GetPlayer()->GetName());
SendGlobalGMSysMessage(ss.str().c_str());
Player *plr = sObjectMgr.GetPlayer(ticket->playerGuid);
sObjectMgr.RemoveGMTicket(ticket, m_session->GetPlayer()->GetGUID());
if (!plr || !plr->IsInWorld())
return true;
// send abandon ticket
WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
data << uint32(9);
plr->GetSession()->SendPacket(&data);
return true;
}
bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
{
if (!*args)
return false;
char* tguid = strtok((char*)args, " ");
uint64 ticketGuid = atoi(tguid);
char* targetgm = strtok(NULL, " ");
if (!targetgm)
return false;
std::string targm = targetgm;
if (!normalizePlayerName(targm))
return false;
Player *cplr = m_session->GetPlayer();
GM_Ticket *ticket = sObjectMgr.GetGMTicket(ticketGuid);
if (!ticket || ticket->closed != 0)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
uint64 tarGUID = sObjectMgr.GetPlayerGUIDByName(targm.c_str());
uint64 accid = sObjectMgr.GetPlayerAccountIdByGUID(tarGUID);
uint32 gmlevel = sAccountMgr.GetSecurity(accid, realmID);
if (!tarGUID || gmlevel == SEC_PLAYER)
{
SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
}
if (ticket->assignedToGM == tarGUID)
{
PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->guid);
return true;
}
std::string gmname;
sObjectMgr.GetPlayerNameByGUID(tarGUID, gmname);
if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
{
PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid, gmname.c_str());
return true;
}
ticket->assignedToGM = tarGUID;
sObjectMgr.AddOrUpdateGMTicket(*ticket);
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
SendGlobalGMSysMessage(ss.str().c_str());
return true;
}
bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
{
if (!*args)
return false;
uint64 ticketGuid = atoi(args);
Player *cplr = m_session->GetPlayer();
GM_Ticket *ticket = sObjectMgr.GetGMTicket(ticketGuid);
if (!ticket|| ticket->closed != 0)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
if (ticket->assignedToGM == 0)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED, ticket->guid);
return true;
}
std::string gmname;
sObjectMgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname);
Player *plr = sObjectMgr.GetPlayer(ticket->assignedToGM);
if (plr && plr->IsInWorld() && plr->GetSession()->GetSecurity() > cplr->GetSession()->GetSecurity())
{
SendSysMessage(LANG_COMMAND_TICKETUNASSIGNSECURITY);
return true;
}
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTUNASSIGNED, cplr->GetName());
SendGlobalGMSysMessage(ss.str().c_str());
ticket->assignedToGM = 0;
sObjectMgr.AddOrUpdateGMTicket(*ticket);
return true;
}
bool ChatHandler::HandleGMTicketCommentCommand(const char* args)
{
if (!*args)
return false;
char* tguid = strtok((char*)args, " ");
uint64 ticketGuid = atoi(tguid);
char* comment = strtok(NULL, "\n");
if (!comment)
return false;
Player *cplr = m_session->GetPlayer();
GM_Ticket *ticket = sObjectMgr.GetGMTicket(ticketGuid);
if (!ticket || ticket->closed != 0)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
{
PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid);
return true;
}
std::string gmname;
sObjectMgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname);
ticket->comment = comment;
sObjectMgr.AddOrUpdateGMTicket(*ticket);
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
if (sObjectMgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
{
ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
}
ss << PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, cplr->GetName(), ticket->comment.c_str());
SendGlobalGMSysMessage(ss.str().c_str());
return true;
}
bool ChatHandler::HandleGMTicketDeleteByIdCommand(const char* args)
{
if (!*args)
return false;
uint64 ticketGuid = atoi(args);
GM_Ticket *ticket = sObjectMgr.GetGMTicket(ticketGuid);
if (!ticket)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
if (ticket->closed == 0)
{
SendSysMessage(LANG_COMMAND_TICKETCLOSEFIRST);
return true;
}
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
ss << PGetParseString(LANG_COMMAND_TICKETDELETED, m_session->GetPlayer()->GetName());
SendGlobalGMSysMessage(ss.str().c_str());
Player *plr = sObjectMgr.GetPlayer(ticket->playerGuid);
sObjectMgr.RemoveGMTicket(ticket, -1, true);
if (plr && plr->IsInWorld())
{
// Force abandon ticket
WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
data << uint32(9);
plr->GetSession()->SendPacket(&data);
}
ticket = NULL;
return true;
}
bool ChatHandler::HandleGMTicketReloadCommand(const char*)
{
sObjectMgr.LoadGMTickets();
return true;
}
//Enable\Dissable Invisible mode
bool ChatHandler::HandleGMVisibleCommand(const char* args)
{