mlaumcherb/Млаумчерб.Клиент/сеть/Сеть.cs
2024-09-29 08:21:48 +05:00

97 lines
3.4 KiB
C#
Raw 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.Buffers;
using System.Net.Http;
using Млаумчерб.Клиент.видимое;
using Млаумчерб.Клиент.классы;
namespace Млаумчерб.Клиент.сеть;
public static class Сеть
{
public static int ParallelDownloadsN = 32;
public static HttpClient http = new();
public static async Task DownloadFileHTTP(string url, IOPath outPath, CancellationToken ct = default,
Action<ArraySegment<byte>>? transformFunc = null)
{
await using var src = await http.GetStreamAsync(url, ct);
await using var dst = File.OpenWrite(outPath);
await src.CopyTransformAsync(dst, transformFunc, ct).ConfigureAwait(false);
}
public static async Task CopyTransformAsync(this Stream src, Stream dst,
Action<ArraySegment<byte>>? transformFunc = null, CancellationToken ct = default)
{
// default dotnet runtime buffer size
int bufferSize = 81920;
byte[] readBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
byte[] writeBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
try
{
var readTask = src.ReadAsync(readBuffer, 0, bufferSize, ct).ConfigureAwait(false);
while (true)
{
int readCount = await readTask;
if (readCount == 0)
break;
(readBuffer, writeBuffer) = (writeBuffer, readBuffer);
readTask = src.ReadAsync(readBuffer, 0, bufferSize, ct).ConfigureAwait(false);
transformFunc?.Invoke(new ArraySegment<byte>(writeBuffer, 0, readCount));
dst.Write(writeBuffer, 0, readCount);
}
}
catch (OperationCanceledException)
{
}
finally
{
ArrayPool<byte>.Shared.Return(readBuffer);
ArrayPool<byte>.Shared.Return(writeBuffer);
}
}
private static readonly string[] VERSION_MANIFEST_URLS =
{
"https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"
};
private static async Task<List<RemoteVersionDescriptorProps>> GetRemoteVersionDescriptorsAsync()
{
List<RemoteVersionDescriptorProps> descriptors = new();
foreach (var url in VERSION_MANIFEST_URLS)
{
try
{
var manifestText = await http.GetStringAsync(url);
var catalog = JsonConvert.DeserializeObject<VersionCatalog>(manifestText);
if (catalog != null)
descriptors.AddRange(catalog.versions);
}
catch (Exception ex)
{
Приложение.Логгер.LogWarn(nameof(Сеть), ex);
}
}
return descriptors;
}
private static List<GameVersionProps>? _versionPropsList;
/// <returns>empty list if couldn't find any remote versions</returns>
public static async Task<IReadOnlyList<GameVersionProps>> GetDownloadableVersions()
{
if (_versionPropsList == null)
{
_versionPropsList = new();
var rvdlist = await GetRemoteVersionDescriptorsAsync();
foreach (var r in rvdlist)
{
if (r.type == "release")
_versionPropsList.Add(new GameVersionProps(r.id, r.url));
}
}
return _versionPropsList;
}
}