Decompiled source of Item Link v1.1.0
ItemLink.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; 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.Configuration; using HarmonyLib; using JetBrains.Annotations; using Jewelcrafting; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using fastJSON; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ItemLink")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ItemLink")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6C07200A-3881-4C2A-8EBF-370A00F20A6E")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 ItemLink { public class ChatPatches { [HarmonyPatch(typeof(TextInput), "IsVisible")] private static class Menu_Patch { [UsedImplicitly] private static void Postfix(ref bool __result) { if (Object.op_Implicit((Object)(object)Chat.instance)) { __result |= ((Component)VersionCompat.GetChatInput_MultiVersion(Chat.instance)).gameObject.activeInHierarchy; } } } } [BepInPlugin("kg.ItemLink", "ItemLink", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ItemLink : BaseUnityPlugin { [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) })] public static class PatchTooltip { public static bool SkipPatch; private static void Postfix(ItemData item, bool crafting, ref string __result) { if (!crafting && Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).m_inventory.ContainsItem(item) && !SkipPatch) { __result += "\n\n<color=yellow>[L.Shift + L.Control]</color> Link in <color=#808080>General</color> chat\n<color=yellow>[L.Shift + L.Alt]</color> Link in <color=yellow>Shout</color> chat"; } } } private const string GUID = "kg.ItemLink"; private const string NAME = "ItemLink"; private const string VERSION = "1.1.0"; private static ItemLink _thistype; private static AssetBundle asset; public static GameObject TooltipTrick; private void Awake() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown JSON.Parameters = new JSONParameters { UseExtensions = false, SerializeNullValues = false, DateTimeMilliseconds = false, UseUTCDateTime = true, UseOptimizedDatasetSchema = true, UseValuesOfEnums = true }; _thistype = this; TooltipTrick = new GameObject("kg_ItemLink_TooltipTrick") { hideFlags = (HideFlags)61 }; TooltipTrick.AddComponent<UITooltip>(); TooltipTrick.SetActive(false); asset = GetAssetBundle("kg_itemlink"); ItemLinkProcessor.TooltipPrefab = asset.LoadAsset<GameObject>("kg_InventoryTooltipLink"); } private void Start() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) new Harmony("kg.ItemLink").PatchAll(); } private 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 static class LinkContainer { private static readonly List<ItemLink_Data> _itemLinks; private static int _lastLink; private static int _lastLinkIndex; static LinkContainer() { _itemLinks = new List<ItemLink_Data>(50); _lastLink = -1; _lastLinkIndex = -1; for (int i = 0; i < 50; i++) { _itemLinks.Add(null); } } public static int AddLink(ItemLink_Data itemLinkData) { _lastLink = (_lastLink + 1) % 50; _itemLinks[_lastLink] = itemLinkData; return _lastLink; } public static ItemLink_Data GetLink(int index) { if (_lastLinkIndex == index) { return null; } return _itemLinks[index]; } public static void SetLastLinkIndex(int index) { _lastLinkIndex = index; } public static void ResetLastLinkIndex() { _lastLinkIndex = -1; } } public class ItemLink_Data { public string Prefab; public int Count; public int Quality; public int Variant; public string CustomData = "{}"; public string CrafterName = ""; public long CrafterID; public byte DurabilityPercent; } [HarmonyPatch(typeof(Chat), "Awake")] public static class Chat_Awake_Patch { [UsedImplicitly] private static void Postfix(Chat __instance) { MonoBehaviour chatInput_MultiVersion = VersionCompat.GetChatInput_MultiVersion(__instance); if (chatInput_MultiVersion != null && !Object.op_Implicit((Object)(object)((Component)chatInput_MultiVersion).GetComponent<ItemLinkProcessor>())) { ((Graphic)((Terminal)__instance).m_output).raycastTarget = true; ((Component)chatInput_MultiVersion).gameObject.AddComponent<ItemLinkProcessor>(); } } } [HarmonyPatch(typeof(InventoryGrid), "OnLeftClick")] public static class InventoryGrid_OnLeftClick_Patch { [UsedImplicitly] private static bool Prefix(InventoryGrid __instance, UIInputHandler clickHandler) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKey((KeyCode)304) && (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)308))) { Type val = (Type)(Input.GetKey((KeyCode)306) ? 1 : 2); Vector2i buttonPos = __instance.GetButtonPos(((Component)clickHandler).gameObject); ItemData itemAt = __instance.m_inventory.GetItemAt(buttonPos.x, buttonPos.y); if (itemAt == null) { return true; } ItemLink_Data obj = new ItemLink_Data { Prefab = ((Object)itemAt.m_dropPrefab).name, Count = itemAt.m_stack, Quality = itemAt.m_quality, Variant = itemAt.m_variant, CustomData = JSON.ToJSON(itemAt.m_customData), CrafterName = itemAt.m_crafterName, CrafterID = itemAt.m_crafterID, DurabilityPercent = (byte)(itemAt.m_durability / itemAt.GetMaxDurability() * 100f) }; string text = JSON.ToJSON(obj); UserInfo localUser = UserInfo.GetLocalUser(); localUser.Name += $" [{val}]"; ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_KG_ItemLink", new object[2] { localUser, text }); return false; } return true; } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance) { ZRoutedRpc.instance.Register<UserInfo, string>("RPC_KG_ItemLink", (Action<long, UserInfo, string>)RPC_Receiver.ReceiveItemLink); } } public static class RPC_Receiver { public const string KEY = "kg.ItemLinkChatKey:"; public static void ReceiveItemLink(long sender, UserInfo userInfo, string json) { string text = ""; try { ItemLink_Data itemLink_Data = JSON.ToObject<ItemLink_Data>(json); int num = LinkContainer.AddLink(itemLink_Data); string text2 = ((itemLink_Data.Count > 1) ? $" x{itemLink_Data.Count}" : ""); ItemLinkProcessor.GetItemData(itemLink_Data, out var topic, out var _, out var _, out var _); text = string.Format("<link=\"{0}{1}\"><color=#ffbf00><u><b>[•{2}{3}]</b></u></color></link>", "kg.ItemLinkChatKey:", num, topic, text2); } catch (Exception arg) { text = "<color=red>[kg.ItemLink] Wrong Data</color>"; MonoBehaviour.print((object)$"[kg.ItemLink] Error: {arg}"); } Chat.instance.m_hideTimer = 0f; ((Terminal)Chat.instance).AddString(userInfo.Name + UserInfo.GamertagSuffix(userInfo.Gamertag), text, (Type)1, false); } } public class ItemLinkProcessor : MonoBehaviour { public static GameObject TooltipPrefab; private static GameObject CurrentTooltip; private static List<GameObject> CompareTooltips = new List<GameObject>(); private int linkStartTextIndex = -1; private int linkTextLength; private TMP_Text _text; private TMP_InputField _input; private List<Color> _oldColors; private Color defaultHoverColor = new Color(1f, 0.96f, 0.99f); private bool changeColor { get { if (linkStartTextIndex != -1) { return linkTextLength != 0; } return false; } } private void Awake() { _text = ((Component)((Terminal)Chat.instance).m_output).GetComponent<TMP_Text>(); _input = ((Component)VersionCompat.GetChatInput_MultiVersion(Chat.instance)).GetComponent<TMP_InputField>(); } private void OnDisable() { if (changeColor) { ChangeVertexColors(isHover: false); } linkStartTextIndex = -1; linkTextLength = 0; LinkContainer.ResetLastLinkIndex(); if (Object.op_Implicit((Object)(object)CurrentTooltip)) { Object.Destroy((Object)(object)CurrentTooltip); } CompareTooltips.ForEach((Action<GameObject>)Object.Destroy); CompareTooltips.Clear(); } public static List<ItemData> GetCompareItems(ItemData item) { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return null; } return ((Humanoid)Player.m_localPlayer).m_inventory.m_inventory.Where((ItemData x) => x.m_equipped && x.m_shared.m_itemType == item.m_shared.m_itemType).ToList(); } private void ProcessTMP(int tryFindLink) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) TMP_LinkInfo val = _text.textInfo.linkInfo[tryFindLink]; string linkID = ((TMP_LinkInfo)(ref val)).GetLinkID(); if (!linkID.Contains("kg.ItemLinkChatKey:")) { return; } try { int num = int.Parse(linkID.Split(new char[1] { ':' })[1]); ItemLink_Data link = LinkContainer.GetLink(num); if (link != null) { if (changeColor) { ChangeVertexColors(isHover: false); } if (Object.op_Implicit((Object)(object)CurrentTooltip)) { Object.Destroy((Object)(object)CurrentTooltip); } CompareTooltips.ForEach((Action<GameObject>)Object.Destroy); CompareTooltips.Clear(); LinkContainer.SetLastLinkIndex(num); linkStartTextIndex = val.linkTextfirstCharacterIndex; linkTextLength = val.linkTextLength; CurrentTooltip = CreateTooltipForItemLinkData(link); ChangeVertexColors(isHover: true); } } catch (Exception arg) { linkStartTextIndex = -1; linkTextLength = 0; MonoBehaviour.print((object)$"[ItemLink] Error: {arg}"); } } private void LateUpdate() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!((UIBehaviour)_input).IsActive()) { return; } int num = TMP_TextUtilities.FindIntersectingLink(_text, Input.mousePosition, (Camera)null); if (num == -1) { OnDisable(); return; } if (Input.GetKeyDown((KeyCode)304) || Input.GetKeyUp((KeyCode)304)) { OnDisable(); } ProcessTMP(num); } private GameObject CreateTooltipForItemLinkData(ItemLink_Data itemLinkData, string additionalText = "") { GetItemData(itemLinkData, out var topic, out var text, out var icon, out var item); GameObject val = Object.Instantiate<GameObject>(TooltipPrefab, ((Component)Hud.instance).transform.parent); ((Component)val.transform.Find("Bkg/Icon")).GetComponent<Image>().sprite = icon; ((Component)val.transform.Find("Bkg/Icon")).GetComponent<Image>().type = (Type)1; ((Component)val.transform.Find("Bkg/Topic")).GetComponent<Text>().text = Localization.instance.Localize(topic) + additionalText; ((Component)val.transform.Find("Bkg/Text")).GetComponent<Text>().text = Localization.instance.Localize(text); Transform val2 = val.transform.Find("Bkg/TrannyHoles"); bool active = API.FillItemContainerTooltip(item, val2.parent, showInteract: false); ((Component)val2).gameObject.SetActive(active); Transform transform = ((Component)val.transform.GetChild(0)).transform; AdjustPosition((RectTransform)(object)((transform is RectTransform) ? transform : null)); if (Input.GetKey((KeyCode)304)) { List<ItemData> compareItems = GetCompareItems(item); if (compareItems != null) { for (int i = 0; i < compareItems.Count; i++) { GameObject item2 = CreateCompareTooltip(compareItems[i], i, " <color=green><b>[Equipped]</b></color>"); CompareTooltips.Add(item2); } } } return val; } private GameObject CreateCompareTooltip(ItemData item, int index, string additionalText = "") { //IL_0104: Unknown result type (might be due to invalid IL or missing references) GetItemData(item, out var topic, out var text, out var icon); GameObject val = Object.Instantiate<GameObject>(TooltipPrefab, ((Component)Hud.instance).transform.parent); ((Component)val.transform.Find("Bkg/Icon")).GetComponent<Image>().sprite = icon; ((Component)val.transform.Find("Bkg/Icon")).GetComponent<Image>().type = (Type)1; ((Component)val.transform.Find("Bkg/Topic")).GetComponent<Text>().text = Localization.instance.Localize(topic) + additionalText; ((Component)val.transform.Find("Bkg/Text")).GetComponent<Text>().text = Localization.instance.Localize(text); Transform val2 = val.transform.Find("Bkg/TrannyHoles"); bool active = API.FillItemContainerTooltip(item, val2.parent, showInteract: false); ((Component)val2).gameObject.SetActive(active); Transform transform = ((Component)val.transform.GetChild(0)).transform; AdjustPosition((RectTransform)(object)((transform is RectTransform) ? transform : null), (0f - ((Component)val.transform.GetChild(0)).GetComponent<RectTransform>().sizeDelta.x) * (float)(index + 1) - 4f); return val; } public static void GetItemData(ItemLink_Data itemLinkData, out string topic, out string text, out Sprite icon, out ItemData item) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown GameObject prefab = ZNetScene.instance.GetPrefab(itemLinkData.Prefab); if (!Object.op_Implicit((Object)(object)prefab)) { item = null; topic = "Unknown"; text = "Unknown"; icon = null; return; } ItemData itemData = prefab.GetComponent<ItemDrop>().m_itemData; SharedData shared = itemData.m_shared; Dictionary<string, string> customData = itemData.m_customData; itemData.m_shared = (SharedData)AccessTools.DeclaredMethod(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(shared, Array.Empty<object>()); itemData.m_customData = JSON.ToObject<Dictionary<string, string>>(itemLinkData.CustomData); item = itemData.Clone(); itemData.m_customData = customData; itemData.m_shared = shared; item.m_stack = itemLinkData.Count; item.m_quality = itemLinkData.Quality; item.m_variant = itemLinkData.Variant; item.m_crafterID = itemLinkData.CrafterID; item.m_crafterName = itemLinkData.CrafterName; item.m_durability = item.GetMaxDurability() * (float)(int)itemLinkData.DurabilityPercent / 100f; UITooltip component = ItemLink.TooltipTrick.GetComponent<UITooltip>(); bool canBeReparied = item.m_shared.m_canBeReparied; item.m_shared.m_canBeReparied = false; InventoryGui.instance.m_playerGrid.CreateItemTooltip(item, component); item.m_shared.m_canBeReparied = canBeReparied; topic = Localization.instance.Localize(component.m_topic); text = Localization.instance.Localize(component.m_text); icon = item.GetIcon(); } public static void GetItemData(ItemData item, out string topic, out string text, out Sprite icon) { ItemLink.PatchTooltip.SkipPatch = true; UITooltip component = ItemLink.TooltipTrick.GetComponent<UITooltip>(); bool canBeReparied = item.m_shared.m_canBeReparied; item.m_shared.m_canBeReparied = false; InventoryGui.instance.m_playerGrid.CreateItemTooltip(item, component); item.m_shared.m_canBeReparied = canBeReparied; ItemLink.PatchTooltip.SkipPatch = false; topic = Localization.instance.Localize(component.m_topic); text = Localization.instance.Localize(component.m_text); icon = item.GetIcon(); } private void AdjustPosition(RectTransform bkg, float minusX = 0f) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) ContentSizeFitter component = ((Component)bkg).GetComponent<ContentSizeFitter>(); ((Behaviour)component).enabled = false; ((Behaviour)component).enabled = true; Canvas.ForceUpdateCanvases(); Vector3 val = _text.transform.TransformPoint(_text.textInfo.characterInfo[linkStartTextIndex].topLeft); Vector3 val2 = _text.transform.TransformPoint(_text.textInfo.characterInfo[linkStartTextIndex + linkTextLength - 1].topRight); Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor((val.x + val2.x) / 2f, val.y, 0f); ((Component)bkg).transform.parent.position = position; Transform parent = ((Component)bkg).transform.parent; Transform obj = ((parent is RectTransform) ? parent : null); ((RectTransform)obj).anchoredPosition = ((RectTransform)obj).anchoredPosition + new Vector2(minusX, bkg.sizeDelta.y); } private void ChangeVertexColors(bool isHover) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) if (isHover) { _oldColors = new List<Color>(linkTextLength); } for (int i = 0; i < linkTextLength; i++) { int num = linkStartTextIndex + i; if (_text.textInfo.characterInfo[num].character == ' ') { _oldColors.Add(defaultHoverColor); _oldColors.Add(defaultHoverColor); _oldColors.Add(defaultHoverColor); _oldColors.Add(defaultHoverColor); continue; } int materialReferenceIndex = _text.textInfo.characterInfo[num].materialReferenceIndex; int vertexIndex = _text.textInfo.characterInfo[num].vertexIndex; Color32[] colors = _text.textInfo.meshInfo[materialReferenceIndex].colors32; if (isHover) { _oldColors.Add(Color32.op_Implicit(colors[vertexIndex])); _oldColors.Add(Color32.op_Implicit(colors[vertexIndex + 1])); _oldColors.Add(Color32.op_Implicit(colors[vertexIndex + 2])); _oldColors.Add(Color32.op_Implicit(colors[vertexIndex + 3])); colors[vertexIndex] = Color32.op_Implicit(defaultHoverColor); colors[vertexIndex + 1] = Color32.op_Implicit(defaultHoverColor); colors[vertexIndex + 2] = Color32.op_Implicit(defaultHoverColor); colors[vertexIndex + 3] = Color32.op_Implicit(defaultHoverColor); } else { colors[vertexIndex] = Color32.op_Implicit(_oldColors[i * 4]); colors[vertexIndex + 1] = Color32.op_Implicit(_oldColors[i * 4 + 1]); colors[vertexIndex + 2] = Color32.op_Implicit(_oldColors[i * 4 + 2]); colors[vertexIndex + 3] = Color32.op_Implicit(_oldColors[i * 4 + 3]); } } _text.UpdateVertexData((TMP_VertexDataUpdateFlags)16); } } public static class VersionCompat { public static MonoBehaviour GetChatInput_MultiVersion(Chat chat) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown return (MonoBehaviour)AccessTools.Field(((object)chat).GetType(), "m_input").GetValue(chat); } } } 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>); } } } public sealed class DatasetSchema { public List<string> Info; public string Name; } public 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(); } } public 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('"'); } } public 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 }; } } public 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); } } public struct Getters { public string Name; public string lcName; public string memberName; public Reflection.GenericGetter Getter; public bool ReadOnly; } public enum myPropInfoType { Int, Long, String, Bool, DateTime, Enum, Guid, Array, ByteArray, Dictionary, StringKeyDictionary, NameValue, StringDictionary, Hashtable, DataSet, DataTable, Custom, Unknown } public 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; } public 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) { if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { return Instance.GetGenericArguments(conversionType)[0]; } return conversionType; } public string GetTypeAssemblyName(Type t) { string value = ""; if (_tyname.TryGetValue(t, out value)) { return value; } string assemblyQualifiedName = t.AssemblyQualifiedName; _tyname.Add(t, assemblyQualifiedName); return assemblyQualifiedName; } internal Type GetTypeFromCache(string typename, bool badlistChecking) { Type value = null; if (_typecache.TryGetValue(typename, out value)) { return value; } if (badlistChecking) { string text = typename.Trim().ToLowerInvariant(); foreach (string badlistType in _badlistTypes) { if (text.StartsWith(badlistType, StringComparison.Ordinal)) { throw new Exception("Black list type encountered, possible attack vector when using $type : " + typename); } } } Type type = Type.GetType(typename); _typecache.Add(typename, type); return type; } internal object FastCreateList(Type objtype, int capacity) { try { int capacity2 = 10; if (capacity > 10) { capacity2 = capacity; } CreateList value = null; if (_conlistcache.TryGetValue(objtype, out value)) { if (value != null) { return value(capacity2); } return FastCreateInstance(objtype); } ConstructorInfo constructor = objtype.GetConstructor(new Type[1] { typeof(int) }); if (constructor != null) { DynamicMethod dynamicMethod = new DynamicMethod("_fcil", objtype, new Type[1] { typeof(int) }, restrictedSkipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Newobj, objtype.GetConstructor(new Type[1] { typeof(int) })); iLGenerator.Emit(OpCodes.Ret); value = (CreateList)dynamicMethod.CreateDelegate(typeof(CreateList)); _conlistcache.Add(objtype, value); return value(capacity2); } _conlistcache.Add(objtype, null); return FastCreateInstance(objtype); } catch (Exception innerException) { throw new Exception($"Failed to fast create instance for type '{objtype.FullName}' from assembly '{objtype.AssemblyQualifiedName}'", innerException); } } internal object FastCreateInstance(Type objtype) { try { CreateObject value = null; if (_constrcache.TryGetValue(objtype, out value)) { return value(); } if (objtype.IsClass) { DynamicMethod dynamicMethod = new DynamicMethod("_fcic", objtype, null, restrictedSkipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); iLGenerator.Emit(OpCodes.Newobj, objtype.GetConstructor(Type.EmptyTypes)); iLGenerator.Emit(OpCodes.Ret); value = (CreateObject)dynamicMethod.CreateDelegate(typeof(CreateObject)); _constrcache.Add(objtype, value); } else { DynamicMethod dynamicMethod2 = new DynamicMethod("_fcis", typeof(object), null, restrictedSkipVisibility: true); ILGenerator iLGenerator2 = dynamicMethod2.GetILGenerator(); LocalBuilder local = iLGenerator2.DeclareLocal(objtype); iLGenerator2.Emit(OpCodes.Ldloca_S, local); iLGenerator2.Emit(OpCodes.Initobj, objtype); iLGenerator2.Emit(OpCodes.Ldloc_0); iLGenerator2.Emit(OpCodes.Box, objtype); iLGenerator2.Emit(OpCodes.Ret); value = (CreateObject)dynamicMethod2.CreateDelegate(typeof(CreateObject)); _constrcache.Add(objtype, value); } return value(); } catch (Exception innerException) { throw new Exception($"Failed to fast create instance for type '{objtype.FullName}' from assembly '{objtype.AssemblyQualifiedName}'", innerExce