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}'"); } }