diff --git a/Nebula.UpdateResolver/MainWindow.axaml b/Nebula.UpdateResolver/MainWindow.axaml index 25e3338..63619d1 100644 --- a/Nebula.UpdateResolver/MainWindow.axaml +++ b/Nebula.UpdateResolver/MainWindow.axaml @@ -14,10 +14,10 @@ mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="225" x:Class="Nebula.UpdateResolver.MainWindow" Title="Nebula.UpdateResolver"> - + - + + diff --git a/Nebula.UpdateResolver/MainWindow.axaml.cs b/Nebula.UpdateResolver/MainWindow.axaml.cs index 2f8504a..1061834 100644 --- a/Nebula.UpdateResolver/MainWindow.axaml.cs +++ b/Nebula.UpdateResolver/MainWindow.axaml.cs @@ -1,12 +1,17 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Net.Http; +using System.Text; using System.Threading; using System.Threading.Tasks; using Avalonia.Controls; +using Nebula.Shared.FileApis; using Nebula.Shared.FileApis.Interfaces; using Nebula.Shared.Models; using Nebula.Shared.Services; +using Tmds.DBus.Protocol; namespace Nebula.UpdateResolver; @@ -15,52 +20,88 @@ public partial class MainWindow : Window private readonly ConfigurationService _configurationService; private readonly RestService _restService; private readonly HttpClient _httpClient = new HttpClient(); - public IReadWriteFileApi FileApi { get; set; } + public FileApi FileApi { get; set; } public MainWindow(FileService fileService, ConfigurationService configurationService, RestService restService) { _configurationService = configurationService; _restService = restService; InitializeComponent(); - FileApi = fileService.CreateFileApi("app"); - + FileApi = (FileApi)fileService.CreateFileApi("app"); + + Start(); } - private async Task DownloadFiles() + private async Task Start() { var info = await EnsureFiles(); + Log("Downloading files..."); foreach (var file in info.ToDelete) { + Log("Deleting " + file.Path); FileApi.Remove(file.Path); } + var loadedManifest = info.FilesExist; + Save(loadedManifest); + + var count = info.ToDownload.Count; + var resolved = 0; + foreach (var file in info.ToDownload) { - using var response = _httpClient.GetAsync( + using var response = await _httpClient.GetAsync( _configurationService.GetConfigValue(UpdateConVars.UpdateCacheUrl) - + "/" + file.Hash - ); - response.Result.EnsureSuccessStatusCode(); - await using var stream = await response.Result.Content.ReadAsStreamAsync(); + + "/" + file.Hash); + + response.EnsureSuccessStatusCode(); + await using var stream = await response.Content.ReadAsStreamAsync(); FileApi.Save(file.Path, stream); + resolved++; + Log("Saving " + file.Path, (int)(resolved/(float)count*100f)); + + loadedManifest.Add(file); + Save(loadedManifest); } + Log("Download finished. Running launcher..."); + + var process = Process.Start(new ProcessStartInfo + { + FileName = "dotnet.exe", + Arguments = Path.Join(FileApi.RootPath,"Nebula.Launcher.dll"), + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + StandardOutputEncoding = Encoding.UTF8 + }); + + Thread.Sleep(2000); + + Environment.Exit(0); } private async Task EnsureFiles() { + Log("Ensuring launcher manifest..."); var manifest = await _restService.GetAsync( - _configurationService.GetConfigValue(UpdateConVars.UpdateCacheUrl)!, CancellationToken.None); - + new Uri(_configurationService.GetConfigValue(UpdateConVars.UpdateCacheUrl)! + "/manifest.json"), CancellationToken.None); + var toDownload = new HashSet(); var toDelete = new HashSet(); + var filesExist = new HashSet(); + Log("Manifest loaded!"); if (_configurationService.TryGetConfigValue(UpdateConVars.CurrentLauncherManifest, out var currentManifest)) { + Log("Delta manifest loaded!"); foreach (var file in currentManifest.Entries) { - if(!manifest.Entries.Contains(file)) + if (!manifest.Entries.Contains(file)) toDelete.Add(file); + else + filesExist.Add(file); } foreach (var file in manifest.Entries) @@ -71,12 +112,29 @@ public partial class MainWindow : Window } else { - _configurationService.SetConfigValue(UpdateConVars.CurrentLauncherManifest, manifest); toDownload = manifest.Entries; } + + Log("Saving launcher manifest..."); - return new ManifestEnsureInfo(toDownload, toDelete); + return new ManifestEnsureInfo(toDownload, toDelete, filesExist); + } + + private void Log(string message, int percentage = 0) + { + ProgressLabel.Content = message; + if (percentage == 0) + PercentLabel.Content = ""; + else + PercentLabel.Content = percentage + "%"; + + Console.WriteLine(message); + } + + private void Save(HashSet entries) + { + _configurationService.SetConfigValue(UpdateConVars.CurrentLauncherManifest, new LauncherManifest(entries)); } } -public record struct ManifestEnsureInfo(HashSet ToDownload, HashSet ToDelete); \ No newline at end of file +public record struct ManifestEnsureInfo(HashSet ToDownload, HashSet ToDelete, HashSet FilesExist); \ No newline at end of file diff --git a/Nebula.UpdateResolver/UpdateCVars.cs b/Nebula.UpdateResolver/UpdateCVars.cs index 0709462..c48928c 100644 --- a/Nebula.UpdateResolver/UpdateCVars.cs +++ b/Nebula.UpdateResolver/UpdateCVars.cs @@ -6,8 +6,8 @@ namespace Nebula.UpdateResolver; public static class UpdateConVars { - public static readonly ConVar UpdateCacheUrl = - ConVarBuilder.Build("update.url",new Uri("https://cinka.ru/nebula-launcher/files/publish/release")); + public static readonly ConVar UpdateCacheUrl = + ConVarBuilder.Build("update.url","https://cinka.ru/nebula-launcher/files/publish/release"); public static readonly ConVar CurrentLauncherManifest = ConVarBuilder.Build("update.manifest"); } \ No newline at end of file diff --git a/Nebula.sln.DotSettings.user b/Nebula.sln.DotSettings.user index 4fc2048..5772bd1 100644 --- a/Nebula.sln.DotSettings.user +++ b/Nebula.sln.DotSettings.user @@ -1,3 +1,4 @@  ForceIncluded + ForceIncluded ForceIncluded \ No newline at end of file