From 3299ce069efe3f9c7ddf0e5a882b5e390e753c58 Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:12:18 -0500 Subject: [PATCH] texture caching --- dotnet-tools.json | 2 +- packages/game/JSExport/GameInterface.cs | 128 ++++++++++-------- packages/game/Models/BlitzFileProvider.cs | 26 +--- .../components/TankopediaLoadout/index.tsx | 2 + packages/website-ue/src/game/game.ts | 10 -- scripts/build_game.sh | 3 +- 6 files changed, 79 insertions(+), 92 deletions(-) diff --git a/dotnet-tools.json b/dotnet-tools.json index 97f37dcc4..6e2e244c4 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "csharpier": { - "version": "1.2.6", + "version": "1.3.0", "commands": [ "csharpier" ], diff --git a/packages/game/JSExport/GameInterface.cs b/packages/game/JSExport/GameInterface.cs index 27e1ff3ab..cc806c41c 100644 --- a/packages/game/JSExport/GameInterface.cs +++ b/packages/game/JSExport/GameInterface.cs @@ -1,4 +1,5 @@ -using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.RegularExpressions; using BlitzKit.Game.Models; using CUE4Parse_Conversion; using CUE4Parse_Conversion.Materials; @@ -28,22 +29,31 @@ public partial class GameInterface public GameInterface(string directory, string map, string temp) { - Console.WriteLine("GameInterface constructor called"); - provider = new(directory, map, temp); - - Console.WriteLine("Provider created"); - files = [.. provider.Files.Keys]; - - Console.WriteLine("Files loaded"); } readonly Dictionary texturePaths = new(); + readonly string textureCache = "../../temp/textures.json"; public void DiscoverTextures(string[] tankTags) { - Console.WriteLine("Discovering textures..."); + if (File.Exists(textureCache)) + { + Console.WriteLine("Found textures cache"); + + var content = File.ReadAllText(textureCache); + var cached = JsonSerializer.Deserialize>(content); + + foreach (var (key, value) in cached) + { + texturePaths[key] = value; + } + + return; + } + + Console.WriteLine("Textures cache not found, building..."); var options = new ExporterOptions() { TextureFormat = ETextureFormat.Jpeg }; @@ -109,6 +119,13 @@ public partial class GameInterface } Console.WriteLine($"Discovered {texturePaths.Count} textures"); + Directory.CreateDirectory(Path.GetDirectoryName(textureCache)); + + var json = JsonSerializer.Serialize(texturePaths); + + File.WriteAllText(textureCache, json); + + Console.WriteLine("Saved textures cache"); } public List Textures => [.. texturePaths.Keys]; @@ -200,62 +217,53 @@ public partial class GameInterface public byte[] TankPart(string tag, string part) { - try + var pda = provider.Discovered(tag); + UDataTable? dataTable = null; + + foreach (var (prefix, name) in tankPartPrefixes) { - var pda = provider.Discovered(tag); - UDataTable? dataTable = null; - - foreach (var (prefix, name) in tankPartPrefixes) + if (!part.StartsWith(prefix)) { - if (!part.StartsWith(prefix)) - { - continue; - } - - dataTable = pda.Get(name); - break; + continue; } - if (dataTable == null) - { - throw new ArgumentException($"Unknown tank part: {part}"); - } - - dataTable.TryGetDataTableRow(part, StringComparison.Ordinal, out var row); - - if (row == null) - { - throw new ArgumentException($"Unknown tank part: {part}"); - } - - var visualData = row.Get("VisualData"); - var meshSettings = visualData.Get("MeshSettings"); - var meshes = new List(); - - foreach (var property in meshSettings.Properties) - { - var name = property.Name.Text; - - if (name == "CollisionMesh") - { - continue; - } - - if (meshSettings.TryGet(name, out var mesh)) - { - meshes.Add(mesh); - } - } - - var gltf = new MonoGltf(meshes); - - return gltf.Write($"{tag}/{part}"); - } - catch (Exception e) - { - Console.WriteLine(e); + dataTable = pda.Get(name); + break; } - return []; + if (dataTable == null) + { + throw new ArgumentException($"Unknown tank part: {part}"); + } + + dataTable.TryGetDataTableRow(part, StringComparison.Ordinal, out var row); + + if (row == null) + { + throw new ArgumentException($"Unknown tank part: {part}"); + } + + var visualData = row.Get("VisualData"); + var meshSettings = visualData.Get("MeshSettings"); + var meshes = new List(); + + foreach (var property in meshSettings.Properties) + { + var name = property.Name.Text; + + if (name == "CollisionMesh") + { + continue; + } + + if (meshSettings.TryGet(name, out var mesh)) + { + meshes.Add(mesh); + } + } + + var gltf = new MonoGltf(meshes); + + return gltf.Write($"{tag}/{part}"); } } diff --git a/packages/game/Models/BlitzFileProvider.cs b/packages/game/Models/BlitzFileProvider.cs index e364a3b2d..778d02bf2 100644 --- a/packages/game/Models/BlitzFileProvider.cs +++ b/packages/game/Models/BlitzFileProvider.cs @@ -1,19 +1,19 @@ using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using CUE4Parse_Conversion.Textures; using CUE4Parse.Compression; using CUE4Parse.FileProvider; using CUE4Parse.MappingsProvider; +using CUE4Parse.UE4.AssetRegistry; +using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Exceptions; using CUE4Parse.UE4.Objects.Engine; using CUE4Parse.UE4.Objects.UObject; +using CUE4Parse.UE4.Readers; using CUE4Parse.UE4.Versions; using CUE4Parse.Utils; using SkiaSharp; -using CUE4Parse.UE4.Readers; -using CUE4Parse.UE4.AssetRegistry; -using System.Text.RegularExpressions; -using CUE4Parse.UE4.Assets.Exports; namespace BlitzKit.Game.Models; @@ -32,28 +32,15 @@ public partial class BlitzFileProvider : DefaultFileProvider pathComparer: StringComparer.OrdinalIgnoreCase ) { - Console.WriteLine("BlitzFileProvider constructor called"); - MappingsContainer = new FileUsmapTypeMappingsProvider(map); - Console.WriteLine("MappingsContainer initialized"); - Initialize(); - - Console.WriteLine("Initialize called"); - Mount(); - Console.WriteLine("Mount called"); - - string oodlePath = $"{temp}/oodle.so"; + // string oodlePath = $"{temp}/oodle.so"; // OodleHelper.DownloadOodleDll(ref oodlePath!); - // Console.WriteLine("DownloadOodleDll called"); - OodleHelper.Initialize("../../stupid/oodle.so"); - Console.WriteLine("Initialize called"); - if (TryGetGameFile("Blitz/AssetRegistry.bin", out var file)) { var bytes = file.Read(); @@ -78,7 +65,8 @@ public partial class BlitzFileProvider : DefaultFileProvider } } - public T Discovered(string path) where T : UObject + public T Discovered(string path) + where T : UObject { return LoadPackageObject(discovered[path]); } diff --git a/packages/website-ue/src/components/TankopediaLoadout/index.tsx b/packages/website-ue/src/components/TankopediaLoadout/index.tsx index 07555c654..505ab18a3 100644 --- a/packages/website-ue/src/components/TankopediaLoadout/index.tsx +++ b/packages/website-ue/src/components/TankopediaLoadout/index.tsx @@ -175,8 +175,10 @@ function Consumables({ characteristics }: ConsumablesProps) { {Object.entries(consumables.consumables).map( ([id, { compatibility, consumable, purchase }]) => { if (!isCompatible(compatibility!)) return null; + return (