Decompiled source of MajesticTesting v1.1.7

kg_ExceptionHandler.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Dynamic;
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.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using fastJSON;

[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: Guid("5B1D6F47-404F-487C-B5DC-DB36B9B3FF2E")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyProduct("kg_ExceptionHandler")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("kg_ExceptionHandler")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace kg_ExceptionHandler
{
	public class ExceptionStorage
	{
		public class Exception_Custom
		{
			private readonly string _condition;

			private readonly string _stackTrace;

			private readonly string _time;

			private string _link;

			private readonly string _possibleInvokers;

			private Vector3? _position;

			private readonly string _modName;

			public Exception_Custom(string modname, string condition, string stackTrace, string possibleInvokers = null, string link = null)
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				_condition = condition;
				_stackTrace = stackTrace;
				_time = DateTime.Now.ToString();
				_link = link;
				_modName = modname;
				_possibleInvokers = possibleInvokers;
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					_position = ((Component)Player.m_localPlayer).transform.position;
				}
			}

			public string GetTopic()
			{
				return "<color=#f40000>" + _condition + "</color> (<color=#FFD700>" + (Chainloader_ModNames.ContainsKey(_modName) ? Chainloader_ModNames[_modName] : _modName) + "</color>)";
			}

			public Sprite GetSprite()
			{
				return TryGetIcon(Chainloader_ModNames.ContainsKey(_modName) ? Chainloader_ModNames[_modName] : _modName);
			}

			public string GetMessage()
			{
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				return "Reason - <color=#f40000>" + _condition + "</color>\n\n" + ((_possibleInvokers != null) ? _possibleInvokers : "") + "\n\nStacktrace:\n\n" + _stackTrace + "\n\nTime: " + _time + "\n" + (_position.HasValue ? $"Position: {(int)_position.Value.x} {(int)_position.Value.y} {(int)_position.Value.z}" : "");
			}

			public string GetLink()
			{
				return TryGetLink(Chainloader_ModNames.ContainsKey(_modName) ? Chainloader_ModNames[_modName] : _modName);
			}
		}

		private static ExceptionStorage instance;

		private static readonly AssetBundle asset = kg_ExceptionHandler.GetAssetBundle("kg_exceptionhandlericons");

		public readonly List<Exception_Custom> Exception_List = new List<Exception_Custom>();

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

		private static Dictionary<string, string> ThunderstoreLinks;

		public static Dictionary<string, string> Chainloader_ModNames = new Dictionary<string, string>();

		public static Dictionary<string, List<string>> Detours = new Dictionary<string, List<string>>();

		private static string LatestModName;

		private static int LatestModCount;

		public static ExceptionStorage Instance => instance ?? (instance = new ExceptionStorage());

		private ExceptionStorage()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			Sprite[] array = asset.LoadAllAssets<Sprite>();
			foreach (Sprite val in array)
			{
				IconsByModName.Add(((Object)val).name, val);
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith("links.json"));
			Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name);
			ThunderstoreLinks = JSON.ToObject<Dictionary<string, string>>(new StreamReader(manifestResourceStream).ReadToEnd());
			Application.logMessageReceived += new LogCallback(HandleException);
		}

		private void HandleException(string condition, string stacktrace, LogType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if ((int)type == 4)
			{
				try
				{
					string modName;
					string possibleInvokers;
					string stackTrace = StackTraceBeautifier.Beautify(stacktrace, out modName, out possibleInvokers);
					if (!CheckSpam(modName))
					{
						Exception_Custom item = new Exception_Custom(modName, "Critical: " + condition, stackTrace, possibleInvokers, TryGetLink(modName));
						Exception_List.Insert(0, item);
						ExceptionUI.UpdateList();
					}
				}
				catch
				{
					if (!CheckSpam("Unknown"))
					{
						Exception_Custom item2 = new Exception_Custom("Unknown", "Critical: " + condition, stacktrace);
						Exception_List.Insert(0, item2);
						ExceptionUI.UpdateList();
					}
				}
			}
			if ((int)type == 0 && kg_ExceptionHandler._logErrors.Value)
			{
				try
				{
					string modName2;
					string stackTrace2 = StackTraceBeautifier.ErrorBeautifier(new StackTrace(6).ToString(), out modName2);
					Exception_Custom item3 = new Exception_Custom(modName2, "Error: " + condition, stackTrace2, null, TryGetLink(modName2));
					Exception_List.Insert(0, item3);
				}
				catch
				{
					Exception_Custom item4 = new Exception_Custom("Unknown", "Error " + condition, stacktrace);
					Exception_List.Insert(0, item4);
				}
				ExceptionUI.UpdateList();
			}
		}

		private bool CheckSpam(string ModName)
		{
			if (ModName != LatestModName)
			{
				LatestModName = ModName;
				LatestModCount = 1;
				return false;
			}
			LatestModCount++;
			if (LatestModCount > 5)
			{
				return true;
			}
			return false;
		}

		public static string TryGetLink(string ModName)
		{
			ThunderstoreLinks.TryGetValue(ModName, out var value);
			return value;
		}

		public static Sprite TryGetIcon(string ModName)
		{
			IconsByModName.TryGetValue(ModName, out var value);
			return value;
		}
	}
	public static class ExceptionUI
	{
		[HarmonyPatch(typeof(AudioMan), "Awake")]
		private static class AudioMan_Awake_Patch
		{
			private static void Postfix(AudioMan __instance)
			{
				AUsrc.reverbZoneMix = 0f;
				AUsrc.spatialBlend = 0f;
				AUsrc.bypassListenerEffects = true;
				AUsrc.bypassEffects = true;
				AUsrc.volume = 0.8f;
				AUsrc.outputAudioMixerGroup = __instance.m_masterMixer.outputAudioMixerGroup;
			}
		}

		[HarmonyPatch(typeof(Menu), "IsVisible")]
		private static class Menu_IsVisible_Patch
		{
			private static void Postfix(Menu __instance, ref bool __result)
			{
				if (IsPanelVisible())
				{
					__result = true;
				}
			}
		}

		private static AudioSource AUsrc;

		private static GameObject UI;

		private static GameObject List_Element;

		private static Transform Content;

		private static Text ExceptionText;

		private static Button ClearButton;

		private static Button LinkButton;

		private static Button Main_Button;

		private static readonly List<GameObject> Elements = new List<GameObject>();

		private static GameObject Panel;

		private static string LatestLink;

		public static void Init()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			AssetBundle assetBundle = kg_ExceptionHandler.GetAssetBundle("exceptionhandler");
			AUsrc = Chainloader.ManagerObject.AddComponent<AudioSource>();
			AUsrc.clip = assetBundle.LoadAsset<AudioClip>("ExceptionHandlerClick");
			UI = Object.Instantiate<GameObject>(assetBundle.LoadAsset<GameObject>("ExceptionHandlerUI"));
			List_Element = assetBundle.LoadAsset<GameObject>("ExceptionItem");
			Content = UI.transform.Find("Canvas/Panel/ExceptionList/ListPanel/Scroll View/Viewport/Content");
			ExceptionText = ((Component)UI.transform.Find("Canvas/Panel/InfoTab/Description/Scroll View/Viewport/Content/ExceptionText")).GetComponent<Text>();
			Object.DontDestroyOnLoad((Object)(object)UI);
			Panel = ((Component)UI.transform.Find("Canvas/Panel")).gameObject;
			UI.SetActive(false);
			ClearButton = ((Component)UI.transform.Find("Canvas/Panel/Clear")).GetComponent<Button>();
			LinkButton = ((Component)UI.transform.Find("Canvas/Panel/ModPage")).GetComponent<Button>();
			((UnityEvent)LinkButton.onClick).AddListener(new UnityAction(OpenLink));
			((UnityEvent)ClearButton.onClick).AddListener(new UnityAction(ClearExceptions));
			Main_Button = ((Component)UI.transform.Find("Canvas/button")).GetComponent<Button>();
			((UnityEvent)Main_Button.onClick).AddListener(new UnityAction(ClickOpen));
			((UnityEvent)((Component)UI.transform.Find("Canvas/Panel/SendAll")).GetComponent<Button>().onClick).AddListener(new UnityAction(JoinDiscord));
			Panel.SetActive(false);
			((Component)Utils.FindChild(UI.transform, "addInfo", (IterativeSearchType)0)).GetComponent<Text>().text = kg_ExceptionHandler.Bottom_Text.Value;
			((MonoBehaviour)kg_ExceptionHandler._thistype).StartCoroutine(JiggleUI());
		}

		private static IEnumerator JiggleUI()
		{
			bool increase = true;
			((Component)Main_Button).transform.localScale = Vector3.one;
			while (true)
			{
				if (IsUIVisible())
				{
					if (increase)
					{
						Transform transform = ((Component)Main_Button).transform;
						transform.localScale += Vector3.one * Time.deltaTime * 1f;
						if (((Component)Main_Button).transform.localScale.x >= 1f)
						{
							increase = false;
						}
					}
					else
					{
						Transform transform2 = ((Component)Main_Button).transform;
						transform2.localScale -= Vector3.one * Time.deltaTime * 0.4f;
						if (((Component)Main_Button).transform.localScale.x <= 0.4f)
						{
							increase = true;
						}
					}
				}
				else
				{
					((Component)Main_Button).transform.localScale = Vector3.zero;
				}
				yield return null;
			}
		}

		private static void JoinDiscord()
		{
			AUsrc.Play();
			Application.OpenURL(kg_ExceptionHandler.Discord_Link.Value);
		}

		private static void ClearExceptions()
		{
			AUsrc.Play();
			kg_ExceptionHandler.Storage.Exception_List.Clear();
			UpdateList();
		}

		private static void OpenLink()
		{
			AUsrc.Play();
			if (!string.IsNullOrEmpty(LatestLink))
			{
				Application.OpenURL(LatestLink);
			}
		}

		public static bool IsPanelVisible()
		{
			if ((Object)(object)UI != (Object)null && UI.activeSelf)
			{
				return Panel.activeSelf;
			}
			return false;
		}

		public static bool IsUIVisible()
		{
			if ((Object)(object)UI != (Object)null)
			{
				return UI.activeSelf;
			}
			return false;
		}

		public static void ClosePanel()
		{
			Default();
			Panel.SetActive(false);
		}

		public static void ClickOpen()
		{
			if (IsUIVisible())
			{
				AUsrc.Play();
				Default();
				Panel.SetActive(!Panel.activeSelf);
				if (Panel.activeSelf)
				{
					UpdateList();
					ScrollView_Optimization.StartOptimization(UI, IsPanelVisible, Elements, kg_ExceptionHandler.OptimizationType.Vertical);
				}
			}
		}

		private static void Default()
		{
			((Component)LinkButton).gameObject.SetActive(false);
			LatestLink = "";
			ExceptionText.text = "";
			Elements.ForEach((Action<GameObject>)Object.Destroy);
		}

		public static void UpdateList()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			((Component)LinkButton).gameObject.SetActive(false);
			Elements.ForEach((Action<GameObject>)Object.Destroy);
			Elements.Clear();
			if (kg_ExceptionHandler.Storage.Exception_List.Count == 0)
			{
				Panel.SetActive(false);
				UI.SetActive(false);
				return;
			}
			UI.SetActive(true);
			int num = 0;
			foreach (ExceptionStorage.Exception_Custom exception in kg_ExceptionHandler.Storage.Exception_List)
			{
				GameObject val = Object.Instantiate<GameObject>(List_Element, Content);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchoredPosition -= new Vector2(0f, (float)(num * 70));
				((Component)val.transform.Find("Text")).GetComponent<Text>().text = exception.GetTopic();
				if (Object.op_Implicit((Object)(object)exception.GetSprite()))
				{
					((Component)val.transform.Find("0")).GetComponent<Image>().sprite = exception.GetSprite();
				}
				int cc = num;
				((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					ClickElement(exception, cc);
				});
				Elements.Add(val);
				num++;
			}
			((Component)Content).GetComponent<RectTransform>().SetSizeWithCurrentAnchors((Axis)1, (float)(num * 70 + 14));
		}

		private static void ClickElement(ExceptionStorage.Exception_Custom ex, int index)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			AUsrc.Play();
			foreach (GameObject element in Elements)
			{
				((Graphic)element.GetComponent<Image>()).color = Color.white;
			}
			((Graphic)Elements[index].GetComponent<Image>()).color = Color.green;
			((Component)LinkButton).gameObject.SetActive(false);
			LatestLink = "";
			if (!string.IsNullOrEmpty(ex.GetLink()))
			{
				((Component)LinkButton).gameObject.SetActive(true);
				LatestLink = ex.GetLink();
			}
			ExceptionText.text = ex.GetMessage();
		}
	}
	[BepInPlugin("AAA_kg_ExceptionHandler", "AAA_kg_ExceptionHandler", "1.3.0")]
	public class kg_ExceptionHandler : BaseUnityPlugin
	{
		public enum OptimizationType
		{
			Horizontal,
			Vertical
		}

		private const string GUID = "AAA_kg_ExceptionHandler";

		private const string PluginName = "AAA_kg_ExceptionHandler";

		private const string Version = "1.3.0";

		public static ExceptionStorage Storage;

		public static kg_ExceptionHandler _thistype;

		public static ConfigEntry<bool> _logErrors;

		public static ConfigEntry<KeyCode> Open_UI_Button;

		public static ConfigEntry<string> Bottom_Text;

		public static ConfigEntry<string> Discord_Link;

		private void Awake()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			_thistype = this;
			Storage = ExceptionStorage.Instance;
			_logErrors = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Hook Errors", true, "Errors also will be catched in addition to Exceptions");
			Open_UI_Button = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Hotkey", (KeyCode)292, (ConfigDescription)null);
			Bottom_Text = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Bottom UI Text", "If you want to get help then click \"Join Discord\" button to join OdinPlus discord. Then click \"Mod Support\" channel and post  your BepInEx log with problem description (<color=yellow>Valheim/BepInEx/LogOutput.log</color>)", (ConfigDescription)null);
			Discord_Link = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Discord Link", "https://discord.gg/HXAzpdQG5m", (ConfigDescription)null);
			ExceptionUI.Init();
			new Harmony("AAA_kg_ExceptionHandler").PatchAll();
		}

		public static void DebugFile(string msg)
		{
			string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "exceptionhandler.txt");
			if (!File.Exists(path))
			{
				File.Create(path).Dispose();
			}
			File.AppendAllText(path, msg + Environment.NewLine);
		}

		private static BepInPlugin GetTypesWithHelpAttribute(Assembly assembly)
		{
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				object[] customAttributes = type.GetCustomAttributes(typeof(BepInPlugin), inherit: false);
				if (customAttributes.Length != 0)
				{
					object obj = customAttributes[0];
					return (BepInPlugin)((obj is BepInPlugin) ? obj : null);
				}
			}
			return null;
		}

		private static IEnumerator DelayStart()
		{
			yield return (object)new WaitForEndOfFrame();
			yield return (object)new WaitForEndOfFrame();
			yield return (object)new WaitForEndOfFrame();
			IEnumerable<MethodBase> allPatchedMethods = Harmony.GetAllPatchedMethods();
			foreach (MethodBase item in allPatchedMethods)
			{
				Patches patchInfo = Harmony.GetPatchInfo(item);
				string key = $"<color=#00FFFF>{item.DeclaringType}</color>.<color=#ffd700>{item.Name}</color>".ToLower();
				Process(patchInfo.Postfixes);
				Process(patchInfo.Prefixes);
				Process(patchInfo.Transpilers);
				void Process(ReadOnlyCollection<Patch> _patches)
				{
					foreach (Patch _patch in _patches)
					{
						try
						{
							Assembly assembly = _patch.PatchMethod.Module.Assembly;
							BepInPlugin typesWithHelpAttribute = GetTypesWithHelpAttribute(assembly);
							if (typesWithHelpAttribute != null)
							{
								if (!ExceptionStorage.Detours.ContainsKey(key))
								{
									ExceptionStorage.Detours[key] = new List<string>();
								}
								ExceptionStorage.Detours[key].Add($"{typesWithHelpAttribute.GUID} (v{typesWithHelpAttribute.Version})");
							}
						}
						catch
						{
						}
					}
				}
			}
		}

		private void Start()
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				try
				{
					ExceptionStorage.Chainloader_ModNames[((object)pluginInfo.Value.Instance).GetType().Namespace] = TryFilterName(pluginInfo.Value.Metadata.Name).Replace(" ", "");
				}
				catch (Exception arg)
				{
					MonoBehaviour.print((object)$"Got error processing {pluginInfo.Key}\n({arg})");
				}
			}
			((MonoBehaviour)this).StartCoroutine(DelayStart());
		}

		private string TryFilterName(string name)
		{
			switch (name)
			{
			case "CreatureLevel&LootControl":
				return "CreatureLevelAndLootControl";
			case "SpawnThat!":
				return "SpawnThat";
			case "DropThat!":
				return "DropThat";
			case "PotionsPlus":
				return "PotionPlus";
			case "Detalhes.EraSystem":
				return "ValheimEraSystemVAS";
			case "kgladder":
				return "BetterLadders";
			case "OdinPlusQOL":
				return "OdinsQOL";
			case "Friendlies":
				return "FriendliesReloaded";
			case "FriendliesAssets":
				return "FriendliesReloaded";
			case "FriendliesAI":
				return "FriendliesReloaded";
			case "SkillInjectorMod":
				return "SkillInjector";
			case "SmartContainersMod":
				return "SmartContainers";
			case "UsefulTrophiesMod":
				return "UsefulTrophies";
			case "BlacksmithTools":
				return "BlacksmithsTools";
			case "Basements":
				return "BasementJVLedition";
			case "SpeedyPathsMod":
				return "SpeedyPaths";
			case "EpicValheimsAdditionsbyHuntard":
				return "EpicValheimsAdditions";
			case "AzuMarketplaceSigns":
				return "MarketplaceSigns";
			case "DigitalrootMaxDungeonRooms":
				return "DigitalrootValheimMaxDungeonRooms";
			case "MorePlayerClothColliders":
				return "MoreandModifiedPlayerClothColliders";
			case "CraftyCarts":
				return "CraftyCartsRemake";
			case "BronzeStoneworking":
				return "BronzeStonecutting";
			case "RagnarsRökareMobAI":
			case "RagnarsRökareMobAI":
				return "MobAILib";
			case "MossBuild":
				return "BalrondMossBuilds";
			case "AFeedBalrondTrough":
				return "BalrondTrough";
			case "BalrondBarrell":
				return "BalrondBarrel";
			case "BalrondMetalLocker":
				return "BalrondMetalShelf";
			case "AllTameableOverhaul":
				return "AllTameableTamingOverhaul";
			case "KrumpacZMonsters":
				return "Monsters";
			case "MrSerjiConstruction":
				return "Construction";
			case "TrashItemsMod":
				return "TrashItems";
			case "TransmogrificationKG":
				return "Transmogrification";
			case "MarketplaceAndServerNPCs":
				return "Marketplace_And_Server_NPCs_Revamped";
			default:
				return name;
			}
		}

		private void Update()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)27) && ExceptionUI.IsPanelVisible())
			{
				ExceptionUI.ClosePanel();
				Menu instance = Menu.instance;
				if (instance != null)
				{
					instance.OnClose();
				}
			}
			if (Input.GetKeyDown(Open_UI_Button.Value))
			{
				ExceptionUI.ClickOpen();
			}
		}

		public static AssetBundle GetAssetBundle(string filename)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename));
			using Stream stream = executingAssembly.GetManifestResourceStream(name);
			return AssetBundle.LoadFromStream(stream);
		}

		public IEnumerator UI_OptimizationCoroutine(int size, Func<bool> isVisible, IEnumerable<GameObject> Objects, OptimizationType type)
		{
			while (isVisible())
			{
				switch (type)
				{
				case OptimizationType.Horizontal:
				{
					int width = Screen.width;
					foreach (GameObject Object in Objects)
					{
						float x = Object.transform.position.x;
						if (x - (float)size > (float)width || x - (float)size < 0f)
						{
							Object.SetActive(false);
						}
						else
						{
							Object.SetActive(true);
						}
					}
					break;
				}
				case OptimizationType.Vertical:
				{
					int height = Screen.height;
					foreach (GameObject Object2 in Objects)
					{
						float y = Object2.transform.position.y;
						if (y - (float)size > (float)height || y - (float)size < 0f)
						{
							Object2.SetActive(false);
						}
						else
						{
							Object2.SetActive(true);
						}
					}
					break;
				}
				}
				yield return null;
			}
		}
	}
	public static class StackTraceBeautifier
	{
		private static readonly HashSet<string> Exclude_Mods = new HashSet<string> { "System", "UnityEngine", "BepInEx", "HarmonyLib" };

		public static string Beautify(string stackTrace, out string modName, out string possibleInvokers)
		{
			modName = FindModName(stackTrace);
			possibleInvokers = "Possible Troublemakers <color=#FFD700>" + FindPossibleInvokers(stackTrace) + "</color>";
			stackTrace = FormatAt(stackTrace);
			stackTrace = GetDMDs(stackTrace);
			try
			{
				string text = "";
				string text2 = stackTrace.Split(new char[1] { '\n' })[0].ToLower();
				foreach (KeyValuePair<string, List<string>> detour in ExceptionStorage.Detours)
				{
					if (text2.Contains(detour.Key))
					{
						text += string.Join(",  ", detour.Value);
						break;
					}
				}
				if (text != "")
				{
					possibleInvokers = possibleInvokers + "\n\nMods that patching error method (" + text2 + "):\n<color=#FFD700>" + text + "</color>";
				}
			}
			catch
			{
			}
			return stackTrace;
		}

		private static string FindPossibleInvokers(string orig)
		{
			HashSet<string> hashSet = new HashSet<string>();
			string text = "";
			string[] array = orig.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array)
			{
				string text3 = text2.Split(new char[1] { '.' })[0].Replace("(wrapper dynamic-method) ", "");
				if (((!Exclude_Mods.Contains(text3) && !text3.EndsWith("Manager") && !text3.StartsWith("Rethrow")) || ExceptionStorage.Chainloader_ModNames.ContainsKey(text3)) && !hashSet.Contains(text3))
				{
					hashSet.Add(text3);
					text = text + " - " + text3;
				}
			}
			if (text == "")
			{
				text = null;
			}
			return text;
		}

		private static string FindModName(string orig)
		{
			string[] array = orig.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string text2 = text.Split(new char[1] { '.' })[0];
				if ((!Exclude_Mods.Contains(text2) && !text2.EndsWith("Manager") && !text2.StartsWith("Rethrow")) || ExceptionStorage.Chainloader_ModNames.ContainsKey(text2))
				{
					return text2;
				}
			}
			return "Unknown";
		}

		public static string ErrorBeautifier(string stackTrace, out string modName)
		{
			stackTrace = FormatAtInError(stackTrace);
			modName = FindModName(stackTrace);
			stackTrace = GetDMDs(stackTrace);
			return stackTrace;
		}

		private static string FormatAtInError(string orig)
		{
			orig = orig.Replace(" at ", "").Replace("[0x00000]", "").TrimStart(new char[1] { ' ' });
			int num = orig.IndexOf("in ");
			if (num != -1)
			{
				orig = orig.Substring(0, num);
			}
			return orig;
		}

		private static string FormatAt(string orig)
		{
			while (orig.IndexOf("(at") != -1)
			{
				int num = orig.IndexOf("(at");
				int num2 = orig.IndexOf(")", num);
				orig = orig.Remove(num, num2 - num + 1);
			}
			return orig;
		}

		private static string GetDMDs(string orig)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string[] array = orig.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i];
				if (!text.Contains("(wrapper dynamic-method) "))
				{
					stringBuilder.AppendLine(ColorLine(text));
					continue;
				}
				text = text.Replace("(wrapper dynamic-method) ", "");
				int startIndex = text.IndexOf("::") + 2;
				string text2 = text.Substring(startIndex).Replace(">", "");
				text2 = text2.Insert(text2.IndexOf("("), " ");
				string orig2 = text.Split(new char[1] { '.' }, 2)[0] + "." + text2;
				stringBuilder.AppendLine(ColorLine(orig2));
			}
			stringBuilder.Replace(" ", "\u00a0");
			return stringBuilder.ToString();
		}

		private static string ColorLine(string orig)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string[] array = orig.Split(new char[1] { ' ' }, 2);
			string text = array[0];
			int num = 0;
			string[] array2 = text.Split(new char[1] { '+' });
			string[] array3 = array2;
			foreach (string text2 in array3)
			{
				string[] array4 = text2.Split(new char[1] { '.' });
				for (int j = 0; j < array4.Length; j++)
				{
					if (j == 0)
					{
						stringBuilder.Append("<color=#00FFFF>" + array4[j] + "</color>");
						continue;
					}
					string text3 = "#FFFFFF";
					text3 = ((num + 1 < array2.Length) ? "#B8D05D" : ((j != array4.Length - 1) ? "#B8D05D" : "#FFD700"));
					stringBuilder.Append(".<color=" + text3 + ">" + array4[j] + "</color>");
				}
				num++;
				if (num < array2.Length)
				{
					stringBuilder.Append("+");
				}
			}
			if (array.Length > 1)
			{
				stringBuilder.Append(" " + array[1]);
			}
			return stringBuilder.ToString();
		}
	}
	public static class ScrollView_Optimization
	{
		private static readonly Dictionary<GameObject, Coroutine> Callers = new Dictionary<GameObject, Coroutine>();

		public static void StartOptimization(GameObject caller, Func<bool> isVisible, IEnumerable<GameObject> Objects, kg_ExceptionHandler.OptimizationType type)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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 (Callers.TryGetValue(caller, out var value))
			{
				((MonoBehaviour)kg_ExceptionHandler._thistype).StopCoroutine(value);
			}
			if (Objects.Any())
			{
				int size;
				if (type == kg_ExceptionHandler.OptimizationType.Horizontal)
				{
					GameObject val = Objects.First();
					size = (int)(val.GetComponent<RectTransform>().sizeDelta.x * val.transform.lossyScale.x) / 2;
				}
				else
				{
					GameObject val2 = Objects.First();
					size = (int)(val2.GetComponent<RectTransform>().sizeDelta.y * val2.transform.lossyScale.y) / 2;
				}
				Callers[caller] = ((MonoBehaviour)kg_ExceptionHandler._thistype).StartCoroutine(kg_ExceptionHandler._thistype.UI_OptimizationCoroutine(size, isVisible, Objects, type));
			}
		}
	}
}
namespace fastJSON
{
	internal class DynamicJson : DynamicObject, IEnumerable
	{
		private IDictionary<string, object> _dictionary { get; set; }

		private List<object> _list { get; set; }

		public DynamicJson(string json)
		{
			object obj = JSON.Parse(json);
			if (obj is IDictionary<string, object>)
			{
				_dictionary = (IDictionary<string, object>)obj;
			}
			else
			{
				_list = (List<object>)obj;
			}
		}

		private DynamicJson(object dictionary)
		{
			if (dictionary is IDictionary<string, object>)
			{
				_dictionary = (IDictionary<string, object>)dictionary;
			}
		}

		public override IEnumerable<string> GetDynamicMemberNames()
		{
			return _dictionary.Keys.ToList();
		}

		public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
		{
			object obj = indexes[0];
			if (obj is int)
			{
				result = _list[(int)obj];
			}
			else
			{
				result = _dictionary[(string)obj];
			}
			if (result is IDictionary<string, object>)
			{
				result = new DynamicJson(result as IDictionary<string, object>);
			}
			return true;
		}

		public override bool TryGetMember(GetMemberBinder binder, out object result)
		{
			if (!_dictionary.TryGetValue(binder.Name, out result) && !_dictionary.TryGetValue(binder.Name.ToLowerInvariant(), out result))
			{
				return false;
			}
			if (result is IDictionary<string, object>)
			{
				result = new DynamicJson(result as IDictionary<string, object>);
			}
			else if (result is List<object>)
			{
				List<object> list = new List<object>();
				foreach (object item in (List<object>)result)
				{
					if (item is IDictionary<string, object>)
					{
						list.Add(new DynamicJson(item as IDictionary<string, object>));
					}
					else
					{
						list.Add(item);
					}
				}
				result = list;
			}
			return _dictionary.ContainsKey(binder.Name);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			foreach (object item in _list)
			{
				yield return new DynamicJson(item as IDictionary<string, object>);
			}
		}
	}
	internal sealed class DatasetSchema
	{
		public List<string> Info;

		public string Name;
	}
	internal class DataMemberAttribute : Attribute
	{
		public string Name { get; set; }
	}
	internal static class Formatter
	{
		private static void AppendIndent(StringBuilder sb, int count, string indent)
		{
			while (count > 0)
			{
				sb.Append(indent);
				count--;
			}
		}

		public static string PrettyPrint(string input)
		{
			return PrettyPrint(input, new string(' ', JSON.Parameters.FormatterIndentSpaces));
		}

		public static string PrettyPrint(string input, string spaces)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			int length = input.Length;
			char[] array = input.ToCharArray();
			for (int i = 0; i < length; i++)
			{
				char c = array[i];
				if (c == '"')
				{
					bool flag = true;
					while (flag)
					{
						stringBuilder.Append(c);
						c = array[++i];
						switch (c)
						{
						case '\\':
							stringBuilder.Append(c);
							c = array[++i];
							break;
						case '"':
							flag = false;
							break;
						}
					}
				}
				switch (c)
				{
				case '[':
				case '{':
					stringBuilder.Append(c);
					stringBuilder.AppendLine();
					AppendIndent(stringBuilder, ++num, spaces);
					break;
				case ']':
				case '}':
					stringBuilder.AppendLine();
					AppendIndent(stringBuilder, --num, spaces);
					stringBuilder.Append(c);
					break;
				case ',':
					stringBuilder.Append(c);
					stringBuilder.AppendLine();
					AppendIndent(stringBuilder, num, spaces);
					break;
				case ':':
					stringBuilder.Append(" : ");
					break;
				default:
					if (!char.IsWhiteSpace(c))
					{
						stringBuilder.Append(c);
					}
					break;
				}
			}
			return stringBuilder.ToString();
		}
	}
	internal class Helper
	{
		public static bool IsNullable(Type t)
		{
			if (!t.IsGenericType)
			{
				return false;
			}
			Type genericTypeDefinition = t.GetGenericTypeDefinition();
			return genericTypeDefinition.Equals(typeof(Nullable<>));
		}

		public static Type UnderlyingTypeOf(Type t)
		{
			return Reflection.Instance.GetGenericArguments(t)[0];
		}

		public static DateTimeOffset CreateDateTimeOffset(int year, int month, int day, int hour, int min, int sec, int milli, int extraTicks, TimeSpan offset)
		{
			DateTimeOffset dateTimeOffset = new DateTimeOffset(year, month, day, hour, min, sec, milli, offset);
			if (extraTicks > 0)
			{
				return dateTimeOffset + TimeSpan.FromTicks(extraTicks);
			}
			return dateTimeOffset;
		}

		public static bool BoolConv(object v)
		{
			bool result = false;
			if (v is bool)
			{
				result = (bool)v;
			}
			else if (v is long)
			{
				result = (((long)v > 0) ? true : false);
			}
			else if (v is string)
			{
				string text = (string)v;
				switch (text.ToLowerInvariant())
				{
				case "1":
				case "true":
				case "yes":
				case "on":
					result = true;
					break;
				}
			}
			return result;
		}

		public static long AutoConv(object value, JSONParameters param)
		{
			if (value is string)
			{
				if (param.AutoConvertStringToNumbers)
				{
					string text = (string)value;
					return CreateLong(text, 0, text.Length);
				}
				throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
			}
			if (value is long)
			{
				return (long)value;
			}
			return Convert.ToInt64(value);
		}

		public unsafe static long CreateLong(string s, int index, int count)
		{
			long num = 0L;
			int num2 = 1;
			fixed (char* ptr = s)
			{
				char* ptr2 = ptr;
				ptr2 += index;
				if (*ptr2 == '-')
				{
					num2 = -1;
					ptr2++;
					count--;
				}
				if (*ptr2 == '+')
				{
					ptr2++;
					count--;
				}
				while (count > 0)
				{
					num = num * 10 + (*ptr2 - 48);
					ptr2++;
					count--;
				}
			}
			return num * num2;
		}

		public unsafe static long CreateLong(char[] s, int index, int count)
		{
			long num = 0L;
			int num2 = 1;
			fixed (char* ptr = s)
			{
				char* ptr2 = ptr;
				ptr2 += index;
				if (*ptr2 == '-')
				{
					num2 = -1;
					ptr2++;
					count--;
				}
				if (*ptr2 == '+')
				{
					ptr2++;
					count--;
				}
				while (count > 0)
				{
					num = num * 10 + (*ptr2 - 48);
					ptr2++;
					count--;
				}
			}
			return num * num2;
		}

		public unsafe static int CreateInteger(string s, int index, int count)
		{
			int num = 0;
			int num2 = 1;
			fixed (char* ptr = s)
			{
				char* ptr2 = ptr;
				ptr2 += index;
				if (*ptr2 == '-')
				{
					num2 = -1;
					ptr2++;
					count--;
				}
				if (*ptr2 == '+')
				{
					ptr2++;
					count--;
				}
				while (count > 0)
				{
					num = num * 10 + (*ptr2 - 48);
					ptr2++;
					count--;
				}
			}
			return num * num2;
		}

		public static object CreateEnum(Type pt, object v)
		{
			return Enum.Parse(pt, v.ToString(), ignoreCase: true);
		}

		public static Guid CreateGuid(string s)
		{
			if (s.Length > 30)
			{
				return new Guid(s);
			}
			return new Guid(Convert.FromBase64String(s));
		}

		public static StringDictionary CreateSD(Dictionary<string, object> d)
		{
			StringDictionary stringDictionary = new StringDictionary();
			foreach (KeyValuePair<string, object> item in d)
			{
				stringDictionary.Add(item.Key, (string)item.Value);
			}
			return stringDictionary;
		}

		public static NameValueCollection CreateNV(Dictionary<string, object> d)
		{
			NameValueCollection nameValueCollection = new NameValueCollection();
			foreach (KeyValuePair<string, object> item in d)
			{
				nameValueCollection.Add(item.Key, (string)item.Value);
			}
			return nameValueCollection;
		}

		public static object CreateDateTimeOffset(string value)
		{
			int milli = 0;
			int extraTicks = 0;
			int num = 0;
			int num2 = 0;
			int year = CreateInteger(value, 0, 4);
			int month = CreateInteger(value, 5, 2);
			int day = CreateInteger(value, 8, 2);
			int hour = CreateInteger(value, 11, 2);
			int min = CreateInteger(value, 14, 2);
			int sec = CreateInteger(value, 17, 2);
			int num3 = 20;
			if (value.Length > 21 && value[19] == '.')
			{
				milli = CreateInteger(value, num3, 3);
				num3 = 23;
				if (value.Length > 25 && char.IsDigit(value[num3]))
				{
					extraTicks = CreateInteger(value, num3, 4);
					num3 = 27;
				}
			}
			if (value[num3] == 'Z')
			{
				return CreateDateTimeOffset(year, month, day, hour, min, sec, milli, extraTicks, TimeSpan.Zero);
			}
			if (value[num3] == ' ')
			{
				num3++;
			}
			num = CreateInteger(value, num3 + 1, 2);
			num2 = CreateInteger(value, num3 + 1 + 2 + 1, 2);
			if (value[num3] == '-')
			{
				num = -num;
			}
			return CreateDateTimeOffset(year, month, day, hour, min, sec, milli, extraTicks, new TimeSpan(num, num2, 0));
		}

		public static DateTime CreateDateTime(string value, bool UseUTCDateTime)
		{
			if (value.Length < 19)
			{
				return DateTime.MinValue;
			}
			bool flag = false;
			int millisecond = 0;
			int year = CreateInteger(value, 0, 4);
			int month = CreateInteger(value, 5, 2);
			int day = CreateInteger(value, 8, 2);
			int hour = CreateInteger(value, 11, 2);
			int minute = CreateInteger(value, 14, 2);
			int second = CreateInteger(value, 17, 2);
			if (value.Length > 21 && value[19] == '.')
			{
				millisecond = CreateInteger(value, 20, 3);
			}
			if (value[value.Length - 1] == 'Z')
			{
				flag = true;
			}
			if (!UseUTCDateTime && !flag)
			{
				return new DateTime(year, month, day, hour, minute, second, millisecond);
			}
			return new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Utc).ToLocalTime();
		}
	}
	internal sealed class JSONSerializer
	{
		private StringBuilder _output = new StringBuilder();

		private int _before;

		private int _MAX_DEPTH = 20;

		private int _current_depth;

		private Dictionary<string, int> _globalTypes = new Dictionary<string, int>();

		private Dictionary<object, int> _cirobj;

		private JSONParameters _params;

		private bool _useEscapedUnicode;

		private bool _TypesWritten;

		internal JSONSerializer(JSONParameters param)
		{
			if (param.OverrideObjectHashCodeChecking)
			{
				_cirobj = new Dictionary<object, int>(10, ReferenceEqualityComparer.Default);
			}
			else
			{
				_cirobj = new Dictionary<object, int>();
			}
			_params = param;
			_useEscapedUnicode = _params.UseEscapedUnicode;
			_MAX_DEPTH = _params.SerializerMaxDepth;
		}

		internal string ConvertToJSON(object obj)
		{
			WriteValue(obj);
			if (_params.UsingGlobalTypes && _globalTypes != null && _globalTypes.Count > 0)
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("\"$types\":{");
				bool flag = false;
				foreach (KeyValuePair<string, int> globalType in _globalTypes)
				{
					if (flag)
					{
						stringBuilder.Append(',');
					}
					flag = true;
					stringBuilder.Append('"');
					stringBuilder.Append(globalType.Key);
					stringBuilder.Append("\":\"");
					stringBuilder.Append(globalType.Value);
					stringBuilder.Append('"');
				}
				stringBuilder.Append("},");
				_output.Insert(_before, stringBuilder.ToString());
			}
			return _output.ToString();
		}

		private void WriteValue(object obj)
		{
			if (obj == null || obj is DBNull)
			{
				_output.Append("null");
			}
			else if (obj is string || obj is char)
			{
				WriteString(obj.ToString());
			}
			else if (obj is Guid)
			{
				WriteGuid((Guid)obj);
			}
			else if (obj is bool)
			{
				_output.Append(((bool)obj) ? "true" : "false");
			}
			else if (obj is int || obj is long || obj is decimal || obj is byte || obj is short || obj is sbyte || obj is ushort || obj is uint || obj is ulong)
			{
				_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
			}
			else if (obj is double || obj is double)
			{
				double d = (double)obj;
				if (double.IsNaN(d))
				{
					_output.Append("\"NaN\"");
				}
				else if (double.IsInfinity(d))
				{
					_output.Append('"');
					_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
					_output.Append('"');
				}
				else
				{
					_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
				}
			}
			else if (obj is float || obj is float)
			{
				float f = (float)obj;
				if (float.IsNaN(f))
				{
					_output.Append("\"NaN\"");
				}
				else if (float.IsInfinity(f))
				{
					_output.Append('"');
					_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
					_output.Append('"');
				}
				else
				{
					_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
				}
			}
			else if (obj is DateTime)
			{
				WriteDateTime((DateTime)obj);
			}
			else if (obj is DateTimeOffset)
			{
				WriteDateTimeOffset((DateTimeOffset)obj);
			}
			else if (obj is TimeSpan)
			{
				_output.Append(((TimeSpan)obj).Ticks);
			}
			else if (!_params.KVStyleStringDictionary && obj is IEnumerable<KeyValuePair<string, object>>)
			{
				WriteStringDictionary((IEnumerable<KeyValuePair<string, object>>)obj);
			}
			else if (!_params.KVStyleStringDictionary && obj is IDictionary && obj.GetType().IsGenericType && Reflection.Instance.GetGenericArguments(obj.GetType())[0] == typeof(string))
			{
				WriteStringDictionary((IDictionary)obj);
			}
			else if (obj is IDictionary)
			{
				WriteDictionary((IDictionary)obj);
			}
			else if (obj is byte[])
			{
				WriteBytes((byte[])obj);
			}
			else if (obj is StringDictionary)
			{
				WriteSD((StringDictionary)obj);
			}
			else if (obj is NameValueCollection)
			{
				WriteNV((NameValueCollection)obj);
			}
			else if (obj is Array)
			{
				WriteArrayRanked((Array)obj);
			}
			else if (obj is IEnumerable)
			{
				WriteArray((IEnumerable)obj);
			}
			else if (obj is Enum)
			{
				WriteEnum((Enum)obj);
			}
			else if (Reflection.Instance.IsTypeRegistered(obj.GetType()))
			{
				WriteCustom(obj);
			}
			else
			{
				WriteObject(obj);
			}
		}

		private void WriteDateTimeOffset(DateTimeOffset d)
		{
			DateTime dt = (_params.UseUTCDateTime ? d.UtcDateTime : d.DateTime);
			write_date_value(dt);
			long num = dt.Ticks % 10000000;
			_output.Append('.');
			_output.Append(num.ToString("0000000", NumberFormatInfo.InvariantInfo));
			if (_params.UseUTCDateTime)
			{
				_output.Append('Z');
			}
			else
			{
				if (d.Offset.Hours > 0)
				{
					_output.Append('+');
				}
				else
				{
					_output.Append('-');
				}
				_output.Append(d.Offset.Hours.ToString("00", NumberFormatInfo.InvariantInfo));
				_output.Append(':');
				_output.Append(d.Offset.Minutes.ToString("00", NumberFormatInfo.InvariantInfo));
			}
			_output.Append('"');
		}

		private void WriteNV(NameValueCollection nameValueCollection)
		{
			_output.Append('{');
			bool flag = false;
			foreach (string item in nameValueCollection)
			{
				if (_params.SerializeNullValues || nameValueCollection[item] != null)
				{
					if (flag)
					{
						_output.Append(',');
					}
					if (_params.SerializeToLowerCaseNames)
					{
						WritePair(item.ToLowerInvariant(), nameValueCollection[item]);
					}
					else
					{
						WritePair(item, nameValueCollection[item]);
					}
					flag = true;
				}
			}
			_output.Append('}');
		}

		private void WriteSD(StringDictionary stringDictionary)
		{
			_output.Append('{');
			bool flag = false;
			foreach (DictionaryEntry item in stringDictionary)
			{
				if (_params.SerializeNullValues || item.Value != null)
				{
					if (flag)
					{
						_output.Append(',');
					}
					string text = (string)item.Key;
					if (_params.SerializeToLowerCaseNames)
					{
						WritePair(text.ToLowerInvariant(), item.Value);
					}
					else
					{
						WritePair(text, item.Value);
					}
					flag = true;
				}
			}
			_output.Append('}');
		}

		private void WriteCustom(object obj)
		{
			Reflection.Instance._customSerializer.TryGetValue(obj.GetType(), out var value);
			WriteStringFast(value(obj));
		}

		private void WriteEnum(Enum e)
		{
			if (_params.UseValuesOfEnums)
			{
				WriteValue(Convert.ToInt32(e));
			}
			else
			{
				WriteStringFast(e.ToString());
			}
		}

		private void WriteGuid(Guid g)
		{
			if (!_params.UseFastGuid)
			{
				WriteStringFast(g.ToString());
			}
			else
			{
				WriteBytes(g.ToByteArray());
			}
		}

		private void WriteBytes(byte[] bytes)
		{
			WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None));
		}

		private void WriteDateTime(DateTime dateTime)
		{
			DateTime dt = dateTime;
			if (_params.UseUTCDateTime)
			{
				dt = dateTime.ToUniversalTime();
			}
			write_date_value(dt);
			if (_params.DateTimeMilliseconds)
			{
				_output.Append('.');
				_output.Append(dt.Millisecond.ToString("000", NumberFormatInfo.InvariantInfo));
			}
			if (_params.UseUTCDateTime)
			{
				_output.Append('Z');
			}
			_output.Append('"');
		}

		private void write_date_value(DateTime dt)
		{
			_output.Append('"');
			_output.Append(dt.Year.ToString("0000", NumberFormatInfo.InvariantInfo));
			_output.Append('-');
			_output.Append(dt.Month.ToString("00", NumberFormatInfo.InvariantInfo));
			_output.Append('-');
			_output.Append(dt.Day.ToString("00", NumberFormatInfo.InvariantInfo));
			_output.Append('T');
			_output.Append(dt.Hour.ToString("00", NumberFormatInfo.InvariantInfo));
			_output.Append(':');
			_output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo));
			_output.Append(':');
			_output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo));
		}

		private void WriteObject(object obj)
		{
			int value = 0;
			if (!_cirobj.TryGetValue(obj, out value))
			{
				_cirobj.Add(obj, _cirobj.Count + 1);
			}
			else if (_current_depth > 0 && !_params.InlineCircularReferences)
			{
				_output.Append("{\"$i\":");
				_output.Append(value.ToString());
				_output.Append('}');
				return;
			}
			if (!_params.UsingGlobalTypes)
			{
				_output.Append('{');
			}
			else if (!_TypesWritten)
			{
				_output.Append('{');
				_before = _output.Length;
			}
			else
			{
				_output.Append('{');
			}
			_TypesWritten = true;
			_current_depth++;
			if (_current_depth > _MAX_DEPTH)
			{
				throw new Exception("Serializer encountered maximum depth of " + _MAX_DEPTH);
			}
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			Type type = obj.GetType();
			bool flag = false;
			if (_params.UseExtensions)
			{
				if (!_params.UsingGlobalTypes)
				{
					WritePairFast("$type", Reflection.Instance.GetTypeAssemblyName(type));
				}
				else
				{
					int value2 = 0;
					string typeAssemblyName = Reflection.Instance.GetTypeAssemblyName(type);
					if (!_globalTypes.TryGetValue(typeAssemblyName, out value2))
					{
						value2 = _globalTypes.Count + 1;
						_globalTypes.Add(typeAssemblyName, value2);
					}
					WritePairFast("$type", value2.ToString());
				}
				flag = true;
			}
			Getters[] getters = Reflection.Instance.GetGetters(type, _params.IgnoreAttributes);
			int num = getters.Length;
			for (int i = 0; i < num; i++)
			{
				Getters getters2 = getters[i];
				if (!_params.ShowReadOnlyProperties && getters2.ReadOnly)
				{
					continue;
				}
				object obj2 = getters2.Getter(obj);
				if (!_params.SerializeNullValues && (obj2 == null || obj2 is DBNull))
				{
					continue;
				}
				if (flag)
				{
					_output.Append(',');
				}
				if (getters2.memberName != null)
				{
					WritePair(getters2.memberName, obj2);
				}
				else if (_params.SerializeToLowerCaseNames)
				{
					WritePair(getters2.lcName, obj2);
				}
				else
				{
					WritePair(getters2.Name, obj2);
				}
				if (obj2 != null && _params.UseExtensions)
				{
					Type type2 = obj2.GetType();
					if (type2 == typeof(object))
					{
						dictionary.Add(getters2.Name, type2.ToString());
					}
				}
				flag = true;
			}
			if (dictionary.Count > 0 && _params.UseExtensions)
			{
				_output.Append(",\"$map\":");
				WriteStringDictionary(dictionary);
			}
			_output.Append('}');
			_current_depth--;
		}

		private void WritePairFast(string name, string value)
		{
			WriteStringFast(name);
			_output.Append(':');
			WriteStringFast(value);
		}

		private void WritePair(string name, object value)
		{
			WriteString(name);
			_output.Append(':');
			WriteValue(value);
		}

		private void WriteArray(IEnumerable array)
		{
			_output.Append('[');
			bool flag = false;
			foreach (object item in array)
			{
				if (flag)
				{
					_output.Append(',');
				}
				WriteValue(item);
				flag = true;
			}
			_output.Append(']');
		}

		private void WriteArrayRanked(Array array)
		{
			if (array.Rank == 1)
			{
				WriteArray(array);
				return;
			}
			_output.Append('[');
			bool flag = false;
			foreach (object item in array)
			{
				if (flag)
				{
					_output.Append(',');
				}
				WriteValue(item);
				flag = true;
			}
			_output.Append(']');
		}

		private void WriteStringDictionary(IDictionary dic)
		{
			_output.Append('{');
			bool flag = false;
			foreach (DictionaryEntry item in dic)
			{
				if (_params.SerializeNullValues || item.Value != null)
				{
					if (flag)
					{
						_output.Append(',');
					}
					string text = (string)item.Key;
					if (_params.SerializeToLowerCaseNames)
					{
						WritePair(text.ToLowerInvariant(), item.Value);
					}
					else
					{
						WritePair(text, item.Value);
					}
					flag = true;
				}
			}
			_output.Append('}');
		}

		private void WriteStringDictionary(IEnumerable<KeyValuePair<string, object>> dic)
		{
			_output.Append('{');
			bool flag = false;
			foreach (KeyValuePair<string, object> item in dic)
			{
				if (_params.SerializeNullValues || item.Value != null)
				{
					if (flag)
					{
						_output.Append(',');
					}
					string key = item.Key;
					if (_params.SerializeToLowerCaseNames)
					{
						WritePair(key.ToLowerInvariant(), item.Value);
					}
					else
					{
						WritePair(key, item.Value);
					}
					flag = true;
				}
			}
			_output.Append('}');
		}

		private void WriteDictionary(IDictionary dic)
		{
			_output.Append('[');
			bool flag = false;
			foreach (DictionaryEntry item in dic)
			{
				if (flag)
				{
					_output.Append(',');
				}
				_output.Append('{');
				WritePair("k", item.Key);
				_output.Append(',');
				WritePair("v", item.Value);
				_output.Append('}');
				flag = true;
			}
			_output.Append(']');
		}

		private void WriteStringFast(string s)
		{
			_output.Append('"');
			_output.Append(s);
			_output.Append('"');
		}

		private void WriteString(string s)
		{
			_output.Append('"');
			int num = -1;
			int length = s.Length;
			for (int i = 0; i < length; i++)
			{
				char c = s[i];
				if (_useEscapedUnicode)
				{
					if (c >= ' ' && c < '\u0080' && c != '"' && c != '\\')
					{
						if (num == -1)
						{
							num = i;
						}
						continue;
					}
				}
				else if (c != '\t' && c != '\n' && c != '\r' && c != '"' && c != '\\' && c != 0)
				{
					if (num == -1)
					{
						num = i;
					}
					continue;
				}
				if (num != -1)
				{
					_output.Append(s, num, i - num);
					num = -1;
				}
				switch (c)
				{
				case '\t':
					_output.Append('\\').Append('t');
					continue;
				case '\r':
					_output.Append('\\').Append('r');
					continue;
				case '\n':
					_output.Append('\\').Append('n');
					continue;
				case '"':
				case '\\':
					_output.Append('\\');
					_output.Append(c);
					continue;
				case '\0':
					_output.Append("\\u0000");
					continue;
				}
				if (_useEscapedUnicode)
				{
					_output.Append("\\u");
					StringBuilder output = _output;
					int num2 = c;
					output.Append(num2.ToString("X4", NumberFormatInfo.InvariantInfo));
				}
				else
				{
					_output.Append(c);
				}
			}
			if (num != -1)
			{
				_output.Append(s, num, s.Length - num);
			}
			_output.Append('"');
		}
	}
	internal sealed class JSONParameters
	{
		public bool UseOptimizedDatasetSchema = true;

		public bool UseFastGuid = true;

		public bool SerializeNullValues = true;

		public bool UseUTCDateTime = true;

		public bool ShowReadOnlyProperties;

		public bool UsingGlobalTypes = true;

		[Obsolete("Not needed anymore and will always match")]
		public bool IgnoreCaseOnDeserialize;

		public bool EnableAnonymousTypes;

		public bool UseExtensions = true;

		public bool UseEscapedUnicode = true;

		public bool KVStyleStringDictionary;

		public bool UseValuesOfEnums;

		public List<Type> IgnoreAttributes = new List<Type>
		{
			typeof(XmlIgnoreAttribute),
			typeof(NonSerializedAttribute)
		};

		public bool ParametricConstructorOverride;

		public bool DateTimeMilliseconds;

		public byte SerializerMaxDepth = 20;

		public bool InlineCircularReferences;

		public bool SerializeToLowerCaseNames;

		public byte FormatterIndentSpaces = 3;

		public bool AllowNonQuotedKeys;

		public bool AutoConvertStringToNumbers = true;

		public bool OverrideObjectHashCodeChecking;

		[Obsolete("Racist term removed, please use BadListTypeChecking")]
		public bool BlackListTypeChecking = true;

		public bool BadListTypeChecking = true;

		public bool FullyQualifiedDataSetSchema;

		public void FixValues()
		{
			if (!UseExtensions)
			{
				UsingGlobalTypes = false;
				InlineCircularReferences = true;
			}
			if (EnableAnonymousTypes)
			{
				ShowReadOnlyProperties = true;
			}
		}

		public JSONParameters MakeCopy()
		{
			return new JSONParameters
			{
				AllowNonQuotedKeys = AllowNonQuotedKeys,
				DateTimeMilliseconds = DateTimeMilliseconds,
				EnableAnonymousTypes = EnableAnonymousTypes,
				FormatterIndentSpaces = FormatterIndentSpaces,
				IgnoreAttributes = new List<Type>(IgnoreAttributes),
				InlineCircularReferences = InlineCircularReferences,
				KVStyleStringDictionary = KVStyleStringDictionary,
				ParametricConstructorOverride = ParametricConstructorOverride,
				SerializeNullValues = SerializeNullValues,
				SerializerMaxDepth = SerializerMaxDepth,
				SerializeToLowerCaseNames = SerializeToLowerCaseNames,
				ShowReadOnlyProperties = ShowReadOnlyProperties,
				UseEscapedUnicode = UseEscapedUnicode,
				UseExtensions = UseExtensions,
				UseFastGuid = UseFastGuid,
				UseOptimizedDatasetSchema = UseOptimizedDatasetSchema,
				UseUTCDateTime = UseUTCDateTime,
				UseValuesOfEnums = UseValuesOfEnums,
				UsingGlobalTypes = UsingGlobalTypes,
				AutoConvertStringToNumbers = AutoConvertStringToNumbers,
				OverrideObjectHashCodeChecking = OverrideObjectHashCodeChecking,
				FullyQualifiedDataSetSchema = FullyQualifiedDataSetSchema,
				BadListTypeChecking = BadListTypeChecking
			};
		}
	}
	internal static class JSON
	{
		public static JSONParameters Parameters = new JSONParameters();

		public static string ToNiceJSON(object obj)
		{
			string input = ToJSON(obj, Parameters);
			return Beautify(input);
		}

		public static string ToNiceJSON(object obj, JSONParameters param)
		{
			string input = ToJSON(obj, param);
			return Beautify(input, param.FormatterIndentSpaces);
		}

		public static string ToJSON(object obj)
		{
			return ToJSON(obj, Parameters);
		}

		public static string ToJSON(object obj, JSONParameters param)
		{
			param.FixValues();
			param = param.MakeCopy();
			Type c = null;
			if (obj == null)
			{
				return "null";
			}
			if (obj.GetType().IsGenericType)
			{
				c = Reflection.Instance.GetGenericTypeDefinition(obj.GetType());
			}
			if (typeof(IDictionary).IsAssignableFrom(c) || typeof(List<>).IsAssignableFrom(c))
			{
				param.UsingGlobalTypes = false;
			}
			if (param.EnableAnonymousTypes)
			{
				param.UseExtensions = false;
				param.UsingGlobalTypes = false;
			}
			return new JSONSerializer(param).ConvertToJSON(obj);
		}

		public static object Parse(string json)
		{
			return new JsonParser(json, Parameters.AllowNonQuotedKeys).Decode(null);
		}

		public static dynamic ToDynamic(string json)
		{
			return new DynamicJson(json);
		}

		public static T ToObject<T>(string json)
		{
			return new deserializer(Parameters).ToObject<T>(json);
		}

		public static T ToObject<T>(string json, JSONParameters param)
		{
			return new deserializer(param).ToObject<T>(json);
		}

		public static object ToObject(string json)
		{
			return new deserializer(Parameters).ToObject(json, null);
		}

		public static object ToObject(string json, JSONParameters param)
		{
			return new deserializer(param).ToObject(json, null);
		}

		public static object ToObject(string json, Type type)
		{
			return new deserializer(Parameters).ToObject(json, type);
		}

		public static object ToObject(string json, Type type, JSONParameters par)
		{
			return new deserializer(par).ToObject(json, type);
		}

		public static object FillObject(object input, string json)
		{
			if (!(new JsonParser(json, Parameters.AllowNonQuotedKeys).Decode(input.GetType()) is Dictionary<string, object> d))
			{
				return null;
			}
			return new deserializer(Parameters).ParseDictionary(d, null, input.GetType(), input);
		}

		public static object DeepCopy(object obj)
		{
			return new deserializer(Parameters).ToObject(ToJSON(obj));
		}

		public static T DeepCopy<T>(T obj)
		{
			return new deserializer(Parameters).ToObject<T>(ToJSON(obj));
		}

		public static string Beautify(string input)
		{
			string spaces = new string(' ', Parameters.FormatterIndentSpaces);
			return Formatter.PrettyPrint(input, spaces);
		}

		public static string Beautify(string input, byte spaces)
		{
			string spaces2 = new string(' ', spaces);
			return Formatter.PrettyPrint(input, spaces2);
		}

		public static void RegisterCustomType(Type type, Reflection.Serialize serializer, Reflection.Deserialize deserializer)
		{
			Reflection.Instance.RegisterCustomType(type, serializer, deserializer);
		}

		public static void ClearReflectionCache()
		{
			Reflection.Instance.ClearReflectionCache();
		}
	}
	internal class deserializer
	{
		private JSONParameters _params;

		private bool _usingglobals;

		private Dictionary<object, int> _circobj;

		private Dictionary<int, object> _cirrev = new Dictionary<int, object>();

		public deserializer(JSONParameters param)
		{
			if (param.OverrideObjectHashCodeChecking)
			{
				_circobj = new Dictionary<object, int>(10, ReferenceEqualityComparer.Default);
			}
			else
			{
				_circobj = new Dictionary<object, int>();
			}
			param.FixValues();
			_params = param.MakeCopy();
		}

		public T ToObject<T>(string json)
		{
			Type typeFromHandle = typeof(T);
			object obj = ToObject(json, typeFromHandle);
			if (typeFromHandle.IsArray)
			{
				if ((obj as ICollection).Count == 0)
				{
					Type elementType = typeFromHandle.GetElementType();
					object obj2 = Array.CreateInstance(elementType, 0);
					return (T)obj2;
				}
				return (T)obj;
			}
			return (T)obj;
		}

		public object ToObject(string json)
		{
			return ToObject(json, null);
		}

		public object ToObject(string json, Type type)
		{
			Type type2 = null;
			if (type != null && type.IsGenericType)
			{
				type2 = Reflection.Instance.GetGenericTypeDefinition(type);
			}
			_usingglobals = _params.UsingGlobalTypes;
			if (typeof(IDictionary).IsAssignableFrom(type2) || typeof(List<>).IsAssignableFrom(type2))
			{
				_usingglobals = false;
			}
			object obj = new JsonParser(json, _params.AllowNonQuotedKeys).Decode(type);
			if (obj == null)
			{
				return null;
			}
			if (obj is IDictionary)
			{
				if (type != null && typeof(Dictionary<, >).IsAssignableFrom(type2))
				{
					return RootDictionary(obj, type);
				}
				return ParseDictionary(obj as Dictionary<string, object>, null, type, null);
			}
			if (obj is List<object>)
			{
				if (!(type != null))
				{
					List<object> list = (List<object>)obj;
					if (list.Count > 0 && list[0].GetType() == typeof(Dictionary<string, object>))
					{
						Dictionary<string, object> globaltypes = new Dictionary<string, object>();
						List<object> list2 = new List<object>();
						{
							foreach (object item in list)
							{
								list2.Add(ParseDictionary((Dictionary<string, object>)item, globaltypes, null, null));
							}
							return list2;
						}
					}
					return list.ToArray();
				}
				if (typeof(Dictionary<, >).IsAssignableFrom(type2))
				{
					return RootDictionary(obj, type);
				}
				if (type2 == typeof(List<>))
				{
					return RootList(obj, type);
				}
				if (type.IsArray)
				{
					return RootArray(obj, type);
				}
				if (type == typeof(Hashtable))
				{
					return RootHashTable((List<object>)obj);
				}
			}
			else if (type != null && obj.GetType() != type)
			{
				return ChangeType(obj, type);
			}
			return obj;
		}

		private object RootHashTable(List<object> o)
		{
			Hashtable hashtable = new Hashtable();
			foreach (Dictionary<string, object> item in o)
			{
				object obj = item["k"];
				object obj2 = item["v"];
				if (obj is Dictionary<string, object>)
				{
					obj = ParseDictionary((Dictionary<string, object>)obj, null, typeof(object), null);
				}
				if (obj2 is Dictionary<string, object>)
				{
					obj2 = ParseDictionary((Dictionary<string, object>)obj2, null, typeof(object), null);
				}
				hashtable.Add(obj, obj2);
			}
			return hashtable;
		}

		private object ChangeType(object value, Type conversionType)
		{
			if (conversionType == typeof(object))
			{
				return value;
			}
			if (conversionType == typeof(int))
			{
				if (!(value is string text))
				{
					return (int)(long)value;
				}
				if (_params.AutoConvertStringToNumbers)
				{
					return Helper.CreateInteger(text, 0, text.Length);
				}
				throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
			}
			if (conversionType == typeof(long))
			{
				if (!(value is string text2))
				{
					return (long)value;
				}
				if (_params.AutoConvertStringToNumbers)
				{
					return Helper.CreateLong(text2, 0, text2.Length);
				}
				throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
			}
			if (conversionType == typeof(string))
			{
				return (string)value;
			}
			if (conversionType.IsEnum)
			{
				return Helper.CreateEnum(conversionType, value);
			}
			if (conversionType == typeof(DateTime))
			{
				return Helper.CreateDateTime((string)value, _params.UseUTCDateTime);
			}
			if (conversionType == typeof(DateTimeOffset))
			{
				return Helper.CreateDateTimeOffset((string)value);
			}
			if (Reflection.Instance.IsTypeRegistered(conversionType))
			{
				return Reflection.Instance.CreateCustom((string)value, conversionType);
			}
			if (Helper.IsNullable(conversionType))
			{
				if (value == null)
				{
					return value;
				}
				conversionType = Helper.UnderlyingTypeOf(conversionType);
			}
			if (conversionType == typeof(Guid))
			{
				return Helper.CreateGuid((string)value);
			}
			if (conversionType == typeof(byte[]))
			{
				return Convert.FromBase64String((string)value);
			}
			if (conversionType == typeof(TimeSpan))
			{
				return new TimeSpan((long)value);
			}
			return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture);
		}

		private object RootList(object parse, Type type)
		{
			Type[] genericArguments = Reflection.Instance.GetGenericArguments(type);
			IList list = (IList)Reflection.Instance.FastCreateList(type, ((IList)parse).Count);
			DoParseList((IList)parse, genericArguments[0], list);
			return list;
		}

		private void DoParseList(IList parse, Type it, IList o)
		{
			Dictionary<string, object> globaltypes = new Dictionary<string, object>();
			foreach (object item in parse)
			{
				_usingglobals = false;
				object obj = item;
				obj = ((!(item is Dictionary<string, object> d)) ? ChangeType(item, it) : ParseDictionary(d, globaltypes, it, null));
				o.Add(obj);
			}
		}

		private object RootArray(object parse, Type type)
		{
			Type elementType = type.GetElementType();
			IList list = (IList)Reflection.Instance.FastCreateInstance(typeof(List<>).MakeGenericType(elementType));
			DoParseList((IList)parse, elementType, list);
			Array array = Array.CreateInstance(elementType, list.Count);
			list.CopyTo(array, 0);
			return array;
		}

		private object RootDictionary(object parse, Type type)
		{
			Type[] genericArguments = Reflection.Instance.GetGenericArguments(type);
			Type type2 = null;
			Type type3 = null;
			bool flag = false;
			if (genericArguments != null)
			{
				type2 = genericArguments[0];
				type3 = genericArguments[1];
				if (type3 != null)
				{
					flag = type3.Name.StartsWith("Dictionary");
				}
			}
			Type elementType = type3.GetElementType();
			if (parse is Dictionary<string, object>)
			{
				IDictionary dictionary = (IDictionary)Reflection.Instance.FastCreateInstance(type);
				{
					foreach (KeyValuePair<string, object> item in (Dictionary<string, object>)parse)
					{
						object key = ChangeType(item.Key, type2);
						object value = ((!flag) ? ((!(item.Value is Dictionary<string, object>)) ? ((type3.IsArray && type3 != typeof(byte[])) ? CreateArray((List<object>)item.Value, type3, elementType, null) : ((!(item.Value is IList)) ? ChangeType(item.Value, type3) : CreateGenericList((List<object>)item.Value, type3, type2, null))) : ParseDictionary(item.Value as Dictionary<string, object>, null, type3, null)) : RootDictionary(item.Value, type3));
						dictionary.Add(key, value);
					}
					return dictionary;
				}
			}
			if (parse is List<object>)
			{
				return CreateDictionary(parse as List<object>, type, genericArguments, null);
			}
			return null;
		}

		internal object ParseDictionary(Dictionary<string, object> d, Dictionary<string, object> globaltypes, Type type, object input)
		{
			object value = "";
			if (type == typeof(NameValueCollection))
			{
				return Helper.CreateNV(d);
			}
			if (type == typeof(StringDictionary))
			{
				return Helper.CreateSD(d);
			}
			if (d.TryGetValue("$i", out value))
			{
				object value2 = null;
				_cirrev.TryGetValue((int)(long)value, out value2);
				return value2;
			}
			if (d.TryGetValue("$types", out value))
			{
				_usingglobals = true;
				if (globaltypes == null)
				{
					globaltypes = new Dictionary<string, object>();
				}
				foreach (KeyValuePair<string, object> item in (Dictionary<string, object>)value)
				{
					globaltypes.Add((string)item.Value, item.Key);
				}
			}
			if (globaltypes != null)
			{
				_usingglobals = true;
			}
			bool flag = d.TryGetValue("$type", out value);
			if (!flag && type == typeof(object))
			{
				return d;
			}
			if (flag)
			{
				if (_usingglobals)
				{
					object value3 = "";
					if (globaltypes != null && globaltypes.TryGetValue((string)value, out value3))
					{
						value = value3;
					}
				}
				type = Reflection.Instance.GetTypeFromCache((string)value, _params.BadListTypeChecking);
			}
			if (type == null)
			{
				throw new Exception("Cannot determine type : " + value);
			}
			string fullName = type.FullName;
			object obj = input;
			if (obj == null)
			{
				obj = ((!_params.ParametricConstructorOverride) ? Reflection.Instance.FastCreateInstance(type) : FormatterServices.GetUninitializedObject(type));
			}
			int value4 = 0;
			if (!_circobj.TryGetValue(obj, out value4))
			{
				value4 = _circobj.Count + 1;
				_circobj.Add(obj, value4);
				_cirrev.Add(value4, obj);
			}
			Dictionary<string, myPropInfo> dictionary = Reflection.Instance.Getproperties(type, fullName, _params.ShowReadOnlyProperties);
			foreach (KeyValuePair<string, object> item2 in d)
			{
				string key = item2.Key;
				object value5 = item2.Value;
				string text = key;
				if (text == "$map")
				{
					ProcessMap(obj, dictionary, (Dictionary<string, object>)d[text]);
				}
				else
				{
					if ((!dictionary.TryGetValue(text, out var value6) && !dictionary.TryGetValue(text.ToLowerInvariant(), out value6)) || !value6.CanWrite)
					{
						continue;
					}
					object value7 = null;
					if (value5 != null)
					{
						switch (value6.Type)
						{
						case myPropInfoType.Int:
							value7 = (int)Helper.AutoConv(value5, _params);
							break;
						case myPropInfoType.Long:
							value7 = Helper.AutoConv(value5, _params);
							break;
						case myPropInfoType.String:
							value7 = value5.ToString();
							break;
						case myPropInfoType.Bool:
							value7 = Helper.BoolConv(value5);
							break;
						case myPropInfoType.DateTime:
							value7 = Helper.CreateDateTime((string)value5, _params.UseUTCDateTime);
							break;
						case myPropInfoType.Enum:
							value7 = Helper.CreateEnum(value6.pt, value5);
							break;
						case myPropInfoType.Guid:
							value7 = Helper.CreateGuid((string)value5);
							break;
						case myPropInfoType.Array:
							if (!value6.IsValueType)
							{
								value7 = CreateArray((List<object>)value5, value6.pt, value6.bt, globaltypes);
							}
							break;
						case myPropInfoType.ByteArray:
							value7 = Convert.FromBase64String((string)value5);
							break;
						case myPropInfoType.Dictionary:
							value7 = CreateDictionary((List<object>)value5, value6.pt, value6.GenericTypes, globaltypes);
							break;
						case myPropInfoType.StringKeyDictionary:
							value7 = CreateStringKeyDictionary((Dictionary<string, object>)value5, value6.pt, value6.GenericTypes, globaltypes);
							break;
						case myPropInfoType.NameValue:
							value7 = Helper.CreateNV((Dictionary<string, object>)value5);
							break;
						case myPropInfoType.StringDictionary:
							value7 = Helper.CreateSD((Dictionary<string, object>)value5);
							break;
						case myPropInfoType.Custom:
							value7 = Reflection.Instance.CreateCustom((string)value5, value6.pt);
							break;
						default:
							value7 = ((value6.IsGenericType && !value6.IsValueType && value5 is List<object>) ? CreateGenericList((List<object>)value5, value6.pt, value6.bt, globaltypes) : (((value6.IsClass || value6.IsStruct || value6.IsInterface) && value5 is Dictionary<string, object>) ? ParseDictionary((Dictionary<string, object>)value5, globaltypes, value6.pt, null) : ((!(value5 is List<object>)) ? ((!value6.IsValueType) ? value5 : ChangeType(value5, value6.changeType)) : CreateArray((List<object>)value5, value6.pt, typeof(object), globaltypes))));
							break;
						}
					}
					obj = value6.setter(obj, value7);
				}
			}
			return obj;
		}

		private static void ProcessMap(object obj, Dictionary<string, myPropInfo> props, Dictionary<string, object> dic)
		{
			foreach (KeyValuePair<string, object> item in dic)
			{
				myPropInfo myPropInfo2 = props[item.Key];
				object obj2 = myPropInfo2.getter(obj);
				Type typeFromCache = Reflection.Instance.GetTypeFromCache((string)item.Value, badlistChecking: true);
				if (typeFromCache == typeof(Guid))
				{
					myPropInfo2.setter(obj, Helper.CreateGuid((string)obj2));
				}
			}
		}

		private object CreateArray(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes)
		{
			if (bt == null)
			{
				bt = typeof(object);
			}
			Array array = Array.CreateInstance(bt, data.Count);
			Type elementType = bt.GetElementType();
			for (int i = 0; i < data.Count; i++)
			{
				object obj = data[i];
				if (obj != null)
				{
					if (obj is IDictionary)
					{
						array.SetValue(ParseDictionary((Dictionary<string, object>)obj, globalTypes, bt, null), i);
					}
					else if (obj is ICollection)
					{
						array.SetValue(CreateArray((List<object>)obj, bt, elementType, globalTypes), i);
					}
					else
					{
						array.SetValue(ChangeType(obj, bt), i);
					}
				}
			}
			return array;
		}

		private object CreateGenericList(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes)
		{
			if (pt != typeof(object))
			{
				IList list = (IList)Reflection.Instance.FastCreateList(pt, data.Count);
				Type type = Reflection.Instance.GetGenericArguments(pt)[0];
				{
					foreach (object datum in data)
					{
						if (datum is IDictionary)
						{
							list.Add(ParseDictionary((Dictionary<string, object>)datum, globalTypes, type, null));
						}
						else if (datum is List<object>)
						{
							if (bt.IsGenericType)
							{
								list.Add((List<object>)datum);
							}
							else
							{
								list.Add(((List<object>)datum).ToArray());
							}
						}
						else
						{
							list.Add(ChangeType(datum, type));
						}
					}
					return list;
				}
			}
			return data;
		}

		private object CreateStringKeyDictionary(Dictionary<string, object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes)
		{
			IDictionary dictionary = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
			Type type = null;
			Type type2 = null;
			if (types != null)
			{
				type2 = types[1];
			}
			Type bt = null;
			Type[] genericArguments = Reflection.Instance.GetGenericArguments(type2);
			if (genericArguments.Length != 0)
			{
				bt = genericArguments[0];
			}
			type = type2.GetElementType();
			foreach (KeyValuePair<string, object> item in reader)
			{
				string key = item.Key;
				object obj = null;
				obj = ((!(item.Value is Dictionary<string, object>)) ? ((types != null && type2.IsArray) ? ((!(item.Value is Array)) ? CreateArray((List<object>)item.Value, type2, type, globalTypes) : item.Value) : ((!(item.Value is IList)) ? ChangeType(item.Value, type2) : CreateGenericList((List<object>)item.Value, type2, bt, globalTypes))) : ParseDictionary((Dictionary<string, object>)item.Value, globalTypes, type2, null));
				dictionary.Add(key, obj);
			}
			return dictionary;
		}

		private object CreateDictionary(List<object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes)
		{
			IDictionary dictionary = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
			Type type = null;
			Type type2 = null;
			Type bt = null;
			if (types != null)
			{
				type = types[0];
				type2 = types[1];
			}
			Type bt2 = type2;
			if (type2 != null)
			{
				Type[] genericArguments = Reflection.Instance.GetGenericArguments(type2);
				if (genericArguments.Length != 0)
				{
					bt = genericArguments[0];
				}
				bt2 = type2.GetElementType();
			}
			bool flag = typeof(IDictionary).IsAssignableFrom(type2);
			foreach (Dictionary<string, object> item in reader)
			{
				object obj = item["k"];
				object obj2 = item["v"];
				obj = ((!(obj is Dictionary<string, object>)) ? ChangeType(obj, type) : ParseDictionary((Dictionary<string, object>)obj, globalTypes, type, null));
				obj2 = ((!flag) ? ((!(obj2 is Dictionary<string, object>)) ? ((types != null && type2.IsArray) ? CreateArray((List<object>)obj2, type2, bt2, globalTypes) : ((!(obj2 is IList)) ? ChangeType(obj2, type2) : CreateGenericList((List<object>)obj2, type2, bt, globalTypes))) : ParseDictionary((Dictionary<string, object>)obj2, globalTypes, type2, null)) : RootDictionary(obj2, type2));
				dictionary.Add(obj, obj2);
			}
			return dictionary;
		}
	}
	internal sealed class JsonParser
	{
		private enum Token
		{
			None = -1,
			Curly_Open,
			Curly_Close,
			Squared_Open,
			Squared_Close,
			Colon,
			Comma,
			String,
			Number,
			True,
			False,
			Null,
			PosInfinity,
			NegInfinity,
			NaN
		}

		private readonly char[] json;

		private readonly StringBuilder s = new StringBuilder();

		private Token lookAheadToken = Token.None;

		private int index;

		private bool allownonquotedkey;

		private int _len;

		private SafeDictionary<string, bool> _lookup;

		private SafeDictionary<Type, bool> _seen;

		private bool _parseJsonType;

		private bool _parseType;

		internal JsonParser(string json, bool AllowNonQuotedKeys)
		{
			allownonquotedkey = AllowNonQuotedKeys;
			this.json = json.ToCharArray();
			_len = json.Length;
		}

		private void SetupLookup()
		{
			_lookup = new SafeDictionary<string, bool>();
			_seen = new SafeDictionary<Type, bool>();
			_lookup.Add("$types", value: true);
			_lookup.Add("$type", value: true);
			_lookup.Add("$i", value: true);
			_lookup.Add("$map", value: true);
			_lookup.Add("$schema", value: true);
			_lookup.Add("k", value: true);
			_lookup.Add("v", value: true);
		}

		public unsafe object Decode(Type objtype)
		{
			fixed (char* p = json)
			{
				if (objtype != null && !CheckForTypeInJson(p))
				{
					_parseJsonType = true;
					SetupLookup();
					BuildLookup(objtype);
					if (!_parseJsonType || _lookup.Count() == 7)
					{
						_lookup = null;
					}
				}
				return ParseValue(p);
			}
		}

		private unsafe bool CheckForTypeInJson(char* p)
		{
			int i = 0;
			for (int num = ((_len > 1000) ? 1000 : _len); i < num; i++)
			{
				if (p[i] == '$' && p[i + 1] == 't' && p[i + 2] == 'y' && p[i + 3] == 'p' && p[i + 4] == 'e' && p[i + 5] == 's')
				{
					return true;
				}
			}
			return false;
		}

		private void BuildGenericTypeLookup(Type t)
		{
			if (_seen.TryGetValue(t, out var _))
			{
				return;
			}
			Type[] genericArguments = t.GetGenericArguments();
			foreach (Type type in genericArguments)
			{
				if (!type.IsPrimitive)
				{
					bool flag = type.IsValueType && !type.IsEnum;
					if ((type.IsClass || flag || type.IsAbstract) && type != typeof(string) && type != typeof(DateTime) && type != typeof(Guid))
					{
						BuildLookup(type);
					}
				}
			}
		}

		private void BuildArrayTypeLookup(Type t)
		{
			if (!_seen.TryGetValue(t, out var _))
			{
				bool flag = t.IsValueType && !t.IsEnum;
				if ((t.IsClass || flag) && t != typeof(string) && t != typeof(DateTime) && t != typeof(Guid))
				{
					BuildLookup(t.GetElementType());
				}
			}
		}

		private void BuildLookup(Type objtype)
		{
			if (objtype == null || objtype == typeof(NameValueCollection) || objtype == typeof(StringDictionary) || typeof(IDictionary).IsAssignableFrom(objtype) || _seen.TryGetValue(objtype, out var _))
			{
				return;
			}
			if (objtype.IsGenericType)
			{
				BuildGenericTypeLookup(objtype);
				return;
			}
			if (objtype.IsArray)
			{
				BuildArrayTypeLookup(objtype);
				return;
			}
			_seen.Add(objtype, value: true);
			foreach (KeyValuePair<string, myPropInfo> item in Reflection.Instance.Getproperties(objtype, objtype.FullName, ShowReadOnlyProperties: true))
			{
				Type pt = item.Value.pt;
				_lookup.Add(item.Key, value: true);
				if (pt.IsArray)
				{
					BuildArrayTypeLookup(pt);
				}
				if (pt.IsGenericType)
				{
					if (typeof(IDictionary).IsAssignableFrom(pt))
					{
						_parseJsonType = false;
						break;
					}
					BuildGenericTypeLookup(pt);
				}
				if (pt.FullName.IndexOf("System.") == -1)
				{
					BuildLookup(pt);
				}
			}
		}

		private bool InLookup(string name)
		{
			if (_lookup == null)
			{
				return true;
			}
			bool value;
			return _lookup.TryGetValue(name.ToLowerInvariant(), out value);
		}

		private unsafe Dictionary<string, object> ParseObject(char* p)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			ConsumeToken();
			while (true)
			{
				switch (LookAhead(p))
				{
				case Token.Comma:
					ConsumeToken();
					continue;
				case Token.Curly_Close:
					ConsumeToken();
					return dictionary;
				}
				string text = ParseKey(p);
				Token token = NextToken(p);
				if (token != Token.Colon)
				{
					throw new Exception("Expected colon at index " + index);
				}
				if (_parseJsonType)
				{
					if (text == "$types")
					{
						_parseType = true;
						Dictionary<string, object> dictionary2 = (Dictionary<string, object>)ParseValue(p);
						_parseType = false;
						if (_lookup == null)
						{
							SetupLookup();
						}
						foreach (string key in dictionary2.Keys)
						{
							BuildLookup(Reflection.Instance.GetTypeFromCache(key, badlistChecking: true));
						}
						dictionary[text] = dictionary2;
					}
					else if (text == "$schema")
					{
						_parseType = true;
						object value = ParseValue(p);
						_parseType = false;
						dictionary[text] = value;
					}
					else if (_parseType || InLookup(text))
					{
						dictionary[text] = ParseValue(p);
					}
					else
					{
						SkipValue(p);
					}
				}
				else
				{
					dictionary[text] = ParseValue(p);
				}
			}
		}

		private unsafe void SkipValue(char* p)
		{
			switch (LookAhead(p))
			{
			case Token.Number:
				ParseNumber(p, skip: true);
				break;
			case Token.String:
				SkipString(p);
				break;
			case Token.Curly_Open:
				SkipObject(p);
				break;
			case Token.Squared_Open:
				SkipArray(p);
				break;
			case Token.True:
			case Token.False:
			case Token.Null:
			case Token.PosInfinity:
			case Token.NegInfinity:
			case Token.NaN:
				ConsumeToken();
				break;
			case Token.Curly_Close:
			case Token.Squared_Close:
			case Token.Colon:
			case Token.Comma:
				break;
			}
		}

		private unsafe void SkipObject(char* p)
		{
			ConsumeToken();
			while (true)
			{
				switch (LookAhead(p))
				{
				case Token.Comma:
					ConsumeToken();
					continue;
				case Token.Curly_Close:
					ConsumeToken();
					return;
				}
				SkipString(p);
				Token token = NextToken(p);
				if (token != Token.Colon)
				{
					throw new Exception("Expected colon at index " + index);
				}
				SkipValue(p);
			}
		}

		private unsafe void SkipArray(char* p)
		{
			ConsumeToken();
			while (true)
			{
				switch (LookAhead(p))
				{
				case Token.Comma:
					ConsumeToken();
					break;
				case Token.Squared_Close:
					ConsumeToken();
					return;
				default:
					SkipValue(p);
					break;
				}
			}
		}

		private unsafe void SkipString(char* p)
		{
			ConsumeToken();
			int len = _len;
			while (index < len)
			{
				switch (p[index++])
				{
				case '"':
					return;
				case '\\':
				{
					char c = p[index++];
					if (c == 'u')
					{
						index += 4;
					}
					break;
				}
				}
			}
		}

		private unsafe List<object> ParseArray(char* p)
		{
			List<object> list = new List<object>();
			ConsumeToken();
			while (true)
			{
				switch (LookAhead(p))
				{
				case Token.Comma:
					ConsumeToken();
					break;
				case Token.Squared_Close:
					ConsumeToken();
					return list;
				default:
					list.Add(ParseValue(p));
					break;
				}
			}
		}

		private unsafe object ParseValue(char* p)
		{
			switch (LookAhead(p))
			{
			case Token.Number:
				return ParseNumber(p, skip: false);
			case Token.String:
				return ParseString(p);
			case Token.Curly_Open:
				return ParseObject(p);
			case Token.Squared_Open:
				return ParseArray(p);
			case Token.True:
				ConsumeToken();
				return true;
			case Token.False:
				ConsumeToken();
				return false;
			case Token.Null:
				ConsumeToken();
				return null;
			case Token.PosInfinity:
				ConsumeToken();
				return double.PositiveInfinity;
			case Token.NegInfinity:
				ConsumeToken();
				return double.NegativeInfinity;
			case Token.NaN:
				ConsumeToken();
				return double.NaN;
			default:
				throw new Exception("Unrecognized token at index " + index);
			}
		}

		private unsafe string ParseKey(char* p)
		{
			if (!allownonquotedkey || p[index - 1] == '"')
			{
				return ParseString(p);
			}
			ConsumeToken();
			int len = _len;
			int num = 0;
			while (index + num < len)
			{
				char c = p[index + num++];
				if (c == ':')
				{
					string result = UnsafeSubstring(p, index, num - 1).Trim();
					index += num - 1;
					return result;
				}
			}
			throw new Exception("Unable to read key");
		}

		private unsafe string ParseString(char* p)
		{
			char c = p[index - 1];
			ConsumeToken();
			if (s.Length > 0)
			{
				s.Length = 0;
			}
			int len = _len;
			int num = 0;
			while (index + num < len)
			{
				char c2 = p[index + num++];
				if (c2 == '\\')
				{
					break;
				}
				if (c2 == c)
				{
					string result = UnsafeSubstring(p, index, num - 1);
					index += num;
					return result;
				}
			}
			while (index < len)
			{
				char c3 = p[index++];
				if (c3 == c)
				{
					return s.ToString();
				}
				if (c3 != '\\')
				{
					s.Append(c3);
					continue;
				}
				c3 = p[index++];
				switch (c3)
				{
				case 'b':
					s.Append('\b');
					continue;
				case 'f':
					s.Append('\f');
					continue;
				case 'n':
					s.Append('\n');
					continue;
				case 'r':
					s.Append('\r');
					continue;
				case 't':
					s.Append('\t');
					continue;
				case 'u':
				{
					uint num2 = ParseUnicode(p[index], p[index + 1], p[index + 2], p[index + 3]);
					s.Append((char)num2);
					index += 4;
					continue;
				}
				}
				if (c3 == '\r' || c3 == '\n' || c3 == ' ' || c3 == '\t')
				{
					while (c3 == '\r' || c3 == '\n' || c3 == ' ' || c3 == '\t')
					{
						index++;
						c3 = p[index];
						if (c3 == '\r' || c3 == '\n')
						{
							c3 = p[index + 1];
							if (c3 == '\r' || c3 == '\n')
							{
								index += 2;
								c3 = p[index];
							}
							break;
						}
					}
				}
				else
				{
					s.Append(c3);
				}
			}
			return s.ToString();
		}

		private unsafe string ParseJson5String(char* p)
		{
			throw new NotImplementedException();
		}

		private uint ParseSingleChar(char c1, uint multipliyer)
		{
			uint result = 0u;
			if (c1 >= '0' && c1 <= '9')
			{
				result = (uint)(c1 - 48) * multipliyer;
			}
			else if (c1 >= 'A' && c1 <= 'F')
			{
				result = (uint)(c1 - 65 + 10) * multipliyer;
			}
			else if (c1 >= 'a' && c1 <= 'f')
			{
				result = (uint)(c1 - 97 + 10) * multipliyer;
			}
			return result;
		}

		private uint ParseUnicode(char c1, char c2, char c3, char c4)
		{
			uint num = ParseSingleChar(c1, 4096u);
			uint num2 = ParseSingleChar(c2, 256u);
			uint num3 = ParseSingleChar(c3, 16u);
			uint num4 = ParseSingleChar(c4, 1u);
			return num + num2 + num3 + num4;
		}

		private unsafe object ParseNumber(char* p, bool skip)
		{
			ConsumeToken();
			int num = index - 1;
			bool flag = false;
			bool flag2 = false;
			bool flag3 = true;
			if (p[num] == '.')
			{
				flag = true;
			}
			while (index != _len)
			{
				switch (p[index])
				{
				case 'X':
				case 'x':
					index++;
					return ReadHexNumber(p);
				case '+':
				case '-':
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					index++;
					break;
				case 'E':
				case 'e':
					flag2 = true;
					index++;
					break;
				case '.':
					index++;
					flag = true;
					break;
				case 'N':
				case 'n':
					index += 3;
					return double.NaN;
				default:
					flag3 = false;
					break;
				}
				if (index == _len)
				{
					flag3 = false;
				}
				if (!flag3)
				{
					break;
				}
			}
			if (skip)
			{
				return 0;
			}
			int num2 = index - num;
			if (flag2 || num2 > 31)
			{
				string text = UnsafeSubstring(p, num, num2);
				return double.Parse(text, NumberFormatInfo.InvariantInfo);
			}
			if (!flag && num2 < 20)
			{
				return Helper.CreateLong(json, num, num2);
			}
			string text2 = UnsafeSubstring(p, num, num2);
			return decimal.Parse(text2, NumberFormatInfo.InvariantInfo);
		}

		private unsafe object ReadHexNumber(char* p)
		{
			long num = 0L;
			bool flag = true;
			while (flag && index < _len)
			{
				char c = p[index];
				switch (c)
				{
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					index++;
					num = (num << 4) + (c - 48);
					break;
				case 'a':
				case 'b':
				case 'c':
				case 'd':
				case 'e':
				case 'f':
					index++;
					num = (num << 4) + (c - 97) + 10;
					break;
				case 'A':
				case 'B':
				case 'C':
				case 'D':
				case 'E':
				case 'F':
					index++;
					num = (num << 4) + (c - 65) + 10;
					break;
				default:
					flag = false;
					break;
				}
			}
			return num;
		}

		private unsafe Token LookAhead(char* p)
		{
			if (lookAheadToken != Token.None)
			{
				return lookAheadToken;
			}
			return lookAheadToken = NextTokenCore(p);
		}

		private void ConsumeToken()
		{
			lookAheadToken = Token.None;
		}

		private unsafe Token NextToken(char* p)
		{
			Token result = ((lookAheadToken != Token.None) ? lookAheadToken : NextTokenCore(p));
			lookAheadToken = Token.None;
			return result;
		}

		private unsafe void SkipWhitespace(char* p)
		{
			char c;
			do
			{
				c = p[index];
				if (c == '/' && p[index + 1] == '/')
				{
					index++;
					index++;
					do
					{
						c = p[index];
					}
					while (c != '\r' && c != '\n' && ++index < _len);
				}
				if (c != '/' || p[index + 1] != '*')
				{
					continue;
				}
				index++;
				index++;
				do
				{
					c = p[index];
					if (c == '*' && p[index + 1] == '/')
					{
						index += 2;
						c = p[index];
						break;
					}
				}
				while (++index < _len);
			}
			while ((c == ' ' || c == '\t' || c == '\n' || c == '\r') && ++index < _len);
		}

		private unsafe Token NextTokenCore(char* p)
		{
			int len = _len;
			SkipWhitespace(p);
			if (index == len)
			{
				throw new Exception("Reached end of string unexpectedly");
			}
			char c = p[index];
			index++;
			switch (c)
			{
			case '{':
				return Token.Curly_Open;
			case '}':
				return Token.Curly_Close;
			case '[':
				return Token.Squared_Open;
			case ']':
				return Token.Squared_Close;
			case ',':
				return Token.Comma;
			case '"':
			case '\'':
				return Token.String;
			case '-':
				if (p[index] == 'i' || p[index] == 'I')
				{
					index += 8;
					return Token.NegInfinity;
				}
				return Token.Number;
			case '+':
				if (p[index] == 'i' || p[index] == 'I')
				{
					index += 8;
					return Token.PosInfinity;
				}
				return Token.Number;
			case '.':
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				return Token.Number;
			case ':':
				return Token.Colon;
			case 'I':
			case 'i':
				index += 7;
				return Token.PosInfinity;
			case 'f':
				if (len - index >= 4 && p[index] == 'a' && p[index + 1] == 'l' && p[index + 2] == 's' && p[index + 3] == 'e')
				{
					index += 4;
					return Token.False;
				}
				break;
			case 't':
				if (len - index >= 3 && p[index] == 'r' && p[index + 1] == 'u' && p[index + 2] == 'e')
				{
					index += 3;
					return Token.True;
				}
				break;
			case 'N':
			case 'n':
				if (len - index >= 3 && p[index] == 'u' && p[index + 1] == 'l' && p[index + 2] == 'l')
				{
					index += 3;
					return Token.Null;
				}
				if (len - index >= 2 && p[index] == 'a' && (p[index + 1] == 'n' || p[index + 1] == 'N'))
				{
					index += 2;
					return Token.NaN;
				}
				break;
			}
			if (allownonquotedkey)
			{
				index--;
				return Token.String;
			}
			throw new Exception("Could not find token at index " + --index + " got '" + p[index].ToString() + "'");
		}

		private unsafe static string UnsafeSubstring(char* p, int startIndex, int length)
		{
			return new string(p, startIndex, length);
		}
	}
	internal struct Getters
	{
		public string Name;

		public string lcName;

		public string memberName;

		public Reflection.GenericGetter Getter;

		public bool ReadOnly;
	}
	internal enum myPropInfoType
	{
		Int,
		Long,
		String,
		Bool,
		DateTime,
		Enum,
		Guid,
		Array,
		ByteArray,
		Dictionary,
		StringKeyDictionary,
		NameValue,
		StringDictionary,
		Hashtable,
		DataSet,
		DataTable,
		Custom,
		Unknown
	}
	internal class myPropInfo
	{
		public Type pt;

		public Type bt;

		public Type changeType;

		public Reflection.GenericSetter setter;

		public Reflection.GenericGetter getter;

		public Type[] GenericTypes;

		public string Name;

		public string memberName;

		public myPropInfoType Type;

		public bool CanWrite;

		public bool IsClass;

		public bool IsValueType;

		public bool IsGenericType;

		public bool IsStruct;

		public bool IsInterface;
	}
	internal sealed class Reflection
	{
		public delegate string Serialize(object data);

		public delegate object Deserialize(string data);

		public delegate object GenericSetter(object target, object value);

		public delegate object GenericGetter(object obj);

		private delegate object CreateObject();

		private delegate object CreateList(int capacity);

		private static readonly Reflection instance;

		public static bool RDBMode;

		private SafeDictionary<Type, string> _tyname = new SafeDictionary<Type, string>(10);

		private SafeDictionary<string, Type> _typecache = new SafeDictionary<string, Type>(10);

		private SafeDictionary<Type, CreateObject> _constrcache = new SafeDictionary<Type, CreateObject>(10);

		private SafeDictionary<Type, CreateList> _conlistcache = new SafeDictionary<Type, CreateList>(10);

		private SafeDictionary<Type, Getters[]> _getterscache = new SafeDictionary<Type, Getters[]>(10);

		private SafeDictionary<string, Dictionary<string, myPropInfo>> _propertycache = new SafeDictionary<string, Dictionary<string, myPropInfo>>(10);

		private SafeDictionary<Type, Type[]> _genericTypes = new SafeDictionary<Type, Type[]>(10);

		private SafeDictionary<Type, Type> _genericTypeDef = new SafeDictionary<Type, Type>(10);

		private static SafeDictionary<short, OpCode> _opCodes;

		private static List<string> _badlistTypes;

		private static UTF8Encoding utf8;

		internal SafeDictionary<Type, Serialize> _customSerializer = new SafeDictionary<Type, Serialize>();

		internal SafeDictionary<Type, Deserialize> _customDeserializer = new SafeDictionary<Type, Deserialize>();

		public static Reflection Instance => instance;

		static Reflection()
		{
			instance = new Reflection();
			RDBMode = false;
			_badlistTypes = new List<string> { "system.configuration.install.assemblyinstaller", "system.activities.presentation.workflowdesigner", "system.windows.resourcedictionary", "system.windows.data.objectdataprovider", "system.windows.forms.bindingsource", "microsoft.exchange.management.systemmanager.winforms.exchangesettingsprovider" };
			utf8 = new UTF8Encoding();
		}

		private Reflection()
		{
		}

		private static bool TryGetOpCode(short code, out OpCode opCode)
		{
			if (_opCodes != null)
			{
				return _opCodes.TryGetValue(code, out opCode);
			}
			SafeDictionary<short, OpCode> safeDictionary = new SafeDictionary<short, OpCode>();
			FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (typeof(OpCode).IsAssignableFrom(fieldInfo.FieldType))
				{
					OpCode value = (OpCode)fieldInfo.GetValue(null);
					if (value.OpCodeType != OpCodeType.Nternal)
					{
						safeDictionary.Add(value.Value, value);
					}
				}
			}
			_opCodes = safeDictionary;
			return _opCodes.TryGetValue(code, out opCode);
		}

		public static byte[] UTF8GetBytes(string str)
		{
			return utf8.GetBytes(str);
		}

		public static string UTF8GetString(byte[] bytes, int offset, int len)
		{
			return utf8.GetString(bytes, offset, len);
		}

		public unsafe static byte[] UnicodeGetBytes(string str)
		{
			int num = str.Length * 2;
			byte[] array = new byte[num];
			fixed (void* value = str)
			{
				Marshal.Copy(new IntPtr(value), array, 0, num);
			}
			return array;
		}

		public static string UnicodeGetString(byte[] b)
		{
			return UnicodeGetString(b, 0, b.Length);
		}

		public unsafe static string UnicodeGetString(byte[] bytes, int offset, int buflen)
		{
			string text = "";
			fixed (byte* ptr = bytes)
			{
				char* value = (char*)(ptr + offset);
				text = new string(value, 0, buflen / 2);
			}
			return text;
		}

		internal object CreateCustom(string v, Type type)
		{
			_customDeserializer.TryGetValue(type, out var value);
			return value(v);
		}

		internal void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer)
		{
			if (type != null && serializer != null && deserializer != null)
			{
				_customSerializer.Add(type, serializer);
				_customDeserializer.Add(type, deserializer);
				Instance.ResetPropertyCache();
			}
		}

		internal bool IsTypeRegistered(Type t)
		{
			if (_customSerializer.Count() == 0)
			{
				return false;
			}
			Serialize value;
			return _customSerializer.TryGetValue(t, out value);
		}

		public Type GetGenericTypeDefinition(Type t)
		{
			Type value = null;
			if (_genericTypeDef.TryGetValue(t, out value))
			{
				return value;
			}
			value = t.GetGenericTypeDefinition();
			_genericTypeDef.Add(t, value);
			return value;
		}

		public Type[] GetGenericArguments(Type t)
		{
			Type[] value = null;
			if (_genericTypes.TryGetValue(t, out value))
			{
				return value;
			}
			value = t.GetGenericArguments();
			_genericTypes.Add(t, value);
			return value;
		}

		public Dictionary<string, myPropInfo> Getproperties(Type type, string typename, bool ShowReadOnlyProperties)
		{
			Dictionary<string, myPropInfo> value = null;
			if (_propertycache.TryGetValue(typename, out value))
			{
				return value;
			}
			value = new Dictionary<string, myPropInfo>(10);
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
			PropertyInfo[] properties = type.GetProperties(bindingAttr);
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				if (propertyInfo.GetIndexParameters().Length != 0)
				{
					continue;
				}
				myPropInfo myPropInfo2 = CreateMyProp(propertyInfo.PropertyType, propertyInfo.Name);
				myPropInfo2.setter = CreateSetMethod(type, propertyInfo, ShowReadOnlyProperties);
				if (myPropInfo2.setter != null)
				{
					myPropInfo2.CanWrite = true;
				}
				myPropInfo2.getter = CreateGetMethod(type, propertyInfo);
				object[] customAttributes = propertyInfo.GetCustomAttributes(inherit: true);
				object[] array2 = customAttributes;
				foreach (object obj in array2)
				{
					if (obj is DataMemberAttribute)
					{
						DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)obj;
						if (dataMemberAttribute.Name != "")
						{
							myPropInfo2.memberName = dataMemberAttribute.Name;
						}
					}
				}
				if (myPropInfo2.memberName != null)
				{
					value.Add(myPropInfo2.memberName, myPropInfo2);
				}
				else
				{
					value.Add(propertyInfo.Name.ToLowerInvariant(), myPropInfo2);
				}
			}
			FieldInfo[] fields = type.GetFields(bindingAttr);
			FieldInfo[] array3 = fields;
			foreach (FieldInfo fieldInfo in array3)
			{
				myPropInfo myPropInfo3 = CreateMyProp(fieldInfo.FieldType, fieldInfo.Name);
				if (fieldInfo.IsLiteral)
				{
					continue;
				}
				if (!fieldInfo.IsInitOnly)
				{
					myPropInfo3.setter = CreateSetField(type, fieldInfo);
				}
				if (myPropInfo3.setter != null)
				{
					myPropInfo3.CanWrite = true;
				}
				myPropInfo3.getter = CreateGetField(type, fieldInfo);
				object[] customAttributes2 = fieldInfo.GetCustomAttributes(inherit: true);
				object[] array4 = customAttributes2;
				foreach (object obj2 in array4)
				{
					if (obj2 is DataMemberAttribute)
					{
						DataMemberAttribute dataMemberAttribute2 = (DataMemberAttribute)obj2;
						if (dataMemberAttribute2.Name != "")
						{
							myPropInfo3.memberName = dataMemberAttribute2.Name;
						}
					}
				}
				if (myPropInfo3.memberName != null)
				{
					value.Add(myPropInfo3.memberName, myPropInfo3);
				}
				else
				{
					value.Add(fieldInfo.Name.ToLowerInvariant(), myPropInfo3);
				}
			}
			_propertycache.Add(typename, value);
			return value;
		}

		private myPropInfo CreateMyProp(Type t, string name)
		{
			myPropInfo myPropInfo2 = new myPropInfo();
			myPropInfoType type = myPropInfoType.Unknown;
			if (t == typeof(int) || t == typeof(int?))
			{
				type = myPropInfoType.Int;
			}
			else if (t == typeof(long) || t == typeof(long?))
			{
				type = myPropInfoType.Long;
			}
			else if (t == typeof(string))
			{
				type = myPropInfoType.String;
			}
			else if (t == typeof(bool) || t == typeof(bool?))
			{
				type = myPropInfoType.Bool;
			}
			else if (t == typeof(DateTime) || t == typeof(DateTime?))
			{
				type = myPropInfoType.DateTime;
			}
			else if (t.IsEnum)
			{
				type = myPropInfoType.Enum;
			}
			else if (t == typeof(Guid) || t == typeof(Guid?))
			{
				type = myPropInfoType.Guid;
			}
			else if (t == typeof(StringDictionary))
			{
				type = myPropInfoType.StringDictionary;
			}
			else if (t == typeof(NameValueCollection))
			{
				type = myPropInfoType.NameValue;
			}
			else if (t.IsArray)
			{
				myPropInfo2.bt = t.GetElementType();
				type = ((!(t == typeof(byte[]))) ? myPropInfoType.Array : myPropInfoType.ByteArray);
			}
			else if (t.Name.Contains("Dictionary"))
			{
				myPropInfo2.GenericTypes = Instance.GetGenericArguments(t);
				type = ((myPropInfo2.GenericTypes.Length == 0 || !(myPropInfo2.GenericTypes[0] == typeof(string))) ? myPropInfoType.Dictionary : myPropInfoType.StringKeyDictionary);
			}
			else if (IsTypeRegistered(t))
			{
				type = myPropInfoType.Custom;
			}
			if (t.IsValueType && !t.IsPrimitive && !t.IsEnum && t != typeof(decimal))
			{
				myPropInfo2.IsStruct = true;
			}
			myPropInfo2.IsInterface = t.IsInterface;
			myPropInfo2.IsClass = t.IsClass;
			myPropInfo2.IsValueType = t.IsValueType;
			if (t.IsGenericType)
			{
				myPropInfo2.IsGenericType = true;
				myPropInfo2.bt = Instance.GetGenericArguments(t)[0];
			}
			myPropInfo2.pt = t;
			myPropInfo2.Name = name;
			myPropInfo2.changeType = GetChangeType(t);
			myPropInfo2.Type = type;
			return myPropInfo2;
		}

		private Type GetChangeType(Type conversionType)
		{

Valheim.WhereAmI.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SpawnThat.Utilities.Extensions;
using SpawnThat.World.Dungeons;
using SpawnThat.World.Locations;
using SpawnThat.World.Zone;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Valheim.WhereAmI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Valheim.WhereAmI")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9bec6429-99ef-4705-b890-e77ddb0b8dd7")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Valheim.WhereAmI
{
	[HarmonyPatch(typeof(Hud))]
	public class HudPatch
	{
		private static GameObject HudGameObject;

		private static RectTransform HudTransform;

		private static string FontName = "AveriaSerifLibre-Bold";

		private static int FontSize = 12;

		public static Vector2 HudPosition = new Vector2((float)(Screen.width / 10), (float)(Screen.height / 4 * 3));

		public static Vector2 Offset = new Vector2(0f, 0f);

		public static float UpdateInterval = 0.1f;

		public static float UpdateTime = 0f;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Instantiate(Hud __instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			HudGameObject = new GameObject("WhereAmI_Hud");
			HudTransform = HudGameObject.AddComponent<RectTransform>();
			((Transform)HudTransform).SetParent(__instance.m_rootObject.transform);
			((Transform)HudTransform).localScale = Vector3.one;
			HudTransform.anchoredPosition = Vector2.zero;
			HudGameObject.AddComponent<Text>().font = GetFont(FontName, FontSize);
			HudTransform.SetSizeWithCurrentAnchors((Axis)0, 300f);
			HudTransform.SetSizeWithCurrentAnchors((Axis)1, 300f);
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void OnUpdate(Hud __instance)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || Player.m_localPlayer == null)
			{
				return;
			}
			UpdateTime += Time.deltaTime;
			if (UpdateTime < UpdateInterval)
			{
				return;
			}
			UpdateTime = 0f;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(HudPosition.x, HudPosition.y, 0f);
			if (!((Object)(object)HudGameObject != (Object)null))
			{
				return;
			}
			HudGameObject.transform.position = val + new Vector3(Offset.x, Offset.y, 0f);
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			SimpleLocation location = LocationManager.GetLocation(position);
			string text = "---";
			RoomData containingRoom = RoomManager.GetContainingRoom(position);
			if (containingRoom != null)
			{
				text = containingRoom.Name;
				text = text.Split(new char[1] { '(' }).First();
			}
			IZone zone = ZoneManager.GetZone(Vector3Extensions.GetZoneId(position));
			Text component = HudGameObject.GetComponent<Text>();
			string text2 = $"Position: {position}\n" + $"Biome: {EnvMan.instance.GetBiome()}\n" + "Location: " + (location?.LocationName ?? "---") + "\nRoom: " + text + "\n" + $"Zone ID: {Vector3Extensions.GetZoneId(position)}\n";
			string text3 = "";
			string text4 = "";
			if (EnvMan.instance != null)
			{
				text3 = EnvMan.instance.GetCurrentEnvironment()?.m_name;
				BiomeEnvSetup biomeEnvSetup = EnvMan.instance.GetBiomeEnvSetup(EnvMan.instance.GetBiome());
				object obj;
				if (biomeEnvSetup == null)
				{
					obj = null;
				}
				else
				{
					List<EnvEntry> environments = biomeEnvSetup.m_environments;
					if (environments == null)
					{
						obj = null;
					}
					else
					{
						IEnumerable<string> enumerable = environments.Select((EnvEntry x) => x.m_env.m_name);
						obj = ((enumerable != null) ? GeneralExtensions.Join<string>(enumerable, (Func<string, string>)null, ", ") : null);
					}
				}
				if (obj == null)
				{
					obj = "";
				}
				text4 = (string)obj;
			}
			text2 = text2 + $"Zone Biome: {zone.Biome}\n" + $"Zone Calc Biome: {zone.GetBiome(position)}\n" + "Zone Corners: " + GeneralExtensions.Join<Biome>((IEnumerable<Biome>)zone.BiomeCorners, (Func<Biome, string>)null, ", ") + "\n" + $"World Biome for player: {WorldGenerator.instance.GetBiome(position)}\n" + $"World Biome for zone: {WorldGenerator.instance.GetBiome(zone.ZonePos)}\n" + "Current Weather: " + text3 + "\nPossible Weather: " + text4 + "\nCurrent Music: " + MusicWatcher.CurrentlyPlaying() + "\nLocation Music: " + MusicWatcher.CurrentLocationPlaying();
			component.text = text2;
		}

		private static Font GetFont(string fontName, int fontSize)
		{
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				if (((Object)val).name == fontName)
				{
					return val;
				}
			}
			return Font.CreateDynamicFontFromOSFont(fontName, fontSize);
		}
	}
	internal class Log
	{
		internal static ManualLogSource Logger;

		public static void LogDebug(string message)
		{
			Logger.LogInfo((object)(message ?? ""));
		}

		public static void LogTrace(string message)
		{
			Logger.LogDebug((object)(message ?? ""));
		}

		public static void LogInfo(string message)
		{
			Logger.LogMessage((object)(message ?? ""));
		}

		public static void LogWarning(string message)
		{
			Logger.LogWarning((object)(message ?? ""));
		}

		public static void LogError(string message, Exception e = null)
		{
			Logger.LogError((object)(message + "; " + e?.Message));
		}
	}
	[HarmonyPatch]
	internal static class MusicWatcher
	{
		private static HashSet<MusicLocation> MusicLocations { get; } = new HashSet<MusicLocation>();


		[HarmonyPatch(typeof(MusicLocation), "Awake")]
		public static void TrackLocation(MusicLocation __instance)
		{
			MusicLocations.Add(__instance);
		}

		public static string CurrentlyPlaying()
		{
			NamedMusic val = null;
			if (MusicMan.instance != null)
			{
				val = MusicMan.instance.m_currentMusic;
			}
			return val?.m_name ?? string.Empty;
		}

		public static string CurrentLocationPlaying()
		{
			MusicLocation[] array = MusicLocations.ToArray();
			foreach (MusicLocation val in array)
			{
				if (!Object.op_Implicit((Object)(object)val) || val == null)
				{
					MusicLocations.Remove(val);
				}
			}
			MusicLocation val2 = ((IEnumerable<MusicLocation>)MusicLocations).FirstOrDefault((Func<MusicLocation, bool>)((MusicLocation x) => x.m_audioSource.isPlaying));
			if (val2 == null)
			{
				return string.Empty;
			}
			return ((Object)val2).name;
		}
	}
	[BepInPlugin("asharppen.valheim.where_am_i", "Where Am I", "1.1.0")]
	public class WhereAmIPlugin : BaseUnityPlugin
	{
		internal static ConfigFile Config;

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Config = ((BaseUnityPlugin)this).Config;
			Log.Logger = ((BaseUnityPlugin)this).Logger;
			new Harmony("mod.where_am_i").PatchAll();
		}
	}
}