using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Sparroh.UI;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2")]
[assembly: AssemblyProduct("UpgradeFiltering")]
[assembly: AssemblyTitle("UpgradeFiltering")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
public static class ConfigManager
{
private const float DebounceSeconds = 0.25f;
private static ConfigFile config;
private static ManualLogSource logger;
private static FileSystemWatcher configWatcher;
private static volatile bool reloadPending;
private static float lastReloadTime;
public static ConfigEntry<bool> EnableStatReformat { get; private set; }
public static void Initialize(ConfigFile configFile, ManualLogSource log)
{
config = configFile;
logger = log;
EnableStatReformat = config.Bind<bool>("General", "Enable Reformat", false, "Force Key: Value stat format");
StatFormatHandling.enableStatReformat = EnableStatReformat.Value;
EnableStatReformat.SettingChanged += OnStatReformatChanged;
try
{
SetupFileWatcher();
}
catch (Exception ex)
{
logger.LogError((object)("Error setting up config file watcher: " + ex.Message));
}
}
public static void Tick()
{
if (!reloadPending || Time.unscaledTime - lastReloadTime < 0.25f)
{
return;
}
reloadPending = false;
lastReloadTime = Time.unscaledTime;
try
{
config.Reload();
StatFormatHandling.enableStatReformat = EnableStatReformat.Value;
logger.LogInfo((object)"Config reloaded from disk.");
}
catch (Exception ex)
{
logger.LogError((object)("Error reloading config: " + ex.Message));
}
}
public static void Dispose()
{
if (EnableStatReformat != null)
{
EnableStatReformat.SettingChanged -= OnStatReformatChanged;
}
if (configWatcher != null)
{
configWatcher.EnableRaisingEvents = false;
configWatcher.Changed -= OnConfigFileChanged;
configWatcher.Created -= OnConfigFileChanged;
configWatcher.Renamed -= OnConfigFileChanged;
configWatcher.Dispose();
configWatcher = null;
}
}
private static void SetupFileWatcher()
{
configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.upgradefiltering.cfg");
configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
configWatcher.Changed += OnConfigFileChanged;
configWatcher.Created += OnConfigFileChanged;
configWatcher.Renamed += OnConfigFileChanged;
configWatcher.EnableRaisingEvents = true;
}
private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
{
reloadPending = true;
}
private static void OnStatReformatChanged(object sender, EventArgs e)
{
StatFormatHandling.enableStatReformat = EnableStatReformat.Value;
}
}
public class FilterPanelUI
{
private readonly Dictionary<Rarity, UIButton> _rarityButtons = new Dictionary<Rarity, UIButton>();
private UIButton _favHide;
private UIButton _favOnly;
private UIButton _favShowAll;
private UIScrollView _statScroll;
private UIWindow _window;
private bool isInitialized;
public bool IsExpanded { get; private set; }
public void Toggle()
{
if (!isInitialized)
{
CreateFilterPanel();
if (!isInitialized)
{
return;
}
}
IsExpanded = !IsExpanded;
if (IsExpanded)
{
RegenerateStatFilters();
_window.Show();
}
else
{
_window.Hide(false);
}
}
public void RegenerateStatFilters()
{
try
{
if (isInitialized && _statScroll != null)
{
FilterState.CurrentFilters.StatIncludeList.Clear();
FilterState.CurrentFilters.FilterStats = false;
RebuildStatToggles();
}
}
catch
{
}
}
public void RebuildFilterPanel()
{
try
{
bool isExpanded = IsExpanded;
if (_window != null)
{
_window.Destroy();
_window = null;
}
_rarityButtons.Clear();
isInitialized = false;
IsExpanded = false;
CreateFilterPanel();
if (isExpanded && isInitialized)
{
IsExpanded = true;
_window.Show();
}
}
catch
{
}
}
private void CreateFilterPanel()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
if (isInitialized)
{
return;
}
try
{
UITheme.Initialize();
_window = UIWindow.Create("UpgradeFilter", (Vector2?)new Vector2(280f, 480f), "Upgrade Filters", true, true, (int?)(UITheme.WindowSortingOrder + 7));
_window.OnClose((Action)delegate
{
IsExpanded = false;
});
Transform content = _window.Content;
UIFactory.AddVerticalLayout(((Component)content).gameObject, UITheme.S(6f), UITheme.ScaledPadding(6, 6, 6, 6), (TextAnchor)0, true, false, true, true);
UIButton.Create(content, "Clear All Filters", (Action)ClearAllFilters, (UIButtonStyle)2, (string)null, (float?)UITheme.S(28f));
UIText.Create(content, "RarityLbl", "Hide Rarities", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)513, false);
(string, Rarity)[] array = new(string, Rarity)[5]
{
("Standard", (Rarity)0),
("Rare", (Rarity)1),
("Epic", (Rarity)2),
("Exotic", (Rarity)3),
("Oddity", (Rarity)4)
};
for (int num = 0; num < array.Length; num++)
{
(string, Rarity) tuple = array[num];
Rarity rarity = tuple.Item2;
bool flag = FilterState.CurrentFilters.HiddenRarities.Contains(rarity);
UIButton value = UIButton.Create(content, tuple.Item1, (Action)delegate
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
if (FilterState.CurrentFilters.HiddenRarities.Contains(rarity))
{
FilterState.CurrentFilters.HiddenRarities.Remove(rarity);
_rarityButtons[rarity].SetStyle((UIButtonStyle)0);
UpgradeFilteringPlugin.Logger.LogInfo((object)$"Filter: show rarity {rarity}");
}
else
{
FilterState.CurrentFilters.HiddenRarities.Add(rarity);
_rarityButtons[rarity].SetStyle((UIButtonStyle)2);
UpgradeFilteringPlugin.Logger.LogInfo((object)$"Filter: hide rarity {rarity}");
}
UpgradeFilteringPlugin.Logger.LogInfo((object)("Filter: HiddenRarities=[" + string.Join(",", FilterState.CurrentFilters.HiddenRarities) + "]"));
RefreshUpgrades();
}, (UIButtonStyle)(flag ? 2 : 0), (string)null, (float?)UITheme.S(24f));
_rarityButtons[rarity] = value;
}
UIText.Create(content, "FavLbl", "Favorites", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)513, false);
_favShowAll = UIButton.Create(content, "Show All", (Action)delegate
{
FilterState.CurrentFilters.FavoriteSetting = FavoriteFilter.ShowAll;
UpdateFavoriteHighlights();
RefreshUpgrades();
}, (UIButtonStyle)3, (string)null, (float?)UITheme.S(24f));
_favOnly = UIButton.Create(content, "Only Favorite", (Action)delegate
{
FilterState.CurrentFilters.FavoriteSetting = FavoriteFilter.ShowOnlyFavorited;
UpdateFavoriteHighlights();
RefreshUpgrades();
}, (UIButtonStyle)0, (string)null, (float?)UITheme.S(24f));
_favHide = UIButton.Create(content, "Hide Favorite", (Action)delegate
{
FilterState.CurrentFilters.FavoriteSetting = FavoriteFilter.HideFavorited;
UpdateFavoriteHighlights();
RefreshUpgrades();
}, (UIButtonStyle)0, (string)null, (float?)UITheme.S(24f));
UIText.Create(content, "StatLbl", "Show Only With", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)513, false);
_statScroll = UIScrollView.Create(content, "StatScroll", true, false);
GameObject gameObject = _statScroll.GameObject;
float? num2 = UITheme.S(160f);
float? num3 = UITheme.S(120f);
UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num2, num3);
RebuildStatToggles();
_window.Hide(false);
isInitialized = true;
IsExpanded = false;
}
catch (Exception)
{
isInitialized = false;
}
}
private void UpdateFavoriteHighlights()
{
FavoriteFilter favoriteSetting = FilterState.CurrentFilters.FavoriteSetting;
if (_favShowAll != null)
{
_favShowAll.SetStyle((UIButtonStyle)((favoriteSetting == FavoriteFilter.ShowAll) ? 3 : 0));
}
if (_favOnly != null)
{
_favOnly.SetStyle((UIButtonStyle)((favoriteSetting == FavoriteFilter.ShowOnlyFavorited) ? 3 : 0));
}
if (_favHide != null)
{
_favHide.SetStyle((UIButtonStyle)((favoriteSetting == FavoriteFilter.HideFavorited) ? 3 : 0));
}
}
private void ClearAllFilters()
{
FilterState.CurrentFilters.HiddenRarities.Clear();
FilterState.CurrentFilters.FavoriteSetting = FavoriteFilter.ShowAll;
FilterState.CurrentFilters.FilterStats = false;
FilterState.CurrentFilters.StatIncludeList.Clear();
foreach (KeyValuePair<Rarity, UIButton> rarityButton in _rarityButtons)
{
rarityButton.Value.SetStyle((UIButtonStyle)0);
}
UpdateFavoriteHighlights();
RebuildStatToggles();
RefreshUpgrades();
}
private void RebuildStatToggles()
{
if (_statScroll == null)
{
return;
}
UIHelpers.DestroyChildren((Transform)(object)_statScroll.Content);
foreach (string item in from p in GetContextAwareProperties()
orderby p
select p)
{
string text = item.Replace("_", " ");
string prop = item;
GameObject gameObject = UIToggle.Create((Transform)(object)_statScroll.Content, text, false, (Action<bool>)delegate(bool value)
{
if (value)
{
FilterState.CurrentFilters.FilterStats = true;
if (!FilterState.CurrentFilters.StatIncludeList.Contains(prop))
{
FilterState.CurrentFilters.StatIncludeList.Add(prop);
}
}
else
{
FilterState.CurrentFilters.StatIncludeList.Remove(prop);
if (FilterState.CurrentFilters.StatIncludeList.Count == 0)
{
FilterState.CurrentFilters.FilterStats = false;
}
}
RefreshUpgrades();
}, (string)null).GameObject;
float? num = UITheme.S(22f);
UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, (float?)null);
}
}
private List<string> GetContextAwareProperties()
{
try
{
GearDetailsWindow openWindow = FilterState.GetOpenWindow();
bool flag = false;
if ((Object)(object)openWindow != (Object)null)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
if (fieldInfo != null)
{
try
{
flag = (bool)fieldInfo.GetValue(openWindow);
}
catch
{
}
}
}
return flag ? DiscoverSkinProperties() : GetCuratedUpgradeProperties();
}
catch
{
return GetCuratedUpgradeProperties();
}
}
private static List<string> GetCuratedUpgradeProperties()
{
return new List<string>
{
"AmmoCapacity", "AutomaticFire", "BatteryCapacity", "BulletsPerShot", "BurstFire", "Carver_Blood", "Charge", "Damage", "FireInterval", "Globbler_Globblometer",
"Health", "HealthRegenDelay", "HitForce", "MagazineSize", "MaxBounces", "MeleeDamage", "Range", "Recoil", "Reload", "Speed"
};
}
private static List<string> DiscoverSkinProperties()
{
List<string> list = new List<string>();
try
{
Type skinUpgradePropertyType = typeof(GearUpgradeUI).Assembly.GetType("SkinUpgradeProperty");
if (skinUpgradePropertyType == null)
{
return list;
}
foreach (Type item in (from t in skinUpgradePropertyType.Assembly.GetTypes()
where t.IsClass && !t.IsAbstract && skinUpgradePropertyType.IsAssignableFrom(t) && t.FullName != null && t.FullName.StartsWith("SkinUpgradeProperty_")
select t).ToList())
{
string text = item.Name;
if (text.StartsWith("SkinUpgradeProperty_"))
{
text = text.Substring("SkinUpgradeProperty_".Length);
}
list.Add(text);
}
return (from p in list.Distinct()
orderby p
select p).ToList();
}
catch
{
return list;
}
}
private void RefreshUpgrades()
{
GearDetailsWindow val = PriorityPatches.ResolveWindow() ?? FilterState.GetOpenWindow();
if ((Object)(object)val == (Object)null)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"Filter refresh: no GearDetailsWindow.");
return;
}
UpgradeFilteringPlugin.Logger.LogInfo((object)$"Filter refresh: window={((Object)val).name}, priorityActive={PriorityPatches.PrioritySortActive}");
try
{
FilterState.ApplyToWindow(val);
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogError((object)("Filter refresh failed: " + ex.Message + "\n" + ex.StackTrace));
}
}
}
[HarmonyPatch(typeof(GearDetailsWindow))]
public static class GearDetailsWindowPatches
{
[HarmonyPostfix]
[HarmonyPatch("OnOpen")]
private static void OnOpen(GearDetailsWindow __instance)
{
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
if (fieldInfo != null)
{
bool flag = (bool)fieldInfo.GetValue(__instance);
if (FilterState.PreviousSkinMode.HasValue && FilterState.PreviousSkinMode.Value != flag && FilterState.FilterPanel != null)
{
FilterState.FilterPanel.RegenerateStatFilters();
}
FilterState.PreviousSkinMode = flag;
}
}
catch
{
}
if (FilterState.FilterPanel == null)
{
FilterState.FilterPanel = new FilterPanelUI();
}
}
[HarmonyPrefix]
[HarmonyPatch("SwitchUpgradeView")]
private static void SwitchUpgradeView_Prefix()
{
ListRebuildReapply.BeginViewSwitch();
}
[HarmonyPostfix]
[HarmonyPatch("SwitchUpgradeView")]
private static void SwitchUpgradeView_Postfix(GearDetailsWindow __instance)
{
try
{
ListRebuildReapply.After(__instance, "SwitchUpgradeView");
}
finally
{
ListRebuildReapply.EndViewSwitch();
}
}
}
[HarmonyPatch(typeof(GearDetailsWindow), "SetupUpgrades", new Type[]
{
typeof(IUpgradable),
typeof(bool),
typeof(bool)
})]
public static class SetupUpgradesPatch
{
[HarmonyPostfix]
public static void Postfix(GearDetailsWindow __instance, bool skins)
{
if (!ListRebuildReapply.SuppressNestedReapply)
{
ListRebuildReapply.After(__instance, $"SetupUpgrades(skins={skins})");
}
}
}
[HarmonyPatch(typeof(GearDetailsWindow), "SortUpgrades", new Type[]
{
typeof(SortingMethod),
typeof(bool)
})]
public static class SortUpgradesMethodPatch
{
private static bool? lastSkinMode;
[HarmonyPostfix]
public static void Postfix(GearDetailsWindow __instance, SortingMethod method, bool resetScroll)
{
if (ListRebuildReapply.SuppressNestedReapply || PriorityPatches.PrioritySortActive)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
bool flag = false;
if (fieldInfo != null)
{
try
{
flag = (bool)fieldInfo.GetValue(__instance);
}
catch
{
}
}
bool num = lastSkinMode.HasValue && lastSkinMode.Value != flag;
lastSkinMode = flag;
if (num)
{
return;
}
try
{
FilterState.ApplyToWindow(__instance);
}
catch
{
}
}
}
internal static class ListRebuildReapply
{
public static bool SuppressNestedReapply { get; private set; }
public static void After(GearDetailsWindow window, string reason)
{
if ((Object)(object)window == (Object)null)
{
return;
}
try
{
PriorityPatches.currentWindow = window;
PriorityPatches.CancelDeferredLayout();
List<GearUpgradeUI> upgradeUIs = FilterState.GetUpgradeUIs();
int num = FilterState.GetUpgradeUICount(window);
if (upgradeUIs == null)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("List rebuild (" + reason + "): upgradeUIs null"));
return;
}
if (num <= 0 || num > upgradeUIs.Count)
{
num = upgradeUIs.Count;
}
PriorityPatches.ClearStalePoolSlots(upgradeUIs, num);
if (!PriorityPatches.LogUniqueInstanceIds("BEFORE repair (" + reason + ")", upgradeUIs, num) && !PriorityPatches.TryRepairDuplicateUiRefs(window, upgradeUIs, num))
{
UpgradeFilteringPlugin.Logger.LogError((object)("List rebuild (" + reason + "): pool repair failed — reopen gear window."));
return;
}
PriorityPatches.ActivateAllLiveSlots(upgradeUIs, num);
if (PriorityPatches.PrioritySortActive)
{
PriorityPatches.ApplyPrioritySort(window, resetScroll: false, skipDeferred: true);
UpgradeFilteringPlugin.Logger.LogInfo((object)$"List rebuild re-apply ({reason}): visual priority + filters, isGrid={PriorityPatches.GetIsGridView(window)}");
}
else if (FilterState.HasActiveFilters())
{
FilterState.ApplyToWindow(window);
UpgradeFilteringPlugin.Logger.LogInfo((object)$"List rebuild re-apply ({reason}): filters only, isGrid={PriorityPatches.GetIsGridView(window)}");
}
else
{
PriorityPatches.ForceLayoutVisibleOnly(window, upgradeUIs, num);
UpgradeFilteringPlugin.Logger.LogInfo((object)$"List rebuild re-apply ({reason}): layout only, isGrid={PriorityPatches.GetIsGridView(window)}");
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogError((object)("List rebuild re-apply failed (" + reason + "): " + ex.Message + "\n" + ex.StackTrace));
}
}
public static void BeginViewSwitch()
{
SuppressNestedReapply = true;
PriorityPatches.CancelDeferredLayout();
}
public static void EndViewSwitch()
{
SuppressNestedReapply = false;
}
}
public enum FavoriteFilter
{
ShowAll,
ShowOnlyFavorited,
HideFavorited
}
public struct FilterSettings
{
public List<Rarity> HiddenRarities;
public bool FilterStats;
public List<string> StatIncludeList;
public FavoriteFilter FavoriteSetting;
}
public static class FilterState
{
internal static FilterPanelUI FilterPanel;
internal static readonly Dictionary<Rarity, int> RarityOrder = new Dictionary<Rarity, int>
{
{
(Rarity)4,
5
},
{
(Rarity)3,
4
},
{
(Rarity)2,
3
},
{
(Rarity)1,
2
},
{
(Rarity)0,
1
},
{
(Rarity)(-1),
0
}
};
internal static FilterSettings CurrentFilters = new FilterSettings
{
HiddenRarities = new List<Rarity>(),
FilterStats = false,
StatIncludeList = new List<string>(),
FavoriteSetting = FavoriteFilter.ShowAll
};
internal static bool? PreviousSkinMode;
private static FieldInfo _upgradeUIsField;
private static FieldInfo _upgradeUICountField;
public static bool HasActiveFilters()
{
if (!CurrentFilters.HiddenRarities.Any() && CurrentFilters.FavoriteSetting == FavoriteFilter.ShowAll)
{
if (CurrentFilters.FilterStats)
{
return CurrentFilters.StatIncludeList.Any();
}
return false;
}
return true;
}
public static void ApplyVisibilityOnly(GearDetailsWindow window)
{
if ((Object)(object)window == (Object)null)
{
return;
}
List<GearUpgradeUI> upgradeUIs = GetUpgradeUIs();
if (upgradeUIs == null || upgradeUIs.Count == 0)
{
return;
}
int num = GetUpgradeUICount(window);
if (num <= 0)
{
num = upgradeUIs.Count;
}
num = Mathf.Min(num, upgradeUIs.Count);
bool isGridView = PriorityPatches.GetIsGridView(window);
int num2 = 0;
int num3 = 0;
int num4 = 0;
for (int i = 0; i < num; i++)
{
GearUpgradeUI val = upgradeUIs[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
UpgradeInstance upgrade = ((HoverInfoUpgrade)val).Upgrade;
if ((Object)(object)((upgrade != null) ? upgrade.Upgrade : null) == (Object)null)
{
if (((Component)val).gameObject.activeSelf)
{
((Component)val).gameObject.SetActive(false);
}
num3++;
}
else if (ShouldShow(val))
{
if (!((Component)val).gameObject.activeSelf)
{
((Component)val).gameObject.SetActive(true);
try
{
val.SetUpgrade(((HoverInfoUpgrade)val).Upgrade, false);
}
catch
{
}
num4++;
}
try
{
val.EnableGridView(isGridView);
}
catch
{
}
num2++;
}
else
{
if (((Component)val).gameObject.activeSelf)
{
((Component)val).gameObject.SetActive(false);
}
num3++;
}
}
UpgradeFilteringPlugin.Logger.LogInfo((object)($"Filter visibility: count={num}, visible={num2}, hidden={num3}, " + $"reenabled={num4}, fav={CurrentFilters.FavoriteSetting}"));
}
public static void ApplyToWindow(GearDetailsWindow window)
{
if ((Object)(object)window == (Object)null)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"ApplyToWindow: window null");
return;
}
List<GearUpgradeUI> upgradeUIs = GetUpgradeUIs();
if (upgradeUIs == null || upgradeUIs.Count == 0)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"ApplyToWindow: upgradeUIs empty");
return;
}
int num = GetUpgradeUICount(window);
if (num <= 0)
{
num = upgradeUIs.Count;
}
num = Mathf.Min(num, upgradeUIs.Count);
string arg = ((CurrentFilters.HiddenRarities != null && CurrentFilters.HiddenRarities.Count > 0) ? string.Join(",", CurrentFilters.HiddenRarities) : "(none)");
UpgradeFilteringPlugin.Logger.LogInfo((object)($"Filter apply: count={num}, hiddenRarities=[{arg}], " + $"fav={CurrentFilters.FavoriteSetting}, stats={CurrentFilters.FilterStats}/" + $"{CurrentFilters.StatIncludeList?.Count ?? 0}"));
ApplyVisibilityOnly(window);
if (PriorityPatches.PrioritySortActive)
{
List<PriorityCriteria> order = PriorityPatches.FilterOrderForAvailableMods(PriorityPatches.LoadPriorityOrder());
PriorityPatches.ApplyVisualPriorityOrder(window, upgradeUIs, num, order);
}
else
{
PriorityPatches.ForceLayoutVisibleOnly(window, upgradeUIs, num);
}
try
{
typeof(GearDetailsWindow).GetMethod("SetUpgradeListScroll", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null)?.Invoke(window, new object[1] { 1f });
}
catch
{
}
}
internal static List<GearUpgradeUI> GetUpgradeUIs()
{
try
{
if (_upgradeUIsField == null)
{
_upgradeUIsField = typeof(GearDetailsWindow).GetField("upgradeUIs", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_upgradeUIsField == null)
{
return null;
}
return _upgradeUIsField.GetValue(null) as List<GearUpgradeUI>;
}
catch
{
return null;
}
}
internal static int GetUpgradeUICount(GearDetailsWindow window)
{
if ((Object)(object)window == (Object)null)
{
return 0;
}
try
{
if (_upgradeUICountField == null)
{
_upgradeUICountField = typeof(GearDetailsWindow).GetField("upgradeUICount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_upgradeUICountField == null)
{
return 0;
}
return (int)_upgradeUICountField.GetValue(window);
}
catch
{
return 0;
}
}
internal static GearDetailsWindow GetOpenWindow()
{
try
{
Menu instance = Menu.Instance;
if ((Object)(object)((instance != null) ? instance.WindowSystem : null) != (Object)null)
{
Window top = Menu.Instance.WindowSystem.GetTop();
GearDetailsWindow val = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
}
catch
{
}
if ((Object)(object)PriorityPatches.currentWindow != (Object)null)
{
try
{
if ((Object)(object)((Component)PriorityPatches.currentWindow).gameObject != (Object)null)
{
return PriorityPatches.currentWindow;
}
}
catch
{
}
}
try
{
return Object.FindObjectOfType<GearDetailsWindow>();
}
catch
{
return null;
}
}
public static bool ShouldShow(GearUpgradeUI ui)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
object obj;
if (ui == null)
{
obj = null;
}
else
{
UpgradeInstance upgrade = ((HoverInfoUpgrade)ui).Upgrade;
obj = ((upgrade != null) ? upgrade.Upgrade : null);
}
if ((Object)obj == (Object)null)
{
return false;
}
bool flag = true;
if (CurrentFilters.HiddenRarities != null && CurrentFilters.HiddenRarities.Count > 0)
{
flag &= !CurrentFilters.HiddenRarities.Contains(((HoverInfoUpgrade)ui).Upgrade.Upgrade.Rarity);
}
switch (CurrentFilters.FavoriteSetting)
{
case FavoriteFilter.ShowOnlyFavorited:
flag &= ((HoverInfoUpgrade)ui).Upgrade.Favorite;
break;
case FavoriteFilter.HideFavorited:
flag &= !((HoverInfoUpgrade)ui).Upgrade.Favorite;
break;
}
if (CurrentFilters.FilterStats && CurrentFilters.StatIncludeList != null && CurrentFilters.StatIncludeList.Count > 0)
{
foreach (string statInclude in CurrentFilters.StatIncludeList)
{
bool flag2 = false;
Enumerator properties = ((HoverInfoUpgrade)ui).Upgrade.Upgrade.GetProperties();
while (((Enumerator)(ref properties)).MoveNext())
{
UpgradeProperty current2 = ((Enumerator)(ref properties)).Current;
if (current2 != null)
{
string text = ((object)current2).GetType().Name;
if (text.StartsWith("UpgradeProperty_"))
{
text = text.Substring("UpgradeProperty_".Length);
}
else if (text.StartsWith("SkinUpgradeProperty_"))
{
text = text.Substring("SkinUpgradeProperty_".Length);
}
if (text == statInclude)
{
flag2 = true;
break;
}
}
}
if (!flag2)
{
return false;
}
}
}
return flag;
}
}
[BepInPlugin("sparroh.upgradefiltering", "UpgradeFiltering", "1.1.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class UpgradeFilteringPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.upgradefiltering";
public const string PluginName = "UpgradeFiltering";
public const string PluginVersion = "1.1.2";
internal static ManualLogSource Logger;
public static UpgradeFilteringPlugin Instance;
private bool _barRegistered;
private void Awake()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
try
{
Logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
Harmony val = new Harmony("sparroh.upgradefiltering");
try
{
ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Logger);
}
catch (Exception ex)
{
Logger.LogError((object)("Failed to setup configuration bindings: " + ex.Message));
}
try
{
StatFormatHandling.Initialize();
}
catch (Exception ex2)
{
Logger.LogError((object)("Failed to initialize StatFormatHandling: " + ex2.Message));
}
try
{
PriorityGUI.EnsureExists();
}
catch (Exception ex3)
{
Logger.LogError((object)("Failed to initialize PriorityGUI: " + ex3.Message));
}
try
{
PriorityPatches.Patch(val);
}
catch (Exception ex4)
{
Logger.LogError((object)("Failed to apply PriorityPatches: " + ex4.Message));
}
Type[] array = new Type[4]
{
typeof(GearDetailsWindowPatches),
typeof(SetupUpgradesPatch),
typeof(SortUpgradesMethodPatch),
typeof(PriorityPatches)
};
foreach (Type type in array)
{
try
{
val.PatchAll(type);
}
catch (Exception ex5)
{
Logger.LogError((object)("Failed to patch " + type.Name + ": " + ex5.Message));
}
}
try
{
array = typeof(UpgradeFilteringPlugin).Assembly.GetTypes();
foreach (Type type2 in array)
{
if (type2 == typeof(GearDetailsWindowPatches) || type2 == typeof(SetupUpgradesPatch) || type2 == typeof(SortUpgradesMethodPatch) || type2 == typeof(PriorityPatches) || type2 == typeof(ListRebuildReapply) || !type2.IsClass)
{
continue;
}
object[] customAttributes = type2.GetCustomAttributes(typeof(HarmonyPatch), inherit: true);
if (customAttributes != null && customAttributes.Length != 0)
{
try
{
val.PatchAll(type2);
}
catch (Exception ex6)
{
Logger.LogError((object)("Failed to patch " + type2.Name + ": " + ex6.Message));
}
}
}
}
catch (Exception ex7)
{
Logger.LogError((object)("Failed scanning assembly patches: " + ex7.Message));
}
}
catch (Exception ex8)
{
Logger.LogError((object)("Critical error during mod initialization: " + ex8.Message + "\n" + ex8.StackTrace));
}
Logger.LogInfo((object)"UpgradeFiltering loaded successfully.");
}
private void Update()
{
ConfigManager.Tick();
GearActionBar.Tick();
if (GearActionBar.IsGearMenuOpen() && !_barRegistered)
{
GearActionBar.Register("filter", "Filter", 100, (Action)delegate
{
FilterState.FilterPanel?.Toggle();
}, (UIButtonStyle)0);
GearActionBar.Register("priority", "Upgr. Sort", 110, (Action)PriorityGUI.ToggleWindowStatic, (UIButtonStyle)1);
_barRegistered = true;
}
}
private void OnDestroy()
{
ConfigManager.Dispose();
GearActionBar.Unregister("filter");
GearActionBar.Unregister("priority");
_barRegistered = false;
}
}
[Serializable]
public class PriorityData
{
public List<int> order;
public PriorityData()
{
order = new List<int>
{
0, 1, 2, 3, 7, 8, 9, 10, 11, 12,
14, 4, 5, 6
};
}
public string ToJson()
{
return JsonUtility.ToJson((object)this);
}
public static PriorityData FromJson(string json)
{
if (string.IsNullOrEmpty(json))
{
return new PriorityData();
}
return JsonUtility.FromJson<PriorityData>(json);
}
}
public enum PriorityCriteria
{
Favorited,
NotFavorited,
Unlocked,
Locked,
RecentlyUsed,
RecentlyAcquired,
InstanceName,
Oddity,
Exotic,
Epic,
Rare,
Standard,
Turbocharged,
Trashed,
NotTurbocharged,
NotTrashed
}
public class PriorityGUI : MonoBehaviour
{
private static readonly PriorityCriteria[] BaseDefaultOrder = new PriorityCriteria[14]
{
PriorityCriteria.Favorited,
PriorityCriteria.NotFavorited,
PriorityCriteria.Unlocked,
PriorityCriteria.Locked,
PriorityCriteria.Oddity,
PriorityCriteria.Exotic,
PriorityCriteria.Epic,
PriorityCriteria.Rare,
PriorityCriteria.Standard,
PriorityCriteria.Turbocharged,
PriorityCriteria.NotTurbocharged,
PriorityCriteria.RecentlyUsed,
PriorityCriteria.RecentlyAcquired,
PriorityCriteria.InstanceName
};
private static readonly PriorityCriteria[] TrashCriteria = new PriorityCriteria[2]
{
PriorityCriteria.Trashed,
PriorityCriteria.NotTrashed
};
private UIDragList _list;
private UIWindow _window;
private List<PriorityCriteria> currentOrder;
private bool showWindow;
public static PriorityGUI Instance { get; private set; }
private void Awake()
{
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
currentOrder = PriorityPatches.LoadPriorityOrder();
}
private void Update()
{
if (!PriorityPatches.IsWindowOpen && !GearActionBar.IsGearMenuOpen() && showWindow)
{
CloseWindow(reload: true);
}
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
private static List<PriorityCriteria> BuildDefaultOrder()
{
List<PriorityCriteria> list = BaseDefaultOrder.ToList();
if (PriorityPatches.IsBatchScrappingPresent())
{
int num = list.IndexOf(PriorityCriteria.Locked);
if (num < 0)
{
num = list.Count - 1;
}
list.InsertRange(num + 1, TrashCriteria);
}
return list;
}
public static void EnsureExists()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
PriorityGUI priorityGUI = Object.FindObjectOfType<PriorityGUI>();
if ((Object)(object)priorityGUI != (Object)null)
{
Object.Destroy((Object)(object)((Component)priorityGUI).gameObject);
Instance = null;
}
new GameObject("PriorityGUI").AddComponent<PriorityGUI>();
}
public static void ToggleWindowStatic()
{
if (!((Object)(object)Instance == (Object)null))
{
Instance.ToggleWindow();
}
}
private void ToggleWindow()
{
if (showWindow)
{
CloseWindow(reload: true);
}
else
{
OpenWindow();
}
}
private void OpenWindow()
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Expected O, but got Unknown
showWindow = true;
currentOrder = PriorityPatches.LoadPriorityOrder();
if (currentOrder == null || currentOrder.Count == 0)
{
currentOrder = BuildDefaultOrder();
}
else
{
currentOrder = PriorityPatches.FilterOrderForAvailableMods(currentOrder);
}
if (_window == null)
{
_window = UIWindow.Create("SortPriority", (Vector2?)new Vector2(340f, 560f), "Sort Priority", false, true, (int?)null);
_window.OnClose((Action)delegate
{
CloseWindow(reload: true);
});
Transform content = _window.Content;
UIFactory.AddVerticalLayout(((Component)content).gameObject, UITheme.S(8f), UITheme.ScaledPadding(8, 8, 8, 8), (TextAnchor)0, true, false, true, true);
UIText.Create(content, "Hint", "Higher = applied first. Put rarities above Name/Recently* or they won't matter.", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)513, false);
_list = UIDragList.Create(content, "PriorityList");
GameObject gameObject = _list.GameObject;
float? num = UITheme.S(400f);
float? num2 = UITheme.S(280f);
UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, num2);
LayoutElement component = _list.GameObject.GetComponent<LayoutElement>();
if ((Object)(object)component != (Object)null)
{
component.flexibleHeight = 1f;
}
_list.OnReordered((Action<int, int>)delegate(int from, int to)
{
if (from >= 0 && to >= 0 && from < currentOrder.Count && to < currentOrder.Count)
{
PriorityCriteria item = currentOrder[from];
currentOrder.RemoveAt(from);
currentOrder.Insert(to, item);
}
});
RectTransform obj = UIFactory.CreateRect("Buttons", content);
GameObject gameObject2 = ((Component)obj).gameObject;
num2 = UITheme.ScaledButtonHeight + UITheme.S(4f);
UIHelpers.EnsureLayoutElement(gameObject2, (float?)null, num2, (float?)null);
UIFactory.AddHorizontalLayout(((Component)obj).gameObject, UITheme.S(8f), new RectOffset(0, 0, 0, 0), (TextAnchor)4, false, false, true, true);
UIButton.Create((Transform)(object)obj, "Save", (Action)delegate
{
PriorityPatches.SavePriorityOrder(currentOrder);
PriorityPatches.TriggerPrioritySort(currentOrder);
CloseWindow(reload: false);
}, (UIButtonStyle)1, (string)null, (float?)null).SetWidth(UITheme.S(90f));
UIButton.Create((Transform)(object)obj, "Cancel", (Action)delegate
{
CloseWindow(reload: true);
}, (UIButtonStyle)0, (string)null, (float?)null).SetWidth(UITheme.S(90f));
UIButton.Create((Transform)(object)obj, "Reset", (Action)delegate
{
currentOrder = BuildDefaultOrder();
RefreshList();
}, (UIButtonStyle)2, (string)null, (float?)null).SetWidth(UITheme.S(90f));
}
RefreshList();
_window.Show();
}
private void RefreshList()
{
if (_list == null || currentOrder == null)
{
return;
}
List<string> list = new List<string>();
foreach (PriorityCriteria item in currentOrder)
{
list.Add(GetCriteriaName(item));
}
_list.SetItems((IList<string>)list);
}
private void CloseWindow(bool reload)
{
showWindow = false;
if (reload)
{
currentOrder = PriorityPatches.LoadPriorityOrder();
}
if (_window != null)
{
_window.Hide(true);
}
}
private string GetCriteriaName(PriorityCriteria criteria)
{
return criteria switch
{
PriorityCriteria.Favorited => "Favorited",
PriorityCriteria.NotFavorited => "Not Favorited",
PriorityCriteria.Unlocked => "Unlocked",
PriorityCriteria.Locked => "Locked",
PriorityCriteria.RecentlyUsed => "Recently Used",
PriorityCriteria.RecentlyAcquired => "Recently Acquired",
PriorityCriteria.InstanceName => "Name (tie-break)",
PriorityCriteria.Oddity => "Oddity",
PriorityCriteria.Exotic => "Exotic",
PriorityCriteria.Epic => "Epic",
PriorityCriteria.Rare => "Rare",
PriorityCriteria.Standard => "Standard",
PriorityCriteria.Turbocharged => "Turbocharged",
PriorityCriteria.Trashed => "Trashed (BatchScrapping)",
PriorityCriteria.NotTurbocharged => "Not Turbocharged",
PriorityCriteria.NotTrashed => "Not Trashed (BatchScrapping)",
_ => "Unknown",
};
}
}
public static class PriorityPatches
{
private struct SortEntry
{
public GearUpgradeUI Ui;
public int[] Keys;
}
private sealed class SortEntryComparer : IComparer<SortEntry>
{
public static readonly SortEntryComparer Instance = new SortEntryComparer();
public int Compare(SortEntry x, SortEntry y)
{
int[] keys = x.Keys;
int[] keys2 = y.Keys;
if (keys == null && keys2 == null)
{
return 0;
}
if (keys == null)
{
return 1;
}
if (keys2 == null)
{
return -1;
}
int num = Math.Min(keys.Length, keys2.Length);
for (int i = 0; i < num; i++)
{
int num2 = keys2[i].CompareTo(keys[i]);
if (num2 != 0)
{
return num2;
}
}
return keys.Length.CompareTo(keys2.Length);
}
}
private static List<PriorityCriteria> priorityOrder;
public static GearDetailsWindow currentWindow;
private static bool? _batchScrappingPresent;
private static MethodInfo _isTrashMarkedMethod;
private static Coroutine _deferredLayoutCoroutine;
private static bool _deferredLayoutCancelled;
private static FieldInfo _isGridViewField;
private static FieldInfo _upgradeListParentField;
private static bool _layoutLookupsDone;
public static bool PrioritySortActive { get; private set; }
public static bool IsWindowOpen { get; private set; }
static PriorityPatches()
{
priorityOrder = new List<PriorityCriteria>();
priorityOrder = LoadPriorityOrder();
try
{
string value = default(string);
PrioritySortActive = PlayerOptions.TryGetConfig<string>("SortPriority.Order", ref value) && !string.IsNullOrEmpty(value);
}
catch
{
PrioritySortActive = false;
}
}
public static bool IsBatchScrappingPresent()
{
if (_batchScrappingPresent.HasValue)
{
return _batchScrappingPresent.Value;
}
try
{
foreach (PluginInfo value in Chainloader.PluginInfos.Values)
{
object obj;
if (value == null)
{
obj = null;
}
else
{
BepInPlugin metadata = value.Metadata;
obj = ((metadata != null) ? metadata.GUID : null);
}
if ((string?)obj == "sparroh.batchscrapping")
{
_batchScrappingPresent = true;
CacheTrashApi();
return true;
}
}
}
catch
{
}
try
{
if (AccessTools.TypeByName("ScrapHandlingMod") != null)
{
_batchScrappingPresent = true;
CacheTrashApi();
return true;
}
}
catch
{
}
_batchScrappingPresent = false;
return false;
}
private static void CacheTrashApi()
{
try
{
Type type = AccessTools.TypeByName("ScrapHandlingMod");
_isTrashMarkedMethod = ((type != null) ? AccessTools.Method(type, "IsTrashMarked", new Type[1] { typeof(UpgradeInstance) }, (Type[])null) : null);
}
catch
{
_isTrashMarkedMethod = null;
}
}
public static bool IsTrashMarked(UpgradeInstance instance)
{
if (instance == null || !IsBatchScrappingPresent())
{
return false;
}
if (_isTrashMarkedMethod != null)
{
try
{
return (bool)_isTrashMarkedMethod.Invoke(null, new object[1] { instance });
}
catch
{
}
}
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(UpgradeInstance), "flags");
if (fieldInfo == null)
{
return false;
}
return (Convert.ToByte(fieldInfo.GetValue(instance)) & 0x20) != 0;
}
catch
{
return false;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GearDetailsWindow), "OnOpen")]
public static void OnOpen_Postfix(GearDetailsWindow __instance)
{
IsWindowOpen = true;
currentWindow = __instance;
if (PrioritySortActive)
{
try
{
ApplyPrioritySort(__instance, priorityOrder, resetScroll: false);
return;
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("Priority sort on open failed: " + ex.Message));
return;
}
}
try
{
FilterState.ApplyToWindow(__instance);
}
catch
{
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GearDetailsWindow), "OnCloseCallback")]
public static void OnCloseCallback_Postfix()
{
IsWindowOpen = false;
currentWindow = null;
}
public static bool SortUpgradesInt_Prefix(int i)
{
if (PrioritySortActive)
{
PrioritySortActive = false;
UpgradeFilteringPlugin.Logger.LogInfo((object)$"Priority sort disabled (vanilla sort button {i}).");
}
return true;
}
public static bool SortUpgradesMethod_Prefix(GearDetailsWindow __instance, SortingMethod method, bool resetScroll)
{
if (!PrioritySortActive)
{
return true;
}
if (ListRebuildReapply.SuppressNestedReapply)
{
return true;
}
try
{
ApplyPrioritySort(__instance, priorityOrder, resetScroll);
return false;
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogError((object)("Priority sort prefix failed: " + ex.Message + "\n" + ex.StackTrace));
return true;
}
}
public static bool SortUpgradesMethodPublic_Prefix(GearDetailsWindow __instance, SortingMethod method)
{
if (!PrioritySortActive)
{
return true;
}
if (ListRebuildReapply.SuppressNestedReapply)
{
return true;
}
try
{
ApplyPrioritySort(__instance, priorityOrder);
return false;
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogError((object)("Priority sort public prefix failed: " + ex.Message));
return true;
}
}
public static void Patch(Harmony harmony)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(GearDetailsWindow), "SortUpgrades", new Type[1] { typeof(int) }, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PriorityPatches), "SortUpgradesInt_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"Could not find SortUpgrades(int).");
}
MethodInfo methodInfo2 = AccessTools.Method(typeof(GearDetailsWindow), "SortUpgrades", new Type[2]
{
typeof(SortingMethod),
typeof(bool)
}, (Type[])null);
if (methodInfo2 != null)
{
harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(PriorityPatches), "SortUpgradesMethod_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
UpgradeFilteringPlugin.Logger.LogInfo((object)"Patched SortUpgrades(SortingMethod, bool) for sticky priority.");
return;
}
MethodInfo methodInfo3 = AccessTools.Method(typeof(GearDetailsWindow), "SortUpgrades", new Type[1] { typeof(SortingMethod) }, (Type[])null);
if (methodInfo3 != null)
{
harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(PriorityPatches), "SortUpgradesMethodPublic_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"Could not find SortUpgrades(SortingMethod) — sticky priority may not hook vanilla sorts.");
}
}
public static void TriggerPrioritySort(List<PriorityCriteria> order = null)
{
if (order != null && order.Count > 0)
{
priorityOrder = new List<PriorityCriteria>(order);
}
else
{
priorityOrder = LoadPriorityOrder();
}
PrioritySortActive = true;
GearDetailsWindow val = ResolveWindow();
if ((Object)(object)val == (Object)null)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"Priority sort: no GearDetailsWindow found — order saved; will apply next open.");
return;
}
currentWindow = val;
ApplyPrioritySort(val, priorityOrder);
}
public static GearDetailsWindow ResolveWindow()
{
if ((Object)(object)currentWindow != (Object)null)
{
try
{
if ((Object)(object)((Component)currentWindow).gameObject != (Object)null && ((Component)currentWindow).gameObject.activeInHierarchy)
{
return currentWindow;
}
}
catch
{
currentWindow = null;
}
}
GearDetailsWindow openWindow = FilterState.GetOpenWindow();
if ((Object)(object)openWindow != (Object)null)
{
return openWindow;
}
try
{
return Object.FindObjectOfType<GearDetailsWindow>();
}
catch
{
return null;
}
}
public static void ApplyPrioritySort(GearDetailsWindow window, bool resetScroll = true, bool skipDeferred = false)
{
ApplyPrioritySort(window, priorityOrder ?? LoadPriorityOrder(), resetScroll, skipDeferred);
}
public static void CancelDeferredLayout()
{
_deferredLayoutCancelled = true;
try
{
if (_deferredLayoutCoroutine != null && (Object)(object)PriorityGUI.Instance != (Object)null)
{
((MonoBehaviour)PriorityGUI.Instance).StopCoroutine(_deferredLayoutCoroutine);
_deferredLayoutCoroutine = null;
}
}
catch
{
}
}
public static void ApplyPrioritySort(GearDetailsWindow window, List<PriorityCriteria> order, bool resetScroll = true, bool skipDeferred = false)
{
if ((Object)(object)window == (Object)null)
{
return;
}
PrioritySortActive = true;
if (order != null && order.Count > 0)
{
priorityOrder = new List<PriorityCriteria>(order);
}
List<PriorityCriteria> list = FilterOrderForAvailableMods(priorityOrder);
List<GearUpgradeUI> upgradeUIs = FilterState.GetUpgradeUIs();
if (upgradeUIs == null || upgradeUIs.Count == 0)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)"Priority sort: upgradeUIs empty.");
return;
}
int num = FilterState.GetUpgradeUICount(window);
if (num <= 0 || num > upgradeUIs.Count)
{
num = upgradeUIs.Count;
}
UpgradeFilteringPlugin.Logger.LogInfo((object)($"Sort begin (visual-only): window={((Object)window).name}, listCount={upgradeUIs.Count}, uiCount={num}, " + "criteria=[" + string.Join(" > ", list) + "]"));
ActivateAllLiveSlots(upgradeUIs, num);
if (!LogUniqueInstanceIds("BEFORE visual sort", upgradeUIs, num) && !TryRepairDuplicateUiRefs(window, upgradeUIs, num))
{
UpgradeFilteringPlugin.Logger.LogError((object)"Pool corrupt and repair failed — skip visual reorder; reopen gear window.");
FilterState.ApplyVisibilityOnly(window);
return;
}
FilterState.ApplyVisibilityOnly(window);
ApplyVisualPriorityOrder(window, upgradeUIs, num, list);
LogRowSnapshot("AFTER visual priority+filter", upgradeUIs, num);
if (resetScroll)
{
try
{
typeof(GearDetailsWindow).GetMethod("SetUpgradeListScroll", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null)?.Invoke(window, new object[1] { 1f });
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("SetUpgradeListScroll failed: " + ex.Message));
}
}
try
{
typeof(GearDetailsWindow).GetMethod("DisableSortButtonContainer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)?.Invoke(window, null);
}
catch
{
}
}
public static void ClearStalePoolSlots(List<GearUpgradeUI> upgradeUIs, int liveCount)
{
if (upgradeUIs == null)
{
return;
}
liveCount = Mathf.Max(0, liveCount);
int num = 0;
for (int i = liveCount; i < upgradeUIs.Count; i++)
{
GearUpgradeUI val = upgradeUIs[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
try
{
if (((Component)val).gameObject.activeSelf)
{
((Component)val).gameObject.SetActive(false);
}
if (((HoverInfoUpgrade)val).Upgrade != null)
{
((HoverInfoUpgrade)val).Upgrade = null;
num++;
}
}
catch
{
try
{
((Component)val).gameObject.SetActive(false);
}
catch
{
}
}
}
if (num > 0)
{
UpgradeFilteringPlugin.Logger.LogInfo((object)$"ClearStalePoolSlots: cleared Upgrade on {num} slots past liveCount={liveCount}");
}
}
public static bool TryRepairDuplicateUiRefs(GearDetailsWindow window, List<GearUpgradeUI> upgradeUIs, int count)
{
if (upgradeUIs == null || (Object)(object)window == (Object)null || count <= 0)
{
return true;
}
count = Mathf.Min(count, upgradeUIs.Count);
HashSet<GearUpgradeUI> hashSet = new HashSet<GearUpgradeUI>();
List<int> list = new List<int>();
for (int i = 0; i < count; i++)
{
GearUpgradeUI val = upgradeUIs[i];
if ((Object)(object)val == (Object)null)
{
list.Add(i);
}
else if (!hashSet.Add(val))
{
list.Add(i);
}
}
if (list.Count == 0)
{
return true;
}
UpgradeFilteringPlugin.Logger.LogWarning((object)$"Repairing {list.Count} duplicate/null GearUpgradeUI refs in live pool.");
Queue<GearUpgradeUI> queue = new Queue<GearUpgradeUI>();
for (int j = 0; j < upgradeUIs.Count; j++)
{
GearUpgradeUI val2 = upgradeUIs[j];
if (!((Object)(object)val2 == (Object)null) && !hashSet.Contains(val2))
{
queue.Enqueue(val2);
}
}
RectTransform val3 = null;
try
{
EnsureLayoutLookups();
object? obj = _upgradeListParentField?.GetValue(window);
val3 = (RectTransform)((obj is RectTransform) ? obj : null);
}
catch
{
}
FieldInfo fieldInfo = null;
try
{
fieldInfo = typeof(GearDetailsWindow).GetField("upgradeUIPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
catch
{
}
foreach (int item in list)
{
GearUpgradeUI obj4 = upgradeUIs[item];
UpgradeInstance val4 = ((obj4 != null) ? ((HoverInfoUpgrade)obj4).Upgrade : null);
GearUpgradeUI val5 = null;
if (queue.Count > 0)
{
val5 = queue.Dequeue();
}
else if (fieldInfo != null && (Object)(object)val3 != (Object)null)
{
try
{
object? value = fieldInfo.GetValue(window);
GearUpgradeUI val6 = (GearUpgradeUI)((value is GearUpgradeUI) ? value : null);
if ((Object)(object)val6 != (Object)null)
{
val5 = Object.Instantiate<GearUpgradeUI>(val6, (Transform)(object)val3);
upgradeUIs.Add(val5);
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("Instantiate repair UI failed: " + ex.Message));
}
}
if ((Object)(object)val5 == (Object)null)
{
UpgradeFilteringPlugin.Logger.LogError((object)$"Could not repair duplicate at index {item}");
return false;
}
upgradeUIs[item] = val5;
hashSet.Add(val5);
try
{
if (val4 != null)
{
((Component)val5).gameObject.SetActive(true);
val5.SetUpgrade(val4, false);
val5.EnableGridView(GetIsGridView(window));
}
else
{
((Component)val5).gameObject.SetActive(false);
}
}
catch
{
}
}
return LogUniqueInstanceIds("AFTER pool ref repair", upgradeUIs, count);
}
public static void ActivateAllLiveSlots(List<GearUpgradeUI> upgradeUIs, int count)
{
if (upgradeUIs == null)
{
return;
}
count = Mathf.Min(count, upgradeUIs.Count);
ClearStalePoolSlots(upgradeUIs, count);
bool isGridView = GetIsGridView(currentWindow);
int num = 0;
for (int i = 0; i < count; i++)
{
GearUpgradeUI val = upgradeUIs[i];
object obj;
if (val == null)
{
obj = null;
}
else
{
UpgradeInstance upgrade = ((HoverInfoUpgrade)val).Upgrade;
obj = ((upgrade != null) ? upgrade.Upgrade : null);
}
if ((Object)obj == (Object)null)
{
continue;
}
try
{
if (!((Component)val).gameObject.activeSelf)
{
((Component)val).gameObject.SetActive(true);
num++;
}
val.EnableGridView(isGridView);
}
catch
{
}
}
UpgradeFilteringPlugin.Logger.LogInfo((object)$"ActivateAllLiveSlots: count={count}, reactivated={num}, isGrid={isGridView}");
}
public static void ApplyVisualPriorityOrder(GearDetailsWindow window, List<GearUpgradeUI> upgradeUIs, int count, List<PriorityCriteria> order)
{
if ((Object)(object)window == (Object)null || upgradeUIs == null)
{
return;
}
count = Mathf.Min(count, upgradeUIs.Count);
List<(GearUpgradeUI, int[])> list = new List<(GearUpgradeUI, int[])>(count);
for (int i = 0; i < count; i++)
{
GearUpgradeUI val = upgradeUIs[i];
if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeSelf)
{
continue;
}
UpgradeInstance upgrade = ((HoverInfoUpgrade)val).Upgrade;
if ((Object)(object)((upgrade != null) ? upgrade.Upgrade : null) == (Object)null || !FilterState.ShouldShow(val))
{
continue;
}
int[] array = new int[(order?.Count ?? 0) + 2];
int num = 0;
if (order != null)
{
foreach (PriorityCriteria item4 in order)
{
array[num++] = ScoreCriteria(val, item4);
}
}
array[num++] = ((HoverInfoUpgrade)val).Upgrade.InstanceID;
array[num] = -i;
list.Add((val, array));
}
list.Sort(delegate((GearUpgradeUI ui, int[] keys) a, (GearUpgradeUI ui, int[] keys) b)
{
int[] item2 = a.keys;
int[] item3 = b.keys;
int num5 = Math.Min(item2.Length, item3.Length);
for (int j = 0; j < num5; j++)
{
int num6 = item3[j].CompareTo(item2[j]);
if (num6 != 0)
{
return num6;
}
}
return 0;
});
EnsureLayoutLookups();
bool isGridView = GetIsGridView(window);
RectTransform listParent = null;
try
{
object? obj = _upgradeListParentField?.GetValue(window);
listParent = (RectTransform)((obj is RectTransform) ? obj : null);
}
catch
{
}
for (int num2 = 0; num2 < count; num2++)
{
try
{
GearUpgradeUI obj3 = upgradeUIs[num2];
if (obj3 != null)
{
((Component)obj3).transform.SetAsLastSibling();
}
}
catch
{
}
}
for (int num3 = 0; num3 < list.Count; num3++)
{
GearUpgradeUI item = list[num3].Item1;
try
{
((Component)item).transform.SetSiblingIndex(num3);
item.EnableGridView(isGridView);
SetUpgradeAnchoredPosition(item, num3, isGridView, listParent);
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("Visual order place failed: " + ex.Message));
}
}
int count2 = list.Count;
for (int num4 = 0; num4 < count; num4++)
{
GearUpgradeUI val2 = upgradeUIs[num4];
if (!((Object)(object)val2 == (Object)null) && !((Component)val2).gameObject.activeSelf)
{
try
{
((Component)val2).transform.SetSiblingIndex(count2++);
}
catch
{
}
}
}
try
{
Canvas.ForceUpdateCanvases();
}
catch
{
}
UpgradeFilteringPlugin.Logger.LogInfo((object)$"Visual priority order: visiblePlaced={list.Count}, isGrid={isGridView}");
}
private static IEnumerator DeferredLayout(GearDetailsWindow window)
{
yield return null;
_deferredLayoutCoroutine = null;
if (_deferredLayoutCancelled || (Object)(object)window == (Object)null)
{
yield break;
}
try
{
if (FilterState.HasActiveFilters() || PrioritySortActive)
{
FilterState.ApplyToWindow(window);
}
else
{
List<GearUpgradeUI> upgradeUIs = FilterState.GetUpgradeUIs();
int num = FilterState.GetUpgradeUICount(window);
if (upgradeUIs == null)
{
yield break;
}
if (num <= 0 || num > upgradeUIs.Count)
{
num = upgradeUIs.Count;
}
ForceLayout(window, upgradeUIs, num);
}
UpgradeFilteringPlugin.Logger.LogInfo((object)"Deferred layout pass complete.");
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("Deferred layout failed: " + ex.Message));
}
}
internal static void LogRowSnapshot(string label, List<GearUpgradeUI> upgradeUIs, int count)
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
try
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(label).Append(':');
int num = 0;
for (int i = 0; i < count; i++)
{
if (num >= 6)
{
break;
}
GearUpgradeUI val = upgradeUIs[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
string value = "?";
string value2 = "?";
try
{
UpgradeInstance upgrade = ((HoverInfoUpgrade)val).Upgrade;
if ((Object)(object)((upgrade != null) ? upgrade.Upgrade : null) != (Object)null)
{
value = ((HoverInfoUpgrade)val).Upgrade.Upgrade.Name ?? "?";
value2 = ((object)((HoverInfoUpgrade)val).Upgrade.Upgrade.Rarity/*cast due to .constrained prefix*/).ToString();
}
}
catch
{
}
Transform transform = ((Component)val).transform;
RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
Vector2 val3 = (((Object)(object)val2 != (Object)null) ? val2.anchoredPosition : Vector2.zero);
int siblingIndex = ((Component)val).transform.GetSiblingIndex();
string value3 = (((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Object)((Component)val).transform.parent).name : "null");
stringBuilder.Append("\n [").Append(i).Append("] ")
.Append(value2)
.Append(" | ")
.Append(value)
.Append(" | active=")
.Append(((Component)val).gameObject.activeSelf)
.Append(" | sib=")
.Append(siblingIndex)
.Append(" | pos=")
.Append(val3)
.Append(" | parent=")
.Append(value3);
num++;
}
UpgradeFilteringPlugin.Logger.LogInfo((object)stringBuilder.ToString());
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("LogRowSnapshot failed: " + ex.Message));
}
}
private static void EnsureLayoutLookups()
{
if (!_layoutLookupsDone)
{
_layoutLookupsDone = true;
Type? typeFromHandle = typeof(GearDetailsWindow);
_isGridViewField = typeFromHandle.GetField("isGridView", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_upgradeListParentField = typeFromHandle.GetField("upgradeListParent", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
UpgradeFilteringPlugin.Logger.LogInfo((object)($"Layout lookups: isGridView={_isGridViewField != null}, " + $"listParent={_upgradeListParentField != null}"));
}
}
internal static bool GetIsGridView(GearDetailsWindow window)
{
EnsureLayoutLookups();
try
{
if (_isGridViewField == null)
{
return false;
}
return _isGridViewField.IsStatic ? ((bool)_isGridViewField.GetValue(null)) : ((bool)_isGridViewField.GetValue(window));
}
catch
{
return false;
}
}
internal static void ForceLayout(GearDetailsWindow window, List<GearUpgradeUI> upgradeUIs, int count)
{
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0288: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0355: Unknown result type (might be due to invalid IL or missing references)
//IL_035e: Unknown result type (might be due to invalid IL or missing references)
if (upgradeUIs == null || (Object)(object)window == (Object)null)
{
return;
}
count = Mathf.Min(count, upgradeUIs.Count);
EnsureLayoutLookups();
bool flag = false;
try
{
if (_isGridViewField != null)
{
flag = (_isGridViewField.IsStatic ? ((bool)_isGridViewField.GetValue(null)) : ((bool)_isGridViewField.GetValue(window)));
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("isGridView read failed: " + ex.Message));
}
RectTransform val = null;
try
{
object? obj = _upgradeListParentField?.GetValue(window);
val = (RectTransform)((obj is RectTransform) ? obj : null);
}
catch (Exception ex2)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("upgradeListParent read failed: " + ex2.Message));
}
string text = null;
try
{
if (count > 0)
{
GearUpgradeUI obj2 = upgradeUIs[0];
object obj3;
if (obj2 == null)
{
obj3 = null;
}
else
{
UpgradeInstance upgrade = ((HoverInfoUpgrade)obj2).Upgrade;
obj3 = ((upgrade != null) ? upgrade.Upgrade : null);
}
if ((Object)obj3 != (Object)null)
{
text = ((HoverInfoUpgrade)upgradeUIs[0]).Upgrade.Upgrade.Name;
}
}
}
catch
{
}
Vector2 val2 = default(Vector2);
if (count > 0 && (Object)(object)upgradeUIs[0] != (Object)null)
{
Transform transform = ((Component)upgradeUIs[0]).transform;
RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val3 != (Object)null)
{
val2 = val3.anchoredPosition;
}
}
for (int i = 0; i < count; i++)
{
GearUpgradeUI val4 = upgradeUIs[i];
if (!((Object)(object)val4 == (Object)null))
{
try
{
((Component)val4).transform.SetAsLastSibling();
}
catch
{
}
}
}
int num = 0;
for (int j = 0; j < count; j++)
{
GearUpgradeUI val5 = upgradeUIs[j];
if ((Object)(object)val5 == (Object)null)
{
continue;
}
try
{
((Component)val5).transform.SetSiblingIndex(j);
}
catch (Exception ex3)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)$"Sibling set failed @ {j}: {ex3.Message}");
}
if (((Component)val5).gameObject.activeSelf)
{
try
{
val5.EnableGridView(flag);
SetUpgradeAnchoredPosition(val5, num, flag, val);
}
catch (Exception ex4)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)$"Inline pos failed @ {j}: {ex4.Message}");
}
num++;
}
}
try
{
Canvas.ForceUpdateCanvases();
}
catch
{
}
string text2 = null;
try
{
if (count > 0)
{
GearUpgradeUI obj7 = upgradeUIs[0];
object obj8;
if (obj7 == null)
{
obj8 = null;
}
else
{
UpgradeInstance upgrade2 = ((HoverInfoUpgrade)obj7).Upgrade;
obj8 = ((upgrade2 != null) ? upgrade2.Upgrade : null);
}
if ((Object)obj8 != (Object)null)
{
text2 = ((HoverInfoUpgrade)upgradeUIs[0]).Upgrade.Upgrade.Name;
}
}
}
catch
{
}
Vector2 val6 = default(Vector2);
if (count > 0 && (Object)(object)upgradeUIs[0] != (Object)null)
{
Transform transform2 = ((Component)upgradeUIs[0]).transform;
RectTransform val7 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
if ((Object)(object)val7 != (Object)null)
{
val6 = val7.anchoredPosition;
}
}
if (text != null && text2 != null && text != text2)
{
UpgradeFilteringPlugin.Logger.LogError((object)("ForceLayout mutated list head! '" + text + "' -> '" + text2 + "'"));
}
UpgradeFilteringPlugin.Logger.LogInfo((object)(string.Format("ForceLayout done: isGrid={0}, listParent={1}, ", flag, ((Object)(object)val != (Object)null) ? ((Object)val).name : "null") + $"visiblePlaced={num}, head={text2}, firstPos {val2} -> {val6}"));
}
private static void SetUpgradeAnchoredPosition(GearUpgradeUI ui, int index, bool isGrid, RectTransform listParent)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = (RectTransform)((Component)ui).transform;
Rect rect = val.rect;
float num;
if (!(((Rect)(ref rect)).height > 1f))
{
num = 52f;
}
else
{
rect = val.rect;
num = ((Rect)(ref rect)).height;
}
float num2 = num;
rect = val.rect;
float num3;
if (!(((Rect)(ref rect)).width > 1f))
{
num3 = 300f;
}
else
{
rect = val.rect;
num3 = ((Rect)(ref rect)).width;
}
float num4 = num3;
if (isGrid && (Object)(object)listParent != (Object)null)
{
float num5 = num4 + 10f;
rect = listParent.rect;
float num6;
if (!(((Rect)(ref rect)).width > 1f))
{
num6 = 400f;
}
else
{
rect = listParent.rect;
num6 = ((Rect)(ref rect)).width;
}
int num7 = Mathf.Max(Mathf.FloorToInt((num6 - 6f) / num5), 1);
float num8 = 3f + (float)(index % num7) * (num4 + 10f);
float num9 = -3f - (float)(index / num7) * (num2 + 10f);
val.anchoredPosition = new Vector2(num8, num9);
}
else
{
Vector2 offsetMin = val.offsetMin;
Vector2 offsetMax = val.offsetMax;
val.offsetMin = new Vector2(0f, offsetMin.y);
val.offsetMax = new Vector2(0f, offsetMax.y);
val.anchoredPosition = new Vector2(0f, -3f - (num2 + 4f) * (float)index);
}
}
public static List<PriorityCriteria> FilterOrderForAvailableMods(List<PriorityCriteria> order)
{
if (order == null)
{
return new List<PriorityCriteria>();
}
List<PriorityCriteria> list = new List<PriorityCriteria>(order.Count);
bool flag = IsBatchScrappingPresent();
foreach (PriorityCriteria item in order)
{
if (flag || (item != PriorityCriteria.Trashed && item != PriorityCriteria.NotTrashed))
{
list.Add(item);
}
}
return MigrateTotalKeysAfterRarities(list);
}
public static List<PriorityCriteria> MigrateTotalKeysAfterRarities(List<PriorityCriteria> order)
{
if (order == null || order.Count == 0)
{
return order ?? new List<PriorityCriteria>();
}
int num = -1;
int num2 = -1;
for (int i = 0; i < order.Count; i++)
{
if (IsRarity(order[i]))
{
if (num < 0)
{
num = i;
}
num2 = i;
}
}
if (num < 0)
{
return order;
}
bool flag = false;
for (int j = 0; j < order.Count; j++)
{
if (IsTotalKey(order[j]) && j < num2)
{
flag = true;
break;
}
}
if (!flag)
{
return order;
}
List<PriorityCriteria> list = new List<PriorityCriteria>(order.Count);
List<PriorityCriteria> list2 = new List<PriorityCriteria>(4);
foreach (PriorityCriteria item in order)
{
if (IsTotalKey(item))
{
list2.Add(item);
}
else
{
list.Add(item);
}
}
list.AddRange(list2);
UpgradeFilteringPlugin.Logger.LogInfo((object)"Migrated sort order: moved Name/Recently* after rarities so rarity criteria apply.");
return list;
static bool IsRarity(PriorityCriteria c)
{
if ((uint)(c - 7) <= 4u)
{
return true;
}
return false;
}
static bool IsTotalKey(PriorityCriteria c)
{
if ((uint)(c - 4) <= 2u)
{
return true;
}
return false;
}
}
public static bool TryDecorateSortLiveSlice(List<GearUpgradeUI> upgradeUIs, int count, List<PriorityCriteria> order)
{
if (upgradeUIs == null || count <= 0)
{
return true;
}
count = Mathf.Min(count, upgradeUIs.Count);
int num = count;
SortEntry[] array = new SortEntry[num];
int num2 = (order?.Count ?? 0) + 2;
for (int i = 0; i < num; i++)
{
GearUpgradeUI val = upgradeUIs[i];
int[] array2 = new int[num2];
int num3 = 0;
if (order != null)
{
foreach (PriorityCriteria item in order)
{
array2[num3++] = ScoreCriteria(val, item);
}
}
array2[num3++] = ((((val != null) ? ((HoverInfoUpgrade)val).Upgrade : null) != null) ? ((HoverInfoUpgrade)val).Upgrade.InstanceID : int.MinValue);
array2[num3] = -i;
array[i] = new SortEntry
{
Ui = val,
Keys = array2
};
}
Array.Sort(array, SortEntryComparer.Instance);
HashSet<int> hashSet = new HashSet<int>();
HashSet<int> hashSet2 = new HashSet<int>();
for (int j = 0; j < num; j++)
{
GearUpgradeUI obj = upgradeUIs[j];
if (((obj != null) ? ((HoverInfoUpgrade)obj).Upgrade : null) != null)
{
hashSet.Add(((HoverInfoUpgrade)upgradeUIs[j]).Upgrade.InstanceID);
}
GearUpgradeUI ui = array[j].Ui;
if (((ui != null) ? ((HoverInfoUpgrade)ui).Upgrade : null) != null)
{
hashSet2.Add(((HoverInfoUpgrade)array[j].Ui).Upgrade.InstanceID);
}
}
if (hashSet.Count != hashSet2.Count || !hashSet.SetEquals(hashSet2))
{
UpgradeFilteringPlugin.Logger.LogError((object)$"Decorate-sort validation failed: beforeIds={hashSet.Count} afterIds={hashSet2.Count}");
return false;
}
HashSet<GearUpgradeUI> hashSet3 = new HashSet<GearUpgradeUI>();
for (int k = 0; k < num; k++)
{
GearUpgradeUI ui2 = array[k].Ui;
if (!((Object)(object)ui2 == (Object)null) && !hashSet3.Add(ui2))
{
UpgradeFilteringPlugin.Logger.LogError((object)"Decorate-sort validation failed: duplicate GearUpgradeUI reference.");
return false;
}
}
for (int l = 0; l < num; l++)
{
upgradeUIs[l] = array[l].Ui;
}
return true;
}
private static int ScoreCriteria(GearUpgradeUI ui, PriorityCriteria criteria)
{
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Invalid comparison between Unknown and I4
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Invalid comparison between Unknown and I4
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Invalid comparison between Unknown and I4
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Invalid comparison between Unknown and I4
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Invalid comparison between Unknown and I4
UpgradeInstance val = ((ui != null) ? ((HoverInfoUpgrade)ui).Upgrade : null);
if ((Object)(object)((val != null) ? val.Upgrade : null) == (Object)null)
{
return int.MinValue;
}
return criteria switch
{
PriorityCriteria.Favorited => val.Favorite ? 1 : 0,
PriorityCriteria.NotFavorited => (!val.Favorite) ? 1 : 0,
PriorityCriteria.Unlocked => val.IsUnlocked ? 1 : 0,
PriorityCriteria.Locked => (!val.IsUnlocked) ? 1 : 0,
PriorityCriteria.Turbocharged => val.IsTurbocharged ? 1 : 0,
PriorityCriteria.NotTurbocharged => (!val.IsTurbocharged) ? 1 : 0,
PriorityCriteria.Trashed => (!IsTrashMarked(val)) ? 1 : 0,
PriorityCriteria.NotTrashed => (!IsTrashMarked(val)) ? 1 : 0,
PriorityCriteria.RecentlyAcquired => (int)Math.Max(-2147483648L, Math.Min(2147483647L, val.TimeUnlocked)),
PriorityCriteria.RecentlyUsed => (int)(val.TimeUnequipped * 1000f),
PriorityCriteria.InstanceName => 0,
PriorityCriteria.Oddity => ((int)val.Upgrade.Rarity == 4) ? 1 : 0,
PriorityCriteria.Exotic => ((int)val.Upgrade.Rarity == 3) ? 1 : 0,
PriorityCriteria.Epic => ((int)val.Upgrade.Rarity == 2) ? 1 : 0,
PriorityCriteria.Rare => ((int)val.Upgrade.Rarity == 1) ? 1 : 0,
PriorityCriteria.Standard => ((int)val.Upgrade.Rarity == 0) ? 1 : 0,
_ => 0,
};
}
public static Comparison<GearUpgradeUI> GetPriorityComparison(List<PriorityCriteria> order)
{
return delegate(GearUpgradeUI a, GearUpgradeUI b)
{
if (a == b)
{
return 0;
}
if ((Object)(object)a == (Object)null)
{
return 1;
}
if ((Object)(object)b == (Object)null)
{
return -1;
}
if (((HoverInfoUpgrade)a).Upgrade == null && ((HoverInfoUpgrade)b).Upgrade == null)
{
return 0;
}
if (((HoverInfoUpgrade)a).Upgrade == null)
{
return 1;
}
if (((HoverInfoUpgrade)b).Upgrade == null)
{
return -1;
}
if ((Object)(object)((HoverInfoUpgrade)a).Upgrade.Upgrade == (Object)null && (Object)(object)((HoverInfoUpgrade)b).Upgrade.Upgrade == (Object)null)
{
return 0;
}
if ((Object)(object)((HoverInfoUpgrade)a).Upgrade.Upgrade == (Object)null)
{
return 1;
}
if ((Object)(object)((HoverInfoUpgrade)b).Upgrade.Upgrade == (Object)null)
{
return -1;
}
if (order != null)
{
foreach (PriorityCriteria item in order)
{
int value = ScoreCriteria(a, item);
int num = ScoreCriteria(b, item).CompareTo(value);
if (num != 0)
{
return num;
}
}
}
return ((HoverInfoUpgrade)a).Upgrade.InstanceID.CompareTo(((HoverInfoUpgrade)b).Upgrade.InstanceID);
};
}
public static bool LogUniqueInstanceIds(string label, List<GearUpgradeUI> upgradeUIs, int count)
{
try
{
HashSet<int> hashSet = new HashSet<int>();
int num = 0;
for (int i = 0; i < count; i++)
{
GearUpgradeUI val = upgradeUIs[i];
if (((val != null) ? ((HoverInfoUpgrade)val).Upgrade : null) == null)
{
num++;
}
else
{
hashSet.Add(((HoverInfoUpgrade)val).Upgrade.InstanceID);
}
}
if (hashSet.Count + num != count)
{
UpgradeFilteringPlugin.Logger.LogError((object)$"{label}: LIST CORRUPTION uniqueIds={hashSet.Count} nulls={num} count={count}");
return false;
}
UpgradeFilteringPlugin.Logger.LogInfo((object)$"{label}: uniqueIds={hashSet.Count} nulls={num} count={count} OK");
return true;
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("LogUniqueInstanceIds failed: " + ex.Message));
return false;
}
}
public static void ForceLayoutVisibleOnly(GearDetailsWindow window, List<GearUpgradeUI> upgradeUIs, int count)
{
if ((Object)(object)window == (Object)null || upgradeUIs == null)
{
return;
}
count = Mathf.Min(count, upgradeUIs.Count);
EnsureLayoutLookups();
bool isGridView = GetIsGridView(window);
RectTransform listParent = null;
try
{
object? obj = _upgradeListParentField?.GetValue(window);
listParent = (RectTransform)((obj is RectTransform) ? obj : null);
}
catch
{
}
int num = 0;
for (int i = 0; i < count; i++)
{
GearUpgradeUI val = upgradeUIs[i];
if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeSelf)
{
try
{
((Component)val).transform.SetSiblingIndex(num);
val.EnableGridView(isGridView);
SetUpgradeAnchoredPosition(val, num, isGridView, listParent);
num++;
}
catch
{
}
}
}
try
{
Canvas.ForceUpdateCanvases();
}
catch
{
}
UpgradeFilteringPlugin.Logger.LogInfo((object)$"ForceLayoutVisibleOnly: visiblePlaced={num}, isGrid={isGridView}");
}
public static int CompareByCriteria(GearUpgradeUI a, GearUpgradeUI b, PriorityCriteria criteria)
{
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_026c: Invalid comparison between Unknown and I4
//IL_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_0282: Invalid comparison between Unknown and I4
//IL_0296: Unknown result type (might be due to invalid IL or missing references)
//IL_029c: Invalid comparison between Unknown and I4
//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
//IL_02b2: Invalid comparison between Unknown and I4
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Invalid comparison between Unknown and I4
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02e2: Invalid comparison between Unknown and I4
//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
//IL_02fc: Invalid comparison between Unknown and I4
//IL_030c: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Invalid comparison between Unknown and I4
//IL_0326: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Invalid comparison between Unknown and I4
//IL_033c: Unknown result type (might be due to invalid IL or missing references)
//IL_0342: Invalid comparison between Unknown and I4
switch (criteria)
{
case PriorityCriteria.Favorited:
return -(((HoverInfoUpgrade)a).Upgrade.Favorite ? 1 : 0).CompareTo(((HoverInfoUpgrade)b).Upgrade.Favorite ? 1 : 0);
case PriorityCriteria.NotFavorited:
return -((!((HoverInfoUpgrade)a).Upgrade.Favorite) ? 1 : 0).CompareTo((!((HoverInfoUpgrade)b).Upgrade.Favorite) ? 1 : 0);
case PriorityCriteria.Unlocked:
return -((HoverInfoUpgrade)a).Upgrade.IsUnlocked.CompareTo(((HoverInfoUpgrade)b).Upgrade.IsUnlocked);
case PriorityCriteria.Locked:
return -((!((HoverInfoUpgrade)a).Upgrade.IsUnlocked) ? 1 : 0).CompareTo((!((HoverInfoUpgrade)b).Upgrade.IsUnlocked) ? 1 : 0);
case PriorityCriteria.Turbocharged:
{
bool isTurbocharged = ((HoverInfoUpgrade)a).Upgrade.IsTurbocharged;
bool isTurbocharged2 = ((HoverInfoUpgrade)b).Upgrade.IsTurbocharged;
return -(isTurbocharged ? 1 : 0).CompareTo(isTurbocharged2 ? 1 : 0);
}
case PriorityCriteria.Trashed:
{
if (!IsBatchScrappingPresent())
{
return 0;
}
bool num = IsTrashMarked(((HoverInfoUpgrade)a).Upgrade);
bool flag = IsTrashMarked(((HoverInfoUpgrade)b).Upgrade);
return (num ? 1 : 0).CompareTo(flag ? 1 : 0);
}
case PriorityCriteria.NotTurbocharged:
{
bool num3 = !((HoverInfoUpgrade)a).Upgrade.IsTurbocharged;
bool flag3 = !((HoverInfoUpgrade)b).Upgrade.IsTurbocharged;
return -(num3 ? 1 : 0).CompareTo(flag3 ? 1 : 0);
}
case PriorityCriteria.NotTrashed:
{
if (!IsBatchScrappingPresent())
{
return 0;
}
bool num2 = !IsTrashMarked(((HoverInfoUpgrade)a).Upgrade);
bool flag2 = !IsTrashMarked(((HoverInfoUpgrade)b).Upgrade);
return -(num2 ? 1 : 0).CompareTo(flag2 ? 1 : 0);
}
case PriorityCriteria.RecentlyAcquired:
return -((HoverInfoUpgrade)a).Upgrade.TimeUnlocked.CompareTo(((HoverInfoUpgrade)b).Upgrade.TimeUnlocked);
case PriorityCriteria.RecentlyUsed:
return -((HoverInfoUpgrade)a).Upgrade.TimeUnequipped.CompareTo(((HoverInfoUpgrade)b).Upgrade.TimeUnequipped);
case PriorityCriteria.InstanceName:
{
string text = ((HoverInfoUpgrade)a).Upgrade.Upgrade.GetInstanceName(((HoverInfoUpgrade)a).Upgrade.Seed);
if (string.IsNullOrEmpty(text))
{
text = ((HoverInfoUpgrade)a).Upgrade.Upgrade.Name;
}
string text2 = ((HoverInfoUpgrade)b).Upgrade.Upgrade.GetInstanceName(((HoverInfoUpgrade)b).Upgrade.Seed);
if (string.IsNullOrEmpty(text2))
{
text2 = ((HoverInfoUpgrade)b).Upgrade.Upgrade.Name;
}
return string.Compare(text, text2, StringComparison.Ordinal);
}
case PriorityCriteria.Oddity:
return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 4) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 4) ? 1 : 0);
case PriorityCriteria.Exotic:
return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 3) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 3) ? 1 : 0);
case PriorityCriteria.Epic:
return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 2) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 2) ? 1 : 0);
case PriorityCriteria.Rare:
return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 1) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 1) ? 1 : 0);
case PriorityCriteria.Standard:
return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 0) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 0) ? 1 : 0);
default:
return 0;
}
}
public static List<PriorityCriteria> LoadPriorityOrder()
{
try
{
string json = default(string);
if (PlayerOptions.TryGetConfig<string>("SortPriority.Order", ref json))
{
try
{
PriorityData priorityData = PriorityData.FromJson(json);
List<PriorityCriteria> list = new List<PriorityCriteria>();
if (priorityData?.order != null)
{
foreach (int item in priorityData.order)
{
if (Enum.IsDefined(typeof(PriorityCriteria), item))
{
list.Add((PriorityCriteria)item);
}
}
}
if (list.Count > 0)
{
return FilterOrderForAvailableMods(list);
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("Failed to parse priority order from config, using defaults: " + ex.Message));
}
}
return FilterOrderForAvailableMods(new PriorityData().order.ConvertAll((int i) => (PriorityCriteria)i));
}
catch (Exception ex2)
{
UpgradeFilteringPlugin.Logger.LogError((object)("Critical error loading priority order: " + ex2.Message));
return FilterOrderForAvailableMods(new PriorityData().order.ConvertAll((int i) => (PriorityCriteria)i));
}
}
public static void SavePriorityOrder(List<PriorityCriteria> order)
{
try
{
if (order != null)
{
priorityOrder = new List<PriorityCriteria>(order);
string text = new PriorityData
{
order = order.ConvertAll((PriorityCriteria c) => (int)c)
}.ToJson();
PlayerOptions.SetConfig<string>("SortPriority.Order", text);
UpgradeFilteringPlugin.Logger.LogInfo((object)$"Saved priority order ({order.Count} criteria).");
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogError((object)("Failed to save priority order: " + ex.Message));
}
}
}
public static class StatFormatHandling
{
public static bool enableStatReformat = true;
public static void Initialize()
{
}
public static void ReformatStats(Upgrade __instance, ref string text)
{
if (!enableStatReformat || string.IsNullOrEmpty(text))
{
return;
}
try
{
string[] array = text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder stringBuilder = new StringBuilder();
string[] array2 = array;
foreach (string text2 in array2)
{
string text3 = text2.Trim();
if (string.IsNullOrWhiteSpace(text3))
{
stringBuilder.AppendLine();
continue;
}
string input = Regex.Replace(text3, "<[^>]*>", "");
if (Regex.IsMatch(input, "^[-+]?\\d"))
{
Match match = Regex.Match(input, "^([-+]?\\d+(?:\\.\\d+)?[%s]?)\\s*(.+)$");
if (match.Success)
{
string value = match.Groups[1].Value;
string text4 = match.Groups[2].Value.Trim();
if (!string.IsNullOrEmpty(text4))
{
string value2 = text4 + ": <b>" + value + "</b>";
stringBuilder.AppendLine(value2);
continue;
}
}
}
stringBuilder.AppendLine(text2);
}
text = stringBuilder.ToString().TrimEnd();
}
catch (Exception)
{
}
}
public static void ReformatUIText(TextMeshProUGUI textComponent, string fieldName = "text")
{
if (!enableStatReformat || (Object)(object)textComponent == (Object)null)
{
return;
}
string text = ((TMP_Text)textComponent).text;
if (string.IsNullOrEmpty(text))
{
return;
}
try
{
string[] array = text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder stringBuilder = new StringBuilder();
string[] array2 = array;
foreach (string text2 in array2)
{
string text3 = text2.Trim();
if (string.IsNullOrWhiteSpace(text3))
{
stringBuilder.AppendLine();
continue;
}
string input = Regex.Replace(text3, "<[^>]*>", "");
if (Regex.IsMatch(input, "^[-+]?\\d"))
{
Match match = Regex.Match(input, "^([-+]?\\d+(?:\\.\\d+)?[%s]?)\\s*(.+)$");
if (match.Success)
{
string value = match.Groups[1].Value;
string text4 = match.Groups[2].Value.Trim();
if (!string.IsNullOrEmpty(text4))
{
string value2 = text4 + ": <b>" + value + "</b>";
stringBuilder.AppendLine(value2);
continue;
}
}
}
stringBuilder.AppendLine(text2);
}
string text5 = stringBuilder.ToString().TrimEnd();
((TMP_Text)textComponent).text = text5;
((TMP_Text)textComponent).ForceMeshUpdate(false, false);
}
catch (Exception)
{
}
}
}
[HarmonyPatch(typeof(Upgrade), "GetStatList")]
public static class StatListReformatPatch
{
private static void Postfix(Upgrade __instance, int seed, ref string __result)
{
StatFormatHandling.ReformatStats(__instance, ref __result);
}
}
[HarmonyPatch(typeof(HoverInfoDisplay), "Activate")]
public static class HoverInfoDisplayReformatPatch
{
private static void Postfix(HoverInfoDisplay __instance, HoverInfo info, bool resetPosition)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
if (!StatFormatHandling.enableStatReformat || (Object)(object)info == (Object)null || ((object)info).GetType().Name == "DirectiveButton")
{
return;
}
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(HoverInfoDisplay), "text");
if (fieldInfo != null)
{
StatFormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo.GetValue(__instance), "main text");
}
FieldInfo fieldInfo2 = AccessTools.Field(typeof(HoverInfoDisplay), "statsText");
if (fieldInfo2 != null)
{
StatFormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo2.GetValue(__instance), "statsText");
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("HoverInfoDisplayReformatPatch: Failed: " + ex.Message));
}
}
}
[HarmonyPatch(typeof(HoverInfoDisplay), "Refresh")]
public static class HoverInfoDisplayRefreshReformatPatch
{
private static void Postfix(HoverInfoDisplay __instance)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
FieldInfo fieldInfo = AccessTools.Field(typeof(HoverInfoDisplay), "selectedInfo");
if (fieldInfo == null)
{
return;
}
object? value = fieldInfo.GetValue(__instance);
HoverInfo val = (HoverInfo)((value is HoverInfo) ? value : null);
if (!StatFormatHandling.enableStatReformat || (Object)(object)val == (Object)null || ((object)val).GetType().Name == "DirectiveButton")
{
return;
}
try
{
FieldInfo fieldInfo2 = AccessTools.Field(typeof(HoverInfoDisplay), "text");
if (fieldInfo2 != null)
{
StatFormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo2.GetValue(__instance), "main text (refresh)");
}
FieldInfo fieldInfo3 = AccessTools.Field(typeof(HoverInfoDisplay), "statsText");
if (fieldInfo3 != null)
{
StatFormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo3.GetValue(__instance), "statsText (refresh)");
}
}
catch (Exception ex)
{
UpgradeFilteringPlugin.Logger.LogWarning((object)("HoverInfoDisplayRefreshReformatPatch: Failed: " + ex.Message));
}
}
}
namespace UpgradeFiltering
{
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "UpgradeFiltering";
public const string PLUGIN_NAME = "UpgradeFiltering";
public const string PLUGIN_VERSION = "1.1.2";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}