From 139c61d9dbf20d46ade378705a6e5bdd1f454b6d Mon Sep 17 00:00:00 2001
From: simon <107362910+simonhxd@users.noreply.github.com>
Date: Thu, 27 Nov 2025 07:10:26 -0800
Subject: [PATCH 01/16] Add Decompile Blueprint to Search View (#615)
---
FModel/Views/SearchView.xaml | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/FModel/Views/SearchView.xaml b/FModel/Views/SearchView.xaml
index 317a8e2a..23b9b3e3 100644
--- a/FModel/Views/SearchView.xaml
+++ b/FModel/Views/SearchView.xaml
@@ -171,6 +171,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1379,25 +1350,25 @@
+ Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}">
+ />
@@ -1961,4 +1932,48 @@
+
+
+
+
diff --git a/FModel/Views/SearchView.xaml b/FModel/Views/SearchView.xaml
index 23b9b3e3..42095bc2 100644
--- a/FModel/Views/SearchView.xaml
+++ b/FModel/Views/SearchView.xaml
@@ -11,149 +11,367 @@
Width="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenWidth}, Converter={converters:RatioConverter}, ConverterParameter='0.65'}">
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FModel/Views/SearchView.xaml.cs b/FModel/Views/SearchView.xaml.cs
index 2900703c..31458820 100644
--- a/FModel/Views/SearchView.xaml.cs
+++ b/FModel/Views/SearchView.xaml.cs
@@ -1,6 +1,9 @@
-using System;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using System.Windows;
+using System.Windows.Controls;
using System.Windows.Input;
using CUE4Parse.FileProvider.Objects;
using FModel.Services;
@@ -8,61 +11,167 @@ using FModel.ViewModels;
namespace FModel.Views;
+public enum ESearchViewTab
+{
+ SearchView,
+ RefView
+}
+
public partial class SearchView
{
private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView;
private ApplicationViewModel _applicationView => ApplicationService.ApplicationView;
+ private SearchViewModel _searchViewModel => _applicationView.CUE4Parse.SearchVm;
+ private SearchViewModel _refViewModel => _applicationView.CUE4Parse.RefVm;
+
+ private ESearchViewTab _currentTab = ESearchViewTab.SearchView;
public SearchView()
{
- DataContext = _applicationView;
+ DataContext = new
+ {
+ mainApplication = _applicationView,
+ SearchTab = _searchViewModel,
+ RefTab = _refViewModel,
+ };
InitializeComponent();
Activate();
- WpfSuckMyDick.Focus();
- WpfSuckMyDick.SelectAll();
+ SearchTextBox.Focus();
+ SearchTextBox.SelectAll();
+ }
+
+ public void FocusTab(ESearchViewTab view)
+ {
+ if (_currentTab == view)
+ return;
+
+ _currentTab = view;
+ SearchTabControl.SelectedIndex = view switch
+ {
+ ESearchViewTab.SearchView => 0,
+ ESearchViewTab.RefView => 1,
+ _ => SearchTabControl.SelectedIndex
+ };
+ CurrentTextBox?.Focus();
+ CurrentTextBox?.SelectAll();
+ }
+
+ public void ChangeCollection(ESearchViewTab view, IEnumerable files, GameFile refFile)
+ {
+ var vm = view switch
+ {
+ ESearchViewTab.SearchView => _searchViewModel,
+ ESearchViewTab.RefView => _refViewModel,
+ _ => null
+ };
+ vm?.ChangeCollection(files, refFile);
+ }
+
+ private async void OnFindRefs(object sender, RoutedEventArgs e)
+ {
+ if (CurrentListView?.SelectedItem is not GameFile entry)
+ return;
+
+ await _threadWorkerView.Begin(_ => _applicationView.CUE4Parse.FindReferences(entry));
+ }
+
+ private void OnTabItemChange(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.OriginalSource is not TabControl tabControl)
+ return;
+
+ _currentTab = tabControl.SelectedIndex switch
+ {
+ 0 => ESearchViewTab.SearchView,
+ 1 => ESearchViewTab.RefView,
+ _ => _currentTab
+ };
+ CurrentTextBox?.Focus();
+ CurrentTextBox?.SelectAll();
}
private void OnDeleteSearchClick(object sender, RoutedEventArgs e)
{
- _applicationView.CUE4Parse.SearchVm.FilterText = string.Empty;
- _applicationView.CUE4Parse.SearchVm.RefreshFilter();
+ var viewModel = CurrentViewModel;
+ if (viewModel == null)
+ return;
+ viewModel.FilterText = string.Empty;
+ viewModel.RefreshFilter();
}
- private async void OnSortClick(object sender, RoutedEventArgs e)
+ private SearchViewModel CurrentViewModel => _currentTab switch
{
- await _applicationView.CUE4Parse.SearchVm.CycleSortSizeMode();
+ ESearchViewTab.SearchView => _applicationView.CUE4Parse.SearchVm,
+ ESearchViewTab.RefView => _applicationView.CUE4Parse.RefVm,
+ _ => null
+ };
+
+ private ListView CurrentListView => _currentTab switch
+ {
+ ESearchViewTab.SearchView => SearchListView,
+ ESearchViewTab.RefView => RefListView,
+ _ => null
+ };
+
+ private TextBox CurrentTextBox => _currentTab switch
+ {
+ ESearchViewTab.SearchView => SearchTextBox,
+ ESearchViewTab.RefView => RefSearchTextBox,
+ _ => null
+ };
+
+ private async void OnSearchSortClick(object sender, RoutedEventArgs e)
+ {
+ await CurrentViewModel?.CycleSortSizeMode();
}
private async void OnAssetDoubleClick(object sender, RoutedEventArgs e)
{
- if (SearchListView.SelectedItem is not GameFile entry)
+ if (CurrentListView?.SelectedItem is not GameFile entry)
return;
+ await NavigateToAssetAndSelect(entry);
+ }
+ private async void OnGoToRefPackage(object sender, RoutedEventArgs e)
+ {
+ if (_refViewModel.RefFile is not GameFile entry)
+ return;
+
+ await NavigateToAssetAndSelect(entry);
+ }
+
+ private async Task NavigateToAssetAndSelect(GameFile entry)
+ {
WindowState = WindowState.Minimized;
MainWindow.YesWeCats.AssetsListName.ItemsSource = null;
var folder = _applicationView.CustomDirectories.GoToCommand.JumpTo(entry.Directory);
- if (folder == null) return;
+ if (folder == null)
+ return;
MainWindow.YesWeCats.Activate();
- do { await Task.Delay(100); } while (MainWindow.YesWeCats.AssetsListName.Items.Count < folder.AssetsList.Assets.Count);
+ do
+ { await Task.Delay(100); } while (MainWindow.YesWeCats.AssetsListName.Items.Count < folder.AssetsList.Assets.Count);
while (!folder.IsSelected || MainWindow.YesWeCats.AssetsFolderName.SelectedItem != folder)
await Task.Delay(50); // stops assets tab from opening too early
- MainWindow.YesWeCats.LeftTabControl.SelectedIndex = 2; // assets tab
+ ApplicationService.ApplicationView.SelectedLeftTabIndex = 2; // assets tab
do
{
await Task.Delay(100);
- MainWindow.YesWeCats.AssetsListName.SelectedItem = entry;
- MainWindow.YesWeCats.AssetsListName.ScrollIntoView(entry);
+ var vm = MainWindow.YesWeCats.AssetsListName.Items
+ .OfType()
+ .FirstOrDefault(x => x.Asset == entry);
+ MainWindow.YesWeCats.AssetsListName.SelectedItem = vm;
+ MainWindow.YesWeCats.AssetsListName.ScrollIntoView(vm);
} while (MainWindow.YesWeCats.AssetsListName.SelectedItem == null);
}
private async void OnAssetExtract(object sender, RoutedEventArgs e)
{
- if (SearchListView.SelectedItem is not GameFile entry)
+ if (CurrentListView?.SelectedItem is not GameFile entry)
return;
WindowState = WindowState.Minimized;
@@ -73,8 +182,9 @@ public partial class SearchView
private void OnWindowKeyDown(object sender, KeyEventArgs e)
{
- if (e.Key != Key.Enter) return;
- _applicationView.CUE4Parse.SearchVm.RefreshFilter();
+ if (e.Key != Key.Enter)
+ return;
+ CurrentViewModel?.RefreshFilter();
}
private void OnStateChanged(object sender, EventArgs e)
@@ -83,8 +193,8 @@ public partial class SearchView
{
case WindowState.Normal:
Activate();
- WpfSuckMyDick.Focus();
- WpfSuckMyDick.SelectAll();
+ CurrentTextBox?.Focus();
+ CurrentTextBox?.SelectAll();
return;
}
}
diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml
index 74562957..3869882d 100644
--- a/FModel/Views/SettingsView.xaml
+++ b/FModel/Views/SettingsView.xaml
@@ -18,10 +18,6 @@
-
-
-
-
@@ -544,6 +540,7 @@
+
@@ -560,32 +557,35 @@
-
+
-
+ HotKey="{Binding SwitchAssetExplorer, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
+
-
+ HotKey="{Binding AssetLeftTab, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
+
+
+
-
-
+
-
+
-
-
-
+
-
+ HotKey="{Binding AddAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
+
-
+ HotKey="{Binding PlayPauseAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
+
+
+
diff --git a/FModel/Views/UpdateView.xaml b/FModel/Views/UpdateView.xaml
index 6d378592..7a2d7a55 100644
--- a/FModel/Views/UpdateView.xaml
+++ b/FModel/Views/UpdateView.xaml
@@ -15,13 +15,6 @@
-
-
-
-
-
-
-
@@ -76,7 +69,7 @@
-
+
@@ -107,6 +100,24 @@
+
+
+
diff --git a/FModel/Views/UpdateView.xaml.cs b/FModel/Views/UpdateView.xaml.cs
index 3b9ca455..df433aff 100644
--- a/FModel/Views/UpdateView.xaml.cs
+++ b/FModel/Views/UpdateView.xaml.cs
@@ -12,10 +12,10 @@ public partial class UpdateView
InitializeComponent();
}
- private async void OnLoaded(object sender, RoutedEventArgs e)
+ private void OnLoaded(object sender, RoutedEventArgs e)
{
if (DataContext is not UpdateViewModel viewModel) return;
- await viewModel.Load();
+ _ = viewModel.LoadAsync();
}
private void OnDownloadLatest(object sender, RoutedEventArgs e)
@@ -24,4 +24,3 @@ public partial class UpdateView
viewModel.DownloadLatest();
}
}
-
diff --git a/NOTICE b/NOTICE
index 96118130..8654d255 100644
--- a/NOTICE
+++ b/NOTICE
@@ -18,6 +18,7 @@ This software includes material developed by the following third-party libraries
- Serilog (https://github.com/serilog/serilog/blob/dev/LICENSE) - Copyright 2013-2015 Serilog Contributors. Licensed under the Apache License 2.0.
- SixLabors.ImageSharp (https://github.com/SixLabors/ImageSharp/blob/main/LICENSE) - Copyright (c) Six Labors. Licensed under the Apache License 2.0.
- SkiaSharp (https://github.com/mono/SkiaSharp/blob/main/LICENSE.md) - Copyright (c) 2015-2016 Xamarin, Inc. & 2017-2018 Microsoft Corporation. Licensed under the MIT License.
+- VirtualizingWrapPanel (https://github.com/sbaeumlisberger/VirtualizingWrapPanel/blob/master/LICENSE) - Copyright (c) 2019 S. Bäumlisberger. Licensed under the MIT License.
---------------------------------------------------------------------------
From 2415c50698d5211ac31b3ec1d48ec27a1b1943fe Mon Sep 17 00:00:00 2001
From: LongerWarrior
Date: Mon, 22 Dec 2025 01:00:24 +0200
Subject: [PATCH 15/16] PUBG Black Budget support Valorant mappings endpoint
---
CUE4Parse | 2 +-
FModel/Settings/EndpointSettings.cs | 24 ++++++++++++------------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/CUE4Parse b/CUE4Parse
index d2f6ce6e..ab20414a 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit d2f6ce6e618576dbbe7f6dd9ed3171f14513182a
+Subproject commit ab20414ab3661fbfda06afdd00c8b54bc7797c90
diff --git a/FModel/Settings/EndpointSettings.cs b/FModel/Settings/EndpointSettings.cs
index e4b755c3..5b70926f 100644
--- a/FModel/Settings/EndpointSettings.cs
+++ b/FModel/Settings/EndpointSettings.cs
@@ -10,18 +10,18 @@ public class EndpointSettings : ViewModel
{
public static EndpointSettings[] Default(string gameName)
{
- switch (gameName)
+ return gameName switch
{
- case "Fortnite":
- case "Fortnite [LIVE]":
- return new EndpointSettings[]
- {
- new("https://uedb.dev/svc/api/v1/fortnite/aes", "$.['mainKey','dynamicKeys']"),
- new("https://uedb.dev/svc/api/v1/fortnite/mappings", "$.mappings.ZStandard")
- };
- default:
- return new EndpointSettings[] { new(), new() };
- }
+ "Fortnite" or "Fortnite [LIVE]" => [
+ new("https://uedb.dev/svc/api/v1/fortnite/aes", "$.['mainKey','dynamicKeys']"),
+ new("https://uedb.dev/svc/api/v1/fortnite/mappings", "$.mappings.ZStandard")
+ ],
+ "VALORANT" or "VALORANT [LIVE]" => [
+ new("https://uedb.dev/svc/api/v1/valorant/aes", "$.['mainKey','dynamicKeys']"),
+ new("https://uedb.dev/svc/api/v1/valorant/mappings", "$.mappings.ZStandard")
+ ],
+ _ => [new(), new()],
+ };
}
private string _url;
@@ -106,4 +106,4 @@ public class EndpointSettings : ViewModel
}
}
}
-}
\ No newline at end of file
+}
From fe4529908ee38e128f789f7e54b72310aac99dfb Mon Sep 17 00:00:00 2001
From: Asval
Date: Mon, 22 Dec 2025 00:02:37 +0100
Subject: [PATCH 16/16] some post update fixes
---
FModel/MainWindow.xaml | 1 +
FModel/MainWindow.xaml.cs | 10 +++++++++-
FModel/ViewModels/UpdateViewModel.cs | 9 ++++++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/FModel/MainWindow.xaml b/FModel/MainWindow.xaml
index 816ed7ff..82da6143 100644
--- a/FModel/MainWindow.xaml
+++ b/FModel/MainWindow.xaml
@@ -351,6 +351,7 @@
diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs
index 434b2d33..2c532723 100644
--- a/FModel/MainWindow.xaml.cs
+++ b/FModel/MainWindow.xaml.cs
@@ -103,7 +103,7 @@ public partial class MainWindow
await Task.WhenAll(
ApplicationViewModel.InitOodle(),
ApplicationViewModel.InitZlib()
- ).ConfigureAwait(false);
+ );
await _applicationView.CUE4Parse.Initialize();
await _applicationView.AesManager.InitAes();
@@ -275,6 +275,14 @@ public partial class MainWindow
}
}
+ private void OnAssetsTreeSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ if (sender is not TreeView { SelectedItem: TreeItem }) return;
+
+ _applicationView.IsAssetsExplorerVisible = true;
+ _applicationView.SelectedLeftTabIndex = 1;
+ }
+
private async void OnAssetsListMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (sender is not ListBox listBox) return;
diff --git a/FModel/ViewModels/UpdateViewModel.cs b/FModel/ViewModels/UpdateViewModel.cs
index b6088e0a..adbc79bd 100644
--- a/FModel/ViewModels/UpdateViewModel.cs
+++ b/FModel/ViewModels/UpdateViewModel.cs
@@ -76,7 +76,14 @@ public partial class UpdateViewModel : ViewModel
foreach (Match match in matches)
{
if (match.Groups.Count < 3) continue;
- coAuthorMap[commit].Add(match.Groups[1].Value);
+
+ var username = match.Groups[1].Value;
+ if (username.Equals("Asval", StringComparison.OrdinalIgnoreCase))
+ {
+ username = "4sval"; // found out the hard way co-authored usernames can't be trusted
+ }
+
+ coAuthorMap[commit].Add(username);
}
}