mlaumcherb/Mlaumcherb.Client.Avalonia/сеть/TaskFactories/LibrariesDownloadTaskFactory.cs

106 lines
3.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.IO.Compression;
using Mlaumcherb.Client.Avalonia.зримое;
using Mlaumcherb.Client.Avalonia.классы;
using Mlaumcherb.Client.Avalonia.холопы;
using static Mlaumcherb.Client.Avalonia.сеть.NetworkHelper;
namespace Mlaumcherb.Client.Avalonia.сеть.TaskFactories;
public class LibrariesDownloadTaskFactory : INetworkTaskFactory
{
private GameVersionDescriptor _descriptor;
private Libraries _libraries;
private List<Libraries.JarLib> _libsToDownload = new();
private IOPath _nativesDir;
public LibrariesDownloadTaskFactory(GameVersionDescriptor descriptor, Libraries libraries)
{
_descriptor = descriptor;
_libraries = libraries;
_nativesDir = PathHelper.GetNativeLibrariesDir(descriptor.id);
}
public Task<NetworkTask?> 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();
bool nativeDirExists = Directory.Exists(_nativesDir);
foreach (var l in _libraries.Libs)
{
if (l is Libraries.NativeLib native)
{
//TODO: replace with actual native libraries check
if(!nativeDirExists || checkHashes)
{
_libsToDownload.Add(l);
}
}
else
{
if (!HashHelper.CheckFileSHA1(l.jarFilePath, l.artifact?.sha1, checkHashes))
{
_libsToDownload.Add(l);
}
}
}
return _libsToDownload.Count == 0;
}
private long GetTotalSize()
{
long total = 0;
foreach (var l in _libsToDownload)
total += l.artifact?.size ?? 0;
return total;
}
private async Task Download(NetworkProgressReporter pr, CancellationToken ct)
{
LauncherApp.Logger.LogInfo(nameof(NetworkHelper), $"started downloading libraries '{_descriptor.id}'");
ParallelOptions opt = new()
{
MaxDegreeOfParallelism = LauncherApp.Config.max_parallel_downloads,
CancellationToken = ct
};
await Parallel.ForEachAsync(_libsToDownload, opt, async (l, _ct) =>
{
LauncherApp.Logger.LogDebug(nameof(NetworkHelper), $"downloading library '{l.name}' to '{l.jarFilePath}'");
if(string.IsNullOrEmpty(l.artifact?.url))
throw new Exception($"library '{l.name}' doesn't have a url to download");
await DownloadFile(l.artifact.url, l.jarFilePath, _ct, pr.AddBytesCount);
if (l is Libraries.NativeLib n)
{
await using var zipf = File.OpenRead(n.jarFilePath);
using var archive = new ZipArchive(zipf);
foreach (var entry in archive.Entries)
{
if (n.extractionOptions?.exclude?.Contains(entry.FullName) is true or null)
continue;
var real_path = Path.Concat(_nativesDir, entry.FullName);
Directory.Create(real_path.ParentDir());
entry.ExtractToFile(real_path.ToString(), true);
}
}
});
LauncherApp.Logger.LogInfo(nameof(NetworkHelper), $"finished downloading libraries '{_descriptor.id}'");
}
}