From 3c487c5cd69c53d6fea948643c0a76df03516605 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 1 Apr 2022 21:23:39 +0200 Subject: Moved Stars45 to StarsEx --- StarsEx/StarServer.cpp | 436 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 StarsEx/StarServer.cpp (limited to 'StarsEx/StarServer.cpp') diff --git a/StarsEx/StarServer.cpp b/StarsEx/StarServer.cpp new file mode 100644 index 0000000..a03bd15 --- /dev/null +++ b/StarsEx/StarServer.cpp @@ -0,0 +1,436 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. + + AUTHOR: John DiCamillo + +*/ + +#include + + +#include "StarServer.h" +#include "Campaign.h" +#include "CombatRoster.h" +#include "Galaxy.h" +#include "Mission.h" +#include "Sim.h" +#include "SimEvent.h" +#include "Ship.h" +#include "Contact.h" +#include "QuantumDrive.h" +#include "Power.h" +#include "SystemDesign.h" +#include "WeaponDesign.h" +#include "Shot.h" +#include "Drive.h" +#include "Explosion.h" +#include "FlightDeck.h" +#include "RadioMessage.h" +#include "RadioTraffic.h" +#include "Random.h" +#include "ModConfig.h" + +#include "NetLayer.h" +#include "NetGame.h" +#include "NetHost.h" +#include "NetServer.h" +#include "HttpServer.h" +#include "HttpServletExec.h" +#include "NetAdminServer.h" +#include "NetLobbyServer.h" +#include "NetServerConfig.h" + +#include "Token.h" +#include "MachineInfo.h" +#include "Game.h" +#include "Clock.h" +#include "ContentBundle.h" +#include "Keyboard.h" +#include "Mouse.h" +#include "EventDispatch.h" +#include "MultiController.h" +#include "DataLoader.h" +#include "ParseUtil.h" +#include "VersionInfo.h" + +// +--------------------------------------------------------------------+ + +StarServer* StarServer::instance = 0; + +static Mission* current_mission = 0; +static double time_til_change = 0; +static bool exit_latch = true; + +// +--------------------------------------------------------------------+ + +StarServer::StarServer() +: loader(0), time_mark(0), minutes(0), game_mode(MENU_MODE), +admin_server(0), lobby_server(0) +{ + if (!instance) + instance = this; + + app_name = "Starserver 5.0"; + title_text = "Starserver"; + palette_name = "alpha"; + + server = true; + show_mouse = true; + + DataLoader::Initialize(); + loader = DataLoader::GetLoader(); + int loadstat = loader->EnableDatafile("shatter.dat"); + + if (loadstat != DataLoader::DATAFILE_OK) { + const char* err_msg = loadstat == DataLoader::DATAFILE_INVALID ? + "The file 'shatter.dat' appears to have been damaged. Please re-install Starshatter." : + "Starshatter cannot open the file 'shatter.dat'. Please re-install Starshatter."; + + ::Print(err_msg); + ::Print("\n\nFATAL ERROR: EXIT."); + exit(-1); + } + + if (loader->FindFile("start.dat")) + loader->EnableDatafile("start.dat"); + + // no images or sounds in server mode: + loader->EnableMedia(false); +} + +StarServer::~StarServer() +{ + delete admin_server; + delete lobby_server; + + admin_server = 0; + lobby_server = 0; + + // delete all the ships and stuff + // BEFORE getting rid of the system + // and weapons catalogs! + delete world; + world = 0; // don't let base class double delete the world + + Drive::Close(); + Explosion::Close(); + FlightDeck::Close(); + Campaign::Close(); + CombatRoster::Close(); + Galaxy::Close(); + RadioTraffic::Close(); + Ship::Close(); + WeaponDesign::Close(); + SystemDesign::Close(); + DataLoader::Close(); + NetServerConfig::Close(); + ModConfig::Close(); + + instance = 0; + + server = false; +} + +// +--------------------------------------------------------------------+ + +bool +StarServer::Init(HINSTANCE hi, HINSTANCE hpi, LPSTR cmdline, int nCmdShow) +{ + if (loader) + loader->UseFileSystem(false); + + return Game::Init(hi, hpi, cmdline, nCmdShow); +} + +// +--------------------------------------------------------------------+ + +bool +StarServer::InitGame() +{ + if (!Game::InitGame()) + return false; + + RandomInit(); + ModConfig::Initialize(); + NetServerConfig::Initialize(); + SystemDesign::Initialize("sys.def"); + WeaponDesign::Initialize("wep.def"); + Ship::Initialize(); + Galaxy::Initialize(); + CombatRoster::Initialize(); + Campaign::Initialize(); + + Drive::Initialize(); + Explosion::Initialize(); + FlightDeck::Initialize(); + Ship::Initialize(); + Shot::Initialize(); + RadioTraffic::Initialize(); + + time_mark = Clock::GetInstance()->GameTime(); + minutes = 0; + + NetServerConfig* server_config = NetServerConfig::GetInstance(); + if (!server_config) + return false; + + ::Print("\n\n\nStarshatter Server Init\n"); + ::Print("-----------------------\n"); + ::Print("Server Name: %s\n", (const char*) server_config->Name()); + ::Print("Server Type: %d\n", server_config->GetGameType()); + + if (server_config->GetMission().length() > 0) + ::Print("Server Mission: %s\n", (const char*) server_config->GetMission()); + + ::Print("Lobby Server Port: %d\n", server_config->GetLobbyPort()); + ::Print("Admin Server Port: %d\n", server_config->GetAdminPort()); + ::Print("-----------------------\n"); + + NetLobbyServer* nls = new NetLobbyServer; + NetAdminServer* nas = NetAdminServer::GetInstance(server_config->GetAdminPort()); + nas->SetServerName(server_config->Name()); + + lobby_server = nls; + admin_server = nas; + + std::cout << "Started server listening on port " << server_config->GetLobbyPort() << std::endl; + + return true; +} + +// +--------------------------------------------------------------------+ + +void +StarServer::SetGameMode(int m) +{ + if (game_mode == m) + return; + + if (m == LOAD_MODE) { + Print(" game_mode = LOAD_MODE\n"); + paused = true; + } + + else if (m == PLAY_MODE) { + Print(" game_mode = PLAY_MODE\n"); + + if (!world) { + CreateWorld(); + InstantiateMission(); + } + + // stand alone server should wait for players to connect + // before unpausing the simulation... + Clock::GetInstance()->SetTimeCompression(1.0); + Pause(true); + } + + else if (m == MENU_MODE) { + Print(" game_mode = MENU_MODE\n"); + paused = true; + + Sim* sim = (Sim*) world; + + if (sim) + sim->UnloadMission(); + } + + game_mode = m; +} + +// +--------------------------------------------------------------------+ + +void +StarServer::SetNextMission(const char* script) +{ + if (lobby_server) + lobby_server->SetServerMission(script); +} + +// +--------------------------------------------------------------------+ + +void +StarServer::CreateWorld() +{ + RadioTraffic::Initialize(); + + // create world + if (!world) { + Sim* sim = new Sim(0); + world = sim; + Print(" World Created.\n"); + } +} + +void +StarServer::InstantiateMission() +{ + current_mission = 0; + + if (Campaign::GetCampaign()) { + current_mission = Campaign::GetCampaign()->GetMission(); + } + + Sim* sim = (Sim*) world; + + if (sim) { + sim->UnloadMission(); + + if (current_mission) { + sim->LoadMission(current_mission); + sim->ExecMission(); + sim->SetTestMode(false); + + Print(" Mission Instantiated.\n"); + std::cout << "Loaded mission: " << current_mission->Name() << std::endl; + } + + else { + Print(" *** WARNING: StarServer::InstantiateMission() - no mission selected ***\n"); + } + } +} + +// +--------------------------------------------------------------------+ + +bool +StarServer::GameLoop() +{ + if (active && paused) { + UpdateWorld(); + GameState(); + } + + else if (!active) { + UpdateWorld(); + GameState(); + Sleep(10); + } + + Game::GameLoop(); + return false; // must return false to keep processing + // true tells the outer loop to sleep until a + // windows event is available +} + +// +--------------------------------------------------------------------+ + +void +StarServer::UpdateWorld() +{ + Galaxy* galaxy = Galaxy::GetInstance(); + if (galaxy) galaxy->ExecFrame(); + + Campaign* campaign = Campaign::GetCampaign(); + if (campaign) campaign->ExecFrame(); + + if (paused) { + if (world) + world->ExecFrame(0); + } + + else { + Drive::StartFrame(); + + if (world) + world->ExecFrame(Clock::GetInstance()->Delta()); + } + + static DWORD refresh_time = 0; + if (Clock::GetInstance()->RealTime() - refresh_time > 1000) { + refresh_time = Clock::GetInstance()->RealTime(); + } +} + +// +--------------------------------------------------------------------+ + +void +StarServer::GameState() +{ + if (lobby_server) { + lobby_server->ExecFrame(); + + if (lobby_server->GetStatus() == NetServerInfo::PERSISTENT) + paused = NetGame::NumPlayers() < 1; + } + + if (game_mode == MENU_MODE) { + Sleep(30); + } + + else if (game_mode == LOAD_MODE) { + CreateWorld(); + InstantiateMission(); + + SetGameMode(PLAY_MODE); + } + + else if (game_mode == PLAY_MODE) { + if (Clock::GetInstance()->GameTime() - time_mark > 60000) { + time_mark = Clock::GetInstance()->GameTime(); + minutes++; + if (minutes > 60) + Print(" TIME %2d:%02d:00\n", minutes/60, minutes%60); + else + Print(" TIME %2d:00\n", minutes); + } + + Sleep(10); + } +} + +// +--------------------------------------------------------------------+ + +DWORD WINAPI StarServerShutdownProc(LPVOID link) +{ + StarServer* stars = (StarServer*) link; + + Sleep(3000); + + if (stars) { + stars->Exit(); + return 0; + } + + return (DWORD) E_POINTER; +} + +DWORD WINAPI StarServerRestartProc(LPVOID link) +{ + StarServer* stars = (StarServer*) link; + + Sleep(3000); + + if (stars) { + char cmdline[256]; + strcpy_s(cmdline, "stars -server"); + + STARTUPINFO s; + ZeroMemory(&s, sizeof(s)); + s.cb = sizeof(s); + + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + CreateProcess("stars.exe", cmdline, 0, 0, 0, 0, 0, 0, &s, &pi); + stars->Exit(); + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + return 0; + } + + return (DWORD) E_POINTER; +} + +void +StarServer::Shutdown(bool restart) +{ + DWORD thread_id = 0; + + if (restart) + CreateThread(0, 4096, StarServerRestartProc, (LPVOID) this, 0, &thread_id); + else + CreateThread(0, 4096, StarServerShutdownProc, (LPVOID) this, 0, &thread_id); +} \ No newline at end of file -- cgit v1.1