Decompiled source of Baby Blocks v1.0.2

Mods/BabyBlocks.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
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;
using System.Text.Json;
using BabyBlocks;
using BabyBlocks.Networking;
using BabyBlocks.UI;
using BabyStepsMenuLib;
using HarmonyLib;
using Il2Cpp;
using Il2CppBeautifyEffect;
using Il2CppCinemachine;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNWH.DWP2.WaterObjects;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.Config;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.Panels;
using UniverseLib.UI.Widgets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "Baby Blocks", "1.0.1", "Caleb Orchard", null)]
[assembly: MelonGame("DefaultCompany", "BabySteps")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BabyBlocks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.0+6bca26d40e0aea8157b6afaae13e39037c1f65c7")]
[assembly: AssemblyProduct("BabyBlocks")]
[assembly: AssemblyTitle("BabyBlocks")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
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 BabyBlocks
{
	public class Core : MelonMod
	{
		public static bool DebugMode = false;

		private static MelonPreferences_Category _prefs;

		private static MelonPreferences_Entry<string> _lastSavePath;

		private static FieldInfo _mpUiManagerField;

		private static FieldInfo _mpShowChatTabField;

		private static bool _mpReflectionDone;

		private const float SomebodyLoadingStuckTimeout = 6f;

		private static bool _somebodyLoadingWasTrue;

		private static float _somebodyLoadingSinceTime;

		private const float MenuTeleportingStuckTimeout = 8f;

		private static bool _menuTeleportingWasTrue;

		private static float _menuTeleportingSinceTime;

		internal static float PendingMicroSplatRefreshTime = -1f;

		internal const float MicroSplatRefreshSettleDelay = 1.5f;

		private static bool _wasFarTeleportActive;

		private const int PostTeleportRescanFrames = 90;

		private static int _postTeleportRescanFramesRemaining;

		private static bool _networkingDisabled;

		public static Instance Logger { get; private set; }

		public static bool IsMultiplayerChatOpen
		{
			get
			{
				EnsureMpReflection();
				if (_mpUiManagerField == null)
				{
					return false;
				}
				try
				{
					object value = _mpUiManagerField.GetValue(null);
					return value != null && (bool)_mpShowChatTabField.GetValue(value);
				}
				catch
				{
					return false;
				}
			}
		}

		public static bool IsKeyboardCaptured => IsMultiplayerChatOpen || ((Object)(object)Menu.me != (Object)null && Menu.me.paused);

		public static string LastSavePath
		{
			get
			{
				return _lastSavePath?.Value ?? "";
			}
			set
			{
				if (_lastSavePath != null)
				{
					_lastSavePath.Value = value;
					_prefs.SaveToFile(true);
				}
			}
		}

		private static void EnsureMpReflection()
		{
			if (_mpReflectionDone)
			{
				return;
			}
			_mpReflectionDone = true;
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (!(assembly.GetName().Name != "BabyStepsMultiplayerClient"))
					{
						FieldInfo fieldInfo = assembly.GetType("BabyStepsMultiplayerClient.Core")?.GetField("uiManager", BindingFlags.Static | BindingFlags.Public);
						FieldInfo fieldInfo2 = fieldInfo?.FieldType.GetField("showChatTab", BindingFlags.Instance | BindingFlags.Public);
						if (fieldInfo != null && fieldInfo2 != null)
						{
							_mpUiManagerField = fieldInfo;
							_mpShowChatTabField = fieldInfo2;
						}
						break;
					}
				}
			}
			catch
			{
			}
		}

		private static void WatchSomebodyLoading()
		{
			if ((Object)(object)BestRegionLoader.me == (Object)null || FlyCamController.FarTeleportActive)
			{
				return;
			}
			if (BestRegionLoader.somebodyLoading)
			{
				if (!_somebodyLoadingWasTrue)
				{
					_somebodyLoadingWasTrue = true;
					_somebodyLoadingSinceTime = Time.realtimeSinceStartup;
				}
				else if (Time.realtimeSinceStartup - _somebodyLoadingSinceTime > 6f)
				{
					MelonLogger.Warning($"[BabyBlocks] BestRegionLoader.somebodyLoading stuck for {6f}s, force-clearing.");
					BestRegionLoader.somebodyLoading = false;
					_somebodyLoadingWasTrue = false;
				}
			}
			else
			{
				_somebodyLoadingWasTrue = false;
			}
		}

		private static void WatchMenuTeleporting()
		{
			if ((Object)(object)Menu.me == (Object)null)
			{
				return;
			}
			if (FlyCamController.FarTeleportActive || FlyCamController.LevelLoadTeleportActive || FlyCamController.NetworkLevelTransferActive)
			{
				_menuTeleportingWasTrue = false;
			}
			else if (Menu.me.teleporting)
			{
				if (!_menuTeleportingWasTrue)
				{
					_menuTeleportingWasTrue = true;
					_menuTeleportingSinceTime = Time.realtimeSinceStartup;
				}
				else if (Time.realtimeSinceStartup - _menuTeleportingSinceTime > 8f)
				{
					MelonLogger.Warning($"[BabyBlocks] Menu.me.teleporting stuck true for {8f}s, force-clearing.");
					Menu.me.teleporting = false;
					_menuTeleportingWasTrue = false;
				}
			}
			else
			{
				_menuTeleportingWasTrue = false;
			}
		}

		public override void OnInitializeMelon()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			Logger = ((MelonBase)this).LoggerInstance;
			_prefs = MelonPreferences.CreateCategory("BabyBlocks");
			_lastSavePath = _prefs.CreateEntry<string>("LastSavePath", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			ClassInjector.RegisterTypeInIl2Cpp<LevelEditorObject>();
			ClassInjector.RegisterTypeInIl2Cpp<LevelEditorManager>();
			ClassInjector.RegisterTypeInIl2Cpp<GizmoHandle>();
			ClassInjector.RegisterTypeInIl2Cpp<GhostCollisionCutter>();
			ClassInjector.RegisterTypeInIl2Cpp<SpawnPointMarker>();
			ClassInjector.RegisterTypeInIl2Cpp<OverlayCamPreRenderHook>();
			ClassInjector.RegisterTypeInIl2Cpp<BbSunglassesChecker>();
			Harmony val = new Harmony("BabyBlocks.Patches");
			val.PatchAll(Assembly.GetExecutingAssembly());
			val.PatchAll(typeof(MenuInjectionLibrary).Assembly);
			MenuInjectionLibrary.Logger = Logger;
			CustomLevelsMenu.Initialize();
			PropBrowserUI.Init();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			MaterialVariantTracker.InvalidateMaterialCache();
			PendingMicroSplatRefreshTime = Time.realtimeSinceStartup;
		}

		public override void OnUpdate()
		{
			CustomLevelsMenu.Update();
			WatchSomebodyLoading();
			WatchMenuTeleporting();
			if (!_networkingDisabled)
			{
				try
				{
					ModNetworking.Update();
				}
				catch (Exception ex)
				{
					_networkingDisabled = true;
					MelonLogger.Warning("[BabyBlocks] Networking unavailable, disabling: " + ex.Message);
				}
			}
			FlyCamController.OnUpdate();
			PropBrowserUI.UpdateVisibility();
			PropInstanceServices.RenderTints();
			BaseMapController.TickWeatherPreset();
			if (!BaseMapController.BaseMapEnabled && !FlyCamController.FarTeleportActive)
			{
				if (_wasFarTeleportActive)
				{
					_postTeleportRescanFramesRemaining = 90;
				}
				_wasFarTeleportActive = false;
				BestRegionLoader me = BestRegionLoader.me;
				if ((Object)(object)me != (Object)null)
				{
					if (_postTeleportRescanFramesRemaining > 0)
					{
						BaseMapController.RescanLoadedChunksForBaseMapOff();
						_postTeleportRescanFramesRemaining--;
					}
					if (!me.off && !BaseMapController.DeferBrlOff && _postTeleportRescanFramesRemaining == 0)
					{
						me.off = true;
					}
					Renderer[] brlRendererCache = BaseMapController._brlRendererCache;
					bool flag = false;
					Renderer[] array = brlRendererCache;
					foreach (Renderer val in array)
					{
						if ((Object)(object)val == (Object)null)
						{
							flag = true;
							break;
						}
						if (val.enabled)
						{
							val.enabled = false;
						}
					}
					if (flag)
					{
						BaseMapController._brlRendererCache = Il2CppArrayBase<Renderer>.op_Implicit(((Component)me).GetComponentsInChildren<Renderer>(true));
					}
				}
				BaseMapController.SuppressHiddenWhileBaseMapOff();
			}
			else if (FlyCamController.FarTeleportActive)
			{
				_wasFarTeleportActive = true;
			}
		}

		public override void OnLateUpdate()
		{
			PropBrowserUI.RestoreCursor();
		}

		public override void OnGUI()
		{
			FlyCamController.OnGUI();
			HatPreviewRenderer.DrawWindowGUI();
		}
	}
	[HarmonyPatch(typeof(FlyCam), "Update")]
	internal class FlyCamUpdatePatch
	{
		private static bool Prefix(FlyCam __instance)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			if (FlyCam.locked)
			{
				return false;
			}
			bool flag = FlyCamController.CursorMode && (LevelEditor.IsTypingInUI || Core.IsKeyboardCaptured);
			Vector3 val = Vector3.zero;
			if (!flag)
			{
				if (Input.GetKey((KeyCode)119))
				{
					val += Vector3.forward;
				}
				if (Input.GetKey((KeyCode)115))
				{
					val += Vector3.back;
				}
				if (Input.GetKey((KeyCode)100))
				{
					val += Vector3.right;
				}
				if (Input.GetKey((KeyCode)97))
				{
					val += Vector3.left;
				}
				if (Input.GetKey((KeyCode)101))
				{
					val += Vector3.up;
				}
				if (Input.GetKey((KeyCode)113))
				{
					val += Vector3.down;
				}
				if (Input.GetKey((KeyCode)304))
				{
					val *= 10f;
				}
				if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)308))
				{
					val *= 30f;
				}
			}
			if (!FlyCamController.CursorMode || (Input.GetMouseButton(1) && !LevelEditor.isDragging))
			{
				Vector3 eulerAngles = ((Component)__instance).transform.eulerAngles;
				if (eulerAngles.x > 180f)
				{
					eulerAngles.x -= 360f;
				}
				eulerAngles.x -= Input.GetAxis("Mouse Y");
				eulerAngles.x = Mathf.Clamp(eulerAngles.x, -85f, 85f);
				eulerAngles.y += Input.GetAxis("Mouse X");
				((Component)__instance).transform.eulerAngles = eulerAngles;
			}
			Transform transform = ((Component)__instance).transform;
			transform.position += ((Component)__instance).transform.rotation * (val * __instance.maxVel) * Time.unscaledDeltaTime;
			if (!FlyCamController.CursorMode && Input.GetMouseButtonDown(0) && !Menu.me.paused)
			{
				FlyCamController.HandleFarTeleport();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(CinemachineBrain), "LateUpdate")]
	internal class CinemachineBrainLateUpdatePatch
	{
		private static void Postfix(CinemachineBrain __instance)
		{
			if (!BaseMapController.BaseMapEnabled)
			{
				__instance.ManualUpdate();
			}
			GizmoRenderer.RefreshSSBufferMatrices();
		}
	}
	[HarmonyPatch(typeof(BBConvoStarter), "OnTriggerEnter")]
	internal class BBConvoStarterTriggerPatch
	{
		private static bool Prefix(BBConvoStarter __instance)
		{
			bool suppressCutsceneTriggers = FlyCamController.SuppressCutsceneTriggers;
			return !suppressCutsceneTriggers;
		}
	}
	[HarmonyPatch(typeof(BBConvoStarter), "PlayCutscene")]
	internal class BBConvoStarterPlayCutscenePatch
	{
		private static bool Prefix(BBConvoStarter __instance)
		{
			bool suppressCutsceneTriggers = FlyCamController.SuppressCutsceneTriggers;
			if (suppressCutsceneTriggers)
			{
				FlyCamController.RegisterSuppressedCutscene(__instance);
			}
			return !suppressCutsceneTriggers;
		}
	}
	[HarmonyPatch(typeof(TractionByteKeeper), "GetGrassAt")]
	internal class TractionByteKeeperGetGrassAtPatch
	{
		private static bool Prefix(Vector3 pos, ref GrassType __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			int grassTypeAtPos = PropInstanceServices.BushAudioTracker.GetGrassTypeAtPos(pos);
			if (grassTypeAtPos != 0)
			{
				__result = (GrassType)grassTypeAtPos;
				return false;
			}
			return true;
		}
	}
	internal static class BBLog
	{
		internal static bool Verbose;

		internal static void Msg(string msg)
		{
			if (Verbose)
			{
				MelonLogger.Msg(msg);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "PlaceCurrentHatOnHead")]
	internal class PlaceCurrentHatOnHeadPatch
	{
		private static bool Prefix(PlayerMovement __instance)
		{
			//IL_0080: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.currentHat == (Object)null)
			{
				return true;
			}
			LevelEditorObject levelEditorObject = ((Component)__instance.currentHat).GetComponent<LevelEditorObject>() ?? ((Component)__instance.currentHat).GetComponentInChildren<LevelEditorObject>();
			if ((Object)(object)levelEditorObject == (Object)null)
			{
				return true;
			}
			Transform transform = ((Component)__instance.currentHat).transform;
			transform.parent = (__instance.inCutscene ? __instance.head : __instance.headRB);
			transform.localPosition = new Vector3(0f, 0.207f, -0.02f) + levelEditorObject.hatOffsetPos;
			transform.localRotation = Quaternion.Euler(-25f + levelEditorObject.hatOffsetRot.x, levelEditorObject.hatOffsetRot.y, levelEditorObject.hatOffsetRot.z);
			if (!__instance.inCutscene)
			{
				transform.parent = null;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(SunglassesChecker), "Update")]
	internal class SunglassesCheckerUpdatePatch
	{
		private static readonly HashSet<int> _forcedVisible = new HashSet<int>();

		private static void Postfix(SunglassesChecker __instance)
		{
			bool flyCamActive = FlyCamController.FlyCamActive;
			int instanceID = ((Object)__instance).GetInstanceID();
			if (flyCamActive)
			{
				_forcedVisible.Add(instanceID);
				SetRends(__instance, enabled: true);
			}
			else if (_forcedVisible.Remove(instanceID))
			{
				bool enabled = BbSunglassesChecker.IsWearingSunglasses();
				SetRends(__instance, enabled);
			}
		}

		private static void SetRends(SunglassesChecker instance, bool enabled)
		{
			try
			{
				FieldInfo field = ((Object)instance).GetIl2CppType().GetField("rends");
				if (field != (FieldInfo)null)
				{
					Object value = field.GetValue(((Il2CppObjectBase)instance).Cast<Object>());
					Il2CppReferenceArray<Renderer> val = ((value != null) ? ((Il2CppObjectBase)value).TryCast<Il2CppReferenceArray<Renderer>>() : null);
					if (val != null)
					{
						foreach (Renderer item in (Il2CppArrayBase<Renderer>)(object)val)
						{
							if ((Object)(object)item != (Object)null)
							{
								item.enabled = enabled;
							}
						}
						return;
					}
				}
			}
			catch
			{
			}
			foreach (Renderer componentsInChild in ((Component)instance).GetComponentsInChildren<Renderer>(true))
			{
				if ((Object)(object)componentsInChild != (Object)null)
				{
					componentsInChild.enabled = enabled;
				}
			}
		}
	}
	public enum PhysicsMode
	{
		Static,
		Rigidbody,
		Grabable,
		Hat
	}
	public class LevelEditorObject : MonoBehaviour
	{
		public string objectType = "Cube";

		public string addressableKey = "";

		public int chunkIndex = -1;

		public Vector2Int chunkCoord = new Vector2Int(-1, -1);

		public Vector3 loopBasePosition;

		public Quaternion loopBaseRotation = Quaternion.identity;

		public Vector3 loopBaseScale = Vector3.one;

		public bool hasLoopBasePosition;

		public bool hasLoopBaseRotation;

		public bool hasLoopBaseScale;

		public PhysicsMode physicsMode = PhysicsMode.Static;

		public float hatHairAmt = 0f;

		public int groupId = 0;

		public int physicsGroupId = 0;

		public bool isPhysicsManaged;

		public bool editorFreezeStateValid;

		public Vector3 editorFreezePosition;

		public Quaternion editorFreezeRotation;

		public Vector3 editorFreezeScale;

		public Vector3 editorFreezeVelocity;

		public Vector3 editorFreezeAngularVelocity;

		public bool editorFreezeIsKinematic;

		public bool editorFreezeUseGravity;

		public RigidbodyConstraints editorFreezeConstraints;

		public Vector3 grabOffsetPos = Vector3.zero;

		public Vector3 grabOffsetRot = Vector3.zero;

		public Vector3 hatOffsetPos = Vector3.zero;

		public Vector3 hatOffsetRot = Vector3.zero;

		public int materialConstructionId = -1;

		public bool sunglassesNeeded;

		public bool playerPassthrough;

		public bool freezeUntilHit;

		public string surfaceTypeTag = "";

		public Vector3 materialTint = new Vector3(255f, 255f, 255f);

		internal Renderer[] _tintRenderers;

		internal Material _tintMaterial;

		public ulong netId = 0uL;

		public LevelEditorObject(IntPtr ptr)
			: base(ptr)
		{
		}//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_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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: 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_0066: 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_0071: 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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)


		public void OnCollisionEnter(Collision collision)
		{
			if (!freezeUntilHit || !PhysicsObjectManager.HasFreezeUntilHit(this))
			{
				return;
			}
			Rigidbody rigidbody = collision.rigidbody;
			int layer = ((Component)collision.collider).gameObject.layer;
			bool flag = layer == LayerCache.RagdollLayer;
			bool flag2 = (Object)(object)rigidbody != (Object)null && !rigidbody.isKinematic && (Object)(object)((Component)rigidbody).GetComponentInParent<LevelEditorObject>(true) != (Object)null;
			if (flag || flag2)
			{
				PhysicsObjectManager.OnFreezeUntilHitTriggered(this);
				PhysicsObjectManager.UnfreezeHitProp(this, collision);
				if (netId != 0)
				{
					ModNetworking.SendPropFreezeReleased(netId);
				}
			}
		}
	}
	public class GizmoHandle : MonoBehaviour
	{
		public int axisIndex;

		public GizmoHandle(IntPtr ptr)
			: base(ptr)
		{
		}
	}
	internal class OverlayCamPreRenderHook : MonoBehaviour
	{
		public OverlayCamPreRenderHook(IntPtr ptr)
			: base(ptr)
		{
		}

		public void OnPreRender()
		{
			GizmoRenderer.RefreshSSBufferMatrices();
		}
	}
	internal class BbSunglassesChecker : MonoBehaviour
	{
		private bool[] _wasEnabled;

		public BbSunglassesChecker(IntPtr ptr)
			: base(ptr)
		{
		}

		public static bool IsWearingSunglasses()
		{
			if (FlyCamController.FlyCamActive)
			{
				return true;
			}
			PlayerMovement me = PlayerMovement.me;
			return (Object)(object)me != (Object)null && (Object)(object)me.currentHat != (Object)null && me.currentHat.isSunglasses && !me.inCutscene;
		}

		private void Awake()
		{
			Il2CppArrayBase<Renderer> componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			_wasEnabled = new bool[componentsInChildren.Length];
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				_wasEnabled[i] = (Object)(object)componentsInChildren[i] != (Object)null && componentsInChildren[i].enabled;
			}
		}

		private void Update()
		{
			if (_wasEnabled == null)
			{
				return;
			}
			bool enabled = IsWearingSunglasses();
			Il2CppArrayBase<Renderer> componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			int num = Math.Min(componentsInChildren.Length, _wasEnabled.Length);
			for (int i = 0; i < num; i++)
			{
				if (!((Object)(object)componentsInChildren[i] == (Object)null) && _wasEnabled[i])
				{
					componentsInChildren[i].enabled = enabled;
				}
			}
		}
	}
	internal static class BbHatSunglassesFlag
	{
		private static readonly HashSet<int> _ids = new HashSet<int>();

		internal static void Clear()
		{
			_ids.Clear();
		}

		internal static void Set(LevelEditorObject leo, bool on)
		{
			if (!((Object)(object)((leo != null) ? ((Component)leo).gameObject : null) == (Object)null))
			{
				int instanceID = ((Object)((Component)leo).gameObject).GetInstanceID();
				if (on)
				{
					_ids.Add(instanceID);
				}
				else
				{
					_ids.Remove(instanceID);
				}
			}
		}

		internal static bool Has(LevelEditorObject leo)
		{
			return (Object)(object)((leo != null) ? ((Component)leo).gameObject : null) != (Object)null && _ids.Contains(((Object)((Component)leo).gameObject).GetInstanceID());
		}
	}
	internal static class FlyCamController
	{
		public static bool FlyCamActive;

		public static bool CursorMode;

		public static bool LevelLoadTeleportActive;

		public static bool NetworkLevelTransferActive;

		private const float CutsceneSuppressGraceTime = 0.3f;

		private static float _cutsceneSuppressUntil = -1f;

		private static readonly List<BBConvoStarter> _pendingCutscenes = new List<BBConvoStarter>();

		private static float _noiseAmplitude = -1f;

		private static bool _editorScanDone;

		private static EnviroSkyRendering _enviroSkyRendering;

		private static Beautify _beautify;

		private static bool _farTeleportActive;

		private static Transform _teleportLoadAnchor;

		private static bool _freezeActive;

		private static PlayerMovement _frozenPlayer;

		private static CharacterController _frozenController;

		private static Rigidbody _frozenRigidbody;

		private static Animator _frozenAnimator;

		private static bool _movementWasEnabled;

		private static bool _controllerWasEnabled;

		private static bool _rigidbodyWasKinematic;

		private static bool _rigidbodyWasUseGravity;

		private static RigidbodyConstraints _rigidbodyConstraints;

		private static Vector3 _rigidbodyVelocity;

		private static Vector3 _rigidbodyAngularVelocity;

		private static float _animatorSpeed = 1f;

		private static GUIStyle _teleportLabelStyle;

		public static bool SuppressCutsceneTriggers => FlyCamActive || !BaseMapController.BaseMapEnabled || Time.unscaledTime < _cutsceneSuppressUntil;

		internal static bool FarTeleportActive => _farTeleportActive;

		private static Transform TeleportLoadAnchor
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)_teleportLoadAnchor == (Object)null)
				{
					GameObject val = new GameObject("BB_TeleportLoadAnchor");
					Object.DontDestroyOnLoad((Object)(object)val);
					_teleportLoadAnchor = val.transform;
				}
				return _teleportLoadAnchor;
			}
		}

		public static void BeginLevelLoadTeleport()
		{
			LevelLoadTeleportActive = true;
		}

		public static void EndLevelLoadTeleport()
		{
			LevelLoadTeleportActive = false;
		}

		public static void BeginNetworkLevelTransfer()
		{
			NetworkLevelTransferActive = true;
		}

		public static void EndNetworkLevelTransfer()
		{
			NetworkLevelTransferActive = false;
		}

		public static void RegisterSuppressedCutscene(BBConvoStarter bcs)
		{
			if ((Object)(object)bcs == (Object)null)
			{
				return;
			}
			string saveName = bcs.GetSaveName();
			foreach (BBConvoStarter pendingCutscene in _pendingCutscenes)
			{
				if ((Object)(object)pendingCutscene != (Object)null && pendingCutscene.GetSaveName() == saveName)
				{
					return;
				}
			}
			_pendingCutscenes.Add(bcs);
		}

		private static void ReplaySuppressedCutscenes()
		{
			if (_pendingCutscenes.Count == 0 || SuppressCutsceneTriggers)
			{
				return;
			}
			List<BBConvoStarter> list = new List<BBConvoStarter>(_pendingCutscenes);
			_pendingCutscenes.Clear();
			foreach (BBConvoStarter item in list)
			{
				if (!((Object)(object)item == (Object)null))
				{
					item.PlayCutscene();
				}
			}
		}

		private static void SetEditorPostProcessing(bool enabled)
		{
			if ((Object)(object)_enviroSkyRendering == (Object)null || (Object)(object)_beautify == (Object)null)
			{
				GameObject obj = GameObject.Find("BigManagerPrefab");
				Transform val = ((obj != null) ? obj.transform.Find("Camera") : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				_enviroSkyRendering = ((Component)val).GetComponent<EnviroSkyRendering>();
				_beautify = ((Component)val).GetComponent<Beautify>();
			}
			if ((Object)(object)_enviroSkyRendering != (Object)null)
			{
				((Behaviour)_enviroSkyRendering).enabled = enabled;
			}
			if ((Object)(object)_beautify != (Object)null)
			{
				((Behaviour)_beautify).enabled = enabled;
			}
		}

		public static void OnUpdate()
		{
			ReplaySuppressedCutscenes();
			if (Core.PendingMicroSplatRefreshTime >= 0f && Time.realtimeSinceStartup - Core.PendingMicroSplatRefreshTime >= 1.5f)
			{
				Core.PendingMicroSplatRefreshTime = -1f;
				MaterialCatalog.RefreshMicroSplatLayerMaterials();
				MaterialVariantTracker.InvalidateMaterialCache();
				MaterialCatalog.EnsureMaterialListLoaded();
				MaterialCatalog.ReapplyAllMaterialOverrides();
				if (!BaseMapController.BaseMapEnabled)
				{
					BaseMapController.SetEditorPropsSnowDisabled(disable: true);
				}
				LevelEditorManager.Instance?.PruneDestroyedObjects();
				LevelEditor.PruneSelection();
				if (GizmoRenderer.IsReady)
				{
					GizmoRenderer.RefreshAssets();
				}
			}
			if (Input.GetKeyDown((KeyCode)114) && (Object)(object)PlayerMovement.me != (Object)null && !Menu.me.teleporting && !_farTeleportActive && !Core.IsKeyboardCaptured && !LevelEditor.IsTypingInUI && !PropPalette.IsDragging && !LevelEditor.IsSurfaceSnapDragging && !PlayerMovement.me.inCutscene)
			{
				ToggleFlyEditorMode();
			}
			if (Input.GetKeyDown((KeyCode)96) && (Object)(object)PlayerMovement.me != (Object)null && !Menu.me.teleporting && !_farTeleportActive && !Core.IsKeyboardCaptured && !PlayerMovement.me.inCutscene)
			{
				ToggleTeleportMode();
			}
			if (FlyCamActive && !CursorMode && Input.GetKeyDown((KeyCode)103) && !Menu.me.teleporting && !_farTeleportActive && !Core.IsKeyboardCaptured)
			{
				HandleFarTeleport();
			}
			if (FlyCamActive && !Menu.me.teleporting)
			{
				PlayerMovement me = PlayerMovement.me;
				if ((Object)(object)me != (Object)null)
				{
					BestRegionLoader.me.loadingTransform = ((Component)me.flyCam).transform;
				}
			}
			if (FlyCamActive && CursorMode)
			{
				if (Input.GetMouseButtonDown(1))
				{
					Cursor.lockState = (CursorLockMode)1;
					Cursor.visible = false;
				}
				if (Input.GetMouseButtonUp(1))
				{
					Cursor.lockState = (CursorLockMode)2;
					Cursor.visible = true;
				}
			}
			if (FlyCamActive && CursorMode && !LevelEditor.IsTypingInUI && !Core.IsKeyboardCaptured && Input.GetKey((KeyCode)306) && Input.GetKeyDown((KeyCode)115))
			{
				SaveLoadWindow.TriggerSave();
			}
			if (FlyCamActive && CursorMode && !LevelEditor.IsTypingInUI && !Core.IsKeyboardCaptured && Input.GetKey((KeyCode)306) && Input.GetKeyDown((KeyCode)97))
			{
				LevelEditor.SelectAll();
			}
			if (FlyCamActive && CursorMode && !LevelEditor.IsTypingInUI && !Core.IsKeyboardCaptured && Input.GetKeyDown((KeyCode)109))
			{
				MaterialInspectorPanel.Toggle();
			}
			if (FlyCamActive && CursorMode)
			{
				LevelEditor.Update();
			}
		}

		public static void OnGUI()
		{
			//IL_0065: 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)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			if (FlyCamActive && CursorMode && (!PropBrowserUI.Ready || Core.DebugMode))
			{
				LevelEditor.OnGUI();
			}
			bool flag = _farTeleportActive || LevelLoadTeleportActive;
			bool networkLevelTransferActive = NetworkLevelTransferActive;
			if (flag || networkLevelTransferActive)
			{
				if (_teleportLabelStyle == null)
				{
					_teleportLabelStyle = new GUIStyle(GUI.skin.label)
					{
						fontSize = 48,
						fontStyle = (FontStyle)1
					};
					_teleportLabelStyle.normal.textColor = Color.white;
				}
				string text = ((networkLevelTransferActive && !flag) ? "Loading level..." : "Teleporting...");
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(13f, (float)Screen.height - 12f - 60f + 1f, 400f, 60f);
				Rect val2 = default(Rect);
				((Rect)(ref val2))..ctor(12f, (float)Screen.height - 12f - 60f, 400f, 60f);
				Color textColor = _teleportLabelStyle.normal.textColor;
				_teleportLabelStyle.normal.textColor = Color.black;
				GUI.Label(val, text, _teleportLabelStyle);
				_teleportLabelStyle.normal.textColor = textColor;
				GUI.Label(val2, text, _teleportLabelStyle);
			}
		}

		private static void ToggleTeleportMode()
		{
			if (!FlyCamActive)
			{
				ToggleFlyMode();
				ToggleCursorMode();
			}
			else
			{
				ToggleFlyMode();
			}
		}

		public static void InvokeRKeyAction()
		{
			if (!((Object)(object)PlayerMovement.me == (Object)null) && !((Object)(object)Menu.me == (Object)null) && !Menu.me.teleporting && !_farTeleportActive && !PlayerMovement.me.inCutscene)
			{
				ToggleFlyEditorMode();
			}
		}

		private static void ToggleFlyEditorMode()
		{
			if (!FlyCamActive)
			{
				ToggleFlyMode();
			}
			else
			{
				ToggleCursorMode();
			}
		}

		private static void ToggleFlyMode()
		{
			PlayerMovement me = PlayerMovement.me;
			bool flag = (Object)(object)((Component)me.flyCam).transform.parent != (Object)null;
			me.ToggleFlyCam();
			if (flag)
			{
				FlyCamActive = true;
				CursorMode = false;
				Cursor.lockState = (CursorLockMode)1;
				FreezePlayer(me, frozen: true);
				LevelEditor.EnsureManager();
				if (!_editorScanDone)
				{
					MaterialCatalog.MarkMaterialSourcesPending();
				}
				MelonCoroutines.Start(ActivateEditorScanCo());
				CinemachineBasicMultiChannelPerlin componentInChildren = ((Component)me.flyCam).GetComponentInChildren<CinemachineBasicMultiChannelPerlin>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					if (_noiseAmplitude < 0f)
					{
						_noiseAmplitude = componentInChildren.m_AmplitudeGain;
					}
					componentInChildren.m_AmplitudeGain = 0f;
				}
				return;
			}
			if ((Object)(object)LevelEditorManager.Instance != (Object)null)
			{
				PhysicsObjectManager.SetEditorModeActive(active: false);
			}
			CursorMode = false;
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			SetEditorPostProcessing(enabled: true);
			FreezePlayer(me, frozen: false);
			me.pm.SwitchToActiveMode();
			me.pm.SwitchModes();
			me.OnStandUp();
			LevelEditor.HideGizmo();
			LevelEditor.ClearRemoteSelectionBroadcast();
			FlyCamActive = false;
			_cutsceneSuppressUntil = Time.unscaledTime + 0.3f;
			if (_noiseAmplitude >= 0f)
			{
				CinemachineBasicMultiChannelPerlin componentInChildren2 = ((Component)me.flyCam).GetComponentInChildren<CinemachineBasicMultiChannelPerlin>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.m_AmplitudeGain = _noiseAmplitude;
				}
			}
		}

		private static IEnumerator ActivateEditorScanCo()
		{
			yield return null;
			GpuiPropScanner.ScanGpuiProps();
			yield return null;
			if (!_editorScanDone)
			{
				MaterialCatalog.InvalidateMaterialSources();
				_editorScanDone = true;
			}
		}

		private static void ToggleCursorMode()
		{
			CursorMode = !CursorMode;
			Cursor.lockState = (CursorLockMode)((!CursorMode) ? 1 : 2);
			Cursor.visible = CursorMode;
			if ((Object)(object)LevelEditorManager.Instance != (Object)null)
			{
				PhysicsObjectManager.SetEditorModeActive(CursorMode && FlyCamActive);
			}
			SetEditorPostProcessing(!CursorMode);
			if (!CursorMode)
			{
				LevelEditor.HideGizmo();
				LevelEditor.ClearRemoteSelectionBroadcast();
			}
		}

		private static void FreezePlayer(PlayerMovement player, bool frozen)
		{
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if (frozen)
			{
				if (!_freezeActive || !((Object)(object)_frozenPlayer == (Object)(object)player))
				{
					_frozenPlayer = player;
					_freezeActive = true;
					_movementWasEnabled = ((Behaviour)player).enabled;
					((Behaviour)player).enabled = false;
					_frozenController = ((Component)player).GetComponent<CharacterController>();
					if ((Object)(object)_frozenController != (Object)null)
					{
						_controllerWasEnabled = ((Collider)_frozenController).enabled;
						((Collider)_frozenController).enabled = false;
					}
					_frozenRigidbody = ((Component)player).GetComponent<Rigidbody>();
					if ((Object)(object)_frozenRigidbody != (Object)null)
					{
						_rigidbodyWasKinematic = _frozenRigidbody.isKinematic;
						_rigidbodyWasUseGravity = _frozenRigidbody.useGravity;
						_rigidbodyConstraints = _frozenRigidbody.constraints;
						_rigidbodyVelocity = _frozenRigidbody.velocity;
						_rigidbodyAngularVelocity = _frozenRigidbody.angularVelocity;
						_frozenRigidbody.velocity = Vector3.zero;
						_frozenRigidbody.angularVelocity = Vector3.zero;
						_frozenRigidbody.isKinematic = true;
						_frozenRigidbody.useGravity = false;
						_frozenRigidbody.constraints = (RigidbodyConstraints)126;
					}
					_frozenAnimator = player.anim;
					if ((Object)(object)_frozenAnimator != (Object)null)
					{
						_animatorSpeed = _frozenAnimator.speed;
						_frozenAnimator.speed = 0f;
					}
					Physics.SyncTransforms();
				}
			}
			else if (_freezeActive && !((Object)(object)_frozenPlayer != (Object)(object)player))
			{
				if ((Object)(object)_frozenAnimator != (Object)null)
				{
					_frozenAnimator.speed = _animatorSpeed;
				}
				if ((Object)(object)_frozenRigidbody != (Object)null)
				{
					_frozenRigidbody.constraints = _rigidbodyConstraints;
					_frozenRigidbody.isKinematic = _rigidbodyWasKinematic;
					_frozenRigidbody.useGravity = _rigidbodyWasUseGravity;
					_frozenRigidbody.velocity = _rigidbodyVelocity;
					_frozenRigidbody.angularVelocity = _rigidbodyAngularVelocity;
				}
				if ((Object)(object)_frozenController != (Object)null)
				{
					((Collider)_frozenController).enabled = _controllerWasEnabled;
				}
				((Behaviour)player).enabled = _movementWasEnabled;
				_freezeActive = false;
				_frozenPlayer = null;
				_frozenController = null;
				_frozenRigidbody = null;
				_frozenAnimator = null;
			}
		}

		public static void HandleFarTeleport()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (Menu.me.teleporting || _farTeleportActive)
			{
				return;
			}
			PlayerMovement me = PlayerMovement.me;
			if (!((Object)(object)me == (Object)null))
			{
				Ray val = Camera.main.ScreenPointToRay(new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f));
				RaycastHit val2 = default(RaycastHit);
				if (Physics.Raycast(val, ref val2, 1000f, LayerMask.op_Implicit(LayerCache.PropTerrainMask)))
				{
					_farTeleportActive = true;
					MelonCoroutines.Start(FlyCamTeleportCo(me, ((RaycastHit)(ref val2)).point));
				}
			}
		}

		private static IEnumerator FlyCamTeleportCo(PlayerMovement player, Vector3 target)
		{
			//IL_000e: 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)
			BestRegionLoader brl = BestRegionLoader.me;
			if (!BaseMapController.BaseMapEnabled && (Object)(object)brl != (Object)null && brl.off)
			{
				brl.off = false;
			}
			FreezePlayer(player, frozen: false);
			float facingY = ((Component)player.flyCam).transform.eulerAngles.y;
			((Component)player.anim).transform.rotation = Quaternion.Euler(0f, facingY, 0f);
			player.pm.SwitchToActiveMode();
			player.pm.SwitchModes();
			((Component)player).gameObject.SetActive(false);
			GameObject crestWater = null;
			if (!BaseMapController.BaseMapEnabled)
			{
				GameObject bigManager = GameObject.Find("BigManagerPrefab");
				object obj;
				if (bigManager == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = bigManager.transform.Find("CrestWaterRenderer");
					obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				}
				crestWater = (GameObject)obj;
				if ((Object)(object)crestWater != (Object)null && !crestWater.activeSelf)
				{
					crestWater.SetActive(true);
				}
				else
				{
					crestWater = null;
				}
			}
			if ((Object)(object)brl != (Object)null && brl.chunkPositions != null && !brl.off)
			{
				Transform anchor = TeleportLoadAnchor;
				anchor.position = target;
				brl.loadingTransform = anchor;
				Il2CppStructArray<Vector3> chunkPositions = brl.chunkPositions;
				Vector3[] prevPositions = (Vector3[])(object)new Vector3[((Il2CppArrayBase<Vector3>)(object)chunkPositions).Length];
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < ((Il2CppArrayBase<Vector3>)(object)chunkPositions).Length; j++)
					{
						prevPositions[j] = ((Il2CppArrayBase<Vector3>)(object)chunkPositions)[j];
					}
					brl.Update();
					bool changed = false;
					for (int k = 0; k < ((Il2CppArrayBase<Vector3>)(object)chunkPositions).Length; k++)
					{
						if (((Il2CppArrayBase<Vector3>)(object)chunkPositions)[k] != prevPositions[k])
						{
							changed = true;
							break;
						}
					}
					if (!changed)
					{
						break;
					}
				}
			}
			SaveGod.me.stopSaving = true;
			SaveGod.theSave.continuePt = target;
			Menu.me.Teleport(target, false);
			float waitStart = Time.unscaledTime;
			bool slWasTrue = false;
			float slStuckSince = 0f;
			bool targetLoaded = false;
			while (Menu.me.teleporting)
			{
				float elapsed = Time.unscaledTime - waitStart;
				if (BestRegionLoader.somebodyLoading)
				{
					if (!slWasTrue)
					{
						slWasTrue = true;
						slStuckSince = Time.unscaledTime;
					}
					else if (Time.unscaledTime - slStuckSince > 5f)
					{
						BestRegionLoader.somebodyLoading = false;
						slWasTrue = false;
					}
				}
				else
				{
					slWasTrue = false;
				}
				if (!targetLoaded && elapsed >= 1f)
				{
					Vector3 origin = new Vector3(target.x, target.y + 100f, target.z);
					if (Physics.Raycast(origin, Vector3.down, 300f, LayerMask.op_Implicit(LayerCache.PropTerrainMask)))
					{
						targetLoaded = true;
					}
				}
				if (targetLoaded || elapsed > 60f)
				{
					if (elapsed > 60f && !targetLoaded)
					{
						MelonLogger.Warning("[FarTeleport] 60s with no terrain hit — forcing anyway");
					}
					BestRegionLoader.fullyLoaded = true;
				}
				yield return null;
			}
			if ((Object)(object)crestWater != (Object)null && !BaseMapController.BaseMapEnabled)
			{
				crestWater.SetActive(false);
			}
			SaveGod.me.stopSaving = false;
			if ((Object)(object)brl != (Object)null)
			{
				brl.loadingTransform = ((Component)player.flyCam).transform;
			}
			FreezePlayer(player, frozen: true);
			if (((Component)player).gameObject.activeInHierarchy && player.torsoRbs != null && ((Il2CppArrayBase<Rigidbody>)(object)player.torsoRbs).Length > 0)
			{
				float playerY = ((Component)((Il2CppArrayBase<Rigidbody>)(object)player.torsoRbs)[0]).transform.position.y;
				Vector3 camPos = ((Component)player.flyCam).transform.position;
				Vector3 camToTarget = target - camPos;
				float camDist = ((Vector3)(ref camToTarget)).magnitude;
				RaycastHit verifyHit = default(RaycastHit);
				if (camDist > 0.1f && Physics.Raycast(camPos, camToTarget / camDist, ref verifyHit, camDist + 100f, LayerMask.op_Implicit(LayerCache.PropTerrainMask)))
				{
					float delta = Mathf.Abs(playerY - ((RaycastHit)(ref verifyHit)).point.y);
					if (delta > 3f)
					{
						Vector3 corrected = ((RaycastHit)(ref verifyHit)).point;
						FreezePlayer(player, frozen: false);
						((Component)player).gameObject.SetActive(false);
						if (!BaseMapController.BaseMapEnabled && (Object)(object)crestWater != (Object)null)
						{
							crestWater.SetActive(true);
						}
						SaveGod.theSave.continuePt = corrected;
						Menu.me.Teleport(corrected, false);
						float corrStart = Time.unscaledTime;
						while (Menu.me.teleporting)
						{
							BestRegionLoader.fullyLoaded = true;
							if (Time.unscaledTime - corrStart > 10f)
							{
								MelonLogger.Warning("[FarTeleport] Correction teleport stuck 10s — forcing");
								BestRegionLoader.fullyLoaded = true;
							}
							yield return null;
						}
						if (!BaseMapController.BaseMapEnabled && (Object)(object)crestWater != (Object)null)
						{
							crestWater.SetActive(false);
						}
						if ((Object)(object)brl != (Object)null)
						{
							brl.loadingTransform = ((Component)player.flyCam).transform;
						}
						FreezePlayer(player, frozen: true);
					}
				}
			}
			MaterialVariantTracker.InvalidateMaterialCache();
			MaterialCatalog.EnsureMaterialListLoaded();
			MaterialCatalog.ReapplyAllMaterialOverrides();
			if (!BaseMapController.BaseMapEnabled)
			{
				BaseMapController.SetEditorPropsSnowDisabled(disable: true);
			}
			_farTeleportActive = false;
		}
	}
	internal static class GhostCubeConfig
	{
		private static Material _frameMaterial;

		public static void Configure(GameObject go)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			foreach (MeshRenderer componentsInChild in go.GetComponentsInChildren<MeshRenderer>(true))
			{
				((Renderer)componentsInChild).forceRenderingOff = true;
				((Renderer)componentsInChild).enabled = false;
			}
			BuildFrame(go);
			BoxCollider val = go.GetComponent<BoxCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = go.AddComponent<BoxCollider>();
			}
			val.center = Vector3.zero;
			val.size = Vector3.one;
			((Collider)val).isTrigger = true;
			if ((Object)(object)go.GetComponent<GhostCollisionCutter>() == (Object)null)
			{
				go.AddComponent<GhostCollisionCutter>();
			}
		}

		internal static void BuildFrame(GameObject root)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Expected O, but got Unknown
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Expected O, but got Unknown
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Material frameMaterial = GetFrameMaterial();
			if (!((Object)(object)frameMaterial == (Object)null))
			{
				(Vector3, Vector3)[] array = new(Vector3, Vector3)[12]
				{
					(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f)),
					(new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, 0.5f)),
					(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(-0.5f, -0.5f, 0.5f)),
					(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, -0.5f, -0.5f)),
					(new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f)),
					(new Vector3(0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, 0.5f)),
					(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f)),
					(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, -0.5f)),
					(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, 0.5f, -0.5f)),
					(new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f)),
					(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f)),
					(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f))
				};
				Transform val = root.transform.Find("GhostFrame");
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				GameObject val2 = new GameObject("GhostFrame");
				val2.transform.SetParent(root.transform, false);
				val2.layer = root.layer;
				for (int i = 0; i < array.Length; i++)
				{
					GameObject val3 = new GameObject($"Edge_{i}");
					val3.transform.SetParent(val2.transform, false);
					val3.layer = root.layer;
					LineRenderer val4 = val3.AddComponent<LineRenderer>();
					val4.useWorldSpace = false;
					val4.positionCount = 2;
					val4.SetPosition(0, array[i].Item1);
					val4.SetPosition(1, array[i].Item2);
					val4.startWidth = 0.01f;
					val4.endWidth = 0.01f;
					val4.numCapVertices = 0;
					val4.numCornerVertices = 0;
					val4.alignment = (LineAlignment)0;
					((Renderer)val4).material = frameMaterial;
					val4.startColor = new Color(1f, 0.95f, 0.3f, 0.9f);
					val4.endColor = new Color(1f, 0.95f, 0.3f, 0.9f);
				}
			}
		}

		private static Material GetFrameMaterial()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0062: Expected O, but got Unknown
			if ((Object)(object)_frameMaterial != (Object)null)
			{
				return _frameMaterial;
			}
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard");
			_frameMaterial = new Material(val)
			{
				name = "BabyBlocks_GhostFrame",
				renderQueue = 5000
			};
			return _frameMaterial;
		}
	}
	public class GhostCollisionCutter : MonoBehaviour
	{
		private struct CarvedTerrainState
		{
			public TerrainData originalData;

			public Array originalHoles;

			public int xBase;

			public int yBase;

			public int width;

			public int height;

			public string carveKey;

			public bool IsValid => (Object)(object)originalData != (Object)null && originalHoles != null;
		}

		private static readonly Dictionary<Terrain, CarvedTerrainState> _carvedTerrains = new Dictionary<Terrain, CarvedTerrainState>();

		private static readonly List<GhostCollisionCutter> _instances = new List<GhostCollisionCutter>();

		private BoxCollider _volume;

		private const float PositionTolerance = 0.01f;

		private const float AngleTolerance = 0.05f;

		private bool _hasLastCarvePose;

		private Vector3 _lastCenter;

		private Vector3 _lastHalfExtents;

		private Quaternion _lastRotation;

		private string _lastCarveKey;

		private Transform _frameRoot;

		public GhostCollisionCutter(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			_volume = ((Component)this).GetComponent<BoxCollider>();
			if ((Object)(object)_volume != (Object)null)
			{
				((Collider)_volume).isTrigger = true;
			}
			_frameRoot = ((Component)this).transform.Find("GhostFrame");
		}

		private void OnEnable()
		{
			_instances.Add(this);
			Refresh();
		}

		private void FixedUpdate()
		{
			Refresh();
		}

		private void Update()
		{
			UpdateFrameVisibility();
		}

		private void OnDisable()
		{
			_instances.Remove(this);
			ReleaseAll();
		}

		private void OnDestroy()
		{
			_instances.Remove(this);
			ReleaseAll();
		}

		private void UpdateFrameVisibility()
		{
			if ((Object)(object)_frameRoot == (Object)null)
			{
				_frameRoot = ((Component)this).transform.Find("GhostFrame");
			}
			if (!((Object)(object)_frameRoot == (Object)null))
			{
				bool flag = FlyCamController.FlyCamActive && FlyCamController.CursorMode;
				if (((Component)_frameRoot).gameObject.activeSelf != flag)
				{
					((Component)_frameRoot).gameObject.SetActive(flag);
				}
			}
		}

		private void Refresh()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_volume == (Object)null)
			{
				_volume = ((Component)this).GetComponent<BoxCollider>();
			}
			if (!((Object)(object)_volume == (Object)null) && ((Component)this).gameObject.activeInHierarchy)
			{
				Vector3 lossyScale = ((Component)this).transform.lossyScale;
				Vector3 val = ((Component)this).transform.TransformPoint(_volume.center);
				Vector3 val2 = Vector3.Scale(_volume.size * 0.5f, new Vector3(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z)));
				Quaternion rotation = ((Component)this).transform.rotation;
				string debouncedCarveKey = GetDebouncedCarveKey(val, val2, rotation);
				RefreshTerrains(debouncedCarveKey, val, rotation, val2);
			}
		}

		private void RefreshTerrains(string carveKey, Vector3 cutterCenter, Quaternion cutterRotation, Vector3 cutterHalfExtents)
		{
			//IL_004e: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Il2CppReferenceArray<Terrain> activeTerrains = Terrain.activeTerrains;
			if (activeTerrains == null)
			{
				return;
			}
			HashSet<Terrain> hashSet = new HashSet<Terrain>();
			for (int i = 0; i < ((Il2CppArrayBase<Terrain>)(object)activeTerrains).Length; i++)
			{
				Terrain val = ((Il2CppArrayBase<Terrain>)(object)activeTerrains)[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.terrainData == (Object)null) && CutterOverlapsTerrainBounds(val, cutterCenter, cutterRotation, cutterHalfExtents))
				{
					hashSet.Add(val);
					ApplyTerrainCarve(val, carveKey, cutterCenter, cutterRotation, cutterHalfExtents);
				}
			}
			if (_carvedTerrains.Count == 0)
			{
				return;
			}
			List<Terrain> list = new List<Terrain>();
			foreach (KeyValuePair<Terrain, CarvedTerrainState> carvedTerrain in _carvedTerrains)
			{
				if (!hashSet.Contains(carvedTerrain.Key))
				{
					list.Add(carvedTerrain.Key);
				}
			}
			foreach (Terrain item in list)
			{
				RestoreTerrain(item);
			}
		}

		private static bool CutterOverlapsTerrainBounds(Terrain terrain, Vector3 cutterCenter, Quaternion cutterRotation, Vector3 cutterHalfExtents)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_001e: 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)
			//IL_0040: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)terrain).transform;
			Vector3 size = terrain.terrainData.size;
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			int num = 0;
			Vector3 val = default(Vector3);
			for (int i = -1; i <= 1; i += 2)
			{
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						((Vector3)(ref val))..ctor(cutterHalfExtents.x * (float)i, cutterHalfExtents.y * (float)j, cutterHalfExtents.z * (float)k);
						Vector3 val2 = cutterCenter + cutterRotation * val;
						array[num++] = transform.InverseTransformPoint(val2);
					}
				}
			}
			float num2 = array[0].x;
			float num3 = array[0].x;
			float num4 = array[0].z;
			float num5 = array[0].z;
			for (int l = 1; l < array.Length; l++)
			{
				num2 = Mathf.Min(num2, array[l].x);
				num3 = Mathf.Max(num3, array[l].x);
				num4 = Mathf.Min(num4, array[l].z);
				num5 = Mathf.Max(num5, array[l].z);
			}
			return num3 >= 0f && num5 >= 0f && num2 <= size.x && num4 <= size.z;
		}

		private void ReleaseAll()
		{
			_hasLastCarvePose = false;
			if (_carvedTerrains.Count <= 0)
			{
				return;
			}
			List<Terrain> list = new List<Terrain>(_carvedTerrains.Keys);
			foreach (Terrain item in list)
			{
				RestoreTerrain(item);
			}
		}

		private void ApplyTerrainCarve(Terrain terrain, string carveKey, Vector3 cutterCenter, Quaternion cutterRotation, Vector3 cutterHalfExtents)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)terrain == (Object)null || (Object)(object)terrain.terrainData == (Object)null)
			{
				return;
			}
			TerrainData terrainData = terrain.terrainData;
			int holesResolution = terrainData.holesResolution;
			if (holesResolution <= 0)
			{
				return;
			}
			CarvedTerrainState value;
			bool flag = _carvedTerrains.TryGetValue(terrain, out value);
			bool flag2 = flag && IsSameNativeObject((Il2CppObjectBase)(object)value.originalData, (Il2CppObjectBase)(object)terrainData);
			if (!flag || !value.IsValid || !flag2)
			{
				value = new CarvedTerrainState
				{
					originalData = terrainData,
					originalHoles = terrainData.GetHoles(0, 0, holesResolution, holesResolution).Cast<Array>()
				};
			}
			if (!string.IsNullOrEmpty(value.carveKey) && string.Equals(value.carveKey, carveKey, StringComparison.Ordinal))
			{
				return;
			}
			if (!string.IsNullOrEmpty(value.carveKey))
			{
				RestoreTerrain(terrain, value);
			}
			if (!TryBuildTerrainHolePatch(terrain, terrainData, value.originalHoles, cutterCenter, cutterRotation, cutterHalfExtents, out var xBase, out var yBase, out var holes))
			{
				if (flag)
				{
					value.carveKey = null;
					value.xBase = (value.yBase = (value.width = (value.height = 0)));
					_carvedTerrains[terrain] = value;
				}
			}
			else
			{
				terrainData.SetHoles(xBase, yBase, (Il2CppObjectBase)(object)holes);
				value.xBase = xBase;
				value.yBase = yBase;
				value.width = holes.GetLength(1);
				value.height = holes.GetLength(0);
				value.carveKey = carveKey;
				_carvedTerrains[terrain] = value;
			}
		}

		private void RestoreTerrain(Terrain terrain)
		{
			if (!((Object)(object)terrain == (Object)null) && _carvedTerrains.TryGetValue(terrain, out var value) && value.IsValid)
			{
				RestoreTerrain(terrain, value);
				_carvedTerrains.Remove(terrain);
			}
		}

		private static void RestoreTerrain(Terrain terrain, CarvedTerrainState state)
		{
			if (!((Object)(object)terrain == (Object)null) && state.IsValid)
			{
				Array val = ExtractTerrainPatch(state.originalHoles, state.xBase, state.yBase, state.width, state.height);
				if (val != null)
				{
					state.originalData.SetHoles(state.xBase, state.yBase, (Il2CppObjectBase)(object)val);
				}
			}
		}

		private static bool TryBuildTerrainHolePatch(Terrain terrain, TerrainData data, Array originalHoles, Vector3 cutterCenter, Quaternion cutterRotation, Vector3 cutterHalfExtents, out int xBase, out int yBase, out Array holes)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00c3: 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)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			xBase = 0;
			yBase = 0;
			holes = null;
			if ((Object)(object)terrain == (Object)null || (Object)(object)data == (Object)null || originalHoles == null)
			{
				return false;
			}
			int holesResolution = data.holesResolution;
			if (holesResolution <= 0)
			{
				return false;
			}
			Transform transform = ((Component)terrain).transform;
			Vector3 size = data.size;
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			int num = 0;
			Vector3 val = default(Vector3);
			for (int i = -1; i <= 1; i += 2)
			{
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						((Vector3)(ref val))..ctor(cutterHalfExtents.x * (float)i, cutterHalfExtents.y * (float)j, cutterHalfExtents.z * (float)k);
						Vector3 val2 = cutterCenter + cutterRotation * val;
						array[num++] = transform.InverseTransformPoint(val2);
					}
				}
			}
			float num2 = array[0].x;
			float num3 = array[0].x;
			float num4 = array[0].z;
			float num5 = array[0].z;
			for (int l = 1; l < array.Length; l++)
			{
				num2 = Mathf.Min(num2, array[l].x);
				num3 = Mathf.Max(num3, array[l].x);
				num4 = Mathf.Min(num4, array[l].z);
				num5 = Mathf.Max(num5, array[l].z);
			}
			if (num3 < 0f || num5 < 0f || num2 > size.x || num4 > size.z)
			{
				return false;
			}
			num2 = Mathf.Clamp(num2, 0f, size.x);
			num3 = Mathf.Clamp(num3, 0f, size.x);
			num4 = Mathf.Clamp(num4, 0f, size.z);
			num5 = Mathf.Clamp(num5, 0f, size.z);
			int num6 = Mathf.Clamp(Mathf.FloorToInt(num2 / size.x * (float)(holesResolution - 1)), 0, holesResolution - 1);
			int num7 = Mathf.Clamp(Mathf.CeilToInt(num3 / size.x * (float)(holesResolution - 1)), 0, holesResolution - 1);
			int num8 = Mathf.Clamp(Mathf.FloorToInt(num4 / size.z * (float)(holesResolution - 1)), 0, holesResolution - 1);
			int num9 = Mathf.Clamp(Mathf.CeilToInt(num5 / size.z * (float)(holesResolution - 1)), 0, holesResolution - 1);
			int num10 = num7 - num6 + 1;
			int num11 = num9 - num8 + 1;
			if (num10 <= 0 || num11 <= 0)
			{
				return false;
			}
			xBase = num6;
			yBase = num8;
			holes = Array.CreateInstance(Il2CppType.Of<bool>(), new Il2CppStructArray<long>(new long[2] { num11, num10 }));
			Quaternion val3 = Quaternion.Inverse(cutterRotation);
			int num12 = Mathf.Max(holesResolution - 1, 1);
			bool flag = false;
			Vector3 val4 = default(Vector3);
			for (int m = 0; m < num11; m++)
			{
				for (int n = 0; n < num10; n++)
				{
					int num13 = num6 + n;
					int num14 = num8 + m;
					float num15 = (float)num13 / (float)num12;
					float num16 = (float)num14 / (float)num12;
					float interpolatedHeight = data.GetInterpolatedHeight(num15, num16);
					((Vector3)(ref val4))..ctor(num15 * size.x, interpolatedHeight, num16 * size.z);
					Vector3 val5 = transform.TransformPoint(val4);
					Vector3 local = val3 * (val5 - cutterCenter);
					bool flag2 = PointInsideBox(local, cutterHalfExtents);
					if (flag2)
					{
						flag = true;
					}
					holes.SetValue(flag2 ? Object.op_Implicit(false) : originalHoles.GetValue(num14, num13), m, n);
				}
			}
			if (!flag)
			{
				holes = null;
				return false;
			}
			return true;
		}

		private static Array ExtractTerrainPatch(Array source, int xBase, int yBase, int width, int height)
		{
			if (source == null || width <= 0 || height <= 0)
			{
				return null;
			}
			Array val = Array.CreateInstance(Il2CppType.Of<bool>(), new Il2CppStructArray<long>(new long[2] { height, width }));
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					val.SetValue(source.GetValue(yBase + i, xBase + j), i, j);
				}
			}
			return val;
		}

		private static bool IsSameNativeObject(Il2CppObjectBase a, Il2CppObjectBase b)
		{
			if (a == null || b == null)
			{
				return false;
			}
			return a.Pointer == b.Pointer;
		}

		private static string BuildCarveKey(Vector3 center, Vector3 half, Quaternion rot)
		{
			//IL_000d: 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)
			//IL_004d: 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_008d: 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_00cd: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			return $"{center.x:F3},{center.y:F3},{center.z:F3}|{half.x:F3},{half.y:F3},{half.z:F3}|{rot.x:F3},{rot.y:F3},{rot.z:F3},{rot.w:F3}";
		}

		private string GetDebouncedCarveKey(Vector3 center, Vector3 halfExtents, Quaternion rotation)
		{
			//IL_0009: 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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0057: 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)
			//IL_0060: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			if (_hasLastCarvePose && Vector3.Distance(center, _lastCenter) <= 0.01f && Vector3.Distance(halfExtents, _lastHalfExtents) <= 0.01f && Quaternion.Angle(rotation, _lastRotation) <= 0.05f)
			{
				return _lastCarveKey;
			}
			string lastCarveKey = BuildCarveKey(center, halfExtents, rotation);
			_lastCenter = center;
			_lastHalfExtents = halfExtents;
			_lastRotation = rotation;
			_lastCarveKey = lastCarveKey;
			_hasLastCarvePose = true;
			return _lastCarveKey;
		}

		private static bool PointInsideBox(Vector3 local, Vector3 half)
		{
			//IL_0000: 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)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Abs(local.x) <= half.x && Mathf.Abs(local.y) <= half.y && Mathf.Abs(local.z) <= half.z;
		}
	}
	internal static class SpawnPointConfig
	{
		private static Material _frameMaterial;

		private static readonly Color MarkerColor = new Color(0.3f, 1f, 0.45f, 0.9f);

		public static void Configure(GameObject go)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			foreach (MeshRenderer componentsInChild in go.GetComponentsInChildren<MeshRenderer>(true))
			{
				((Renderer)componentsInChild).forceRenderingOff = true;
				((Renderer)componentsInChild).enabled = false;
			}
			BuildMarker(go);
			BoxCollider val = go.GetComponent<BoxCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = go.AddComponent<BoxCollider>();
			}
			val.center = new Vector3(0f, 0.9f, 0f);
			val.size = new Vector3(0.8f, 1.8f, 0.8f);
			((Collider)val).isTrigger = true;
			if ((Object)(object)go.GetComponent<SpawnPointMarker>() == (Object)null)
			{
				go.AddComponent<SpawnPointMarker>();
			}
		}

		internal static void BuildMarker(GameObject root)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Material frameMaterial = GetFrameMaterial();
			if (!((Object)(object)frameMaterial == (Object)null))
			{
				Transform val = root.transform.Find("SpawnFrame");
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				GameObject val2 = new GameObject("SpawnFrame");
				val2.transform.SetParent(root.transform, false);
				val2.layer = root.layer;
				Vector3[] array = (Vector3[])(object)new Vector3[24];
				for (int i = 0; i < 24; i++)
				{
					float num = (float)i / 24f * (float)Math.PI * 2f;
					array[i] = new Vector3(Mathf.Cos(num) * 0.4f, 0.02f, Mathf.Sin(num) * 0.4f);
				}
				AddLineLoop(val2, "Ring", array, frameMaterial, loop: true);
				AddLine(val2, "Pole", frameMaterial, new Vector3(0f, 0f, 0f), new Vector3(0f, 1.8f, 0f));
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(0f, 0.05f, 0.7f);
				AddLine(val2, "ArrowShaft", frameMaterial, new Vector3(0f, 0.05f, 0f), val3);
				AddLine(val2, "ArrowHeadL", frameMaterial, val3, val3 + Quaternion.Euler(0f, 150f, 0f) * Vector3.forward * 0.18f);
				AddLine(val2, "ArrowHeadR", frameMaterial, val3, val3 + Quaternion.Euler(0f, -150f, 0f) * Vector3.forward * 0.18f);
			}
		}

		private static void AddLine(GameObject parent, string name, Material mat, Vector3 a, Vector3 b)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent.transform, false);
			val.layer = parent.layer;
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.useWorldSpace = false;
			val2.positionCount = 2;
			val2.SetPosition(0, a);
			val2.SetPosition(1, b);
			val2.startWidth = 0.015f;
			val2.endWidth = 0.015f;
			val2.numCapVertices = 0;
			val2.numCornerVertices = 0;
			val2.alignment = (LineAlignment)0;
			((Renderer)val2).material = mat;
			val2.startColor = MarkerColor;
			val2.endColor = MarkerColor;
		}

		private static void AddLineLoop(GameObject parent, string name, Vector3[] points, Material mat, bool loop)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent.transform, false);
			val.layer = parent.layer;
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.useWorldSpace = false;
			val2.loop = loop;
			val2.positionCount = points.Length;
			val2.SetPositions(Il2CppStructArray<Vector3>.op_Implicit(points));
			val2.startWidth = 0.015f;
			val2.endWidth = 0.015f;
			val2.numCapVertices = 0;
			val2.numCornerVertices = 0;
			val2.alignment = (LineAlignment)0;
			((Renderer)val2).material = mat;
			val2.startColor = MarkerColor;
			val2.endColor = MarkerColor;
		}

		private static Material GetFrameMaterial()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0062: Expected O, but got Unknown
			if ((Object)(object)_frameMaterial != (Object)null)
			{
				return _frameMaterial;
			}
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard");
			_frameMaterial = new Material(val)
			{
				name = "BabyBlocks_SpawnFrame",
				renderQueue = 5000
			};
			return _frameMaterial;
		}
	}
	public class SpawnPointMarker : MonoBehaviour
	{
		private Transform _frameRoot;

		public SpawnPointMarker(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			_frameRoot = ((Component)this).transform.Find("SpawnFrame");
		}

		private void Update()
		{
			if ((Object)(object)_frameRoot == (Object)null)
			{
				_frameRoot = ((Component)this).transform.Find("SpawnFrame");
			}
			if (!((Object)(object)_frameRoot == (Object)null))
			{
				bool flag = FlyCamController.FlyCamActive && FlyCamController.CursorMode;
				if (((Component)_frameRoot).gameObject.activeSelf != flag)
				{
					((Component)_frameRoot).gameObject.SetActive(flag);
				}
			}
		}
	}
	internal static class GizmoRenderer
	{
		private struct MeshData
		{
			public Vector3[] verts;

			public int[] tris;

			public Vector3[] smoothNormals;
		}

		private struct OutlineShellData
		{
			public int meshId;

			public Vector3 position;

			public Quaternion rotation;

			public Vector3 scale;

			public float thickness;

			public Vector3[] worldVerts;

			public int[] tris;

			public Mesh mesh;
		}

		public const int Layer = 31;

		public static readonly int Mask = int.MinValue;

		public const int FreeRotateAxis = 7;

		public const float FreeRotSphereDrawScale = 0.85f;

		private const float RingOuterRadius = 0.65f;

		private const float RingInnerRadius = 0.5f;

		private const float RingPickPadding = 0.05f;

		public static readonly Quaternion[] PivotRots = (Quaternion[])(object)new Quaternion[3]
		{
			Quaternion.Euler(0f, 0f, -90f),
			Quaternion.identity,
			Quaternion.Euler(-90f, 0f, 0f)
		};

		private static readonly Quaternion[] RingPivotRots = (Quaternion[])(object)new Quaternion[3]
		{
			Quaternion.Euler(0f, 0f, -90f),
			Quaternion.identity,
			Quaternion.Euler(90f, 0f, 0f)
		};

		private static readonly Vector3 ShaftPos = new Vector3(0f, 0.25f, 0f);

		private static readonly Vector3 ShaftScale = new Vector3(0.05f, 0.25f, 0.05f);

		private static readonly Vector3 TipPos = new Vector3(0f, 0.5f, 0f);

		private static readonly Vector3 TipScale = new Vector3(0.14f, 0.2f, 0.14f);

		private static readonly Vector3 ScaleTipPos = new Vector3(0f, 0.55f, 0f);

		private static readonly Vector3 ScaleTipScale = new Vector3(0.16f, 0.16f, 0.16f);

		private static readonly float PlaneSizeMove = 0.2625f;

		private static readonly float PlaneSizeScale = 0.3f;

		private static readonly float PlaneThickness = 0.03f;

		private static Mesh _shaftMesh;

		private static Mesh _coneTipMesh;

		private static Mesh _cubeTipMesh;

		private static Mesh _sphereMesh;

		private static Mesh _ringMesh;

		private static Material[] _mats;

		private static Material[] _hoverMats;

		private static Material[] _planeMats;

		private static Material[] _planeHoverMats;

		private static Material _freeMat;

		private static Material _freeHoverMat;

		private static Material _freeRotMat;

		private static Material _freeRotHoverMat;

		private static Material[] _occMats;

		private static Material[] _planeOccMats;

		private static Material _freeOccMat;

		public static float OutlineThickness = 0.03f;

		public static float OutlineOccludedAlpha = 0.35f;

		public static float OutlineWidth = 2f;

		private static Material _stencilClearMat;

		private static Material _stencilMarkMat;

		private static Material _outlineMat;

		private static Material _outlineOccMat;

		private static CommandBuffer _outlineBuffer;

		private static Camera _outlineCameraTarget;

		private static CommandBuffer _gizmoZTestBuffer;

		private static Material _maskMat;

		private static Material _ppMat;

		private static Material _depthCaptureMat;

		private static RenderTexture _depthCopyRT;

		private static CommandBuffer _depthCaptureBuffer;

		private static Camera _depthCaptureCameraTarget;

		private static readonly int _maskRTId = Shader.PropertyToID("_BabyBlocks_SelectionMaskRT");

		private static readonly int _depthCopyTexId = Shader.PropertyToID("_BabyBlocksDepthCopy");

		private static CommandBuffer _ssBuffer;

		private static Camera _ssCameraTarget;

		private static IReadOnlyList<LevelEditorObject> _ssLastSelection;

		private static readonly List<(Color color, IReadOnlyList<LevelEditorObject> targets)> _ssRemoteHighlights = new List<(Color, IReadOnlyList<LevelEditorObject>)>();

		private static readonly List<MaterialPropertyBlock> _ssRemoteMpbPool = new List<MaterialPropertyBlock>();

		private static bool _outlineTranslateDrag;

		private static Vector3 _outlineTranslateDelta;

		private static readonly Dictionary<Mesh, MeshData> _meshDataCache = new Dictionary<Mesh, MeshData>();

		private static readonly Dictionary<int, OutlineShellData> _outlineShellCache = new Dictionary<int, OutlineShellData>();

		private static Mesh _combinedOutlineShell;

		private static int _combinedOutlineSignature;

		private static readonly List<CombineInstance> _combinedOutlineCombines = new List<CombineInstance>();

		private static readonly List<(Mesh mesh, Matrix4x4 matrix, int subMeshCount)> _outlineMarks = new List<(Mesh, Matrix4x4, int)>();

		private static readonly List<Mesh> _remoteOutlineShells = new List<Mesh>();

		private static readonly List<(Mesh mesh, Matrix4x4 matrix, int subMeshCount)> _remoteOutlineMarks = new List<(Mesh, Matrix4x4, int)>();

		private static GameObject _root;

		private static GameObject _arrowHandles;

		private static GameObject _ringHandles;

		private static Camera _overlayCam;

		private static Vector3 _pivotPos;

		private static bool _pivotOverrideActive;

		private static Vector3 _pivotOverride;

		private static readonly Quaternion FlipArrowQ = Quaternion.Euler(180f, 0f, 0f);

		private static Transform[] _axisPivots = (Transform[])(object)new Transform[3];

		private static Transform[] _planeHandles = (Transform[])(object)new Transform[3];

		private static bool[] _axisFlipped = new bool[3];

		private static GizmoHandle[] _ringHandleRefs = new GizmoHandle[3];

		private const float MaxPlausibleBoundsExtent = 100f;

		public static bool HasRemoteHighlights => _ssRemoteHighlights.Count > 0;

		public static bool ScreenSpaceShadersLoaded => (Object)(object)_maskMat != (Object)null && (Object)(object)_ppMat != (Object)null;

		public static bool IsReady => (Object)(object)_root != (Object)null && (Object)(object)_overlayCam != (Object)null;

		public static Vector3 PivotPosition => _pivotPos;

		public static bool StencilMaterialsReady => (Object)(object)_stencilClearMat != (Object)null && (Object)(object)_stencilMarkMat != (Object)null;

		public static void ClearRemoteHighlights()
		{
			_ssRemoteHighlights.Clear();
		}

		public static void AddRemoteHighlight(Color color, IReadOnlyList<LevelEditorObject> targets)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (targets != null && targets.Count > 0)
			{
				_ssRemoteHighlights.Add((color, targets));
			}
		}

		public static void SetTranslateDragDelta(Vector3 delta)
		{
			//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)
			_outlineTranslateDrag = true;
			_outlineTranslateDelta = delta;
		}

		public static void ClearDragDelta()
		{
			_outlineTranslateDrag = false;
		}

		public static Quaternion GetEffectivePivotRot(int i)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			return (i >= 0 && i < 3 && _axisFlipped[i]) ? (PivotRots[i] * FlipArrowQ) : PivotRots[i];
		}

		public static void SetPivotOverride(Vector3 pivot)
		{
			//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)
			_pivotOverrideActive = true;
			_pivotOverride = pivot;
		}

		public static void ClearPivotOverride()
		{
			_pivotOverrideActive = false;
		}

		public static void Init()
		{
			InitMeshes();
			InitMaterials();
			BuildColliders();
			_overlayCam = BuildCam(100f, 500000f, (CameraClearFlags)3);
			AttachGizmoZTestBuffer(_overlayCam);
			LoadScreenSpaceShaders();
		}

		public static void Sync(IReadOnlyList<LevelEditorObject> selection, LevelEditorObject primary, LevelEditor.ToolMode tool, Camera mainCam)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root == (Object)null)
			{
				return;
			}
			bool flag = selection != null && selection.Count > 0;
			_root.SetActive(flag);
			if ((Object)(object)_overlayCam != (Object)null)
			{
				((Behaviour)_overlayCam).enabled = flag || _ssRemoteHighlights.Count > 0;
			}
			if (!flag)
			{
				return;
			}
			_pivotPos = (_pivotOverrideActive ? _pivotOverride : GetSelectionBoundsCenter(selection));
			_root.transform.position = _pivotPos;
			Quaternion rotation;
			if ((!LevelEditor.LocalMode && tool != LevelEditor.ToolMode.Scale) || !((Object)(object)primary != (Object)null))
			{
				rotation = Quaternion.identity;
			}
			else if (primary.groupId > 0)
			{
				GameObject groupRoot = GroupManager.GetGroupRoot(primary.groupId);
				rotation = ((groupRoot != null) ? groupRoot.transform.rotation : Quaternion.identity);
			}
			else
			{
				rotation = ((Component)primary).transform.rotation;
			}
			_root.transform.rotation = rotation;
			float num = Vector3.Distance(((Component)mainCam).transform.position, _root.transform.position);
			_root.transform.localScale = Vector3.one * Mathf.Max(num * 0.14f, 0.02f);
			bool flag2 = tool == LevelEditor.ToolMode.Rotate;
			if ((Object)(object)_arrowHandles != (Object)null)
			{
				_arrowHandles.SetActive(!flag2);
			}
			if ((Object)(object)_ringHandles != (Object)null)
			{
				_ringHandles.SetActive(flag2);
			}
			for (int i = 0; i < 3; i++)
			{
				if (!flag2 && (Object)(object)_axisPivots[i] != (Object)null)
				{
					Vector3 val = _root.transform.rotation * (PivotRots[i] * Vector3.up);
					_axisFlipped[i] = Vector3.Dot(val, ((Component)mainCam).transform.position - _pivotPos) < 0f;
					_axisPivots[i].localRotation = GetEffectivePivotRot(i);
					continue;
				}
				_axisFlipped[i] = false;
				if ((Object)(object)_axisPivots[i] != (Object)null)
				{
					_axisPivots[i].localRotation = PivotRots[i];
				}
			}
			for (int j = 0; j < 3; j++)
			{
				if (!((Object)(object)_planeHandles[j] == (Object)null))
				{
					int num2 = j switch
					{
						1 => 1, 
						0 => 0, 
						_ => 0, 
					};
					int num3 = j switch
					{
						1 => 2, 
						0 => 1, 
						_ => 2, 
					};
					float num4 = (_axisFlipped[num2] ? (-1f) : 1f);
					float num5 = (_axisFlipped[num3] ? (-1f) : 1f);
					Vector3 val2 = PivotRots[num2] * Vector3.up * num4;
					Vector3 val3 = PivotRots[num3] * Vector3.up * num5;
					_planeHandles[j].localPosition = (val2 + val3) * PlaneSizeMove * 0.5f;
				}
			}
			SyncCamToMain(_overlayCam, mainCam);
		}

		private static void SyncCamToMain(Camera cam, Camera mainCam)
		{
			//IL_001a: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)cam == (Object)null))
			{
				((Component)cam).transform.SetPositionAndRotation(((Component)mainCam).transform.position, ((Component)mainCam).transform.rotation);
				cam.fieldOfView = mainCam.fieldOfView;
				cam.aspect = mainCam.aspect;
				cam.nearClipPlane = mainCam.nearClipPlane;
				cam.rect = mainCam.rect;
			}
		}

		public static void EnsureCamera()
		{
			if ((Object)(object)_root != (Object)null && (Object)(object)_overlayCam == (Object)null)
			{
				_overlayCam = BuildCam(100f, 500000f, (CameraClearFlags)3);
				_gizmoZTestBuffer = null;
				AttachGizmoZTestBuffer(_overlayCam);
			}
		}

		private static void AttachGizmoZTestBuffer(Camera cam)
		{
			//IL_001b: Unknown result type (might be due to 

Mods/BabyStepsMenuLib.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using Il2Cpp;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
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(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Caleb Orchard")]
[assembly: AssemblyConfiguration("Retail - Debug")]
[assembly: AssemblyDescription("A reusable menu injection library for Baby Steps MelonLoader mods.")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+11a490c829d6b67512aa6da54556de709c4ef3c3")]
[assembly: AssemblyProduct("BabyStepsMenuLib")]
[assembly: AssemblyTitle("BabyStepsMenuLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/caleborchard/BabyStepsMenuLib")]
[assembly: NeutralResourcesLanguage("en-US")]
[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 BabyStepsMenuLib
{
	public static class MenuInjectionLibrary
	{
		public sealed class RuntimeTabMenu
		{
			private readonly string[] _tabNames;

			private readonly List<Selectable>[] _pageSelectables;

			private int _setTabFrame = -1;

			private Selectable[] _fixedItems;

			public RectTransform Root { get; internal set; }

			public RectTransform Header { get; internal set; }

			public Button[] Tabs { get; internal set; }

			public RectTransform[] Pages { get; internal set; }

			public int ActiveTab { get; private set; }

			public int TabCount
			{
				get
				{
					Button[] tabs = Tabs;
					return (tabs != null) ? tabs.Length : 0;
				}
			}

			internal MenuItemList ManagedItemList { get; set; }

			internal Color NativeHighlightedColor { get; set; } = TabHighlighted;

			internal void SetFixedMenuItems(params Selectable[] items)
			{
				_fixedItems = items;
			}

			internal RuntimeTabMenu(string[] tabNames)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				_tabNames = tabNames;
				_pageSelectables = new List<Selectable>[tabNames.Length];
				for (int i = 0; i < tabNames.Length; i++)
				{
					_pageSelectables[i] = new List<Selectable>();
				}
			}

			public RectTransform GetPage(int index)
			{
				return (Pages != null && index >= 0 && index < Pages.Length) ? Pages[index] : null;
			}

			public void UpdateTabName(int index, string name)
			{
				if (_tabNames != null && index >= 0 && index < _tabNames.Length)
				{
					_tabNames[index] = name;
				}
			}

			public void OnShown()
			{
				SetActiveTab(ActiveTab);
			}

			internal void RegisterPageSelectable(int page, Selectable s)
			{
				if (!((Object)(object)s == (Object)null) && _pageSelectables != null && page >= 0 && page < _pageSelectables.Length)
				{
					_pageSelectables[page].Add(s);
				}
			}

			public void SetActiveTab(int index)
			{
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				//IL_0213: Unknown result type (might be due to invalid IL or missing references)
				//IL_0218: Unknown result type (might be due to invalid IL or missing references)
				//IL_021c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: Unknown result type (might be due to invalid IL or missing references)
				//IL_0235: Unknown result type (might be due to invalid IL or missing references)
				//IL_0243: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Unknown result type (might be due to invalid IL or missing references)
				//IL_026e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
				if (Tabs == null || Pages == null || index < 0 || index >= TabCount)
				{
					return;
				}
				int frameCount = Time.frameCount;
				if (frameCount == _setTabFrame)
				{
					return;
				}
				_setTabFrame = frameCount;
				ActiveTab = index;
				List<Selectable>[] pageSelectables = _pageSelectables;
				List<Selectable> list = ((pageSelectables != null) ? pageSelectables[index] : null);
				for (int i = 0; i < TabCount; i++)
				{
					bool flag = i == index;
					if ((Object)(object)Pages[i] != (Object)null)
					{
						CanvasGroup component = ((Component)Pages[i]).GetComponent<CanvasGroup>();
						if ((Object)(object)component != (Object)null)
						{
							component.alpha = (flag ? 1f : 0f);
							component.interactable = flag;
							component.blocksRaycasts = flag;
						}
						if (flag)
						{
							Il2CppArrayBase<TMP_Text> componentsInChildren = ((Component)Pages[i]).GetComponentsInChildren<TMP_Text>(true);
							for (int j = 0; j < componentsInChildren.Length; j++)
							{
								if ((Object)(object)componentsInChildren[j] != (Object)null)
								{
									componentsInChildren[j].ForceMeshUpdate(false, false);
								}
							}
						}
					}
					if (!((Object)(object)Tabs[i] != (Object)null))
					{
						continue;
					}
					Color val = (flag ? TabSelected : TabUnselected);
					Image component2 = ((Component)Tabs[i]).GetComponent<Image>();
					if ((Object)(object)component2 != (Object)null)
					{
						((Graphic)component2).color = Color.white;
						((Graphic)component2).CrossFadeColor(val, 0f, true, true);
					}
					TMP_Text componentInChildren = ((Component)Tabs[i]).GetComponentInChildren<TMP_Text>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						if (_tabNames != null && i < _tabNames.Length)
						{
							componentInChildren.text = _tabNames[i];
						}
						((Graphic)componentInChildren).color = TabText;
						componentInChildren.ForceMeshUpdate(false, false);
					}
					ColorBlock colors = ((Selectable)Tabs[i]).colors;
					((ColorBlock)(ref colors)).normalColor = val;
					((ColorBlock)(ref colors)).selectedColor = NativeHighlightedColor;
					((ColorBlock)(ref colors)).highlightedColor = NativeHighlightedColor;
					((ColorBlock)(ref colors)).pressedColor = NativeHighlightedColor;
					((ColorBlock)(ref colors)).disabledColor = val;
					((ColorBlock)(ref colors)).colorMultiplier = 1f;
					((Selectable)Tabs[i]).colors = colors;
				}
				int num = list?.Count ?? 0;
				Selectable[] fixedItems = _fixedItems;
				int num2 = ((fixedItems != null) ? fixedItems.Length : 0);
				List<Selectable> list2 = new List<Selectable>(num + num2);
				for (int k = 0; k < num; k++)
				{
					if ((Object)(object)list[k] != (Object)null)
					{
						list2.Add(list[k]);
					}
				}
				for (int l = 0; l < num2; l++)
				{
					if ((Object)(object)_fixedItems[l] != (Object)null)
					{
						list2.Add(_fixedItems[l]);
					}
				}
				if ((Object)(object)ManagedItemList != (Object)null)
				{
					GameObject[] array = (GameObject[])(object)new GameObject[list2.Count];
					for (int m = 0; m < list2.Count; m++)
					{
						array[m] = ((Component)list2[m]).gameObject;
					}
					ManagedItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit(array);
				}
				for (int n = 0; n < list2.Count; n++)
				{
					Selectable val2 = list2[n];
					Navigation navigation = val2.navigation;
					navigation.mode = (Mode)4;
					navigation.selectOnUp = ((n > 0) ? list2[n - 1] : null);
					navigation.selectOnDown = ((n < list2.Count - 1) ? list2[n + 1] : null);
					navigation.selectOnLeft = null;
					navigation.selectOnRight = null;
					val2.navigation = navigation;
				}
			}
		}

		public sealed class TabBuilder
		{
			internal TabBuilder()
			{
			}

			public TMP_Text AddLabel(string text)
			{
				return MenuInjectionLibrary.AddLabel(text, (RectTransform)null);
			}

			public Button AddButton(string text, UnityAction onClick)
			{
				return MenuInjectionLibrary.AddButton(text, onClick, (RectTransform)null);
			}

			public Toggle AddToggle(string text, bool initial, UnityAction<bool> onChange)
			{
				return MenuInjectionLibrary.AddToggle(text, initial, onChange, (RectTransform)null);
			}

			public Slider AddSlider(string text, float min, float max, float value, UnityAction<float> onChange, bool wholeNumbers = false)
			{
				return MenuInjectionLibrary.AddSlider(text, min, max, value, onChange, wholeNumbers, (RectTransform)null);
			}

			public Button AddInputField(string placeholder = "", UnityAction<string> onChange = null, string initialValue = null)
			{
				return MenuInjectionLibrary.AddInputField(placeholder, onChange, initialValue, (RectTransform)null);
			}

			public Image AddImage(Color color, float height = 52f)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return MenuInjectionLibrary.AddImage(color, height, (RectTransform)null);
			}
		}

		public sealed class MenuBuilder
		{
			internal readonly string _mainButtonLabel;

			internal readonly List<(string name, Action<TabBuilder> configure)> _tabs = new List<(string, Action<TabBuilder>)>();

			internal readonly List<(string label, UnityAction action)> _fixed = new List<(string, UnityAction)>();

			internal float _sideMargin;

			internal float _topMargin;

			internal MenuBuilder(string mainButtonLabel)
			{
				_mainButtonLabel = mainButtonLabel;
			}

			public MenuBuilder AddTab(string name, Action<TabBuilder> configure)
			{
				_tabs.Add((name, configure));
				return this;
			}

			public MenuBuilder AddFixedButton(string label, UnityAction action = null)
			{
				_fixed.Add((label, action));
				return this;
			}

			public MenuBuilder WithMargin(float sideMargin, float topMargin)
			{
				_sideMargin = sideMargin;
				_topMargin = topMargin;
				return this;
			}

			public InjectedMenu Build()
			{
				InjectedMenu injectedMenu = new InjectedMenu(this);
				if (!_registeredMenus.Contains(injectedMenu))
				{
					_registeredMenus.Add(injectedMenu);
				}
				return injectedMenu;
			}
		}

		public sealed class InputFieldInfo
		{
			public string Value = "";

			public TMP_Text DisplayText;

			public UnityAction<string> OnChanged;

			public string Placeholder = "";

			public RectTransform Viewport;

			public Color ActiveColor = Color.white;

			public Color PlaceholderColor = new Color(1f, 1f, 1f, 0.45f);

			public Button OwnerButton;

			public Image CursorImage;
		}

		public sealed class InjectedMenu
		{
			private readonly string _mainButtonLabel;

			private readonly List<(string name, Action<TabBuilder> configure)> _tabDescs;

			private readonly List<(string label, UnityAction action)> _fixedDescs;

			private Menu _activeMenu;

			private RuntimeTabMenu _tabMenu;

			private bool _contentBuilt;

			private bool _hasAttemptedInitialDump;

			private GameObject _mainButtonObj;

			private Button _mainButton;

			private Transform _mainMenuRoot;

			private CanvasGroup _mainMenuCG;

			private MenuItemList _mainMenuItemList;

			private GameObject _submenuObj;

			private CanvasGroup _submenuCG;

			private MenuItemList _submenuItemList;

			private readonly List<Button> _fixedButtonInstances = new List<Button>();

			private GameObject _kbRoot;

			private CanvasGroup _kbCG;

			private Button[][] _kbCharRows;

			private string[][] _kbLowerRows;

			private string[][] _kbUpperRows;

			private Button[] _kbSpecialRow;

			private readonly List<GameObject> _kbAllButtons = new List<GameObject>();

			private bool _kbShift;

			private bool _kbUseLowercaseFontForKeyLabels;

			private Button _kbShiftBtn;

			private InputFieldInfo _kbActiveField;

			private Button _kbReturnButton;

			private Action _kbOnDone;

			private bool _kbBuilt;

			private GameObject[] _savedSubmenuItems;

			private bool _kbHasEdited;

			private int _kbNavFrame = -1;

			private float _kbCursorTimer = 0f;

			private bool _kbCursorVisible = true;

			private InputFieldInfo _mouseTypingField;

			private bool _mouseTypingActive;

			private int _mouseTypingNavFrame = -1;

			private int _mouseCursorBlinkFrame = -1;

			private bool _mouseHasEdited;

			private float _mouseCursorTimer = 0f;

			private bool _mouseCursorVisible = true;

			private bool _kbUsingOverlay;

			private const float CanvasW = 860f;

			private const float CanvasH = 650f;

			private const float ContentH = 460f;

			private const float ContentPad = 10f;

			private readonly float _sideMargin;

			private readonly float _topMargin;

			private RectTransform _submenuRect;

			private string[] _currentTabNames;

			private readonly string _tag;

			internal bool IsMouseTyping => _mouseTypingActive;

			internal bool KbVisible => (Object)(object)_kbCG != (Object)null && _kbCG.alpha > 0.5f;

			internal Transform GameCanvasTransform => ((Object)(object)_kbRoot != (Object)null && !_kbUsingOverlay) ? _kbRoot.transform.parent : null;

			internal Transform KbRootTransform
			{
				get
				{
					GameObject kbRoot = _kbRoot;
					return (kbRoot != null) ? kbRoot.transform : null;
				}
			}

			public bool IsKeyboardOpen => _kbActiveField != null;

			private bool IsKbButton(GameObject go)
			{
				return (Object)(object)go != (Object)null && _kbAllButtons.Contains(go);
			}

			private static string MakeTag(string label)
			{
				if (string.IsNullOrEmpty(label))
				{
					return "Menu";
				}
				StringBuilder stringBuilder = new StringBuilder(label.Length);
				foreach (char c in label)
				{
					stringBuilder.Append(char.IsLetterOrDigit(c) ? c : '_');
				}
				string text = stringBuilder.ToString().Trim('_');
				return (text.Length > 0) ? text : "Menu";
			}

			internal InjectedMenu(MenuBuilder b)
			{
				_mainButtonLabel = b._mainButtonLabel;
				_tabDescs = b._tabs;
				_fixedDescs = b._fixed;
				_sideMargin = b._sideMargin;
				_topMargin = b._topMargin;
				_tag = MakeTag(b._mainButtonLabel);
				_currentTabNames = new string[b._tabs.Count];
				for (int i = 0; i < b._tabs.Count; i++)
				{
					_currentTabNames[i] = b._tabs[i].name;
				}
			}

			public Button GetFixedButton(int index)
			{
				return (index >= 0 && index < _fixedButtonInstances.Count) ? _fixedButtonInstances[index] : null;
			}

			public Button GetTab(int index)
			{
				return (_tabMenu?.Tabs != null && index >= 0 && index < _tabMenu.Tabs.Length) ? _tabMenu.Tabs[index] : null;
			}

			public void SetMainButtonLabel(string label)
			{
				if (!((Object)(object)_mainButtonObj == (Object)null))
				{
					TMP_Text componentInChildren = _mainButtonObj.GetComponentInChildren<TMP_Text>(true);
					if (!((Object)(object)componentInChildren == (Object)null))
					{
						componentInChildren.text = label;
						componentInChildren.ForceMeshUpdate(false, false);
					}
				}
			}

			public void SetTabName(int index, string name)
			{
				if (index < 0)
				{
					return;
				}
				if (_currentTabNames != null && index < _currentTabNames.Length)
				{
					_currentTabNames[index] = name;
				}
				_tabMenu?.UpdateTabName(index, name);
				if (_tabMenu?.Tabs != null && index < _tabMenu.Tabs.Length)
				{
					Button val = _tabMenu.Tabs[index];
					if ((Object)(object)val != (Object)null)
					{
						SetButtonLabel(((Component)val).gameObject, name);
					}
				}
			}

			public void OnMenuAwake(Menu menu)
			{
				_activeMenu = menu;
				TryInject(menu, "Awake");
			}

			public void OnMenuPreUpdate(Menu menu)
			{
				//IL_058f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0595: Invalid comparison between Unknown and I4
				_activeMenu = menu;
				if ((Object)(object)menu == (Object)null)
				{
					return;
				}
				if ((Object)(object)_mainButtonObj == (Object)null || (Object)(object)_submenuObj == (Object)null)
				{
					TryInject(menu, "PreUpdateRetry");
				}
				bool submenuVisible = GetSubmenuVisible();
				bool kbVisible = KbVisible;
				bool flag = IsCapturingKeybindProvider?.Invoke() ?? false;
				bool flag2 = IsOverlayBlockingMenuProvider?.Invoke() ?? false;
				if (kbVisible)
				{
					HandleKeyboardInput(menu, flag, submenuVisible);
				}
				if (submenuVisible && !kbVisible && !flag)
				{
					if (_mouseTypingActive && _mouseTypingField != null && Time.frameCount != _mouseTypingNavFrame)
					{
						_mouseTypingNavFrame = Time.frameCount;
						bool flag3 = false;
						string inputString = Input.inputString;
						for (int i = 0; i < inputString.Length; i++)
						{
							char c = inputString[i];
							switch (c)
							{
							case '\b':
								if (_mouseTypingField.Value.Length > 0)
								{
									_mouseTypingField.Value = _mouseTypingField.Value.Substring(0, _mouseTypingField.Value.Length - 1);
									flag3 = true;
								}
								continue;
							default:
								if (c != '\n')
								{
									_mouseTypingField.Value += c;
									flag3 = true;
									continue;
								}
								break;
							case '\r':
								break;
							}
							_mouseTypingField.OnChanged?.Invoke(_mouseTypingField.Value);
							CloseMouseTyping(restoreSelection: false);
							flag3 = false;
							break;
						}
						if (Input.GetKeyDown((KeyCode)27) && _mouseTypingActive)
						{
							CloseMouseTyping();
							flag3 = false;
						}
						if (Input.GetMouseButtonDown(0) && _mouseTypingActive && (Object)(object)_mouseTypingField?.OwnerButton != (Object)null && !IsPointerOverGameObject(((Component)_mouseTypingField.OwnerButton).gameObject))
						{
							CloseMouseTyping(restoreSelection: false);
							flag3 = false;
						}
						if (flag3 && _mouseTypingField != null)
						{
							_mouseHasEdited = true;
							RefreshMouseTypingDisplay();
							_mouseTypingField.OnChanged?.Invoke(_mouseTypingField.Value);
						}
					}
					if (_mouseTypingActive && (Object)(object)_mouseTypingField?.DisplayText != (Object)null && Time.frameCount != _mouseCursorBlinkFrame)
					{
						_mouseCursorBlinkFrame = Time.frameCount;
						_mouseCursorTimer += Time.unscaledDeltaTime;
						if (_mouseCursorTimer >= 0.53f)
						{
							_mouseCursorTimer = 0f;
							_mouseCursorVisible = !_mouseCursorVisible;
							RefreshMouseTypingDisplay();
						}
					}
					if (!flag2)
					{
						TryHandleCancel(menu);
						if (_tabMenu != null && menu.rwPlayer != null)
						{
							if (menu.rwPlayer.GetButtonDown(18))
							{
								_tabMenu.SetActiveTab((_tabMenu.ActiveTab - 1 + _tabMenu.TabCount) % _tabMenu.TabCount);
							}
							else if (menu.rwPlayer.GetButtonDown(17))
							{
								_tabMenu.SetActiveTab((_tabMenu.ActiveTab + 1) % _tabMenu.TabCount);
							}
						}
					}
				}
				if (kbVisible)
				{
					if (submenuVisible && (Object)(object)_submenuItemList != (Object)null && !flag2)
					{
						MenuItemList.active = _submenuItemList;
					}
				}
				else if (submenuVisible && flag2)
				{
					GameObject[] overlayNavigableItems = OverlayNavigableItems;
					if ((Object)(object)_submenuItemList != (Object)null && overlayNavigableItems != null && overlayNavigableItems.Length != 0)
					{
						if (_savedSubmenuItems == null)
						{
							_savedSubmenuItems = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)_submenuItemList.items);
						}
						_submenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit(overlayNavigableItems);
						MenuItemList.active = _submenuItemList;
					}
					else
					{
						MenuItemList.active = null;
					}
				}
				else if (submenuVisible && !flag2)
				{
					if ((Object)(object)_submenuItemList != (Object)null && _savedSubmenuItems != null)
					{
						_submenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit(_savedSubmenuItems);
						_savedSubmenuItems = null;
					}
					if ((Object)(object)_submenuItemList != (Object)null)
					{
						MenuItemList.active = _submenuItemList;
					}
					if (_mouseTypingActive && (Object)(object)_mouseTypingField?.OwnerButton != (Object)null && (Object)(object)_submenuItemList != (Object)null)
					{
						_submenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit((GameObject[])(object)new GameObject[1] { ((Component)_mouseTypingField.OwnerButton).gameObject });
					}
				}
				else if ((int)menu.currentMenuScreen == 0 && (Object)(object)_mainMenuItemList != (Object)null)
				{
					MenuItemList.active = _mainMenuItemList;
				}
			}

			private void HandleKeyboardInput(Menu menu, bool isCapturingKeybind, bool submenuVisible)
			{
				EventSystem current = EventSystem.current;
				GameObject val = ((current != null) ? current.currentSelectedGameObject : null);
				if (((Object)(object)val == (Object)null || !IsKbButton(val)) && _kbCharRows != null && _kbCharRows.Length != 0)
				{
					val = ((Component)_kbCharRows[0][0]).gameObject;
					if (current != null)
					{
						current.SetSelectedGameObject(val);
					}
				}
				if (!isCapturingKeybind && Time.frameCount != _kbNavFrame)
				{
					_kbNavFrame = Time.frameCount;
					if ((Object)(object)val != (Object)null && IsKbButton(val) && menu.rwPlayer != null)
					{
						float axis = menu.rwPlayer.GetAxis(12);
						float axisPrev = menu.rwPlayer.GetAxisPrev(12);
						float axis2 = menu.rwPlayer.GetAxis(13);
						float axisPrev2 = menu.rwPlayer.GetAxisPrev(13);
						Selectable component = val.GetComponent<Selectable>();
						Selectable val2 = null;
						if (axis2 < -0.5f && axisPrev2 >= -0.5f)
						{
							val2 = ((component != null) ? component.navigation.selectOnDown : null);
						}
						else if (axis2 > 0.5f && axisPrev2 <= 0.5f)
						{
							val2 = ((component != null) ? component.navigation.selectOnUp : null);
						}
						else if (axis > 0.5f && axisPrev <= 0.5f)
						{
							val2 = ((component != null) ? component.navigation.selectOnRight : null);
						}
						else if (axis < -0.5f && axisPrev >= -0.5f)
						{
							val2 = ((component != null) ? component.navigation.selectOnLeft : null);
						}
						if ((Object)(object)val2 != (Object)null)
						{
							if (current != null)
							{
								current.SetSelectedGameObject(((Component)val2).gameObject);
							}
							val = ((Component)val2).gameObject;
						}
						if (_kbUsingOverlay && (Input.GetKeyDown((KeyCode)330) || Input.GetKeyDown((KeyCode)331)))
						{
							Button val3 = ((val != null) ? val.GetComponent<Button>() : null);
							if (val3 != null)
							{
								((UnityEvent)val3.onClick).Invoke();
							}
						}
					}
					if (menu.rwPlayer != null && (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)332) || menu.rwPlayer.GetButtonDown(15)))
					{
						CloseKeyboardOverlay((Object)(object)_kbReturnButton == (Object)null && _kbOnDone != null);
					}
					if ((Object)(object)_kbActiveField?.DisplayText != (Object)null)
					{
						_kbCursorTimer += Time.unscaledDeltaTime;
						if (_kbCursorTimer >= 0.53f)
						{
							_kbCursorTimer = 0f;
							_kbCursorVisible = !_kbCursorVisible;
							KbBlinkCursor();
						}
					}
				}
				if (submenuVisible && (Object)(object)_submenuItemList != (Object)null && (Object)(object)val != (Object)null)
				{
					_submenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit((GameObject[])(object)new GameObject[1] { val });
				}
			}

			public void OnMenuUpdate(Menu menu)
			{
				_activeMenu = menu;
				if (!((Object)(object)menu == (Object)null))
				{
					if (Input.GetKeyDown((KeyCode)290))
					{
						Reset();
						TryInject(menu, "Reinject_F9");
					}
					if ((Object)(object)_mainButtonObj == (Object)null || (Object)(object)_submenuObj == (Object)null)
					{
						TryInject(menu, "UpdateRetry");
					}
					UpdateVisibility(menu);
					EnsureSelection();
				}
			}

			private void TryInject(Menu menu, string reason)
			{
				if ((Object)(object)menu == (Object)null)
				{
					return;
				}
				ResolveExisting(menu);
				if (!_hasAttemptedInitialDump)
				{
					_hasAttemptedInitialDump = true;
				}
				if ((Object)(object)menu.mainMenuCanvas == (Object)null)
				{
					return;
				}
				Button val = FindTemplateButton(menu);
				if (!((Object)(object)val == (Object)null))
				{
					_mainMenuRoot = ((Component)val).transform.parent;
					if ((Object)(object)_mainMenuRoot != (Object)null)
					{
						_mainMenuCG = ((Component)_mainMenuRoot).GetComponent<CanvasGroup>() ?? ((Component)_mainMenuRoot).gameObject.AddComponent<CanvasGroup>();
						_mainMenuItemList = ((Component)_mainMenuRoot).GetComponent<MenuItemList>();
					}
					if ((Object)(object)_mainButtonObj == (Object)null)
					{
						_mainButtonObj = BuildMainButton(menu, val);
					}
					if ((Object)(object)_submenuObj == (Object)null)
					{
						_submenuObj = BuildSubmenu(menu, val);
					}
					IntegrateIntoMainItemList();
					EnsureTabContent(menu, val);
					UpdateVisibility(menu);
				}
			}

			private void EnsureTabContent(Menu menu, Button tmpl)
			{
				if (_contentBuilt || (Object)(object)_submenuObj == (Object)null)
				{
					return;
				}
				Transform obj = _submenuObj.transform.Find("CustomSettingsContentRoot");
				RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Button nativeTabSource = null;
				Menu me = Menu.me;
				if ((Object)(object)((me != null) ? me.tabs : null) != (Object)null)
				{
					Transform transform = ((Component)Menu.me.tabs).transform;
					for (int i = 0; i < transform.childCount; i++)
					{
						Transform child = transform.GetChild(i);
						Button val2 = ((child != null) ? ((Component)child).GetComponent<Button>() : null);
						if ((Object)(object)val2 != (Object)null)
						{
							nativeTabSource = val2;
							break;
						}
					}
				}
				string[] array = new string[_tabDescs.Count];
				for (int j = 0; j < _tabDescs.Count; j++)
				{
					array[j] = ((_currentTabNames != null && j < _currentTabNames.Length) ? _currentTabNames[j] : _tabDescs[j].name);
				}
				_tabMenu = BuildNativeTabMenu(array, val, nativeTabSource, tmpl);
				_tabMenu.ManagedItemList = _submenuItemList;
				Selectable[] array2 = (Selectable[])(object)new Selectable[_fixedButtonInstances.Count];
				for (int k = 0; k < _fixedButtonInstances.Count; k++)
				{
					array2[k] = (Selectable)(object)_fixedButtonInstances[k];
				}
				_tabMenu.SetFixedMenuItems(array2);
				Toggle toggle = FindToggleTemplate(menu);
				Slider slider = FindSliderTemplate(menu);
				TabBuilder obj2 = new TabBuilder();
				_currentInjectedMenu = this;
				for (int l = 0; l < _tabDescs.Count; l++)
				{
					ConfigureTabPage(_tabMenu, l, tmpl, toggle, slider);
					_tabDescs[l].configure?.Invoke(obj2);
				}
				_currentInjectedMenu = null;
				BuildKeyboard(menu, tmpl);
				_tabMenu.SetActiveTab(0);
				_contentBuilt = true;
			}

			private GameObject BuildMainButton(Menu menu, Button tmpl)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_015b: 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_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: 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)
				RectTransform component = ((Component)tmpl).GetComponent<RectTransform>();
				float num = Mathf.Max(45f, Mathf.Abs((component != null) ? component.sizeDelta.y : 52f) + 10f);
				float num2 = ((component != null) ? component.anchoredPosition.y : 0f) + num;
				Transform parent = ((Component)tmpl).transform.parent;
				if ((Object)(object)parent != (Object)null)
				{
					for (int i = 0; i < parent.childCount; i++)
					{
						Transform child = parent.GetChild(i);
						if (!((Object)(object)child == (Object)null) && ((Object)child).name.StartsWith("BBSMP_Btn_"))
						{
							RectTransform component2 = ((Component)child).GetComponent<RectTransform>();
							if ((Object)(object)component2 != (Object)null)
							{
								num2 = Mathf.Max(num2, component2.anchoredPosition.y + num);
							}
						}
					}
				}
				GameObject val = Object.Instantiate<GameObject>(((Component)tmpl).gameObject, ((Component)tmpl).transform.parent);
				((Object)val).name = "BBSMP_Btn_" + _tag;
				StripLocalizationComponents(val);
				val.transform.SetSiblingIndex(((Component)tmpl).transform.GetSiblingIndex() + 1);
				RectTransform component3 = val.GetComponent<RectTransform>();
				if ((Object)(object)component3 != (Object)null && (Object)(object)component != (Object)null)
				{
					component3.anchorMin = component.anchorMin;
					component3.anchorMax = component.anchorMax;
					component3.pivot = component.pivot;
					component3.sizeDelta = component.sizeDelta;
					((Transform)component3).localScale = Vector3.one;
					component3.anchoredPosition = new Vector2(component.anchoredPosition.x, num2);
				}
				_mainButton = val.GetComponent<Button>();
				ClearButtonEvents(_mainButton);
				Button mainButton = _mainButton;
				if (mainButton != null)
				{
					((UnityEvent)mainButton.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
					{
						List<InjectedMenu> registeredMenus = _registeredMenus;
						for (int j = 0; j < registeredMenus.Count; j++)
						{
							if (registeredMenus[j] != this)
							{
								registeredMenus[j].SetSubmenuVisible(isVisible: false);
							}
						}
						SetSubmenuVisible(isVisible: true);
					}));
				}
				TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.text = _mainButtonLabel;
					componentInChildren.ForceMeshUpdate(false, false);
				}
				return val;
			}

			private GameObject BuildSubmenu(Menu menu, Button tmpl)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Expected O, but got Unknown
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_019a: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0313: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = new GameObject("BBSMP_Sub_" + _tag);
				val.transform.SetParent(menu.mainMenuCanvas.transform, false);
				val.transform.SetAsLastSibling();
				RectTransform val2 = val.AddComponent<RectTransform>();
				val2.anchorMin = new Vector2(0f, 1f);
				val2.anchorMax = new Vector2(0f, 1f);
				val2.pivot = new Vector2(0f, 1f);
				val2.sizeDelta = new Vector2(860f, 650f);
				val2.anchoredPosition = new Vector2(10f, -10f);
				_submenuCG = val.AddComponent<CanvasGroup>();
				_submenuCG.alpha = 0f;
				_submenuCG.blocksRaycasts = false;
				_submenuCG.interactable = false;
				GameObject val3 = new GameObject("CustomSettingsContentRoot");
				val3.transform.SetParent(val.transform, false);
				RectTransform val4 = val3.AddComponent<RectTransform>();
				val4.anchorMin = new Vector2(0f, 1f);
				val4.anchorMax = new Vector2(0f, 1f);
				val4.pivot = new Vector2(0f, 1f);
				val4.sizeDelta = new Vector2(800f, 460f);
				val4.anchoredPosition = new Vector2(10f, -10f);
				RectTransform component = ((Component)tmpl).GetComponent<RectTransform>();
				float num = (((Object)(object)component != (Object)null) ? Mathf.Max(200f, component.sizeDelta.x) : 520f);
				float num2 = (((Object)(object)component != (Object)null) ? Mathf.Clamp(component.sizeDelta.y, 40f, 72f) : 52f);
				_fixedButtonInstances.Clear();
				for (int num3 = _fixedDescs.Count - 1; num3 >= 0; num3--)
				{
					(string label, UnityAction action) tuple = _fixedDescs[num3];
					string item = tuple.label;
					UnityAction item2 = tuple.action;
					GameObject val5 = Object.Instantiate<GameObject>(((Component)tmpl).gameObject, val.transform);
					((Object)val5).name = $"BBSMP_Fixed_{_tag}_{num3}";
					StripLocalizationComponents(val5);
					Button component2 = val5.GetComponent<Button>();
					ClearButtonEvents(component2);
					SetButtonLabel(val5, item);
					RectTransform component3 = val5.GetComponent<RectTransform>();
					component3.anchorMin = Vector2.zero;
					component3.anchorMax = Vector2.zero;
					component3.pivot = Vector2.zero;
					component3.sizeDelta = new Vector2(num, num2);
					int num4 = _fixedDescs.Count - 1 - num3;
					component3.anchoredPosition = new Vector2(10f, 10f + (float)num4 * (num2 + 10f));
					UnityAction capturedAction = item2;
					if (component2 != null)
					{
						((UnityEvent)component2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
						{
							UnityAction obj = capturedAction;
							if (obj != null)
							{
								obj.Invoke();
							}
							SetSubmenuVisible(isVisible: false);
						}));
					}
					_fixedButtonInstances.Insert(0, component2);
				}
				_submenuItemList = val.AddComponent<MenuItemList>();
				_submenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit((GameObject[])(object)new GameObject[0]);
				_submenuRect = val2;
				ApplyMargin();
				return val;
			}

			private void BuildKeyboard(Menu menu, Button tmpl, bool useLowercaseFontForLetterKeys = true)
			{
				//IL_0387: Unknown result type (might be due to invalid IL or missing references)
				//IL_0391: Expected O, but got Unknown
				//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0406: Unknown result type (might be due to invalid IL or missing references)
				//IL_0419: Unknown result type (might be due to invalid IL or missing references)
				//IL_0430: Unknown result type (might be due to invalid IL or missing references)
				//IL_045e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0602: Unknown result type (might be due to invalid IL or missing references)
				//IL_0619: Unknown result type (might be due to invalid IL or missing references)
				//IL_0630: Unknown result type (might be due to invalid IL or missing references)
				//IL_0644: Unknown result type (might be due to invalid IL or missing references)
				//IL_0662: Unknown result type (might be due to invalid IL or missing references)
				//IL_0882: Unknown result type (might be due to invalid IL or missing references)
				//IL_0899: Unknown result type (might be due to invalid IL or missing references)
				//IL_08b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_08d8: Unknown result type (might be due to invalid IL or missing references)
				if (_kbBuilt || (Object)(object)((menu != null) ? menu.mainMenuCanvas : null) == (Object)null || (Object)(object)tmpl == (Object)null)
				{
					return;
				}
				_kbUseLowercaseFontForKeyLabels = useLowercaseFontForLetterKeys;
				_kbLowerRows = new string[4][]
				{
					new string[11]
					{
						"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
						"."
					},
					new string[10] { "q", "w", "e", "r", "t", "y", "u", "i", "o", "p" },
					new string[9] { "a", "s", "d", "f", "g", "h", "j", "k", "l" },
					new string[7] { "z", "x", "c", "v", "b", "n", "m" }
				};
				_kbUpperRows = new string[4][]
				{
					new string[11]
					{
						"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
						"."
					},
					new string[10] { "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P" },
					new string[9] { "A", "S", "D", "F", "G", "H", "J", "K", "L" },
					new string[7] { "Z", "X", "C", "V", "B", "N", "M" }
				};
				int num = _kbLowerRows.Length + 1;
				float num2 = 20f + (float)num * 44f + (float)(num - 1) * 4f - 15f;
				float num3 = 780f;
				int num4 = 0;
				for (int i = 0; i < _kbLowerRows.Length; i++)
				{
					if (_kbLowerRows[i].Length > num4)
					{
						num4 = _kbLowerRows[i].Length;
					}
				}
				float num5 = (num3 - (float)(num4 - 1) * 6f) / (float)num4;
				_kbRoot = new GameObject("BBSMP_Keyboard_" + _tag);
				_kbRoot.transform.SetParent(menu.mainMenuCanvas.transform, false);
				_kbRoot.transform.SetAsLastSibling();
				RectTransform val = _kbRoot.AddComponent<RectTransform>();
				val.anchorMin = new Vector2(0.5f, 0f);
				val.anchorMax = new Vector2(0.5f, 0f);
				val.pivot = new Vector2(0.5f, 0f);
				val.sizeDelta = new Vector2(800f, num2);
				val.anchoredPosition = new Vector2(0f, 100f);
				Image val2 = _kbRoot.AddComponent<Image>();
				((Graphic)val2).color = new Color(0.05f, 0.11f, 0.18f, 0.97f);
				_kbCG = _kbRoot.AddComponent<CanvasGroup>();
				_kbCG.alpha = 0f;
				_kbCG.interactable = false;
				_kbCG.blocksRaycasts = false;
				_kbCharRows = new Button[_kbLowerRows.Length][];
				float num6 = -10f;
				for (int j = 0; j < _kbLowerRows.Length; j++)
				{
					int num7 = _kbLowerRows[j].Length;
					float num8 = num5;
					float num9 = (float)num7 * num8 + (float)(num7 - 1) * 6f;
					float num10 = (0f - num9) * 0.5f;
					_kbCharRows[j] = (Button[])(object)new Button[num7];
					for (int k = 0; k < num7; k++)
					{
						int capturedRow = j;
						int capturedCol = k;
						GameObject val3 = Object.Instantiate<GameObject>(((Component)tmpl).gameObject, _kbRoot.transform);
						((Object)val3).name = "BBSMP_Key_" + _kbUpperRows[j][k];
						StripLocalizationComponents(val3);
						Button component = val3.GetComponent<Button>();
						ClearButtonEvents(component);
						if ((Object)(object)component != (Object)null)
						{
							((UnityEvent)component.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
							{
								KbType(capturedRow, capturedCol);
							}));
						}
						SetButtonLabel(val3, _kbLowerRows[j][k], _kbUseLowercaseFontForKeyLabels);
						TMP_Text componentInChildren = val3.GetComponentInChildren<TMP_Text>(true);
						if ((Object)(object)componentInChildren != (Object)null)
						{
							componentInChildren.fontSize = 20f;
						}
						RectTransform component2 = val3.GetComponent<RectTransform>();
						component2.anchorMin = new Vector2(0.5f, 1f);
						component2.anchorMax = new Vector2(0.5f, 1f);
						component2.pivot = new Vector2(0f, 1f);
						component2.sizeDelta = new Vector2(num8, 44f);
						component2.anchoredPosition = new Vector2(num10 + (float)k * (num8 + 6f), num6);
						_kbCharRows[j][k] = component;
						_kbAllButtons.Add(val3);
					}
					num6 -= 48f;
				}
				float num11 = num3 - 216f - 18f;
				float[] obj = new float[4] { 72f, 0f, 72f, 72f };
				obj[1] = num11;
				float[] array = obj;
				string[] array2 = new string[4] { "Shift", "Space", "Back", "Done" };
				_kbSpecialRow = (Button[])(object)new Button[4];
				float num12 = (0f - num3) * 0.5f;
				for (int num13 = 0; num13 < 4; num13++)
				{
					GameObject val4 = Object.Instantiate<GameObject>(((Component)tmpl).gameObject, _kbRoot.transform);
					((Object)val4).name = "BBSMP_Key_" + array2[num13];
					StripLocalizationComponentsImmediate(val4);
					Button component3 = val4.GetComponent<Button>();
					ClearButtonEvents(component3);
					if ((Object)(object)component3 != (Object)null)
					{
						switch (num13)
						{
						case 0:
							((UnityEvent)component3.onClick).AddListener(UnityAction.op_Implicit((Action)KbToggleShift));
							_kbShiftBtn = component3;
							break;
						case 1:
							((UnityEvent)component3.onClick).AddListener(UnityAction.op_Implicit((Action)KbSpace));
							break;
						case 2:
							((UnityEvent)component3.onClick).AddListener(UnityAction.op_Implicit((Action)KbBackspace));
							break;
						case 3:
							((UnityEvent)component3.onClick).AddListener(UnityAction.op_Implicit((Action)KbDone));
							break;
						}
					}
					SetButtonLabel(val4, array2[num13]);
					TMP_Text componentInChildren2 = val4.GetComponentInChildren<TMP_Text>(true);
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						componentInChildren2.fontSize = 20f;
					}
					RectTransform component4 = val4.GetComponent<RectTransform>();
					component4.anchorMin = new Vector2(0.5f, 1f);
					component4.anchorMax = new Vector2(0.5f, 1f);
					component4.pivot = new Vector2(0f, 1f);
					component4.sizeDelta = new Vector2(array[num13], 44f);
					component4.anchoredPosition = new Vector2(num12, num6);
					num12 += array[num13] + 6f;
					_kbSpecialRow[num13] = component3;
					_kbAllButtons.Add(val4);
				}
				WireKeyboardNavigation();
				ForceKeyboardFontSizes();
				MelonCoroutines.Start(EnforceKeyboardFontSizesCoroutine());
				_kbBuilt = true;
			}

			private void WireKeyboardNavigation()
			{
				//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_002c: Expected O, but got Unknown
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_0180: Expected O, but got Unknown
				for (int i = 0; i < _kbCharRows.Length; i++)
				{
					int num = _kbCharRows[i].Length;
					for (int j = 0; j < num; j++)
					{
						Navigation val = new Navigation
						{
							mode = (Mode)0
						};
						val.selectOnLeft = (Selectable)(object)((j > 0) ? _kbCharRows[i][j - 1] : null);
						val.selectOnRight = (Selectable)(object)((j < num - 1) ? _kbCharRows[i][j + 1] : null);
						val.selectOnUp = (Selectable)(object)((i > 0) ? _kbCharRows[i - 1][Mathf.Min(j, _kbCharRows[i - 1].Length - 1)] : null);
						if (i < _kbCharRows.Length - 1)
						{
							val.selectOnDown = (Selectable)(object)_kbCharRows[i + 1][Mathf.Min(j, _kbCharRows[i + 1].Length - 1)];
						}
						else
						{
							int num2 = Mathf.Clamp(j * _kbSpecialRow.Length / _kbCharRows[i].Length, 0, _kbSpecialRow.Length - 1);
							val.selectOnDown = (Selectable)(object)_kbSpecialRow[num2];
						}
						((Selectable)_kbCharRows[i][j]).navigation = val;
					}
				}
				int num3 = _kbCharRows.Length - 1;
				int num4 = _kbCharRows[num3].Length;
				for (int k = 0; k < _kbSpecialRow.Length; k++)
				{
					Navigation val2 = new Navigation
					{
						mode = (Mode)0
					};
					val2.selectOnLeft = (Selectable)(object)((k > 0) ? _kbSpecialRow[k - 1] : null);
					val2.selectOnRight = (Selectable)(object)((k < _kbSpecialRow.Length - 1) ? _kbSpecialRow[k + 1] : null);
					val2.selectOnDown = null;
					int num5 = Mathf.Clamp(k * num4 / _kbSpecialRow.Length, 0, num4 - 1);
					val2.selectOnUp = (Selectable)(object)_kbCharRows[num3][num5];
					((Selectable)_kbSpecialRow[k]).navigation = val2;
				}
			}

			private void KbType(int row, int col)
			{
				if (_kbActiveField != null)
				{
					string[][] array = (_kbShift ? _kbUpperRows : _kbLowerRows);
					_kbActiveField.Value += array[row][col];
					_kbHasEdited = true;
					KbRefreshDisplay();
					_kbActiveField.OnChanged?.Invoke(_kbActiveField.Value);
					if (_kbShift)
					{
						_kbShift = false;
						KbRefreshKeyLabels();
					}
				}
			}

			private void KbSpace()
			{
				if (_kbActiveField != null)
				{
					_kbActiveField.Value += " ";
					_kbHasEdited = true;
					KbRefreshDisplay();
					_kbActiveField.OnChanged?.Invoke(_kbActiveField.Value);
				}
			}

			private void KbBackspace()
			{
				if (_kbActiveField != null && _kbActiveField.Value.Length != 0)
				{
					_kbActiveField.Value = _kbActiveField.Value.Substring(0, _kbActiveField.Value.Length - 1);
					_kbHasEdited = true;
					KbRefreshDisplay();
					_kbActiveField.OnChanged?.Invoke(_kbActiveField.Value);
				}
			}

			private void KbToggleShift()
			{
				_kbShift = !_kbShift;
				KbRefreshKeyLabels();
			}

			private void KbRefreshKeyLabels()
			{
				if (_kbCharRows == null)
				{
					return;
				}
				string[][] array = (_kbShift ? _kbUpperRows : _kbLowerRows);
				for (int i = 0; i < _kbCharRows.Length; i++)
				{
					for (int j = 0; j < _kbCharRows[i].Length; j++)
					{
						SetButtonLabel(((Component)_kbCharRows[i][j]).gameObject, array[i][j], _kbUseLowercaseFontForKeyLabels);
					}
				}
				if ((Object)(object)_kbShiftBtn != (Object)null)
				{
					SetButtonLabel(((Component)_kbShiftBtn).gameObject, _kbShift ? "SHIFT" : "Shift");
					ForceKeyboardFontSize(((Component)_kbShiftBtn).gameObject);
				}
			}

			private void ForceKeyboardFontSizes()
			{
				if (_kbAllButtons.Count != 0)
				{
					for (int i = 0; i < _kbAllButtons.Count; i++)
					{
						ForceKeyboardFontSize(_kbAllButtons[i]);
					}
				}
			}

			private static void ForceKeyboardFontSize(GameObject keyObj)
			{
				if (!((Object)(object)keyObj == (Object)null))
				{
					TMP_Text componentInChildren = keyObj.GetComponentInChildren<TMP_Text>(true);
					if (!((Object)(object)componentInChildren == (Object)null))
					{
						componentInChildren.fontSize = 20f;
						componentInChildren.ForceMeshUpdate(false, false);
					}
				}
			}

			private IEnumerator EnforceKeyboardFontSizesCoroutine()
			{
				for (int i = 0; i < 3; i++)
				{
					ForceKeyboardFontSizes();
					yield return null;
				}
			}

			private void KbRefreshDisplay()
			{
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				InputFieldInfo kbActiveField = _kbActiveField;
				if (kbActiveField != null && !((Object)(object)kbActiveField.DisplayText == (Object)null))
				{
					TMP_Text displayText = kbActiveField.DisplayText;
					_kbCursorVisible = true;
					_kbCursorTimer = 0f;
					ApplyCaretText(kbActiveField, _kbCursorVisible, _kbHasEdited);
					displayText.ForceMeshUpdate(false, false);
					float num = 0f;
					RectTransform rectTransform = displayText.rectTransform;
					if ((Object)(object)rectTransform != (Object)null && (Object)(object)kbActiveField.Viewport != (Object)null)
					{
						Rect rect = kbActiveField.Viewport.rect;
						float width = ((Rect)(ref rect)).width;
						float displayWidthForRenderedText = GetDisplayWidthForRenderedText(displayText, displayText.text);
						num = ((width > 1f) ? Mathf.Max(0f, displayWidthForRenderedText - width) : 0f);
						rectTransform.offsetMin = new Vector2(0f - num, rectTransform.offsetMin.y);
						rectTransform.offsetMax = new Vector2(0f - num, rectTransform.offsetMax.y);
					}
					if ((Object)(object)kbActiveField.CursorImage != (Object)null)
					{
						((Graphic)kbActiveField.CursorImage).color = Color.clear;
					}
				}
			}

			private void KbBlinkCursor()
			{
				//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_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: 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)
				InputFieldInfo kbActiveField = _kbActiveField;
				if (!((Object)(object)kbActiveField?.DisplayText == (Object)null))
				{
					TMP_Text displayText = kbActiveField.DisplayText;
					ApplyCaretText(kbActiveField, _kbCursorVisible, _kbHasEdited);
					displayText.ForceMeshUpdate(false, false);
					RectTransform rectTransform = displayText.rectTransform;
					if ((Object)(object)rectTransform != (Object)null && (Object)(object)kbActiveField.Viewport != (Object)null)
					{
						Rect rect = kbActiveField.Viewport.rect;
						float width = ((Rect)(ref rect)).width;
						float displayWidthForRenderedText = GetDisplayWidthForRenderedText(displayText, displayText.text);
						float num = ((width > 1f) ? Mathf.Max(0f, displayWidthForRenderedText - width) : 0f);
						rectTransform.offsetMin = new Vector2(0f - num, rectTransform.offsetMin.y);
						rectTransform.offsetMax = new Vector2(0f - num, rectTransform.offsetMax.y);
					}
				}
			}

			internal void OpenKeyboard(InputFieldInfo info, Button returnButton)
			{
				OpenKeyboard(info, returnButton, null, useOverlay: false);
			}

			internal void OpenKeyboard(InputFieldInfo info, Button returnButton, Action onDone)
			{
				OpenKeyboard(info, returnButton, onDone, useOverlay: false);
			}

			public void OpenKeyboardForChat(InputFieldInfo info, Action onDone)
			{
				OpenKeyboard(info, null, onDone, useOverlay: true);
			}

			private void OpenKeyboard(InputFieldInfo info, Button returnButton, Action onDone, bool useOverlay)
			{
				if (_kbBuilt)
				{
					_kbActiveField = info;
					_kbReturnButton = returnButton;
					_kbOnDone = onDone;
					_kbUsingOverlay = useOverlay;
					_kbShift = false;
					_kbHasEdited = false;
					_kbCursorVisible = true;
					_kbCursorTimer = 0f;
					if (useOverlay && (Object)(object)_kbRoot != (Object)null)
					{
						RectTransform val = EnsureKeyboardOverlayRoot();
						_kbRoot.transform.SetParent((Transform)(object)val, false);
						_kbRoot.transform.SetAsLastSibling();
						ShowKeyboardOverlay();
					}
					KbRefreshKeyLabels();
					KbRefreshDisplay();
					SetKeyboardVisible(visible: true);
				}
			}

			internal void CloseKeyboardForChat()
			{
				CloseKeyboard();
			}

			public void CloseKeyboardOverlay()
			{
				CloseKeyboardOverlay(fireChatCancelledEvent: false);
			}

			public void CloseKeyboardOverlay(bool fireChatCancelledEvent)
			{
				CloseKeyboard();
				HideKeyboardOverlay();
				if (fireChatCancelledEvent)
				{
					MenuInjectionLibrary.OnChatKeyboardCancelled?.Invoke();
				}
			}

			private void CloseKeyboard()
			{
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_kbActiveField?.DisplayText != (Object)null)
				{
					TMP_Text displayText = _kbActiveField.DisplayText;
					if (_kbActiveField.Value.Length > 0)
					{
						displayText.text = _kbActiveField.Value;
						((Graphic)displayText).color = _kbActiveField.ActiveColor;
					}
					else
					{
						displayText.text = _kbActiveField.Placeholder;
						((Graphic)displayText).color = _kbActiveField.PlaceholderColor;
					}
					displayText.ForceMeshUpdate(false, false);
					RectTransform rectTransform = displayText.rectTransform;
					if ((Object)(object)rectTransform != (Object)null)
					{
						rectTransform.offsetMin = new Vector2(0f, rectTransform.offsetMin.y);
						rectTransform.offsetMax = new Vector2(0f, rectTransform.offsetMax.y);
					}
					if ((Object)(object)_kbActiveField.CursorImage != (Object)null)
					{
						((Graphic)_kbActiveField.CursorImage).color = Color.clear;
					}
				}
				SetKeyboardVisible(visible: false);
				_tabMenu?.SetActiveTab(_tabMenu.ActiveTab);
				Button kbReturnButton = _kbReturnButton;
				_kbActiveField = null;
				_kbReturnButton = null;
				_kbOnDone = null;
				if ((Object)(object)kbReturnButton != (Object)null)
				{
					EventSystem current = EventSystem.current;
					if (current != null)
					{
						current.SetSelectedGameObject(((Component)kbReturnButton).gameObject);
					}
				}
			}

			private void KbDone()
			{
				_kbOnDone?.Invoke();
				CloseKeyboard();
			}

			internal void OnInputFieldButtonClick(InputFieldInfo info, Button btn)
			{
				if (!IsMouseTyping)
				{
					if (Input.GetMouseButtonUp(0))
					{
						OpenMouseTyping(info);
					}
					else
					{
						OpenKeyboard(info, btn);
					}
				}
			}

			internal void OpenMouseTyping(InputFieldInfo info)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				_mouseTypingField = info;
				_mouseTypingActive = true;
				_mouseTypingNavFrame = -1;
				_mouseCursorBlinkFrame = -1;
				_mouseHasEdited = false;
				_mouseCursorTimer = 0f;
				_mouseCursorVisible = true;
				if ((Object)(object)info?.CursorImage != (Object)null)
				{
					((Graphic)info.CursorImage).color = Color.clear;
				}
				EventSystem current = EventSystem.current;
				if (current != null)
				{
					current.SetSelectedGameObject((GameObject)null);
				}
				RefreshMouseTypingDisplay();
			}

			internal void ForceCloseMouseTypingInternal()
			{
				if (_mouseTypingActive)
				{
					CloseMouseTyping(restoreSelection: false);
				}
			}

			private void CloseMouseTyping(bool restoreSelection = true)
			{
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				_mouseTypingActive = false;
				InputFieldInfo mouseTypingField = _mouseTypingField;
				_mouseTypingField = null;
				if (restoreSelection && (Object)(object)mouseTypingField?.OwnerButton != (Object)null)
				{
					EventSystem current = EventSystem.current;
					if (current != null)
					{
						current.SetSelectedGameObject(((Component)mouseTypingField.OwnerButton).gameObject);
					}
				}
				if ((Object)(object)mouseTypingField.CursorImage != (Object)null)
				{
					((Graphic)mouseTypingField.CursorImage).color = Color.clear;
				}
				if (!((Object)(object)mouseTypingField?.DisplayText == (Object)null))
				{
					TMP_Text displayText = mouseTypingField.DisplayText;
					if (mouseTypingField.Value.Length > 0)
					{
						displayText.text = mouseTypingField.Value;
						((Graphic)displayText).color = mouseTypingField.ActiveColor;
					}
					else
					{
						displayText.text = mouseTypingField.Placeholder;
						((Graphic)displayText).color = mouseTypingField.PlaceholderColor;
					}
					displayText.ForceMeshUpdate(false, false);
					RectTransform rectTransform = displayText.rectTransform;
					if ((Object)(object)rectTransform != (Object)null)
					{
						rectTransform.offsetMin = new Vector2(0f, rectTransform.offsetMin.y);
						rectTransform.offsetMax = new Vector2(0f, rectTransform.offsetMax.y);
					}
				}
			}

			private void RefreshMouseTypingDisplay()
			{
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				InputFieldInfo mouseTypingField = _mouseTypingField;
				if (!((Object)(object)mouseTypingField?.DisplayText == (Object)null))
				{
					TMP_Text displayText = mouseTypingField.DisplayText;
					ApplyCaretText(mouseTypingField, _mouseCursorVisible, _mouseHasEdited);
					displayText.ForceMeshUpdate(false, false);
					float num = 0f;
					RectTransform rectTransform = displayText.rectTransform;
					if ((Object)(object)rectTransform != (Object)null && (Object)(object)mouseTypingField.Viewport != (Object)null)
					{
						Rect rect = mouseTypingField.Viewport.rect;
						float width = ((Rect)(ref rect)).width;
						float displayWidthForRenderedText = GetDisplayWidthForRenderedText(displayText, displayText.text);
						num = ((width > 1f) ? Mathf.Max(0f, displayWidthForRenderedText - width) : 0f);
						rectTransform.offsetMin = new Vector2(0f - num, rectTransform.offsetMin.y);
						rectTransform.offsetMax = new Vector2(0f - num, rectTransform.offsetMax.y);
					}
					if ((Object)(object)mouseTypingField.CursorImage != (Object)null)
					{
						((Graphic)mouseTypingField.CursorImage).color = Color.clear;
					}
				}
			}

			private static void ApplyCaretText(InputFieldInfo field, bool showCaret, bool hasEdited)
			{
				//IL_003d: 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)
				if (!((Object)(object)field?.DisplayText == (Object)null))
				{
					bool flag = !string.IsNullOrEmpty(field.Value);
					((Graphic)field.DisplayText).color = (flag ? field.ActiveColor : field.PlaceholderColor);
					if (!flag)
					{
						field.DisplayText.text = (showCaret ? "|" : "<color=#FFFFFF00>|</color>");
					}
					else
					{
						field.DisplayText.text = (showCaret ? (field.Value + "|") : (field.Value + "<color=#FFFFFF00>|</color>"));
					}
				}
			}

			private static float GetDisplayWidthForRenderedText(TMP_Text text, string renderedText)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)text == (Object)null)
				{
					return 0f;
				}
				if (string.IsNullOrEmpty(renderedText))
				{
					return 0f;
				}
				float x = text.GetPreferredValues(renderedText + "M").x;
				float x2 = text.GetPreferredValues("M").x;
				return Mathf.Max(0f, x - x2);
			}

			private static bool IsPointerOverGameObject(GameObject target)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				EventSystem current = EventSystem.current;
				if ((Object)(object)current == (Object)null || (Object)(object)target == (Object)null)
				{
					return false;
				}
				PointerEventData val = new PointerEventData(current)
				{
					position = Vector2.op_Implicit(Input.mousePosition)
				};
				List<RaycastResult> val2 = new List<RaycastResult>();
				current.RaycastAll(val, val2);
				for (int i = 0; i < val2.Count; i++)
				{
					GameObject gameObject = val2[i].gameObject;
					if (!((Object)(object)gameObject == (Object)null) && ((Object)(object)gameObject == (Object)(object)target || gameObject.transform.IsChildOf(target.transform)))
					{
						return true;
					}
				}
				return false;
			}

			private void SetKeyboardVisible(bool visible)
			{
				if ((Object)(object)_kbCG == (Object)null)
				{
					return;
				}
				_kbCG.alpha = (visible ? 1f : 0f);
				_kbCG.interactable = visible;
				_kbCG.blocksRaycasts = visible;
				if (visible && _kbCharRows != null && _kbCharRows.Length != 0)
				{
					Button val = _kbCharRows[0][0];
					if ((Object)(object)_submenuItemList != (Object)null)
					{
						_submenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit((GameObject[])(object)new GameObject[1] { ((Component)val).gameObject });
					}
					EventSystem current = EventSystem.current;
					if (current != null)
					{
						current.SetSelectedGameObject(((Component)val).gameObject);
					}
					MenuItemList.active = _submenuItemList;
				}
			}

			private void IntegrateIntoMainItemList()
			{
				if ((Object)(object)_mainMenuItemList == (Object)null || (Object)(object)_mainButtonObj == (Object)null)
				{
					return;
				}
				Il2CppReferenceArray<GameObject> items = _mainMenuItemList.items;
				if (items == null || ((Il2CppArrayBase<GameObject>)(object)items).Length == 0)
				{
					return;
				}
				for (int i = 0; i < ((Il2CppArrayBase<GameObject>)(object)items).Length; i++)
				{
					if ((Object)(object)((Il2CppArrayBase<GameObject>)(object)items)[i] == (Object)(object)_mainButtonObj)
					{
						return;
					}
				}
				Menu activeMenu = _activeMenu;
				Button val = ((activeMenu != null) ? activeMenu.ContinueGameButton : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				int num = -1;
				for (int j = 0; j < ((Il2CppArrayBase<GameObject>)(object)items).Length; j++)
				{
					if ((Object)(object)((Il2CppArrayBase<GameObject>)(object)items)[j] == (Object)(object)((Component)val).gameObject)
					{
						num = j;
						break;
					}
				}
				if (num < 0)
				{
					return;
				}
				GameObject[] array = (GameObject[])(object)new GameObject[((Il2CppArrayBase<GameObject>)(object)items).Length + 1];
				int k = 0;
				int num2 = 0;
				for (; k < array.Length; k++)
				{
					if (k == num + 1)
					{
						array[k] = _mainButtonObj;
					}
					else
					{
						array[k] = ((Il2CppArrayBase<GameObject>)(object)items)[num2++];
					}
				}
				_mainMenuItemList.items = Il2CppReferenceArray<GameObject>.op_Implicit(array);
			}

			private void UpdateVisibility(Menu menu)
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Invalid comparison between Unknown and I4
				if ((Object)(object)menu == (Object)null)
				{
					return;
				}
				bool flag = (Object)(object)menu.mainMenuCanvas != (Object)null && menu.mainMenuCanvas.activeInHierarchy && (int)menu.currentMenuScreen == 0;
				if ((Object)(object)_mainButtonObj != (Object)null)
				{
					_mainButtonObj.SetActive(flag);
				}
				if (!flag)
				{
					if (GetSubmenuVisible())
					{
						SetSubmenuVisible(isVisible: false);
					}
					return;
				}
				bool submenuVisible = GetSubmenuVisible();
				bool flag2 = submenuVisible;
				if (!flag2)
				{
					List<InjectedMenu> registeredMenus = _registeredMenus;
					for (int i = 0; i < registeredMenus.Count; i++)
					{
						if (registeredMenus[i].GetSubmenuVisible())
						{
							flag2 = true;
							break;
						}
					}
				}
				if ((Object)(object)_mainMenuCG != (Object)null)
				{
					_mainMenuCG.alpha = (flag2 ? 0f : 1f);
					_mainMenuCG.blocksRaycasts = !flag2;
					_mainMenuCG.interactable = !flag2;
				}
				if ((Object)(object)menu.titleGroup != (Object)null)
				{
					menu.titleGroup.alpha = (flag2 ? 0f : 1f);
				}
			}

			private void SetSubmenuVisible(bool isVisible)
			{
				if ((Object)(object)_submenuCG == (Object)null)
				{
					return;
				}
				bool flag = _submenuCG.alpha > 0.5f;
				if (flag == isVisible)
				{
					return;
				}
				if (!isVisible && KbVisible)
				{
					SetKeyboardVisible(visible: false);
				}
				_submenuCG.alpha = (isVisible ? 1f : 0f);
				_submenuCG.blocksRaycasts = isVisible;
				_submenuCG.interactable = isVisible;
				for (int i = 0; i < _fixedButtonInstances.Count; i++)
				{
					if ((Object)(object)_fixedButtonInstances[i] != (Object)null)
					{
						((Selectable)_fixedButtonInstances[i]).interactable = isVisible;
					}
				}
				if ((Object)(object)_mainButton != (Object)null)
				{
					((Selectable)_mainButton).interactable = !isVisible;
				}
				if (isVisible)
				{
					ApplyMargin();
					_tabMenu?.OnShown();
					if ((Object)(object)_submenuItemList != (Object)null)
					{
						MenuItemList.active = _submenuItemList;
					}
				}
				else if ((Object)(object)_mainMenuItemList != (Object)null)
				{
					MenuItemList.active = _mainMenuItemList;
				}
				EventSystem current = EventSystem.current;
				if ((Object)(object)current != (Object)null)
				{
					if (isVisible && _fixedButtonInstances.Count > 0 && (Object)(object)_fixedButtonInstances[0] != (Object)null)
					{
						current.SetSelectedGameObject(((Component)_fixedButtonInstances[0]).gameObject);
					}
					else if (!isVisible && (Object)(object)_mainButton != (Object)null)
					{
						current.SetSelectedGameObject(((Component)_mainButton).gameObject);
					}
				}
				UpdateVisibility(_activeMenu);
			}

			private void EnsureSelection()
			{
				if (KbVisible || _mouseTypingActive)
				{
					return;
				}
				EventSystem current = EventSystem.current;
				if ((Object)(object)current == (Object)null)
				{
					return;
				}
				GameObject currentSelectedGameObject = current.currentSelectedGameObject;
				if (!((Object)(object)currentSelectedGameObject == (Object)null) && currentSelectedGameObject.activeInHierarchy)
				{
					Selectable component = currentSelectedGameObject.GetComponent<Selectable>();
					if (component == null || component.interactable)
					{
						return;
					}
				}
				if (GetSubmenuVisible())
				{
					if (_fixedButtonInstances.Count > 0 && (Object)(object)_fixedButtonInstances[0] != (Object)null)
					{
						current.SetSelectedGameObject(((Component)_fixedButtonInstances[0]).gameObject);
					}
					return;
				}
				Menu activeMenu = _activeMenu;
				if ((Object)(object)((activeMenu != null) ? activeMenu.ContinueGameButton : null) != (Object)null)
				{
					current.SetSelectedGameObject(((Component)_activeMenu.ContinueGameButton).gameObject);
				}
			}

			private void TryHandleCancel(Menu menu)
			{
				if (((menu != null) ? menu.rwPlayer : null) != null && !KbVisible && !_mouseTypingActive && (Input.GetKeyDown((KeyCode)27) || menu.rwPlayer.GetButtonDown(15)))
				{
					SetSubmenuVisible(isVisible: false);
				}
			}

			private void ApplyMargin()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_submenuRect != (Object)null)
				{
					_submenuRect.anchoredPosition = new Vector2(10f + _sideMargin, -10f - _topMargin);
				}
			}

			private bool GetSubmenuVisible()
			{
				return (Object)(object)_submenuCG != (Object)null && _submenuCG.alpha > 0.5f;
			}

			private void ResolveExisting(Menu menu)
			{
				if ((Object)(object)((menu != null) ? menu.mainMenuCanvas : null) == (Object)null)
				{
					return;
				}
				Il2CppArrayBase<Transform> componentsInChildren = menu.mainMenuCanvas.GetComponentsInChildren<Transform>(true);
				List<GameObject> list = new List<GameObject>();
				List<GameObject> list2 = new List<GameObject>();
				List<GameObject> list3 = new List<GameObject>();
				string text = "BBSMP_Btn_" + _tag;
				string text2 = "BBSMP_Sub_" + _tag;
				string text3 = "BBSMP_Keyboard_" + _tag;
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Transform val = componentsInChildren[i];
					if (!((Object)(object)val == (Object)null))
					{
						if (((Object)val).name == text)
						{
							list.Add(((Component)val).gameObject);
						}
						else if (((Object)val).name == text2)
						{
							list2.Add(((Component)val).gameObject);
						}
						else if (((Object)val).name == text3)
						{
							list3.Add(((Component)val).gameObject);
						}
					}
				}
				if (list3.Count > 0)
				{
					if (_kbBuilt)
					{
						_kbRoot = list3[0];
						GameObject kbRoot = _kbRoot;
						_kbCG = ((kbRoot != null) ? kbRoot.GetComponent<CanvasGroup>() : null);
					}
					else
					{
						for (int j = 0; j < list3.Count; j++)
						{
							Object.Destroy((Object)(object)list3[j]);
						}
						_kbRoot = null;
						_kbCG = null;
					}
					for (int k = 1; k < list3.Count; k++)
					{
						Object.Destroy((Object)(object)list3[k]);
					}
				}
				if (list.Count > 0)
				{
					_mainButtonObj = list[0];
					_mainButton = _mainButtonObj.GetComponent<Button>();
					for (int l = 1; l < list.Count; l++)
					{
						Object.Destroy((Object)(object)list[l]);
					}
					_mainMenuRoot = _mainButtonObj.transform.parent;
					Transform mainMenuRoot = _mainMenuRoot;
					object obj = ((mainMenuRoot != null) ? ((Component)mainMenuRoot).GetComponent<CanvasGroup>() : null);
					if (obj == null)
					{
						Transform mainMenuRoot2 = _mainMenuRoot;
						obj = ((mainMenuRoot2 != null) ? ((Component)mainMenuRoot2).gameObject.AddComponent<CanvasGroup>() : null);
					}
					_mainMenuCG = (CanvasGroup)obj;
					Transform mainMenuRoot3 = _mainMenuRoot;
					_mainMenuItemList = ((mainMenuRoot3 != null) ? ((Component)mainMenuRoot3).GetComponent<MenuItemList>() : null);
				}
				if (list2.Count > 0)
				{
					_submenuObj = list2[0];
					_submenuCG = _submenuObj.GetComponent<CanvasGroup>();
					_submenuItemList = _submenuObj.GetComponent<MenuItemList>();
					for (int m = 1; m < list2.Count; m++)
					{
						Object.Destroy((Object)(object)list2[m]);
					}
					_fixedButtonInstances.Clear();
					for (int n = 0; n < _fixedDescs.Count; n++)
					{
						Transform val2 = _submenuObj.transform.Find($"BBSMP_Fixed_{_tag}_{n}");
						_fixedButtonInstances.Add((val2 != null) ? ((Component)val2).GetComponent<Button>() : null);
					}
				}
			}

			private void Reset()
			{
				if ((Object)(object)_mainButtonObj != (Object)null)
				{
					Object.Destroy((Object)(object)_mainButtonObj);
				}
				if ((Object)(object)_submenuObj != (Object)null)
				{
					Object.Destroy((Object)(object)_submenuObj);
				}
				if ((Object)(object)_kbRoot != (Object)null)
				{
					Object.Destroy((Object)(object)_kbRoot);
				}
				_mainButtonObj = null;
				_mainButton = null;
				_submenuObj = null;
				_submenuCG = null;
				_submenuItemList = null;
				_submenuRect = null;
				_mainMenuRoot = null;
				_mainMenuCG = null;
				_mainMenuItemList = null;
				_tabMenu = null;
				_contentBuilt = false;
				_fixedButtonInstances.Clear();
				_kbRoot = null;
				_kbCG = null;
				_kbCharRows = null;
				_kbSpecialRow = null;
				_kbLowerRows = null;
				_kbUpperRows = null;
				_kbAllButtons.Clear();
				_kbActiveField = null;
				_kbReturnButton = null;
				_kbBuilt = false;
				_kbShift = false;
				_kbShiftBtn = null;
				_kbNavFrame = -1;
				_kbCursorTimer = 0f;
				_kbCursorVisible = true;
			}

			private static Button FindTemplateButton(Menu menu)
			{
				if ((Object)(object)menu.ContinueGameButton != (Object)null)
				{
					return menu.ContinueGameButton;
				}
				if ((Object)(object)menu.mainMenuCanvas == (Object)null)
				{
					return null;
				}
				Il2CppArrayBase<Button> componentsInChildren = menu.mainMenuCanvas.GetComponentsInChildren<Button>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return null;
				}
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (!((Object)(object)componentsInChildren[i] == (Object)null))
					{
						TMP_Text componentInChildren = ((Component)componentsInChildren[i]).GetComponentInChildren<TMP_Text>(true);
						string text = ((componentInChildren != null) ? componentInChildren.text : null) ?? "";
						if (text.Contains("continue", StringComparison.OrdinalIgnoreCase))
						{
							return componentsInChildren[i];
						}
					}
				}
				return componentsInChildren[0];
			}

			private static Toggle FindToggleTemplate(Menu menu)
			{
				if ((Object)(object)((menu != null) ? menu.mainMenuCanvas : null) == (Object)null)
				{
					return null;
				}
				Il2CppArrayBase<Toggle> componentsInChildren = menu.mainMenuCanvas.GetComponentsInChildren<Toggle>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return null;
				}
				Toggle val = componentsInChildren[0];
				if ((Object)(object)val != (Object)null)
				{
					StripLocalizationComponentsImmediate(((Component)val).gameObject);
				}
				return val;
			}

			private static Slider FindSliderTemplate(Menu menu)
			{
				if ((Object)(object)((menu != null) ? menu.mainMenuCanvas : null) == (Object)null)
				{
					return null;
				}
				Il2CppArrayBase<Slider> componentsInChildren = menu.mainMenuCanvas.GetComponentsInChildren<Slider>(true);
				return (componentsInChildren != null && componentsInChildren.Length > 0) ? componentsInChildren[0] : null;
			}

			private static void DumpHierarchy(Menu menu, string reason)
			{
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!((Object)(object)menu == (Object)null))
					{
						StringBuilder stringBuilder = new StringBuilder();
						stringBuilder.AppendLine("=== BabyStepsMenuLib Hierarchy Dump ===");
						StringBuilder stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder3 = stringBuilder2;
						StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 1, stringBuilder2);
						handler.AppendLiteral("Reason: ");
						handler.AppendFormatted(reason);
						stringBuilder3.AppendLine(ref handler);
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder4 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(6, 1, stringBuilder2);
						handler.AppendLiteral("Time: ");
						handler.AppendFormatted(DateTime.Now, "O");
						stringBuilder4.AppendLine(ref handler);
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder5 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(18, 2, stringBuilder2);
						handler.AppendLiteral("Screen: ");
						handler.AppendFormatted<MenuScreen>(menu.currentMenuScreen);
						handler.AppendLiteral("  Paused: ");
						handler.AppendFormatted(menu.paused);
						stringBuilder5.AppendLine(ref handler);
						if ((Object)(object)menu.mainMenuCanvas != (Object)null)
						{
							stringBuilder2 = stringBuilder;
							StringBuilder stringBuilder6 = stringBuilder2;
							handler = new StringBuilder.AppendInterpolatedStringHandler(9, 1, stringBuilder2);
							handler.AppendLiteral("CanvasW: ");
							handler.AppendFormatted(GetPath(menu.mainMenuCanvas.transform));
							stringBuilder6.AppendLine(ref handler);
							AppendTransform(stringBuilder, menu.mainMenuCanvas.transform, 0, 6);
						}
						string text = Path.Combine(Environment.CurrentDirectory, "UserData");
						Directory.CreateDirectory(text);
						File.WriteAllText(Path.Combine(text, "BabyStepsMenuLib_MenuHierarchyDump.txt"), stringBuilder.ToString());
					}
				}
				catch (Exception value)
				{
					Instance logger = Logger;
					if (logger != null)
					{
						logger.Error($"[MenuInject] Dump failed: {value}");
					}
				}
			}

			private static void AppendTransform(StringBuilder sb, Transform root, int depth, int maxDepth)
			{
				if ((Object)(object)root == (Object)null || depth > maxDepth)
				{
					return;
				}
				string value = new string(' ', depth * 2);
				Il2CppArrayBase<Component> components = ((Component)root).GetComponents<Component>();
				List<string> list = new List<string>();
				for (int i = 0; i < components.Length; i++)
				{
					if ((Object)(object)components[i] != (Object)null)
					{
						list.Add(((object)components[i]).GetType().Name);
					}
				}
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(5, 3, sb);
				handler.AppendFormatted(value);
				handler.AppendLiteral("- ");
				handler.AppendFormatted(((Object)root).name);
				handler.AppendLiteral(" [");
				handler.AppendFormatted(string.Join(", ", list));
				handler.AppendLiteral("]");
				sb.AppendLine(ref handler);
				for (int j = 0; j < root.childCount; j++)
				{
					AppendTransform(sb, root.GetChild(j), depth + 1, maxDepth);
				}
			}

			private static string GetPath(Transform t)
			{
				if ((Object)(object)t == (Object)null)
				{
					return "<null>";
				}
				Stack<string> stack = new Stack<string>();
				while ((Object)(object)t != (Object)null)
				{
					stack.Push(((Object)t).name);
					t = t.parent;
				}
				return string.Join("/", stack);
			}
		}

		internal static readonly List<InjectedMenu> _registeredMenus = new List<InjectedMenu>();

		private static RectTransform customRoot;

		private static Button buttonTemplate;

		private static Toggle toggleTemplate;

		private static Slider sliderTemplate;

		private const float SliderHandleSize = 112f;

		private static Sprite _inputFieldSprite;

		private static Sprite _sliderHandleSprite;

		private static Sprite _solidSprite;

		private static TMP_FontAsset _lowercaseTextFont;

		private const float KeyboardKeyFontSize = 20f;

		private static RectTransform _keyboardOverlayRoot;

		private static CanvasGroup _keyboardOverlayCanvasGroup;

		private static Image _popupDimImage;

		private static Canvas _popupDimCanvas;

		private static RuntimeTabMenu _currentTabMenu;

		private static int _currentTabPage = -1;

		private static InjectedMenu _currentInjectedMenu;

		private static float nextY;

		private const float Spacing = 10f;

		private const float DefaultHeight = 52f;

		internal static readonly Color TabUnselected = new Color(0.435f, 0.676f, 0.726f, 1f);

		internal static readonly Color TabSelected = new Color(1f, 1f, 1f, 0.78f);

		internal static readonly Color TabText = new Color(0f, 0.169f, 0.283f, 1f);

		internal static readonly Color TabHighlighted = new Color(0.519f, 0.804f, 0.865f, 1f);

		public static Instance Logger { get; set; }

		public static Func<bool> IsCapturingKeybindProvider { get; set; }

		public static Func<bool> IsOverlayBlockingMenuProvider { get; set; }

		public static GameObject[] OverlayNavigableItems { get; set; }

		public static bool IsAnyKeyboardVisible => _registeredMenus.Exists((InjectedMenu m) => m.KbVisible);

		internal static InjectedMenu CurrentMenu => _currentInjectedMenu;

		public static InputFieldInfo LastCreatedInputFieldInfo { get; private set; }

		public static event Action OnChatKeyboardCancelled;

		public static InjectedMenu GetKeyboardMenu()
		{
			if (_registeredMenus.Count > 0)
			{
				return _registeredMenus[0];
			}
			return null;
		}

		private static RectTransform EnsureKeyboardOverlayRoot()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00de: 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)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_keyboardOverlayRoot != (Object)null)
			{
				return _keyboardOverlayRoot;
			}
			Il2CppReferenceArray<Type> val = new Il2CppReferenceArray<Type>(5L);
			((Il2CppArrayBase<Type>)(object)val)[0] = Il2CppType.Of<RectTransform>();
			((Il2CppArrayBase<Type>)(object)val)[1] = Il2CppType.Of<Canvas>();
			((Il2CppArrayBase<Type>)(object)val)[2] = Il2CppType.Of<CanvasScaler>();
			((Il2CppArrayBase<Type>)(object)val)[3] = Il2CppType.Of<GraphicRaycaster>();
			((Il2CppArrayBase<Type>)(object)val)[4] = Il2CppType.Of<CanvasGroup>();
			GameObject val2 = new GameObject("BBSMP_ChatKeyboardOverlay", val);
			Object.DontDestroyOnLoad((Object)(object)val2);
			Canvas component = val2.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.overrideSorting = true;
			component.sortingOrder = 10000;
			_keyboardOverlayCanvasGroup = val2.GetComponent<CanvasGroup>();
			_keyboardOverlayCanvasGroup.alpha = 1f;
			_keyboardOverlayCanvasGroup.blocksRaycasts = true;
			_keyboardOverlayCanvasGroup.interactable = true;
			_keyboardOverlayRoot = val2.GetComponent<RectTransform>();
			_keyboardOverlayRoot.anchorMin = Vector2.zero;
			_keyboardOverlayRoot.anchorMax = Vector2.one;
			_keyboardOverlayRoot.offsetMin = Vector2.zero;
			_keyboardOverlayRoot.offsetMax = Vector2.zero;
			return _keyboardOverlayRoot;
		}

		public static void ShowPopupDim(Color color)
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if ((Object)(object)_popupDimImage == (Object)null)
			{
				Transform val = ((_registeredMenus.Count > 0) ? _registeredMenus[0] : null)?.GameCanvasTransform;
				if ((Object)(object)val == (Object)null)
				{
					GameObject val2 = new GameObject("BBSMP_PopupDimCanvas");
					Object.DontDestroyOnLoad((Object)(object)val2);
					_popupDimCanvas = val2.AddComponent<Canvas>();
					_popupDimCanvas.renderMode = (RenderMode)0;
					_popupDimCanvas.sortingOrder = 9998;
					val2.AddComponent<CanvasScaler>();
					val2.AddComponent<GraphicRaycaster>();
					val = val2.transform;
				}
				GameObject val3 = new GameObject("BBSMP_PopupDim");
				val3.transform.SetParent(val, false);
				RectTransform val4 = val3.AddComponent<RectTransform>();
				val4.anchorMin = Vector2.zero;
				val4.anchorMax = Vector2.one;
				Vector2 offsetMin = (val4.offsetMax = Vector2.zero);
				val4.offsetMin = offsetMin;
				_popupDimImage = val3.AddComponent<Image>();
				((Graphic)_popupDimImage).raycastTarget = true;
			}
			if ((Object)(object)_popupDimImage != (Object)null)
			{
				((Graphic)_popupDimImage).color = color;
				((Component)_popupDimImage).gameObject.SetActive(true);
				Canvas popupDimCanvas = _popupDimCanvas;
				if (popupDimCanvas != null)
				{
					((Component)popupDimCanvas).gameObject.SetActive(true);
				}
			}
			InjectedMenu injectedMenu = ((_registeredMenus.Count > 0) ? _registeredMenus[0] : null);
			Transform val5 = injectedMenu?.GameCanvasTransform;
			Transform val6 = injectedMenu?.KbRootTransform;
			if ((Object)(object)val5 != (Object)null && (Object)(object)val6 != (Object)null && (Object)(object)_popupDimImage != (Object)null && (Object)(object)((Component)_popupDimImage).transform.parent == (Object)(object)val5)
			{
				((Component)_popupDimImage).transform.SetAsLastSibling();
				val6.SetAsLastSibling();
			}
		}

		public static void HidePopupDim()
		{
			if ((Object)(object)_popupDimImage != (Object)null)
			{
				((Component)_popupDimImage).gameObject.SetActive(false);
			}
			if ((Object)(object)_popupDimCanvas != (Object)null)
			{
				((Component)_popupDimCanvas).gameObject.SetActive(false);
			}
		}

		internal static void HideKeyboardOverlay()
		{
			if ((Object)(object)_keyboardOverlayCanvasGroup != (Object)null)
			{
				_keyboardOverlayCanvasGroup.alpha = 0f;
				_keyboardOverlayCanvasGroup.blocksRaycasts = false;
				_keyboardOverlayCanvasGroup.interactable = false;
			}
		}

		internal static void ShowKeyboardOverlay()
		{
			RectTransform val = EnsureKeyboardOverlayRoot();
			if ((Object)(object)val != (Object)null)
			{
				CanvasGroup keyboardOverlayCanvasGroup = _keyboardOverlayCanvasGroup;
				if ((Object)(object)keyboardOverlayCanvasGroup != (Object)null)
				{
					keyboardOverlayCanvasGroup.alpha = 1f;
					keyboardOverlayCanvasGroup.blocksRaycasts = true;
					keyboardOverlayCanvasGroup.interactable = true;
				}
			}
		}

		private static TMP_FontAsset GetOrCreateLowercaseTextFont()
		{
			if ((Object)(object)_lowercaseTextFont != (Object)null)
			{
				return _lowercaseTextFont;
			}
			Font builtinResource = Resources.GetBuiltinResource<Font>("Arial.ttf");
			if ((Object)(object)builtinResource == (Object)null)
			{
				return null;
			}
			_lowercaseTextFont = TMP_FontAsset.CreateFontAsset(builtinResource);
			return _lowercaseTextFont;
		}

		private static void ApplyLowercaseTextFont(TMP_Text text)
		{
			if (!((Object)(object)text == (Object)null))
			{
				TMP_FontAsset orCreateLowercaseTextFont = GetOrCreateLowercaseTextFont();
				if ((Object)(object)orCreateLowercaseTextFont != (Object)null)
				{
					text.font = orCreateLowercaseTextFont;
				}
			}
		}

		private static Sprite GetOrCreateSliderHandleSprite()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_sliderHandleSprite != (Object)null)
			{
				return _sliderHandleSprite;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			Color32[] array = (Color32[])(object)new Color32[4096];
			float num = 31.5f;
			float num2 = 31.5f;
			float num3 = 26f;
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num4 = (float)j - num;
					float num5 = (float)i - num2;
					float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5);
					byte b = (byte)(Mathf.Clamp01(num3 + 0.5f - num6) * 255f);
					array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(Il2CppStructArray<Color32>.op_Implicit(array));
			val.Apply(false, false);
			_sliderHandleSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
			return _sliderHandleSprite;
		}

		private static Sprite GetOrCreateInputFieldSprite()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_inputFieldSprite != (Object)null)
			{
				return _inputFieldSprite;
			}
			Texture2D val = new Texture2D(128, 64, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			float num = 18f;
			float num2 = 109f;
			float num3 = 18f;
			float num4 = 45f;
			Color32[] array = (Color32[])(object)new Color32[8192];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num5 = (((float)j < num) ? (num - (float)j) : (((float)j > num2) ? ((float)j - num2) : 0f));
					float num6 = (((float)i < num3) ? (num3 - (float)i) : (((float)i > num4) ? ((float)i - num4) : 0f));
					float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
					byte b = (byte)(Mathf.Clamp01(18.5f - num7) * 255f);
					array[i * 128 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(Il2CppStructArray<Color32>.op_Implicit(array));
			val.Apply(false, false);
			_inputFieldSprite = Sprite.Create(val, new Rect(0f, 0f, 128f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(18f, 18f, 18f, 18f));
			return _inputFieldSprite;
		}

		private static Sprite GetOrCreateSolidSprite()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			if ((Object)(object)_solidSprite != (Object)null)
			{
				return _solidSprite;
			}
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixels32(Il2CppStructArray<Color32>.op_Implicit((Color32[])(object)new Color32[1]
			{
				new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			}));
			val.Apply(false, false);
			_solidSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f));
			return _solidSprite;
		}

		public static void ForceCloseMouseTyping()
		{
			foreach (InjectedMenu registeredMenu in _registeredMenus)
			{
				registeredMenu.ForceCloseMouseTypingInternal();
			}
		}

		public static MenuBuilder CreateMenu(string mainButtonLabel)
		{
			return new MenuBuilder(mainButtonLabel);
		}

		public static TMP_FontAsset GetCurrentToggleFont()
		{
			Toggle obj = toggleTemplate;
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = ((Component)obj).transform.Find("Label");
				obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
			}
			TMP_Text val = (TMP_Text)obj2;
			return (val != null) ? val.font : null;
		}

		public static void Configure(RectTransform root, Button button, Toggle toggle = null, Slider slider = null)
		{
			customRoot = root;
			buttonTemplate = button;
			toggleTemplate = toggle;
			sliderTemplate = slider;
			_currentTabMenu = null;
			_currentTabPage = -1;
			ResetLayout();
		}

		public static void ConfigureTabPage(RuntimeTabMenu tabMenu, int pageIndex, Button button, Toggle toggle = null, Slider slider = null)
		{
			Configure(tabMenu?.GetPage(pageIndex), button, toggle, slider);
			_currentTabMenu = tabMenu;
			_currentTabPage = pageIndex;
		}

		public static RectTransform GetCustomRoot()
		{
			return customRoot;
		}

		public static void ClearCustomContent()
		{
			if ((Object)(object)customRoot == (Object)null)
			{
				return;
			}
			for (int num = ((Transform)customRoot).childCount - 1; num >= 0; num--)
			{
				Transform child = ((Transform)customRoot).GetChild(num);
				if ((Object)(object)child != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
				}
			}
			ResetLayout();
		}

		public static TMP_Text AddLabel(string text, RectTransform parent = null)
		{
			RectTransform val = parent ?? customRoot;
			if ((Object)(object)val == (Object)null || (Object)(object)buttonTemplate == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)buttonTemplate).gameObject, (Transform)(object)val);
			((Object)val2).name = "BBSMP_Label";
			StripLocalizationComponents(val2);
			Button component = val2.GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Image component2 = val2.GetComponent<Image>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Behaviour)component2).enabled = false;
			}
			TMP_Text componentInChildren = val2.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = text;
				componentInChildren.alignment = (TextAlignmentOptions)4097;
				componentInChildren.ForceMeshUpdate(false, false);
			}
			PlaceInLayout(val2.GetComponent<RectTransform>(), val, 52f);
			return componentInChildren;
		}

		public static Image AddImage(Color color, float height = 52f, RectTransform parent = null)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = parent ?? customRoot;
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = new GameObject("BBSMP_Image");
			val2.transform.SetParent((Transform)(object)val, false);
			RectTransform rect = val2.AddComponent<RectTransform>();
			Image val3 = val2.AddComponent<Image>();
			val3.sprite = GetOrCreateSolidSprite();
			val3.type = (Type)0;
			((Graphic)val3).color = color;
			PlaceInLayout(rect, val, height);
			return val3;
		}

		public static Button AddButton(string text, UnityAction onClick, RectTransform parent = null)
		{
			RectTransform val = parent ?? customRoot;
			if ((Object)(object)val == (Object)null || (Object)(object)buttonTemplate == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)buttonTemplate).gameObject, (Transform)(object)val);
			((Object)val2).name = "BBSMP_Button";
			StripLocalizationComponents(val2);
			Button component = val2.GetComponent<Button>();
			ClearButtonEvents(component);
			if ((Object)(object)component != (Object)null && (Delegate)(object)onClick != (Delegate)null)
			{
				((UnityEvent)component.onClick).AddListener(onClick);
			}
			SetButtonLabel(val2, text);
			PlaceInLayout(val2.GetComponent<RectTransform>(), val, 52f);
			_currentTabMenu?.RegisterPageSelectable(_currentTabPage, (Selectable)(object)component);
			return component;
		}

		public static Toggle AddToggle(string text, bool initialValue, UnityAction<bool> onValueChanged, RectTransform parent = null)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			RectTransform val = parent ?? customRoot;
			if ((Object)(object)val == (Object)null || (Object)(object)toggleTemplate == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)toggleTemplate).gameObject, (Transform)(object)val);
			((Object)val2).name = "BBSMP_Toggle";
			Transform val3 = val2.transform.Find("Label");
			if ((Object)(object)val3 != (Object)null)
			{
				BBLocalize component = ((Component)val3).GetComponent<BBLocalize>();
				if ((Object)(object)component != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component);
				}
				TMP_Text component2 = ((Component)val3).GetComponent<TMP_Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.text = text;
				}
			}
			Toggle component3 = val2.GetComponent<Toggle>();
			if ((Object)(object)component3 == (Object)null)
			{
				return null;
			}
			component3.onValueChanged = new ToggleEvent();
			component3.isOn = initialValue;
			if ((Delegate)(object)onValueChanged != (Delegate)null)
			{
				((UnityEvent<bool>)(object)component3.onValueChanged).AddListener(onValueChanged);
			}
			PlaceInLayout(val2.GetComponent<RectTransform>(), val, 52f);
			_currentTabMenu?.RegisterPageSelectable(_currentTabPage, (Selectable)(object)component3);
			return component3;
		}

		public static Slider AddSlider(string text, float min, float max, float value, UnityAction<float> onValueChanged, bool wholeNumbers = false, RectTransform parent = null)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = parent ?? customRoot;
			if ((Object)(object)val == (Object)null || (Object)(object)sliderTemplate == (Object)null)
			{
				return null;
			}
			Il2CppReferenceArray<Type> val2 = new Il2CppReferenceArray<Type>(2L);
			((Il2CppArrayBase<Type>)(object)val2)[0] = Il2CppType.Of<RectTransform>();
			((Il2CppArrayBase<Type>)(object)val2)[1] = Il2CppType.Of<HorizontalLayoutGroup>();
			GameObject val3 = new GameObject("BBSMP_SliderContainer", val2);
			RectTransform component = val3.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)val, false);
			HorizontalLayoutGroup component2 = val3.GetComponent<HorizontalLayoutGroup>();
			((LayoutGroup)component2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)component2).spacing = 30f;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true;
			if (!string.IsNullOrEmpty(text))
			{
				TMP_Text val4 = AddLabel(text, component);
				if ((Object)(object)val4 != (Object)null)
				{
					LayoutElement val5 = ((Component)val4).GetComponent<LayoutElement>() ?? ((Component)val4).gameObject.AddComponent<LayoutElement>();
					val5.flexibleWidth = 0f;
					val4.ForceMeshUpdate(false, false);
				}
			}
			GameObject val6 = InstantiateSliderTemplateSafely(((Component)sliderTemplate).gameObject, (Transform)(object)component);
			((Object)val6).name = "BBSMP_Slider";
			StripLocalizationComponents(val6);
			Slider component3 = val6.GetComponent<Slider>();
			if ((Object)(object)component3 == (Object)null)
			{
				return null;
			}
			component3.onValueChanged = new SliderEvent();
			component3.minValue = min;
			component3.maxValue = max;
			component3.wholeNumbers = wholeNumbers;
			component3.SetValueWithoutNotify(Mathf.Clamp(value, min, max));
			if ((Delegate)(object)onValueChanged != (Delegate)null)
			{
				((UnityEvent<float>)(object)component3.onValueChanged).AddListener(onValueChanged);
			}
			LayoutElement val7 = val6.GetComponent<LayoutElement>() ?? val6.AddComponent<LayoutElement>();
			val7.flexibleWidth = 1f;
			val7.minWidth = 100f;
			RectTransform val8 = component3.handleRect;
			if ((Object)(object)val8 == (Object)null)
			{
				Il2CppArrayBase<RectTransform> componentsInChildren = val6.GetComponentsInChildren<RectTransform>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					RectTransform val9 = componentsInChildren[i];
					if (!((Object)(object)val9 == (Object)null))
					{
						string name = ((Object)((Component)val9).gameObject).name;
						if (name.IndexOf("Handle", StringComparison.OrdinalIgnoreCase) >= 0 && name.IndexOf("Area", StringComparison.OrdinalIgnoreCase) < 0 &&

Mods/UniverseLib.ML.IL2CPP.Interop.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using HarmonyLib;
using Il2CppInterop.Common;
using Il2CppInterop.Common.Attributes;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppSystem.Threading;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UniverseLib.Config;
using UniverseLib.Input;
using UniverseLib.Reflection;
using UniverseLib.Runtime;
using UniverseLib.Runtime.Il2Cpp;
using UniverseLib.UI;
using UniverseLib.UI.Models;
using UniverseLib.UI.ObjectPool;
using UniverseLib.UI.Panels;
using UniverseLib.UI.Widgets;
using UniverseLib.UI.Widgets.ScrollView;
using UniverseLib.Utility;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("UniverseLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Sinai, yukieiji")]
[assembly: AssemblyProduct("UniverseLib")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b21dbde3-5d6f-4726-93ab-cc3cc68bae7d")]
[assembly: AssemblyFileVersion("1.5.10")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.10.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
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 UniverseLib
{
	public static class ReflectionExtensions
	{
		public static Type GetActualType(this object obj)
		{
			return ReflectionUtility.Instance.Internal_GetActualType(obj);
		}

		public static object TryCast(this object obj)
		{
			return ReflectionUtility.Instance.Internal_TryCast(obj, ReflectionUtility.Instance.Internal_GetActualType(obj));
		}

		public static object TryCast(this object obj, Type castTo)
		{
			return ReflectionUtility.Instance.Internal_TryCast(obj, castTo);
		}

		public static T TryCast<T>(this object obj)
		{
			try
			{
				return (T)ReflectionUtility.Instance.Internal_TryCast(obj, typeof(T));
			}
			catch
			{
				return default(T);
			}
		}

		public static Type[] TryGetTypes(this Assembly asm)
		{
			try
			{
				return asm.GetTypes();
			}
			catch (ReflectionTypeLoadException e)
			{
				return ReflectionUtility.TryExtractTypesFromException(e);
			}
			catch
			{
				try
				{
					return asm.GetExportedTypes();
				}
				catch (ReflectionTypeLoadException e2)
				{
					return ReflectionUtility.TryExtractTypesFromException(e2);
				}
				catch
				{
					return ArgumentUtility.EmptyTypes;
				}
			}
		}

		public static bool ReferenceEqual(this object objA, object objB)
		{
			if (objA == objB)
			{
				return true;
			}
			Object val = (Object)((objA is Object) ? objA : null);
			if (val != null)
			{
				Object val2 = (Object)((objB is Object) ? objB : null);
				if (val2 != null && Object.op_Implicit(val) && Object.op_Implicit(val2) && val.m_CachedPtr == val2.m_CachedPtr)
				{
					return true;
				}
			}
			Object val3 = (Object)((objA is Object) ? objA : null);
			if (val3 != null)
			{
				Object val4 = (Object)((objB is Object) ? objB : null);
				if (val4 != null && ((Il2CppObjectBase)val3).Pointer == ((Il2CppObjectBase)val4).Pointer)
				{
					return true;
				}
			}
			return false;
		}

		public static string ReflectionExToString(this Exception e, bool innerMost = true)
		{
			if (e == null)
			{
				return "The exception was null.";
			}
			if (innerMost)
			{
				e = e.GetInnerMostException();
			}
			return $"{e.GetType()}: {e.Message}";
		}

		public static Exception GetInnerMostException(this Exception e)
		{
			while (e != null && e.InnerException != null && !(e.InnerException is RuntimeWrappedException))
			{
				e = e.InnerException;
			}
			return e;
		}
	}
	internal class Il2CppDictionary : IEnumerator<DictionaryEntry>, IEnumerator, IDisposable
	{
		private readonly Il2CppEnumerator keysEnumerator;

		private readonly Il2CppEnumerator valuesEnumerator;

		public object Current => new DictionaryEntry(keysEnumerator.Current, valuesEnumerator.Current);

		DictionaryEntry IEnumerator<DictionaryEntry>.Current => new DictionaryEntry(keysEnumerator.Current, valuesEnumerator.Current);

		public Il2CppDictionary(Il2CppEnumerator keysEnumerator, Il2CppEnumerator valuesEnumerator)
		{
			this.keysEnumerator = keysEnumerator;
			this.valuesEnumerator = valuesEnumerator;
		}

		public bool MoveNext()
		{
			if (keysEnumerator.MoveNext())
			{
				return valuesEnumerator.MoveNext();
			}
			return false;
		}

		public void Dispose()
		{
			throw new NotImplementedException();
		}

		public void Reset()
		{
			throw new NotImplementedException();
		}
	}
	internal class Il2CppEnumerator : IEnumerator
	{
		private readonly object enumerator;

		private readonly MethodInfo m_GetEnumerator;

		private readonly object instanceForMoveNext;

		private readonly MethodInfo m_MoveNext;

		private readonly object instanceForCurrent;

		private readonly MethodInfo p_Current;

		public object Current => p_Current.Invoke(instanceForCurrent, null);

		public bool MoveNext()
		{
			return (bool)m_MoveNext.Invoke(instanceForMoveNext, null);
		}

		public void Reset()
		{
			throw new NotImplementedException();
		}

		public Il2CppEnumerator(object instance, Type type)
		{
			m_GetEnumerator = type.GetMethod("GetEnumerator") ?? type.GetMethod("System_Collections_IEnumerable_GetEnumerator", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			enumerator = m_GetEnumerator.Invoke(instance.TryCast(m_GetEnumerator.DeclaringType), ArgumentUtility.EmptyArgs);
			if (enumerator == null)
			{
				throw new Exception("GetEnumerator returned null");
			}
			Type actualType = enumerator.GetActualType();
			m_MoveNext = actualType.GetMethod("MoveNext") ?? actualType.GetMethod("System_Collections_IEnumerator_MoveNext", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			instanceForMoveNext = enumerator.TryCast(m_MoveNext.DeclaringType);
			p_Current = actualType.GetProperty("Current")?.GetGetMethod() ?? actualType.GetMethod("System_Collections_IEnumerator_get_Current", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			instanceForCurrent = enumerator.TryCast(p_Current.DeclaringType);
		}
	}
	public class Il2CppReflection : ReflectionUtility
	{
		internal Stopwatch initStopwatch = new Stopwatch();

		internal static readonly Dictionary<string, MethodInfo> unboxMethods = new Dictionary<string, MethodInfo>();

		internal static readonly IReadOnlyDictionary<string, Type> il2cppPrimitivesToMono = new Dictionary<string, Type>
		{
			{
				"Il2CppSystem.Boolean",
				typeof(bool)
			},
			{
				"Il2CppSystem.Byte",
				typeof(byte)
			},
			{
				"Il2CppSystem.SByte",
				typeof(sbyte)
			},
			{
				"Il2CppSystem.Char",
				typeof(char)
			},
			{
				"Il2CppSystem.Double",
				typeof(double)
			},
			{
				"Il2CppSystem.Single",
				typeof(float)
			},
			{
				"Il2CppSystem.Int32",
				typeof(int)
			},
			{
				"Il2CppSystem.UInt32",
				typeof(uint)
			},
			{
				"Il2CppSystem.Int64",
				typeof(long)
			},
			{
				"Il2CppSystem.UInt64",
				typeof(ulong)
			},
			{
				"Il2CppSystem.Int16",
				typeof(short)
			},
			{
				"Il2CppSystem.UInt16",
				typeof(ushort)
			},
			{
				"Il2CppSystem.IntPtr",
				typeof(IntPtr)
			},
			{
				"Il2CppSystem.UIntPtr",
				typeof(UIntPtr)
			}
		};

		private const string IL2CPP_STRING_FULLNAME = "Il2CppSystem.String";

		private const string STRING_FULLNAME = "System.String";

		private static readonly Dictionary<string, IntPtr> cppClassPointers = new Dictionary<string, IntPtr>();

		private static readonly Dictionary<string, Type> obfuscatedToDeobfuscatedTypes = new Dictionary<string, Type>();

		private static readonly Dictionary<string, string> deobfuscatedToObfuscatedNames = new Dictionary<string, string>();

		internal static IntPtr cppIEnumerablePointer;

		internal static IntPtr cppIDictionaryPointer;

		protected override void Initialize()
		{
			base.Initialize();
			ReflectionUtility.Initializing = true;
			((MonoBehaviour)UniversalBehaviour.Instance).StartCoroutine(InitCoroutine().WrapToIl2Cpp());
		}

		private IEnumerator InitCoroutine()
		{
			initStopwatch.Start();
			Stopwatch sw = new Stopwatch();
			sw.Start();
			IEnumerator coro = TryLoadGameModules();
			while (coro.MoveNext())
			{
				yield return null;
			}
			Universe.Log($"Loaded Unhollowed modules in {(float)sw.ElapsedMilliseconds * 0.001f} seconds.");
			sw.Reset();
			sw.Start();
			BuildDeobfuscationCache();
			Universe.Log($"Setup deobfuscation cache in {(float)sw.ElapsedMilliseconds * 0.001f} seconds.");
			ReflectionUtility.OnTypeLoaded += TryCacheDeobfuscatedType;
			ReflectionUtility.Initializing = false;
		}

		internal override Type Internal_GetTypeByName(string fullName)
		{
			if (obfuscatedToDeobfuscatedTypes.TryGetValue(fullName, out var value))
			{
				return value;
			}
			return base.Internal_GetTypeByName(fullName);
		}

		internal override Type Internal_GetActualType(object obj)
		{
			if (obj == null)
			{
				return null;
			}
			Type type = obj.GetType();
			try
			{
				if (il2cppPrimitivesToMono.TryGetValue(type.FullName, out var value))
				{
					return value;
				}
				Il2CppObjectBase val = (Il2CppObjectBase)((obj is Il2CppObjectBase) ? obj : null);
				if (val != null)
				{
					if (type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(Il2CppArrayBase<>))
					{
						return type;
					}
					IntPtr intPtr = IL2CPP.il2cpp_object_get_class(val.Pointer);
					Object val2 = (Object)((obj is Object) ? obj : null);
					Type cppType = ((val2 == null) ? Il2CppType.TypeFromPointer(intPtr, "<unknown type>") : val2.GetIl2CppType());
					return GetUnhollowedType(cppType) ?? type;
				}
			}
			catch (Exception ex)
			{
				Universe.LogWarning("Exception in IL2CPP GetActualType: " + ex);
			}
			return type;
		}

		public static Type GetUnhollowedType(Type cppType)
		{
			if (cppType.IsArray)
			{
				return GetArrayBaseForArray(cppType);
			}
			if (ReflectionUtility.AllTypes.TryGetValue(cppType.FullName, out var value) && value.IsPrimitive)
			{
				return value;
			}
			if (IsString(cppType))
			{
				return typeof(string);
			}
			string text = cppType.FullName;
			if (obfuscatedToDeobfuscatedTypes.TryGetValue(text, out var value2))
			{
				return value2;
			}
			bool num = text.StartsWith("Unity") && text.Contains('.');
			bool flag = "InjectedMonoTypes".Equals(cppType.Assembly.GetName().Name);
			if (!num && !flag)
			{
				text = ((!text.Contains('.')) ? ("Il2Cpp." + text) : ("Il2Cpp" + text));
			}
			if (!ReflectionUtility.AllTypes.TryGetValue(text, out var value3))
			{
				string text2;
				try
				{
					text2 = Il2CppTypeRedirector.GetAssemblyQualifiedName(cppType);
				}
				catch
				{
					text2 = cppType.AssemblyQualifiedName;
				}
				for (int i = 0; i < text2.Length; i++)
				{
					char c = text2[i];
					if (c == '<' || c == '>')
					{
						text2 = text2.Remove(i, 1);
						text2 = text2.Insert(i, "_");
					}
				}
				value3 = Type.GetType(text2);
				if (value3 == null)
				{
					Universe.LogWarning($"Failed to get Unhollowed type from '{text2}' (originally '{cppType.AssemblyQualifiedName}')!");
				}
			}
			return value3;
		}

		internal static Type GetArrayBaseForArray(Type cppType)
		{
			Type unhollowedType = GetUnhollowedType(cppType.GetElementType());
			if (unhollowedType == null)
			{
				throw new Exception("Could not get unhollowed Element type for Array: " + cppType.FullName);
			}
			if (unhollowedType.IsValueType)
			{
				return typeof(Il2CppStructArray<>).MakeGenericType(unhollowedType);
			}
			if (unhollowedType == typeof(string))
			{
				return typeof(Il2CppStringArray);
			}
			return typeof(Il2CppReferenceArray<>).MakeGenericType(unhollowedType);
		}

		internal override object Internal_TryCast(object obj, Type toType)
		{
			if (obj == null)
			{
				return null;
			}
			Type type = obj.GetType();
			if (type == toType)
			{
				return obj;
			}
			if (type.IsValueType)
			{
				if (IsIl2CppPrimitive(type) && toType.IsPrimitive)
				{
					return MakeMonoPrimitive(obj);
				}
				if (IsIl2CppPrimitive(toType))
				{
					return MakeIl2CppPrimitive(toType, obj);
				}
				if (typeof(Object).IsAssignableFrom(toType))
				{
					return BoxIl2CppObject(obj).TryCast(toType);
				}
				return obj;
			}
			if (obj is string && typeof(Object).IsAssignableFrom(toType))
			{
				return BoxStringToType(obj, toType);
			}
			Il2CppObjectBase val = (Il2CppObjectBase)((obj is Il2CppObjectBase) ? obj : null);
			if (val == null)
			{
				return obj;
			}
			if (toType.IsValueType)
			{
				return UnboxCppObject(val, toType);
			}
			if (toType == typeof(string))
			{
				return UnboxString(obj);
			}
			if (toType.IsSubclassOf(typeof(Il2CppObjectBase)))
			{
				if (!Il2CppTypeNotNull(toType, out var il2cppPtr))
				{
					return obj;
				}
				IntPtr intPtr = IL2CPP.il2cpp_object_get_class(val.Pointer);
				if (!IL2CPP.il2cpp_class_is_assignable_from(il2cppPtr, intPtr))
				{
					return obj;
				}
				if (RuntimeSpecificsStore.IsInjected(il2cppPtr))
				{
					object monoObjectFromIl2CppPointer = ClassInjectorBase.GetMonoObjectFromIl2CppPointer(val.Pointer);
					if (monoObjectFromIl2CppPointer != null)
					{
						return monoObjectFromIl2CppPointer;
					}
				}
				try
				{
					return Activator.CreateInstance(toType, val.Pointer);
				}
				catch
				{
					return obj;
				}
			}
			return obj;
		}

		public static object UnboxCppObject(Il2CppObjectBase cppObj, Type toType)
		{
			if (!toType.IsValueType)
			{
				return null;
			}
			try
			{
				if (toType.IsEnum)
				{
					Type type = ((object)cppObj).GetType();
					if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
					{
						object obj = cppObj.TryCast(type);
						if ((bool)type.GetProperty("HasValue").GetValue(obj, null))
						{
							PropertyInfo property = type.GetProperty("Value");
							return Enum.Parse(toType, property.GetValue(obj, null).ToString());
						}
						return cppObj;
					}
					return Enum.Parse(toType, ((Object)cppObj.TryCast<Enum>()).ToString());
				}
				string assemblyQualifiedName = toType.AssemblyQualifiedName;
				if (!unboxMethods.ContainsKey(assemblyQualifiedName))
				{
					unboxMethods.Add(assemblyQualifiedName, typeof(Il2CppObjectBase).GetMethod("Unbox").MakeGenericMethod(toType));
				}
				return unboxMethods[assemblyQualifiedName].Invoke(cppObj, ArgumentUtility.EmptyArgs);
			}
			catch (Exception ex)
			{
				Universe.LogWarning("Exception Unboxing Il2Cpp object to struct: " + ex);
				return null;
			}
		}

		public static Object BoxIl2CppObject(object value)
		{
			if (value == null)
			{
				return null;
			}
			try
			{
				Type type = value.GetType();
				if (!type.IsValueType)
				{
					return null;
				}
				if (type.IsEnum)
				{
					return Enum.Parse(Il2CppType.From(type), value.ToString());
				}
				if (type.IsPrimitive && ReflectionUtility.AllTypes.TryGetValue("Il2Cpp" + type.FullName, out var value2))
				{
					return BoxIl2CppObject(MakeIl2CppPrimitive(value2, value), value2);
				}
				return BoxIl2CppObject(value, type);
			}
			catch (Exception ex)
			{
				Universe.LogWarning("Exception in BoxIl2CppObject: " + ex);
				return null;
			}
		}

		private static Object BoxIl2CppObject(object cppStruct, Type structType)
		{
			object? obj = AccessTools.Method(structType, "BoxIl2CppObject", ArgumentUtility.EmptyTypes, (Type[])null).Invoke(cppStruct, ArgumentUtility.EmptyArgs);
			return (Object)((obj is Object) ? obj : null);
		}

		public static bool IsIl2CppPrimitive(object obj)
		{
			return IsIl2CppPrimitive(obj.GetType());
		}

		public static bool IsIl2CppPrimitive(Type type)
		{
			return il2cppPrimitivesToMono.ContainsKey(type.FullName);
		}

		public static object MakeMonoPrimitive(object cppPrimitive)
		{
			return AccessTools.Field(cppPrimitive.GetType(), "m_value").GetValue(cppPrimitive);
		}

		public static object MakeIl2CppPrimitive(Type cppType, object monoValue)
		{
			object obj = Activator.CreateInstance(cppType);
			AccessTools.Field(cppType, "m_value").SetValue(obj, monoValue);
			return obj;
		}

		public static bool IsString(object obj)
		{
			if (obj is string || obj is String)
			{
				return true;
			}
			Object val = (Object)((obj is Object) ? obj : null);
			if (val != null)
			{
				Type il2CppType = val.GetIl2CppType();
				if (!(il2CppType.FullName == "Il2CppSystem.String"))
				{
					return il2CppType.FullName == "System.String";
				}
				return true;
			}
			return false;
		}

		public static bool IsString(Type type)
		{
			if (!(type == typeof(string)))
			{
				return type == typeof(String);
			}
			return true;
		}

		public static bool IsString(Type cppType)
		{
			if (!(cppType.FullName == "System.String"))
			{
				return cppType.FullName == "Il2CppSystem.String";
			}
			return true;
		}

		public static object BoxStringToType(object value, Type castTo)
		{
			if (castTo == typeof(String))
			{
				return String.op_Implicit(value as string);
			}
			return Object.op_Implicit(value as string);
		}

		public static string UnboxString(object value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			if (value is string result)
			{
				return result;
			}
			Object val = (Object)((value is Object) ? value : null);
			if (val == null)
			{
				throw new NotSupportedException("Unable to unbox string from type " + value.GetActualType().FullName + ".");
			}
			string text = String.op_Implicit((String)(object)((val is String) ? val : null));
			if (string.IsNullOrEmpty(text))
			{
				text = val.ToString();
			}
			return text;
		}

		public static bool Il2CppTypeNotNull(Type type)
		{
			IntPtr il2cppPtr;
			return Il2CppTypeNotNull(type, out il2cppPtr);
		}

		public static bool Il2CppTypeNotNull(Type type, out IntPtr il2cppPtr)
		{
			if (!cppClassPointers.TryGetValue(type.AssemblyQualifiedName, out il2cppPtr))
			{
				il2cppPtr = (IntPtr)typeof(Il2CppClassPointerStore<>).MakeGenericType(type).GetField("NativeClassPtr", BindingFlags.Static | BindingFlags.Public).GetValue(null);
				cppClassPointers.Add(type.AssemblyQualifiedName, il2cppPtr);
			}
			return il2cppPtr != IntPtr.Zero;
		}

		private static void BuildDeobfuscationCache()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type[] array = assemblies[i].TryGetTypes();
				for (int j = 0; j < array.Length; j++)
				{
					TryCacheDeobfuscatedType(array[j]);
				}
			}
		}

		private static void TryCacheDeobfuscatedType(Type type)
		{
			try
			{
				if (!type.CustomAttributes.Any())
				{
					return;
				}
				foreach (CustomAttributeData customAttribute in type.CustomAttributes)
				{
					if (customAttribute.AttributeType == typeof(ObfuscatedNameAttribute))
					{
						string text = customAttribute.ConstructorArguments[0].Value.ToString();
						obfuscatedToDeobfuscatedTypes.Add(text, type);
						deobfuscatedToObfuscatedNames.Add(type.FullName, text);
						break;
					}
				}
			}
			catch
			{
			}
		}

		internal override string Internal_ProcessTypeInString(string theString, Type type)
		{
			if (deobfuscatedToObfuscatedNames.TryGetValue(type.FullName, out var value))
			{
				return theString.Replace(value, type.FullName);
			}
			return theString;
		}

		internal override void Internal_FindSingleton(string[] possibleNames, Type type, BindingFlags flags, List<object> instances)
		{
			foreach (string name in possibleNames)
			{
				PropertyInfo property = type.GetProperty(name, flags);
				if (property != null)
				{
					object value = property.GetValue(null, null);
					if (value != null)
					{
						instances.Add(value);
						return;
					}
				}
			}
			base.Internal_FindSingleton(possibleNames, type, flags, instances);
		}

		internal IEnumerator TryLoadGameModules()
		{
			string unhollowed_Modules_Folder = ConfigManager.Unhollowed_Modules_Folder;
			if (Directory.Exists(unhollowed_Modules_Folder))
			{
				string[] files = Directory.GetFiles(unhollowed_Modules_Folder, "*.dll");
				foreach (string filePath in files)
				{
					if (initStopwatch.ElapsedMilliseconds > 10)
					{
						yield return null;
						initStopwatch.Reset();
						initStopwatch.Start();
					}
					DoLoadModule(filePath);
				}
			}
			else
			{
				Universe.LogWarning("Expected Unhollowed folder path does not exist: '" + unhollowed_Modules_Folder + "'. If you are using the standalone release, you can specify the Unhollowed modules path when you call CreateInstance().");
			}
		}

		internal bool DoLoadModule(string fullPath)
		{
			if (string.IsNullOrEmpty(fullPath) || !File.Exists(fullPath))
			{
				return false;
			}
			try
			{
				Assembly.LoadFrom(fullPath);
				return true;
			}
			catch
			{
				return false;
			}
		}

		protected override bool Internal_IsEnumerable(Type type)
		{
			if (base.Internal_IsEnumerable(type))
			{
				return true;
			}
			try
			{
				if (cppIEnumerablePointer == IntPtr.Zero)
				{
					Il2CppTypeNotNull(typeof(IEnumerable), out cppIEnumerablePointer);
				}
				if (cppIEnumerablePointer != IntPtr.Zero && Il2CppTypeNotNull(type, out var il2cppPtr) && IL2CPP.il2cpp_class_is_assignable_from(cppIEnumerablePointer, il2cppPtr))
				{
					return true;
				}
			}
			catch (Exception value)
			{
				Universe.LogWarning($"IEnumerable of type [{type.FullName}] failed to check: {value}");
			}
			return false;
		}

		protected override bool Internal_TryGetEntryType(Type enumerableType, out Type type)
		{
			if (base.Internal_TryGetEntryType(enumerableType, out type))
			{
				return true;
			}
			if (type.IsGenericType)
			{
				type = type.GetGenericArguments()[0];
				return true;
			}
			type = typeof(object);
			return false;
		}

		protected override bool Internal_TryGetEnumerator(object instance, out IEnumerator enumerator)
		{
			if (instance == null)
			{
				throw new ArgumentNullException("instance");
			}
			if (instance is IEnumerable)
			{
				return base.Internal_TryGetEnumerator(instance, out enumerator);
			}
			enumerator = null;
			Type actualType = instance.GetActualType();
			try
			{
				enumerator = new Il2CppEnumerator(instance, actualType);
				return true;
			}
			catch (Exception value)
			{
				Universe.LogWarning($"IEnumerable of type {actualType.FullName} failed to get enumerator: {value}");
				return false;
			}
		}

		protected override bool Internal_IsDictionary(Type type)
		{
			if (base.Internal_IsDictionary(type))
			{
				return true;
			}
			try
			{
				if (cppIDictionaryPointer == IntPtr.Zero && !Il2CppTypeNotNull(typeof(IDictionary), out cppIDictionaryPointer))
				{
					return false;
				}
				if (Il2CppTypeNotNull(type, out var il2cppPtr) && IL2CPP.il2cpp_class_is_assignable_from(cppIDictionaryPointer, il2cppPtr))
				{
					return true;
				}
			}
			catch (Exception value)
			{
				Universe.LogWarning($"IDictionary of type [{type.FullName}] failed to check : {value}");
			}
			return false;
		}

		protected override bool Internal_TryGetEntryTypes(Type type, out Type keys, out Type values)
		{
			if (base.Internal_TryGetEntryTypes(type, out keys, out values))
			{
				return true;
			}
			if (type.IsGenericType)
			{
				Type[] genericArguments = type.GetGenericArguments();
				if (genericArguments.Length == 2)
				{
					keys = genericArguments[0];
					values = genericArguments[1];
					return true;
				}
			}
			keys = typeof(object);
			values = typeof(object);
			return false;
		}

		protected override bool Internal_TryGetDictEnumerator(object dictionary, out IEnumerator<DictionaryEntry> dictEnumerator)
		{
			if (dictionary is IDictionary)
			{
				return base.Internal_TryGetDictEnumerator(dictionary, out dictEnumerator);
			}
			try
			{
				Type actualType = dictionary.GetActualType();
				if (typeof(Hashtable).IsAssignableFrom(actualType))
				{
					dictEnumerator = EnumerateCppHashTable(dictionary.TryCast<Hashtable>());
					return true;
				}
				PropertyInfo property = actualType.GetProperty("Keys");
				object value = property.GetValue(dictionary.TryCast(property.DeclaringType), null);
				PropertyInfo property2 = actualType.GetProperty("Values");
				object? value2 = property2.GetValue(dictionary.TryCast(property2.DeclaringType), null);
				Il2CppEnumerator keysEnumerator = new Il2CppEnumerator(value, value.GetActualType());
				Il2CppEnumerator valuesEnumerator = new Il2CppEnumerator(value2, value2.GetActualType());
				dictEnumerator = new Il2CppDictionary(keysEnumerator, valuesEnumerator);
				return true;
			}
			catch (Exception value3)
			{
				Universe.LogWarning($"IDictionary failed to enumerate: {value3}");
				dictEnumerator = null;
				return false;
			}
		}

		private static IEnumerator<DictionaryEntry> EnumerateCppHashTable(Hashtable hashtable)
		{
			for (int i = 0; i < ((Il2CppArrayBase<bucket>)(object)hashtable.buckets).Count; i++)
			{
				bucket val = ((Il2CppArrayBase<bucket>)(object)hashtable.buckets)[i];
				if (val != null && val.key != null)
				{
					yield return new DictionaryEntry(val.key, val.val);
				}
			}
		}
	}
	public class ReflectionUtility
	{
		public static bool Initializing;

		public const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		public static readonly SortedDictionary<string, Type> AllTypes = new SortedDictionary<string, Type>(StringComparer.OrdinalIgnoreCase);

		public static readonly List<string> AllNamespaces = new List<string>();

		private static readonly HashSet<string> uniqueNamespaces = new HashSet<string>();

		private static string[] allTypeNamesArray;

		private static readonly IReadOnlyDictionary<string, Type> shorthandToType = new Dictionary<string, Type>
		{
			{
				"object",
				typeof(object)
			},
			{
				"string",
				typeof(string)
			},
			{
				"bool",
				typeof(bool)
			},
			{
				"byte",
				typeof(byte)
			},
			{
				"sbyte",
				typeof(sbyte)
			},
			{
				"char",
				typeof(char)
			},
			{
				"decimal",
				typeof(decimal)
			},
			{
				"double",
				typeof(double)
			},
			{
				"float",
				typeof(float)
			},
			{
				"int",
				typeof(int)
			},
			{
				"uint",
				typeof(uint)
			},
			{
				"long",
				typeof(long)
			},
			{
				"ulong",
				typeof(ulong)
			},
			{
				"short",
				typeof(short)
			},
			{
				"ushort",
				typeof(ushort)
			},
			{
				"void",
				typeof(void)
			}
		};

		internal static readonly Dictionary<string, Type[]> baseTypes = new Dictionary<string, Type[]>();

		internal static ReflectionUtility Instance { get; private set; }

		public static event Action<Type> OnTypeLoaded;

		internal static void Init()
		{
			Instance = new Il2CppReflection();
			Instance.Initialize();
		}

		protected virtual void Initialize()
		{
			SetupTypeCache();
			Initializing = false;
		}

		public static string[] GetTypeNameArray()
		{
			if (allTypeNamesArray == null || allTypeNamesArray.Length != AllTypes.Count)
			{
				allTypeNamesArray = new string[AllTypes.Count];
				int num = 0;
				foreach (string key in AllTypes.Keys)
				{
					allTypeNamesArray[num] = key;
					num++;
				}
			}
			return allTypeNamesArray;
		}

		private static void SetupTypeCache()
		{
			if (!ConfigManager.Disable_Setup_Force_ReLoad_ManagedAssemblies && Universe.Context == RuntimeContext.Mono)
			{
				ForceLoadManagedAssemblies();
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				CacheTypes(assemblies[i]);
			}
			AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoaded;
		}

		private static void AssemblyLoaded(object sender, AssemblyLoadEventArgs args)
		{
			if (!(args.LoadedAssembly == null) && !(args.LoadedAssembly.GetName().Name == "completions"))
			{
				CacheTypes(args.LoadedAssembly);
			}
		}

		private static void ForceLoadManagedAssemblies()
		{
			string path = Path.Combine(Application.dataPath, "Managed");
			if (!Directory.Exists(path))
			{
				return;
			}
			string[] files = Directory.GetFiles(path, "*.dll");
			foreach (string assemblyFile in files)
			{
				try
				{
					Assembly.LoadFrom(assemblyFile).TryGetTypes();
				}
				catch
				{
				}
			}
		}

		internal static void CacheTypes(Assembly asm)
		{
			Type[] array = asm.TryGetTypes();
			foreach (Type type in array)
			{
				try
				{
					string text = type.Namespace;
					if (!string.IsNullOrEmpty(text) && uniqueNamespaces.Add(text))
					{
						int num = 0;
						foreach (string allNamespace in AllNamespaces)
						{
							if (text.CompareTo(allNamespace) >= 0)
							{
								num++;
								continue;
							}
							break;
						}
						AllNamespaces.Insert(num, text);
					}
				}
				catch (Exception value)
				{
					Universe.LogWarning($"THIS WARNING IS NOT BUG!!!! DON'T REPORT THIS!!!!!\n Can't cache type named {type.Name} Error: {value}");
				}
				AllTypes[type.FullName] = type;
				ReflectionUtility.OnTypeLoaded?.Invoke(type);
			}
		}

		public static Type GetTypeByName(string fullName)
		{
			return Instance.Internal_GetTypeByName(fullName);
		}

		internal virtual Type Internal_GetTypeByName(string fullName)
		{
			if (shorthandToType.TryGetValue(fullName, out var value))
			{
				return value;
			}
			AllTypes.TryGetValue(fullName, out var value2);
			if (value2 == null)
			{
				return Type.GetType(fullName);
			}
			return value2;
		}

		internal virtual Type Internal_GetActualType(object obj)
		{
			return obj?.GetType();
		}

		internal virtual object Internal_TryCast(object obj, Type castTo)
		{
			return obj;
		}

		public static string ProcessTypeInString(Type type, string theString)
		{
			return Instance.Internal_ProcessTypeInString(theString, type);
		}

		internal virtual string Internal_ProcessTypeInString(string theString, Type type)
		{
			return theString;
		}

		public static void FindSingleton(string[] possibleNames, Type type, BindingFlags flags, List<object> instances)
		{
			Instance.Internal_FindSingleton(possibleNames, type, flags, instances);
		}

		internal virtual void Internal_FindSingleton(string[] possibleNames, Type type, BindingFlags flags, List<object> instances)
		{
			foreach (string name in possibleNames)
			{
				FieldInfo field = type.GetField(name, flags);
				if (field != null)
				{
					object value = field.GetValue(null);
					if (value != null)
					{
						instances.Add(value);
						break;
					}
				}
			}
		}

		public static Type[] TryExtractTypesFromException(ReflectionTypeLoadException e)
		{
			try
			{
				return e.Types.Where((Type it) => it != null).ToArray();
			}
			catch
			{
				return ArgumentUtility.EmptyTypes;
			}
		}

		public static Type[] GetAllBaseTypes(object obj)
		{
			return GetAllBaseTypes(obj?.GetActualType());
		}

		public static Type[] GetAllBaseTypes(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			string assemblyQualifiedName = type.AssemblyQualifiedName;
			if (baseTypes.TryGetValue(assemblyQualifiedName, out var value))
			{
				return value;
			}
			List<Type> list = new List<Type>();
			while (type != null)
			{
				list.Add(type);
				type = type.BaseType;
			}
			value = list.ToArray();
			baseTypes.Add(assemblyQualifiedName, value);
			return value;
		}

		public static void GetImplementationsOf(Type baseType, Action<HashSet<Type>> onResultsFetched, bool allowAbstract, bool allowGeneric, bool allowEnum)
		{
			RuntimeHelper.StartCoroutine(DoGetImplementations(onResultsFetched, baseType, allowAbstract, allowGeneric, allowEnum));
		}

		private static IEnumerator DoGetImplementations(Action<HashSet<Type>> onResultsFetched, Type baseType, bool allowAbstract, bool allowGeneric, bool allowEnum)
		{
			List<Type> resolvedTypes = new List<Type>();
			OnTypeLoaded += ourListener;
			HashSet<Type> set = new HashSet<Type>();
			IEnumerator coro = GetImplementationsAsync(baseType, set, allowAbstract, allowGeneric, allowEnum, DefaultTypesEnumerator());
			while (coro.MoveNext())
			{
				yield return null;
			}
			OnTypeLoaded -= ourListener;
			if (resolvedTypes.Count > 0)
			{
				coro = GetImplementationsAsync(baseType, set, allowAbstract, allowGeneric, allowEnum, resolvedTypes.GetEnumerator());
				while (coro.MoveNext())
				{
					yield return null;
				}
			}
			onResultsFetched(set);
			void ourListener(Type t)
			{
				resolvedTypes.Add(t);
			}
		}

		private static IEnumerator<Type> DefaultTypesEnumerator()
		{
			string[] names = GetTypeNameArray();
			foreach (string key in names)
			{
				yield return AllTypes[key];
			}
		}

		private static IEnumerator GetImplementationsAsync(Type baseType, HashSet<Type> set, bool allowAbstract, bool allowGeneric, bool allowEnum, IEnumerator<Type> enumerator)
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			bool isGenericParam = baseType != null && baseType.IsGenericParameter;
			while (enumerator.MoveNext())
			{
				if (sw.ElapsedMilliseconds > 10)
				{
					yield return null;
					sw.Reset();
					sw.Start();
				}
				try
				{
					Type type = enumerator.Current;
					if (set.Contains(type) || (!allowAbstract && type.IsAbstract) || (!allowGeneric && type.IsGenericType) || (!allowEnum && type.IsEnum) || type.FullName.Contains("PrivateImplementationDetails") || type.FullName.Contains("DisplayClass") || type.FullName.Contains('<'))
					{
						continue;
					}
					if (!isGenericParam)
					{
						if (!(baseType != null) || baseType.IsAssignableFrom(type))
						{
							goto IL_01ee;
						}
					}
					else if ((!type.IsClass || !baseType.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) && (!type.IsValueType || !baseType.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) && !baseType.GetGenericParameterConstraints().Any((Type it) => !it.IsAssignableFrom(type)))
					{
						goto IL_01ee;
					}
					goto end_IL_0092;
					IL_01ee:
					set.Add(type);
					end_IL_0092:;
				}
				catch
				{
				}
			}
		}

		public static bool IsEnumerable(Type type)
		{
			return Instance.Internal_IsEnumerable(type);
		}

		protected virtual bool Internal_IsEnumerable(Type type)
		{
			return typeof(IEnumerable).IsAssignableFrom(type);
		}

		public static bool TryGetEnumerator(object ienumerable, out IEnumerator enumerator)
		{
			return Instance.Internal_TryGetEnumerator(ienumerable, out enumerator);
		}

		protected virtual bool Internal_TryGetEnumerator(object list, out IEnumerator enumerator)
		{
			enumerator = (list as IEnumerable).GetEnumerator();
			return true;
		}

		public static bool TryGetEntryType(Type enumerableType, out Type type)
		{
			return Instance.Internal_TryGetEntryType(enumerableType, out type);
		}

		protected virtual bool Internal_TryGetEntryType(Type enumerableType, out Type type)
		{
			if (enumerableType.IsArray)
			{
				type = enumerableType.GetElementType();
				return true;
			}
			Type[] interfaces = enumerableType.GetInterfaces();
			foreach (Type type2 in interfaces)
			{
				if (type2.IsGenericType)
				{
					Type genericTypeDefinition = type2.GetGenericTypeDefinition();
					if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>))
					{
						type = type2.GetGenericArguments()[0];
						return true;
					}
				}
			}
			type = typeof(object);
			return false;
		}

		public static bool IsDictionary(Type type)
		{
			return Instance.Internal_IsDictionary(type);
		}

		protected virtual bool Internal_IsDictionary(Type type)
		{
			return typeof(IDictionary).IsAssignableFrom(type);
		}

		public static bool TryGetDictEnumerator(object dictionary, out IEnumerator<DictionaryEntry> dictEnumerator)
		{
			return Instance.Internal_TryGetDictEnumerator(dictionary, out dictEnumerator);
		}

		protected virtual bool Internal_TryGetDictEnumerator(object dictionary, out IEnumerator<DictionaryEntry> dictEnumerator)
		{
			dictEnumerator = EnumerateDictionary((IDictionary)dictionary);
			return true;
		}

		private IEnumerator<DictionaryEntry> EnumerateDictionary(IDictionary dict)
		{
			IDictionaryEnumerator enumerator = dict.GetEnumerator();
			while (enumerator.MoveNext())
			{
				yield return new DictionaryEntry(enumerator.Key, enumerator.Value);
			}
		}

		public static bool TryGetEntryTypes(Type dictionaryType, out Type keys, out Type values)
		{
			return Instance.Internal_TryGetEntryTypes(dictionaryType, out keys, out values);
		}

		protected virtual bool Internal_TryGetEntryTypes(Type dictionaryType, out Type keys, out Type values)
		{
			Type[] interfaces = dictionaryType.GetInterfaces();
			foreach (Type type in interfaces)
			{
				if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<, >))
				{
					Type[] genericArguments = type.GetGenericArguments();
					keys = genericArguments[0];
					values = genericArguments[1];
					return true;
				}
			}
			keys = typeof(object);
			values = typeof(object);
			return false;
		}
	}
	public abstract class RuntimeHelper
	{
		internal static RuntimeHelper Instance { get; private set; }

		internal static void Init()
		{
			Instance = new Il2CppProvider();
			Instance.OnInitialize();
		}

		protected internal abstract void OnInitialize();

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			return Instance.Internal_StartCoroutine(routine);
		}

		protected internal abstract Coroutine Internal_StartCoroutine(IEnumerator routine);

		public static void StopCoroutine(Coroutine coroutine)
		{
			Instance.Internal_StopCoroutine(coroutine);
		}

		protected internal abstract void Internal_StopCoroutine(Coroutine coroutine);

		public static T AddComponent<T>(GameObject obj, Type type) where T : Component
		{
			return Instance.Internal_AddComponent<T>(obj, type);
		}

		protected internal abstract T Internal_AddComponent<T>(GameObject obj, Type type) where T : Component;

		public static ScriptableObject CreateScriptable(Type type)
		{
			return Instance.Internal_CreateScriptable(type);
		}

		protected internal abstract ScriptableObject Internal_CreateScriptable(Type type);

		public static string LayerToName(int layer)
		{
			return Instance.Internal_LayerToName(layer);
		}

		protected internal abstract string Internal_LayerToName(int layer);

		public static T[] FindObjectsOfTypeAll<T>() where T : Object
		{
			return Instance.Internal_FindObjectsOfTypeAll<T>();
		}

		public static Object[] FindObjectsOfTypeAll(Type type)
		{
			return Instance.Internal_FindObjectsOfTypeAll(type);
		}

		protected internal abstract T[] Internal_FindObjectsOfTypeAll<T>() where T : Object;

		protected internal abstract Object[] Internal_FindObjectsOfTypeAll(Type type);

		public static void GraphicRaycast(GraphicRaycaster raycaster, PointerEventData data, List<RaycastResult> list)
		{
			Instance.Internal_GraphicRaycast(raycaster, data, list);
		}

		protected internal abstract void Internal_GraphicRaycast(GraphicRaycaster raycaster, PointerEventData data, List<RaycastResult> list);

		public static GameObject[] GetRootGameObjects(Scene scene)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Instance.Internal_GetRootGameObjects(scene);
		}

		protected internal abstract GameObject[] Internal_GetRootGameObjects(Scene scene);

		public static int GetRootCount(Scene scene)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Instance.Internal_GetRootCount(scene);
		}

		protected internal abstract int Internal_GetRootCount(Scene scene);

		public static void SetColorBlockAuto(Selectable selectable, Color baseColor)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_001c: 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)
			Instance.Internal_SetColorBlock(selectable, baseColor, baseColor * 1.2f, baseColor * 0.8f);
		}

		public static void SetColorBlock(Selectable selectable, ColorBlock colors)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Instance.Internal_SetColorBlock(selectable, colors);
		}

		protected internal abstract void Internal_SetColorBlock(Selectable selectable, ColorBlock colors);

		public static void SetColorBlock(Selectable selectable, Color? normal = null, Color? highlighted = null, Color? pressed = null, Color? disabled = null)
		{
			Instance.Internal_SetColorBlock(selectable, normal, highlighted, pressed, disabled);
		}

		protected internal abstract void Internal_SetColorBlock(Selectable selectable, Color? normal = null, Color? highlighted = null, Color? pressed = null, Color? disabled = null);
	}
	public class AssetBundle : Object
	{
		internal delegate IntPtr d_LoadFromFile(IntPtr path, uint crc, ulong offset);

		private delegate IntPtr d_LoadFromMemory(IntPtr binary, uint crc);

		public delegate IntPtr d_GetAllLoadedAssetBundles_Native();

		internal delegate IntPtr d_LoadAssetWithSubAssets_Internal(IntPtr _this, IntPtr name, IntPtr type);

		internal delegate IntPtr d_LoadAsset_Internal(IntPtr _this, IntPtr name, IntPtr type);

		internal delegate void d_Unload(IntPtr _this, bool unloadAllLoadedObjects);

		public readonly IntPtr m_bundlePtr = IntPtr.Zero;

		static AssetBundle()
		{
			ClassInjector.RegisterTypeInIl2Cpp<AssetBundle>();
		}

		[HideFromIl2Cpp]
		public static AssetBundle LoadFromFile(string path)
		{
			IntPtr intPtr = ICallManager.GetICallUnreliable<d_LoadFromFile>(new string[2] { "UnityEngine.AssetBundle::LoadFromFile_Internal", "UnityEngine.AssetBundle::LoadFromFile" })(IL2CPP.ManagedStringToIl2Cpp(path), 0u, 0uL);
			if (!(intPtr != IntPtr.Zero))
			{
				return null;
			}
			return new AssetBundle(intPtr);
		}

		[HideFromIl2Cpp]
		public static AssetBundle LoadFromMemory(byte[] binary, uint crc = 0u)
		{
			IntPtr intPtr = ICallManager.GetICallUnreliable<d_LoadFromMemory>(new string[2] { "UnityEngine.AssetBundle::LoadFromMemory_Internal", "UnityEngine.AssetBundle::LoadFromMemory" })(((Il2CppObjectBase)Il2CppStructArray<byte>.op_Implicit(binary)).Pointer, crc);
			if (!(intPtr != IntPtr.Zero))
			{
				return null;
			}
			return new AssetBundle(intPtr);
		}

		[HideFromIl2Cpp]
		public static AssetBundle[] GetAllLoadedAssetBundles()
		{
			IntPtr intPtr = ICallManager.GetICall<d_GetAllLoadedAssetBundles_Native>("UnityEngine.AssetBundle::GetAllLoadedAssetBundles_Native")();
			if (!(intPtr != IntPtr.Zero))
			{
				return null;
			}
			return Il2CppArrayBase<AssetBundle>.op_Implicit((Il2CppArrayBase<AssetBundle>)(object)new Il2CppReferenceArray<AssetBundle>(intPtr));
		}

		public AssetBundle(IntPtr ptr)
			: base(ptr)
		{
			m_bundlePtr = ptr;
		}

		[HideFromIl2Cpp]
		public Object[] LoadAllAssets()
		{
			IntPtr intPtr = ICallManager.GetICall<d_LoadAssetWithSubAssets_Internal>("UnityEngine.AssetBundle::LoadAssetWithSubAssets_Internal")(m_bundlePtr, IL2CPP.ManagedStringToIl2Cpp(""), ((Il2CppObjectBase)Il2CppType.Of<Object>()).Pointer);
			if (!(intPtr != IntPtr.Zero))
			{
				return (Object[])(object)new Object[0];
			}
			return Il2CppArrayBase<Object>.op_Implicit((Il2CppArrayBase<Object>)(object)new Il2CppReferenceArray<Object>(intPtr));
		}

		[HideFromIl2Cpp]
		public T LoadAsset<T>(string name) where T : Object
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			IntPtr intPtr = ICallManager.GetICall<d_LoadAsset_Internal>("UnityEngine.AssetBundle::LoadAsset_Internal")(m_bundlePtr, IL2CPP.ManagedStringToIl2Cpp(name), ((Il2CppObjectBase)Il2CppType.Of<T>()).Pointer);
			if (!(intPtr != IntPtr.Zero))
			{
				return default(T);
			}
			return ((Il2CppObjectBase)new Object(intPtr)).TryCast<T>();
		}

		[HideFromIl2Cpp]
		public void Unload(bool unloadAllLoadedObjects)
		{
			ICallManager.GetICall<d_Unload>("UnityEngine.AssetBundle::Unload")(m_bundlePtr, unloadAllLoadedObjects);
		}
	}
	public static class Il2CppExtensions
	{
		public static void AddListener(this UnityEvent action, Action listener)
		{
			action.AddListener(UnityAction.op_Implicit(listener));
		}

		public static void AddListener<T>(this UnityEvent<T> action, Action<T> listener)
		{
			action.AddListener(UnityAction<T>.op_Implicit(listener));
		}

		public static void RemoveListener(this UnityEvent action, Action listener)
		{
			action.RemoveListener(UnityAction.op_Implicit(listener));
		}

		public static void RemoveListener<T>(this UnityEvent<T> action, Action<T> listener)
		{
			action.RemoveListener(UnityAction<T>.op_Implicit(listener));
		}

		public static void SetChildControlHeight(this HorizontalOrVerticalLayoutGroup group, bool value)
		{
			group.childControlHeight = value;
		}

		public static void SetChildControlWidth(this HorizontalOrVerticalLayoutGroup group, bool value)
		{
			group.childControlWidth = value;
		}
	}
	internal class UniversalBehaviour : MonoBehaviour
	{
		private static Delegate queuedDelegate;

		internal static UniversalBehaviour Instance { get; private set; }

		internal static void Setup()
		{
			//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: Expected O, but got Unknown
			//IL_0015: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			ClassInjector.RegisterTypeInIl2Cpp<UniversalBehaviour>();
			GameObject val = new GameObject("UniverseLibBehaviour");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D);
			Instance = val.AddComponent<UniversalBehaviour>();
		}

		internal void Update()
		{
			Universe.Update();
		}

		public UniversalBehaviour(IntPtr ptr)
			: base(ptr)
		{
		}

		internal static void InvokeDelegate(Delegate method)
		{
			queuedDelegate = method;
			((MonoBehaviour)Instance).Invoke("InvokeQueuedAction", 0f);
		}

		private void InvokeQueuedAction()
		{
			try
			{
				Delegate obj = queuedDelegate;
				queuedDelegate = null;
				obj?.DynamicInvoke();
			}
			catch (Exception value)
			{
				Universe.LogWarning($"Exception invoking action from IL2CPP thread: {value}");
			}
		}
	}
	public static class Universe
	{
		public enum GlobalState
		{
			WaitingToSetup,
			SettingUp,
			SetupCompleted
		}

		public const string NAME = "UniverseLib";

		public const string VERSION = "1.5.10";

		public const string AUTHOR = "Sinai, yukieiji";

		public const string GUID = "com.sinai.universelib";

		private static float startupDelay;

		private static Action<string, LogType> logHandler;

		public static RuntimeContext Context { get; } = RuntimeContext.IL2CPP;

		public static GlobalState CurrentGlobalState { get; private set; }

		internal static Harmony Harmony { get; } = new Harmony("com.sinai.universelib");

		private static event Action OnInitialized;

		public static void Init(Action onInitialized = null, Action<string, LogType> logHandler = null)
		{
			Init(1f, onInitialized, logHandler, default(UniverseLibConfig));
		}

		public static void Init(float startupDelay, Action onInitialized, Action<string, LogType> logHandler, UniverseLibConfig config)
		{
			if (CurrentGlobalState == GlobalState.SetupCompleted)
			{
				InvokeOnInitialized(onInitialized);
				return;
			}
			if (startupDelay > Universe.startupDelay)
			{
				Universe.startupDelay = startupDelay;
			}
			ConfigManager.LoadConfig(config);
			OnInitialized += onInitialized;
			if (logHandler != null && Universe.logHandler == null)
			{
				Universe.logHandler = logHandler;
			}
			if (CurrentGlobalState == GlobalState.WaitingToSetup)
			{
				CurrentGlobalState = GlobalState.SettingUp;
				Log("UniverseLib 1.5.10 initializing...");
				UniversalBehaviour.Setup();
				ReflectionUtility.Init();
				RuntimeHelper.Init();
				RuntimeHelper.Instance.Internal_StartCoroutine(SetupCoroutine());
				Log("Finished UniverseLib initial setup.");
			}
		}

		internal static void Update()
		{
			UniversalUI.Update();
		}

		private static IEnumerator SetupCoroutine()
		{
			yield return null;
			Stopwatch sw = new Stopwatch();
			sw.Start();
			while (ReflectionUtility.Initializing || (float)sw.ElapsedMilliseconds * 0.001f < startupDelay)
			{
				yield return null;
			}
			InputManager.Init();
			UniversalUI.Init();
			Log("UniverseLib 1.5.10 initialized.");
			CurrentGlobalState = GlobalState.SetupCompleted;
			InvokeOnInitialized(Universe.OnInitialized);
		}

		private static void InvokeOnInitialized(Action onInitialized)
		{
			if (onInitialized == null)
			{
				return;
			}
			Delegate[] invocationList = onInitialized.GetInvocationList();
			foreach (Delegate obj in invocationList)
			{
				try
				{
					obj.DynamicInvoke();
				}
				catch (Exception value)
				{
					LogWarning($"Exception invoking onInitialized callback! {value}");
				}
			}
		}

		internal static void Log(object message)
		{
			Log(message, (LogType)3);
		}

		internal static void LogWarning(object message)
		{
			Log(message, (LogType)2);
		}

		internal static void LogError(object message)
		{
			Log(message, (LogType)0);
		}

		private static void Log(object message, LogType logType)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (logHandler != null)
			{
				logHandler("[UniverseLib] " + (message?.ToString() ?? string.Empty), logType);
			}
		}

		internal static bool Patch(Type type, string methodName, MethodType methodType, Type[] arguments = null, MethodInfo prefix = null, MethodInfo postfix = null, MethodInfo finalizer = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			try
			{
				string text = (((int)methodType == 1) ? "get_" : (((int)methodType != 2) ? string.Empty : "set_"));
				string text2 = text;
				MethodInfo methodInfo = ((arguments == null) ? type.GetMethod(text2 + methodName, AccessTools.all) : type.GetMethod(text2 + methodName, AccessTools.all, null, arguments, null));
				if (methodInfo == null)
				{
					return false;
				}
				if (Il2CppType.From(type, false) != (Type)null && Il2CppInteropUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod((MethodBase)methodInfo) == null)
				{
					Log("\t IL2CPP method has no corresponding pointer, aborting patch of " + type.FullName + "." + methodName);
					return false;
				}
				PatchProcessor val = Harmony.CreateProcessor((MethodBase)methodInfo);
				if (prefix != null)
				{
					val.AddPrefix(new HarmonyMethod(prefix));
				}
				if (postfix != null)
				{
					val.AddPostfix(new HarmonyMethod(postfix));
				}
				if (finalizer != null)
				{
					val.AddFinalizer(new HarmonyMethod(finalizer));
				}
				val.Patch();
				return true;
			}
			catch (Exception value)
			{
				LogWarning($"\t Exception patching {type.FullName}.{methodName}: {value}");
				return false;
			}
		}

		internal static bool Patch(Type type, string[] possibleNames, MethodType methodType, Type[] arguments = null, MethodInfo prefix = null, MethodInfo postfix = null, MethodInfo finalizer = null)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			foreach (string methodName in possibleNames)
			{
				if (Patch(type, methodName, methodType, arguments, prefix, postfix, finalizer))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool Patch(Type type, string[] possibleNames, MethodType methodType, Type[][] possibleArguments, MethodInfo prefix = null, MethodInfo postfix = null, MethodInfo finalizer = null)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			foreach (string methodName in possibleNames)
			{
				foreach (Type[] arguments in possibleArguments)
				{
					if (Patch(type, methodName, methodType, arguments, prefix, postfix, finalizer))
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static bool Patch(Type type, string methodName, MethodType methodType, Type[][] possibleArguments, MethodInfo prefix = null, MethodInfo postfix = null, MethodInfo finalizer = null)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			foreach (Type[] arguments in possibleArguments)
			{
				if (Patch(type, methodName, methodType, arguments, prefix, postfix, finalizer))
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace UniverseLib.Utility
{
	public static class ArgumentUtility
	{
		public static readonly Type[] EmptyTypes = new Type[0];

		public static readonly object[] EmptyArgs = new object[0];

		public static readonly Type[] ParseArgs = new Type[1] { typeof(string) };
	}
	public static class IOUtility
	{
		private static readonly char[] invalidDirectoryCharacters = Path.GetInvalidPathChars();

		private static readonly char[] invalidFilenameCharacters = Path.GetInvalidFileNameChars();

		public static string EnsureValidFilePath(string fullPathWithFile)
		{
			fullPathWithFile = string.Concat(fullPathWithFile.Split(invalidDirectoryCharacters));
			Directory.CreateDirectory(Path.GetDirectoryName(fullPathWithFile));
			return fullPathWithFile;
		}

		public static string EnsureValidFilename(string filename)
		{
			return string.Concat(filename.Split(invalidFilenameCharacters));
		}
	}
	public static class MiscUtility
	{
		public static bool ContainsIgnoreCase(this string _this, string s)
		{
			return CultureInfo.CurrentCulture.CompareInfo.IndexOf(_this, s, CompareOptions.IgnoreCase) >= 0;
		}

		public static bool HasFlag(this Enum flags, Enum value)
		{
			try
			{
				ulong num = Convert.ToUInt64(value);
				return (Convert.ToUInt64(flags) & num) == num;
			}
			catch
			{
				long num2 = Convert.ToInt64(value);
				return (Convert.ToInt64(flags) & num2) == num2;
			}
		}

		public static bool EndsWith(this StringBuilder sb, string _string)
		{
			int length = _string.Length;
			if (sb.Length < length)
			{
				return false;
			}
			int num = 0;
			int num2 = sb.Length - length;
			while (num2 < sb.Length)
			{
				if (sb[num2] != _string[num])
				{
					return false;
				}
				num2++;
				num++;
			}
			return true;
		}
	}
	public static class ParseUtility
	{
		internal delegate object ParseMethod(string input);

		internal delegate string ToStringMethod(object obj);

		public static readonly string NumberFormatString = "0.####";

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

		private static readonly HashSet<Type> nonPrimitiveTypes = new HashSet<Type>
		{
			typeof(string),
			typeof(decimal),
			typeof(DateTime)
		};

		private static readonly HashSet<Type> formattedTypes = new HashSet<Type>
		{
			typeof(float),
			typeof(double),
			typeof(decimal)
		};

		private static readonly Dictionary<string, string> typeInputExamples = new Dictionary<string, string>();

		private static readonly Dictionary<string, ParseMethod> customTypes = new Dictionary<string, ParseMethod>
		{
			{
				typeof(Vector2).FullName,
				TryParseVector2
			},
			{
				typeof(Vector3).FullName,
				TryParseVector3
			},
			{
				typeof(Vector4).FullName,
				TryParseVector4
			},
			{
				typeof(Quaternion).FullName,
				TryParseQuaternion
			},
			{
				typeof(Rect).FullName,
				TryParseRect
			},
			{
				typeof(Color).FullName,
				TryParseColor
			},
			{
				typeof(Color32).FullName,
				TryParseColor32
			},
			{
				typeof(LayerMask).FullName,
				TryParseLayerMask
			}
		};

		private static readonly Dictionary<string, ToStringMethod> customTypesToString = new Dictionary<string, ToStringMethod>
		{
			{
				typeof(Vector2).FullName,
				Vector2ToString
			},
			{
				typeof(Vector3).FullName,
				Vector3ToString
			},
			{
				typeof(Vector4).FullName,
				Vector4ToString
			},
			{
				typeof(Quaternion).FullName,
				QuaternionToString
			},
			{
				typeof(Rect).FullName,
				RectToString
			},
			{
				typeof(Color).FullName,
				ColorToString
			},
			{
				typeof(Color32).FullName,
				Color32ToString
			},
			{
				typeof(LayerMask).FullName,
				LayerMaskToString
			}
		};

		public static string FormatDecimalSequence(params object[] numbers)
		{
			if (numbers.Length == 0)
			{
				return null;
			}
			return string.Format(CultureInfo.CurrentCulture, GetSequenceFormatString(numbers.Length), numbers);
		}

		internal static string GetSequenceFormatString(int count)
		{
			if (count <= 0)
			{
				return null;
			}
			if (numSequenceStrings.ContainsKey(count))
			{
				return numSequenceStrings[count];
			}
			string[] array = new string[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = $"{{{i}:{NumberFormatString}}}";
			}
			string text = string.Join(" ", array);
			numSequenceStrings.Add(count, text);
			return text;
		}

		public static bool CanParse(Type type)
		{
			if (!string.IsNullOrEmpty(type?.FullName))
			{
				if (!type.IsPrimitive && !type.IsEnum && !nonPrimitiveTypes.Contains(type))
				{
					return customTypes.ContainsKey(type.FullName);
				}
				return true;
			}
			return false;
		}

		public static bool CanParse<T>()
		{
			return CanParse(typeof(T));
		}

		public static bool TryParse<T>(string input, out T obj, out Exception parseException)
		{
			object obj2;
			bool result = TryParse(input, typeof(T), out obj2, out parseException);
			if (obj2 != null)
			{
				obj = (T)obj2;
				return result;
			}
			obj = default(T);
			return result;
		}

		public static bool TryParse(string input, Type type, out object obj, out Exception parseException)
		{
			obj = null;
			parseException = null;
			if (type == null)
			{
				return false;
			}
			if (type == typeof(string))
			{
				obj = input;
				return true;
			}
			if (type.IsEnum)
			{
				try
				{
					obj = Enum.Parse(type, input);
					return true;
				}
				catch (Exception e)
				{
					parseException = e.GetInnerMostException();
					return false;
				}
			}
			try
			{
				if (customTypes.ContainsKey(type.FullName))
				{
					obj = customTypes[type.FullName](input);
				}
				else
				{
					obj = AccessTools.Method(type, "Parse", ArgumentUtility.ParseArgs, (Type[])null).Invoke(null, new object[1] { input });
				}
				return true;
			}
			catch (Exception e2)
			{
				Exception innerMostException = e2.GetInnerMostException();
				parseException = innerMostException;
			}
			return false;
		}

		public static string ToStringForInput<T>(object obj)
		{
			return ToStringForInput(obj, typeof(T));
		}

		public static string ToStringForInput(object obj, Type type)
		{
			if (type == null || obj == null)
			{
				return null;
			}
			if (type == typeof(string))
			{
				return obj as string;
			}
			if (type.IsEnum)
			{
				if (!Enum.IsDefined(type, obj))
				{
					return obj.ToString();
				}
				return Enum.GetName(type, obj);
			}
			try
			{
				if (customTypes.ContainsKey(type.FullName))
				{
					return customTypesToString[type.FullName](obj);
				}
				if (formattedTypes.Contains(type))
				{
					return AccessTools.Method(type, "ToString", new Type[2]
					{
						typeof(string),
						typeof(IFormatProvider)
					}, (Type[])null).Invoke(obj, new object[2]
					{
						NumberFormatString,
						CultureInfo.CurrentCulture
					}) as string;
				}
				return obj.ToString();
			}
			catch (Exception value)
			{
				Universe.LogWarning($"Exception formatting object for input: {value}");
				return null;
			}
		}

		public static string GetExampleInput<T>()
		{
			return GetExampleInput(typeof(T));
		}

		public static string GetExampleInput(Type type)
		{
			if (!typeInputExamples.ContainsKey(type.AssemblyQualifiedName))
			{
				try
				{
					if (type.IsEnum)
					{
						typeInputExamples.Add(type.AssemblyQualifiedName, Enum.GetNames(type).First());
					}
					else
					{
						object obj = Activator.CreateInstance(type);
						typeInputExamples.Add(type.AssemblyQualifiedName, ToStringForInput(obj, type));
					}
				}
				catch (Exception message)
				{
					Universe.LogWarning("Exception generating default instance for example input for '" + type.FullName + "'");
					Universe.Log(message);
					return "";
				}
			}
			return typeInputExamples[type.AssemblyQualifiedName];
		}

		internal static object TryParseVector2(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			string[] array = input.Split(' ');
			val.x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			val.y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			return val;
		}

		internal static string Vector2ToString(object obj)
		{
			//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)
			//IL_001b: 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)
			if (!(obj is Vector2 val))
			{
				return null;
			}
			return FormatDecimalSequence(val.x, val.y);
		}

		internal static object TryParseVector3(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			string[] array = input.Split(' ');
			val.x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			val.y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			val.z = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
			return val;
		}

		internal static string Vector3ToString(object obj)
		{
			//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)
			//IL_001b: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			if (!(obj is Vector3 val))
			{
				return null;
			}
			return FormatDecimalSequence(val.x, val.y, val.z);
		}

		internal static object TryParseVector4(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Vector4 val = default(Vector4);
			string[] array = input.Split(' ');
			val.x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			val.y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			val.z = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
			val.w = float.Parse(array[3].Trim(), CultureInfo.CurrentCulture);
			return val;
		}

		internal static string Vector4ToString(object obj)
		{
			//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)
			//IL_001b: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!(obj is Vector4 val))
			{
				return null;
			}
			return FormatDecimalSequence(val.x, val.y, val.z, val.w);
		}

		internal static object TryParseQuaternion(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			Vector3 val = default(Vector3);
			string[] array = input.Split(' ');
			if (array.Length == 4)
			{
				return (object)new Quaternion
				{
					x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture),
					y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture),
					z = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture),
					w = float.Parse(array[3].Trim(), CultureInfo.CurrentCulture)
				};
			}
			val.x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			val.y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			val.z = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
			return Quaternion.Euler(val);
		}

		internal static string QuaternionToString(object obj)
		{
			//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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			if (!(obj is Quaternion val))
			{
				return null;
			}
			Vector3 eulerAngles = ((Quaternion)(ref val)).eulerAngles;
			return FormatDecimalSequence(eulerAngles.x, eulerAngles.y, eulerAngles.z);
		}

		internal static object TryParseRect(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			string[] array = input.Split(' ');
			((Rect)(ref val)).x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			((Rect)(ref val)).y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			((Rect)(ref val)).width = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
			((Rect)(ref val)).height = float.Parse(array[3].Trim(), CultureInfo.CurrentCulture);
			return val;
		}

		internal static string RectToString(object obj)
		{
			//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 (!(obj is Rect val))
			{
				return null;
			}
			return FormatDecimalSequence(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, ((Rect)(ref val)).height);
		}

		internal static object TryParseColor(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			string[] array = input.Split(' ');
			val.r = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			val.g = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			val.b = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
			if (array.Length > 3)
			{
				val.a = float.Parse(array[3].Trim(), CultureInfo.CurrentCulture);
			}
			else
			{
				val.a = 1f;
			}
			return val;
		}

		internal static string ColorToString(object obj)
		{
			//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)
			//IL_001b: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!(obj is Color val))
			{
				return null;
			}
			return FormatDecimalSequence(val.r, val.g, val.b, val.a);
		}

		internal static object TryParseColor32(string input)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Color32 val = default(Color32);
			string[] array = input.Split(' ');
			val.r = byte.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
			val.g = byte.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
			val.b = byte.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
			if (array.Length > 3)
			{
				val.a = byte.Parse(array[3].Trim(), CultureInfo.CurrentCulture);
			}
			else
			{
				val.a = byte.MaxValue;
			}
			return val;
		}

		internal static string Color32ToString(object obj)
		{
			//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)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!(obj is Color32 val))
			{
				return null;
			}
			return $"{val.r} {val.g} {val.b} {val.a}";
		}

		internal static object TryParseLayerMask(string input)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return LayerMask.op_Implicit(int.Parse(input));
		}

		internal static string LayerMaskToString(object obj)
		{
			//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 (!(obj is LayerMask val))
			{
				return null;
			}
			return ((LayerMask)(ref val)).value.ToString();
		}
	}
	public static class SignatureHighlighter
	{
		public const string NAMESPACE = "#a8a8a8";

		public const string CONST = "#92c470";

		public const string CLASS_STATIC = "#3a8d71";

		public const string CLASS_INSTANCE = "#2df7b2";

		public const string STRUCT = "#0fba3a";

		public const string INTERFACE = "#9b9b82";

		public const string FIELD_STATIC = "#8d8dc6";

		public const string FIELD_INSTANCE = "#c266ff";

		public const string METHOD_STATIC = "#b55b02";

		public const string METHOD_INSTANCE = "#ff8000";

		public const string PROP_STATIC = "#588075";

		public const string PROP_INSTANCE = "#55a38e";

		public const string LOCAL_ARG = "#a6e9e9";

		public const string OPEN_COLOR = "<color=";

		public const string CLOSE_COLOR = "</color>";

		public const string OPEN_ITALIC = "<i>";

		public const string CLOSE_ITALIC = "</i>";

		public static readonly Regex ArrayTokenRegex = new Regex("\\[,*?\\]");

		private static readonly Regex colorTagRegex = new Regex("<color=#?[\\d|\\w]*>");

		public static readonly Color StringOrange = new Color(0.83f, 0.61f, 0.52f);

		public static readonly Color EnumGreen = new Color(0.57f, 0.76f, 0.43f);

		public static readonly Color KeywordBlue = new Color(0.3f, 0.61f, 0.83f);

		public static readonly string keywordBlueHex = KeywordBlue.ToHex();

		public static readonly Color NumberGreen = new Color(0.71f, 0.8f, 0.65f);

		private static readonly Dictionary<string, string> typeToRichType = new Dictionary<string, string>();

		private static readonly Dictionary<string, string> highlightedMethods = new Dictionary<string, string>();

		private static readonly Dictionary<Type, string> builtInTypesToShorthand = new Dictionary<Type, string>
		{
			{
				typeof(object),
				"object"
			},
			{
				typeof(string),
				"string"
			},
			{
				typeof(bool),
				"bool"
			},
			{
				typeof(byte),
				"byte"
			},
			{
				typeof(sbyte),
				"sbyte"
			},
			{
				typeof(char),
				"char"
			},
			{
				typeof(decimal),
				"decimal"
			},
			{
				typeof(double),
				"double"
			},
			{
				typeof(float),
				"float"
			},
			{
				typeof(int),
				"int"
			},
			{
				typeof(uint),
				"uint"
			},
			{
				typeof(long),
				"long"
			},
			{
				typeof(ulong),
				"ulong"
			},
			{
				typeof(short),
				"short"
			},
			{
				typeof(ushort),
				"ushort"
			},
			{
				typeof(void),
				"void"
			}
		};

		public static string Parse(Type type, bool includeNamespace, MemberInfo memberInfo = null)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (memberInfo is MethodInfo method)
			{
				return ParseMethod(method);
			}
			if (memberInfo is ConstructorInfo ctor)
			{
				return ParseConstructor(ctor);
			}
			StringBuilder stringBuilder = new StringBuilder();
			if (type.IsByRef)
			{
				AppendOpenColor(stringBuilder, "#" + keywordBlueHex).Append("ref ").Append("</color>");
			}
			Type type2 = type;
			while (type2.HasElementType)
			{
				type2 = type2.GetElementType();
			}
			includeNamespace &= !builtInTypesToShorthand.ContainsKey(type2);
			if (!type.IsGenericParameter && (!type.HasElementType || !type.GetElementType().IsGenericParameter) && includeNamespace && TryGetNamespace(type, out var ns))
			{
				AppendOpenColor(stringBuilder, "#a8a8a8").Append(ns).Append("</color>").Append('.');
			}
			stringBuilder.Append(ProcessType(type));
			if (memberInfo != null)
			{
				stringBuilder.Append('.');
				int index = stringBuilder.Length - 1;
				AppendOpenColor(stringBuilder, GetMemberInfoColor(memberInfo, out var isStatic)).Append(memberInfo.Name).Append("</color>");
				if (isStatic)
				{
					stringBuilder.Insert(index, "<i>");
					stringBuilder.Append("</i>");
				}
			}
			return stringBuilder.ToString();
		}

		private static string ProcessType(Type type)
		{
			string key = type.ToString();
			if (typeToRichType.ContainsKey(key))
			{
				return typeToRichType[key];
			}
			StringBuilder stringBuilder = new StringBuilder();
			if (!type.IsGenericParameter)
			{
				int length = stringBuilder.Length;
				Type declaringType = type.DeclaringType;
				while (declaringType != null)
				{
					stringBuilder.Insert(length, HighlightType(declaringType) + ".");
					declaringType = declaringType.DeclaringType;
				}
				stringBuilder.Append(HighlightType(type));
				if (type.IsGenericType)
				{
					ProcessGenericArguments(type, stringBuilder);
				}
			}
			else
			{
				stringBuilder.Append("<color=").Append("#92c470").Append('>')
					.Append(type.Name)
					.Append("</color>");
			}
			string text = stringBuilder.ToString();
			typeToRichType.Add(key, text);
			return text;
		}

		internal static string GetClassColor(Type type)
		{
			if (type.IsAbstract && type.IsSealed)
			{
				return "#3a8d71";
			}
			if (type.IsEnum || type.IsGenericParameter)
			{
				return "#92c470";
			}
			if (type.IsValueType)
			{
				return "#0fba3a";
			}
			if (type.IsInterface)
			{
				return "#9b9b82";
			}
			return "#2df7b2";
		}

		private static bool TryGetNamespace(Type type, out string ns)
		{
			return !string.IsNullOrEmpty(ns = type.Namespace?.Trim());
		}

		private static StringBuilder AppendOpenColor(StringBuilder sb, string color)
		{
			return sb.Append("<color=").Append(color).Append('>');
		}

		private static string HighlightType(Type type)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (type.IsByRef)
			{
				type = type.GetElementType();
			}
			int num = 0;
			Match match = ArrayTokenRegex.Match(type.Name);
			if (match != null && match.Success)
			{
				num = 1 + match.Value.Count((char c) => c == ',');
				type = type.GetElementType();
			}
			if (builtInTypesToShorthand.TryGetValue(type, out var value))
			{
				AppendOpenColor(stringBuilder, "#" + keywordBlueHex).Append(value).Append("</color>");
			}
			else
			{
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 2, stringBuilder2);
				handler.AppendFormatted("<color=");
				handler.AppendFormatted(GetClassColor(type));
				handler.AppendLiteral(">");
				stringBuilder2.Append(ref handler).Append(type.Name).Append("</color>");
			}
			if (num > 0)
			{
				stringBuilder.Append('[').Append(new string(',', num - 1)).Append(']');
			}
			return stringBuilder.ToString();
		}

		private static void ProcessGenericArguments(Type type, StringBuilder sb)
		{
			List<Type> list = type.GetGenericArguments().ToList();
			for (int i = 0; i < sb.Length; i++)
			{
				if (!list.Any())
				{
					break;
				}
				if (sb[i] != '`')
				{
					continue;
				}
				int num = i;
				i++;
				StringBuilder stringBuilder = new StringBuilder();
				for (; char.IsDigit(sb[i]); i++)
				{
					stringBuilder.Append(sb[i]);
				}
				string text = stringBuilder.ToString();
				int num2 = int.Parse(text);
				sb.Remove(num, text.Length + 1);
				int num3 = 1;
				num++;
				while (num3 < "</color>".Length && sb[num] == "</color>"[num3])
				{
					num3++;
					num++;
				}
				sb.Insert(num, '<');
				num++;
				int length = sb.Length;
				while (num2 > 0 && list.Any())
				{
					num2--;
					Type type2 = list.First();
					list.RemoveAt(0);
					sb.Insert(num, ProcessType(type2));
					if (num2 > 0)
					{
						num += sb.Length - length;
						sb.Insert(num, ", ");
						num += 2;
						length = sb.Length;
					}
				}
				sb.Insert(num + sb.Length - length, '>');
			}
		}

		public static string RemoveHighlighting(string _string)
		{
			if (_string == null)
			{
				throw new ArgumentNullException("_string");
			}
			_string = _string.Replace("<i>", string.Empty);
			_string = _string.Replace("</i>", string.Empty);
			_string = colorTagRegex.Replace(_string, string.Empty);
			_string = _string.Replace("</color>", string.Empty);
			return _string;
		}

		[Obsolete("Use 'ParseMethod(MethodInfo)' instead (rename).")]
		public static string HighlightMethod(MethodInfo method)
		{
			return ParseMethod(method);
		}

		public static string ParseMethod(MethodInfo method)
		{
			string key = GeneralExtensions.FullDescription((MethodBase)method);
			if (highlightedMethods.ContainsKey(key))
			{
				return highlightedMethods[key];
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Parse(method.DeclaringType, includeNamespace: false));
			stringBuilder.Append('.');
			string value = ((!method.IsStatic) ? "#ff8000" : "#b55b02");
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(16, 2, stringBuilder2);
			handler.AppendLiteral("<color=");
			handler.AppendFormatted(value);
			handler.AppendLiteral(">");
			handler.AppendFormatted(method.Name);
			handler.AppendLiteral("</color>");
			stringBuilder3.Append(ref handler);
			if (method.IsGenericMethod)
			{
				stringBuilder.Append("<");
				Type[] genericArguments = method.GetGenericArguments();
				for (int i = 0; i < genericArguments.Length; i++)
				{
					Type type = genericArguments[i];
					if (type.IsGenericParameter)
					{
						stringBuilder2 = stringBuilder;
						StringBuilder stringBuilder4 = stringBuilder2;
						handler = new StringBuilder.AppendInterpolatedStringHandler(16, 2, stringBuilder2);
						handler.AppendLiteral("<color=");
						handler.AppendFormatted("#92c470");
						handler.AppendLiteral(">");
						handler.AppendFormatted(genericArguments[i].Name);
						handler.AppendLiteral("</color>");
						stringBuilder4.Append(ref handler);
					}
					else
					{
						stringBuilder.Append(Parse(type, includeNamespace: false));
					}
					if (i < genericArguments.Length - 1)
					{
						stringBuilder.Append(", ");
					}
				}
				stringBuilder.Append(">");
			}
			stringBuilder.Append('(');
			ParameterInfo[] parameters = method.GetParameters();
			for (int j = 0; j < parameters.Length; j++)
			{
				ParameterInfo parameterInfo = parameters[j];
				stringBuilder.Append(Parse(parameterInfo.ParameterType, includeNamespace: false));
				if (j < parameters.Length - 1)
				{
					stringBuilder.Append(", ");
				}
			}
			stringBuilder.Append(')');
			string text = stringBuilder.ToString();
			highlightedMethods.Add(key, text);
			return text;
		}

		[Obsolete("Use 'ParseConstructor(ConstructorInfo)' instead (rename).")]
		public static string HighlightConstructor(ConstructorInfo ctor)
		{
			return ParseConstructor(ctor);
		}

		public static string ParseConstructor(ConstructorInfo ctor)
		{
			string key = GeneralExtensions.FullDescription((MethodBase)ctor);
			if (highlightedMethods.ContainsKey(key))
			{
				return highlightedMethods[key];
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Parse(ctor.DeclaringType, includeNamespace: false));
			string value = stringBuilder.ToString();
			stringBuilder.Append('.');
			stringBuilder.Append(value);
			stringBuilder.Append('(');
			ParameterInfo[] parameters = ctor.GetParameters();
			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo parameterInfo = parameters[i];
				stringBuilder.Append(Parse(parameterInfo.ParameterType, includeNamespace: false));
				if (i < parameters.Length - 1)
				{
					stringBuilder.Append(", ");
				}
			}
			stringBuilder.Append(')');
			string text = stringBuilder.ToString();
			highlightedMethods.Add(key, text);
			return text;
		}

		public static string GetMemberInfoColor(MemberInfo memberInfo, out bool isStatic)
		{
			isStatic = false;
			if (memberInfo is FieldInfo fieldInfo)
			{
				if (fieldInfo.IsStatic)
				{
					isStatic = true;
					return "#8d8dc6";
				}
				return "#c266ff";
			}
			if (memberInfo is MethodInfo methodInfo)
			{
				if (methodInfo.IsStatic)
				{
					isStatic = true;
					return "#b55b02";
				}
				return "#ff8000";
			}
			if (memberInfo is PropertyInfo propertyInfo)
			{
				if (propertyInfo.GetAccessors(nonPublic: true)[0].IsStatic)
				{
					isStatic = true;
					return "#588075";
				}
				return "#55a38e";
			}
			if (memberInfo is ConstructorInfo)
			{
				isStatic = true;
				return "#2df7b2";
			}
			throw new NotImplementedException(memberInfo.GetType().Name + " is not supported");
		}
	}
	public static class ToStringUtility
	{
		internal static Dictionary<string, MethodInfo> toStringMethods = new Dictionary<string, MethodInfo>();

		private const string nullString = "<color=grey>null</color>";

		private const string nullUnknown = "<color=grey>null</color> (?)";

		private const string destroyedString = "<color=red>Destroyed</color>";

		private const string untitledString = "<i><color=grey>untitled</color></i>";

		private const string eventSystemNamespace = "UnityEngine.EventSystem";

		public static string PruneString(string s, int chars = 200, int lines = 5)
		{
			if (string.IsNullOrEmpty(s))
			{
				return s;
			}
			StringBuilder stringBuilder = new StringBuilder(Math.Max(chars, s.Length));
			int num = 0;
			for (int i = 0; i < s.Length; i++)
			{
				if (num >= lines || i >= chars)
				{
					stringBuilder.Append("...");
					break;
				}
				char c = s[i];
				if (c == '\r' || c == '\n')
				{
					num++;
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		public static string ToStringWithType(object value, Type fallbackType, bool includeNamespace = true)
		{
			if (value.IsNullOrDestroyed() && fallbackType == null)
			{
				return "<color=grey>null</color> (?)";
			}
			Type type = value?.GetActualType() ?? fallbackType;
			string text = SignatureHighlighter.Parse(type, includeNamespace);
			StringBuilder stringBuilder = new StringBuilder();
			if (value.IsNullOrDestroyed())
			{
				if (value == null)
				{
					stringBuilder.Append("<color=grey>null</color>");
					AppendRichType(stringBuilder, text);
					return stringBuilder.ToString();
				}
				stringBuilder.Append("<color=red>Destroyed</color>");
				AppendRichType(stringBuilder, text);
				return stringBuilder.ToString();
			}
			Object val = (Object)((value is Object) ? value : null);
			if (val != null)
			{
				if (string.IsNullOrEmpty(val.name))
				{
					stringBuilder.Append("<i><color=grey>untitled</color></i>");
				}
				else
				{
					stringBuilder.Append('"');
					stringBuilder.Append(PruneString(val.name, 50, 1));
					stringBuilder.Append('"');
				}
				AppendRichType(stringBuilder, text);
			}
			else if (type.FullName.StartsWith("UnityEngine.EventSystem"))
			{
				stringBuilder.Append(text);
			}
			else
			{
				string text2 = ToString(value);
				if (type.IsGenericType || text2 == type.FullName || text2 == type.FullName + " " + type.FullName || text2 == "Il2Cpp" + type.FullName || type.FullName == "Il2Cpp" + text2)
				{
					stringBuilder.Append(text);
				}
				else
				{
					stringBuilder.Append(PruneString(text2));
					AppendRichType(stringBuilder, text);
				}
			}
			return stringBuilder.ToString();
		}

		private static void AppendRichType(StringBuilder sb, string richType)
		{
			sb.Append(' ');
			sb.Append('(');
			sb.Append(richType);
			sb.Append(')');
		}

		private static string ToString(object value)
		{
			if (value.IsNullOrDestroyed())
			{
				if (value == null)
				{
					return "<color=grey>null</color>";
				}
				return "<color=red>Destroyed</color>";
			}
			Type actualType = value.GetActualType();
			if (!toStringMethods.ContainsKey(actualType.AssemblyQualifiedName))
			{
				MethodInfo method = actualType.GetMethod("ToString", ArgumentUtility.EmptyTypes);
				toStringMethods.Add(actualType.AssemblyQualifiedName, method);
			}
			value = value.TryCast(actualType);
			string theString;
			try
			{
				theString = (string)toStringMethods[actualType.AssemblyQualifiedName].Invoke(value, ArgumentUtility.EmptyArgs);
			}
			catch (Exception e)
			{
				theString = e.ReflectionExToString();
			}
			theString = ReflectionUtility.ProcessTypeInString(actualType, theString);
			Type val = (Type)((value is Type) ? value : null);
			if (val != null)
			{
				Type unhollowedType = Il2CppReflection.GetUnhollowedType(val);
				if (unhollowedType != null)
				{
					theString = ReflectionUtility.ProcessTypeInString(unhollowedType, theString);
				}
			}
			return theString;
		}
	}
	public static class UnityHelpers
	{
		private static PropertyInfo onEndEdit;

		public static bool OccuredEarlierThanDefault(this float time)
		{
			return Time.realtimeSinceStartup - 0.01f >= time;
		}

		public static bool OccuredEarlierThan(this float time, float secondsAgo)
		{
			return Time.realtimeSinceStartup - secondsAgo >= time;
		}

		public static bool IsNullOrDestroyed(this object obj, bool suppressWarning = true)
		{
			try
			{
				if (obj == null)
				{
					if (!suppressWarning)
					{
						Universe.LogWarning("The target instance is null!");
					}
					return true;
				}
				Object val = (Object)((obj is Object) ? obj : null);
				if (val != null && !Object.op_Implicit(val))
				{
					if (!suppressWarning)
					{
						Universe.LogWarning("The target UnityEngine.Object was destroyed!");
					}
					return true;
				}
				return false;
			}
			catch
			{
				return true;
			}
		}

		public static string GetTransformPath(this Transform transform, bool includeSelf = false)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (includeSelf)
			{
				stringBuilder.Append(((Object)transform).name);
			}
			while (Object.op_Implicit((Object)(object)transform.parent))
			{
				transform = transform.parent;
				stringBuilder.Insert(0, '/');
				stringBuilder.Insert(0, ((Object)transform).name);
			}
			return stringBuilder.ToString();
		}

		public static string ToHex(this Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			byte value = (byte)Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
			byte value2 = (byte)Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
			byte value3 = (byte)Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
			return $"{value:X2}{value2:X2}{value3:X2}";
		}

		public static Color ToColor(this string _string)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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)
			_string = _string.Replace("#", "");
			if (_string.Length != 6)
			{
				return Color.magenta;
			}
			byte b = byte.Parse(_string.Substring(0, 2), NumberStyles.HexNumber);
			byte b2 = byte.Parse(_string.Substring(2, 2), NumberStyles.HexNumber);
			byte b3 = byte.Parse(_string.Substring(4, 2), NumberStyles.HexNumber);
			return new Color
			{
				r = (float)((decimal)b / 255m),
				g = (float)((decimal)b2 / 255m),
				b = (float)((decimal)b3 / 255m),
				a = 1f
			};
		}

		public static UnityEvent<string> GetOnEndEdit(this InputField _this)
		{
			if (onEndEdit == null)
			{
				onEndEdit = AccessTools.Property(typeof(InputField), "onEndEdit") ?? throw new Exception("Could not get InputField.onEndEdit property!");
			}
			return onEndEdit.GetValue(_this, null).TryCast<UnityEvent<string>>();
		}
	}
}
namespace UniverseLib.UI
{
	public class UIBase
	{
		internal static readonly int TOP_SORTORDER = 30000;

		public string ID { get; }

		public GameObject RootObject { get; }

		public RectTransform RootRect { get; }

		public Canvas Canvas { get; }

		public Action UpdateMethod { get; }

		public PanelManager Panels { get; }

		public bool Enabled
		{
			get
			{
				if (Object.op_Implicit((Object)(object)RootObject))
				{
					return RootObject.activeSelf;
				}
				return false;
			}
			set
			{
				UniversalUI.SetUIActive(ID, value);
			}
		}

		public UIBase(string id, Action updateMethod)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("Cannot register a UI with a null or empty id!");
			}
			if (UniversalUI.registeredUIs.ContainsKey(id))
			{
				throw new ArgumentException("A UI with the id '" + id + "' is already registered!");
			}
			ID = id;
			UpdateMethod = updateMethod;
			RootObject = UIFactory.CreateUIObject(id + "_Root", UniversalUI.CanvasRoot);
			RootObject.SetActive(false);
			RootRect = RootObject.GetComponent<RectTransform>();
			Canvas = RootObject.AddComponent<Canvas>();
			Canvas.renderMode = (RenderMode)1;
			Canvas.referencePixelsPerUnit = 100f;
			Canvas.sortingOrder = TOP_SORTORDER;
			Canvas.overrideSorting = true;
			CanvasScaler obj = RootObject.AddComponent<CanvasScaler>();
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.screenMatchMode = (ScreenMatchMode)1;
			RootObject.AddComponent<GraphicRaycaster>();
			RectTransform component = RootObject.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 0.5f);
			Panels = CreatePanelManager();
			RootObject.SetActive(true);
			UniversalUI.registeredUIs.Add(id, this);
			UniversalUI.uiBases.Add(this);
		}

		protected virtual PanelManager CreatePanelManager()
		{
			return new PanelManager(this);
		}

		public void SetOnTop()
		{
			RootObject.transform.SetAsLastSibling();
			foreach (UIBase uiBasis in UniversalUI.uiBases)
			{
				int num = UniversalUI.CanvasRoot.transform.childCount - ((Transform)uiBasis.RootRect).GetSiblingIndex();
				uiBasis.Canvas.sortingOrder = TOP_SORTORDER - num;
			}
			UniversalUI.uiBases.Sort((UIBase a, UIBase b) => b.RootObject.transform.GetSiblingIndex().CompareTo(a.RootObject.transform.GetSiblingIndex()));
		}

		internal void Update()
		{
			try
			{
				Panels.Update();
				UpdateMethod?.Invoke();
			}
			catch (Exception value)
			{
				Universe.LogWarning($"Exception invoking update method for {ID}: {value}");
			}
		}
	}
	public static class UIFactory
	{
		internal static Vector2 largeElementSize = new Vector2(100f, 30f);

		internal static Vector2 smallElementSize = new Vector2(25f, 25f);

		internal static Color defaultTextColor = Color.white;

		public static GameObject CreateUIObject(string name, GameObject parent, Vector2 sizeDelta = default(Vector2))
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name)
			{
				layer = 5,
				hideFlags = (HideFlags)61
			};
			if (Object.op_Implicit((Object)(object)parent))
			{
				val.transform.SetParent(parent.transform, false);
			}
			val.AddComponent<RectTransform>().sizeDelta = sizeDelta;
			return val;
		}

		internal static void SetDefaultTextValues(Text text)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			((Graphic)text).color = defaultTextColor;
			text.font = UniversalUI.DefaultFont;
			text.fontSize = 14;
		}

		internal static void SetDefaultSelectableValues(Selectable selectable)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Navigation navigation = selectable.navigation;
			navigation.mode = (Mode)4;
			selectable.navigation = navigation;
			RuntimeHelper.Instance.Internal_SetColorBlock(selectable, (Color?)new Color(0.2f, 0.2f, 0.2f), (Color?)new Color(0.3f, 0.3f, 0.3f), (Color?)new Color(0.15f, 0.15f, 0.15f), (Color?)null);
		}

		public static LayoutElement SetLayoutElement(GameObject gameObject, int? minWidth = null, int? minHeight = null, int? flexibleWidth = null, int? flexibleHeight = null, int? preferredWidth = null, int? preferredHeight = null, bool? ignoreLayout = null)
		{
			LayoutElement val = gameObject.GetComponent<LayoutElement>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = gameObject.AddComponent<LayoutElement>();
			}
			if (minWidth.HasValue)
			{
				val.minWidth = minWidth.Value;
			}
			if (minHeight.HasValue)
			{
				val.minHeight = minHeight.Value;
			}
			if (flexibleWidth.HasValue)
			{
				val.flexibleWidth = flexibleWidth.Value;
			}
			if (flexibleHeight.HasValue)
			{
				val.flexibleHeight = flexibleHeight.Value;
			}
			if (preferredWidth.HasValue)
			{
				val.preferredWidth = preferredWidth.Value;
			}
			if (preferredHeight.HasValue)
			{
				val.preferredHeight = preferredHeight.Value;
			}
			if (ignoreLayout.HasValue)
			{
				val.ignoreLayout = ignoreLayout.Value;
			}
			return val;
		}

		public static T SetLayoutGroup<T>(GameObject gameObject, bool? forceWidth = null, bool? forceHeight = null, bool? childControlWidth = null, bool? childControlHeight = null, int? spacing = null, int? padTop = null, int? padBottom = null, int? padLeft = null, int? padRight = null, TextAnchor? childAlignment = null) where T : HorizontalOrVerticalLayoutGroup
		{
			T val = gameObject.GetComponent<T>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = gameObject.AddComponent<T>();
			}
			return SetLayoutGroup(val, forceWidth, forceHeight, childControlWidth, childControlHeight, spacing, padTop, padBottom, padLeft, padRight, childAlignment);
		}

		public static T SetLayoutGroup<T>(T group, bool? forceWidth = null, bool? forceHeight = null, bool? childControlWidth = null, bool? childControlHeight = null, int? spacing = null, int? padTop = null, int? padBottom = null, int? padLeft = null, int? padRight = null, TextAnchor? childAlignment = null) where T : HorizontalOrVerticalLayoutGroup
		{
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (forceWidth.HasValue)
			{
				((HorizontalOrVerticalLayoutGroup)group).childForceExpandWidth = forceWidth.Value;
			}
			if (forceHeight.HasValue)
			{
				((HorizontalOrVerticalLayoutGroup)group).childForceExpandHeight = forceHeight.Value;
			}
			if (childControlWidth.HasValue)
			{
				((HorizontalOrVerticalLayoutGroup)(object)group).SetChildControlWidth(childControlWidth.Value);
			}
			if (childControlHeight.HasValue)
			{
				((HorizontalOrVerticalLayoutGroup)(object)group).SetChildControlHeight(childControlHeight.Value);
			}
			if (spacing.HasValue)
			{
				((HorizontalOrVerticalLayoutGroup)group).spacing = spacing.Value;
			}
			if (padTop.HasValue)
			{
				((LayoutGroup)(object)group).padding.top = padTop.Value;
			}
			if (padBottom.HasValue)
			{
				((LayoutGroup)(object)group).padding.bottom = padBottom.Value;
			}
			if (padLeft.HasValue)
			{
				((LayoutGroup)(object)group).padding.left = padLeft.Value;
			}
			if (padRight.HasValue)
			{
				((LayoutGroup)(object)group).padding.right = padRight.Value;
			}
			if (childAlignment.HasValue)
			{
				((LayoutGroup)(object)group).childAlignment = childAlignment.Value;
			}
			return group;
		}

		public static GameObject CreatePanel(string name, GameObject parent, out GameObject contentHolder, Color? bgColor = null)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateUIObject(name, pare