From 259ba527dfdd62a3a6f57a776214a6a6d8d82233 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 4 Jan 2024 22:37:40 -0800 Subject: [PATCH 1/5] Logger to Server class Dont handle master packets from our clients --- CMakeLists.txt | 1 + dAuthServer/AuthServer.cpp | 25 +-- dAuthServer/CMakeLists.txt | 6 +- dChatServer/CMakeLists.txt | 4 +- dChatServer/ChatServer.cpp | 21 +-- dMasterServer/CMakeLists.txt | 3 +- dMasterServer/MasterServer.cpp | 22 +-- dServer/CMakeLists.txt | 6 + dServer/Server.cpp | 29 ++++ dServer/Server.h | 11 ++ dWorldServer/CMakeLists.txt | 3 +- dWorldServer/WorldServer.cpp | 297 +++++++++++++++------------------ 12 files changed, 211 insertions(+), 217 deletions(-) create mode 100644 dServer/CMakeLists.txt create mode 100644 dServer/Server.cpp create mode 100644 dServer/Server.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 91a26dc5c..638b81d4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -313,6 +313,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 414c572f5..8d2bb8415 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,15 +48,12 @@ int main(int argc, char** argv) { std::signal(SIGINT, Game::OnSignal); std::signal(SIGTERM, Game::OnSignal); + Game::config = new dConfig("authconfig.ini"); + //Create all the objects we need to run our service: - Game::logger = SetupLogger(); + Server::SetupLogger("AuthServer"); 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"); - LOG("Starting Auth server..."); LOG("Version: %s", PROJECT_VERSION); LOG("Compiled on: %s", __TIMESTAMP__); @@ -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 ebcbccad4..7dcbf0413 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 b6a3efb85..cc4cee1f5 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 72220d830..d2ef2344f 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 2ebdee376..200bb09d9 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 15d8db153..e9aeb80fb 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 000000000..356e55b7b --- /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 000000000..cd801a3b3 --- /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 000000000..f187e1abf --- /dev/null +++ b/dServer/Server.h @@ -0,0 +1,11 @@ +#ifndef __SERVER__H__ +#define __SERVER__H__ + +#include + +class Server { +public: + static void SetupLogger(const std::string_view serviceName); +}; + +#endif //!__SERVER__H__ diff --git a/dWorldServer/CMakeLists.txt b/dWorldServer/CMakeLists.txt index a790487e9..3cd832f7c 100644 --- a/dWorldServer/CMakeLists.txt +++ b/dWorldServer/CMakeLists.txt @@ -8,5 +8,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 c8866b135..876864744 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,15 +144,12 @@ int main(int argc, char** argv) { if (argument == "-port") ourPort = atoi(argv[i + 1]); } + Game::config = new dConfig("worldconfig.ini"); + //Create all the objects we need to run our service: - Game::logger = SetupLogger(zoneID, instanceID); + Server::SetupLogger("WorldServer_" + std::to_string(zoneID) + "_" + std::to_string(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"); - LOG("Starting World server..."); LOG("Version: %s", Game::projectVersion.c_str()); LOG("Compiled on: %s", __TIMESTAMP__); @@ -413,7 +411,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); } @@ -530,18 +528,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()); @@ -673,6 +659,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::Instance()->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); @@ -731,145 +849,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::Instance()->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])) { From eb539b1a3f3d85ff359c3371a83fbbc6e512f8be Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 4 Jan 2024 22:51:06 -0800 Subject: [PATCH 2/5] move to namespace Revert "remove extra headers" This reverts commit ac7b901ece22165cdb0f38fca4be7d8fdf004de8. remove extra headers no changes otherwise. --- dServer/Server.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dServer/Server.h b/dServer/Server.h index f187e1abf..4e9f2543d 100644 --- a/dServer/Server.h +++ b/dServer/Server.h @@ -3,9 +3,8 @@ #include -class Server { -public: - static void SetupLogger(const std::string_view serviceName); +namespace Server { + void SetupLogger(const std::string_view serviceName); }; #endif //!__SERVER__H__ From cd4378cafefe05436ee25b25b29feed6dae02985 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Fri, 5 Jan 2024 21:55:25 -0600 Subject: [PATCH 3/5] Merge branch 'main' into server_consolidation_of_work --- CMakeLists.txt | 1 + dAuthServer/AuthServer.cpp | 2 +- dChatServer/ChatServer.cpp | 2 +- dCommon/AmfSerialize.h | 2 +- dCommon/GeneralUtils.h | 2 +- dCommon/ZCompression.cpp | 2 +- dCommon/dClient/AssetManager.cpp | 2 +- dGame/Character.h | 2 +- dGame/Entity.cpp | 2 +- dGame/EntityManager.cpp | 4 +- dGame/TradingManager.cpp | 4 +- dGame/User.h | 2 +- dGame/UserManager.cpp | 8 +- dGame/dBehaviors/ProjectileAttackBehavior.cpp | 4 +- dGame/dComponents/ActivityComponent.cpp | 2 +- dGame/dComponents/BaseCombatAIComponent.cpp | 2 +- dGame/dComponents/BouncerComponent.cpp | 2 +- dGame/dComponents/BuffComponent.cpp | 2 +- dGame/dComponents/CharacterComponent.cpp | 2 +- dGame/dComponents/Component.h | 2 +- dGame/dComponents/DestroyableComponent.cpp | 2 +- dGame/dComponents/InventoryComponent.cpp | 8 +- dGame/dComponents/PetComponent.cpp | 4 +- .../dComponents/PropertyEntranceComponent.cpp | 2 +- .../PropertyManagementComponent.cpp | 4 +- dGame/dComponents/QuickBuildComponent.h | 2 +- dGame/dComponents/RenderComponent.h | 2 +- dGame/dGameMessages/GameMessageHandler.cpp | 2 +- dGame/dGameMessages/GameMessages.cpp | 12 +-- dGame/dInventory/Item.cpp | 2 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 4 +- dGame/dUtilities/CMakeLists.txt | 1 + dGame/dUtilities/ObjectIDManager.cpp | 51 +++++++++++++ dGame/dUtilities/ObjectIDManager.h | 40 ++++++++++ dGame/dUtilities/SlashCommandHandler.cpp | 50 +++---------- dGame/dUtilities/VanityUtilities.cpp | 4 +- dMasterServer/CMakeLists.txt | 2 +- dMasterServer/MasterServer.cpp | 19 ++--- dMasterServer/ObjectIDManager.h | 47 ------------ ...tIDManager.cpp => PersistentIDManager.cpp} | 27 +++---- dMasterServer/PersistentIDManager.h | 23 ++++++ dNet/AuthPackets.cpp | 2 +- dNet/PacketUtils.h | 4 +- dNet/ZoneInstanceManager.h | 2 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 2 +- dWorldServer/CMakeLists.txt | 1 - dWorldServer/ObjectIDManager.cpp | 55 -------------- dWorldServer/ObjectIDManager.h | 75 ------------------- dWorldServer/WorldServer.cpp | 1 - dZoneManager/dZoneManager.cpp | 4 +- docs/Commands.md | 43 ++++++----- tests/dCommonTests/dCommonDependencies.h | 2 - .../dEnumsTests/MagicEnumTests.cpp | 29 +++---- 53 files changed, 244 insertions(+), 335 deletions(-) create mode 100644 dGame/dUtilities/ObjectIDManager.cpp create mode 100644 dGame/dUtilities/ObjectIDManager.h delete mode 100644 dMasterServer/ObjectIDManager.h rename dMasterServer/{ObjectIDManager.cpp => PersistentIDManager.cpp} (58%) create mode 100644 dMasterServer/PersistentIDManager.h delete mode 100644 dWorldServer/ObjectIDManager.cpp delete mode 100644 dWorldServer/ObjectIDManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 638b81d4f..cd6577722 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,6 +243,7 @@ set(INCLUDED_DIRECTORIES "thirdparty/recastnavigation" "thirdparty/SQLite" "thirdparty/cpplinq" + "thirdparty/cpp-httplib" "tests" "tests/dCommonTests" diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 8d2bb8415..5593f0e19 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -16,7 +16,7 @@ //RakNet includes: #include "RakNetDefines.h" -#include +#include "MessageIdentifiers.h" //Auth includes: #include "AuthPackets.h" diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index d2ef2344f..8ab66d733 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -26,7 +26,7 @@ //RakNet includes: #include "RakNetDefines.h" -#include +#include "MessageIdentifiers.h" namespace Game { Logger* logger = nullptr; diff --git a/dCommon/AmfSerialize.h b/dCommon/AmfSerialize.h index 9a6f56f28..06abae74a 100644 --- a/dCommon/AmfSerialize.h +++ b/dCommon/AmfSerialize.h @@ -4,7 +4,7 @@ #include "Amf3.h" // RakNet -#include +#include "BitStream.h" /*! \file AmfSerialize.h diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 964a864bb..37291ab80 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include "BitStream.h" #include "NiPoint3.h" #include "Game.h" diff --git a/dCommon/ZCompression.cpp b/dCommon/ZCompression.cpp index d5d4c126d..e5b3c8fb4 100644 --- a/dCommon/ZCompression.cpp +++ b/dCommon/ZCompression.cpp @@ -1,6 +1,6 @@ #include "ZCompression.h" -#include +#include "zlib.h" namespace ZCompression { int32_t GetMaxCompressedLength(int32_t nLenSrc) { diff --git a/dCommon/dClient/AssetManager.cpp b/dCommon/dClient/AssetManager.cpp index 98a71e372..59427ee52 100644 --- a/dCommon/dClient/AssetManager.cpp +++ b/dCommon/dClient/AssetManager.cpp @@ -4,7 +4,7 @@ #include "Game.h" #include "Logger.h" -#include +#include "zlib.h" AssetManager::AssetManager(const std::filesystem::path& path) { if (!std::filesystem::is_directory(path)) { diff --git a/dGame/Character.h b/dGame/Character.h index 77a52f447..6c8ead30b 100644 --- a/dGame/Character.h +++ b/dGame/Character.h @@ -3,7 +3,7 @@ #include "dCommonVars.h" #include -#include "../thirdparty/tinyxml2/tinyxml2.h" +#include "tinyxml2.h" #include #include diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index fce2aefe7..aaa01e975 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -3,7 +3,7 @@ #include "CDClientManager.h" #include "Game.h" #include "Logger.h" -#include +#include "PacketUtils.h" #include #include "CDDestructibleComponentTable.h" #include "CDClientDatabase.h" diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index 493e910e5..a098dbcf6 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -2,7 +2,7 @@ #include "RakNetTypes.h" #include "Game.h" #include "User.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "Character.h" #include "GeneralUtils.h" #include "dServer.h" @@ -89,7 +89,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE // Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID if (info.id == 0) { - id = ObjectIDManager::Instance()->GenerateObjectID(); + id = ObjectIDManager::GenerateObjectID(); } // Entities with an ID already set, often level entities, we'll use that ID as a base diff --git a/dGame/TradingManager.cpp b/dGame/TradingManager.cpp index 7c3c9bb67..3d9a209c5 100644 --- a/dGame/TradingManager.cpp +++ b/dGame/TradingManager.cpp @@ -2,7 +2,7 @@ #include "EntityManager.h" #include "GameMessages.h" #include "InventoryComponent.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "Game.h" #include "Logger.h" #include "Item.h" @@ -273,7 +273,7 @@ void TradingManager::CancelTrade(LWOOBJID tradeId) { } Trade* TradingManager::NewTrade(LWOOBJID participantA, LWOOBJID participantB) { - const LWOOBJID tradeId = ObjectIDManager::Instance()->GenerateObjectID(); + const LWOOBJID tradeId = ObjectIDManager::GenerateObjectID(); auto* trade = new Trade(tradeId, participantA, participantB); diff --git a/dGame/User.h b/dGame/User.h index 5d9ea8f13..54e6ad529 100644 --- a/dGame/User.h +++ b/dGame/User.h @@ -3,7 +3,7 @@ #include #include -#include "../thirdparty/raknet/Source/RakNetTypes.h" +#include "RakNetTypes.h" #include "dCommonVars.h" #include diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 9afd38b21..736339a43 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -8,11 +8,11 @@ #include "Game.h" #include "Logger.h" #include "User.h" -#include +#include "WorldPackets.h" #include "Character.h" -#include +#include "BitStream.h" #include "PacketUtils.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "Logger.h" #include "GeneralUtils.h" #include "ZoneInstanceManager.h" @@ -263,7 +263,7 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) } //Now that the name is ok, we can get an objectID from Master: - ObjectIDManager::Instance()->RequestPersistentID([=, this](uint32_t objectID) { + ObjectIDManager::RequestPersistentID([=, this](uint32_t objectID) { if (Database::Get()->GetCharacterInfo(objectID)) { LOG("Character object id unavailable, check object_id_tracker!"); WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::OBJECT_ID_UNAVAILABLE); diff --git a/dGame/dBehaviors/ProjectileAttackBehavior.cpp b/dGame/dBehaviors/ProjectileAttackBehavior.cpp index c63a3d6fe..732ff186c 100644 --- a/dGame/dBehaviors/ProjectileAttackBehavior.cpp +++ b/dGame/dBehaviors/ProjectileAttackBehavior.cpp @@ -5,7 +5,7 @@ #include "Game.h" #include "Logger.h" #include "SkillComponent.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "eObjectBits.h" void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { @@ -106,7 +106,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt const auto maxTime = this->m_maxDistance / this->m_projectileSpeed; for (auto i = 0u; i < this->m_projectileCount; ++i) { - auto id = static_cast(ObjectIDManager::Instance()->GenerateObjectID()); + auto id = static_cast(ObjectIDManager::GenerateObjectID()); GeneralUtils::SetBit(id, eObjectBits::SPAWNED); diff --git a/dGame/dComponents/ActivityComponent.cpp b/dGame/dComponents/ActivityComponent.cpp index 55bc4c08a..7ea7500b1 100644 --- a/dGame/dComponents/ActivityComponent.cpp +++ b/dGame/dComponents/ActivityComponent.cpp @@ -7,7 +7,7 @@ #include "ZoneInstanceManager.h" #include "Game.h" #include "Logger.h" -#include +#include "WorldPackets.h" #include "EntityManager.h" #include "ChatPackets.h" #include "Player.h" diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 17a2f1ea0..4e969ced6 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -1,5 +1,5 @@ #include "BaseCombatAIComponent.h" -#include +#include "BitStream.h" #include "Entity.h" #include "EntityManager.h" diff --git a/dGame/dComponents/BouncerComponent.cpp b/dGame/dComponents/BouncerComponent.cpp index 56002ac40..78ee3637f 100644 --- a/dGame/dComponents/BouncerComponent.cpp +++ b/dGame/dComponents/BouncerComponent.cpp @@ -6,7 +6,7 @@ #include "Game.h" #include "Logger.h" #include "GameMessages.h" -#include +#include "BitStream.h" #include "eTriggerEventType.h" BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) { diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index 1819438b9..10ac4ebbe 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -1,5 +1,5 @@ #include "BuffComponent.h" -#include +#include "BitStream.h" #include "CDClientDatabase.h" #include #include "DestroyableComponent.h" diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp index efc5d9d51..702ab70fc 100644 --- a/dGame/dComponents/CharacterComponent.cpp +++ b/dGame/dComponents/CharacterComponent.cpp @@ -1,5 +1,5 @@ #include "CharacterComponent.h" -#include +#include "BitStream.h" #include "tinyxml2.h" #include "Game.h" #include "Logger.h" diff --git a/dGame/dComponents/Component.h b/dGame/dComponents/Component.h index c0debb0bc..d1ad08600 100644 --- a/dGame/dComponents/Component.h +++ b/dGame/dComponents/Component.h @@ -1,6 +1,6 @@ #pragma once -#include "../thirdparty/tinyxml2/tinyxml2.h" +#include "tinyxml2.h" class Entity; diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 1ced2f545..64dca4f1d 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -1,5 +1,5 @@ #include "DestroyableComponent.h" -#include +#include "BitStream.h" #include "Logger.h" #include "Game.h" #include "dConfig.h" diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index fc3793988..92b5171a0 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -7,7 +7,7 @@ #include "Game.h" #include "Logger.h" #include "CDClientManager.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "MissionComponent.h" #include "GameMessages.h" #include "SkillComponent.h" @@ -68,7 +68,7 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do continue; } - const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); + const LWOOBJID id = ObjectIDManager::GenerateObjectID(); const auto& info = Inventory::FindItemComponent(item.itemid); @@ -86,7 +86,7 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do const auto proxyLOT = static_cast(std::stoi(proxyLotAsString)); const auto& proxyInfo = Inventory::FindItemComponent(proxyLOT); - const LWOOBJID proxyId = ObjectIDManager::Instance()->GenerateObjectID(); + const LWOOBJID proxyId = ObjectIDManager::GenerateObjectID(); // Use item.count since we equip item.count number of the item this is a requested proxy of UpdateSlot(proxyInfo.equipLocation, { proxyId, proxyLOT, item.count, slot++ }); @@ -1341,7 +1341,7 @@ void InventoryComponent::SetNPCItems(const std::vector& items) { auto slot = 0u; for (const auto& item : items) { - const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); + const LWOOBJID id = ObjectIDManager::GenerateObjectID(); const auto& info = Inventory::FindItemComponent(item); diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 901d74854..902edffe0 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -13,7 +13,7 @@ #include "DestroyableComponent.h" #include "dpWorld.h" #include "PetDigServer.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "eUnequippableActiveType.h" #include "eTerminateType.h" #include "ePetTamingNotifyType.h" @@ -562,7 +562,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) { return; } - LWOOBJID petSubKey = ObjectIDManager::Instance()->GenerateRandomObjectID(); + LWOOBJID petSubKey = ObjectIDManager::GenerateRandomObjectID(); GeneralUtils::SetBit(petSubKey, eObjectBits::CHARACTER); GeneralUtils::SetBit(petSubKey, eObjectBits::PERSISTENT); diff --git a/dGame/dComponents/PropertyEntranceComponent.cpp b/dGame/dComponents/PropertyEntranceComponent.cpp index c49d89859..2bb6ea309 100644 --- a/dGame/dComponents/PropertyEntranceComponent.cpp +++ b/dGame/dComponents/PropertyEntranceComponent.cpp @@ -1,6 +1,6 @@ #include "PropertyEntranceComponent.h" -#include +#include "CDPropertyEntranceComponentTable.h" #include "Character.h" #include "Database.h" diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index de37308fe..833b7d734 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -13,7 +13,7 @@ #include "Game.h" #include "Item.h" #include "Database.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "Player.h" #include "RocketLaunchpadControlComponent.h" #include "PropertyEntranceComponent.h" @@ -334,7 +334,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N node->position = position; node->rotation = rotation; - ObjectIDManager::Instance()->RequestPersistentID([this, node, modelLOT, entity, position, rotation, originalRotation](uint32_t persistentId) { + ObjectIDManager::RequestPersistentID([this, node, modelLOT, entity, position, rotation, originalRotation](uint32_t persistentId) { SpawnerInfo info{}; info.templateID = modelLOT; diff --git a/dGame/dComponents/QuickBuildComponent.h b/dGame/dComponents/QuickBuildComponent.h index feef1f74f..f1106a61c 100644 --- a/dGame/dComponents/QuickBuildComponent.h +++ b/dGame/dComponents/QuickBuildComponent.h @@ -1,7 +1,7 @@ #ifndef QUICKBUILDCOMPONENT_H #define QUICKBUILDCOMPONENT_H -#include +#include "BitStream.h" #include #include #include "dCommonVars.h" diff --git a/dGame/dComponents/RenderComponent.h b/dGame/dComponents/RenderComponent.h index d4d1e5c3c..74f39625a 100644 --- a/dGame/dComponents/RenderComponent.h +++ b/dGame/dComponents/RenderComponent.h @@ -1,7 +1,7 @@ #ifndef RENDERCOMPONENT_H #define RENDERCOMPONENT_H -#include +#include "BitStream.h" #include #include #include diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index c4ac19100..6e313ab1e 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -7,7 +7,7 @@ #include "MissionComponent.h" #include "BitStreamUtils.h" #include "dServer.h" -#include "../thirdparty/raknet/Source/RakNetworkFactory.h" +#include "RakNetworkFactory.h" #include #include "User.h" #include "UserManager.h" diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 5d3384cc7..eb6f11bb9 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -14,7 +14,7 @@ #include "EntityManager.h" #include "Database.h" #include "dServer.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "CppScripts.h" #include "UserManager.h" #include "ZoneInstanceManager.h" @@ -50,7 +50,7 @@ #include #include "RakString.h" -#include "../thirdparty/cpp-httplib/httplib.h" //sorry not sorry. +#include "httplib.h" //sorry not sorry. //CDB includes: #include "CDClientManager.h" @@ -1045,7 +1045,7 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, LWOOBJID owner = entity->GetObjectID(); if (item != LOT_NULL && item != 0) { - lootID = ObjectIDManager::Instance()->GenerateObjectID(); + lootID = ObjectIDManager::GenerateObjectID(); Loot::Info info; info.id = lootID; @@ -2565,12 +2565,12 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent //But we don't want the server to go unresponsive, because then the client would disconnect. //We need to get a new ID for our model first: - ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t newID) { + ObjectIDManager::RequestPersistentID([=](uint32_t newID) { LWOOBJID newIDL = newID; GeneralUtils::SetBit(newIDL, eObjectBits::CHARACTER); GeneralUtils::SetBit(newIDL, eObjectBits::PERSISTENT); - uint32_t blueprintIDSmall = ObjectIDManager::Instance()->GenerateRandomObjectID(); + uint32_t blueprintIDSmall = ObjectIDManager::GenerateRandomObjectID(); LWOOBJID blueprintID = blueprintIDSmall; GeneralUtils::SetBit(blueprintID, eObjectBits::CHARACTER); GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT); @@ -5565,7 +5565,7 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream* inStream, Entity* } } - ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t newId) { + ObjectIDManager::RequestPersistentID([=](uint32_t newId) { LOG("Build finished"); GameMessages::SendFinishArrangingWithItem(character, entity->GetObjectID()); // kick them from modular build GameMessages::SendModularBuildEnd(character); // i dont know if this does anything but DLUv2 did it diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index e68cdebc9..4a13cd92c 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -2,7 +2,7 @@ #include -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "GeneralUtils.h" #include "GameMessages.h" #include "Entity.h" diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 248ce4e7d..c541257ce 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -5,7 +5,7 @@ #include "Game.h" #include "GameMessages.h" #include "ModelComponent.h" -#include "../../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "Logger.h" #include "BehaviorStates.h" #include "AssetManager.h" @@ -31,7 +31,7 @@ #include "UpdateStripUiMessage.h" void ControlBehaviors::RequestUpdatedID(ControlBehaviorContext& context) { - ObjectIDManager::Instance()->RequestPersistentID( + ObjectIDManager::RequestPersistentID( [context](uint32_t persistentId) { if (!context) { LOG("Model to update behavior ID for is null. Cannot update ID."); diff --git a/dGame/dUtilities/CMakeLists.txt b/dGame/dUtilities/CMakeLists.txt index b6bb6059b..055cc7061 100644 --- a/dGame/dUtilities/CMakeLists.txt +++ b/dGame/dUtilities/CMakeLists.txt @@ -3,6 +3,7 @@ set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp" "GUID.cpp" "Loot.cpp" "Mail.cpp" + "ObjectIDManager.cpp" "Preconditions.cpp" "SlashCommandHandler.cpp" "VanityUtilities.cpp") diff --git a/dGame/dUtilities/ObjectIDManager.cpp b/dGame/dUtilities/ObjectIDManager.cpp new file mode 100644 index 000000000..a30ede05d --- /dev/null +++ b/dGame/dUtilities/ObjectIDManager.cpp @@ -0,0 +1,51 @@ +#include "ObjectIDManager.h" + +// Custom Classes +#include "MasterPackets.h" +#include "Database.h" +#include "Logger.h" +#include "Game.h" + + //! The persistent ID request +struct PersistentIDRequest { + PersistentIDRequest(const uint64_t& requestID, const std::function& callback) : requestID(requestID), callback(callback) {} + uint64_t requestID; + + std::function callback; +}; + +namespace { + std::vector Requests; //!< All outstanding persistent ID requests + uint64_t CurrentRequestID = 0; //!< The current request ID + uint32_t CurrentObjectID = uint32_t(1152921508165007067); //!< The current object ID + std::uniform_int_distribution Uni(10000000, INT32_MAX); +}; + +//! Requests a persistent ID +void ObjectIDManager::RequestPersistentID(const std::function callback) { + const auto& request = Requests.emplace_back(++CurrentRequestID, callback); + + MasterPackets::SendPersistentIDRequest(Game::server, request.requestID); +} + +//! Handles a persistent ID response +void ObjectIDManager::HandleRequestPersistentIDResponse(const uint64_t requestID, const uint32_t persistentID) { + auto it = std::find_if(Requests.begin(), Requests.end(), [requestID](const PersistentIDRequest& request) { + return request.requestID == requestID; + }); + + if (it == Requests.end()) return; + + it->callback(persistentID); + Requests.erase(it); +} + +//! Handles cases where we have to get a unique object ID synchronously +uint32_t ObjectIDManager::GenerateRandomObjectID() { + return Uni(Game::randomEngine); +} + +//! Generates an object ID server-sided (used for regular entities like smashables) +uint32_t ObjectIDManager::GenerateObjectID() { + return ++CurrentObjectID; +} diff --git a/dGame/dUtilities/ObjectIDManager.h b/dGame/dUtilities/ObjectIDManager.h new file mode 100644 index 000000000..7650e4ccf --- /dev/null +++ b/dGame/dUtilities/ObjectIDManager.h @@ -0,0 +1,40 @@ +#pragma once + +// C++ +#include +#include +#include + +/*! + \file ObjectIDManager.h + \brief A manager for handling object ID generation + */ + +//! The Object ID Manager +namespace ObjectIDManager { + //! Requests a persistent ID + /*! + \param callback The callback function + */ + void RequestPersistentID(const std::function callback); + + + //! Handles a persistent ID response + /*! + \param requestID The request ID + \param persistentID The persistent ID + */ + void HandleRequestPersistentIDResponse(const uint64_t requestID, const uint32_t persistentID); + + //! Generates an object ID server-sided + /*! + \return A generated object ID + */ + uint32_t GenerateObjectID(); + + //! Generates a random object ID server-sided + /*! + \return A generated object ID + */ + uint32_t GenerateRandomObjectID(); +}; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 104b12326..1cff553da 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -347,17 +347,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit }); } - if (chatCommand == "resetmission") { - uint32_t missionId; - if (!GeneralUtils::TryParse(args[0], missionId)) { - ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission ID."); - return; - } - auto* missionComponent = entity->GetComponent(); - if (!missionComponent) return; - missionComponent->ResetMission(missionId); - } - if (user->GetMaxGMLevel() == eGameMasterLevel::CIVILIAN || entity->GetGMLevel() >= eGameMasterLevel::CIVILIAN) { if (chatCommand == "die") { entity->Smash(entity->GetObjectID()); @@ -387,6 +376,18 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (entity->GetGMLevel() == eGameMasterLevel::CIVILIAN) return; } + if (chatCommand == "resetmission" && args.size() >= 1 && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { + uint32_t missionId; + if (!GeneralUtils::TryParse(args[0], missionId)) { + ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission ID."); + return; + } + + auto* missionComponent = entity->GetComponent(); + if (!missionComponent) return; + missionComponent->ResetMission(missionId); + } + // Log command to database Database::Get()->InsertSlashCommandUsage(entity->GetObjectID(), chatCommand); @@ -703,33 +704,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit entity->GetCharacter()->SetPlayerFlag(flagId, false); } - if (chatCommand == "resetmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) { - if (args.size() == 0) return; - - uint32_t missionID; - - if (!GeneralUtils::TryParse(args[0], missionID)) { - ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id."); - return; - } - - auto* comp = static_cast(entity->GetComponent(eReplicaComponentType::MISSION)); - - if (comp == nullptr) { - return; - } - - auto* mission = comp->GetMission(missionID); - - if (mission == nullptr) { - return; - } - - mission->SetMissionState(eMissionState::ACTIVE); - - return; - } - if (chatCommand == "playeffect" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 3) { int32_t effectID = 0; diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index 6d5f996c7..fa1a3eac3 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -17,7 +17,7 @@ #include "EntityInfo.h" #include "Spawner.h" #include "dZoneManager.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "Level.h" #include @@ -182,7 +182,7 @@ LWOOBJID VanityUtilities::SpawnSpawner(LOT lot, const NiPoint3& position, const obj.lot = lot; // guratantee we have no collisions do { - obj.id = ObjectIDManager::Instance()->GenerateObjectID(); + obj.id = ObjectIDManager::GenerateObjectID(); } while(Game::zoneManager->GetSpawner(obj.id)); obj.position = position; obj.rotation = rotation; diff --git a/dMasterServer/CMakeLists.txt b/dMasterServer/CMakeLists.txt index 200bb09d9..32a7b1eca 100644 --- a/dMasterServer/CMakeLists.txt +++ b/dMasterServer/CMakeLists.txt @@ -1,6 +1,6 @@ set(DMASTERSERVER_SOURCES "InstanceManager.cpp" - "ObjectIDManager.cpp" + "PersistentIDManager.cpp" "Start.cpp" ) diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index e9aeb80fb..a5691e49e 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -35,7 +35,7 @@ #include "Game.h" #include "InstanceManager.h" #include "MasterPackets.h" -#include "ObjectIDManager.h" +#include "PersistentIDManager.h" #include "PacketUtils.h" #include "FdbToSqlite.h" #include "BitStreamUtils.h" @@ -133,7 +133,7 @@ int main(int argc, char** argv) { if (!resServerPathExists) { LOG("%s does not exist, creating it.", (resServerPath).c_str()); - if(!std::filesystem::create_directories(resServerPath)){ + if (!std::filesystem::create_directories(resServerPath)) { LOG("Failed to create %s", (resServerPath).string().c_str()); return EXIT_FAILURE; } @@ -256,8 +256,8 @@ int main(int argc, char** argv) { //Create account try { Database::Get()->InsertNewAccount(username, std::string(hash, BCRYPT_HASHSIZE)); - } catch(sql::SQLException& e) { - LOG("A SQL error occurred!:\n %s", e.what()); + } catch (sql::SQLException& e) { + LOG("A SQL error occurred!:\n %s", e.what()); return EXIT_FAILURE; } @@ -287,7 +287,7 @@ int main(int argc, char** argv) { Database::Get()->SetMasterIp(master_server_ip, Game::server->GetPort()); //Create additional objects here: - ObjectIDManager::Instance()->Initialize(Game::logger); + PersistentIDManager::Initialize(); Game::im = new InstanceManager(Game::logger, Game::server->GetIP()); //Depending on the config, start up servers: @@ -450,7 +450,7 @@ void HandlePacket(Packet* packet) { uint64_t requestID = 0; inStream.Read(requestID); - uint32_t objID = ObjectIDManager::Instance()->GeneratePersistentID(); + uint32_t objID = PersistentIDManager::GeneratePersistentID(); MasterPackets::SendPersistentIDResponse(Game::server, packet->systemAddress, requestID, objID); break; } @@ -808,11 +808,8 @@ int ShutdownSequence(int32_t signal) { LOG("Triggered master shutdown"); } - auto* objIdManager = ObjectIDManager::TryInstance(); - if (objIdManager) { - objIdManager->SaveToDatabase(); - LOG("Saved ObjectIDTracker to DB"); - } + PersistentIDManager::SaveToDatabase(); + LOG("Saved ObjectIDTracker to DB"); // A server might not be finished spinning up yet, remove all of those here. for (auto* instance : Game::im->GetInstances()) { diff --git a/dMasterServer/ObjectIDManager.h b/dMasterServer/ObjectIDManager.h deleted file mode 100644 index cdb6dcdf2..000000000 --- a/dMasterServer/ObjectIDManager.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// C++ -#include - -class Logger; - -/*! - \file ObjectIDManager.hpp - \brief A manager that handles requests for object IDs - */ - - //! The Object ID Manager -class ObjectIDManager { -private: - Logger* mLogger; - static ObjectIDManager* m_Address; //!< The singleton instance - - uint32_t currentPersistentID; //!< The highest current persistent ID in use - -public: - - //! Return the singleton if it is initialized - static ObjectIDManager* TryInstance() { - return m_Address; - } - - //! The singleton method - static ObjectIDManager* Instance() { - if (m_Address == nullptr) { - m_Address = new ObjectIDManager; - } - - return m_Address; - } - - //! Initializes the manager - void Initialize(Logger* logger); - - //! Generates a new persistent ID - /*! - \return The new persistent ID - */ - uint32_t GeneratePersistentID(); - - void SaveToDatabase(); -}; diff --git a/dMasterServer/ObjectIDManager.cpp b/dMasterServer/PersistentIDManager.cpp similarity index 58% rename from dMasterServer/ObjectIDManager.cpp rename to dMasterServer/PersistentIDManager.cpp index 4739addff..3e56fadca 100644 --- a/dMasterServer/ObjectIDManager.cpp +++ b/dMasterServer/PersistentIDManager.cpp @@ -1,48 +1,45 @@ -#include "ObjectIDManager.h" +#include "PersistentIDManager.h" // Custom Classes #include "Database.h" #include "Logger.h" #include "Game.h" -// Static Variables -ObjectIDManager* ObjectIDManager::m_Address = nullptr; +namespace { + uint32_t CurrentPersistentID = 1; //!< The highest current persistent ID in use +}; //! Initializes the manager -void ObjectIDManager::Initialize(Logger* logger) { - this->mLogger = logger; - this->currentPersistentID = 1; - +void PersistentIDManager::Initialize() { try { auto lastObjectId = Database::Get()->GetCurrentPersistentId(); if (!lastObjectId) { Database::Get()->InsertDefaultPersistentId(); - return; } else { - this->currentPersistentID = lastObjectId.value(); + CurrentPersistentID = lastObjectId.value(); } - if (this->currentPersistentID <= 0) { + if (CurrentPersistentID <= 0) { LOG("Invalid persistent object ID in database. Aborting to prevent bad id generation."); throw std::runtime_error("Invalid persistent object ID in database. Aborting to prevent bad id generation."); } } catch (sql::SQLException& e) { LOG("Unable to fetch max persistent object ID in use. This will cause issues. Aborting to prevent collisions."); LOG("SQL error: %s", e.what()); - throw; + throw e; } } //! Generates a new persistent ID -uint32_t ObjectIDManager::GeneratePersistentID() { - uint32_t toReturn = ++this->currentPersistentID; +uint32_t PersistentIDManager::GeneratePersistentID() { + uint32_t toReturn = ++CurrentPersistentID; SaveToDatabase(); return toReturn; } -void ObjectIDManager::SaveToDatabase() { - Database::Get()->UpdatePersistentId(this->currentPersistentID); +void PersistentIDManager::SaveToDatabase() { + Database::Get()->UpdatePersistentId(CurrentPersistentID); } diff --git a/dMasterServer/PersistentIDManager.h b/dMasterServer/PersistentIDManager.h new file mode 100644 index 000000000..916ee33a6 --- /dev/null +++ b/dMasterServer/PersistentIDManager.h @@ -0,0 +1,23 @@ +#pragma once + +// C++ +#include + +/*! + \file PersistentIDManager.h + \brief A manager that handles requests for object IDs + */ + + //! The Object ID Manager +namespace PersistentIDManager { + //! Initializes the manager + void Initialize(); + + //! Generates a new persistent ID + /*! + \return The new persistent ID + */ + uint32_t GeneratePersistentID(); + + void SaveToDatabase(); +}; diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index b6a1f9138..7feb0cc3a 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -13,7 +13,7 @@ #include -#include +#include "BitStream.h" #include #include "Game.h" diff --git a/dNet/PacketUtils.h b/dNet/PacketUtils.h index 2afd53c76..f8558dfd1 100644 --- a/dNet/PacketUtils.h +++ b/dNet/PacketUtils.h @@ -1,8 +1,8 @@ #ifndef PACKETUTILS_H #define PACKETUTILS_H -#include -#include +#include "MessageIdentifiers.h" +#include "BitStream.h" #include enum class eConnectionType : uint16_t; diff --git a/dNet/ZoneInstanceManager.h b/dNet/ZoneInstanceManager.h index a8e32c4e8..3f8da1ae6 100644 --- a/dNet/ZoneInstanceManager.h +++ b/dNet/ZoneInstanceManager.h @@ -7,7 +7,7 @@ #include // RakNet -#include +#include "RakNetTypes.h" class dServer; diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 55c82b958..1a2988433 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -9,7 +9,7 @@ #include "CharacterComponent.h" #include "SimplePhysicsComponent.h" #include "MovementAIComponent.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" #include "MissionComponent.h" #include "Loot.h" #include "InventoryComponent.h" diff --git a/dWorldServer/CMakeLists.txt b/dWorldServer/CMakeLists.txt index 3cd832f7c..41cba0e27 100644 --- a/dWorldServer/CMakeLists.txt +++ b/dWorldServer/CMakeLists.txt @@ -1,5 +1,4 @@ set(DWORLDSERVER_SOURCES - "ObjectIDManager.cpp" "PerformanceManager.cpp" ) diff --git a/dWorldServer/ObjectIDManager.cpp b/dWorldServer/ObjectIDManager.cpp deleted file mode 100644 index 44a45437e..000000000 --- a/dWorldServer/ObjectIDManager.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ObjectIDManager.h" - -// Custom Classes -#include "MasterPackets.h" -#include "Database.h" -#include "Logger.h" -#include "Game.h" - -// Static Variables -ObjectIDManager* ObjectIDManager::m_Address = nullptr; -static std::uniform_int_distribution uni(10000000, INT32_MAX); - -//! Initializes the manager -void ObjectIDManager::Initialize(void) { - //this->currentRequestID = 0; - this->currentObjectID = uint32_t(1152921508165007067); //Initial value for this server's objectIDs -} - -//! Requests a persistent ID -void ObjectIDManager::RequestPersistentID(std::function callback) { - PersistentIDRequest* request = new PersistentIDRequest(); - request->requestID = ++this->currentRequestID; - request->callback = callback; - - this->requests.push_back(request); - - MasterPackets::SendPersistentIDRequest(Game::server, request->requestID); -} - -//! Handles a persistent ID response -void ObjectIDManager::HandleRequestPersistentIDResponse(uint64_t requestID, uint32_t persistentID) { - for (uint32_t i = 0; i < this->requests.size(); ++i) { - if (this->requests[i]->requestID == requestID) { - - // Call the callback function - this->requests[i]->callback(persistentID); - - // Then delete the request - delete this->requests[i]; - this->requests.erase(this->requests.begin() + i); - return; - } - } -} - -//! Handles cases where we have to get a unique object ID synchronously -uint32_t ObjectIDManager::GenerateRandomObjectID() { - return uni(Game::randomEngine); -} - - -//! Generates an object ID server-sided (used for regular entities like smashables) -uint32_t ObjectIDManager::GenerateObjectID(void) { - return ++this->currentObjectID; -} diff --git a/dWorldServer/ObjectIDManager.h b/dWorldServer/ObjectIDManager.h deleted file mode 100644 index deef89fdf..000000000 --- a/dWorldServer/ObjectIDManager.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -// C++ -#include -#include -#include - -/*! - \file ObjectIDManager.hpp - \brief A manager for handling object ID generation - */ - - //! The persistent ID request -struct PersistentIDRequest { - uint64_t requestID; - - std::function callback; -}; - -//! The Object ID Manager -class ObjectIDManager { -private: - static ObjectIDManager* m_Address; //!< The singleton instance - - std::vector requests; //!< All outstanding persistent ID requests - uint64_t currentRequestID; //!< The current request ID - - uint32_t currentObjectID; //!< The current object ID - -public: - - //! The singleton instance - static ObjectIDManager* Instance() { - if (m_Address == 0) { - m_Address = new ObjectIDManager; - } - - return m_Address; - } - - //! Initializes the manager - void Initialize(void); - - //! Requests a persistent ID - /*! - \param callback The callback function - */ - void RequestPersistentID(std::function callback); - - - //! Handles a persistent ID response - /*! - \param requestID The request ID - \param persistentID The persistent ID - */ - void HandleRequestPersistentIDResponse(uint64_t requestID, uint32_t persistentID); - - //! Generates an object ID server-sided - /*! - \return A generated object ID - */ - uint32_t GenerateObjectID(void); - - //! Generates a random object ID server-sided - /*! - \return A generated object ID - */ - static uint32_t GenerateRandomObjectID(); - - //! Generates a persistent object ID server-sided - /*! - \return A generated object ID - */ - uint32_t GeneratePersistentObjectID(void); -}; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 876864744..7fd205ea1 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -206,7 +206,6 @@ int main(int argc, char** argv) { masterPort = masterInfo->port; } - ObjectIDManager::Instance()->Initialize(); UserManager::Instance()->Initialize(); bool dontGenerateDCF = false; diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index a6ce09447..3aa35485b 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -15,7 +15,7 @@ #include "CDZoneTableTable.h" #include "AssetManager.h" -#include "../dWorldServer/ObjectIDManager.h" +#include "ObjectIDManager.h" void dZoneManager::Initialize(const LWOZONEID& zoneID) { LOG("Preparing zone: %i/%i/%i", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID()); @@ -112,7 +112,7 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) { auto objectId = info.spawnerID; if (objectId == LWOOBJID_EMPTY) { - objectId = ObjectIDManager::Instance()->GenerateObjectID(); + objectId = ObjectIDManager::GenerateObjectID(); GeneralUtils::SetBit(objectId, eObjectBits::CLIENT); info.spawnerID = objectId; diff --git a/docs/Commands.md b/docs/Commands.md index 0ba7d86ea..62607939f 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -1,3 +1,4 @@ + # In-game commands * All commands are prefixed by `/` and typed in the in-game chat window. Some commands require elevated gmlevel privileges. Operands within `<>` are required, operands within `()` are not. @@ -5,34 +6,34 @@ |Command|Usage|Description|Admin Level Requirement| |--- |--- |--- |--- | -|credits|`/credits`|Displays the names of the people behind Darkflame Universe.|| -|die|`/die`|Smashes the player.|| -|info|`/info`|Displays server info to the user, including where to find the server's source code.|| -|instanceinfo|`/instanceinfo`|Displays in the chat the current zone, clone, and instance id.|| +|credits|`/credits`|Displays the names of the people behind Darkflame Universe.|0| +|die|`/die`|Smashes the player.|0| +|info|`/info`|Displays server info to the user, including where to find the server's source code.|0| +|instanceinfo|`/instanceinfo`|Displays in the chat the current zone, clone, and instance id.|0| |ping|`/ping (-l)`|Displays in chat your average ping. If the `-l` flag is used, the latest ping is displayed.|| -|pvp|`/pvp`|Toggle your PVP flag.|| -|resurrect|`/resurrect`|Resurrects the player.|| -|requestmailcount|`/requestmailcount`|Sends notification with number of unread messages in the player's mailbox.|| -|who|`/who`|Displays in chat all players on the instance.|| -|togglenameplate|`/togglenameplate`|Turns the nameplate above your head that is visible to other players off and on.|8 or if `allow_nameplate_off` is set to exactly `1` in the settings| -|toggleskipcinematics|`/toggleskipcinematics`|Skips mission and world load related cinematics.|8 or if `allow_players_to_skip_cinematics` is set to exactly `1` in the settings then 0| +|pvp|`/pvp`|Toggle your PVP flag.|0| +|resurrect|`/resurrect`|Resurrects the player.|0| +|requestmailcount|`/requestmailcount`|Sends notification with number of unread messages in the player's mailbox.|0| +|who|`/who`|Displays in chat all players on the instance.|0| +|togglenameplate|`/togglenameplate`|Turns the nameplate above your head that is visible to other players off and on.|8 unless `allow_nameplate_off` is set to exactly `1` in the settings then admin level requirement is 0| +|toggleskipcinematics|`/toggleskipcinematics`|Skips mission and world load related cinematics.|8 unless `allow_players_to_skip_cinematics` is set to exactly `1` in the settings then admin level requirement is 0| ## Moderation Commands |Command|Usage|Description|Admin Level Requirement| |--- |--- |--- |--- | -|gmlevel|`/gmlevel `|Within the authorized range of levels for the current account, changes the character's game master level to the specified value. This is required to use certain commands. Aliases: `/setgmlevel`, `/makegm`.|| +|gmlevel|`/gmlevel `|Within the authorized range of levels for the current account, changes the character's game master level to the specified value. This is required to use certain commands. Aliases: `/setgmlevel`, `/makegm`.|Account GM level greater than 0| |kick|`/kick `|Kicks the player off the server.|2| |mailitem|`/mailitem `|Mails an item to the given player. The mailed item has predetermined content. The sender name is set to "Darkflame Universe." The title of the message is "Lost item." The body of the message is "This is a replacement item for one you lost."|3| |ban|`/ban `|Bans a user from the server.|4| |approveproperty|`/approveproperty`|Approves the property the player is currently visiting.|5| |mute|`/mute (days) (hours)`|Mute player for the given amount of time. If no time is given, the mute is indefinite.|6| +|fly|`/fly `|This toggles your flying state with an optional parameter for the speed scale.|6| |attackimmune|`/attackimmune `|Sets the character's immunity to basic attacks state, where value can be one of "1", to make yourself immune to basic attack damage, or "0" to undo.|8| |gmimmune|`/gmimmunve `|Sets the character's GMImmune state, where value can be one of "1", to make yourself immune to damage, or "0" to undo.|8| |gminvis|`/gminvis`|Toggles invisibility for the character, though it's currently a bit buggy. Requires nonzero GM Level for the character, but the account must have a GM level of 8.|8| |setname|`/setname `|Sets a temporary name for your player. The name resets when you log out.|8| |title|`/title `|Temporarily appends your player's name with " - <title>". This resets when you log out.|8| -|fly|`/fly <speed>`|This toggles your flying state with an optional parameter for the speed scale.|4| ## Server Operation Commands @@ -51,14 +52,14 @@ These commands are primarily for development and testing. The usage of many of t |Command|Usage|Description|Admin Level Requirement| |--- |--- |--- |--- | -|fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.|| -|join|`/join <password>`|Joins a private zone with given password.|| -|leave-zone|`/leave-zone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.|| +|fix-stats|`/fix-stats`|Resets skills, buffs, and destroyables.|0| +|join|`/join <password>`|Joins a private zone with given password.|0| +|leave-zone|`/leave-zone` or <br> `/leavezone`|If you are in an instanced zone, transfers you to the closest main world. For example, if you are in an instance of Avant Gardens Survival or the Spider Queen Battle, you are sent to Avant Gardens. If you are in the Battle of Nimbus Station, you are sent to Nimbus Station.|0| |setminifig|`/setminifig <body part> <minifig item id>`|Alters your player's minifig. Body part can be one of "Eyebrows", "Eyes", "HairColor", "HairStyle", "Pants", "LeftHand", "Mouth", "RightHand", "Shirt", or "Hands". Changing minifig parts could break the character so this command is limited to GMs.|1| |testmap|`/testmap <zone> (force) (clone-id)`|Transfers you to the given zone by id and clone id. Add "force" to skip checking if the zone is accessible (this can softlock your character, though, if you e.g. try to teleport to Frostburgh).|1| |reportproxphys|`/reportproxphys`|Prints to console the position and radius of proximity sensors.|6| |spawnphysicsverts|`/spawnphysicsverts`|Spawns a 1x1 brick at all vertices of phantom physics objects.|6| -|teleport|`/teleport <x> (y) <z>`|Teleports you. If no Y is given, you are teleported to the height of the terrain or physics object at (x, z). Alias: `/tele`.|6| +|teleport|`/teleport <x> (y) <z>` or <br> `/tele <x> (y) <z>`|Teleports you. If no Y is given, you are teleported to the height of the terrain or physics object at (x, z). Alias: `/tele`.|6| |activatespawner|`/activatespawner <spawner name>`|Activates spawner by name.|8| |addmission|`/addmission <mission id>`|Accepts the mission, adding it to your journal.|8| |boost|`/boost (time)`|Adds a passive boost action if you are in a vehicle. If time is given it will end after that amount of time|8| @@ -95,9 +96,10 @@ These commands are primarily for development and testing. The usage of many of t |setcontrolscheme|`/setcontrolscheme <scheme number>`|Sets the character control scheme to the specified number.|8| |setcurrency|`/setcurrency <coins>`|Sets your coins.|8| |setflag|`/setflag (value) <flag id>`|Sets the given inventory or health flag to the given value, where value can be one of "on" or "off". If no value is given, by default this adds the flag to your character (equivalent of calling `/setflag on <flag id>`).|8| -|setinventorysize|`/setinventorysize <size> (inventory)`|Sets your inventory size to the given size. If `inventory` is provided, the number or string will be used to set that inventory to the requested size. Alias: `/setinvsize`|8| +|setinventorysize|`/setinventorysize <size> (inventory)` or <br> `/setinvsize <size> (inventory)`|Sets your inventory size to the given size. If `inventory` is provided, the number or string will be used to set that inventory to the requested size. Alias: `/setinvsize`|8| |setuistate|`/setuistate <ui state>`|Changes UI state.|8| |spawn|`/spawn <id>`|Spawns an object at your location by id.|8| +|spawngroup|`/spawngroup <id> <amount> <radius>`|Spawns `<amount>` of object `<id>` within the given `<radius>` from your location|8| |speedboost|`/speedboost <amount>`|Sets the speed multiplier to the given amount. `/speedboost 1.5` will set the speed multiplier to 1.5x the normal speed.|8| |startcelebration|`/startcelebration <id>`|Starts a celebration effect on your character.|8| |stopeffect|`/stopeffect <effect id>`|Stops the given effect.|8| @@ -106,14 +108,15 @@ These commands are primarily for development and testing. The usage of many of t |triggerspawner|`/triggerspawner <spawner name>`|Triggers spawner by name.|8| |unlock-emote|`/unlock-emote <emote id>`|Unlocks for your character the emote of the given id.|8| |Set Level|`/setlevel <requested_level> (username)`|Sets the using entities level to the requested level. Takes an optional parameter of an in-game players username to set the level of.|8| -|crash|`/crash`|Crashes the server.|9| -|rollloot|`/rollloot <loot matrix index> <item id> <amount>`|Given a `loot matrix index`, look for `item id` in that matrix `amount` times and print to the chat box statistics of rolling that loot matrix.|9| -|castskill|`/castskill <skill id>`|Casts the skill as the player|9| |setskillslot|`/setskillslot <slot> <skill id>`||8| |setfaction|`/setfaction <faction id>`|Clears the users current factions and sets it|8| |addfaction|`/addfaction <faction id>`|Add the faction to the users list of factions|8| |getfactions|`/getfactions`|Shows the player's factions|8| |setrewardcode|`/setrewardcode <code>`|Sets the rewardcode for the account you are logged into if it's a valid rewardcode, See cdclient table `RewardCodes`|8| +|crash|`/crash`|Crashes the server.|9| +|rollloot|`/rollloot <loot matrix index> <item id> <amount>`|Given a `loot matrix index`, look for `item id` in that matrix `amount` times and print to the chat box statistics of rolling that loot matrix.|9| +|castskill|`/castskill <skill id>`|Casts the skill as the player|9| + ## Detailed `/inspect` Usage `/inspect <component> (-m <waypoint> | -a <animation> | -s | -p | -f (faction) | -t)` diff --git a/tests/dCommonTests/dCommonDependencies.h b/tests/dCommonTests/dCommonDependencies.h index 228c3c521..e82f4a4b1 100644 --- a/tests/dCommonTests/dCommonDependencies.h +++ b/tests/dCommonTests/dCommonDependencies.h @@ -4,8 +4,6 @@ #include "Game.h" #include "Logger.h" #include "dServer.h" -#include "EntityInfo.h" -#include "EntityManager.h" #include "dConfig.h" #include <gtest/gtest.h> diff --git a/tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp b/tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp index 2ad92914b..0ca2e2ea9 100644 --- a/tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp +++ b/tests/dCommonTests/dEnumsTests/MagicEnumTests.cpp @@ -116,27 +116,30 @@ TEST(MagicEnumTest, eGameMessageTypeTest) { delete Game::logger; } -#define ASSERT_EARRAY_SORTED(EARRAY_VAR)\ - for (int i = 0; i < EARRAY_VAR->size(); i++) {\ - const auto entryCurr = EARRAY_VAR->at(i).first;\ - LOG_EARRAY(EARRAY_VAR, i, entryCurr);\ - const auto entryNext = EARRAY_VAR->at(++i).first;\ - LOG_EARRAY(EARRAY_VAR, i, entryNext);\ - ASSERT_TRUE(entryCurr < entryNext);\ - };\ - -#define LOG_EARRAY(EARRAY_VAR, INDICE, ENTRY)\ - LOG(#EARRAY_VAR"[%i] = %i, %s", INDICE, ENTRY, magic_enum::enum_name(ENTRY).data()); +#define LOG_EARRAY(EARRAY_VAR, INDICE, ENTRY) LOG(#EARRAY_VAR"[%i] = %i, %s", INDICE, ENTRY, magic_enum::enum_name(ENTRY).data()); + +namespace { + template <typename T> + void AssertEnumArraySorted(const T& eArray) { + for (int i = 0; i < eArray->size(); ++i) { + const auto entryCurr = eArray->at(i).first; + LOG_EARRAY(eArray, i, entryCurr); + const auto entryNext = eArray->at(++i).first; + LOG_EARRAY(eArray, i, entryNext); + ASSERT_TRUE(entryCurr < entryNext); + } + } +} // Test that the magic enum arrays are pre-sorted TEST(MagicEnumTest, ArraysAreSorted) { Game::logger = new Logger("./MagicEnumTest_ArraysAreSorted.log", true, true); constexpr auto wmArray = &magic_enum::enum_entries<eWorldMessageType>(); - ASSERT_EARRAY_SORTED(wmArray); + AssertEnumArraySorted(wmArray); constexpr auto gmArray = &magic_enum::enum_entries<eGameMessageType>(); - ASSERT_EARRAY_SORTED(gmArray); + AssertEnumArraySorted(gmArray); delete Game::logger; } From 9e21d9d40261de23b32fae32cc1de23de07fb2e7 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Fri, 5 Jan 2024 20:16:23 -0800 Subject: [PATCH 4/5] Update WorldServer.cpp --- dWorldServer/WorldServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 7fd205ea1..d65596b63 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -665,7 +665,7 @@ void HandleMasterPacket(Packet* packet) { case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { uint64_t requestID = PacketUtils::ReadU64(8, packet); uint32_t objectID = PacketUtils::ReadU32(16, packet); - ObjectIDManager::Instance()->HandleRequestPersistentIDResponse(requestID, objectID); + ObjectIDManager::HandleRequestPersistentIDResponse(requestID, objectID); break; } From 8eb815234ad28ed2e059ed41a062a99e2e67f600 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre <aronwk.aaron@gmail.com> Date: Fri, 5 Jan 2024 22:45:40 -0600 Subject: [PATCH 5/5] fix submodule version --- thirdparty/mariadb-connector-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/mariadb-connector-cpp b/thirdparty/mariadb-connector-cpp index ef0873998..8641b1453 160000 --- a/thirdparty/mariadb-connector-cpp +++ b/thirdparty/mariadb-connector-cpp @@ -1 +1 @@ -Subproject commit ef0873998b3f94a4f76a485fb90b14866fbb99d4 +Subproject commit 8641b1453ae3ce5a70f78248a1f7fc20a048cb88