its downloading!!!
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using DTLib.Extensions;
|
||||
using Млаумчерб.Клиент.видимое;
|
||||
using Млаумчерб.Клиент.зримое;
|
||||
using Млаумчерб.Клиент.классы;
|
||||
using static Млаумчерб.Клиент.сеть.Сеть;
|
||||
|
||||
@@ -37,7 +39,7 @@ public class AssetsDownloadTaskFactory : INetworkTaskFactory
|
||||
if(!File.Exists(_indexFilePath))
|
||||
{
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"started downloading asset index to '{_indexFilePath}'");
|
||||
await DownloadFileHTTP(_descriptor.assetIndex.url, _indexFilePath);
|
||||
await DownloadFile(_descriptor.assetIndex.url, _indexFilePath);
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), "finished downloading asset index");
|
||||
}
|
||||
|
||||
@@ -86,7 +88,7 @@ public class AssetsDownloadTaskFactory : INetworkTaskFactory
|
||||
public string url;
|
||||
public IOPath filePath;
|
||||
|
||||
public AssetDownloadProperties(string key, GameAssetProperties p)
|
||||
public AssetDownloadProperties(string key, AssetProperties p)
|
||||
{
|
||||
name = key;
|
||||
hash = p.hash;
|
||||
@@ -100,13 +102,35 @@ public class AssetsDownloadTaskFactory : INetworkTaskFactory
|
||||
private async Task Download(NetworkProgressReporter pr, CancellationToken ct)
|
||||
{
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"started downloading assets '{_descriptor.assetIndex.id}'");
|
||||
ParallelOptions opt = new() { MaxDegreeOfParallelism = ParallelDownloadsN, CancellationToken = ct };
|
||||
ParallelOptions opt = new()
|
||||
{
|
||||
MaxDegreeOfParallelism = Приложение.Настройки.максимум_параллельных_загрузок,
|
||||
CancellationToken = ct
|
||||
};
|
||||
await Parallel.ForEachAsync(_assetsToDownload, opt,
|
||||
async (a, _ct) =>
|
||||
async (a, _ct) =>
|
||||
{
|
||||
bool completed = false;
|
||||
while(!completed)
|
||||
{
|
||||
Приложение.Логгер.LogDebug(nameof(Сеть), $"downloading asset '{a.name}' {a.hash}");
|
||||
await DownloadFileHTTP(a.url, a.filePath, _ct, pr.AddBytesCount);
|
||||
});
|
||||
try
|
||||
{
|
||||
await DownloadFile(a.url, a.filePath, _ct, pr.AddBytesCount);
|
||||
completed = true;
|
||||
}
|
||||
catch (HttpRequestException httpException)
|
||||
{
|
||||
// wait on rate limit
|
||||
if(httpException.StatusCode == HttpStatusCode.TooManyRequests)
|
||||
{
|
||||
Приложение.Логгер.LogDebug(nameof(Сеть), "rate limit hit");
|
||||
await Task.Delay(1000, _ct);
|
||||
}
|
||||
else throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"finished downloading assets '{_descriptor.assetIndex.id}'");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Security.Cryptography;
|
||||
using EasyCompressor;
|
||||
using DTLib.Extensions;
|
||||
using Млаумчерб.Клиент.зримое;
|
||||
using Млаумчерб.Клиент.классы;
|
||||
using static Млаумчерб.Клиент.сеть.Сеть;
|
||||
|
||||
@@ -7,23 +8,27 @@ namespace Млаумчерб.Клиент.сеть.NetworkTaskFactories;
|
||||
|
||||
public class JavaDownloadTaskFactory : INetworkTaskFactory
|
||||
{
|
||||
private const string INDEX_URL =
|
||||
private const string CATALOG_URL =
|
||||
"https://launchermeta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json";
|
||||
private GameVersionDescriptor _descriptor;
|
||||
private IOPath _javaVersionDir;
|
||||
private SHA1 _hasher;
|
||||
private LZMACompressor _lzma;
|
||||
private JavaDistributiveManifest? _distributiveManifest;
|
||||
private List<(IOPath path, JavaDistributiveElementProps props)> _filesToDownload = new();
|
||||
|
||||
public JavaDownloadTaskFactory(GameVersionDescriptor descriptor)
|
||||
{
|
||||
_descriptor = descriptor;
|
||||
_javaVersionDir = Пути.GetJavaRuntimeDir(_descriptor.javaVersion.component);
|
||||
_hasher = SHA1.Create();
|
||||
_lzma = new LZMACompressor();
|
||||
}
|
||||
|
||||
public Task<NetworkTask?> CreateAsync(bool checkHashes)
|
||||
public async Task<NetworkTask?> CreateAsync(bool checkHashes)
|
||||
{
|
||||
var catalog = await DownloadStringAndDeserialize<JavaVersionCatalog>(CATALOG_URL);
|
||||
var versionProps = catalog.GetVersionProps(_descriptor.javaVersion);
|
||||
_distributiveManifest = await DownloadStringAndDeserialize<JavaDistributiveManifest>(versionProps.manifest.url);
|
||||
|
||||
NetworkTask? networkTask = null;
|
||||
if (!CheckFiles(checkHashes))
|
||||
networkTask = new(
|
||||
@@ -31,26 +36,87 @@ public class JavaDownloadTaskFactory : INetworkTaskFactory
|
||||
GetTotalSize(),
|
||||
Download
|
||||
);
|
||||
return Task.FromResult(networkTask);
|
||||
return networkTask;
|
||||
}
|
||||
|
||||
private bool CheckFiles(bool checkHashes)
|
||||
{
|
||||
//TODO: download catalog
|
||||
//TODO: download manifest for required runtime
|
||||
//TODO: check whether files from manifest exist and match hashes
|
||||
throw new NotImplementedException();
|
||||
_filesToDownload.Clear();
|
||||
foreach (var pair in _distributiveManifest!.files)
|
||||
{
|
||||
if (pair.Value.type != "file")
|
||||
continue;
|
||||
|
||||
if (pair.Value.downloads != null)
|
||||
{
|
||||
var artifact = pair.Value.downloads;
|
||||
IOPath file_path = Path.Concat(_javaVersionDir, pair.Key);
|
||||
if (!File.Exists(file_path))
|
||||
{
|
||||
_filesToDownload.Add((file_path, pair.Value));
|
||||
}
|
||||
else if(checkHashes)
|
||||
{
|
||||
using var fs = File.OpenRead(file_path);
|
||||
if (_hasher.ComputeHash(fs).HashToString() != artifact.raw.sha1)
|
||||
{
|
||||
_filesToDownload.Add((file_path, pair.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _filesToDownload.Count == 0;
|
||||
}
|
||||
|
||||
private long GetTotalSize()
|
||||
{
|
||||
//TODO: sum up size of all files invalidated by CheckFiles
|
||||
throw new NotImplementedException();
|
||||
long totalSize = 0;
|
||||
foreach (var file in _filesToDownload)
|
||||
{
|
||||
if(file.props.downloads == null)
|
||||
continue;
|
||||
totalSize += file.props.downloads.lzma?.size ?? file.props.downloads.raw.size;
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
private Task Download(NetworkProgressReporter pr, CancellationToken ct)
|
||||
private async Task Download(NetworkProgressReporter pr, CancellationToken ct)
|
||||
{
|
||||
//TODO: download files using lzma decompression
|
||||
throw new NotImplementedException();
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), "started downloading java runtime " +
|
||||
$"{_descriptor.javaVersion.majorVersion} '{_descriptor.javaVersion.component}'");
|
||||
|
||||
ParallelOptions opt = new()
|
||||
{
|
||||
MaxDegreeOfParallelism = Приложение.Настройки.максимум_параллельных_загрузок,
|
||||
CancellationToken = ct
|
||||
};
|
||||
await Parallel.ForEachAsync(_filesToDownload, opt, async (f, _ct) =>
|
||||
{
|
||||
if (f.props.downloads!.lzma != null)
|
||||
{
|
||||
Приложение.Логгер.LogDebug(nameof(Сеть), $"downloading lzma-compressed file '{f.path}'");
|
||||
await using var pipe = new TransformStream(await GetStream(f.props.downloads.lzma.url, _ct));
|
||||
pipe.AddTransform(pr.AddBytesCount);
|
||||
await using var fs = File.OpenWrite(f.path);
|
||||
LZMACompressor.Decompress(pipe, fs);
|
||||
}
|
||||
else
|
||||
{
|
||||
Приложение.Логгер.LogDebug(nameof(Сеть), $"downloading raw file '{f.path}'");
|
||||
await DownloadFile(f.props.downloads.raw.url, f.path, _ct, pr.AddBytesCount);
|
||||
}
|
||||
|
||||
if(!OperatingSystem.IsWindows() && f.props.executable is true)
|
||||
{
|
||||
Приложение.Логгер.LogDebug(nameof(Сеть), $"adding execute rights to file '{f.path}'");
|
||||
System.IO.File.SetUnixFileMode(f.path.ToString(), UnixFileMode.UserExecute);
|
||||
}
|
||||
});
|
||||
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), "finished downloading java runtime " +
|
||||
$"{_descriptor.javaVersion.majorVersion} '{_descriptor.javaVersion.component}'");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO.Compression;
|
||||
using System.Security.Cryptography;
|
||||
using DTLib.Extensions;
|
||||
using Млаумчерб.Клиент.видимое;
|
||||
using Млаумчерб.Клиент.зримое;
|
||||
using Млаумчерб.Клиент.классы;
|
||||
using static Млаумчерб.Клиент.сеть.Сеть;
|
||||
|
||||
@@ -73,12 +73,16 @@ public class LibrariesDownloadTaskFactory : INetworkTaskFactory
|
||||
private async Task Download(NetworkProgressReporter pr, CancellationToken ct)
|
||||
{
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"started downloading libraries '{_descriptor.id}'");
|
||||
ParallelOptions opt = new() { MaxDegreeOfParallelism = ParallelDownloadsN, CancellationToken = ct };
|
||||
|
||||
ParallelOptions opt = new()
|
||||
{
|
||||
MaxDegreeOfParallelism = Приложение.Настройки.максимум_параллельных_загрузок,
|
||||
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);
|
||||
Приложение.Логгер.LogDebug(nameof(Сеть), $"downloading library '{l.name}' to '{l.jarFilePath}'");
|
||||
await DownloadFile(l.artifact.url, l.jarFilePath, _ct, pr.AddBytesCount);
|
||||
if (l is Libraries.NativeLib n)
|
||||
{
|
||||
var zipf = File.OpenRead(n.jarFilePath);
|
||||
@@ -96,6 +100,7 @@ public class LibrariesDownloadTaskFactory : INetworkTaskFactory
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"finished downloading libraries '{_descriptor.id}'");
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Security.Cryptography;
|
||||
using DTLib.Extensions;
|
||||
using Млаумчерб.Клиент.видимое;
|
||||
using Млаумчерб.Клиент.зримое;
|
||||
using Млаумчерб.Клиент.классы;
|
||||
using static Млаумчерб.Клиент.сеть.Сеть;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class VersionFileDownloadTaskFactory : INetworkTaskFactory
|
||||
private async Task Download(NetworkProgressReporter pr, CancellationToken ct)
|
||||
{
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"started downloading version file '{_descriptor.id}'");
|
||||
await DownloadFileHTTP(_descriptor.downloads.client.url, _filePath, ct, pr.AddBytesCount);
|
||||
await DownloadFile(_descriptor.downloads.client.url, _filePath, ct, pr.AddBytesCount);
|
||||
Приложение.Логгер.LogInfo(nameof(Сеть), $"finished downloading version file '{_descriptor.id}'");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user