using System.Collections.ObjectModel; using System.IO; using Avalonia.Threading; using CommonwealthOnline.Host.Services; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace CommonwealthOnline.Host.ViewModels; public partial class MainWindowViewModel : ObservableObject { private const int MaxLogLines = 2000; private readonly ServerController _controller = new(); private readonly string _serverDir = System.IO.Directory.GetCurrentDirectory(); private readonly string _configPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "commonwealth-server.json"); [ObservableProperty] private string _serverName; [ObservableProperty] private string _host; [ObservableProperty] private int _port; [ObservableProperty] private int _maxPlayers; [ObservableProperty] private int _adminPort; [ObservableProperty] private string _logVerbosity; [ObservableProperty] private bool _enableGnsTransport; [ObservableProperty] private bool _isRunning; [ObservableProperty] private string _statusText = "Stopped"; public ObservableCollection Log { get; } = new(); public string[] VerbosityOptions { get; } = { "error", "warning", "info", "debug" }; public MainWindowViewModel() { var config = ServerConfig.Load(_configPath); _serverName = config.ServerName; _host = config.Host; _port = config.Port; _maxPlayers = config.MaxPlayers; _adminPort = config.AdminPort; _logVerbosity = config.LogVerbosity; _enableGnsTransport = config.EnableGnsTransport; _controller.LogReceived += line => Dispatcher.UIThread.Post(() => Append(line)); _controller.RunningChanged += running => Dispatcher.UIThread.Post(() => { IsRunning = running; StatusText = running ? "Running" : "Stopped"; StartCommand.NotifyCanExecuteChanged(); StopCommand.NotifyCanExecuteChanged(); }); } private void Append(string line) { Log.Add(line); while (Log.Count > MaxLogLines) { Log.RemoveAt(0); } } private ServerConfig CurrentConfig() => new() { ServerName = ServerName, Host = Host, Port = Port, MaxPlayers = MaxPlayers, AdminPort = AdminPort, LogVerbosity = LogVerbosity, EnableGnsTransport = EnableGnsTransport, }; [RelayCommand] private void Save() => CurrentConfig().Save(_configPath); [RelayCommand(CanExecute = nameof(CanStart))] private void Start() { Save(); Append($"[host] starting server on {Host}:{Port}..."); _controller.Start(_serverDir, _configPath); } private bool CanStart() => !IsRunning; [RelayCommand(CanExecute = nameof(CanStop))] private void Stop() { Append("[host] stopping server..."); _controller.Stop(); } private bool CanStop() => IsRunning; }