Decompiled source of GameSpeed v1.0.1

GameSpeed.dll

Decompiled 2 months ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameSpeed.Hooks;
using GameSpeed.Settings;
using GameSpeed.Systems;
using GameSpeed.UI;
using GameSpeed.UI.Panels;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib;
using UniverseLib.Config;
using UniverseLib.Input;
using UniverseLib.UI;
using UniverseLib.UI.Panels;
using Utils.Database;
using Utils.Logger;
using Utils.Settings;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("GameSpeed")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A plugin that allows players to adjust the game speed according to their preferences.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GameSpeed")]
[assembly: AssemblyTitle("GameSpeed")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Utils.Settings
{
	public class Config
	{
		public static string PluginGUID;

		public static string PluginFolderPath;

		internal static ConfigFile cfg;

		private static List<Action> configActions = new List<Action>();

		public static ConfigElement<T> Bind<T>(string section, string key, T defaultValue, string description)
		{
			return new ConfigElement<T>(cfg.Bind<T>(section, key, defaultValue, description), section, key, defaultValue, description);
		}

		public static void Save()
		{
			cfg.Save();
		}

		public static void Setup(string pluginGUID, ConfigFile config, int skipCaller = 4, params Action[] actions)
		{
			PluginGUID = pluginGUID;
			cfg = config;
			PluginFolderPath = Paths.ConfigPath + "\\" + PluginGUID;
			if (!Directory.Exists(PluginFolderPath))
			{
				Directory.CreateDirectory(PluginFolderPath);
			}
			ENV.Debug.Setup(skipCaller);
			AddConfigActions(actions);
		}

		public static void Load()
		{
			if (configActions == null || configActions.Count == 0)
			{
				return;
			}
			foreach (Action configAction in configActions)
			{
				configAction();
			}
		}

		public static void AddConfigActions(params Action[] actions)
		{
			configActions.AddRange(actions);
		}
	}
	public class ConfigElement<T>
	{
		public List<Action<T>> OnValueChanged = new List<Action<T>>();

		private ConfigEntry<T> OriginalConfig;

		public string Section { get; }

		public string Key { get; }

		public string Description { get; }

		public Type ElementType => typeof(T);

		public T Value
		{
			get
			{
				return GetValue();
			}
			set
			{
				SetValue(value);
			}
		}

		public T DefaultValue { get; }

		private T GetValue()
		{
			return OriginalConfig.Value;
		}

		public ConfigElement(ConfigEntry<T> original, string section, string key, T defaultValue, string description)
		{
			OriginalConfig = original;
			Section = section;
			Key = key;
			DefaultValue = defaultValue;
			Description = description;
		}

		private void SetValue(T value)
		{
			if ((Value == null && value == null) || (Value != null && Value.Equals(value)))
			{
				return;
			}
			OriginalConfig.Value = value;
			foreach (Action<T> item in OnValueChanged)
			{
				item?.Invoke(value);
			}
		}
	}
	public static class ENV
	{
		public class Debug
		{
			private static string debugSection = "\ud83e\udeb2Debug";

			private static ConfigElement<bool> DebugLogOnTempFile;

			private static ConfigElement<bool> DebugEnableTraceLogs;

			public static void Setup(int skipCaller)
			{
				Config.AddConfigActions(delegate
				{
					load(skipCaller);
				});
			}

			private static void load(int skipCaller)
			{
				if (enableDebugConfigs(skipCaller))
				{
					DebugLogOnTempFile = Config.Bind(debugSection, "LogOnTempFile", defaultValue: false, "Enabled, will log every plugin log on a temp file");
					DebugEnableTraceLogs = Config.Bind(debugSection, "EnableTraceLogs", defaultValue: false, "Enabled, will print Trace logs (Debug output in BepInEx)");
				}
				validateValues();
			}

			private static void validateValues()
			{
				if (DebugLogOnTempFile != null)
				{
					LogOnTempFile = DebugLogOnTempFile.Value;
				}
				if (DebugEnableTraceLogs != null)
				{
					EnableTraceLogs = DebugEnableTraceLogs.Value;
				}
				Config.cfg.Save();
			}

			private static bool enableDebugConfigs(int skipCaller)
			{
				return new StackTrace().GetFrame(skipCaller).GetMethod().DeclaringType.Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration != "Release";
			}
		}

		public static bool LogOnTempFile;

		public static bool EnableTraceLogs;
	}
}
namespace Utils.Logger
{
	public class Config
	{
		internal static ManualLogSource logger;

		private static string tempLogFile;

		public static void Setup(ManualLogSource logger, string worldType = "")
		{
			Config.logger = logger;
			string value = "";
			if (worldType != "")
			{
				value = "-" + worldType;
			}
			tempLogFile = $"{Utils.Settings.Config.PluginFolderPath}\\{Utils.Settings.Config.PluginGUID}{value}.txt";
			Log.Start("Using \"" + tempLogFile + "\" to save logs.");
		}

		public static void TestSetup()
		{
		}

		internal static void logFile(object data, string level, string prefix = "")
		{
			if (Utils.Settings.ENV.LogOnTempFile)
			{
				using (StreamWriter streamWriter = File.AppendText(tempLogFile))
				{
					string value = $"{prefix}{DateTime.Now.ToString("hh:mm:ss")} [{level} {Utils.Settings.Config.PluginGUID}]: {data}";
					streamWriter.WriteLine(value);
				}
			}
		}
	}
	public class Log
	{
		private static ConcurrentDictionary<string, long> timedLog = new ConcurrentDictionary<string, long>();

		private static List<string> firstLog = new List<string>();

		public static void Info(object data)
		{
			Config.logger.LogInfo(data);
			Config.logFile(data, "Info:   ");
		}

		public static void Error(object data)
		{
			Config.logger.LogError(data);
			Config.logFile(data, "Error:  ");
		}

		public static void Debug(object data)
		{
			Config.logger.LogDebug(data);
			Config.logFile(data, "Debug:  ");
		}

		public static void Fatal(object data)
		{
			Config.logger.LogFatal(data);
			Config.logFile(data, "Fatal:  ");
		}

		public static void Warning(object data)
		{
			Config.logger.LogWarning(data);
			Config.logFile(data, "Warning:");
		}

		public static void Message(object data)
		{
			Config.logger.LogMessage(data);
			Config.logFile(data, "Message:");
		}

		public static void Start(object data)
		{
			Config.logger.LogMessage(data);
			Config.logFile(data, "Start:  ", "\n");
		}

		public static void Trace(object data)
		{
			if (Utils.Settings.ENV.EnableTraceLogs)
			{
				Config.logger.LogDebug(data);
				Config.logFile(data, "Trace:  ");
			}
		}

		public static void Struct<T>(T data)
		{
			if (Utils.Settings.ENV.EnableTraceLogs)
			{
				string text = structToString(data);
				Config.logger.LogDebug((object)text);
				Config.logFile(text, "Struct: ");
			}
		}

		public static void Timed(Action action, int ms, string id = "")
		{
			if (!blocked(ms, id))
			{
				action();
			}
		}

		public static void First(Action action, string id = "")
		{
			if (first(id))
			{
				action();
			}
		}

		private static string structToString<T>(T data)
		{
			Type type = data.GetType();
			FieldInfo[] fields = type.GetFields();
			PropertyInfo[] properties = type.GetProperties();
			Dictionary<string, object> values = new Dictionary<string, object>();
			Array.ForEach(properties, delegate(PropertyInfo property)
			{
				values.TryAdd(property.Name, property.GetValue(data));
			});
			Array.ForEach(fields, delegate(FieldInfo field)
			{
				values.TryAdd(field.Name, field.GetValue(data));
			});
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, object> item in values)
			{
				list.Add($"\"{item.Key}\":\"{item.Value}\"");
			}
			return "\"" + type.ToString() + "\": {" + string.Join(",", list) + "}";
		}

		private static bool first(string id)
		{
			if (firstLog.Contains(id))
			{
				return false;
			}
			firstLog.Add(id);
			return true;
		}

		private static bool blocked(int ms, string id)
		{
			long num = DateTimeOffset.Now.ToUnixTimeMilliseconds();
			if (!timedLog.TryGetValue(id, out var value))
			{
				long newTimestamp = DateTimeOffset.Now.AddMilliseconds(ms).ToUnixTimeMilliseconds();
				timedLog.AddOrUpdate(id, newTimestamp, (string key, long oldValue) => newTimestamp);
				return true;
			}
			if (num < value)
			{
				return true;
			}
			timedLog.TryRemove(id, out var _);
			return false;
		}
	}
}
namespace Utils.Database
{
	public static class Cache
	{
		public static ConcurrentDictionary<string, long> LastUpdate = new ConcurrentDictionary<string, long>();

		public static ConcurrentDictionary<string, bool> Cached = new ConcurrentDictionary<string, bool>();

		public static bool IsBlocked(string key, long blockedDuration)
		{
			long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
			if (LastUpdate.TryGetValue(key, out var value) && now - value < blockedDuration)
			{
				return true;
			}
			LastUpdate.AddOrUpdate(key, now, (string _, long _) => now);
			return false;
		}

		public static bool Key(string key, bool cache = true)
		{
			if (!cache)
			{
				return false;
			}
			return Cached.AddOrUpdate(key, addValue: true, (string _, bool _) => true);
		}

		public static bool Exists(string key)
		{
			if (Cached.TryGetValue(key, out var value) && value)
			{
				return true;
			}
			return false;
		}

		public static bool RemoveKey(string key)
		{
			bool value;
			return Cached.TryRemove(key, out value);
		}
	}
	public static class DB
	{
		private static JsonSerializerOptions JSONOptions = new JsonSerializerOptions
		{
			WriteIndented = false,
			IncludeFields = false
		};

		private static JsonSerializerOptions Pretty_JSON_options = new JsonSerializerOptions
		{
			WriteIndented = true,
			IncludeFields = true
		};

		private static List<Action> loadActions = new List<Action>();

		private static List<Action> saveActions = new List<Action>();

		private static List<Action> cleanActions = new List<Action>();

		public static void Setup(List<Action> load, List<Action> save, List<Action> clean)
		{
			if (load != null)
			{
				loadActions.AddRange(load);
			}
			if (save != null)
			{
				saveActions.AddRange(save);
			}
			if (clean != null)
			{
				cleanActions.AddRange(clean);
			}
		}

		public static void Load()
		{
			if (loadActions == null)
			{
				return;
			}
			foreach (Action loadAction in loadActions)
			{
				loadAction();
			}
			Log.Info($"All({loadActions.Count}) database actions loaded.");
		}

		public static void Save()
		{
			if (saveActions == null)
			{
				return;
			}
			foreach (Action saveAction in saveActions)
			{
				saveAction();
			}
			Log.Info($"All({saveActions.Count}) database actions saved.");
		}

		public static void Clean()
		{
			if (cleanActions == null)
			{
				return;
			}
			foreach (Action cleanAction in cleanActions)
			{
				cleanAction();
			}
			Log.Info($"All({cleanActions.Count}) database actions cleaned.");
		}

		public static void AddLoadActions(params Action[] actions)
		{
			loadActions.AddRange(actions);
		}

		public static void AddSaveActions(params Action[] actions)
		{
			saveActions.AddRange(actions);
		}

		public static void AddCleanActions(params Action[] actions)
		{
			cleanActions.AddRange(actions);
		}

		public static void saveFile<T>(string fileName, T data, bool pretty = false, string extension = ".json")
		{
			JsonSerializerOptions options = JSONOptions;
			if (pretty)
			{
				options = Pretty_JSON_options;
			}
			File.WriteAllText(Utils.Settings.Config.PluginFolderPath + "\\" + fileName + extension, JsonSerializer.Serialize(data, options));
		}

		public static void loadFile<T>(string fileName, ref T data, string extension = ".json") where T : new()
		{
			string path = Utils.Settings.Config.PluginFolderPath + "\\" + fileName + extension;
			if (!File.Exists(path))
			{
				File.Create(path).Dispose();
			}
			string json = File.ReadAllText(path);
			try
			{
				data = JsonSerializer.Deserialize<T>(json);
				Log.Trace(fileName + " DB Populated");
			}
			catch
			{
				data = new T();
				Log.Trace(fileName + " DB Created");
			}
		}
	}
}
namespace GameSpeed
{
	[BepInPlugin("GameSpeed", "GameSpeed", "1.0.0")]
	public class Plugin : BasePlugin
	{
		private static Harmony harmony;

		public override void Load()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			GameSpeed.Settings.Config.Load(((BasePlugin)this).Config, ((BasePlugin)this).Log, "Client");
			UIManager.Initialize(delegate
			{
				Time.timeScale = TimePatch.originalTimeScale;
			});
			((BasePlugin)this).AddComponent<KeyBindsBehaviour>();
			harmony = new Harmony("GameSpeed");
			Log.Trace("Patching harmony");
			harmony.PatchAll();
			Log.Info("Plugin GameSpeed is loaded!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "GameSpeed";

		public const string PLUGIN_NAME = "GameSpeed";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace GameSpeed.UI
{
	public class UIManager
	{
		private static Action onInitAction;

		public static UIBase UiBase { get; private set; }

		public static SpeedPanel SpeedPanel { get; private set; }

		public static GameObject UIRoot
		{
			get
			{
				UIBase uiBase = UiBase;
				if (uiBase == null)
				{
					return null;
				}
				return uiBase.RootObject;
			}
		}

		internal static void Initialize(Action onInit)
		{
			//IL_0008: 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_004c: 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)
			onInitAction = onInit;
			UniverseLibConfig val = default(UniverseLibConfig);
			val.Disable_EventSystem_Override = false;
			val.Force_Unlock_Mouse = false;
			val.Allow_UI_Selection_Outside_UIBase = true;
			val.Unhollowed_Modules_Folder = Path.Combine(Paths.BepInExRootPath, "interop");
			UniverseLibConfig val2 = val;
			Universe.Init(3f, (Action)LateInit, (Action<string, LogType>)CustomLog, val2);
		}

		private static void UiUpdate()
		{
		}

		private static void LateInit()
		{
			UiBase = UniversalUI.RegisterUI(((int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString(), (Action)UiUpdate);
			SpeedPanel = new SpeedPanel();
			onInitAction?.Invoke();
		}

		private static void CustomLog(string message, LogType type)
		{
			Log.Trace(message);
		}
	}
}
namespace GameSpeed.UI.Panels
{
	public class SpeedPanel
	{
		public static RectTransform NavBarRect;

		public static SpeedPanel Instance { get; private set; }

		public Text SpeedLabel { get; set; }

		public SpeedPanel()
		{
			//IL_0018: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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)
			Instance = this;
			GameObject val = UIFactory.CreateUIObject("MainNavbar", UIManager.UIRoot, default(Vector2));
			UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(val, (bool?)false, (bool?)false, (bool?)true, (bool?)true, (int?)5, (int?)4, (int?)4, (int?)4, (int?)4, (TextAnchor?)(TextAnchor)4);
			((Graphic)val.AddComponent<Image>()).color = new Color(0.1f, 0.1f, 0.1f);
			NavBarRect = val.GetComponent<RectTransform>();
			NavBarRect.pivot = new Vector2(0.5f, 1f);
			SetNavBarAnchor();
			SpeedLabel = UIFactory.CreateLabel(val, "SpeedLabel", "100x", (TextAnchor)3, default(Color), true, 14);
			GameObject gameObject = ((Component)SpeedLabel).gameObject;
			int? num = 50;
			int? num2 = 60;
			int? num3 = 0;
			int? num4 = 60;
			UIFactory.SetLayoutElement(gameObject, num, num2, (int?)0, num3, (int?)50, num4, (bool?)null);
			val.SetActive(true);
		}

		public static void SetNavBarAnchor()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			NavBarRect.anchorMin = new Vector2(0.5f, 1f);
			NavBarRect.anchorMax = new Vector2(0.5f, 1f);
			NavBarRect.anchoredPosition = new Vector2(NavBarRect.anchoredPosition.x, 0f);
			NavBarRect.sizeDelta = new Vector2(0f, 35f);
		}
	}
	public class TemplatePanel : PanelBase
	{
		public static TemplatePanel Instance { get; private set; }

		public override string Name => "Template Panel";

		public override int MinWidth => 10;

		public override int MinHeight => 10;

		public override Vector2 DefaultAnchorMin => new Vector2(0.5f, 1f);

		public override Vector2 DefaultAnchorMax => new Vector2(0.5f, 1f);

		public override Vector2 DefaultPosition => new Vector2((float)(-(((PanelBase)this).MinWidth / 2)), (float)Screen.height);

		public override bool CanDragAndResize => false;

		public TemplatePanel(UIBase owner)
			: base(owner)
		{
			Instance = this;
		}

		protected override void ConstructPanelContent()
		{
		}
	}
}
namespace GameSpeed.Systems
{
	public class KeyBindsBehaviour : MonoBehaviour
	{
		private long threshold = 100L;

		public KeyBindsBehaviour(IntPtr handle)
			: base(handle)
		{
		}

		public void Start()
		{
			GameSpeed.Settings.ENV.Enabled.OnValueChanged.Add(delegate(bool value)
			{
				Time.timeScale = TimePatch.originalTimeScale;
				Log.Trace(value);
			});
			GameSpeed.Settings.ENV.Modifier.OnValueChanged.Add(delegate(float value)
			{
				Time.timeScale = TimePatch.originalTimeScale;
				Log.Trace(value);
			});
		}

		public void Update()
		{
			//IL_0005: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			if (InputManager.GetKeyDown(GameSpeed.Settings.ENV.EnableDisableKey.Value))
			{
				GameSpeed.Settings.ENV.Enabled.Value = !GameSpeed.Settings.ENV.Enabled.Value;
			}
			if (InputManager.GetKey(GameSpeed.Settings.ENV.IncreaseSpeedKey.Value) && !Cache.IsBlocked("IncreaseSpeedKey", threshold))
			{
				GameSpeed.Settings.ENV.Modifier.Value = (float)Math.Round(GameSpeed.Settings.ENV.Modifier.Value + GameSpeed.Settings.ENV.IncreaseDecreaseRate.Value, GameSpeed.Settings.ENV.RoundDigits.Value);
			}
			if (InputManager.GetKey(GameSpeed.Settings.ENV.DecreaseSpeedKey.Value) && !Cache.IsBlocked("DecreaseSpeedKey", threshold))
			{
				GameSpeed.Settings.ENV.Modifier.Value = (float)Math.Round(GameSpeed.Settings.ENV.Modifier.Value - GameSpeed.Settings.ENV.IncreaseDecreaseRate.Value, GameSpeed.Settings.ENV.RoundDigits.Value);
			}
		}
	}
}
namespace GameSpeed.Settings
{
	public class Config
	{
		public static void Load(ConfigFile configFile, ManualLogSource logger, string worldType)
		{
			ENV.Settings.Setup();
			Utils.Settings.Config.Setup("GameSpeed", configFile, 4);
			Utils.Settings.Config.Load();
			Utils.Logger.Config.Setup(logger, worldType);
		}
	}
	public static class ENV
	{
		public static class Settings
		{
			public static void Setup()
			{
				Utils.Settings.Config.AddConfigActions(Load);
			}

			private static void Load()
			{
				Enabled = Utils.Settings.Config.Bind(settings, "Enabled", defaultValue: true, "Start the game with the speed modifier enabled/disabled");
				Modifier = Utils.Settings.Config.Bind(settings, "Modifier", 2f, "Define the game speed multiplier. e.g. (1 * modifier) during the game (0 * modifier) on paused screen");
				IncreaseDecreaseRate = Utils.Settings.Config.Bind(settings, "IncreaseDecreaseRate", 0.1f, "Define the speed increase/decrease rate");
				RoundDigits = Utils.Settings.Config.Bind(settings, "RoundDigits", 1, "Used to round the game speed when increased/decreased");
				EnableDisableKey = Utils.Settings.Config.Bind<KeyCode>(settings, "EnableDisableKey", (KeyCode)290, "Enable/Disable the speed modifier");
				IncreaseSpeedKey = Utils.Settings.Config.Bind<KeyCode>(settings, "IncreaseSpeedKey", (KeyCode)61, "Increase the game speed based on the IncreaseDecreaseRate value");
				DecreaseSpeedKey = Utils.Settings.Config.Bind<KeyCode>(settings, "DecreaseSpeedKey", (KeyCode)45, "Decrease the game speed based on the IncreaseDecreaseRate value");
				Utils.Settings.Config.Save();
			}
		}

		private static readonly string settings = "0.⚙\ufe0f Settings";

		public static ConfigElement<bool> Enabled { get; set; }

		public static ConfigElement<float> Modifier { get; set; }

		public static ConfigElement<float> IncreaseDecreaseRate { get; set; }

		public static ConfigElement<int> RoundDigits { get; set; }

		public static ConfigElement<KeyCode> EnableDisableKey { get; set; }

		public static ConfigElement<KeyCode> IncreaseSpeedKey { get; set; }

		public static ConfigElement<KeyCode> DecreaseSpeedKey { get; set; }
	}
}
namespace GameSpeed.Hooks
{
	[HarmonyPatch]
	public class TimePatch
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static class SetTimeScale
		{
			public static bool Prefix(ref float value)
			{
				//IL_0042: 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)
				try
				{
					originalTimeScale = value;
					if (GameSpeed.Settings.ENV.Enabled.Value)
					{
						value *= GameSpeed.Settings.ENV.Modifier.Value;
						((Graphic)UIManager.SpeedPanel.SpeedLabel).color = Color.green;
					}
					else
					{
						((Graphic)UIManager.SpeedPanel.SpeedLabel).color = Color.red;
					}
					UIManager.SpeedPanel.SpeedLabel.text = $"{(float)Math.Round(value, GameSpeed.Settings.ENV.RoundDigits.Value)}x";
					return true;
				}
				catch (Exception data)
				{
					Log.Fatal(data);
				}
				return true;
			}
		}

		internal static float originalTimeScale { get; private set; } = 1f;

	}
}

UniverseLib.BIE.IL2CPP.Interop.dll

Decompiled 2 months 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[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.6")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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()
		{
			return keysEnumerator.MoveNext() && valuesEnumerator.MoveNext();
		}

		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 Dictionary<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;
			}
			if (text.StartsWith("System."))
			{
				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);
						PropertyInfo property = type.GetProperty("HasValue");
						if ((bool)property.GetValue(obj, null))
						{
							PropertyInfo property2 = type.GetProperty("Value");
							return Enum.Parse(toType, property2.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();
				return il2CppType.FullName == "Il2CppSystem.String" || il2CppType.FullName == "System.String";
			}
			return false;
		}

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

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

		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();
			foreach (Assembly asm in assemblies)
			{
				Type[] array = asm.TryGetTypes();
				foreach (Type type in array)
				{
					TryCacheDeobfuscatedType(type);
				}
			}
		}

		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 dir = ConfigManager.Unhollowed_Modules_Folder;
			if (Directory.Exists(dir))
			{
				string[] files = Directory.GetFiles(dir, "*.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: '" + dir + "'. 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
			{
			}
			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
			{
			}
			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.Log($"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 bucket = ((Il2CppArrayBase<bucket>)(object)hashtable.buckets)[i];
				if (bucket != null && bucket.key != null)
				{
					yield return new DictionaryEntry(bucket.key, bucket.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 Dictionary<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 (Universe.Context == RuntimeContext.Mono)
			{
				ForceLoadManagedAssemblies();
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly asm in assemblies)
			{
				CacheTypes(asm);
			}
			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 asm = Assembly.LoadFrom(assemblyFile);
					asm.TryGetTypes();
				}
				catch
				{
				}
			}
		}

		internal static void CacheTypes(Assembly asm)
		{
			Type[] array = asm.TryGetTypes();
			foreach (Type type in array)
			{
				try
				{
					string @namespace = type.Namespace;
					if (!string.IsNullOrEmpty(@namespace) && !uniqueNamespaces.Contains(@namespace))
					{
						uniqueNamespaces.Add(@namespace);
						int j;
						for (j = 0; j < AllNamespaces.Count && @namespace.CompareTo(AllNamespaces[j]) >= 0; j++)
						{
						}
						AllNamespaces.Insert(j, @namespace);
					}
				}
				catch (Exception value)
				{
					Universe.Log($"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)
			{
				value2 = 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 coro2 = GetImplementationsAsync(baseType, set, allowAbstract, allowGeneric, allowEnum, DefaultTypesEnumerator());
			while (coro2.MoveNext())
			{
				yield return null;
			}
			OnTypeLoaded -= ourListener;
			if (resolvedTypes.Count > 0)
			{
				coro2 = GetImplementationsAsync(baseType, set, allowAbstract, allowGeneric, allowEnum, resolvedTypes.GetEnumerator());
				while (coro2.MoveNext())
				{
					yield return null;
				}
			}
			onResultsFetched(set);
			void ourListener(Type t)
			{
				resolvedTypes.Add(t);
			}
		}

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

		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_0275;
						}
					}
					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_0275;
					}
					goto end_IL_00a5;
					IL_0275:
					set.Add(type);
					end_IL_00a5:;
				}
				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);
			return (intPtr != IntPtr.Zero) ? new AssetBundle(intPtr) : null;
		}

		[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);
			return (intPtr != IntPtr.Zero) ? new AssetBundle(intPtr) : null;
		}

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

		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);
			return (Object[])((intPtr != IntPtr.Zero) ? ((Array)Il2CppArrayBase<Object>.op_Implicit((Il2CppArrayBase<Object>)(object)new Il2CppReferenceArray<Object>(intPtr))) : ((Array)new Object[0]));
		}

		[HideFromIl2Cpp]
		public T LoadAsset<T>(string name) where T : Object
		{
			//IL_0040: 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);
			return (intPtr != IntPtr.Zero) ? ((Il2CppObjectBase)new Object(intPtr)).TryCast<T>() : default(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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			ClassInjector.RegisterTypeInIl2Cpp<UniversalBehaviour>();
			GameObject val = new GameObject("UniverseLibBehaviour");
			Object.DontDestroyOnLoad((Object)(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 @delegate = queuedDelegate;
				queuedDelegate = null;
				@delegate?.DynamicInvoke();
			}
			catch (Exception value)
			{
				Universe.LogWarning($"Exception invoking action from IL2CPP thread: {value}");
			}
		}
	}
	public class Universe
	{
		public enum GlobalState
		{
			WaitingToSetup,
			SettingUp,
			SetupCompleted
		}

		public const string NAME = "UniverseLib";

		public const string VERSION = "1.5.6";

		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.6 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.6 initialized.");
			CurrentGlobalState = GlobalState.SetupCompleted;
			InvokeOnInitialized(Universe.OnInitialized);
		}

		private static void InvokeOnInitialized(Action onInitialized)
		{
			if (onInitialized == null)
			{
				return;
			}
			Delegate[] invocationList = onInitialized.GetInvocationList();
			foreach (Delegate @delegate in invocationList)
			{
				try
				{
					@delegate.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_0033: 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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			try
			{
				if (1 == 0)
				{
				}
				string text = (((int)methodType == 1) ? "get_" : (((int)methodType != 2) ? string.Empty : "set_"));
				if (1 == 0)
				{
				}
				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_000f: 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_001e: 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_000f: 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)
		{
			return !string.IsNullOrEmpty(type?.FullName) && (type.IsPrimitive || type.IsEnum || nonPrimitiveTypes.Contains(type) || customTypes.ContainsKey(type.FullName));
		}

		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;
			}
			else
			{
				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)
			{
				return Enum.IsDefined(type, obj) ? Enum.GetName(type, obj) : obj.ToString();
			}
			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_0003: 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)
			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_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_0027: 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 (!(obj is Vector2 val) || 1 == 0)
			{
				return null;
			}
			return FormatDecimalSequence(val.x, val.y);
		}

		internal static object TryParseVector3(string input)
		{
			//IL_0003: 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)
			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_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_0027: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!(obj is Vector3 val) || 1 == 0)
			{
				return null;
			}
			return FormatDecimalSequence(val.x, val.y, val.z);
		}

		internal static object TryParseVector4(string input)
		{
			//IL_0003: 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)
			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_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_0027: 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_0043: 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)
			if (!(obj is Vector4 val) || 1 == 0)
			{
				return null;
			}
			return FormatDecimalSequence(val.x, val.y, val.z, val.w);
		}

		internal static object TryParseQuaternion(string input)
		{
			//IL_0003: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			string[] array = input.Split(' ');
			if (array.Length == 4)
			{
				Quaternion val2 = default(Quaternion);
				val2.x = float.Parse(array[0].Trim(), CultureInfo.CurrentCulture);
				val2.y = float.Parse(array[1].Trim(), CultureInfo.CurrentCulture);
				val2.z = float.Parse(array[2].Trim(), CultureInfo.CurrentCulture);
				val2.w = float.Parse(array[3].Trim(), CultureInfo.CurrentCulture);
				return val2;
			}
			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_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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!(obj is Quaternion val) || 1 == 0)
			{
				return null;
			}
			Vector3 eulerAngles = ((Quaternion)(ref val)).eulerAngles;
			return FormatDecimalSequence(eulerAngles.x, eulerAngles.y, eulerAngles.z);
		}

		internal static object TryParseRect(string input)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_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)
			if (!(obj is Rect val) || 1 == 0)
			{
				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_0003: 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)
			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_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_0027: 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_0043: 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)
			if (!(obj is Color val) || 1 == 0)
			{
				return null;
			}
			return FormatDecimalSequence(val.r, val.g, val.b, val.a);
		}

		internal static object TryParseColor32(string input)
		{
			//IL_0003: 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)
			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_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_002a: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0007: 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_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)
			if (!(obj is LayerMask val) || 1 == 0)
			{
				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_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			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_006c: 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_00e6: 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_00e8: 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_002a: 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)
			_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);
			Color result = default(Color);
			result.r = (float)((decimal)b / 255m);
			result.g = (float)((decimal)b2 / 255m);
			result.b = (float)((decimal)b3 / 255m);
			result.a = 1f;
			return result;
		}

		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
			{
				return Object.op_Implicit((Object)(object)RootObject) && RootObject.activeSelf;
			}
			set
			{
				UniversalUI.SetUIActive(ID, value);
			}
		}

		public UIBase(string id, Action updateMethod)
		{
			//IL_0063: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: 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 val = RootObject.AddComponent<CanvasScaler>();
			val.referenceResolution = new Vector2(1920f, 1080f);
			val.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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_003e: 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);
			}
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = sizeDelta;
			return val;
		}

		internal static void SetDefaultTextValues(Text text)
		{
			//IL_0002: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0143: 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_0005: 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_0061: 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_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_0096: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateUIObject(name, parent);
			UIFactory.SetLayoutGroup<VerticalLayoutGroup>(val, (bool?)true, (bool?)true, (bool?)true, (bool?)true, (int?)0, (int?)1, (int?)1, (int?)1, (int?)1, (TextAnchor?)null);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			co