From 2447c38c82e89859dd916ae3a4a010c74b3e21fe Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 2 Jan 2017 22:38:47 -0800 Subject: [PATCH] Working on world <-> zone communication needs a ton of work really need to rewrite how world works with zones. --- common/net/servertalk_client_connection.cpp | 2 +- common/net/servertalk_server_connection.cpp | 2 + common/net/servertalk_server_connection.h | 2 + common/servertalk.h | 17 + queryserv/worldserver.cpp | 36 +- queryserv/worldserver.h | 4 +- world/CMakeLists.txt | 2 - world/client.cpp | 10 +- world/clientlist.cpp | 2 - world/console.cpp | 46 +- world/net.cpp | 105 +- world/queryserv.cpp | 131 +- world/queryserv.h | 14 +- world/zonelist.cpp | 315 +- world/zonelist.h | 4 +- world/zoneserver.cpp | 2286 ++++++------- world/zoneserver.h | 20 +- zone/attack.cpp | 1 + zone/command.cpp | 12 - zone/effects.cpp | 1 + zone/mob.cpp | 1 + zone/net.cpp | 12 +- zone/spell_effects.cpp | 1 + zone/spells.cpp | 1 + zone/titles.cpp | 1 + zone/trading.cpp | 1 + zone/worldserver.cpp | 3337 +++++++++---------- zone/worldserver.h | 18 +- 28 files changed, 3080 insertions(+), 3304 deletions(-) diff --git a/common/net/servertalk_client_connection.cpp b/common/net/servertalk_client_connection.cpp index fbd0e1d05..79a8b8234 100644 --- a/common/net/servertalk_client_connection.cpp +++ b/common/net/servertalk_client_connection.cpp @@ -297,7 +297,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p) auto cb = m_message_callbacks.find(opcode); if (cb != m_message_callbacks.end()) { - cb->second(opcode, packet); + m_message_callback_any(opcode, packet); } #endif } diff --git a/common/net/servertalk_server_connection.cpp b/common/net/servertalk_server_connection.cpp index 7aade1e30..90393abe1 100644 --- a/common/net/servertalk_server_connection.cpp +++ b/common/net/servertalk_server_connection.cpp @@ -1,6 +1,7 @@ #include "servertalk_server_connection.h" #include "servertalk_server.h" #include "../eqemu_logsys.h" +#include "../util/uuid.h" EQ::Net::ServertalkServerConnection::ServertalkServerConnection(std::shared_ptr c, EQ::Net::ServertalkServer *parent, bool encrypted, bool allow_downgrade) { @@ -8,6 +9,7 @@ EQ::Net::ServertalkServerConnection::ServertalkServerConnection(std::shared_ptr< m_parent = parent; m_encrypted = encrypted; m_allow_downgrade = allow_downgrade; + m_uuid = EQ::Util::UUID::Generate().ToString(); m_connection->OnRead(std::bind(&ServertalkServerConnection::OnRead, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); m_connection->OnDisconnect(std::bind(&ServertalkServerConnection::OnDisconnect, this, std::placeholders::_1)); m_connection->Start(); diff --git a/common/net/servertalk_server_connection.h b/common/net/servertalk_server_connection.h index 0e496e920..0557fd1a9 100644 --- a/common/net/servertalk_server_connection.h +++ b/common/net/servertalk_server_connection.h @@ -25,6 +25,7 @@ namespace EQ std::string GetIdentifier() const { return m_identifier; } std::shared_ptr Handle() { return m_connection; } + std::string GetUUID() const { return m_uuid; } private: void OnRead(TCPConnection* c, const unsigned char* data, size_t sz); void ProcessReadBuffer(); @@ -41,6 +42,7 @@ namespace EQ std::vector m_buffer; std::unordered_map> m_message_callbacks; std::string m_identifier; + std::string m_uuid; bool m_encrypted; bool m_allow_downgrade; diff --git a/common/servertalk.h b/common/servertalk.h index b7a52750a..78f46c684 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -4,6 +4,7 @@ #include "../common/types.h" #include "../common/packet_functions.h" #include "../common/eq_packet_structs.h" +#include "../net/packet.h" #include #include @@ -223,6 +224,22 @@ public: _wpos = 0; _rpos = 0; } + + ServerPacket(uint16 in_opcode, const EQ::Net::Packet &p) { + this->compressed = false; + size = p.Length(); + opcode = in_opcode; + if (size == 0) { + pBuffer = 0; + } + else { + pBuffer = new uchar[size]; + memcpy(pBuffer, p.Data(), size); + } + _wpos = 0; + _rpos = 0; + } + ServerPacket* Copy() { if (this == 0) { return 0; diff --git a/queryserv/worldserver.cpp b/queryserv/worldserver.cpp index 615f88d1a..314c61fee 100644 --- a/queryserv/worldserver.cpp +++ b/queryserv/worldserver.cpp @@ -52,40 +52,38 @@ WorldServer::~WorldServer() void WorldServer::Connect() { - m_server.reset(new EQ::Net::ServertalkServer()); - //Config->WorldIP, Config->WorldTCPPort, "QS", Config->SharedKey + m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "QueryServ", Config->SharedKey)); - m_link->OnMessageType(ServerOP_Speech, std::bind(&WorldServer::HandleMessage, this, ServerOP_Speech, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSPlayerLogTrades, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSPlayerLogTrades, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSPlayerLogHandins, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSPlayerLogHandins, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSPlayerLogNPCKills, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSPlayerLogNPCKills, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSPlayerLogDeletes, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSPlayerLogDeletes, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSPlayerLogMoves, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSPlayerLogMoves, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSPlayerLogMerchantTransactions, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSPlayerLogMerchantTransactions, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QueryServGeneric, std::bind(&WorldServer::HandleMessage, this, ServerOP_QueryServGeneric, std::placeholders::_1)); - m_link->OnMessageType(ServerOP_QSSendQuery, std::bind(&WorldServer::HandleMessage, this, ServerOP_QSSendQuery, std::placeholders::_1)); + m_connection->OnMessage(ServerOP_Speech, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSPlayerLogTrades, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSPlayerLogHandins, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSPlayerLogNPCKills, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSPlayerLogDeletes, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSPlayerLogMoves, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSPlayerLogMerchantTransactions, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QueryServGeneric, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_connection->OnMessage(ServerOP_QSSendQuery, std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); } bool WorldServer::SendPacket(ServerPacket *pack) { - EQ::Net::ReadOnlyPacket p(pack->pBuffer, pack->size); - ->SendPacket(pack->opcode, p); + m_connection->SendPacket(pack); return true; } std::string WorldServer::GetIP() const { - return m_link->GetIP(); + return m_connection->Handle()->RemoteIP(); } uint16 WorldServer::GetPort() const { - return m_link->GetPort(); + return m_connection->Handle()->RemotePort(); } bool WorldServer::Connected() const { - return m_link->Connected(); + return m_connection->Connected(); } void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) @@ -118,7 +116,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } case ServerOP_QSPlayerLogNPCKills: { QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)p.Data(); - uint32 Members = p.Length() - sizeof(QSPlayerLogNPCKill_Struct); + uint32 Members = (uint32)(p.Length() - sizeof(QSPlayerLogNPCKill_Struct)); if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct); database.LogPlayerNPCKill(QS, Members); break; @@ -170,7 +168,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ServerPacket pack; pack.pBuffer = (uchar*)p.Data(); pack.opcode = opcode; - pack.size = p.Length(); + pack.size = (uint32)p.Length(); lfguildmanager.HandlePacket(&pack); pack.pBuffer = nullptr; break; @@ -186,7 +184,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ServerPacket pack; pack.pBuffer = (uchar*)p.Data(); pack.opcode = opcode; - pack.size = p.Length(); + pack.size = (uint32)p.Length(); database.GeneralQueryReceive(&pack); pack.pBuffer = nullptr; diff --git a/queryserv/worldserver.h b/queryserv/worldserver.h index 8e9d5acc7..7a3d21e6f 100644 --- a/queryserv/worldserver.h +++ b/queryserv/worldserver.h @@ -19,7 +19,7 @@ #define WORLDSERVER_H #include "../common/eq_packet_structs.h" -#include "../common/net/servertalk_server.h" +#include "../common/net/servertalk_client_connection.h" class WorldServer { @@ -35,7 +35,7 @@ class WorldServer void HandleMessage(uint16 opcode, const EQ::Net::Packet &p); private: - std::unique_ptr m_server; + std::unique_ptr m_connection; }; #endif diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index 03b23df08..cb981939c 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -7,7 +7,6 @@ SET(world_sources cliententry.cpp clientlist.cpp CMakeLists.txt - console.cpp eql_config.cpp eqw.cpp eqw_http_handler.cpp @@ -39,7 +38,6 @@ SET(world_headers cliententry.h clientlist.h CMakeLists.txt - console.h eql_config.h eqw.h eqw_http_handler.h diff --git a/world/client.cpp b/world/client.cpp index c9785db41..8feb7e381 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -432,15 +432,11 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { } else id=atoi(name); -#ifdef IPBASED_AUTH_HACK - if ((cle = zoneserver_list.CheckAuth(inet_ntoa(tmpip), password))) -#else if (loginserverlist.Connected() == false && !is_player_zoning) { Log.Out(Logs::General, Logs::World_Server,"Error: Login server login while not connected to login server."); return false; } if (((cle = client_list.CheckAuth(name, password)) || (cle = client_list.CheckAuth(id, password)))) -#endif { if (cle->AccountID() == 0 || (!minilogin && cle->LSID()==0)) { Log.Out(Logs::General, Logs::World_Server,"ID is 0. Is this server connected to minilogin?"); @@ -1255,11 +1251,7 @@ void Client::Clearance(int8 response) if(local_addr[0]) { zs_addr = local_addr; } else { - struct in_addr in; - in.s_addr = zs->GetIP(); - zs_addr = inet_ntoa(in); - - if(strcmp(zs_addr, "127.0.0.1") == 0) + if(strcmp(zs->GetIP().c_str(), "127.0.0.1") == 0) { Log.Out(Logs::Detail, Logs::World_Server, "Local zone address was %s, setting local address to: %s", zs_addr, WorldConfig::get()->LocalAddress.c_str()); zs_addr = WorldConfig::get()->LocalAddress.c_str(); diff --git a/world/clientlist.cpp b/world/clientlist.cpp index fd92051b3..b670b5fb9 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -33,7 +33,6 @@ #include -extern ConsoleList console_list; extern ZSList zoneserver_list; uint32 numplayers = 0; //this really wants to be a member variable of ClientList... @@ -1113,7 +1112,6 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct* AppendAnyLenString(&output, &outsize, &outlen, "\r\n"); else AppendAnyLenString(&output, &outsize, &outlen, "\n"); - console_list.SendConsoleWho(connection, to, admin, &output, &outsize, &outlen); } if (output) connection->SendEmoteMessageRaw(to, 0, 0, 10, output); diff --git a/world/console.cpp b/world/console.cpp index f67f714d2..6f37d0bf1 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -241,32 +241,26 @@ bool Console::Process() { if (tcpc->GetMode() == EmuTCPConnection::modePacket) { struct in_addr in; in.s_addr = GetIP(); - if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) { - auto zs = new ZoneServer(tcpc); - Log.Out(Logs::Detail, Logs::World_Server,"New zoneserver #%d from %s:%d", zs->GetID(), inet_ntoa(in), GetPort()); - zoneserver_list.Add(zs); - numzones++; - tcpc = 0; - } else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) { - Log.Out(Logs::Detail, Logs::World_Server,"New launcher from %s:%d", inet_ntoa(in), GetPort()); - launcher_list.Add(tcpc); - tcpc = 0; - } - else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS) - { - Log.Out(Logs::Detail, Logs::World_Server,"New UCS Connection from %s:%d", inet_ntoa(in), GetPort()); - UCSLink.SetConnection(tcpc); - tcpc = 0; - } - else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeQueryServ) - { - Log.Out(Logs::Detail, Logs::World_Server,"New QS Connection from %s:%d", inet_ntoa(in), GetPort()); - QSLink.SetConnection(tcpc); - tcpc = 0; - } - else { - Log.Out(Logs::Detail, Logs::World_Server,"Unsupported packet mode from %s:%d", inet_ntoa(in), GetPort()); - } + //if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) { + // auto zs = new ZoneServer(tcpc); + // Log.Out(Logs::Detail, Logs::World_Server,"New zoneserver #%d from %s:%d", zs->GetID(), inet_ntoa(in), GetPort()); + // zoneserver_list.Add(zs); + // numzones++; + // tcpc = 0; + //} else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) { + // Log.Out(Logs::Detail, Logs::World_Server,"New launcher from %s:%d", inet_ntoa(in), GetPort()); + // launcher_list.Add(tcpc); + // tcpc = 0; + //} + //else if(tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS) + //{ + // Log.Out(Logs::Detail, Logs::World_Server,"New UCS Connection from %s:%d", inet_ntoa(in), GetPort()); + // UCSLink.SetConnection(tcpc); + // tcpc = 0; + //} + //else { + // Log.Out(Logs::Detail, Logs::World_Server,"Unsupported packet mode from %s:%d", inet_ntoa(in), GetPort()); + //} return false; } char* command = 0; diff --git a/world/net.cpp b/world/net.cpp index 08ff31189..768180a3a 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -107,8 +107,6 @@ bool holdzones = false; const WorldConfig *Config; EQEmuLogSys Log; -extern ConsoleList console_list; - void CatchSignal(int sig_num); int main(int argc, char** argv) { @@ -338,10 +336,12 @@ int main(int argc, char** argv) { } } } + if(RuleB(World, ClearTempMerchantlist)){ Log.Out(Logs::General, Logs::World_Server, "Clearing temporary merchant lists.."); database.ClearMerchantTemp(); } + Log.Out(Logs::General, Logs::World_Server, "Loading EQ time of day.."); TimeOfDay_Struct eqTime; time_t realtime; @@ -385,14 +385,43 @@ int main(int argc, char** argv) { database.LoadCharacterCreateAllocations(); database.LoadCharacterCreateCombos(); - char errbuf[TCPConnection_ErrorBufferSize]; - if (tcps.Open(Config->WorldTCPPort, errbuf)) { - Log.Out(Logs::General, Logs::World_Server,"Zone (TCP) listener started."); - } else { - Log.Out(Logs::General, Logs::World_Server,"Failed to start zone (TCP) listener on port %d:",Config->WorldTCPPort); - Log.Out(Logs::General, Logs::World_Server," %s",errbuf); - return 1; - } + std::unique_ptr server_connection; + server_connection.reset(new EQ::Net::ServertalkServer()); + + EQ::Net::ServertalkServerOptions server_opts; + server_opts.port = Config->WorldTCPPort; + server_opts.ipv6 = false; + server_opts.credentials = Config->SharedKey; + server_connection->Listen(server_opts); + Log.Out(Logs::General, Logs::World_Server, "Server (TCP) listener started."); + + server_connection->OnConnectionIdentified("Zone", [](std::shared_ptr connection) { + Log.OutF(Logs::General, Logs::World_Server, "New Zone Server connection from {2} at {0}:{1}", + connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); + + zoneserver_list.Add(new ZoneServer(connection)); + }); + + server_connection->OnConnectionRemoved("Zone", [](std::shared_ptr connection) { + Log.OutF(Logs::General, Logs::World_Server, "Removed Zone Server connection from {0}", + connection->GetUUID()); + + zoneserver_list.Remove(connection->GetUUID()); + }); + + server_connection->OnConnectionIdentified("QueryServ", [](std::shared_ptr connection) { + Log.OutF(Logs::General, Logs::World_Server, "New Query Server connection from {2} at {0}:{1}", + connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); + + QSLink.AddConnection(connection); + }); + + server_connection->OnConnectionRemoved("QueryServ", [](std::shared_ptr connection) { + Log.OutF(Logs::General, Logs::World_Server, "Removed Query Server connection from {0}", + connection->GetUUID()); + + QSLink.RemoveConnection(connection); + }); EQ::Net::EQStreamManagerOptions opts(9000, false, false); EQ::Net::EQStreamManager eqsm(opts); @@ -450,31 +479,31 @@ int main(int argc, char** argv) { client_list.Process(); - while ((tcpc = tcps.NewQueuePop())) { - struct in_addr in; - in.s_addr = tcpc->GetrIP(); - - /* World - Tell what is being connected */ - if (tcpc->GetMode() == EmuTCPConnection::modePacket) { - if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) { - Log.Out(Logs::General, Logs::World_Server, "New Zone Server from %s:%d", inet_ntoa(in), tcpc->GetrPort()); - } - else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) { - Log.Out(Logs::General, Logs::World_Server, "New Launcher from %s:%d", inet_ntoa(in), tcpc->GetrPort()); - } - else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS) { - Log.Out(Logs::General, Logs::World_Server, "New UCS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort()); - } - else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeQueryServ) { - Log.Out(Logs::General, Logs::World_Server, "New QS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort()); - } - else { - Log.Out(Logs::General, Logs::World_Server, "Unsupported packet mode from %s:%d", inet_ntoa(in), tcpc->GetrPort()); - } - } - - console_list.Add(new Console(tcpc)); - } + //while ((tcpc = tcps.NewQueuePop())) { + // struct in_addr in; + // in.s_addr = tcpc->GetrIP(); + // + // /* World - Tell what is being connected */ + // if (tcpc->GetMode() == EmuTCPConnection::modePacket) { + // if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeZone) { + // Log.Out(Logs::General, Logs::World_Server, "New Zone Server from %s:%d", inet_ntoa(in), tcpc->GetrPort()); + // } + // else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeLauncher) { + // Log.Out(Logs::General, Logs::World_Server, "New Launcher from %s:%d", inet_ntoa(in), tcpc->GetrPort()); + // } + // else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeUCS) { + // Log.Out(Logs::General, Logs::World_Server, "New UCS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort()); + // } + // else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeQueryServ) { + // Log.Out(Logs::General, Logs::World_Server, "New QS Connection from %s:%d", inet_ntoa(in), tcpc->GetrPort()); + // } + // else { + // Log.Out(Logs::General, Logs::World_Server, "Unsupported packet mode from %s:%d", inet_ntoa(in), tcpc->GetrPort()); + // } + // } + // + // console_list.Add(new Console(tcpc)); + //} if(PurgeInstanceTimer.Check()) { @@ -491,11 +520,9 @@ int main(int argc, char** argv) { Log.Out(Logs::Detail, Logs::World_Server, "EQTime successfully saved."); } - console_list.Process(); zoneserver_list.Process(); launcher_list.Process(); UCSLink.Process(); - QSLink.Process(); LFPGroupList.Process(); adventure_manager.Process(); @@ -508,12 +535,10 @@ int main(int argc, char** argv) { Sleep(1); } Log.Out(Logs::General, Logs::World_Server, "World main loop completed."); - Log.Out(Logs::General, Logs::World_Server, "Shutting down console connections (if any)."); - console_list.KillAll(); Log.Out(Logs::General, Logs::World_Server, "Shutting down zone connections (if any)."); zoneserver_list.KillAll(); Log.Out(Logs::General, Logs::World_Server, "Zone (TCP) listener stopped."); - tcps.Close(); + //tcps.Close(); Log.Out(Logs::General, Logs::World_Server, "Signaling HTTP service to stop..."); http_server.Stop(); Log.CloseFileLogs(); diff --git a/world/queryserv.cpp b/world/queryserv.cpp index 9a5c3e268..552b45659 100644 --- a/world/queryserv.cpp +++ b/world/queryserv.cpp @@ -15,122 +15,41 @@ extern ZSList zoneserver_list; QueryServConnection::QueryServConnection() { - Stream = 0; - authenticated = false; } -void QueryServConnection::SetConnection(EmuTCPConnection *inStream) +void QueryServConnection::AddConnection(std::shared_ptr connection) { - if(Stream) - { - Log.Out(Logs::Detail, Logs::QS_Server, "Incoming QueryServ Connection while we were already connected to a QueryServ."); - Stream->Disconnect(); - } - - Stream = inStream; - - authenticated = false; + //Set handlers + connection->OnMessage(ServerOP_QueryServGeneric, std::bind(&QueryServConnection::HandleGenericMessage, this, std::placeholders::_1, std::placeholders::_2)); + connection->OnMessage(ServerOP_LFGuildUpdate, std::bind(&QueryServConnection::HandleLFGuildUpdateMessage, this, std::placeholders::_1, std::placeholders::_2)); + m_streams.insert(std::make_pair(connection->GetUUID(), connection)); } -bool QueryServConnection::Process() +void QueryServConnection::RemoveConnection(std::shared_ptr connection) { - if (!Stream || !Stream->Connected()) - return false; - - ServerPacket *pack = 0; - - while((pack = Stream->PopPacket())) - { - if (!authenticated) - { - if (WorldConfig::get()->SharedKey.length() > 0) - { - if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) - { - uint8 tmppass[16]; - - MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass); - - if (memcmp(pack->pBuffer, tmppass, 16) == 0) - authenticated = true; - else - { - struct in_addr in; - in.s_addr = GetIP(); - Log.Out(Logs::Detail, Logs::QS_Server, "QueryServ authorization failed."); - auto pack = new ServerPacket(ServerOP_ZAAuthFailed); - SendPacket(pack); - delete pack; - Disconnect(); - return false; - } - } - else - { - struct in_addr in; - in.s_addr = GetIP(); - Log.Out(Logs::General, Logs::QS_Server, "QueryServ authorization failed."); - auto pack = new ServerPacket(ServerOP_ZAAuthFailed); - SendPacket(pack); - delete pack; - Disconnect(); - return false; - } - } - else - { - Log.Out(Logs::Detail, Logs::QS_Server,"**WARNING** You have not configured a world shared key in your config file. You should add a STRING element to your element to prevent unauthroized zone access."); - authenticated = true; - } - - delete pack; - continue; - } - switch(pack->opcode) - { - case 0: - break; - - case ServerOP_KeepAlive: - { - // ignore this - break; - } - case ServerOP_ZAAuth: - { - Log.Out(Logs::Detail, Logs::QS_Server, "Got authentication from QueryServ when they are already authenticated."); - break; - } - case ServerOP_QueryServGeneric: - { - uint32 ZoneID = pack->ReadUInt32(); - uint16 InstanceID = pack->ReadUInt32(); - zoneserver_list.SendPacket(ZoneID, InstanceID, pack); - break; - } - case ServerOP_LFGuildUpdate: - { - zoneserver_list.SendPacket(pack); - break; - } - default: - { - Log.Out(Logs::Detail, Logs::QS_Server, "Unknown ServerOPcode from QueryServ 0x%04x, size %d", pack->opcode, pack->size); - DumpPacket(pack->pBuffer, pack->size); - break; - } - } - - delete pack; + auto iter = m_streams.find(connection->GetUUID()); + if (iter != m_streams.end()) { + m_streams.erase(iter); } - return(true); +} + +void QueryServConnection::HandleGenericMessage(uint16_t opcode, EQ::Net::Packet &p) { + uint32 ZoneID = p.GetUInt32(0); + uint16 InstanceID = p.GetUInt32(4); + ServerPacket pack(opcode, p); + zoneserver_list.SendPacket(ZoneID, InstanceID, &pack); +} + +void QueryServConnection::HandleLFGuildUpdateMessage(uint16_t opcode, EQ::Net::Packet &p) { + ServerPacket pack(opcode, p); + zoneserver_list.SendPacket(&pack); } bool QueryServConnection::SendPacket(ServerPacket* pack) { - if(!Stream) - return false; + for (auto &stream : m_streams) { + stream.second->SendPacket(pack); + } - return Stream->SendPacket(pack); + return true; } - diff --git a/world/queryserv.h b/world/queryserv.h index 5053d7c99..f19520b7d 100644 --- a/world/queryserv.h +++ b/world/queryserv.h @@ -2,22 +2,20 @@ #define QueryServ_H #include "../common/types.h" -#include "../common/emu_tcp_connection.h" +#include "../common/net/servertalk_server.h" #include "../common/servertalk.h" class QueryServConnection { public: QueryServConnection(); - void SetConnection(EmuTCPConnection *inStream); - bool Process(); + void AddConnection(std::shared_ptr connection); + void RemoveConnection(std::shared_ptr connection); + void HandleGenericMessage(uint16_t opcode, EQ::Net::Packet &p); + void HandleLFGuildUpdateMessage(uint16_t opcode, EQ::Net::Packet &p); bool SendPacket(ServerPacket* pack); - void Disconnect() { if(Stream) Stream->Disconnect(); } - void SendMessage(const char *From, const char *Message); private: - inline uint32 GetIP() const { return Stream ? Stream->GetrIP() : 0; } - EmuTCPConnection *Stream; - bool authenticated; + std::map> m_streams; }; #endif /*QueryServ_H_*/ diff --git a/world/zonelist.cpp b/world/zonelist.cpp index 55600c367..cb2dff73f 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -26,9 +26,8 @@ #include "../common/string_util.h" #include "../common/random.h" -extern uint32 numzones; +extern uint32 numzones; extern bool holdzones; -extern ConsoleList console_list; extern EQEmu::Random emu_random; void CatchSignal(int sig_num); @@ -61,17 +60,27 @@ void ZSList::ShowUpTime(WorldTCPConnection* con, const char* adminname) { } void ZSList::Add(ZoneServer* zoneserver) { - list.Insert(zoneserver); - zoneserver->SendGroupIDs(); //send its initial set of group ids + list.push_back(std::unique_ptr(zoneserver)); + zoneserver->SendGroupIDs(); +} + +void ZSList::Remove(const std::string &uuid) +{ + auto iter = list.begin(); + while (iter != list.end()) { + if ((*iter)->GetUUID().compare(uuid) == 0) { + list.erase(iter); + return; + } + iter++; + } } void ZSList::KillAll() { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) { - iterator.GetData()->Disconnect(); - iterator.RemoveCurrent(); + auto iterator = list.begin(); + while(iterator != list.end()) { + (*iterator)->Disconnect(); + iterator = list.erase(iterator); numzones--; } } @@ -88,159 +97,120 @@ void ZSList::Process() { Process(); CatchSignal(2); } + if(reminder && reminder->Check() && shutdowntimer){ SendEmoteMessage(0,0,0,15,":SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i minutes...", ((shutdowntimer->GetRemainingTime()/1000) / 60)); } - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) { - if (!iterator.GetData()->Process()) { - ZoneServer* zs = iterator.GetData(); - struct in_addr in; - in.s_addr = zs->GetIP(); - Log.Out(Logs::Detail, Logs::World_Server,"Removing zoneserver #%d at %s:%d",zs->GetID(),zs->GetCAddress(),zs->GetCPort()); - zs->LSShutDownUpdate(zs->GetZoneID()); - if (holdzones){ - Log.Out(Logs::Detail, Logs::World_Server,"Hold Zones mode is ON - rebooting lost zone"); - if(!zs->IsStaticZone()) - RebootZone(inet_ntoa(in),zs->GetCPort(),zs->GetCAddress(),zs->GetID()); - else - RebootZone(inet_ntoa(in),zs->GetCPort(),zs->GetCAddress(),zs->GetID(),database.GetZoneID(zs->GetZoneName())); - } - - iterator.RemoveCurrent(); - numzones--; - } - else { - iterator.Advance(); - } - } } bool ZSList::SendPacket(ServerPacket* pack) { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) { - iterator.GetData()->SendPacket(pack); - iterator.Advance(); + auto iterator = list.begin(); + while (iterator != list.end()) { + (*iterator)->SendPacket(pack); + iterator++; } return true; } bool ZSList::SendPacket(uint32 ZoneID, ServerPacket* pack) { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->GetZoneID() == ZoneID) { - ZoneServer* tmp = iterator.GetData(); - return(tmp->SendPacket(pack)); + auto iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetZoneID() == ZoneID) { + ZoneServer* tmp = (*iterator).get(); + tmp->SendPacket(pack); + return true; } - iterator.Advance(); + iterator++; } return(false); } bool ZSList::SendPacket(uint32 ZoneID, uint16 instanceID, ServerPacket* pack) { - LinkedListIterator iterator(list); - - iterator.Reset(); if(instanceID != 0) { - while(iterator.MoreElements()) { - if(iterator.GetData()->GetInstanceID() == instanceID) { - ZoneServer* tmp = iterator.GetData(); - return(tmp->SendPacket(pack)); + auto iterator = list.begin(); + while (iterator != list.end()) { + if((*iterator)->GetInstanceID() == instanceID) { + ZoneServer* tmp = (*iterator).get(); + tmp->SendPacket(pack); + return true; } - iterator.Advance(); + iterator++; } } else { - while(iterator.MoreElements()) { - if (iterator.GetData()->GetZoneID() == ZoneID - && iterator.GetData()->GetInstanceID() == 0) { - ZoneServer* tmp = iterator.GetData(); - return(tmp->SendPacket(pack)); + auto iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetZoneID() == ZoneID + && (*iterator)->GetInstanceID() == 0) { + ZoneServer* tmp = (*iterator).get(); + tmp->SendPacket(pack); + return true; } - iterator.Advance(); + iterator++; } } return(false); } ZoneServer* ZSList::FindByName(const char* zonename) { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) - { - if (strcasecmp(iterator.GetData()->GetZoneName(), zonename) == 0) { - ZoneServer* tmp = iterator.GetData(); + auto iterator = list.begin(); + while (iterator != list.end()) { + if (strcasecmp((*iterator)->GetZoneName(), zonename) == 0) { + ZoneServer* tmp = (*iterator).get(); return tmp; } - iterator.Advance(); + iterator++; } return 0; } ZoneServer* ZSList::FindByID(uint32 ZoneID) { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->GetID() == ZoneID) { - ZoneServer* tmp = iterator.GetData(); + auto iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetID() == ZoneID) { + ZoneServer* tmp = (*iterator).get(); return tmp; } - iterator.Advance(); + iterator++; } return 0; } ZoneServer* ZSList::FindByZoneID(uint32 ZoneID) { - LinkedListIterator iterator(list); - iterator.Reset(); - while(iterator.MoreElements()) - { - ZoneServer* tmp = iterator.GetData(); + auto iterator = list.begin(); + while (iterator != list.end()) { + ZoneServer* tmp = (*iterator).get(); if (tmp->GetZoneID() == ZoneID && tmp->GetInstanceID() == 0) { return tmp; } - iterator.Advance(); + iterator++; } return 0; } ZoneServer* ZSList::FindByPort(uint16 port) { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) - { - if (iterator.GetData()->GetCPort() == port) { - ZoneServer* tmp = iterator.GetData(); + auto iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetCPort() == port) { + ZoneServer* tmp = (*iterator).get(); return tmp; } - iterator.Advance(); + iterator++; } return 0; } ZoneServer* ZSList::FindByInstanceID(uint32 InstanceID) { - LinkedListIterator iterator(list); - - iterator.Reset(); - while(iterator.MoreElements()) - { - if (iterator.GetData()->GetInstanceID() == InstanceID) { - ZoneServer* tmp = iterator.GetData(); + auto iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetInstanceID() == InstanceID) { + ZoneServer* tmp = (*iterator).get(); return tmp; } - iterator.Advance(); + iterator++; } return 0; } @@ -283,11 +253,6 @@ void ZSList::ListLockedZones(const char* to, WorldTCPConnection* connection) { } void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* connection) { - - LinkedListIterator iterator(list); - struct in_addr in; - - iterator.Reset(); char locked[4]; if (WorldConfig::get()->Locked == true){ strcpy(locked, "Yes"); @@ -318,9 +283,10 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con ZoneServer* zone_server_data = 0; - while (iterator.MoreElements()) { - zone_server_data = iterator.GetData(); - in.s_addr = zone_server_data->GetIP(); + auto iterator = list.begin(); + while (iterator != list.end()) { + zone_server_data = (*iterator).get(); + auto addr = zone_server_data->GetIP(); if (zone_server_data->IsStaticZone()){ z++; @@ -352,7 +318,7 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con "#%-3i :: %s :: %15s:%-5i :: %2i :: %s:%i :: %s :: (%u)", zone_server_data->GetID(), is_static_string, - inet_ntoa(in), + addr.c_str(), zone_server_data->GetPort(), zone_server_data->NumPlayers(), zone_server_data->GetCAddress(), @@ -398,7 +364,7 @@ void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* con x++; } y++; - iterator.Advance(); + iterator++; } if (connection->IsConsole()){ @@ -462,9 +428,7 @@ void ZSList::SendChannelMessageRaw(const char* from, const char* to, uint8 chan_ scm->language = language; scm->chan_num = chan_num; strcpy(&scm->message[0], message); - if (scm->chan_num == 5 || scm->chan_num == 6 || scm->chan_num == 11) { - console_list.SendChannelMessage(scm); - } + pack->Deflate(); SendPacket(pack); delete pack; @@ -496,13 +460,6 @@ void ZSList::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_m ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; if (to) { - if (to[0] == '*') { - Console* con = console_list.FindByAccountName(&to[1]); - if (con) - con->SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, message); - delete pack; - return; - } strcpy((char *) sem->to, to); } else { @@ -519,8 +476,6 @@ void ZSList::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_m pack->Deflate(); if (tempto[0] == 0) { SendPacket(pack); - if (to_guilddbid == 0) - console_list.SendEmoteMessageRaw(type, message); } else { ZoneServer* zs = FindByName(to); @@ -578,24 +533,24 @@ void ZSList::SOPZoneBootup(const char* adminname, uint32 ZoneServerID, const cha } void ZSList::RebootZone(const char* ip1,uint16 port,const char* ip2, uint32 skipid, uint32 zoneid){ -// get random zone - LinkedListIterator iterator(list); + // get random zone uint32 x = 0; - iterator.Reset(); - while(iterator.MoreElements()) { + auto iterator = list.begin(); + while (iterator != list.end()) { x++; - iterator.Advance(); + iterator++; } if (x == 0) return; auto tmp = new ZoneServer *[x]; uint32 y = 0; - iterator.Reset(); - while(iterator.MoreElements()) { - if (!strcmp(iterator.GetData()->GetCAddress(),ip2) && !iterator.GetData()->IsBootingUp() && iterator.GetData()->GetID() != skipid) { - tmp[y++] = iterator.GetData(); + + iterator = list.begin(); + while (iterator != list.end()) { + if (!strcmp((*iterator)->GetCAddress(),ip2) && !(*iterator)->IsBootingUp() && (*iterator)->GetID() != skipid) { + tmp[y++] = (*iterator).get(); } - iterator.Advance(); + iterator++; } if (y == 0) { safe_delete_array(tmp); @@ -645,95 +600,56 @@ uint16 ZSList::GetAvailableZonePort() uint32 ZSList::TriggerBootup(uint32 iZoneID, uint32 iInstanceID) { if(iInstanceID > 0) { - LinkedListIterator iterator(list); - iterator.Reset(); - while(iterator.MoreElements()) { - if(iterator.GetData()->GetInstanceID() == iInstanceID) + auto iterator = list.begin(); + while (iterator != list.end()) { + if((*iterator)->GetInstanceID() == iInstanceID) { - return iterator.GetData()->GetID(); + return (*iterator)->GetID(); } - iterator.Advance(); + iterator++; } - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->GetZoneID() == 0 && !iterator.GetData()->IsBootingUp()) { - ZoneServer* zone=iterator.GetData(); + iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetZoneID() == 0 && !(*iterator)->IsBootingUp()) { + ZoneServer* zone=(*iterator).get(); zone->TriggerBootup(iZoneID, iInstanceID); return zone->GetID(); } - iterator.Advance(); + iterator++; } return 0; } else { - LinkedListIterator iterator(list); - iterator.Reset(); - while(iterator.MoreElements()) { - if(iterator.GetData()->GetZoneID() == iZoneID && iterator.GetData()->GetInstanceID() == 0) + auto iterator = list.begin(); + while (iterator != list.end()) { + if((*iterator)->GetZoneID() == iZoneID && (*iterator)->GetInstanceID() == 0) { - return iterator.GetData()->GetID(); + return (*iterator)->GetID(); } - iterator.Advance(); + iterator++; } - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->GetZoneID() == 0 && !iterator.GetData()->IsBootingUp()) { - ZoneServer* zone=iterator.GetData(); + iterator = list.begin(); + while (iterator != list.end()) { + if ((*iterator)->GetZoneID() == 0 && !(*iterator)->IsBootingUp()) { + ZoneServer* zone = (*iterator).get(); zone->TriggerBootup(iZoneID); return zone->GetID(); } - iterator.Advance(); + iterator++; } return 0; } - /*Old Random boot zones use this if your server is distributed across computers. - LinkedListIterator iterator(list); - - srand(time(nullptr)); - uint32 x = 0; - iterator.Reset(); - while(iterator.MoreElements()) { - x++; - iterator.Advance(); - } - if (x == 0) { - return 0; - } - - ZoneServer** tmp = new ZoneServer*[x]; - uint32 y = 0; - - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->GetZoneID() == 0 && !iterator.GetData()->IsBootingUp()) { - tmp[y++] = iterator.GetData(); - } - iterator.Advance(); - } - if (y == 0) { - safe_delete(tmp); - return 0; - } - - uint32 z = rand() % y; - - tmp[z]->TriggerBootup(iZoneID); - uint32 ret = tmp[z]->GetID(); - safe_delete(tmp); - return ret; - */ } void ZSList::SendLSZones(){ - LinkedListIterator iterator(list); - iterator.Reset(); - while(iterator.MoreElements()) { - ZoneServer* zs = iterator.GetData(); + auto iterator = list.begin(); + while(iterator != list.end()) { + ZoneServer* zs = (*iterator).get(); zs->LSBootUpdate(zs->GetZoneID(),true); - iterator.Advance(); + iterator++; } } @@ -742,12 +658,11 @@ int ZSList::GetZoneCount() { } void ZSList::GetZoneIDList(std::vector &zones) { - LinkedListIterator iterator(list); - iterator.Reset(); - while(iterator.MoreElements()) { - ZoneServer* zs = iterator.GetData(); + auto iterator = list.begin(); + while (iterator != list.end()) { + ZoneServer* zs = (*iterator).get(); zones.push_back(zs->GetID()); - iterator.Advance(); + iterator++; } } diff --git a/world/zonelist.h b/world/zonelist.h index 19160f790..45974cdad 100644 --- a/world/zonelist.h +++ b/world/zonelist.h @@ -6,6 +6,7 @@ #include "../common/timer.h" #include "../common/linked_list.h" #include +#include class WorldTCPConnection; class ServerPacket; @@ -35,6 +36,7 @@ public: void SendTimeSync(); void Add(ZoneServer* zoneserver); + void Remove(const std::string &uuid); void Process(); void KillAll(); bool SendPacket(ServerPacket* pack); @@ -60,7 +62,7 @@ public: protected: uint32 NextID; - LinkedList list; + std::list> list; uint16 pLockedZones[MaxLockedZones]; uint32 CurGroupID; uint16 LastAllocatedPort; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 9a9572f97..aabb20cdd 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -40,7 +40,6 @@ extern ClientList client_list; extern GroupLFPList LFPGroupList; extern ZSList zoneserver_list; -extern ConsoleList console_list; extern LoginServerList loginserverlist; extern volatile bool RunLoops; extern AdventureManager adventure_manager; @@ -48,11 +47,10 @@ extern UCSConnection UCSLink; extern QueryServConnection QSLink; void CatchSignal(int sig_num); -ZoneServer::ZoneServer(EmuTCPConnection* itcpc) -: WorldTCPConnection(), tcpc(itcpc), zone_boot_timer(5000) { +ZoneServer::ZoneServer(std::shared_ptr connection) +: tcpc(connection), zone_boot_timer(5000) { /* Set Process tracking variable defaults */ - memset(zone_name, 0, sizeof(zone_name)); memset(compiled, 0, sizeof(compiled)); memset(client_address, 0, sizeof(client_address)); @@ -67,12 +65,20 @@ ZoneServer::ZoneServer(EmuTCPConnection* itcpc) is_authenticated = false; is_static_zone = false; zone_player_count = 0; + + tcpc->OnAnyMessage(std::bind(&ZoneServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); + + boot_timer_obj.reset(new EQ::Timer(1000, true, [this](EQ::Timer *obj) { + if (zone_boot_timer.Check()) { + LSBootUpdate(GetZoneID(), true); + zone_boot_timer.Disable(); + } + })); } ZoneServer::~ZoneServer() { if (RunLoops) client_list.CLERemoveZSRef(this); - tcpc->Free(); } bool ZoneServer::SetZone(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { @@ -173,1199 +179,1119 @@ void ZoneServer::LSSleepUpdate(uint32 zoneid){ } } -bool ZoneServer::Process() { - if (!tcpc->Connected()) - return false; - if(zone_boot_timer.Check()){ - LSBootUpdate(GetZoneID(), true); - zone_boot_timer.Disable(); - } - ServerPacket *pack = 0; - while((pack = tcpc->PopPacket())) { - if (!is_authenticated) { - if (WorldConfig::get()->SharedKey.length() > 0) { - if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) { - uint8 tmppass[16]; - MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass); - if (memcmp(pack->pBuffer, tmppass, 16) == 0) { - is_authenticated = true; - Log.Out(Logs::Detail, Logs::World_Server, "Zone process connected."); +void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { + ServerPacket tpack(opcode, p); + ServerPacket *pack = &tpack; + + switch(opcode) { + case 0: + break; + case ServerOP_KeepAlive: { + // ignore this + break; + } + case ServerOP_ZAAuth: { + break; + } + case ServerOP_LSZoneBoot:{ + if(pack->size==sizeof(ZoneBoot_Struct)){ + ZoneBoot_Struct* zbs= (ZoneBoot_Struct*)pack->pBuffer; + SetCompile(zbs->compile_time); + } + break; + } + case ServerOP_GroupInvite: { + if(pack->size != sizeof(GroupInvite_Struct)) + break; + + GroupInvite_Struct* gis = (GroupInvite_Struct*) pack->pBuffer; + + client_list.SendPacket(gis->invitee_name, pack); + break; + } + case ServerOP_GroupFollow: { + if(pack->size != sizeof(ServerGroupFollow_Struct)) + break; + + ServerGroupFollow_Struct *sgfs = (ServerGroupFollow_Struct *) pack->pBuffer; + + client_list.SendPacket(sgfs->gf.name1, pack); + break; + } + case ServerOP_GroupFollowAck: { + if(pack->size != sizeof(ServerGroupFollowAck_Struct)) + break; + + ServerGroupFollowAck_Struct *sgfas = (ServerGroupFollowAck_Struct *) pack->pBuffer; + + client_list.SendPacket(sgfas->Name, pack); + break; + } + case ServerOP_GroupCancelInvite: { + if(pack->size != sizeof(GroupCancel_Struct)) + break; + + GroupCancel_Struct *gcs = (GroupCancel_Struct *) pack->pBuffer; + + client_list.SendPacket(gcs->name1, pack); + break; + } + case ServerOP_GroupIDReq: { + SendGroupIDs(); + break; + } + case ServerOP_GroupLeave: { + if(pack->size != sizeof(ServerGroupLeave_Struct)) + break; + zoneserver_list.SendPacket(pack); //bounce it to all zones + break; + } + + case ServerOP_GroupJoin: { + if(pack->size != sizeof(ServerGroupJoin_Struct)) + break; + zoneserver_list.SendPacket(pack); //bounce it to all zones + break; + } + + case ServerOP_ForceGroupUpdate: { + if(pack->size != sizeof(ServerForceGroupUpdate_Struct)) + break; + zoneserver_list.SendPacket(pack); //bounce it to all zones + break; + } + + case ServerOP_OOZGroupMessage: { + zoneserver_list.SendPacket(pack); //bounce it to all zones + break; + } + + case ServerOP_DisbandGroup: { + if(pack->size != sizeof(ServerDisbandGroup_Struct)) + break; + zoneserver_list.SendPacket(pack); //bounce it to all zones + break; + } + + case ServerOP_RaidAdd:{ + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidRemove: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidDisband: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidLockFlag: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidChangeGroup: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_UpdateGroup: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidGroupDisband: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidGroupAdd: { + if(pack->size != sizeof(ServerRaidGroupAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidGroupRemove: { + if(pack->size != sizeof(ServerRaidGroupAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidGroupSay: { + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidSay: { + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidGroupLeader: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidLeader: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_DetailsChange: { + if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RaidMOTD: { + if (pack->size < sizeof(ServerRaidMOTD_Struct)) + break; + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_SpawnCondition: { + if(pack->size != sizeof(ServerSpawnCondition_Struct)) + break; + //bounce the packet to the correct zone server, if its up + ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*)pack->pBuffer; + zoneserver_list.SendPacket(ssc->zoneID, ssc->instanceID, pack); + break; + } + case ServerOP_SpawnEvent: { + if(pack->size != sizeof(ServerSpawnEvent_Struct)) + break; + //bounce the packet to the correct zone server, if its up + ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*)pack->pBuffer; + zoneserver_list.SendPacket(sse->zoneID, 0, pack); + break; + } + case ServerOP_ChannelMessage: { + if (pack->size < sizeof(ServerChannelMessage_Struct)) + break; + ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer; + if(scm->chan_num == 20) + { + UCSLink.SendMessage(scm->from, scm->message); + break; + } + if (scm->chan_num == 7 || scm->chan_num == 14) { + ClientListEntry* cle = client_list.FindCharacter(scm->deliverto); + if (cle == 0 || cle->Online() < CLE_Status_Zoning || + (cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) { + if (!scm->noreply) { + ClientListEntry* sender = client_list.FindCharacter(scm->from); + if (!sender || !sender->Server()) + break; + scm->noreply = true; + scm->queued = 3; // offline + strcpy(scm->deliverto, scm->from); + // ideally this would be trimming off the message too, oh well + sender->Server()->SendPacket(pack); } - else { - struct in_addr in; - in.s_addr = GetIP(); - Log.Out(Logs::General, Logs::Error, "Zone authorization failed."); - auto pack = new ServerPacket(ServerOP_ZAAuthFailed); - SendPacket(pack); - safe_delete(pack); - Disconnect(); - return false; + } else if (cle->Online() == CLE_Status_Zoning) { + if (!scm->noreply) { + ClientListEntry* sender = client_list.FindCharacter(scm->from); + if (cle->TellQueueFull()) { + if (!sender || !sender->Server()) + break; + scm->noreply = true; + scm->queued = 2; // queue full + strcpy(scm->deliverto, scm->from); + sender->Server()->SendPacket(pack); + } else { + size_t struct_size = sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1; + ServerChannelMessage_Struct *temp = (ServerChannelMessage_Struct *) new uchar[struct_size]; + memset(temp, 0, struct_size); // just in case, was seeing some corrupt messages, but it shouldn't happen + memcpy(temp, scm, struct_size); + temp->noreply = true; + cle->PushToTellQueue(temp); // deallocation is handled in processing or deconstructor + + if (!sender || !sender->Server()) + break; + scm->noreply = true; + scm->queued = 1; // queued + strcpy(scm->deliverto, scm->from); + sender->Server()->SendPacket(pack); + } } } - else { - struct in_addr in; - in.s_addr = GetIP(); - Log.Out(Logs::General, Logs::Error, "Zone authorization failed."); - auto pack = new ServerPacket(ServerOP_ZAAuthFailed); + else if (cle->Server() == 0) { + if (!scm->noreply) + zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not contactable at this time'", scm->to, scm->to); + } + else + cle->Server()->SendPacket(pack); + } + else { + zoneserver_list.SendPacket(pack); + } + break; + } + case ServerOP_EmoteMessage: { + ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; + zoneserver_list.SendEmoteMessageRaw(sem->to, sem->guilddbid, sem->minstatus, sem->type, sem->message); + break; + } + case ServerOP_VoiceMacro: { + + ServerVoiceMacro_Struct* svm = (ServerVoiceMacro_Struct*) pack->pBuffer; + + if(svm->Type == VoiceMacroTell) { + + ClientListEntry* cle = client_list.FindCharacter(svm->To); + + if (!cle || (cle->Online() < CLE_Status_Zoning) || !cle->Server()) { + + zoneserver_list.SendEmoteMessage(svm->From, 0, 0, 0, "'%s is not online at this time'", svm->To); + + break; + } + + cle->Server()->SendPacket(pack); + } + else + zoneserver_list.SendPacket(pack); + + break; + } + + case ServerOP_RezzPlayerAccept: { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_RezzPlayer: { + + RezzPlayer_Struct* sRezz = (RezzPlayer_Struct*) pack->pBuffer; + if (zoneserver_list.SendPacket(pack)){ + Log.Out(Logs::Detail, Logs::World_Server,"Sent Rez packet for %s",sRezz->rez.your_name); + } + else { + Log.Out(Logs::Detail, Logs::World_Server,"Could not send Rez packet for %s",sRezz->rez.your_name); + } + break; + } + case ServerOP_RezzPlayerReject: + { + char *Recipient = (char *)pack->pBuffer; + client_list.SendPacket(Recipient, pack); + break; + } + + case ServerOP_MultiLineMsg: { + ServerMultiLineMsg_Struct* mlm = (ServerMultiLineMsg_Struct*) pack->pBuffer; + client_list.SendPacket(mlm->to, pack); + break; + } + case ServerOP_SetZone: { + if(pack->size != sizeof(SetZone_Struct)) + break; + + SetZone_Struct* szs = (SetZone_Struct*) pack->pBuffer; + if (szs->zoneid != 0) { + if(database.GetZoneName(szs->zoneid)) + SetZone(szs->zoneid, szs->instanceid, szs->staticzone); + else + SetZone(0); + } + else + SetZone(0); + + break; + } + case ServerOP_SetConnectInfo: { + if (pack->size != sizeof(ServerConnectInfo)) + break; + ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer; + + if (!sci->port) { + client_port = zoneserver_list.GetAvailableZonePort(); + + ServerPacket p(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo)); + memset(p.pBuffer,0,sizeof(ServerConnectInfo)); + ServerConnectInfo* sci = (ServerConnectInfo*) p.pBuffer; + sci->port = client_port; + SendPacket(&p); + Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",client_port); + } else { + client_port = sci->port; + Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d.",client_port); + } + + if(sci->address[0]) { + strn0cpy(client_address, sci->address, 250); + Log.Out(Logs::Detail, Logs::World_Server, "Zone specified address %s.", sci->address); + } + + if(sci->local_address[0]) { + strn0cpy(client_local_address, sci->local_address, 250); + Log.Out(Logs::Detail, Logs::World_Server, "Zone specified local address %s.", sci->address); + } + + if (sci->process_id){ + zone_os_process_id = sci->process_id; + } + + } + case ServerOP_SetLaunchName: { + if(pack->size != sizeof(LaunchName_Struct)) + break; + const LaunchName_Struct* ln = (const LaunchName_Struct*)pack->pBuffer; + launcher_name = ln->launcher_name; + launched_name = ln->zone_name; + Log.Out(Logs::Detail, Logs::World_Server, "Zone started with name %s by launcher %s", launched_name.c_str(), launcher_name.c_str()); + break; + } + case ServerOP_ShutdownAll: { + if(pack->size==0){ + zoneserver_list.SendPacket(pack); + zoneserver_list.Process(); + CatchSignal(2); + } + else{ + WorldShutDown_Struct* wsd=(WorldShutDown_Struct*)pack->pBuffer; + if(wsd->time==0 && wsd->interval==0 && zoneserver_list.shutdowntimer->Enabled()){ + zoneserver_list.shutdowntimer->Disable(); + zoneserver_list.reminder->Disable(); + } + else{ + zoneserver_list.shutdowntimer->SetTimer(wsd->time); + zoneserver_list.reminder->SetTimer(wsd->interval-1000); + zoneserver_list.reminder->SetAtTrigger(wsd->interval); + zoneserver_list.shutdowntimer->Start(); + zoneserver_list.reminder->Start(); + } + } + break; + } + case ServerOP_ZoneShutdown: { + ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer; + ZoneServer* zs = 0; + if (s->ZoneServerID != 0) + zs = zoneserver_list.FindByID(s->ZoneServerID); + else if (s->zoneid != 0) + zs = zoneserver_list.FindByName(database.GetZoneName(s->zoneid)); + else + zoneserver_list.SendEmoteMessage(s->adminname, 0, 0, 0, "Error: SOP_ZoneShutdown: neither ID nor name specified"); + + if (zs == 0) + zoneserver_list.SendEmoteMessage(s->adminname, 0, 0, 0, "Error: SOP_ZoneShutdown: zoneserver not found"); + else + zs->SendPacket(pack); + break; + } + case ServerOP_ZoneBootup: { + ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer; + zoneserver_list.SOPZoneBootup(s->adminname, s->ZoneServerID, database.GetZoneName(s->zoneid), s->makestatic); + break; + } + case ServerOP_ZoneStatus: { + if (pack->size >= 1) + zoneserver_list.SendZoneStatus((char *) &pack->pBuffer[1], (uint8) pack->pBuffer[0], this); + break; + + } + case ServerOP_AcceptWorldEntrance: { + if(pack->size != sizeof(WorldToZone_Struct)) + break; + + WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer; + Client* client = 0; + client = client_list.FindByAccountID(wtz->account_id); + if(client != 0) + client->Clearance(wtz->response); + } + case ServerOP_ZoneToZoneRequest: { + // + // ZoneChange is received by the zone the player is in, then the + // zone sends a ZTZ which ends up here. This code then find the target + // (ingress point) and boots it if needed, then sends the ZTZ to it. + // The ingress server will decide wether the player can enter, then will + // send back the ZTZ to here. This packet is passed back to the egress + // server, which will send a ZoneChange response back to the client + // which can be an error, or a success, in which case the client will + // disconnect, and their zone location will be saved when ~Client is + // called, so it will be available when they ask to zone. + // + + + if(pack->size != sizeof(ZoneToZone_Struct)) + break; + ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; + ClientListEntry* client = nullptr; + if(WorldConfig::get()->UpdateStats) + client = client_list.FindCharacter(ztz->name); + + Log.Out(Logs::Detail, Logs::World_Server,"ZoneToZone request for %s current zone %d req zone %d\n", + ztz->name, ztz->current_zone_id, ztz->requested_zone_id); + + /* This is a request from the egress zone */ + if(GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) { + Log.Out(Logs::Detail, Logs::World_Server,"Processing ZTZ for egress from zone for client %s\n", ztz->name); + + if (ztz->admin < 80 && ztz->ignorerestrictions < 2 && zoneserver_list.IsZoneLocked(ztz->requested_zone_id)) { + ztz->response = 0; SendPacket(pack); - safe_delete(pack); - Disconnect(); - return false; + break; + } + + ZoneServer *ingress_server = nullptr; + if(ztz->requested_instance_id > 0) { + ingress_server = zoneserver_list.FindByInstanceID(ztz->requested_instance_id); + } + else { + ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id); + } + + /* Zone was already running*/ + if(ingress_server) { + Log.Out(Logs::Detail, Logs::World_Server,"Found a zone already booted for %s\n", ztz->name); + ztz->response = 1; + } + /* Boot the Zone*/ + else { + int server_id; + if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id, ztz->requested_instance_id))){ + Log.Out(Logs::Detail, Logs::World_Server,"Successfully booted a zone for %s\n", ztz->name); + // bootup successful, ready to rock + ztz->response = 1; + ingress_server = zoneserver_list.FindByID(server_id); + } + else { + Log.Out(Logs::Detail, Logs::World_Server,"FAILED to boot a zone for %s\n", ztz->name); + // bootup failed, send back error code 0 + ztz->response = 0; + } + } + if(ztz->response!=0 && client) + client->LSZoneChange(ztz); + SendPacket(pack); // send back to egress server + if(ingress_server) { + ingress_server->SendPacket(pack); // inform target server + } + } + /* Response from Ingress server, route back to egress */ + else{ + + Log.Out(Logs::Detail, Logs::World_Server,"Processing ZTZ for ingress to zone for client %s\n", ztz->name); + ZoneServer *egress_server = nullptr; + if(ztz->current_instance_id > 0) { + egress_server = zoneserver_list.FindByInstanceID(ztz->current_instance_id); + } + else { + egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id); + } + + if(egress_server) { + egress_server->SendPacket(pack); + } + } + + break; + } + case ServerOP_ClientList: { + if (pack->size != sizeof(ServerClientList_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_ClientList. Got: %d, Expected: %d",pack->size,sizeof(ServerClientList_Struct)); + break; + } + client_list.ClientUpdate(this, (ServerClientList_Struct*) pack->pBuffer); + break; + } + case ServerOP_ClientListKA: { + ServerClientListKeepAlive_Struct* sclka = (ServerClientListKeepAlive_Struct*) pack->pBuffer; + if (pack->size < 4 || pack->size != 4 + (4 * sclka->numupdates)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_ClientListKA. Got: %d, Expected: %d",pack->size, (4 + (4 * sclka->numupdates))); + break; + } + client_list.CLEKeepAlive(sclka->numupdates, sclka->wid); + break; + } + case ServerOP_Who: { + ServerWhoAll_Struct* whoall = (ServerWhoAll_Struct*) pack->pBuffer; + auto whom = new Who_All_Struct; + memset(whom,0,sizeof(Who_All_Struct)); + whom->gmlookup = whoall->gmlookup; + whom->lvllow = whoall->lvllow; + whom->lvlhigh = whoall->lvlhigh; + whom->wclass = whoall->wclass; + whom->wrace = whoall->wrace; + strcpy(whom->whom,whoall->whom); + client_list.SendWhoAll(whoall->fromid,whoall->from, whoall->admin, whom, this); + safe_delete(whom); + break; + } + case ServerOP_RequestOnlineGuildMembers: { + ServerRequestOnlineGuildMembers_Struct *srogms = (ServerRequestOnlineGuildMembers_Struct*) pack->pBuffer; + client_list.SendOnlineGuildMembers(srogms->FromID, srogms->GuildID); + break; + } + case ServerOP_ClientVersionSummary: { + ServerRequestClientVersionSummary_Struct *srcvss = (ServerRequestClientVersionSummary_Struct*) pack->pBuffer; + client_list.SendClientVersionSummary(srcvss->Name); + break; + } + case ServerOP_ReloadLogs: { + zoneserver_list.SendPacket(pack); + database.LoadLogSettings(Log.log_settings); + break; + } + case ServerOP_ReloadRules: { + zoneserver_list.SendPacket(pack); + RuleManager::Instance()->LoadRules(&database, "default"); + break; + } + case ServerOP_ReloadRulesWorld: + { + RuleManager::Instance()->LoadRules(&database, "default"); + break; + } + case ServerOP_ReloadPerlExportSettings: + { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_CameraShake: + { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_FriendsWho: { + ServerFriendsWho_Struct* FriendsWho = (ServerFriendsWho_Struct*) pack->pBuffer; + client_list.SendFriendsWho(FriendsWho, this); + break; + } + case ServerOP_LFGMatches: { + ServerLFGMatchesRequest_Struct* smrs = (ServerLFGMatchesRequest_Struct*) pack->pBuffer; + client_list.SendLFGMatches(smrs); + break; + } + case ServerOP_LFPMatches: { + ServerLFPMatchesRequest_Struct* smrs = (ServerLFPMatchesRequest_Struct*) pack->pBuffer; + LFPGroupList.SendLFPMatches(smrs); + break; + } + case ServerOP_LFPUpdate: { + ServerLFPUpdate_Struct* sus = (ServerLFPUpdate_Struct*) pack->pBuffer; + if(sus->Action) + LFPGroupList.UpdateGroup(sus); + else + LFPGroupList.RemoveGroup(sus); + break; + } + case ServerOP_ZonePlayer: { + //ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) pack->pBuffer; + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_KickPlayer: { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_KillPlayer: { + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_GuildRankUpdate: + { + zoneserver_list.SendPacket(pack); + break; + } + //these opcodes get processed by the guild manager. + case ServerOP_RefreshGuild: + case ServerOP_DeleteGuild: + case ServerOP_GuildCharRefresh: + case ServerOP_GuildMemberUpdate: { + guild_mgr.ProcessZonePacket(pack); + break; + } + + case ServerOP_FlagUpdate: { + ClientListEntry* cle = client_list.FindCLEByAccountID(*((uint32*) pack->pBuffer)); + if (cle) + cle->SetAdmin(*((int16*) &pack->pBuffer[4])); + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_GMGoto: { + if (pack->size != sizeof(ServerGMGoto_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_GMGoto. Got: %d, Expected: %d",pack->size,sizeof(ServerGMGoto_Struct)); + break; + } + ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer; + ClientListEntry* cle = client_list.FindCharacter(gmg->gotoname); + if (cle != 0) { + if (cle->Server() == 0) + this->SendEmoteMessage(gmg->myname, 0, 0, 13, "Error: Cannot identify %s's zoneserver.", gmg->gotoname); + else if (cle->Anon() == 1 && cle->Admin() > gmg->admin) // no snooping for anon GMs + this->SendEmoteMessage(gmg->myname, 0, 0, 13, "Error: %s not found", gmg->gotoname); + else + cle->Server()->SendPacket(pack); + } + else { + this->SendEmoteMessage(gmg->myname, 0, 0, 13, "Error: %s not found", gmg->gotoname); + } + break; + } + case ServerOP_Lock: { + if (pack->size != sizeof(ServerLock_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_Lock. Got: %d, Expected: %d",pack->size,sizeof(ServerLock_Struct)); + break; + } + ServerLock_Struct* slock = (ServerLock_Struct*) pack->pBuffer; + if (slock->mode >= 1) + WorldConfig::LockWorld(); + else + WorldConfig::UnlockWorld(); + if (loginserverlist.Connected()) { + loginserverlist.SendStatus(); + if (slock->mode >= 1) + this->SendEmoteMessage(slock->myname, 0, 0, 13, "World locked"); + else + this->SendEmoteMessage(slock->myname, 0, 0, 13, "World unlocked"); + } + else { + if (slock->mode >= 1) + this->SendEmoteMessage(slock->myname, 0, 0, 13, "World locked, but login server not connected."); + else + this->SendEmoteMessage(slock->myname, 0, 0, 13, "World unlocked, but login server not conencted."); + } + break; + } + case ServerOP_Motd: { + if (pack->size != sizeof(ServerMotd_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_Motd. Got: %d, Expected: %d",pack->size,sizeof(ServerMotd_Struct)); + break; + } + ServerMotd_Struct* smotd = (ServerMotd_Struct*) pack->pBuffer; + database.SetVariable("MOTD",smotd->motd); + //this->SendEmoteMessage(smotd->myname, 0, 0, 13, "Updated Motd."); + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_Uptime: { + if (pack->size != sizeof(ServerUptime_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_Uptime. Got: %d, Expected: %d",pack->size,sizeof(ServerUptime_Struct)); + break; + } + ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer; + if (sus->zoneserverid == 0) { + ZSList::ShowUpTime(this, sus->adminname); + } + else { + ZoneServer* zs = zoneserver_list.FindByID(sus->zoneserverid); + if (zs) + zs->SendPacket(pack); + } + break; + } + case ServerOP_Petition: { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_GetWorldTime: { + Log.Out(Logs::Detail, Logs::World_Server,"Broadcasting a world time update"); + auto pack = new ServerPacket; + + pack->opcode = ServerOP_SyncWorldTime; + pack->size = sizeof(eqTimeOfDay); + pack->pBuffer = new uchar[pack->size]; + memset(pack->pBuffer, 0, pack->size); + eqTimeOfDay* tod = (eqTimeOfDay*) pack->pBuffer; + tod->start_eqtime=zoneserver_list.worldclock.getStartEQTime(); + tod->start_realtime=zoneserver_list.worldclock.getStartRealTime(); + SendPacket(pack); + safe_delete(pack); + break; + } + case ServerOP_SetWorldTime: { + Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime"); + eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer; + zoneserver_list.worldclock.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime); + Log.Out(Logs::Detail, Logs::World_Server, "New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime); + database.SaveTime((int)newtime->start_eqtime.minute, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.day, newtime->start_eqtime.month, newtime->start_eqtime.year); + zoneserver_list.SendTimeSync(); + break; + } + case ServerOP_IPLookup: { + if (pack->size < sizeof(ServerGenericWorldQuery_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_IPLookup. Got: %d, Expected (at least): %d",pack->size,sizeof(ServerGenericWorldQuery_Struct)); + break; + } + ServerGenericWorldQuery_Struct* sgwq = (ServerGenericWorldQuery_Struct*) pack->pBuffer; + if (pack->size == sizeof(ServerGenericWorldQuery_Struct)) + client_list.SendCLEList(sgwq->admin, sgwq->from, this); + else + client_list.SendCLEList(sgwq->admin, sgwq->from, this, sgwq->query); + break; + } + case ServerOP_LockZone: { + if (pack->size < sizeof(ServerLockZone_Struct)) { + Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_LockZone. Got: %d, Expected: %d",pack->size,sizeof(ServerLockZone_Struct)); + break; + } + ServerLockZone_Struct* s = (ServerLockZone_Struct*) pack->pBuffer; + switch (s->op) { + case 0: + zoneserver_list.ListLockedZones(s->adminname, this); + break; + case 1: + if (zoneserver_list.SetLockedZone(s->zoneID, true)) + zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone locked: %s", database.GetZoneName(s->zoneID)); + else + this->SendEmoteMessageRaw(s->adminname, 0, 0, 0, "Failed to change lock"); + break; + case 2: + if (zoneserver_list.SetLockedZone(s->zoneID, false)) + zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone unlocked: %s", database.GetZoneName(s->zoneID)); + else + this->SendEmoteMessageRaw(s->adminname, 0, 0, 0, "Failed to change lock"); + break; + } + break; + } + case ServerOP_ItemStatus: { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_OOCMute: { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_Revoke: { + RevokeStruct* rev = (RevokeStruct*)pack->pBuffer; + ClientListEntry* cle = client_list.FindCharacter(rev->name); + if (cle != 0 && cle->Server() != 0) + { + cle->Server()->SendPacket(pack); + } + break; + } + case ServerOP_SpawnPlayerCorpse: { + SpawnPlayerCorpse_Struct* s = (SpawnPlayerCorpse_Struct*)pack->pBuffer; + ZoneServer* zs = zoneserver_list.FindByZoneID(s->zone_id); + if(zs) { + zs->SendPacket(pack); + } + break; + } + case ServerOP_Consent: { + // Message string id's likely to be used here are: + // CONSENT_YOURSELF = 399 + // CONSENT_INVALID_NAME = 397 + // TARGET_NOT_FOUND = 101 + ZoneServer* zs; + ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; + ClientListEntry* cle = client_list.FindCharacter(s->grantname); + if(cle) { + if(cle->instance() != 0) + { + zs = zoneserver_list.FindByInstanceID(cle->instance()); + if(zs) { + zs->SendPacket(pack); + } + else + { + auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); + ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer; + strcpy(scs->grantname, s->grantname); + strcpy(scs->ownername, s->ownername); + scs->permission = s->permission; + scs->zone_id = s->zone_id; + scs->instance_id = s->instance_id; + scs->message_string_id = 101; + zs = zoneserver_list.FindByInstanceID(s->instance_id); + if(zs) { + zs->SendPacket(pack); + } + else { + Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id); + } + safe_delete(pack); + } + } + else + { + zs = zoneserver_list.FindByZoneID(cle->zone()); + if(zs) { + zs->SendPacket(pack); + } + else { + // send target not found back to requester + auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); + ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer; + strcpy(scs->grantname, s->grantname); + strcpy(scs->ownername, s->ownername); + scs->permission = s->permission; + scs->zone_id = s->zone_id; + scs->message_string_id = 101; + zs = zoneserver_list.FindByZoneID(s->zone_id); + if(zs) { + zs->SendPacket(pack); + } + else { + Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id); + } + safe_delete(pack); + } + } + } + else { + // send target not found back to requester + auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); + ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer; + strcpy(scs->grantname, s->grantname); + strcpy(scs->ownername, s->ownername); + scs->permission = s->permission; + scs->zone_id = s->zone_id; + scs->message_string_id = 397; + zs = zoneserver_list.FindByZoneID(s->zone_id); + if(zs) { + zs->SendPacket(pack); + } + else { + Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id); + } + safe_delete(pack); + } + break; + } + case ServerOP_Consent_Response: { + // Message string id's likely to be used here are: + // CONSENT_YOURSELF = 399 + // CONSENT_INVALID_NAME = 397 + // TARGET_NOT_FOUND = 101 + ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; + if(s->instance_id != 0) + { + ZoneServer* zs = zoneserver_list.FindByInstanceID(s->instance_id); + if(zs) { + zs->SendPacket(pack); + } + else { + Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id); } } else { - Log.Out(Logs::General, Logs::Error, "**WARNING** You have not configured a world shared key in your config file. You should add a STRING element to your element to prevent unauthroized zone access."); - is_authenticated = true; - } - } - switch(pack->opcode) { - case 0: - break; - case ServerOP_KeepAlive: { - // ignore this - break; - } - case ServerOP_ZAAuth: { - break; - } - case ServerOP_LSZoneBoot:{ - if(pack->size==sizeof(ZoneBoot_Struct)){ - ZoneBoot_Struct* zbs= (ZoneBoot_Struct*)pack->pBuffer; - SetCompile(zbs->compile_time); - } - break; - } - case ServerOP_GroupInvite: { - if(pack->size != sizeof(GroupInvite_Struct)) - break; - - GroupInvite_Struct* gis = (GroupInvite_Struct*) pack->pBuffer; - - client_list.SendPacket(gis->invitee_name, pack); - break; - } - case ServerOP_GroupFollow: { - if(pack->size != sizeof(ServerGroupFollow_Struct)) - break; - - ServerGroupFollow_Struct *sgfs = (ServerGroupFollow_Struct *) pack->pBuffer; - - client_list.SendPacket(sgfs->gf.name1, pack); - break; - } - case ServerOP_GroupFollowAck: { - if(pack->size != sizeof(ServerGroupFollowAck_Struct)) - break; - - ServerGroupFollowAck_Struct *sgfas = (ServerGroupFollowAck_Struct *) pack->pBuffer; - - client_list.SendPacket(sgfas->Name, pack); - break; - } - case ServerOP_GroupCancelInvite: { - if(pack->size != sizeof(GroupCancel_Struct)) - break; - - GroupCancel_Struct *gcs = (GroupCancel_Struct *) pack->pBuffer; - - client_list.SendPacket(gcs->name1, pack); - break; - } - case ServerOP_GroupIDReq: { - SendGroupIDs(); - break; - } - case ServerOP_GroupLeave: { - if(pack->size != sizeof(ServerGroupLeave_Struct)) - break; - zoneserver_list.SendPacket(pack); //bounce it to all zones - break; - } - - case ServerOP_GroupJoin: { - if(pack->size != sizeof(ServerGroupJoin_Struct)) - break; - zoneserver_list.SendPacket(pack); //bounce it to all zones - break; - } - - case ServerOP_ForceGroupUpdate: { - if(pack->size != sizeof(ServerForceGroupUpdate_Struct)) - break; - zoneserver_list.SendPacket(pack); //bounce it to all zones - break; - } - - case ServerOP_OOZGroupMessage: { - zoneserver_list.SendPacket(pack); //bounce it to all zones - break; - } - - case ServerOP_DisbandGroup: { - if(pack->size != sizeof(ServerDisbandGroup_Struct)) - break; - zoneserver_list.SendPacket(pack); //bounce it to all zones - break; - } - - case ServerOP_RaidAdd:{ - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidRemove: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidDisband: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidLockFlag: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidChangeGroup: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_UpdateGroup: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidGroupDisband: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidGroupAdd: { - if(pack->size != sizeof(ServerRaidGroupAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidGroupRemove: { - if(pack->size != sizeof(ServerRaidGroupAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidGroupSay: { - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidSay: { - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidGroupLeader: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidLeader: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_DetailsChange: { - if(pack->size != sizeof(ServerRaidGeneralAction_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RaidMOTD: { - if (pack->size < sizeof(ServerRaidMOTD_Struct)) - break; - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_SpawnCondition: { - if(pack->size != sizeof(ServerSpawnCondition_Struct)) - break; - //bounce the packet to the correct zone server, if its up - ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*)pack->pBuffer; - zoneserver_list.SendPacket(ssc->zoneID, ssc->instanceID, pack); - break; - } - case ServerOP_SpawnEvent: { - if(pack->size != sizeof(ServerSpawnEvent_Struct)) - break; - //bounce the packet to the correct zone server, if its up - ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*)pack->pBuffer; - zoneserver_list.SendPacket(sse->zoneID, 0, pack); - break; - } - case ServerOP_ChannelMessage: { - if (pack->size < sizeof(ServerChannelMessage_Struct)) - break; - ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer; - if(scm->chan_num == 20) - { - UCSLink.SendMessage(scm->from, scm->message); - break; - } - if (scm->chan_num == 7 || scm->chan_num == 14) { - if (scm->deliverto[0] == '*') { - Console* con = 0; - con = console_list.FindByAccountName(&scm->deliverto[1]); - if (((!con) || (!con->SendChannelMessage(scm))) && (!scm->noreply)) - zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "%s is not online at this time.", scm->to); - break; - } - ClientListEntry* cle = client_list.FindCharacter(scm->deliverto); - if (cle == 0 || cle->Online() < CLE_Status_Zoning || - (cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) { - if (!scm->noreply) { - ClientListEntry* sender = client_list.FindCharacter(scm->from); - if (!sender || !sender->Server()) - break; - scm->noreply = true; - scm->queued = 3; // offline - strcpy(scm->deliverto, scm->from); - // ideally this would be trimming off the message too, oh well - sender->Server()->SendPacket(pack); - } - } else if (cle->Online() == CLE_Status_Zoning) { - if (!scm->noreply) { - ClientListEntry* sender = client_list.FindCharacter(scm->from); - if (cle->TellQueueFull()) { - if (!sender || !sender->Server()) - break; - scm->noreply = true; - scm->queued = 2; // queue full - strcpy(scm->deliverto, scm->from); - sender->Server()->SendPacket(pack); - } else { - size_t struct_size = sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1; - ServerChannelMessage_Struct *temp = (ServerChannelMessage_Struct *) new uchar[struct_size]; - memset(temp, 0, struct_size); // just in case, was seeing some corrupt messages, but it shouldn't happen - memcpy(temp, scm, struct_size); - temp->noreply = true; - cle->PushToTellQueue(temp); // deallocation is handled in processing or deconstructor - - if (!sender || !sender->Server()) - break; - scm->noreply = true; - scm->queued = 1; // queued - strcpy(scm->deliverto, scm->from); - sender->Server()->SendPacket(pack); - } - } - } - else if (cle->Server() == 0) { - if (!scm->noreply) - zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not contactable at this time'", scm->to, scm->to); - } - else - cle->Server()->SendPacket(pack); - } - else { - if (scm->chan_num == 5 || scm->chan_num == 6 || scm->chan_num == 11) { - console_list.SendChannelMessage(scm); - } - zoneserver_list.SendPacket(pack); - } - break; - } - case ServerOP_EmoteMessage: { - ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; - zoneserver_list.SendEmoteMessageRaw(sem->to, sem->guilddbid, sem->minstatus, sem->type, sem->message); - break; - } - case ServerOP_VoiceMacro: { - - ServerVoiceMacro_Struct* svm = (ServerVoiceMacro_Struct*) pack->pBuffer; - - if(svm->Type == VoiceMacroTell) { - - ClientListEntry* cle = client_list.FindCharacter(svm->To); - - if (!cle || (cle->Online() < CLE_Status_Zoning) || !cle->Server()) { - - zoneserver_list.SendEmoteMessage(svm->From, 0, 0, 0, "'%s is not online at this time'", svm->To); - - break; - } - - cle->Server()->SendPacket(pack); - } - else - zoneserver_list.SendPacket(pack); - - break; - } - - case ServerOP_RezzPlayerAccept: { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_RezzPlayer: { - - RezzPlayer_Struct* sRezz = (RezzPlayer_Struct*) pack->pBuffer; - if (zoneserver_list.SendPacket(pack)){ - Log.Out(Logs::Detail, Logs::World_Server,"Sent Rez packet for %s",sRezz->rez.your_name); - } - else { - Log.Out(Logs::Detail, Logs::World_Server,"Could not send Rez packet for %s",sRezz->rez.your_name); - } - break; - } - case ServerOP_RezzPlayerReject: - { - char *Recipient = (char *)pack->pBuffer; - client_list.SendPacket(Recipient, pack); - break; - } - - case ServerOP_MultiLineMsg: { - ServerMultiLineMsg_Struct* mlm = (ServerMultiLineMsg_Struct*) pack->pBuffer; - client_list.SendPacket(mlm->to, pack); - break; - } - case ServerOP_SetZone: { - if(pack->size != sizeof(SetZone_Struct)) - break; - - SetZone_Struct* szs = (SetZone_Struct*) pack->pBuffer; - if (szs->zoneid != 0) { - if(database.GetZoneName(szs->zoneid)) - SetZone(szs->zoneid, szs->instanceid, szs->staticzone); - else - SetZone(0); - } - else - SetZone(0); - - break; - } - case ServerOP_SetConnectInfo: { - if (pack->size != sizeof(ServerConnectInfo)) - break; - ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer; - - if (!sci->port) { - client_port = zoneserver_list.GetAvailableZonePort(); - - ServerPacket p(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo)); - memset(p.pBuffer,0,sizeof(ServerConnectInfo)); - ServerConnectInfo* sci = (ServerConnectInfo*) p.pBuffer; - sci->port = client_port; - SendPacket(&p); - Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",client_port); - } else { - client_port = sci->port; - Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d.",client_port); - } - - if(sci->address[0]) { - strn0cpy(client_address, sci->address, 250); - Log.Out(Logs::Detail, Logs::World_Server, "Zone specified address %s.", sci->address); - } - - if(sci->local_address[0]) { - strn0cpy(client_local_address, sci->local_address, 250); - Log.Out(Logs::Detail, Logs::World_Server, "Zone specified local address %s.", sci->address); - } - - if (sci->process_id){ - zone_os_process_id = sci->process_id; - } - - } - case ServerOP_SetLaunchName: { - if(pack->size != sizeof(LaunchName_Struct)) - break; - const LaunchName_Struct* ln = (const LaunchName_Struct*)pack->pBuffer; - launcher_name = ln->launcher_name; - launched_name = ln->zone_name; - Log.Out(Logs::Detail, Logs::World_Server, "Zone started with name %s by launcher %s", launched_name.c_str(), launcher_name.c_str()); - break; - } - case ServerOP_ShutdownAll: { - if(pack->size==0){ - zoneserver_list.SendPacket(pack); - zoneserver_list.Process(); - CatchSignal(2); - } - else{ - WorldShutDown_Struct* wsd=(WorldShutDown_Struct*)pack->pBuffer; - if(wsd->time==0 && wsd->interval==0 && zoneserver_list.shutdowntimer->Enabled()){ - zoneserver_list.shutdowntimer->Disable(); - zoneserver_list.reminder->Disable(); - } - else{ - zoneserver_list.shutdowntimer->SetTimer(wsd->time); - zoneserver_list.reminder->SetTimer(wsd->interval-1000); - zoneserver_list.reminder->SetAtTrigger(wsd->interval); - zoneserver_list.shutdowntimer->Start(); - zoneserver_list.reminder->Start(); - } - } - break; - } - case ServerOP_ZoneShutdown: { - ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer; - ZoneServer* zs = 0; - if (s->ZoneServerID != 0) - zs = zoneserver_list.FindByID(s->ZoneServerID); - else if (s->zoneid != 0) - zs = zoneserver_list.FindByName(database.GetZoneName(s->zoneid)); - else - zoneserver_list.SendEmoteMessage(s->adminname, 0, 0, 0, "Error: SOP_ZoneShutdown: neither ID nor name specified"); - - if (zs == 0) - zoneserver_list.SendEmoteMessage(s->adminname, 0, 0, 0, "Error: SOP_ZoneShutdown: zoneserver not found"); - else - zs->SendPacket(pack); - break; - } - case ServerOP_ZoneBootup: { - ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer; - zoneserver_list.SOPZoneBootup(s->adminname, s->ZoneServerID, database.GetZoneName(s->zoneid), s->makestatic); - break; - } - case ServerOP_ZoneStatus: { - if (pack->size >= 1) - zoneserver_list.SendZoneStatus((char *) &pack->pBuffer[1], (uint8) pack->pBuffer[0], this); - break; - - } - case ServerOP_AcceptWorldEntrance: { - if(pack->size != sizeof(WorldToZone_Struct)) - break; - - WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer; - Client* client = 0; - client = client_list.FindByAccountID(wtz->account_id); - if(client != 0) - client->Clearance(wtz->response); - } - case ServerOP_ZoneToZoneRequest: { - // - // ZoneChange is received by the zone the player is in, then the - // zone sends a ZTZ which ends up here. This code then find the target - // (ingress point) and boots it if needed, then sends the ZTZ to it. - // The ingress server will decide wether the player can enter, then will - // send back the ZTZ to here. This packet is passed back to the egress - // server, which will send a ZoneChange response back to the client - // which can be an error, or a success, in which case the client will - // disconnect, and their zone location will be saved when ~Client is - // called, so it will be available when they ask to zone. - // - - - if(pack->size != sizeof(ZoneToZone_Struct)) - break; - ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; - ClientListEntry* client = nullptr; - if(WorldConfig::get()->UpdateStats) - client = client_list.FindCharacter(ztz->name); - - Log.Out(Logs::Detail, Logs::World_Server,"ZoneToZone request for %s current zone %d req zone %d\n", - ztz->name, ztz->current_zone_id, ztz->requested_zone_id); - - /* This is a request from the egress zone */ - if(GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) { - Log.Out(Logs::Detail, Logs::World_Server,"Processing ZTZ for egress from zone for client %s\n", ztz->name); - - if (ztz->admin < 80 && ztz->ignorerestrictions < 2 && zoneserver_list.IsZoneLocked(ztz->requested_zone_id)) { - ztz->response = 0; - SendPacket(pack); - break; - } - - ZoneServer *ingress_server = nullptr; - if(ztz->requested_instance_id > 0) { - ingress_server = zoneserver_list.FindByInstanceID(ztz->requested_instance_id); - } - else { - ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id); - } - - /* Zone was already running*/ - if(ingress_server) { - Log.Out(Logs::Detail, Logs::World_Server,"Found a zone already booted for %s\n", ztz->name); - ztz->response = 1; - } - /* Boot the Zone*/ - else { - int server_id; - if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id, ztz->requested_instance_id))){ - Log.Out(Logs::Detail, Logs::World_Server,"Successfully booted a zone for %s\n", ztz->name); - // bootup successful, ready to rock - ztz->response = 1; - ingress_server = zoneserver_list.FindByID(server_id); - } - else { - Log.Out(Logs::Detail, Logs::World_Server,"FAILED to boot a zone for %s\n", ztz->name); - // bootup failed, send back error code 0 - ztz->response = 0; - } - } - if(ztz->response!=0 && client) - client->LSZoneChange(ztz); - SendPacket(pack); // send back to egress server - if(ingress_server) { - ingress_server->SendPacket(pack); // inform target server - } - } - /* Response from Ingress server, route back to egress */ - else{ - - Log.Out(Logs::Detail, Logs::World_Server,"Processing ZTZ for ingress to zone for client %s\n", ztz->name); - ZoneServer *egress_server = nullptr; - if(ztz->current_instance_id > 0) { - egress_server = zoneserver_list.FindByInstanceID(ztz->current_instance_id); - } - else { - egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id); - } - - if(egress_server) { - egress_server->SendPacket(pack); - } - } - - break; - } - case ServerOP_ClientList: { - if (pack->size != sizeof(ServerClientList_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_ClientList. Got: %d, Expected: %d",pack->size,sizeof(ServerClientList_Struct)); - break; - } - client_list.ClientUpdate(this, (ServerClientList_Struct*) pack->pBuffer); - break; - } - case ServerOP_ClientListKA: { - ServerClientListKeepAlive_Struct* sclka = (ServerClientListKeepAlive_Struct*) pack->pBuffer; - if (pack->size < 4 || pack->size != 4 + (4 * sclka->numupdates)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_ClientListKA. Got: %d, Expected: %d",pack->size, (4 + (4 * sclka->numupdates))); - break; - } - client_list.CLEKeepAlive(sclka->numupdates, sclka->wid); - break; - } - case ServerOP_Who: { - ServerWhoAll_Struct* whoall = (ServerWhoAll_Struct*) pack->pBuffer; - auto whom = new Who_All_Struct; - memset(whom,0,sizeof(Who_All_Struct)); - whom->gmlookup = whoall->gmlookup; - whom->lvllow = whoall->lvllow; - whom->lvlhigh = whoall->lvlhigh; - whom->wclass = whoall->wclass; - whom->wrace = whoall->wrace; - strcpy(whom->whom,whoall->whom); - client_list.SendWhoAll(whoall->fromid,whoall->from, whoall->admin, whom, this); - safe_delete(whom); - break; - } - case ServerOP_RequestOnlineGuildMembers: { - ServerRequestOnlineGuildMembers_Struct *srogms = (ServerRequestOnlineGuildMembers_Struct*) pack->pBuffer; - client_list.SendOnlineGuildMembers(srogms->FromID, srogms->GuildID); - break; - } - case ServerOP_ClientVersionSummary: { - ServerRequestClientVersionSummary_Struct *srcvss = (ServerRequestClientVersionSummary_Struct*) pack->pBuffer; - client_list.SendClientVersionSummary(srcvss->Name); - break; - } - case ServerOP_ReloadLogs: { - zoneserver_list.SendPacket(pack); - database.LoadLogSettings(Log.log_settings); - break; - } - case ServerOP_ReloadRules: { - zoneserver_list.SendPacket(pack); - RuleManager::Instance()->LoadRules(&database, "default"); - break; - } - case ServerOP_ReloadRulesWorld: - { - RuleManager::Instance()->LoadRules(&database, "default"); - break; - } - case ServerOP_ReloadPerlExportSettings: - { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_CameraShake: - { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_FriendsWho: { - ServerFriendsWho_Struct* FriendsWho = (ServerFriendsWho_Struct*) pack->pBuffer; - client_list.SendFriendsWho(FriendsWho, this); - break; - } - case ServerOP_LFGMatches: { - ServerLFGMatchesRequest_Struct* smrs = (ServerLFGMatchesRequest_Struct*) pack->pBuffer; - client_list.SendLFGMatches(smrs); - break; - } - case ServerOP_LFPMatches: { - ServerLFPMatchesRequest_Struct* smrs = (ServerLFPMatchesRequest_Struct*) pack->pBuffer; - LFPGroupList.SendLFPMatches(smrs); - break; - } - case ServerOP_LFPUpdate: { - ServerLFPUpdate_Struct* sus = (ServerLFPUpdate_Struct*) pack->pBuffer; - if(sus->Action) - LFPGroupList.UpdateGroup(sus); - else - LFPGroupList.RemoveGroup(sus); - break; - } - case ServerOP_ZonePlayer: { - //ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) pack->pBuffer; - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_KickPlayer: { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_KillPlayer: { - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_GuildRankUpdate: - { - zoneserver_list.SendPacket(pack); - break; - } - //these opcodes get processed by the guild manager. - case ServerOP_RefreshGuild: - case ServerOP_DeleteGuild: - case ServerOP_GuildCharRefresh: - case ServerOP_GuildMemberUpdate: { - guild_mgr.ProcessZonePacket(pack); - break; - } - - case ServerOP_FlagUpdate: { - ClientListEntry* cle = client_list.FindCLEByAccountID(*((uint32*) pack->pBuffer)); - if (cle) - cle->SetAdmin(*((int16*) &pack->pBuffer[4])); - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_GMGoto: { - if (pack->size != sizeof(ServerGMGoto_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_GMGoto. Got: %d, Expected: %d",pack->size,sizeof(ServerGMGoto_Struct)); - break; - } - ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer; - ClientListEntry* cle = client_list.FindCharacter(gmg->gotoname); - if (cle != 0) { - if (cle->Server() == 0) - this->SendEmoteMessage(gmg->myname, 0, 0, 13, "Error: Cannot identify %s's zoneserver.", gmg->gotoname); - else if (cle->Anon() == 1 && cle->Admin() > gmg->admin) // no snooping for anon GMs - this->SendEmoteMessage(gmg->myname, 0, 0, 13, "Error: %s not found", gmg->gotoname); - else - cle->Server()->SendPacket(pack); - } - else { - this->SendEmoteMessage(gmg->myname, 0, 0, 13, "Error: %s not found", gmg->gotoname); - } - break; - } - case ServerOP_Lock: { - if (pack->size != sizeof(ServerLock_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_Lock. Got: %d, Expected: %d",pack->size,sizeof(ServerLock_Struct)); - break; - } - ServerLock_Struct* slock = (ServerLock_Struct*) pack->pBuffer; - if (slock->mode >= 1) - WorldConfig::LockWorld(); - else - WorldConfig::UnlockWorld(); - if (loginserverlist.Connected()) { - loginserverlist.SendStatus(); - if (slock->mode >= 1) - this->SendEmoteMessage(slock->myname, 0, 0, 13, "World locked"); - else - this->SendEmoteMessage(slock->myname, 0, 0, 13, "World unlocked"); - } - else { - if (slock->mode >= 1) - this->SendEmoteMessage(slock->myname, 0, 0, 13, "World locked, but login server not connected."); - else - this->SendEmoteMessage(slock->myname, 0, 0, 13, "World unlocked, but login server not conencted."); - } - break; - } - case ServerOP_Motd: { - if (pack->size != sizeof(ServerMotd_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_Motd. Got: %d, Expected: %d",pack->size,sizeof(ServerMotd_Struct)); - break; - } - ServerMotd_Struct* smotd = (ServerMotd_Struct*) pack->pBuffer; - database.SetVariable("MOTD",smotd->motd); - //this->SendEmoteMessage(smotd->myname, 0, 0, 13, "Updated Motd."); - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_Uptime: { - if (pack->size != sizeof(ServerUptime_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_Uptime. Got: %d, Expected: %d",pack->size,sizeof(ServerUptime_Struct)); - break; - } - ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer; - if (sus->zoneserverid == 0) { - ZSList::ShowUpTime(this, sus->adminname); - } - else { - ZoneServer* zs = zoneserver_list.FindByID(sus->zoneserverid); - if (zs) - zs->SendPacket(pack); - } - break; - } - case ServerOP_Petition: { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_GetWorldTime: { - Log.Out(Logs::Detail, Logs::World_Server,"Broadcasting a world time update"); - auto pack = new ServerPacket; - - pack->opcode = ServerOP_SyncWorldTime; - pack->size = sizeof(eqTimeOfDay); - pack->pBuffer = new uchar[pack->size]; - memset(pack->pBuffer, 0, pack->size); - eqTimeOfDay* tod = (eqTimeOfDay*) pack->pBuffer; - tod->start_eqtime=zoneserver_list.worldclock.getStartEQTime(); - tod->start_realtime=zoneserver_list.worldclock.getStartRealTime(); - SendPacket(pack); - safe_delete(pack); - break; - } - case ServerOP_SetWorldTime: { - Log.Out(Logs::Detail, Logs::World_Server,"Received SetWorldTime"); - eqTimeOfDay* newtime = (eqTimeOfDay*) pack->pBuffer; - zoneserver_list.worldclock.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime); - Log.Out(Logs::Detail, Logs::World_Server, "New time = %d-%d-%d %d:%d (%d)\n", newtime->start_eqtime.year, newtime->start_eqtime.month, (int)newtime->start_eqtime.day, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.minute, (int)newtime->start_realtime); - database.SaveTime((int)newtime->start_eqtime.minute, (int)newtime->start_eqtime.hour, (int)newtime->start_eqtime.day, newtime->start_eqtime.month, newtime->start_eqtime.year); - zoneserver_list.SendTimeSync(); - break; - } - case ServerOP_IPLookup: { - if (pack->size < sizeof(ServerGenericWorldQuery_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_IPLookup. Got: %d, Expected (at least): %d",pack->size,sizeof(ServerGenericWorldQuery_Struct)); - break; - } - ServerGenericWorldQuery_Struct* sgwq = (ServerGenericWorldQuery_Struct*) pack->pBuffer; - if (pack->size == sizeof(ServerGenericWorldQuery_Struct)) - client_list.SendCLEList(sgwq->admin, sgwq->from, this); - else - client_list.SendCLEList(sgwq->admin, sgwq->from, this, sgwq->query); - break; - } - case ServerOP_LockZone: { - if (pack->size < sizeof(ServerLockZone_Struct)) { - Log.Out(Logs::Detail, Logs::World_Server,"Wrong size on ServerOP_LockZone. Got: %d, Expected: %d",pack->size,sizeof(ServerLockZone_Struct)); - break; - } - ServerLockZone_Struct* s = (ServerLockZone_Struct*) pack->pBuffer; - switch (s->op) { - case 0: - zoneserver_list.ListLockedZones(s->adminname, this); - break; - case 1: - if (zoneserver_list.SetLockedZone(s->zoneID, true)) - zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone locked: %s", database.GetZoneName(s->zoneID)); - else - this->SendEmoteMessageRaw(s->adminname, 0, 0, 0, "Failed to change lock"); - break; - case 2: - if (zoneserver_list.SetLockedZone(s->zoneID, false)) - zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone unlocked: %s", database.GetZoneName(s->zoneID)); - else - this->SendEmoteMessageRaw(s->adminname, 0, 0, 0, "Failed to change lock"); - break; - } - break; - } - case ServerOP_ItemStatus: { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_OOCMute: { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_Revoke: { - RevokeStruct* rev = (RevokeStruct*)pack->pBuffer; - ClientListEntry* cle = client_list.FindCharacter(rev->name); - if (cle != 0 && cle->Server() != 0) - { - cle->Server()->SendPacket(pack); - } - break; - } - case ServerOP_SpawnPlayerCorpse: { - SpawnPlayerCorpse_Struct* s = (SpawnPlayerCorpse_Struct*)pack->pBuffer; ZoneServer* zs = zoneserver_list.FindByZoneID(s->zone_id); if(zs) { - if (zs->SendPacket(pack)) { - Log.Out(Logs::Detail, Logs::World_Server,"Sent request to spawn player corpse id %i in zone %u.",s->player_corpse_id, s->zone_id); - } - else { - Log.Out(Logs::Detail, Logs::World_Server,"Could not send request to spawn player corpse id %i in zone %u.",s->player_corpse_id, s->zone_id); - } - } - break; - } - case ServerOP_Consent: { - // Message string id's likely to be used here are: - // CONSENT_YOURSELF = 399 - // CONSENT_INVALID_NAME = 397 - // TARGET_NOT_FOUND = 101 - ZoneServer* zs; - ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; - ClientListEntry* cle = client_list.FindCharacter(s->grantname); - if(cle) { - if(cle->instance() != 0) - { - zs = zoneserver_list.FindByInstanceID(cle->instance()); - if(zs) { - if(zs->SendPacket(pack)) { - Log.Out(Logs::Detail, Logs::World_Server, "Sent consent packet from player %s to player %s in zone %u.", s->ownername, s->grantname, cle->instance()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent operation.", s->instance_id); - } - } - else - { - auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); - ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer; - strcpy(scs->grantname, s->grantname); - strcpy(scs->ownername, s->ownername); - scs->permission = s->permission; - scs->zone_id = s->zone_id; - scs->instance_id = s->instance_id; - scs->message_string_id = 101; - zs = zoneserver_list.FindByInstanceID(s->instance_id); - if(zs) { - if(!zs->SendPacket(pack)) - Log.Out(Logs::Detail, Logs::World_Server, "Unable to send consent response back to player %s in instance %u.", s->ownername, zs->GetInstanceID()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id); - } - safe_delete(pack); - } - } - else - { - zs = zoneserver_list.FindByZoneID(cle->zone()); - if(zs) { - if(zs->SendPacket(pack)) { - Log.Out(Logs::Detail, Logs::World_Server, "Sent consent packet from player %s to player %s in zone %u.", s->ownername, s->grantname, cle->zone()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent operation.", s->zone_id); - } - } - else { - // send target not found back to requester - auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); - ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer; - strcpy(scs->grantname, s->grantname); - strcpy(scs->ownername, s->ownername); - scs->permission = s->permission; - scs->zone_id = s->zone_id; - scs->message_string_id = 101; - zs = zoneserver_list.FindByZoneID(s->zone_id); - if(zs) { - if(!zs->SendPacket(pack)) - Log.Out(Logs::Detail, Logs::World_Server, "Unable to send consent response back to player %s in zone %s.", s->ownername, zs->GetZoneName()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id); - } - safe_delete(pack); - } - } + zs->SendPacket(pack); } else { - // send target not found back to requester - auto pack = new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); - ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)pack->pBuffer; - strcpy(scs->grantname, s->grantname); - strcpy(scs->ownername, s->ownername); - scs->permission = s->permission; - scs->zone_id = s->zone_id; - scs->message_string_id = 397; - zs = zoneserver_list.FindByZoneID(s->zone_id); - if(zs) { - if(!zs->SendPacket(pack)) - Log.Out(Logs::Detail, Logs::World_Server, "Unable to send consent response back to player %s in zone %s.", s->ownername, zs->GetZoneName()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id); - } - safe_delete(pack); + Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id); } - break; - } - case ServerOP_Consent_Response: { - // Message string id's likely to be used here are: - // CONSENT_YOURSELF = 399 - // CONSENT_INVALID_NAME = 397 - // TARGET_NOT_FOUND = 101 - ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; - if(s->instance_id != 0) - { - ZoneServer* zs = zoneserver_list.FindByInstanceID(s->instance_id); - if(zs) { - if(!zs->SendPacket(pack)) - Log.Out(Logs::Detail, Logs::World_Server, "Unable to send consent response back to player %s in instance %u.", s->ownername, zs->GetInstanceID()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for instance id %u in zoneserver list for ServerOP_Consent_Response operation.", s->instance_id); - } - } - else - { - ZoneServer* zs = zoneserver_list.FindByZoneID(s->zone_id); - if(zs) { - if(!zs->SendPacket(pack)) - Log.Out(Logs::Detail, Logs::World_Server, "Unable to send consent response back to player %s in zone %s.", s->ownername, zs->GetZoneName()); - } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Unable to locate zone record for zone id %u in zoneserver list for ServerOP_Consent_Response operation.", s->zone_id); - } - } - break; - } - - case ServerOP_InstanceUpdateTime : - { - ServerInstanceUpdateTime_Struct *iut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer; - ZoneServer *zm = zoneserver_list.FindByInstanceID(iut->instance_id); - if(zm) - { - zm->SendPacket(pack); - } - break; - } - case ServerOP_QGlobalUpdate: - { - if(pack->size != sizeof(ServerQGlobalUpdate_Struct)) - { - break; - } - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_QGlobalDelete: - { - if(pack->size != sizeof(ServerQGlobalDelete_Struct)) - { - break; - } - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_AdventureRequest: - { - adventure_manager.CalculateAdventureRequestReply((const char*)pack->pBuffer); - break; - } - - case ServerOP_AdventureRequestCreate: - { - adventure_manager.TryAdventureCreate((const char*)pack->pBuffer); - break; - } - - case ServerOP_AdventureDataRequest: - { - AdventureFinishEvent fe; - while(adventure_manager.PopFinishedEvent((const char*)pack->pBuffer, fe)) - { - adventure_manager.SendAdventureFinish(fe); - } - adventure_manager.GetAdventureData((const char*)pack->pBuffer); - break; - } - - case ServerOP_AdventureClickDoor: - { - ServerPlayerClickedAdventureDoor_Struct *pcad = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer; - adventure_manager.PlayerClickedDoor(pcad->player, pcad->zone_id, pcad->id); - break; - } - - case ServerOP_AdventureLeave: - { - adventure_manager.LeaveAdventure((const char*)pack->pBuffer); - break; - } - - case ServerOP_AdventureCountUpdate: - { - ServerAdventureCount_Struct *sc = (ServerAdventureCount_Struct*)pack->pBuffer; - adventure_manager.IncrementCount(sc->instance_id); - break; - } - - case ServerOP_AdventureAssaCountUpdate: - { - adventure_manager.IncrementAssassinationCount(*((uint16*)pack->pBuffer)); - break; - } - - case ServerOP_AdventureZoneData: - { - adventure_manager.GetZoneData(*((uint16*)pack->pBuffer)); - break; - } - - case ServerOP_AdventureLeaderboard: - { - ServerLeaderboardRequest_Struct *lr = (ServerLeaderboardRequest_Struct*)pack->pBuffer; - adventure_manager.DoLeaderboardRequest(lr->player, lr->type); - break; - } - - case ServerOP_LSAccountUpdate: - { - Log.Out(Logs::Detail, Logs::World_Server, "Received ServerOP_LSAccountUpdate packet from zone"); - loginserverlist.SendAccountUpdate(pack); - break; - } - - case ServerOP_UCSMailMessage: - { - UCSLink.SendPacket(pack); - break; - } - case ServerOP_QSSendQuery: - case ServerOP_QueryServGeneric: - case ServerOP_Speech: - case ServerOP_QSPlayerLogTrades: - case ServerOP_QSPlayerLogHandins: - case ServerOP_QSPlayerLogNPCKills: - case ServerOP_QSPlayerLogDeletes: - case ServerOP_QSPlayerLogMoves: - case ServerOP_QSPlayerLogMerchantTransactions: - { - QSLink.SendPacket(pack); - break; - } - case ServerOP_CZSignalClientByName: - case ServerOP_CZMessagePlayer: - case ServerOP_CZSignalNPC: - case ServerOP_CZSetEntityVariableByNPCTypeID: - case ServerOP_CZSignalClient: - case ServerOP_WWMarquee: - case ServerOP_DepopAllPlayersCorpses: - case ServerOP_DepopPlayerCorpse: - case ServerOP_ReloadTitles: - case ServerOP_SpawnStatusChange: - case ServerOP_ReloadTasks: - case ServerOP_ReloadWorld: - case ServerOP_UpdateSpawn: - { - zoneserver_list.SendPacket(pack); - break; - } - case ServerOP_ChangeSharedMem: { - std::string hotfix_name = std::string((char*)pack->pBuffer); - - Log.Out(Logs::General, Logs::World_Server, "Loading items..."); - if(!database.LoadItems(hotfix_name)) { - Log.Out(Logs::General, Logs::World_Server, "Error: Could not load item data. But ignoring"); - } - - Log.Out(Logs::General, Logs::World_Server, "Loading skill caps..."); - if(!database.LoadSkillCaps(hotfix_name)) { - Log.Out(Logs::General, Logs::World_Server, "Error: Could not load skill cap data. But ignoring"); - } - - zoneserver_list.SendPacket(pack); - break; - } - - case ServerOP_RequestTellQueue: - { - ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer; - ClientListEntry *cle = client_list.FindCharacter(rtq->name); - if (!cle || cle->TellQueueEmpty()) - break; - - cle->ProcessTellQueue(); - break; - } - default: - { - Log.Out(Logs::Detail, Logs::World_Server, "Unknown ServerOPcode from zone 0x%04x, size %d", pack->opcode, pack->size); - DumpPacket(pack->pBuffer, pack->size); - break; } + break; } - if (pack) { - safe_delete(pack); + + case ServerOP_InstanceUpdateTime : + { + ServerInstanceUpdateTime_Struct *iut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer; + ZoneServer *zm = zoneserver_list.FindByInstanceID(iut->instance_id); + if(zm) + { + zm->SendPacket(pack); + } + break; } - else { - Log.Out(Logs::Detail, Logs::World_Server, "Zoneserver process attempted to delete pack when pack does not exist."); + case ServerOP_QGlobalUpdate: + { + if(pack->size != sizeof(ServerQGlobalUpdate_Struct)) + { + break; + } + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_QGlobalDelete: + { + if(pack->size != sizeof(ServerQGlobalDelete_Struct)) + { + break; + } + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_AdventureRequest: + { + adventure_manager.CalculateAdventureRequestReply((const char*)pack->pBuffer); + break; + } + + case ServerOP_AdventureRequestCreate: + { + adventure_manager.TryAdventureCreate((const char*)pack->pBuffer); + break; + } + + case ServerOP_AdventureDataRequest: + { + AdventureFinishEvent fe; + while(adventure_manager.PopFinishedEvent((const char*)pack->pBuffer, fe)) + { + adventure_manager.SendAdventureFinish(fe); + } + adventure_manager.GetAdventureData((const char*)pack->pBuffer); + break; + } + + case ServerOP_AdventureClickDoor: + { + ServerPlayerClickedAdventureDoor_Struct *pcad = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer; + adventure_manager.PlayerClickedDoor(pcad->player, pcad->zone_id, pcad->id); + break; + } + + case ServerOP_AdventureLeave: + { + adventure_manager.LeaveAdventure((const char*)pack->pBuffer); + break; + } + + case ServerOP_AdventureCountUpdate: + { + ServerAdventureCount_Struct *sc = (ServerAdventureCount_Struct*)pack->pBuffer; + adventure_manager.IncrementCount(sc->instance_id); + break; + } + + case ServerOP_AdventureAssaCountUpdate: + { + adventure_manager.IncrementAssassinationCount(*((uint16*)pack->pBuffer)); + break; + } + + case ServerOP_AdventureZoneData: + { + adventure_manager.GetZoneData(*((uint16*)pack->pBuffer)); + break; + } + + case ServerOP_AdventureLeaderboard: + { + ServerLeaderboardRequest_Struct *lr = (ServerLeaderboardRequest_Struct*)pack->pBuffer; + adventure_manager.DoLeaderboardRequest(lr->player, lr->type); + break; + } + + case ServerOP_LSAccountUpdate: + { + Log.Out(Logs::Detail, Logs::World_Server, "Received ServerOP_LSAccountUpdate packet from zone"); + loginserverlist.SendAccountUpdate(pack); + break; + } + + case ServerOP_UCSMailMessage: + { + UCSLink.SendPacket(pack); + break; + } + case ServerOP_QSSendQuery: + case ServerOP_QueryServGeneric: + case ServerOP_Speech: + case ServerOP_QSPlayerLogTrades: + case ServerOP_QSPlayerLogHandins: + case ServerOP_QSPlayerLogNPCKills: + case ServerOP_QSPlayerLogDeletes: + case ServerOP_QSPlayerLogMoves: + case ServerOP_QSPlayerLogMerchantTransactions: + { + QSLink.SendPacket(pack); + break; + } + case ServerOP_CZSignalClientByName: + case ServerOP_CZMessagePlayer: + case ServerOP_CZSignalNPC: + case ServerOP_CZSetEntityVariableByNPCTypeID: + case ServerOP_CZSignalClient: + case ServerOP_WWMarquee: + case ServerOP_DepopAllPlayersCorpses: + case ServerOP_DepopPlayerCorpse: + case ServerOP_ReloadTitles: + case ServerOP_SpawnStatusChange: + case ServerOP_ReloadTasks: + case ServerOP_ReloadWorld: + case ServerOP_UpdateSpawn: + { + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_ChangeSharedMem: { + std::string hotfix_name = std::string((char*)pack->pBuffer); + + Log.Out(Logs::General, Logs::World_Server, "Loading items..."); + if(!database.LoadItems(hotfix_name)) { + Log.Out(Logs::General, Logs::World_Server, "Error: Could not load item data. But ignoring"); + } + + Log.Out(Logs::General, Logs::World_Server, "Loading skill caps..."); + if(!database.LoadSkillCaps(hotfix_name)) { + Log.Out(Logs::General, Logs::World_Server, "Error: Could not load skill cap data. But ignoring"); + } + + zoneserver_list.SendPacket(pack); + break; + } + + case ServerOP_RequestTellQueue: + { + ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer; + ClientListEntry *cle = client_list.FindCharacter(rtq->name); + if (!cle || cle->TellQueueEmpty()) + break; + + cle->ProcessTellQueue(); + break; + } + default: + { + Log.Out(Logs::Detail, Logs::World_Server, "Unknown ServerOPcode from zone 0x%04x, size %d", pack->opcode, pack->size); + DumpPacket(pack->pBuffer, pack->size); + break; } } - return true; } void ZoneServer::SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...) { diff --git a/world/zoneserver.h b/world/zoneserver.h index 8d26271d1..a6bbc8373 100644 --- a/world/zoneserver.h +++ b/world/zoneserver.h @@ -19,7 +19,9 @@ #define ZONESERVER_H #include "world_tcp_connection.h" -#include "../common/emu_tcp_connection.h" +#include "../net/servertalk_server.h" +#include "../event/timer.h" +#include "../timer.h" #include #include @@ -29,17 +31,16 @@ class ServerPacket; class ZoneServer : public WorldTCPConnection { public: - ZoneServer(EmuTCPConnection* itcpc); + ZoneServer(std::shared_ptr connection); ~ZoneServer(); virtual inline bool IsZoneServer() { return true; } - bool Process(); - bool SendPacket(ServerPacket* pack) { return tcpc->SendPacket(pack); } + void SendPacket(ServerPacket* pack) { tcpc->SendPacket(pack); } void SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...); void SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message); bool SetZone(uint32 iZoneID, uint32 iInstanceID = 0, bool iStaticZone = false); void TriggerBootup(uint32 iZoneID = 0, uint32 iInstanceID = 0, const char* iAdminName = 0, bool iMakeStatic = false); - void Disconnect() { tcpc->Disconnect(); } + void Disconnect() { auto handle = tcpc->Handle(); if (handle) { handle->Disconnect(); } } void IncomingClient(Client* client); void LSBootUpdate(uint32 zoneid, uint32 iInstanceID = 0, bool startup = false); void LSSleepUpdate(uint32 zoneid); @@ -47,14 +48,15 @@ public: uint32 GetPrevZoneID() { return zone_server_previous_zone_id; } void ChangeWID(uint32 iCharID, uint32 iWID); void SendGroupIDs(); + void HandleMessage(uint16 opcode, const EQ::Net::Packet &p); inline const char* GetZoneName() const { return zone_name; } inline const char* GetZoneLongName() const { return long_name; } const char* GetCompileTime() const{ return compiled; } void SetCompile(char* in_compile){ strcpy(compiled,in_compile); } inline uint32 GetZoneID() const { return zone_server_zone_id; } - inline uint32 GetIP() const { return tcpc->GetrIP(); } - inline uint16 GetPort() const { return tcpc->GetrPort(); } + inline std::string GetIP() const { return tcpc->Handle() ? tcpc->Handle()->RemoteIP() : ""; } + inline uint16 GetPort() const { return tcpc->Handle() ? tcpc->Handle()->RemotePort() : 0; } inline const char* GetCAddress() const { return client_address; } inline const char* GetCLocalAddress() const { return client_local_address; } inline uint16 GetCPort() const { return client_port; } @@ -66,6 +68,7 @@ public: inline void RemovePlayer() { zone_player_count--; } inline const char * GetLaunchName() const { return(launcher_name.c_str()); } inline const char * GetLaunchedName() const { return(launched_name.c_str()); } + std::string GetUUID() const { return tcpc->GetUUID(); } inline uint32 GetInstanceID() { return instance_id; } inline void SetInstanceID(uint32 i) { instance_id = i; } @@ -73,7 +76,8 @@ public: inline uint32 GetZoneOSProcessID() { return zone_os_process_id; } private: - EmuTCPConnection* const tcpc; + std::shared_ptr tcpc; + std::unique_ptr boot_timer_obj; uint32 zone_server_id; char client_address[250]; diff --git a/zone/attack.cpp b/zone/attack.cpp index 448bc94de..3b89f2af9 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -24,6 +24,7 @@ #include "../common/spdat.h" #include "../common/string_util.h" #include "../common/data_verification.h" +#include "../common/misc_functions.h" #include "queryserv.h" #include "quest_parser_collection.h" #include "string_ids.h" diff --git a/zone/command.cpp b/zone/command.cpp index 307b4e949..9aac66eaa 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -172,7 +172,6 @@ int command_init(void) command_add("chat", "[channel num] [message] - Send a channel message to all zones", 200, command_chat) || command_add("checklos", "- Check for line of sight to your target", 50, command_checklos) || command_add("clearinvsnapshots", "[use rule] - Clear inventory snapshot history (true - elapsed entries, false - all entries)", 200, command_clearinvsnapshots) || - command_add("connectworldserver", "- Make zone attempt to connect to worldserver", 200, command_connectworldserver) || command_add("corpse", "- Manipulate corpses, use with no arguments for help", 50, command_corpse) || command_add("crashtest", "- Crash the zoneserver", 255, command_crashtest) || command_add("cvs", "- Summary of client versions currently online.", 200, command_cvs) || @@ -820,17 +819,6 @@ void command_setanim(Client *c, const Seperator *sep) c->Message(0, "Usage: #setanim [animnum]"); } -void command_connectworldserver(Client *c, const Seperator *sep) -{ - if(worldserver.Connected()) - c->Message(0, "Error: Already connected to world server"); - else - { - c->Message(0, "Attempting to connect to world server..."); - worldserver.AsyncConnect(); - } -} - void command_serverinfo(Client *c, const Seperator *sep) { #ifdef _WINDOWS diff --git a/zone/effects.cpp b/zone/effects.cpp index 0cec65877..bc5750e9a 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -19,6 +19,7 @@ #include "../common/global_define.h" #include "../common/eqemu_logsys.h" #include "../common/spdat.h" +#include "../common/misc_functions.h" #include "client.h" #include "entity.h" diff --git a/zone/mob.cpp b/zone/mob.cpp index c47788ee5..9366e70b6 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -18,6 +18,7 @@ #include "../common/spdat.h" #include "../common/string_util.h" +#include "../common/misc_functions.h" #include "quest_parser_collection.h" #include "string_ids.h" diff --git a/zone/net.cpp b/zone/net.cpp index 883ea8b64..a663d6093 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -216,7 +216,6 @@ int main(int argc, char** argv) { worldserver.SetLauncherName("NONE"); } - worldserver.SetPassword(Config->SharedKey.c_str()); Log.Out(Logs::General, Logs::Zone_Server, "Connecting to MySQL..."); if (!database.Connect( @@ -397,9 +396,7 @@ int main(int argc, char** argv) { Log.Out(Logs::General, Logs::Zone_Server, "Loading quests"); parse->ReloadQuests(); - if (!worldserver.Connect()) { - Log.Out(Logs::General, Logs::Error, "Worldserver Connection Failed :: worldserver.Connect()"); - } + worldserver.Connect(); Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect #ifdef EQPROFILE @@ -440,8 +437,6 @@ int main(int argc, char** argv) { //Advance the timer to our current point in time Timer::SetCurrentTime(); - worldserver.Process(); - if (!eqsf_open && Config->ZonePort != 0) { Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort); @@ -524,10 +519,7 @@ int main(int argc, char** argv) { if (InterserverTimer.Check()) { InterserverTimer.Start(); database.ping(); - // AsyncLoadVariables(dbasync, &database); entity_list.UpdateWho(); - if (worldserver.TryReconnect() && (!worldserver.Connected())) - worldserver.AsyncConnect(); } }); @@ -553,7 +545,6 @@ int main(int argc, char** argv) { if (zone != 0) Zone::Shutdown(true); //Fix for Linux world server problem. - worldserver.Disconnect(); safe_delete(taskmanager); command_deinit(); #ifdef BOTS @@ -576,7 +567,6 @@ void Shutdown() { Zone::Shutdown(true); RunLoops = false; - worldserver.Disconnect(); Log.Out(Logs::General, Logs::Zone_Server, "Shutting down..."); Log.CloseFileLogs(); } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index a2841ee8e..3270333f8 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -25,6 +25,7 @@ #include "../common/skills.h" #include "../common/spdat.h" #include "../common/data_verification.h" +#include "../common/misc_functions.h" #include "quest_parser_collection.h" #include "string_ids.h" diff --git a/zone/spells.cpp b/zone/spells.cpp index 409a07f47..69b143d1c 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -76,6 +76,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) #include "../common/spdat.h" #include "../common/string_util.h" #include "../common/data_verification.h" +#include "../common/misc_functions.h" #include "quest_parser_collection.h" #include "string_ids.h" diff --git a/zone/titles.cpp b/zone/titles.cpp index 388f12997..95bebc442 100644 --- a/zone/titles.cpp +++ b/zone/titles.cpp @@ -18,6 +18,7 @@ #include "../common/eq_packet_structs.h" #include "../common/string_util.h" +#include "../common/misc_functions.h" #include "client.h" #include "entity.h" diff --git a/zone/trading.cpp b/zone/trading.cpp index 85ed824b2..227e8ac4f 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -20,6 +20,7 @@ #include "../common/eqemu_logsys.h" #include "../common/rulesys.h" #include "../common/string_util.h" +#include "../common/misc_functions.h" #include "client.h" #include "entity.h" diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 84d4cb399..409ef2b6f 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -66,7 +66,6 @@ extern QuestParserCollection *parse; // QuestParserCollection *parse = 0; WorldServer::WorldServer() -: WorldConnection(EmuTCPConnection::packetModeZone) { cur_groupid = 0; last_groupid = 0; @@ -76,18 +75,37 @@ WorldServer::WorldServer() WorldServer::~WorldServer() { } -/*void WorldServer::SendGuildJoin(GuildJoin_Struct* gj){ - ServerPacket* pack = new ServerPacket(ServerOP_GuildJoin, sizeof(GuildJoin_Struct)); - GuildJoin_Struct* wgj = (GuildJoin_Struct*)pack->pBuffer; - wgj->class_=gj->class_; - wgj->guild_id=gj->guild_id; - wgj->level=gj->level; - strcpy(wgj->name,gj->name); - wgj->rank=gj->rank; - wgj->zoneid=gj->zoneid; - SendPacket(pack); - safe_delete(pack); -}*/ +void WorldServer::Connect() +{ + m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "Zone", Config->SharedKey)); + m_connection->OnConnect([this](EQ::Net::ServertalkClient *client) { + OnConnected(); + }); + + //TODO FIX MKAY + //m_connection->OnAnyMessage(std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2)); +} + +bool WorldServer::SendPacket(ServerPacket *pack) +{ + m_connection->SendPacket(pack); + return true; +} + +std::string WorldServer::GetIP() const +{ + return m_connection->Handle()->RemoteIP(); +} + +uint16 WorldServer::GetPort() const +{ + return m_connection->Handle()->RemotePort(); +} + +bool WorldServer::Connected() const +{ + return m_connection->Connected(); +} void WorldServer::SetZoneData(uint32 iZoneID, uint32 iInstanceID) { auto pack = new ServerPacket(ServerOP_SetZone, sizeof(SetZone_Struct)); @@ -102,7 +120,6 @@ void WorldServer::SetZoneData(uint32 iZoneID, uint32 iInstanceID) { } void WorldServer::OnConnected() { - WorldConnection::OnConnected(); ServerPacket* pack; /* Tell the launcher what our information is */ @@ -153,1770 +170,1748 @@ void WorldServer::OnConnected() { SendPacket(pack); safe_delete(pack); } + /* Zone Process Packets from World */ -void WorldServer::Process() { - WorldConnection::Process(); - - if (!Connected()) - return; - - ServerPacket *pack = 0; - while((pack = tcpc.PopPacket())) { - Log.Out(Logs::Detail, Logs::Zone_Server, "Got 0x%04x from world:", pack->opcode); - switch(pack->opcode) { - case 0: { +void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) +{ + ServerPacket tpack(opcode, p); + ServerPacket *pack = &tpack; + switch(opcode) { + case 0: { + break; + } + case ServerOP_KeepAlive: { + // ignore this + break; + } + // World is tellins us what port to use. + case ServerOP_SetConnectInfo: { + if (pack->size != sizeof(ServerConnectInfo)) break; - } - case ServerOP_KeepAlive: { - // ignore this + ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer; + Log.Out(Logs::Detail, Logs::Zone_Server, "World assigned Port: %d for this zone.", sci->port); + ZoneConfig::SetZonePort(sci->port); + break; + } + case ServerOP_ChannelMessage: { + if (!is_zone_loaded) break; - } - // World is tellins us what port to use. - case ServerOP_SetConnectInfo: { - if (pack->size != sizeof(ServerConnectInfo)) - break; - ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer; - Log.Out(Logs::Detail, Logs::Zone_Server, "World assigned Port: %d for this zone.", sci->port); - ZoneConfig::SetZonePort(sci->port); - break; - } - case ServerOP_ZAAuthFailed: { - Log.Out(Logs::Detail, Logs::Zone_Server, "World server responded 'Not Authorized', disabling reconnect"); - pTryReconnect = false; - Disconnect(); - break; - } - case ServerOP_ChannelMessage: { - if (!is_zone_loaded) - break; - ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer; - if (scm->deliverto[0] == 0) { - entity_list.ChannelMessageFromWorld(scm->from, scm->to, scm->chan_num, scm->guilddbid, scm->language, scm->message); - } else { - Client* client = entity_list.GetClientByName(scm->deliverto); - if (client) { - if (client->Connected()) { - if (scm->queued == 1) // tell was queued - client->Tell_StringID(QUEUED_TELL, scm->to, scm->message); - else if (scm->queued == 2) // tell queue was full - client->Tell_StringID(QUEUE_TELL_FULL, scm->to, scm->message); - else if (scm->queued == 3) // person was offline - client->Message_StringID(MT_TellEcho, TOLD_NOT_ONLINE, scm->to); - else // normal stuff - client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, scm->language, scm->message); - if (!scm->noreply && scm->chan_num != 2) { //dont echo on group chat - // if it's a tell, echo back so it shows up - scm->noreply = true; - scm->chan_num = 14; - memset(scm->deliverto, 0, sizeof(scm->deliverto)); - strcpy(scm->deliverto, scm->from); - pack->Deflate(); - SendPacket(pack); - } + ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer; + if (scm->deliverto[0] == 0) { + entity_list.ChannelMessageFromWorld(scm->from, scm->to, scm->chan_num, scm->guilddbid, scm->language, scm->message); + } else { + Client* client = entity_list.GetClientByName(scm->deliverto); + if (client) { + if (client->Connected()) { + if (scm->queued == 1) // tell was queued + client->Tell_StringID(QUEUED_TELL, scm->to, scm->message); + else if (scm->queued == 2) // tell queue was full + client->Tell_StringID(QUEUE_TELL_FULL, scm->to, scm->message); + else if (scm->queued == 3) // person was offline + client->Message_StringID(MT_TellEcho, TOLD_NOT_ONLINE, scm->to); + else // normal stuff + client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, scm->language, scm->message); + if (!scm->noreply && scm->chan_num != 2) { //dont echo on group chat + // if it's a tell, echo back so it shows up + scm->noreply = true; + scm->chan_num = 14; + memset(scm->deliverto, 0, sizeof(scm->deliverto)); + strcpy(scm->deliverto, scm->from); + pack->Deflate(); + SendPacket(pack); } } } - break; } - case ServerOP_VoiceMacro: { + break; + } + case ServerOP_VoiceMacro: { - if (!is_zone_loaded) + if (!is_zone_loaded) + break; + + ServerVoiceMacro_Struct* svm = (ServerVoiceMacro_Struct*) pack->pBuffer; + + auto outapp = new EQApplicationPacket(OP_VoiceMacroOut, sizeof(VoiceMacroOut_Struct)); + VoiceMacroOut_Struct* vmo = (VoiceMacroOut_Struct*)outapp->pBuffer; + + strcpy(vmo->From, svm->From); + vmo->Type = svm->Type; + vmo->Voice =svm->Voice; + vmo->MacroNumber = svm->MacroNumber; + + switch(svm->Type) { + case VoiceMacroTell: { + Client* c = entity_list.GetClientByName(svm->To); + if(!c) + break; + + c->QueuePacket(outapp); + break; + } + + case VoiceMacroGroup: { + Group* g = entity_list.GetGroupByID(svm->GroupID); + + if(!g) + break; + + for(unsigned int i = 0; i < MAX_GROUP_MEMBERS; i++) { + if(g->members[i] && g->members[i]->IsClient()) + g->members[i]->CastToClient()->QueuePacket(outapp); + + } + break; + } + + case VoiceMacroRaid: { + Raid *r = entity_list.GetRaidByID(svm->RaidID); + + if(!r) + break; + + for(int i = 0; i < MAX_RAID_MEMBERS; i++) + if(r->members[i].member) + r->members[i].member->QueuePacket(outapp); + + break; + } + } + safe_delete(outapp); + break; + } + + case ServerOP_SpawnCondition: { + if(pack->size != sizeof(ServerSpawnCondition_Struct)) + break; + if (!is_zone_loaded) + break; + ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*) pack->pBuffer; + + zone->spawn_conditions.SetCondition(zone->GetShortName(), zone->GetInstanceID(), ssc->condition_id, ssc->value, true); + break; + } + case ServerOP_SpawnEvent: { + if(pack->size != sizeof(ServerSpawnEvent_Struct)) + break; + if (!is_zone_loaded) + break; + ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*) pack->pBuffer; + + zone->spawn_conditions.ReloadEvent(sse->event_id); + + break; + } + case ServerOP_AcceptWorldEntrance: { + if(pack->size != sizeof(WorldToZone_Struct)) + break; + if (!is_zone_loaded) + break; + WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer; + + if(zone->GetMaxClients() != 0 && numclients >= zone->GetMaxClients()) + wtz->response = -1; + else + wtz->response = 1; + + SendPacket(pack); + break; + } + case ServerOP_ZoneToZoneRequest: { + if(pack->size != sizeof(ZoneToZone_Struct)) + break; + if (!is_zone_loaded) + break; + ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; + + if(ztz->current_zone_id == zone->GetZoneID() + && ztz->current_instance_id == zone->GetInstanceID()) { + // it's a response + Entity* entity = entity_list.GetClientByName(ztz->name); + if(entity == 0) break; - ServerVoiceMacro_Struct* svm = (ServerVoiceMacro_Struct*) pack->pBuffer; + EQApplicationPacket *outapp; + outapp = new EQApplicationPacket(OP_ZoneChange,sizeof(ZoneChange_Struct)); + ZoneChange_Struct* zc2=(ZoneChange_Struct*)outapp->pBuffer; - auto outapp = new EQApplicationPacket(OP_VoiceMacroOut, sizeof(VoiceMacroOut_Struct)); - VoiceMacroOut_Struct* vmo = (VoiceMacroOut_Struct*)outapp->pBuffer; - - strcpy(vmo->From, svm->From); - vmo->Type = svm->Type; - vmo->Voice =svm->Voice; - vmo->MacroNumber = svm->MacroNumber; - - switch(svm->Type) { - case VoiceMacroTell: { - Client* c = entity_list.GetClientByName(svm->To); - if(!c) - break; - - c->QueuePacket(outapp); - break; - } - - case VoiceMacroGroup: { - Group* g = entity_list.GetGroupByID(svm->GroupID); - - if(!g) - break; - - for(unsigned int i = 0; i < MAX_GROUP_MEMBERS; i++) { - if(g->members[i] && g->members[i]->IsClient()) - g->members[i]->CastToClient()->QueuePacket(outapp); - - } - break; - } - - case VoiceMacroRaid: { - Raid *r = entity_list.GetRaidByID(svm->RaidID); - - if(!r) - break; - - for(int i = 0; i < MAX_RAID_MEMBERS; i++) - if(r->members[i].member) - r->members[i].member->QueuePacket(outapp); - - break; - } + if(ztz->response <= 0) { + zc2->success = ZONE_ERROR_NOTREADY; + entity->CastToMob()->SetZone(ztz->current_zone_id, ztz->current_instance_id); } + else { + entity->CastToClient()->UpdateWho(1); + strn0cpy(zc2->char_name,entity->CastToMob()->GetName(),64); + zc2->zoneID=ztz->requested_zone_id; + zc2->instanceID=ztz->requested_instance_id; + zc2->success = 1; + + // This block is necessary to clean up any merc objects owned by a Client. Maybe we should do this for bots, too? + if(entity->CastToClient()->GetMerc() != nullptr) + { + entity->CastToClient()->GetMerc()->ProcessClientZoneChange(entity->CastToClient()); + } + + entity->CastToMob()->SetZone(ztz->requested_zone_id, ztz->requested_instance_id); + + if(ztz->ignorerestrictions == 3) + entity->CastToClient()->GoToSafeCoords(ztz->requested_zone_id, ztz->requested_instance_id); + } + + outapp->priority = 6; + entity->CastToClient()->QueuePacket(outapp); safe_delete(outapp); - break; + + switch(ztz->response) + { + case -2: { + entity->CastToClient()->Message(13,"You do not own the required locations to enter this zone."); + break; + } + case -1: { + entity->CastToClient()->Message(13,"The zone is currently full, please try again later."); + break; + } + case 0: { + entity->CastToClient()->Message(13,"All zone servers are taken at this time, please try again later."); + break; + } + } } - - case ServerOP_SpawnCondition: { - if(pack->size != sizeof(ServerSpawnCondition_Struct)) - break; - if (!is_zone_loaded) - break; - ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*) pack->pBuffer; - - zone->spawn_conditions.SetCondition(zone->GetShortName(), zone->GetInstanceID(), ssc->condition_id, ssc->value, true); - break; - } - case ServerOP_SpawnEvent: { - if(pack->size != sizeof(ServerSpawnEvent_Struct)) - break; - if (!is_zone_loaded) - break; - ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*) pack->pBuffer; - - zone->spawn_conditions.ReloadEvent(sse->event_id); - - break; - } - case ServerOP_AcceptWorldEntrance: { - if(pack->size != sizeof(WorldToZone_Struct)) - break; - if (!is_zone_loaded) - break; - WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer; + else { + // it's a request + ztz->response = 0; if(zone->GetMaxClients() != 0 && numclients >= zone->GetMaxClients()) - wtz->response = -1; - else - wtz->response = 1; + ztz->response = -1; + else { + ztz->response = 1; + // since they asked about comming, lets assume they are on their way and not shut down. + zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); + } SendPacket(pack); break; } - case ServerOP_ZoneToZoneRequest: { - if(pack->size != sizeof(ZoneToZone_Struct)) - break; - if (!is_zone_loaded) - break; - ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; - - if(ztz->current_zone_id == zone->GetZoneID() - && ztz->current_instance_id == zone->GetInstanceID()) { - // it's a response - Entity* entity = entity_list.GetClientByName(ztz->name); - if(entity == 0) - break; - - EQApplicationPacket *outapp; - outapp = new EQApplicationPacket(OP_ZoneChange,sizeof(ZoneChange_Struct)); - ZoneChange_Struct* zc2=(ZoneChange_Struct*)outapp->pBuffer; - - if(ztz->response <= 0) { - zc2->success = ZONE_ERROR_NOTREADY; - entity->CastToMob()->SetZone(ztz->current_zone_id, ztz->current_instance_id); - } - else { - entity->CastToClient()->UpdateWho(1); - strn0cpy(zc2->char_name,entity->CastToMob()->GetName(),64); - zc2->zoneID=ztz->requested_zone_id; - zc2->instanceID=ztz->requested_instance_id; - zc2->success = 1; - - // This block is necessary to clean up any merc objects owned by a Client. Maybe we should do this for bots, too? - if(entity->CastToClient()->GetMerc() != nullptr) - { - entity->CastToClient()->GetMerc()->ProcessClientZoneChange(entity->CastToClient()); - } - - entity->CastToMob()->SetZone(ztz->requested_zone_id, ztz->requested_instance_id); - - if(ztz->ignorerestrictions == 3) - entity->CastToClient()->GoToSafeCoords(ztz->requested_zone_id, ztz->requested_instance_id); - } - - outapp->priority = 6; - entity->CastToClient()->QueuePacket(outapp); - safe_delete(outapp); - - switch(ztz->response) - { - case -2: { - entity->CastToClient()->Message(13,"You do not own the required locations to enter this zone."); - break; - } - case -1: { - entity->CastToClient()->Message(13,"The zone is currently full, please try again later."); - break; - } - case 0: { - entity->CastToClient()->Message(13,"All zone servers are taken at this time, please try again later."); - break; - } - } - } - else { - // it's a request - ztz->response = 0; - - if(zone->GetMaxClients() != 0 && numclients >= zone->GetMaxClients()) - ztz->response = -1; - else { - ztz->response = 1; - // since they asked about comming, lets assume they are on their way and not shut down. - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); - } - - SendPacket(pack); - break; - } + break; + } + case ServerOP_WhoAllReply:{ + if(!is_zone_loaded) break; - } - case ServerOP_WhoAllReply:{ - if(!is_zone_loaded) - break; - WhoAllReturnStruct* wars= (WhoAllReturnStruct*)pack->pBuffer; - if (wars && wars->id!=0 && wars->id<0xFFFFFFFF){ - Client* client = entity_list.GetClientByID(wars->id); - if (client) { - if(pack->size==64)//no results - client->Message_StringID(0,WHOALL_NO_RESULTS); - else{ - auto outapp = new EQApplicationPacket(OP_WhoAllResponse, pack->size); - memcpy(outapp->pBuffer, pack->pBuffer, pack->size); - client->QueuePacket(outapp); - safe_delete(outapp); - } - } - else { - Log.Out(Logs::Detail, Logs::None, "[CLIENT] id=%i, playerineqstring=%i, playersinzonestring=%i. Dumping WhoAllReturnStruct:", - wars->id, wars->playerineqstring, wars->playersinzonestring); - } - } - else - Log.Out(Logs::General, Logs::Error, "WhoAllReturnStruct: Could not get return struct!"); - break; - } - case ServerOP_EmoteMessage: { - if (!is_zone_loaded) - break; - ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; - if (sem->to[0] != 0) { - if (strcasecmp(sem->to, zone->GetShortName()) == 0) - entity_list.MessageStatus(sem->guilddbid, sem->minstatus, sem->type, (char*)sem->message); - else { - Client* client = entity_list.GetClientByName(sem->to); - if (client != 0){ - char* newmessage=0; - if(strstr(sem->message,"^")==0) - client->Message(sem->type, (char*)sem->message); - else{ - for(newmessage = strtok((char*)sem->message,"^");newmessage!=nullptr;newmessage=strtok(nullptr, "^")) - client->Message(sem->type, newmessage); - } - } - } - } - else{ - char* newmessage=0; - if(strstr(sem->message,"^")==0) - entity_list.MessageStatus(sem->guilddbid, sem->minstatus, sem->type, sem->message); + WhoAllReturnStruct* wars= (WhoAllReturnStruct*)pack->pBuffer; + if (wars && wars->id!=0 && wars->id<0xFFFFFFFF){ + Client* client = entity_list.GetClientByID(wars->id); + if (client) { + if(pack->size==64)//no results + client->Message_StringID(0,WHOALL_NO_RESULTS); else{ - for(newmessage = strtok((char*)sem->message,"^");newmessage!=nullptr;newmessage=strtok(nullptr, "^")) - entity_list.MessageStatus(sem->guilddbid, sem->minstatus, sem->type, newmessage); + auto outapp = new EQApplicationPacket(OP_WhoAllResponse, pack->size); + memcpy(outapp->pBuffer, pack->pBuffer, pack->size); + client->QueuePacket(outapp); + safe_delete(outapp); } } - break; - } - case ServerOP_Motd: { - ServerMotd_Struct* smotd = (ServerMotd_Struct*) pack->pBuffer; - EQApplicationPacket *outapp; - outapp = new EQApplicationPacket(OP_MOTD); - char tmp[500] = {0}; - sprintf(tmp, "%s", smotd->motd); - - outapp->size = strlen(tmp)+1; - outapp->pBuffer = new uchar[outapp->size]; - memset(outapp->pBuffer,0,outapp->size); - strcpy((char*)outapp->pBuffer, tmp); - - entity_list.QueueClients(0, outapp); - safe_delete(outapp); - - break; - } - case ServerOP_ShutdownAll: { - entity_list.Save(); - CatchSignal(2); - break; - } - case ServerOP_ZoneShutdown: { - if (pack->size != sizeof(ServerZoneStateChange_struct)) { - std::cout << "Wrong size on ServerOP_ZoneShutdown. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneStateChange_struct) << std::endl; - break; - } - // Annouce the change to the world - if (!is_zone_loaded) { - SetZoneData(0); - } else { - SendEmoteMessage(0, 0, 15, "Zone shutdown: %s", zone->GetLongName()); - - ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer; - std::cout << "Zone shutdown by " << zst->adminname << std::endl; - Zone::Shutdown(); + Log.Out(Logs::Detail, Logs::None, "[CLIENT] id=%i, playerineqstring=%i, playersinzonestring=%i. Dumping WhoAllReturnStruct:", + wars->id, wars->playerineqstring, wars->playersinzonestring); } + } + else + Log.Out(Logs::General, Logs::Error, "WhoAllReturnStruct: Could not get return struct!"); + break; + } + case ServerOP_EmoteMessage: { + if (!is_zone_loaded) + break; + ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; + if (sem->to[0] != 0) { + if (strcasecmp(sem->to, zone->GetShortName()) == 0) + entity_list.MessageStatus(sem->guilddbid, sem->minstatus, sem->type, (char*)sem->message); + else { + Client* client = entity_list.GetClientByName(sem->to); + if (client != 0){ + char* newmessage=0; + if(strstr(sem->message,"^")==0) + client->Message(sem->type, (char*)sem->message); + else{ + for(newmessage = strtok((char*)sem->message,"^");newmessage!=nullptr;newmessage=strtok(nullptr, "^")) + client->Message(sem->type, newmessage); + } + } + } + } + else{ + char* newmessage=0; + if(strstr(sem->message,"^")==0) + entity_list.MessageStatus(sem->guilddbid, sem->minstatus, sem->type, sem->message); + else{ + for(newmessage = strtok((char*)sem->message,"^");newmessage!=nullptr;newmessage=strtok(nullptr, "^")) + entity_list.MessageStatus(sem->guilddbid, sem->minstatus, sem->type, newmessage); + } + } + break; + } + case ServerOP_Motd: { + ServerMotd_Struct* smotd = (ServerMotd_Struct*) pack->pBuffer; + EQApplicationPacket *outapp; + outapp = new EQApplicationPacket(OP_MOTD); + char tmp[500] = {0}; + sprintf(tmp, "%s", smotd->motd); + + outapp->size = strlen(tmp)+1; + outapp->pBuffer = new uchar[outapp->size]; + memset(outapp->pBuffer,0,outapp->size); + strcpy((char*)outapp->pBuffer, tmp); + + entity_list.QueueClients(0, outapp); + safe_delete(outapp); + + break; + } + case ServerOP_ShutdownAll: { + entity_list.Save(); + CatchSignal(2); + break; + } + case ServerOP_ZoneShutdown: { + if (pack->size != sizeof(ServerZoneStateChange_struct)) { + std::cout << "Wrong size on ServerOP_ZoneShutdown. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneStateChange_struct) << std::endl; break; } - case ServerOP_ZoneBootup: { - if (pack->size != sizeof(ServerZoneStateChange_struct)) { - std::cout << "Wrong size on ServerOP_ZoneBootup. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneStateChange_struct) << std::endl; - break; - } + // Annouce the change to the world + if (!is_zone_loaded) { + SetZoneData(0); + } + else { + SendEmoteMessage(0, 0, 15, "Zone shutdown: %s", zone->GetLongName()); + ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer; - if (is_zone_loaded) { - SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); - if (zst->zoneid == zone->GetZoneID()) { - // This packet also doubles as "incoming client" notification, lets not shut down before they get here - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); - } - else { - SendEmoteMessage(zst->adminname, 0, 0, "Zone bootup failed: Already running '%s'", zone->GetShortName()); - } - break; - } - - if (zst->adminname[0] != 0) - std::cout << "Zone bootup by " << zst->adminname << std::endl; - - Zone::Bootup(zst->zoneid, zst->instanceid, zst->makestatic); + std::cout << "Zone shutdown by " << zst->adminname << std::endl; + Zone::Shutdown(); + } + break; + } + case ServerOP_ZoneBootup: { + if (pack->size != sizeof(ServerZoneStateChange_struct)) { + std::cout << "Wrong size on ServerOP_ZoneBootup. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneStateChange_struct) << std::endl; break; } - case ServerOP_ZoneIncClient: { - if (pack->size != sizeof(ServerZoneIncomingClient_Struct)) { - std::cout << "Wrong size on ServerOP_ZoneIncClient. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneIncomingClient_Struct) << std::endl; - break; - } - ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*) pack->pBuffer; - if (is_zone_loaded) { - SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); - if (szic->zoneid == zone->GetZoneID()) { - zone->AddAuth(szic); - // This packet also doubles as "incoming client" notification, lets not shut down before they get here - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); - } + ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer; + if (is_zone_loaded) { + SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); + if (zst->zoneid == zone->GetZoneID()) { + // This packet also doubles as "incoming client" notification, lets not shut down before they get here + zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } else { - if ((Zone::Bootup(szic->zoneid, szic->instanceid))) { - zone->AddAuth(szic); - } + SendEmoteMessage(zst->adminname, 0, 0, "Zone bootup failed: Already running '%s'", zone->GetShortName()); } break; } - case ServerOP_ZonePlayer: { - ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(szp->name); - printf("Zoning %s to %s(%u) - %u\n", client != nullptr ? client->GetCleanName() : "Unknown", szp->zone, database.GetZoneID(szp->zone), szp->instance_id); - if (client != 0) { - if (strcasecmp(szp->adminname, szp->name) == 0) - client->Message(0, "Zoning to: %s", szp->zone); - else if (client->GetAnon() == 1 && client->Admin() > szp->adminrank) - break; - else { - SendEmoteMessage(szp->adminname, 0, 0, "Summoning %s to %s %1.1f, %1.1f, %1.1f", szp->name, szp->zone, szp->x_pos, szp->y_pos, szp->z_pos); - } - if (!szp->instance_id) { + + if (zst->adminname[0] != 0) + std::cout << "Zone bootup by " << zst->adminname << std::endl; + + Zone::Bootup(zst->zoneid, zst->instanceid, zst->makestatic); + break; + } + case ServerOP_ZoneIncClient: { + if (pack->size != sizeof(ServerZoneIncomingClient_Struct)) { + std::cout << "Wrong size on ServerOP_ZoneIncClient. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneIncomingClient_Struct) << std::endl; + break; + } + ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*) pack->pBuffer; + if (is_zone_loaded) { + SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); + if (szic->zoneid == zone->GetZoneID()) { + zone->AddAuth(szic); + // This packet also doubles as "incoming client" notification, lets not shut down before they get here + zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); + } + } + else { + if ((Zone::Bootup(szic->zoneid, szic->instanceid))) { + zone->AddAuth(szic); + } + } + break; + } + case ServerOP_ZonePlayer: { + ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(szp->name); + printf("Zoning %s to %s(%u) - %u\n", client != nullptr ? client->GetCleanName() : "Unknown", szp->zone, database.GetZoneID(szp->zone), szp->instance_id); + if (client != 0) { + if (strcasecmp(szp->adminname, szp->name) == 0) + client->Message(0, "Zoning to: %s", szp->zone); + else if (client->GetAnon() == 1 && client->Admin() > szp->adminrank) + break; + else { + SendEmoteMessage(szp->adminname, 0, 0, "Summoning %s to %s %1.1f, %1.1f, %1.1f", szp->name, szp->zone, szp->x_pos, szp->y_pos, szp->z_pos); + } + if (!szp->instance_id) { + client->MovePC(database.GetZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); + } else { + if (database.GetInstanceID(client->CharacterID(), database.GetZoneID(szp->zone)) == 0) { + client->AssignToInstance(szp->instance_id); client->MovePC(database.GetZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); } else { - if (database.GetInstanceID(client->CharacterID(), database.GetZoneID(szp->zone)) == 0) { - client->AssignToInstance(szp->instance_id); - client->MovePC(database.GetZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); - } else { - client->RemoveFromInstance(database.GetInstanceID(client->CharacterID(), database.GetZoneID(szp->zone))); - client->AssignToInstance(szp->instance_id); - client->MovePC(database.GetZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); - } + client->RemoveFromInstance(database.GetInstanceID(client->CharacterID(), database.GetZoneID(szp->zone))); + client->AssignToInstance(szp->instance_id); + client->MovePC(database.GetZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); } } - break; } - case ServerOP_KickPlayer: { - ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(skp->name); - if (client != 0) { - if (skp->adminrank >= client->Admin()) { - client->WorldKick(); - if (is_zone_loaded) - SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted in zone %s.", skp->name, zone->GetShortName()); - else - SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted.", skp->name); - } - else if (client->GetAnon() != 1) - SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: Your avatar level is not high enough to kick %s", skp->name); + break; + } + case ServerOP_KickPlayer: { + ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(skp->name); + if (client != 0) { + if (skp->adminrank >= client->Admin()) { + client->WorldKick(); + if (is_zone_loaded) + SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted in zone %s.", skp->name, zone->GetShortName()); + else + SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted.", skp->name); } - break; + else if (client->GetAnon() != 1) + SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: Your avatar level is not high enough to kick %s", skp->name); } - case ServerOP_KillPlayer: { - ServerKillPlayer_Struct* skp = (ServerKillPlayer_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(skp->target); - if (client != 0) { - if (skp->admin >= client->Admin()) { - client->GMKill(); - if (is_zone_loaded) - SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed in zone %s.", skp->target, zone->GetShortName()); - else - SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed.", skp->target); - } - else if (client->GetAnon() != 1) - SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: Your avatar level is not high enough to kill %s", skp->target); + break; + } + case ServerOP_KillPlayer: { + ServerKillPlayer_Struct* skp = (ServerKillPlayer_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(skp->target); + if (client != 0) { + if (skp->admin >= client->Admin()) { + client->GMKill(); + if (is_zone_loaded) + SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed in zone %s.", skp->target, zone->GetShortName()); + else + SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed.", skp->target); } - break; + else if (client->GetAnon() != 1) + SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: Your avatar level is not high enough to kill %s", skp->target); } + break; + } - //hand all the guild related packets to the guild manager for processing. - case ServerOP_OnlineGuildMembersResponse: - case ServerOP_RefreshGuild: -// case ServerOP_GuildInvite: - case ServerOP_DeleteGuild: - case ServerOP_GuildCharRefresh: - case ServerOP_GuildMemberUpdate: - case ServerOP_GuildRankUpdate: - case ServerOP_LFGuildUpdate: -// case ServerOP_GuildGMSet: -// case ServerOP_GuildGMSetRank: -// case ServerOP_GuildJoin: - guild_mgr.ProcessWorldPacket(pack); - break; + //hand all the guild related packets to the guild manager for processing. + case ServerOP_OnlineGuildMembersResponse: + case ServerOP_RefreshGuild: +// case ServerOP_GuildInvite: + case ServerOP_DeleteGuild: + case ServerOP_GuildCharRefresh: + case ServerOP_GuildMemberUpdate: + case ServerOP_GuildRankUpdate: + case ServerOP_LFGuildUpdate: +// case ServerOP_GuildGMSet: +// case ServerOP_GuildGMSetRank: +// case ServerOP_GuildJoin: + guild_mgr.ProcessWorldPacket(pack); + break; - case ServerOP_FlagUpdate: { - Client* client = entity_list.GetClientByAccID(*((uint32*) pack->pBuffer)); - if (client != 0) { - client->UpdateAdmin(); - } + case ServerOP_FlagUpdate: { + Client* client = entity_list.GetClientByAccID(*((uint32*) pack->pBuffer)); + if (client != 0) { + client->UpdateAdmin(); + } + break; + } + case ServerOP_GMGoto: { + if (pack->size != sizeof(ServerGMGoto_Struct)) { + std::cout << "Wrong size on ServerOP_GMGoto. Got: " << pack->size << ", Expected: " << sizeof(ServerGMGoto_Struct) << std::endl; break; } - case ServerOP_GMGoto: { - if (pack->size != sizeof(ServerGMGoto_Struct)) { - std::cout << "Wrong size on ServerOP_GMGoto. Got: " << pack->size << ", Expected: " << sizeof(ServerGMGoto_Struct) << std::endl; - break; - } - if (!is_zone_loaded) - break; - ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(gmg->gotoname); - if (client != 0) { - SendEmoteMessage(gmg->myname, 0, 13, "Summoning you to: %s @ %s, %1.1f, %1.1f, %1.1f", client->GetName(), zone->GetShortName(), client->GetX(), client->GetY(), client->GetZ()); - auto outpack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct)); - ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) outpack->pBuffer; - strcpy(szp->adminname, gmg->myname); - strcpy(szp->name, gmg->myname); - strcpy(szp->zone, zone->GetShortName()); - szp->instance_id = zone->GetInstanceID(); - szp->x_pos = client->GetX(); - szp->y_pos = client->GetY(); - szp->z_pos = client->GetZ(); - SendPacket(outpack); - safe_delete(outpack); - } - else { - SendEmoteMessage(gmg->myname, 0, 13, "Error: %s not found", gmg->gotoname); - } + if (!is_zone_loaded) + break; + ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(gmg->gotoname); + if (client != 0) { + SendEmoteMessage(gmg->myname, 0, 13, "Summoning you to: %s @ %s, %1.1f, %1.1f, %1.1f", client->GetName(), zone->GetShortName(), client->GetX(), client->GetY(), client->GetZ()); + auto outpack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct)); + ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*) outpack->pBuffer; + strcpy(szp->adminname, gmg->myname); + strcpy(szp->name, gmg->myname); + strcpy(szp->zone, zone->GetShortName()); + szp->instance_id = zone->GetInstanceID(); + szp->x_pos = client->GetX(); + szp->y_pos = client->GetY(); + szp->z_pos = client->GetZ(); + SendPacket(outpack); + safe_delete(outpack); + } + else { + SendEmoteMessage(gmg->myname, 0, 13, "Error: %s not found", gmg->gotoname); + } + break; + } + case ServerOP_MultiLineMsg: { + ServerMultiLineMsg_Struct* mlm = (ServerMultiLineMsg_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(mlm->to); + if (client) { + auto outapp = new EQApplicationPacket(OP_MultiLineMsg, strlen(mlm->message)); + strcpy((char*) outapp->pBuffer, mlm->message); + client->QueuePacket(outapp); + safe_delete(outapp); + } + break; + } + case ServerOP_Uptime: { + if (pack->size != sizeof(ServerUptime_Struct)) { + std::cout << "Wrong size on ServerOP_Uptime. Got: " << pack->size << ", Expected: " << sizeof(ServerUptime_Struct) << std::endl; break; } - case ServerOP_MultiLineMsg: { - ServerMultiLineMsg_Struct* mlm = (ServerMultiLineMsg_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(mlm->to); - if (client) { - auto outapp = new EQApplicationPacket(OP_MultiLineMsg, strlen(mlm->message)); - strcpy((char*) outapp->pBuffer, mlm->message); - client->QueuePacket(outapp); - safe_delete(outapp); - } - break; - } - case ServerOP_Uptime: { - if (pack->size != sizeof(ServerUptime_Struct)) { - std::cout << "Wrong size on ServerOP_Uptime. Got: " << pack->size << ", Expected: " << sizeof(ServerUptime_Struct) << std::endl; - break; - } - ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer; - uint32 ms = Timer::GetCurrentTime(); - uint32 d = ms / 86400000; - ms -= d * 86400000; - uint32 h = ms / 3600000; - ms -= h * 3600000; - uint32 m = ms / 60000; - ms -= m * 60000; - uint32 s = ms / 1000; - if (d) - this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02id %02ih %02im %02is", sus->zoneserverid, d, h, m, s); - else if (h) - this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02ih %02im %02is", sus->zoneserverid, h, m, s); - else - this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02im %02is", sus->zoneserverid, m, s); - } - case ServerOP_Petition: { - std::cout << "Got Server Requested Petition List Refresh" << std::endl; - ServerPetitionUpdate_Struct* sus = (ServerPetitionUpdate_Struct*) pack->pBuffer; - // this was typoed to = instead of ==, not that it acts any different now though.. - if (sus->status == 0) petition_list.ReadDatabase(); - else if (sus->status == 1) petition_list.ReadDatabase(); // Until I fix this to be better.... - break; - } - case ServerOP_RezzPlayer: { - RezzPlayer_Struct* srs = (RezzPlayer_Struct*) pack->pBuffer; - if (srs->rezzopcode == OP_RezzRequest) - { - // The Rezz request has arrived in the zone the player to be rezzed is currently in, - // so we send the request to their client which will bring up the confirmation box. - Client* client = entity_list.GetClientByName(srs->rez.your_name); - if (client) - { - if(client->IsRezzPending()) - { - auto Response = new ServerPacket(ServerOP_RezzPlayerReject, - strlen(srs->rez.rezzer_name) + 1); - - char *Buffer = (char *)Response->pBuffer; - sprintf(Buffer, "%s", srs->rez.rezzer_name); - worldserver.SendPacket(Response); - safe_delete(Response); - break; - } - //pendingrezexp is the amount of XP on the corpse. Setting it to a value >= 0 - //also serves to inform Client::OPRezzAnswer to expect a packet. - client->SetPendingRezzData(srs->exp, srs->dbid, srs->rez.spellid, srs->rez.corpse_name); - Log.Out(Logs::Detail, Logs::Spells, "OP_RezzRequest in zone %s for %s, spellid:%i", - zone->GetShortName(), client->GetName(), srs->rez.spellid); - auto outapp = new EQApplicationPacket(OP_RezzRequest, - sizeof(Resurrect_Struct)); - memcpy(outapp->pBuffer, &srs->rez, sizeof(Resurrect_Struct)); - client->QueuePacket(outapp); - safe_delete(outapp); - break; - } - } - if (srs->rezzopcode == OP_RezzComplete){ - // We get here when the Rezz complete packet has come back via the world server - // to the zone that the corpse is in. - Corpse* corpse = entity_list.GetCorpseByName(srs->rez.corpse_name); - if (corpse && corpse->IsCorpse()) { - Log.Out(Logs::Detail, Logs::Spells, "OP_RezzComplete received in zone %s for corpse %s", - zone->GetShortName(), srs->rez.corpse_name); - - Log.Out(Logs::Detail, Logs::Spells, "Found corpse. Marking corpse as rezzed if needed."); - // I don't know why Rezzed is not set to true in CompleteRezz(). - if (!IsEffectInSpell(srs->rez.spellid, SE_SummonToCorpse)) { - corpse->IsRezzed(true); - corpse->CompleteResurrection(); - } - } - } - - break; - } - case ServerOP_RezzPlayerReject: + ServerUptime_Struct* sus = (ServerUptime_Struct*) pack->pBuffer; + uint32 ms = Timer::GetCurrentTime(); + uint32 d = ms / 86400000; + ms -= d * 86400000; + uint32 h = ms / 3600000; + ms -= h * 3600000; + uint32 m = ms / 60000; + ms -= m * 60000; + uint32 s = ms / 1000; + if (d) + this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02id %02ih %02im %02is", sus->zoneserverid, d, h, m, s); + else if (h) + this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02ih %02im %02is", sus->zoneserverid, h, m, s); + else + this->SendEmoteMessage(sus->adminname, 0, 0, "Zone #%i Uptime: %02im %02is", sus->zoneserverid, m, s); + } + case ServerOP_Petition: { + std::cout << "Got Server Requested Petition List Refresh" << std::endl; + ServerPetitionUpdate_Struct* sus = (ServerPetitionUpdate_Struct*) pack->pBuffer; + // this was typoed to = instead of ==, not that it acts any different now though.. + if (sus->status == 0) petition_list.ReadDatabase(); + else if (sus->status == 1) petition_list.ReadDatabase(); // Until I fix this to be better.... + break; + } + case ServerOP_RezzPlayer: { + RezzPlayer_Struct* srs = (RezzPlayer_Struct*) pack->pBuffer; + if (srs->rezzopcode == OP_RezzRequest) { - char *Rezzer = (char *)pack->pBuffer; - - Client* c = entity_list.GetClientByName(Rezzer); - - if (c) - c->Message_StringID(MT_WornOff, REZZ_ALREADY_PENDING); - - break; - } - case ServerOP_ZoneReboot: { - std::cout << "Got Server Requested Zone reboot" << std::endl; - ServerZoneReboot_Struct* zb = (ServerZoneReboot_Struct*) pack->pBuffer; - break; - } - case ServerOP_SyncWorldTime: { - if (zone != 0 && !zone->is_zone_time_localized) { - Log.Out(Logs::Moderate, Logs::Zone_Server, "%s Received Message SyncWorldTime", __FUNCTION__); - - eqTimeOfDay* newtime = (eqTimeOfDay*)pack->pBuffer; - zone->zone_time.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime); - auto outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct)); - TimeOfDay_Struct* time_of_day = (TimeOfDay_Struct*)outapp->pBuffer; - zone->zone_time.GetCurrentEQTimeOfDay(time(0), time_of_day); - entity_list.QueueClients(0, outapp, false); - safe_delete(outapp); - - /* Buffer garbage to generate debug message */ - char time_message[255]; - time_t current_time = time(nullptr); - TimeOfDay_Struct eq_time; - zone->zone_time.GetCurrentEQTimeOfDay(current_time, &eq_time); - - sprintf(time_message, "EQTime [%02d:%s%d %s]", - ((eq_time.hour - 1) % 12) == 0 ? 12 : ((eq_time.hour - 1) % 12), - (eq_time.minute < 10) ? "0" : "", - eq_time.minute, - (eq_time.hour >= 13) ? "pm" : "am" - ); - - Log.Out(Logs::General, Logs::Zone_Server, "Time Broadcast Packet: %s", time_message); - zone->SetZoneHasCurrentTime(true); - - } - if (zone && zone->is_zone_time_localized){ - Log.Out(Logs::General, Logs::Zone_Server, "Received request to sync time from world, but our time is localized currently"); - } - break; - } - case ServerOP_ChangeWID: { - if (pack->size != sizeof(ServerChangeWID_Struct)) { - std::cout << "Wrong size on ServerChangeWID_Struct. Got: " << pack->size << ", Expected: " << sizeof(ServerChangeWID_Struct) << std::endl; - break; - } - ServerChangeWID_Struct* scw = (ServerChangeWID_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByCharID(scw->charid); - if (client) - client->SetWID(scw->newwid); - break; - } - case ServerOP_OOCMute: { - oocmuted = *(pack->pBuffer); - break; - } - case ServerOP_Revoke: { - RevokeStruct* rev = (RevokeStruct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(rev->name); + // The Rezz request has arrived in the zone the player to be rezzed is currently in, + // so we send the request to their client which will bring up the confirmation box. + Client* client = entity_list.GetClientByName(srs->rez.your_name); if (client) { - SendEmoteMessage(rev->adminname, 0, 0, "%s: %srevoking %s", zone->GetShortName(), rev->toggle?"":"un", client->GetName()); - client->SetRevoked(rev->toggle); - } -#if EQDEBUG >= 6 - else - SendEmoteMessage(rev->adminname, 0, 0, "%s: Can't find %s", zone->GetShortName(), rev->name); -#endif - break; - } - case ServerOP_GroupIDReply: { - ServerGroupIDReply_Struct* ids = (ServerGroupIDReply_Struct*) pack->pBuffer; - cur_groupid = ids->start; - last_groupid = ids->end; -#ifdef _EQDEBUG - printf("Got new group id set: %lu -> %lu\n", (unsigned long)cur_groupid, (unsigned long)last_groupid); -#endif - break; - } - case ServerOP_GroupLeave: { - ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer; - if(zone){ - if(gl->zoneid == zone->GetZoneID() && gl->instance_id == zone->GetInstanceID()) - break; - - entity_list.SendGroupLeave(gl->gid, gl->member_name); - } - break; - } - case ServerOP_GroupInvite: { - // A player in another zone invited a player in this zone to join their group. - GroupInvite_Struct* gis = (GroupInvite_Struct*)pack->pBuffer; - - Mob *Invitee = entity_list.GetMob(gis->invitee_name); - - if(Invitee && Invitee->IsClient() && Invitee->CastToClient()->MercOnlyOrNoGroup() && !Invitee->IsRaidGrouped()) - { - auto outapp = new EQApplicationPacket(OP_GroupInvite, sizeof(GroupInvite_Struct)); - memcpy(outapp->pBuffer, gis, sizeof(GroupInvite_Struct)); - Invitee->CastToClient()->QueuePacket(outapp); - safe_delete(outapp); - } - - break; - } - case ServerOP_GroupFollow: { - // Player in another zone accepted a group invitation from a player in this zone. - ServerGroupFollow_Struct* sgfs = (ServerGroupFollow_Struct*) pack->pBuffer; - - Mob* Inviter = entity_list.GetClientByName(sgfs->gf.name1); - - if(Inviter && Inviter->IsClient()) - { - Group* group = entity_list.GetGroupByClient(Inviter->CastToClient()); - - if(!group) + if(client->IsRezzPending()) { - //Make new group - group = new Group(Inviter); + auto Response = new ServerPacket(ServerOP_RezzPlayerReject, + strlen(srs->rez.rezzer_name) + 1); - if (!group) - { - break; - } - - entity_list.AddGroup(group); - - if(group->GetID() == 0) { - Inviter->Message(13, "Unable to get new group id. Cannot create group."); - break; - } - - database.SetGroupID(Inviter->GetName(), group->GetID(), Inviter->CastToClient()->CharacterID(), false); - database.SetGroupLeaderName(group->GetID(), Inviter->GetName()); - group->UpdateGroupAAs(); - - if (Inviter->CastToClient()->ClientVersion() < EQEmu::versions::ClientVersion::SoD) - { - auto outapp = - new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); - GroupJoin_Struct* outgj=(GroupJoin_Struct*)outapp->pBuffer; - strcpy(outgj->membername, Inviter->GetName()); - strcpy(outgj->yourname, Inviter->GetName()); - outgj->action = groupActInviteInitial; // 'You have formed the group'. - group->GetGroupAAs(&outgj->leader_aas); - Inviter->CastToClient()->QueuePacket(outapp); + char *Buffer = (char *)Response->pBuffer; + sprintf(Buffer, "%s", srs->rez.rezzer_name); + worldserver.SendPacket(Response); + safe_delete(Response); + break; + } + //pendingrezexp is the amount of XP on the corpse. Setting it to a value >= 0 + //also serves to inform Client::OPRezzAnswer to expect a packet. + client->SetPendingRezzData(srs->exp, srs->dbid, srs->rez.spellid, srs->rez.corpse_name); + Log.Out(Logs::Detail, Logs::Spells, "OP_RezzRequest in zone %s for %s, spellid:%i", + zone->GetShortName(), client->GetName(), srs->rez.spellid); + auto outapp = new EQApplicationPacket(OP_RezzRequest, + sizeof(Resurrect_Struct)); + memcpy(outapp->pBuffer, &srs->rez, sizeof(Resurrect_Struct)); + client->QueuePacket(outapp); safe_delete(outapp); - } - else - { - // SoD and later - Inviter->CastToClient()->SendGroupCreatePacket(); - Inviter->CastToClient()->SendGroupLeaderChangePacket(Inviter->GetName()); - Inviter->CastToClient()->SendGroupJoinAcknowledge(); - } - } + break; + } + } + if (srs->rezzopcode == OP_RezzComplete){ + // We get here when the Rezz complete packet has come back via the world server + // to the zone that the corpse is in. + Corpse* corpse = entity_list.GetCorpseByName(srs->rez.corpse_name); + if (corpse && corpse->IsCorpse()) { + Log.Out(Logs::Detail, Logs::Spells, "OP_RezzComplete received in zone %s for corpse %s", + zone->GetShortName(), srs->rez.corpse_name); - if(!group) + Log.Out(Logs::Detail, Logs::Spells, "Found corpse. Marking corpse as rezzed if needed."); + // I don't know why Rezzed is not set to true in CompleteRezz(). + if (!IsEffectInSpell(srs->rez.spellid, SE_SummonToCorpse)) { + corpse->IsRezzed(true); + corpse->CompleteResurrection(); + } + } + } + + break; + } + case ServerOP_RezzPlayerReject: + { + char *Rezzer = (char *)pack->pBuffer; + + Client* c = entity_list.GetClientByName(Rezzer); + + if (c) + c->Message_StringID(MT_WornOff, REZZ_ALREADY_PENDING); + + break; + } + case ServerOP_ZoneReboot: { + std::cout << "Got Server Requested Zone reboot" << std::endl; + ServerZoneReboot_Struct* zb = (ServerZoneReboot_Struct*) pack->pBuffer; + break; + } + case ServerOP_SyncWorldTime: { + if (zone != 0 && !zone->is_zone_time_localized) { + Log.Out(Logs::Moderate, Logs::Zone_Server, "%s Received Message SyncWorldTime", __FUNCTION__); + + eqTimeOfDay* newtime = (eqTimeOfDay*)pack->pBuffer; + zone->zone_time.SetCurrentEQTimeOfDay(newtime->start_eqtime, newtime->start_realtime); + auto outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct)); + TimeOfDay_Struct* time_of_day = (TimeOfDay_Struct*)outapp->pBuffer; + zone->zone_time.GetCurrentEQTimeOfDay(time(0), time_of_day); + entity_list.QueueClients(0, outapp, false); + safe_delete(outapp); + + char time_message[255]; + time_t current_time = time(nullptr); + TimeOfDay_Struct eq_time; + zone->zone_time.GetCurrentEQTimeOfDay(current_time, &eq_time); + + sprintf(time_message, "EQTime [%02d:%s%d %s]", + ((eq_time.hour - 1) % 12) == 0 ? 12 : ((eq_time.hour - 1) % 12), + (eq_time.minute < 10) ? "0" : "", + eq_time.minute, + (eq_time.hour >= 13) ? "pm" : "am" + ); + + Log.Out(Logs::General, Logs::Zone_Server, "Time Broadcast Packet: %s", time_message); + zone->SetZoneHasCurrentTime(true); + + } + if (zone && zone->is_zone_time_localized){ + Log.Out(Logs::General, Logs::Zone_Server, "Received request to sync time from world, but our time is localized currently"); + } + break; + } + case ServerOP_ChangeWID: { + if (pack->size != sizeof(ServerChangeWID_Struct)) { + std::cout << "Wrong size on ServerChangeWID_Struct. Got: " << pack->size << ", Expected: " << sizeof(ServerChangeWID_Struct) << std::endl; + break; + } + ServerChangeWID_Struct* scw = (ServerChangeWID_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByCharID(scw->charid); + if (client) + client->SetWID(scw->newwid); + break; + } + case ServerOP_OOCMute: { + oocmuted = *(pack->pBuffer); + break; + } + case ServerOP_Revoke: { + RevokeStruct* rev = (RevokeStruct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(rev->name); + if (client) + { + SendEmoteMessage(rev->adminname, 0, 0, "%s: %srevoking %s", zone->GetShortName(), rev->toggle?"":"un", client->GetName()); + client->SetRevoked(rev->toggle); + } + break; + } + case ServerOP_GroupIDReply: { + ServerGroupIDReply_Struct* ids = (ServerGroupIDReply_Struct*) pack->pBuffer; + cur_groupid = ids->start; + last_groupid = ids->end; + break; + } + case ServerOP_GroupLeave: { + ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer; + if(zone){ + if(gl->zoneid == zone->GetZoneID() && gl->instance_id == zone->GetInstanceID()) + break; + + entity_list.SendGroupLeave(gl->gid, gl->member_name); + } + break; + } + case ServerOP_GroupInvite: { + // A player in another zone invited a player in this zone to join their group. + GroupInvite_Struct* gis = (GroupInvite_Struct*)pack->pBuffer; + + Mob *Invitee = entity_list.GetMob(gis->invitee_name); + + if(Invitee && Invitee->IsClient() && Invitee->CastToClient()->MercOnlyOrNoGroup() && !Invitee->IsRaidGrouped()) + { + auto outapp = new EQApplicationPacket(OP_GroupInvite, sizeof(GroupInvite_Struct)); + memcpy(outapp->pBuffer, gis, sizeof(GroupInvite_Struct)); + Invitee->CastToClient()->QueuePacket(outapp); + safe_delete(outapp); + } + + break; + } + case ServerOP_GroupFollow: { + // Player in another zone accepted a group invitation from a player in this zone. + ServerGroupFollow_Struct* sgfs = (ServerGroupFollow_Struct*) pack->pBuffer; + + Mob* Inviter = entity_list.GetClientByName(sgfs->gf.name1); + + if(Inviter && Inviter->IsClient()) + { + Group* group = entity_list.GetGroupByClient(Inviter->CastToClient()); + + if(!group) + { + //Make new group + group = new Group(Inviter); + + if (!group) { break; } - auto outapp = new EQApplicationPacket(OP_GroupFollow, sizeof(GroupGeneric_Struct)); - GroupGeneric_Struct *gg = (GroupGeneric_Struct *)outapp->pBuffer; - strn0cpy(gg->name1, sgfs->gf.name1, sizeof(gg->name1)); - strn0cpy(gg->name2, sgfs->gf.name2, sizeof(gg->name2)); - Inviter->CastToClient()->QueuePacket(outapp); - safe_delete(outapp); + entity_list.AddGroup(group); - if(!group->AddMember(nullptr, sgfs->gf.name2, sgfs->CharacterID)) + if(group->GetID() == 0) { + Inviter->Message(13, "Unable to get new group id. Cannot create group."); break; - - if(Inviter->CastToClient()->IsLFP()) - Inviter->CastToClient()->UpdateLFP(); - - auto pack2 = new ServerPacket(ServerOP_GroupJoin, sizeof(ServerGroupJoin_Struct)); - ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack2->pBuffer; - gj->gid = group->GetID(); - gj->zoneid = zone->GetZoneID(); - gj->instance_id = zone->GetInstanceID(); - strn0cpy(gj->member_name, sgfs->gf.name2, sizeof(gj->member_name)); - worldserver.SendPacket(pack2); - safe_delete(pack2); - - - - // Send acknowledgement back to the Invitee to let them know we have added them to the group. - auto pack3 = - new ServerPacket(ServerOP_GroupFollowAck, sizeof(ServerGroupFollowAck_Struct)); - ServerGroupFollowAck_Struct* sgfas = (ServerGroupFollowAck_Struct*)pack3->pBuffer; - strn0cpy(sgfas->Name, sgfs->gf.name2, sizeof(sgfas->Name)); - worldserver.SendPacket(pack3); - safe_delete(pack3); - } - break; - } - case ServerOP_GroupFollowAck: { - // The Inviter (in another zone) has successfully added the Invitee (in this zone) to the group. - ServerGroupFollowAck_Struct* sgfas = (ServerGroupFollowAck_Struct*)pack->pBuffer; - - Client *client = entity_list.GetClientByName(sgfas->Name); - - if(!client) - break; - - uint32 groupid = database.GetGroupID(client->GetName()); - - Group* group = nullptr; - - if(groupid > 0) - { - group = entity_list.GetGroupByID(groupid); - - if(!group) - { //nobody from our group is here... start a new group - group = new Group(groupid); - - if(group->GetID() != 0) - entity_list.AddGroup(group, groupid); - else - group = nullptr; } - if(group) - group->UpdatePlayer(client); + database.SetGroupID(Inviter->GetName(), group->GetID(), Inviter->CastToClient()->CharacterID(), false); + database.SetGroupLeaderName(group->GetID(), Inviter->GetName()); + group->UpdateGroupAAs(); + + if (Inviter->CastToClient()->ClientVersion() < EQEmu::versions::ClientVersion::SoD) + { + auto outapp = + new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); + GroupJoin_Struct* outgj=(GroupJoin_Struct*)outapp->pBuffer; + strcpy(outgj->membername, Inviter->GetName()); + strcpy(outgj->yourname, Inviter->GetName()); + outgj->action = groupActInviteInitial; // 'You have formed the group'. + group->GetGroupAAs(&outgj->leader_aas); + Inviter->CastToClient()->QueuePacket(outapp); + safe_delete(outapp); + } else { - if(client->GetMerc()) - database.SetGroupID(client->GetMerc()->GetCleanName(), 0, client->CharacterID(), true); - database.SetGroupID(client->GetName(), 0, client->CharacterID(), false); //cannot re-establish group, kill it + // SoD and later + Inviter->CastToClient()->SendGroupCreatePacket(); + Inviter->CastToClient()->SendGroupLeaderChangePacket(Inviter->GetName()); + Inviter->CastToClient()->SendGroupJoinAcknowledge(); } + } + if(!group) + { + break; + } + + auto outapp = new EQApplicationPacket(OP_GroupFollow, sizeof(GroupGeneric_Struct)); + GroupGeneric_Struct *gg = (GroupGeneric_Struct *)outapp->pBuffer; + strn0cpy(gg->name1, sgfs->gf.name1, sizeof(gg->name1)); + strn0cpy(gg->name2, sgfs->gf.name2, sizeof(gg->name2)); + Inviter->CastToClient()->QueuePacket(outapp); + safe_delete(outapp); + + if(!group->AddMember(nullptr, sgfs->gf.name2, sgfs->CharacterID)) + break; + + if(Inviter->CastToClient()->IsLFP()) + Inviter->CastToClient()->UpdateLFP(); + + auto pack2 = new ServerPacket(ServerOP_GroupJoin, sizeof(ServerGroupJoin_Struct)); + ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack2->pBuffer; + gj->gid = group->GetID(); + gj->zoneid = zone->GetZoneID(); + gj->instance_id = zone->GetInstanceID(); + strn0cpy(gj->member_name, sgfs->gf.name2, sizeof(gj->member_name)); + worldserver.SendPacket(pack2); + safe_delete(pack2); + + + + // Send acknowledgement back to the Invitee to let them know we have added them to the group. + auto pack3 = + new ServerPacket(ServerOP_GroupFollowAck, sizeof(ServerGroupFollowAck_Struct)); + ServerGroupFollowAck_Struct* sgfas = (ServerGroupFollowAck_Struct*)pack3->pBuffer; + strn0cpy(sgfas->Name, sgfs->gf.name2, sizeof(sgfas->Name)); + worldserver.SendPacket(pack3); + safe_delete(pack3); + } + break; + } + case ServerOP_GroupFollowAck: { + // The Inviter (in another zone) has successfully added the Invitee (in this zone) to the group. + ServerGroupFollowAck_Struct* sgfas = (ServerGroupFollowAck_Struct*)pack->pBuffer; + + Client *client = entity_list.GetClientByName(sgfas->Name); + + if(!client) + break; + + uint32 groupid = database.GetGroupID(client->GetName()); + + Group* group = nullptr; + + if(groupid > 0) + { + group = entity_list.GetGroupByID(groupid); + + if(!group) + { //nobody from our group is here... start a new group + group = new Group(groupid); + + if(group->GetID() != 0) + entity_list.AddGroup(group, groupid); + else + group = nullptr; } if(group) + group->UpdatePlayer(client); + else { - if (client->GetMerc()) - { - client->GetMerc()->MercJoinClientGroup(); - } - database.RefreshGroupFromDB(client); - - group->SendHPPacketsTo(client); - - // If the group leader is not set, pull the group leader information from the database. - if(!group->GetLeader()) - { - char ln[64]; - char MainTankName[64]; - char AssistName[64]; - char PullerName[64]; - char NPCMarkerName[64]; - char mentoree_name[64]; - int mentor_percent; - GroupLeadershipAA_Struct GLAA; - memset(ln, 0, 64); - strcpy(ln, database.GetGroupLeadershipInfo(group->GetID(), ln, MainTankName, AssistName, PullerName, NPCMarkerName, mentoree_name, &mentor_percent, &GLAA)); - Client *lc = entity_list.GetClientByName(ln); - if(lc) - group->SetLeader(lc); - - group->SetMainTank(MainTankName); - group->SetMainAssist(AssistName); - group->SetPuller(PullerName); - group->SetNPCMarker(NPCMarkerName); - group->SetGroupAAs(&GLAA); - group->SetGroupMentor(mentor_percent, mentoree_name); - - } + if(client->GetMerc()) + database.SetGroupID(client->GetMerc()->GetCleanName(), 0, client->CharacterID(), true); + database.SetGroupID(client->GetName(), 0, client->CharacterID(), false); //cannot re-establish group, kill it } - else if (client->GetMerc()) + + } + + if(group) + { + if (client->GetMerc()) { client->GetMerc()->MercJoinClientGroup(); } - break; + database.RefreshGroupFromDB(client); - } - case ServerOP_GroupCancelInvite: { + group->SendHPPacketsTo(client); - GroupCancel_Struct* sgcs = (GroupCancel_Struct*) pack->pBuffer; - - Mob* Inviter = entity_list.GetClientByName(sgcs->name1); - - if(Inviter && Inviter->IsClient()) + // If the group leader is not set, pull the group leader information from the database. + if(!group->GetLeader()) { - auto outapp = new EQApplicationPacket(OP_GroupCancelInvite, sizeof(GroupCancel_Struct)); - memcpy(outapp->pBuffer, sgcs, sizeof(GroupCancel_Struct)); - Inviter->CastToClient()->QueuePacket(outapp); - safe_delete(outapp); + char ln[64]; + char MainTankName[64]; + char AssistName[64]; + char PullerName[64]; + char NPCMarkerName[64]; + char mentoree_name[64]; + int mentor_percent; + GroupLeadershipAA_Struct GLAA; + memset(ln, 0, 64); + strcpy(ln, database.GetGroupLeadershipInfo(group->GetID(), ln, MainTankName, AssistName, PullerName, NPCMarkerName, mentoree_name, &mentor_percent, &GLAA)); + Client *lc = entity_list.GetClientByName(ln); + if(lc) + group->SetLeader(lc); + + group->SetMainTank(MainTankName); + group->SetMainAssist(AssistName); + group->SetPuller(PullerName); + group->SetNPCMarker(NPCMarkerName); + group->SetGroupAAs(&GLAA); + group->SetGroupMentor(mentor_percent, mentoree_name); + } - break; } - case ServerOP_GroupJoin: { - ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack->pBuffer; - if(zone){ - if(gj->zoneid == zone->GetZoneID() && gj->instance_id == zone->GetInstanceID()) - break; + else if (client->GetMerc()) + { + client->GetMerc()->MercJoinClientGroup(); + } + break; - Group* g = entity_list.GetGroupByID(gj->gid); - if(g) - g->AddMember(gj->member_name); + } + case ServerOP_GroupCancelInvite: { - entity_list.SendGroupJoin(gj->gid, gj->member_name); + GroupCancel_Struct* sgcs = (GroupCancel_Struct*) pack->pBuffer; + + Mob* Inviter = entity_list.GetClientByName(sgcs->name1); + + if(Inviter && Inviter->IsClient()) + { + auto outapp = new EQApplicationPacket(OP_GroupCancelInvite, sizeof(GroupCancel_Struct)); + memcpy(outapp->pBuffer, sgcs, sizeof(GroupCancel_Struct)); + Inviter->CastToClient()->QueuePacket(outapp); + safe_delete(outapp); + } + break; + } + case ServerOP_GroupJoin: { + ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack->pBuffer; + if(zone){ + if(gj->zoneid == zone->GetZoneID() && gj->instance_id == zone->GetInstanceID()) + break; + + Group* g = entity_list.GetGroupByID(gj->gid); + if(g) + g->AddMember(gj->member_name); + + entity_list.SendGroupJoin(gj->gid, gj->member_name); + } + break; + } + + case ServerOP_ForceGroupUpdate: { + ServerForceGroupUpdate_Struct* fgu = (ServerForceGroupUpdate_Struct*)pack->pBuffer; + if(zone){ + if(fgu->origZoneID == zone->GetZoneID() && fgu->instance_id == zone->GetInstanceID()) + break; + + entity_list.ForceGroupUpdate(fgu->gid); + } + break; + } + + case ServerOP_OOZGroupMessage: { + ServerGroupChannelMessage_Struct* gcm = (ServerGroupChannelMessage_Struct*)pack->pBuffer; + if(zone){ + if(gcm->zoneid == zone->GetZoneID() && gcm->instanceid == zone->GetInstanceID()) + break; + + entity_list.GroupMessage(gcm->groupid, gcm->from, gcm->message); + } + break; + } + case ServerOP_DisbandGroup: { + ServerDisbandGroup_Struct* sd = (ServerDisbandGroup_Struct*)pack->pBuffer; + if(zone){ + if(sd->zoneid == zone->GetZoneID() && sd->instance_id == zone->GetInstanceID()) + break; + + Group *g = entity_list.GetGroupByID(sd->groupid); + if(g) + g->DisbandGroup(); + } + break; + } + case ServerOP_RaidAdd:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->LearnMembers(); + r->VerifyRaid(); + r->SendRaidAddAll(rga->playername); } - break; } + break; + } - case ServerOP_ForceGroupUpdate: { - ServerForceGroupUpdate_Struct* fgu = (ServerForceGroupUpdate_Struct*)pack->pBuffer; - if(zone){ - if(fgu->origZoneID == zone->GetZoneID() && fgu->instance_id == zone->GetInstanceID()) - break; + case ServerOP_RaidRemove:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; - entity_list.ForceGroupUpdate(fgu->gid); + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->SendRaidRemoveAll(rga->playername); + Client *rem = entity_list.GetClientByName(rga->playername); + if(rem){ + r->SendRaidDisband(rem); + } + r->LearnMembers(); + r->VerifyRaid(); } - break; } + break; + } - case ServerOP_OOZGroupMessage: { - ServerGroupChannelMessage_Struct* gcm = (ServerGroupChannelMessage_Struct*)pack->pBuffer; - if(zone){ - if(gcm->zoneid == zone->GetZoneID() && gcm->instanceid == zone->GetInstanceID()) - break; + case ServerOP_RaidDisband:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; - entity_list.GroupMessage(gcm->groupid, gcm->from, gcm->message); + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->SendRaidDisbandAll(); + r->LearnMembers(); + r->VerifyRaid(); } - break; } - case ServerOP_DisbandGroup: { - ServerDisbandGroup_Struct* sd = (ServerDisbandGroup_Struct*)pack->pBuffer; - if(zone){ - if(sd->zoneid == zone->GetZoneID() && sd->instance_id == zone->GetInstanceID()) - break; + break; + } - Group *g = entity_list.GetGroupByID(sd->groupid); - if(g) - g->DisbandGroup(); + case ServerOP_RaidLockFlag:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->GetRaidDetails(); //update our details + if(rga->gid) + r->SendRaidLock(); + else + r->SendRaidUnlock(); } - break; } - case ServerOP_RaidAdd:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; + break; + } - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->LearnMembers(); - r->VerifyRaid(); + case ServerOP_RaidChangeGroup:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->LearnMembers(); + r->VerifyRaid(); + Client *c = entity_list.GetClientByName(rga->playername); + if(c){ + r->SendRaidDisband(c); + r->SendRaidRemoveAll(rga->playername); + r->SendRaidCreate(c); + r->SendMakeLeaderPacketTo(r->leadername, c); + r->SendBulkRaid(c); + r->SendRaidAddAll(rga->playername); + if(r->IsLocked()) { r->SendRaidLockTo(c); } + } + else{ + r->SendRaidRemoveAll(rga->playername); r->SendRaidAddAll(rga->playername); } } - break; } - - case ServerOP_RaidRemove:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->SendRaidRemoveAll(rga->playername); - Client *rem = entity_list.GetClientByName(rga->playername); - if(rem){ - r->SendRaidDisband(rem); - } - r->LearnMembers(); - r->VerifyRaid(); - } - } - break; - } - - case ServerOP_RaidDisband:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->SendRaidDisbandAll(); - r->LearnMembers(); - r->VerifyRaid(); - } - } - break; - } - - case ServerOP_RaidLockFlag:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->GetRaidDetails(); //update our details - if(rga->gid) - r->SendRaidLock(); - else - r->SendRaidUnlock(); - } - } - break; - } - - case ServerOP_RaidChangeGroup:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->LearnMembers(); - r->VerifyRaid(); - Client *c = entity_list.GetClientByName(rga->playername); - if(c){ - r->SendRaidDisband(c); - r->SendRaidRemoveAll(rga->playername); - r->SendRaidCreate(c); - r->SendMakeLeaderPacketTo(r->leadername, c); - r->SendBulkRaid(c); - r->SendRaidAddAll(rga->playername); - if(r->IsLocked()) { r->SendRaidLockTo(c); } - } - else{ - r->SendRaidRemoveAll(rga->playername); - r->SendRaidAddAll(rga->playername); - } - } - } - break; - } - - case ServerOP_UpdateGroup:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->GroupUpdate(rga->gid, false); - } - } - break; - } - - case ServerOP_RaidGroupLeader:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - } - break; - } - - case ServerOP_RaidLeader:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - Client *c = entity_list.GetClientByName(rga->playername); - strn0cpy(r->leadername, rga->playername, 64); - if(c){ - r->SetLeader(c); - } - r->LearnMembers(); - r->VerifyRaid(); - r->SendMakeLeaderPacket(rga->playername); - } - } - break; - } - - case ServerOP_DetailsChange:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->GetRaidDetails(); - r->LearnMembers(); - r->VerifyRaid(); - } - } - break; - } - - case ServerOP_RaidGroupDisband:{ - ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; - if(zone){ - if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) - break; - - Client *c = entity_list.GetClientByName(rga->playername); - if(c) - { - auto outapp = - new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate_Struct)); - GroupUpdate_Struct* gu = (GroupUpdate_Struct*) outapp->pBuffer; - gu->action = groupActDisband; - strn0cpy(gu->leadersname, c->GetName(), 64); - strn0cpy(gu->yourname, c->GetName(), 64); - c->FastQueuePacket(&outapp); - } - } - break; - } - - case ServerOP_RaidGroupAdd:{ - ServerRaidGroupAction_Struct* rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; - if(zone){ - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->LearnMembers(); - r->VerifyRaid(); - auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); - GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer; - strn0cpy(gj->membername, rga->membername, 64); - gj->action = groupActJoin; - - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(r->members[x].member) - { - if(strcmp(r->members[x].member->GetName(), rga->membername) != 0){ - if((rga->gid < 12) && rga->gid == r->members[x].GroupNumber) - { - strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); - r->members[x].member->QueuePacket(outapp); - } - } - } - } - safe_delete(outapp); - } - } - break; - } - - case ServerOP_RaidGroupRemove:{ - ServerRaidGroupAction_Struct* rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; - if(zone){ - Raid *r = entity_list.GetRaidByID(rga->rid); - if(r){ - r->LearnMembers(); - r->VerifyRaid(); - auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); - GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer; - strn0cpy(gj->membername, rga->membername, 64); - gj->action = groupActLeave; - - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(r->members[x].member) - { - if(strcmp(r->members[x].member->GetName(), rga->membername) != 0){ - if((rga->gid < 12) && rga->gid == r->members[x].GroupNumber) - { - strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); - r->members[x].member->QueuePacket(outapp); - } - } - } - } - safe_delete(outapp); - } - } - break; - } - - case ServerOP_RaidGroupSay:{ - ServerRaidMessage_Struct* rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; - if(zone){ - Raid *r = entity_list.GetRaidByID(rmsg->rid); - if(r) - { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(r->members[x].member){ - if(strcmp(rmsg->from, r->members[x].member->GetName()) != 0) - { - if(r->members[x].GroupNumber == rmsg->gid){ - if(r->members[x].member->GetFilter(FilterGroupChat)!=0) - { - r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), 2, 0, rmsg->message); - } - } - } - } - } - } - } - break; - } - - case ServerOP_RaidSay:{ - ServerRaidMessage_Struct* rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; - if(zone) - { - Raid *r = entity_list.GetRaidByID(rmsg->rid); - if(r) - { - for(int x = 0; x < MAX_RAID_MEMBERS; x++) - { - if(r->members[x].member){ - if(strcmp(rmsg->from, r->members[x].member->GetName()) != 0) - { - if(r->members[x].member->GetFilter(FilterGroupChat)!=0) - { - r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), 15, 0, rmsg->message); - } - } - } - } - } - } - break; - } - - case ServerOP_RaidMOTD: { - ServerRaidMOTD_Struct *rmotd = (ServerRaidMOTD_Struct *)pack->pBuffer; - if (!zone) - break; - Raid *r = entity_list.GetRaidByID(rmotd->rid); - if (!r) - break; - r->SetRaidMOTD(std::string(rmotd->motd)); - r->SendRaidMOTD(); - break; - } - - case ServerOP_SpawnPlayerCorpse: { - SpawnPlayerCorpse_Struct* s = (SpawnPlayerCorpse_Struct*)pack->pBuffer; - Corpse* NewCorpse = database.LoadCharacterCorpse(s->player_corpse_id); - if(NewCorpse) - NewCorpse->Spawn(); - else - Log.Out(Logs::General, Logs::Error, "Unable to load player corpse id %u for zone %s.", s->player_corpse_id, zone->GetShortName()); - - break; - } - case ServerOP_Consent: { - ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; - Client* client = entity_list.GetClientByName(s->grantname); - if(client) { - if(s->permission == 1) - client->consent_list.push_back(s->ownername); - else - client->consent_list.remove(s->ownername); - - auto outapp = - new EQApplicationPacket(OP_ConsentResponse, sizeof(ConsentResponse_Struct)); - ConsentResponse_Struct* crs = (ConsentResponse_Struct*)outapp->pBuffer; - strcpy(crs->grantname, s->grantname); - strcpy(crs->ownername, s->ownername); - crs->permission = s->permission; - strcpy(crs->zonename,"all zones"); - client->QueuePacket(outapp); - safe_delete(outapp); - } - else { - // target not found - - // Message string id's likely to be used here are: - // CONSENT_YOURSELF = 399 - // CONSENT_INVALID_NAME = 397 - // TARGET_NOT_FOUND = 101 - - auto scs_pack = - new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); - ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)scs_pack->pBuffer; - strcpy(scs->grantname, s->grantname); - strcpy(scs->ownername, s->ownername); - scs->permission = s->permission; - scs->zone_id = s->zone_id; - scs->instance_id = s->instance_id; - scs->message_string_id = TARGET_NOT_FOUND; - worldserver.SendPacket(scs_pack); - safe_delete(scs_pack); - } - break; - } - case ServerOP_Consent_Response: { - ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; - Client* client = entity_list.GetClientByName(s->ownername); - if(client) { - client->Message_StringID(0, s->message_string_id); - } - break; - } - case ServerOP_ReloadTasks: { - if(RuleB(Tasks,EnableTaskSystem)) { - HandleReloadTasks(pack); - } - break; - } - case ServerOP_LFGMatches: { - HandleLFGMatches(pack); - break; - } - case ServerOP_LFPMatches: { - HandleLFPMatches(pack); - break; - } - - case ServerOP_UpdateSpawn: { - if(zone) - { - UpdateSpawnTimer_Struct *ust = (UpdateSpawnTimer_Struct*)pack->pBuffer; - LinkedListIterator iterator(zone->spawn2_list); - iterator.Reset(); - while (iterator.MoreElements()) - { - if(iterator.GetData()->GetID() == ust->id) - { - if(!iterator.GetData()->NPCPointerValid()) - { - iterator.GetData()->SetTimer(ust->duration); - } - break; - } - iterator.Advance(); - } - } - break; - } - - case ServerOP_InstanceUpdateTime: - { - ServerInstanceUpdateTime_Struct *iut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer; - if(zone) - { - if(zone->GetInstanceID() == iut->instance_id) - { - zone->SetInstanceTimer(iut->new_duration); - } - } - break; - } - - case ServerOP_DepopAllPlayersCorpses: - { - ServerDepopAllPlayersCorpses_Struct *sdapcs = (ServerDepopAllPlayersCorpses_Struct *)pack->pBuffer; - - if(zone && !((zone->GetZoneID() == sdapcs->ZoneID) && (zone->GetInstanceID() == sdapcs->InstanceID))) - entity_list.RemoveAllCorpsesByCharID(sdapcs->CharacterID); - - break; - - } - - case ServerOP_DepopPlayerCorpse: - { - ServerDepopPlayerCorpse_Struct *sdpcs = (ServerDepopPlayerCorpse_Struct *)pack->pBuffer; - - if(zone && !((zone->GetZoneID() == sdpcs->ZoneID) && (zone->GetInstanceID() == sdpcs->InstanceID))) - entity_list.RemoveCorpseByDBID(sdpcs->DBID); - - break; - - } - - case ServerOP_ReloadTitles: - { - title_manager.LoadTitles(); - break; - } - - case ServerOP_SpawnStatusChange: - { - if(zone) - { - ServerSpawnStatusChange_Struct *ssc = (ServerSpawnStatusChange_Struct*)pack->pBuffer; - LinkedListIterator iterator(zone->spawn2_list); - iterator.Reset(); - Spawn2 *found_spawn = nullptr; - while(iterator.MoreElements()) - { - Spawn2* cur = iterator.GetData(); - if(cur->GetID() == ssc->id) - { - found_spawn = cur; - break; - } - iterator.Advance(); - } - - if(found_spawn) - { - if(ssc->new_status == 0) - { - found_spawn->Disable(); - } - else - { - found_spawn->Enable(); - } - } - } - break; - } - - case ServerOP_QGlobalUpdate: - { - if(pack->size != sizeof(ServerQGlobalUpdate_Struct)) - { - break; - } - - if(zone) - { - ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer; - if(qgu->from_zone_id != zone->GetZoneID() || qgu->from_instance_id != zone->GetInstanceID()) - { - QGlobal temp; - temp.npc_id = qgu->npc_id; - temp.char_id = qgu->char_id; - temp.zone_id = qgu->zone_id; - temp.expdate = qgu->expdate; - temp.name.assign(qgu->name); - temp.value.assign(qgu->value); - entity_list.UpdateQGlobal(qgu->id, temp); - zone->UpdateQGlobal(qgu->id, temp); - } - } - break; - } - - case ServerOP_QGlobalDelete: - { - if(pack->size != sizeof(ServerQGlobalDelete_Struct)) - { - break; - } - - if(zone) - { - ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer; - if(qgd->from_zone_id != zone->GetZoneID() || qgd->from_instance_id != zone->GetInstanceID()) - { - entity_list.DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id); - zone->DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id); - } - } - break; - } - - case ServerOP_AdventureRequestAccept: - { - ServerAdventureRequestAccept_Struct *ars = (ServerAdventureRequestAccept_Struct*)pack->pBuffer; - Client *c = entity_list.GetClientByName(ars->leader); - if(c) - { - c->NewAdventure(ars->id, ars->theme, ars->text, ars->member_count, (const char*)(pack->pBuffer + sizeof(ServerAdventureRequestAccept_Struct))); - c->ClearPendingAdventureRequest(); - } - break; - } - - case ServerOP_AdventureRequestDeny: - { - ServerAdventureRequestDeny_Struct *ars = (ServerAdventureRequestDeny_Struct*)pack->pBuffer; - Client *c = entity_list.GetClientByName(ars->leader); - if(c) - { - c->SendAdventureError(ars->reason); - c->ClearPendingAdventureRequest(); - } - break; - } - - case ServerOP_AdventureCreateDeny: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - c->ClearPendingAdventureData(); - c->ClearPendingAdventureCreate(); - } - break; - } - - case ServerOP_AdventureData: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - c->ClearAdventureData(); - auto adv_data = new char[pack->size]; - memcpy(adv_data, pack->pBuffer, pack->size); - c->SetAdventureData(adv_data); - c->ClearPendingAdventureData(); - c->ClearPendingAdventureCreate(); - c->SendAdventureDetails(); - } - break; - } - - case ServerOP_AdventureDataClear: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - if(c->HasAdventureData()) - { - c->ClearAdventureData(); - c->SendAdventureError("You are not currently assigned to an adventure."); - } - } - break; - } - - case ServerOP_AdventureClickDoorReply: - { - ServerPlayerClickedAdventureDoorReply_Struct *adr = (ServerPlayerClickedAdventureDoorReply_Struct*)pack->pBuffer; - Client *c = entity_list.GetClientByName(adr->player); - if(c) - { - c->ClearPendingAdventureDoorClick(); - c->MovePC(adr->zone_id, adr->instance_id, adr->x, adr->y, adr->z, adr->h, 0); - } - break; - } - - case ServerOP_AdventureClickDoorError: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - c->ClearPendingAdventureDoorClick(); - c->Message_StringID(13, 5141); - } - break; - } - - case ServerOP_AdventureLeaveReply: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - c->ClearPendingAdventureLeave(); - c->ClearCurrentAdventure(); - } - break; - } - - case ServerOP_AdventureLeaveDeny: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - c->ClearPendingAdventureLeave(); - c->Message(13, "You cannot leave this adventure at this time."); - } - break; - } - - case ServerOP_AdventureCountUpdate: - { - ServerAdventureCountUpdate_Struct *ac = (ServerAdventureCountUpdate_Struct*)pack->pBuffer; - Client *c = entity_list.GetClientByName(ac->player); - if(c) - { - c->SendAdventureCount(ac->count, ac->total); - } - break; - } - - case ServerOP_AdventureZoneData: - { - if(zone) - { - safe_delete(zone->adv_data); - zone->adv_data = new char[pack->size]; - memcpy(zone->adv_data, pack->pBuffer, pack->size); - ServerZoneAdventureDataReply_Struct* ds = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; - } - break; - } - - case ServerOP_AdventureFinish: - { - ServerAdventureFinish_Struct *af = (ServerAdventureFinish_Struct*)pack->pBuffer; - Client *c = entity_list.GetClientByName(af->player); - if(c) - { - c->AdventureFinish(af->win, af->theme, af->points); - } - break; - } - - case ServerOP_AdventureLeaderboard: - { - Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); - if(c) - { - auto outapp = new EQApplicationPacket(OP_AdventureLeaderboardReply, - sizeof(AdventureLeaderboard_Struct)); - memcpy(outapp->pBuffer, pack->pBuffer+64, sizeof(AdventureLeaderboard_Struct)); - c->FastQueuePacket(&outapp); - } - break; - } - case ServerOP_ReloadRules: - { - RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset()); - break; - } - case ServerOP_ReloadLogs: { - database.LoadLogSettings(Log.log_settings); - break; - } - case ServerOP_ReloadPerlExportSettings: { - parse->LoadPerlEventExportSettings(parse->perl_event_export_settings); - break; - } - case ServerOP_CameraShake: - { - if(zone) - { - ServerCameraShake_Struct *scss = (ServerCameraShake_Struct*)pack->pBuffer; - entity_list.CameraEffect(scss->duration, scss->intensity); - } - break; - } - case ServerOP_QueryServGeneric: - { - pack->SetReadPosition(8); - char From[64]; - pack->ReadString(From); - - Client *c = entity_list.GetClientByName(From); - - if(!c) - return; - - uint32 Type = pack->ReadUInt32();; - - switch(Type) - { - case QSG_LFGuild: - { - c->HandleLFGuildResponse(pack); - break; - } - - default: - break; - } - - break; - } - case ServerOP_CZSetEntityVariableByNPCTypeID: - { - CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer; - NPC* n = entity_list.GetNPCByNPCTypeID(CZM->npctype_id); - if (n != 0) { - n->SetEntityVariable(CZM->id, CZM->m_var); - } - break; - } - case ServerOP_CZSignalNPC: - { - CZNPCSignal_Struct* CZCN = (CZNPCSignal_Struct*)pack->pBuffer; - NPC* n = entity_list.GetNPCByNPCTypeID(CZCN->npctype_id); - if (n != 0) { - n->SignalNPC(CZCN->data); - } - break; - } - case ServerOP_CZSignalClient: - { - CZClientSignal_Struct* CZCS = (CZClientSignal_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByCharID(CZCS->charid); - if (client != 0) { - client->Signal(CZCS->data); - } - break; - } - case ServerOP_CZSignalClientByName: - { - CZClientSignalByName_Struct* CZCS = (CZClientSignalByName_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(CZCS->Name); - if (client != 0) { - client->Signal(CZCS->data); - } - break; - } - case ServerOP_CZMessagePlayer: - { - CZMessagePlayer_Struct* CZCS = (CZMessagePlayer_Struct*) pack->pBuffer; - Client* client = entity_list.GetClientByName(CZCS->CharName); - if (client != 0) { - client->Message(CZCS->Type, CZCS->Message); - } - break; - } - case ServerOP_WWMarquee: - { - WWMarquee_Struct* WWMS = (WWMarquee_Struct*) pack->pBuffer; - std::list client_list; - entity_list.GetClientList(client_list); - auto iter = client_list.begin(); - std::string Message = WWMS->Message; - while (iter != client_list.end()) { - Client* client = (*iter); - client->SendMarqueeMessage(WWMS->Type, WWMS->Priority, WWMS->FadeIn, WWMS->FadeOut, WWMS->Duration, Message); - iter++; - } - } - case ServerOP_ReloadWorld: - { - ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer; - if(zone){ - zone->ReloadWorld(RW->Option); - } - break; - } - - case ServerOP_ChangeSharedMem: - { - std::string hotfix_name = std::string((char*)pack->pBuffer); - Log.Out(Logs::General, Logs::Zone_Server, "Loading items"); - if(!database.LoadItems(hotfix_name)) { - Log.Out(Logs::General, Logs::Error, "Loading items FAILED!"); - } - - Log.Out(Logs::General, Logs::Zone_Server, "Loading npc faction lists"); - if(!database.LoadNPCFactionLists(hotfix_name)) { - Log.Out(Logs::General, Logs::Error, "Loading npcs faction lists FAILED!"); - } - - Log.Out(Logs::General, Logs::Zone_Server, "Loading loot tables"); - if(!database.LoadLoot(hotfix_name)) { - Log.Out(Logs::General, Logs::Error, "Loading loot FAILED!"); - } - - Log.Out(Logs::General, Logs::Zone_Server, "Loading skill caps"); - if(!database.LoadSkillCaps(std::string(hotfix_name))) { - Log.Out(Logs::General, Logs::Error, "Loading skill caps FAILED!"); - } - - Log.Out(Logs::General, Logs::Zone_Server, "Loading spells"); - if(!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) { - Log.Out(Logs::General, Logs::Error, "Loading spells FAILED!"); - } - - Log.Out(Logs::General, Logs::Zone_Server, "Loading base data"); - if(!database.LoadBaseData(hotfix_name)) { - Log.Out(Logs::General, Logs::Error, "Loading base data FAILED!"); - } - break; - } - default: { - std::cout << " Unknown ZSopcode:" << (int)pack->opcode; - std::cout << " size:" << pack->size << std::endl; - break; - } - } - safe_delete(pack); + break; } - return; + case ServerOP_UpdateGroup:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->GroupUpdate(rga->gid, false); + } + } + break; + } + + case ServerOP_RaidGroupLeader:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + } + break; + } + + case ServerOP_RaidLeader:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + Client *c = entity_list.GetClientByName(rga->playername); + strn0cpy(r->leadername, rga->playername, 64); + if(c){ + r->SetLeader(c); + } + r->LearnMembers(); + r->VerifyRaid(); + r->SendMakeLeaderPacket(rga->playername); + } + } + break; + } + + case ServerOP_DetailsChange:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->GetRaidDetails(); + r->LearnMembers(); + r->VerifyRaid(); + } + } + break; + } + + case ServerOP_RaidGroupDisband:{ + ServerRaidGeneralAction_Struct* rga = (ServerRaidGeneralAction_Struct*)pack->pBuffer; + if(zone){ + if(rga->zoneid == zone->GetZoneID() && rga->instance_id == zone->GetInstanceID()) + break; + + Client *c = entity_list.GetClientByName(rga->playername); + if(c) + { + auto outapp = + new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupUpdate_Struct)); + GroupUpdate_Struct* gu = (GroupUpdate_Struct*) outapp->pBuffer; + gu->action = groupActDisband; + strn0cpy(gu->leadersname, c->GetName(), 64); + strn0cpy(gu->yourname, c->GetName(), 64); + c->FastQueuePacket(&outapp); + } + } + break; + } + + case ServerOP_RaidGroupAdd:{ + ServerRaidGroupAction_Struct* rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; + if(zone){ + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->LearnMembers(); + r->VerifyRaid(); + auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); + GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer; + strn0cpy(gj->membername, rga->membername, 64); + gj->action = groupActJoin; + + for(int x = 0; x < MAX_RAID_MEMBERS; x++) + { + if(r->members[x].member) + { + if(strcmp(r->members[x].member->GetName(), rga->membername) != 0){ + if((rga->gid < 12) && rga->gid == r->members[x].GroupNumber) + { + strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); + r->members[x].member->QueuePacket(outapp); + } + } + } + } + safe_delete(outapp); + } + } + break; + } + + case ServerOP_RaidGroupRemove:{ + ServerRaidGroupAction_Struct* rga = (ServerRaidGroupAction_Struct*)pack->pBuffer; + if(zone){ + Raid *r = entity_list.GetRaidByID(rga->rid); + if(r){ + r->LearnMembers(); + r->VerifyRaid(); + auto outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct)); + GroupJoin_Struct* gj = (GroupJoin_Struct*) outapp->pBuffer; + strn0cpy(gj->membername, rga->membername, 64); + gj->action = groupActLeave; + + for(int x = 0; x < MAX_RAID_MEMBERS; x++) + { + if(r->members[x].member) + { + if(strcmp(r->members[x].member->GetName(), rga->membername) != 0){ + if((rga->gid < 12) && rga->gid == r->members[x].GroupNumber) + { + strn0cpy(gj->yourname, r->members[x].member->GetName(), 64); + r->members[x].member->QueuePacket(outapp); + } + } + } + } + safe_delete(outapp); + } + } + break; + } + + case ServerOP_RaidGroupSay:{ + ServerRaidMessage_Struct* rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; + if(zone){ + Raid *r = entity_list.GetRaidByID(rmsg->rid); + if(r) + { + for(int x = 0; x < MAX_RAID_MEMBERS; x++) + { + if(r->members[x].member){ + if(strcmp(rmsg->from, r->members[x].member->GetName()) != 0) + { + if(r->members[x].GroupNumber == rmsg->gid){ + if(r->members[x].member->GetFilter(FilterGroupChat)!=0) + { + r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), 2, 0, rmsg->message); + } + } + } + } + } + } + } + break; + } + + case ServerOP_RaidSay:{ + ServerRaidMessage_Struct* rmsg = (ServerRaidMessage_Struct*)pack->pBuffer; + if(zone) + { + Raid *r = entity_list.GetRaidByID(rmsg->rid); + if(r) + { + for(int x = 0; x < MAX_RAID_MEMBERS; x++) + { + if(r->members[x].member){ + if(strcmp(rmsg->from, r->members[x].member->GetName()) != 0) + { + if(r->members[x].member->GetFilter(FilterGroupChat)!=0) + { + r->members[x].member->ChannelMessageSend(rmsg->from, r->members[x].member->GetName(), 15, 0, rmsg->message); + } + } + } + } + } + } + break; + } + + case ServerOP_RaidMOTD: { + ServerRaidMOTD_Struct *rmotd = (ServerRaidMOTD_Struct *)pack->pBuffer; + if (!zone) + break; + Raid *r = entity_list.GetRaidByID(rmotd->rid); + if (!r) + break; + r->SetRaidMOTD(std::string(rmotd->motd)); + r->SendRaidMOTD(); + break; + } + + case ServerOP_SpawnPlayerCorpse: { + SpawnPlayerCorpse_Struct* s = (SpawnPlayerCorpse_Struct*)pack->pBuffer; + Corpse* NewCorpse = database.LoadCharacterCorpse(s->player_corpse_id); + if(NewCorpse) + NewCorpse->Spawn(); + else + Log.Out(Logs::General, Logs::Error, "Unable to load player corpse id %u for zone %s.", s->player_corpse_id, zone->GetShortName()); + + break; + } + case ServerOP_Consent: { + ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; + Client* client = entity_list.GetClientByName(s->grantname); + if(client) { + if(s->permission == 1) + client->consent_list.push_back(s->ownername); + else + client->consent_list.remove(s->ownername); + + auto outapp = + new EQApplicationPacket(OP_ConsentResponse, sizeof(ConsentResponse_Struct)); + ConsentResponse_Struct* crs = (ConsentResponse_Struct*)outapp->pBuffer; + strcpy(crs->grantname, s->grantname); + strcpy(crs->ownername, s->ownername); + crs->permission = s->permission; + strcpy(crs->zonename,"all zones"); + client->QueuePacket(outapp); + safe_delete(outapp); + } + else { + // target not found + + // Message string id's likely to be used here are: + // CONSENT_YOURSELF = 399 + // CONSENT_INVALID_NAME = 397 + // TARGET_NOT_FOUND = 101 + + auto scs_pack = + new ServerPacket(ServerOP_Consent_Response, sizeof(ServerOP_Consent_Struct)); + ServerOP_Consent_Struct* scs = (ServerOP_Consent_Struct*)scs_pack->pBuffer; + strcpy(scs->grantname, s->grantname); + strcpy(scs->ownername, s->ownername); + scs->permission = s->permission; + scs->zone_id = s->zone_id; + scs->instance_id = s->instance_id; + scs->message_string_id = TARGET_NOT_FOUND; + worldserver.SendPacket(scs_pack); + safe_delete(scs_pack); + } + break; + } + case ServerOP_Consent_Response: { + ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; + Client* client = entity_list.GetClientByName(s->ownername); + if(client) { + client->Message_StringID(0, s->message_string_id); + } + break; + } + case ServerOP_ReloadTasks: { + if(RuleB(Tasks,EnableTaskSystem)) { + HandleReloadTasks(pack); + } + break; + } + case ServerOP_LFGMatches: { + HandleLFGMatches(pack); + break; + } + case ServerOP_LFPMatches: { + HandleLFPMatches(pack); + break; + } + + case ServerOP_UpdateSpawn: { + if(zone) + { + UpdateSpawnTimer_Struct *ust = (UpdateSpawnTimer_Struct*)pack->pBuffer; + LinkedListIterator iterator(zone->spawn2_list); + iterator.Reset(); + while (iterator.MoreElements()) + { + if(iterator.GetData()->GetID() == ust->id) + { + if(!iterator.GetData()->NPCPointerValid()) + { + iterator.GetData()->SetTimer(ust->duration); + } + break; + } + iterator.Advance(); + } + } + break; + } + + case ServerOP_InstanceUpdateTime: + { + ServerInstanceUpdateTime_Struct *iut = (ServerInstanceUpdateTime_Struct*)pack->pBuffer; + if(zone) + { + if(zone->GetInstanceID() == iut->instance_id) + { + zone->SetInstanceTimer(iut->new_duration); + } + } + break; + } + + case ServerOP_DepopAllPlayersCorpses: + { + ServerDepopAllPlayersCorpses_Struct *sdapcs = (ServerDepopAllPlayersCorpses_Struct *)pack->pBuffer; + + if(zone && !((zone->GetZoneID() == sdapcs->ZoneID) && (zone->GetInstanceID() == sdapcs->InstanceID))) + entity_list.RemoveAllCorpsesByCharID(sdapcs->CharacterID); + + break; + + } + + case ServerOP_DepopPlayerCorpse: + { + ServerDepopPlayerCorpse_Struct *sdpcs = (ServerDepopPlayerCorpse_Struct *)pack->pBuffer; + + if(zone && !((zone->GetZoneID() == sdpcs->ZoneID) && (zone->GetInstanceID() == sdpcs->InstanceID))) + entity_list.RemoveCorpseByDBID(sdpcs->DBID); + + break; + + } + + case ServerOP_ReloadTitles: + { + title_manager.LoadTitles(); + break; + } + + case ServerOP_SpawnStatusChange: + { + if(zone) + { + ServerSpawnStatusChange_Struct *ssc = (ServerSpawnStatusChange_Struct*)pack->pBuffer; + LinkedListIterator iterator(zone->spawn2_list); + iterator.Reset(); + Spawn2 *found_spawn = nullptr; + while(iterator.MoreElements()) + { + Spawn2* cur = iterator.GetData(); + if(cur->GetID() == ssc->id) + { + found_spawn = cur; + break; + } + iterator.Advance(); + } + + if(found_spawn) + { + if(ssc->new_status == 0) + { + found_spawn->Disable(); + } + else + { + found_spawn->Enable(); + } + } + } + break; + } + + case ServerOP_QGlobalUpdate: + { + if(pack->size != sizeof(ServerQGlobalUpdate_Struct)) + { + break; + } + + if(zone) + { + ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer; + if(qgu->from_zone_id != zone->GetZoneID() || qgu->from_instance_id != zone->GetInstanceID()) + { + QGlobal temp; + temp.npc_id = qgu->npc_id; + temp.char_id = qgu->char_id; + temp.zone_id = qgu->zone_id; + temp.expdate = qgu->expdate; + temp.name.assign(qgu->name); + temp.value.assign(qgu->value); + entity_list.UpdateQGlobal(qgu->id, temp); + zone->UpdateQGlobal(qgu->id, temp); + } + } + break; + } + + case ServerOP_QGlobalDelete: + { + if(pack->size != sizeof(ServerQGlobalDelete_Struct)) + { + break; + } + + if(zone) + { + ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer; + if(qgd->from_zone_id != zone->GetZoneID() || qgd->from_instance_id != zone->GetInstanceID()) + { + entity_list.DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id); + zone->DeleteQGlobal(std::string((char*)qgd->name), qgd->npc_id, qgd->char_id, qgd->zone_id); + } + } + break; + } + + case ServerOP_AdventureRequestAccept: + { + ServerAdventureRequestAccept_Struct *ars = (ServerAdventureRequestAccept_Struct*)pack->pBuffer; + Client *c = entity_list.GetClientByName(ars->leader); + if(c) + { + c->NewAdventure(ars->id, ars->theme, ars->text, ars->member_count, (const char*)(pack->pBuffer + sizeof(ServerAdventureRequestAccept_Struct))); + c->ClearPendingAdventureRequest(); + } + break; + } + + case ServerOP_AdventureRequestDeny: + { + ServerAdventureRequestDeny_Struct *ars = (ServerAdventureRequestDeny_Struct*)pack->pBuffer; + Client *c = entity_list.GetClientByName(ars->leader); + if(c) + { + c->SendAdventureError(ars->reason); + c->ClearPendingAdventureRequest(); + } + break; + } + + case ServerOP_AdventureCreateDeny: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + c->ClearPendingAdventureData(); + c->ClearPendingAdventureCreate(); + } + break; + } + + case ServerOP_AdventureData: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + c->ClearAdventureData(); + auto adv_data = new char[pack->size]; + memcpy(adv_data, pack->pBuffer, pack->size); + c->SetAdventureData(adv_data); + c->ClearPendingAdventureData(); + c->ClearPendingAdventureCreate(); + c->SendAdventureDetails(); + } + break; + } + + case ServerOP_AdventureDataClear: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + if(c->HasAdventureData()) + { + c->ClearAdventureData(); + c->SendAdventureError("You are not currently assigned to an adventure."); + } + } + break; + } + + case ServerOP_AdventureClickDoorReply: + { + ServerPlayerClickedAdventureDoorReply_Struct *adr = (ServerPlayerClickedAdventureDoorReply_Struct*)pack->pBuffer; + Client *c = entity_list.GetClientByName(adr->player); + if(c) + { + c->ClearPendingAdventureDoorClick(); + c->MovePC(adr->zone_id, adr->instance_id, adr->x, adr->y, adr->z, adr->h, 0); + } + break; + } + + case ServerOP_AdventureClickDoorError: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + c->ClearPendingAdventureDoorClick(); + c->Message_StringID(13, 5141); + } + break; + } + + case ServerOP_AdventureLeaveReply: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + c->ClearPendingAdventureLeave(); + c->ClearCurrentAdventure(); + } + break; + } + + case ServerOP_AdventureLeaveDeny: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + c->ClearPendingAdventureLeave(); + c->Message(13, "You cannot leave this adventure at this time."); + } + break; + } + + case ServerOP_AdventureCountUpdate: + { + ServerAdventureCountUpdate_Struct *ac = (ServerAdventureCountUpdate_Struct*)pack->pBuffer; + Client *c = entity_list.GetClientByName(ac->player); + if(c) + { + c->SendAdventureCount(ac->count, ac->total); + } + break; + } + + case ServerOP_AdventureZoneData: + { + if(zone) + { + safe_delete(zone->adv_data); + zone->adv_data = new char[pack->size]; + memcpy(zone->adv_data, pack->pBuffer, pack->size); + ServerZoneAdventureDataReply_Struct* ds = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; + } + break; + } + + case ServerOP_AdventureFinish: + { + ServerAdventureFinish_Struct *af = (ServerAdventureFinish_Struct*)pack->pBuffer; + Client *c = entity_list.GetClientByName(af->player); + if(c) + { + c->AdventureFinish(af->win, af->theme, af->points); + } + break; + } + + case ServerOP_AdventureLeaderboard: + { + Client *c = entity_list.GetClientByName((const char*)pack->pBuffer); + if(c) + { + auto outapp = new EQApplicationPacket(OP_AdventureLeaderboardReply, + sizeof(AdventureLeaderboard_Struct)); + memcpy(outapp->pBuffer, pack->pBuffer+64, sizeof(AdventureLeaderboard_Struct)); + c->FastQueuePacket(&outapp); + } + break; + } + case ServerOP_ReloadRules: + { + RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset()); + break; + } + case ServerOP_ReloadLogs: { + database.LoadLogSettings(Log.log_settings); + break; + } + case ServerOP_ReloadPerlExportSettings: { + parse->LoadPerlEventExportSettings(parse->perl_event_export_settings); + break; + } + case ServerOP_CameraShake: + { + if(zone) + { + ServerCameraShake_Struct *scss = (ServerCameraShake_Struct*)pack->pBuffer; + entity_list.CameraEffect(scss->duration, scss->intensity); + } + break; + } + case ServerOP_QueryServGeneric: + { + pack->SetReadPosition(8); + char From[64]; + pack->ReadString(From); + + Client *c = entity_list.GetClientByName(From); + + if(!c) + return; + + uint32 Type = pack->ReadUInt32();; + + switch(Type) + { + case QSG_LFGuild: + { + c->HandleLFGuildResponse(pack); + break; + } + + default: + break; + } + + break; + } + case ServerOP_CZSetEntityVariableByNPCTypeID: + { + CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer; + NPC* n = entity_list.GetNPCByNPCTypeID(CZM->npctype_id); + if (n != 0) { + n->SetEntityVariable(CZM->id, CZM->m_var); + } + break; + } + case ServerOP_CZSignalNPC: + { + CZNPCSignal_Struct* CZCN = (CZNPCSignal_Struct*)pack->pBuffer; + NPC* n = entity_list.GetNPCByNPCTypeID(CZCN->npctype_id); + if (n != 0) { + n->SignalNPC(CZCN->data); + } + break; + } + case ServerOP_CZSignalClient: + { + CZClientSignal_Struct* CZCS = (CZClientSignal_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByCharID(CZCS->charid); + if (client != 0) { + client->Signal(CZCS->data); + } + break; + } + case ServerOP_CZSignalClientByName: + { + CZClientSignalByName_Struct* CZCS = (CZClientSignalByName_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(CZCS->Name); + if (client != 0) { + client->Signal(CZCS->data); + } + break; + } + case ServerOP_CZMessagePlayer: + { + CZMessagePlayer_Struct* CZCS = (CZMessagePlayer_Struct*) pack->pBuffer; + Client* client = entity_list.GetClientByName(CZCS->CharName); + if (client != 0) { + client->Message(CZCS->Type, CZCS->Message); + } + break; + } + case ServerOP_WWMarquee: + { + WWMarquee_Struct* WWMS = (WWMarquee_Struct*) pack->pBuffer; + std::list client_list; + entity_list.GetClientList(client_list); + auto iter = client_list.begin(); + std::string Message = WWMS->Message; + while (iter != client_list.end()) { + Client* client = (*iter); + client->SendMarqueeMessage(WWMS->Type, WWMS->Priority, WWMS->FadeIn, WWMS->FadeOut, WWMS->Duration, Message); + iter++; + } + } + case ServerOP_ReloadWorld: + { + ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer; + if(zone){ + zone->ReloadWorld(RW->Option); + } + break; + } + + case ServerOP_ChangeSharedMem: + { + std::string hotfix_name = std::string((char*)pack->pBuffer); + Log.Out(Logs::General, Logs::Zone_Server, "Loading items"); + if(!database.LoadItems(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading items FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading npc faction lists"); + if(!database.LoadNPCFactionLists(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading npcs faction lists FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading loot tables"); + if(!database.LoadLoot(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading loot FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading skill caps"); + if(!database.LoadSkillCaps(std::string(hotfix_name))) { + Log.Out(Logs::General, Logs::Error, "Loading skill caps FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading spells"); + if(!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) { + Log.Out(Logs::General, Logs::Error, "Loading spells FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading base data"); + if(!database.LoadBaseData(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading base data FAILED!"); + } + break; + } + default: { + std::cout << " Unknown ZSopcode:" << (int)pack->opcode; + std::cout << " size:" << pack->size << std::endl; + break; + } + } } bool WorldServer::SendChannelMessage(Client* from, const char* to, uint8 chan_num, uint32 guilddbid, uint8 language, const char* message, ...) { diff --git a/zone/worldserver.h b/zone/worldserver.h index e1831ea4c..7dc6b02f8 100644 --- a/zone/worldserver.h +++ b/zone/worldserver.h @@ -18,27 +18,31 @@ #ifndef WORLDSERVER_H #define WORLDSERVER_H -#include "../common/worldconn.h" #include "../common/eq_packet_structs.h" +#include "../common/net/servertalk_client_connection.h" class ServerPacket; class EQApplicationPacket; class Client; -class WorldServer : public WorldConnection { +class WorldServer { public: WorldServer(); - virtual ~WorldServer(); + ~WorldServer(); - virtual void Process(); + void Connect(); + bool SendPacket(ServerPacket* pack); + std::string GetIP() const; + uint16 GetPort() const; + bool Connected() const; + + void HandleMessage(uint16 opcode, const EQ::Net::Packet &p); - void SendGuildJoin(GuildJoin_Struct* gj); bool SendChannelMessage(Client* from, const char* to, uint8 chan_num, uint32 guilddbid, uint8 language, const char* message, ...); bool SendEmoteMessage(const char* to, uint32 to_guilddbid, uint32 type, const char* message, ...); bool SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...); bool SendVoiceMacro(Client* From, uint32 Type, char* Target, uint32 MacroNumber, uint32 GroupOrRaidID = 0); void SetZoneData(uint32 iZoneID, uint32 iInstanceID = 0); - uint32 SendGroupIdRequest(); bool RezzPlayer(EQApplicationPacket* rpack, uint32 rezzexp, uint32 dbid, uint16 opcode); bool IsOOCMuted() const { return(oocmuted); } @@ -67,6 +71,8 @@ private: uint32 cur_groupid; uint32 last_groupid; + + std::unique_ptr m_connection; }; #endif