From c16f2edf9b7468a1942f3e69b58623ac244f8870 Mon Sep 17 00:00:00 2001 From: Masusder <59669685+Masusder@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:10:17 +0200 Subject: [PATCH] Roco Kingdom: World datatables support --- CUE4Parse | 2 +- FModel/ViewModels/CUE4ParseViewModel.cs | 41 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/CUE4Parse b/CUE4Parse index 75f3878b..a3821bdc 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 75f3878b7a348cbda3927048b142a0a6923e79c0 +Subproject commit a3821bdc34ef75f10a2003092ad2502dc648e53a diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 9f1dfa3f..df1d3560 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; +using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; @@ -23,6 +24,7 @@ using CUE4Parse.GameTypes.Borderlands3.Assets.Exports; using CUE4Parse.GameTypes.Borderlands4.Assets.Exports; using CUE4Parse.GameTypes.Borderlands4.Wwise; using CUE4Parse.GameTypes.KRD.Assets.Exports; +using CUE4Parse.GameTypes.RocoKingdomWorld.Assets.Objects; using CUE4Parse.GameTypes.SMG.UE4.Assets.Exports.Wwise; using CUE4Parse.GameTypes.SquareEnix.UE4.Assets.Exports; using CUE4Parse.MappingsProvider; @@ -683,6 +685,11 @@ public class CUE4ParseViewModel : ViewModel ProcessAion2DatFile(entry, updateUi, saveProperties); break; } + case "bytes" when Provider.Versions.Game is EGame.GAME_RocoKingdomWorld: + { + ProcessRocoBinFile(entry, updateUi, saveProperties); + break; + } case "dbc" when Provider.Versions.Game is EGame.GAME_AshesOfCreation: { ProcessCacheDBFile(entry, updateUi, saveProperties); @@ -969,6 +976,40 @@ public class CUE4ParseViewModel : ViewModel } } + // Roco Kingdom: World + void ProcessRocoBinFile(GameFile entry, bool updateUi, bool saveProperties) + { + TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("json"); + var nonFileName = "/" + entry.NameWithoutExtension + ".non"; + var nonPath = Provider.Files.Keys.FirstOrDefault(k => k.EndsWith(nonFileName, StringComparison.OrdinalIgnoreCase)); + + // I will only get one localization file because they did not translate any languages, lol + var locPathKey = entry.Path.Replace("/BinData/", "/BinLocalize/en_US/").Replace("/BinDataCompressed/", "/BinLocalize/en_US/"); + var locFileFound = Provider.Files.TryGetValue(locPathKey, out var locEntry); + + if (!string.IsNullOrEmpty(nonPath) && Provider.Files.TryGetValue(nonPath, out var nonEntry)) + { + string json = Encoding.UTF8.GetString(nonEntry.Read()); + var schema = JsonConvert.DeserializeObject(json); + var archive = entry.CreateReader(); + var locArchive = locFileFound ? new FRocoBinData(locEntry.CreateReader(), null, ERocoBinDataType.BinLocalize) : null; + + var data = entry.PathWithoutExtension switch + { + var p when p.Contains("BinDataCompressed") => new FRocoBinData(archive, schema, ERocoBinDataType.BinDataCompressed, locArchive), + var p when p.Contains("BinData") => new FRocoBinData(archive, schema, ERocoBinDataType.BinData, locArchive), + var p when p.Contains("BinLocalize") => new FRocoBinData(archive, null, ERocoBinDataType.BinLocalize), + _ => null + }; + + TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(data, Formatting.Indented), saveProperties, updateUi); + } + else if (entry.PathWithoutExtension.Contains("/Bin/")) + { + throw new Exception($"Could not find associated .non file for {entry.Name}"); + } + } + void ProcessAion2DatFile(GameFile entry, bool updateUi, bool saveProperties) { TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("json");