using MoonlightServers.Daemon.Models; using MoonlightServers.Daemon.ServerSystem.Abstractions; using MoonlightServers.Daemon.Services; namespace MoonlightServers.Daemon.ServerSystem; public partial class Server : IAsyncDisposable { public ServerState State { get; private set; } private IRuntimeEnvironment? RuntimeEnvironment; private RuntimeConfiguration RuntimeConfiguration; private IRuntimeStorage? RuntimeStorage; private IInstallEnvironment? InstallEnvironment; private InstallConfiguration InstallConfiguration; private IInstallStorage? InstallStorage; private readonly IRuntimeEnvironmentService RuntimeEnvironmentService; private readonly IInstallEnvironmentService InstallEnvironmentService; private readonly IRuntimeStorageService RuntimeStorageService; private readonly IInstallStorageService InstallStorageService; private readonly ServerConfigurationService ConfigurationService; private readonly string Uuid; private readonly ILogger Logger; private readonly SemaphoreSlim Lock = new(1, 1); public Server( string uuid, IRuntimeEnvironmentService runtimeEnvironmentService, IInstallEnvironmentService installEnvironmentService, IRuntimeStorageService runtimeStorageService, IInstallStorageService installStorageService, ServerConfigurationService configurationService, ILogger logger ) { Uuid = uuid; RuntimeEnvironmentService = runtimeEnvironmentService; InstallEnvironmentService = installEnvironmentService; RuntimeStorageService = runtimeStorageService; InstallStorageService = installStorageService; ConfigurationService = configurationService; Logger = logger; } public async Task InitializeAsync() { Logger.LogTrace("Initializing"); await Lock.WaitAsync(); try { // Restore state State = await RestoreAsync(); Logger.LogTrace("Initialization complete, restored to state {State}", State); } finally { Lock.Release(); } } private async Task OnConsoleMessageAsync(string message) { Console.Write($"Console: {message}"); } private async Task OnStatisticsReceivedAsync(ServerStatistics statistics) { Logger.LogTrace("{cpu:F} {used:F} {total:F}", statistics.CpuUsage, statistics.UsedMemory / 1024 / 1024, statistics.TotalMemory / 1024 / 1024); } private Task ChangeStateAsync(ServerState newState) { Logger.LogTrace("State changed from {OldState} to {NewState}", State, newState); State = newState; return Task.CompletedTask; } public async ValueTask DisposeAsync() { Logger.LogTrace("Disposing"); if (RuntimeEnvironment != null) { Logger.LogTrace("Detaching events and disposing runtime environment"); RuntimeEnvironment.Console.OnOutput -= OnConsoleMessageAsync; RuntimeEnvironment.Statistics.OnStatisticsReceived -= OnStatisticsReceivedAsync; RuntimeEnvironment.OnExited -= OnRuntimeExitedAsync; await RuntimeEnvironment.DisposeAsync(); } if (InstallEnvironment != null) { Logger.LogTrace("Detaching events and disposing install environment"); InstallEnvironment.Console.OnOutput -= OnConsoleMessageAsync; InstallEnvironment.Statistics.OnStatisticsReceived -= OnStatisticsReceivedAsync; InstallEnvironment.OnExited -= OnInstallExitedAsync; await InstallEnvironment.DisposeAsync(); } } }