using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GastrodonGroup.UpgradeListEnhance.Behaviours; using GastrodonGroup.UpgradeListEnhance.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("GastrodonGroup")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+99644d73c5f5eba0254006439b2f2e344ed28143")] [assembly: AssemblyProduct("UpgradeListEnhance")] [assembly: AssemblyTitle("UpgradeListEnhance")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } namespace GastrodonGroup.UpgradeListEnhance { [BepInPlugin("GastrodonGroup.UpgradeListEnhance", "Upgrade List Enhance", "0.1.0")] public class UpgradeListEnhancePlugin : BaseUnityPlugin { internal const string TextUpgradesUIScaleGuid = "DarkSpider90.TextUpgradesUIScale"; internal const string DefaultHeaderEnglish = "UPGRADES"; private Harmony? _harmony; internal static UpgradeListEnhancePlugin Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal static ConfigEntry EnableAlign { get; private set; } internal static ConfigEntry AdjustNames { get; private set; } internal static ConfigEntry NameFontSize { get; private set; } internal static ConfigEntry NameLineSpacing { get; private set; } internal static ConfigEntry AdjustNumbers { get; private set; } internal static ConfigEntry RewriteNumbersNoBold { get; private set; } internal static ConfigEntry NumberFontSizeOffset { get; private set; } internal static ConfigEntry NumberLineSpacing { get; private set; } internal static ConfigEntry HeaderOffset { get; private set; } internal static ConfigEntry HeaderEnglish { get; private set; } internal static ConfigEntry EnablePaging { get; private set; } internal static ConfigEntry PageSize { get; private set; } internal static ConfigEntry PageCycleSeconds { get; private set; } internal static ConfigEntry ShowPageInHeader { get; private set; } internal static ConfigEntry LogOnFetch { get; private set; } private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; BindConfig(); if (Chainloader.PluginInfos.ContainsKey("DarkSpider90.TextUpgradesUIScale")) { Logger.LogInfo((object)"Detected DarkSpider90.TextUpgradesUIScale: layout applies after it on Fetch. If rows still shrink/fight this mod, set TextUpgradesUIScale \"Start shrinking after upgrades count\" to 100 (effectively ignore shrink)."); } _harmony = new Harmony("GastrodonGroup.UpgradeListEnhance"); _harmony.PatchAll(typeof(StatsUIAlignPatch)); Logger.LogInfo((object)string.Format("{0} v{1} has loaded! Build: {2}", ((BaseUnityPlugin)this).Info.Metadata.GUID, ((BaseUnityPlugin)this).Info.Metadata.Version, "2026-08-09 17:26")); } private void BindConfig() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Expected O, but got Unknown EnableAlign = ((BaseUnityPlugin)this).Config.Bind("Align", "EnableAlign", true, "Master switch for StatsUI upgrade-list layout tweaks after Fetch."); AdjustNames = ((BaseUnityPlugin)this).Config.Bind("Align", "AdjustNames", true, "When true, change name-column font size and lineSpacing."); NameFontSize = ((BaseUnityPlugin)this).Config.Bind("Align", "NameFontSize", 28f, new ConfigDescription("Font size for the name column (× 名稱).", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 48f), Array.Empty())); NameLineSpacing = ((BaseUnityPlugin)this).Config.Bind("Align", "NameLineSpacing", -50f, new ConfigDescription("ABSOLUTE TMP lineSpacing for names (float OK). Default -50 for English; try about -70 for Traditional Chinese packs.", (AcceptableValueBase)(object)new AcceptableValueRange(-80f, 80f), Array.Empty())); AdjustNumbers = ((BaseUnityPlugin)this).Config.Bind("Align", "AdjustNumbers", false, "When false, leave number column fontSize/lineSpacing as vanilla (still sliced when paging)."); RewriteNumbersNoBold = ((BaseUnityPlugin)this).Config.Bind("Align", "RewriteNumbersNoBold", true, "When AdjustNumbers=true: rewrite page numbers without ."); NumberFontSizeOffset = ((BaseUnityPlugin)this).Config.Bind("Align", "NumberFontSizeOffset", 0.4f, new ConfigDescription("When AdjustNumbers=true: number fontSize = NameFontSize + this.", (AcceptableValueBase)(object)new AcceptableValueRange(-10f, 10f), Array.Empty())); NumberLineSpacing = ((BaseUnityPlugin)this).Config.Bind("Align", "NumberLineSpacing", -50f, new ConfigDescription("When AdjustNumbers=true: ABSOLUTE TMP lineSpacing for numbers (same tip as NameLineSpacing).", (AcceptableValueBase)(object)new AcceptableValueRange(-80f, 80f), Array.Empty())); HeaderOffset = ((BaseUnityPlugin)this).Config.Bind("Align", "HeaderOffset", 7f, new ConfigDescription("When AdjustNames=true: header fontSize = NameFontSize + this.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 15f), Array.Empty())); HeaderEnglish = ((BaseUnityPlugin)this).Config.Bind("Align", "HeaderEnglish", "UPGRADES", "Vanilla English header written by this mod (so 漢化 can translate). Page suffix: \"UPGRADES (1/2)\"."); LogOnFetch = ((BaseUnityPlugin)this).Config.Bind("Align", "LogOnFetch", false, "Log applied layout / page each StatsUI.Fetch or page change."); EnablePaging = ((BaseUnityPlugin)this).Config.Bind("Paging", "EnablePaging", true, "When active upgrades exceed PageSize, cycle pages over time."); PageSize = ((BaseUnityPlugin)this).Config.Bind("Paging", "PageSize", 12, new ConfigDescription("Max upgrades shown per page.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 40), Array.Empty())); PageCycleSeconds = ((BaseUnityPlugin)this).Config.Bind("Paging", "PageCycleSeconds", 3f, new ConfigDescription("Seconds between page switches while the list is visible.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); ShowPageInHeader = ((BaseUnityPlugin)this).Config.Bind("Paging", "ShowPageInHeader", true, "Append English \" (page/total)\" to HeaderEnglish when more than one page."); } } internal static class PluginInfo { internal const string PLUGIN_GUID = "GastrodonGroup.UpgradeListEnhance"; internal const string PLUGIN_NAME = "Upgrade List Enhance"; internal const string PLUGIN_VERSION = "0.1.0"; } internal static class BuildInfo { internal const string Timestamp = "2026-08-09 17:26"; } } namespace GastrodonGroup.UpgradeListEnhance.Patches { internal static class StatsUIAlignPatch { private readonly struct Row { public readonly int Value; public readonly string Name; public Row(int value, string name) { Value = value; Name = name; } } private static readonly StringBuilder TextBuilder = new StringBuilder(256); private static readonly List Rows = new List(32); private static int _pageIndex; private static int _rowsHash; internal static int PageCount { get; private set; } = 1; [HarmonyPostfix] [HarmonyPatch(typeof(StatsUI), "Fetch")] [HarmonyAfter(new string[] { "DarkSpider90.TextUpgradesUIScale" })] private static void FetchPostfix(StatsUI __instance) { if (!UpgradeListEnhancePlugin.EnableAlign.Value) { return; } TextMeshProUGUI text = __instance.Text; TextMeshProUGUI textNumbers = __instance.textNumbers; if ((Object)(object)text == (Object)null || (Object)(object)textNumbers == (Object)null) { return; } Dictionary playerUpgrades = __instance.playerUpgrades; if (playerUpgrades == null || playerUpgrades.Count == 0 || (string.IsNullOrEmpty(((TMP_Text)text).text) && string.IsNullOrEmpty(((TMP_Text)textNumbers).text))) { return; } int num = BuildRows(__instance, playerUpgrades); PageCount = ComputePageCount(Rows.Count); bool flag = num != _rowsHash; _rowsHash = num; if (flag) { _pageIndex = 0; UpgradeListPager.Ensure(); UpgradeListPager.Instance?.ResetTimer(); } else { UpgradeListPager.Ensure(); if (_pageIndex >= PageCount) { _pageIndex = 0; } } ApplyPage(__instance); if (UpgradeListEnhancePlugin.LogOnFetch.Value) { UpgradeListEnhancePlugin.Logger.LogInfo((object)($"[Fetch] rows={Rows.Count}, page={_pageIndex + 1}/{PageCount}, changed={flag}, " + "header=" + UpgradeListEnhancePlugin.HeaderEnglish.Value + ", " + $"nameSize={((TMP_Text)text).fontSize:0.##}, nameLineSpacing={((TMP_Text)text).lineSpacing:0.##}")); } } internal static void AdvancePage(StatsUI ui) { if (PageCount > 1 && Rows.Count != 0) { _pageIndex = (_pageIndex + 1) % PageCount; ApplyPage(ui); if (UpgradeListEnhancePlugin.LogOnFetch.Value) { UpgradeListEnhancePlugin.Logger.LogInfo((object)$"[Page] {_pageIndex + 1}/{PageCount}"); } } } private static void ApplyPage(StatsUI ui) { TextMeshProUGUI text = ui.Text; TextMeshProUGUI textNumbers = ui.textNumbers; if (!((Object)(object)text == (Object)null) && !((Object)(object)textNumbers == (Object)null)) { int num = Mathf.Max(1, UpgradeListEnhancePlugin.PageSize.Value); bool flag = UpgradeListEnhancePlugin.EnablePaging.Value && Rows.Count > num; int num2 = (flag ? (_pageIndex * num) : 0); int count = (flag ? Mathf.Min(num, Rows.Count - num2) : Rows.Count); WriteColumns(text, textNumbers, num2, count); ApplyLayout(text, textNumbers, ui.upgradesHeader); UpdateHeader(ui.upgradesHeader); } } private static int BuildRows(StatsUI ui, Dictionary upgrades) { Rows.Clear(); int num = Rows.Count; foreach (KeyValuePair upgrade in upgrades) { if (upgrade.Value > 0) { string text = StatsUI.GetUpgradeDisplayName(upgrade.Key); if (string.IsNullOrEmpty(text)) { text = upgrade.Key.ToUpperInvariant(); } Rows.Add(new Row(upgrade.Value, text)); num = (num * 397) ^ upgrade.Key.GetHashCode(); num = (num * 397) ^ upgrade.Value; } } return (num * 397) ^ Rows.Count; } private static void WriteColumns(TextMeshProUGUI names, TextMeshProUGUI numbers, int start, int count) { TextBuilder.Clear(); for (int i = 0; i < count; i++) { TextBuilder.Append(Rows[start + i].Name).Append('\n'); } ((TMP_Text)names).text = TextBuilder.ToString(); TextBuilder.Clear(); bool flag = UpgradeListEnhancePlugin.AdjustNumbers.Value && UpgradeListEnhancePlugin.RewriteNumbersNoBold.Value; for (int j = 0; j < count; j++) { int value = Rows[start + j].Value; if (flag) { TextBuilder.Append(' ').Append(value).Append(" \n"); } else { TextBuilder.Append("").Append(value).Append("\n"); } } ((TMP_Text)numbers).text = TextBuilder.ToString(); } private static void ApplyLayout(TextMeshProUGUI names, TextMeshProUGUI numbers, TextMeshProUGUI? header) { if (UpgradeListEnhancePlugin.AdjustNames.Value) { float num = (((TMP_Text)names).fontSize = UpgradeListEnhancePlugin.NameFontSize.Value); ((TMP_Text)names).lineSpacing = UpgradeListEnhancePlugin.NameLineSpacing.Value; if ((Object)(object)header != (Object)null) { ((TMP_Text)header).fontSize = num + UpgradeListEnhancePlugin.HeaderOffset.Value; } } if (UpgradeListEnhancePlugin.AdjustNumbers.Value) { float num2 = (UpgradeListEnhancePlugin.AdjustNames.Value ? UpgradeListEnhancePlugin.NameFontSize.Value : ((TMP_Text)names).fontSize); ((TMP_Text)numbers).fontSize = num2 + UpgradeListEnhancePlugin.NumberFontSizeOffset.Value; ((TMP_Text)numbers).lineSpacing = UpgradeListEnhancePlugin.NumberLineSpacing.Value; } } private static void UpdateHeader(TextMeshProUGUI? header) { if (!((Object)(object)header == (Object)null)) { string text = UpgradeListEnhancePlugin.HeaderEnglish.Value; if (string.IsNullOrEmpty(text)) { text = "UPGRADES"; } if (!UpgradeListEnhancePlugin.ShowPageInHeader.Value || PageCount <= 1) { ((TMP_Text)header).text = text; } else { ((TMP_Text)header).text = $"{text} ({_pageIndex + 1}/{PageCount})"; } } } private static int ComputePageCount(int rowCount) { if (!UpgradeListEnhancePlugin.EnablePaging.Value || rowCount <= 0) { return 1; } int num = Mathf.Max(1, UpgradeListEnhancePlugin.PageSize.Value); if (rowCount <= num) { return 1; } return (rowCount + num - 1) / num; } } } namespace GastrodonGroup.UpgradeListEnhance.Behaviours { internal sealed class UpgradeListPager : MonoBehaviour { private float _cycleTimer; internal static UpgradeListPager? Instance { get; private set; } private void Awake() { Instance = this; _cycleTimer = UpgradeListEnhancePlugin.PageCycleSeconds.Value; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { if (!UpgradeListEnhancePlugin.EnableAlign.Value || !UpgradeListEnhancePlugin.EnablePaging.Value || StatsUIAlignPatch.PageCount <= 1) { return; } StatsUI instance = StatsUI.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.upgradesHeader == (Object)null) && ((Behaviour)instance.upgradesHeader).enabled) { _cycleTimer -= Time.deltaTime; if (!(_cycleTimer > 0f)) { _cycleTimer = UpgradeListEnhancePlugin.PageCycleSeconds.Value; StatsUIAlignPatch.AdvancePage(instance); } } } internal void ResetTimer() { _cycleTimer = UpgradeListEnhancePlugin.PageCycleSeconds.Value; } internal static void Ensure() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)Instance != (Object)null)) { GameObject val = new GameObject("UpgradeListEnhancePager"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent(); } } } }