using System.IO.Compression; using Mlaumcherb.Client.Avalonia.зримое; using Mlaumcherb.Client.Avalonia.классы; using Mlaumcherb.Client.Avalonia.холопы; namespace Mlaumcherb.Client.Avalonia.сеть.TaskFactories; public class ModpackDownloadTaskFactory : INetworkTaskFactory { INetworkTaskFactory _implementationVersion; public ModpackDownloadTaskFactory(GameVersionDescriptor descriptor) { if(descriptor.modpack is null) throw new ArgumentNullException(nameof(descriptor.modpack)); _implementationVersion = descriptor.modpack.format_version switch { 1 => new MyModpackV1DownloadTaskFactory(descriptor), _ => throw new Exception($"Unknown Modpack format_version: {descriptor.modpack.format_version}") }; } public Task CreateAsync(bool checkHashes) { return _implementationVersion.CreateAsync(checkHashes); } } 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); } public async Task CreateAsync(bool checkHashes) { if(_descriptor.modpack is null) throw new ArgumentNullException(nameof(_descriptor.modpack)); _modpack = 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}"); _modpackManifest = await NetworkHelper.ReadOrDownloadAndDeserialize( _modpackManifesPath, _modpack.manifest.url, _modpack.manifest.sha1, checkHashes); if(!_modpackManifest.CheckFiles(_versionDir, checkHashes, _filesToDosnload)) return new NetworkTask( $"modpack '{_descriptor.assetIndex.id}'", _modpack.zip.size, Download ); return null; } 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("downloads/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}'"); } }