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>? 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>? transformFunc = null, CancellationToken ct = default) { // default dotnet runtime buffer size int bufferSize = 81920; byte[] readBuffer = ArrayPool.Shared.Rent(bufferSize); byte[] writeBuffer = ArrayPool.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(writeBuffer, 0, readCount)); dst.Write(writeBuffer, 0, readCount); } } catch (OperationCanceledException) { } finally { ArrayPool.Shared.Return(readBuffer); ArrayPool.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> GetRemoteVersionDescriptorsAsync() { List descriptors = new(); foreach (var url in VERSION_MANIFEST_URLS) { try { var manifestText = await http.GetStringAsync(url); var catalog = JsonConvert.DeserializeObject(manifestText); if (catalog != null) descriptors.AddRange(catalog.versions); } catch (Exception ex) { Приложение.Логгер.LogWarn(nameof(Сеть), ex); } } return descriptors; } private static List? _versionPropsList; /// empty list if couldn't find any remote versions public static async Task> 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; } }