diff --git a/CMakeLists.txt b/CMakeLists.txt index 00c12e28..cd657772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,6 +314,7 @@ add_subdirectory(dGame) add_subdirectory(dZoneManager) add_subdirectory(dNavigation) add_subdirectory(dPhysics) +add_subdirectory(dServer) # Create a list of common libraries shared between all binaries set(COMMON_LIBRARIES "dCommon" "dDatabase" "dNet" "raknet" "mariadbConnCpp" "magic_enum") diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index c2cfbfcc..5593f0e1 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -25,6 +25,9 @@ #include "eAuthMessageType.h" #include "Game.h" +#include "Server.h" + + namespace Game { Logger* logger = nullptr; dServer* server = nullptr; @@ -33,7 +36,6 @@ namespace Game { std::mt19937 randomEngine; } -Logger* SetupLogger(); void HandlePacket(Packet* packet); int main(int argc, char** argv) { @@ -46,14 +48,11 @@ int main(int argc, char** argv) { std::signal(SIGINT, Game::OnSignal); std::signal(SIGTERM, Game::OnSignal); - //Create all the objects we need to run our service: - Game::logger = SetupLogger(); - if (!Game::logger) return EXIT_FAILURE; - - //Read our config: Game::config = new dConfig("authconfig.ini"); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + + //Create all the objects we need to run our service: + Server::SetupLogger("AuthServer"); + if (!Game::logger) return EXIT_FAILURE; LOG("Starting Auth server..."); LOG("Version: %s", PROJECT_VERSION); @@ -162,18 +161,6 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } -Logger* SetupLogger() { - std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/AuthServer_" + std::to_string(time(nullptr)) + ".log")).string(); - bool logToConsole = false; - bool logDebugStatements = false; -#ifdef _DEBUG - logToConsole = true; - logDebugStatements = true; -#endif - - return new Logger(logPath, logToConsole, logDebugStatements); -} - void HandlePacket(Packet* packet) { if (packet->length < 4) return; diff --git a/dAuthServer/CMakeLists.txt b/dAuthServer/CMakeLists.txt index ebcbccad..7dcbf041 100644 --- a/dAuthServer/CMakeLists.txt +++ b/dAuthServer/CMakeLists.txt @@ -1,3 +1,7 @@ add_executable(AuthServer "AuthServer.cpp") -target_link_libraries(AuthServer ${COMMON_LIBRARIES}) + +target_link_libraries(AuthServer ${COMMON_LIBRARIES} dServer) + +target_include_directories(AuthServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer) + add_compile_definitions(AuthServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") diff --git a/dChatServer/CMakeLists.txt b/dChatServer/CMakeLists.txt index b6a3efb8..cc4cee1f 100644 --- a/dChatServer/CMakeLists.txt +++ b/dChatServer/CMakeLists.txt @@ -6,7 +6,9 @@ set(DCHATSERVER_SOURCES add_executable(ChatServer "ChatServer.cpp") add_library(dChatServer ${DCHATSERVER_SOURCES}) +target_include_directories(dChatServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer) add_compile_definitions(ChatServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") target_link_libraries(dChatServer ${COMMON_LIBRARIES} dChatFilter) -target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer) +target_link_libraries(ChatServer ${COMMON_LIBRARIES} dChatFilter dChatServer dServer) + diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index 8e1d3adf..8ab66d73 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -22,6 +22,7 @@ #include "ChatIgnoreList.h" #include "Game.h" +#include "Server.h" //RakNet includes: #include "RakNetDefines.h" @@ -38,7 +39,6 @@ namespace Game { PlayerContainer playerContainer; } -Logger* SetupLogger(); void HandlePacket(Packet* packet); int main(int argc, char** argv) { @@ -51,14 +51,13 @@ int main(int argc, char** argv) { std::signal(SIGINT, Game::OnSignal); std::signal(SIGTERM, Game::OnSignal); + Game::config = new dConfig("chatconfig.ini"); + //Create all the objects we need to run our service: - Game::logger = SetupLogger(); + Server::SetupLogger("ChatServer"); if (!Game::logger) return EXIT_FAILURE; //Read our config: - Game::config = new dConfig("chatconfig.ini"); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); LOG("Starting Chat server..."); LOG("Version: %s", PROJECT_VERSION); @@ -182,18 +181,6 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } -Logger* SetupLogger() { - std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/ChatServer_" + std::to_string(time(nullptr)) + ".log")).string(); - bool logToConsole = false; - bool logDebugStatements = false; -#ifdef _DEBUG - logToConsole = true; - logDebugStatements = true; -#endif - - return new Logger(logPath, logToConsole, logDebugStatements); -} - void HandlePacket(Packet* packet) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { LOG("A server has disconnected, erasing their connected players from the list."); diff --git a/dMasterServer/CMakeLists.txt b/dMasterServer/CMakeLists.txt index 108cddc2..32a7b1ec 100644 --- a/dMasterServer/CMakeLists.txt +++ b/dMasterServer/CMakeLists.txt @@ -9,7 +9,8 @@ add_executable(MasterServer "MasterServer.cpp") add_compile_definitions(MasterServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") target_link_libraries(dMasterServer ${COMMON_LIBRARIES}) -target_link_libraries(MasterServer ${COMMON_LIBRARIES} dMasterServer) +target_link_libraries(MasterServer ${COMMON_LIBRARIES} dMasterServer dServer) +target_include_directories(dMasterServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer) if(WIN32) add_dependencies(MasterServer WorldServer AuthServer ChatServer) diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index e5997b51..a5691e49 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -40,6 +40,7 @@ #include "FdbToSqlite.h" #include "BitStreamUtils.h" #include "Start.h" +#include "Server.h" namespace Game { Logger* logger = nullptr; @@ -55,7 +56,6 @@ namespace Game { bool shutdownSequenceStarted = false; int ShutdownSequence(int32_t signal = -1); int32_t FinalizeShutdown(int32_t signal = -1); -Logger* SetupLogger(); void HandlePacket(Packet* packet); std::map activeSessions; SystemAddress authServerMasterPeerSysAddr; @@ -77,8 +77,10 @@ int main(int argc, char** argv) { std::signal(SIGINT, Game::OnSignal); std::signal(SIGTERM, Game::OnSignal); + Game::config = new dConfig("masterconfig.ini"); + //Create all the objects we need to run our service: - Game::logger = SetupLogger(); + Server::SetupLogger("MasterServer"); if (!Game::logger) return EXIT_FAILURE; if (!dConfig::Exists("authconfig.ini")) LOG("Could not find authconfig.ini, using default settings"); @@ -87,9 +89,6 @@ int main(int argc, char** argv) { if (!dConfig::Exists("sharedconfig.ini")) LOG("Could not find sharedconfig.ini, using default settings"); if (!dConfig::Exists("worldconfig.ini")) LOG("Could not find worldconfig.ini, using default settings"); - Game::config = new dConfig("masterconfig.ini"); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); uint32_t clientNetVersion = 171022; const auto clientNetVersionString = Game::config->GetValue("client_net_version"); @@ -395,19 +394,6 @@ int main(int argc, char** argv) { return ShutdownSequence(EXIT_SUCCESS); } -Logger* SetupLogger() { - std::string logPath = - (BinaryPathFinder::GetBinaryDir() / ("logs/MasterServer_" + std::to_string(time(nullptr)) + ".log")).string(); - bool logToConsole = false; - bool logDebugStatements = false; -#ifdef _DEBUG - logToConsole = true; - logDebugStatements = true; -#endif - - return new Logger(logPath, logToConsole, logDebugStatements); -} - void HandlePacket(Packet* packet) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION) { LOG("A server has disconnected"); diff --git a/dServer/CMakeLists.txt b/dServer/CMakeLists.txt new file mode 100644 index 00000000..356e55b7 --- /dev/null +++ b/dServer/CMakeLists.txt @@ -0,0 +1,6 @@ +set(DSERVER_SOURCES + "Server.cpp") + +add_library(dServer STATIC ${DSERVER_SOURCES}) + +target_include_directories(dServer PUBLIC ".") diff --git a/dServer/Server.cpp b/dServer/Server.cpp new file mode 100644 index 00000000..cd801a3b --- /dev/null +++ b/dServer/Server.cpp @@ -0,0 +1,29 @@ +#include "Server.h" + +#include "BinaryPathFinder.h" +#include "Game.h" +#include "Logger.h" +#include "dConfig.h" + +void Server::SetupLogger(const std::string_view serviceName) { + if (Game::logger) { + LOG("A logger has already been setup, skipping."); + return; + } + + const auto logsDir = BinaryPathFinder::GetBinaryDir() / "logs"; + + if (!std::filesystem::exists(logsDir)) std::filesystem::create_directory(logsDir); + + std::string logPath = (logsDir / serviceName).string() + "_" + std::to_string(time(nullptr)) + ".log"; + bool logToConsole = false; + bool logDebugStatements = false; +#ifdef _DEBUG + logToConsole = true; + logDebugStatements = true; +#endif + Game::logger = new Logger(logPath, logToConsole, logDebugStatements); + + Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); + Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); +} diff --git a/dServer/Server.h b/dServer/Server.h new file mode 100644 index 00000000..4e9f2543 --- /dev/null +++ b/dServer/Server.h @@ -0,0 +1,10 @@ +#ifndef __SERVER__H__ +#define __SERVER__H__ + +#include + +namespace Server { + void SetupLogger(const std::string_view serviceName); +}; + +#endif //!__SERVER__H__ diff --git a/dWorldServer/CMakeLists.txt b/dWorldServer/CMakeLists.txt index 336a60f9..41cba0e2 100644 --- a/dWorldServer/CMakeLists.txt +++ b/dWorldServer/CMakeLists.txt @@ -7,5 +7,6 @@ add_executable(WorldServer "WorldServer.cpp") add_compile_definitions(WorldServer PRIVATE PROJECT_VERSION="\"${PROJECT_VERSION}\"") target_link_libraries(dWorldServer ${COMMON_LIBRARIES}) -target_link_libraries(WorldServer ${COMMON_LIBRARIES} dChatFilter dGame dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dNavigation) +target_link_libraries(WorldServer ${COMMON_LIBRARIES} dChatFilter dGame dZoneManager dPhysics Detour Recast tinyxml2 dWorldServer dNavigation dServer) +target_include_directories(WorldServer PRIVATE ${PROJECT_SOURCE_DIR}/dServer) diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index f911f804..d65596b6 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -77,6 +77,7 @@ #include "CheatDetection.h" #include "eGameMasterLevel.h" #include "StringifiedEnum.h" +#include "Server.h" namespace Game { Logger* logger = nullptr; @@ -102,8 +103,8 @@ void WorldShutdownProcess(uint32_t zoneId); void FinalizeShutdown(); void SendShutdownMessageToMaster(); -Logger* SetupLogger(uint32_t zoneID, uint32_t instanceID); void HandlePacketChat(Packet* packet); +void HandleMasterPacket(Packet* packet); void HandlePacket(Packet* packet); struct tempSessionInfo { @@ -143,14 +144,11 @@ int main(int argc, char** argv) { if (argument == "-port") ourPort = atoi(argv[i + 1]); } - //Create all the objects we need to run our service: - Game::logger = SetupLogger(zoneID, instanceID); - if (!Game::logger) return EXIT_FAILURE; - - //Read our config: Game::config = new dConfig("worldconfig.ini"); - Game::logger->SetLogToConsole(Game::config->GetValue("log_to_console") != "0"); - Game::logger->SetLogDebugStatements(Game::config->GetValue("log_debug_statements") == "1"); + + //Create all the objects we need to run our service: + Server::SetupLogger("WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID)); + if (!Game::logger) return EXIT_FAILURE; LOG("Starting World server..."); LOG("Version: %s", Game::projectVersion.c_str()); @@ -412,7 +410,7 @@ int main(int argc, char** argv) { //Check for packets here: packet = Game::server->ReceiveFromMaster(); if (packet) { //We can get messages not handle-able by the dServer class, so handle them if we returned anything. - HandlePacket(packet); + HandleMasterPacket(packet); Game::server->DeallocateMasterPacket(packet); } @@ -529,18 +527,6 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } -Logger* SetupLogger(uint32_t zoneID, uint32_t instanceID) { - std::string logPath = (BinaryPathFinder::GetBinaryDir() / ("logs/WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(instanceID) + "_" + std::to_string(time(nullptr)) + ".log")).string(); - bool logToConsole = false; - bool logDebugStatements = false; -#ifdef _DEBUG - logToConsole = true; - logDebugStatements = true; -#endif - - return new Logger(logPath, logToConsole, logDebugStatements); -} - void HandlePacketChat(Packet* packet) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { LOG("Lost our connection to chat, zone(%i), instance(%i)", Game::server->GetZoneID(), Game::server->GetInstanceID()); @@ -672,6 +658,138 @@ void HandlePacketChat(Packet* packet) { } } +void HandleMasterPacket(Packet* packet) { + + if (static_cast(packet->data[1]) != eConnectionType::MASTER || packet->length < 4) return; + switch (static_cast(packet->data[3])) { + case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { + uint64_t requestID = PacketUtils::ReadU64(8, packet); + uint32_t objectID = PacketUtils::ReadU32(16, packet); + ObjectIDManager::HandleRequestPersistentIDResponse(requestID, objectID); + break; + } + + case eMasterMessageType::SESSION_KEY_RESPONSE: { + //Read our session key and to which user it belongs: + RakNet::BitStream inStream(packet->data, packet->length, false); + uint64_t header = inStream.Read(header); + uint32_t sessionKey = 0; + std::string username; + + inStream.Read(sessionKey); + username = PacketUtils::ReadString(12, packet, false); + + //Find them: + auto it = m_PendingUsers.find(username); + if (it == m_PendingUsers.end()) return; + + //Convert our key: + std::string userHash = std::to_string(sessionKey); + userHash = md5(userHash); + + //Verify it: + if (userHash != it->second.hash) { + LOG("SOMEONE IS TRYING TO HACK? SESSION KEY MISMATCH: ours: %s != master: %s", userHash.c_str(), it->second.hash.c_str()); + Game::server->Disconnect(it->second.sysAddr, eServerDisconnectIdentifiers::INVALID_SESSION_KEY); + return; + } else { + LOG("User %s authenticated with correct key.", username.c_str()); + + UserManager::Instance()->DeleteUser(packet->systemAddress); + + //Create our user and send them in: + UserManager::Instance()->CreateUser(it->second.sysAddr, username, userHash); + + auto zone = Game::zoneManager->GetZone(); + if (zone) { + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + + if (zone->GetZoneID().GetMapID() == 1100) { + auto pos = zone->GetSpawnPos(); + x = pos.x; + y = pos.y; + z = pos.z; + } + + WorldPackets::SendLoadStaticZone(it->second.sysAddr, x, y, z, zone->GetChecksum()); + } + + if (Game::server->GetZoneID() == 0) { + //Since doing this reroute breaks the client's request, we have to call this manually. + UserManager::Instance()->RequestCharacterList(it->second.sysAddr); + } + + m_PendingUsers.erase(username); + + //Notify master: + { + CBITSTREAM; + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_ADDED); + bitStream.Write((LWOMAPID)Game::server->GetZoneID()); + bitStream.Write((LWOINSTANCEID)instanceID); + Game::server->SendToMaster(&bitStream); + } + } + + break; + } + case eMasterMessageType::AFFIRM_TRANSFER_REQUEST: { + const uint64_t requestID = PacketUtils::ReadU64(8, packet); + + LOG("Got affirmation request of transfer %llu", requestID); + + CBITSTREAM; + + BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_RESPONSE); + bitStream.Write(requestID); + Game::server->SendToMaster(&bitStream); + + break; + } + + case eMasterMessageType::SHUTDOWN: { + Game::lastSignal = -1; + LOG("Got shutdown request from master, zone (%i), instance (%i)", Game::server->GetZoneID(), Game::server->GetInstanceID()); + break; + } + + case eMasterMessageType::NEW_SESSION_ALERT: { + RakNet::BitStream inStream(packet->data, packet->length, false); + uint64_t header = inStream.Read(header); + uint32_t sessionKey = inStream.Read(sessionKey); + + std::string username; + + uint32_t len; + inStream.Read(len); + + for (uint32_t i = 0; i < len; i++) { + char character; inStream.Read(character); + username += character; + } + + //Find them: + User* user = UserManager::Instance()->GetUser(username.c_str()); + if (!user) { + LOG("Got new session alert for user %s, but they're not logged in.", username.c_str()); + return; + } + + //Check the key: + if (sessionKey != std::atoi(user->GetSessionKey().c_str())) { + LOG("Got new session alert for user %s, but the session key is invalid.", username.c_str()); + Game::server->Disconnect(user->GetSystemAddress(), eServerDisconnectIdentifiers::INVALID_SESSION_KEY); + return; + } + break; + } + default: + LOG("Unknown packet ID from master %i", int(packet->data[3])); + } +} + void HandlePacket(Packet* packet) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION || packet->data[0] == ID_CONNECTION_LOST) { auto user = UserManager::Instance()->GetUser(packet->systemAddress); @@ -730,145 +848,6 @@ void HandlePacket(Packet* packet) { } } - if (static_cast(packet->data[1]) == eConnectionType::MASTER) { - switch (static_cast(packet->data[3])) { - case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { - uint64_t requestID = PacketUtils::ReadU64(8, packet); - uint32_t objectID = PacketUtils::ReadU32(16, packet); - ObjectIDManager::HandleRequestPersistentIDResponse(requestID, objectID); - break; - } - - case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: { - uint64_t requestID = PacketUtils::ReadU64(8, packet); - ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); - break; - } - - case eMasterMessageType::SESSION_KEY_RESPONSE: { - //Read our session key and to which user it belongs: - RakNet::BitStream inStream(packet->data, packet->length, false); - uint64_t header = inStream.Read(header); - uint32_t sessionKey = 0; - std::string username; - - inStream.Read(sessionKey); - username = PacketUtils::ReadString(12, packet, false); - - //Find them: - auto it = m_PendingUsers.find(username); - if (it == m_PendingUsers.end()) return; - - //Convert our key: - std::string userHash = std::to_string(sessionKey); - userHash = md5(userHash); - - //Verify it: - if (userHash != it->second.hash) { - LOG("SOMEONE IS TRYING TO HACK? SESSION KEY MISMATCH: ours: %s != master: %s", userHash.c_str(), it->second.hash.c_str()); - Game::server->Disconnect(it->second.sysAddr, eServerDisconnectIdentifiers::INVALID_SESSION_KEY); - return; - } else { - LOG("User %s authenticated with correct key.", username.c_str()); - - UserManager::Instance()->DeleteUser(packet->systemAddress); - - //Create our user and send them in: - UserManager::Instance()->CreateUser(it->second.sysAddr, username, userHash); - - auto zone = Game::zoneManager->GetZone(); - if (zone) { - float x = 0.0f; - float y = 0.0f; - float z = 0.0f; - - if (zone->GetZoneID().GetMapID() == 1100) { - auto pos = zone->GetSpawnPos(); - x = pos.x; - y = pos.y; - z = pos.z; - } - - WorldPackets::SendLoadStaticZone(it->second.sysAddr, x, y, z, zone->GetChecksum()); - } - - if (Game::server->GetZoneID() == 0) { - //Since doing this reroute breaks the client's request, we have to call this manually. - UserManager::Instance()->RequestCharacterList(it->second.sysAddr); - } - - m_PendingUsers.erase(username); - - //Notify master: - { - CBITSTREAM; - BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_ADDED); - bitStream.Write((LWOMAPID)Game::server->GetZoneID()); - bitStream.Write((LWOINSTANCEID)instanceID); - Game::server->SendToMaster(&bitStream); - } - } - - break; - } - case eMasterMessageType::AFFIRM_TRANSFER_REQUEST: { - const uint64_t requestID = PacketUtils::ReadU64(8, packet); - - LOG("Got affirmation request of transfer %llu", requestID); - - CBITSTREAM; - - BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_RESPONSE); - bitStream.Write(requestID); - Game::server->SendToMaster(&bitStream); - - break; - } - - case eMasterMessageType::SHUTDOWN: { - Game::lastSignal = -1; - LOG("Got shutdown request from master, zone (%i), instance (%i)", Game::server->GetZoneID(), Game::server->GetInstanceID()); - break; - } - - case eMasterMessageType::NEW_SESSION_ALERT: { - RakNet::BitStream inStream(packet->data, packet->length, false); - uint64_t header = inStream.Read(header); - uint32_t sessionKey = inStream.Read(sessionKey); - - std::string username; - - uint32_t len; - inStream.Read(len); - - for (uint32_t i = 0; i < len; i++) { - char character; inStream.Read(character); - username += character; - } - - //Find them: - User* user = UserManager::Instance()->GetUser(username.c_str()); - if (!user) { - LOG("Got new session alert for user %s, but they're not logged in.", username.c_str()); - return; - } - - //Check the key: - if (sessionKey != std::atoi(user->GetSessionKey().c_str())) { - LOG("Got new session alert for user %s, but the session key is invalid.", username.c_str()); - Game::server->Disconnect(user->GetSystemAddress(), eServerDisconnectIdentifiers::INVALID_SESSION_KEY); - return; - } - break; - } - - default: - LOG("Unknown packet ID from master %i", int(packet->data[3])); - } - - return; - } - if (static_cast(packet->data[1]) != eConnectionType::WORLD) return; switch (static_cast(packet->data[3])) {