Decompiled source of DebugMod v1.2.1

plugins/DebugMod.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DebugMod.Helpers;
using DebugMod.Hitbox;
using DebugMod.Interop;
using DebugMod.MonoBehaviours;
using DebugMod.SaveStates;
using DebugMod.UI;
using DebugMod.UI.Canvas;
using DebugMod.UI.CommandPalette;
using DebugMod.UI.Dialogs;
using GlobalEnums;
using GlobalSettings;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using InControl;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using Newtonsoft.Json;
using Steamworks;
using TeamCherry.Localization;
using TeamCherry.NestedFadeGroup;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DebugMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+7a1284158799f80fad574300d5c73bc833571501")]
[assembly: AssemblyProduct("DebugMod")]
[assembly: AssemblyTitle("DebugMod")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/hk-speedrunning/Silksong.DebugMod")]
[assembly: NeutralResourcesLanguage("EN")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace DebugMod
{
	[HarmonyPatch]
	[HarmonyPatch]
	public static class BindableFunctions
	{
		private static string saveLevelStateAction;

		internal static int frameCounter;

		[BindableMethod(name = "CHEATS_KILLALL", category = "CATEGORY_CHEATS")]
		public static void KillAll()
		{
			int num = 0;
			HealthManager[] array = Object.FindObjectsByType<HealthManager>((FindObjectsSortMode)0);
			foreach (HealthManager val in array)
			{
				if (!val.isDead)
				{
					val.Die((float?)null, (AttackTypes)1, true);
					num++;
				}
			}
			DebugMod.LogConsole($"Killing {num} HealthManagers in scene");
		}

		[BindableMethod(name = "CHEATS_INFINITEJUMP", category = "CATEGORY_CHEATS")]
		public static void ToggleInfiniteJump()
		{
			PlayerData.instance.infiniteAirJump = !PlayerData.instance.infiniteAirJump;
			DebugMod.LogConsole("Infinite Jump set to " + PlayerData.instance.infiniteAirJump.ToString().ToUpper());
		}

		[BindableMethod(name = "CHEATS_INFINITESILK", category = "CATEGORY_CHEATS")]
		public static void ToggleInfiniteSilk()
		{
			DebugMod.infiniteSilk = !DebugMod.infiniteSilk;
			DebugMod.LogConsole("Infinite Silk set to " + DebugMod.infiniteSilk.ToString().ToUpper());
		}

		[BindableMethod(name = "CHEATS_INFINITEHP", category = "CATEGORY_CHEATS")]
		public static void ToggleInfiniteHP()
		{
			DebugMod.infiniteHP = !DebugMod.infiniteHP;
			DebugMod.LogConsole("Infinite HP set to " + DebugMod.infiniteHP.ToString().ToUpper());
		}

		[BindableMethod(name = "CHEATS_INFINITETOOLS", category = "CATEGORY_CHEATS")]
		public static void ToggleInfiniteTools()
		{
			DebugMod.infiniteTools = !DebugMod.infiniteTools;
			DebugMod.LogConsole("Infinite Tools set to " + DebugMod.infiniteTools.ToString().ToUpper());
		}

		[BindableMethod(name = "CHEATS_INVINCIBILITY", category = "CATEGORY_CHEATS")]
		public static void ToggleInvincibility()
		{
			DebugMod.playerInvincible = !DebugMod.playerInvincible;
			DebugMod.LogConsole("Invincibility set to " + DebugMod.playerInvincible.ToString().ToUpper());
			PlayerData.instance.isInvincible = DebugMod.playerInvincible;
		}

		[BindableMethod(name = "CHEATS_NOCLIP", category = "CATEGORY_CHEATS")]
		public static void ToggleNoclip()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			DebugMod.noclip = !DebugMod.noclip;
			if (DebugMod.noclip)
			{
				DebugMod.LogConsole("Enabled noclip");
				DebugMod.noclipPos = DebugMod.RefKnight.transform.position;
			}
			else
			{
				DebugMod.LogConsole("Disabled noclip");
				Rigidbody2D component = DebugMod.RefKnight.GetComponent<Rigidbody2D>();
				component.constraints = (RigidbodyConstraints2D)(component.constraints & -4);
			}
		}

		[BindableMethod(name = "CHEATS_TOGGLEHEROCOLLIDER", category = "CATEGORY_CHEATS")]
		public static void ToggleHeroCollider()
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (DebugMod.heroColliderDisabled)
			{
				DebugMod.heroColliderDisabled = false;
				((Behaviour)DebugMod.RefHeroCollider).enabled = true;
				HeroBox.Inactive = false;
				DebugMod.LogConsole("Enabled hero collider" + (DebugMod.noclip ? " and disabled noclip" : ""));
				DebugMod.noclip = false;
				Rigidbody2D component = DebugMod.RefKnight.GetComponent<Rigidbody2D>();
				component.constraints = (RigidbodyConstraints2D)(component.constraints & -4);
			}
			else
			{
				DebugMod.heroColliderDisabled = true;
				((Behaviour)DebugMod.RefHeroCollider).enabled = false;
				HeroBox.Inactive = true;
				DebugMod.LogConsole("Disabled hero collider" + (DebugMod.noclip ? "" : " and enabled noclip"));
				DebugMod.noclip = true;
				DebugMod.noclipPos = DebugMod.RefKnight.transform.position;
			}
		}

		[BindableMethod(name = "CONSUMABLES_GIVEROSARIES", category = "CATEGORY_CONSUMABLES")]
		public static void GiveRosaries()
		{
			HeroController.instance.AddGeo(1000);
			DebugMod.LogConsole("Giving player 1000 rosaries");
		}

		[BindableMethod(name = "CONSUMABLES_GIVESHELLSHARDS", category = "CATEGORY_CONSUMABLES")]
		public static void GiveShellShards()
		{
			HeroController.instance.AddShards(100);
			DebugMod.LogConsole("Giving player 100 shell shards");
		}

		[BindableMethod(name = "CONSUMABLES_GIVEQUESTITEMS", category = "CATEGORY_CONSUMABLES")]
		public static void GiveQuestItems()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			foreach (FullQuestBase activeQuest in QuestManager.GetActiveQuests())
			{
				foreach (QuestTarget target in activeQuest.Targets)
				{
					QuestTargetCounter counter = target.Counter;
					CollectableItem val = (CollectableItem)(object)((counter is CollectableItem) ? counter : null);
					if (val != null)
					{
						int num = target.Count - val.CollectedAmount;
						if (num > 0)
						{
							val.Collect(num, true);
							flag = true;
						}
					}
				}
			}
			if (flag)
			{
				DebugMod.LogConsole("Gave necessary items for all active quests");
			}
			else
			{
				DebugMod.LogConsole("No active quests that need items, doing nothing");
			}
		}

		[BindableMethod(name = "ENEMIES_TOGGLEHPBARS", category = "CATEGORY_ENEMIES")]
		public static void ToggleEnemyHPBars()
		{
			EnemiesPanel.hpBars = !EnemiesPanel.hpBars;
			if (EnemiesPanel.hpBars)
			{
				DebugMod.LogConsole("Enabled HP bars");
			}
			else
			{
				DebugMod.LogConsole("Disabled HP bars");
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_GIVEMASK", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void GiveMask()
		{
			if (PlayerData.instance.maxHealthBase < 10)
			{
				HeroController.instance.MaxHealth();
				HeroController.instance.AddToMaxHealth(1);
				HudHelper.RefreshMasks();
				DebugMod.LogConsole("Added mask");
			}
			else
			{
				DebugMod.LogConsole("You have the maximum number of masks");
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_GIVESPOOL", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void GiveSpool()
		{
			if (PlayerData.instance.silkMax < 18)
			{
				HeroController.instance.AddToMaxSilk(1);
				HudHelper.RefreshSpool();
				DebugMod.LogConsole("Added spool");
			}
			else
			{
				DebugMod.LogConsole("You have the maximum number of spools");
			}
			PlayerData.instance.IsSilkSpoolBroken = false;
			EventRegister.SendEvent("SPOOL UNBROKEN", (GameObject)null);
		}

		[BindableMethod(name = "MASKSANDSPOOLS_TAKEMASK", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void TakeAwayMask()
		{
			if (PlayerData.instance.maxHealthBase > 1)
			{
				PlayerData instance = PlayerData.instance;
				instance.maxHealth--;
				PlayerData instance2 = PlayerData.instance;
				instance2.maxHealthBase--;
				PlayerData.instance.health = Math.Min(PlayerData.instance.health, PlayerData.instance.maxHealth);
				HudHelper.RefreshMasks();
				DebugMod.LogConsole("Removed mask");
			}
			else
			{
				DebugMod.LogConsole("You have the minimum number of masks");
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_TAKESPOOL", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void TakeAwaySpool()
		{
			if (PlayerData.instance.silkMax > 9)
			{
				PlayerData instance = PlayerData.instance;
				instance.silkMax--;
				PlayerData.instance.silk = Math.Min(PlayerData.instance.silk, PlayerData.instance.silkMax);
				HudHelper.RefreshSpool();
				DebugMod.LogConsole("Removed spool");
			}
			else
			{
				DebugMod.LogConsole("You have the minimum number of spools");
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_GIVEMASKSHARD", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void GiveMaskShard()
		{
			if (PlayerData.instance.heartPieces < 3)
			{
				PlayerData instance = PlayerData.instance;
				instance.heartPieces++;
				DebugMod.LogConsole($"Added mask shard (now {PlayerData.instance.heartPieces})");
			}
			else
			{
				PlayerData.instance.heartPieces = 0;
				GiveMask();
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_TAKEMASKSHARD", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void TakeMaskShard()
		{
			if (PlayerData.instance.heartPieces > 0)
			{
				PlayerData instance = PlayerData.instance;
				instance.heartPieces--;
				DebugMod.LogConsole($"Removed mask shard (now {PlayerData.instance.heartPieces})");
			}
			else
			{
				PlayerData.instance.heartPieces = 3;
				TakeAwayMask();
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_GIVESPOOLFRAGMENT", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void GiveSpoolFragment()
		{
			if (PlayerData.instance.silkSpoolParts < 1)
			{
				PlayerData instance = PlayerData.instance;
				instance.silkSpoolParts++;
				DebugMod.LogConsole("Added spool fragment");
			}
			else
			{
				PlayerData.instance.silkSpoolParts = 0;
				GiveSpool();
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_TAKESPOOLFRAGMENT", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void TakeSpoolFragment()
		{
			if (PlayerData.instance.silkSpoolParts > 0)
			{
				PlayerData instance = PlayerData.instance;
				instance.silkSpoolParts--;
				DebugMod.LogConsole("Removed spool fragment");
			}
			else
			{
				PlayerData.instance.silkSpoolParts = 1;
				TakeAwaySpool();
			}
		}

		private static bool CanModifyHealth(int health)
		{
			if (health <= 0)
			{
				DebugMod.LogConsole("Cannot add/take health: health <= 0");
				return false;
			}
			if (HeroController.instance.cState.dead)
			{
				DebugMod.LogConsole("Cannot add/take health: player is dead");
				return false;
			}
			if (!GameManager.instance.IsGameplayScene())
			{
				DebugMod.LogConsole("Cannot add/take health: not a gameplay scene");
				return false;
			}
			return true;
		}

		[BindableMethod(name = "MASKSANDSPOOLS_ADDHEALTH", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void AddHealth()
		{
			if (CanModifyHealth(PlayerData.instance.health + 1))
			{
				HeroController.instance.AddHealth(1);
				HudHelper.RefreshMasks();
				DebugMod.LogConsole("Added health");
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_TAKEHEALTH", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void TakeHealth()
		{
			if (CanModifyHealth(PlayerData.instance.health - 1))
			{
				HeroController.instance.TakeHealth(1);
				HudHelper.RefreshMasks();
				DebugMod.LogConsole("Took health");
			}
		}

		[BindableMethod(name = "MASKSANDSPOOLS_ADDSILK", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void AddSilk()
		{
			HeroController.instance.AddSilk(1, true);
			DebugMod.LogConsole("Added silk");
		}

		[BindableMethod(name = "MASKSANDSPOOLS_TAKESILK", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void TakeSilk()
		{
			HeroController.instance.TakeSilk(1);
			DebugMod.LogConsole("Attempting to take silk");
		}

		[BindableMethod(name = "MASKSANDSPOOLS_ADDLIFEBLOOD", category = "CATEGORY_MASKSANDSPOOLS")]
		public static void Lifeblood()
		{
			bool isInLifebloodState = HeroController.instance.IsInLifebloodState;
			EventRegister.SendEvent("ADD BLUE HEALTH", (GameObject)null);
			if (!isInLifebloodState && HeroController.instance.IsInLifebloodState)
			{
				HeroController.instance.HitMaxBlueHealthBurst();
			}
			DebugMod.LogConsole("Attempting to add lifeblood");
		}

		[BindableMethod(name = "MISC_TOGGLEACT3", category = "CATEGORY_MISC")]
		public static void ToggleAct3()
		{
			PlayerData.instance.blackThreadWorld = !PlayerData.instance.blackThreadWorld;
			DebugMod.LogConsole("Act 3 world is now " + (PlayerData.instance.blackThreadWorld ? "enabled" : "disabled") + ", reload the scene to apply changes");
		}

		[BindableMethod(name = "MISC_SETHAZARDRESPAWN", category = "CATEGORY_MISC")]
		public unsafe static void SetHazardRespawn()
		{
			//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_0015: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = DebugMod.RefKnight.transform.position;
			HeroController.instance.SetHazardRespawn(position, false);
			Vector3 val = position;
			DebugMod.LogConsole("Manual respawn point on this map set to" + ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString());
		}

		[BindableMethod(name = "MISC_HAZARDRESPAWN", category = "CATEGORY_MISC")]
		public static void Respawn()
		{
			if (GameManager.instance.IsGameplayScene() && !HeroController.instance.cState.dead && PlayerData.instance.health > 0)
			{
				if (((object)Unsafe.As<UIState, UIState>(ref UIManager.instance.uiState)/*cast due to .constrained prefix*/).ToString() == "PAUSED")
				{
					((MonoBehaviour)ManagerSingleton<InputHandler>.Instance).StartCoroutine(GameManager.instance.PauseGameToggle(false));
					GameManager.instance.HazardRespawn();
					DebugMod.LogConsole("Closing pause menu and respawning...");
				}
				else if (((object)Unsafe.As<UIState, UIState>(ref UIManager.instance.uiState)/*cast due to .constrained prefix*/).ToString() == "PLAYING")
				{
					HeroController.instance.RelinquishControl();
					GameManager.instance.HazardRespawn();
					HeroController.instance.RegainControl();
					DebugMod.LogConsole("Respawn signal sent");
				}
				else
				{
					DebugMod.LogConsole("How are you seeing this??? (please create a bug report)");
				}
			}
		}

		[BindableMethod(name = "MISC_DAMAGESELF", category = "CATEGORY_MISC")]
		public static void SelfDamage()
		{
			if (PlayerData.instance.health <= 0)
			{
				DebugMod.LogConsole("Cannot damage self: health <= 0");
				return;
			}
			if (HeroController.instance.cState.dead)
			{
				DebugMod.LogConsole("Cannot damage self: player is dead");
				return;
			}
			if (!GameManager.instance.IsGameplayScene())
			{
				DebugMod.LogConsole("Cannot damage self: not a gameplay scene");
				return;
			}
			if (HeroController.instance.cState.recoiling)
			{
				DebugMod.LogConsole("Cannot damage self: player is recoiling");
				return;
			}
			if (HeroController.instance.cState.invulnerable)
			{
				DebugMod.LogConsole("Cannot damage self: player is invulnerable");
				return;
			}
			HeroController.instance.DamageSelf(1);
			DebugMod.LogConsole("Attempting self damage");
		}

		[BindableMethod(name = "MISC_KILLSELF", category = "CATEGORY_MISC")]
		public static void KillSelf()
		{
			if (!HeroController.instance.cState.dead && !HeroController.instance.cState.transitioning)
			{
				((MonoBehaviour)HeroController.instance).StartCoroutine(HeroController.instance.Die(false, false));
				DebugMod.LogConsole("Killed player");
			}
		}

		[BindableMethod(name = "MISC_BREAKCOCOON", category = "CATEGORY_MISC")]
		public static void BreakCocoon()
		{
			HeroController instance = HeroController.instance;
			if (instance != null)
			{
				instance.CocoonBroken();
			}
			EventRegister.SendEvent("BREAK HERO CORPSE", (GameObject)null);
		}

		[BindableMethod(name = "MISC_RESETCURRENTSCENEDATA", category = "CATEGORY_MISC")]
		public static void ResetCurrentScene()
		{
			saveLevelStateAction = GameManager.instance.GetSceneNameString();
			DebugMod.LogConsole("Clearing scene data from this scene, reload the scene to apply changes");
		}

		[BindableMethod(name = "MISC_BLOCKSCENEDATACHANGES", category = "CATEGORY_MISC")]
		public static void BlockCurrentSceneChanges()
		{
			saveLevelStateAction = "block";
			DebugMod.LogConsole("Scene data changes made since entering this scene will not be saved");
		}

		[BindableMethod(name = "MISC_QUEUEWALLJUMPINTERRUPT", category = "CATEGORY_MISC")]
		public static void QueueWallJump()
		{
			HeroController.instance.queuedWallJumpInterrupt = true;
		}

		[HarmonyPatch(typeof(GameManager), "SaveLevelState")]
		[HarmonyPrefix]
		private static bool GameManager_SaveLevelState_Prefix()
		{
			if (saveLevelStateAction == "block")
			{
				saveLevelStateAction = null;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(GameManager), "SaveLevelState")]
		[HarmonyPostfix]
		private static void GameManager_SaveLevelState_Postfix()
		{
			if (saveLevelStateAction != null && saveLevelStateAction != "block")
			{
				((PersistentItemDataCollection<bool, SerializableBoolData>)(object)SceneData.instance.persistentBools).scenes.Remove(saveLevelStateAction);
				((PersistentItemDataCollection<int, SerializableIntData>)(object)SceneData.instance.persistentInts).scenes.Remove(saveLevelStateAction);
				((PersistentItemDataCollection<int, SerializableIntData>)(object)SceneData.instance.geoRocks).scenes.Remove(saveLevelStateAction);
				saveLevelStateAction = null;
			}
		}

		[BindableMethod(name = "MISC_LOCKKEYBINDS", category = "CATEGORY_MISC")]
		public static void ToggleLockKeyBinds()
		{
			DebugMod.KeyBindLock = !DebugMod.KeyBindLock;
			DebugMod.LogConsole((DebugMod.KeyBindLock ? "Removing" : "Adding") + " the ability to use keybinds");
		}

		[BindableMethod(name = "MISC_RESETCHEATS", category = "CATEGORY_MISC")]
		public static void Reset()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			PlayerData instance = PlayerData.instance;
			_ = HeroController.instance;
			GameCameras instance2 = GameCameras.instance;
			DebugMod.extraNailDamage = 0;
			PlayerData.instance.nailUpgrades = 0;
			PlayMakerFSM.BroadcastEvent("UPDATE NAIL DAMAGE");
			GameObject gameObject = ((Component)DebugMod.RefKnight.transform.Find("HeroLight")).gameObject;
			Color color = gameObject.GetComponent<SpriteRenderer>().color;
			color.a = 0.7f;
			gameObject.GetComponent<SpriteRenderer>().color = color;
			tk2dSprite component = DebugMod.RefKnight.GetComponent<tk2dSprite>();
			color = ((tk2dBaseSprite)component).color;
			color.a = 1f;
			((tk2dBaseSprite)component).color = color;
			DebugMod.noclip = false;
			Rigidbody2D component2 = DebugMod.RefKnight.GetComponent<Rigidbody2D>();
			component2.constraints = (RigidbodyConstraints2D)(component2.constraints & -4);
			TimeScale.Reset();
			instance2.tk2dCam.ZoomFactor = 1f;
			VisualMaskHelper.vignetteDisabled = false;
			((Renderer)DebugMod.HC.vignette).enabled = true;
			EnemiesPanel.hpBars = false;
			instance.infiniteAirJump = false;
			DebugMod.infiniteSilk = false;
			DebugMod.infiniteHP = false;
			instance.isInvincible = false;
			DebugMod.LogConsole("Reset all gameplay toggles");
		}

		[BindableMethod(name = "MODUI_TOGGLECOMMANDPALETTE", category = "CATEGORY_MODUI", allowLock = false)]
		public static void ToggleCommandPalette()
		{
			CommandPaletteController.Toggle();
		}

		[BindableMethod(name = "MODUI_TOGGLEALLUI", category = "CATEGORY_MODUI", allowLock = false)]
		public static void ToggleAllPanels()
		{
			bool flag = !DebugMod.settings.InfoPanelVisible || !DebugMod.settings.EnemiesPanelVisible || !DebugMod.settings.MainPanelVisible || !DebugMod.settings.ConsoleVisible || !DebugMod.settings.SaveStatePanelVisible;
			DebugMod.settings.InfoPanelVisible = flag;
			DebugMod.settings.MainPanelVisible = flag;
			DebugMod.settings.EnemiesPanelVisible = flag;
			DebugMod.settings.ConsoleVisible = flag;
			DebugMod.settings.SaveStatePanelVisible = flag;
		}

		[BindableMethod(name = "MODUI_TOGGLEMAINPANEL", category = "CATEGORY_MODUI")]
		public static void ToggleMainPanel()
		{
			DebugMod.settings.MainPanelVisible = !DebugMod.settings.MainPanelVisible;
		}

		[BindableMethod(name = "MODUI_TOGGLEENEMIESPANEL", category = "CATEGORY_MODUI")]
		public static void ToggleEnemiesPanel()
		{
			DebugMod.settings.EnemiesPanelVisible = !DebugMod.settings.EnemiesPanelVisible;
		}

		[BindableMethod(name = "MODUI_TOGGLECONSOLEPANEL", category = "CATEGORY_MODUI")]
		public static void ToggleConsolePanel()
		{
			DebugMod.settings.ConsoleVisible = !DebugMod.settings.ConsoleVisible;
		}

		[BindableMethod(name = "MODUI_TOGGLEINFOPANEL", category = "CATEGORY_MODUI")]
		public static void ToggleInfoPanel()
		{
			DebugMod.settings.InfoPanelVisible = !DebugMod.settings.InfoPanelVisible;
		}

		[BindableMethod(name = "MODUI_TOGGLESAVESTATESPANEL", category = "CATEGORY_MODUI")]
		public static void ToggleSaveStatePanel()
		{
			DebugMod.settings.SaveStatePanelVisible = !DebugMod.settings.SaveStatePanelVisible;
			if (!DebugMod.settings.SaveStatePanelVisible)
			{
				SaveStatesPanel.Instance.CancelSelectState();
			}
		}

		[BindableMethod(name = "MODUI_EXPANDCOLLAPSESAVESTATES", category = "CATEGORY_MODUI")]
		public static void ToggleExpandedSaveStatePanel()
		{
			SaveStatesPanel.Instance.ToggleView();
		}

		[BindableMethod(name = "MODUI_ALWAYSSHOWCURSOR", category = "CATEGORY_MODUI")]
		public static void ToggleAlwaysShowCursor()
		{
			DebugMod.settings.ShowCursorWhileUnpaused = !DebugMod.settings.ShowCursorWhileUnpaused;
			if (DebugMod.settings.ShowCursorWhileUnpaused)
			{
				DebugMod.LogConsole("Showing cursor while unpaused");
			}
			else
			{
				DebugMod.LogConsole("Not showing cursor while unpaused");
			}
		}

		[BindableMethod(name = "SAVESTATES_QUICKSLOTSAVE", category = "CATEGORY_SAVESTATES")]
		public static void SaveState()
		{
			SaveStateManager.SetQuickState(SaveStateManager.SaveNewState());
		}

		[BindableMethod(name = "SAVESTATES_QUICKSLOTLOAD", category = "CATEGORY_SAVESTATES")]
		public static void LoadState()
		{
			SaveStateManager.LoadState(SaveStateManager.GetQuickState());
		}

		[BindableMethod(name = "SAVESTATES_QUICKSLOTTOFILE", category = "CATEGORY_SAVESTATES")]
		public static void CurrentSaveStateToFile()
		{
			SaveStatesPanel.Instance.EnterSelectState(SelectOperation.QuickslotToFile);
		}

		[BindableMethod(name = "SAVESTATES_FILETOQUICKSLOT", category = "CATEGORY_SAVESTATES")]
		public static void CurrentSlotToSaveMemory()
		{
			SaveStatesPanel.Instance.EnterSelectState(SelectOperation.FileToQuickslot);
		}

		[BindableMethod(name = "SAVESTATES_SAVETOFILE", category = "CATEGORY_SAVESTATES")]
		public static void NewSaveStateToFile()
		{
			SaveStatesPanel.Instance.EnterSelectState(SelectOperation.SaveToFile);
		}

		[BindableMethod(name = "SAVESTATES_LOADFROMFILE", category = "CATEGORY_SAVESTATES")]
		public static void LoadFromFile()
		{
			SaveStatesPanel.Instance.EnterSelectState(SelectOperation.LoadFromFile);
		}

		[BindableMethod(name = "SAVESTATES_NEXTSAVESTATEPAGE", category = "CATEGORY_SAVESTATES")]
		public static void NextStatePage()
		{
			SaveStatesPanel.Instance.NextPage();
		}

		[BindableMethod(name = "SAVESTATES_PREVSAVESTATEPAGE", category = "CATEGORY_SAVESTATES")]
		public static void PrevStatePage()
		{
			SaveStatesPanel.Instance.PrevPage();
		}

		[BindableMethod(name = "SAVESTATES_REFRESHFILESLOTS", category = "CATEGORY_SAVESTATES")]
		public static void RefreshFileSlots()
		{
			SaveStateManager.LoadSavestateFiles();
			DebugMod.LogConsole("Reimporting savestates from disk");
		}

		[BindableMethod(name = "SAVESTATES_SAVESTATEONDEATH", category = "CATEGORY_SAVESTATES")]
		public static void LoadStateOnDeath()
		{
			DebugMod.stateOnDeath = !DebugMod.stateOnDeath;
			DebugMod.LogConsole("Quickslot savestate will now" + (DebugMod.stateOnDeath ? " be" : " no longer") + " loaded on death");
		}

		[BindableMethod(name = "SAVESTATES_OVERRIDELOADLOCKOUT", category = "CATEGORY_SAVESTATES")]
		public static void OverrideLoadLockout()
		{
			DebugMod.overrideLoadLockout = !DebugMod.overrideLoadLockout;
			DebugMod.LogConsole("Savestate lockout override set to " + DebugMod.overrideLoadLockout.ToString().ToUpper());
		}

		[BindableMethod(name = "SKILLS_GIVEALLSKILLS", category = "CATEGORY_SKILLS")]
		public static void GiveAllSkills()
		{
			PlayerData.instance.hasDash = true;
			PlayerData.instance.hasBrolly = true;
			PlayerData.instance.hasWalljump = true;
			PlayerData.instance.hasHarpoonDash = true;
			PlayerData.instance.hasDoubleJump = true;
			PlayerData.instance.hasSuperJump = true;
			PlayerData.instance.hasNeedolin = true;
			PlayerData.instance.UnlockedFastTravelTeleport = true;
			PlayerData.instance.hasNeedolinMemoryPowerup = true;
			PlayerData.instance.hasChargeSlash = true;
			PlayerData.instance.nailUpgrades = 4;
			PlayerData.instance.silkRegenMax = 3;
			PlayerData.instance.ToolKitUpgrades = 4;
			PlayerData.instance.ToolPouchUpgrades = 4;
			DebugMod.extraNailDamage = 0;
			DebugMod.LogConsole("Giving player all skills and upgrades");
		}

		[BindableMethod(name = "SKILLS_TOGGLESWIFTSTEP", category = "CATEGORY_SKILLS")]
		public static void ToggleSwiftStep()
		{
			if (!PlayerData.instance.hasDash)
			{
				PlayerData.instance.hasDash = true;
				DebugMod.LogConsole("Giving player Swift Step");
			}
			else
			{
				PlayerData.instance.hasDash = false;
				DebugMod.LogConsole("Taking away Swift Step");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLEDRIFTERSCLOAK", category = "CATEGORY_SKILLS")]
		public static void ToggleDriftersCloak()
		{
			if (!PlayerData.instance.hasBrolly)
			{
				PlayerData.instance.hasBrolly = true;
				DebugMod.LogConsole("Giving player Drifter's Cloak");
			}
			else
			{
				PlayerData.instance.hasBrolly = false;
				DebugMod.LogConsole("Taking away Drifter's Cloak");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLECLINGGRIP", category = "CATEGORY_SKILLS")]
		public static void ToggleClingGrip()
		{
			if (!PlayerData.instance.hasWalljump)
			{
				PlayerData.instance.hasWalljump = true;
				DebugMod.LogConsole("Giving player Cling Grip");
			}
			else
			{
				PlayerData.instance.hasWalljump = false;
				DebugMod.LogConsole("Taking away Cling Grip");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLENEEDOLIN", category = "CATEGORY_SKILLS")]
		public static void ToggleNeedolin()
		{
			if (!PlayerData.instance.hasNeedolin)
			{
				PlayerData.instance.hasNeedolin = true;
				DebugMod.LogConsole("Giving player Needolin");
				return;
			}
			PlayerData.instance.hasNeedolin = false;
			PlayerData.instance.UnlockedFastTravelTeleport = false;
			PlayerData.instance.hasNeedolinMemoryPowerup = false;
			DebugMod.LogConsole("Taking away Needolin and any upgrades");
		}

		[BindableMethod(name = "SKILLS_TOGGLECLAWLINE", category = "CATEGORY_SKILLS")]
		public static void ToggleClawline()
		{
			if (!PlayerData.instance.hasHarpoonDash)
			{
				PlayerData.instance.hasHarpoonDash = true;
				DebugMod.LogConsole("Giving player Clawline");
			}
			else
			{
				PlayerData.instance.hasHarpoonDash = false;
				DebugMod.LogConsole("Taking away Clawline");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLEFAYDOWNCLOAK", category = "CATEGORY_SKILLS")]
		public static void ToggleFaydownCloak()
		{
			if (!PlayerData.instance.hasDoubleJump)
			{
				PlayerData.instance.hasDoubleJump = true;
				DebugMod.LogConsole("Giving player Faydown Cloak");
			}
			else
			{
				PlayerData.instance.hasDoubleJump = false;
				DebugMod.LogConsole("Taking away Faydown Cloak");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLESILKSOAR", category = "CATEGORY_SKILLS")]
		public static void ToggleSilkSoar()
		{
			if (!PlayerData.instance.hasSuperJump)
			{
				PlayerData.instance.hasSuperJump = true;
				DebugMod.LogConsole("Giving player Silk Soar");
			}
			else
			{
				PlayerData.instance.hasSuperJump = false;
				DebugMod.LogConsole("Taking away Silk Soar");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLEBEASTLINGCALL", category = "CATEGORY_SKILLS")]
		public static void ToggleBeastlingCall()
		{
			if (!PlayerData.instance.hasNeedolin && !PlayerData.instance.UnlockedFastTravelTeleport)
			{
				PlayerData.instance.hasNeedolin = true;
				PlayerData.instance.UnlockedFastTravelTeleport = true;
				DebugMod.LogConsole("Giving player Needolin with Beastling Call");
			}
			else if (PlayerData.instance.hasNeedolin && !PlayerData.instance.UnlockedFastTravelTeleport)
			{
				PlayerData.instance.UnlockedFastTravelTeleport = true;
				DebugMod.LogConsole("Giving player Beastling Call");
			}
			else
			{
				PlayerData.instance.UnlockedFastTravelTeleport = false;
				DebugMod.LogConsole("Taking away Beastling Call");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLEELEGYOFTHEDEEP", category = "CATEGORY_SKILLS")]
		public static void ToggleElegyOfTheDeep()
		{
			if (!PlayerData.instance.hasNeedolin && !PlayerData.instance.hasNeedolinMemoryPowerup)
			{
				PlayerData.instance.hasNeedolin = true;
				PlayerData.instance.hasNeedolinMemoryPowerup = true;
				DebugMod.LogConsole("Giving player Needolin with Elegy of the Deep");
			}
			else if (PlayerData.instance.hasNeedolin && !PlayerData.instance.hasNeedolinMemoryPowerup)
			{
				PlayerData.instance.hasNeedolinMemoryPowerup = true;
				DebugMod.LogConsole("Giving player Elegy of the Deep");
			}
			else
			{
				PlayerData.instance.hasNeedolinMemoryPowerup = false;
				DebugMod.LogConsole("Taking away Elegy of the Deep");
			}
		}

		[BindableMethod(name = "SKILLS_TOGGLENEEDLESTRIKE", category = "CATEGORY_SKILLS")]
		public static void ToggleNeedleStrike()
		{
			if (!PlayerData.instance.hasChargeSlash)
			{
				PlayerData.instance.hasChargeSlash = true;
				DebugMod.LogConsole("Giving player Needle Strike");
			}
			else
			{
				PlayerData.instance.hasChargeSlash = false;
				DebugMod.LogConsole("Taking away Needle Strike");
			}
		}

		[BindableMethod(name = "TIME_INCREASETIMESCALE", category = "CATEGORY_TIME")]
		public static void TimescaleUp()
		{
			TimeScale.CustomTimeScale = Mathf.Round(TimeScale.CustomTimeScale * 10f + 1f) / 10f;
		}

		[BindableMethod(name = "TIME_DECREASETIMESCALE", category = "CATEGORY_TIME")]
		public static void TimescaleDown()
		{
			TimeScale.CustomTimeScale = Mathf.Round(TimeScale.CustomTimeScale * 10f - 1f) / 10f;
		}

		[BindableMethod(name = "TIME_RESETTIMESCALE", category = "CATEGORY_TIME")]
		public static void TimescaleReset()
		{
			TimeScale.CustomTimeScale = 1f;
		}

		[BindableMethod(name = "TIME_FREEZEGAME", category = "CATEGORY_TIME")]
		public static void PauseGameNoUI()
		{
			TimeScale.Frozen = !TimeScale.Frozen;
			if (TimeScale.Frozen)
			{
				frameCounter = 0;
				DebugMod.LogConsole("Game frozen");
			}
			else
			{
				DebugMod.LogConsole("Game unfrozen");
			}
		}

		[BindableMethod(name = "TIME_FORCEPAUSE", category = "CATEGORY_TIME")]
		public static void ForcePause()
		{
			try
			{
				if (PlayerData.instance.disablePause || GameManager.instance.TimeSlowed || (UIManager.instance.ignoreUnpause && DebugMod.GetSceneName() != "Menu_Title" && DebugMod.GM.IsGameplayScene()))
				{
					GameManager.instance.timeSlowedCount = 0;
					UIManager.instance.ignoreUnpause = false;
					PlayerData.instance.disablePause = false;
					UIManager.instance.TogglePauseGame();
					DebugMod.LogConsole("Forcing pause menu because pause is disabled");
				}
				else
				{
					DebugMod.LogConsole("Pausing game");
					UIManager.instance.TogglePauseGame();
				}
				DebugMod.forcePaused = !GameManager.instance.isPaused;
			}
			catch (Exception ex)
			{
				DebugMod.LogConsole("Error while attempting to pause, please create a bug report");
				DebugMod.Log("Error while attempting force pause:\n" + ex);
			}
		}

		[BindableMethod(name = "TIME_ADVANCEFRAME", category = "CATEGORY_TIME")]
		public static void AdvanceFrame()
		{
			if (!TimeScale.Frozen)
			{
				TimeScale.Frozen = true;
			}
			frameCounter++;
			((MonoBehaviour)GameManager.instance).StartCoroutine(AdvanceMyFrame());
		}

		private static IEnumerator AdvanceMyFrame()
		{
			TimeScale.Frozen = false;
			yield return (object)new WaitForFixedUpdate();
			TimeScale.Frozen = true;
		}

		[BindableMethod(name = "TIME_RESETFRAMECOUNTER", category = "CATEGORY_TIME")]
		public static void ResetFrameCounter()
		{
			DebugMod.LogConsole($"Frame counter reset (was {frameCounter})");
			frameCounter = 0;
		}

		[BindableMethod(name = "TOOLS_UNLOCKALLTOOLS", category = "CATEGORY_TOOLS")]
		public static void UnlockAllTools()
		{
			HashSet<string> hashSet = new HashSet<string> { "Curve Claws Upgraded", "WebShot Architect", "WebShot Weaver", "Mosscreep Tool 2", "Dazzle Bind Upgraded", "Shell Satchel" };
			foreach (ToolItem allTool in ToolItemManager.GetAllTools())
			{
				if (!hashSet.Contains(allTool.name))
				{
					allTool.Unlock((Action)null, (PopupFlags)0);
				}
				else
				{
					allTool.Lock();
				}
			}
			DebugMod.LogConsole("Unlocked all tools");
		}

		[BindableMethod(name = "CRESTS_UNLOCKALLCRESTS", category = "CATEGORY_TOOLS")]
		public static void UnlockAllCrests()
		{
			ToolItemManager.UnlockAllCrests();
			DebugMod.LogConsole("Unlocked all crests");
		}

		[BindableMethod(name = "TOOLS_CRAFTTOOLS", category = "CATEGORY_TOOLS")]
		public static void CraftTools()
		{
			ToolItemManager.TryReplenishTools(true, (ReplenishMethod)0);
			DebugMod.LogConsole("Crafted new tools");
		}

		[BindableMethod(name = "CRESTS_FREEEQUIP", category = "CATEGORY_TOOLS")]
		public static void FreeEquip()
		{
			if (DebugMod.freeEquip)
			{
				DebugMod.freeEquip = false;
				DebugMod.LogConsole("You can no longer change crests and tools away from a bench");
			}
			else
			{
				DebugMod.freeEquip = true;
				DebugMod.LogConsole("You can now change crests and tools away from a bench");
			}
		}

		[BindableMethod(name = "CRESTS_TOGGLECURSED", category = "CATEGORY_TOOLS")]
		public static void ToggleCursed()
		{
			if (((ToolBase)Gameplay.CursedCrest).IsEquipped)
			{
				ToolItemManager.ResetPreviousCrest();
				PlayerData.instance.PreviousCrestID = "";
				Utils.AutoEquipCrest(null, removeTools: false);
				DebugMod.LogConsole("Disabled cursed state");
			}
			else
			{
				Utils.AutoEquipCrest(Gameplay.CursedCrest, removeTools: true);
				DebugMod.LogConsole("Enabled cursed state");
			}
			HeroController.instance.UpdateSilkCursed();
		}

		[BindableMethod(name = "CRESTS_TOGGLECLOAKLESS", category = "CATEGORY_TOOLS")]
		public static void ToggleCloakless()
		{
			if (((ToolBase)Gameplay.CloaklessCrest).IsEquipped)
			{
				ToolItemManager.ResetPreviousCrest();
				PlayerData.instance.PreviousCrestID = "";
				Utils.AutoEquipCrest(null, removeTools: false);
				DebugMod.LogConsole("Disabled cloakless state");
			}
			else
			{
				Utils.AutoEquipCrest(Gameplay.CloaklessCrest, removeTools: true);
				DebugMod.LogConsole("Enabled cloakless state");
			}
			if (PlayerData.instance.PreviousCrestID == "Cursed")
			{
				HeroController.instance.UpdateSilkCursed();
			}
			HeroController.instance.ResetAllCrestState();
			HeroController.instance.animCtrl.PlayFromFrame(HeroController.instance.animCtrl.animator.CurrentClip.name, HeroController.instance.animCtrl.animator.CurrentFrame, true);
		}

		[BindableMethod(name = "UPGRADES_INCREASENEEDLEDAMAGE", category = "CATEGORY_UPGRADES")]
		public static void IncreaseNeedleDamage()
		{
			if (PlayerData.instance.nailDamage == 0)
			{
				PlayerData.instance.nailUpgrades = 0;
				DebugMod.extraNailDamage = 0;
				DebugMod.LogConsole("Resetting needle damage to 5");
			}
			else if (PlayerData.instance.nailUpgrades == 4 || DebugMod.extraNailDamage < 0)
			{
				DebugMod.extraNailDamage += 4;
				DebugMod.LogConsole("Adding 4 extra needle damage");
			}
			else
			{
				PlayerData instance = PlayerData.instance;
				instance.nailUpgrades++;
				DebugMod.LogConsole("Adding needle upgrade");
			}
			PlayMakerFSM.BroadcastEvent("UPDATE NAIL DAMAGE");
		}

		[BindableMethod(name = "UPGRADES_DECREASENEEDLEDAMAGE", category = "CATEGORY_UPGRADES")]
		public static void DecreaseNeedleDamage()
		{
			if (PlayerData.instance.nailUpgrades == 0 || DebugMod.extraNailDamage > 0)
			{
				DebugMod.extraNailDamage -= 4;
				if (DebugMod.extraNailDamage < -5)
				{
					DebugMod.extraNailDamage = -5;
					DebugMod.LogConsole("Setting needle damage to 0");
				}
				else
				{
					DebugMod.LogConsole("Reducing needle damage by 4");
				}
			}
			else
			{
				PlayerData instance = PlayerData.instance;
				instance.nailUpgrades--;
				DebugMod.LogConsole("Removing needle upgrade");
			}
			PlayMakerFSM.BroadcastEvent("UPDATE NAIL DAMAGE");
		}

		[BindableMethod(name = "UPGRADES_INCREMENTCRAFTINGKIT", category = "CATEGORY_UPGRADES")]
		public static void IncrementKits()
		{
			if (PlayerData.instance.ToolKitUpgrades < 4)
			{
				PlayerData instance = PlayerData.instance;
				instance.ToolKitUpgrades++;
				DebugMod.LogConsole($"Increasing crafting kit level (now {PlayerData.instance.ToolKitUpgrades})");
			}
			else
			{
				DebugMod.LogConsole("Crafting kit already at max level");
			}
		}

		[BindableMethod(name = "UPGRADES_DECREMENTCRAFTINGKIT", category = "CATEGORY_UPGRADES")]
		public static void DecrementKits()
		{
			if (PlayerData.instance.ToolKitUpgrades > 0)
			{
				PlayerData instance = PlayerData.instance;
				instance.ToolKitUpgrades--;
				DebugMod.LogConsole($"Decreasing crafting kit level (now {PlayerData.instance.ToolKitUpgrades})");
			}
			else
			{
				DebugMod.LogConsole("Crafting kit already at base level");
			}
		}

		[BindableMethod(name = "UPGRADES_INCREMENTTOOLPOUCH", category = "CATEGORY_UPGRADES")]
		public static void IncrementPouches()
		{
			if (PlayerData.instance.ToolPouchUpgrades < 4)
			{
				PlayerData instance = PlayerData.instance;
				instance.ToolPouchUpgrades++;
				DebugMod.LogConsole($"Increasing tool pouch level (now {PlayerData.instance.ToolPouchUpgrades})");
			}
			else
			{
				DebugMod.LogConsole("Tool pouch already at max level");
			}
		}

		[BindableMethod(name = "UPGRADES_DECREMENTTOOLPOUCH", category = "CATEGORY_UPGRADES")]
		public static void DecrementPouches()
		{
			if (PlayerData.instance.ToolPouchUpgrades > 0)
			{
				PlayerData instance = PlayerData.instance;
				instance.ToolPouchUpgrades--;
				DebugMod.LogConsole($"Decreasing tool pouch level (now {PlayerData.instance.ToolPouchUpgrades})");
			}
			else
			{
				DebugMod.LogConsole("Tool pouch already at base level");
			}
		}

		[BindableMethod(name = "UPGRADES_INCREMENTSILKHEARTS", category = "CATEGORY_UPGRADES")]
		public static void IncrementSilkHeart()
		{
			PlayerData instance = PlayerData.instance;
			instance.silkRegenMax++;
			DebugMod.LogConsole($"Incremented silk hearts (now {PlayerData.instance.silkRegenMax})");
		}

		[BindableMethod(name = "UPGRADES_DECREMENTSILKHEARTS", category = "CATEGORY_UPGRADES")]
		public static void DecrementSilkHeart()
		{
			if (PlayerData.instance.silkRegenMax > 0)
			{
				PlayerData instance = PlayerData.instance;
				instance.silkRegenMax--;
				DebugMod.LogConsole($"Decremented silk hearts (now {PlayerData.instance.silkRegenMax})");
			}
			else
			{
				DebugMod.LogConsole("Already at 0 silk hearts");
			}
		}

		[BindableMethod(name = "WORLD_ALLMAPS", category = "CATEGORY_UPGRADES")]
		public static void UnlockAllMaps()
		{
			if (PlayerData.instance.HasAllMaps)
			{
				PlayerData.instance.HasAbyssMap = false;
				PlayerData.instance.HasAqueductMap = false;
				PlayerData.instance.HasArboriumMap = false;
				PlayerData.instance.HasBellhartMap = false;
				PlayerData.instance.HasBoneforestMap = false;
				PlayerData.instance.HasCitadelUnderstoreMap = false;
				PlayerData.instance.HasCloverMap = false;
				PlayerData.instance.HasCogMap = false;
				PlayerData.instance.HasCoralMap = false;
				PlayerData.instance.HasCradleMap = false;
				PlayerData.instance.HasCrawlMap = false;
				PlayerData.instance.HasDocksMap = false;
				PlayerData.instance.HasDustpensMap = false;
				PlayerData.instance.HasGreymoorMap = false;
				PlayerData.instance.HasHallsMap = false;
				PlayerData.instance.HasHangMap = false;
				PlayerData.instance.HasHuntersNestMap = false;
				PlayerData.instance.HasJudgeStepsMap = false;
				PlayerData.instance.HasLibraryMap = false;
				PlayerData.instance.HasMossGrottoMap = false;
				PlayerData.instance.HasPeakMap = false;
				PlayerData.instance.HasShellwoodMap = false;
				PlayerData.instance.HasSlabMap = false;
				PlayerData.instance.HasSongGateMap = false;
				PlayerData.instance.HasSwampMap = false;
				PlayerData.instance.HasWardMap = false;
				PlayerData.instance.HasWeavehomeMap = false;
				PlayerData.instance.HasWildsMap = false;
				PlayerData.instance.hasQuill = false;
				CollectableItemManager.IncrementVersion();
				DebugMod.LogConsole("Removed all maps");
				return;
			}
			PlayerData.instance.HasAbyssMap = true;
			PlayerData.instance.HasAqueductMap = true;
			PlayerData.instance.HasArboriumMap = true;
			PlayerData.instance.HasBellhartMap = true;
			PlayerData.instance.HasBoneforestMap = true;
			PlayerData.instance.HasCitadelUnderstoreMap = true;
			PlayerData.instance.HasCloverMap = true;
			PlayerData.instance.HasCogMap = true;
			PlayerData.instance.HasCoralMap = true;
			PlayerData.instance.HasCradleMap = true;
			PlayerData.instance.HasCrawlMap = true;
			PlayerData.instance.HasDocksMap = true;
			PlayerData.instance.HasDustpensMap = true;
			PlayerData.instance.HasGreymoorMap = true;
			PlayerData.instance.HasHallsMap = true;
			PlayerData.instance.HasHangMap = true;
			PlayerData.instance.HasHuntersNestMap = true;
			PlayerData.instance.HasJudgeStepsMap = true;
			PlayerData.instance.HasLibraryMap = true;
			PlayerData.instance.HasMossGrottoMap = true;
			PlayerData.instance.HasPeakMap = true;
			PlayerData.instance.HasShellwoodMap = true;
			PlayerData.instance.HasSlabMap = true;
			PlayerData.instance.HasSongGateMap = true;
			PlayerData.instance.HasSwampMap = true;
			PlayerData.instance.HasWardMap = true;
			PlayerData.instance.HasWeavehomeMap = true;
			PlayerData.instance.HasWildsMap = true;
			PlayerData.instance.hasQuill = true;
			PlayerData.instance.QuillState = 1;
			CollectableItemManager.IncrementVersion();
			ZoneInfo[] mapZoneInfo = GameManager.instance.gameMap.mapZoneInfo;
			for (int i = 0; i < mapZoneInfo.Length; i++)
			{
				ParentInfo[] parents = mapZoneInfo[i].Parents;
				for (int j = 0; j < parents.Length; j++)
				{
					foreach (MapCache map in parents[j].Maps)
					{
						string sceneName = map.sceneName;
						if (!string.IsNullOrEmpty(sceneName))
						{
							PlayerData.instance.scenesVisited.Add(sceneName);
							PlayerData.instance.scenesMapped.Add(sceneName);
						}
					}
				}
			}
			GameManager.instance.gameMap.SetupMap(false);
			DebugMod.LogConsole("Unlocked all maps");
		}

		[BindableMethod(name = "WORLD_ALLFASTTRAVEL", category = "CATEGORY_UPGRADES")]
		public static void UnlockAllFastTravel()
		{
			if (PlayerData.instance.UnlockedAqueductStation && PlayerData.instance.UnlockedBelltownStation && PlayerData.instance.UnlockedBoneforestEastStation && PlayerData.instance.UnlockedCityStation && PlayerData.instance.UnlockedCoralTowerStation && PlayerData.instance.UnlockedDocksStation && PlayerData.instance.UnlockedGreymoorStation && PlayerData.instance.UnlockedPeakStation && PlayerData.instance.UnlockedShadowStation && PlayerData.instance.UnlockedShellwoodStation && PlayerData.instance.UnlockedArboriumTube && PlayerData.instance.UnlockedCityBellwayTube && PlayerData.instance.UnlockedEnclaveTube && PlayerData.instance.UnlockedHangTube && PlayerData.instance.UnlockedSongTube && PlayerData.instance.UnlockedUnderTube)
			{
				PlayerData.instance.UnlockedAqueductStation = false;
				PlayerData.instance.UnlockedBelltownStation = false;
				PlayerData.instance.UnlockedBoneforestEastStation = false;
				PlayerData.instance.UnlockedCityStation = false;
				PlayerData.instance.UnlockedCoralTowerStation = false;
				PlayerData.instance.UnlockedDocksStation = false;
				PlayerData.instance.UnlockedGreymoorStation = false;
				PlayerData.instance.UnlockedPeakStation = false;
				PlayerData.instance.UnlockedShadowStation = false;
				PlayerData.instance.UnlockedShellwoodStation = false;
				PlayerData.instance.UnlockedArboriumTube = false;
				PlayerData.instance.UnlockedCityBellwayTube = false;
				PlayerData.instance.UnlockedEnclaveTube = false;
				PlayerData.instance.UnlockedHangTube = false;
				PlayerData.instance.UnlockedSongTube = false;
				PlayerData.instance.UnlockedUnderTube = false;
				DebugMod.LogConsole("Removed all fast travel");
			}
			else
			{
				PlayerData.instance.UnlockedAqueductStation = true;
				PlayerData.instance.UnlockedBelltownStation = true;
				PlayerData.instance.UnlockedBoneforestEastStation = true;
				PlayerData.instance.UnlockedCityStation = true;
				PlayerData.instance.UnlockedCoralTowerStation = true;
				PlayerData.instance.UnlockedDocksStation = true;
				PlayerData.instance.UnlockedGreymoorStation = true;
				PlayerData.instance.UnlockedPeakStation = true;
				PlayerData.instance.UnlockedShadowStation = true;
				PlayerData.instance.UnlockedShellwoodStation = true;
				PlayerData.instance.UnlockedArboriumTube = true;
				PlayerData.instance.UnlockedCityBellwayTube = true;
				PlayerData.instance.UnlockedEnclaveTube = true;
				PlayerData.instance.UnlockedHangTube = true;
				PlayerData.instance.UnlockedSongTube = true;
				PlayerData.instance.UnlockedUnderTube = true;
				DebugMod.LogConsole("Unlocked all fast travel");
			}
		}

		[BindableMethod(name = "VISUAL_TOGGLEHITBOXES", category = "CATEGORY_VISUAL")]
		public static void ShowHitboxes()
		{
			if (++DebugMod.settings.ShowHitBoxes > 2)
			{
				DebugMod.settings.ShowHitBoxes = 0;
			}
			switch (DebugMod.settings.ShowHitBoxes)
			{
			case 0:
				DebugMod.LogConsole("Not showing hitboxes");
				break;
			case 1:
				DebugMod.LogConsole("Showing hitboxes");
				break;
			case 2:
				DebugMod.LogConsole("Showing all hitboxes");
				break;
			}
		}

		[BindableMethod(name = "VISUAL_FORCECAMERAFOLLOW", category = "CATEGORY_VISUAL")]
		public static void ForceCameraFollow()
		{
			if (!DebugMod.cameraFollow)
			{
				DebugMod.LogConsole("Forcing camera follow");
				DebugMod.cameraFollow = true;
			}
			else
			{
				DebugMod.cameraFollow = false;
				DebugMod.RefCamera.isGameplayScene = true;
				DebugMod.LogConsole("Returning camera to normal settings");
			}
		}

		[BindableMethod(name = "VISUAL_PREVIEWCOCOONPOSITION", category = "CATEGORY_VISUAL")]
		public static void PreviewCocoonPosition()
		{
			CocoonPreviewer cocoonPreviewer = ((Component)GameManager.instance).GetComponent<CocoonPreviewer>() ?? ((Component)GameManager.instance).gameObject.AddComponent<CocoonPreviewer>();
			if (!cocoonPreviewer.previewEnabled)
			{
				cocoonPreviewer.previewEnabled = true;
				DebugMod.LogConsole("Enabled cocoon spawn point preview");
			}
			else
			{
				cocoonPreviewer.previewEnabled = false;
				DebugMod.LogConsole("Disabled cocoon spawn point preview");
			}
		}

		[BindableMethod(name = "VISUAL_TOGGLEVIGNETTE", category = "CATEGORY_VISUAL")]
		public static void ToggleVignette()
		{
			VisualMaskHelper.ToggleVignette();
		}

		[BindableMethod(name = "VISUAL_DEACTIVATEVISUALMASKS", category = "CATEGORY_VISUAL")]
		public static void DoDeactivateVisualMasks()
		{
			VisualMaskHelper.ToggleAllMasks();
		}

		[BindableMethod(name = "VISUAL_TOGGLEHEROLIGHT", category = "CATEGORY_VISUAL")]
		public static void ToggleHeroLight()
		{
			//IL_0020: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)DebugMod.RefKnight.transform.Find("HeroLight")).gameObject;
			Color color = gameObject.GetComponent<SpriteRenderer>().color;
			if (Math.Abs(color.a) > 0f)
			{
				color.a = 0f;
				gameObject.GetComponent<SpriteRenderer>().color = color;
				DebugMod.LogConsole("Making hero light invisible");
			}
			else
			{
				color.a = 0.7f;
				gameObject.GetComponent<SpriteRenderer>().color = color;
				DebugMod.LogConsole("Making hero light visible");
			}
		}

		[BindableMethod(name = "VISUAL_TOGGLEHUD", category = "CATEGORY_VISUAL")]
		public static void ToggleHUD()
		{
			if (((Component)GameCameras.instance.hudCanvasSlideOut).gameObject.activeInHierarchy)
			{
				((Component)GameCameras.instance.hudCanvasSlideOut).gameObject.SetActive(false);
				DebugMod.LogConsole("Disabling HUD");
			}
			else
			{
				((Component)GameCameras.instance.hudCanvasSlideOut).gameObject.SetActive(true);
				HudHelper.RefreshSpool();
				DebugMod.LogConsole("Enabling HUD");
			}
		}

		[HarmonyPatch(typeof(SilkSpool), "ChangeSilk")]
		[HarmonyPrefix]
		private static bool SilkSpool_ChangeSilk()
		{
			return ((Component)GameCameras.instance.hudCanvasSlideOut).gameObject.activeInHierarchy;
		}

		[BindableMethod(name = "VISUAL_ZOOMIN", category = "CATEGORY_VISUAL")]
		public static void ZoomIn()
		{
			tk2dCamera tk2dCam = GameCameras.instance.tk2dCam;
			tk2dCam.zoomFactor *= 1.1f;
			ZoomHelper.UpdateCameraFOV();
			DebugMod.LogConsole($"Zoom level increased to {GameCameras.instance.tk2dCam.ZoomFactor}");
		}

		[BindableMethod(name = "VISUAL_ZOOMOUT", category = "CATEGORY_VISUAL")]
		public static void ZoomOut()
		{
			tk2dCamera tk2dCam = GameCameras.instance.tk2dCam;
			tk2dCam.zoomFactor *= 0.9f;
			ZoomHelper.UpdateCameraFOV();
			DebugMod.LogConsole($"Zoom level increased to {GameCameras.instance.tk2dCam.ZoomFactor}");
		}

		[BindableMethod(name = "VISUAL_RESETZOOM", category = "CATEGORY_VISUAL")]
		public static void ResetZoom()
		{
			GameCameras.instance.tk2dCam.ZoomFactor = 1f;
			ZoomHelper.UpdateCameraFOV();
			DebugMod.LogConsole("Zoom level was reset");
		}

		[BindableMethod(name = "VISUAL_HIDEHERO", category = "CATEGORY_VISUAL")]
		public static void HideHero()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_004f: 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)
			tk2dSprite component = DebugMod.RefKnight.GetComponent<tk2dSprite>();
			Color color = ((tk2dBaseSprite)component).color;
			if (Math.Abs(color.a) > 0f)
			{
				color.a = 0f;
				((tk2dBaseSprite)component).color = color;
				DebugMod.LogConsole("Making hero sprite invisible");
			}
			else
			{
				color.a = 1f;
				((tk2dBaseSprite)component).color = color;
				DebugMod.LogConsole("Making hero sprite visible");
			}
		}

		[BindableMethod(name = "VISUAL_TOGGLECAMERASHAKE", category = "CATEGORY_VISUAL")]
		public static void ToggleCameraShake()
		{
			bool flag = !((Behaviour)GameCameras.instance.cameraShakeFSM).enabled;
			((Behaviour)GameCameras.instance.cameraShakeFSM).enabled = flag;
			DebugMod.LogConsole((flag ? "Enabling" : "Disabling") + " camera shake");
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	public class BindableMethod : Attribute
	{
		public string name;

		public string category;

		public bool allowLock = true;
	}
	public class BindAction
	{
		public string Name { get; }

		public string Category { get; }

		public bool AllowLock { get; }

		public Action Action { get; }

		public BindAction(string name, string category, bool allowLock, Action action)
		{
			Name = name;
			Category = category;
			AllowLock = allowLock;
			Action = action;
		}

		public BindAction(BindableMethod attribute, MethodInfo method)
		{
			Name = attribute.name;
			Category = attribute.category;
			AllowLock = attribute.allowLock;
			Action = (Action)Delegate.CreateDelegate(typeof(Action), method);
		}
	}
	[JsonConverter(typeof(BindingJsonConverter))]
	public readonly struct Binding : IEquatable<Binding>
	{
		private sealed class BindingJsonConverter : JsonConverter<Binding>
		{
			public override void WriteJson(JsonWriter writer, Binding value, JsonSerializer serializer)
			{
				writer.WriteValue(value.ToString());
			}

			public override Binding ReadJson(JsonReader reader, Type objectType, Binding existingValue, bool hasExistingValue, JsonSerializer serializer)
			{
				object value = reader.Value;
				if (!(value is string value2))
				{
					if (value == null)
					{
						return default(Binding);
					}
					throw new ArgumentException($"Invalid binding '{reader.Value}'");
				}
				return Parse(value2);
			}
		}

		public Modifier Modifiers { get; }

		public KeyCode Key { get; }

		private static Modifier TextShortcutModifier
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				if ((int)Application.platform != 1)
				{
					return Modifier.Ctrl;
				}
				return Modifier.Meta;
			}
		}

		public Binding(Modifier modifiers, KeyCode key)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Modifiers = modifiers;
			Key = key;
		}

		public Binding(KeyCode key)
			: this(Modifier.None, key)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)


		public static implicit operator Binding(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new Binding(key);
		}

		public bool Equals(Binding other)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (Modifiers == other.Modifiers)
			{
				return Key == other.Key;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Binding other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return HashCode.Combine<Modifier, KeyCode>(Modifiers, Key);
		}

		public static bool operator ==(Binding left, Binding right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(Binding left, Binding right)
		{
			return !(left == right);
		}

		public bool IsDown()
		{
			return IsDown(global::DebugMod.Modifiers.Held());
		}

		public bool IsDown(Modifier modifiers)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Key != 0 && Input.GetKeyDown(Key))
			{
				return modifiers.Without(Key) == Modifiers;
			}
			return false;
		}

		public bool IsCapturedByTextField()
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0021: 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_0051: Expected I4, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_00a3: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Invalid comparison between Unknown and I4
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Invalid comparison between Unknown and I4
			KeyCode key = Key;
			if ((int)key <= 13)
			{
				if ((int)key != 8 && (int)key != 13)
				{
					goto IL_0057;
				}
			}
			else if ((int)key != 27 && (int)key != 127)
			{
				switch (key - 271)
				{
				case 0:
				case 2:
				case 3:
				case 4:
				case 5:
				case 7:
				case 8:
					break;
				default:
					goto IL_0057;
				}
			}
			bool flag = true;
			goto IL_0059;
			IL_00cb:
			bool flag2;
			if (flag2)
			{
				return Modifiers == Modifier.None;
			}
			return false;
			IL_0088:
			bool flag3;
			flag2 = flag3 && Modifiers == TextShortcutModifier;
			goto IL_009d;
			IL_00c5:
			flag2 = true;
			goto IL_00cb;
			IL_0080:
			flag3 = true;
			goto IL_0088;
			IL_009d:
			if (flag2)
			{
				return true;
			}
			key = Key;
			if ((int)key >= 256)
			{
				if ((int)key <= 272)
				{
					goto IL_00c5;
				}
			}
			else if ((int)key >= 32 && (int)key <= 126)
			{
				goto IL_00c5;
			}
			flag2 = false;
			goto IL_00cb;
			IL_0059:
			flag2 = flag;
			if (!flag2)
			{
				KeyCode key2 = Key;
				if ((int)key2 <= 99)
				{
					if ((int)key2 == 97 || (int)key2 == 99)
					{
						goto IL_0080;
					}
				}
				else if ((int)key2 == 118 || (int)key2 == 120)
				{
					goto IL_0080;
				}
				flag3 = false;
				goto IL_0088;
			}
			goto IL_009d;
			IL_0057:
			flag = false;
			goto IL_0059;
		}

		public override string ToString()
		{
			//IL_0038: 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)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (Modifiers == Modifier.None)
			{
				return ((object)Key/*cast due to .constrained prefix*/).ToString();
			}
			return string.Join("+", Modifiers.Active()) + "+" + ((object)Key/*cast due to .constrained prefix*/).ToString();
		}

		private static Binding Parse(string value)
		{
			if (!TryParse(value, out var binding))
			{
				throw new ArgumentException("Invalid binding '" + value + "'");
			}
			return binding;
		}

		private static bool TryParse(string value, out Binding binding)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			binding = default(Binding);
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			string[] array = value.Split('+');
			if (!Enum.TryParse<KeyCode>(array[^1], ignoreCase: true, out KeyCode result))
			{
				return false;
			}
			Modifier modifier = Modifier.None;
			for (int i = 0; i < array.Length - 1; i++)
			{
				if (!Enum.TryParse<Modifier>(array[i], ignoreCase: true, out var result2))
				{
					return false;
				}
				modifier |= result2;
			}
			binding = new Binding(modifier, result);
			return true;
		}
	}
	[BepInDependency("org.silksong-modding.modlist", "0.2.0")]
	[HarmonyPatch]
	[BepInPlugin("io.github.hk-speedrunning.debugmod", "DebugMod", "1.2.1")]
	public class DebugMod : BaseUnityPlugin
	{
		[PublicAPI]
		public enum InfoPanelColumn
		{
			LEFT,
			RIGHT
		}

		private static GameManager _gm;

		private static InputHandler _ih;

		private static HeroController _hc;

		private static GameObject _refKnight;

		private static CameraController _refCamera;

		private static Collider2D _refHeroCollider;

		private static LightBlurredBackground _lbb;

		internal static IEnumerator CurrentHazardCoro;

		internal static IEnumerator CurrentInvulnCoro;

		internal static IEnumerator CurrentDieCoro;

		internal static IEnumerator CurrentPlayerDeadCoro;

		public static DebugMod instance;

		private Harmony harmony;

		private static bool settingsLoaded;

		public static readonly CommandPaletteRegistry CommandPaletteRegistry = new CommandPaletteRegistry();

		public static readonly string ModBaseDirectory = Path.Combine(Application.persistentDataPath, "DebugModData");

		private static float _loadTime;

		private static float _unloadTime;

		private static bool _loadingChar;

		internal static HitInstance? lastHit;

		internal static int lastDamage;

		[CanBeNull]
		internal static DamageScalingConfig lastScaling;

		internal static int lastScaleLevel;

		public static bool stateOnDeath;

		public static bool infiniteHP;

		public static bool infiniteSilk;

		public static bool infiniteTools;

		public static bool playerInvincible;

		public static bool noclip;

		internal static Vector3 noclipPos;

		public static bool heroColliderDisabled;

		public static bool cameraFollow;

		public static bool KeyBindLock;

		public static bool overrideLoadLockout = false;

		public static int extraNailDamage;

		public static bool forcePaused;

		public static bool freeEquip;

		public static readonly Dictionary<string, BindAction> bindActions = new Dictionary<string, BindAction>();

		internal static readonly Dictionary<MethodInfo, BindAction> bindsByMethod = new Dictionary<MethodInfo, BindAction>();

		public static readonly Dictionary<KeyCode, int> alphaKeyDict = new Dictionary<KeyCode, int>();

		public const string Id = "io.github.hk-speedrunning.debugmod";

		internal static GameManager GM
		{
			get
			{
				if (!((Object)(object)_gm != (Object)null))
				{
					return _gm = GameManager.SilentInstance;
				}
				return _gm;
			}
		}

		internal static InputHandler IH
		{
			get
			{
				if (!((Object)(object)_ih != (Object)null))
				{
					return _ih = GM.inputHandler;
				}
				return _ih;
			}
		}

		internal static HeroController HC
		{
			get
			{
				if (!((Object)(object)_hc != (Object)null))
				{
					return _hc = HeroController.instance;
				}
				return _hc;
			}
		}

		internal static GameObject RefKnight
		{
			get
			{
				if (!((Object)(object)_refKnight != (Object)null))
				{
					return _refKnight = ((Component)HC).gameObject;
				}
				return _refKnight;
			}
		}

		internal static CameraController RefCamera
		{
			get
			{
				if (!((Object)(object)_refCamera != (Object)null))
				{
					return _refCamera = GM.cameraCtrl;
				}
				return _refCamera;
			}
		}

		internal static Collider2D RefHeroCollider
		{
			get
			{
				if (!((Object)(object)_refHeroCollider != (Object)null))
				{
					return _refHeroCollider = RefKnight.GetComponent<Collider2D>();
				}
				return _refHeroCollider;
			}
		}

		internal static LightBlurredBackground LBB
		{
			get
			{
				if (!((Object)(object)_lbb != (Object)null))
				{
					return _lbb = Object.FindFirstObjectByType<LightBlurredBackground>();
				}
				return _lbb;
			}
		}

		public static Settings settings { get; set; } = new Settings();

		public static string Name => "DebugMod";

		public static string Version => "1.2.1";

		public static event Action<string, Binding?> bindUpdated;

		public void Awake()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			settings.InitMenu(((BaseUnityPlugin)this).Config);
			LoadSettings();
			if (settings.LogUnityExceptions && !Logger.Sources.Any((ILogSource x) => x is UnityLogSource))
			{
				Application.logMessageReceived += new LogCallback(HandleUnityLog);
			}
			bindActions.Clear();
			MethodInfo[] methods = typeof(BindableFunctions).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				object[] customAttributes = methodInfo.GetCustomAttributes(typeof(BindableMethod), inherit: false);
				if (customAttributes.Any())
				{
					BindAction bindAction = new BindAction((BindableMethod)customAttributes[0], methodInfo);
					bindActions.Add(bindAction.Name, bindAction);
					bindsByMethod.Add(methodInfo, bindAction);
				}
			}
			if (!settings.binds.ContainsKey("MODUI_TOGGLEALLUI"))
			{
				LogWarn("Toggle All UI was unset, resetting to the default value");
				settings.binds.Add("MODUI_TOGGLEALLUI", (KeyCode)283);
				SaveSettings();
			}
			if (!settings.binds.ContainsKey("MODUI_TOGGLECOMMANDPALETTE"))
			{
				settings.binds.Add("MODUI_TOGGLECOMMANDPALETTE", new Binding(Modifier.Ctrl, (KeyCode)112));
			}
			DebugMod.bindUpdated?.Invoke("MODUI_TOGGLEALLUI", settings.binds["MODUI_TOGGLEALLUI"]);
			DebugMod.bindUpdated?.Invoke("MODUI_TOGGLECOMMANDPALETTE", settings.binds["MODUI_TOGGLECOMMANDPALETTE"]);
			alphaKeyDict.Clear();
			for (int num2 = 0; num2 < 10; num2++)
			{
				alphaKeyDict.Add((KeyCode)(256 + num2), num2);
				alphaKeyDict.Add((KeyCode)(48 + num2), num2);
			}
			SaveStateManager.Initialize();
			TimeScale.Initialize();
			harmony = new Harmony("io.github.hk-speedrunning.debugmod");
			harmony.PatchAll();
			PlayerDeathWatcher.Init();
			SceneManager.activeSceneChanged += LevelActivated;
			ModHooks.AfterSavegameLoadHook += LoadCharacter;
			ModHooks.NewGameHook += NewCharacter;
			ModHooks.BeforeSceneLoadHook += OnLevelUnload;
			ModHooks.TakeHealthHook += PlayerDamaged;
			ModHooks.FinishedLoadingModsHook += OnFinishedLoadingMods;
			KeyBindLock = false;
			if ((Object)(object)GameManager.SilentInstance != (Object)null)
			{
				OnFinishedLoadingMods();
			}
			Log("Initialized");
		}

		private void HandleUnityLog(string condition, string stackTrace, LogType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			bool flag = (((int)type == 0 || (int)type == 4) ? true : false);
			if (flag && condition.Contains("Exception"))
			{
				LogError(("[UNITY] " + condition + "\n" + stackTrace).Trim());
			}
		}

		private void OnFinishedLoadingMods()
		{
			UICommon.LoadResources();
			GUIController.Instance.BuildMenus();
			SceneWatcher.Init();
			CommandPaletteCommands.Initialize();
		}

		private void OnEnable()
		{
			TimeScale.Initialize();
		}

		private void OnDisable()
		{
			TimeScale.Reset();
		}

		private void OnDestroy()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			Application.logMessageReceived -= new LogCallback(HandleUnityLog);
			SceneManager.activeSceneChanged -= LevelActivated;
			ModHooks.AfterSavegameLoadHook -= LoadCharacter;
			ModHooks.NewGameHook -= NewCharacter;
			ModHooks.BeforeSceneLoadHook -= OnLevelUnload;
			ModHooks.TakeHealthHook -= PlayerDamaged;
			ModHooks.FinishedLoadingModsHook -= OnFinishedLoadingMods;
			PlayerDeathWatcher.Unload();
			SceneWatcher.Unload();
			CocoonPreviewer.Unload();
			GUIController.Unload();
			TimeScale.Release();
		}

		public DebugMod()
		{
			instance = this;
		}

		private static void LoadSettings()
		{
			try
			{
				Directory.CreateDirectory(ModBaseDirectory);
				string path = Path.Combine(ModBaseDirectory, "Settings.json");
				if (File.Exists(path))
				{
					settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(path));
					if (settings == null)
					{
						settings = new Settings();
					}
					Log("Loaded settings");
				}
			}
			catch (Exception arg)
			{
				LogError($"Error loading settings: {arg}");
			}
			finally
			{
				settingsLoaded = true;
			}
		}

		internal static void SaveSettings()
		{
			if (!settingsLoaded)
			{
				return;
			}
			settings.binds = new Dictionary<string, Binding>(settings.binds.OrderBy((KeyValuePair<string, Binding> pair) => pair.Key));
			try
			{
				File.WriteAllText(Path.Combine(ModBaseDirectory, "Settings.json"), JsonConvert.SerializeObject((object)settings, (Formatting)1));
			}
			catch (Exception arg)
			{
				LogError($"Error saving settings: {arg}");
			}
		}

		public static void UpdateBind(string name, Binding? binding)
		{
			if (binding.HasValue)
			{
				settings.binds[name] = binding.Value;
			}
			else
			{
				settings.binds.Remove(name);
				GUIController.CancelRebind(name);
			}
			SaveSettings();
			DebugMod.bindUpdated?.Invoke(name, binding);
		}

		private int PlayerDamaged(int damageAmount)
		{
			int damage = ((!infiniteHP) ? damageAmount : 0);
			if (stateOnDeath && WillDie() && SaveState.loadingSavestate == null && SaveStateManager.GetQuickState().IsSet())
			{
				LogConsole("Lethal damage prevented, savestate loading");
				((MonoBehaviour)this).StartCoroutine(Routine());
				return 0;
			}
			return damage;
			static IEnumerator Routine()
			{
				yield return (object)new WaitForSecondsRealtime(0.3f);
				SaveStateManager.LoadState(SaveStateManager.GetQuickState());
			}
			bool WillDie()
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if (PlayerData.instance.health + PlayerData.instance.healthBlue - damage > 0)
				{
					return false;
				}
				ToolItem fracturedMaskTool = Gameplay.FracturedMaskTool;
				if (Object.op_Implicit((Object)(object)fracturedMaskTool) && ((ToolBase)fracturedMaskTool).IsEquipped && fracturedMaskTool.SavedData.AmountLeft > 0)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(HeroController), "HazardRespawn")]
		[HarmonyPostfix]
		private static void OnHazardRespawn(HeroController __instance, IEnumerator __result)
		{
			CurrentHazardCoro = __result;
		}

		[HarmonyPatch(typeof(HeroController), "Invulnerable")]
		[HarmonyPostfix]
		private static void OnInvulnerable(HeroController __instance, IEnumerator __result)
		{
			CurrentInvulnCoro = __result;
		}

		[HarmonyPatch(typeof(GameManager), "PlayerDead")]
		[HarmonyPostfix]
		private static void OnPlayerDead(IEnumerator __result)
		{
			CurrentPlayerDeadCoro = __result;
		}

		[HarmonyPatch(typeof(HeroController), "Die", new Type[]
		{
			typeof(bool),
			typeof(bool)
		})]
		[HarmonyPostfix]
		private static void OnDie(IEnumerator __result)
		{
			CurrentDieCoro = __result;
		}

		private void NewCharacter()
		{
			LoadCharacter(null);
		}

		private void LoadCharacter(SaveGameData saveGameData)
		{
			ConsolePanel.Instance?.Reset();
			playerInvincible = false;
			infiniteHP = false;
			infiniteSilk = false;
			noclip = false;
			extraNailDamage = 0;
			lastHit = null;
			lastDamage = 0;
			lastScaling = null;
			lastScaleLevel = 0;
			_loadingChar = true;
		}

		private void LevelActivated(Scene sceneFrom, Scene sceneTo)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Scene)(ref sceneTo)).name;
			if (_loadingChar)
			{
				string text = TimeSpan.FromSeconds(PlayerData.instance.playTime).ToString("hh\\:mm\\:ss");
				LogConsole("DebugMod " + Version + " on Silksong " + Constants.GetConstantValue<string>("GAME_VERSION"));
				LogConsole($"\tSave slot: {PlayerData.instance.profileID}");
				LogConsole("\tProfile playtime: " + text);
				LogConsole($"\tCompletion: {PlayerData.instance.completionPercentage}%");
				GUIController.Instance.respawnSceneWatch = PlayerData.instance.respawnScene;
				_loadingChar = false;
			}
			if (Object.op_Implicit((Object)(object)GM) && GM.IsGameplayScene())
			{
				_loadTime = Time.realtimeSinceStartup;
				LogConsole("New scene loaded: " + name);
				PlayerDeathWatcher.Reset();
				VisualMaskHelper.OnSceneChange(sceneTo);
			}
		}

		private string OnLevelUnload(string toScene)
		{
			_unloadTime = Time.realtimeSinceStartup;
			return toScene;
		}

		public static string GetSceneName()
		{
			if ((Object)(object)GM == (Object)null)
			{
				LogWarn("GameManager reference is null in GetSceneName");
				return "";
			}
			return GM.GetSceneNameString();
		}

		public static float GetLoadTime()
		{
			return (float)Math.Round(_loadTime - _unloadTime, 2);
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static int Get_NailDamage(int nailDamage)
		{
			return nailDamage + extraNailDamage;
		}

		[HarmonyPatch(typeof(HealthManager), "TakeDamage")]
		[HarmonyPrefix]
		private static void TakeDamage(HealthManager __instance, HitInstance hitInstance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Invalid comparison between Unknown and I4
			HitInstance val = __instance.ApplyDamageScaling(hitInstance);
			lastHit = val;
			lastDamage = (__instance.damageOverride ? 1 : Mathf.RoundToInt((float)val.DamageDealt * val.Multiplier));
			lastScaling = __instance.damageScaling;
			int num = hitInstance.DamageScalingLevel - 1;
			if (hitInstance.IsUsingNeedleDamageMult)
			{
				num = PlayerData.instance.nailUpgrades;
			}
			else if (Object.op_Implicit((Object)(object)hitInstance.RepresentingTool) && (int)hitInstance.RepresentingTool.Type != 3)
			{
				num = PlayerData.instance.ToolKitUpgrades;
			}
			lastScaleLevel = num;
		}

		[HarmonyPatch(typeof(SurfaceWaterRegion), "OnTriggerEnter2D")]
		[HarmonyPrefix]
		private static void OnTriggerEnter2D_Prefix(Collider2D collision)
		{
			if (Object.op_Implicit((Object)(object)((Component)collision).gameObject.GetComponent<HeroController>()) && playerInvincible)
			{
				PlayerData.instance.isInvincible = false;
			}
		}

		[HarmonyPatch(typeof(SurfaceWaterRegion), "OnTriggerEnter2D")]
		[HarmonyPostfix]
		private static void OnTriggerEnter2D_Postfix()
		{
			if (playerInvincible)
			{
				PlayerData.instance.isInvincible = true;
			}
		}

		[HarmonyPatch(typeof(HeroWaterController), "TumbleOut")]
		[HarmonyPrefix]
		private static bool HeroWaterController_TumbleOut_Prefix(HeroWaterController __instance)
		{
			if (SaveState.loadingSavestate == null)
			{
				return true;
			}
			__instance.ExitedWater(true);
			return false;
		}

		[HarmonyPatch(typeof(HeroController), "TakeDamage")]
		[HarmonyPrefix]
		private static bool HeroController_TakeDamage(GameObject go, HazardType hazardType)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			if (playerInvincible)
			{
				PlayerData.instance.isInvincible = true;
			}
			if (playerInvincible && !noclip && (int)hazardType == 4 && ((Object)go).name.Contains("Lava Box"))
			{
				HeroController.instance.ShroomBounce();
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(HeroController), "TakeSilk", new Type[]
		{
			typeof(int),
			typeof(SilkTakeSource)
		})]
		[HarmonyPrefix]
		private static void TakeSilk(ref int amount)
		{
			if (infiniteSilk)
			{
				amount = 0;
			}
		}

		[HarmonyPatch(typeof(HeroController), "DoSpecialDamage")]
		[HarmonyPrefix]
		private static bool HeroController_DoSpecialDamage()
		{
			return !playerInvincible;
		}

		[HarmonyPatch(typeof(HeroController), "CanBeBarnacleGrabbed")]
		[HarmonyPrefix]
		private static bool HeroController_CanBeBarnacleGrabbed(ref bool __result)
		{
			if (playerInvincible)
			{
				__result = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayMakerFSM), "Start")]
		[HarmonyPrefix]
		private static void PlayMakerFSM_Start(PlayMakerFSM __instance)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			if (((Object)((Component)__instance).gameObject).name == "Hero Damager" && __instance.FsmName == "Multihitter")
			{
				FsmState? state = __instance.GetState("Start Hit?");
				CanHeroTakeDamage val = ((state != null) ? state.Actions.OfType<CanHeroTakeDamage>().FirstOrDefault() : null);
				if (val != null && val.canTakeDmgEvent.Name == "HIT" && val.cannotTakeDmgEvent.Name == "HIT")
				{
					val.cannotTakeDmgEvent = new FsmEvent("CANCEL");
				}
			}
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "CanChangeEquips", new Type[] { })]
		[HarmonyPrefix]
		private static bool InventoryItemToolManager_CanChangeEquips(ref bool __result)
		{
			if (freeEquip)
			{
				__result = true;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(GameManager), "SetIsInventoryOpen")]
		[HarmonyPrefix]
		private static void GameManager_SetIsInventoryOpen(bool value)
		{
			if (freeEquip && !value)
			{
				ToolItemManager.SendEquippedChangedEvent(false);
			}
		}

		[PublicAPI]
		public static void AddToKeyBindList(Type BindableFunctionsClass)
		{
			MethodInfo[] methods = BindableFunctionsClass.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				BindableMethod customAttribute = methodInfo.GetCustomAttribute<BindableMethod>(inherit: false);
				if (customAttribute != null)
				{
					Log("Adding new keybind: " + customAttribute.name + " (from " + BindableFunctionsClass.Name + ")");
					BindAction bindAction = new BindAction(customAttribute, methodInfo);
					bindActions.Add(bindAction.Name, bindAction);
					bindsByMethod.Add(methodInfo, bindAction);
				}
			}
		}

		[PublicAPI]
		public static void AddActionToKeyBindList(Action method, string name, string category)
		{
			AddActionToKeyBindList(method, name, category, allowLock: true);
		}

		[PublicAPI]
		public static void AddActionToKeyBindList(Action method, string name, string category, bool allowLock)
		{
			Log("Adding new keybind: " + name);
			BindAction bindAction = new BindAction(name, category, allowLock, method);
			bindActions.Add(bindAction.Name, bindAction);
			bindsByMethod.Add(method.Method, bindAction);
		}

		[PublicAPI]
		public static void AddTextToInfoPanel(string label, Func<string> dataGenerator, InfoPanelColumn column = InfoPanelColumn.LEFT)
		{
			((column == InfoPanelColumn.LEFT) ? InfoPanel.LeftColumnInjects : InfoPanel.RightColumnInjects).Add(new InfoPanel.InjectedInfo(label, dataGenerator));
		}

		[PublicAPI]
		public static void AddTranslationSheet(string sheet)
		{
			Localization.AddSheet(sheet);
		}

		public static void LogDebug(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogDebug((object)message);
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}

		public static void LogWarn(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning((object)message);
		}

		public static void LogError(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)message);
		}

		public static void LogConsole(string message)
		{
			ConsolePanel.Log(message);
		}
	}
	[HarmonyPatch]
	public class GUIController : MonoBehaviour
	{
		public Vector3 hazardLocation;

		public string respawnSceneWatch;

		private static readonly HitboxViewer hitboxes = new HitboxViewer();

		private static Binding? keyWarning;

		private static KeyCode pendingModifierKey;

		private Size resolution;

		internal LanguageCode language;

		private bool benchwarpShifted;

		[CompilerGenerated]
		private static string <RebindTarget>k__BackingField;

		private float? lastRescale;

		private const float RebuildDelay = 0.1f;

		public GameObject canvas;

		private readonly Array allKeyCodes = Enum.GetValues(typeof(KeyCode));

		private readonly List<KeyCode> UnbindableKeys = new List<KeyCode>
		{
			(KeyCode)323,
			(KeyCode)311,
			(KeyCode)312
		};

		private static GUIController _instance;

		internal static string RebindTarget
		{
			[CompilerGenerated]
			get
			{
				return <RebindTarget>k__BackingField;
			}
			private set
			{
				string text = <RebindTarget>k__BackingField;
				if (!(text == value))
				{
					<RebindTarget>k__BackingField = value;
					GUIController.RebindTargetChanged?.Invoke(text);
					GUIController.RebindTargetChanged?.Invoke(value);
				}
			}
		}

		public static GUIController Instance
		{
			get
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				if (!Object.op_Implicit((Object)(object)_instance))
				{
					DebugMod.Log("Creating new GUIController");
					GameObject val = new GameObject("GUIController");
					_instance = val.AddComponent<GUIController>();
					Object.DontDestroyOnLoad((Object)val);
				}
				return _instance;
			}
		}

		internal static event Action<string> RebindTargetChanged;

		public static void Unload()
		{
			hitboxes.Unload();
			CommandPaletteController.Unload();
			if (Object.op_Implicit((Object)(object)_instance))
			{
				if (Object.op_Implicit((Object)(object)_instance.canvas))
				{
					Object.Destroy((Object)(object)_instance.canvas);
				}
				Object.Destroy((Object)(object)((Component)_instance).gameObject);
				_instance = null;
			}
		}

		public static bool ForceHideUI()
		{
			if (DebugMod.GM.IsNonGameplayScene())
			{
				return true;
			}
			if (SaveState.loadingSavestate != null)
			{
				return true;
			}
			return false;
		}

		public void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			hazardLocation = PlayerData.instance.hazardRespawnLocation;
			respawnSceneWatch = PlayerData.instance.respawnScene;
		}

		public void BuildMenus()
		{
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CommandPaletteController.Unload();
				resolution = new Size(Screen.width, Screen.height);
				language = GetLanguage();
				benchwarpShifted = false;
				if (Object.op_Implicit((Object)(object)canvas))
				{
					foreach (EnemyHandle item in EnemiesPanel.enemyPool)
					{
						item.DestroyUI();
					}
					Object.Destroy((Object)(object)canvas);
					CanvasNode.allNodes.Clear();
				}
				canvas = new GameObject("DebugModCanvas");
				canvas.SetActive(false);
				canvas.AddComponent<Canvas>().renderMode = (RenderMode)0;
				canvas.AddComponent<GraphicRaycaster>();
				RectTransform component = canvas.GetComponent<RectTransform>();
				Vector2 anchorMin = (component.anchorMax = Vector2.zero);
				component.anchorMin = anchorMin;
				component.pivot = Vector2.zero;
				component.sizeDelta = new Vector2((float)Screen.width, (float)Screen.height);
				Object.DontDestroyOnLoad((Object)(object)canvas);
				CommandPaletteController.Build();
				MainPanel.BuildPanel();
				EnemiesPanel.BuildPanel();
				ConsolePanel.BuildPanel();
				InfoPanel.BuildPanel();
				SaveStatesPanel.BuildPanel();
				CanvasButton.BuildHoverBorder();
				KeybindDialog.BuildPanel();
				ConfirmDialog.BuildPanel();
				DropdownDialog.BuildPanel();
				ImportPackDialog.BuildPanel();
				ExportPackDialog.BuildPanel();
				DebugMod.LogDebug("UI built");
			}
			catch (Exception arg)
			{
				DebugMod.LogError($"Error building UI: {arg}");
			}
		}

		private LanguageCode GetLanguage()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (InteropHelper.IsModInstalled(InteropHelper.I18NModId, "1.1.0"))
			{
				return I18NInterop.GetLanguage();
			}
			return Language.CurrentLanguage();
		}

		public void Update()
		{
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0610: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Unknown result type (might be due to invalid IL or missing references)
			//IL_064c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)DebugMod.GM == (Object)null)
			{
				return;
			}
			Profiler.NewFrame();
			if (!resolution.IsEmpty && (resolution.Width != Screen.width || resolution.Height != Screen.height))
			{
				resolution = new Size(Screen.width, Screen.height);
				lastRescale = Time.realtimeSinceStartup;
			}
			if (lastRescale.HasValue && Time.realtimeSinceStartup > lastRescale + 0.1f)
			{
				DebugMod.LogDebug($"Resize complete, rebuilding for new resolution ({Screen.width}, {Screen.height})");
				lastRescale = null;
				BuildMenus();
			}
			if (InteropHelper.IsModInstalled(InteropHelper.BenchwarpModId))
			{
				bool flag = GameManager.instance.IsGamePaused() && !GameManager.instance.IsNonGameplayScene();
				if (flag != benchwarpShifted)
				{
					benchwarpShifted = flag;
					int num = UICommon.ScaleHeight(50);
					if (benchwarpShifted)
					{
						MainPanel.Instance.LayoutTabsSide(num);
						SaveStatesPanel instance = SaveStatesPanel.Instance;
						instance.LocalPosition += new Vector2(0f, (float)num);
					}
					else
					{
						MainPanel.Instance.LayoutTabsNormal();
						SaveStatesPanel instance2 = SaveStatesPanel.Instance;
						instance2.LocalPosition -= new Vector2(0f, (float)num);
					}
				}
			}
			if (ForceHideUI())
			{
				canvas.SetActive(false);
			}
			else
			{
				canvas.SetActive(true);
				MainPanel instance3 = MainPanel.Instance;
				if (instance3 != null)
				{
					instance3.ActiveSelf = DebugMod.settings.MainPanelVisible;
				}
				EnemiesPanel instance4 = EnemiesPanel.Instance;
				if (instance4 != null)
				{
					instance4.ActiveSelf = DebugMod.settings.EnemiesPanelVisible;
				}
				ConsolePanel instance5 = ConsolePanel.Instance;
				if (instance5 != null)
				{
					instance5.ActiveSelf = DebugMod.settings.ConsoleVisible;
				}
				InfoPanel instance6 = InfoPanel.Instance;
				if (instance6 != null)
				{
					instance6.ActiveSelf = DebugMod.settings.InfoPanelVisible;
				}
				SaveStatesPanel instance7 = SaveStatesPanel.Instance;
				if (instance7 != null)
				{
					instance7.ActiveSelf = SaveStatesPanel.ShouldBeVisible;
				}
				int num2 = 0;
				while (num2 < CanvasNode.allNodes.Count)
				{
					CanvasNode canvasNode = CanvasNode.allNodes[num2];
					if (canvasNode.ActiveSelf)
					{
						canvasNode.Update();
						num2++;
					}
					else
					{
						num2 += canvasNode.childCount;
					}
				}
			}
			GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
			if (Object.op_Implicit((Object)(object)currentSelectedGameObject) && Object.op_Implicit((Object)(object)currentSelectedGameObject.GetComponent<NodeRef>()) && !Object.op_Implicit((Object)(object)currentSelectedGameObject.GetComponent<InputField>()))
			{
				EventSystem.current.SetSelectedGameObject((GameObject)null);
			}
			if (DebugMod.GetSceneName() == "Menu_Title")
			{
				return;
			}
			LanguageCode val = GetLanguage();
			if (language != val)
			{
				DebugMod.LogDebug($"Detected language change from {language} to {val}, rebuilding UI");
				BuildMenus();
			}
			HandleKeybinds(CanvasTextField.AnyFieldFocused || CommandPaletteController.IsOpen);
			if (DebugMod.infiniteSilk && PlayerData.instance.silk < PlayerData.instance.silkMax && PlayerData.instance.health > 0 && (Object)(object)HeroController.instance != (Object)null && !HeroController.instance.cState.dead && GameManager.instance.IsGameplayScene())
			{
				PlayerData.instance.silk = PlayerData.instance.silkMax;
				HeroController.instance.AddSilk(1, false);
			}
			if (DebugMod.infiniteTools && Object.op_Implicit((Object)(object)ManagerSingleton<ToolItemManager>.Instance) && Object.op_Implicit((Object)(object)ManagerSingleton<ToolItemManager>.Instance.toolItems))
			{
				foreach (ToolItem item in (NamedScriptableObjectList<ToolItem>)(object)ManagerSingleton<ToolItemManager>.Instance.toolItems)
				{
					if (Object.op_Implicit((Object)(object)item))
					{
						Data savedData = item.SavedData;
						int amountLeft = savedData.AmountLeft;
						savedData.AmountLeft = ToolItemManager.GetToolStorageAmount(item);
						item.SavedData = savedData;
						AttackToolBinding? attackToolBinding = ToolItemManager.GetAttackToolBinding(item);
						if (attackToolBinding.HasValue && amountLeft != savedData.AmountLeft)
						{
							ToolItemManager.ReportBoundAttackToolUpdated(attackToolBinding.Value);
						}
					}
				}
			}
			if (DebugMod.playerInvincible && PlayerData.instance != null)
			{
				PlayerData.instance.isInvincible = true;
			}
			if (DebugMod.noclip)
			{
				Vector3 val2 = Vector3.zero;
				float num3 = (Input.GetKey((KeyCode)304) ? 40f : 20f) * DebugMod.settings.NoClipSpeedModifier * Time.deltaTime;
				if (((OneAxisInputControl)DebugMod.IH.inputActions.Left).IsPressed)
				{
					val2 += Vector3.left * num3;
				}
				if (((OneAxisInputControl)DebugMod.IH.inputActions.Right).IsPressed)
				{
					val2 += Vector3.right * num3;
				}
				if (((OneAxisInputControl)DebugMod.IH.inputActions.Up).IsPressed)
				{
					val2 += Vector3.up * num3;
				}
				if (((OneAxisInputControl)DebugMod.IH.inputActions.Down).IsPressed)
				{
					val2 += Vector3.down * num3;
				}
				DebugMod.noclipPos += val2;
				if ((int)HeroController.instance.transitionState == 0 && SaveState.loadingSavestate == null)
				{
					DebugMod.RefKnight.transform.position = DebugMod.noclipPos;
					Rigidbody2D component = DebugMod.RefKnight.GetComponent<Rigidbody2D>();
					component.constraints = (RigidbodyConstraints2D)(component.constraints | 3);
				}
				else
				{
					D