Merge branch 'pr-685' into feature/new-exporter

This commit is contained in:
Masusder 2026-06-28 11:45:02 +02:00
commit 788dc45242
4 changed files with 76 additions and 6 deletions

View File

@ -275,6 +275,13 @@ namespace FModel.Settings
set => SetProperty(ref _convertAudioOnBulkExport, value);
}
private bool _mergeEditorOnlyDataExports = true;
public bool MergeEditorOnlyDataExports
{
get => _mergeEditorOnlyDataExports;
set => SetProperty(ref _mergeEditorOnlyDataExports, value);
}
private bool _decompileLua;
public bool DecompileLua
{

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -229,11 +230,17 @@ public class AssetsFolderViewModel
return null;
}
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
foreach (var entry in entries)
{
TreeItem lastNode = null;
TreeItem parentItem = null;
var folders = entry.Path.Split('/', StringSplitOptions.RemoveEmptyEntries);
var path = entry.Path;
if (path.StartsWith(localAppData, StringComparison.OrdinalIgnoreCase))
path = path[localAppData.Length..].TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var folders = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
var builder = new StringBuilder(64);
var parentNode = treeItems;

View File

@ -48,6 +48,7 @@ using CUE4Parse.UE4.BinaryConfig;
using CUE4Parse.UE4.CriWare;
using CUE4Parse.UE4.CriWare.Readers;
using CUE4Parse.UE4.FMod;
using CUE4Parse.UE4.GameFeatures;
using CUE4Parse.UE4.IO;
using CUE4Parse.UE4.Localization;
using CUE4Parse.UE4.Lua.unluac;
@ -199,6 +200,10 @@ public class CUE4ParseViewModel : ViewModel
[
new(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\KONAMI\\eFootball\\ST\\Download")
], SearchOption.AllDirectories, versionContainer, pathComparer),
"DeadByDaylight" => new DefaultFileProvider(new DirectoryInfo(gameDirectory),
[
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\DeadByDaylight\\Saved\\PersistentDownloadDir\\DynamicContent")
], SearchOption.AllDirectories, versionContainer, pathComparer),
_ when versionContainer.Game is EGame.GAME_AshEchoes => new AEDefaultFileProvider(gameDirectory, SearchOption.AllDirectories, versionContainer, pathComparer),
_ when versionContainer.Game is EGame.GAME_BlackStigma => new DefaultFileProvider(gameDirectory, SearchOption.AllDirectories, versionContainer, StringComparer.Ordinal),
_ when versionContainer.Game is EGame.GAME_HonorofKingsWorld => new HoKWDefaultFileProvider(gameDirectory, SearchOption.AllDirectories, versionContainer, pathComparer),
@ -650,7 +655,34 @@ public class CUE4ParseViewModel : ViewModel
if (saveProperties || updateUi)
{
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(result.GetDisplayData(saveProperties), Formatting.Indented), saveProperties, updateUi);
var displayData = result.GetDisplayData(saveProperties);
if (UserSettings.Default.MergeEditorOnlyDataExports && Provider.TryLoadPackage(entry.Path.SubstringBefore('.') + ".o.uasset", out var editorAsset))
{
var pkg = Provider.LoadPackage(entry.Path);
var exports = pkg.GetExports().ToArray();
var finalExports = new List<UObject>(exports);
var editorOnlyDataExports = new HashSet<UObject>();
foreach (var export in exports)
{
var editorData = editorAsset.GetExportOrNull(export.Name + "EditorOnlyData");
if (editorData == null)
continue;
export.Properties.AddRange(editorData.Properties);
editorOnlyDataExports.Add(editorData);
}
if (editorOnlyDataExports.Count > 0)
{
finalExports.AddRange(editorAsset.GetExports().Where(editorExport => !editorOnlyDataExports.Contains(editorExport)));
}
displayData = finalExports;
}
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(displayData, Formatting.Indented), saveProperties, updateUi);
if (saveProperties) break; // do not search for viewable exports if we are dealing with jsons
}
@ -831,6 +863,13 @@ public class CUE4ParseViewModel : ViewModel
break;
}
case "bin" when entry.Name.Contains("GameFeatureVersePaths", StringComparison.OrdinalIgnoreCase):
{
var archive = entry.CreateReader();
var versePathLookup = new FGameFeatureVersePathLookup(archive);
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(versePathLookup, Formatting.Indented), saveProperties, updateUi);
break;
}
case "bank":
{
var archive = entry.CreateReader();
@ -1076,6 +1115,11 @@ public class CUE4ParseViewModel : ViewModel
var l10nData = new FAion2L10NFile(entry, Provider);
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(l10nData, Formatting.Indented), saveProperties, updateUi);
}
else if (entry.NameWithoutExtension.Equals("key_manifest"))
{
var keymanifest = new FAion2KeyManifestFile(entry, Provider);
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(keymanifest, Formatting.Indented), saveProperties, updateUi);
}
else
{
FAion2DataFile datfile = entry.NameWithoutExtension switch

View File

@ -46,6 +46,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -258,13 +259,25 @@
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<TextBlock Grid.Row="21"
Grid.Column="0"
Text="Merge Editor-Only Data (.o.uasset)"
VerticalAlignment="Center"
ToolTip="Reads .o.uasset packages and merges their editor-only data into the parent asset. Useful for JSON-based asset export workflows"
Margin="0 0 0 5" />
<CheckBox Grid.Row="21"
Grid.Column="2"
Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding MergeEditorOnlyDataExports, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"
Margin="0 5 0 10"
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<TextBlock Grid.Row="22"
Grid.Column="0"
Text="CRIWARE Decryption Key"
VerticalAlignment="Center"
Margin="0 0 0 10" />
<TextBox x:Name="CriwareKeyBox"
Grid.Row="21"
Grid.Row="22"
Grid.Column="2"
Grid.ColumnSpan="5"
Margin="0 5 0 10"
@ -274,8 +287,7 @@
ToolTip="Enter decryption key in numeric or hexadecimal format (valid key is up to 20 digits or 8 bytes long)"
TextAlignment="Right"
TextChanged="CriwareKeyBox_TextChanged"
Loaded="CriwareKeyBox_Loaded"/>
Loaded="CriwareKeyBox_Loaded" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="CreatorTemplate">