Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TextUpgradesUIScale v1.4.1
TextUpgradesUIScale.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using TextUpgradesUIScale.Patches; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("TextUpgradesUIScale")] [assembly: AssemblyDescription("Resizes the R.E.P.O. upgrades UI text for large upgrade lists.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("DarkSpider90")] [assembly: AssemblyProduct("TextUpgradesUIScale")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a27adabc-310b-43d6-8584-f2e1ec7a34cb")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("1.2.1.0")] [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; } } } namespace TextUpgradesUIScale { [BepInPlugin("DarkSpider90.TextUpgradesUIScale", "TextUpgradesUIScale", "1.4.1")] public class Plugin : BaseUnityPlugin { private const string ModGuid = "DarkSpider90.TextUpgradesUIScale"; private const string ModName = "TextUpgradesUIScale"; private const string ModVersion = "1.4.1"; private readonly Harmony harmony = new Harmony("DarkSpider90.TextUpgradesUIScale"); internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<bool> ModEnabled { get; private set; } internal static ConfigEntry<int> StartShrinkingAfterUpgradesCount { get; private set; } internal static ConfigEntry<int> ShrinkEveryUpgrades { get; private set; } internal static ConfigEntry<float> ShrinkStep { get; private set; } internal static ConfigEntry<float> LineSpacing { get; private set; } internal static ConfigEntry<float> MaxTextWidthBeforeShrinking { get; private set; } internal static ConfigEntry<float> MinimumTextScale { get; private set; } internal static ConfigEntry<bool> AlignColumns { get; private set; } internal static ConfigEntry<float> NameColumnOffset { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; BindConfig(); Log.LogInfo((object)"Loaded TextUpgradesUIScale 1.4.1 for R.E.P.O. v0.5.0 UI."); harmony.PatchAll(typeof(StatsUIPatch)); } private void BindConfig() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable the mod."); StartShrinkingAfterUpgradesCount = ((BaseUnityPlugin)this).Config.Bind<int>("Text fitting", "StartShrinkingAfterUpgradesCount", 10, new ConfigDescription("Start shrinking text after this many active upgrades.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ShrinkEveryUpgrades = ((BaseUnityPlugin)this).Config.Bind<int>("Text fitting", "ShrinkEveryUpgrades", 2, new ConfigDescription("Shrink text once per this many additional upgrades.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); ShrinkStep = ((BaseUnityPlugin)this).Config.Bind<float>("Text fitting", "ShrinkStep", 0.07f, new ConfigDescription("Text scale removed per shrink step. 0.07 means 7%.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), Array.Empty<object>())); MinimumTextScale = ((BaseUnityPlugin)this).Config.Bind<float>("Text fitting", "MinimumTextScale", 0.45f, new ConfigDescription("The smallest the text is allowed to get, as a share of its normal size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); AlignColumns = ((BaseUnityPlugin)this).Config.Bind<bool>("Layout", "AlignColumns", true, "Draw each upgrade's level and name on one line so they always line up. The game draws them as two separate columns, which drift apart when a language uses a taller font than the digits do."); NameColumnOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "NameColumnOffset", 1.5f, new ConfigDescription("How far from the left the upgrade names start, in character widths. Only used when AlignColumns is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>())); LineSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "LineSpacing", -4f, new ConfigDescription("Extra vertical spacing between upgrade rows while scaled. Negative values make the list tighter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-30f, 30f), Array.Empty<object>())); MaxTextWidthBeforeShrinking = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "MaxTextWidthBeforeShrinking", 0f, new ConfigDescription("Shrink text if the upgrade names become wider than this value. Set to 0 to disable width-based shrinking.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2000f), Array.Empty<object>())); } } } namespace TextUpgradesUIScale.Patches { [HarmonyPatch(typeof(StatsUI), "Fetch")] public static class StatsUIPatch { private const float TechnicalMinimumScale = 0.05f; private static readonly FieldInfo TextField = AccessTools.Field(typeof(StatsUI), "Text"); private static readonly FieldInfo NumbersTextField = AccessTools.Field(typeof(StatsUI), "textNumbers"); private static readonly FieldInfo PlayerUpgradesField = AccessTools.Field(typeof(StatsUI), "playerUpgrades"); private static TextMeshProUGUI _cachedMainText; private static TextMeshProUGUI _cachedNumbersText; private static float _defaultFontSize; private static float _defaultNumbersFontSize; private static bool _defaultAutoSizing; private static bool _defaultNumbersAutoSizing; private static TextWrappingModes _defaultWrappingMode; private static TextWrappingModes _defaultNumbersWrappingMode; private static TextOverflowModes _defaultOverflowMode; private static TextOverflowModes _defaultNumbersOverflowMode; private static VerticalAlignmentOptions _defaultVerticalAlignment; private static VerticalAlignmentOptions _defaultNumbersVerticalAlignment; private static float _defaultLineSpacing; private static float _defaultNumbersLineSpacing; private static bool _defaultFontSizeInitialized; private static bool _loggedMissingFields; private static bool _loggedException; private static bool _loggedFittingNumbers; private const char LineBreak = '\n'; public static void Postfix(StatsUI __instance) { try { TextMeshProUGUI val = (TextMeshProUGUI)((TextField == null) ? null : /*isinst with value type is only supported in some contexts*/); TextMeshProUGUI val2 = (TextMeshProUGUI)((NumbersTextField == null) ? null : /*isinst with value type is only supported in some contexts*/); Dictionary<string, int> dictionary = ((PlayerUpgradesField == null) ? null : (PlayerUpgradesField.GetValue(__instance) as Dictionary<string, int>)); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || dictionary == null) { LogMissingFieldsOnce(); return; } CaptureDefaultsIfNeeded(val, val2); if (!Plugin.ModEnabled.Value) { RestoreTextColumns(val, val2); return; } if (Plugin.AlignColumns.Value) { MergeColumns(val, val2); } float scaleForUpgradeCount = GetScaleForUpgradeCount(CountActiveUpgrades(dictionary)); scaleForUpgradeCount = ApplyWidthLimit(val, scaleForUpgradeCount); ReportFittingNumbersOnce(val, scaleForUpgradeCount); if (scaleForUpgradeCount >= 0.999f) { RestoreTextColumns(val, val2); return; } ConfigureTextColumn(val, _defaultLineSpacing); ConfigureTextColumn(val2, _defaultNumbersLineSpacing); ((TMP_Text)val).fontSize = _defaultFontSize * scaleForUpgradeCount; ((TMP_Text)val2).fontSize = _defaultNumbersFontSize * scaleForUpgradeCount; } catch (Exception ex) { if (!_loggedException) { _loggedException = true; if (Plugin.Log != null) { Plugin.Log.LogWarning((object)("[TextUpgradesUIScale] Failed to resize StatsUI text: " + ex.Message)); } } } } private static void CaptureDefaultsIfNeeded(TextMeshProUGUI mainText, TextMeshProUGUI numbersText) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (!_defaultFontSizeInitialized || !((Object)(object)_cachedMainText == (Object)(object)mainText) || !((Object)(object)_cachedNumbersText == (Object)(object)numbersText)) { _cachedMainText = mainText; _cachedNumbersText = numbersText; _defaultFontSize = ((TMP_Text)mainText).fontSize; _defaultNumbersFontSize = ((TMP_Text)numbersText).fontSize; _defaultAutoSizing = ((TMP_Text)mainText).enableAutoSizing; _defaultNumbersAutoSizing = ((TMP_Text)numbersText).enableAutoSizing; _defaultWrappingMode = ((TMP_Text)mainText).textWrappingMode; _defaultNumbersWrappingMode = ((TMP_Text)numbersText).textWrappingMode; _defaultOverflowMode = ((TMP_Text)mainText).overflowMode; _defaultNumbersOverflowMode = ((TMP_Text)numbersText).overflowMode; _defaultVerticalAlignment = ((TMP_Text)mainText).verticalAlignment; _defaultNumbersVerticalAlignment = ((TMP_Text)numbersText).verticalAlignment; _defaultLineSpacing = ((TMP_Text)mainText).lineSpacing; _defaultNumbersLineSpacing = ((TMP_Text)numbersText).lineSpacing; _defaultFontSizeInitialized = true; } } private static void MergeColumns(TextMeshProUGUI mainText, TextMeshProUGUI numbersText) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) string text = ((TMP_Text)mainText).text; string text2 = ((TMP_Text)numbersText).text; if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2)) { return; } string[] array = text.Split('\n'); string[] array2 = text2.Split('\n'); int num = Mathf.Min(array.Length, array2.Length); StringBuilder stringBuilder = new StringBuilder(text.Length + text2.Length + num * 32); float num2 = Mathf.Max(0.5f, Plugin.NameColumnOffset.Value); string value = ColorUtility.ToHtmlStringRGB(((Graphic)numbersText).color); for (int i = 0; i < num; i++) { string value2 = array[i]; if (!string.IsNullOrEmpty(value2)) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append("<color=#").Append(value).Append('>') .Append(array2[i]) .Append("</color>") .Append("<pos=") .Append(num2.ToString("0.##", CultureInfo.InvariantCulture)) .Append("em>") .Append(value2); } } ((TMP_Text)mainText).text = stringBuilder.ToString(); ((TMP_Text)numbersText).text = string.Empty; } private static int CountActiveUpgrades(Dictionary<string, int> playerUpgrades) { int num = 0; foreach (KeyValuePair<string, int> playerUpgrade in playerUpgrades) { if (playerUpgrade.Value > 0) { num++; } } return num; } private static void ConfigureTextColumn(TextMeshProUGUI text, float defaultLineSpacing) { ((TMP_Text)text).enableAutoSizing = false; ((TMP_Text)text).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)text).overflowMode = (TextOverflowModes)0; ((TMP_Text)text).verticalAlignment = (VerticalAlignmentOptions)256; ((TMP_Text)text).lineSpacing = defaultLineSpacing + Plugin.LineSpacing.Value; } private static void RestoreTextColumns(TextMeshProUGUI mainText, TextMeshProUGUI numbersText) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) RestoreTextColumn(mainText, _defaultFontSize, _defaultAutoSizing, _defaultWrappingMode, _defaultOverflowMode, _defaultVerticalAlignment, _defaultLineSpacing); RestoreTextColumn(numbersText, _defaultNumbersFontSize, _defaultNumbersAutoSizing, _defaultNumbersWrappingMode, _defaultNumbersOverflowMode, _defaultNumbersVerticalAlignment, _defaultNumbersLineSpacing); } private static void RestoreTextColumn(TextMeshProUGUI text, float fontSize, bool autoSizing, TextWrappingModes wrappingMode, TextOverflowModes overflowMode, VerticalAlignmentOptions verticalAlignment, float lineSpacing) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)text).fontSize = fontSize; ((TMP_Text)text).enableAutoSizing = autoSizing; ((TMP_Text)text).textWrappingMode = wrappingMode; ((TMP_Text)text).overflowMode = overflowMode; ((TMP_Text)text).verticalAlignment = verticalAlignment; ((TMP_Text)text).lineSpacing = lineSpacing; } private static float GetScaleForUpgradeCount(int activeUpgradesCount) { int num = Mathf.Max(0, Plugin.StartShrinkingAfterUpgradesCount.Value); if (activeUpgradesCount <= num) { return 1f; } int num2 = Mathf.Max(1, Plugin.ShrinkEveryUpgrades.Value); float num3 = Mathf.Clamp(Plugin.ShrinkStep.Value, 0.01f, 0.5f); int num4 = Mathf.CeilToInt((float)Mathf.Max(0, activeUpgradesCount - num) / (float)num2); return ClampScale(1f - (float)num4 * num3); } private static float ApplyWidthLimit(TextMeshProUGUI mainText, float currentScale) { //IL_003e: 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) float value = Plugin.MaxTextWidthBeforeShrinking.Value; if (value <= 1f) { return currentScale; } ConfigureTextColumn(mainText, _defaultLineSpacing); ((TMP_Text)mainText).fontSize = _defaultFontSize * currentScale; if (((TMP_Text)mainText).GetPreferredValues(((TMP_Text)mainText).text, float.PositiveInfinity, float.PositiveInfinity).x <= value) { return currentScale; } float num = MinimumScale(); float num2 = currentScale; for (int i = 0; i < 8; i++) { float num3 = (num + num2) * 0.5f; ((TMP_Text)mainText).fontSize = _defaultFontSize * num3; if (((TMP_Text)mainText).GetPreferredValues(((TMP_Text)mainText).text, float.PositiveInfinity, float.PositiveInfinity).x <= value) { num = num3; } else { num2 = num3; } } return ClampScale(num); } private static void ReportFittingNumbersOnce(TextMeshProUGUI mainText, float scale) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!_loggedFittingNumbers && Plugin.Log != null) { _loggedFittingNumbers = true; Rect rect = ((TMP_Text)mainText).rectTransform.rect; float height = ((Rect)(ref rect)).height; Transform parent = ((Transform)((TMP_Text)mainText).rectTransform).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); float num; if (!((Object)(object)val != (Object)null)) { num = -1f; } else { rect = val.rect; num = ((Rect)(ref rect)).height; } float num2 = num; float num3 = MeasuredHeight(mainText, scale); ((TMP_Text)mainText).fontSize = _defaultFontSize * scale; Plugin.Log.LogInfo((object)($"[TextUpgradesUIScale] Column rect={height:F1}, parent rect={num2:F1}, " + $"rendered={num3:F1} at scale {scale:F2}, lines={CountLines(((TMP_Text)mainText).text)}.")); } } private static int CountLines(string text) { if (string.IsNullOrEmpty(text)) { return 0; } int num = 1; for (int i = 0; i < text.Length; i++) { if (text[i] == '\n') { num++; } } return num; } private static float MeasuredHeight(TextMeshProUGUI text, float scale) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)text).fontSize = _defaultFontSize * scale; return ((TMP_Text)text).GetPreferredValues(((TMP_Text)text).text, float.PositiveInfinity, float.PositiveInfinity).y; } private static float MinimumScale() { return Mathf.Clamp(Plugin.MinimumTextScale.Value, 0.05f, 1f); } private static float ClampScale(float scale) { return Mathf.Clamp(scale, MinimumScale(), 1f); } private static void LogMissingFieldsOnce() { if (!_loggedMissingFields) { _loggedMissingFields = true; if (Plugin.Log != null) { Plugin.Log.LogWarning((object)"[TextUpgradesUIScale] Could not access StatsUI text fields. The game UI may have changed."); } } } } }