mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-04 11:33:48 +00:00
First Commit
For Azeroth!
This commit is contained in:
401
src/server/game/Tickets/TicketMgr.cpp
Normal file
401
src/server/game/Tickets/TicketMgr.cpp
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "TicketMgr.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Chat.h"
|
||||
#include "World.h"
|
||||
#include "Player.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GM ticket
|
||||
GmTicket::GmTicket() : _id(0), _playerGuid(0), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(0), _lastModifiedTime(0),
|
||||
_closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false),
|
||||
_needResponse(false), _needMoreHelp(false) { }
|
||||
|
||||
GmTicket::GmTicket(Player* player) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needMoreHelp(false)
|
||||
{
|
||||
_id = sTicketMgr->GenerateTicketId();
|
||||
_playerName = player->GetName();
|
||||
_playerGuid = player->GetGUID();
|
||||
}
|
||||
|
||||
GmTicket::~GmTicket() { }
|
||||
|
||||
bool GmTicket::LoadFromDB(Field* fields)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
||||
// ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket
|
||||
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();
|
||||
_response = fields[++index].GetString();
|
||||
_completed = fields[++index].GetBool();
|
||||
_escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8());
|
||||
_viewed = fields[++index].GetBool();
|
||||
_needMoreHelp = fields[++index].GetBool();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GmTicket::SaveToDB(SQLTransaction& trans) const
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
// ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed
|
||||
uint8 index = 0;
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_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->setString(++index, _response);
|
||||
stmt->setBool (++index, _completed);
|
||||
stmt->setUInt8 (++index, uint8(_escalatedStatus));
|
||||
stmt->setBool (++index, _viewed);
|
||||
stmt->setBool (++index, _needMoreHelp);
|
||||
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
|
||||
void GmTicket::DeleteFromDB()
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GM_TICKET);
|
||||
stmt->setUInt32(0, _id);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void GmTicket::WritePacket(WorldPacket& data) const
|
||||
{
|
||||
data << uint32(GMTICKET_STATUS_HASTEXT);
|
||||
data << uint32(_id);
|
||||
data << _message;
|
||||
data << uint8(_needMoreHelp);
|
||||
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); // responseID
|
||||
data << uint32(_id); // ticketID
|
||||
data << _message.c_str();
|
||||
|
||||
size_t len = _response.size();
|
||||
char const* s = _response.c_str();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (len)
|
||||
{
|
||||
size_t writeLen = std::min<size_t>(len, 3999);
|
||||
data.append(s, writeLen);
|
||||
|
||||
len -= writeLen;
|
||||
s += writeLen;
|
||||
}
|
||||
|
||||
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)).c_str());
|
||||
ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(curTime - _lastModifiedTime, true)).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());
|
||||
if (!_response.empty())
|
||||
ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTRESPONSE, _response.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::SetPosition(uint32 mapId, float x, float y, float z)
|
||||
{
|
||||
_mapId = mapId;
|
||||
_posX = x;
|
||||
_posY = y;
|
||||
_posZ = z;
|
||||
}
|
||||
|
||||
void GmTicket::SetGmAction(uint32 needResponse, bool needMoreHelp)
|
||||
{
|
||||
_needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default)
|
||||
_needMoreHelp = needMoreHelp; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket"
|
||||
}
|
||||
|
||||
void GmTicket::TeleportTo(Player* player) const
|
||||
{
|
||||
player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f, 0);
|
||||
}
|
||||
|
||||
void GmTicket::SetChatLog(std::list<uint32> time, std::string const& log)
|
||||
{
|
||||
std::stringstream ss(log);
|
||||
std::stringstream newss;
|
||||
std::string line;
|
||||
while (std::getline(ss, line) && !time.empty())
|
||||
{
|
||||
newss << secsToTimeString(time.front()) << ": " << line << "\n";
|
||||
time.pop_front();
|
||||
}
|
||||
|
||||
_chatLog = newss.str();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Ticket manager
|
||||
TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)) { }
|
||||
|
||||
TicketMgr::~TicketMgr()
|
||||
{
|
||||
for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
void TicketMgr::Initialize() { SetStatus(sWorld->getBoolConfig(CONFIG_ALLOW_TICKETS)); }
|
||||
|
||||
void TicketMgr::ResetTickets()
|
||||
{
|
||||
for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end();)
|
||||
{
|
||||
if (itr->second->IsClosed())
|
||||
{
|
||||
uint32 ticketId = itr->second->GetId();
|
||||
++itr;
|
||||
sTicketMgr->RemoveTicket(ticketId);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
||||
_lastTicketId = 0;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GM_TICKETS);
|
||||
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void TicketMgr::LoadTickets()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
for (GmTicketList::const_iterator itr = _ticketList.begin(); itr != _ticketList.end(); ++itr)
|
||||
delete itr->second;
|
||||
_ticketList.clear();
|
||||
|
||||
_lastTicketId = 0;
|
||||
_openTicketCount = 0;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GM_TICKETS);
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
if (!result)
|
||||
{
|
||||
sLog->outString(">> Loaded 0 GM tickets. DB table `gm_tickets` is empty!");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
GmTicket* ticket = new GmTicket();
|
||||
if (!ticket->LoadFromDB(fields))
|
||||
{
|
||||
delete ticket;
|
||||
continue;
|
||||
}
|
||||
if (!ticket->IsClosed())
|
||||
++_openTicketCount;
|
||||
|
||||
// Update max ticket id if necessary
|
||||
uint32 id = ticket->GetId();
|
||||
if (_lastTicketId < id)
|
||||
_lastTicketId = id;
|
||||
|
||||
_ticketList[id] = ticket;
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog->outString(">> Loaded %u GM tickets in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
|
||||
}
|
||||
|
||||
void TicketMgr::LoadSurveys()
|
||||
{
|
||||
// we don't actually load anything into memory here as there's no reason to
|
||||
_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));
|
||||
|
||||
}
|
||||
|
||||
void TicketMgr::AddTicket(GmTicket* ticket)
|
||||
{
|
||||
_ticketList[ticket->GetId()] = ticket;
|
||||
if (!ticket->IsClosed())
|
||||
++_openTicketCount;
|
||||
SQLTransaction trans = SQLTransaction(NULL);
|
||||
ticket->SaveToDB(trans);
|
||||
}
|
||||
|
||||
void TicketMgr::CloseTicket(uint32 ticketId, int64 source)
|
||||
{
|
||||
if (GmTicket* ticket = GetTicket(ticketId))
|
||||
{
|
||||
SQLTransaction trans = SQLTransaction(NULL);
|
||||
ticket->SetClosedBy(source);
|
||||
if (source)
|
||||
--_openTicketCount;
|
||||
ticket->SaveToDB(trans);
|
||||
}
|
||||
}
|
||||
|
||||
void TicketMgr::RemoveTicket(uint32 ticketId)
|
||||
{
|
||||
if (GmTicket* ticket = GetTicket(ticketId))
|
||||
{
|
||||
ticket->DeleteFromDB();
|
||||
_ticketList.erase(ticketId);
|
||||
delete ticket;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
WorldPacket data(SMSG_GMTICKET_GETTICKET, (ticket ? (4 + 4 + 1 + 4 + 4 + 4 + 1 + 1) : 4));
|
||||
|
||||
if (ticket)
|
||||
ticket->WritePacket(data);
|
||||
else
|
||||
data << uint32(GMTICKET_STATUS_DEFAULT);
|
||||
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
251
src/server/game/Tickets/TicketMgr.h
Normal file
251
src/server/game/Tickets/TicketMgr.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TICKETMGR_H
|
||||
#define _TICKETMGR_H
|
||||
|
||||
#include <string>
|
||||
#include <ace/Singleton.h>
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
|
||||
class ChatHandler;
|
||||
|
||||
// from blizzard lua
|
||||
enum GMTicketSystemStatus
|
||||
{
|
||||
GMTICKET_QUEUE_STATUS_DISABLED = 0,
|
||||
GMTICKET_QUEUE_STATUS_ENABLED = 1
|
||||
};
|
||||
|
||||
enum GMTicketStatus
|
||||
{
|
||||
GMTICKET_STATUS_HASTEXT = 0x06,
|
||||
GMTICKET_STATUS_DEFAULT = 0x0A
|
||||
};
|
||||
|
||||
enum GMTicketResponse
|
||||
{
|
||||
GMTICKET_RESPONSE_ALREADY_EXIST = 1,
|
||||
GMTICKET_RESPONSE_CREATE_SUCCESS = 2,
|
||||
GMTICKET_RESPONSE_CREATE_ERROR = 3,
|
||||
GMTICKET_RESPONSE_UPDATE_SUCCESS = 4,
|
||||
GMTICKET_RESPONSE_UPDATE_ERROR = 5,
|
||||
GMTICKET_RESPONSE_TICKET_DELETED = 9
|
||||
};
|
||||
|
||||
// from Blizzard LUA:
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_NOT_ASSIGNED = 0; -- ticket is not currently assigned to a gm
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_ASSIGNED = 1; -- ticket is assigned to a normal gm
|
||||
// GMTICKET_ASSIGNEDTOGM_STATUS_ESCALATED = 2; -- ticket is in the escalation queue
|
||||
// 3 is a custom value and should never actually be sent
|
||||
enum GMTicketEscalationStatus
|
||||
{
|
||||
TICKET_UNASSIGNED = 0,
|
||||
TICKET_ASSIGNED = 1,
|
||||
TICKET_IN_ESCALATION_QUEUE = 2,
|
||||
TICKET_ESCALATED_ASSIGNED = 3
|
||||
};
|
||||
|
||||
// from blizzard lua
|
||||
enum GMTicketOpenedByGMStatus
|
||||
{
|
||||
GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED = 0, // ticket has never been opened by a gm
|
||||
GMTICKET_OPENEDBYGM_STATUS_OPENED = 1 // ticket has been opened by a gm
|
||||
};
|
||||
|
||||
enum LagReportType
|
||||
{
|
||||
LAG_REPORT_TYPE_LOOT = 1,
|
||||
LAG_REPORT_TYPE_AUCTION_HOUSE = 2,
|
||||
LAG_REPORT_TYPE_MAIL = 3,
|
||||
LAG_REPORT_TYPE_CHAT = 4,
|
||||
LAG_REPORT_TYPE_MOVEMENT = 5,
|
||||
LAG_REPORT_TYPE_SPELL = 6
|
||||
};
|
||||
|
||||
class GmTicket
|
||||
{
|
||||
public:
|
||||
GmTicket();
|
||||
GmTicket(Player* player);
|
||||
~GmTicket();
|
||||
|
||||
bool IsClosed() const { return _closedBy; }
|
||||
bool IsCompleted() const { return _completed; }
|
||||
bool IsFromPlayer(uint64 guid) const { return guid == _playerGuid; }
|
||||
bool IsAssigned() const { return _assignedTo != 0; }
|
||||
bool IsAssignedTo(uint64 guid) const { return guid == _assignedTo; }
|
||||
bool IsAssignedNotTo(uint64 guid) const { return IsAssigned() && !IsAssignedTo(guid); }
|
||||
|
||||
uint32 GetId() const { return _id; }
|
||||
Player* GetPlayer() const { return ObjectAccessor::FindPlayerInOrOutOfWorld(_playerGuid); }
|
||||
std::string const& GetPlayerName() const { return _playerName; }
|
||||
std::string const& GetMessage() const { return _message; }
|
||||
Player* GetAssignedPlayer() const { return ObjectAccessor::FindPlayerInOrOutOfWorld(_assignedTo); }
|
||||
uint64 GetAssignedToGUID() const { return _assignedTo; }
|
||||
std::string GetAssignedToName() const
|
||||
{
|
||||
std::string name;
|
||||
// save queries if ticket is not assigned
|
||||
if (_assignedTo)
|
||||
sObjectMgr->GetPlayerNameByGUID(_assignedTo, name);
|
||||
|
||||
return name;
|
||||
}
|
||||
uint64 GetLastModifiedTime() const { return _lastModifiedTime; }
|
||||
GMTicketEscalationStatus GetEscalatedStatus() const { return _escalatedStatus; }
|
||||
|
||||
void SetEscalatedStatus(GMTicketEscalationStatus escalatedStatus) { _escalatedStatus = escalatedStatus; }
|
||||
void SetAssignedTo(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(int64 value) { _closedBy = value; }
|
||||
void SetCompleted() { _completed = true; }
|
||||
void SetMessage(std::string const& message)
|
||||
{
|
||||
_message = message;
|
||||
_lastModifiedTime = uint64(time(NULL));
|
||||
}
|
||||
void SetComment(std::string const& comment) { _comment = comment; }
|
||||
void SetViewed() { _viewed = true; }
|
||||
void SetUnassigned();
|
||||
void SetPosition(uint32 mapId, float x, float y, float z);
|
||||
void SetGmAction(uint32 needResponse, bool needMoreHelp);
|
||||
|
||||
void AppendResponse(std::string const& response) { _response += response; }
|
||||
|
||||
bool LoadFromDB(Field* fields);
|
||||
void SaveToDB(SQLTransaction& trans) const;
|
||||
void DeleteFromDB();
|
||||
|
||||
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;
|
||||
|
||||
void SetChatLog(std::list<uint32> time, std::string const& log);
|
||||
std::string const& GetChatLog() const { return _chatLog; }
|
||||
|
||||
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;
|
||||
bool _needResponse; // TODO: find out the use of this, and then store it in DB
|
||||
bool _needMoreHelp;
|
||||
std::string _response;
|
||||
std::string _chatLog; // No need to store in db, will be refreshed every session client side
|
||||
};
|
||||
typedef std::map<uint32, GmTicket*> GmTicketList;
|
||||
|
||||
class TicketMgr
|
||||
{
|
||||
friend class ACE_Singleton<TicketMgr, ACE_Null_Mutex>;
|
||||
|
||||
private:
|
||||
TicketMgr();
|
||||
~TicketMgr();
|
||||
|
||||
public:
|
||||
void LoadTickets();
|
||||
void LoadSurveys();
|
||||
|
||||
GmTicket* GetTicket(uint32 ticketId)
|
||||
{
|
||||
GmTicketList::iterator itr = _ticketList.find(ticketId);
|
||||
if (itr != _ticketList.end())
|
||||
return itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GmTicket* GetTicketByPlayer(uint64 playerGuid)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
GmTicket* GetOldestOpenTicket()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
void Initialize();
|
||||
void ResetTickets();
|
||||
|
||||
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:
|
||||
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()
|
||||
|
||||
#endif // _TICKETMGR_H
|
||||
Reference in New Issue
Block a user