Files
DarkflameServer/dMasterServer/Start.cpp
Aaron Kimbrell e213a7aeff feat: web dashboard and playground work
The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch:
accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy
reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live
events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved
captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes
they need.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:30:43 -05:00

186 lines
5.2 KiB
C++

#include "Start.h"
#include "Logger.h"
#include "dConfig.h"
#include "Game.h"
#include "BinaryPathFinder.h"
#ifdef _WIN32
#include <windows.h>
#include <handleapi.h>
#include <processthreadsapi.h>
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 <unistd.h>
#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 StartDashboardServer() {
if (Game::ShouldShutdown()) {
LOG("Currently shutting down. DashboardServer will not be restarted.");
return 0;
}
auto web_path = BinaryPathFinder::GetBinaryDir() / "DashboardServer";
#ifdef _WIN32
web_path.replace_extension(".exe");
auto web_startup = startup;
auto web_info = PROCESS_INFORMATION{};
if (!CreateProcessW(web_path.wstring().data(), web_path.wstring().data(),
nullptr, nullptr, false, 0, nullptr, nullptr,
&web_startup, &web_info))
{
LOG("Failed to launch DashboardServer");
return 0;
}
// get pid and close unused handles
auto web_pid = web_info.dwProcessId;
CloseHandle(web_info.hProcess);
CloseHandle(web_info.hThread);
#else // *nix systems
const auto web_pid = fork();
if (web_pid < 0) {
LOG("Failed to launch DashboardServer");
return 0;
} else if (web_pid == 0) {
// We are the child process
execl(web_path.string().c_str(), web_path.string().c_str(), nullptr);
}
#endif
LOG("DashboardServer PID is %d", web_pid);
return web_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;
}