Decompiled source of LevelViewer v1.0.0

LevelViewer.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Drawing;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LevelViewer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LevelViewer")]
[assembly: AssemblyTitle("LevelViewer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LevelViewer
{
	public class UI_LevelViewer : MonoBehaviour
	{
		public class Patches
		{
			[HarmonyPatch(typeof(DebugCameraController), "Update")]
			[HarmonyPrefix]
			public static bool FreecamUpdatePatch()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				return (int)Cursor.lockState == 1;
			}

			[HarmonyPatch(typeof(UT_SpawnChance), "Start")]
			[HarmonyPrefix]
			private static bool GuaranteedSpawns(UT_SpawnChance __instance)
			{
				if ((Object)(object)instance == (Object)null || __instance.spawnSettings.spawnChance == 0f)
				{
					return true;
				}
				AddCached(new Tuple<Func<bool>, GameObject>(() => DrawUTSpawnChance(__instance, GetCleanName(((Component)__instance).gameObject)), ((Component)__instance).gameObject));
				return false;
			}

			public unsafe static bool DrawUTSpawnChance(UT_SpawnChance chance, string textOverride = null)
			{
				//IL_005c: 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_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				if (((Object)(object)((Component)chance).GetComponent<Denizen>() != (Object)null && !instance.denizenSpawnsToggle.isOn) || ((Object)(object)((Component)chance).GetComponent<Item_Object>() != (Object)null && !instance.itemSpawnsToggle.isOn))
				{
					return false;
				}
				((CommandBuilder)(ref viewDraw)).SphereOutline(float3.op_Implicit(((Component)chance).transform.position), 0.5f);
				((CommandBuilder)(ref viewDraw)).Label2D(float3.op_Implicit(((Component)chance).transform.position), $"{textOverride ?? ((Object)chance).name}\n{chance.spawnSettings.spawnChance * 100f:F2}%", 16f, Color.yellow);
				MeshFilter val = default(MeshFilter);
				if (((Component)chance).TryGetComponent<MeshFilter>(ref val) && val.sharedMesh.isReadable)
				{
					ScopeMatrix val2 = ((CommandBuilder)(ref viewDraw)).InLocalSpace(((Component)chance).transform);
					try
					{
						((CommandBuilder)(ref viewDraw)).WireMesh(val.sharedMesh);
					}
					finally
					{
						((IDisposable)(*(ScopeMatrix*)(&val2))/*cast due to .constrained prefix*/).Dispose();
					}
				}
				return true;
			}

			[HarmonyPatch(typeof(UT_SpawnEntityByID), "Start")]
			[HarmonyPrefix]
			private static bool EntityByIDPatch(UT_SpawnEntityByID __instance)
			{
				if ((Object)(object)instance == (Object)null || __instance.spawnSettings.spawnChance == 0f)
				{
					return true;
				}
				AddCached(new Tuple<Func<bool>, GameObject>(() => DrawEntityByID(__instance), ((Component)__instance).gameObject));
				if (Object.op_Implicit((Object)(object)CL_AssetManager.GetAssetGameObject(__instance.idToSpawn, __instance.customDatabase).GetComponent<Denizen>()) && !instance.allowDenizenSpawnsToggle.isOn)
				{
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(UT_SpawnEntityByID), "Spawn")]
			[HarmonyPrefix]
			private static bool EntityByIDPatch_Guarantee(UT_SpawnEntityByID __instance)
			{
				if ((Object)(object)instance == (Object)null || __instance.spawnSettings.spawnChance == 0f)
				{
					return true;
				}
				__instance.SpawnCustom(__instance.idToSpawn);
				return false;
			}

			public unsafe static bool DrawEntityByID(UT_SpawnEntityByID IDspawner)
			{
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: 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)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject(IDspawner.idToSpawn, IDspawner.customDatabase);
				if ((Object)(object)assetGameObject == (Object)null)
				{
					return false;
				}
				if (((Object)(object)assetGameObject.GetComponent<Denizen>() != (Object)null && !instance.denizenSpawnsToggle.isOn) || ((Object)(object)assetGameObject.GetComponent<Item_Object>() != (Object)null && !instance.itemSpawnsToggle.isOn))
				{
					return false;
				}
				((CommandBuilder)(ref viewDraw)).WireBox(float3.op_Implicit(((Component)IDspawner).transform.position), quaternion.op_Implicit(((Component)IDspawner).transform.rotation), float3.op_Implicit(0.5f));
				((CommandBuilder)(ref viewDraw)).Label2D(float3.op_Implicit(((Component)IDspawner).transform.position), $"ID Spawner\n{IDspawner.idToSpawn}\n{IDspawner.spawnSettings.spawnChance * 100f:F2}%", 16f, Color.yellow);
				MeshFilter val = default(MeshFilter);
				if (CL_AssetManager.GetAssetGameObject(IDspawner.idToSpawn, IDspawner.customDatabase).TryGetComponent<MeshFilter>(ref val) && val.sharedMesh.isReadable)
				{
					ScopeMatrix val2 = ((CommandBuilder)(ref viewDraw)).InLocalSpace(((Component)IDspawner).transform);
					try
					{
						((CommandBuilder)(ref viewDraw)).WireMesh(val.sharedMesh);
					}
					finally
					{
						((IDisposable)(*(ScopeMatrix*)(&val2))/*cast due to .constrained prefix*/).Dispose();
					}
				}
				return true;
			}

			[HarmonyPatch(typeof(UT_SPT_Spawner), "Start")]
			[HarmonyPrefix]
			private static bool SPTSpawner_Entry(UT_SPT_Spawner __instance)
			{
				if ((Object)(object)instance == (Object)null)
				{
					return true;
				}
				AddCached(new Tuple<Func<bool>, GameObject>(() => DrawSpawner(__instance), ((Component)__instance).gameObject));
				if (__instance.spawnTable.spawnList.SelectMany((SpawnTableAsset x) => x.prefabs).Any((GameObject x) => (Object)(object)x.GetComponent<Denizen>() != (Object)null))
				{
					return false;
				}
				return true;
			}

			public static bool DrawSpawner(UT_SPT_Spawner tabler)
			{
				//IL_0067: 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_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				Denizen val = default(Denizen);
				if (tabler.spawnTable.spawnList.SelectMany((SpawnTableAsset x) => x.prefabs).Any((GameObject x) => x.TryGetComponent<Denizen>(ref val) && ((GameEntity)val).objectType != "roach"))
				{
					return false;
				}
				((CommandBuilder)(ref viewDraw)).WireBox(float3.op_Implicit(((Component)tabler).transform.position), quaternion.op_Implicit(((Component)tabler).transform.rotation), float3.op_Implicit(0.65f), Color.green);
				((CommandBuilder)(ref viewDraw)).Label2D(float3.op_Implicit(((Component)tabler).transform.position), "Table Spawner\n" + ((Object)((Component)tabler).gameObject).name, 16f, Color.yellow);
				return true;
			}

			public static bool GenericDraw(GameObject obj, string textOverride = null)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				if (!obj.activeSelf)
				{
					return false;
				}
				((CommandBuilder)(ref viewDraw)).SphereOutline(float3.op_Implicit(obj.transform.position), 0.5f);
				((CommandBuilder)(ref viewDraw)).Label2D(float3.op_Implicit(obj.transform.position), (textOverride ?? ((Object)obj).name) ?? "", 16f, Color.yellow);
				return true;
			}

			[HarmonyPatch(typeof(UT_TriggerSpawner), "Start")]
			[HarmonyPrefix]
			private static bool TriggerSpawner_Entry(UT_TriggerSpawner __instance)
			{
				if ((Object)(object)instance == (Object)null)
				{
					return true;
				}
				AddCached(new Tuple<Func<bool>, GameObject>(() => DrawTriggerSpawner(__instance), ((Component)__instance).gameObject));
				return true;
			}

			public static bool DrawTriggerSpawner(UT_TriggerSpawner chance)
			{
				//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_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_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				((CommandBuilder)(ref viewDraw)).WireBox(float3.op_Implicit(((Component)chance).transform.position), quaternion.op_Implicit(((Component)chance).transform.rotation), float3.op_Implicit(0.65f), Color.green);
				((CommandBuilder)(ref viewDraw)).Label2D(float3.op_Implicit(((Component)chance).transform.position), "Trigger Spawner\n" + ((Object)((Component)chance).gameObject).name, 16f, Color.yellow);
				return true;
			}

			[HarmonyPatch(typeof(Denizen), "Start")]
			[HarmonyPostfix]
			private static void Denizen_Entry(Denizen __instance)
			{
				if (!((Object)(object)instance == (Object)null))
				{
					if (!((Component)__instance).gameObject.activeInHierarchy)
					{
						Debug.LogWarning((object)(((Object)((Component)__instance).gameObject).name + " wasnt active, still including, bug probably?"));
					}
					instance.startDenizens.Add(__instance);
					if (!instance.allowDenizenSpawnsToggle.isOn)
					{
						((Component)__instance).gameObject.SetActive(false);
					}
					AddCached(new Tuple<Func<bool>, GameObject>(null, ((Component)__instance).gameObject));
				}
			}

			[HarmonyPatch(typeof(Item_Object), "Start")]
			[HarmonyPostfix]
			private static void Item_Entry(Item_Object __instance)
			{
				if (!((Object)(object)instance == (Object)null))
				{
					AddCached(new Tuple<Func<bool>, GameObject>(null, ((Component)__instance).gameObject));
				}
			}
		}

		public RectTransform levelListContent;

		public TMP_Text levelInfoText;

		public TMP_Text itemInfoText;

		public TMP_Text controlsText;

		public GameObject windowContent;

		[Header("Prefabs")]
		public GameObject subregionListPrefab;

		public GameObject levelButtonPrefab;

		[Header("Toggles")]
		public Toggle hideAllSpawnsToggle;

		public Toggle denizenSpawnsToggle;

		public Toggle itemSpawnsToggle;

		public Toggle allowDenizenSpawnsToggle;

		public Toggle showFullNamesToggle;

		[Header("Dropdowns")]
		public TMP_Dropdown regionDropdown;

		private readonly HashSet<Tuple<Func<bool>, GameObject>> cache_objectsToDraw = new HashSet<Tuple<Func<bool>, GameObject>>();

		private DebugCameraController freecamController;

		private static Harmony harmony;

		public static UI_LevelViewer instance;

		private const string everythingName = "Everything (laggy)";

		public static CommandBuilder viewDraw;

		public HashSet<Denizen> startDenizens = new HashSet<Denizen>();

		private ConfigEntry<KeyCode> _noclipKey;

		private ConfigEntry<KeyCode> _toggleViewerKey;

		private ConfigEntry<KeyCode> _unlockCursorKey;

		private ConfigEntry<KeyCode> _freezeTimeKey;

		private KeyCode noclipKey => (KeyCode)((_noclipKey == null) ? 118 : ((int)_noclipKey.Value));

		private KeyCode toggleViewerKey => (KeyCode)((_toggleViewerKey == null) ? 287 : ((int)_toggleViewerKey.Value));

		private KeyCode unlockCursorKey => (KeyCode)((_unlockCursorKey == null) ? 289 : ((int)_unlockCursorKey.Value));

		private KeyCode freezeTimeKey => (KeyCode)((_freezeTimeKey == null) ? 103 : ((int)_freezeTimeKey.Value));

		public void Event_LevelButton(Button button, string levelName)
		{
			UpdateDataViewWithLevel(CL_AssetManager.GetLevelAsset(levelName, "").level);
			ChangeLevel(levelName);
		}

		public void Event_RegionDropdownChanged()
		{
			PopulateLevelList(regionDropdown.options[regionDropdown.value].text);
		}

		public void Event_ToggleActivation(GameObject target)
		{
			target.SetActive(!target.activeSelf);
		}

		public void Event_DenizenToggleChanged()
		{
			if (startDenizens == null)
			{
				return;
			}
			foreach (Denizen startDenizen in startDenizens)
			{
				((Component)startDenizen).gameObject.SetActive(allowDenizenSpawnsToggle.isOn);
			}
		}

		private void SetFreecam(bool setTo)
		{
			//IL_0063: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			((Component)((Component)ENT_Player.playerObject).transform.Find("FXCam")).gameObject.SetActive(!setTo);
			((Behaviour)((Component)ENT_Player.playerObject.cam).GetComponent<AudioListener>()).enabled = !setTo;
			SetHandVis(!setTo);
			if (setTo)
			{
				((Component)freecamController).transform.SetPositionAndRotation(ENT_Player.playerObject.camTransform.position, ENT_Player.playerObject.camTransform.rotation);
				freecamController.targetRotation = ENT_Player.playerObject.camTransform.forward;
			}
			freecamController.ToggleActive(new string[1] { setTo.ToString() });
		}

		private void SetHandVis(bool state)
		{
			Hand[] hands = ENT_Player.playerObject.hands;
			foreach (Hand val in hands)
			{
				((Renderer)val.handSprite).enabled = state;
			}
		}

		private string GetLevelName(M_Level level)
		{
			if (showFullNamesToggle.isOn)
			{
				return level.levelName;
			}
			List<string> list = level.levelName.Split('_').ToList();
			if (list.Count <= 2 || (list.Count >= 2 && list[0].Length > 2))
			{
				return level.levelName;
			}
			if (list.Count == 3)
			{
				list.RemoveAt(0);
				return string.Join("_", list);
			}
			list.RemoveRange(0, 2);
			return string.Join("_", list);
		}

		private M_Region GetRegionByName(string name)
		{
			M_Region regionAsset = CL_AssetManager.GetRegionAsset("Region_" + name, "");
			return ((Object)(object)regionAsset != (Object)null) ? regionAsset : CL_AssetManager.GetRegionAsset(name, "");
		}

		public M_Level ChangeLevel(string levelName)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			cache_objectsToDraw.Clear();
			Transform transform = ((Component)WorldLoader.instance).transform;
			HandholdManager component = ((Component)transform).GetComponent<HandholdManager>();
			foreach (Transform item in transform)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			startDenizens.Clear();
			M_Level level = CL_AssetManager.GetLevelAsset(levelName, "").level;
			M_Level component2 = Object.Instantiate<GameObject>(((Component)level).gameObject, transform).GetComponent<M_Level>();
			component.LoadHandholds(((Component)component2).gameObject);
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(0f, 5f, 0f);
			if ((Object)(object)component2.spawnPosition != (Object)null)
			{
				position = ((Component)component2.spawnPosition).transform.position;
			}
			if (CL_GameManager.gMan.freecam)
			{
				((Component)freecamController).transform.position = position;
			}
			else
			{
				((GameEntity)ENT_Player.playerObject).Teleport(position);
			}
			return component2;
		}

		private string GetSpawnDataForSettings(SpawnSettings settings)
		{
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Expected I4, but got Unknown
			List<string> list = new List<string> { $"Chance: {settings.spawnChance * 100f:F2}%" };
			if (settings.useFlags)
			{
				if (settings.flagWhitelist.Count != 0)
				{
					list.Add("Flag whitelist: " + string.Join(",", settings.flagWhitelist));
				}
				if (settings.flagBlacklist.Count != 0)
				{
					list.Add("Flag blacklist: " + string.Join(",", settings.flagBlacklist));
				}
			}
			if (settings.useProgressionUnlock)
			{
				list.Add("Unlocked by: " + settings.unlockName);
			}
			if (settings.useStats)
			{
				list.Add($"{settings.sessionStat}: {settings.sessionStatMin} to {settings.sessionStatMax}");
			}
			if (settings.useHardMode)
			{
				list.Add("Checks hardmode");
			}
			if (settings.checkStatList)
			{
				foreach (StatCheck statChecker in settings.statCheckers)
				{
					string arg = "error";
					Evaluation evaluation = statChecker.evaluation;
					Evaluation val = evaluation;
					switch ((int)val)
					{
					case 0:
						arg = "equals";
						break;
					case 1:
						arg = "lesser than";
						break;
					case 2:
						arg = "greater than";
						break;
					}
					list.Add($"{statChecker.statName}: {arg} {statChecker.evaluationInteger}");
				}
			}
			return string.Join("<br>", list);
		}

		private string GetSpawnDataForSettings(GameObject settings)
		{
			UT_SpawnChance val = default(UT_SpawnChance);
			if (settings.TryGetComponent<UT_SpawnChance>(ref val))
			{
				return GetSpawnDataForSettings(val.spawnSettings);
			}
			UT_SpawnEntityByID val2 = default(UT_SpawnEntityByID);
			if (settings.TryGetComponent<UT_SpawnEntityByID>(ref val2))
			{
				string text = "ID Spawner";
				text = text + "<br>Spawns: " + val2.idToSpawn + "<br>";
				text += GetSpawnDataForSettings(val2.spawnSettings);
				if (!val2.spawnOnStart)
				{
					text += "<br>Does not spawn on load.";
					text += "<br>Likely uses a trigger or otherwise.";
				}
				return text;
			}
			UT_SPT_Spawner val3 = default(UT_SPT_Spawner);
			if (settings.TryGetComponent<UT_SPT_Spawner>(ref val3))
			{
				string text2 = $"Table Spawner<br>Spawns {val3.minSpawnAmount}-{val3.maxSpawnAmount} items<br>";
				text2 += SpawnTableData(val3.spawnTable);
				if (!val3.spawnOnStart)
				{
					text2 += "<br>No spawn on load.";
					text2 += "<br>Possibly uses trigger.";
				}
				return text2;
			}
			UT_TriggerSpawner val4 = default(UT_TriggerSpawner);
			if (settings.TryGetComponent<UT_TriggerSpawner>(ref val4))
			{
				string text3 = $"Trigger Spawner<br>Spawns {val4.minSpawnAmount}-{val4.maxSpawnAmount} items<br>";
				if ((Object)(object)val4.spawnTable != (Object)null)
				{
					text3 += SpawnTableData(val4.spawnTable);
				}
				else
				{
					text3 += "Spawns these objects:<br>";
					text3 += string.Join("<br>", val4.spawnObjects.Select((GameObject x) => ((Object)x).name));
				}
				text3 = text3 + "<br>" + GetSpawnDataForSettings(val4.spawnSettings);
				if (!val4.spawnOnStart)
				{
					text3 += "<br>No spawn on load.";
					text3 += "<br>Possibly uses trigger.";
				}
			}
			return "Spawning mechanism not found (probably pre-placed)";
		}

		private string SpawnTableData(SpawnTable mainTable)
		{
			List<string> list = new List<string>();
			Item_Object val = default(Item_Object);
			foreach (SpawnTableAsset spawn in mainTable.spawnList)
			{
				List<string> list2 = new List<string>();
				foreach (GameObject prefab in spawn.prefabs)
				{
					if (prefab.TryGetComponent<Item_Object>(ref val))
					{
						list2.Add(val.itemData.itemName);
					}
					else
					{
						list2.Add(((Object)prefab).name.Replace("Denizen_", ""));
					}
				}
				list.Add(string.Format("{0:F0}%: {1}", spawn.spawnSettings.spawnChance * 100f, string.Join(" ", list2)));
			}
			return string.Join("<br>", list);
		}

		private static string GetCleanName(GameObject obj)
		{
			Item_Object val = default(Item_Object);
			if (obj.TryGetComponent<Item_Object>(ref val))
			{
				return val.itemData.itemName;
			}
			Denizen val2 = default(Denizen);
			if (obj.TryGetComponent<Denizen>(ref val2))
			{
				return ((GameEntity)val2).entityPrefabID;
			}
			CL_Prop val3 = default(CL_Prop);
			if (obj.TryGetComponent<CL_Prop>(ref val3))
			{
				return ((GameEntity)val3).entityPrefabID;
			}
			return ((Object)obj).name;
		}

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			controlsText.text = $"{noclipKey} - Toggle Freecam<br>{freezeTimeKey} - Toggle time freeze<br>{toggleViewerKey} - Toggle Viewer<br>{unlockCursorKey} - Unlock Cursor";
			viewDraw = DrawingManager.GetBuilder(true);
			instance = this;
		}

		private void Start()
		{
			if (harmony == null)
			{
				harmony = Harmony.CreateAndPatchAll(typeof(Patches), (string)null);
			}
			((MonoBehaviour)this).StartCoroutine(AwaitInit());
		}

		private IEnumerator AwaitInit()
		{
			yield return (object)new WaitWhile((Func<bool>)(() => (Object)(object)((Component)CL_GameManager.gMan).transform.Find("CinemaCamera") == (Object)null));
			freecamController = ((Component)((Component)CL_GameManager.gMan).transform.Find("CinemaCamera")).GetComponent<DebugCameraController>();
			yield return (object)new WaitWhile((Func<bool>)(() => (Object)(object)freecamController.cam == (Object)null));
			ENT_Player.playerObject.SetGodMode(true);
			CL_GameManager.noTarget = true;
			SetFreecam(setTo: true);
			SetHandVis(state: false);
			CL_UIManager.instance.SetCrosshairVisibility(false);
			regionDropdown.ClearOptions();
			regionDropdown.AddOptions(CL_AssetManager.GetFullCombinedAssetDatabase().regionAssets.Select((M_Region x) => ((Object)x).name.Replace("Region_", "")).ToList());
			regionDropdown.AddOptions(new List<string> { "Everything (laggy)" });
			regionDropdown.value = regionDropdown.options.FindIndex((OptionData x) => x.text == "Silos_Campaign");
			PopulateLevelList();
			WorldLoader.instance.UnloadAllLevels();
			DEN_DeathFloor obj = DEN_DeathFloor.instance;
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
			UpdateDataViewWithLevel(ChangeLevel("m1_silos_storage_01"));
		}

		private void Update()
		{
			//IL_0035: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			//IL_00ed: 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_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			if (CL_GameManager.gMan.freecam)
			{
				((GameEntity)ENT_Player.playerObject).Teleport(((Component)freecamController).transform.position);
			}
			if (Input.GetKeyDown(toggleViewerKey))
			{
				windowContent.SetActive(!windowContent.activeSelf);
			}
			if (Input.GetKeyDown(unlockCursorKey))
			{
				if ((int)Cursor.lockState != 1 && !CL_GameManager.isDead())
				{
					Cursor.lockState = (CursorLockMode)1;
					CL_GameManager.showCursor = false;
					ENT_Player.playerObject.UnlockCamera();
				}
				else
				{
					CL_GameManager.showCursor = true;
					Cursor.lockState = (CursorLockMode)0;
					ENT_Player.playerObject.LockCamera();
				}
			}
			if (Input.GetKeyDown(noclipKey))
			{
				SetFreecam(!CL_GameManager.gMan.freecam);
			}
			if (Input.GetKeyDown(freezeTimeKey))
			{
				CL_GameManager.SetTimescale((CL_GameManager.GetBaseTimescale() > 0f) ? 0f : 1f);
			}
			if (hideAllSpawnsToggle.isOn || cache_objectsToDraw.Count <= 0 || (!CL_GameManager.gMan.freecam && !ENT_Player.playerObject.noclip))
			{
				return;
			}
			Camera currentCam = (CL_GameManager.gMan.freecam ? ((Component)freecamController).GetComponent<Camera>() : ENT_Player.playerObject.cam);
			((CommandBuilder)(ref viewDraw)).Dispose();
			viewDraw = DrawingManager.GetBuilder(true);
			((CommandBuilder)(ref viewDraw)).cameraTargets = (Camera[])(object)new Camera[1] { currentCam };
			cache_objectsToDraw.RemoveWhere((Tuple<Func<bool>, GameObject> x) => (Object)(object)x.Item2 == (Object)null);
			List<Tuple<Func<bool>, GameObject>> list = cache_objectsToDraw.OrderBy(delegate(Tuple<Func<bool>, GameObject> d)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0025: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = currentCam.WorldToScreenPoint(d.Item2.transform.position) - Input.mousePosition;
				return ((Vector3)(ref val)).sqrMagnitude;
			}).ToList();
			Tuple<Func<bool>, GameObject> tuple = list.FirstOrDefault(delegate(Tuple<Func<bool>, GameObject> m)
			{
				//IL_0012: 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)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = currentCam.WorldToScreenPoint(m.Item2.transform.position);
				return val.z > 0f && Vector2.Distance(Vector2.op_Implicit(val), Vector2.op_Implicit(Input.mousePosition)) < 100f;
			});
			bool flag = false;
			foreach (Tuple<Func<bool>, GameObject> item in list)
			{
				if ((item.Item1 != null || Patches.GenericDraw(item.Item2, GetCleanName(item.Item2))) && (item.Item1 == null || item.Item1()) && tuple != null && (Object)(object)tuple.Item2 == (Object)(object)item.Item2)
				{
					flag = true;
					((CommandBuilder)(ref viewDraw)).Cross(float3.op_Implicit(tuple.Item2.transform.position), Color.red);
				}
			}
			if ((tuple == null || !flag) && ((Component)itemInfoText.transform.parent).gameObject.activeSelf)
			{
				((Component)itemInfoText.transform.parent).gameObject.SetActive(false);
				((Component)levelInfoText.transform.parent).gameObject.SetActive(true);
			}
			else if (tuple != null && flag)
			{
				if (((Component)levelInfoText.transform.parent).gameObject.activeSelf)
				{
					((Component)itemInfoText.transform.parent).gameObject.SetActive(true);
					((Component)levelInfoText.transform.parent).gameObject.SetActive(false);
				}
				itemInfoText.text = GetCleanName(tuple.Item2) + "\n" + GetSpawnDataForSettings(tuple.Item2);
			}
		}

		private static void AddCached(Tuple<Func<bool>, GameObject> thing)
		{
			if (thing.Item1 != null || !instance.cache_objectsToDraw.Any((Tuple<Func<bool>, GameObject> x) => (Object)(object)x.Item2 == (Object)(object)thing.Item2 && x.Item1 != null))
			{
				instance.cache_objectsToDraw.RemoveWhere((Tuple<Func<bool>, GameObject> x) => (Object)(object)x.Item2.gameObject == (Object)(object)thing.Item2);
				instance.cache_objectsToDraw.Add(thing);
			}
		}

		private void PopulateLevelList(string regionName = null)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Expected O, but got Unknown
			foreach (Transform item in (Transform)levelListContent)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			if (regionName == "Everything (laggy)")
			{
				GameObject val2 = Object.Instantiate<GameObject>(subregionListPrefab, (Transform)(object)levelListContent);
				Button component = ((Component)val2.transform.Find("regionsubregheader")).GetComponent<Button>();
				((Component)component).GetComponentInChildren<TMP_Text>().text = "Everything (laggy)";
				Transform val3 = val2.transform.Find("subregionholder");
				List<M_Level> list = CL_AssetManager.GetFullCombinedAssetDatabase().levelAssets.Select((LevelAssetHolder x) => x.level).ToList();
				{
					foreach (M_Level level in list)
					{
						Button newButton = Object.Instantiate<GameObject>(levelButtonPrefab, val3).GetComponent<Button>();
						((Component)newButton).GetComponentInChildren<TMP_Text>().text = GetLevelName(level);
						((UnityEvent)newButton.onClick).AddListener((UnityAction)delegate
						{
							Event_LevelButton(newButton, level.levelName);
						});
					}
					return;
				}
			}
			M_Region regionByName = GetRegionByName(regionName ?? regionDropdown.options[regionDropdown.value].text);
			foreach (SubregionGroup subregionGroup in regionByName.subregionGroups)
			{
				GameObject val4 = Object.Instantiate<GameObject>(subregionListPrefab, (Transform)(object)levelListContent);
				Button component2 = ((Component)val4.transform.Find("regionsubregheader")).GetComponent<Button>();
				((Component)component2).GetComponentInChildren<TMP_Text>().text = subregionGroup.name;
				Transform val5 = val4.transform.Find("subregionholder");
				List<M_Level> list2 = (from x in subregionGroup.subregions.SelectMany((M_Subregion x) => x.levelReferences)
					select x.level).ToList();
				List<M_Level> list3 = (from x in subregionGroup.subregions.SelectMany((M_Subregion x) => x.levelGroups).SelectMany((LevelGroup x) => x.levelReferences)
					select x.level).ToList();
				HashSet<M_Level> intersection = new HashSet<M_Level>(list2.Intersect(list3));
				list2.AddRange(list3.Where((M_Level item) => !intersection.Contains(item)));
				foreach (M_Level level2 in list2)
				{
					Button newButton2 = Object.Instantiate<GameObject>(levelButtonPrefab, val5).GetComponent<Button>();
					((Component)newButton2).GetComponentInChildren<TMP_Text>().text = GetLevelName(level2);
					((UnityEvent)newButton2.onClick).AddListener((UnityAction)delegate
					{
						Event_LevelButton(newButton2, level2.levelName);
					});
				}
			}
		}

		private void UpdateDataViewWithLevel(M_Level level)
		{
			List<string> list = new List<string>
			{
				level.levelName,
				GetSpawnDataForSettings(level.spawnSettings)
			};
			if (level.massSpeedMult != 1f)
			{
				list.Add($"Mass speed mult: {level.massSpeedMult * 100f}%");
			}
			if (level.safeArea)
			{
				list.Add("Safe area");
			}
			if (!level.showInLevelList)
			{
				list.Add("Hidden from level list");
			}
			if (!level.allowEvents)
			{
				list.Add("Events not allowed");
			}
			if (level.tags.Count > 0)
			{
				list.Add(string.Join(",", level.tags));
			}
			levelInfoText.text = string.Join("<br>", list);
		}
	}
	[BepInPlugin("LevelViewer", "LevelViewer", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource Logger;

		public static AssetBundle bundle;

		public static GameObject viewerPrefab;

		public static bool loadViewerNextSceneLoad;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "levelviewer_bundle");
			bundle = AssetBundle.LoadFromFile(text);
			viewerPrefab = bundle.LoadAsset<GameObject>("ViewerPrefab");
			SceneManager.sceneLoaded += OnSceneLoad;
			Harmony val = Harmony.CreateAndPatchAll(typeof(Patches), "LevelViewer 123");
		}

		public static void OnSceneLoad(Scene scene, LoadSceneMode _)
		{
			if (!(((Scene)(ref scene)).name != "Game-Main") && loadViewerNextSceneLoad)
			{
				loadViewerNextSceneLoad = false;
				Object.Instantiate<GameObject>(viewerPrefab, CL_UIManager.instance.canvas.parent);
			}
		}

		public static void MainMenuButtonPressed()
		{
			M_Gamemode gamemodeAsset = CL_AssetManager.GetGamemodeAsset("GM_Level_Tester", "");
			CL_GameManager.gMan.SetGamemode(gamemodeAsset);
			CL_GameManager.gMan.baseGamemode = gamemodeAsset;
			loadViewerNextSceneLoad = true;
			SceneManager.LoadScene("Game-Main");
		}
	}
	public class Patches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__MainMenuButtonPressed;
		}

		[HarmonyPatch(typeof(UI_PlayPane), "Start")]
		[HarmonyPostfix]
		public static void AddOurButton(UI_PlayPane __instance)
		{
			//IL_0068: 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_0073: Expected O, but got Unknown
			Transform val = ((Component)__instance).transform.Find("Tab Objects/Play Pane - Scroll View Tab - Main/Viewport/Content");
			Transform val2 = val.Find("Mode Selection Button - Tutorial");
			Transform val3 = Object.Instantiate<Transform>(val2, val);
			Object.Destroy((Object)(object)((Component)val3).GetComponent<UI_Gamemode_Button>());
			((Component)val3.Find("Mode Name")).GetComponent<TMP_Text>().text = "Level Viewer";
			ButtonClickedEvent onClick = ((Component)val3).GetComponent<Button>().onClick;
			object obj = <>O.<0>__MainMenuButtonPressed;
			if (obj == null)
			{
				UnityAction val4 = Plugin.MainMenuButtonPressed;
				<>O.<0>__MainMenuButtonPressed = val4;
				obj = (object)val4;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LevelViewer";

		public const string PLUGIN_NAME = "LevelViewer";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}