Decompiled source of SimpleUITweaks v1.1.1

SimpleUITweaks.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Assets.Scripts.Actors;
using Assets.Scripts.Actors.Enemies;
using Assets.Scripts.Actors.Player;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Inventory__Items__Pickups;
using Inventory__Items__Pickups.Xp_and_Levels;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SimpleUITweaks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SimpleUITweaks")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("50d8afb3-3515-40d2-84f1-ff17938f5516")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 SUIT
{
	[BepInPlugin("com.maskoliver.suit", "Simple UI Tweaks (SUIT)", "1.1.1")]
	public sealed class BepInEntry : BasePlugin
	{
		private sealed class UpdateDriver : MonoBehaviour
		{
			public UpdateDriver(IntPtr ptr)
				: base(ptr)
			{
			}

			private void Start()
			{
				try
				{
					_core = new SuitCore();
					_core.Init();
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogError((object)ex);
					}
				}
			}

			private void Update()
			{
				_core?.UpdateLoop();
			}

			private void OnDestroy()
			{
				_core?.Deinit();
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"SUIT_UpdateHost destroyed");
				}
			}
		}

		private Harmony _harmony;

		internal static ManualLogSource Log;

		private static GameObject _host;

		private static SuitCore _core;

		public override void Load()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			Log = Logger.CreateLogSource("SUIT");
			LoggerBridge.Info = delegate(string s)
			{
				Log.LogInfo((object)s);
			};
			LoggerBridge.Warn = delegate(string s)
			{
				Log.LogWarning((object)s);
			};
			LoggerBridge.Error = delegate(string s)
			{
				Log.LogError((object)s);
			};
			ClassInjector.RegisterTypeInIl2Cpp<UpdateDriver>();
			_host = new GameObject("SUIT_UpdateHost");
			Object.DontDestroyOnLoad((Object)(object)_host);
			((Object)_host).hideFlags = (HideFlags)61;
			_host.AddComponent<UpdateDriver>();
			_harmony = new Harmony("com.maskoliver.suit");
			_harmony.PatchAll();
			Log.LogInfo((object)"SUIT (BepInEx) loaded.");
		}
	}
	internal static class LoggerBridge
	{
		public static Action<string> Info = delegate
		{
		};

		public static Action<string> Warn = delegate
		{
		};

		public static Action<string> Error = delegate
		{
		};
	}
	internal static class PathsBridge
	{
		public static string UserDataDir => Paths.ConfigPath;
	}
	public sealed class SuitCore
	{
		private sealed class PrefsShim
		{
			public float Scale = 1f;

			public bool Hidden;

			public bool ShowXpBar = true;

			public bool ShowTimerStage = true;

			public bool ShowLevel = true;

			public bool ShowChestPrice = true;

			public bool ShowKillsAndGold = true;

			public bool ShowInventory = true;

			public bool ShowGold = true;

			public bool ShowSilver = true;

			public bool ShowKills = true;

			public bool ShowDps = true;
		}

		private struct DmgEvt
		{
			public float t;

			public float dmg;
		}

		private readonly PrefsShim _prefs = new PrefsShim();

		private const string PublicCfgFileName = "SUIT.SimpleUITweaks.cfg";

		private const string AnnotMarker = "# Simple UI Tweaks (SUIT) configuration";

		private static readonly UTF8Encoding Utf8NoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		private Transform _top;

		private int _topInstanceId = -1;

		private float _scale = 1f;

		private bool _hidden;

		private bool _invPinned;

		private bool _invOffsetApplied;

		private Vector2 _invBaseAnchored;

		private const float INVENTORY_Y_OFFSET = -45f;

		private Transform _killsAndGold;

		private int _kgInstanceId = -1;

		private bool _kgAugmented;

		private Transform _dpsT;

		private Transform _xpBarOuter;

		private int _xpBarInstanceId = -1;

		private Transform _xpText;

		private bool _xpTextReady;

		private string _lastXpText;

		private float _lastXpLabelTick = -1f;

		private const float XP_LABEL_THROTTLE = 0.1f;

		private const float XP_TEXT_UNIFORM_FACTOR = 0.9f;

		private const float XP_AUTOSIZE_MIN_FACTOR = 0.6f;

		private const float XP_AUTOSIZE_MAX_FACTOR = 0.85f;

		private Transform _timerStage;

		private Transform _tLevel;

		private Transform _tChestPrice;

		private bool _showXpBar;

		private bool _showTimerStage;

		private bool _showLevel;

		private bool _showChestPrice;

		private bool _showKillsAndGold;

		private bool _showInventory;

		private bool _showGold;

		private bool _showSilver;

		private bool _showKills;

		private bool _showDps;

		private readonly Dictionary<string, bool> _childEnabled = new Dictionary<string, bool>(StringComparer.Ordinal);

		private readonly List<Transform> _childOrder = new List<Transform>();

		private readonly Dictionary<int, string> _indexToName = new Dictionary<int, string>();

		private static readonly string[] KnownPaths = new string[4] { "GameUI/GameUI/HUD/Top", "GameUI/HUD/Top", "HUD/Top", "Top" };

		private static readonly Color32 DPS_COLOR = new Color32(byte.MaxValue, (byte)170, (byte)64, byte.MaxValue);

		private static readonly Color32 XP_TEXT_COLOR = new Color32(byte.MaxValue, (byte)212, (byte)64, byte.MaxValue);

		private readonly List<DmgEvt> _dmg = new List<DmgEvt>();

		private float _rawDps;

		private float _smoothDps;

		private float _lastDpsRecalc = -1f;

		private float _lastDpsDisplay = -1f;

		private const float DPS_WINDOW = 3f;

		private const float DPS_RECALC_THROTTLE = 0.1f;

		private const float DPS_DISPLAY_THROTTLE = 0.066f;

		private const float DPS_SMOOTH = 60f;

		private float _heartbeatNext = -1f;

		private static string PublicCfgPath => Path.Combine(PathsBridge.UserDataDir, "SUIT.SimpleUITweaks.cfg");

		public SuitCore()
		{
			SuitCoreAccess.Instance = this;
		}

		public void Init()
		{
			if (File.Exists(PublicCfgPath))
			{
				if (!TryParsePublicConfig(PublicCfgPath))
				{
					LoggerBridge.Warn("[SUIT] Config parse failed; using defaults.");
					ResetToFactoryDefaults();
				}
			}
			else
			{
				ResetToFactoryDefaults();
			}
			MirrorFieldsToPrefs();
			WriteAnnotatedPublicCfg();
			ApplyAll();
			LoggerBridge.Info("[SUIT] Public cfg: " + PublicCfgPath);
			_heartbeatNext = Time.realtimeSinceStartup + 0.5f;
		}

		public void UpdateLoop()
		{
			HandleKeysAndHotReload();
			TickHeartbeat();
			TickDpsXp();
		}

		public void Deinit()
		{
		}

		private void HandleKeysAndHotReload()
		{
			if (IsCtrl() && Input.GetKeyDown((KeyCode)273))
			{
				_scale = Mathf.Clamp(_scale + 0.05f, 0.1f, 5f);
				LoggerBridge.Info($"[SUIT] Scale = {_scale:0.00}");
				ApplyAll();
				MirrorFieldsToPrefs();
				WriteAnnotatedPublicCfg();
			}
			if (IsCtrl() && Input.GetKeyDown((KeyCode)274))
			{
				_scale = Mathf.Clamp(_scale - 0.05f, 0.1f, 5f);
				LoggerBridge.Info($"[SUIT] Scale = {_scale:0.00}");
				ApplyAll();
				MirrorFieldsToPrefs();
				WriteAnnotatedPublicCfg();
			}
			if (IsCtrl() && Input.GetKeyDown((KeyCode)114))
			{
				if (TryParsePublicConfig(PublicCfgPath))
				{
					ApplyAll();
					MirrorFieldsToPrefs();
					LoggerBridge.Info("[SUIT] Hot reloaded (public cfg).");
				}
				else
				{
					LoggerBridge.Warn("[SUIT] Hot reload failed: parse error in public cfg.");
				}
				return;
			}
			if (!IsCtrl() && Input.GetKeyDown((KeyCode)114))
			{
				RescanTop();
				if ((Object)(object)_top != (Object)null)
				{
					BuildChildIndex();
				}
				EnsureKillsAndGoldExtras();
				EnsureXpBarLabel(forceCheck: true);
				ApplyAll();
			}
			if (Input.GetKeyDown((KeyCode)104))
			{
				_hidden = !_hidden;
				LoggerBridge.Info("[SUIT] " + (_hidden ? "Hiding" : "Showing") + " all");
				ApplyAll();
				MirrorFieldsToPrefs();
				WriteAnnotatedPublicCfg();
			}
			if (IsCtrl() && TryGetDigitPressed(out var idx))
			{
				HandleShortcut(idx);
				ApplyAll();
				MirrorFieldsToPrefs();
				WriteAnnotatedPublicCfg();
			}
		}

		private void HandleShortcut(int idx)
		{
			switch (idx)
			{
			case 1:
				_showXpBar = !_showXpBar;
				LoggerBridge.Info("[SUIT] XpBarOuter -> " + (_showXpBar ? "ON" : "OFF"));
				break;
			case 2:
				_showTimerStage = !_showTimerStage;
				LoggerBridge.Info("[SUIT] t_Timer_Stage -> " + (_showTimerStage ? "ON" : "OFF"));
				break;
			case 3:
			{
				bool flag = (_showChestPrice = (_showLevel = !_showLevel || !_showChestPrice));
				LoggerBridge.Info("[SUIT] T_Level + T_ChestPrice -> " + (flag ? "ON" : "OFF") + " (pair)");
				break;
			}
			case 4:
				_showKillsAndGold = !_showKillsAndGold;
				LoggerBridge.Info("[SUIT] KillsAndGold -> " + (_showKillsAndGold ? "ON" : "OFF"));
				break;
			case 5:
				_showInventory = !_showInventory;
				LoggerBridge.Info("[SUIT] Inventory -> " + (_showInventory ? "ON" : "OFF"));
				break;
			}
		}

		private static bool IsCtrl()
		{
			if (!Input.GetKey((KeyCode)306))
			{
				return Input.GetKey((KeyCode)305);
			}
			return true;
		}

		private static bool TryGetDigitPressed(out int idx)
		{
			if (Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)257))
			{
				idx = 1;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)258))
			{
				idx = 2;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)51) || Input.GetKeyDown((KeyCode)259))
			{
				idx = 3;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)52) || Input.GetKeyDown((KeyCode)260))
			{
				idx = 4;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)53) || Input.GetKeyDown((KeyCode)261))
			{
				idx = 5;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)54) || Input.GetKeyDown((KeyCode)262))
			{
				idx = 6;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)55) || Input.GetKeyDown((KeyCode)263))
			{
				idx = 7;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)56) || Input.GetKeyDown((KeyCode)264))
			{
				idx = 8;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)57) || Input.GetKeyDown((KeyCode)265))
			{
				idx = 9;
				return true;
			}
			if (Input.GetKeyDown((KeyCode)48) || Input.GetKeyDown((KeyCode)256))
			{
				idx = 10;
				return true;
			}
			idx = 0;
			return false;
		}

		private void TickHeartbeat()
		{
			if (Time.realtimeSinceStartup < _heartbeatNext)
			{
				return;
			}
			_heartbeatNext = Time.realtimeSinceStartup + 0.5f;
			try
			{
				if ((Object)(object)_top == (Object)null)
				{
					Transform val = FindTopByKnownPaths();
					if ((Object)(object)val != (Object)null)
					{
						_top = val;
						_topInstanceId = ((Object)((Component)val).gameObject).GetInstanceID();
						_invPinned = false;
						_invOffsetApplied = false;
						_timerStage = null;
						_tLevel = null;
						_tChestPrice = null;
						ResetRuntimeStats();
						BuildChildIndex();
						LoggerBridge.Info("[SUIT] Top found: " + Hierarchy(_top));
					}
				}
				EnsureKillsAndGoldExtras();
				EnsureXpBarLabel(forceCheck: true);
				ApplyAll();
			}
			catch (Exception ex)
			{
				LoggerBridge.Warn("[SUIT] Heartbeat non-fatal: " + ex.Message);
			}
		}

		private void TickDpsXp()
		{
			if (!((Object)(object)_top == (Object)null))
			{
				UpdateDps();
				if (_showKillsAndGold)
				{
					UpdateCountersUI();
				}
				if (_showXpBar)
				{
					UpdateXpBarLabel();
				}
			}
		}

		private void ApplyAll()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_top == (Object)null)
			{
				return;
			}
			Vector3 val = default(Vector3);
			Vector3 val3 = default(Vector3);
			Vector3 val4 = default(Vector3);
			Vector3 val5 = default(Vector3);
			Vector3 val6 = default(Vector3);
			for (int i = 0; i < _top.childCount; i++)
			{
				Transform child = _top.GetChild(i);
				if ((Object)(object)child == (Object)null)
				{
					continue;
				}
				string name = ((Object)child).name;
				if (name == "XpBarOuter")
				{
					bool flag = !_hidden && _showXpBar;
					if (((Component)child).gameObject.activeSelf != flag)
					{
						((Component)child).gameObject.SetActive(flag);
					}
					if (!flag)
					{
						continue;
					}
					RectTransform component = ((Component)child).GetComponent<RectTransform>();
					((Vector3)(ref val))..ctor(1f, _scale, 1f);
					if ((Object)(object)component != (Object)null)
					{
						if (((Transform)component).localScale != val)
						{
							((Transform)component).localScale = val;
						}
					}
					else if (child.localScale != val)
					{
						child.localScale = val;
					}
					Transform val2 = child.Find("XpText");
					if ((Object)(object)val2 == (Object)null || (Object)(object)_xpText == (Object)null)
					{
						_xpBarOuter = child;
						_xpBarInstanceId = ((Object)((Component)child).gameObject).GetInstanceID();
						_xpText = null;
						_xpTextReady = false;
						EnsureXpBarLabel(forceCheck: true);
						val2 = child.Find("XpText");
					}
					if (!((Object)(object)val2 != (Object)null))
					{
						continue;
					}
					float num = Mathf.Max(0.01f, _scale);
					float num2 = num * 0.9f;
					((Vector3)(ref val3))..ctor(num2, num2 / num, 1f);
					RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
					if ((Object)(object)component2 != (Object)null)
					{
						if (((Transform)component2).localScale != val3)
						{
							((Transform)component2).localScale = val3;
						}
					}
					else if (val2.localScale != val3)
					{
						val2.localScale = val3;
					}
					continue;
				}
				if (name == "Inventory")
				{
					bool flag2 = !_hidden && _showInventory;
					if (((Component)child).gameObject.activeSelf != flag2)
					{
						((Component)child).gameObject.SetActive(flag2);
					}
					if (!flag2)
					{
						continue;
					}
					RectTransform component3 = ((Component)child).GetComponent<RectTransform>();
					if ((Object)(object)component3 != (Object)null)
					{
						EnsureInventoryAnchorsPivot(component3);
						((Vector3)(ref val4))..ctor(_scale, _scale, 1f);
						if (((Transform)component3).localScale != val4)
						{
							((Transform)component3).localScale = val4;
						}
						if (_invPinned && component3.anchoredPosition != _invBaseAnchored)
						{
							component3.anchoredPosition = _invBaseAnchored;
						}
					}
					else
					{
						((Vector3)(ref val5))..ctor(_scale, _scale, 1f);
						if (child.localScale != val5)
						{
							child.localScale = val5;
						}
					}
					continue;
				}
				bool flag3 = !_hidden && IsChildEnabled(name);
				if (((Component)child).gameObject.activeSelf != flag3)
				{
					((Component)child).gameObject.SetActive(flag3);
				}
				if (!flag3)
				{
					continue;
				}
				((Vector3)(ref val6))..ctor(_scale, _scale, 1f);
				RectTransform component4 = ((Component)child).GetComponent<RectTransform>();
				if ((Object)(object)component4 != (Object)null)
				{
					if (((Transform)component4).localScale != val6)
					{
						((Transform)component4).localScale = val6;
					}
				}
				else if (child.localScale != val6)
				{
					child.localScale = val6;
				}
			}
			if ((Object)(object)_timerStage == (Object)null)
			{
				_timerStage = FindUnderTop("t_Timer_Stage");
			}
			if ((Object)(object)_timerStage != (Object)null)
			{
				((Component)_timerStage).gameObject.SetActive(!_hidden && _showTimerStage);
			}
			if ((Object)(object)_tLevel == (Object)null)
			{
				_tLevel = FindUnderTop("T_Level") ?? FindUnderTop("t_Level");
			}
			if ((Object)(object)_tChestPrice == (Object)null)
			{
				_tChestPrice = FindUnderTop("T_ChestPrice") ?? FindUnderTop("t_ChestPrice");
			}
			bool active = !_hidden && _showLevel;
			bool active2 = !_hidden && _showChestPrice;
			if ((Object)(object)_tLevel != (Object)null)
			{
				((Component)_tLevel).gameObject.SetActive(active);
			}
			if ((Object)(object)_tChestPrice != (Object)null)
			{
				((Component)_tChestPrice).gameObject.SetActive(active2);
			}
			EnsureKillsAndGoldExtras();
			if ((Object)(object)_killsAndGold != (Object)null)
			{
				bool flag4 = !_hidden && _showKillsAndGold;
				if (((Component)_killsAndGold).gameObject.activeSelf != flag4)
				{
					((Component)_killsAndGold).gameObject.SetActive(flag4);
				}
				if (flag4)
				{
					ApplyKillsAndGoldVisibility();
				}
			}
		}

		private void EnsureInventoryAnchorsPivot(RectTransform rtInv)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0050: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00ad: 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)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			bool flag = false;
			if (rtInv.anchorMin != val)
			{
				rtInv.anchorMin = val;
				flag = true;
			}
			if (rtInv.anchorMax != val)
			{
				rtInv.anchorMax = val;
				flag = true;
			}
			if (rtInv.pivot != val)
			{
				rtInv.pivot = val;
				flag = true;
			}
			if ((!_invPinned || flag) && rtInv.anchorMin == val && rtInv.anchorMax == val && rtInv.pivot == val)
			{
				if (!_invOffsetApplied)
				{
					_invBaseAnchored = rtInv.anchoredPosition + new Vector2(0f, -45f);
					_invOffsetApplied = true;
				}
				rtInv.anchoredPosition = _invBaseAnchored;
				_invPinned = true;
			}
		}

		private void EnsureKillsAndGoldExtras()
		{
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_top == (Object)null)
			{
				return;
			}
			if ((Object)(object)_killsAndGold == (Object)null)
			{
				_killsAndGold = FindKillsAndGoldUnderTop();
				if ((Object)(object)_killsAndGold != (Object)null)
				{
					_kgInstanceId = ((Object)((Component)_killsAndGold).gameObject).GetInstanceID();
					_kgAugmented = false;
					_dpsT = null;
				}
			}
			else
			{
				int instanceID = ((Object)((Component)_killsAndGold).gameObject).GetInstanceID();
				if (instanceID != _kgInstanceId)
				{
					_kgInstanceId = instanceID;
					_kgAugmented = false;
					_dpsT = null;
				}
			}
			if ((Object)(object)_killsAndGold == (Object)null)
			{
				return;
			}
			Transform val = _killsAndGold.Find("DPS");
			int siblingIndex = _killsAndGold.childCount;
			Transform val2 = _killsAndGold.Find("Kills");
			if ((Object)(object)val2 != (Object)null)
			{
				siblingIndex = val2.GetSiblingIndex() + 1;
			}
			if ((Object)(object)val != (Object)null && !_kgAugmented)
			{
				val.SetSiblingIndex(siblingIndex);
				_kgAugmented = true;
				_dpsT = val;
				LoggerBridge.Info("[SUIT] Reordered DPS after Kills.");
				return;
			}
			if (_kgAugmented)
			{
				if ((Object)(object)_dpsT == (Object)null)
				{
					_dpsT = _killsAndGold.Find("DPS");
				}
				return;
			}
			Transform val3 = val2 ?? _killsAndGold.Find("Gold");
			if ((Object)(object)val3 == (Object)null && _killsAndGold.childCount > 0)
			{
				val3 = _killsAndGold.GetChild(_killsAndGold.childCount - 1);
			}
			if ((Object)(object)val3 == (Object)null)
			{
				LoggerBridge.Warn("[SUIT] KillsAndGold has no cloneable children; skipping DPS.");
				_kgAugmented = true;
				return;
			}
			try
			{
				if ((Object)(object)val == (Object)null)
				{
					GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, _killsAndGold);
					((Object)val4).name = "DPS";
					SetAnyTextAndColor(val4.transform, "DPS: 0.0", DPS_COLOR);
					val4.transform.SetSiblingIndex(siblingIndex);
					_dpsT = val4.transform;
				}
				else
				{
					val.SetSiblingIndex(siblingIndex);
					_dpsT = val;
				}
			}
			catch (Exception ex)
			{
				LoggerBridge.Warn("[SUIT] KillsAndGold clone failed: " + ex.Message);
				_kgAugmented = true;
				return;
			}
			_kgAugmented = true;
			LoggerBridge.Info("[SUIT] Added DPS after Kills.");
		}

		private Transform FindKillsAndGoldUnderTop()
		{
			Transform top = _top;
			Transform val = ((top != null) ? top.Find("KillsAndGold") : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			int num = 0;
			while (true)
			{
				int num2 = num;
				Transform top2 = _top;
				if (num2 >= ((top2 != null) ? top2.childCount : 0))
				{
					break;
				}
				Transform child = _top.GetChild(num);
				if ((Object)(object)child != (Object)null && ((Object)child).name == "KillsAndGold")
				{
					return child;
				}
				num++;
			}
			string[] array = new string[4] { "GameUI/GameUI/HUD/Top/KillsAndGold", "GameUI/HUD/Top/KillsAndGold", "HUD/Top/KillsAndGold", "Top/KillsAndGold" };
			for (int i = 0; i < array.Length; i++)
			{
				GameObject val2 = GameObject.Find(array[i]);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2.transform;
				}
			}
			return null;
		}

		private void ApplyKillsAndGoldVisibility()
		{
			if (!((Object)(object)_killsAndGold == (Object)null))
			{
				Transform val = _killsAndGold.Find("Kills");
				Transform val2 = _killsAndGold.Find("Gold");
				Transform val3 = _killsAndGold.Find("Silver") ?? _killsAndGold.Find("Sliver");
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(_showKills);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).gameObject.SetActive(_showGold);
				}
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(_showSilver);
				}
				if ((Object)(object)_dpsT == (Object)null)
				{
					_dpsT = _killsAndGold.Find("DPS");
				}
				if ((Object)(object)_dpsT != (Object)null)
				{
					((Component)_dpsT).gameObject.SetActive(_showDps);
				}
			}
		}

		internal void RecordDamage(float dmg)
		{
			if (!(dmg <= 0f))
			{
				_dmg.Add(new DmgEvt
				{
					t = Time.time,
					dmg = dmg
				});
			}
		}

		private void UpdateDps()
		{
			float time = Time.time;
			if (time - _lastDpsRecalc > 0.1f)
			{
				float num = 0f;
				for (int num2 = _dmg.Count - 1; num2 >= 0; num2--)
				{
					if (time - _dmg[num2].t > 3f)
					{
						_dmg.RemoveAt(num2);
					}
					else
					{
						num += _dmg[num2].dmg;
					}
				}
				_rawDps = num / 3f;
				_lastDpsRecalc = time;
			}
			if (time - _lastDpsDisplay > 0.066f)
			{
				_smoothDps = Mathf.Lerp(_smoothDps, _rawDps, Time.deltaTime * 60f);
				if (_smoothDps < 0.01f)
				{
					_smoothDps = 0f;
				}
				_lastDpsDisplay = time;
			}
		}

		private void ResetRuntimeStats()
		{
			_dmg.Clear();
			_rawDps = 0f;
			_smoothDps = 0f;
			_lastDpsRecalc = -1f;
			_lastDpsDisplay = -1f;
		}

		private void UpdateCountersUI()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_killsAndGold == (Object)null) && _showKillsAndGold && _showDps)
			{
				if ((Object)(object)_dpsT == (Object)null)
				{
					_dpsT = _killsAndGold.Find("DPS");
				}
				if ((Object)(object)_dpsT != (Object)null && ((Component)_dpsT).gameObject.activeSelf)
				{
					SetAnyTextAndColor(_dpsT, $"DPS: {_smoothDps:F1}", DPS_COLOR);
				}
			}
		}

		private void EnsureXpBarLabel(bool forceCheck = false)
		{
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_top == (Object)null)
			{
				return;
			}
			if ((Object)(object)_xpBarOuter == (Object)null)
			{
				_xpBarOuter = FindUnderTop("XpBarOuter");
				if ((Object)(object)_xpBarOuter != (Object)null)
				{
					_xpBarInstanceId = ((Object)((Component)_xpBarOuter).gameObject).GetInstanceID();
				}
			}
			else
			{
				int instanceID = ((Object)((Component)_xpBarOuter).gameObject).GetInstanceID();
				if (instanceID != _xpBarInstanceId)
				{
					_xpBarInstanceId = instanceID;
					_xpText = null;
					_xpTextReady = false;
					_lastXpText = null;
				}
			}
			if ((Object)(object)_xpBarOuter == (Object)null || !_showXpBar)
			{
				return;
			}
			if (forceCheck && (Object)(object)_xpBarOuter.Find("XpText") == (Object)null)
			{
				_xpText = null;
				_xpTextReady = false;
			}
			if (_xpTextReady)
			{
				return;
			}
			Transform val = _xpBarOuter.Find("XpText");
			if ((Object)(object)val != (Object)null)
			{
				_xpText = val;
				_xpTextReady = true;
				return;
			}
			Transform val2 = FindFirstTMPTransformUnder(_top);
			GameObject val3;
			if ((Object)(object)val2 != (Object)null)
			{
				val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, _xpBarOuter);
				((Object)val3).name = "XpText";
				RectTransform component = val3.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.anchorMin = Vector2.zero;
					component.anchorMax = Vector2.one;
					component.pivot = new Vector2(0.5f, 0.5f);
					component.anchoredPosition = Vector2.zero;
					component.sizeDelta = Vector2.zero;
					((Transform)component).localScale = Vector3.one;
				}
				TextMeshProUGUI component2 = val3.GetComponent<TextMeshProUGUI>();
				if ((Object)(object)component2 != (Object)null)
				{
					((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
					((TMP_Text)component2).enableWordWrapping = false;
					((Graphic)component2).raycastTarget = false;
					float num = Mathf.Max(8f, ((TMP_Text)component2).fontSize);
					((TMP_Text)component2).enableAutoSizing = true;
					((TMP_Text)component2).fontSizeMin = Mathf.Max(8f, num * 0.6f);
					((TMP_Text)component2).fontSizeMax = Mathf.Max(9f, num * 0.85f);
					((TMP_Text)component2).text = string.Empty;
					((Graphic)component2).color = Color32.op_Implicit(XP_TEXT_COLOR);
				}
				else
				{
					Text val4 = val3.GetComponent<Text>();
					if ((Object)(object)val4 == (Object)null)
					{
						val4 = val3.AddComponent<Text>();
					}
					val4.alignment = (TextAnchor)4;
					((Graphic)val4).raycastTarget = false;
					val4.text = string.Empty;
					((Graphic)val4).color = Color32.op_Implicit(XP_TEXT_COLOR);
					val4.resizeTextForBestFit = true;
					val4.resizeTextMinSize = 8;
					val4.resizeTextMaxSize = 24;
				}
			}
			else
			{
				val3 = new GameObject("XpText");
				RectTransform obj = val3.AddComponent<RectTransform>();
				val3.transform.SetParent(_xpBarOuter, false);
				obj.anchorMin = Vector2.zero;
				obj.anchorMax = Vector2.one;
				obj.pivot = new Vector2(0.5f, 0.5f);
				obj.anchoredPosition = Vector2.zero;
				obj.sizeDelta = Vector2.zero;
				Text val5 = val3.AddComponent<Text>();
				val5.alignment = (TextAnchor)4;
				((Graphic)val5).raycastTarget = false;
				val5.text = string.Empty;
				try
				{
					val5.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
				}
				catch
				{
				}
				((Graphic)val5).color = Color32.op_Implicit(XP_TEXT_COLOR);
				val5.resizeTextForBestFit = true;
				val5.resizeTextMinSize = 8;
				val5.resizeTextMaxSize = 24;
			}
			_xpText = val3.transform;
			_xpTextReady = true;
			float num2 = Mathf.Max(0.01f, _scale);
			float num3 = num2 * 0.9f;
			Vector3 localScale = default(Vector3);
			((Vector3)(ref localScale))..ctor(num3, num3 / num2, 1f);
			RectTransform component3 = ((Component)_xpText).GetComponent<RectTransform>();
			if ((Object)(object)component3 != (Object)null)
			{
				((Transform)component3).localScale = localScale;
			}
			else
			{
				_xpText.localScale = localScale;
			}
		}

		private bool TryGetXpAndCap(out int xp, out int cap)
		{
			xp = 0;
			cap = 0;
			try
			{
				MyPlayer instance = MyPlayer.Instance;
				if ((Object)(object)instance == (Object)null || instance.inventory == null || instance.inventory.playerXp == null)
				{
					return false;
				}
				PlayerXp playerXp = instance.inventory.playerXp;
				try
				{
					xp = playerXp.GetXpInt();
				}
				catch
				{
					xp = playerXp.xp;
				}
				try
				{
					cap = XpUtility.XpTotalNextLevel(playerXp.xp);
				}
				catch
				{
					cap = 0;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		private void UpdateXpBarLabel()
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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)
			if ((Object)(object)_xpBarOuter == (Object)null || !_showXpBar)
			{
				return;
			}
			if ((Object)(object)_xpText == (Object)null || (Object)(object)_xpBarOuter.Find("XpText") == (Object)null)
			{
				_xpTextReady = false;
				EnsureXpBarLabel(forceCheck: true);
				if ((Object)(object)_xpText == (Object)null)
				{
					return;
				}
			}
			if (!_xpTextReady || Time.time - _lastXpLabelTick < 0.1f)
			{
				return;
			}
			_lastXpLabelTick = Time.time;
			if (!TryGetXpAndCap(out var xp, out var cap))
			{
				return;
			}
			string text = ((cap > 0) ? $"{xp:N0} / {cap:N0}" : $"{xp:N0} / ?");
			if (text == _lastXpText)
			{
				return;
			}
			TextMeshProUGUI component = ((Component)_xpText).GetComponent<TextMeshProUGUI>();
			if ((Object)(object)component != (Object)null)
			{
				((TMP_Text)component).text = text;
				((Graphic)component).color = Color32.op_Implicit(XP_TEXT_COLOR);
				try
				{
					((TMP_Text)component).ForceMeshUpdate(true, true);
				}
				catch
				{
				}
			}
			else
			{
				Text component2 = ((Component)_xpText).GetComponent<Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.text = text;
					((Graphic)component2).color = Color32.op_Implicit(XP_TEXT_COLOR);
					RectTransform component3 = ((Component)_xpText).GetComponent<RectTransform>();
					if ((Object)(object)component3 != (Object)null)
					{
						try
						{
							LayoutRebuilder.ForceRebuildLayoutImmediate(component3);
						}
						catch
						{
						}
					}
				}
			}
			_lastXpText = text;
		}

		private static TextMeshProUGUI FindTMPDeep(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			TextMeshProUGUI component = ((Component)root).GetComponent<TextMeshProUGUI>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			Stack<Transform> stack = new Stack<Transform>();
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				stack.Push(root.GetChild(num));
			}
			while (stack.Count > 0)
			{
				Transform val = stack.Pop();
				TextMeshProUGUI component2 = ((Component)val).GetComponent<TextMeshProUGUI>();
				if ((Object)(object)component2 != (Object)null)
				{
					return component2;
				}
				for (int num2 = val.childCount - 1; num2 >= 0; num2--)
				{
					stack.Push(val.GetChild(num2));
				}
			}
			return null;
		}

		private static Text FindUITextDeep(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			Text component = ((Component)root).GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			Stack<Transform> stack = new Stack<Transform>();
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				stack.Push(root.GetChild(num));
			}
			while (stack.Count > 0)
			{
				Transform val = stack.Pop();
				Text component2 = ((Component)val).GetComponent<Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					return component2;
				}
				for (int num2 = val.childCount - 1; num2 >= 0; num2--)
				{
					stack.Push(val.GetChild(num2));
				}
			}
			return null;
		}

		private static void SetAnyTextAndColor(Transform t, string text, Color32 color)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			TextMeshProUGUI val = FindTMPDeep(t);
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)val).text = text;
				((Graphic)val).color = Color32.op_Implicit(color);
				return;
			}
			Text val2 = FindUITextDeep(t);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = text;
				((Graphic)val2).color = Color32.op_Implicit(color);
			}
		}

		private void BuildChildIndex()
		{
			_childOrder.Clear();
			_indexToName.Clear();
			for (int i = 0; i < _top.childCount; i++)
			{
				Transform child = _top.GetChild(i);
				if (!((Object)(object)child == (Object)null))
				{
					_childOrder.Add(child);
					int key = i + 1;
					string name = ((Object)child).name;
					_indexToName[key] = name;
					if (!_childEnabled.ContainsKey(name))
					{
						_childEnabled[name] = true;
					}
				}
			}
		}

		private bool IsChildEnabled(string name)
		{
			if (_childEnabled.TryGetValue(name, out var value))
			{
				return value;
			}
			_childEnabled[name] = true;
			return true;
		}

		private void RescanTop()
		{
			Transform val = FindTopByKnownPaths();
			if (!((Object)(object)val == (Object)null))
			{
				int instanceID = ((Object)((Component)val).gameObject).GetInstanceID();
				if ((Object)(object)_top == (Object)null || instanceID != _topInstanceId)
				{
					_top = val;
					_topInstanceId = instanceID;
					_invPinned = false;
					_invOffsetApplied = false;
					_killsAndGold = null;
					_kgInstanceId = -1;
					_kgAugmented = false;
					_dpsT = null;
					_xpBarOuter = null;
					_xpBarInstanceId = -1;
					_xpText = null;
					_xpTextReady = false;
					_lastXpText = null;
					_lastXpLabelTick = -1f;
					_timerStage = null;
					_tLevel = null;
					_tChestPrice = null;
					ResetRuntimeStats();
					LoggerBridge.Info("[SUIT] Top changed: " + Hierarchy(_top));
				}
			}
		}

		private Transform FindTopByKnownPaths()
		{
			string[] knownPaths = KnownPaths;
			foreach (string path in knownPaths)
			{
				Transform val = TryPath(path);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private Transform TryPath(string path)
		{
			try
			{
				GameObject val = GameObject.Find(path);
				return ((Object)(object)val != (Object)null) ? val.transform : null;
			}
			catch
			{
				return null;
			}
		}

		private Transform FindUnderTop(string childName)
		{
			if ((Object)(object)_top == (Object)null)
			{
				return null;
			}
			Transform val = _top.Find(childName);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			for (int i = 0; i < _top.childCount; i++)
			{
				Transform child = _top.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Object)child).name == childName)
				{
					return child;
				}
			}
			string[] array = new string[4]
			{
				"GameUI/GameUI/HUD/Top/" + childName,
				"GameUI/HUD/Top/" + childName,
				"HUD/Top/" + childName,
				"Top/" + childName
			};
			foreach (string text in array)
			{
				try
				{
					GameObject val2 = GameObject.Find(text);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2.transform;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static string Hierarchy(Transform t)
		{
			List<string> list = new List<string>();
			while ((Object)(object)t != (Object)null)
			{
				list.Add(((Object)t).name);
				t = t.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		private Transform FindFirstTMPTransformUnder(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			if ((Object)(object)((Component)root).GetComponent<TextMeshProUGUI>() != (Object)null)
			{
				return root;
			}
			Stack<Transform> stack = new Stack<Transform>();
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				stack.Push(root.GetChild(num));
			}
			while (stack.Count > 0)
			{
				Transform val = stack.Pop();
				if ((Object)(object)((Component)val).GetComponent<TextMeshProUGUI>() != (Object)null)
				{
					return val;
				}
				for (int num2 = val.childCount - 1; num2 >= 0; num2--)
				{
					stack.Push(val.GetChild(num2));
				}
			}
			return null;
		}

		private void WriteAnnotatedPublicCfg()
		{
			StringBuilder stringBuilder = new StringBuilder();
			string value = "\r\n";
			stringBuilder.Append("# Simple UI Tweaks (SUIT) configuration").Append(value).Append("#")
				.Append(value)
				.Append("# This file lives at: ")
				.Append(PublicCfgPath.Replace("\\", "/"))
				.Append(value)
				.Append("# Edit values below, then press Ctrl+R in-game to HOT RELOAD without restarting.")
				.Append(value)
				.Append("# Shortcuts:")
				.Append(value)
				.Append("#   Ctrl+Up/Down  : Scale")
				.Append(value)
				.Append("#   Ctrl+1        : Toggle XpBarOuter")
				.Append(value)
				.Append("#   Ctrl+2        : Toggle t_Timer_Stage")
				.Append(value)
				.Append("#   Ctrl+3        : Toggle T_Level + T_ChestPrice together")
				.Append(value)
				.Append("#   Ctrl+4        : Toggle KillsAndGold")
				.Append(value)
				.Append("#   Ctrl+5        : Toggle Inventory")
				.Append(value)
				.Append("#   Ctrl+R        : HOT RELOAD this file")
				.Append(value)
				.Append("#   H             : Global hide/show")
				.Append(value)
				.Append("#   R             : Rescan UI (no config changes)")
				.Append(value)
				.Append(value);
			stringBuilder.Append("[SUIT]").Append(value);
			stringBuilder.Append("# Global UI scale (0.1–5.0). Use Ctrl+Up/Down to tweak live.").Append(value);
			stringBuilder.Append("Scale = ").Append(_scale.ToString("0.########", CultureInfo.InvariantCulture)).Append(value);
			stringBuilder.Append("# Global hide/show toggle. Same as pressing H in-game.").Append(value);
			stringBuilder.Append("Hidden = ").Append(_hidden ? "true" : "false").Append(value);
			stringBuilder.Append("# Show the experience bar at the top (XpBarOuter). Hotkey: Ctrl+1").Append(value);
			stringBuilder.Append("ShowXpBar = ").Append(_showXpBar ? "true" : "false").Append(value);
			stringBuilder.Append("# Show the stage timer label (t_Timer_Stage). Hotkey: Ctrl+2").Append(value);
			stringBuilder.Append("ShowTimerStage = ").Append(_showTimerStage ? "true" : "false").Append(value);
			stringBuilder.Append("# Show the level label (T_Level). Ctrl+3 toggles this together with ChestPrice.").Append(value);
			stringBuilder.Append("ShowLevel = ").Append(_showLevel ? "true" : "false").Append(value);
			stringBuilder.Append("# Show the chest price label (T_ChestPrice). Ctrl+3 toggles this together with Level.").Append(value);
			stringBuilder.Append("ShowChestPrice = ").Append(_showChestPrice ? "true" : "false").Append(value);
			stringBuilder.Append("# Show the Kills/Gold/Silver/DPS group. Hotkey: Ctrl+4").Append(value);
			stringBuilder.Append("ShowKillsAndGold = ").Append(_showKillsAndGold ? "true" : "false").Append(value);
			stringBuilder.Append("# Show inventory panel. Hotkey: Ctrl+5").Append(value);
			stringBuilder.Append("ShowInventory = ").Append(_showInventory ? "true" : "false").Append(value);
			stringBuilder.Append("# Inside KillsAndGold: toggle Gold counter.").Append(value);
			stringBuilder.Append("ShowGold = ").Append(_showGold ? "true" : "false").Append(value);
			stringBuilder.Append("# Inside KillsAndGold: toggle Silver counter.").Append(value);
			stringBuilder.Append("ShowSilver = ").Append(_showSilver ? "true" : "false").Append(value);
			stringBuilder.Append("# Inside KillsAndGold: toggle Kills counter.").Append(value);
			stringBuilder.Append("ShowKills = ").Append(_showKills ? "true" : "false").Append(value);
			stringBuilder.Append("# Inside KillsAndGold: toggle DPS readout (added by SUIT).").Append(value);
			stringBuilder.Append("ShowDps = ").Append(_showDps ? "true" : "false").Append(value);
			File.WriteAllText(PublicCfgPath, stringBuilder.ToString(), Utf8NoBom);
		}

		private bool TryParsePublicConfig(string path)
		{
			try
			{
				float scale = 1f;
				bool hidden = false;
				bool showXpBar = true;
				bool showTimerStage = true;
				bool showLevel = true;
				bool showChestPrice = true;
				bool showKillsAndGold = true;
				bool showInventory = true;
				bool showGold = true;
				bool showSilver = true;
				bool showKills = true;
				bool showDps = true;
				string[] array = File.ReadAllLines(path);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.Length == 0 || text.StartsWith("#"))
					{
						continue;
					}
					int num = text.IndexOf('=');
					if (num <= 0)
					{
						continue;
					}
					string text2 = text.Substring(0, num).Trim();
					string s = text.Substring(num + 1).Trim();
					switch (text2)
					{
					case "Scale":
					{
						if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
						{
							scale = Mathf.Clamp(result, 0.1f, 5f);
						}
						break;
					}
					case "Hidden":
						hidden = ParseBool(s);
						break;
					case "ShowXpBar":
						showXpBar = ParseBool(s);
						break;
					case "ShowTimerStage":
						showTimerStage = ParseBool(s);
						break;
					case "ShowLevel":
						showLevel = ParseBool(s);
						break;
					case "ShowChestPrice":
						showChestPrice = ParseBool(s);
						break;
					case "ShowKillsAndGold":
						showKillsAndGold = ParseBool(s);
						break;
					case "ShowInventory":
						showInventory = ParseBool(s);
						break;
					case "ShowGold":
						showGold = ParseBool(s);
						break;
					case "ShowSilver":
						showSilver = ParseBool(s);
						break;
					case "ShowKills":
						showKills = ParseBool(s);
						break;
					case "ShowDps":
						showDps = ParseBool(s);
						break;
					}
				}
				_scale = scale;
				_hidden = hidden;
				_showXpBar = showXpBar;
				_showTimerStage = showTimerStage;
				_showLevel = showLevel;
				_showChestPrice = showChestPrice;
				_showKillsAndGold = showKillsAndGold;
				_showInventory = showInventory;
				_showGold = showGold;
				_showSilver = showSilver;
				_showKills = showKills;
				_showDps = showDps;
				return true;
			}
			catch (Exception ex)
			{
				LoggerBridge.Warn("[SUIT] Parse public cfg failed: " + ex.Message);
				return false;
			}
		}

		private static bool ParseBool(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return false;
			}
			s = s.Trim().ToLowerInvariant();
			switch (s)
			{
			default:
				return s == "on";
			case "1":
			case "true":
			case "yes":
				return true;
			}
		}

		private void MirrorFieldsToPrefs()
		{
			_prefs.Scale = _scale;
			_prefs.Hidden = _hidden;
			_prefs.ShowXpBar = _showXpBar;
			_prefs.ShowTimerStage = _showTimerStage;
			_prefs.ShowLevel = _showLevel;
			_prefs.ShowChestPrice = _showChestPrice;
			_prefs.ShowKillsAndGold = _showKillsAndGold;
			_prefs.ShowInventory = _showInventory;
			_prefs.ShowGold = _showGold;
			_prefs.ShowSilver = _showSilver;
			_prefs.ShowKills = _showKills;
			_prefs.ShowDps = _showDps;
		}

		private void ResetToFactoryDefaults()
		{
			_scale = 1f;
			_hidden = false;
			_showXpBar = true;
			_showTimerStage = true;
			_showLevel = true;
			_showChestPrice = true;
			_showKillsAndGold = true;
			_showInventory = true;
			_showGold = true;
			_showSilver = true;
			_showKills = true;
			_showDps = true;
		}
	}
	internal static class SuitCoreAccess
	{
		internal static SuitCore Instance;
	}
	[HarmonyPatch(typeof(Enemy), "DamageFromPlayerWeapon")]
	internal static class Patch_Enemy_DamageFromPlayerWeapon
	{
		private static void Postfix(DamageContainer dc)
		{
			try
			{
				if (dc != null)
				{
					SuitCoreAccess.Instance?.RecordDamage(dc.damage);
				}
			}
			catch
			{
			}
		}
	}
}