diff --git a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs index bf0084f..ac2d0da 100644 --- a/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs +++ b/Mlaumcherb.Client.Avalonia/классы/Пролетариат/MyModpack.cs @@ -29,21 +29,25 @@ public class MyModpackV1 public bool optional { get; set; } } - public bool CheckFiles(IOPath basedir, bool checkHashes, bool downloadOptionalFiles, HashSet unmatchedFilesLocalPaths) + /// relative, absolute + public Dictionary CheckFiles(IOPath basedir, bool checkHashes, bool downloadOptionalFiles) { + Dictionary unmatchedFiles = new(); + IOPath launcherRoot = PathHelper.GetRootFullPath(); 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)) + IOPath relativePath = new IOPath(p.Key); + var absolutePath = Path.Concat(relativePath.StartsWith("libraries") + ? launcherRoot : basedir, relativePath); + if (!HashHelper.CheckFileSHA1(absolutePath, p.Value.sha1, checkHashes && !p.Value.allow_edit)) { - unmatchedFilesLocalPaths.Add(localPath); + unmatchedFiles.Add(relativePath, absolutePath); } } - - return unmatchedFilesLocalPaths.Count == 0; + + return unmatchedFiles; } } \ No newline at end of file diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs index f60dbc6..1444c1a 100644 --- a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/ModpackDownloadTaskFactory.cs @@ -1,7 +1,4 @@ -using System.IO.Compression; -using Mlaumcherb.Client.Avalonia.зримое; -using Mlaumcherb.Client.Avalonia.классы; -using Mlaumcherb.Client.Avalonia.холопы; +using Mlaumcherb.Client.Avalonia.классы; namespace Mlaumcherb.Client.Avalonia.сеть.TaskFactories; @@ -25,89 +22,6 @@ public class ModpackDownloadTaskFactory : INetworkTaskFactory public Task CreateAsync(bool checkHashes) { - // Modpacks can include libraries. - // This libraries are downloaded in launcher_dir/libraries through symbolic link. - var localLibsDir = Path.Concat(PathHelper.GetVersionDir(_descriptor.id), "libraries"); - var globalLibsDir = PathHelper.GetLibrariesDir(); - var dirInfo = new DirectoryInfo(localLibsDir.ToString()); - // delete dir if it isn't symlink - if(dirInfo.Exists && dirInfo.LinkTarget is null) - dirInfo.Delete(true); - if (!dirInfo.Exists) - { - LauncherApp.Logger.LogInfo(nameof(ModpackDownloadTaskFactory), - $"Creating symbolic link '{localLibsDir}' -> '{globalLibsDir}'"); - dirInfo.CreateAsSymbolicLink(globalLibsDir.ToString()); - } - return _implementationVersion.CreateAsync(checkHashes); } -} - -public class MyModpackV1DownloadTaskFactory : INetworkTaskFactory -{ - private readonly GameVersionDescriptor _descriptor; - private IOPath _modpackDescriptorPath; - private IOPath _versionDir; - private MyModpackV1? _modpack; - private HashSet _filesToDosnload = new(); - - public MyModpackV1DownloadTaskFactory(GameVersionDescriptor descriptor) - { - _descriptor = descriptor; - _modpackDescriptorPath = PathHelper.GetModpackDescriptorPath(_descriptor.id); - _versionDir = PathHelper.GetVersionDir(_descriptor.id); - } - - public async Task CreateAsync(bool checkHashes) - { - if(_descriptor.modpack is null) - throw new ArgumentNullException(nameof(_descriptor.modpack)); - - (_modpack, bool didDownloadModpackDescriptor) = await NetworkHelper.ReadOrDownloadAndDeserialize( - _modpackDescriptorPath, - _descriptor.modpack.artifact.url, - _descriptor.modpack.artifact.sha1, - checkHashes); - 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}"); - - NetworkTask? networkTask = null; - if(!_modpack.CheckFiles(_versionDir, checkHashes, didDownloadModpackDescriptor, _filesToDosnload)) - { - networkTask = new NetworkTask( - $"modpack '{_descriptor.assetIndex.id}'", - _modpack.zip.size, - Download - ); - } - - return networkTask; - } - - private async Task Download(NetworkProgressReporter pr, CancellationToken ct) - { - LauncherApp.Logger.LogInfo(nameof(NetworkHelper), $"started downloading modpack '{_modpack!.name}'"); - if(string.IsNullOrEmpty(_modpack.zip.url)) - throw new Exception($"modpack '{_modpack.name}' doesn't have a url to download"); - - var _archivePath = Path.Concat(PathHelper.GetCacheDir(), "modpacks", _modpack.name + ".zip"); - await NetworkHelper.DownloadFile(_modpack.zip.url, _archivePath, ct, pr.AddBytesCount); - - await using var zipf = File.OpenRead(_archivePath); - using var archive = new ZipArchive(zipf); - foreach (var entry in archive.Entries) - { - IOPath localPath = new(entry.FullName); - if(_filesToDosnload.Contains(localPath)) - { - var real_path = Path.Concat(_versionDir, localPath); - Directory.Create(real_path.ParentDir()); - entry.ExtractToFile(real_path.ToString(), true); - } - } - - LauncherApp.Logger.LogInfo(nameof(NetworkHelper), $"finished downloading modpack '{_modpack.name}'"); - } } \ No newline at end of file diff --git a/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/MyModpackV1DownloadTaskFactory.cs b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/MyModpackV1DownloadTaskFactory.cs new file mode 100644 index 0000000..7dc7999 --- /dev/null +++ b/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/MyModpackV1DownloadTaskFactory.cs @@ -0,0 +1,75 @@ +using System.IO.Compression; +using Mlaumcherb.Client.Avalonia.зримое; +using Mlaumcherb.Client.Avalonia.классы; +using Mlaumcherb.Client.Avalonia.холопы; + +namespace Mlaumcherb.Client.Avalonia.сеть.TaskFactories; + +public class MyModpackV1DownloadTaskFactory : INetworkTaskFactory +{ + private readonly GameVersionDescriptor _descriptor; + private IOPath _modpackDescriptorPath; + private IOPath _versionDir; + private MyModpackV1? _modpack; + // relative, absolute + private Dictionary _filesToDosnload = new(); + + public MyModpackV1DownloadTaskFactory(GameVersionDescriptor descriptor) + { + _descriptor = descriptor; + _modpackDescriptorPath = PathHelper.GetModpackDescriptorPath(_descriptor.id); + _versionDir = PathHelper.GetVersionDir(_descriptor.id); + } + + public async Task CreateAsync(bool checkHashes) + { + if(_descriptor.modpack is null) + throw new ArgumentNullException(nameof(_descriptor.modpack)); + + (_modpack, bool didDownloadModpackDescriptor) = await NetworkHelper.ReadOrDownloadAndDeserialize( + _modpackDescriptorPath, + _descriptor.modpack.artifact.url, + _descriptor.modpack.artifact.sha1, + checkHashes); + 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}"); + + NetworkTask? networkTask = null; + _filesToDosnload = _modpack.CheckFiles(_versionDir, checkHashes, didDownloadModpackDescriptor); + if(_filesToDosnload.Count > 0) + { + networkTask = new NetworkTask( + $"modpack '{_modpack.name}'", + _modpack.zip.size, + Download + ); + } + + return networkTask; + } + + private async Task Download(NetworkProgressReporter pr, CancellationToken ct) + { + LauncherApp.Logger.LogInfo(nameof(NetworkHelper), $"started downloading modpack '{_modpack!.name}'"); + if(string.IsNullOrEmpty(_modpack.zip.url)) + throw new Exception($"modpack '{_modpack.name}' doesn't have a url to download"); + + var _archivePath = Path.Concat(PathHelper.GetCacheDir(), "modpacks", _modpack.name + ".zip"); + await NetworkHelper.DownloadFile(_modpack.zip.url, _archivePath, ct, pr.AddBytesCount); + + await using var zipf = File.OpenRead(_archivePath); + using var archive = new ZipArchive(zipf); + foreach (var entry in archive.Entries) + { + IOPath relativePath = new(entry.FullName); + if(_filesToDosnload.TryGetValue(relativePath, out var absolutePath)) + { + Directory.Create(absolutePath.ParentDir()); + entry.ExtractToFile(absolutePath.ToString(), true); + } + } + + LauncherApp.Logger.LogInfo(nameof(NetworkHelper), $"finished downloading modpack '{_modpack.name}'"); + } +} \ No newline at end of file