diff --git a/README.md b/README.md
index 212ffcb6..acbf1b41 100644
--- a/README.md
+++ b/README.md
@@ -1,52 +1,52 @@
# Bannerlord.UIExtenderEx
-
-
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -62,7 +62,7 @@
-
+
A library that enables multiple mods to alter standard game interface.
@@ -72,7 +72,7 @@ Previously, a fork of [UIExtenderLib](https://github.com/shdwp/UIExtenderLib) th
This module should be one of the highest in loading order. Ideally, it should be loaded after ``Bannerlord.Harmony`` or ``Bannerlord.ButterLib``.
## For Players
-This mod is a dependency mod that does not provide anything by itself. You need to additionaly install mods that use it.
+This mod is a dependency mod that does not provide anything by itself. You need to additionally install mods that use it.
## Usage
Check the [``Articles``](https://butr.github.io/Bannerlord.UIExtenderEx/articles/v2/Overview.html) section of our documentation!
diff --git a/build/common.props b/build/common.props
index 4770de8c..92165722 100644
--- a/build/common.props
+++ b/build/common.props
@@ -4,7 +4,7 @@
- 2.9.0
+ 2.10.0
2.2.2
3.2.0.77
diff --git a/changelog.txt b/changelog.txt
index 96ebb7df..73a074c8 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,4 +1,9 @@
---------------------------------------------------------------------------------------------------
+Version: 2.10.0
+Game Versions: v1.0.0,v1.0.1,v1.0.2,v1.0.3,v1.1.0,v1.1.1,v1.1.2,v1.1.3,v1.1.4,v1.1.5,v1.1.6,v1.2.8
+* BETA! Might cause issues with the UI in specific cases!
+* UIExtender now only disables AutoGens that are patched, should increase the game's performance
+---------------------------------------------------------------------------------------------------
Version: 2.9.0
Game Versions: v1.0.0,v1.0.1,v1.0.2,v1.0.3,v1.1.0,v1.1.1,v1.1.2,v1.1.3,v1.1.4,v1.1.5,v1.1.6,v1.2.8
* Added the ability to disable specific Prefabs and Mixins, also to deregister a mods UIExtender
diff --git a/docs/articles/general/InteractingWithOtherMods.md b/docs/articles/general/InteractingWithOtherMods.md
new file mode 100644
index 00000000..5878e1ae
--- /dev/null
+++ b/docs/articles/general/InteractingWithOtherMods.md
@@ -0,0 +1,17 @@
+# Interacting with Other Mods
+
+You can access another mod's `UIExtender` and modify it to your liking.
+At the moment you are able to disable the UIExtender, deregister it (meaning fully disabling it without the ability to enable it back) and enable.
+You are able to disable a specific Prefab or Mixin.
+```csharp
+// Get Mod Configuration Menu's UIExtender
+var mcm = UIExtender.GetUIExtenderFor("MCM.UI");
+
+// Disable a prefab
+var mcmPrefab = AccessTools.TypeByName("MCM.UI.UIExtenderEx.OptionsPrefabExtension1");
+mcm.Disable(mcmPrefab);
+
+// Disable a Mixin
+var mcmMixin = AccessTools.TypeByName("MCM.UI.UIExtenderEx.OptionsVMMixin");
+mcm.Disable(mcmMixin);
+```
\ No newline at end of file
diff --git a/docs/articles/general/Overview.md b/docs/articles/general/Overview.md
new file mode 100644
index 00000000..8316c31a
--- /dev/null
+++ b/docs/articles/general/Overview.md
@@ -0,0 +1,3 @@
+# Overview
+
+Check the specific articles.
\ No newline at end of file
diff --git a/docs/articles/general/toc.yml b/docs/articles/general/toc.yml
new file mode 100644
index 00000000..9831a478
--- /dev/null
+++ b/docs/articles/general/toc.yml
@@ -0,0 +1,6 @@
+- name: Overview
+ href: Overview.md
+- name: Prefab
+ href: Prefab.md
+- name: Interacting With Other Mods
+ href: InteractingWithOtherMods.md
diff --git a/docs/articles/interface/toc.yml b/docs/articles/interface/toc.yml
index 7018247e..e8fbca11 100644
--- a/docs/articles/interface/toc.yml
+++ b/docs/articles/interface/toc.yml
@@ -2,5 +2,5 @@
href: Overview.md
- name: Prefab
href: Prefab.md
-- name: ViewModelMixin
+- name: ViewModel Mixin
href: ViewModelMixin.md
diff --git a/docs/articles/runtime/toc.yml b/docs/articles/runtime/toc.yml
index 80d02a8c..ca802cec 100644
--- a/docs/articles/runtime/toc.yml
+++ b/docs/articles/runtime/toc.yml
@@ -2,7 +2,7 @@
href: Overview.md
- name: Registration
href: Registration.md
-- name: PrefabPatching
+- name: Prefab Patching
href: PrefabPatching.md
-- name: ViewModelPatching
+- name: ViewModel Patching
href: ViewModelPatching.md
diff --git a/docs/articles/toc.yml b/docs/articles/toc.yml
index dd8ebace..022ced4e 100644
--- a/docs/articles/toc.yml
+++ b/docs/articles/toc.yml
@@ -1,4 +1,7 @@
items:
+- name: General
+ href: general/toc.yml
+ homepage: general/Overview.md
- name: APIv2
href: v2/toc.yml
homepage: v2/Overview.md
diff --git a/docs/articles/v2/toc.yml b/docs/articles/v2/toc.yml
index 581ec6b6..df13d403 100644
--- a/docs/articles/v2/toc.yml
+++ b/docs/articles/v2/toc.yml
@@ -4,7 +4,7 @@
href: PrefabExtensionSetAttributePatch.md
- name: PrefabExtensionInsertPatch
href: PrefabExtensionInsertPatch.md
-- name: ViewModelMixin
+- name: ViewModel Mixin
href: ViewModelMixin.md
- name: Examples
href: Examples.md
diff --git a/src/Bannerlord.UIExtenderEx.sln b/src/Bannerlord.UIExtenderEx.sln
index dbd0fc86..7eec80dc 100644
--- a/src/Bannerlord.UIExtenderEx.sln
+++ b/src/Bannerlord.UIExtenderEx.sln
@@ -31,8 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bannerlord.UIExtenderEx.Tes
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{6A6FB1BE-5426-4835-A308-0E74E66299D5}"
ProjectSection(SolutionItems) = preProject
- ..\docs\articles\toc.yml = ..\docs\articles\toc.yml
..\docs\docfx.json = ..\docs\docfx.json
+ ..\docs\toc.yml = ..\docs\toc.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "v1", "v1", "{395402D4-28B5-4974-943D-04B7D5F6673D}"
@@ -53,33 +53,38 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "v2", "v2", "{B4D6A888-2D8F-
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "interface", "interface", "{252A68C5-9E10-4E28-AF49-37E6DF1E62F0}"
ProjectSection(SolutionItems) = preProject
- ..\docs\articles\Interface\Overview.png = ..\docs\articles\Interface\Overview.png
- ..\docs\articles\Interface\Overview.puml = ..\docs\articles\Interface\Overview.puml
- ..\docs\articles\Interface\Prefab.png = ..\docs\articles\Interface\Prefab.png
- ..\docs\articles\Interface\Prefab.puml = ..\docs\articles\Interface\Prefab.puml
- ..\docs\articles\Interface\ViewModelMixin.png = ..\docs\articles\Interface\ViewModelMixin.png
- ..\docs\articles\Interface\ViewModelMixin.puml = ..\docs\articles\Interface\ViewModelMixin.puml
- ..\docs\articles\Interface\Overview.md = ..\docs\articles\Interface\Overview.md
- ..\docs\articles\Interface\Prefab.md = ..\docs\articles\Interface\Prefab.md
- ..\docs\articles\Interface\ViewModelMixin.md = ..\docs\articles\Interface\ViewModelMixin.md
- ..\docs\articles\Interface\toc.yml = ..\docs\articles\Interface\toc.yml
+ ..\docs\articles\interface\Overview.svg = ..\docs\articles\interface\Overview.svg
+ ..\docs\articles\interface\Overview.puml = ..\docs\articles\interface\Overview.puml
+ ..\docs\articles\interface\Overview.md = ..\docs\articles\interface\Overview.md
+ ..\docs\articles\interface\Prefab.svg = ..\docs\articles\interface\Prefab.svg
+ ..\docs\articles\interface\Prefab.puml = ..\docs\articles\interface\Prefab.puml
+ ..\docs\articles\interface\Prefab.md = ..\docs\articles\interface\Prefab.md
+ ..\docs\articles\interface\ViewModelMixin.svg = ..\docs\articles\interface\ViewModelMixin.svg
+ ..\docs\articles\interface\ViewModelMixin.puml = ..\docs\articles\interface\ViewModelMixin.puml
+ ..\docs\articles\interface\ViewModelMixin.md = ..\docs\articles\interface\ViewModelMixin.md
+ ..\docs\articles\interface\toc.yml = ..\docs\articles\interface\toc.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "runtime", "runtime", "{8969A5E2-BC12-46F8-BF4A-E8F73771E4E5}"
ProjectSection(SolutionItems) = preProject
- ..\docs\articles\Runtime\ViewModelPatching.png = ..\docs\articles\Runtime\ViewModelPatching.png
- ..\docs\articles\Runtime\ViewModelPatching.puml = ..\docs\articles\Runtime\ViewModelPatching.puml
- ..\docs\articles\Runtime\Overview.png = ..\docs\articles\Runtime\Overview.png
- ..\docs\articles\Runtime\Overview.puml = ..\docs\articles\Runtime\Overview.puml
- ..\docs\articles\Runtime\PrefabPatching.png = ..\docs\articles\Runtime\PrefabPatching.png
- ..\docs\articles\Runtime\PrefabPatching.puml = ..\docs\articles\Runtime\PrefabPatching.puml
- ..\docs\articles\Runtime\Registration.png = ..\docs\articles\Runtime\Registration.png
- ..\docs\articles\Runtime\Registration.puml = ..\docs\articles\Runtime\Registration.puml
- ..\docs\articles\Runtime\Overview.md = ..\docs\articles\Runtime\Overview.md
- ..\docs\articles\Runtime\PrefabPatching.md = ..\docs\articles\Runtime\PrefabPatching.md
- ..\docs\articles\Runtime\Registration.md = ..\docs\articles\Runtime\Registration.md
- ..\docs\articles\Runtime\ViewModelPatching.md = ..\docs\articles\Runtime\ViewModelPatching.md
- ..\docs\articles\Runtime\toc.yml = ..\docs\articles\Runtime\toc.yml
+ ..\docs\articles\runtime\ViewModelPatching.svg = ..\docs\articles\runtime\ViewModelPatching.svg
+ ..\docs\articles\runtime\ViewModelPatching.puml = ..\docs\articles\runtime\ViewModelPatching.puml
+ ..\docs\articles\runtime\ViewModelPatching.md = ..\docs\articles\runtime\ViewModelPatching.md
+ ..\docs\articles\runtime\Overview.svg = ..\docs\articles\runtime\Overview.svg
+ ..\docs\articles\runtime\Overview.puml = ..\docs\articles\runtime\Overview.puml
+ ..\docs\articles\runtime\Overview.md = ..\docs\articles\runtime\Overview.md
+ ..\docs\articles\runtime\PrefabPatching.svg = ..\docs\articles\runtime\PrefabPatching.svg
+ ..\docs\articles\runtime\PrefabPatching.puml = ..\docs\articles\runtime\PrefabPatching.puml
+ ..\docs\articles\runtime\PrefabPatching.md = ..\docs\articles\runtime\PrefabPatching.md
+ ..\docs\articles\runtime\Registration.svg = ..\docs\articles\runtime\Registration.svg
+ ..\docs\articles\runtime\Registration.puml = ..\docs\articles\runtime\Registration.puml
+ ..\docs\articles\runtime\Registration.md = ..\docs\articles\runtime\Registration.md
+ ..\docs\articles\runtime\toc.yml = ..\docs\articles\runtime\toc.yml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "articles", "articles", "{8034BC17-4282-4A4B-942B-80EEC315C1C2}"
+ ProjectSection(SolutionItems) = preProject
+ ..\docs\articles\toc.yml = ..\docs\articles\toc.yml
EndProjectSection
EndProject
Global
@@ -118,10 +123,11 @@ Global
{74E13D44-2846-49A3-A5AC-D432AD83C9F0} = {9D2C61D6-D1B6-4C89-80B2-6DAE2D5FCEE4}
{7C6449DA-635E-4BD9-AAFE-CF2C4B2FB988} = {74E13D44-2846-49A3-A5AC-D432AD83C9F0}
{6A6FB1BE-5426-4835-A308-0E74E66299D5} = {9D2C61D6-D1B6-4C89-80B2-6DAE2D5FCEE4}
- {395402D4-28B5-4974-943D-04B7D5F6673D} = {6A6FB1BE-5426-4835-A308-0E74E66299D5}
- {B4D6A888-2D8F-49A4-87C5-6CD18D8F818B} = {6A6FB1BE-5426-4835-A308-0E74E66299D5}
- {252A68C5-9E10-4E28-AF49-37E6DF1E62F0} = {6A6FB1BE-5426-4835-A308-0E74E66299D5}
- {8969A5E2-BC12-46F8-BF4A-E8F73771E4E5} = {6A6FB1BE-5426-4835-A308-0E74E66299D5}
+ {8034BC17-4282-4A4B-942B-80EEC315C1C2} = {6A6FB1BE-5426-4835-A308-0E74E66299D5}
+ {252A68C5-9E10-4E28-AF49-37E6DF1E62F0} = {8034BC17-4282-4A4B-942B-80EEC315C1C2}
+ {8969A5E2-BC12-46F8-BF4A-E8F73771E4E5} = {8034BC17-4282-4A4B-942B-80EEC315C1C2}
+ {395402D4-28B5-4974-943D-04B7D5F6673D} = {8034BC17-4282-4A4B-942B-80EEC315C1C2}
+ {B4D6A888-2D8F-49A4-87C5-6CD18D8F818B} = {8034BC17-4282-4A4B-942B-80EEC315C1C2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {31629F18-48B4-4C3E-87C3-BDCB9BBF1BBD}
diff --git a/src/Bannerlord.UIExtenderEx/Components/PrefabComponent.cs b/src/Bannerlord.UIExtenderEx/Components/PrefabComponent.cs
index 2346df92..cb334cab 100644
--- a/src/Bannerlord.UIExtenderEx/Components/PrefabComponent.cs
+++ b/src/Bannerlord.UIExtenderEx/Components/PrefabComponent.cs
@@ -1,4 +1,5 @@
-using Bannerlord.BUTR.Shared.Helpers;
+using Bannerlord.BUTR.Shared.Extensions;
+using Bannerlord.BUTR.Shared.Helpers;
using Bannerlord.UIExtenderEx.Utils;
using HarmonyLib.BUTR.Extensions;
@@ -21,7 +22,7 @@ namespace Bannerlord.UIExtenderEx.Components;
///
internal partial class PrefabComponent
{
- private sealed record PrefabPatch(Type Type, Action Patcher);
+ internal sealed record PrefabPatch(Type Type, Action Patcher);
private delegate Dictionary GetPrefabNamesAndPathsFromCurrentPathDelegate(object instance);
private static readonly GetPrefabNamesAndPathsFromCurrentPathDelegate? PrefabNamesMethod =
@@ -36,7 +37,7 @@ private sealed record PrefabPatch(Type Type, Action Patcher);
///
/// Registered movie patches
///
- private readonly ConcurrentDictionary> _moviePatches = new();
+ internal readonly ConcurrentDictionary> MoviePatches = new();
private readonly ConcurrentDictionary _enabledPatches = new();
public PrefabComponent(string moduleName)
@@ -44,6 +45,15 @@ public PrefabComponent(string moduleName)
_moduleName = moduleName;
}
+ public IEnumerable GetMoviesToPatch()
+ {
+ foreach (var (movie, patches) in MoviePatches)
+ {
+ if (patches.Any(x => _enabledPatches.TryGetValue(x.Type, out var enabled) && enabled))
+ yield return movie;
+ }
+ }
+
///
/// Enables all Prefabs.
///
@@ -96,7 +106,7 @@ public void RegisterPatch(string movie, Type prefabType, Action pat
return;
}
- _moviePatches.GetOrAdd(movie, _ => new List()).Add(new(prefabType, patcher));
+ MoviePatches.GetOrAdd(movie, _ => new List()).Add(new(prefabType, patcher));
_enabledPatches[prefabType] = false;
}
@@ -115,7 +125,7 @@ public void RegisterPatch(string movie, Type prefabType, Action patcher
return;
}
- _moviePatches.GetOrAdd(movie, _ => new List()).Add(new(prefabType, patcher));
+ MoviePatches.GetOrAdd(movie, _ => new List()).Add(new(prefabType, patcher));
_enabledPatches[prefabType] = false;
}
@@ -140,7 +150,7 @@ public void RegisterPatch(string movie, string? xpath, Type prefabType, Action
public void ProcessMovieIfNeeded(string movie, XmlDocument document)
{
- if (!_moviePatches.TryGetValue(movie, out var patches))
+ if (!MoviePatches.TryGetValue(movie, out var patches))
return;
if (_enabledPatches.Values.All(x => !x))
diff --git a/src/Bannerlord.UIExtenderEx/Patches/GauntletMoviePatch.cs b/src/Bannerlord.UIExtenderEx/Patches/GauntletMoviePatch.cs
index d72f851d..7aa00fbc 100644
--- a/src/Bannerlord.UIExtenderEx/Patches/GauntletMoviePatch.cs
+++ b/src/Bannerlord.UIExtenderEx/Patches/GauntletMoviePatch.cs
@@ -1,22 +1,30 @@
using HarmonyLib;
using HarmonyLib.BUTR.Extensions;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
+using TaleWorlds.GauntletUI.BaseTypes;
+using TaleWorlds.GauntletUI.PrefabSystem;
+using TaleWorlds.Library;
+
namespace Bannerlord.UIExtenderEx.Patches;
internal static class GauntletMoviePatch
{
- private static readonly ConcurrentDictionary> WidgetNames = new();
-
+ private static readonly ConcurrentDictionary> _widgetNames = new();
+ private static readonly ConcurrentDictionary _widgetChildCache = new();
+ private static readonly AccessTools.FieldRef>>? _generatedPrefabs =
+ AccessTools2.FieldRefAccess>>("_generatedPrefabs");
+
public static void Register(UIExtenderRuntime runtime, string? autoGenWidgetName)
{
if (string.IsNullOrEmpty(autoGenWidgetName))
return;
- WidgetNames.AddOrUpdate(runtime, _ => [autoGenWidgetName], (_, list) =>
+ _widgetNames.AddOrUpdate(runtime, _ => [autoGenWidgetName], (_, list) =>
{
list.Add(autoGenWidgetName!);
return list;
@@ -25,25 +33,73 @@ public static void Register(UIExtenderRuntime runtime, string? autoGenWidgetName
public static void Deregister(UIExtenderRuntime runtime)
{
- WidgetNames.TryRemove(runtime, out var _);
+ _widgetNames.TryRemove(runtime, out var _);
}
public static void Patch(Harmony harmony)
{
- if (AccessTools2.DeclaredMethod("TaleWorlds.GauntletUI.Data.GauntletMovie:Load") is { } methodInfo &&
- methodInfo.GetParameters() is { } @params &&
- @params.Any(p => p.Name == "doNotUseGeneratedPrefabs"))
+ if (AccessTools2.DeclaredMethod("TaleWorlds.GauntletUI.Data.GauntletMovie:Load") is { } mi && mi.GetParameters() is { } p && p.Any(x => x.Name == "doNotUseGeneratedPrefabs"))
{
harmony.Patch(
- methodInfo,
+ mi,
prefix: new HarmonyMethod(typeof(GauntletMoviePatch), nameof(LoadPrefix)));
}
}
- private static void LoadPrefix(string movieName, ref bool doNotUseGeneratedPrefabs)
+ private static void LoadPrefix(WidgetFactory widgetFactory, string movieName, IViewModel? datasource, ref bool doNotUseGeneratedPrefabs)
{
- var movies = WidgetNames.SelectMany(kv => kv.Value);
- if (movies.Contains(movieName))
+ static IEnumerable GetAllInvolvedAutoGenNames(WidgetFactory widgetFactory, string movieName, IViewModel? datasource)
+ {
+ static IEnumerable GetChildWidgets(Type widgetType)
+ {
+ var children = _widgetChildCache.GetOrAdd(widgetType, static x => x.GetFields(AccessTools.all).Select(x => x.FieldType).Where(x => x.IsSubclassOf(typeof(Widget))).Distinct().ToArray());
+ foreach (var childWidgetType in children.Where(x => x != widgetType))
+ {
+ foreach (var childChildWidgetType in GetChildWidgets(childWidgetType).Where(x => x != widgetType && x != childWidgetType))
+ {
+ yield return childChildWidgetType;
+ }
+ }
+ }
+
+ if (_generatedPrefabs?.Invoke(widgetFactory.GeneratedPrefabContext) is { } generatedPrefabs)
+ {
+ const string create = "Create";
+ var variantName = datasource != null ? datasource.GetType().FullName : "Default";
+ if (generatedPrefabs.TryGetValue(movieName, out var dict2) && dict2.TryGetValue(variantName, out var creator) && AccessTools2.TypeByName(creator.Method.Name.Remove(0, create.Length)) is { } type)
+ {
+ var widgets = new List { type }.Concat(GetChildWidgets(type));
+ var widgetNames = widgets.Select(x => x.Name);
+ var autoGenNames = widgetNames.Where(x => x.Contains("__"));
+ return autoGenNames.Select(x => x.Split(["__"], StringSplitOptions.None)[0]);
+ }
+ }
+ /* This implementation actually created the Widget, but it seems that game didn't intend for that
+ var variantName = datasource == null ? "Default" : datasource.GetType().FullName;
+ var data = datasource == null ? new Dictionary() : new() { {"DataSource", datasource} };
+ if (widgetFactory.GeneratedPrefabContext.InstantiatePrefab(context, movieName, variantName, data) is { } autogenResult)
+ {
+ var autoGen = autogenResult.Root;
+ autoGen.DisableRender = true;
+ autoGen.IsVisible = false;
+ autoGen.UpdateChildrenStates = false;
+ var widgetNames = new HashSet { autoGen.GetType().Name };
+ CheckChildrenAutoGens(ref widgetNames, autoGen);
+ var autoGenNames = widgetNames.Where(x => x.Contains("__")).ToArray();
+ return autoGenNames.Select(x => x.Split(["__"], StringSplitOptions.None)[0]);
+ }
+ */
+
+ return Enumerable.Empty();
+ }
+
+ var moviesPatched = new HashSet(UIExtender.GetAllRuntimes().SelectMany(x => x.PrefabComponent.GetMoviesToPatch()));
+ var moviesInvolved = new HashSet(GetAllInvolvedAutoGenNames(widgetFactory, movieName, datasource));
+ if (moviesInvolved.Overlaps(moviesPatched))
+ doNotUseGeneratedPrefabs = true;
+
+ var moviesBlacklisted = _widgetNames.SelectMany(kv => kv.Value);
+ if (moviesBlacklisted.Contains(movieName))
doNotUseGeneratedPrefabs = true;
}
}
\ No newline at end of file
diff --git a/src/Bannerlord.UIExtenderEx/Patches/UIConfigPatch.cs b/src/Bannerlord.UIExtenderEx/Patches/UIConfigPatch.cs
deleted file mode 100644
index 40ec37ae..00000000
--- a/src/Bannerlord.UIExtenderEx/Patches/UIConfigPatch.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using HarmonyLib;
-using HarmonyLib.BUTR.Extensions;
-
-namespace Bannerlord.UIExtenderEx.Patches;
-
-internal static class UIConfigPatch
-{
- public static void Patch(Harmony harmony)
- {
- harmony.TryPatch(
- AccessTools2.DeclaredPropertySetter("TaleWorlds.Engine.GauntletUI.UIConfig:DoNotUseGeneratedPrefabs"),
- prefix: AccessTools2.DeclaredMethod("Bannerlord.UIExtenderEx.Patches.UIConfigPatch:Prefix"));
- }
-
- // Disable setting a value to DoNotUseGeneratedPrefabs
- private static bool Prefix() => false;
-}
\ No newline at end of file
diff --git a/src/Bannerlord.UIExtenderEx/SubModule.cs b/src/Bannerlord.UIExtenderEx/SubModule.cs
index 9d960c30..8d3f843c 100644
--- a/src/Bannerlord.UIExtenderEx/SubModule.cs
+++ b/src/Bannerlord.UIExtenderEx/SubModule.cs
@@ -1,14 +1,10 @@
using Bannerlord.BUTR.Shared.Helpers;
-using Bannerlord.UIExtenderEx.Utils;
-
using BUTR.MessageBoxPInvoke.Helpers;
using System;
using System.Linq;
-using System.Reflection;
using System.Text;
-using TaleWorlds.Engine.GauntletUI;
using TaleWorlds.Localization;
using TaleWorlds.MountAndBlade;
@@ -16,22 +12,6 @@ namespace Bannerlord.UIExtenderEx;
public class SubModule : MBSubModuleBase
{
- static SubModule()
- {
- // Disable AutoGens as early as possible
- try
- {
- // Force load TaleWorlds.Engine.GauntletUI as it might not be loaded yet!
- Assembly.Load("TaleWorlds.Engine.GauntletUI");
- }
- catch (Exception e)
- {
- MessageUtils.Fail($"Failed to load 'TaleWorlds.Engine.GauntletUI'! Exception: {e}");
- }
-
- UIConfig.DoNotUseGeneratedPrefabs = true;
- }
-
// We can't rely on EN since the game assumes that the default locale is always English
private const string SWarningTitle =
@"{=eySpdc25EE}Warning from Bannerlord.UIExtenderEx!";
diff --git a/src/Bannerlord.UIExtenderEx/UIExtender.cs b/src/Bannerlord.UIExtenderEx/UIExtender.cs
index 958d621b..01724e73 100644
--- a/src/Bannerlord.UIExtenderEx/UIExtender.cs
+++ b/src/Bannerlord.UIExtenderEx/UIExtender.cs
@@ -19,7 +19,7 @@ namespace Bannerlord.UIExtenderEx;
public class UIExtender
{
public static UIExtender Create(string moduleName) => new(moduleName, false);
- public static UIExtender GetUIExtenderFor(string moduleName) => Instances[moduleName];
+ public static UIExtender? GetUIExtenderFor(string moduleName) => Instances.TryGetValue(moduleName, out var uiExtender) ? uiExtender : null;
internal static UIExtenderRuntime? GetRuntimeFor(string moduleName) => Instances[moduleName]._runtime;
internal static IReadOnlyList GetAllRuntimes() => Instances.Select(x => x.Value._runtime).OfType().ToList();
@@ -29,10 +29,8 @@ public class UIExtender
static UIExtender()
{
- // AutoGens are globally disabled for now. When the game will be released on Linux/OSX we'll reuse this property again.
- //GauntletMoviePatch.Patch(Harmony);
+ GauntletMoviePatch.Patch(Harmony);
ViewModelPatch.Patch(Harmony);
- UIConfigPatch.Patch(Harmony);
WidgetPrefabPatch.Patch(Harmony);
BrushFactoryManager.Patch(Harmony);
WidgetFactoryManager.Patch(Harmony);
diff --git a/tests/Bannerlord.UIExtenderEx.Tests/Prefabs/IntegrationTests/PrefabsTests.cs b/tests/Bannerlord.UIExtenderEx.Tests/Prefabs/IntegrationTests/PrefabsTests.cs
index 62e7b48d..119ac6af 100644
--- a/tests/Bannerlord.UIExtenderEx.Tests/Prefabs/IntegrationTests/PrefabsTests.cs
+++ b/tests/Bannerlord.UIExtenderEx.Tests/Prefabs/IntegrationTests/PrefabsTests.cs
@@ -34,7 +34,7 @@ public void Finalization()
{
_uiExtender?.Deregister();
}
-
+
[Test]
public void PrefabsInsertTest()
{
diff --git a/tests/Bannerlord.UIExtenderEx.Tests/Prefabs2/UnitTests/PrefabComponentPrefabs2Tests.cs b/tests/Bannerlord.UIExtenderEx.Tests/Prefabs2/UnitTests/PrefabComponentPrefabs2Tests.cs
index e83dfefd..51b1090e 100644
--- a/tests/Bannerlord.UIExtenderEx.Tests/Prefabs2/UnitTests/PrefabComponentPrefabs2Tests.cs
+++ b/tests/Bannerlord.UIExtenderEx.Tests/Prefabs2/UnitTests/PrefabComponentPrefabs2Tests.cs
@@ -68,7 +68,7 @@ public void RegisterPatch_XmlDocument_InsertAsFirstChild()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.FirstChild, $"First child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -96,7 +96,7 @@ public void RegisterPatch_XmlNode_InsertAsMiddleChild()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.ChildNodes[2], $"Third child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -124,7 +124,7 @@ public void RegisterPatch_XmlNode_PassXmlDocumentAsXmlNode()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.ChildNodes[2], $"Third child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -150,7 +150,7 @@ public void RegisterPatch_Text_InsertAsLastChild()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.ChildNodes[validRootNode.ParentNode.ChildNodes.Count - 1], $"Last child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -177,7 +177,7 @@ public void RegisterPatch_Text_ReplaceRemoveRootNode()
Assert.AreEqual(4, someChild1Node!.ParentNode!.ChildNodes.Count);
Assert.AreEqual("SomeChild1", someChild1Node!.ParentNode!.ChildNodes[0].Name);
Assert.AreEqual("SomeChild2", someChild1Node!.ParentNode!.ChildNodes[1].Name);
-
+
prefabComponent.Deregister();
}
@@ -203,7 +203,7 @@ public void RegisterPatch_FileName_InsertAsLastChild()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.ChildNodes[validRootNode.ParentNode.ChildNodes.Count - 1], $"Last child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -230,7 +230,7 @@ public void RegisterPatch_FileName_ReplaceRemoveRootNode()
Assert.AreEqual(4, someChild1Node!.ParentNode!.ChildNodes.Count);
Assert.AreEqual("SomeChild1", someChild1Node!.ParentNode!.ChildNodes[0].Name);
Assert.AreEqual("SomeChild2", someChild1Node!.ParentNode!.ChildNodes[1].Name);
-
+
prefabComponent.Deregister();
}
@@ -260,7 +260,7 @@ public void RegisterPatch_XmlNodes_InsertMultipleChildren()
Assert.AreEqual("Child1", child1Node.ParentNode.ChildNodes[0].Name, $"First child should be Child1. Was {child1Node.ParentNode.FirstChild.Name}");
Assert.AreEqual("Child2", child1Node.ParentNode.ChildNodes[1].Name, $"Second child should be Child2. Was {child1Node.ParentNode.FirstChild.Name}");
Assert.AreEqual("Child3", child1Node.ParentNode.ChildNodes[2].Name, $"Third child should be Child3. Was {child1Node.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -294,7 +294,7 @@ public void RegisterPatch_XmlNodes_PassXmlDocumentsAsXmlNodes()
Assert.AreEqual("Child1", child1Node.ParentNode.ChildNodes[0].Name, $"First child should be Child1. Was {child1Node.ParentNode.FirstChild.Name}");
Assert.AreEqual("Child2", child1Node.ParentNode.ChildNodes[1].Name, $"Second child should be Child2. Was {child1Node.ParentNode.FirstChild.Name}");
Assert.AreEqual("Child3", child1Node.ParentNode.ChildNodes[2].Name, $"Third child should be Child3. Was {child1Node.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -325,7 +325,7 @@ public void RegisterPatch_RemoveComments_ChildComments()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.FirstChild, $"First child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -356,7 +356,7 @@ public void RegisterPatch_RemoveComments_RootComment()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.FirstChild, $"First child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -387,7 +387,7 @@ public void RegisterPatch_RemoveComments_FirstNodeRootComment()
Assert.AreEqual("Children", validRootNode!.ParentNode!.Name);
Assert.AreEqual("SomeChild", validRootNode.FirstChild.Name);
Assert.AreEqual(validRootNode, validRootNode.ParentNode.FirstChild, $"First child should be ValidRoot. Was {validRootNode.ParentNode.FirstChild.Name}");
-
+
prefabComponent.Deregister();
}
@@ -410,7 +410,7 @@ public void RegisterPatch_Remove()
// Assert
var removedNode = movieDocument.SelectSingleNode("descendant::OptionsScreenWidget[@Id='Options']");
Assert.IsNull(removedNode);
-
+
prefabComponent.Deregister();
}
}
\ No newline at end of file
diff --git a/tests/Bannerlord.UIExtenderEx.Tests/SharedTests.cs b/tests/Bannerlord.UIExtenderEx.Tests/SharedTests.cs
index 751da2d2..c2c6c631 100644
--- a/tests/Bannerlord.UIExtenderEx.Tests/SharedTests.cs
+++ b/tests/Bannerlord.UIExtenderEx.Tests/SharedTests.cs
@@ -1,4 +1,4 @@
-using Bannerlord.UIExtenderEx.Tests.Prefabs2;
+using Bannerlord.UIExtenderEx.Tests.Prefabs2;
using HarmonyLib;
using HarmonyLib.BUTR.Extensions;
@@ -21,26 +21,26 @@ private static bool MockedGetBasePathPath(ref string __result)
__result = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets");
return false;
}
-
+
private Harmony _harmony;
-
+
[OneTimeSetUp]
public void SharedOneTimeSetUp()
{
Trace.Listeners.Add(new ConsoleTraceListener());
-
+
_harmony = new Harmony($"{nameof(PrefabComponentPrefabs2Tests)}");
_harmony.Patch(SymbolExtensions2.GetMethodInfo(() => TaleWorlds.Engine.Utilities.GetBasePath()),
prefix: new HarmonyMethod(typeof(PrefabComponentPrefabs2Tests), nameof(MockedGetBasePathPath)));
_harmony.Patch(SymbolExtensions2.GetPropertyGetter(() => TaleWorlds.Library.BasePath.Name),
prefix: new HarmonyMethod(typeof(PrefabComponentPrefabs2Tests), nameof(MockedGetBasePathPath)));
}
-
+
[OneTimeTearDown]
public void SharedOneTimeTearDown()
{
Trace.Flush();
-
+
foreach (var patchedMethod in _harmony.GetPatchedMethods())
{
if (patchedMethod is not MethodInfo patchedMethodInfo)