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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
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());
|
||||
SQLTransaction trans = SQLTransaction(NULL);
|
||||
ticket->SetComment(comment);
|
||||
ticket->SaveToDB(trans);
|
||||
sTicketMgr->UpdateLastChange();
|
||||
|
||||
std::string msg = ticket->FormatMessageString(*this, NULL, ticket->GetAssignedToName(), NULL, NULL);
|
||||
msg += PGetParseString(LANG_COMMAND_TICKETLISTADDCOMMENT, player->GetName(), comment);
|
||||
SendGlobalGMSysMessage(msg.c_str());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
inline bool ChatHandler::_HandleGMTicketResponseAppendCommand(const char* args, bool newLine)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
char* sTicketId = strtok((char*)args, " ");
|
||||
uint32 ticketId = atoi(sTicketId);
|
||||
|
||||
char* response = strtok(NULL, "\n");
|
||||
if (!response)
|
||||
return false;
|
||||
|
||||
GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
|
||||
if (!ticket || !ticket->IsClosed())
|
||||
{
|
||||
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
|
||||
return true;
|
||||
}
|
||||
// Cannot add response to ticket, assigned to someone else
|
||||
Player* player = m_session->GetPlayer();
|
||||
if (ticket->IsAssignedNotTo(player->GetGUID()))
|
||||
{
|
||||
PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
|
||||
return true;
|
||||
}
|
||||
|
||||
SQLTransaction trans = SQLTransaction(NULL);
|
||||
ticket->AppendResponse(response);
|
||||
if (newLine)
|
||||
ticket->AppendResponse("\n");
|
||||
ticket->SaveToDB(trans);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << ticket->response;
|
||||
ss << response;
|
||||
ticket->response = ss.str();
|
||||
sTicketMgr->AddOrUpdateGMTicket(*ticket);
|
||||
return true;
|
||||
return _HandleGMTicketResponseAppendCommand(args, false);
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleGMTicketResponseAppendLnCommand(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;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << ticket->response;
|
||||
ss << response;
|
||||
ss << "\n";
|
||||
ticket->response = ss.str();
|
||||
sTicketMgr->AddOrUpdateGMTicket(*ticket);
|
||||
return true;
|
||||
return _HandleGMTicketResponseAppendCommand(args, true);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName(), ticket->GetId());
|
||||
|
||||
response = GMTICKET_RESPONSE_SUCCESS;
|
||||
}
|
||||
|
||||
uint32 map, unk1;
|
||||
uint8 needResponse; // ignored
|
||||
float x, y, z;
|
||||
std::string ticketText, ticketText2;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName(), ticket->GetId());
|
||||
|
||||
response = GMTICKET_RESPONSE_SUCCESS;
|
||||
}
|
||||
|
||||
ticket->message = message;
|
||||
ticket->timestamp = time(NULL);
|
||||
|
||||
sTicketMgr->AddOrUpdateGMTicket(*ticket);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void GmTicket::TeleportTo(Player* player) const
|
||||
{
|
||||
player->TeleportTo(_mapId, _posX, _posY, _posZ, 1, 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Ticket manager
|
||||
TicketMgr::TicketMgr() : _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)), _status(true) { }
|
||||
|
||||
void TicketMgr::LoadTickets()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
if (!m_GMTicketList.empty())
|
||||
for (GmTicketList::const_iterator itr = m_GMTicketList.begin(); itr != m_GMTicketList.end(); ++itr)
|
||||
delete *itr;
|
||||
if (!_ticketList.empty())
|
||||
for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
|
||||
if (itr->second)
|
||||
delete itr->second;
|
||||
_ticketList.clear();
|
||||
|
||||
m_GMTicketList.clear();
|
||||
m_GMticketid = 0;
|
||||
m_openTickets = 0;
|
||||
|
||||
QueryResult result = CharacterDatabase.Query("SELECT guid, playerGuid, name, message, createtime, map, posX, posY, posZ, timestamp, closed,"
|
||||
"assignedto, comment, completed, escalated, viewed FROM gm_tickets");
|
||||
_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++;
|
||||
Field* fields = result->Fetch();
|
||||
GmTicket* ticket = new GmTicket();
|
||||
if (!ticket->LoadFromDB(fields))
|
||||
{
|
||||
delete ticket;
|
||||
continue;
|
||||
}
|
||||
if (!ticket->IsClosed())
|
||||
++_openTicketCount;
|
||||
|
||||
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();
|
||||
// Update max ticket id if necessary
|
||||
uint32 id = ticket->GetId();
|
||||
if (_lastTicketId < id)
|
||||
_lastTicketId = id;
|
||||
|
||||
_ticketList[id] = ticket;
|
||||
++count;
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
||||
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::ShowClosedList(ChatHandler& handler) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
_AddOrUpdateGMTicket(ticket);
|
||||
}
|
||||
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
|
||||
|
||||
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) << ");";
|
||||
if (ticket)
|
||||
{
|
||||
data << message.c_str(); // ticket text
|
||||
data << uint8(0x7); // ticket category; why is this hardcoded? does it make a diff re: client?
|
||||
|
||||
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)
|
||||
// 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
|
||||
{
|
||||
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));
|
||||
// we can't actually get any numbers here...
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(1);
|
||||
data << uint8(0);
|
||||
data << uint8(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TicketMgr::RemoveGMTicket(uint64 ticketGuid, int64 source, bool permanently)
|
||||
{
|
||||
GM_Ticket *ticket = GetGMTicket(ticketGuid);
|
||||
ASSERT(ticket); // hmm
|
||||
RemoveGMTicket(ticket, source, permanently);
|
||||
}
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
GmTicketList m_GMTicketList;
|
||||
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; }
|
||||
|
||||
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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user