Decompiled source of InfoSkull v1.0.2

InfoSkull.dll

Decompiled 3 months 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Febucci.UI;
using Febucci.UI.Core;
using Febucci.UI.Effects;
using HarmonyLib;
using InfoSkull.components;
using InfoSkull.patches;
using InfoSkull.utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyCompany("InfoSkull")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+460cd4e55f4ede9caf7663a69baf89ab785792ae")]
[assembly: AssemblyProduct("Projects more info right into your skull")]
[assembly: AssemblyTitle("InfoSkull")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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 InfoSkull
{
	public class Commands
	{
		public static CommandConsole console;

		public static void register()
		{
			console.RegisterCommand("is", (Action<string[]>)delegate(string[] args)
			{
				if (args.Length == 0)
				{
					args = new string[1] { "" };
				}
				switch (args[0])
				{
				case "leveltimer":
					levelTimer(args.Skip(1).ToArray());
					break;
				case "display":
					display(args.Skip(1).ToArray());
					break;
				case "wipe":
					StatsUtil.wipe((KeyValuePair<string, string> pair) => pair.Key.StartsWith("info-skull-"));
					sendMessage("Wiped all data");
					break;
				default:
					sendMessage("Commands:\r\nleveltimer: level timer and end of level text \r\ndisplay: Text that's displayed at the top of the screen\r\nwipe: wipes the data saved (doesn't include config). BACKUP YOUR SAVE FILE BEFORE DOING THIS!");
					break;
				}
			}, false);
		}

		private static void levelTimer(string[] args)
		{
			if (args.Length == 0)
			{
				args = new string[1] { "" };
			}
			switch (args[0])
			{
			case "format":
				Plugin.LevelTimer.format.Value = string.Join(" ", args.Skip(1).ToArray()).Replace("\\n", "\n");
				sendMessage("Updated format");
				Plugin.checkLeaderboardLegality();
				break;
			case "onlybest":
				Plugin.LevelTimer.onlyBest.Value = !Plugin.LevelTimer.onlyBest.Value;
				sendMessage("Now " + (Plugin.LevelTimer.onlyBest.Value ? "only new best" : "all") + " times will be shown");
				break;
			case "saving":
				Plugin.LevelTimer.saving.Value = !Plugin.LevelTimer.saving.Value;
				sendMessage("Best times will " + (Plugin.LevelTimer.saving.Value ? "now" : "no longer") + " be saved");
				break;
			case "wipe":
				StatsUtil.wipe((KeyValuePair<string, string> pair) => pair.Key.StartsWith("info-skull-") && pair.Key.EndsWith("-best-time"));
				sendMessage("Wiped all best times data");
				break;
			default:
				sendMessage("Commands:\r\nformat: Sets the format for the end of level message. See Github for possible formats\r\nonlybest: toggles whether the text only appears on new PBs\r\nwipe: wipes the data saved for level times (doesn't include config). BACKUP YOUR SAVE FILE BEFORE DOING THIS!");
				break;
			}
		}

		private static void display(string[] args)
		{
			if (args.Length == 0)
			{
				args = new string[1] { "" };
			}
			if (args[0] == "format")
			{
				Plugin.Display.format.Value = string.Join(" ", args.Skip(1).ToArray()).Replace("\\n", "\n");
				sendMessage("Updated format");
				Plugin.checkLeaderboardLegality();
			}
			else
			{
				sendMessage("Commands:\r\nformat: Sets the format for the display. See Github for possible formats");
			}
		}

		public static void sendMessage(string message)
		{
			if (Object.op_Implicit((Object)(object)console))
			{
				((object)console).GetType().GetMethod("AddMessageToHistory", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(console, new object[1] { message });
			}
		}
	}
	public class Formatter
	{
		public const string LEVEL = "{level}";

		public const string LEVEL_TIME = "{level_time}";

		public const string HEIGHT = "{height}";

		public const string BEST_LEVEL_TIME = "{best_level_time}";

		public const string ASCENT_RATE = "{ascent_rate}";

		public const string GAME_TIME = "{game_time}";

		public const string CLOCK = "{clock}";

		public const string LEFT_STAMINA = "{left_stamina}";

		public const string RIGHT_STAMINA = "{right_stamina}";

		public const string MASS_HEIGHT = "{mass_height}";

		public const string MASS_SPEED = "{mass_speed}";

		public const string MASS_ACC_MULT = "{mass_acc_mult}";

		public const string MASS_DISTANCE = "{mass_distance}";

		public const string SCORE = "{score}";

		public const string HIGH_SCORE = "{high_score}";

		public const string ASCENT = "{ascent}";

		public const string VELOCITY = "{velocity}";

		public const string HEALTH = "{health}";

		public const string EXTRA_JUMPS = "{extra_jumps}";

		public static readonly string EMPTY = "{empty}";

		public static M_Level levelOverride;

		public static string format(string format, Dictionary<string, string> overrides = null)
		{
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (overrides != null)
				{
					foreach (KeyValuePair<string, string> @override in overrides)
					{
						format = format.Replace(@override.Key, @override.Value);
					}
				}
				ENT_Player playerObject = ENT_Player.playerObject;
				CL_GameManager gMan = CL_GameManager.gMan;
				if (Object.op_Implicit((Object)(object)WorldLoader.instance))
				{
					M_Level val = (Object.op_Implicit((Object)(object)levelOverride) ? levelOverride : WorldLoader.instance.GetCurrentLevel().level);
					format = format.Replace("{level}", val.levelName).Replace("{best_level_time}", Math.Round(Timer.bestLevelTime(val), 2).ToString());
				}
				if (Object.op_Implicit((Object)(object)DEN_DeathFloor.instance))
				{
					DEN_DeathFloor instance = DEN_DeathFloor.instance;
					Traverse val2 = Traverse.Create((object)instance);
					float num = (Object.op_Implicit((Object)(object)CL_GameManager.gamemode) ? CL_GameManager.gamemode.gooSpeedMult : 1f);
					if (SettingsManager.settings.g_hard)
					{
						num *= 2f;
					}
					float num2 = val2.Field("speedMult").GetValue<float>() * num * val2.Field("speedMultFrame").GetValue<float>();
					if (WorldLoader.initialized && WorldLoader.isLoaded && WorldLoader.instance.GetCurrentLevel() != null)
					{
						num2 *= WorldLoader.instance.GetCurrentLevel().level.massSpeedMult;
						if ((Object)(object)WorldLoader.instance.GetCurrentLevel().level.subRegion != (Object)null)
						{
							num2 *= WorldLoader.instance.GetCurrentLevel().level.subRegion.massSpeedMult;
						}
					}
					float num3 = instance.speed * num2;
					format = format.Replace("{mass_speed}", Math.Round(num3, 2).ToString()).Replace("{mass_distance}", Math.Round(((Component)playerObject).transform.position.y - ((Component)instance).transform.position.y, 0).ToString()).Replace("{mass_height}", Math.Round(((Component)instance).transform.position.y, 0).ToString());
				}
				TimeSpan timeSpan = TimeSpan.FromSeconds(CL_GameManager.gMan.GetGameTime());
				string newValue = ((timeSpan.TotalHours >= 1.0) ? timeSpan.ToString("hh\\:mm\\:ss\\:ff") : timeSpan.ToString("mm\\:ss\\:ff"));
				string text = format.Replace("\\n", "\n").Replace("{level_time}", Math.Round(Timer.currentLevelTime(), 2).ToString()).Replace("{ascent_rate}", Math.Round(gMan.GetPlayerAscentRate(), 2).ToString())
					.Replace("{game_time}", newValue)
					.Replace("{clock}", DateTime.Now.ToString("HH:mm"))
					.Replace("{left_stamina}", Math.Round(playerObject.hands[0].gripStrength, 0).ToString())
					.Replace("{right_stamina}", Math.Round(playerObject.hands[1].gripStrength, 0).ToString())
					.Replace("{height}", Math.Round(((Component)playerObject).transform.position.y, 0).ToString())
					.Replace("{score}", Math.Round(gMan.GetPlayerAscent() * gMan.GetPlayerAscentRate(), 0).ToString())
					.Replace("{high_score}", Math.Round(Traverse.Create((object)gMan).Field("previousHighScore").GetValue<float>(), 0).ToString())
					.Replace("{ascent}", Math.Round(Traverse.Create((object)gMan).Field("playerAscent").GetValue<float>(), 0).ToString());
				Vector3 value = Traverse.Create((object)playerObject).Field("lastVel").GetValue<Vector3>();
				return text.Replace("{velocity}", Math.Round(((Vector3)(ref value)).magnitude, 2).ToString()).Replace("{extra_jumps}", Traverse.Create((object)playerObject).Field("extraJumpsRemaining").GetValue<int>()
					.ToString()).Replace("{health}", Math.Round(((GameEntity)playerObject).health, 1).ToString())
					.Replace("{mass_acc_mult}", Math.Round(CL_GameManager.gamemode.gooSpeedIncreaseMult).ToString())
					.Replace(EMPTY, "");
			}
			catch (NullReferenceException)
			{
			}
			return "ERROR";
		}
	}
	[BepInPlugin("InfoSkull", "InfoSkull", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		public static class LevelTimer
		{
			public static ConfigEntry<string> format;

			public static ConfigEntry<Vector2> position;

			public static ConfigEntry<bool> onlyBest;

			public static ConfigEntry<bool> saving;
		}

		public static class Display
		{
			public static ConfigEntry<string> format;

			public static ConfigEntry<Vector2> position;
		}

		private const string GUID = "InfoSkull";

		private const string NAME = "InfoSkull";

		private const string VERSION = "1.0.2";

		public static Plugin instance;

		internal static ManualLogSource logger;

		private static Harmony harmony;

		private static readonly List<string> LEADERBOARD_ILLEGAL = new List<string>(7) { "{left_stamina}", "{right_stamina}", "{mass_distance}", "{mass_height}", "{mass_speed}", "{health}", "{extra_jumps}" };

		private static readonly List<string> UI_POS = new List<string>(4) { "High Score", "Ascent Header", "Tip Header", "Header Text" };

		public static bool isAdjustingUI;

		public static GameObject adjustUI;

		public static GameObject display;

		public static GameObject levelTimer;

		public static void checkLeaderboardLegality()
		{
			//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)
			CL_GameManager.gamemode.allowLeaderboardScoring = !LEADERBOARD_ILLEGAL.Any((string illegal) => LevelTimer.format.Value.Contains(illegal) || Display.format.Value.Contains(illegal)) && CL_GameManager.gamemode.allowLeaderboardScoring && !CL_GameManager.HasActiveFlag("leaderboardIllegal");
			if (!CL_GameManager.gamemode.allowLeaderboardScoring)
			{
				Scene sceneByName = SceneManager.GetSceneByName("Main-Menu");
				if (!((Scene)(ref sceneByName)).isLoaded)
				{
					GameManagerPatch.highScoreQueue = "RUN IS LEADERBOARD ILLEGAL";
					Commands.sendMessage("Leaderboard illegal variable used run will not be scored");
					CL_GameManager.SetGameFlag("leaderboardIllegal", true, "", false);
				}
			}
		}

		private void Awake()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			instance = this;
			upgradeConfig();
			LevelTimer.format = ((BaseUnityPlugin)this).Config.Bind<string>("LevelTimer", "format", "{level_time} / {best_level_time}", "Format to display");
			LevelTimer.onlyBest = ((BaseUnityPlugin)this).Config.Bind<bool>("LevelTimer", "only-best", false, "Whether to only show new bests");
			LevelTimer.saving = ((BaseUnityPlugin)this).Config.Bind<bool>("LevelTimer", "saving", true, "Whether to save best times in the games stats file");
			Display.format = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "format", "{clock}", "Format to display");
			logger = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("InfoSkull");
			harmony.PatchAll();
			callbacks();
			logger.LogInfo((object)"InfoSkull is loaded!");
		}

		private void upgradeConfig()
		{
			ConfigEntry<string> val = default(ConfigEntry<string>);
			if (!((BaseUnityPlugin)this).Config.TryGetEntry<string>("General", "version", ref val))
			{
				foreach (ConfigDefinition key in ((BaseUnityPlugin)this).Config.Keys)
				{
					if (key.Key == "position")
					{
						((BaseUnityPlugin)this).Config.Remove(key);
					}
				}
			}
			((BaseUnityPlugin)this).Config.Bind<string>("General", "version", "1.0.2", "Used internally").Value = "1.0.2";
		}

		private void callbacks()
		{
			SceneManager.sceneLoaded += delegate
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: 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_009a: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0191: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = GameObject.Find("High Score");
				if (Object.op_Implicit((Object)(object)val))
				{
					Vector2 anchoredPosition = val.GetComponent<RectTransform>().anchoredPosition;
					Display.position = ((BaseUnityPlugin)instance).Config.Bind<Vector2>("Display", "position", new Vector2(0f, (float)Screen.height / 2f - 50f), "position to show at");
					display = Object.Instantiate<GameObject>(val, GameObject.Find("Game UI").transform);
					display.AddComponent<InfoSkull.components.Display>();
					LevelTimer.position = ((BaseUnityPlugin)instance).Config.Bind<Vector2>("LevelTimer", "position", new Vector2(anchoredPosition.x, anchoredPosition.y - 50f), "position to show at");
					levelTimer = Object.Instantiate<GameObject>(val, GameObject.Find("Game UI").transform);
					levelTimer.AddComponent<InfoSkull.components.LevelTimer>();
					foreach (string uI_PO in UI_POS)
					{
						GameObject obj = GameObject.Find(uI_PO);
						RectTransform component = obj.GetComponent<RectTransform>();
						component.anchoredPosition = new Vector2((component.anchorMax.x - 0.5f) * ((float)Screen.width / 1.08f) + component.anchoredPosition.x, (component.anchorMax.y - 0.5f) * ((float)Screen.height / 1.08f) + component.anchoredPosition.y);
						component.anchorMax = new Vector2(0.5f, 0.5f);
						component.anchorMin = new Vector2(0.5f, 0.5f);
						ConfigEntry<Vector2> val2 = ((BaseUnityPlugin)instance).Config.Bind<Vector2>(uI_PO, "position", component.anchoredPosition, "position to show at");
						component.anchoredPosition = val2.Value;
						obj.AddComponent<Positionable>();
					}
				}
			};
		}

		public static void enableUIAdjust()
		{
			GameObject.Find("Pause Menu").SetActive(false);
			isAdjustingUI = true;
			TMP_InputField component = display.GetComponent<TMP_InputField>();
			component.text = Display.format.Value;
			((Behaviour)component).enabled = true;
			TMP_InputField component2 = levelTimer.GetComponent<TMP_InputField>();
			component2.text = LevelTimer.format.Value;
			((Behaviour)component2).enabled = true;
			foreach (string uI_PO in UI_POS)
			{
				((TMP_Text)GameObject.Find(uI_PO).GetComponent<TextMeshProUGUI>()).SetText(uI_PO, true);
			}
		}

		public static void disableUIAdjust()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			((Behaviour)display.GetComponent<TMP_InputField>()).enabled = false;
			Display.format.Value = display.GetComponent<Formatable>().lastCommittedText;
			Display.position.Value = display.GetComponent<RectTransform>().anchoredPosition;
			TMP_InputField component = levelTimer.GetComponent<TMP_InputField>();
			component.text = "";
			((Behaviour)component).enabled = false;
			LevelTimer.format.Value = levelTimer.GetComponent<Formatable>().lastCommittedText;
			LevelTimer.position.Value = levelTimer.GetComponent<RectTransform>().anchoredPosition;
			isAdjustingUI = false;
			ConfigEntry<Vector2> val2 = default(ConfigEntry<Vector2>);
			foreach (string uI_PO in UI_POS)
			{
				GameObject val = GameObject.Find(uI_PO);
				((BaseUnityPlugin)instance).Config.TryGetEntry<Vector2>(uI_PO, "position", ref val2);
				val2.Value = val.GetComponent<RectTransform>().anchoredPosition;
				((TMP_Text)val.GetComponent<TextMeshProUGUI>()).SetText("", true);
			}
			checkLeaderboardLegality();
		}
	}
	public class Timer
	{
		public static float levelEnterTime;

		public static void completeRoom(M_Level level)
		{
			float num = currentLevelTime();
			string text = "info-skull-" + level.levelName + "-best-time";
			if (Plugin.LevelTimer.saving.Value)
			{
				StatManager.sessionStats.UpdateStatistic(text, (object)num, (DataType)2, (ModType)3, (DisplayType)4, (ModType)3);
			}
			string value = Plugin.LevelTimer.format.Value;
			if ((currentLevelTime() < bestLevelTime(level) || !Plugin.LevelTimer.onlyBest.Value) && value != "")
			{
				Plugin.levelTimer.GetComponent<UT_TextScrawl>().ShowText(Formatter.format(value));
			}
			levelEnterTime = CL_GameManager.gMan.GetGameTime();
		}

		public static float currentLevelTime()
		{
			return CL_GameManager.gMan.GetGameTime() - levelEnterTime;
		}

		public static float bestLevelTime(M_Level level)
		{
			string text = "info-skull-" + level.levelName + "-best-time";
			Statistic statistic = StatManager.saveData.gameStats.GetStatistic(text);
			if (!(statistic.value == ""))
			{
				return float.Parse(statistic.value);
			}
			return 0f;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "InfoSkull";

		public const string PLUGIN_NAME = "Projects more info right into your skull";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace InfoSkull.utils
{
	public class StatsUtil
	{
		public static void wipe(Func<KeyValuePair<string, string>, bool> predicate)
		{
			StatManager.saveData.gameStats.statsDictionary = StatManager.saveData.gameStats.statsDictionary.Where((KeyValuePair<string, Statistic> pair) => !predicate(new KeyValuePair<string, string>(pair.Key, pair.Value.value))).ToDictionary((KeyValuePair<string, Statistic> i) => i.Key, (KeyValuePair<string, Statistic> i) => i.Value);
			StatManager.saveData.gameStats.statistics = StatManager.saveData.gameStats.statistics.Where((Statistic stat) => !predicate(new KeyValuePair<string, string>(stat.id, stat.value))).ToList();
			StatManager.sessionStats.statsDictionary = StatManager.saveData.gameStats.statsDictionary.Where((KeyValuePair<string, Statistic> pair) => !predicate(new KeyValuePair<string, string>(pair.Key, pair.Value.value))).ToDictionary((KeyValuePair<string, Statistic> i) => i.Key, (KeyValuePair<string, Statistic> i) => i.Value);
			StatManager.sessionStats.statistics = StatManager.saveData.gameStats.statistics.Where((Statistic stat) => !predicate(new KeyValuePair<string, string>(stat.id, stat.value))).ToList();
			foreach (GameModeData gameMode in StatManager.saveData.gameModes)
			{
				gameMode.stats.statsDictionary = StatManager.saveData.gameStats.statsDictionary.Where((KeyValuePair<string, Statistic> pair) => !predicate(new KeyValuePair<string, string>(pair.Key, pair.Value.value))).ToDictionary((KeyValuePair<string, Statistic> i) => i.Key, (KeyValuePair<string, Statistic> i) => i.Value);
				gameMode.stats.statistics = StatManager.saveData.gameStats.statistics.Where((Statistic stat) => !predicate(new KeyValuePair<string, string>(stat.id, stat.value))).ToList();
			}
		}
	}
}
namespace InfoSkull.patches
{
	[HarmonyPatch(typeof(CommandConsole))]
	public class CommandConsolePatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void postfixAwake(CommandConsole __instance)
		{
			Commands.console = __instance;
			Commands.register();
		}
	}
	[HarmonyPatch(typeof(CL_GameManager))]
	public class GameManagerPatch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__4_0;

			internal void <postfixPause>b__4_0()
			{
				Plugin.enableUIAdjust();
			}
		}

		public static string highScoreQueue;

		[HarmonyPatch("SetGameTime")]
		[HarmonyPostfix]
		public static void postfixSetGameTime(CL_GameManager __instance)
		{
			Timer.levelEnterTime = __instance.GetGameTime();
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void postfixStart(CL_GameManager __instance)
		{
			Timer.levelEnterTime = __instance.GetGameTime();
			Formatter.levelOverride = null;
			Plugin.checkLeaderboardLegality();
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void postfixUpdate(CL_GameManager __instance)
		{
			if (highScoreQueue != null && !Traverse.Create((object)__instance).Field("loading").GetValue<bool>() && Object.op_Implicit((Object)(object)__instance.uiMan))
			{
				__instance.uiMan.highscoreHeader.ShowText(highScoreQueue);
				highScoreQueue = null;
			}
		}

		[HarmonyPatch("Pause")]
		[HarmonyPostfix]
		public static void postfixPause(CL_GameManager __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//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_00ce: Expected O, but got Unknown
			GameObject val = GameObject.Find("Report Bug");
			if (!Object.op_Implicit((Object)(object)val) || Object.op_Implicit((Object)(object)GameObject.Find("Adjust UI")))
			{
				return;
			}
			GameObject obj = (Plugin.adjustUI = Object.Instantiate<GameObject>(val, new Vector3((float)Screen.width - val.transform.position.x, val.transform.position.y, 0f), Quaternion.identity, GameObject.Find("Pause Buttons").transform));
			((Object)obj).name = "Adjust UI";
			Button component = obj.GetComponent<Button>();
			((Object)component).name = "Adjust UI";
			((TMP_Text)obj.GetComponentInChildren<TextMeshProUGUI>()).SetText("Adjust UI", true);
			ButtonClickedEvent onClick = component.onClick;
			object obj2 = <>c.<>9__4_0;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					Plugin.enableUIAdjust();
				};
				<>c.<>9__4_0 = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			((Behaviour)component).enabled = true;
			((Behaviour)obj.GetComponent<UI_AnimateOnSelect>()).enabled = true;
			((Behaviour)obj.GetComponent<UI_MenuButton>()).enabled = true;
		}

		[HarmonyPatch("UnPause")]
		[HarmonyPostfix]
		public static void postfixUnPause(CL_GameManager __instance)
		{
			if (Plugin.isAdjustingUI)
			{
				Plugin.disableUIAdjust();
			}
		}
	}
	[HarmonyPatch(typeof(M_Level))]
	public class LevelPatch
	{
		[HarmonyPatch("OnExit")]
		[HarmonyPostfix]
		public static void prefixOnExit(M_Level __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			M_Level level = WorldLoader.GetClosestLevelToPosition(((Component)ENT_Player.playerObject).transform.position).level;
			if (!level.HasEntered())
			{
				if (__instance.levelName.Equals("M1_Intro_01"))
				{
					Formatter.levelOverride = __instance;
					TriggerZonePatch.time_on_close = __instance;
				}
				else
				{
					Plugin.logger.LogInfo((object)("Changed level: " + __instance.levelName + " - " + level.levelName));
					Timer.completeRoom(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CL_SaveManager))]
	public class SaveManagerPatch
	{
		[HarmonyPatch("LoadSession")]
		[HarmonyPostfix]
		private static void postfixLoadSession()
		{
			if (CL_GameManager.HasActiveFlag("leaderboardIllegal"))
			{
				CL_GameManager.gamemode.allowLeaderboardScoring = false;
			}
			Plugin.checkLeaderboardLegality();
		}
	}
	[HarmonyPatch(typeof(UT_TriggerZone))]
	public class TriggerZonePatch
	{
		public static M_Level time_on_close;

		[HarmonyPatch("OnTriggerEnter")]
		[HarmonyPostfix]
		public static void postfixOnTriggerEnter(UT_TriggerZone __instance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			try
			{
				M_Level val = (M_Level)((Component)((Component)__instance).gameObject.transform.parent.parent).GetComponent(typeof(M_Level));
				if (!((Object)(object)WorldLoader.instance.GetCurrentLevel().level != (Object)(object)val) && !((Object)(object)time_on_close == (Object)null) && Traverse.Create((object)__instance).Field<bool>("hasRun").Value)
				{
					Plugin.logger.LogInfo((object)("Changed level: " + time_on_close.levelName + " - " + val.levelName));
					Timer.completeRoom(time_on_close);
					Formatter.levelOverride = null;
					time_on_close = null;
				}
			}
			catch (NullReferenceException)
			{
			}
		}
	}
}
namespace InfoSkull.components
{
	public class Display : MonoBehaviour
	{
		private TextAnimator_TMP animator;

		private bool animatorConfigured;

		private bool lastFrameSet;

		private TextMeshProUGUI text;

		private void Awake()
		{
			//IL_002e: 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)
			((Object)this).name = "InfoSkull Display";
			((Component)this).gameObject.AddComponent<Formatable>();
			((Component)this).gameObject.AddComponent<Positionable>();
			((Component)this).GetComponent<RectTransform>().anchoredPosition = Plugin.Display.position.Value;
			text = ((Component)this).GetComponent<TextMeshProUGUI>();
			((Graphic)text).color = new Color(1f, 1f, 1f, 0.1f);
			animator = ((Component)this).GetComponent<TextAnimator_TMP>();
		}

		private void Update()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (lastFrameSet || Plugin.isAdjustingUI)
			{
				lastFrameSet = false;
				return;
			}
			lastFrameSet = true;
			if (Object.op_Implicit((Object)(object)text))
			{
				((TMP_Text)text).SetText(Formatter.format(Plugin.Display.format.Value), true);
			}
			if (!animatorConfigured && Object.op_Implicit((Object)(object)animator) && ((TAnimCore)animator).Behaviors.Length == 2)
			{
				((ShakeBehavior)((TAnimCore)animator).Behaviors[0].animation).baseAmplitude = 0.5f;
				((SizeBehavior)((TAnimCore)animator).Behaviors[1].animation).baseAmplitude = 1f;
				animatorConfigured = true;
			}
		}
	}
	public class Formatable : MonoBehaviour
	{
		private TMP_InputField inputField;

		public string lastCommittedText = "";

		private TextMeshProUGUI text;

		private void Awake()
		{
			text = ((Component)this).GetComponent<TextMeshProUGUI>();
			((Graphic)text).raycastTarget = true;
			inputField = ((Component)this).gameObject.AddComponent<TMP_InputField>();
			inputField.textComponent = (TMP_Text)(object)text;
			inputField.contentType = (ContentType)0;
			inputField.lineType = (LineType)2;
			((UnityEvent<string>)(object)inputField.onEndEdit).AddListener((UnityAction<string>)delegate(string text)
			{
				if (string.IsNullOrWhiteSpace(text))
				{
					inputField.text = "{empty}";
				}
			});
			((UnityEvent<string>)(object)inputField.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
			{
				if (!Input.GetKeyDown((KeyCode)27))
				{
					lastCommittedText = (string.IsNullOrWhiteSpace(text) ? "{empty}" : text);
				}
			});
			((Behaviour)inputField).enabled = true;
			((Behaviour)inputField).enabled = false;
			ContentSizeFitter obj = ((Component)this).gameObject.AddComponent<ContentSizeFitter>();
			obj.horizontalFit = (FitMode)2;
			obj.verticalFit = (FitMode)2;
		}
	}
	public class LevelTimer : MonoBehaviour
	{
		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			((Object)this).name = "InfoSkull LevelTimer";
			((Component)this).gameObject.AddComponent<Formatable>();
			((Component)this).gameObject.AddComponent<Positionable>();
			((Component)this).GetComponent<RectTransform>().anchoredPosition = Plugin.LevelTimer.position.Value;
		}
	}
	public class Positionable : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		private Canvas canvas;

		private CanvasGroup canvasGroup;

		private Vector2 pointerOffset;

		private RectTransform rectTransform;

		private TMP_InputField inputField;

		private readonly float snapThreshold = 20f;

		public void OnBeginDrag(PointerEventData eventData)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)inputField))
			{
				((Behaviour)inputField).enabled = false;
			}
			canvasGroup.blocksRaycasts = false;
			RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, ref pointerOffset);
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0091: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)canvas).transform;
			Vector2 val = default(Vector2);
			if (!RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((transform is RectTransform) ? transform : null), eventData.position, eventData.pressEventCamera, ref val))
			{
				return;
			}
			Vector2 val2 = val - pointerOffset;
			if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303))
			{
				if (Mathf.Abs(val2.x) <= snapThreshold)
				{
					val2.x = 0f;
				}
				if (Mathf.Abs(val2.y) <= snapThreshold)
				{
					val2.y = 0f;
				}
			}
			rectTransform.anchoredPosition = val2;
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)inputField))
			{
				((Behaviour)inputField).enabled = true;
				inputField.ActivateInputField();
				Traverse.Create((object)inputField).Field("caretRectTrans").GetValue<RectTransform>()
					.anchoredPosition = rectTransform.anchoredPosition;
			}
			canvasGroup.blocksRaycasts = true;
		}

		private void Awake()
		{
			canvas = ((Component)this).GetComponentInParent<Canvas>();
			canvasGroup = ((Component)this).GetComponent<CanvasGroup>() ?? ((Component)this).gameObject.AddComponent<CanvasGroup>();
			((Graphic)((Component)this).GetComponent<TextMeshProUGUI>()).raycastTarget = true;
			rectTransform = ((Component)this).GetComponent<RectTransform>();
			inputField = ((Component)this).GetComponent<TMP_InputField>();
		}
	}
}