From cd3a41d18c3e614b17e49f013179342f97d88bdd Mon Sep 17 00:00:00 2001 From: Marlon Date: Mon, 30 Sep 2024 21:16:44 +0200 Subject: [PATCH] make use of RandomAccess archives --- CUE4Parse | 2 +- .../ApiEndpoints/ValorantApiEndpoint.cs | 27 ++++++++++++++----- FModel/ViewModels/CUE4ParseViewModel.cs | 6 ++--- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index 76fcf8cc..f30b4807 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 76fcf8cca1e5cc0e8949f56eecdf43986235706b +Subproject commit f30b4807467a6d91bdb10210ff20db5812160bbf diff --git a/FModel/ViewModels/ApiEndpoints/ValorantApiEndpoint.cs b/FModel/ViewModels/ApiEndpoints/ValorantApiEndpoint.cs index 8c827867..031b5e82 100644 --- a/FModel/ViewModels/ApiEndpoints/ValorantApiEndpoint.cs +++ b/FModel/ViewModels/ApiEndpoints/ValorantApiEndpoint.cs @@ -15,7 +15,7 @@ using CUE4Parse.UE4.Readers; using FModel.Framework; using FModel.Settings; - +using OffiUtils; using RestSharp; namespace FModel.ViewModels.ApiEndpoints; @@ -117,7 +117,7 @@ public class VManifest return chunkBytes; } - public Stream GetPakStream(int index) => new VPakStream(this, index); + public VPakStream GetPakStream(int index) => new VPakStream(this, index); } public readonly struct VHeader @@ -179,7 +179,7 @@ public readonly struct VChunk public string GetUrl() => $"https://fmodel.fortnite-api.com/valorant/v2/chunks/{Id}"; } -public class VPakStream : Stream, ICloneable +public class VPakStream : Stream, IRandomAccessStream, ICloneable { private readonly VManifest _manifest; private readonly int _pakIndex; @@ -203,11 +203,22 @@ public class VPakStream : Stream, ICloneable public object Clone() => new VPakStream(_manifest, _pakIndex, _position); - public override int Read(byte[] buffer, int offset, int count) => ReadAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); + public override int Read(byte[] buffer, int offset, int count) => + ReadAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); + + public int ReadAt(long position, byte[] buffer, int offset, int count) => + ReadAtAsync(position, buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { - var (i, startPos) = GetChunkIndex(_position); + var bytesRead = await ReadAtAsync(_position, buffer, offset, count, cancellationToken); + _position += bytesRead; + return bytesRead; + } + + public async Task ReadAtAsync(long position, byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + var (i, startPos) = GetChunkIndex(position); if (i == -1) return 0; await PrefetchAsync(i, startPos, count, cancellationToken).ConfigureAwait(false); @@ -234,10 +245,14 @@ public class VPakStream : Stream, ICloneable if (++i == _chunks.Length) break; } - _position += bytesRead; return bytesRead; } + public Task ReadAtAsync(long position, Memory memory, CancellationToken cancellationToken) + { + throw new NotSupportedException(); + } + private async Task PrefetchAsync(int i, uint startPos, long count, CancellationToken cancellationToken, int concurrentDownloads = 4) { var tasks = new List(); diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 14f6ce5b..7b6a4c5a 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -63,7 +63,7 @@ using FModel.Views.Resources.Controls; using FModel.Views.Snooper; using Newtonsoft.Json; - +using OffiUtils; using OpenTK.Windowing.Common; using OpenTK.Windowing.Desktop; @@ -258,7 +258,7 @@ public class CUE4ParseViewModel : ViewModel continue; } - p.RegisterVfs(fileManifest.FileName, [fileManifest.GetStream()] + p.RegisterVfs(fileManifest.FileName, [(IRandomAccessStream)fileManifest.GetStream()] , it => new FRandomAccessStreamArchive(it, manifest.FileManifestList.First(x => x.FileName.Equals(it)).GetStream(), p.Versions)); } @@ -276,7 +276,7 @@ public class CUE4ParseViewModel : ViewModel for (var i = 0; i < manifestInfo.Paks.Length; i++) { - p.RegisterVfs(manifestInfo.Paks[i].GetFullName(), [manifestInfo.GetPakStream(i)]); + p.RegisterVfs(manifestInfo.Paks[i].GetFullName(), [(IRandomAccessStream)manifestInfo.GetPakStream(i)]); } FLogger.Append(ELog.Information, () =>