diff options
Diffstat (limited to 'src/server/game')
| -rwxr-xr-x | src/server/game/Chat/Chat.cpp | 11 | ||||
| -rwxr-xr-x | src/server/game/Chat/Chat.h | 4 | ||||
| -rwxr-xr-x | src/server/game/Chat/Commands/TicketCommands.cpp | 478 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 4 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Handlers/TicketHandler.cpp | 236 | ||||
| -rwxr-xr-x | src/server/game/Server/WorldSession.h | 3 | ||||
| -rwxr-xr-x | src/server/game/Tickets/TicketMgr.cpp | 402 | ||||
| -rwxr-xr-x | src/server/game/Tickets/TicketMgr.h | 182 | ||||
| -rwxr-xr-x | src/server/game/World/World.cpp | 4 |
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(); |
