[GM] .ticket command rework

Including ticket numbering fix (now real ticket IDs throughout)
Closing tickets for offline players
This commit is contained in:
Olion17 2016-03-19 22:23:31 +00:00 committed by Antz
parent 6f853a1bbe
commit 2f17dbe017
11 changed files with 390 additions and 251 deletions

View File

@ -2410,7 +2410,7 @@ bool ChatHandler::HandlePInfoCommand(char* args)
return true;
}
// show tickets
// show ticket (helper)
void ChatHandler::ShowTicket(GMTicket const* ticket)
{
std::string lastupdated = TimeToTimestampStr(ticket->GetLastUpdate());
@ -2429,238 +2429,88 @@ void ChatHandler::ShowTicket(GMTicket const* ticket)
}
// ticket commands
bool ChatHandler::HandleTicketCommand(char* args)
bool ChatHandler::HandleTicketAcceptCommand(char* args)
{
char* px = ExtractLiteralArg(&args);
// ticket<end>
if (!px)
{
size_t count = sTicketMgr.GetTicketCount();
if (m_session)
{
bool accept = m_session->GetPlayer()->isAcceptTickets();
PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, GetOnOffStr(accept));
}
else
{ PSendSysMessage(LANG_COMMAND_TICKETCOUNT_CONSOLE, count); }
return true;
}
if (strncmp(px, "system_on", 10) == 0)
if (strncmp(px, "on", 3) == 0)
{
sTicketMgr.SetAcceptTickets(true);
SendSysMessage(LANG_COMMAND_TICKETS_SYSTEM_ON);
return true;
}
if (strncmp(px, "system_off", 11) == 0)
else if (strncmp(px, "off", 4) == 0)
{
sTicketMgr.SetAcceptTickets(false);
SendSysMessage(LANG_COMMAND_TICKETS_SYSTEM_OFF);
return true;
}
// ticket on
if (strncmp(px, "on", 3) == 0)
{
if (!m_session)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
else
return false;
m_session->GetPlayer()->SetAcceptTicket(true);
SendSysMessage(LANG_COMMAND_TICKETON);
return true;
}
return true;
}
// ticket off
if (strncmp(px, "off", 4) == 0)
{
if (!m_session)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
bool ChatHandler::HandleTicketCloseCommand(char* args)
{
GMTicket* ticket = NULL;
m_session->GetPlayer()->SetAcceptTicket(false);
SendSysMessage(LANG_COMMAND_TICKETOFF);
return true;
}
//TODO: Break both of these out into extract functions
// ticket close, can show them a gm-survey
if (strncmp(px, "close", 6) == 0 || strncmp(px, "close_survey", 13) == 0)
{
GMTicket* ticket = NULL;
uint32 num;
if (ExtractUInt32(&args, num))
{
if (num == 0)
return false;
ticket = sTicketMgr.GetGMTicketByOrderPos(num - 1);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, num);
SetSentErrorMessage(true);
return false;
}
}
else
{
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&args, NULL, &target_guid, &target_name))
return false;
// ticket respond $char_name
ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
if (strncmp(px, "close_survey", 13) == 0)
ticket->CloseWithSurvey();
else
ticket->Close();
//This needs to be before we delete the ticket
Player* pPlayer = sObjectMgr.GetPlayer(ticket->GetPlayerGuid());
//For now we can't close tickets for offline players, TODO
if (!pPlayer)
{
SendSysMessage(LANG_COMMAND_TICKET_CANT_CLOSE);
return false;
}
//This logic feels misplaced, but you can't have it in GMTicket?
sTicketMgr.Delete(ticket->GetPlayerGuid());
ticket = NULL;
PSendSysMessage(LANG_COMMAND_TICKETCLOSED_NAME, pPlayer->GetName());
return true;
}
// ticket respond
if (strncmp(px, "respond", 8) == 0 || strncmp(px, "response", 9) == 0
|| strncmp(px, "whisper", 8) == 0)
{
GMTicket* ticket = NULL;
// ticket respond #num
uint32 num;
if (ExtractUInt32(&args, num))
{
if (num == 0)
{ return false; }
// mgr numbering tickets start from 0
ticket = sTicketMgr.GetGMTicketByOrderPos(num - 1);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, num);
SetSentErrorMessage(true);
return false;
}
}
else
{
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&args, NULL, &target_guid, &target_name))
{ return false; }
// ticket respond $char_name
ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
// no response text?
if (!*args)
{ return false; }
ticket->SetResponseText(args);
if (Player* pl = sObjectMgr.GetPlayer(ticket->GetPlayerGuid()))
{
pl->GetSession()->SendGMTicketGetTicket(0x06, ticket);
//How should we error here?
if (m_session)
m_session->GetPlayer()->Whisper(args, LANG_UNIVERSAL, pl->GetObjectGuid());
}
return true;
}
// ticket #num
uint32 num;
if (ExtractUInt32(&px, num))
if (ExtractUInt32(&args, num))
{
if (num == 0)
{ return false; }
return false;
ticket = sTicketMgr.GetGMTicket(num);
// mgr numbering tickets start from 0
GMTicket* ticket = sTicketMgr.GetGMTicketByOrderPos(num - 1);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, num);
SetSentErrorMessage(true);
return false;
}
}
else
{
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&args, NULL, &target_guid, &target_name))
return false;
ShowTicket(ticket);
return true;
// ticket respond $char_name
ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&px, NULL, &target_guid, &target_name))
{ return false; }
Player* pPlayer = sObjectMgr.GetPlayer(ticket->GetPlayerGuid());
// ticket $char_name
GMTicket* ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
if (!pPlayer && !sWorld.getConfig(CONFIG_BOOL_GM_TICKET_OFFLINE_CLOSING))
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
SendSysMessage(LANG_COMMAND_TICKET_CANT_CLOSE);
return false;
}
ShowTicket(ticket);
ticket->Close();
//This logic feels misplaced, but you can't have it in GMTicket?
sTicketMgr.Delete(ticket->GetPlayerGuid()); // here, ticket become invalidated and should not be used below
PSendSysMessage(LANG_COMMAND_TICKETCLOSED_NAME, pPlayer ? pPlayer->GetName() : "an offline player");
return true;
}
// dell all tickets
bool ChatHandler::HandleDelTicketCommand(char* args)
bool ChatHandler::HandleTicketDeleteCommand(char* args)
{
char* px = ExtractLiteralArg(&args);
if (!px)
{ return false; }
return false;
// delticket all
// ticket delete all
if (strncmp(px, "all", 4) == 0)
{
sTicketMgr.DeleteAll();
@ -2670,14 +2520,14 @@ bool ChatHandler::HandleDelTicketCommand(char* args)
uint32 num;
// delticket #num
// ticket delete #id
if (ExtractUInt32(&px, num))
{
if (num == 0)
{ return false; }
return false;
// mgr numbering tickets start from 0
GMTicket* ticket = sTicketMgr.GetGMTicketByOrderPos(num - 1);
GMTicket* ticket = sTicketMgr.GetGMTicket(num);
if (!ticket)
{
@ -2697,23 +2547,23 @@ bool ChatHandler::HandleDelTicketCommand(char* args)
PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, GetNameLink(pl).c_str());
}
else
{ PSendSysMessage(LANG_COMMAND_TICKETDEL); }
PSendSysMessage(LANG_COMMAND_TICKETDEL);
return true;
}
// ticket delete $charName
Player* target;
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&px, &target, &target_guid, &target_name))
{ return false; }
return false;
// delticket $char_name
sTicketMgr.Delete(target_guid);
// notify players about ticket deleting
if (target)
{ target->GetSession()->SendGMTicketGetTicket(0x0A); }
target->GetSession()->SendGMTicketGetTicket(0x0A);
std::string nameLink = playerLink(target_name);
@ -2721,6 +2571,248 @@ bool ChatHandler::HandleDelTicketCommand(char* args)
return true;
}
bool ChatHandler::HandleTicketInfoCommand(char *args)
{
char* px = ExtractLiteralArg(&args);
size_t count = sTicketMgr.GetTicketCount();
if (m_session)
PSendSysMessage(LANG_COMMAND_TICKETCOUNT, count, GetOnOffStr(m_session->GetPlayer()->isAcceptTickets()));
else
PSendSysMessage(LANG_COMMAND_TICKETCOUNT_CONSOLE, count);
return true;
}
bool ChatHandler::HandleTicketListCommand(char* args)
{
uint16 numToShow = std::min(uint16(sTicketMgr.GetTicketCount()), uint16(sWorld.getConfig(CONFIG_UINT32_GM_TICKET_LIST_SIZE)));
for (uint16 i = 0; i < numToShow; ++i)
{
GMTicket* ticket = sTicketMgr.GetGMTicketByOrderPos(i);
time_t lastChanged = time_t(ticket->GetLastUpdate());
PSendSysMessage(LANG_COMMAND_TICKET_OFFLINE_INFO, ticket->GetId(), ticket->GetPlayerGuid().GetCounter(), ticket->HasResponse() ? "+" : "-", ctime(&lastChanged));
}
PSendSysMessage(LANG_COMMAND_TICKET_COUNT_ALL, numToShow, sTicketMgr.GetTicketCount());
return true;
}
bool ChatHandler::HandleTicketOnlineListCommand(char* args)
{
uint16 count = 0;
for (uint16 i = 0; i < sTicketMgr.GetTicketCount(); ++i)
{
GMTicket* ticket = sTicketMgr.GetGMTicketByOrderPos(i);
if (Player* player = sObjectMgr.GetPlayer(ticket->GetPlayerGuid(), true))
{
++count;
if (i < sWorld.getConfig(CONFIG_UINT32_GM_TICKET_LIST_SIZE))
{
time_t lastChanged = time_t(ticket->GetLastUpdate());
PSendSysMessage(LANG_COMMAND_TICKET_BRIEF_INFO, ticket->GetId(), player->GetName(), ticket->HasResponse() ? "+" : "-", ctime(&lastChanged));
}
}
}
PSendSysMessage(LANG_COMMAND_TICKET_COUNT_ONLINE, std::min(count, uint16(sWorld.getConfig(CONFIG_UINT32_GM_TICKET_LIST_SIZE))), count);
return true;
}
bool ChatHandler::HandleTicketMeAcceptCommand(char* args)
{
char* px = ExtractLiteralArg(&args);
if (!px)
{
PSendSysMessage(LANG_COMMAND_TICKET_ACCEPT_STATE, m_session->GetPlayer()->isAcceptTickets() ? "on" : "off");
return true;
}
if (!m_session)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
// ticket on
if (strncmp(px, "on", 3) == 0)
{
m_session->GetPlayer()->SetAcceptTicket(true);
SendSysMessage(LANG_COMMAND_TICKETON);
}
// ticket off
else if (strncmp(px, "off", 4) == 0)
{
m_session->GetPlayer()->SetAcceptTicket(false);
SendSysMessage(LANG_COMMAND_TICKETOFF);
}
else
return false;
return true;
}
bool ChatHandler::HandleTicketRespondCommand(char* args)
{
GMTicket* ticket = NULL;
// ticket respond #num
uint32 num;
if (ExtractUInt32(&args, num))
{
if (num == 0)
return false;
// mgr numbering tickets start from 0
ticket = sTicketMgr.GetGMTicket(num);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, num);
SetSentErrorMessage(true);
return false;
}
}
else
{
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&args, NULL, &target_guid, &target_name))
return false;
// ticket respond $char_name
ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
// no response text?
if (!*args)
return false;
ticket->SetResponseText(args);
if (Player* pl = sObjectMgr.GetPlayer(ticket->GetPlayerGuid()))
{
pl->GetSession()->SendGMTicketGetTicket(0x06, ticket);
//How should we error here?
if (m_session)
m_session->GetPlayer()->Whisper(args, LANG_UNIVERSAL, pl->GetObjectGuid());
}
return true;
}
bool ChatHandler::HandleTicketShowCommand(char *args)
{
// ticket #num
char* px = ExtractLiteralArg(&args);
if (!px)
return false;
uint32 num;
if (ExtractUInt32(&px, num))
{
if (num == 0)
return false;
// mgr numbering tickets start from 0
GMTicket* ticket = sTicketMgr.GetGMTicket(num);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, num);
SetSentErrorMessage(true);
return false;
}
ShowTicket(ticket);
return true;
}
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&px, NULL, &target_guid, &target_name))
return false;
// ticket $char_name
GMTicket* ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
return false;
}
ShowTicket(ticket);
return true;
}
bool ChatHandler::HandleTickerSurveyClose(char *args)
{
GMTicket* ticket = NULL;
uint32 num;
if (ExtractUInt32(&args, num))
{
if (num == 0)
return false;
ticket = sTicketMgr.GetGMTicket(num);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, num);
SetSentErrorMessage(true);
return false;
}
}
else
{
ObjectGuid target_guid;
std::string target_name;
if (!ExtractPlayerTarget(&args, NULL, &target_guid, &target_name))
return false;
// ticket respond $char_name
ticket = sTicketMgr.GetGMTicket(target_guid);
if (!ticket)
{
PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST_NAME, target_name.c_str());
SetSentErrorMessage(true);
return false;
}
}
ticket->CloseWithSurvey();
//This needs to be before we delete the ticket
Player* pPlayer = sObjectMgr.GetPlayer(ticket->GetPlayerGuid());
//For now we can't close tickets for offline players, TODO
if (!pPlayer)
{
SendSysMessage(LANG_COMMAND_TICKET_CANT_CLOSE);
return false;
}
//This logic feels misplaced, but you can't have it in GMTicket?
sTicketMgr.Delete(ticket->GetPlayerGuid());
ticket = NULL;
PSendSysMessage(LANG_COMMAND_TICKETCLOSED_NAME, pPlayer->GetName());
return true;
}
/// Helper function
inline Creature* Helper_CreateWaypointFor(Creature* wpOwner, WaypointPathOrigin wpOrigin, int32 pathId, uint32 wpId, WaypointNode const* wpNode, CreatureInfo const* waypointInfo)
{

View File

@ -116,15 +116,13 @@ void GMTicket::Close() const
void GMTicket::_Close(GMTicketStatus statusCode) const
{
Player* pPlayer = sObjectMgr.GetPlayer(m_guid);
if (!pPlayer)
return;
CharacterDatabase.PExecute("UPDATE character_ticket "
"SET resolved = 1 "
"WHERE guid = %u AND resolved = 0",
m_guid.GetCounter());
if (statusCode != GM_TICKET_STATUS_DO_NOTHING)
if (pPlayer && statusCode != GM_TICKET_STATUS_DO_NOTHING)
{ pPlayer->GetSession()->SendGMTicketStatusUpdate(statusCode); }
}
@ -164,7 +162,7 @@ void GMTicketMgr::LoadGMTickets()
GMTicket& ticket = m_GMTicketMap[guid];
ticket.Init(guid, fields[1].GetCppString(), fields[2].GetCppString(), time_t(fields[3].GetUInt64()), fields[4].GetUInt32());
m_GMTicketListByCreatingOrder.push_back(&ticket);
m_GMTicketIdMap[ticket.GetId()] = &ticket;
}
while (result->NextRow());
delete result;
@ -202,11 +200,11 @@ void GMTicketMgr::Create(ObjectGuid guid, const char* text)
//This implicitly creates a new instance since we're using operator[]
GMTicket& ticket = m_GMTicketMap[guid];
if (ticket.GetPlayerGuid())
m_GMTicketListByCreatingOrder.remove(&ticket);
m_GMTicketIdMap.erase(ticketId);
//Lets reinitialize with new data
ticket.Init(guid, text, "", time(NULL), ticketId);
m_GMTicketListByCreatingOrder.push_back(&ticket);
m_GMTicketIdMap[ticketId] = &ticket;
}
void GMTicketMgr::DeleteAll()
@ -217,6 +215,6 @@ void GMTicketMgr::DeleteAll()
{ owner->GetSession()->SendGMTicketGetTicket(0x0A); }
}
CharacterDatabase.Execute("DELETE FROM character_ticket");
m_GMTicketListByCreatingOrder.clear();
m_GMTicketIdMap.clear();
m_GMTicketMap.clear();
}

View File

@ -57,31 +57,30 @@
* care of what needs to be done by giving back a \ref GMTicket. The database table interesting
* in this case is character_ticket in the characaters database.
*
* Theres also some handling of tickets in \ref ChatHandler::HandleTicketCommand where
* Theres also some handling of tickets in \ref ChatHandler::HandleTicketAcceptCommand where
* you can turn on/off accepting tickets with your current GM char. You can also turn
* off tickets globally, this will show the client a message about tickets not being
* available at the moment. The commands that can be used are:
* <dl>
* <dt>.ticket on/off</dt>
* <dt>.ticket meaccept on/off</dt>
* <dd>Turns on/off showing new incoming tickets for you character</dd>
* <dt>.ticket system_on/off</dt>
* <dt>.ticket accept on/off</dt>
* <dd>Will turn the whole ticket reporting system on/off, ie: if it's off the clients
* will get a message that the system is unavailable when trying to submit a ticket</dd>
* <dt>.ticket close $character_name/.ticket close #num_of_ticket</dt>
* <dd>Will close a ticket for the given character name or the given number of the ticket,
* this will make the little icon in the top right go away for the player</dd>
* <dt>.ticket close_survey $character_name/.ticket close_survey #num_of_ticket</dt>
* <dt>.ticket surveyclose $character_name/.ticket surveyclose #num_of_ticket</dt>
* <dd>Does the same as .ticket close but instead of just closing it it also asks the \ref Player
* to answer a survey about how please they were with the experience</dd>
* <dt>.ticket respond $character_name/.ticket respond #num_of_ticket</dt>
* <dd>Will respond to a ticket, this will whisper the \ref Player who asked the question and from
* there on you will have to explain the solution etc. and then close the ticket again.</dd>
* <dt>.ticket</dt>
* <dt>.ticket info</dt>
* <dd>Shows the number of currently active tickets</dd>
* <dt>.ticket $character_name/.ticket #num_of_ticket</dt>
* <dt>.ticket show $character_name/.ticket show #num_of_ticket</dt>
* <dd>Will show the question and name of the character for the given ticket</dd>
*
* \todo Do not remove tickets from db when closing but mark them as solved instead.
* \todo Log conversations between GM and the player receiving help.
*/
class GMTicket
@ -144,7 +143,7 @@ class GMTicket
* \deprecated
* \todo Change to resolved/not resolved instead, via the check in db
*/
bool HasResponse() { return !m_responseText.empty(); };
bool HasResponse() { return !m_responseText.empty(); }
/**
* This will take care of a \ref OpcodesList::CMSG_GMSURVEY_SUBMIT packet
@ -179,7 +178,7 @@ class GMTicket
time_t m_lastUpdate;
};
typedef std::map<ObjectGuid, GMTicket> GMTicketMap;
typedef std::list<GMTicket*> GMTicketList; // for creating order access
typedef std::map<uint32, GMTicket*> GMTicketIdMap; // for creating order access
class GMTicketMgr
{
@ -198,7 +197,15 @@ class GMTicketMgr
{ return NULL; }
return &(itr->second);
}
GMTicket* GetGMTicket(uint32 id)
{
GMTicketIdMap::iterator itr = m_GMTicketIdMap.find(id);
if (itr == m_GMTicketIdMap.end())
return NULL;
return itr->second;
}
size_t GetTicketCount() const
{
return m_GMTicketMap.size();
@ -209,11 +216,11 @@ class GMTicketMgr
if (pos >= GetTicketCount())
{ return NULL; }
GMTicketList::iterator itr = m_GMTicketListByCreatingOrder.begin();
GMTicketMap::iterator itr = m_GMTicketMap.begin();
std::advance(itr, pos);
if (itr == m_GMTicketListByCreatingOrder.end())
if (itr == m_GMTicketMap.end())
{ return NULL; }
return *itr;
return &(itr->second);
}
/**
@ -229,7 +236,7 @@ class GMTicketMgr
GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
if (itr == m_GMTicketMap.end())
{ return; }
m_GMTicketListByCreatingOrder.remove(&itr->second);
m_GMTicketIdMap.erase(itr->second.GetId());
m_GMTicketMap.erase(itr);
}
@ -255,17 +262,17 @@ class GMTicketMgr
* file a ticket.
* @param accept true means that we accept tickets, false means that we don't
*/
void SetAcceptTickets(bool accept) { m_TicketSystemOn = accept; };
void SetAcceptTickets(bool accept) { m_TicketSystemOn = accept; }
/**
* Checks if we accept tickets globally (see \ref GMTicketMgr::SetAcceptTickets)
* @return true if we are accepting tickets globally, false otherwise
* \todo Perhaps rename to IsAcceptingTickets?
*/
bool WillAcceptTickets() { return m_TicketSystemOn; };
bool WillAcceptTickets() { return m_TicketSystemOn; }
private:
bool m_TicketSystemOn;
GMTicketMap m_GMTicketMap;
GMTicketList m_GMTicketListByCreatingOrder;
GMTicketIdMap m_GMTicketIdMap;
};
#define sTicketMgr MaNGOS::Singleton<GMTicketMgr>::Instance()

View File

@ -1029,7 +1029,12 @@ enum MangosStrings
LANG_COMMAND_TICKETS_SYSTEM_ON = 1511,
LANG_COMMAND_TICKETS_SYSTEM_OFF = 1512,
LANG_COMMAND_TICKET_CANT_CLOSE = 1513,
// Room for more Level 2 1514-1599 not used
LANG_COMMAND_TICKET_BRIEF_INFO = 1514,
LANG_COMMAND_TICKET_COUNT_ONLINE = 1515,
LANG_COMMAND_TICKET_OFFLINE_INFO = 1516,
LANG_COMMAND_TICKET_COUNT_ALL = 1517,
LANG_COMMAND_TICKET_ACCEPT_STATE = 1518,
// Room for more Level 2 1519-1599 not used
// Outdoor PvP
LANG_OPVP_EP_CAPTURE_NPT_H = 1600,

View File

@ -661,6 +661,21 @@ ChatCommand* ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand ticketCommandTable[] =
{
{ "accept", SEC_ADMINISTRATOR, true, &ChatHandler::HandleTicketAcceptCommand, "", NULL },
{ "close", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketCloseCommand, "", NULL },
{ "delete", SEC_ADMINISTRATOR, true, &ChatHandler::HandleTicketDeleteCommand, "", NULL },
{ "info", SEC_MODERATOR, true, &ChatHandler::HandleTicketInfoCommand, "", NULL },
{ "list", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketListCommand, "", NULL },
{ "meaccept", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketMeAcceptCommand, "", NULL },
{ "onlinelist", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketOnlineListCommand, "", NULL },
{ "respond", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketRespondCommand, "", NULL },
{ "show", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketShowCommand, "", NULL },
{ "surveyclose", SEC_GAMEMASTER, true, &ChatHandler::HandleTickerSurveyClose, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand triggerCommandTable[] =
{
{ "active", SEC_GAMEMASTER, false, &ChatHandler::HandleTriggerActiveCommand, "", NULL },
@ -755,8 +770,7 @@ ChatCommand* ChatHandler::getCommandTable()
{ "additemset", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemSetCommand, "", NULL },
{ "bank", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBankCommand, "", NULL },
{ "wchange", SEC_ADMINISTRATOR, false, &ChatHandler::HandleChangeWeatherCommand, "", NULL },
{ "ticket", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketCommand, "", NULL },
{ "delticket", SEC_GAMEMASTER, true, &ChatHandler::HandleDelTicketCommand, "", NULL },
{ "ticket", SEC_GAMEMASTER, true, NULL, "", ticketCommandTable },
{ "maxskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMaxSkillCommand, "", NULL },
{ "setskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetSkillCommand, "", NULL },
{ "whispers", SEC_MODERATOR, false, &ChatHandler::HandleWhispersCommand, "", NULL },

View File

@ -574,8 +574,17 @@ class ChatHandler
bool HandleChangeWeatherCommand(char* args);
bool HandleKickPlayerCommand(char* args);
bool HandleTicketCommand(char* args);
bool HandleDelTicketCommand(char* args);
bool HandleTicketAcceptCommand(char* args);
bool HandleTicketCloseCommand(char* args);
bool HandleTicketDeleteCommand(char* args);
bool HandleTicketInfoCommand(char* args);
bool HandleTicketListCommand(char* args);
bool HandleTicketMeAcceptCommand(char* args);
bool HandleTicketOnlineListCommand(char* args);
bool HandleTicketRespondCommand(char* args);
bool HandleTicketShowCommand(char* args);
bool HandleTickerSurveyClose(char* args);
bool HandleMaxSkillCommand(char* args);
bool HandleSetSkillCommand(char* args);
bool HandleRespawnCommand(char* args);

View File

@ -589,11 +589,13 @@ void World::LoadConfigSettings(bool reload)
setConfigMinMax(CONFIG_UINT32_MIN_PETITION_SIGNS, "MinPetitionSigns", 9, 0, 9);
setConfig(CONFIG_UINT32_GM_LOGIN_STATE, "GM.LoginState", 2);
setConfig(CONFIG_UINT32_GM_VISIBLE_STATE, "GM.Visible", 2);
setConfig(CONFIG_UINT32_GM_ACCEPT_TICKETS, "GM.AcceptTickets", 2);
setConfig(CONFIG_UINT32_GM_CHAT, "GM.Chat", 2);
setConfig(CONFIG_UINT32_GM_WISPERING_TO, "GM.WhisperingTo", 2);
setConfig(CONFIG_UINT32_GM_LOGIN_STATE, "GM.LoginState", 2);
setConfig(CONFIG_UINT32_GM_VISIBLE_STATE, "GM.Visible", 2);
setConfig(CONFIG_UINT32_GM_ACCEPT_TICKETS, "GM.AcceptTickets", 2);
setConfig(CONFIG_UINT32_GM_TICKET_LIST_SIZE, "GM.TicketListSize", 30);
setConfig(CONFIG_BOOL_GM_TICKET_OFFLINE_CLOSING, "GM.TicketOfflineClosing", false);
setConfig(CONFIG_UINT32_GM_CHAT, "GM.Chat", 2);
setConfig(CONFIG_UINT32_GM_WISPERING_TO, "GM.WhisperingTo", 2);
setConfig(CONFIG_UINT32_GM_LEVEL_IN_GM_LIST, "GM.InGMList.Level", SEC_ADMINISTRATOR);
setConfig(CONFIG_UINT32_GM_LEVEL_IN_WHO_LIST, "GM.InWhoList.Level", SEC_ADMINISTRATOR);

View File

@ -128,6 +128,7 @@ enum eConfigUInt32Values
CONFIG_UINT32_GM_LOGIN_STATE,
CONFIG_UINT32_GM_VISIBLE_STATE,
CONFIG_UINT32_GM_ACCEPT_TICKETS,
CONFIG_UINT32_GM_TICKET_LIST_SIZE,
CONFIG_UINT32_GM_CHAT,
CONFIG_UINT32_GM_WISPERING_TO,
CONFIG_UINT32_GM_LEVEL_IN_GM_LIST,
@ -362,6 +363,7 @@ enum eConfigBoolValues
#endif
CONFIG_BOOL_WARDEN_WIN_ENABLED,
CONFIG_BOOL_WARDEN_OSX_ENABLED,
CONFIG_BOOL_GM_TICKET_OFFLINE_CLOSING,
CONFIG_BOOL_VALUE_COUNT
};
@ -412,7 +414,6 @@ enum RealmZone
REALM_ZONE_CN9 = 29 // basic-Latin at create, any at login
};
/// Storage class for commands issued for delayed execution
struct CliCommandHolder
{

View File

@ -3,7 +3,7 @@
################################################################################
[MangosdConf]
ConfVersion=2015082701
ConfVersion=2016031901
################################################################################
# CONNECTIONS AND DIRECTORIES
@ -1088,6 +1088,15 @@ Channel.SilentlyGMJoin = 0
# 0 (disable)
# 1 (enable)
#
# GM.TicketListSize
# Number of tickets shown to a GM by .ticket list/onlinelist.
# Default: 30
#
# GM.TicketOfflineClosing
# Is GM ticket close available for teh offline players or not.
# Default: 0 (false) closing denied
# 1 (true) closing enabled
#
# GM.Chat
# GM chat mode at login
# Default: 2 (last save state)
@ -1135,17 +1144,19 @@ Channel.SilentlyGMJoin = 0
#
################################################################################
GM.LoginState = 2
GM.Visible = 2
GM.AcceptTickets = 2
GM.Chat = 2
GM.WhisperingTo = 2
GM.InGMList.Level = 3
GM.InWhoList.Level = 3
GM.LogTrade = 1
GM.StartLevel = 1
GM.LowerSecurity = 0
GM.InvisibleAura = 31748
GM.LoginState = 2
GM.Visible = 2
GM.AcceptTickets = 2
GM.TicketListSize = 30
GM.TicketOfflineClosing = 1
GM.Chat = 2
GM.WhisperingTo = 2
GM.InGMList.Level = 3
GM.InWhoList.Level = 3
GM.LogTrade = 1
GM.StartLevel = 1
GM.LowerSecurity = 0
GM.InvisibleAura = 31748
################################################################################
# VISIBILITY AND RADIUSES

View File

@ -42,7 +42,7 @@
// Format is YYYYMMDDRR where RR is the change in the conf file
// for that day.
#ifndef MANGOSD_CONFIG_VERSION
# define MANGOSD_CONFIG_VERSION 2015082701
# define MANGOSD_CONFIG_VERSION 2016031901
#endif
#ifndef REALMD_CONFIG_VERSION
# define REALMD_CONFIG_VERSION 2010062001

View File

@ -37,7 +37,7 @@
#define CHAR_DB_UPDATE_DESCRIPTION "Fix SoR paladin"
#define WORLD_DB_VERSION_NR 21
#define WORLD_DB_STRUCTURE_NR 5
#define WORLD_DB_CONTENT_NR 2
#define WORLD_DB_UPDATE_DESCRIPTION "BG template addition"
#define WORLD_DB_STRUCTURE_NR 6
#define WORLD_DB_CONTENT_NR 1
#define WORLD_DB_UPDATE_DESCRIPTION "GM Ticket Additions"
#endif // __REVISION_H__