113 lines
4.7 KiB
C#
113 lines
4.7 KiB
C#
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;
|
||
private GameVersionDescriptor _descriptor;
|
||
|
||
public ModpackDownloadTaskFactory(GameVersionDescriptor descriptor)
|
||
{
|
||
if(descriptor.modpack is null)
|
||
throw new ArgumentNullException(nameof(descriptor.modpack));
|
||
|
||
_descriptor = descriptor;
|
||
_implementationVersion = descriptor.modpack.format_version switch
|
||
{
|
||
1 => new MyModpackV1DownloadTaskFactory(descriptor),
|
||
_ => throw new Exception($"Unknown Modpack format_version: {descriptor.modpack.format_version}")
|
||
};
|
||
}
|
||
|
||
public Task<NetworkTask?> 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<IOPath> _filesToDosnload = new();
|
||
|
||
public MyModpackV1DownloadTaskFactory(GameVersionDescriptor descriptor)
|
||
{
|
||
_descriptor = descriptor;
|
||
_modpackDescriptorPath = PathHelper.GetModpackDescriptorPath(_descriptor.id);
|
||
_versionDir = PathHelper.GetVersionDir(_descriptor.id);
|
||
}
|
||
|
||
public async Task<NetworkTask?> CreateAsync(bool checkHashes)
|
||
{
|
||
if(_descriptor.modpack is null)
|
||
throw new ArgumentNullException(nameof(_descriptor.modpack));
|
||
|
||
(_modpack, bool didDownloadModpackDescriptor) = await NetworkHelper.ReadOrDownloadAndDeserialize<MyModpackV1>(
|
||
_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}'");
|
||
}
|
||
} |