From 6327f1b2d39a807324255f9e77051e01ed983ef3 Mon Sep 17 00:00:00 2001 From: Krowe Moh <27891447+Krowe-moh@users.noreply.github.com> Date: Thu, 2 Apr 2026 11:17:30 +1100 Subject: [PATCH 01/11] Search for Shipping exe within Engine folder --- FModel/ViewModels/GameSelectorViewModel.cs | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/FModel/ViewModels/GameSelectorViewModel.cs b/FModel/ViewModels/GameSelectorViewModel.cs index 369945b2..6447e2d7 100644 --- a/FModel/ViewModels/GameSelectorViewModel.cs +++ b/FModel/ViewModels/GameSelectorViewModel.cs @@ -134,11 +134,27 @@ private bool TryDetectUeVersion(string gameDirectory, out EGame ueVersion, [Mayb } } - var crashReportClientExe = Path.Combine(projectDir, "..", "Engine", "Binaries", "Win64", "CrashReportClient.exe"); - if (File.Exists(crashReportClientExe) && TryGetUeVersionFromExe(crashReportClientExe, out ueVersion)) + var projectEngineBinariesDir = Path.Combine(projectDir, "..", "Engine", "Binaries", "Win64"); + + if (Directory.Exists(projectEngineBinariesDir)) { - Log.Information("Detected UE version {UeVersion} from \"{Exe}\"", ueVersion, crashReportClientExe); - return true; + var crashReportClientExe = Path.Combine(projectEngineBinariesDir, "CrashReportClient.exe"); + if (File.Exists(crashReportClientExe) && TryGetUeVersionFromExe(crashReportClientExe, out ueVersion)) + { + Log.Information("Detected UE version {UeVersion} from \"{Exe}\"", ueVersion, crashReportClientExe); + return true; + } + if (Directory.GetFiles(projectEngineBinariesDir, "*-Win64-Shipping.exe") is { Length: > 0 } shipping) + { + foreach (var exe in shipping) + { + if (TryGetUeVersionFromExe(exe, out ueVersion)) + { + Log.Information("Detected UE version {UeVersion} from \"{Exe}\"", ueVersion, exe); + return true; + } + } + } } ueVersion = EGame.GAME_UE4_LATEST; From 9f298c544fdbf31400456116a61785003048a770 Mon Sep 17 00:00:00 2001 From: Krowe Moh <27891447+Krowe-moh@users.noreply.github.com> Date: Thu, 2 Apr 2026 11:18:00 +1100 Subject: [PATCH 02/11] Prevent Export logs on Search menu extracts reduces logs flood causing slowdown on export --- .../Commands/RightClickMenuCommand.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/FModel/ViewModels/Commands/RightClickMenuCommand.cs b/FModel/ViewModels/Commands/RightClickMenuCommand.cs index b490957c..e82b4905 100644 --- a/FModel/ViewModels/Commands/RightClickMenuCommand.cs +++ b/FModel/ViewModels/Commands/RightClickMenuCommand.cs @@ -43,6 +43,7 @@ public override async void Execute(ApplicationViewModel contextViewModel, object if (param.Length == 0) return; var folders = param.OfType().ToArray(); + var searchMenu = param[0] is GameFile; var assets = param .Select(static item => item switch { @@ -138,6 +139,20 @@ await _threadWorkerView.Begin(cancellationToken => _ => (entry, bulk, update) => contextViewModel.CUE4Parse.Extract(cancellationToken, entry, false, bulk), }; + if (searchMenu) + { + var update = assets.Length > 1; + foreach (var entry in assets) + { + Thread.Yield(); + cancellationToken.ThrowIfCancellationRequested(); + fileAction(entry, bulktype | EBulkType.Auto, update); + } + + LogExport(contextViewModel, filetype); + return; + } + foreach (var group in assetsGroups) { var directory = group.Key; @@ -190,4 +205,26 @@ private void LogExport(ApplicationViewModel contextViewModel, string directory, Interlocked.Exchange(ref contextViewModel.CUE4Parse.ExportedCount, 0); Interlocked.Exchange(ref contextViewModel.CUE4Parse.FailedExportCount, 0); } + + private void LogExport(ApplicationViewModel contextViewModel, string fileType) + { + if (contextViewModel.CUE4Parse.ExportedCount > 0) + { + FLogger.Append(ELog.Information, () => + { + FLogger.Text($"Successfully exported {contextViewModel.CUE4Parse.ExportedCount} {fileType}", Constants.WHITE, true); + }); + } + + if (contextViewModel.CUE4Parse.FailedExportCount > 0) + { + FLogger.Append(ELog.Error, () => + { + FLogger.Text($"Failed to export {contextViewModel.CUE4Parse.FailedExportCount} {fileType}", Constants.WHITE, true); + }); + } + + Interlocked.Exchange(ref contextViewModel.CUE4Parse.ExportedCount, 0); + Interlocked.Exchange(ref contextViewModel.CUE4Parse.FailedExportCount, 0); + } } From bb41727e8843976be0a43e420bfcc85373e16ef7 Mon Sep 17 00:00:00 2001 From: Chompster86 Date: Mon, 23 Feb 2026 11:18:56 -0500 Subject: [PATCH 03/11] Update SearchView.xaml Fixed metadata in search view and added it to reference view. --- FModel/Views/SearchView.xaml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/FModel/Views/SearchView.xaml b/FModel/Views/SearchView.xaml index 9e3a1f93..defa4853 100644 --- a/FModel/Views/SearchView.xaml +++ b/FModel/Views/SearchView.xaml @@ -161,6 +161,21 @@ + + + + + + + + + + + + + + + @@ -529,6 +544,21 @@ + + + + + + + + + + + + + + + From ee3af8480f2a28839313421f8f291666bbcf71f2 Mon Sep 17 00:00:00 2001 From: Chompster86 Date: Mon, 23 Feb 2026 10:36:42 -0500 Subject: [PATCH 04/11] Update TabCommand.cs --- FModel/ViewModels/Commands/TabCommand.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/FModel/ViewModels/Commands/TabCommand.cs b/FModel/ViewModels/Commands/TabCommand.cs index a622d5e4..2867f87a 100644 --- a/FModel/ViewModels/Commands/TabCommand.cs +++ b/FModel/ViewModels/Commands/TabCommand.cs @@ -31,9 +31,15 @@ public override async void Execute(TabItem tabViewModel, object parameter) case "Close_Other_Tabs": _applicationView.CUE4Parse.TabControl.RemoveOtherTabs(tabViewModel); break; + case "Assets_Show_Metadata": + _applicationView.CUE4Parse.ShowMetadata(tabViewModel.Entry); + break; case "Find_References": _applicationView.CUE4Parse.FindReferences(tabViewModel.Entry); break; + case "Assets_Decompile": + _applicationView.CUE4Parse.Decompile(tabViewModel.Entry); + break; case "Save_Data": await _threadWorkerView.Begin(_ => _applicationView.CUE4Parse.ExportData(tabViewModel.Entry)); break; @@ -77,9 +83,21 @@ await _threadWorkerView.Begin(cancellationToken => }.Show(); }); break; - case "Copy_Asset_Path": + case "File_Path": Clipboard.SetText(tabViewModel.Entry.Path); break; + case "File_Name": + Clipboard.SetText(tabViewModel.Entry.Name); + break; + case "Directory_Path": + Clipboard.SetText(tabViewModel.Entry.Directory); + break; + case "File_Path_No_Extension": + Clipboard.SetText(tabViewModel.Entry.PathWithoutExtension); + break; + case "File_Name_No_Extension": + Clipboard.SetText(tabViewModel.Entry.NameWithoutExtension); + break; } } } From 879063cf5385b393617d9aa75c048f46f51ea004 Mon Sep 17 00:00:00 2001 From: Chompster86 Date: Mon, 23 Feb 2026 10:33:57 -0500 Subject: [PATCH 05/11] Update Resources.xaml --- FModel/Views/Resources/Resources.xaml | 61 ++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/FModel/Views/Resources/Resources.xaml b/FModel/Views/Resources/Resources.xaml index c33eb148..ce77bf5c 100644 --- a/FModel/Views/Resources/Resources.xaml +++ b/FModel/Views/Resources/Resources.xaml @@ -910,6 +910,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -931,6 +951,35 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -1010,7 +1059,7 @@ - + @@ -1018,6 +1067,16 @@ + + + + + + + + + + From f21060105d4bad4d8c859ba9cd7824b774ca7581 Mon Sep 17 00:00:00 2001 From: ScrubN <72096833+ScrubN@users.noreply.github.com> Date: Sun, 31 Dec 2023 02:17:47 -0500 Subject: [PATCH 06/11] Clear _waveSource and PlayedFile if last file was removed --- FModel/ViewModels/AudioPlayerViewModel.cs | 31 +++++++++++++++++++ .../Resources/Controls/Aup/SourceEventArgs.cs | 5 +-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/FModel/ViewModels/AudioPlayerViewModel.cs b/FModel/ViewModels/AudioPlayerViewModel.cs index 26ed628c..1409e9f6 100644 --- a/FModel/ViewModels/AudioPlayerViewModel.cs +++ b/FModel/ViewModels/AudioPlayerViewModel.cs @@ -238,6 +238,20 @@ public void Load() }); } + public void Unload() + { + Application.Current.Dispatcher.Invoke(() => + { + _waveSource = null; + + PlayedFile = new AudioFile(-1, "No audio file"); + Spectrum = null; + + RaiseSourceEvent(ESourceEventType.Clearing); + ClearSoundOut(); + }); + } + public void AddToPlaylist(byte[] data, string filePath) { Application.Current.Dispatcher.Invoke(() => @@ -274,6 +288,18 @@ public void Remove() { _audioFiles[i].Id = i; } + + if (_audioFiles.Count < 1) + { + Unload(); + return; + } + + SelectedAudioFile = _audioFiles[SelectedAudioFile.Id]; + + if (!removedPlaying) return; + Load(); + Play(); }); } @@ -525,6 +551,11 @@ private void LoadSoundOut() _soundOut.Volume = UserSettings.Default.AudioPlayerVolume / 100; } + private void ClearSoundOut() + { + _soundOut = null; + } + private IEnumerable EnumerateDevices() { using var deviceEnumerator = new MMDeviceEnumerator(); diff --git a/FModel/Views/Resources/Controls/Aup/SourceEventArgs.cs b/FModel/Views/Resources/Controls/Aup/SourceEventArgs.cs index 102546ea..964638b7 100644 --- a/FModel/Views/Resources/Controls/Aup/SourceEventArgs.cs +++ b/FModel/Views/Resources/Controls/Aup/SourceEventArgs.cs @@ -4,7 +4,8 @@ namespace FModel.Views.Resources.Controls.Aup; public enum ESourceEventType { - Loading + Loading, + Clearing } public class SourceEventArgs : EventArgs @@ -15,4 +16,4 @@ public SourceEventArgs(ESourceEventType e) { Event = e; } -} \ No newline at end of file +} From 749790b1deaafe71069f93ab2e586a2a48f65d0d Mon Sep 17 00:00:00 2001 From: ScrubN <72096833+ScrubN@users.noreply.github.com> Date: Sun, 31 Dec 2023 02:13:16 -0500 Subject: [PATCH 07/11] Stop playback if removed file was currently playing file --- FModel/ViewModels/AudioPlayerViewModel.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FModel/ViewModels/AudioPlayerViewModel.cs b/FModel/ViewModels/AudioPlayerViewModel.cs index 1409e9f6..70d33ffc 100644 --- a/FModel/ViewModels/AudioPlayerViewModel.cs +++ b/FModel/ViewModels/AudioPlayerViewModel.cs @@ -283,6 +283,13 @@ public void Remove() if (_audioFiles.Count < 1) return; Application.Current.Dispatcher.Invoke(() => { + var removedPlaying = false; + if (PlayedFile.Id == SelectedAudioFile.Id) + { + removedPlaying = true; + Stop(); + } + _audioFiles.RemoveAt(SelectedAudioFile.Id); for (var i = 0; i < _audioFiles.Count; i++) { From cbc580ce37da7b61572fe632e662fd2a53c1d43f Mon Sep 17 00:00:00 2001 From: ScrubN <72096833+ScrubN@users.noreply.github.com> Date: Sun, 31 Dec 2023 02:06:05 -0500 Subject: [PATCH 08/11] Add 'X' hotkey for removing selected audio from the playlist --- FModel/Settings/UserSettings.cs | 7 +++++++ FModel/Views/AudioPlayer.xaml.cs | 2 ++ FModel/Views/SettingsView.xaml | 3 +++ 3 files changed, 12 insertions(+) diff --git a/FModel/Settings/UserSettings.cs b/FModel/Settings/UserSettings.cs index bca1427d..68a6c775 100644 --- a/FModel/Settings/UserSettings.cs +++ b/FModel/Settings/UserSettings.cs @@ -363,6 +363,13 @@ public Hotkey AddAudio set => SetProperty(ref _addAudio, value); } + private Hotkey _removeAudio = new(Key.X); + public Hotkey RemoveAudio + { + get => _removeAudio; + set => SetProperty(ref _removeAudio, value); + } + private Hotkey _playPauseAudio = new(Key.K); public Hotkey PlayPauseAudio { diff --git a/FModel/Views/AudioPlayer.xaml.cs b/FModel/Views/AudioPlayer.xaml.cs index 332b6101..f65660ce 100644 --- a/FModel/Views/AudioPlayer.xaml.cs +++ b/FModel/Views/AudioPlayer.xaml.cs @@ -75,6 +75,8 @@ private void OnPreviewKeyDown(object sender, KeyEventArgs e) _applicationView.AudioPlayer.Previous(); else if (UserSettings.Default.NextAudio.IsTriggered(e.Key)) _applicationView.AudioPlayer.Next(); + else if (UserSettings.Default.RemoveAudio.IsTriggered(e.Key)) + _applicationView.AudioPlayer.Remove(); } private void OnAudioFileMouseDoubleClick(object sender, MouseButtonEventArgs e) diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index b38b62d5..800e3d60 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -602,6 +602,9 @@ + + From d33dc959bfa5302adc27eca6647ba9f190a11a00 Mon Sep 17 00:00:00 2001 From: Krowe Moh <27891447+Krowe-moh@users.noreply.github.com> Date: Sat, 4 Apr 2026 18:47:34 +1100 Subject: [PATCH 09/11] Fixed Both in one --- FModel/Views/SettingsView.xaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index 800e3d60..d08606ec 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -556,6 +556,7 @@ + @@ -602,8 +603,8 @@ - - + From d159aa483d7592543fe6f581ef102735f2f8294d Mon Sep 17 00:00:00 2001 From: Krowe Moh <27891447+Krowe-moh@users.noreply.github.com> Date: Sat, 4 Apr 2026 20:13:31 +1100 Subject: [PATCH 10/11] Bump CUE4parse --- CUE4Parse | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CUE4Parse b/CUE4Parse index 721e812b..39d1b4b1 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 721e812b7bd82f94a23ab728d0887245bb4c56d9 +Subproject commit 39d1b4b1fb57cc7cf47e10b003a1dca3961661c3 From bb160e798e8a7092ca68bb86ad24dacd1c1377f2 Mon Sep 17 00:00:00 2001 From: Krowe Moh <27891447+Krowe-moh@users.noreply.github.com> Date: Thu, 9 Apr 2026 05:53:45 +1000 Subject: [PATCH 11/11] Added 50 Entry Limit --- .../ViewModels/Commands/RightClickMenuCommand.cs | 14 +++----------- FModel/ViewModels/TabControlViewModel.cs | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/FModel/ViewModels/Commands/RightClickMenuCommand.cs b/FModel/ViewModels/Commands/RightClickMenuCommand.cs index e82b4905..28e50f7b 100644 --- a/FModel/ViewModels/Commands/RightClickMenuCommand.cs +++ b/FModel/ViewModels/Commands/RightClickMenuCommand.cs @@ -146,10 +146,10 @@ await _threadWorkerView.Begin(cancellationToken => { Thread.Yield(); cancellationToken.ThrowIfCancellationRequested(); - fileAction(entry, bulktype | EBulkType.Auto, update); + fileAction(entry, bulktype, update); } - LogExport(contextViewModel, filetype); + if (assets.Length > 50) LogExport(contextViewModel, filetype); return; } @@ -212,15 +212,7 @@ private void LogExport(ApplicationViewModel contextViewModel, string fileType) { FLogger.Append(ELog.Information, () => { - FLogger.Text($"Successfully exported {contextViewModel.CUE4Parse.ExportedCount} {fileType}", Constants.WHITE, true); - }); - } - - if (contextViewModel.CUE4Parse.FailedExportCount > 0) - { - FLogger.Append(ELog.Error, () => - { - FLogger.Text($"Failed to export {contextViewModel.CUE4Parse.FailedExportCount} {fileType}", Constants.WHITE, true); + FLogger.Text($"Successfully exported {contextViewModel.CUE4Parse.ExportedCount} {fileType}, Failed to export {contextViewModel.CUE4Parse.FailedExportCount} {fileType} in other folders.", Constants.WHITE, true); }); } diff --git a/FModel/ViewModels/TabControlViewModel.cs b/FModel/ViewModels/TabControlViewModel.cs index dbeb4423..7f18c1e7 100644 --- a/FModel/ViewModels/TabControlViewModel.cs +++ b/FModel/ViewModels/TabControlViewModel.cs @@ -426,7 +426,7 @@ private void SaveCheck(string path, string fileName, bool updateUi) { Interlocked.Increment(ref ApplicationService.ApplicationView.CUE4Parse.ExportedCount); Log.Information("{FileName} successfully saved", fileName); - if (updateUi) + if (updateUi && ApplicationService.ApplicationView.CUE4Parse.ExportedCount < 50) { FLogger.Append(ELog.Information, () => {