diff --git a/Mlaumcherb.Client.Avalonia/зримое/MainWindow.axaml b/Mlaumcherb.Client.Avalonia/зримое/MainWindow.axaml index 937b397..b2619b8 100644 --- a/Mlaumcherb.Client.Avalonia/зримое/MainWindow.axaml +++ b/Mlaumcherb.Client.Avalonia/зримое/MainWindow.axaml @@ -93,7 +93,7 @@ - Проверить файлы игры + Обновить файлы игры Скачивать джаву diff --git a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/InstalledGameVersionProps.cs b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/InstalledGameVersionProps.cs index b337d4a..5456a4a 100644 --- a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/InstalledGameVersionProps.cs +++ b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/InstalledGameVersionProps.cs @@ -53,7 +53,7 @@ public class InstalledGameVersionProps : IComparable, } // Descriptor is downloaded here - if (HashHelper.CheckFileSHA1(DescriptorPath, DescriptorProps?.sha1, checkForUpdates)) + if (!HashHelper.CheckFileSHA1(DescriptorPath, DescriptorProps?.sha1, checkForUpdates)) { if (DescriptorProps is null) throw new NullReferenceException( diff --git a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/ModpackFilesManifest.cs b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/ModpackFilesManifest.cs deleted file mode 100644 index c3f8e98..0000000 --- a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/ModpackFilesManifest.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Mlaumcherb.Client.Avalonia.холопы; - -namespace Mlaumcherb.Client.Avalonia.классы; - -public class ModpackFilesManifest -{ - public class FileProps - { - [JsonRequired] public string sha1 { get; set; } = ""; - public bool allow_edit { get; set; } = false; - } - - /// relative_path, hash - [JsonRequired] public Dictionary files { get; set; } = new(); - - public bool CheckFiles(IOPath basedir, bool checkHashes, HashSet unmatchedFilesLocalPaths) - { - foreach (var p in files) - { - var localPath = new IOPath(p.Key); - var realPath = Path.Concat(basedir, localPath); - if (!HashHelper.CheckFileSHA1(realPath, p.Value.sha1, checkHashes && !p.Value.allow_edit)) - { - unmatchedFilesLocalPaths.Add(localPath); - } - } - - return unmatchedFilesLocalPaths.Count == 0; - } -} \ No newline at end of file diff --git a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs index 757df62..bf0084f 100644 --- a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs +++ b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs @@ -1,4 +1,6 @@ -namespace Mlaumcherb.Client.Avalonia.классы; +using Mlaumcherb.Client.Avalonia.холопы; + +namespace Mlaumcherb.Client.Avalonia.классы; public class MyModpackRemoteProps { @@ -8,12 +10,40 @@ public class MyModpackRemoteProps public class MyModpackV1 { - // 1 [JsonRequired] public int format_version { get; set; } [JsonRequired] public string name { get; set; } = ""; // zip archive with all files [JsonRequired] public Artifact zip { get; set; } = null!; - // ModpackFilesManifest - [JsonRequired] public Artifact manifest { get; set; } = null!; + /// relative_path, hash + // ReSharper disable once CollectionNeverUpdated.Global + [JsonRequired] public Dictionary files { get; set; } = new(); + + + public class FileProps + { + [JsonRequired] public string sha1 { get; set; } = ""; + // disable hash validation, allowing users to edit this file + public bool allow_edit { get; set; } + // don't re-download file if it was deleted by user + public bool optional { get; set; } + } + + public bool CheckFiles(IOPath basedir, bool checkHashes, bool downloadOptionalFiles, HashSet unmatchedFilesLocalPaths) + { + foreach (var p in files) + { + if(!downloadOptionalFiles && p.Value.optional) + continue; + + var localPath = new IOPath(p.Key); + var realPath = Path.Concat(basedir, localPath); + if (!HashHelper.CheckFileSHA1(realPath, p.Value.sha1, checkHashes && !p.Value.allow_edit)) + { + unmatchedFilesLocalPaths.Add(localPath); + } + } + + return unmatchedFilesLocalPaths.Count == 0; + } } \ No newline at end of file diff --git a/Mlaumcherb.Client.Avalonia/сеть/NetworkHelper.cs b/Mlaumcherb.Client.Avalonia/сеть/NetworkHelper.cs index 1ff5762..258c9c9 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/NetworkHelper.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/NetworkHelper.cs @@ -42,23 +42,25 @@ public static class NetworkHelper } - public static async Task ReadOrDownload(IOPath filePath, string url, + /// (file_content, didDownload) + public static async Task<(string, bool)> ReadOrDownload(IOPath filePath, string url, string? sha1, bool checkHashes) { if (HashHelper.CheckFileSHA1(filePath, sha1, checkHashes)) - return File.ReadAllText(filePath); + return (File.ReadAllText(filePath), false); string txt = await NetworkHelper.GetString(url); File.WriteAllText(filePath, txt); - return txt; + return (txt, true); } - public static async Task ReadOrDownloadAndDeserialize(IOPath filePath, string url, + /// (file_content, didDownload) + public static async Task<(T, bool)> ReadOrDownloadAndDeserialize(IOPath filePath, string url, string? sha1, bool checkHashes) { - string text = await ReadOrDownload(filePath, url, sha1, checkHashes); + (string text, bool didDownload) = await ReadOrDownload(filePath, url, sha1, checkHashes); var result = JsonConvert.DeserializeObject(text) ?? throw new Exception($"can't deserialize {typeof(T).Name}"); - return result; + return (result, didDownload); } } \ No newline at end of file diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/AssetsDownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/AssetsDownloadTaskFactory.cs index 1b5469d..bd73b5e 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/AssetsDownloadTaskFactory.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/AssetsDownloadTaskFactory.cs @@ -22,24 +22,26 @@ public class AssetsDownloadTaskFactory : INetworkTaskFactory public async Task CreateAsync(bool checkHashes) { + NetworkTask? networkTask = null; if (!await CheckFilesAsync(checkHashes)) - return new NetworkTask( + { + networkTask = new NetworkTask( $"assets '{_descriptor.assetIndex.id}'", GetTotalSize(), Download ); + } - return null; + return networkTask; } private async Task CheckFilesAsync(bool checkHashes) { - var assetIndex = await ReadOrDownloadAndDeserialize( + (AssetIndex assetIndex, _) = await ReadOrDownloadAndDeserialize( _indexFilePath, _descriptor.assetIndex.url, _descriptor.assetIndex.sha1, checkHashes); - _assetsToDownload.Clear(); // removing duplicates for Dictionary (idk how can it be possible, but Newtonsoft.Json creates them) HashSet assetHashes = new HashSet(); foreach (var pair in assetIndex.objects) diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/JavaDownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/JavaDownloadTaskFactory.cs index 5966ebd..9711cda 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/JavaDownloadTaskFactory.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/JavaDownloadTaskFactory.cs @@ -28,11 +28,14 @@ public class JavaDownloadTaskFactory : INetworkTaskFactory NetworkTask? networkTask = null; if (!CheckFiles(checkHashes)) - networkTask = new( - $"java runtime '{_descriptor.javaVersion.component}'", - GetTotalSize(), - Download - ); + { + networkTask = new NetworkTask( + $"java runtime '{_descriptor.javaVersion.component}'", + GetTotalSize(), + Download + ); + } + return networkTask; } diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/LibrariesDownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/LibrariesDownloadTaskFactory.cs index c88b0ea..3d00145 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/LibrariesDownloadTaskFactory.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/LibrariesDownloadTaskFactory.cs @@ -24,11 +24,14 @@ public class LibrariesDownloadTaskFactory : INetworkTaskFactory { NetworkTask? networkTask = null; if (!CheckFiles(checkHashes)) + { networkTask = new NetworkTask( $"libraries '{_descriptor.id}'", GetTotalSize(), Download ); + } + return Task.FromResult(networkTask); } diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs index d52b376..d93bf45 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs @@ -28,19 +28,16 @@ public class ModpackDownloadTaskFactory : INetworkTaskFactory public class MyModpackV1DownloadTaskFactory : INetworkTaskFactory { - private IOPath _modpackManifesPath; private readonly GameVersionDescriptor _descriptor; private IOPath _modpackDescriptorPath; private IOPath _versionDir; private MyModpackV1? _modpack; - private ModpackFilesManifest? _modpackManifest; private HashSet _filesToDosnload = new(); public MyModpackV1DownloadTaskFactory(GameVersionDescriptor descriptor) { _descriptor = descriptor; _modpackDescriptorPath = PathHelper.GetModpackDescriptorPath(_descriptor.id); - _modpackManifesPath = PathHelper.GetModpackManifestPath(_descriptor.id); _versionDir = PathHelper.GetVersionDir(_descriptor.id); } @@ -48,9 +45,8 @@ public class MyModpackV1DownloadTaskFactory : INetworkTaskFactory { if(_descriptor.modpack is null) throw new ArgumentNullException(nameof(_descriptor.modpack)); - - - _modpack = await NetworkHelper.ReadOrDownloadAndDeserialize( + + (_modpack, bool didDownloadModpackDescriptor) = await NetworkHelper.ReadOrDownloadAndDeserialize( _modpackDescriptorPath, _descriptor.modpack.artifact.url, _descriptor.modpack.artifact.sha1, @@ -58,21 +54,18 @@ public class MyModpackV1DownloadTaskFactory : INetworkTaskFactory if (_modpack.format_version != _descriptor.modpack.format_version) throw new Exception($"Modpack.format_version mismatches descriptor.modpack.version: " + $"{_modpack.format_version} != {_descriptor.modpack.format_version}"); - - _modpackManifest = await NetworkHelper.ReadOrDownloadAndDeserialize( - _modpackManifesPath, - _modpack.manifest.url, - _modpack.manifest.sha1, - checkHashes); - - if(!_modpackManifest.CheckFiles(_versionDir, checkHashes, _filesToDosnload)) - return new NetworkTask( + + NetworkTask? networkTask = null; + if(!_modpack.CheckFiles(_versionDir, checkHashes, didDownloadModpackDescriptor, _filesToDosnload)) + { + networkTask = new NetworkTask( $"modpack '{_descriptor.assetIndex.id}'", _modpack.zip.size, Download ); + } - return null; + return networkTask; } private async Task Download(NetworkProgressReporter pr, CancellationToken ct) diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/VersionJarDownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/VersionJarDownloadTaskFactory.cs index ede6492..42f65d1 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/VersionJarDownloadTaskFactory.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/VersionJarDownloadTaskFactory.cs @@ -20,11 +20,14 @@ public class VersionJarDownloadTaskFactory : INetworkTaskFactory { NetworkTask? networkTask = null; if (!CheckFiles(checkHashes)) + { networkTask = new NetworkTask( - $"game version jar '{_descriptor.id}'", - GetTotalSize(), - Download - ); + $"game version jar '{_descriptor.id}'", + GetTotalSize(), + Download + ); + } + return Task.FromResult(networkTask); } diff --git a/Mlaumcherb.Client.Avalonia/холопы/PathHelper.cs b/Mlaumcherb.Client.Avalonia/холопы/PathHelper.cs index 3d56b8d..10f70ec 100644 --- a/Mlaumcherb.Client.Avalonia/холопы/PathHelper.cs +++ b/Mlaumcherb.Client.Avalonia/холопы/PathHelper.cs @@ -57,9 +57,6 @@ public static class PathHelper public static IOPath GetModpackDescriptorPath(string game_version) => Path.Concat(GetVersionDir(game_version), "timerix_modpack.json"); - - public static IOPath GetModpackManifestPath(string game_version) => - Path.Concat(GetVersionDir(game_version), "timerix_modpack_files.json"); public static IOPath GetCacheDir() => Path.Concat(GetRootFullPath(), "cache");