|
@@ -22,866 +22,811 @@ using System.IO.Compression;
|
|
|
using ReactiveUI.Validation.Extensions;
|
|
|
using Avalonia.Media;
|
|
|
using Avalonia.Data;
|
|
|
-using ReactiveUI.Validation.Helpers;
|
|
|
using System.Collections.Generic;
|
|
|
using VeloeMinecraftLauncher.Models.Entity;
|
|
|
+using VeloeMinecraftLauncher.Models;
|
|
|
|
|
|
-namespace VeloeMinecraftLauncher.ViewModels
|
|
|
+namespace VeloeMinecraftLauncher.ViewModels;
|
|
|
+
|
|
|
+public class MainWindowViewModel : ViewModelBase
|
|
|
{
|
|
|
- public class MainWindowViewModel : ViewModelBase
|
|
|
- {
|
|
|
- public MainWindowViewModel()
|
|
|
- {
|
|
|
- Task.Run(() =>
|
|
|
+ public MainWindowViewModel()
|
|
|
+ {
|
|
|
+ Task.Run(() =>
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- //creating logger
|
|
|
- EventSink eventSink = new(null);
|
|
|
- eventSink.DataReceived += LogHandler;
|
|
|
-
|
|
|
- logger = new LoggerConfiguration()
|
|
|
- .MinimumLevel.Debug()
|
|
|
- .WriteTo.Sink(eventSink , Settings.consoleLogEventLevel)
|
|
|
- .WriteTo.File("launcher.log", Settings.fileLogEventLevel, fileSizeLimitBytes: Settings.MaxLog * 1024, rollOnFileSizeLimit: true)// restricted... is Optional
|
|
|
- .CreateLogger();
|
|
|
- Settings.logger = logger;
|
|
|
-
|
|
|
- //loading settings
|
|
|
- logger.Debug("Loading settings.");
|
|
|
- Settings.LoadSettings();
|
|
|
- username = Settings.Username;
|
|
|
-
|
|
|
- //loading local verions
|
|
|
- logger.Debug("Loading local versions.");
|
|
|
- updateAvailable();
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- OpenErrorWindow(ex);
|
|
|
- }
|
|
|
+ //creating logger
|
|
|
+ EventSink eventSink = new(null);
|
|
|
+ eventSink.DataReceived += LogHandler;
|
|
|
+
|
|
|
+ _logger = new LoggerConfiguration()
|
|
|
+ .MinimumLevel.Debug()
|
|
|
+ .WriteTo.Sink(eventSink , Settings.consoleLogEventLevel)
|
|
|
+ .WriteTo.File("launcher.log", Settings.fileLogEventLevel, fileSizeLimitBytes: Settings.MaxLog * 1024, rollOnFileSizeLimit: true)// restricted... is Optional
|
|
|
+ .CreateLogger();
|
|
|
+ Settings.logger = _logger;
|
|
|
+
|
|
|
+ //loading settings
|
|
|
+ _logger.Debug("Loading settings.");
|
|
|
+ Settings.LoadSettings();
|
|
|
+ _username = Settings.Username;
|
|
|
+
|
|
|
+ //loading local verions
|
|
|
+ _logger.Debug("Loading local versions.");
|
|
|
+ updateAvailable();
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
|
|
|
- this.ValidationRule(
|
|
|
+ this.ValidationRule(
|
|
|
viewModel => viewModel.Username,
|
|
|
value => { return !string.IsNullOrEmpty(value); },
|
|
|
"Empty username.");
|
|
|
|
|
|
- UpdateUpdater();
|
|
|
+ UpdateUpdater();
|
|
|
|
|
|
- try
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //check launcher update
|
|
|
+ _logger.Information("Checking launcher versions updates.");
|
|
|
+ _latestLauncherInfo = Downloader.DownloadAndDeserializeJsonData<LatestLauncherVersion>("https://files.veloe.link/launcher/update/versions.json");
|
|
|
+ if (_latestLauncherInfo is not null)
|
|
|
{
|
|
|
- //check launcher update
|
|
|
- logger.Information("Checking launcher versions updates.");
|
|
|
- latestLauncherInfo = Downloader.DownloadAndDeserializeJsonData<LatestLauncherVersion>("https://files.veloe.link/launcher/update/versions.json");
|
|
|
- if (latestLauncherInfo is not null)
|
|
|
- {
|
|
|
- logger.Information("Launcher version on server: {0}", latestLauncherInfo.latest);
|
|
|
- logger.Information("Launcher version: {0}", Assembly.GetExecutingAssembly().GetName().Version);
|
|
|
-
|
|
|
- if (new Version(latestLauncherInfo.latest) > Assembly.GetExecutingAssembly().GetName().Version)
|
|
|
- {
|
|
|
- logger.Debug("Update available!");
|
|
|
- IsUpdateAvailable = true;
|
|
|
- }
|
|
|
+ _logger.Information("Launcher version on server: {0}", _latestLauncherInfo.Latest);
|
|
|
+ _logger.Information("Launcher version: {0}", Assembly.GetExecutingAssembly().GetName().Version);
|
|
|
|
|
|
+ if (new Version(_latestLauncherInfo.Latest) > Assembly.GetExecutingAssembly().GetName().Version)
|
|
|
+ {
|
|
|
+ _logger.Debug("Update available!");
|
|
|
+ IsUpdateAvailable = true;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- OpenErrorWindow(ex);
|
|
|
- }
|
|
|
- try
|
|
|
- {
|
|
|
- var changelog = Downloader.DownloadAndDeserializeJsonData<List<Changelog>>("https://files.veloe.link/launcher/changelog.json");
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var changelog = Downloader.DownloadAndDeserializeJsonData<List<Changelog>>("https://files.veloe.link/launcher/changelog.json");
|
|
|
|
|
|
- if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
{
|
|
|
- Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
+ var stackpanel = desktop.MainWindow.GetControl<StackPanel>("ChangeLogStackPanel");
|
|
|
+ foreach (var version in changelog)
|
|
|
{
|
|
|
- var stackpanel = desktop.MainWindow.GetControl<StackPanel>("ChangeLogStackPanel");
|
|
|
- foreach (var version in changelog)
|
|
|
+ if (version.Title is not null)
|
|
|
{
|
|
|
- if (version.title is not null)
|
|
|
- {
|
|
|
- stackpanel.Children.Add(new TextBlock()
|
|
|
- {
|
|
|
- Text = version.title,
|
|
|
- VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
|
|
|
- TextWrapping = TextWrapping.Wrap,
|
|
|
- FontSize = 16
|
|
|
- });
|
|
|
- }
|
|
|
stackpanel.Children.Add(new TextBlock()
|
|
|
{
|
|
|
- Text = version.text,
|
|
|
+ Text = version.Title,
|
|
|
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
|
|
|
- TextWrapping = TextWrapping.Wrap
|
|
|
+ TextWrapping = TextWrapping.Wrap,
|
|
|
+ FontSize = 16
|
|
|
});
|
|
|
}
|
|
|
- });
|
|
|
+ stackpanel.Children.Add(new TextBlock()
|
|
|
+ {
|
|
|
+ Text = version.Text,
|
|
|
+ VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
|
|
|
+ TextWrapping = TextWrapping.Wrap
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- }
|
|
|
}
|
|
|
- catch (Exception ex)
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+
|
|
|
+ _logger.Debug("Connecting to WebSoket");
|
|
|
+ //conection to my servers
|
|
|
+
|
|
|
+ var serverNames = Downloader.DownloadAndDeserializeJsonData<List<string>>("https://files.veloe.link/launcher/servers.json");
|
|
|
+
|
|
|
+ _connection = new HubConnectionBuilder()
|
|
|
+ .WithUrl("https://monitor.veloe.link/hubs/data")
|
|
|
+ .WithAutomaticReconnect()
|
|
|
+ .Build();
|
|
|
+
|
|
|
+ Func<Exception, Task> reconnecting = ex => Task.Run(() =>
|
|
|
{
|
|
|
- OpenErrorWindow(ex);
|
|
|
- }
|
|
|
- try
|
|
|
+ _logger.Warning("Reconnecting to WebCoket...");
|
|
|
+ });
|
|
|
+ Func<string, Task> reconnected = str => Task.Run(() =>
|
|
|
{
|
|
|
-
|
|
|
- logger.Debug("Connecting to WebSoket");
|
|
|
- //conection to my servers
|
|
|
+ _logger.Warning("Reconnected to WebCoket.");
|
|
|
+ foreach (var server in serverNames)
|
|
|
+ {
|
|
|
+ _connection.InvokeAsync("ConnectToGroup", server);
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- var serverNames = Downloader.DownloadAndDeserializeJsonData<List<string>>("https://files.veloe.link/launcher/servers.json");
|
|
|
+ _connection.Reconnecting += reconnecting;
|
|
|
+ _connection.Reconnected += reconnected;
|
|
|
|
|
|
- connection = new HubConnectionBuilder()
|
|
|
- .WithUrl("https://monitor.veloe.link/hubs/data")
|
|
|
- .WithAutomaticReconnect()
|
|
|
- .Build();
|
|
|
-
|
|
|
- Func<Exception, Task> reconnecting = ex => Task.Run(() =>
|
|
|
- {
|
|
|
- logger.Warning("Reconnecting to WebCoket...");
|
|
|
- });
|
|
|
- Func<string, Task> reconnected = str => Task.Run(() =>
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
{
|
|
|
- logger.Warning("Reconnected to WebCoket.");
|
|
|
+ var stackpanel = desktop.MainWindow.GetControl<StackPanel>("ServersStackPanel");
|
|
|
foreach (var server in serverNames)
|
|
|
- {
|
|
|
- connection.InvokeAsync("ConnectToGroup", server);
|
|
|
- }
|
|
|
+ stackpanel.Children.Add(CreateServerPanel(server));
|
|
|
});
|
|
|
|
|
|
- connection.Reconnecting += reconnecting;
|
|
|
- connection.Reconnected += reconnected;
|
|
|
-
|
|
|
- if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
- {
|
|
|
- Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
- {
|
|
|
- var stackpanel = desktop.MainWindow.GetControl<StackPanel>("ServersStackPanel");
|
|
|
- foreach (var server in serverNames)
|
|
|
- stackpanel.Children.Add(CreateServerPanel(server));
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- connection.StartAsync();
|
|
|
+ }
|
|
|
|
|
|
- foreach (var server in serverNames)
|
|
|
- {
|
|
|
- connection.InvokeAsync("ConnectToGroup", server);
|
|
|
- }
|
|
|
- logger.Debug("Connected to WebSoket");
|
|
|
+ _connection.StartAsync();
|
|
|
|
|
|
- consoleOutputTimer.Elapsed += UpdateConsoleOutput;
|
|
|
- consoleOutputTimer.AutoReset = false;
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
+ foreach (var server in serverNames)
|
|
|
{
|
|
|
- OpenErrorWindow(ex);
|
|
|
+ _connection.InvokeAsync("ConnectToGroup", server);
|
|
|
}
|
|
|
- });
|
|
|
+ _logger.Debug("Connected to WebSoket");
|
|
|
|
|
|
- }
|
|
|
+ _consoleOutputTimer.Elapsed += UpdateConsoleOutput;
|
|
|
+ _consoleOutputTimer.AutoReset = false;
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- System.Timers.Timer consoleOutputTimer = new(250);
|
|
|
+ }
|
|
|
|
|
|
- private HubConnection connection;
|
|
|
- private string downloadButton = "Download versions";
|
|
|
- private string startButton = "Start Minecraft";
|
|
|
- private string username = "";
|
|
|
- private StringBuilder consoleText = new StringBuilder();
|
|
|
- private int downloadedIndex;
|
|
|
- private string argumentsBox;
|
|
|
- private bool isNoGameRunning = true;
|
|
|
- private bool isUpdateAvailable = false;
|
|
|
- private string settingsButton = "Settings";
|
|
|
- private string startButtonOutput;
|
|
|
+ System.Timers.Timer _consoleOutputTimer = new(250);
|
|
|
|
|
|
- ILogger logger;
|
|
|
+ private HubConnection _connection;
|
|
|
+ private string _downloadButton = "Download versions";
|
|
|
+ private string _startButton = "Start Minecraft";
|
|
|
+ private string _username = "";
|
|
|
+ private StringBuilder _consoleText = new StringBuilder();
|
|
|
+ private int _downloadedIndex;
|
|
|
+ private string _argumentsBox;
|
|
|
+ private bool _isNoGameRunning = true;
|
|
|
+ private bool _isUpdateAvailable = false;
|
|
|
+ private string _settingsButton = "Settings";
|
|
|
+ private string _startButtonOutput;
|
|
|
|
|
|
- LatestLauncherVersion latestLauncherInfo;
|
|
|
- DownloadedVerion downloadedVersion;
|
|
|
+ ILogger _logger;
|
|
|
|
|
|
- ObservableCollection<DownloadedVerion> downloadedVersions;
|
|
|
+ LatestLauncherVersion _latestLauncherInfo;
|
|
|
+ DownloadedVersion _downloadedVersion;
|
|
|
|
|
|
- public ObservableCollection<DownloadedVerion> DownloadedVersions {
|
|
|
- get => downloadedVersions;
|
|
|
- set
|
|
|
- {
|
|
|
- this.RaiseAndSetIfChanged(ref downloadedVersions, value);
|
|
|
- }
|
|
|
- }
|
|
|
+ ObservableCollection<DownloadedVersion> _downloadedVersions;
|
|
|
|
|
|
- public DownloadedVerion DownloadedVerion
|
|
|
+ public ObservableCollection<DownloadedVersion> DownloadedVersions {
|
|
|
+ get => _downloadedVersions;
|
|
|
+ set
|
|
|
{
|
|
|
- get => downloadedVersion;
|
|
|
- set
|
|
|
- {
|
|
|
- this.RaiseAndSetIfChanged(ref downloadedVersion, value);
|
|
|
- //Settings.lastChosenVersion = value.version;
|
|
|
- //logger.Debug("Version choosen: {0}",value.version);
|
|
|
- //logger.Debug("Version json: {0}", value.path);
|
|
|
- }
|
|
|
+ this.RaiseAndSetIfChanged(ref _downloadedVersions, value);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public int DownloadedIndex
|
|
|
+ public DownloadedVersion DownloadedVerion
|
|
|
+ {
|
|
|
+ get => _downloadedVersion;
|
|
|
+ set
|
|
|
{
|
|
|
- get => downloadedIndex;
|
|
|
- set
|
|
|
- {
|
|
|
- this.RaiseAndSetIfChanged(ref downloadedIndex, value);
|
|
|
- if (value >= 0 && value < DownloadedVersions.Count)
|
|
|
- DownloadedVerion = DownloadedVersions[value];
|
|
|
- }
|
|
|
- }
|
|
|
- public string Greeting => "Welcome to Cringe Launcher!";
|
|
|
- public string DownloadButton {
|
|
|
- get => downloadButton;
|
|
|
- set => this.RaiseAndSetIfChanged(ref downloadButton, value);
|
|
|
+ this.RaiseAndSetIfChanged(ref _downloadedVersion, value);
|
|
|
+ //Settings.lastChosenVersion = value.version;
|
|
|
+ //logger.Debug("Version choosen: {0}",value.version);
|
|
|
+ //logger.Debug("Version json: {0}", value.path);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public string StartButton
|
|
|
+ public int DownloadedIndex
|
|
|
+ {
|
|
|
+ get => _downloadedIndex;
|
|
|
+ set
|
|
|
{
|
|
|
- get => startButton;
|
|
|
- set => this.RaiseAndSetIfChanged(ref startButton, value);
|
|
|
+ this.RaiseAndSetIfChanged(ref _downloadedIndex, value);
|
|
|
+ if (value >= 0 && value < DownloadedVersions.Count)
|
|
|
+ DownloadedVerion = DownloadedVersions[value];
|
|
|
}
|
|
|
+ }
|
|
|
+ public string Greeting => "Welcome to Cringe Launcher!";
|
|
|
+ public string DownloadButton {
|
|
|
+ get => _downloadButton;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _downloadButton, value);
|
|
|
+ }
|
|
|
|
|
|
- public string Username
|
|
|
- {
|
|
|
- get => username;
|
|
|
- set
|
|
|
- {
|
|
|
- this.RaiseAndSetIfChanged(ref username, value);
|
|
|
- this.RaisePropertyChanged(nameof(IsStartButtonEnabled));
|
|
|
- }
|
|
|
- }
|
|
|
+ public string StartButton
|
|
|
+ {
|
|
|
+ get => _startButton;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _startButton, value);
|
|
|
+ }
|
|
|
|
|
|
- public string ConsoleText
|
|
|
+ public string Username
|
|
|
+ {
|
|
|
+ get => _username;
|
|
|
+ set
|
|
|
{
|
|
|
- get
|
|
|
- {
|
|
|
- if (consoleText.Length < UInt16.MaxValue)
|
|
|
- return consoleText.ToString();
|
|
|
- else
|
|
|
- return consoleText.ToString(consoleText.Length - UInt16.MaxValue, UInt16.MaxValue);
|
|
|
- }
|
|
|
- set
|
|
|
- {
|
|
|
- consoleText.Clear();
|
|
|
- consoleText.Append(value);
|
|
|
- this.RaisePropertyChanged(nameof(ConsoleText));
|
|
|
- ConsoleTextCaretIndex = int.MaxValue;
|
|
|
- }
|
|
|
+ this.RaiseAndSetIfChanged(ref _username, value);
|
|
|
+ this.RaisePropertyChanged(nameof(IsStartButtonEnabled));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public string StartButtonOutput
|
|
|
+ public string ConsoleText
|
|
|
+ {
|
|
|
+ get
|
|
|
{
|
|
|
- get => startButtonOutput;
|
|
|
- set => this.RaiseAndSetIfChanged(ref startButtonOutput, value);
|
|
|
+ if (_consoleText.Length < UInt16.MaxValue)
|
|
|
+ return _consoleText.ToString();
|
|
|
+ else
|
|
|
+ return _consoleText.ToString(_consoleText.Length - UInt16.MaxValue, UInt16.MaxValue);
|
|
|
}
|
|
|
-
|
|
|
- public string ArgumentsBox
|
|
|
+ set
|
|
|
{
|
|
|
- get => argumentsBox;
|
|
|
- set => this.RaiseAndSetIfChanged(ref argumentsBox, value);
|
|
|
+ _consoleText.Clear();
|
|
|
+ _consoleText.Append(value);
|
|
|
+ this.RaisePropertyChanged(nameof(ConsoleText));
|
|
|
+ ConsoleTextCaretIndex = int.MaxValue;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public string SettingsButton
|
|
|
- {
|
|
|
- get => settingsButton;
|
|
|
- set => this.RaiseAndSetIfChanged(ref settingsButton, value);
|
|
|
- }
|
|
|
+ public string StartButtonOutput
|
|
|
+ {
|
|
|
+ get => _startButtonOutput;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _startButtonOutput, value);
|
|
|
+ }
|
|
|
|
|
|
- public bool IsNoGameRunning
|
|
|
- {
|
|
|
- get => isNoGameRunning;
|
|
|
- set
|
|
|
- {
|
|
|
- this.RaiseAndSetIfChanged(ref isNoGameRunning, value);
|
|
|
- this.RaisePropertyChanged(nameof(IsStartButtonEnabled));
|
|
|
- }
|
|
|
- }
|
|
|
+ public string ArgumentsBox
|
|
|
+ {
|
|
|
+ get => _argumentsBox;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _argumentsBox, value);
|
|
|
+ }
|
|
|
|
|
|
- public bool IsStartButtonEnabled
|
|
|
- {
|
|
|
- get => IsNoGameRunning && !string.IsNullOrEmpty(Username);
|
|
|
- }
|
|
|
+ public string SettingsButton
|
|
|
+ {
|
|
|
+ get => _settingsButton;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _settingsButton, value);
|
|
|
+ }
|
|
|
|
|
|
- public bool IsUpdateAvailable
|
|
|
+ public bool IsNoGameRunning
|
|
|
+ {
|
|
|
+ get => _isNoGameRunning;
|
|
|
+ set
|
|
|
{
|
|
|
- get => isUpdateAvailable;
|
|
|
- set => this.RaiseAndSetIfChanged(ref isUpdateAvailable, value);
|
|
|
+ this.RaiseAndSetIfChanged(ref _isNoGameRunning, value);
|
|
|
+ this.RaisePropertyChanged(nameof(IsStartButtonEnabled));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public int ConsoleTextCaretIndex
|
|
|
- {
|
|
|
- get => int.MaxValue;
|
|
|
- set => this.RaisePropertyChanged(nameof(ConsoleTextCaretIndex));
|
|
|
- }
|
|
|
+ public bool IsStartButtonEnabled
|
|
|
+ {
|
|
|
+ get => IsNoGameRunning && !string.IsNullOrEmpty(Username);
|
|
|
+ }
|
|
|
|
|
|
- public void OnClickCommand()
|
|
|
+ public bool IsUpdateAvailable
|
|
|
+ {
|
|
|
+ get => _isUpdateAvailable;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _isUpdateAvailable, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int ConsoleTextCaretIndex
|
|
|
+ {
|
|
|
+ get => int.MaxValue;
|
|
|
+ set => this.RaisePropertyChanged(nameof(ConsoleTextCaretIndex));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OnClickCommand()
|
|
|
+ {
|
|
|
+ var versionsDownloader = new VersionsDownloader
|
|
|
+ {
|
|
|
+ DataContext = new VersionsDownloaderViewModel()
|
|
|
+ };
|
|
|
+
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
{
|
|
|
- var versionsDownloader = new VersionsDownloader
|
|
|
- {
|
|
|
- DataContext = new VersionsDownloaderViewModel()
|
|
|
- };
|
|
|
-
|
|
|
- if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
- {
|
|
|
- //var versionsDownloaderTask =
|
|
|
- versionsDownloader.Closed += updateAvailable;
|
|
|
- versionsDownloader.ShowDialog(desktop.MainWindow);
|
|
|
- //versionsDownloaderTask.Wait();
|
|
|
- }
|
|
|
+ versionsDownloader.Closed += updateAvailable;
|
|
|
+ versionsDownloader.ShowDialog(desktop.MainWindow);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public async void StartMinecraft()
|
|
|
+ public async void StartMinecraft()
|
|
|
+ {
|
|
|
+ Task.Run(async() =>
|
|
|
{
|
|
|
- Task.Run(async() =>
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
+ _logger.Debug("Starting minecraft.");
|
|
|
+ if (DownloadedVerion is null)
|
|
|
{
|
|
|
- logger.Debug("Starting minecraft.");
|
|
|
- if (DownloadedVerion is null)
|
|
|
- {
|
|
|
- IsNoGameRunning = true;
|
|
|
- return;
|
|
|
- }
|
|
|
+ IsNoGameRunning = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- int version = 0;
|
|
|
+ int version = 0;
|
|
|
|
|
|
- //var verionJsonFileStream = File.OpenRead(DownloadedVerion.path);
|
|
|
- using (StreamReader reader = new StreamReader(DownloadedVerion.path))
|
|
|
- {
|
|
|
- string json = reader.ReadToEnd();
|
|
|
+ using (StreamReader reader = new StreamReader(DownloadedVerion.path))
|
|
|
+ {
|
|
|
+ string json = reader.ReadToEnd();
|
|
|
|
|
|
- var versionJson = JsonSerializer.Deserialize<Entity.Version.Version>(json);
|
|
|
+ var versionJson = JsonSerializer.Deserialize<Entity.Version.Version>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
|
|
- if (Settings.checkGameAssets)
|
|
|
- {
|
|
|
- TaskStatus result;
|
|
|
+ if (Settings.checkGameAssets)
|
|
|
+ {
|
|
|
+ TaskStatus result;
|
|
|
|
|
|
- if (versionJson.inheritsFrom is null)
|
|
|
- result = Downloader.StartDownload(value => StartButtonOutput = value, value => IsNoGameRunning = value, value => { }, value => { }, versionJson).Result;
|
|
|
- else
|
|
|
+ if (versionJson.InheritsFrom is null)
|
|
|
+ result = Downloader.StartDownload(value => StartButtonOutput = value, value => IsNoGameRunning = value, value => { }, value => { }, versionJson).Result;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ using (StreamReader inheritsFromReader = new StreamReader(Settings.MinecraftForlderPath + "versions/" + versionJson.InheritsFrom + "/" + versionJson.InheritsFrom + ".json"))
|
|
|
{
|
|
|
- using (StreamReader inheritsFromReader = new StreamReader(Settings.MinecraftForlderPath + "versions/" + versionJson.inheritsFrom + "/" + versionJson.inheritsFrom + ".json"))
|
|
|
- {
|
|
|
- string jsonInheritsFrom = inheritsFromReader.ReadToEnd();
|
|
|
- var inheritsFromJson = JsonSerializer.Deserialize<Entity.Version.Version>(jsonInheritsFrom);
|
|
|
+ string jsonInheritsFrom = inheritsFromReader.ReadToEnd();
|
|
|
+ var inheritsFromJson = JsonSerializer.Deserialize<Entity.Version.Version>(jsonInheritsFrom, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
|
|
- result = Downloader.StartDownload(value => StartButtonOutput = value, value => IsNoGameRunning = value, value => { }, value => { }, inheritsFromJson).Result;
|
|
|
- }
|
|
|
+ result = Downloader.StartDownload(value => StartButtonOutput = value, value => IsNoGameRunning = value, value => { }, value => { }, inheritsFromJson).Result;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (result != TaskStatus.RanToCompletion)
|
|
|
- {
|
|
|
- IsNoGameRunning = true;
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (result != TaskStatus.RanToCompletion)
|
|
|
+ {
|
|
|
+ IsNoGameRunning = true;
|
|
|
+ return;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- string arguments = StartCommandBuilder.Build(versionJson, Username);
|
|
|
+ string arguments = StartCommandBuilder.Build(versionJson, Username);
|
|
|
|
|
|
- if (!Settings.useCustomJava)
|
|
|
+ if (!Settings.useCustomJava)
|
|
|
+ {
|
|
|
+ if (versionJson.JavaVersion != null)
|
|
|
{
|
|
|
- if (versionJson.javaVersion != null)
|
|
|
- {
|
|
|
- logger.Debug("Java version required: {0}", versionJson.javaVersion.majorVersion);
|
|
|
- version = versionJson.javaVersion.majorVersion;
|
|
|
- }
|
|
|
- else
|
|
|
+ _logger.Debug("Java version required: {0}", versionJson.JavaVersion.MajorVersion);
|
|
|
+ version = versionJson.JavaVersion.MajorVersion;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (versionJson.InheritsFrom != null)
|
|
|
{
|
|
|
- if (versionJson.inheritsFrom != null)
|
|
|
+ using (StreamReader inheritsFromReader = new StreamReader(Settings.MinecraftForlderPath + "versions/" + versionJson.InheritsFrom + "/" + versionJson.InheritsFrom + ".json"))
|
|
|
{
|
|
|
- using (StreamReader inheritsFromReader = new StreamReader(Settings.MinecraftForlderPath + "versions/" + versionJson.inheritsFrom + "/" + versionJson.inheritsFrom + ".json"))
|
|
|
+ string jsonInheritsFrom = inheritsFromReader.ReadToEnd();
|
|
|
+ var inheritsFromJson = JsonSerializer.Deserialize<Entity.Version.Version>(jsonInheritsFrom, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
+ if (inheritsFromJson.JavaVersion != null)
|
|
|
{
|
|
|
- string jsonInheritsFrom = inheritsFromReader.ReadToEnd();
|
|
|
- var inheritsFromJson = JsonSerializer.Deserialize<Entity.Version.Version>(jsonInheritsFrom);
|
|
|
- if (inheritsFromJson.javaVersion != null)
|
|
|
- {
|
|
|
- logger.Debug("Java version required: {0}", inheritsFromJson.javaVersion.majorVersion);
|
|
|
- version = inheritsFromJson.javaVersion.majorVersion;
|
|
|
- }
|
|
|
+ _logger.Debug("Java version required: {0}", inheritsFromJson.JavaVersion.MajorVersion);
|
|
|
+ version = inheritsFromJson.JavaVersion.MajorVersion;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- ConsoleText += arguments;
|
|
|
- ArgumentsBox = arguments;
|
|
|
}
|
|
|
|
|
|
- if (DownloadedVerion is null)
|
|
|
- return;
|
|
|
+ ConsoleText += arguments;
|
|
|
+ ArgumentsBox = arguments;
|
|
|
+ }
|
|
|
|
|
|
- string javaPath = Settings.JavaPath;
|
|
|
+ if (DownloadedVerion is null)
|
|
|
+ return;
|
|
|
|
|
|
- if (!Settings.useCustomJava)
|
|
|
- {
|
|
|
- javaPath = Settings.MinecraftForlderPath + "javaruntime/" + version + "/bin/java";
|
|
|
- if (OperatingSystem.IsWindows())
|
|
|
- javaPath += ".exe";
|
|
|
- }
|
|
|
+ string javaPath = Settings.JavaPath;
|
|
|
|
|
|
- logger.Debug("Java version path: {0}", javaPath);
|
|
|
- logger.Debug("Minecraft arguments: {0}", ArgumentsBox);
|
|
|
+ if (!Settings.useCustomJava)
|
|
|
+ {
|
|
|
+ javaPath = Settings.MinecraftForlderPath + "javaruntime/" + version + "/bin/java";
|
|
|
+ if (OperatingSystem.IsWindows())
|
|
|
+ javaPath += ".exe";
|
|
|
+ }
|
|
|
|
|
|
- ProcessStartInfo proc;
|
|
|
- proc = new ProcessStartInfo
|
|
|
- {
|
|
|
- UseShellExecute = false,
|
|
|
- RedirectStandardOutput = true,
|
|
|
- RedirectStandardError = true,
|
|
|
- WindowStyle = ProcessWindowStyle.Hidden,
|
|
|
- CreateNoWindow = true,
|
|
|
- FileName = System.IO.Path.Combine(Settings.MinecraftForlderPath, javaPath),
|
|
|
- StandardErrorEncoding = Encoding.UTF8,
|
|
|
- WorkingDirectory = Settings.MinecraftForlderPath,
|
|
|
- Arguments = ArgumentsBox
|
|
|
- };
|
|
|
+ _logger.Debug("Java version path: {0}", javaPath);
|
|
|
+ _logger.Debug("Minecraft arguments: {0}", ArgumentsBox);
|
|
|
|
|
|
+ ProcessStartInfo proc;
|
|
|
+ proc = new ProcessStartInfo
|
|
|
+ {
|
|
|
+ UseShellExecute = false,
|
|
|
+ RedirectStandardOutput = true,
|
|
|
+ RedirectStandardError = true,
|
|
|
+ WindowStyle = ProcessWindowStyle.Hidden,
|
|
|
+ CreateNoWindow = true,
|
|
|
+ FileName = System.IO.Path.Combine(Settings.MinecraftForlderPath, javaPath),
|
|
|
+ StandardErrorEncoding = Encoding.UTF8,
|
|
|
+ WorkingDirectory = Settings.MinecraftForlderPath,
|
|
|
+ Arguments = ArgumentsBox
|
|
|
+ };
|
|
|
|
|
|
- Process minecraft = new Process();
|
|
|
|
|
|
- minecraft.StartInfo = proc;
|
|
|
+ Process minecraft = new Process();
|
|
|
|
|
|
- Task.Run(() =>
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- logger.Debug("Starting java process.");
|
|
|
+ minecraft.StartInfo = proc;
|
|
|
|
|
|
- minecraft.OutputDataReceived += OutputHandler;
|
|
|
- minecraft.ErrorDataReceived += OutputHandler;
|
|
|
+ Task.Run(() =>
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _logger.Debug("Starting java process.");
|
|
|
|
|
|
- //* Start process and handlers
|
|
|
- //minecraft.WaitForExit();
|
|
|
+ minecraft.OutputDataReceived += OutputHandler;
|
|
|
+ minecraft.ErrorDataReceived += OutputHandler;
|
|
|
|
|
|
- minecraft.EnableRaisingEvents = true;
|
|
|
+ //* Start process and handlers
|
|
|
+ //minecraft.WaitForExit();
|
|
|
|
|
|
- IsNoGameRunning = false;
|
|
|
- minecraft.Start();
|
|
|
+ minecraft.EnableRaisingEvents = true;
|
|
|
|
|
|
- minecraft.Exited += ProcessExited;
|
|
|
+ IsNoGameRunning = false;
|
|
|
+ minecraft.Start();
|
|
|
|
|
|
- minecraft.BeginOutputReadLine();
|
|
|
- minecraft.BeginErrorReadLine();
|
|
|
+ minecraft.Exited += ProcessExited;
|
|
|
|
|
|
- if (!Settings.gameLogToLauncher)
|
|
|
- {
|
|
|
- minecraft.OutputDataReceived -= OutputHandler;
|
|
|
- minecraft.CancelOutputRead();
|
|
|
- }
|
|
|
+ minecraft.BeginOutputReadLine();
|
|
|
+ minecraft.BeginErrorReadLine();
|
|
|
|
|
|
- return Task.CompletedTask;
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
+ if (!Settings.gameLogToLauncher)
|
|
|
{
|
|
|
- OpenErrorWindow(ex);
|
|
|
- return Task.CompletedTask;
|
|
|
+ minecraft.OutputDataReceived -= OutputHandler;
|
|
|
+ minecraft.CancelOutputRead();
|
|
|
}
|
|
|
- });
|
|
|
- logger.Debug("Updating Settings");
|
|
|
- Settings.Username = username;
|
|
|
- Settings.lastChosenVersion = DownloadedVerion.version;
|
|
|
- Settings.SaveSettings();
|
|
|
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- OpenErrorWindow(ex);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
+ return Task.CompletedTask;
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ return Task.CompletedTask;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ _logger.Debug("Updating Settings");
|
|
|
+ Settings.Username = _username;
|
|
|
+ Settings.lastChosenVersion = DownloadedVerion.version;
|
|
|
+ Settings.SaveSettings();
|
|
|
|
|
|
- void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
|
|
|
- {
|
|
|
- //Todo create multiple TextBlocks if char limit
|
|
|
- if (!consoleOutputTimer.Enabled)
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
{
|
|
|
- consoleOutputTimer.Stop();
|
|
|
- consoleOutputTimer.Start();
|
|
|
+ OpenErrorWindow(ex);
|
|
|
}
|
|
|
- consoleText.Append(outLine.Data + "\n");
|
|
|
- }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- void LogHandler(object sendingProcess, EventArgs args)
|
|
|
+ void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
|
|
|
+ {
|
|
|
+ //Todo create multiple TextBlocks if char limit
|
|
|
+ if (!_consoleOutputTimer.Enabled)
|
|
|
{
|
|
|
- if (!consoleOutputTimer.Enabled)
|
|
|
- {
|
|
|
- consoleOutputTimer.Stop();
|
|
|
- consoleOutputTimer.Start();
|
|
|
- }
|
|
|
- consoleText.Append(((MyEventArgs)args).Data);
|
|
|
+ _consoleOutputTimer.Stop();
|
|
|
+ _consoleOutputTimer.Start();
|
|
|
}
|
|
|
+ _consoleText.Append(outLine.Data + "\n");
|
|
|
+ }
|
|
|
|
|
|
- void UpdateConsoleOutput(Object source, ElapsedEventArgs e)
|
|
|
+ void LogHandler(object sendingProcess, EventArgs args)
|
|
|
+ {
|
|
|
+ if (!_consoleOutputTimer.Enabled)
|
|
|
{
|
|
|
- this.RaisePropertyChanged(nameof(ConsoleText));
|
|
|
-
|
|
|
- ScrollToEnd("ConsoleScroll");
|
|
|
+ _consoleOutputTimer.Stop();
|
|
|
+ _consoleOutputTimer.Start();
|
|
|
}
|
|
|
+ _consoleText.Append(((MyEventArgs)args).Data);
|
|
|
+ }
|
|
|
+
|
|
|
+ void UpdateConsoleOutput(Object source, ElapsedEventArgs e)
|
|
|
+ {
|
|
|
+ this.RaisePropertyChanged(nameof(ConsoleText));
|
|
|
+
|
|
|
+ ScrollToEnd("ConsoleScroll");
|
|
|
+ }
|
|
|
|
|
|
- void ScrollToEnd(string ScrollName)
|
|
|
+ void ScrollToEnd(string ScrollName)
|
|
|
+ {
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
{
|
|
|
- if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
{
|
|
|
- Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
- {
|
|
|
- var scroll = desktop.MainWindow.GetControl<ScrollViewer>("ConsoleScroll");
|
|
|
- scroll.ScrollToEnd();
|
|
|
- });
|
|
|
+ var scroll = desktop.MainWindow.GetControl<ScrollViewer>("ConsoleScroll");
|
|
|
+ scroll.ScrollToEnd();
|
|
|
+ });
|
|
|
|
|
|
- }
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- void ProcessExited(object sendingProcess, EventArgs e)
|
|
|
- {
|
|
|
- ((Process)sendingProcess).Exited -= ProcessExited;
|
|
|
+ void ProcessExited(object sendingProcess, EventArgs e)
|
|
|
+ {
|
|
|
+ ((Process)sendingProcess).Exited -= ProcessExited;
|
|
|
|
|
|
- logger.Debug("Exit code: {0}", ((Process)sendingProcess).ExitCode);
|
|
|
+ _logger.Debug("Exit code: {0}", ((Process)sendingProcess).ExitCode);
|
|
|
|
|
|
- StartButtonOutput = "";
|
|
|
- IsNoGameRunning = true;
|
|
|
- if (((Process)sendingProcess).ExitCode != 0)
|
|
|
- OpenErrorWindow(new Exception("Minecraft process exited with an error.\nCheck log in game folder or in launcher console."));
|
|
|
+ StartButtonOutput = "";
|
|
|
+ IsNoGameRunning = true;
|
|
|
+ if (((Process)sendingProcess).ExitCode != 0)
|
|
|
+ OpenErrorWindow(new Exception("Minecraft process exited with an error.\nCheck log in game folder or in launcher console."));
|
|
|
+
|
|
|
+ ((Process)sendingProcess).Dispose();
|
|
|
+ }
|
|
|
|
|
|
- ((Process)sendingProcess).Dispose();
|
|
|
- }
|
|
|
|
|
|
|
|
|
+ public void updateAvailable()
|
|
|
+ {
|
|
|
+ if (DownloadedVersions is null)
|
|
|
+ DownloadedVersions = new();
|
|
|
|
|
|
- public void updateAvailable()
|
|
|
+ DownloadedVersions.Clear();
|
|
|
+ DirectoryInfo versions = new( Settings.MinecraftForlderPath + "versions");
|
|
|
+ try
|
|
|
{
|
|
|
- if (DownloadedVersions is null)
|
|
|
- DownloadedVersions = new();
|
|
|
+ var dirs = versions.GetDirectories("*", SearchOption.TopDirectoryOnly);
|
|
|
+ LauncherProfiles profiles = new LauncherProfiles();
|
|
|
+ profiles.SelectedProfile = "NotImplemented";
|
|
|
|
|
|
- DownloadedVersions.Clear();
|
|
|
- DirectoryInfo versions = new( Settings.MinecraftForlderPath + "versions");
|
|
|
- try
|
|
|
+ foreach (var dir in dirs)
|
|
|
{
|
|
|
- var dirs = versions.GetDirectories("*", SearchOption.TopDirectoryOnly);
|
|
|
- LauncherProfiles profiles = new LauncherProfiles();
|
|
|
- profiles.selectedProfile = "NotImplemented";
|
|
|
-
|
|
|
- foreach (var dir in dirs)
|
|
|
+ _logger.Debug("Checking folder {0}", dir.Name);
|
|
|
+ string checkedPath;
|
|
|
+ if (File.Exists(checkedPath = dir.FullName + "/" + dir.Name + ".json"))
|
|
|
{
|
|
|
- logger.Debug("Checking folder {0}", dir.Name);
|
|
|
- string checkedPath;
|
|
|
- if (File.Exists(checkedPath = dir.FullName + "/" + dir.Name + ".json"))
|
|
|
- {
|
|
|
- logger.Debug("Found version {0}",dir.Name);
|
|
|
- DownloadedVersions.Add(new DownloadedVerion() { path = checkedPath, version = dir.Name });
|
|
|
- profiles.profiles.Add($"Version {dir.Name}", new Profile() { name = dir.Name, lastVersionId = dir.Name, launcherVisibilityOnGameClose = "keep the launcher open" });
|
|
|
- }
|
|
|
-
|
|
|
+ _logger.Debug("Found version {0}",dir.Name);
|
|
|
+ DownloadedVersions.Add(new DownloadedVersion() { path = checkedPath, version = dir.Name });
|
|
|
+ profiles.Profiles.Add($"Version {dir.Name}", new Profile() { Name = dir.Name, LastVersionId = dir.Name, LauncherVisibilityOnGameClose = "keep the launcher open" });
|
|
|
}
|
|
|
|
|
|
- if (Settings.lastChosenVersion != null)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Settings.lastChosenVersion != null)
|
|
|
+ {
|
|
|
+ DownloadedIndex = 0;
|
|
|
+ for (int i = 0; i < DownloadedVersions.Count; i++)
|
|
|
{
|
|
|
- DownloadedIndex = 0;
|
|
|
- for (int i = 0; i < DownloadedVersions.Count; i++)
|
|
|
+ if (DownloadedVersions[i].version == Settings.lastChosenVersion)
|
|
|
{
|
|
|
- if (DownloadedVersions[i].version == Settings.lastChosenVersion)
|
|
|
- {
|
|
|
- DownloadedIndex = i;
|
|
|
- break;
|
|
|
- }
|
|
|
+ DownloadedIndex = i;
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
- if (!File.Exists(Settings.MinecraftForlderPath + "launcher_profiles.json"))
|
|
|
- {
|
|
|
- var file = File.Create(Settings.MinecraftForlderPath + "launcher_profiles.json");
|
|
|
- file.Close();
|
|
|
- file.Dispose();
|
|
|
- }
|
|
|
- var lpString = JsonSerializer.Serialize(profiles);
|
|
|
- File.WriteAllText(Settings.MinecraftForlderPath + "launcher_profiles.json", lpString);
|
|
|
+
|
|
|
}
|
|
|
- catch (DirectoryNotFoundException ex)
|
|
|
+ if (!File.Exists(Settings.MinecraftForlderPath + "launcher_profiles.json"))
|
|
|
{
|
|
|
- Directory.CreateDirectory(Settings.MinecraftForlderPath + "versions");
|
|
|
- return;
|
|
|
+ var file = File.Create(Settings.MinecraftForlderPath + "launcher_profiles.json");
|
|
|
+ file.Close();
|
|
|
+ file.Dispose();
|
|
|
}
|
|
|
-
|
|
|
+ var lpString = JsonSerializer.Serialize(profiles, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
+ File.WriteAllText(Settings.MinecraftForlderPath + "launcher_profiles.json", lpString);
|
|
|
+ }
|
|
|
+ catch (DirectoryNotFoundException ex)
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(Settings.MinecraftForlderPath + "versions");
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- public void updateAvailable(object sendingObject, EventArgs e)
|
|
|
+ public void updateAvailable(object sendingObject, EventArgs e)
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- updateAvailable();
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- OpenErrorWindow(ex);
|
|
|
- }
|
|
|
+ updateAvailable();
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
|
|
|
- switch (sendingObject)
|
|
|
- {
|
|
|
- case VersionsDownloader:
|
|
|
- ((VersionsDownloader)sendingObject).Closed -= updateAvailable;
|
|
|
- break;
|
|
|
+ switch (sendingObject)
|
|
|
+ {
|
|
|
+ case VersionsDownloader:
|
|
|
+ ((VersionsDownloader)sendingObject).Closed -= updateAvailable;
|
|
|
+ break;
|
|
|
|
|
|
- case SettingsWindow:
|
|
|
- ((SettingsWindow)sendingObject).Closed -= updateAvailable;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
+ case SettingsWindow:
|
|
|
+ ((SettingsWindow)sendingObject).Closed -= updateAvailable;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OpenSettings()
|
|
|
+ {
|
|
|
+ var settingsWindow = new SettingsWindow { DataContext = new SettingsWindowViewModel() };
|
|
|
+
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ {
|
|
|
+ settingsWindow.Closed += updateAvailable;
|
|
|
+ settingsWindow.ShowDialog(desktop.MainWindow);
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public void DownloadUpdate()
|
|
|
+ {
|
|
|
+ _logger.Debug("Started updater.exe");
|
|
|
+ Process updater = new Process();
|
|
|
+ updater.StartInfo.FileName = "Updater";
|
|
|
+ if (OperatingSystem.IsWindows())
|
|
|
+ updater.StartInfo.FileName += ".exe";
|
|
|
|
|
|
- public void OpenSettings()
|
|
|
+ if (!File.Exists(updater.StartInfo.FileName))
|
|
|
+ UpdateUpdater();
|
|
|
+
|
|
|
+ if (!File.Exists(updater.StartInfo.FileName))
|
|
|
{
|
|
|
- var settingsWindow = new SettingsWindow { DataContext = new SettingsWindowViewModel() };
|
|
|
+ updater.Start();
|
|
|
|
|
|
if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
{
|
|
|
- settingsWindow.Closed += updateAvailable;
|
|
|
- settingsWindow.ShowDialog(desktop.MainWindow);
|
|
|
+ desktop.MainWindow.Close();
|
|
|
}
|
|
|
}
|
|
|
+ else
|
|
|
+ OpenErrorWindow(new FileNotFoundException($"File {updater.StartInfo.FileName} not found!"));
|
|
|
+ }
|
|
|
|
|
|
- public void DownloadUpdate()
|
|
|
+ private void UpdateUpdater()
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- logger.Debug("Started updater.exe");
|
|
|
- Process updater = new Process();
|
|
|
- updater.StartInfo.FileName = "Updater";
|
|
|
+ string fileName = "Updater";
|
|
|
if (OperatingSystem.IsWindows())
|
|
|
- updater.StartInfo.FileName += ".exe";
|
|
|
-
|
|
|
- if (!File.Exists(updater.StartInfo.FileName))
|
|
|
- UpdateUpdater();
|
|
|
-
|
|
|
- if (!File.Exists(updater.StartInfo.FileName))
|
|
|
+ fileName += ".exe";
|
|
|
+ if (File.Exists(fileName))
|
|
|
{
|
|
|
- updater.Start();
|
|
|
+ FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(fileName);
|
|
|
+ LatestLauncherVersion latestLauncherVersion = Downloader.DownloadAndDeserializeJsonData<LatestLauncherVersion>("https://files.veloe.link/launcher/update/versions.json");
|
|
|
|
|
|
- if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ if (OperatingSystem.IsLinux())
|
|
|
{
|
|
|
- desktop.MainWindow.Close();
|
|
|
+ _logger.Information("Manual updates only.");
|
|
|
+ return;
|
|
|
}
|
|
|
- }
|
|
|
- else
|
|
|
- OpenErrorWindow(new FileNotFoundException($"File {updater.StartInfo.FileName} not found!"));
|
|
|
- }
|
|
|
|
|
|
- private void UpdateUpdater()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- string fileName = "Updater";
|
|
|
- if (OperatingSystem.IsWindows())
|
|
|
- fileName += ".exe";
|
|
|
- if (File.Exists(fileName))
|
|
|
+ if (latestLauncherVersion != null)
|
|
|
{
|
|
|
- FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(fileName);
|
|
|
- LatestLauncherVersion latestLauncherVersion = Downloader.DownloadAndDeserializeJsonData<LatestLauncherVersion>("https://files.veloe.link/launcher/update/versions.json");
|
|
|
+ _logger.Information("Latest updater version on server: {0}", latestLauncherVersion.Updater);
|
|
|
+ _logger.Information("Updater version: {0}", fileVersionInfo.FileVersion);
|
|
|
|
|
|
- if (OperatingSystem.IsLinux())
|
|
|
+ if (!(new Version(latestLauncherVersion.Updater) > new Version(fileVersionInfo.FileVersion)))
|
|
|
{
|
|
|
- logger.Information("Manual updates only.");
|
|
|
+ _logger.Information($"No update for \"{fileName}\" required.");
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- if (latestLauncherVersion != null)
|
|
|
- {
|
|
|
- logger.Information("Latest updater version on server: {0}", latestLauncherVersion.updater);
|
|
|
- logger.Information("Updater version: {0}", fileVersionInfo.FileVersion);
|
|
|
-
|
|
|
- if (!(new Version(latestLauncherVersion.updater) > new Version(fileVersionInfo.FileVersion)))
|
|
|
- {
|
|
|
- logger.Information($"No update for \"{fileName}\" required.");
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
-
|
|
|
- WebClient webClient = new WebClient();
|
|
|
- try
|
|
|
- {
|
|
|
- logger.Information("Downloading updater.zip");
|
|
|
- string url = String.Empty;
|
|
|
-
|
|
|
- if (OperatingSystem.IsWindows())
|
|
|
- url = "https://files.veloe.link/launcher/update/updater.zip";
|
|
|
+ }
|
|
|
+
|
|
|
+ WebClient webClient = new WebClient();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _logger.Information("Downloading updater.zip");
|
|
|
+ string url = String.Empty;
|
|
|
|
|
|
- if (OperatingSystem.IsLinux())
|
|
|
- url = "https://files.veloe.link/launcher/update/updater_linux-x64.zip";
|
|
|
+ if (OperatingSystem.IsWindows())
|
|
|
+ url = "https://files.veloe.link/launcher/update/updater.zip";
|
|
|
|
|
|
- if (url == String.Empty)
|
|
|
- return;
|
|
|
+ if (OperatingSystem.IsLinux())
|
|
|
+ url = "https://files.veloe.link/launcher/update/updater_linux-x64.zip";
|
|
|
|
|
|
- webClient.DownloadFile(new System.Uri(url), "updater.zip");
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- logger.Error("Error occured on getting updater.zip from the server.");
|
|
|
- throw;
|
|
|
- }
|
|
|
- webClient.Dispose();
|
|
|
- logger.Information("Unpacking updater.zip");
|
|
|
- ZipFile.ExtractToDirectory($"updater.zip", Directory.GetCurrentDirectory(), true);
|
|
|
+ if (url == String.Empty)
|
|
|
+ return;
|
|
|
|
|
|
- logger.Information("Deleting updater.zip");
|
|
|
- File.Delete($"updater.zip");
|
|
|
-
|
|
|
+ webClient.DownloadFile(new System.Uri(url), "updater.zip");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- OpenErrorWindow(ex);
|
|
|
+ _logger.Error("Error occured on getting updater.zip from the server.");
|
|
|
+ throw;
|
|
|
}
|
|
|
+ webClient.Dispose();
|
|
|
+ _logger.Information("Unpacking updater.zip");
|
|
|
+ ZipFile.ExtractToDirectory($"updater.zip", Directory.GetCurrentDirectory(), true);
|
|
|
|
|
|
+ _logger.Information("Deleting updater.zip");
|
|
|
+ File.Delete($"updater.zip");
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
- private Panel CreateServerPanel(string name)
|
|
|
+ catch (Exception ex)
|
|
|
{
|
|
|
- ServerPanelModel serverPanelModel = new() { Name = name , Status = "Wait for update...", Tip = "No players.", Players = string.Empty};
|
|
|
-
|
|
|
- Panel panel = new Panel()
|
|
|
- {
|
|
|
- VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top,
|
|
|
- HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
|
|
|
- Height = 75,
|
|
|
- Width = 150,
|
|
|
- Margin = Avalonia.Thickness.Parse("0 0 10 10")
|
|
|
- };
|
|
|
-
|
|
|
- panel.Children.Add(new Border()
|
|
|
- {
|
|
|
- Background = Brushes.Black,
|
|
|
- Opacity = 0.2,
|
|
|
- CornerRadius = Avalonia.CornerRadius.Parse("15")
|
|
|
- });
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
|
|
|
- var tip = new ToolTip()
|
|
|
- {
|
|
|
- Content = new TextBlock() {TextWrapping = TextWrapping.Wrap, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel,Path = nameof(serverPanelModel.Tip) } }
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
- ToolTip.SetTip(panel, tip);
|
|
|
+ private Panel CreateServerPanel(string name)
|
|
|
+ {
|
|
|
+ ServerPanelModel serverPanelModel = new() { Name = name , Status = "Wait for update...", Tip = "No players.", Players = string.Empty};
|
|
|
|
|
|
- StackPanel textPanel = new() { VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center };
|
|
|
+ Panel panel = new Panel()
|
|
|
+ {
|
|
|
+ VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top,
|
|
|
+ HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
|
|
|
+ Height = 75,
|
|
|
+ Width = 150,
|
|
|
+ Margin = Avalonia.Thickness.Parse("0 0 10 10")
|
|
|
+ };
|
|
|
+
|
|
|
+ panel.Children.Add(new Border()
|
|
|
+ {
|
|
|
+ Background = Brushes.Black,
|
|
|
+ Opacity = 0.2,
|
|
|
+ CornerRadius = Avalonia.CornerRadius.Parse("15")
|
|
|
+ });
|
|
|
|
|
|
- textPanel.Children.Add(new TextBlock() { VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel, Path = nameof(serverPanelModel.Status) } });
|
|
|
- textPanel.Children.Add(new TextBlock() { FontSize = 20, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel, Path = nameof(serverPanelModel.Players) } });
|
|
|
-
|
|
|
- panel.Children.Add(textPanel);
|
|
|
+ var tip = new ToolTip()
|
|
|
+ {
|
|
|
+ Content = new TextBlock() {TextWrapping = TextWrapping.Wrap, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel,Path = nameof(serverPanelModel.Tip) } }
|
|
|
+ };
|
|
|
|
|
|
- System.Timers.Timer timeoutTimer = new System.Timers.Timer(30000);
|
|
|
+ ToolTip.SetTip(panel, tip);
|
|
|
|
|
|
- timeoutTimer.Elapsed += (Object source, ElapsedEventArgs e) =>
|
|
|
- {
|
|
|
- serverPanelModel.Status = $"{serverPanelModel.Name}: Offline";
|
|
|
- serverPanelModel.Players = string.Empty;
|
|
|
- };
|
|
|
- timeoutTimer.Start();
|
|
|
+ StackPanel textPanel = new() { VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center };
|
|
|
|
|
|
- connection.On<string>($"Update{serverPanelModel.Name}", (message) =>
|
|
|
- {
|
|
|
- McStatus status = JsonSerializer.Deserialize<McStatus>(message);
|
|
|
- serverPanelModel.Status = $"{serverPanelModel.Name}: Online";
|
|
|
- serverPanelModel.Players = $"{status.NumPlayers}/{status.MaxPlayers}";
|
|
|
- serverPanelModel.Tip = String.Empty;
|
|
|
- if (UInt16.Parse(status.NumPlayers) > 0)
|
|
|
- foreach (var player in status.Players)
|
|
|
- {
|
|
|
- serverPanelModel.Tip += player;
|
|
|
- serverPanelModel.Tip += "\n";
|
|
|
- }
|
|
|
- else
|
|
|
- serverPanelModel.Tip = "No players.";
|
|
|
- timeoutTimer.Stop();
|
|
|
- timeoutTimer.Start();
|
|
|
- });
|
|
|
+ textPanel.Children.Add(new TextBlock() { VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel, Path = nameof(serverPanelModel.Status) } });
|
|
|
+ textPanel.Children.Add(new TextBlock() { FontSize = 20, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel, Path = nameof(serverPanelModel.Players) } });
|
|
|
+
|
|
|
+ panel.Children.Add(textPanel);
|
|
|
|
|
|
- return panel;
|
|
|
- }
|
|
|
+ System.Timers.Timer timeoutTimer = new System.Timers.Timer(30000);
|
|
|
|
|
|
- private void OpenErrorWindow(Exception ex)
|
|
|
- {
|
|
|
- var message = ex.Message;
|
|
|
- var stackTrace = ex.StackTrace;
|
|
|
- Settings.logger.Error(ex.Message);
|
|
|
- Settings.logger.Error(ex.StackTrace);
|
|
|
- Exception innerException = ex.InnerException;
|
|
|
- while (innerException is not null)
|
|
|
- {
|
|
|
- message += "\n" + innerException.Message;
|
|
|
- stackTrace += "\n" + innerException.StackTrace;
|
|
|
- Settings.logger.Error(innerException.Message);
|
|
|
- Settings.logger.Error(innerException.StackTrace);
|
|
|
- innerException = innerException.InnerException;
|
|
|
- }
|
|
|
+ timeoutTimer.Elapsed += (Object source, ElapsedEventArgs e) =>
|
|
|
+ {
|
|
|
+ serverPanelModel.Status = $"{serverPanelModel.Name}: Offline";
|
|
|
+ serverPanelModel.Players = string.Empty;
|
|
|
+ };
|
|
|
+ timeoutTimer.Start();
|
|
|
|
|
|
- Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
- {
|
|
|
- if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ _connection.On<string>($"Update{serverPanelModel.Name}", (message) =>
|
|
|
+ {
|
|
|
+ McStatus status = JsonSerializer.Deserialize<McStatus>(message, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
+ serverPanelModel.Status = $"{serverPanelModel.Name}: Online";
|
|
|
+ serverPanelModel.Players = $"{status.NumPlayers}/{status.MaxPlayers}";
|
|
|
+ serverPanelModel.Tip = String.Empty;
|
|
|
+ if (UInt16.Parse(status.NumPlayers) > 0)
|
|
|
+ foreach (var player in status.Players)
|
|
|
{
|
|
|
- var ErrorMessageViewModel = new ErrorWindowViewModel(message, stackTrace);
|
|
|
- var ErrorMessage = new ErrorWindow()
|
|
|
- {
|
|
|
- DataContext = ErrorMessageViewModel
|
|
|
- };
|
|
|
- ErrorMessage.ShowDialog(desktop.MainWindow);
|
|
|
+ serverPanelModel.Tip += player;
|
|
|
+ serverPanelModel.Tip += "\n";
|
|
|
}
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public class LatestLauncherVersion
|
|
|
- {
|
|
|
- public string latest { get; set; }
|
|
|
- public string updater { get; set; }
|
|
|
- public string url { get; set; }
|
|
|
- }
|
|
|
-
|
|
|
- public class DownloadedVerion
|
|
|
- {
|
|
|
- public string path;
|
|
|
- public string version;
|
|
|
+ else
|
|
|
+ serverPanelModel.Tip = "No players.";
|
|
|
+ timeoutTimer.Stop();
|
|
|
+ timeoutTimer.Start();
|
|
|
+ });
|
|
|
|
|
|
- public override string ToString()
|
|
|
- {
|
|
|
- return version;
|
|
|
- }
|
|
|
+ return panel;
|
|
|
}
|
|
|
|
|
|
- public class ServerPanelModel: ReactiveValidationObject
|
|
|
+ private void OpenErrorWindow(Exception ex)
|
|
|
{
|
|
|
- private string _name;
|
|
|
- private string _status;
|
|
|
- private string _tip;
|
|
|
- private string _players;
|
|
|
-
|
|
|
- public string Name
|
|
|
- {
|
|
|
- get => _name;
|
|
|
- set => this.RaiseAndSetIfChanged(ref _name, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string Status
|
|
|
- {
|
|
|
- get => _status;
|
|
|
- set => this.RaiseAndSetIfChanged(ref _status, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string Tip
|
|
|
+ var message = ex.Message;
|
|
|
+ var stackTrace = ex.StackTrace;
|
|
|
+ Settings.logger.Error(ex.Message);
|
|
|
+ Settings.logger.Error(ex.StackTrace);
|
|
|
+ Exception innerException = ex.InnerException;
|
|
|
+ while (innerException is not null)
|
|
|
{
|
|
|
- get => _tip;
|
|
|
- set => this.RaiseAndSetIfChanged(ref _tip, value);
|
|
|
+ message += "\n" + innerException.Message;
|
|
|
+ stackTrace += "\n" + innerException.StackTrace;
|
|
|
+ Settings.logger.Error(innerException.Message);
|
|
|
+ Settings.logger.Error(innerException.StackTrace);
|
|
|
+ innerException = innerException.InnerException;
|
|
|
}
|
|
|
|
|
|
- public string Players
|
|
|
+ Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
{
|
|
|
- get => _players;
|
|
|
- set => this.RaiseAndSetIfChanged(ref _players, value);
|
|
|
- }
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ {
|
|
|
+ var ErrorMessageViewModel = new ErrorWindowViewModel(message, stackTrace);
|
|
|
+ var ErrorMessage = new ErrorWindow()
|
|
|
+ {
|
|
|
+ DataContext = ErrorMessageViewModel
|
|
|
+ };
|
|
|
+ ErrorMessage.ShowDialog(desktop.MainWindow);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
-
|
|
|
}
|