Decompiled source of StatHUD v1.2.1

StatHUD.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 Assets.Scripts.Actors;
using Assets.Scripts.Actors.Enemies;
using Assets.Scripts.Actors.Player;
using Assets.Scripts.Game.Combat;
using Assets.Scripts.Inventory.Stats;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using FoxLib.UI;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Inventory__Items__Pickups;
using Microsoft.CodeAnalysis;
using StatsHUD;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("StatHUD")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+4002a0c243826fee905acd42b57abb04fbccc16b")]
[assembly: AssemblyProduct("StatHUD")]
[assembly: AssemblyTitle("StatHUD")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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;
		}
	}
}
public class DPSModule
{
	public struct DamageInstance
	{
		public float damage;

		public float time;
	}

	[HarmonyPatch(typeof(Enemy))]
	[HarmonyPatch("DamageFromPlayerWeapon")]
	public class EnemyHurtPatch
	{
		public static void Postfix(DamageContainer dc)
		{
			AddDamageInstance(dc);
		}
	}

	public const float DPS_WINDOW_SECONDS = 3f;

	public const float SMOOTHING_FACTOR = 60f;

	public const float RECALC_THROTTLE = 0.1f;

	public const float DISPLAY_THROTTLE = 0.066f;

	private static float rawDPS = 0f;

	private static float displayedDPS = 0f;

	private static float lastRecalcTime = -1f;

	private static float lastDisplayTime = -1f;

	public static List<DamageInstance> damageInstances = new List<DamageInstance>();

	public static void AddDamageInstance(DamageContainer dc)
	{
		DamageInstance damageInstance = default(DamageInstance);
		damageInstance.damage = dc.damage;
		damageInstance.time = TimeModule.GetTime();
		DamageInstance item = damageInstance;
		damageInstances.Add(item);
	}

	public static void Update()
	{
		float time = TimeModule.GetTime();
		if (TimeModule.isPaused)
		{
			lastRecalcTime = -1f;
			lastDisplayTime = -1f;
			return;
		}
		if (time - lastRecalcTime > 0.1f)
		{
			RecalculateRawDPS(time);
			lastRecalcTime = time;
		}
		if (time - lastDisplayTime > 0.066f)
		{
			lastDisplayTime = time;
			displayedDPS = Mathf.Lerp(displayedDPS, rawDPS, Time.deltaTime * 60f);
			if (displayedDPS < 0.01f)
			{
				displayedDPS = 0f;
			}
		}
	}

	private static void RecalculateRawDPS(float now)
	{
		if (damageInstances.Count == 0)
		{
			rawDPS = 0f;
			return;
		}
		float num = 0f;
		for (int num2 = damageInstances.Count - 1; num2 >= 0; num2--)
		{
			if (now - damageInstances[num2].time > 3f)
			{
				damageInstances.RemoveAt(num2);
			}
			else
			{
				num += damageInstances[num2].damage;
			}
		}
		rawDPS = num / 3f;
	}

	public static float GetDPS()
	{
		return displayedDPS;
	}

	public static void Reset()
	{
		rawDPS = 0f;
		displayedDPS = 0f;
		lastRecalcTime = -1f;
		damageInstances.Clear();
	}
}
public class EnemyModule
{
	[HarmonyPatch(typeof(Enemy))]
	[HarmonyPatch("InitEnemy")]
	public class EnemySpawnPatch
	{
		public static void Postfix(Enemy __instance)
		{
			float basePlayerDamage = __instance.GetBasePlayerDamage();
			if (enemyDamages.TryAdd(__instance, basePlayerDamage))
			{
				isDirty = true;
			}
		}
	}

	[HarmonyPatch(typeof(Enemy))]
	[HarmonyPatch("Despawn")]
	public class EnemyDeathPatch
	{
		public static void Prefix(Enemy __instance)
		{
			enemyDamages.Remove(__instance);
			isDirty = true;
		}
	}

	public static Dictionary<Enemy, float> enemyDamages = new Dictionary<Enemy, float>();

	public static bool isDirty = false;

	public static float lastRecalcTime = 0f;

	public static float MinDamage;

	public static float MaxDamage;

	public const float RECALC_THROTTLE = 0.5f;

	public static void RecalculateDamage()
	{
		if (enemyDamages.Count == 0)
		{
			MinDamage = 0f;
			MaxDamage = 0f;
			isDirty = false;
			return;
		}
		float num = default(float);
		float num2 = default(float);
		float num3 = default(float);
		CombatScaling.GetDamageMultiplierAddition(ref num, ref num2, ref num3);
		float num4 = 1f + num + num2 + num3;
		Dictionary<Enemy, float>.ValueCollection values = enemyDamages.Values;
		float num5 = values.Min();
		float num6 = values.Max();
		MinDamage = num5 * num4;
		MaxDamage = num6 * num4;
		isDirty = false;
	}

	public static void Update()
	{
		if (isDirty && Time.time - lastRecalcTime > 0.5f)
		{
			RecalculateDamage();
			lastRecalcTime = Time.time;
		}
	}

	public static void Reset()
	{
		enemyDamages.Clear();
		MinDamage = 0f;
		MaxDamage = 0f;
		isDirty = false;
	}
}
public static class EnemyExtensions
{
	public static float GetBasePlayerDamage(this Enemy enemy)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		DamageContainer playerDamage = DamageUtility.GetPlayerDamage(EnemyStats.GetDamage(enemy), 0f, Vector3.zero, enemy, "", (DcFlags)0);
		playerDamage.damageEffect = (EDamageEffect)0;
		return playerDamage.damage;
	}

	public static float GetCurrentDamage(this Enemy enemy)
	{
		float basePlayerDamage = enemy.GetBasePlayerDamage();
		float num = default(float);
		float num2 = default(float);
		float num3 = default(float);
		CombatScaling.GetDamageMultiplierAddition(ref num, ref num2, ref num3);
		float num4 = 1f + num + num2 + num3;
		return basePlayerDamage * num4;
	}
}
public class PlayerModule
{
	public struct HistoryEntry
	{
		public float Time;

		public float Value;
	}

	public static float lastHistoryRefresh = 0f;

	public const float HISTORY_THROTTLE = 0.1f;

	public const float HISTORY_LIFETIME = 1f;

	public static float MaxXp;

	public static float Xp;

	public static float XpSec;

	public static float XpPct;

	public static float Gold;

	public static float GoldSec;

	public static List<HistoryEntry> xpHistory = new List<HistoryEntry>();

	public static List<HistoryEntry> goldHistory = new List<HistoryEntry>();

	public static MyPlayer GetPlayer()
	{
		return MyPlayer.Instance;
	}

	public static void RecalculateStats()
	{
		MyPlayer player = GetPlayer();
		float time = TimeModule.GetTime();
		if ((Object)(object)player == (Object)null || player.inventory == null || player.inventory.playerXp == null)
		{
			Reset();
			return;
		}
		float xp = Xp;
		float gold = Gold;
		Xp = player.inventory.playerXp.xp;
		Gold = player.inventory.gold;
		MaxXp = XpUtility.XpTotalNextLevel(player.inventory.playerXp.xp);
		XpPct = ((MaxXp > 0f) ? (Xp / MaxXp * 100f) : 0f);
		if (Xp > xp)
		{
			xpHistory.Add(new HistoryEntry
			{
				Time = time,
				Value = Xp - xp
			});
		}
		if (Gold > gold)
		{
			goldHistory.Add(new HistoryEntry
			{
				Time = time,
				Value = Gold - gold
			});
		}
		if (time - lastHistoryRefresh < 0.1f)
		{
			return;
		}
		lastHistoryRefresh = time;
		for (int num = xpHistory.Count - 1; num >= 0; num--)
		{
			if (time - xpHistory[num].Time > 1f)
			{
				xpHistory.RemoveAt(num);
			}
		}
		for (int num2 = goldHistory.Count - 1; num2 >= 0; num2--)
		{
			if (time - goldHistory[num2].Time > 1f)
			{
				goldHistory.RemoveAt(num2);
			}
		}
		XpSec = 0f;
		for (int i = 0; i < xpHistory.Count; i++)
		{
			XpSec += xpHistory[i].Value;
		}
		XpSec /= 1f;
		GoldSec = 0f;
		for (int j = 0; j < goldHistory.Count; j++)
		{
			GoldSec += goldHistory[j].Value;
		}
		GoldSec /= 1f;
	}

	public static void Update()
	{
		RecalculateStats();
	}

	public static float GetXp()
	{
		return Xp;
	}

	public static float GetMaxXp()
	{
		return MaxXp;
	}

	public static float GetXpSec()
	{
		return XpSec;
	}

	public static float GetXpPct()
	{
		return XpPct;
	}

	public static float GetGold()
	{
		return Gold;
	}

	public static float GetGoldSec()
	{
		return GoldSec;
	}

	public static void Reset()
	{
		lastHistoryRefresh = 0f;
		MaxXp = 0f;
		Xp = 0f;
		XpSec = 0f;
		XpPct = 0f;
		Gold = 0f;
		GoldSec = 0f;
		xpHistory.Clear();
		goldHistory.Clear();
	}
}
public class TimeModule
{
	public static float time;

	public static bool isPaused;

	public static void Update()
	{
		if ((Object)(object)UiManager.Instance == (Object)null)
		{
			isPaused = true;
		}
		else if ((Object)(object)UiManager.Instance.encounterWindows == (Object)null || (Object)(object)UiManager.Instance.pause == (Object)null)
		{
			isPaused = false;
		}
		else
		{
			isPaused = (!((Object)(object)UiManager.Instance.pause.current == (Object)null) && UiManager.Instance.pause.current.activeInHierarchy) || (Object)(object)UiManager.Instance.encounterWindows.activeEncounterWindow != (Object)null;
		}
		if (!isPaused)
		{
			time += Time.deltaTime;
		}
	}

	public static float GetTime()
	{
		return time;
	}

	public static void Reset()
	{
		time = 0f;
	}
}
internal class StatGUI : MonoBehaviour
{
	public Image mainPanel;

	public bool isCreated;

	public int lastScene;

	public float lastCheck;

	public Text xpText;

	public Text xpSecText;

	public Text goldText;

	public Text goldSecText;

	public Text minDamageText;

	public Text maxDamageText;

	public Text dpsText;

	public static Vector2 TargetPosition = new Vector2(800f, -70f);

	public static bool isVisible;

	private float _lastXp;

	private float _lastMaxXp;

	private float _lastXpPct;

	private float _lastXpSec;

	private float _lastGold;

	private float _lastGoldSec;

	private float _lastMinDmg;

	private float _lastMaxDmg;

	private float _lastDps;

	private string _xpString;

	private string _goldString;

	private string _minDmgString;

	private string _maxDmgString;

	private string _dpsString;

	public static bool ShowXPModule = true;

	public static bool ShowGoldModule = true;

	public static bool ShowEnemyModule = false;

	public static bool ShowDPSModule = true;

	private void Update()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Expected O, but got Unknown
		if (Time.time - lastCheck > 0.01f)
		{
			lastCheck = Time.time;
			Scene activeScene = SceneManager.GetActiveScene();
			int buildIndex = ((Scene)(ref activeScene)).buildIndex;
			if (buildIndex != lastScene)
			{
				lastScene = buildIndex;
				bool flag = default(bool);
				if (buildIndex == 2)
				{
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 0, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Enabling GUI.");
					}
					log.LogInfo(val);
					EnableGUI();
				}
				else if (isCreated && isVisible)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(14, 0, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Disabling GUI.");
					}
					log2.LogInfo(val);
					DisableGUI();
				}
			}
		}
		if (lastScene == 2)
		{
			TimeModule.Update();
			EnemyModule.Update();
			PlayerModule.Update();
			DPSModule.Update();
		}
		if (isCreated)
		{
			UpdateGUI();
		}
	}

	private void CreateGUI()
	{
		//IL_000a: 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_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: 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_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		if (!isCreated)
		{
			mainPanel = UIBuilder.CreatePanel(TargetPosition, new Vector2(300f, 300f), "StatHUD Panel");
			VerticalLayoutGroup obj = ((Component)mainPanel).gameObject.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f;
			((LayoutGroup)obj).padding.top = 5;
			((LayoutGroup)obj).padding.bottom = 5;
			((LayoutGroup)obj).padding.left = 20;
			((LayoutGroup)obj).padding.right = 15;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			int num = 0;
			if (ShowXPModule)
			{
				xpText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "XP: 0", 24, "XPText");
				((Component)xpText).transform.SetParent(((Component)mainPanel).transform, false);
				xpSecText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "XP/s: 0", 24, "XPSecText");
				((Component)xpSecText).transform.SetParent(((Component)mainPanel).transform, false);
				num += 2;
			}
			if (ShowGoldModule)
			{
				goldText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "Gold: 0", 24, "GoldText");
				((Component)goldText).transform.SetParent(((Component)mainPanel).transform, false);
				goldSecText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "Gold/s: 0", 24, "GoldSecText");
				((Component)goldSecText).transform.SetParent(((Component)mainPanel).transform, false);
				num += 2;
			}
			if (ShowEnemyModule)
			{
				minDamageText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "Min, Foe Dmg: 0", 24, "MinDamageText");
				((Component)minDamageText).transform.SetParent(((Component)mainPanel).transform, false);
				maxDamageText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "Max, Foe Dmg: 0", 24, "MaxDamageText");
				((Component)maxDamageText).transform.SetParent(((Component)mainPanel).transform, false);
				num += 2;
			}
			if (ShowDPSModule)
			{
				dpsText = UIBuilder.CreateText(Vector2.zero, new Vector2(280f, 30f), "DPS: 0", 24, "DPSText");
				((Component)dpsText).transform.SetParent(((Component)mainPanel).transform, false);
				num++;
			}
			float num2 = 30f;
			float num3 = 10f;
			float num4 = 10f;
			float num5 = (float)num * num2 + (float)(num - 1) * num3 + num4;
			((Graphic)mainPanel).rectTransform.sizeDelta = new Vector2(300f, num5);
			Plugin.Log.LogInfo((object)"StatGUI created.");
			isCreated = true;
			DisableGUI();
			UpdateGUIPosition();
			EnableGUI();
		}
	}

	private void EnableGUI()
	{
		if (!isCreated)
		{
			CreateGUI();
		}
		isVisible = true;
		((Component)mainPanel).gameObject.SetActive(true);
	}

	private void DisableGUI()
	{
		if (!isCreated)
		{
			CreateGUI();
		}
		isVisible = false;
		((Component)mainPanel).gameObject.SetActive(false);
		DPSModule.Reset();
		PlayerModule.Reset();
		TimeModule.Reset();
		EnemyModule.Reset();
	}

	private void UpdateGUI()
	{
		if (isVisible)
		{
			UpdateGUIText();
		}
		UpdateGUIPosition();
	}

	private void UpdateGUIPosition()
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0032: Unknown result type (might be due to invalid IL or missing references)
		if (isVisible)
		{
			((Graphic)mainPanel).rectTransform.anchoredPosition = Vector2.Lerp(((Graphic)mainPanel).rectTransform.anchoredPosition, TargetPosition, Time.deltaTime * 12f);
		}
		else
		{
			((Graphic)mainPanel).rectTransform.anchoredPosition = new Vector2(TargetPosition.x + 550f, TargetPosition.y);
		}
	}

	private void UpdateGUIText()
	{
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
		if (ShowXPModule)
		{
			float xp = PlayerModule.GetXp();
			float maxXp = PlayerModule.GetMaxXp();
			float xpPct = PlayerModule.GetXpPct();
			float xpSec = PlayerModule.GetXpSec();
			if (xp != _lastXp || maxXp != _lastMaxXp || xpPct != _lastXpPct || xpSec != _lastXpSec)
			{
				_xpString = $"XP: {xp.ToString("F0")}/{maxXp.ToString("F0")} ({xpPct.ToString("F1")}%)";
				UIBuilder.SetText(xpText, _xpString);
				_xpString = "XP/s: " + xpSec.ToString("F0");
				UIBuilder.SetText(xpSecText, _xpString);
				_lastXp = xp;
				_lastMaxXp = maxXp;
				_lastXpPct = xpPct;
				_lastXpSec = xpSec;
			}
		}
		if (ShowGoldModule)
		{
			float gold = PlayerModule.GetGold();
			float goldSec = PlayerModule.GetGoldSec();
			if (gold != _lastGold || goldSec != _lastGoldSec)
			{
				_goldString = "Gold: " + gold.ToString("F0");
				UIBuilder.SetText(goldText, _goldString);
				_goldString = "Gold/s: " + goldSec.ToString("F0");
				UIBuilder.SetText(goldSecText, _goldString);
				_lastGold = gold;
				_lastGoldSec = goldSec;
			}
		}
		if (ShowEnemyModule)
		{
			float minDamage = EnemyModule.MinDamage;
			float maxDamage = EnemyModule.MaxDamage;
			if (minDamage != _lastMinDmg || maxDamage != _lastMaxDmg)
			{
				_minDmgString = "Min. Foe Dmg: " + minDamage.ToString("F0");
				UIBuilder.SetText(minDamageText, _minDmgString);
				_maxDmgString = "Max. Foe Dmg: " + maxDamage.ToString("F0");
				UIBuilder.SetText(maxDamageText, _maxDmgString);
				_lastMinDmg = minDamage;
				_lastMaxDmg = maxDamage;
				MyPlayer player = PlayerModule.GetPlayer();
				if ((Object)(object)player != (Object)null && player.inventory != null)
				{
					if (player.inventory.playerHealth.WillDamageKill(EnemyModule.MinDamage, false))
					{
						UIBuilder.SetColor(minDamageText, Color.red);
					}
					else
					{
						UIBuilder.SetColor(minDamageText, Color.white);
					}
					if (player.inventory.playerHealth.WillDamageKill(EnemyModule.MaxDamage, false))
					{
						UIBuilder.SetColor(maxDamageText, Color.red);
					}
					else
					{
						UIBuilder.SetColor(maxDamageText, Color.white);
					}
				}
			}
		}
		if (ShowDPSModule)
		{
			float dPS = DPSModule.GetDPS();
			if (dPS != _lastDps)
			{
				_dpsString = "DPS: " + dPS.ToString("F1");
				UIBuilder.SetText(dpsText, _dpsString);
				_lastDps = dPS;
			}
		}
	}
}
namespace StatsHUD
{
	[BepInPlugin("StatHUD", "StatHUD", "1.2.0")]
	public class Plugin : BasePlugin
	{
		internal static ManualLogSource Log;

		private static Harmony _harmony;

		public override void Load()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(11, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("StatHUD");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			log.LogInfo(val);
			_harmony = new Harmony("StatHUD");
			_harmony.PatchAll();
			FoxUI.Initialize();
			ClassInjector.RegisterTypeInIl2Cpp<StatGUI>();
			GameObject val2 = new GameObject("StatHUD");
			val2.AddComponent<StatGUI>();
			Object.DontDestroyOnLoad((Object)val2);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "StatHUD";

		public const string PLUGIN_NAME = "StatHUD";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}
namespace FoxLib
{
	public class AssetManager : MonoBehaviour
	{
		public static Font font;

		public static Sprite border;

		public static Font GetFont()
		{
			if ((Object)(object)font == (Object)null)
			{
				Plugin.Log.LogInfo((object)"Loading font...");
				font = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name == "alagard"));
				if ((Object)(object)font == (Object)null)
				{
					Plugin.Log.LogError((object)"Font not found!");
				}
				else
				{
					Plugin.Log.LogInfo((object)"Font loaded successfully.");
				}
			}
			return font;
		}

		public static Sprite GetBorder()
		{
			if ((Object)(object)border == (Object)null)
			{
				Plugin.Log.LogInfo((object)"Loading border sprite...");
				border = ((IEnumerable<Sprite>)Resources.FindObjectsOfTypeAll<Sprite>()).FirstOrDefault((Func<Sprite, bool>)((Sprite s) => ((Object)s).name == "Border2_Gray"));
				if ((Object)(object)border == (Object)null)
				{
					Plugin.Log.LogError((object)"Border sprite not found!");
				}
				else
				{
					Plugin.Log.LogInfo((object)"Border sprite loaded successfully.");
				}
			}
			return border;
		}

		public void Start()
		{
			Plugin.Log.LogInfo((object)"FoxUIAssetManager initialized.");
		}
	}
	public class FoxLib
	{
		public static void Initialize()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ClassInjector.RegisterTypeInIl2Cpp<AssetManager>();
			GameObject val = new GameObject("FoxLib Asset Manager");
			val.AddComponent<AssetManager>();
			Object.DontDestroyOnLoad((Object)val);
		}
	}
}
namespace FoxLib.UI
{
	public class FoxUI
	{
		public static void Initialize()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			FoxLib.Initialize();
			ClassInjector.RegisterTypeInIl2Cpp<UIBuilder>();
			GameObject val = new GameObject("FoxLib UI Builder");
			val.AddComponent<UIBuilder>();
			Object.DontDestroyOnLoad((Object)val);
		}
	}
	public class UIBuilder : MonoBehaviour
	{
		public static Canvas canvas;

		public static UIBuilder Instance;

		public Dictionary<Text, StringBuilder> textBuilders = new Dictionary<Text, StringBuilder>();

		public void Start()
		{
			//IL_003d: 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_0048: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			if ((Object)(object)Instance != (Object)null)
			{
				Plugin.Log.LogWarning((object)"Multiple UI Builder instances detected! Destroying duplicate");
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			Plugin.Log.LogInfo((object)"FoxLib UI Builder initialized.");
			GameObject val = new GameObject("FoxLib UI");
			Object.DontDestroyOnLoad((Object)val);
			canvas = val.AddComponent<Canvas>();
			canvas.renderMode = (RenderMode)0;
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.screenMatchMode = (ScreenMatchMode)0;
			val.AddComponent<GraphicRaycaster>();
			Plugin.Log.LogInfo((object)"FoxLib UI canvas created.");
		}

		public static Image CreatePanel(Vector2 position, Vector2 size, string name = "Panel")
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0050: 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_006c: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Creating panel: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector2>(position);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" with size ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector2>(size);
			}
			log.LogInfo(val);
			Image obj = new GameObject(name).AddComponent<Image>();
			((Graphic)obj).rectTransform.anchoredPosition = position;
			((Graphic)obj).rectTransform.sizeDelta = size;
			obj.sprite = AssetManager.GetBorder();
			obj.type = (Type)1;
			((Graphic)obj).color = new Color(1f, 1f, 1f, 0.8f);
			((Component)obj).transform.SetParent(((Component)canvas).transform, false);
			return obj;
		}

		public static Text CreateText(Vector2 position, Vector2 size, string content, int fontSize = 24, string name = "Text")
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0064: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Creating text: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector2>(position);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" with size ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector2>(size);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" and content: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(content);
			}
			log.LogInfo(val);
			Text obj = new GameObject(name).AddComponent<Text>();
			((Graphic)obj).rectTransform.anchoredPosition = position;
			((Graphic)obj).rectTransform.sizeDelta = size;
			obj.font = AssetManager.GetFont();
			obj.text = content;
			obj.fontSize = fontSize;
			((Graphic)obj).color = Color.white;
			obj.alignment = (TextAnchor)3;
			Shadow obj2 = ((Component)obj).gameObject.AddComponent<Shadow>();
			obj2.effectColor = Color.black;
			obj2.effectDistance = new Vector2(2f, -2f);
			((Component)obj).transform.SetParent(((Component)canvas).transform, false);
			return obj;
		}

		public static void SetText(Text text, string content)
		{
			if (text.text != content)
			{
				text.text = content;
			}
		}

		public static void SetColor(Text text, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (((Graphic)text).color != color)
			{
				((Graphic)text).color = color;
			}
		}

		public static void SetColor(Text text, float r = 1f, float g = 1f, float b = 1f, float a = 1f)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(r, g, b, a);
			if (((Graphic)text).color != val)
			{
				((Graphic)text).color = val;
			}
		}
	}
}