123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857 |
- using Avalonia.Controls.ApplicationLifetimes;
- using ReactiveUI;
- using System;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- using System.IO;
- using System.Text;
- using System.Text.Json;
- using System.Threading.Tasks;
- using VeloeMinecraftLauncher.Entity.LauncherProfiles;
- using VeloeMinecraftLauncher.Utils;
- using VeloeMinecraftLauncher.Views;
- using Microsoft.AspNetCore.SignalR.Client;
- using VeloeMinecraftLauncher.Entity.McStatus;
- using System.Timers;
- using System.Reflection;
- using Serilog;
- using Avalonia.Controls;
- using Avalonia.Threading;
- using System.IO.Compression;
- using ReactiveUI.Validation.Extensions;
- using System.Collections.Generic;
- using VeloeMinecraftLauncher.Models.Entity;
- using VeloeMinecraftLauncher.Models;
- using System.Linq;
- using System.Threading;
- using System.ComponentModel;
- namespace VeloeMinecraftLauncher.ViewModels;
- public class MainWindowViewModel : ViewModelBase
- {
- public MainWindowViewModel()
- {
- _downloadedVersions = new();
- _serverPanels = new();
- try
- {
- //creating logger
- EventSink eventSink = new(null);
- eventSink.DataReceived += LogHandler;
- var hook = new CaptureFilePathHook();
- _logger = new LoggerConfiguration()
- .MinimumLevel.Debug()
- .WriteTo.Sink(eventSink, Settings.consoleLogEventLevel)
- .WriteTo.File("launcher.log", Settings.fileLogEventLevel, fileSizeLimitBytes: Settings.maxLog * 1024, rollOnFileSizeLimit: true, hooks: hook)// restricted... is Optional
- .CreateLogger();
- Settings.logger = _logger;
- Settings.logFilePath = hook;
- //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);
- if (_logger is null)
- {
- _logger = new LoggerConfiguration().MinimumLevel.Debug().CreateLogger();
- }
- }
- finally
- {
- this.ValidationRule(
- viewModel => viewModel.Username,
- value => { return !string.IsNullOrEmpty(value); },
- "Empty username.");
- }
- Task.Run(async () =>
- {
- UpdateUpdater();
- try
- {
- //check launcher update
- _logger.Information("Checking launcher versions updates.");
- _latestLauncherInfo = await Downloader.DownloadAndDeserializeJsonData<LatestLauncherVersion>("https://files.veloe.link/launcher/update/versions.json");
- if (_latestLauncherInfo is not null && _latestLauncherInfo.Latest 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;
- }
- }
- else
- _logger.Warning("Can't get latest verion info! Skipping...");
- }
- catch (Exception ex)
- {
- OpenErrorWindow(ex);
- }
-
- try
- {
- Changelogs = new ObservableCollection<Changelog>(await Downloader.DownloadAndDeserializeJsonData<List<Changelog>>("https://files.veloe.link/launcher/changelog.json"));
- this.RaisePropertyChanged(nameof(Changelogs));
- }
- catch (Exception ex)
- {
- OpenErrorWindow(ex);
- }
- try
- {
- _logger.Debug("Connecting to WebSoket");
- //conection to my servers
- var serverNames = await Downloader.DownloadAndDeserializeJsonData<List<string>>("https://files.veloe.link/launcher/servers.json");
- if (serverNames is not null)
- {
- _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(() =>
- {
- _logger.Warning("Reconnected to WebCoket.");
- foreach (var server in serverNames)
- {
- _connection.InvokeAsync("ConnectToGroup", server);
- }
- });
- _connection.Reconnecting += reconnecting;
- _connection.Reconnected += reconnected;
-
- foreach (var server in serverNames)
- ServerPanels.Add(CreateServerPanel(server));
- await _connection.StartAsync();
- foreach (var server in serverNames)
- {
- await _connection.InvokeAsync("ConnectToGroup", server);
- }
- _logger.Debug("Connected to WebSoket");
- }
- _consoleOutputTimer.Elapsed += UpdateConsoleOutput;
- _consoleOutputTimer.AutoReset = false;
- }
- catch (Exception ex)
- {
- OpenErrorWindow(ex);
- }
- try
- {
- _logger.Debug("Checking modpacks updates...");
- var modpacksInfo = await Downloader.DownloadAndDeserializeJsonData<List<Modpack>>("https://files.veloe.link/launcher/modpacks.json") ?? new List<Modpack>();
- var installedModpacks = //DownloadedVersions.Where(v => modpacksInfo.Select(m => m.Name).Contains(v.version)).Join(modpacksInfo, (v, m) => v.version == m.);
- from downloadedVersion in DownloadedVersions
- join modpack in modpacksInfo on downloadedVersion.version equals modpack.Name
- select new
- {
- Name = downloadedVersion.version,
- Path = downloadedVersion.path,
- Revision = modpack.Revision
- };
- var modpacksToUpdate = new List<string>();
- var modpacksRevsionUnknown = new List<string>();
- foreach (var modpack in installedModpacks)
- {
- if (File.Exists(Path.GetDirectoryName(modpack.Path) + "/revision.json"))
- {
- try
- {
- if (modpack.Revision > JsonSerializer.Deserialize<int>(File.ReadAllText(Path.GetDirectoryName(modpack.Path) + "/revision.json")))
- modpacksToUpdate.Add(modpack.Name);
- }
- catch (Exception)
- {
- modpacksRevsionUnknown.Add(modpack.Name);
- }
- }
- else
- modpacksRevsionUnknown.Add(modpack.Name);
- }
- var message = string.Empty;
- if (modpacksToUpdate.Any())
- message = $"Found updates for selected installed modpacks:{Environment.NewLine} {string.Join($"{Environment.NewLine} ", modpacksToUpdate)}";
- if (modpacksRevsionUnknown.Any())
- {
- if (!string.IsNullOrEmpty(message))
- message += Environment.NewLine;
- message += $"Can't get revision for selected installed modpacks:{Environment.NewLine} {string.Join($"{Environment.NewLine} ", modpacksRevsionUnknown)}{Environment.NewLine}Please update them for correct verion checking!";
- }
- if (!string.IsNullOrEmpty(message))
- OpenErrorWindow(message);
- _logger.Debug("Checking modpacks updates finished successfully!");
- }
- 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 = string.Empty;
- private StringBuilder _consoleText = new();
- private int _downloadedIndex;
- private string _argumentsBox = string.Empty;
- private bool _isNoGameRunning = true;
- private bool _isUpdateAvailable = false;
- private string _settingsButton = "Settings";
- private string _startButtonOutput = string.Empty;
- private CancellationTokenSource _tokenSource = new();
- ILogger _logger;
- LatestLauncherVersion? _latestLauncherInfo;
- DownloadedVersion? _downloadedVersion;
- DownloadedVersion? _startedVersion;
- ObservableCollection<DownloadedVersion> _downloadedVersions;
- ObservableCollection<ServerPanelModel> _serverPanels;
- public ObservableCollection<DownloadedVersion> DownloadedVersions
- {
- get => _downloadedVersions;
- set => this.RaiseAndSetIfChanged(ref _downloadedVersions, value);
- }
- public ObservableCollection<ServerPanelModel> ServerPanels
- {
- get => _serverPanels;
- set => this.RaiseAndSetIfChanged(ref _serverPanels, value);
- }
- public ObservableCollection<Changelog>? Changelogs { get; private set; }
- public DownloadedVersion? DownloadedVersion
- {
- get => _downloadedVersion;
- set => this.RaiseAndSetIfChanged(ref _downloadedVersion, value);
- }
- public int DownloadedIndex
- {
- get => _downloadedIndex;
- set
- {
- this.RaiseAndSetIfChanged(ref _downloadedIndex, value);
- if (value >= 0 && value < DownloadedVersions.Count)
- DownloadedVersion = DownloadedVersions[value];
- }
- }
- public string Greeting => "Welcome to Cringe Launcher!";
- public string DownloadButton {
- get => _downloadButton;
- set => this.RaiseAndSetIfChanged(ref _downloadButton, value);
- }
- public string StartButton
- {
- get => _startButton;
- set => this.RaiseAndSetIfChanged(ref _startButton, value);
- }
- public string Username
- {
- get => _username;
- set
- {
- this.RaiseAndSetIfChanged(ref _username, value);
- this.RaisePropertyChanged(nameof(IsStartButtonEnabled));
- }
- }
- public string ConsoleText
- {
- 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;
- }
- }
- public string StartButtonOutput
- {
- get => _startButtonOutput;
- set => this.RaiseAndSetIfChanged(ref _startButtonOutput, value);
- }
- public string ArgumentsBox
- {
- get => _argumentsBox;
- set => this.RaiseAndSetIfChanged(ref _argumentsBox, value);
- }
- public string SettingsButton
- {
- get => _settingsButton;
- set => this.RaiseAndSetIfChanged(ref _settingsButton, value);
- }
- public bool IsNoGameRunning
- {
- get => _isNoGameRunning;
- set
- {
- this.RaiseAndSetIfChanged(ref _isNoGameRunning, value);
- this.RaisePropertyChanged(nameof(IsStartButtonEnabled));
- }
- }
- public bool IsStartButtonEnabled
- {
- get => IsNoGameRunning && !string.IsNullOrEmpty(Username);
- }
- public bool IsUpdateAvailable
- {
- get => _isUpdateAvailable;
- set => this.RaiseAndSetIfChanged(ref _isUpdateAvailable, value);
- }
- public int ConsoleTextCaretIndex
- {
- get => int.MaxValue;
- set => this.RaisePropertyChanged(nameof(ConsoleTextCaretIndex));
- }
- public async void OnClickCommand()
- {
- using var versionsDownloaderViewModel = new VersionsDownloaderViewModel();
- var versionsDownloader = new VersionsDownloader
- {
- DataContext = versionsDownloaderViewModel
- };
-
- if (Avalonia.Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop && desktop.MainWindow is not null)
- {
- try
- {
- versionsDownloader.Closed += updateAvailable;
- await versionsDownloader.ShowDialog(desktop.MainWindow);
- }
- catch (Exception ex)
- {
- //sometimes throws collection modified exception in manager tab
- OpenErrorWindow(ex);
- }
- }
- }
- public async void StartMinecraft()
- {
- await Task.Run(async() =>
- {
- try
- {
- _logger.Debug("Starting minecraft.");
- if (DownloadedVersion is null)
- {
- IsNoGameRunning = true;
- return;
- }
- int version = 0;
- using (StreamReader reader = new StreamReader(DownloadedVersion.path))
- {
- string json = reader.ReadToEnd();
- var versionJson = JsonSerializer.Deserialize<Entity.Version.Version>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
- if (versionJson is null)
- throw new ArgumentNullException(nameof(versionJson));
- if (Settings.checkGameAssets)
- {
- TaskStatus result;
- if (string.IsNullOrEmpty(versionJson.InheritsFrom))
- result = await Downloader.StartDownload(value => StartButtonOutput = value, value => { } ,value => IsNoGameRunning = value, value => { }, versionJson, _tokenSource.Token);
- else
- {
- 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 is not null)
- result = await Downloader.StartDownload(value => StartButtonOutput = value, value => { }, value => IsNoGameRunning = value, value => { }, inheritsFromJson, _tokenSource.Token);
- else
- result = TaskStatus.Faulted;
- }
- }
- if (result != TaskStatus.RanToCompletion)
- {
- IsNoGameRunning = true;
- StartButtonOutput = "Checking game files task faulted.";
- return;
- }
- }
- string arguments = StartCommandBuilder.Build(versionJson, Username);
- if (!Settings.useCustomJava)
- {
- if (versionJson?.JavaVersion?.MajorVersion is not null)
- {
- _logger.Debug("Java version required: {0}", versionJson.JavaVersion.MajorVersion);
- version = versionJson.JavaVersion.MajorVersion.Value;
- }
- else
- {
- if (!string.IsNullOrEmpty(versionJson?.InheritsFrom))
- {
- 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?.MajorVersion is not null)
- {
- _logger.Debug("Java version required: {0}", inheritsFromJson.JavaVersion.MajorVersion);
- version = inheritsFromJson.JavaVersion.MajorVersion.Value;
- }
- }
- }
- else
- {
- version = 8;
- }
- }
- }
- //ConsoleText += arguments;
- ArgumentsBox = arguments;
- }
- if (DownloadedVersion is null)
- return;
- string javaPath = Settings.javaPath;
- if (!Settings.useCustomJava)
- {
- javaPath = Path.GetFullPath(Settings.minecraftForlderPath + "javaruntime/" + version + "/bin/java");
- if (OperatingSystem.IsWindows())
- javaPath += ".exe";
- }
- else
- {
- javaPath = Path.Combine(Settings.javaPath, "bin/java");
- if (OperatingSystem.IsWindows())
- javaPath += ".exe";
- }
- _logger.Debug("Java version path: {0}", Path.Combine(Settings.minecraftForlderPath, javaPath));
- _logger.Debug("Minecraft arguments: {0}", ArgumentsBox);
- ProcessStartInfo proc;
- proc = new ProcessStartInfo
- {
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- WindowStyle = ProcessWindowStyle.Hidden,
- CreateNoWindow = true,
- FileName = Path.GetFullPath(Path.Combine(Settings.minecraftForlderPath, javaPath)),
- StandardErrorEncoding = Encoding.UTF8,
- WorkingDirectory = Path.GetDirectoryName(Path.Combine(Settings.minecraftForlderPath, javaPath)),
- Arguments = ArgumentsBox
- };
- Process minecraft = new Process();
- minecraft.StartInfo = proc;
- if (!Settings.useCustomJava)
- minecraft.StartInfo.EnvironmentVariables["JAVA_HOME"] = $"{Settings.minecraftForlderPath}javaruntime/{version}";
- else
- minecraft.StartInfo.EnvironmentVariables["JAVA_HOME"] = Settings.javaPath;
- minecraft.StartInfo.EnvironmentVariables["PATH"] = "%JAVA_HOME%\bin;%PATH%";
- #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
- Task.Run(() =>
- {
- try
- {
- _logger.Debug("Starting java process.");
- minecraft.OutputDataReceived += OutputHandler;
- minecraft.ErrorDataReceived += OutputHandler;
- //* Start process and handlers
- //minecraft.WaitForExit();
- minecraft.EnableRaisingEvents = true;
- IsNoGameRunning = false;
- _startedVersion = DownloadedVersion;
- minecraft.Start();
- minecraft.Exited += ProcessExited;
- minecraft.BeginOutputReadLine();
- minecraft.BeginErrorReadLine();
- if (!Settings.gameLogToLauncher)
- {
- minecraft.OutputDataReceived -= OutputHandler;
- minecraft.CancelOutputRead();
- }
- return Task.CompletedTask;
- }
- catch (Exception ex)
- {
- IsNoGameRunning = true;
- OpenErrorWindow(ex);
- return Task.CompletedTask;
- }
- });
- #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
- _logger.Debug("Updating Settings");
- Settings.username = _username;
- Settings.lastChosenVersion = DownloadedVersion.version;
- Settings.SaveSettings();
- }
- catch (Exception ex)
- {
- OpenErrorWindow(ex);
- }
- });
- }
- void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
- {
- //Todo create multiple TextBlocks if char limit
- if (!_consoleOutputTimer.Enabled)
- {
- _consoleOutputTimer.Stop();
- _consoleOutputTimer.Start();
- }
- _consoleText.Append(outLine.Data + "\n");
- }
- void LogHandler(object? sendingProcess, EventArgs args)
- {
- if (!_consoleOutputTimer.Enabled)
- {
- _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)
- {
- if (Avalonia.Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
- {
- Dispatcher.UIThread.InvokeAsync(() =>
- {
- var scroll = desktop.MainWindow?.GetControl<ScrollViewer>(scrollName);
- scroll?.ScrollToEnd();
- });
- }
- }
- void ProcessExited(object? sendingProcess, EventArgs e)
- {
- if(sendingProcess is Process minecraftProcess)
- {
- minecraftProcess.Exited -= ProcessExited;
- minecraftProcess.OutputDataReceived -= OutputHandler;
- minecraftProcess.ErrorDataReceived -= OutputHandler;
- minecraftProcess.CancelOutputRead();
- minecraftProcess.CancelErrorRead();
- _logger.Debug("Exit code: {0}", minecraftProcess.ExitCode);
- StartButtonOutput = "";
- IsNoGameRunning = true;
- if (minecraftProcess.ExitCode is not (0 or 2))
- OpenErrorWindow(new JavaProcessException($"Minecraft process exited with an error code {minecraftProcess.ExitCode}.\nCheck log in game folder or launcher console.", $"{Settings.minecraftForlderPath}versions/{_startedVersion.version}/crash-reports"));
- else if (minecraftProcess.ExitCode is 2)
- {
- OpenErrorWindow(new Exception("JVM exited on the startup (Exit code 2). Check your Java installation. Get more info in the laucher console."));
- }
- minecraftProcess.Dispose();
- }
- }
- public void updateAvailable()
- {
- if (DownloadedVersions is null)
- DownloadedVersions = new();
- DownloadedVersions.Clear();
- DirectoryInfo versions = new( Settings.minecraftForlderPath + "versions");
- try
- {
- 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("Found version {0}",dir.Name);
- DownloadedVersions.Add(new DownloadedVersion(checkedPath,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)
- {
- DownloadedIndex = 0;
- for (int i = 0; i < DownloadedVersions.Count; i++)
- {
- if (DownloadedVersions[i].version == Settings.lastChosenVersion)
- {
- 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, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
- File.WriteAllText(Settings.minecraftForlderPath + "launcher_profiles.json", lpString);
- }
- catch (DirectoryNotFoundException)
- {
- Directory.CreateDirectory(Settings.minecraftForlderPath + "versions");
- return;
- }
-
- }
- public void updateAvailable(object? sendingObject, EventArgs e)
- {
- try
- {
- updateAvailable();
- }
- catch (Exception ex)
- {
- OpenErrorWindow(ex);
- }
- switch (sendingObject)
- {
- case VersionsDownloader:
- ((VersionsDownloader)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 && desktop.MainWindow is not null)
- {
- 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";
- if (!File.Exists(updater.StartInfo.FileName))
- Task.Run(UpdateUpdater).Wait();
- if (File.Exists(updater.StartInfo.FileName))
- {
- updater.Start();
- if (Avalonia.Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop && desktop.MainWindow is not null)
- desktop.MainWindow.Close();
- }
- else
- OpenErrorWindow(new FileNotFoundException($"File {updater.StartInfo.FileName} not found!"));
- }
- private async void UpdateUpdater()
- {
- try
- {
- string fileName = "Updater";
- if (OperatingSystem.IsWindows())
- fileName += ".exe";
- if (File.Exists(fileName))
- {
- FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(fileName);
- var latestLauncherVersion = await Downloader.DownloadAndDeserializeJsonData<LatestLauncherVersion>("https://files.veloe.link/launcher/update/versions.json");
- if (OperatingSystem.IsLinux())
- {
- _logger.Information("Manual updates only.");
- return;
- }
- if (latestLauncherVersion?.Updater is not null && fileVersionInfo?.FileVersion is not 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;
- }
- }
- else
- _logger.Warning("Version verification for {0} failed: latestLauncherVersion or fileVersionInfo does not contain version info or null!", fileName);
- }
-
- try
- {
- _logger.Information("Downloading updater.zip");
- string url = String.Empty;
- if (OperatingSystem.IsWindows())
- url = "https://files.veloe.link/launcher/update/updater.zip";
- if (OperatingSystem.IsLinux())
- url = "https://files.veloe.link/launcher/update/updater_linux-x64.zip";
- if (url == String.Empty)
- return;
- await Downloader.DownloadFileAsync(url, "updater.zip", _tokenSource.Token);
- }
- catch (Exception)
- {
- _logger.Error("Error occured on getting updater.zip from the server.");
- throw;
- }
- _logger.Information("Unpacking updater.zip");
- ZipFile.ExtractToDirectory($"updater.zip", Directory.GetCurrentDirectory(), true);
- _logger.Information("Deleting updater.zip");
- File.Delete($"updater.zip");
-
- }
- catch (Exception ex)
- {
- OpenErrorWindow(ex);
- }
- }
- private ServerPanelModel CreateServerPanel(string name)
- {
- ServerPanelModel serverPanelModel = new(name, "Wait for update...", "No players.","-/-");
- System.Timers.Timer timeoutTimer = new System.Timers.Timer(30000);
- timeoutTimer.Elapsed += (object? source, ElapsedEventArgs e) =>
- {
- serverPanelModel.Status = $"{serverPanelModel.Name}: Offline";
- serverPanelModel.Players = "-/-";
- };
- timeoutTimer.Start();
- _connection?.On<string>($"Update{serverPanelModel.Name}", (message) =>
- {
- McStatus? status = JsonSerializer.Deserialize<McStatus>(message, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
- if(status is not null)
- {
- serverPanelModel.Status = $"{serverPanelModel.Name}: Online";
- serverPanelModel.Players = $"{status.NumPlayers}/{status.MaxPlayers}";
- serverPanelModel.Tip = String.Empty;
- if (UInt16.Parse(status.NumPlayers ?? "0") > 0)
- foreach (var player in status.Players ?? new())
- {
- serverPanelModel.Tip += player;
- serverPanelModel.Tip += "\n";
- }
- else
- serverPanelModel.Tip = "No players.";
- }
- timeoutTimer.Stop();
- timeoutTimer.Start();
- });
- return serverPanelModel;
- }
- public void OnClosing(object sender, CancelEventArgs args)
- {
- _tokenSource.Cancel();
- _tokenSource.Dispose();
- }
- }
|