using System.Security.Cryptography; using DTLib.Extensions; using Млаумчерб.Клиент.видимое; using Млаумчерб.Клиент.классы; using static Млаумчерб.Клиент.сеть.Сеть; namespace Млаумчерб.Клиент.сеть.NetworkTaskFactories; public class LibrariesDownloadTaskFactory : INetworkTaskFactory { private VersionDescriptor _descriptor; private Libraries _libraries; private SHA1 _hasher; private List _libsToDownload = new(); public LibrariesDownloadTaskFactory(VersionDescriptor descriptor, Libraries libraries) { _descriptor = descriptor; _libraries = libraries; _hasher = SHA1.Create(); } public Task CreateAsync(bool checkHashes) { NetworkTask? networkTask = null; if (!CheckFiles(checkHashes)) networkTask = new NetworkTask( $"libraries '{_descriptor.id}'", GetTotalSize(), Download ); return Task.FromResult(networkTask); } private bool CheckFiles(bool checkHashes) { _libsToDownload.Clear(); foreach (var l in _libraries.Libs) { if (!File.Exists(l.jarFilePath)) { _libsToDownload.Add(l); } else if (checkHashes) { using var fs = File.OpenRead(l.jarFilePath); string hash = _hasher.ComputeHash(fs).HashToString(); if(hash != l.artifact.sha1) _libsToDownload.Add(l); } } return _libsToDownload.Count == 0; } private long GetTotalSize() { long total = 0; foreach (var l in _libsToDownload) total += l.artifact.size; return total; } private async Task Download(NetworkProgressReporter pr, CancellationToken ct) { Приложение.Логгер.LogInfo(nameof(Сеть), "started downloading libraries"); ParallelOptions opt = new() { MaxDegreeOfParallelism = ParallelDownloadsN, CancellationToken = ct }; await Parallel.ForEachAsync(_libsToDownload, opt, async (l, _ct) => { Приложение.Логгер.LogDebug(nameof(Сеть), $"downloading library '{l.name}' to '{l.jarFilePath}'"); await DownloadFileHTTP(l.artifact.url, l.jarFilePath, _ct, pr.AddBytesCount); //TODO: extract natives from jar }); Приложение.Логгер.LogInfo(nameof(Сеть), "finished downloading libraries"); } }