Cache GM tickets on server startup.

This commit is contained in:
hunuza 2008-11-03 21:03:58 +01:00
parent 49307f6a13
commit 843a0d7d02
11 changed files with 435 additions and 260 deletions

View file

@ -438,7 +438,6 @@ class ChatHandler
// Utility methods for commands // Utility methods for commands
void ShowTicket(uint64 guid, char const* text, char const* time); void ShowTicket(uint64 guid, char const* text, char const* time);
uint32 GetTicketIDByNum(uint32 num);
bool LookupPlayerSearchCommand(QueryResult* result, int32 limit); bool LookupPlayerSearchCommand(QueryResult* result, int32 limit);
bool HandleBanListHelper(QueryResult* result); bool HandleBanListHelper(QueryResult* result);
bool HandleBanHelper(BanMode mode,char const* args); bool HandleBanHelper(BanMode mode,char const* args);

View file

@ -0,0 +1,179 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Language.h"
#include "WorldPacket.h"
#include "Log.h"
#include "GMTicketMgr.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "Chat.h"
void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
{
int len = text ? strlen(text) : 0;
WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
data << uint32(status); // standard 0x0A, 0x06 if text present
if(status == 6)
{
data << text; // ticket text
data << uint8(0x7); // ticket category
data << float(0); // time from ticket creation?
data << float(0); // const
data << float(0); // const
data << uint8(0); // const
data << uint8(0); // const
}
SendPacket( &data );
}
void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
{
WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
data << (uint32)time(NULL);
data << (uint32)0;
SendPacket( &data );
GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow());
if(ticket)
SendGMTicketGetTicket(0x06,ticket->GetText());
else
SendGMTicketGetTicket(0x0A,0);
}
void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,1);
std::string ticketText;
recv_data >> ticketText;
CharacterDatabase.escape_string(ticketText);
if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
ticket->SetText(ticketText.c_str());
else
sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
}
void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
{
ticketmgr.Delete(GetPlayer()->GetGUIDLow());
WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
data << uint32(9);
SendPacket( &data );
SendGMTicketGetTicket(0x0A, 0);
}
void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
uint32 map;
float x, y, z;
std::string ticketText = "";
uint32 unk1, unk2;
recv_data >> map >> x >> y >> z; // last check 2.4.3
recv_data >> ticketText;
// recheck
CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
recv_data >> unk1 >> unk2;
// note: the packet might contain more data, but the exact structure of that is unknown
sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
CharacterDatabase.escape_string(ticketText);
if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
{
WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
data << uint32(1);
SendPacket( &data );
return;
}
ticketmgr.Create(_player->GetGUIDLow(), ticketText.c_str());
WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
data << (uint32)time(NULL);
data << (uint32)0;
SendPacket( &data );
data.Initialize( SMSG_GMTICKET_CREATE, 4 );
data << uint32(2);
SendPacket( &data );
DEBUG_LOG("update the ticket\n");
//TODO: Guard player map
HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
{
if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
}
}
void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
{
WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
data << uint32(1); // we can also disable ticket system by sending 0 value
SendPacket( &data );
}
void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
{
// GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
CHECK_PACKET_SIZE(recv_data,4+4);
uint32 x;
recv_data >> x; // answer range? (6 = 0-5?)
sLog.outDebug("SURVEY: X = %u", x);
uint8 result[10];
memset(result, 0, sizeof(result));
for( int i = 0; i < 10; ++i)
{
CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
uint32 questionID;
recv_data >> questionID; // GMSurveyQuestions.dbc
if (!questionID)
break;
CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
uint8 value;
std::string unk_text;
recv_data >> value; // answer
recv_data >> unk_text; // always empty?
result[i] = value;
sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
}
CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
std::string comment;
recv_data >> comment; // addional comment
sLog.outDebug("SURVEY: comment %s", comment.c_str());
// TODO: chart this data in some way
}

80
src/game/GMTicketMgr.cpp Normal file
View file

@ -0,0 +1,80 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "Database/SQLStorage.h"
#include "GMTicketMgr.h"
#include "ObjectMgr.h"
#include "ProgressBar.h"
#include "Policies/SingletonImp.h"
#include "Player.h"
#include "ObjectDefines.h"
INSTANTIATE_SINGLETON_1(GMTicketMgr);
void GMTicketMgr::LoadGMTickets()
{
m_GMTicketMap.clear(); // For reload case
QueryResult *result = CharacterDatabase.Query(
// 0 1 2
"SELECT guid, ticket_text,UNIX_TIMESTAMP(ticket_lastchange) FROM character_ticket");
if( !result )
{
barGoLink bar( 1 );
bar.step();
sLog.outString();
sLog.outErrorDb(">> Loaded `character_ticket`, table is empty!");
return;
}
barGoLink bar( result->GetRowCount() );
uint32 count = 0;
do
{
bar.step();
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
m_GMTicketMap[guid] = GMTicket(guid, fields[1].GetCppString(), time_t(fields[2].GetUInt64()));
++count;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString( ">> Loaded %d GM tickets", count );
}
void GMTicketMgr::DeleteAll()
{
for(GMTicketMap::iterator itr = m_GMTicketMap.begin(); itr != m_GMTicketMap.end(); ++itr)
{
if(Player* owner = objmgr.GetPlayer(MAKE_NEW_GUID(itr->first,0,HIGHGUID_PLAYER)))
owner->GetSession()->SendGMTicketGetTicket(0x0A,0);
}
CharacterDatabase.PExecute("DELETE FROM character_ticket");
m_GMTicketMap.clear();
}

118
src/game/GMTicketMgr.h Normal file
View file

@ -0,0 +1,118 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _GMTICKETMGR_H
#define _GMTICKETMGR_H
#include "Policies/Singleton.h"
#include "Database/DatabaseEnv.h"
#include "Util.h"
#include <map>
class GMTicket
{
public:
explicit GMTicket()
{
}
GMTicket(uint32 guid, std::string text, time_t update) : m_guid(guid), m_text(text), m_lastUpdate(update)
{
}
const char* GetText() const
{
return m_text.c_str();
}
uint64 GetLastUpdate() const
{
return m_lastUpdate;
}
void SetText(const char* text)
{
m_text = text ? text : "";
m_lastUpdate = time(NULL);
CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", m_text.c_str(), m_guid);
}
void DeleteFromDB() const
{
CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1", m_guid);
}
void SaveToDB() const
{
CharacterDatabase.BeginTransaction();
DeleteFromDB();
CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, GetText());
CharacterDatabase.CommitTransaction();
}
private:
uint32 m_guid;
std::string m_text;
time_t m_lastUpdate;
};
typedef std::map<uint32, GMTicket> GMTicketMap;
class GMTicketMgr
{
public:
GMTicketMgr() { }
~GMTicketMgr() { }
void LoadGMTickets();
GMTicket* GetGMTicket(uint32 guid)
{
GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
if(itr == m_GMTicketMap.end())
return NULL;
return &(itr->second);
}
size_t GetTicketCount() const
{
return m_GMTicketMap.size();
}
void Delete(uint32 guid)
{
GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
if(itr == m_GMTicketMap.end())
return;
itr->second.DeleteFromDB();
m_GMTicketMap.erase(itr);
}
void DeleteAll();
void Create(uint32 guid, const char* text)
{
GMTicket t = GMTicket(guid, text, time(NULL));
t.SaveToDB();
m_GMTicketMap[guid] = t;
}
private:
GMTicketMap m_GMTicketMap;
};
#define ticketmgr MaNGOS::Singleton<GMTicketMgr>::Instance()
#endif

View file

@ -34,6 +34,7 @@
#include "GameEvent.h" #include "GameEvent.h"
#include "SpellMgr.h" #include "SpellMgr.h"
#include "AccountMgr.h" #include "AccountMgr.h"
#include "GMTicketMgr.h"
#include "WaypointManager.h" #include "WaypointManager.h"
#include "Util.h" #include "Util.h"
#include <cctype> #include <cctype>
@ -1926,15 +1927,7 @@ bool ChatHandler::HandleTicketCommand(const char* args)
return false; return false;
} }
size_t count; size_t count = ticketmgr.GetTicketCount();
QueryResult *result = CharacterDatabase.Query("SELECT COUNT(ticket_id) FROM character_ticket");
if(result)
{
count = (*result)[0].GetUInt32();
delete result;
}
else
count = 0;
bool accept = m_session->GetPlayer()->isAcceptTickets(); bool accept = m_session->GetPlayer()->isAcceptTickets();
@ -1981,18 +1974,17 @@ bool ChatHandler::HandleTicketCommand(const char* args)
if(!result) if(!result)
{ {
PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
delete result;
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
Field* fields = result->Fetch(); Field* fields = result->Fetch();
uint64 guid = fields[0].GetUInt64(); uint32 guid = fields[0].GetUInt32();
char const* text = fields[1].GetString(); char const* text = fields[1].GetString();
char const* time = fields[2].GetString(); char const* time = fields[2].GetString();
ShowTicket(guid,text,time); ShowTicket(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),text,time);
delete result; delete result;
return true; return true;
} }
@ -2012,43 +2004,17 @@ bool ChatHandler::HandleTicketCommand(const char* args)
return false; return false;
// ticket $char_name // ticket $char_name
QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_text,ticket_lastchange FROM character_ticket WHERE guid = '%u' ORDER BY ticket_id ASC",GUID_LOPART(guid)); GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid));
if(!ticket)
if(!result)
return false; return false;
Field* fields = result->Fetch(); std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
char const* text = fields[0].GetString(); ShowTicket(guid, ticket->GetText(), time.c_str());
char const* time = fields[1].GetString();
ShowTicket(guid,text,time);
delete result;
return true; return true;
} }
uint32 ChatHandler::GetTicketIDByNum(uint32 num)
{
QueryResult *result = CharacterDatabase.Query("SELECT ticket_id FROM character_ticket");
if(!result || num > result->GetRowCount())
{
PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
delete result;
return 0;
}
for(uint32 i = 1; i < num; ++i)
result->NextRow();
Field* fields = result->Fetch();
uint32 id = fields[0].GetUInt32();
delete result;
return id;
}
//dell all tickets //dell all tickets
bool ChatHandler::HandleDelTicketCommand(const char *args) bool ChatHandler::HandleDelTicketCommand(const char *args)
{ {
@ -2059,26 +2025,7 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
// delticket all // delticket all
if(strncmp(px,"all",4) == 0) if(strncmp(px,"all",4) == 0)
{ {
QueryResult *result = CharacterDatabase.Query("SELECT guid FROM character_ticket"); ticketmgr.DeleteAll();
if(!result)
return true;
// notify players about ticket deleting
do
{
Field* fields = result->Fetch();
uint64 guid = fields[0].GetUInt64();
if(Player* sender = objmgr.GetPlayer(guid))
sender->GetSession()->SendGMTicketGetTicket(0x0A,0);
}while(result->NextRow());
delete result;
CharacterDatabase.PExecute("DELETE FROM character_ticket");
SendSysMessage(LANG_COMMAND_ALLTICKETDELETED); SendSysMessage(LANG_COMMAND_ALLTICKETDELETED);
return true; return true;
} }
@ -2088,32 +2035,27 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
// delticket #num // delticket #num
if(num > 0) if(num > 0)
{ {
QueryResult *result = CharacterDatabase.PQuery("SELECT ticket_id,guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1); QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM character_ticket ORDER BY ticket_id ASC "_OFFSET_,num-1);
if(!result) if(!result)
{ {
PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num); PSendSysMessage(LANG_COMMAND_TICKENOTEXIST, num);
delete result;
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
Field* fields = result->Fetch(); Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
uint32 id = fields[0].GetUInt32();
uint64 guid = fields[1].GetUInt64();
delete result; delete result;
CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE ticket_id = '%u'", id); ticketmgr.Delete(guid);
// notify players about ticket deleting //notify player
if(Player* sender = objmgr.GetPlayer(guid)) if(Player* pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
{ {
sender->GetSession()->SendGMTicketGetTicket(0x0A,0); pl->GetSession()->SendGMTicketGetTicket(0x0A, 0);
PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,sender->GetName()); PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL, pl->GetName());
} }
else else
SendSysMessage(LANG_COMMAND_TICKETDEL); PSendSysMessage(LANG_COMMAND_TICKETDEL);
return true; return true;
} }
@ -2133,7 +2075,7 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
return false; return false;
// delticket $char_name // delticket $char_name
CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u'",GUID_LOPART(guid)); ticketmgr.Delete(GUID_LOPART(guid));
// notify players about ticket deleting // notify players about ticket deleting
if(Player* sender = objmgr.GetPlayer(guid)) if(Player* sender = objmgr.GetPlayer(guid))

View file

@ -103,6 +103,9 @@ libmangosgame_a_SOURCES = \
GameObject.h \ GameObject.h \
GlobalEvents.cpp \ GlobalEvents.cpp \
GlobalEvents.h \ GlobalEvents.h \
GMTicketHandler.cpp \
GMTicketMgr.cpp \
GMTicketMgr.h \
GossipDef.cpp \ GossipDef.cpp \
GossipDef.h \ GossipDef.h \
GridDefines.h \ GridDefines.h \

View file

@ -355,189 +355,6 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ )
sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" ); sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" );
} }
void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
{
int len = text ? strlen(text) : 0;
WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
data << uint32(status); // standard 0x0A, 0x06 if text present
if(status == 6)
{
data << text; // ticket text
data << uint8(0x7); // ticket category
data << float(0); // time from ticket creation?
data << float(0); // const
data << float(0); // const
data << uint8(0); // const
data << uint8(0); // const
}
SendPacket( &data );
}
void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
{
WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
data << (uint32)time(NULL);
data << (uint32)0;
SendPacket( &data );
uint64 guid;
Field *fields;
guid = GetPlayer()->GetGUID();
QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(ticket_id) FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid));
if (result)
{
int cnt;
fields = result->Fetch();
cnt = fields[0].GetUInt32();
delete result;
if ( cnt > 0 )
{
QueryResult *result2 = CharacterDatabase.PQuery("SELECT ticket_text FROM character_ticket WHERE guid = '%u'", GUID_LOPART(guid));
if(result2)
{
Field *fields2 = result2->Fetch();
SendGMTicketGetTicket(0x06,fields2[0].GetString());
delete result2;
}
}
else
SendGMTicketGetTicket(0x0A,0);
}
}
void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,1);
std::string ticketText;
recv_data >> ticketText;
CharacterDatabase.escape_string(ticketText);
CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", ticketText.c_str(), _player->GetGUIDLow());
}
void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
{
uint32 guid = GetPlayer()->GetGUIDLow();
CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1",guid);
WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
data << uint32(9);
SendPacket( &data );
SendGMTicketGetTicket(0x0A, 0);
}
void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
uint32 map;
float x, y, z;
std::string ticketText = "";
uint32 unk1, unk2;
recv_data >> map >> x >> y >> z; // last check 2.4.3
recv_data >> ticketText;
// recheck
CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
recv_data >> unk1 >> unk2;
// note: the packet might contain more data, but the exact structure of that is unknown
sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
CharacterDatabase.escape_string(ticketText);
QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM character_ticket WHERE guid = '%u'", _player->GetGUIDLow());
if (result)
{
int cnt;
Field *fields = result->Fetch();
cnt = fields[0].GetUInt32();
delete result;
if ( cnt > 0 )
{
WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
data << uint32(1);
SendPacket( &data );
}
else
{
CharacterDatabase.PExecute("INSERT INTO character_ticket (guid,ticket_text) VALUES ('%u', '%s')", _player->GetGUIDLow(), ticketText.c_str());
WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
data << (uint32)time(NULL);
data << (uint32)0;
SendPacket( &data );
data.Initialize( SMSG_GMTICKET_CREATE, 4 );
data << uint32(2);
SendPacket( &data );
DEBUG_LOG("update the ticket\n");
//TODO: Guard player map
HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
{
if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
}
}
}
}
void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
{
WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
data << uint32(1); // we can also disable ticket system by sending 0 value
SendPacket( &data );
}
void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
{
// GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
CHECK_PACKET_SIZE(recv_data,4+4);
uint32 x;
recv_data >> x; // answer range? (6 = 0-5?)
sLog.outDebug("SURVEY: X = %u", x);
uint8 result[10];
memset(result, 0, sizeof(result));
for( int i = 0; i < 10; ++i)
{
CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
uint32 questionID;
recv_data >> questionID; // GMSurveyQuestions.dbc
if (!questionID)
break;
CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
uint8 value;
std::string unk_text;
recv_data >> value; // answer
recv_data >> unk_text; // always empty?
result[i] = value;
sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
}
CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
std::string comment;
recv_data >> comment; // addional comment
sLog.outDebug("SURVEY: comment %s", comment.c_str());
// TODO: chart this data in some way
}
void WorldSession::HandleTogglePvP( WorldPacket & recv_data ) void WorldSession::HandleTogglePvP( WorldPacket & recv_data )
{ {
// this opcode can be used in two ways: Either set explicit new status or toggle old status // this opcode can be used in two ways: Either set explicit new status or toggle old status

View file

@ -56,6 +56,7 @@
#include "CellImpl.h" #include "CellImpl.h"
#include "InstanceSaveMgr.h" #include "InstanceSaveMgr.h"
#include "WaypointManager.h" #include "WaypointManager.h"
#include "GMTicketMgr.h"
#include "Util.h" #include "Util.h"
INSTANTIATE_SINGLETON_1( World ); INSTANTIATE_SINGLETON_1( World );
@ -1125,6 +1126,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Waypoints..." ); sLog.outString( "Loading Waypoints..." );
WaypointMgr.Load(); WaypointMgr.Load();
sLog.outString( "Loading GM tickets...");
ticketmgr.LoadGMTickets();
///- Handle outdated emails (delete/return) ///- Handle outdated emails (delete/return)
sLog.outString( "Returning old mails..." ); sLog.outString( "Returning old mails..." );
objmgr.ReturnOrDeleteOldMails(false); objmgr.ReturnOrDeleteOldMails(false);

View file

@ -252,6 +252,9 @@
<File <File
RelativePath="..\..\src\game\GameEvent.h"> RelativePath="..\..\src\game\GameEvent.h">
</File> </File>
<File
RelativePath="..\..\src\game\GMTicketHandler.cpp">
</File>
<File <File
RelativePath="..\..\src\game\GossipDef.cpp"> RelativePath="..\..\src\game\GossipDef.cpp">
</File> </File>
@ -549,6 +552,12 @@
<File <File
RelativePath="..\..\src\game\GameObject.h"> RelativePath="..\..\src\game\GameObject.h">
</File> </File>
<File
RelativePath="..\..\src\game\GMTicketMgr.cpp">
</File>
<File
RelativePath="..\..\src\game\GMTicketMgr.h">
</File>
<File <File
RelativePath="..\..\src\game\GuardAI.cpp"> RelativePath="..\..\src\game\GuardAI.cpp">
</File> </File>

View file

@ -510,6 +510,10 @@
RelativePath="..\..\src\game\GameEvent.h" RelativePath="..\..\src\game\GameEvent.h"
> >
</File> </File>
<File
RelativePath="..\..\src\game\GMTicketHandler.cpp"
>
</File>
<File <File
RelativePath="..\..\src\game\GossipDef.cpp" RelativePath="..\..\src\game\GossipDef.cpp"
> >
@ -906,6 +910,14 @@
RelativePath="..\..\src\game\GameObject.h" RelativePath="..\..\src\game\GameObject.h"
> >
</File> </File>
<File
RelativePath="..\..\src\game\GMTicketMgr.cpp"
>
</File>
<File
RelativePath="..\..\src\game\GMTicketMgr.h"
>
</File>
<File <File
RelativePath="..\..\src\game\GuardAI.cpp" RelativePath="..\..\src\game\GuardAI.cpp"
> >

View file

@ -511,6 +511,10 @@
RelativePath="..\..\src\game\GameEvent.h" RelativePath="..\..\src\game\GameEvent.h"
> >
</File> </File>
<File
RelativePath="..\..\src\game\GMTicketHandler.cpp"
>
</File>
<File <File
RelativePath="..\..\src\game\GossipDef.cpp" RelativePath="..\..\src\game\GossipDef.cpp"
> >
@ -907,6 +911,14 @@
RelativePath="..\..\src\game\GameObject.h" RelativePath="..\..\src\game\GameObject.h"
> >
</File> </File>
<File
RelativePath="..\..\src\game\GMTicketMgr.cpp"
>
</File>
<File
RelativePath="..\..\src\game\GMTicketMgr.h"
>
</File>
<File <File
RelativePath="..\..\src\game\GuardAI.cpp" RelativePath="..\..\src\game\GuardAI.cpp"
> >