#include "Start.h" #include "Logger.h" #include "dConfig.h" #include "Game.h" #include "BinaryPathFinder.h" #ifdef _WIN32 #include #include #include namespace { const auto startup = STARTUPINFOW{ .cb = sizeof(STARTUPINFOW), .lpReserved = nullptr, .lpDesktop = nullptr, .lpTitle = nullptr, .dwX = 0, .dwY = 0, .dwXSize = 0, .dwYSize = 0, .dwXCountChars = 0, .dwYCountChars = 0, .dwFillAttribute = 0, .dwFlags = 0, .wShowWindow = 0, .cbReserved2 = 0, .lpReserved2 = nullptr, .hStdInput = INVALID_HANDLE_VALUE, .hStdOutput = INVALID_HANDLE_VALUE, .hStdError = INVALID_HANDLE_VALUE, }; } #else #include #endif uint32_t StartChatServer() { if (Game::ShouldShutdown()) { LOG("Currently shutting down. Chat will not be restarted."); return 0; } auto chat_path = BinaryPathFinder::GetBinaryDir() / "ChatServer"; #ifdef _WIN32 chat_path.replace_extension(".exe"); auto chat_startup = startup; auto chat_info = PROCESS_INFORMATION{}; if (!CreateProcessW(chat_path.wstring().data(), chat_path.wstring().data(), nullptr, nullptr, false, 0, nullptr, nullptr, &chat_startup, &chat_info)) { LOG("Failed to launch ChatServer"); return 0; } // get pid and close unused handles auto chat_pid = chat_info.dwProcessId; CloseHandle(chat_info.hProcess); CloseHandle(chat_info.hThread); #else // *nix systems const auto chat_pid = fork(); if (chat_pid < 0) { LOG("Failed to launch ChatServer"); return 0; } else if (chat_pid == 0) { // We are the child process execl(chat_path.string().c_str(), chat_path.string().c_str(), nullptr); } #endif LOG("ChatServer PID is %d", chat_pid); return chat_pid; } uint32_t StartAuthServer() { if (Game::ShouldShutdown()) { LOG("Currently shutting down. Auth will not be restarted."); return 0; } auto auth_path = BinaryPathFinder::GetBinaryDir() / "AuthServer"; #ifdef _WIN32 auth_path.replace_extension(".exe"); auto auth_startup = startup; auto auth_info = PROCESS_INFORMATION{}; if (!CreateProcessW(auth_path.wstring().data(), auth_path.wstring().data(), nullptr, nullptr, false, 0, nullptr, nullptr, &auth_startup, &auth_info)) { LOG("Failed to launch AuthServer"); return 0; } // get pid and close unused handles auto auth_pid = auth_info.dwProcessId; CloseHandle(auth_info.hProcess); CloseHandle(auth_info.hThread); #else // *nix systems const auto auth_pid = fork(); if (auth_pid < 0) { LOG("Failed to launch AuthServer"); return 0; } else if (auth_pid == 0) { // We are the child process execl(auth_path.string().c_str(), auth_path.string().c_str(), nullptr); } #endif LOG("AuthServer PID is %d", auth_pid); return auth_pid; } uint32_t StartWorldServer(LWOMAPID mapID, uint16_t port, LWOINSTANCEID lastInstanceID, int maxPlayers, LWOCLONEID cloneID) { auto world_path = BinaryPathFinder::GetBinaryDir() / "WorldServer"; #ifdef _WIN32 world_path.replace_extension(".exe"); auto cmd = world_path.wstring() + L" -zone " + std::to_wstring(mapID) + L" -port " + std::to_wstring(port) + L" -instance " + std::to_wstring(lastInstanceID) + L" -maxclients " + std::to_wstring(maxPlayers) + L" -clone " + std::to_wstring(cloneID); auto world_startup = startup; auto world_info = PROCESS_INFORMATION{}; if (!CreateProcessW(world_path.wstring().data(), cmd.data(), nullptr, nullptr, false, 0, nullptr, nullptr, &world_startup, &world_info)) { LOG("Failed to launch WorldServer"); return 0; } // get pid and close unused handles auto world_pid = world_info.dwProcessId; CloseHandle(world_info.hProcess); CloseHandle(world_info.hThread); #else const auto world_pid = fork(); if (world_pid < 0) { LOG("Failed to launch WorldServer"); return 0; } else if (world_pid == 0) { // We are the child process execl(world_path.string().c_str(), world_path.string().c_str(), "-zone", std::to_string(mapID).c_str(), "-port", std::to_string(port).c_str(), "-instance", std::to_string(lastInstanceID).c_str(), "-maxclients", std::to_string(maxPlayers).c_str(), "-clone", std::to_string(cloneID).c_str(), nullptr); } #endif LOG("WorldServer PID is %d", world_pid); return world_pid; }