Cross-platform C# GUI to replace the Qt/C++ Host GUI, on the same dotnet toolchain as the server. MVP: load/save commonwealth-server.json, Start/Stop the CommonwealthOnline.Server process (published exe, then dll, then source run), and stream its output to a live log. Themed to the Commonwealth Online brand (near-black + amber). Builds clean on net8.0. Next: player list + kick/ban via the admin port, then retire the Qt host.
107 lines
3.1 KiB
C#
107 lines
3.1 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
|
|
namespace CommonwealthOnline.Host.Services;
|
|
|
|
// Launches the CommonwealthOnline.Server process, preferring a published
|
|
// apphost, then a framework-dependent DLL, then a source-tree dotnet run.
|
|
public sealed class ServerController
|
|
{
|
|
private Process? _process;
|
|
|
|
public bool IsRunning => _process is { HasExited: false };
|
|
|
|
public event Action<string>? LogReceived;
|
|
public event Action<bool>? RunningChanged;
|
|
|
|
public void Start(string serverDir, string configPath)
|
|
{
|
|
if (IsRunning)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var startInfo = ResolveLaunch(serverDir, configPath);
|
|
var process = new Process { StartInfo = startInfo, EnableRaisingEvents = true };
|
|
process.OutputDataReceived += (_, e) => Emit(e.Data);
|
|
process.ErrorDataReceived += (_, e) => Emit(e.Data);
|
|
process.Exited += (_, _) => RunningChanged?.Invoke(false);
|
|
|
|
_process = process;
|
|
process.Start();
|
|
process.BeginOutputReadLine();
|
|
process.BeginErrorReadLine();
|
|
RunningChanged?.Invoke(true);
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (_process is { HasExited: false } process)
|
|
{
|
|
try
|
|
{
|
|
process.Kill(entireProcessTree: true);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// Process already gone or not killable; RunningChanged fires on Exited.
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Emit(string? line)
|
|
{
|
|
if (!string.IsNullOrEmpty(line))
|
|
{
|
|
LogReceived?.Invoke(line);
|
|
}
|
|
}
|
|
|
|
private static ProcessStartInfo ResolveLaunch(string serverDir, string configPath)
|
|
{
|
|
var exeName = OperatingSystem.IsWindows()
|
|
? "CommonwealthOnline.Server.exe"
|
|
: "CommonwealthOnline.Server";
|
|
var apphost = Path.Combine(serverDir, exeName);
|
|
var dll = Path.Combine(serverDir, "CommonwealthOnline.Server.dll");
|
|
var project = Path.Combine(serverDir, "CommonwealthOnline.Server.csproj");
|
|
|
|
var info = new ProcessStartInfo
|
|
{
|
|
WorkingDirectory = serverDir,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
};
|
|
|
|
if (File.Exists(apphost))
|
|
{
|
|
info.FileName = apphost;
|
|
info.ArgumentList.Add("serve");
|
|
}
|
|
else if (File.Exists(dll))
|
|
{
|
|
info.FileName = "dotnet";
|
|
info.ArgumentList.Add(dll);
|
|
info.ArgumentList.Add("serve");
|
|
}
|
|
else
|
|
{
|
|
info.FileName = "dotnet";
|
|
info.ArgumentList.Add("run");
|
|
info.ArgumentList.Add("--project");
|
|
info.ArgumentList.Add(project);
|
|
info.ArgumentList.Add("-c");
|
|
info.ArgumentList.Add("Release");
|
|
info.ArgumentList.Add("--");
|
|
info.ArgumentList.Add("serve");
|
|
}
|
|
|
|
info.ArgumentList.Add("--config");
|
|
info.ArgumentList.Add(configPath);
|
|
return info;
|
|
}
|
|
}
|