aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorAzazel <azazel.kon@gmail.com>2011-04-19 14:04:18 +0600
committerAzazel <azazel.kon@gmail.com>2011-04-19 14:04:18 +0600
commitc36846d78a861f49194d1a008a49adc27e17bf4c (patch)
tree59199d55a67042917fd3a480136ef5a6b89dbd12 /src/server/game
parent890b1f6cc731719e633655c7347e25ce812f3710 (diff)
Core/GM System: rename columns of gm_surveys, gm_subsurveys, gm_tickets and lag_reports tables to lowerCamel, move queries to prepared statements and refactor the code of TicketMgr.
Diffstat (limited to 'src/server/game')
-rwxr-xr-xsrc/server/game/Chat/Chat.cpp11
-rwxr-xr-xsrc/server/game/Chat/Chat.h4
-rwxr-xr-xsrc/server/game/Chat/Commands/TicketCommands.cpp478
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp4
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/TicketHandler.cpp236
-rwxr-xr-xsrc/server/game/Server/WorldSession.h3
-rwxr-xr-xsrc/server/game/Tickets/TicketMgr.cpp402
-rwxr-xr-xsrc/server/game/Tickets/TicketMgr.h182
-rwxr-xr-xsrc/server/game/World/World.cpp4
9 files changed, 656 insertions, 668 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index b22e27a7693..21b32c0a24c 100755
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -490,6 +490,17 @@ ChatCommand * ChatHandler::getCommandTable()
return commandTableCache;
}
+std::string ChatHandler::PGetParseString(int32 entry, ...) const
+{
+ const char *format = GetTrinityString(entry);
+ char str[1024];
+ va_list ap;
+ va_start(ap, entry);
+ vsnprintf(str, 1024, format, ap);
+ va_end(ap);
+ return std::string(str);
+}
+
const char *ChatHandler::GetTrinityString(int32 entry) const
{
return m_session->GetTrinityString(entry);
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index a75d1af9cc1..18b3fa2efbc 100755
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -72,7 +72,7 @@ class ChatHandler
void SendSysMessage(int32 entry);
void PSendSysMessage(const char *format, ...) ATTR_PRINTF(2,3);
void PSendSysMessage(int32 entry, ...);
- std::string PGetParseString(int32 entry, ...);
+ std::string PGetParseString(int32 entry, ...) const;
int ParseCommands(const char* text);
@@ -376,6 +376,8 @@ class ChatHandler
uint32 _ReadUInt32(std::istringstream& reader) const;
private:
+ bool _HandleGMTicketResponseAppendCommand(const char* args, bool newLine);
+
WorldSession * m_session; // != NULL for chat command call and NULL for CLI command
// common global flag
diff --git a/src/server/game/Chat/Commands/TicketCommands.cpp b/src/server/game/Chat/Commands/TicketCommands.cpp
index d85a3f2763e..88396349a20 100755
--- a/src/server/game/Chat/Commands/TicketCommands.cpp
+++ b/src/server/game/Chat/Commands/TicketCommands.cpp
@@ -25,98 +25,27 @@
#include "Chat.h"
#include "Player.h"
-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 = sTicketMgr->m_GMTicketList.begin(); itr != sTicketMgr->m_GMTicketList.end(); ++itr)
- {
- if ((*itr)->closed != 0 || (*itr)->completed)
- 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());
- }
+ sTicketMgr->ShowList(*this, false);
return true;
}
bool ChatHandler::HandleGMTicketListOnlineCommand(const char* /*args*/)
{
- SendSysMessage(LANG_COMMAND_TICKETSHOWONLINELIST);
- for (GmTicketList::iterator itr = sTicketMgr->m_GMTicketList.begin(); itr != sTicketMgr->m_GMTicketList.end(); ++itr)
- {
- if ((*itr)->closed != 0 || (*itr)->completed || !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());
- }
+ sTicketMgr->ShowList(*this, true);
return true;
}
bool ChatHandler::HandleGMTicketListClosedCommand(const char* /*args*/)
{
- SendSysMessage(LANG_COMMAND_TICKETSHOWCLOSEDLIST);
- for (GmTicketList::iterator itr = sTicketMgr->m_GMTicketList.begin(); itr != sTicketMgr->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());
- }
+ sTicketMgr->ShowClosedList(*this);
return true;
}
bool ChatHandler::HandleGMTicketListEscalatedCommand(const char* /*args*/)
{
- SendSysMessage(LANG_COMMAND_TICKETSHOWESCALATEDLIST);
- for (GmTicketList::iterator itr = sTicketMgr->m_GMTicketList.begin(); itr != sTicketMgr->m_GMTicketList.end(); ++itr)
- {
- if (!((*itr)->escalated == TICKET_IN_ESCALATION_QUEUE) || (*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());
- SendSysMessage(ss.str().c_str());
- }
+ sTicketMgr->ShowEscalatedList(*this);
return true;
}
@@ -125,31 +54,19 @@ bool ChatHandler::HandleGMTicketGetByIdCommand(const char* args)
if (!*args)
return false;
- uint64 tguid = atoi(args);
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(tguid);
- if (!ticket || ticket->closed != 0 || ticket->completed)
+ uint32 ticketId = atoi(args);
+ GmTicket *ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || ticket->IsClosed() || ticket->IsCompleted())
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- ticket->viewed = 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());
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetViewed();
+ ticket->SaveToDB(trans);
- if (sObjectMgr->GetPlayerNameByGUID(ticket->assignedToGM, gmname))
- ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
-
- ss << PGetParseString(LANG_COMMAND_TICKETLISTMESSAGE, ticket->message.c_str());
-
- if (strlen(ticket->comment.c_str()) != 0)
- ss << PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, ticket->comment.c_str());
-
- SendSysMessage(ss.str().c_str());
+ SendSysMessage(ticket->FormatMessageString(*this, true).c_str());
return true;
}
@@ -158,41 +75,35 @@ bool ChatHandler::HandleGMTicketGetByNameCommand(const char* args)
if (!*args)
return false;
- std::string name = (char*)args;
- normalizePlayerName(name);
+ std::string name(args);
+ if (!normalizePlayerName(name))
+ return false;
- Player *plr = sObjectMgr->GetPlayer(name.c_str());
- if (!plr)
+ // Detect target's GUID
+ uint64 guid = 0;
+ if (Player *player = sObjectMgr->GetPlayer(name.c_str()))
+ guid = player->GetGUID();
+ else
+ guid = sObjectMgr->GetPlayerGUIDByName(name);
+ // Target must exist
+ if (!guid)
{
SendSysMessage(LANG_NO_PLAYERS_FOUND);
return true;
}
-
- GM_Ticket *ticket = sTicketMgr->GetGMTicketByPlayer(plr->GetGUID());
+ // Ticket must exist
+ GmTicket *ticket = sTicketMgr->GetTicketByPlayer(guid);
if (!ticket)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- ticket->viewed = 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 (strlen(ticket->comment.c_str()) != 0)
- ss << PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, ticket->comment.c_str());
-
- SendSysMessage(ss.str().c_str());
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetViewed();
+ ticket->SaveToDB(trans);
+ SendSysMessage(ticket->FormatMessageString(*this, true).c_str());
return true;
}
@@ -201,37 +112,34 @@ bool ChatHandler::HandleGMTicketCloseByIdCommand(const char* args)
if (!*args)
return false;
- uint64 tguid = atoi(args);
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(tguid);
- if (!ticket || ticket->closed != 0 || ticket->completed)
+ uint32 ticketId = atoi(args);
+ GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || ticket->IsClosed() || ticket->IsCompleted())
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
-
- if (ticket && ticket->assignedToGM != 0 && ticket->assignedToGM != m_session->GetPlayer()->GetGUID())
+ // Ticket must be assigned to player, who tries to close it.
+ uint64 guid = m_session->GetPlayer()->GetGUID();
+ if (ticket->IsAssignedNotTo(guid))
{
- PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->guid);
+ PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->GetId());
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);
- sTicketMgr->RemoveGMTicket(ticket, m_session->GetPlayer()->GetGUID());
-
- if (!plr || !plr->IsInWorld())
- return true;
-
- // send abandon ticket
- WorldPacket deleteTicket(SMSG_GMTICKET_DELETETICKET, 4);
- deleteTicket << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- plr->GetSession()->SendPacket(&deleteTicket);
-
+ sTicketMgr->CloseTicket(ticket->GetId(), guid);
sTicketMgr->UpdateLastChange();
+
+ std::string msg = ticket->FormatMessageString(*this, m_session->GetPlayer()->GetName(), NULL, NULL, NULL);
+ SendGlobalGMSysMessage(msg.c_str());
+
+ // Inform player, who submitted this ticket, that it is closed
+ if (Player *player = ticket->GetPlayer())
+ if (player->IsInWorld())
+ {
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
+ player->GetSession()->SendPacket(&data);
+ }
return true;
}
@@ -240,66 +148,55 @@ bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
if (!*args)
return false;
- char* tguid = strtok((char*)args, " ");
- uint64 ticketGuid = atoi(tguid);
- char* targetgm = strtok(NULL, " ");
+ char* sTicketId = strtok((char*)args, " ");
+ uint32 ticketId = atoi(sTicketId);
- if (!targetgm)
+ char* sTarget = strtok(NULL, " ");
+ if (!sTarget)
return false;
- std::string targm = targetgm;
- if (!normalizePlayerName(targm))
+ std::string target(sTarget);
+ if (!normalizePlayerName(target))
return false;
- Player *cplr = m_session->GetPlayer();
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(ticketGuid);
-
- if (!ticket || ticket->closed != 0)
+ GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || ticket->IsClosed())
{
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)
+ // Get target information
+ uint64 targetGuid = sObjectMgr->GetPlayerGUIDByName(target.c_str());
+ uint64 targetAccId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid);
+ uint32 targetGmLevel = sAccountMgr->GetSecurity(targetAccId, realmID);
+ // Target must exist and have administrative rights
+ if (!targetGuid || targetGmLevel == SEC_PLAYER)
{
SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
return true;
}
-
- if (ticket->assignedToGM == tarGUID)
+ // If already assigned, leave
+ if (ticket->IsAssignedTo(targetGuid))
{
- PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->guid);
+ PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->GetId());
return true;
}
-
- std::string gmname;
- sObjectMgr->GetPlayerNameByGUID(tarGUID, gmname);
- if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
+ // If assigned to different player other than current, leave
+ Player *player = m_session->GetPlayer();
+ if (ticket->IsAssignedNotTo(player->GetGUID()))
{
- PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid, gmname.c_str());
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId(), target.c_str());
return true;
}
-
- ticket->assignedToGM = tarGUID;
-
- if (gmlevel == SEC_ADMINISTRATOR && ticket->escalated == TICKET_IN_ESCALATION_QUEUE)
- ticket->escalated = TICKET_ESCALATED_ASSIGNED;
- else if (ticket->escalated == TICKET_UNASSIGNED)
- ticket->escalated = TICKET_ASSIGNED;
-
- sTicketMgr->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());
-
+ // Assign ticket
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetAssignedTo(targetGuid, targetGmLevel == SEC_ADMINISTRATOR);
+ ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
+
+ std::string msg = ticket->FormatMessageString(*this, NULL, target.c_str(), NULL, NULL);
+ SendGlobalGMSysMessage(msg.c_str());
return true;
}
@@ -308,41 +205,45 @@ bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
if (!*args)
return false;
- uint64 ticketGuid = atoi(args);
- Player *cplr = m_session->GetPlayer();
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(ticketGuid);
-
- if (!ticket|| ticket->closed != 0)
+ uint32 ticketId = atoi(args);
+ GmTicket *ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || ticket->IsClosed())
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- if (ticket->assignedToGM == 0)
+ // Ticket must be assigned
+ if (!ticket->IsAssigned())
{
- PSendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED, ticket->guid);
+ PSendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED, ticket->GetId());
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())
+ // Get security level of player, whom this ticket is assigned to
+ uint32 security = SEC_PLAYER;
+ Player* assignedPlayer = ticket->GetAssignedPlayer();
+ if (assignedPlayer && assignedPlayer->IsInWorld())
+ security = assignedPlayer->GetSession()->GetSecurity();
+ else
+ {
+ uint64 guid = ticket->GetAssignedToGUID();
+ uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid);
+ security = sAccountMgr->GetSecurity(accountId, realmID);
+ }
+ // Check security
+ Player *player = m_session->GetPlayer();
+ if (security > uint32(player->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;
- if (ticket->escalated != TICKET_UNASSIGNED && ticket->escalated != TICKET_IN_ESCALATION_QUEUE)
- ticket->escalated--;
- sTicketMgr->AddOrUpdateGMTicket(*ticket);
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetUnassigned();
+ ticket->SaveToDB(trans);
sTicketMgr->UpdateLastChange();
+
+ std::string msg = ticket->FormatMessageString(*this, NULL, ticket->GetAssignedToName(), player->GetName(), NULL);
+ SendGlobalGMSysMessage(msg.c_str());
return true;
}
@@ -352,40 +253,35 @@ bool ChatHandler::HandleGMTicketCommentCommand(const char* args)
return false;
char* tguid = strtok((char*)args, " ");
- uint64 ticketGuid = atoi(tguid);
- char* comment = strtok(NULL, "\n");
+ uint32 ticketId = atoi(tguid);
+ char* comment = strtok(NULL, "\n");
if (!comment)
return false;
- Player *cplr = m_session->GetPlayer();
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(ticketGuid);
-
- if (!ticket || ticket->closed != 0)
+ GmTicket *ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || ticket->IsClosed())
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
+ // Cannot comment ticket assigned to someone else
+ Player* player = m_session->GetPlayer();
+ if (ticket->IsAssignedNotTo(player->GetGUID()))
{
- PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid);
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
return true;
}
- std::string gmname;
- sObjectMgr->GetPlayerNameByGUID(ticket->assignedToGM, gmname);
- ticket->comment = comment;
- sTicketMgr->AddOrUpdateGMTicket(*ticket);
- std::stringstream ss;
- ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
- ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetComment(comment);
+ ticket->SaveToDB(trans);
+ sTicketMgr->UpdateLastChange();
- if (sObjectMgr->GetPlayerNameByGUID(ticket->assignedToGM, gmname))
- ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, gmname.c_str());
+ std::string msg = ticket->FormatMessageString(*this, NULL, ticket->GetAssignedToName(), NULL, NULL);
+ msg += PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, player->GetName(), comment);
+ SendGlobalGMSysMessage(msg.c_str());
- ss << PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, cplr->GetName(), ticket->comment.c_str());
- SendGlobalGMSysMessage(ss.str().c_str());
- sTicketMgr->UpdateLastChange();
return true;
}
@@ -393,48 +289,42 @@ bool ChatHandler::HandleGMTicketDeleteByIdCommand(const char* args)
{
if (!*args)
return false;
- uint64 ticketGuid = atoi(args);
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(ticketGuid);
+ uint32 ticketId = atoi(args);
+ GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
if (!ticket)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- if (ticket->closed == 0)
+ if (!ticket->IsClosed())
{
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);
- sTicketMgr->RemoveGMTicket(ticket, -1, true); // we don't need to care about who deleted it...
- if (plr && plr->IsInWorld())
- {
- // Force abandon ticket
- WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
- data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
- plr->GetSession()->SendPacket(&data);
- }
+ std::string msg = ticket->FormatMessageString(*this, NULL, NULL, NULL, m_session->GetPlayer()->GetName());
+ SendGlobalGMSysMessage(msg.c_str());
- ticket = NULL;
+ sTicketMgr->RemoveTicket(ticket->GetId());
sTicketMgr->UpdateLastChange();
+
+ if (Player* player = ticket->GetPlayer())
+ if (player->IsInWorld())
+ {
+ // Force abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
+ player->GetSession()->SendPacket(&data);
+ }
return true;
}
bool ChatHandler::HandleToggleGMTicketSystem(const char* /* args */)
{
- sTicketMgr->SetStatus(!sTicketMgr->GetStatus());
- if (sTicketMgr->GetStatus())
- PSendSysMessage(LANG_ALLOW_TICKETS);
- else
- PSendSysMessage(LANG_DISALLOW_TICKETS);
-
+ bool status = !sTicketMgr->GetStatus();
+ sTicketMgr->SetStatus(status);
+ PSendSysMessage(status ? LANG_ALLOW_TICKETS : LANG_DISALLOW_TICKETS);
return true;
}
@@ -443,19 +333,20 @@ bool ChatHandler::HandleGMTicketEscalateCommand(const char *args)
if (!*args)
return false;
- uint64 tguid = atoi(args);
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(tguid);
- if (!ticket || ticket->closed != 0 || ticket->completed || ticket->escalated != TICKET_UNASSIGNED)
+ uint32 ticketId = atoi(args);
+ GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || !ticket->IsClosed() || ticket->IsCompleted() || ticket->GetEscalatedStatus() != TICKET_UNASSIGNED)
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- ticket->escalated = TICKET_IN_ESCALATION_QUEUE;
+ ticket->SetEscalatedStatus(TICKET_IN_ESCALATION_QUEUE);
+
+ if (Player* player = ticket->GetPlayer())
+ if (player->IsInWorld())
+ sTicketMgr->SendTicket(player->GetSession(), ticket);
- Player *plr = sObjectMgr->GetPlayer(ticket->playerGuid);
- if (plr && plr->IsInWorld())
- plr->GetSession()->SendGMTicketGetTicket(GMTICKET_STATUS_HASTEXT, ticket->message.c_str(), ticket);
sTicketMgr->UpdateLastChange();
return true;
}
@@ -465,88 +356,63 @@ bool ChatHandler::HandleGMTicketCompleteCommand(const char* args)
if (!*args)
return false;
- uint64 tguid = atoi(args);
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(tguid);
- if (!ticket || ticket->closed != 0 || ticket->completed)
+ uint32 ticketId = atoi(args);
+ GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || !ticket->IsClosed() || ticket->IsCompleted())
{
SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
- Player *plr = sObjectMgr->GetPlayer(ticket->playerGuid);
- if (plr && plr->IsInWorld())
- plr->GetSession()->SendGMTicketResponse(ticket);
+ if (Player *player = ticket->GetPlayer())
+ if (player->IsInWorld())
+ ticket->SendResponse(player->GetSession());
+
sTicketMgr->UpdateLastChange();
return true;
}
-bool ChatHandler::HandleGMTicketResponseAppendCommand(const char* args)
+inline bool ChatHandler::_HandleGMTicketResponseAppendCommand(const char* args, bool newLine)
{
if (!*args)
return false;
- char* tguid = strtok((char*)args, " ");
- uint64 ticketGuid = atoi(tguid);
- char* response = strtok(NULL, "\n");
+ char* sTicketId = strtok((char*)args, " ");
+ uint32 ticketId = atoi(sTicketId);
+ char* response = strtok(NULL, "\n");
if (!response)
return false;
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(ticketGuid);
- Player *cplr = m_session->GetPlayer();
-
- if (!ticket || ticket->closed != 0)
+ GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
+ if (!ticket || !ticket->IsClosed())
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
return true;
}
-
- if (ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
+ // Cannot add response to ticket, assigned to someone else
+ Player* player = m_session->GetPlayer();
+ if (ticket->IsAssignedNotTo(player->GetGUID()))
{
- PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid);
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
return true;
}
- std::stringstream ss;
- ss << ticket->response;
- ss << response;
- ticket->response = ss.str();
- sTicketMgr->AddOrUpdateGMTicket(*ticket);
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->AppendResponse(response);
+ if (newLine)
+ ticket->AppendResponse("\n");
+ ticket->SaveToDB(trans);
+
return true;
}
-bool ChatHandler::HandleGMTicketResponseAppendLnCommand(const char* args)
+bool ChatHandler::HandleGMTicketResponseAppendCommand(const char* args)
{
- if (!*args)
- return false;
-
- char* tguid = strtok((char*)args, " ");
- uint64 ticketGuid = atoi(tguid);
- char* response = strtok(NULL, "\n");
-
- if (!response)
- return false;
-
- GM_Ticket *ticket = sTicketMgr->GetGMTicket(ticketGuid);
- Player *cplr = m_session->GetPlayer();
-
- 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;
- }
+ return _HandleGMTicketResponseAppendCommand(args, false);
+}
- std::stringstream ss;
- ss << ticket->response;
- ss << response;
- ss << "\n";
- ticket->response = ss.str();
- sTicketMgr->AddOrUpdateGMTicket(*ticket);
- return true;
+bool ChatHandler::HandleGMTicketResponseAppendLnCommand(const char* args)
+{
+ return _HandleGMTicketResponseAppendCommand(args, true);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 37b3fffe916..e130a570359 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4870,7 +4870,9 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_spell WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid);
- trans->PAppend("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_GM_TICKETS);
+ stmt->setUInt32(0, guid);
+ trans->Append(stmt);
trans->PAppend("DELETE FROM item_instance WHERE owner_guid = '%u'",guid);
trans->PAppend("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid);
trans->PAppend("DELETE FROM mail WHERE receiver = '%u'",guid);
diff --git a/src/server/game/Server/Protocol/Handlers/TicketHandler.cpp b/src/server/game/Server/Protocol/Handlers/TicketHandler.cpp
index e96cfa2dbbd..ad883394270 100755
--- a/src/server/game/Server/Protocol/Handlers/TicketHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/TicketHandler.cpp
@@ -38,54 +38,22 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recv_data)
return;
}
- if (sTicketMgr->GetGMTicketByPlayer(GetPlayer()->GetGUID()))
+ GMTicketResponse response = GMTICKET_RESPONSE_FAILURE;
+ // Player must not have ticket
+ if (!sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
- WorldPacket data(SMSG_GMTICKET_CREATE, 4);
- data << uint32(GMTICKET_RESPONSE_FAILURE); // You already have GM ticket
- SendPacket(&data);
- return;
- }
+ GmTicket* ticket = new GmTicket(GetPlayer(), recv_data);
+ sTicketMgr->AddTicket(ticket);
+ sTicketMgr->UpdateLastChange();
- uint32 map, unk1;
- uint8 needResponse; // ignored
- float x, y, z;
- std::string ticketText, ticketText2;
+ sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName(), ticket->GetId());
- SendQueryTimeResponse();
-
- recv_data >> map;
- recv_data >> x;
- recv_data >> y;
- recv_data >> z;
- recv_data >> ticketText;
- recv_data >> unk1; // not sure what this is... replyTo?
- recv_data >> needResponse; // always 1/0 -- not sure what retail does with this
-
- GM_Ticket *ticket = new GM_Ticket;
- ticket->name = GetPlayer()->GetName();
- ticket->guid = sTicketMgr->GenerateGMTicketId();
- ticket->playerGuid = GetPlayer()->GetGUID();
- ticket->message = ticketText;
- ticket->createtime = time(NULL);
- ticket->map = map;
- ticket->pos_x = x;
- ticket->pos_y = y;
- ticket->pos_z = z;
- ticket->timestamp = time(NULL);
- ticket->closed = 0;
- ticket->assignedToGM = 0;
- ticket->comment = "";
- ticket->completed = false;
- ticket->escalated = TICKET_UNASSIGNED;
- ticket->response = "";
-
- sTicketMgr->AddOrUpdateGMTicket(*ticket, true);
+ response = GMTICKET_RESPONSE_SUCCESS;
+ }
WorldPacket data(SMSG_GMTICKET_CREATE, 4);
- data << uint32(GMTICKET_RESPONSE_SUCCESS);
+ data << uint32(response);
SendPacket(&data);
-
- sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName(), ticket->guid);
}
void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket & recv_data)
@@ -93,40 +61,35 @@ void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket & recv_data)
std::string message;
recv_data >> message;
- GM_Ticket *ticket = sTicketMgr->GetGMTicketByPlayer(GetPlayer()->GetGUID());
- if (!ticket)
+ GMTicketResponse response = GMTICKET_RESPONSE_FAILURE;
+ if (GmTicket *ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
- WorldPacket data(SMSG_GMTICKET_UPDATETEXT, 4);
- data << uint32(GMTICKET_RESPONSE_FAILURE);
- SendPacket(&data);
- return;
- }
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetMessage(message);
+ ticket->SaveToDB(trans);
- ticket->message = message;
- ticket->timestamp = time(NULL);
+ sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName(), ticket->GetId());
- sTicketMgr->AddOrUpdateGMTicket(*ticket);
+ response = GMTICKET_RESPONSE_SUCCESS;
+ }
WorldPacket data(SMSG_GMTICKET_UPDATETEXT, 4);
- data << uint32(GMTICKET_RESPONSE_SUCCESS);
+ data << uint32(response);
SendPacket(&data);
-
- sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName(), ticket->guid);
}
void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket & /*recv_data*/)
{
- GM_Ticket* ticket = sTicketMgr->GetGMTicketByPlayer(GetPlayer()->GetGUID());
-
- if (ticket)
+ if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
SendPacket(&data);
- sWorld->SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName(), ticket->guid);
- sTicketMgr->RemoveGMTicket(ticket, GetPlayer()->GetGUID(), false);
- SendGMTicketGetTicket(GMTICKET_STATUS_DEFAULT, NULL);
+ sWorld->SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName(), ticket->GetId());
+
+ sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
+ sTicketMgr->SendTicket(this, NULL);
}
}
@@ -134,139 +97,64 @@ void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket & /*recv_data*/)
{
SendQueryTimeResponse();
- if (GM_Ticket *ticket = sTicketMgr->GetGMTicketByPlayer(GetPlayer()->GetGUID()))
+ if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
- if (ticket->completed)
- SendGMTicketResponse(ticket);
+ if (ticket->IsCompleted())
+ ticket->SendResponse(this);
else
- SendGMTicketGetTicket(GMTICKET_STATUS_HASTEXT, ticket->message.c_str(), ticket);
+ sTicketMgr->SendTicket(this, ticket);
}
else
- SendGMTicketGetTicket(GMTICKET_STATUS_DEFAULT, NULL);
+ sTicketMgr->SendTicket(this, NULL);
}
void WorldSession::HandleGMTicketSystemStatusOpcode(WorldPacket & /*recv_data*/)
{
- WorldPacket data(SMSG_GMTICKET_SYSTEMSTATUS, 4);
// Note: This only disables the ticket UI at client side and is not fully reliable
// are we sure this is a uint32? Should ask Zor
+ WorldPacket data(SMSG_GMTICKET_SYSTEMSTATUS, 4);
data << uint32(sTicketMgr->GetStatus() ? GMTICKET_QUEUE_STATUS_ENABLED : GMTICKET_QUEUE_STATUS_DISABLED);
SendPacket(&data);
}
-void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text, GM_Ticket *ticket /* = NULL */)
-{
- int len = text ? strlen(text) : 0;
- WorldPacket data(SMSG_GMTICKET_GETTICKET, (4+4+((status == GMTICKET_STATUS_HASTEXT) ? (len+1+4+4+4+1+1) : 0)));
- data << uint32(status); // standard 0x0A, 0x06 if text present
- data << uint32(1); // g_HasActiveGMTicket -- not a flag
-
- if (status == GMTICKET_STATUS_HASTEXT)
- {
- data << text; // ticket text
- data << uint8(0x7); // ticket category; why is this hardcoded? does it make a diff re: client?
-
- // we've got the easy stuff done by now.
- // Now we need to go through the client logic for displaying various levels of ticket load
- if (ticket)
- {
- // get ticketage, but it's stored in seconds so we have to do it in days
- float ticketAge = (float)time(NULL) - (float)ticket->timestamp;
- ticketAge /= DAY;
-
- data << float(ticketAge); // ticketAge (days)
- if (GM_Ticket *oldestTicket = sTicketMgr->GetOldestOpenGMTicket())
- {
- // get ticketage, but it's stored in seconds so we have to do it in days
- float oldestTicketAge = (float)time(NULL) - (float)oldestTicket->timestamp;
- oldestTicketAge /= DAY;
- data << float(oldestTicketAge);
- }
- else
- data << float(0);
-
- // I am not sure how blizzlike this is, and we don't really have a way to find out
- int64 lastChange = int64(sTicketMgr->GetLastChange());
- float timeDiff = float(int64(time(NULL)) - lastChange);
- timeDiff /= DAY;
- data << float(timeDiff);
-
- data << uint8(std::min(ticket->escalated, uint8(TICKET_IN_ESCALATION_QUEUE))); // escalated data
- data << uint8(ticket->viewed ? GMTICKET_OPENEDBYGM_STATUS_OPENED : GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED); // whether or not it has been viewed
- }
- else
- {
- // we can't actually get any numbers here...
- data << float(0);
- data << float(0);
- data << float(1);
- data << uint8(0);
- data << uint8(0);
- }
- }
-
- SendPacket(&data);
-}
-
-void WorldSession::SendGMTicketResponse(GM_Ticket *ticket)
-{
- if (!ticket)
- return;
-
- WorldPacket data(SMSG_GMRESPONSE_RECEIVED);
- data << uint32(1); // unk? Zor says "hasActiveTicket"
- data << uint32(0); // can-edit - always 1 or 0, not flags
- data << ticket->message.c_str();
- data << ticket->response.c_str();
- for (int8 j = 0; j < 3; j++)
- data << uint8(0); // 3 null strings
- SendPacket(&data);
-}
-
void WorldSession::HandleGMSurveySubmit(WorldPacket& recv_data)
{
- uint64 nextSurveyID = sTicketMgr->GetNextSurveyID();
+ uint32 nextSurveyID = sTicketMgr->GetNextSurveyID();
// just put the survey into the database
- std::ostringstream ss;
uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
recv_data >> mainSurvey;
- ss << "INSERT INTO gm_surveys (player, surveyid, mainSurvey, overall_comment, timestamp) VALUES (";
- ss << GetPlayer()->GetGUID() << ", ";
- ss << uint32(nextSurveyID) << ", ";
- ss << mainSurvey << ", ";
-
// sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
-
for (uint8 i = 0; i < 10; i++)
{
- std::ostringstream os;
- os << "INSERT INTO gm_subsurveys (surveyid, subsurveyid, rank, comment) VALUES (";
uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
recv_data >> subSurveyId;
- if(!subSurveyId)
+ if (!subSurveyId)
break;
uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc
- std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
recv_data >> rank;
+ std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
recv_data >> comment;
- os << uint32(nextSurveyID) << " ";
- os << subSurveyId << ", ";
- os << uint16(rank) << ", '";
- CharacterDatabase.escape_string(comment);
- os << comment << "');";
- CharacterDatabase.PExecute(os.str().c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GM_SUBSURVEY);
+ stmt->setUInt32(0, nextSurveyID);
+ stmt->setUInt32(1, subSurveyId);
+ stmt->setUInt32(2, rank);
+ stmt->setString(3, comment);
+ CharacterDatabase.Execute(stmt);
}
std::string comment; // just a guess
recv_data >> comment;
- CharacterDatabase.escape_string(comment);
- ss << "'" << comment << "', ";
- ss << int64(time_t(NULL)) << ");";
- CharacterDatabase.PExecute(ss.str().c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GM_SURVEY);
+ stmt->setUInt32(0, GUID_LOPART(GetPlayer()->GetGUID()));
+ stmt->setUInt32(1, nextSurveyID);
+ stmt->setUInt32(2, mainSurvey);
+ stmt->setString(3, comment);
+
+ CharacterDatabase.Execute(stmt);
}
void WorldSession::HandleReportLag(WorldPacket& recv_data)
@@ -274,35 +162,30 @@ void WorldSession::HandleReportLag(WorldPacket& recv_data)
// just put the lag report into the database...
// can't think of anything else to do with it
uint32 lagType, mapId;
- float x, y, z;
recv_data >> lagType;
recv_data >> mapId;
+ float x, y, z;
recv_data >> x;
recv_data >> y;
recv_data >> z;
- // build and execute query
- std::ostringstream os;
- os << "INSERT INTO lag_reports (player, lag_type, map, posX, posY, posZ) VALUES (";
- os << GetPlayer()->GetGUID() << ", ";
- os << lagType << ", ";
- os << mapId << ", ";
- os << x << ", ";
- os << y << ", ";
- os << z << ");";
-
- CharacterDatabase.Execute(os.str().c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_LAG_REPORT);
+ stmt->setUInt32(0, GUID_LOPART(GetPlayer()->GetGUID()));
+ stmt->setUInt8 (1, lagType);
+ stmt->setUInt16(2, mapId);
+ stmt->setFloat (3, x);
+ stmt->setFloat (4, y);
+ stmt->setFloat (5, z);
+ CharacterDatabase.Execute(stmt);
}
void WorldSession::HandleGMResponseResolve(WorldPacket& /*recvPacket*/)
{
// empty packet
- GM_Ticket* ticket = sTicketMgr->GetGMTicketByPlayer(GetPlayer()->GetGUID());
-
- if (ticket)
+ if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
{
uint8 getSurvey = 0;
- if ((float)rand_chance() < sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY))
+ if (float(rand_chance()) < sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY))
getSurvey = 1;
WorldPacket data(SMSG_GMRESPONSE_STATUS_UPDATE, 4);
@@ -312,7 +195,8 @@ void WorldSession::HandleGMResponseResolve(WorldPacket& /*recvPacket*/)
WorldPacket data2(SMSG_GMTICKET_DELETETICKET, 4);
data2 << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
SendPacket(&data2);
- sTicketMgr->RemoveGMTicket(ticket, GetPlayer()->GetGUID(), true);
- SendGMTicketGetTicket(GMTICKET_STATUS_DEFAULT, NULL);
+
+ sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
+ sTicketMgr->SendTicket(this, NULL);
}
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 82e8aa20919..9cf9f4f3d37 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -47,7 +47,6 @@ class LoginQueryHolder;
class CharacterHandler;
class SpellCastTargets;
struct AreaTableEntry;
-struct GM_Ticket;
struct LfgJoinResultData;
struct LfgLockStatus;
struct LfgPlayerBoot;
@@ -425,8 +424,6 @@ class WorldSession
void HandleGMTicketDeleteOpcode(WorldPacket& recvPacket);
void HandleGMTicketGetTicketOpcode(WorldPacket& recvPacket);
void HandleGMTicketSystemStatusOpcode(WorldPacket& recvPacket);
- void SendGMTicketGetTicket(uint32 status, char const* text, GM_Ticket *ticket = NULL);
- void SendGMTicketResponse(GM_Ticket *ticket);
void HandleGMSurveySubmit(WorldPacket& recvPacket);
void HandleReportLag(WorldPacket& recvPacket);
void HandleGMResponseResolve(WorldPacket& recvPacket);
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 9452c920c3e..ecd9f7c6caf 100755
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -24,35 +24,194 @@
#include "WorldPacket.h"
#include "WorldSession.h"
-TicketMgr::TicketMgr()
+inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// GM ticket
+GmTicket::GmTicket() { }
+
+GmTicket::GmTicket(Player* player, WorldPacket& recv_data) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED)
{
- m_GMticketid = 0; // this is initialized in LoadGMTickets() but it's best to be safe
- m_GMSurveyID = 0;
- m_openTickets = 0;
- lastChange = time(NULL);
- status = true;
+ _id = sTicketMgr->GenerateTicketId();
+ _playerName = player->GetName();
+ _playerGuid = player->GetGUID();
+
+ uint32 mapId;
+ recv_data >> mapId;
+ _mapId = mapId;
+
+ recv_data >> _posX;
+ recv_data >> _posY;
+ recv_data >> _posZ;
+ recv_data >> _message;
+
+ uint32 unk1;
+ recv_data >> unk1; // not sure what this is... replyTo?
+ uint8 needResponse;
+ recv_data >> needResponse; // always 1/0 -- not sure what retail does with this
}
-uint64 TicketMgr::GenerateGMTicketId()
+GmTicket::~GmTicket() { }
+
+bool GmTicket::LoadFromDB(Field* fields)
{
- return ++m_GMticketid;
+ uint8 index = 0;
+ _id = fields[ index].GetUInt32();
+ _playerGuid = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
+ _playerName = fields[++index].GetString();
+ _message = fields[++index].GetString();
+ _createTime = fields[++index].GetUInt32();
+ _mapId = fields[++index].GetUInt16();
+ _posX = fields[++index].GetFloat();
+ _posY = fields[++index].GetFloat();
+ _posZ = fields[++index].GetFloat();
+ _lastModifiedTime = fields[++index].GetUInt32();
+ _closedBy = fields[++index].GetInt32();
+ _assignedTo = MAKE_NEW_GUID(fields[++index].GetUInt32(), 0, HIGHGUID_PLAYER);
+ _comment = fields[++index].GetString();
+ _completed = fields[++index].GetBool();
+ _escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8());
+ _viewed = fields[++index].GetBool();
+ return true;
}
-void TicketMgr::LoadGMTickets()
+void GmTicket::SaveToDB(SQLTransaction& trans) const
{
- uint32 oldMSTime = getMSTime();
+ uint8 index = 0;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GM_TICKET);
+ stmt->setUInt32( index, _id);
+ stmt->setUInt32(++index, GUID_LOPART(_playerGuid));
+ stmt->setString(++index, _playerName);
+ stmt->setString(++index, _message);
+ stmt->setUInt32(++index, uint32(_createTime));
+ stmt->setUInt16(++index, _mapId);
+ stmt->setFloat (++index, _posX);
+ stmt->setFloat (++index, _posY);
+ stmt->setFloat (++index, _posZ);
+ stmt->setUInt32(++index, uint32(_lastModifiedTime));
+ stmt->setInt32 (++index, GUID_LOPART(_closedBy));
+ stmt->setUInt32(++index, GUID_LOPART(_assignedTo));
+ stmt->setString(++index, _comment);
+ stmt->setBool (++index, _completed);
+ stmt->setUInt8 (++index, uint8(_escalatedStatus));
+ stmt->setBool (++index, _viewed);
+
+ CharacterDatabase.ExecuteOrAppend(trans, stmt);
+}
+
+void GmTicket::DeleteFromDB(SQLTransaction& trans)
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GM_TICKET);
+ stmt->setUInt32(0, _id);
+ CharacterDatabase.Execute(stmt);
+}
+
+void GmTicket::WritePacket(WorldPacket& data) const
+{
+ data << GetAge(_lastModifiedTime);
+ if (GmTicket* ticket = sTicketMgr->GetOldestOpenTicket())
+ data << GetAge(ticket->GetLastModifiedTime());
+ else
+ data << float(0);
+
+ // I am not sure how blizzlike this is, and we don't really have a way to find out
+ data << GetAge(sTicketMgr->GetLastChange());
+
+ data << uint8(std::min(_escalatedStatus, TICKET_IN_ESCALATION_QUEUE)); // escalated data
+ data << uint8(_viewed ? GMTICKET_OPENEDBYGM_STATUS_OPENED : GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED); // whether or not it has been viewed
+}
+
+void GmTicket::SendResponse(WorldSession* session) const
+{
+ WorldPacket data(SMSG_GMRESPONSE_RECEIVED);
+ data << uint32(1); // unk? Zor says "hasActiveTicket"
+ data << uint32(0); // can-edit - always 1 or 0, not flags
+ data << _message.c_str();
+ data << _response.c_str();
+ // 3 null strings
+ data << uint8(0);
+ data << uint8(0);
+ data << uint8(0);
+ session->SendPacket(&data);
+}
+
+std::string GmTicket::FormatMessageString(ChatHandler& handler, bool detailed) const
+{
+ time_t curTime = time(NULL);
+
+ std::stringstream ss;
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTGUID, _id);
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTNAME, _playerName.c_str());
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(curTime - _createTime, true, false)).c_str());
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(curTime - _lastModifiedTime, true, false)).c_str());
+
+ std::string name;
+ if (sObjectMgr->GetPlayerNameByGUID(_assignedTo, name))
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, name.c_str());
+
+ if (detailed)
+ {
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTMESSAGE, _message.c_str());
+ if (!_comment.empty())
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTCOMMENT, _comment.c_str());
+ }
+ return ss.str();
+}
+
+std::string GmTicket::FormatMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName) const
+{
+ std::stringstream ss;
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTGUID, _id);
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTNAME, _playerName.c_str());
+ if (szClosedName)
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETCLOSED, szClosedName);
+ if (szAssignedToName)
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, szAssignedToName);
+ if (szUnassignedName)
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTUNASSIGNED, szUnassignedName);
+ if (szDeletedName)
+ ss << handler.PGetParseString(LANG_COMMAND_TICKETDELETED, szDeletedName);
+ return ss.str();
+}
+
+void GmTicket::SetUnassigned()
+{
+ _assignedTo = 0;
+ switch (_escalatedStatus)
+ {
+ case TICKET_ASSIGNED: _escalatedStatus = TICKET_UNASSIGNED; break;
+ case TICKET_ESCALATED_ASSIGNED: _escalatedStatus = TICKET_IN_ESCALATION_QUEUE; break;
+ case TICKET_UNASSIGNED:
+ case TICKET_IN_ESCALATION_QUEUE:
+ default:
+ break;
+ }
+}
- if (!m_GMTicketList.empty())
- for (GmTicketList::const_iterator itr = m_GMTicketList.begin(); itr != m_GMTicketList.end(); ++itr)
- delete *itr;
+void GmTicket::TeleportTo(Player* player) const
+{
+ player->TeleportTo(_mapId, _posX, _posY, _posZ, 1, 0);
+}
- m_GMTicketList.clear();
- m_GMticketid = 0;
- m_openTickets = 0;
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Ticket manager
+TicketMgr::TicketMgr() : _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)), _status(true) { }
- QueryResult result = CharacterDatabase.Query("SELECT guid, playerGuid, name, message, createtime, map, posX, posY, posZ, timestamp, closed,"
- "assignedto, comment, completed, escalated, viewed FROM gm_tickets");
+void TicketMgr::LoadTickets()
+{
+ uint32 oldMSTime = getMSTime();
+
+ if (!_ticketList.empty())
+ for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
+ if (itr->second)
+ delete itr->second;
+ _ticketList.clear();
+ _lastTicketId = 0;
+ _openTicketCount = 0;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_GM_TICKETS);
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
{
sLog->outString(">> Loaded 0 GM tickets. DB table `gm_tickets` is empty!");
@@ -61,131 +220,130 @@ void TicketMgr::LoadGMTickets()
}
uint32 count = 0;
-
do
{
- Field *fields = result->Fetch();
- GM_Ticket *ticket = new GM_Ticket;
- ticket->guid = fields[0].GetUInt32();
- ticket->playerGuid = fields[1].GetUInt32();
- ticket->name = fields[2].GetString();
- ticket->message = fields[3].GetString();
- ticket->createtime = fields[4].GetUInt32();
- 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].GetUInt32();
- ticket->closed = fields[10].GetInt32();
- if (ticket->closed == 0)
- m_openTickets++;
-
- ticket->assignedToGM = fields[11].GetUInt64();
- ticket->comment = fields[12].GetString();
- ticket->completed = fields[13].GetBool();
- ticket->escalated = fields[14].GetUInt8();
- ticket->viewed = fields[15].GetBool();
- ++count;
-
- m_GMTicketList.push_back(ticket);
- } while (result->NextRow());
+ Field* fields = result->Fetch();
+ GmTicket* ticket = new GmTicket();
+ if (!ticket->LoadFromDB(fields))
+ {
+ delete ticket;
+ continue;
+ }
+ if (!ticket->IsClosed())
+ ++_openTicketCount;
- result = CharacterDatabase.Query("SELECT MAX(guid) from gm_tickets");
+ // Update max ticket id if necessary
+ uint32 id = ticket->GetId();
+ if (_lastTicketId < id)
+ _lastTicketId = id;
- if (result)
- {
- Field *fields = result->Fetch();
- m_GMticketid = fields[0].GetUInt64();
- }
+ _ticketList[id] = ticket;
+ ++count;
+ } while (result->NextRow());
sLog->outString(">> Loaded %u GM tickets in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
-void TicketMgr::LoadGMSurveys()
+void TicketMgr::LoadSurveys()
{
- uint32 oldMSTime = getMSTime();
-
// we don't actually load anything into memory here as there's no reason to
- QueryResult result = CharacterDatabase.Query("SELECT MAX(surveyid) FROM gm_surveys");
- if (result)
- {
- Field *fields = result->Fetch();
- m_GMSurveyID = fields[0].GetUInt32();
- }
- else
- m_GMSurveyID = 0;
+ _lastSurveyId = 0;
+
+ uint32 oldMSTime = getMSTime();
+ if (QueryResult result = CharacterDatabase.Query("SELECT MAX(surveyId) FROM gm_surveys"))
+ _lastSurveyId = (*result)[0].GetUInt32();
sLog->outString(">> Loaded GM Survey count from database in %u ms", GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
-void TicketMgr::AddOrUpdateGMTicket(GM_Ticket &ticket, bool create)
+void TicketMgr::AddTicket(GmTicket* ticket)
{
- if (create)
+ _ticketList[ticket->GetId()] = ticket;
+ if (!ticket->IsClosed())
+ ++_openTicketCount;
+}
+
+void TicketMgr::CloseTicket(uint32 ticketId, int64 source)
+{
+ if (GmTicket* ticket = GetTicket(ticketId))
{
- m_GMTicketList.push_back(&ticket);
- if (ticket.closed == 0)
- m_openTickets++;
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetClosedBy(source);
+ if (source)
+ --_openTicketCount;
+ ticket->SaveToDB(trans);
}
+}
- _AddOrUpdateGMTicket(ticket);
-}
-
-void TicketMgr::_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, completed, escalated, viewed) 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 << "', ";
- ss << (ticket.completed ? 1 : 0) << ", ";
- ss << uint32(ticket.escalated) << ", ";
- ss << (ticket.viewed ? 1 : 0) << ");";
-
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
- trans->Append(ss.str().c_str());
- CharacterDatabase.CommitTransaction(trans);
-}
-
-void TicketMgr::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;
-
- if (source != 0)
- m_openTickets--;
-
- _AddOrUpdateGMTicket(*(*i));
- }
+void TicketMgr::RemoveTicket(uint32 ticketId)
+{
+ if (GmTicket* ticket = GetTicket(ticketId))
+ {
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->DeleteFromDB(trans);
+ _ticketList.erase(ticketId);
+ }
+}
+
+void TicketMgr::ShowList(ChatHandler& handler, bool onlineOnly) const
+{
+ handler.SendSysMessage(onlineOnly ? LANG_COMMAND_TICKETSHOWONLINELIST : LANG_COMMAND_TICKETSHOWLIST);
+ for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
+ if (!itr->second->IsClosed() && !itr->second->IsCompleted())
+ if (!onlineOnly || itr->second->GetPlayer())
+ handler.SendSysMessage(itr->second->FormatMessageString(handler).c_str());
}
-void TicketMgr::RemoveGMTicket(uint64 ticketGuid, int64 source, bool permanently)
+void TicketMgr::ShowClosedList(ChatHandler& handler) const
{
- GM_Ticket *ticket = GetGMTicket(ticketGuid);
- ASSERT(ticket); // hmm
- RemoveGMTicket(ticket, source, permanently);
+ handler.SendSysMessage(LANG_COMMAND_TICKETSHOWCLOSEDLIST);
+ for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
+ if (itr->second->IsClosed())
+ handler.SendSysMessage(itr->second->FormatMessageString(handler).c_str());
+}
+
+void TicketMgr::ShowEscalatedList(ChatHandler& handler) const
+{
+ handler.SendSysMessage(LANG_COMMAND_TICKETSHOWESCALATEDLIST);
+ for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
+ if (!itr->second->IsClosed() && itr->second->GetEscalatedStatus() == TICKET_IN_ESCALATION_QUEUE)
+ handler.SendSysMessage(itr->second->FormatMessageString(handler).c_str());
+}
+
+void TicketMgr::SendTicket(WorldSession* session, GmTicket* ticket) const
+{
+ uint32 status = GMTICKET_STATUS_DEFAULT;
+ std::string message;
+ if (ticket)
+ {
+ message = ticket->GetMessage();
+ status = GMTICKET_STATUS_HASTEXT;
+ }
+
+ WorldPacket data(SMSG_GMTICKET_GETTICKET, (4 + 4 + (ticket ? message.length() + 1 + 4 + 4 + 4 + 1 + 1 : 0)));
+ data << uint32(status); // standard 0x0A, 0x06 if text present
+ data << uint32(1); // g_HasActiveGMTicket -- not a flag
+
+ if (ticket)
+ {
+ data << message.c_str(); // ticket text
+ data << uint8(0x7); // ticket category; why is this hardcoded? does it make a diff re: client?
+
+ // we've got the easy stuff done by now.
+ // Now we need to go through the client logic for displaying various levels of ticket load
+ if (ticket)
+ ticket->WritePacket(data);
+ else
+ {
+ // we can't actually get any numbers here...
+ data << float(0);
+ data << float(0);
+ data << float(1);
+ data << uint8(0);
+ data << uint8(0);
+ }
+ }
+ session->SendPacket(&data);
}
diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h
index 69bfcd86844..9f222727510 100755
--- a/src/server/game/Tickets/TicketMgr.h
+++ b/src/server/game/Tickets/TicketMgr.h
@@ -24,6 +24,7 @@
#include "DatabaseEnv.h"
#include "SQLStorage.h"
#include "SQLStorageImpl.h"
+#include "Chat.h"
#include "World.h"
// from blizzard lua
@@ -76,27 +77,89 @@ enum LagReportType
LAG_REPORT_TYPE_SPELL = 6
};
-struct GM_Ticket
+class GmTicket
{
- 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;
- bool completed;
- uint8 escalated;
- bool viewed;
- std::string response;
+public:
+ GmTicket();
+ explicit GmTicket(Player* player, WorldPacket& recv_data);
+ ~GmTicket();
+
+ bool IsClosed() const { return _closedBy; }
+ bool IsCompleted() const { return _completed; }
+ bool IsFromPlayer(const uint64& guid) { return guid == _playerGuid; }
+ bool IsAssigned() const { return _assignedTo != 0; }
+ bool IsAssignedTo(const uint64& guid) const { return guid == _assignedTo; }
+ bool IsAssignedNotTo(const uint64& guid) const { return IsAssigned() && !IsAssignedTo(guid); }
+
+ uint32 GetId() const { return _id; }
+ Player* GetPlayer() const { return sObjectMgr->GetPlayer(_playerGuid); }
+ std::string GetPlayerName() const { return _playerName; }
+ std::string GetMessage() const { return _message; }
+ Player* GetAssignedPlayer() const { return sObjectMgr->GetPlayer(_assignedTo); }
+ const uint64& GetAssignedToGUID() const { return _assignedTo; }
+ const char* GetAssignedToName() const
+ {
+ std::string name;
+ if (_assignedTo)
+ if (sObjectMgr->GetPlayerNameByGUID(_assignedTo, name))
+ return name.c_str();
+ return NULL;
+ }
+ const uint64& GetLastModifiedTime() const { return _lastModifiedTime; }
+ GMTicketEscalationStatus GetEscalatedStatus() const { return _escalatedStatus; }
+
+ void SetEscalatedStatus(GMTicketEscalationStatus escalatedStatus) { _escalatedStatus = escalatedStatus; }
+ void SetAssignedTo(const uint64& guid, bool isAdmin)
+ {
+ _assignedTo = guid;
+ if (isAdmin && _escalatedStatus == TICKET_IN_ESCALATION_QUEUE)
+ _escalatedStatus = TICKET_ESCALATED_ASSIGNED;
+ else if (_escalatedStatus == TICKET_UNASSIGNED)
+ _escalatedStatus = TICKET_ASSIGNED;
+ }
+ void SetClosedBy(const int64& value) { _closedBy = value; }
+ void SetMessage(const std::string& message)
+ {
+ _message = message;
+ _lastModifiedTime = uint64(time(NULL));
+ }
+ void SetComment(const std::string& comment) { _comment = comment; }
+ void SetViewed() { _viewed = true; }
+ void SetUnassigned();
+
+ void AppendResponse(const std::string& response) { _response += response; }
+
+ bool LoadFromDB(Field* fields);
+ void SaveToDB(SQLTransaction& trans) const;
+ void DeleteFromDB(SQLTransaction& trans);
+
+ void WritePacket(WorldPacket& data) const;
+ void SendResponse(WorldSession* session) const;
+
+ void TeleportTo(Player* player) const;
+ std::string FormatMessageString(ChatHandler& handler, bool detailed = false) const;
+ std::string FormatMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName) const;
+
+private:
+ uint32 _id;
+ uint64 _playerGuid;
+ std::string _playerName;
+ float _posX;
+ float _posY;
+ float _posZ;
+ uint16 _mapId;
+ std::string _message;
+ uint64 _createTime;
+ uint64 _lastModifiedTime;
+ int64 _closedBy; // 0 = Open, -1 = Console, playerGuid = player abandoned ticket, other = GM who closed it.
+ uint64 _assignedTo;
+ std::string _comment;
+ bool _completed;
+ GMTicketEscalationStatus _escalatedStatus;
+ bool _viewed;
+ std::string _response;
};
-typedef std::list<GM_Ticket*> GmTicketList;
+typedef std::map<uint32, GmTicket*> GmTicketList;
class TicketMgr
{
@@ -104,63 +167,68 @@ class TicketMgr
friend class ACE_Singleton<TicketMgr, ACE_Null_Mutex>;
public:
- void LoadGMTickets();
- void LoadGMSurveys();
+ void LoadTickets();
+ void LoadSurveys();
- GM_Ticket *GetGMTicket(uint64 ticketGuid)
+ GmTicket* GetTicket(uint32 ticketId)
{
- for (GmTicketList::const_iterator i = m_GMTicketList.begin(); i != m_GMTicketList.end(); ++i)
- if ((*i) && (*i)->guid == ticketGuid)
- return (*i);
+ GmTicketList::iterator itr = _ticketList.find(ticketId);
+ if (itr != _ticketList.end())
+ return itr->second;
return NULL;
}
- GM_Ticket *GetGMTicketByPlayer(uint64 playerGuid)
+ GmTicket* GetTicketByPlayer(const 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);
+ for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
+ if (itr->second && itr->second->IsFromPlayer(playerGuid) && !itr->second->IsClosed())
+ return itr->second;
return NULL;
}
- 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);
- uint64 GenerateGMTicketId();
- bool GetStatus() const { return status; }
- void SetStatus(bool newStatus) { status = newStatus; }
- uint64 GetOpenTicketCount() const { return m_openTickets; }
- uint64 GetNextSurveyID() { return ++m_GMSurveyID; }
-
- void Initialize()
+ GmTicket* GetOldestOpenTicket()
{
- SetStatus(sWorld->getBoolConfig(CONFIG_ALLOW_TICKETS));
- }
-
- GM_Ticket *GetOldestOpenGMTicket()
- {
- for (GmTicketList::const_iterator i = m_GMTicketList.begin(); i != m_GMTicketList.end(); ++i)
- if ((*i) && (*i)->closed == 0 && !(*i)->completed)
- return (*i);
+ for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
+ if (itr->second && !itr->second->IsClosed() && !itr->second->IsCompleted())
+ return itr->second;
return NULL;
}
- time_t GetLastChange() const { return lastChange; }
- void UpdateLastChange() { lastChange = time(NULL); }
+ void AddTicket(GmTicket* ticket);
+ void CloseTicket(uint32 ticketId, int64 source = -1);
+ void RemoveTicket(uint32 ticketId);
+
+ bool GetStatus() const { return _status; }
+ void SetStatus(bool status) { _status = status; }
+
+ uint64 GetLastChange() const { return _lastChange; }
+ void UpdateLastChange() { _lastChange = uint64(time(NULL)); }
+
+ uint32 GenerateTicketId() { return ++_lastTicketId; }
+ uint32 GetOpenTicketCount() const { return _openTicketCount; }
+ uint32 GetNextSurveyID() { return ++_lastSurveyId; }
- GmTicketList m_GMTicketList;
+ void Initialize() { SetStatus(sWorld->getBoolConfig(CONFIG_ALLOW_TICKETS)); }
+
+ void ShowList(ChatHandler& handler, bool onlineOnly) const;
+ void ShowClosedList(ChatHandler& handler) const;
+ void ShowEscalatedList(ChatHandler& handler) const;
+
+ void SendTicket(WorldSession* session, GmTicket* ticket) const;
protected:
- uint64 m_GMticketid;
- uint64 m_GMSurveyID;
- bool status;
- uint64 m_openTickets;
- uint32 m_gmCount;
- time_t lastChange;
+ void _RemoveTicket(uint32 ticketId, int64 source = -1, bool permanently = false);
+
+ GmTicketList _ticketList;
+
+ bool _status;
+ uint32 _lastTicketId;
+ uint32 _lastSurveyId;
+ uint32 _openTicketCount;
+ uint64 _lastChange;
};
#define sTicketMgr ACE_Singleton<TicketMgr, ACE_Null_Mutex>::instance()
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index f0e10b8bd74..c5a9b63b423 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1567,10 +1567,10 @@ void World::SetInitialWorldSettings()
sObjectMgr->LoadFactionChangeReputations();
sLog->outString("Loading GM tickets...");
- sTicketMgr->LoadGMTickets();
+ sTicketMgr->LoadTickets();
sLog->outString("Loading GM surveys...");
- sTicketMgr->LoadGMSurveys();
+ sTicketMgr->LoadSurveys();
sLog->outString("Loading client addons...");
sAddonMgr->LoadFromDB();