Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Server Control v1.1.3
kg.ServerControl.dll
Decompiled 2 years 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.Concurrent; 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.Net.Http; 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.Threading.Tasks; using System.Xml.Serialization; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using fastJSON; [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: Guid("49BF64A4-1330-4E3B-9EF7-2D71D227BC73")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyProduct("ServerControl")] [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("ServerControl")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [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] namespace kg.ServerControl { public static class CommandExecution { public enum Command { ShowPlayers = 1, Kick = 2, Ban = 3, Unban = 4, BanList = 5, BanSteamID = 6, Give = 7, Spawn = 8, Position = 9, Say = 10, Damage = 11, Heal = 12, SayChat = 13, ScanObject = 14, RemoveObjects = 15, Whitelist = 16, AddWhitelist = 17, RemoveWhitelist = 18, ShowGlobalKeys = 35, AddGlobalKey = 36, RemoveGlobalKey = 37, Teleport = 38, Adminlist = 39, AddAdminlist = 40, RemoveAdminlist = 41, StartEvent = 42, StopEvent = 43, RCON = 99 } private delegate bool Invoke(string[] args, out string result); [HarmonyPatch(typeof(Terminal), "AddString", new Type[] { typeof(string) })] private static class Terminal_AddString_Patch { private static void Prefix(string text) { if (HookRCON) { LatestRCONmessage = text; } } } private static readonly Dictionary<string, Dictionary<string, string>> LOCALIZATION = new Dictionary<string, Dictionary<string, string>> { { "English", new Dictionary<string, string> { { "ERROR", "ERROR" }, { "Position", "Position" }, { "Health", "Health" }, { "Players", "Players" }, { "Banlist", "Banlist" }, { "CantFind", "Can't find player {0}" }, { "CantGetPrefab", "Can't get prefab {0}" }, { "Banned", "{0} Banned" }, { "Unbanned", "{0} Unbanned" }, { "Kicked", "{0} Kicked" }, { "Killed", "{0} Killed" }, { "MessageSent", "Message Sent" }, { "Spawned", "Spawned {0} {1} in {2}" }, { "Gave", "Gave {0} {1} to {2}" }, { "Damage", "Dealt {0} damage to {1}" }, { "Heal", "Healed {0} HP for {1}" }, { "BadCommand", "Bad Command" }, { "ErrorPassword", "Wrong Password" }, { "Whitelist", "Whitelist" }, { "AddWhitelist", "{0} Added in Whitelist" }, { "RemoveWhitelist", "{0} Removed from Whitelist" }, { "PlayerTeleported", "{0} Teleported to ({1}, {2}, {3})" } } }, { "Russian", new Dictionary<string, string> { { "ERROR", "ОШИБКА" }, { "Position", "Позиция" }, { "Health", "ХП" }, { "Players", "Игроки" }, { "Banlist", "Банлист" }, { "CantFind", "Игрок {0} не найден" }, { "CantGetPrefab", "Префаб {0} не найден" }, { "Banned", "{0} Забанен" }, { "Unbanned", "{0} Разбанен" }, { "Kicked", "{0} Кикнут" }, { "Killed", "{0} Убит" }, { "MessageSent", "Сообщение Отправленно" }, { "Spawned", "Заспавнено {0} {1} в {2}" }, { "Gave", "{2} получил {0} {1}" }, { "Damage", "Нанесено {0} урона {1}" }, { "Heal", "{1} исцелён на {0} ХП" }, { "BadCommand", "Bad Command" }, { "ErrorPassword", "Неверный Пароль" }, { "Whitelist", "Whitelist" }, { "AddWhitelist", "{0} Добавлен в Whitelist" }, { "RemoveWhitelist", "{0} Удалён из Whitelist'а" }, { "PlayerTeleported", "{0} Телепортирован в ({1}, {2}, {3})" } } } }; private static readonly Dictionary<Command, Invoke> _commands = new Dictionary<Command, Invoke>(); private static string LatestRCONmessage = "Unknown"; private static bool HookRCON; public static void Init(string language = "English") { Dictionary<string, string> Localize = LOCALIZATION[language]; _commands.Add(Command.ShowPlayers, delegate(string[] _, out string result) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) string text10 = ""; foreach (ZNetPeer peer in ZNet.instance.m_peers) { ZDO zDO2 = ZDOMan.instance.GetZDO(peer.m_characterID); if (zDO2 != null) { text10 += string.Format("\n{0} ({1}: {2} {3} {4} {5}: {6}/{7} SteamID: {8} CreatorID: {9})", peer.m_playerName, Localize["Position"], (int)peer.m_refPos.x, (int)peer.m_refPos.y, (int)peer.m_refPos.z, Localize["Health"], (int)zDO2.GetFloat("health", 0f), (int)zDO2.GetFloat("max_health", 0f), peer.m_socket.GetHostName(), zDO2.GetLong("playerID", 0L)); } } result = Localize["Players"] + ":\n" + text10; return true; }); _commands.Add(Command.Kick, delegate(string[] args, out string result) { ZNetPeer peerByPlayerName7 = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName7 != null) { ZNet.instance.ClearPlayerData(peerByPlayerName7); ZNet.instance.m_peers.Remove(peerByPlayerName7); peerByPlayerName7.Dispose(); result = string.Format(Localize["Kicked"], args[0]); return true; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.Ban, delegate(string[] args, out string result) { ZNetPeer peerByPlayerName6 = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName6 != null) { ZNet.instance.Ban(args[0]); result = string.Format(Localize["Banned"], args[0]); return true; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.Unban, delegate(string[] args, out string result) { ZNet.instance.m_bannedList.Remove(args[0]); result = string.Format(Localize["Unbanned"], args[0]); return true; }); _commands.Add(Command.BanList, delegate(string[] _, out string result) { string text9 = ""; foreach (string item in ZNet.instance.m_bannedList.GetList()) { text9 = text9 + "\n" + item; } result = Localize["Banlist"] + ":" + text9; return true; }); _commands.Add(Command.BanSteamID, delegate(string[] args, out string result) { ZNet.instance.m_bannedList.Add(args[0]); result = string.Format(Localize["Banned"], args[0]); return true; }); _commands.Add(Command.Give, delegate(string[] args, out string result) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) ZNetPeer peerByPlayerName5 = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName5 != null) { string text8 = args[1]; int num10 = int.Parse(args[2]); int num11 = int.Parse(args[3]); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text8); if (Object.op_Implicit((Object)(object)itemPrefab) && Object.op_Implicit((Object)(object)itemPrefab.GetComponent<ItemDrop>())) { ZDO zDO = ZDOMan.instance.GetZDO(peerByPlayerName5.m_characterID); Vector3 val8 = zDO.m_position - zDO.GetRotation() * ((Vector3)(ref zDO.m_position)).normalized * 2f; CreateZdoFromPrefab("fx_creature_tamed", val8 + Vector3.up * 2f, peerByPlayerName5.m_uid); int maxStackSize = itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize; if (maxStackSize > 1) { ZDO val9 = CreateZdoFromPrefab(text8, val8 + Vector3.up * 2f, 0L); val9.Set("stack", num10); val9.Set("quality", num11); val9.Set("durability", itemPrefab.GetComponent<ItemDrop>().m_itemData.GetMaxDurability(num11)); } else { for (int n = 0; n < num10; n++) { float num12 = Random.Range(-1f, 1f); float num13 = Random.Range(-1f, 1f); ZDO val10 = CreateZdoFromPrefab(text8, val8 + Vector3.left * num12 + Vector3.forward * num13 + Vector3.up, 0L); val10.Set("stack", 1); val10.Set("quality", num11); val10.Set("durability", itemPrefab.GetComponent<ItemDrop>().m_itemData.GetMaxDurability(num11)); } } result = string.Format(Localize["Gave"], num10, Localization.instance.Localize(itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name), args[0]); return true; } result = string.Format(Localize["CantGetPrefab"], text8); return false; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.Spawn, delegate(string[] args, out string result) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) string text7 = args[0]; Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor((float)int.Parse(args[1]), (float)int.Parse(args[2]), (float)int.Parse(args[3])); int num6 = int.Parse(args[4]); GameObject prefab = ZNetScene.instance.GetPrefab(text7); int num7 = int.Parse(args[5]); if (!Object.op_Implicit((Object)(object)prefab)) { result = string.Format(Localize["CantGetPrefab"], text7); return false; } if (Object.op_Implicit((Object)(object)prefab.GetComponent<ZNetView>()) && (Object.op_Implicit((Object)(object)prefab.GetComponent<ItemDrop>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Character>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Piece>()))) { for (int m = 0; m < num6; m++) { float num8 = Random.Range(-3f, 3f); float num9 = Random.Range(-3f, 3f); ZDO val7 = CreateZdoFromPrefab(text7, val6 + Vector3.left * num8 + Vector3.forward * num9 + Vector3.up, 0L); if (Object.op_Implicit((Object)(object)prefab.GetComponent<ItemDrop>())) { val7.Set("quality", num7); } if (Object.op_Implicit((Object)(object)prefab.GetComponent<Character>())) { val7.Set("level", num7); } } result = string.Format(Localize["Spawned"], num6, text7, val6); return true; } result = Localize["ERROR"]; return false; }); _commands.Add(Command.Position, delegate(string[] args, out string result) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_005d: Unknown result type (might be due to invalid IL or missing references) ZNetPeer peerByPlayerName4 = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName4 != null) { Vector3 refPos = peerByPlayerName4.m_refPos; result = string.Format("{0} {1}: {2} {3} {4}", args[0], Localize["Position"], (int)refPos.x, (int)refPos.y, (int)refPos.z); return true; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.Say, delegate(string[] args, out string result) { MessageHud.instance.MessageAll((MessageType)2, args[0]); result = Localize["MessageSent"]; return true; }); _commands.Add(Command.Damage, delegate(string[] args, out string result) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) ZNetPeer peerByPlayerName3 = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName3 != null) { int num5 = int.Parse(args[1]); HitData val5 = new HitData(); val5.m_damage.m_damage = num5; CreateZdoFromPrefab("fx_shaman_fireball_expl", peerByPlayerName3.m_refPos, peerByPlayerName3.m_uid); ZRoutedRpc.instance.InvokeRoutedRPC(peerByPlayerName3.m_uid, peerByPlayerName3.m_characterID, "Damage", new object[1] { val5 }); result = ((num5 == 999999) ? string.Format(Localize["Killed"], args[0]) : string.Format(Localize["Damage"], num5, args[0])); return true; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.Heal, delegate(string[] args, out string result) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) ZNetPeer peerByPlayerName2 = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName2 != null) { float num4 = float.Parse(args[1]); CreateZdoFromPrefab("fx_creature_tamed", peerByPlayerName2.m_refPos, peerByPlayerName2.m_uid); ZRoutedRpc.instance.InvokeRoutedRPC(peerByPlayerName2.m_uid, peerByPlayerName2.m_characterID, "Heal", new object[2] { num4, true }); result = string.Format(Localize["Heal"], num4, args[0]); return true; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.SayChat, delegate(string[] args, out string result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) UserInfo val4 = new UserInfo { Name = args[0], Gamertag = "", NetworkUserId = "Steam_0" }; ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ChatMessage", new object[5] { (object)new Vector3(0f, 200f, 0f), 2, val4, args[1], "Steam_0" }); result = Localize["MessageSent"]; return true; }); _commands.Add(Command.ScanObject, delegate(string[] args, out string result) { Dictionary<long, int> dictionary = new Dictionary<long, int>(); int stableHashCode2 = StringExtensionMethods.GetStableHashCode(args[0]); List<ZDO>[] objectsBySector2 = ZDOMan.instance.m_objectsBySector; foreach (List<ZDO> list3 in objectsBySector2) { if (list3 != null) { for (int l = 0; l < list3.Count; l++) { ZDO val3 = list3[l]; if (val3.GetPrefab() == stableHashCode2) { long @long = val3.GetLong(ZDOVars.s_creator, 0L); if (@long != 0L) { if (!dictionary.ContainsKey(@long)) { dictionary[@long] = 0; } dictionary[@long]++; } } } } } string text6 = args[0] + "'s:\n"; if (dictionary.Count == 0) { result = text6; return true; } foreach (KeyValuePair<long, int> item2 in dictionary) { text6 += $"Creator ID: {item2.Key} - Quantity: {item2.Value}\n"; } result = text6; return true; }); _commands.Add(Command.RemoveObjects, delegate(string[] args, out string result) { int stableHashCode = StringExtensionMethods.GetStableHashCode(args[0]); long CreatorID = long.Parse(args[1]); List<ZDO> list = new List<ZDO>(); List<ZDO>[] objectsBySector = ZDOMan.instance.m_objectsBySector; foreach (List<ZDO> list2 in objectsBySector) { if (list2 != null) { for (int j = 0; j < list2.Count; j++) { ZDO val2 = list2[j]; if (val2.GetPrefab() == stableHashCode) { list.Add(val2); } } } } string text5; if (CreatorID != 0L) { text5 = $"Removing Objects With name {args[0]} for player (creator id) {CreatorID}:\n"; list = list.Where((ZDO zdo) => zdo.GetLong(ZDOVars.s_creator, 0L) == CreatorID).ToList(); } else { text5 = "Removing Objects With name " + args[0] + " for ALL PLAYERS\n"; } list.ForEach(delegate(ZDO z) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) ZDOMan.instance.m_destroySendList.Add(z.m_uid); }); text5 += $"Removed total {list.Count} objects"; result = text5; return true; }); _commands.Add(Command.Whitelist, delegate(string[] _, out string result) { string text4 = ""; foreach (string item3 in ZNet.instance.m_permittedList.GetList()) { text4 = text4 + "\n" + item3; } result = Localize["Whitelist"] + ":" + text4; return true; }); _commands.Add(Command.AddWhitelist, delegate(string[] args, out string result) { ZNet.instance.m_permittedList.Add(args[0]); result = string.Format(Localize["AddWhitelist"], args[0]); return true; }); _commands.Add(Command.RemoveWhitelist, delegate(string[] args, out string result) { ZNet.instance.m_permittedList.Remove(args[0]); result = string.Format(Localize["RemoveWhitelist"], args[0]); return true; }); _commands.Add(Command.ShowGlobalKeys, delegate(string[] _, out string result) { string text3 = ""; foreach (string globalKey in ZoneSystem.instance.GetGlobalKeys()) { text3 = text3 + "\n" + globalKey; } result = "Global Keys:" + text3; return true; }); _commands.Add(Command.AddGlobalKey, delegate(string[] args, out string result) { ZoneSystem.instance.GlobalKeyAdd(args[0], true); result = "Added " + args[0] + " to Global Keys"; return true; }); _commands.Add(Command.RemoveGlobalKey, delegate(string[] args, out string result) { ZoneSystem.instance.GlobalKeyRemove(args[0], true); result = "Removed " + args[0] + " from Global Keys"; return true; }); _commands.Add(Command.Teleport, delegate(string[] args, out string result) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) ZNetPeer peerByPlayerName = ZNet.instance.GetPeerByPlayerName(args[0]); if (peerByPlayerName != null) { int num = int.Parse(args[1]); int num2 = int.Parse(args[2]); int num3 = int.Parse(args[3]); ZRoutedRpc.instance.InvokeRoutedRPC(peerByPlayerName.m_uid, peerByPlayerName.m_characterID, "RPC_TeleportTo", new object[3] { (object)new Vector3((float)num, (float)num2, (float)num3), Quaternion.identity, true }); result = string.Format(Localize["PlayerTeleported"], args[0], args[1], args[2], args[3]); return true; } result = string.Format(Localize["CantFind"], args[0]); return false; }); _commands.Add(Command.Adminlist, delegate(string[] _, out string result) { string text2 = ""; foreach (string item4 in ZNet.instance.m_adminList.GetList()) { text2 = text2 + "\n" + item4; } result = "Adminlist:" + text2; return true; }); _commands.Add(Command.AddAdminlist, delegate(string[] args, out string result) { ZNet.instance.m_adminList.Add(args[0]); result = "Added " + args[0] + " to Adminlist"; return true; }); _commands.Add(Command.RemoveAdminlist, delegate(string[] args, out string result) { ZNet.instance.m_adminList.Remove(args[0]); result = "Removed " + args[0] + " from Adminlist"; return true; }); _commands.Add(Command.StartEvent, delegate(string[] args, out string result) { //IL_004c: 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) RandomEvent @event = RandEventSystem.instance.GetEvent(args[0]); if (@event == null) { result = "Can't find event " + args[0]; return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((float)Convert.ToInt32(args[1]), (float)Convert.ToInt32(args[2]), (float)Convert.ToInt32(args[3])); RandEventSystem.instance.SetRandomEventByName(args[0], val); result = $"Event {args[0]} started at: {val}"; return true; }); _commands.Add(Command.StopEvent, delegate(string[] _, out string result) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) string text = RandEventSystem.instance.m_activeEvent?.m_name ?? "Unknown"; RandEventSystem.instance.SetRandomEventByName("stopEvent", Vector3.zero); result = "Latest Event stopped (" + text + ")"; return true; }); _commands.Add(Command.RCON, delegate(string[] args, out string result) { LatestRCONmessage = "Unknown"; HookRCON = true; ((Terminal)Console.instance).TryRunCommand(args[0], false, true); HookRCON = false; result = "Command executed. Result:\n" + (string.IsNullOrWhiteSpace(LatestRCONmessage) ? "Unknown" : LatestRCONmessage); return true; }); } private static ZDO CreateZdoFromPrefab(string prefab, Vector3 pos, long ID = 0L) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); ZNetView val = ((prefab2 != null) ? prefab2.GetComponent<ZNetView>() : null); if ((Object)(object)val == (Object)null) { return null; } ZDO val2 = ZDOMan.instance.CreateNewZDO(pos, StringExtensionMethods.GetStableHashCode(prefab)); val2.Persistent = val.m_persistent; val2.Type = val.m_type; val2.Distant = val.m_distant; val2.SetPrefab(StringExtensionMethods.GetStableHashCode(prefab)); val2.SetRotation(Quaternion.identity); if (val.m_syncInitialScale) { val2.Set("scale", ((Component)val).transform.localScale); } val2.SetOwner(ID); return val2; } public static bool Execute(Command cmd, string args, out string result) { if (_commands.TryGetValue(cmd, out var value)) { try { ServerControl.print(string.Format("Executing command {0} with args: \"{1}\"", cmd, args.Replace("&%&", " | ")), ConsoleColor.Cyan); return value(args.Split(new string[1] { "&%&" }, StringSplitOptions.None), out result); } catch (Exception ex) { result = ex.ToString(); return false; } } result = "Unknown command"; return false; } } [BepInPlugin("kg.ServerControl_WEB", "kg.ServerControl_WEB", "1.1.3")] public class ServerControl : BaseUnityPlugin { private enum Result : byte { Pending, Sent, Success, Failed, Timeout } private struct ToInvoke { public long ID; public CommandExecution.Command Command; public string Arguments; public override string ToString() { return $"UID: {ID}, Action: {Command}, Args: {Arguments}"; } } private struct Response { public long ID; public Result Result; public string Message; private Response(long uid, byte result, string message) { ID = uid; Result = (Result)result; Message = message; } public static Response Failed(long uid, string message) { return new Response(uid, 3, message); } public static Response Success(long uid, string message) { return new Response(uid, 2, message); } public override string ToString() { return $"ID: {ID}, Result: {Result}, Message: {Message}"; } } private const string GUID = "kg.ServerControl_WEB"; private const string VERSION = "1.1.3"; private const string POST_REQUEST = "https://kg.sayless.eu/API/RCON.php"; private readonly ConcurrentQueue<ToInvoke> _queue = new ConcurrentQueue<ToInvoke>(); private ConfigEntry<string> IDENTIFIER; private ConfigEntry<int> SECONDS_BETWEEN_REQUESTS; private FileSystemWatcher FSW; private DateTime LastConfigReload = DateTime.Now; private float _timerGET; private void Awake() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) JSON.Parameters = new JSONParameters { UseExtensions = false, SerializeNullValues = false, DateTimeMilliseconds = false, UseUTCDateTime = true, UseOptimizedDatasetSchema = true, UseValuesOfEnums = true }; CommandExecution.Init(); IDENTIFIER = ((BaseUnityPlugin)this).Config.Bind<string>("ServerControl", "ID", "Put ID Here", "ServerControl ID (32 symbols)"); SECONDS_BETWEEN_REQUESTS = ((BaseUnityPlugin)this).Config.Bind<int>("RCON", "Seconds Between Requests", 4, "Seconds between requests to the RCON server"); SECONDS_BETWEEN_REQUESTS.Value = Mathf.Clamp(SECONDS_BETWEEN_REQUESTS.Value, 2, 20); new Harmony("kg.ServerControl_WEB").PatchAll(); FSW = new FileSystemWatcher { Path = Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Filter = Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath), NotifyFilter = NotifyFilters.LastWrite, EnableRaisingEvents = true }; FSW.Changed += delegate { if (!(LastConfigReload.AddSeconds(3.0) > DateTime.Now)) { LastConfigReload = DateTime.Now; print("Config changed, reloading..."); ((BaseUnityPlugin)this).Config.Reload(); SECONDS_BETWEEN_REQUESTS.Value = Mathf.Clamp(SECONDS_BETWEEN_REQUESTS.Value, 2, 20); } }; } private void FixedUpdate() { float fixedDeltaTime = Time.fixedDeltaTime; UpdateGet(fixedDeltaTime); QueueProcess(); } private void QueueProcess() { if (IDENTIFIER.Value.Length != 32 || !Object.op_Implicit((Object)(object)ZNet.instance) || _queue.Count <= 0) { return; } List<Response> list = new List<Response>(); ToInvoke result; while (_queue.TryDequeue(out result)) { Response item = ProcessInvoke(result); list.Add(item); } if (list.Count > 0) { string json = JSON.ToJSON(list); Task.Run(async delegate { HttpClient val = new HttpClient(); Dictionary<string, string> dictionary = new Dictionary<string, string> { { "id", IDENTIFIER.Value }, { "type", "update" }, { "json", json } }; FormUrlEncodedContent val2 = new FormUrlEncodedContent((IEnumerable<KeyValuePair<string, string>>)dictionary); await val.PostAsync("https://kg.sayless.eu/API/RCON.php", (HttpContent)(object)val2); }); } } private void UpdateGet(float dt) { if (IDENTIFIER.Value.Length != 32 || !Object.op_Implicit((Object)(object)ZNet.instance)) { return; } _timerGET += dt; if (!(_timerGET >= (float)SECONDS_BETWEEN_REQUESTS.Value)) { return; } _timerGET = 0f; Task.Run(async delegate { _ = 1; try { HttpClient val = new HttpClient(); JSON.ToObject<List<ToInvoke>>(await (await val.GetAsync("https://kg.sayless.eu/API/RCON.php?id=" + IDENTIFIER.Value + "&type=valheim")).Content.ReadAsStringAsync()).ForEach(_queue.Enqueue); } catch (Exception arg) { print($"Error while parsing response: {arg}", ConsoleColor.Red); } }); } private Response ProcessInvoke(ToInvoke invoke) { string args = invoke.Arguments ?? string.Empty; if (CommandExecution.Execute(invoke.Command, args, out var result)) { return Response.Success(invoke.ID, result); } return Response.Failed(invoke.ID, result); } public static void print(object obj, ConsoleColor color = ConsoleColor.DarkGreen) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)Application.platform == 2) { ConsoleManager.SetConsoleColor(color); ConsoleManager.StandardOutStream.WriteLine($"[{DateTime.Now}] [kg.ServerControl_WEB] {obj}"); ConsoleManager.SetConsoleColor(ConsoleColor.White); { foreach (ILogListener listener in Logger.Listeners) { DiskLogListener val = (DiskLogListener)(object)((listener is DiskLogListener) ? listener : null); if (val != null && val.LogWriter != null) { val.LogWriter.WriteLine($"[{DateTime.Now}] [kg.ServerControl_WEB] {obj}"); } } return; } } MonoBehaviour.print((object)($"[{DateTime.Now}] [kg.ServerControl_WEB] " + obj)); } } } 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.Na