Decompiled source of Server Control v1.1.3
kg.ServerControl.dll
Decompiled a year 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