Please disclose if any significant portion of your mod was created 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 CleabShip v1.0.0
BepInEx/plugins/CustomCompany.CleabShip.dll
Decompiled 9 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CustomCompany.Behaviour; using CustomCompany.Patch; using GameNetcodeStuff; using HarmonyLib; using LitJson; using OPJosMod.ReviveCompany; using OPJosMod.ReviveCompany.CustomRpc; using Steamworks; using Steamworks.Data; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CustomCompany")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CustomCompany")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("409b1866-07ec-4891-8037-38ee545cb7ad")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace CustomCompany { [BepInPlugin("TAIGU.CleanShip", "CleanShip", "2.5.1")] public class Plugin : BaseUnityPlugin { public static Plugin Instance; private static readonly Harmony harmony = new Harmony("TAIGU.CustomCompany"); public static CustomLog Log = new CustomLog(); private void Awake() { Log.LogInfo("Loading CustomCompany.CleanShip Mod"); Log.enable = true; Instance = this; CustomCompanyManager.Init(); CustomCompanyUI.Init(); TryPatch(typeof(PlayerControllerB_Patch)); TryPatch(typeof(StartOfRound_Patch)); } private static void TryPatch(Type type) { try { harmony.PatchAll(type); } catch (Exception arg) { Log.LogError($"Unable to patch {type}. {arg}"); } } } internal static class CustomCompanyConfig { public static KeyControl menuKey = Keyboard.current.equalsKey; public static BehaviourConfig BehaviourConfig = new BehaviourConfig(); private static string keyDisplayNames; public static void LoadConfig() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) keyDisplayNames = string.Join(", ", ((IEnumerable<KeyControl>)(object)Keyboard.current.allKeys).Select((KeyControl x) => (x == null) ? "null" : ((InputControl)x).displayName)); menuKey = BindKey("按键配置", "菜单键", Keyboard.current.equalsKey, "参考按键对应字符串: " + keyDisplayNames); } public static void LoadBehaviourConfig() { if (File.Exists("BepInEx/config/TAIGU.CleanShip.json")) { BehaviourConfig = (BehaviourConfig)JsonMapper.ToObject(File.ReadAllText("BepInEx/config/TAIGU.CleanShip.json"), typeof(BehaviourConfig)); } } public static void SaveBehaviourConfig() { File.WriteAllText("BepInEx/config/TAIGU.CleanShip.json", JsonMapper.ToJson((object)BehaviourConfig)); } private static KeyControl BindKey(string section, string key, KeyControl defaultValue, string configDescription = null) { try { ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>(section, key, ((InputControl)defaultValue).displayName, configDescription); KeyControl val2 = Keyboard.current.FindKeyOnCurrentKeyboardLayout(val.Value); if (val2 != null) { return val2; } Plugin.Log.LogWarning("按键设置失败!" + key + ":" + val.Value); return defaultValue; } catch (Exception ex) { Plugin.Log.LogWarning("按键设置失败!" + ex.Message); return defaultValue; } } } public class CustomCompanyManager : MonoBehaviour { private static CustomCompanyManager instance; public static CustomCompanyManager Instance { get { if ((Object)(object)instance == (Object)null) { Init(); } return instance; } } public static void Init() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)instance != (Object)null)) { GameObject val = new GameObject("CustomCompanyManager"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; instance = val.AddComponent<CustomCompanyManager>(); } } private void Start() { CustomCompanyConfig.LoadConfig(); CustomCompanyConfig.LoadBehaviourConfig(); CleanShipBehaviour.LoadConfig(); CollectScrapBehaviour.LoadConfig(); } private void Update() { } } internal class CustomCompanyUI : MonoBehaviour { private static Rect WinRect = new Rect(1300f, 100f, 450f, 700f); private string[] SelectStr = new string[3] { "整理", "收集", "其他功能" }; private bool bRelease = false; private int selectedId; private bool isRandom = false; private bool isSorting = false; private string cleanOffset = Setting.cleanOffset.ToString(); private string saveStr = string.Empty; private bool isCollecting = false; private string collectSaveStr = string.Empty; private bool isUnfold; private Vector2 scollView; private bool isViewItemNames; private string namesLabel = string.Empty; private bool isCollectTargetListUnfold; private Vector2 CollectTargetListScollView; private bool isCollectIgnoreListUnfold; private Vector2 CollectIgnoreListScollView; private string allCollectNames = string.Empty; private Vector2 playersScollViewPos; private bool bPlayersScollView; internal CustomLog Log = Plugin.Log; public static void Init() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("CustomCompanyMenu.CleanShip"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<CustomCompanyUI>(); } private void Update() { if (((ButtonControl)CustomCompanyConfig.menuKey).wasPressedThisFrame) { Setting.bMenu = !Setting.bMenu; if (Setting.bMenu) { OnOpen(); } else { OnClose(); } } } private void OnOpen() { //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) if (bRelease) { SelectStr = new string[3] { "整理", "其他功能", "说明" }; } else { SelectStr = new string[4] { "整理", "收集", "其他功能", "说明" }; } if (Utility.IsModLoaded("OpJosMod.ReviveCompany")) { Setting.hasReviveCompany = true; } else { Setting.hasReviveCompany = false; } float num = (float)Screen.width * 0.67f; float num2 = (float)Screen.height * 0.1f; WinRect = new Rect(num, num2, 450f, 700f); } private void OnClose() { saveStr = string.Empty; } private void OnGUI() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (Setting.bMenu) { WinRect = GUILayout.Window(0, WinRect, new WindowFunction(WindowFunc), "CleanShip", Array.Empty<GUILayoutOption>()); } } private void WindowFunc(int id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 13) { GUI.FocusControl((string)null); } SelectFunc(); if (bRelease) { if (selectedId == 0) { SortFunc(); } else if (selectedId == 1) { OtherFunc(); } else if (selectedId == 2) { ReadMeFunc(); } } else if (selectedId == 0) { SortFunc(); } else if (selectedId == 1) { CollectFunc(); } else if (selectedId == 2) { OtherFunc(); } else if (selectedId == 3) { ReadMeFunc(); } GUI.DragWindow(); } private void SelectFunc() { selectedId = GUILayout.Toolbar(selectedId, SelectStr, Array.Empty<GUILayoutOption>()); } private void SortFunc() { //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) if (CleanShipBehaviour.CleanShipConfig == null) { return; } if (!bRelease) { isRandom = GUILayout.Toggle(isRandom, "随机位置 (将你的飞船弄得乱七八糟!)", Array.Empty<GUILayoutOption>()); } GUI.enabled = !isCollecting; if (GUILayout.Button(isSorting ? "停止整理" : "开始整理", Array.Empty<GUILayoutOption>())) { if (!isSorting) { Setting.bRandomTidy = isRandom; CleanShipBehaviour.StartSort(delegate { isSorting = false; }); } else { CleanShipBehaviour.StopSort(); } isSorting = !isSorting; } GUI.enabled = true; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("位置随机偏移", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); cleanOffset = GUILayout.TextField(cleanOffset, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); GUI.SetNextControlName("应用按钮"); if (GUILayout.Button("应用", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { Setting.cleanOffset = (float.TryParse(cleanOffset, out var result) ? result : Setting.cleanOffset); cleanOffset = Setting.cleanOffset.ToString(); GUI.FocusControl("应用按钮"); } GUILayout.EndHorizontal(); Setting.bOnlyCustom = GUILayout.Toggle(Setting.bOnlyCustom, "仅整理自定义物品", Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUI.color = Color.green; GUILayout.Label(saveStr, Array.Empty<GUILayoutOption>()); GUI.color = Color.white; if (GUILayout.Button("保存配置信息", Array.Empty<GUILayoutOption>())) { CleanShipBehaviour.SaveConfig(); saveStr = "保存成功"; } GUILayout.EndHorizontal(); CleanShipBehaviour.CleanShipConfig.bigItemPos = DrawSortPosOne("大件废料位置", CleanShipBehaviour.CleanShipConfig.bigItemPos); CleanShipBehaviour.CleanShipConfig.smallItemPos = DrawSortPosOne("小件废料位置", CleanShipBehaviour.CleanShipConfig.smallItemPos); CleanShipBehaviour.CleanShipConfig.shovelPos = DrawSortPosOne("铲子位置", CleanShipBehaviour.CleanShipConfig.shovelPos); CleanShipBehaviour.CleanShipConfig.lightPos = DrawSortPosOne("手电筒位置", CleanShipBehaviour.CleanShipConfig.lightPos); CleanShipBehaviour.CleanShipConfig.stunPos = DrawSortPosOne("震撼闪光弹位置", CleanShipBehaviour.CleanShipConfig.stunPos); CleanShipBehaviour.CleanShipConfig.sprPos = DrawSortPosOne("喷漆罐位置", CleanShipBehaviour.CleanShipConfig.sprPos); CleanShipBehaviour.CleanShipConfig.keyPos = DrawSortPosOne("钥匙位置", CleanShipBehaviour.CleanShipConfig.keyPos); CleanShipBehaviour.CleanShipConfig.bagPos = DrawSortPosOne("喷气背包位置", CleanShipBehaviour.CleanShipConfig.bagPos); CleanShipBehaviour.CleanShipConfig.radarPos = DrawSortPosOne("雷达位置", CleanShipBehaviour.CleanShipConfig.radarPos); CleanShipBehaviour.CleanShipConfig.gunPos = DrawSortPosOne("霰弹枪位置", CleanShipBehaviour.CleanShipConfig.gunPos); CleanShipBehaviour.CleanShipConfig.ammoPos = DrawSortPosOne("霰弹枪子弹位置", CleanShipBehaviour.CleanShipConfig.ammoPos); CleanShipBehaviour.CleanShipConfig.otherPos = DrawSortPosOne("其他物品位置", CleanShipBehaviour.CleanShipConfig.otherPos); DrawSortPosList(); DrawGetItemsName(); } private void CollectFunc() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) GUI.enabled = !isSorting; if (GUILayout.Button(isCollecting ? "停止收集" : "开始收集", Array.Empty<GUILayoutOption>())) { if (!isCollecting) { CollectScrapBehaviour.StartCollect(delegate { isCollecting = false; }); } else { CollectScrapBehaviour.StopCollect(); } isCollecting = !isCollecting; } GUI.enabled = true; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUI.color = Color.green; GUILayout.Label(collectSaveStr, Array.Empty<GUILayoutOption>()); GUI.color = Color.white; if (GUILayout.Button("保存配置信息", Array.Empty<GUILayoutOption>())) { CollectScrapBehaviour.SaveConfig(); collectSaveStr = "保存成功"; } GUILayout.EndHorizontal(); CollectScrapBehaviour.Config.bTarget = GUILayout.Toggle(CollectScrapBehaviour.Config.bTarget, "仅收集目标", Array.Empty<GUILayoutOption>()); DrawCollectTargetList(); CollectScrapBehaviour.Config.bIgnore = GUILayout.Toggle(CollectScrapBehaviour.Config.bIgnore, "忽略物品", Array.Empty<GUILayoutOption>()); DrawCollectIgnoreList(); DrawAllItemNames(); } private void OtherFunc() { DrawDisconnect(); DrawTeleportPlayer(); DrawNightVision(); DrawRevivePlayers(); DrawDamageCkeck(); DrawReviveCompany(); DrawKillEnemy(); DrawTest(); } private void ReadMeFunc() { //IL_0012: 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) GUI.skin.label.wordWrap = true; GUI.color = Color.red; GUILayout.Label("* 整理或收集期间无法使用物品栏,出现卡住的情况请点击停止整理或收集。", Array.Empty<GUILayoutOption>()); GUILayout.Label("* 复活功能已知问题:非主机好友看不到复活的玩家,复活后无法造成伤害。", Array.Empty<GUILayoutOption>()); GUI.color = Color.white; GUI.skin.label.wordWrap = false; } private StrVector3 DrawSortPosOne(string posName, StrVector3 posInfo) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(posName, Array.Empty<GUILayoutOption>()); GUILayout.Label("x:", Array.Empty<GUILayoutOption>()); GUILayout.Label(posInfo.X, Array.Empty<GUILayoutOption>()); GUILayout.Label("z:", Array.Empty<GUILayoutOption>()); GUILayout.Label(posInfo.Z, Array.Empty<GUILayoutOption>()); if (GUILayout.Button("应用玩家当前位置", Array.Empty<GUILayoutOption>())) { Vector3 localPlayerPosition = Utility.GetLocalPlayerPosition(); posInfo.X = localPlayerPosition.x.ToString(); posInfo.Y = localPlayerPosition.y.ToString(); posInfo.Z = localPlayerPosition.z.ToString(); } GUILayout.EndHorizontal(); return posInfo; } private void DrawSortPosList() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) if (GUILayout.Button(isUnfold ? "▼ 自定义物品列表" : "▶ 自定义物品列表", Array.Empty<GUILayoutOption>())) { isUnfold = !isUnfold; } if (!isUnfold) { return; } scollView = GUILayout.BeginScrollView(scollView, false, true, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(100f) }); List<CleanShipCustomItem> customItems = CleanShipBehaviour.CleanShipConfig.customItems; for (int i = 0; i < customItems.Count; i++) { CleanShipCustomItem cleanShipCustomItem = customItems[i]; StrVector3 pos = cleanShipCustomItem.pos; GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) }); GUILayout.Label("名称", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) }); cleanShipCustomItem.name = GUILayout.TextField(cleanShipCustomItem.name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); GUILayout.Label("x:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(15f) }); GUILayout.Label(pos.X, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); GUILayout.Label("z:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(15f) }); GUILayout.Label(pos.Z, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); if (GUILayout.Button("应用玩家位置", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { Vector3 localPlayerPosition = Utility.GetLocalPlayerPosition(); pos.X = localPlayerPosition.x.ToString(); pos.Y = localPlayerPosition.y.ToString(); pos.Z = localPlayerPosition.z.ToString(); cleanShipCustomItem.pos = pos; } if (GUILayout.Button("删除", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { customItems.Remove(cleanShipCustomItem); } GUILayout.EndHorizontal(); } if (GUILayout.Button("添加", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) })) { CleanShipBehaviour.CleanShipConfig.customItems.Add(new CleanShipCustomItem()); } GUILayout.EndScrollView(); } private void DrawGetItemsName() { if (GUILayout.Button("查看飞船物品名称参考", Array.Empty<GUILayoutOption>()) && CleanShipBehaviour.TryGetShipItemNames(out var names)) { namesLabel = string.Join(", ", names); } GUILayout.TextArea(namesLabel, Array.Empty<GUILayoutOption>()); } private void DrawCollectTargetList() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if (GUILayout.Button(isCollectTargetListUnfold ? "▼ 收集目标列表" : "▶ 收集目标列表", Array.Empty<GUILayoutOption>())) { isCollectTargetListUnfold = !isCollectTargetListUnfold; } if (!isCollectTargetListUnfold) { return; } CollectTargetListScollView = GUILayout.BeginScrollView(CollectTargetListScollView, false, true, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxHeight(100f) }); List<string> targetList = CollectScrapBehaviour.Config.targetList; for (int i = 0; i < targetList.Count; i++) { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) }); GUILayout.Label("物品名称", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); targetList[i] = GUILayout.TextField(targetList[i], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (GUILayout.Button("删除", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { targetList.RemoveAt(i); } GUILayout.EndHorizontal(); } if (GUILayout.Button("添加", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) })) { CollectScrapBehaviour.Config.targetList.Add(string.Empty); } GUILayout.EndScrollView(); } private void DrawCollectIgnoreList() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if (GUILayout.Button(isCollectIgnoreListUnfold ? "▼ 忽略物品列表" : "▶ 忽略物品列表", Array.Empty<GUILayoutOption>())) { isCollectIgnoreListUnfold = !isCollectIgnoreListUnfold; } if (!isCollectIgnoreListUnfold) { return; } CollectIgnoreListScollView = GUILayout.BeginScrollView(CollectIgnoreListScollView, false, true, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxHeight(100f) }); List<string> ignoreList = CollectScrapBehaviour.Config.ignoreList; for (int i = 0; i < ignoreList.Count; i++) { GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) }); GUILayout.Label("物品名称", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }); ignoreList[i] = GUILayout.TextField(ignoreList[i], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (GUILayout.Button("删除", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) })) { ignoreList.RemoveAt(i); } GUILayout.EndHorizontal(); } if (GUILayout.Button("添加", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(400f) })) { CollectScrapBehaviour.Config.ignoreList.Add(string.Empty); } GUILayout.EndScrollView(); } private void DrawAllItemNames() { if (GUILayout.Button("查看所有废料名称参考", Array.Empty<GUILayoutOption>()) && CollectScrapBehaviour.TryGetAllScrapNames(out var names)) { allCollectNames = string.Join(",", names); } GUILayout.TextArea(allCollectNames, Array.Empty<GUILayoutOption>()); } private void DrawDisconnect() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("强制断开连接", Array.Empty<GUILayoutOption>())) { ForceDisconnectBehaviour.ForceDisconnec(); } GUILayout.Label(" 进房间黑屏时使用", Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void DrawTeleportPlayer() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("传送指定玩家", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { TeleportPlayerBehaviour.TeleportPlayer(); } string text = "[选择目标]"; if ((Object)(object)Setting.curTarget != (Object)null) { text = Setting.curTarget.playerUsername; } if (GUILayout.Button(text, Array.Empty<GUILayoutOption>())) { bPlayersScollView = !bPlayersScollView; } GUILayout.EndHorizontal(); if (!bPlayersScollView) { return; } playersScollViewPos = GUILayout.BeginScrollView(playersScollViewPos, false, true, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxHeight(120f) }); if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.allPlayerScripts != null && StartOfRound.Instance.allPlayerScripts.Length != 0) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; PlayerControllerB[] array = allPlayerScripts; foreach (PlayerControllerB val in array) { if (!val.playerUsername.StartsWith("Player #")) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(125f); if (GUILayout.Button(val.playerUsername, Array.Empty<GUILayoutOption>())) { Setting.curTarget = val; bPlayersScollView = false; } GUILayout.EndHorizontal(); } } } GUILayout.EndScrollView(); } private void DrawNightVision() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Setting.bNightVision = GUILayout.Toggle(Setting.bNightVision, "开启夜视仪功能", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } private void DrawRevivePlayers() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("复活所有队友", Array.Empty<GUILayoutOption>()) && (Object)(object)StartOfRound.Instance != (Object)null) { StartOfRound.Instance.Debug_ReviveAllPlayersServerRpc(); } GUILayout.Label("仅支持主机复活Steam好友", Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void DrawDamageCkeck() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Setting.bDmgCheck = GUILayout.Toggle(Setting.bDmgCheck, "开启队友伤害检测", Array.Empty<GUILayoutOption>()); GUILayout.Label("仅主机", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } private void DrawReviveCompany() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!Setting.hasReviveCompany || !((Object)(object)StartOfRound.Instance != (Object)null)) { return; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.color = Color.blue; GUILayout.Label("ReviveCompany专用:", Array.Empty<GUILayoutOption>()); GUI.color = Color.white; if (GUILayout.Button("复活所有队友", Array.Empty<GUILayoutOption>())) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.isPlayerDead) { Log.LogInfo("开始复活队友:" + val.playerUsername); ReviveFromReviveCompany(val); } } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void ReviveFromReviveCompany(PlayerControllerB player) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown RpcMessage val = new RpcMessage((MessageTasks)1, player.playerClientId.ToString(), (int)StartOfRound.Instance.localPlayerController.playerClientId, (MessageCodes)0); RpcMessageHandler.SendRpcMessage(val); ResponseHandler.SentMessageNeedResponses(val); GeneralUtil.RevivePlayer((int)player.playerClientId); RpcMessage val2 = new RpcMessage((MessageTasks)2, player.playerClientId.ToString(), (int)StartOfRound.Instance.localPlayerController.playerClientId, (MessageCodes)0); RpcMessageHandler.SendRpcMessage(val2); } private void DrawKillEnemy() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Setting.bKillEnemy = GUILayout.Toggle(Setting.bKillEnemy, "开启强制击杀怪物", Array.Empty<GUILayoutOption>()); GUILayout.Label(" 瞄准怪物后按z键", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(" 击杀距离 " + Setting.killEnemyDis.ToString("0.00"), Array.Empty<GUILayoutOption>()); Setting.killEnemyDis = GUILayout.HorizontalSlider(Setting.killEnemyDis, 1f, 50f, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Setting.bDestroyEnemy = GUILayout.Toggle(Setting.bDestroyEnemy, "强制击杀后删除怪物", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } private void DrawTest() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("获取所有房间", Array.Empty<GUILayoutOption>())) { GetLobbysAsync(); } GUILayout.EndHorizontal(); } private async void GetLobbysAsync() { LobbyQuery query = SteamMatchmaking.LobbyList; ((LobbyQuery)(ref query)).WithMaxResults(100); Lobby[] array = await ((LobbyQuery)(ref query)).RequestAsync(); for (int i = 0; i < array.Length; i++) { Lobby lobby = array[i]; Plugin.Log.LogInfo("房间:" + ((Lobby)(ref lobby)).GetData("name")); lobby = default(Lobby); } } } internal static class Setting { public static bool bMenu; public static bool bCleaning; public static bool bCollecting; public static bool bRandomTidy; public static bool bCleanCustom; public static float cleanOffset = 0.2f; public static bool bOnlyCustom; public static bool bNoclip; public static float noclipSpeed; public static PlayerControllerB curTarget; public static bool bNightVision; public static float playerVolumesRate = 1f; public static bool bDmgCheck; public static bool hasReviveCompany; public static bool bKillEnemy; public static bool bDestroyEnemy; public static float killEnemyDis = 10f; } public static class Utility { internal static CustomLog Log = Plugin.Log; public static BindingFlags protectedFlags = BindingFlags.Instance | BindingFlags.NonPublic; public static Vector3 GetLocalPlayerPosition() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null || StartOfRound.Instance.localPlayerController.isPlayerDead) { return Vector3.zero; } return ((Component)StartOfRound.Instance.localPlayerController).transform.position; } public static object CallMethod(object instance, string methodName, BindingFlags bindingFlags, params object[] parameters) { Type type = instance.GetType(); MethodInfo method = type.GetMethod(methodName, bindingFlags); object result; if (method != null) { object obj = method.Invoke(instance, parameters); result = obj; } else { result = null; Log.LogError($"执行方法失败!{instance}.{methodName}"); } return result; } public static Vector3 SetPositionY(this Vector3 position, float y) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return new Vector3(position.x, y, position.z); } public static bool IsModLoaded(string guid) { return Chainloader.PluginInfos.ContainsKey(guid); } public static T DeepCopy<T>(T obj) { using MemoryStream memoryStream = new MemoryStream(); BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(memoryStream, obj); memoryStream.Seek(0L, SeekOrigin.Begin); return (T)binaryFormatter.Deserialize(memoryStream); } } public class CustomLog { public bool enable = true; internal static ManualLogSource Log = Logger.CreateLogSource("TAIGU.CustomCompany.CleanShip"); public void LogInfo(object message) { if (enable) { Log.LogInfo(message); } } public void LogWarning(object message) { if (enable) { Log.LogWarning(message); } } public void LogError(object message) { if (enable) { Log.LogError(message); } } public void LogDebug(object message) { if (enable) { Log.LogDebug(message); } } public void LogMessage(object message) { if (enable) { Log.LogMessage(message); } } public void LogFatal(object message) { if (enable) { Log.LogFatal(message); } } } } namespace CustomCompany.Patch { [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRound_Patch { private static IEnumerable<CodeInstruction> Debug_ReviveAllPlayersServerRpcTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); list[73].opcode = OpCodes.Nop; return list; } private static IEnumerable<CodeInstruction> Debug_ReviveAllPlayersClientRpcTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); list[58].opcode = OpCodes.Nop; return list; } } [HarmonyPatch] public class PlayerControllerB_Patch { [HarmonyPatch(typeof(PlayerControllerB), "SetObjectAsNoLongerHeld")] [HarmonyPostfix] private static void SetObjectAsNoLongerHeldPostfix(PlayerControllerB __instance, bool droppedInElevator, bool droppedInShipRoom, Vector3 targetFloorPosition, GrabbableObject dropObject, int floorYRot = -1) { if (((NetworkBehaviour)__instance).IsOwner) { Plugin.Log.LogInfo("物品丢弃成功!:" + dropObject.itemProperties.itemName); } } [HarmonyPatch(typeof(PlayerControllerB), "SetObjectAsNoLongerHeld")] [HarmonyPrefix] private static bool SetObjectAsNoLongerHeldPrefix(PlayerControllerB __instance, bool droppedInElevator, bool droppedInShipRoom, Vector3 targetFloorPosition, GrabbableObject dropObject, int floorYRot = -1) { if (!((NetworkBehaviour)__instance).IsOwner) { return true; } if ((Object)(object)dropObject == (Object)null) { Plugin.Log.LogInfo("物品丢弃失败!:目标为空"); return true; } Plugin.Log.LogInfo("物品丢弃成功!:" + dropObject.itemProperties.itemName); return true; } [HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")] [HarmonyPostfix] private static void SwitchToItemSlotPrefix(PlayerControllerB __instance, int slot, GrabbableObject fillSlotWithItem = null) { if (((NetworkBehaviour)__instance).IsOwner && (Object)(object)fillSlotWithItem != (Object)null) { Plugin.Log.LogInfo($"物品拿取成功!{slot} {fillSlotWithItem.itemProperties.itemName}"); } } [HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")] [HarmonyPrefix] private static bool ScrollMouse_performedPrefix(PlayerControllerB __instance, CallbackContext context) { if (!((NetworkBehaviour)__instance).IsOwner) { return true; } if (Setting.bCleaning || Setting.bCollecting) { Plugin.Log.LogInfo("正在操作飞船物品,无法切换!"); return false; } return true; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPrefix] public static bool UpdatePrefix(PlayerControllerB __instance) { if ((Object)(object)__instance == (Object)(object)StartOfRound.Instance.localPlayerController) { __instance.disableLookInput = __instance.quickMenuManager.isMenuOpen || Setting.bMenu; if (__instance.quickMenuManager.isMenuOpen || Setting.bMenu) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } else { Cursor.visible = false; Cursor.lockState = (CursorLockMode)1; } } return true; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] public static void UpdatePostfix(PlayerControllerB __instance) { if ((Object)(object)__instance == (Object)(object)StartOfRound.Instance.localPlayerController) { NoclipBehaviour.Update(); NightVisionBehaviour.Update(__instance); KillEnemyBehaviour.Update(__instance); } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] [HarmonyPostfix] public static void StartPostfix(PlayerControllerB __instance) { if (!((Object)(object)__instance == (Object)(object)StartOfRound.Instance.localPlayerController)) { } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerFromOtherClientServerRpc")] [HarmonyPostfix] public static void DamagePlayerFromOtherClientServerRpcPostfix(PlayerControllerB __instance, int damageAmount, Vector3 hitDirection, int playerWhoHit) { DamageCkeckBehaviour.Check(__instance, playerWhoHit); } } } namespace CustomCompany.Behaviour { [Serializable] public class BehaviourConfig { public CleanShipConfig CleanShipConfig = new CleanShipConfig(); public CollectScrapConfig CollectScrapConfig = new CollectScrapConfig(); } internal static class CollectScrapBehaviour { public static CollectScrapConfig Config = new CollectScrapConfig(); private static Coroutine collectCoroutine; internal static CustomLog Log => Plugin.Log; public static void StartCollect(Action callBack) { if (!((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) && !StartOfRound.Instance.localPlayerController.isPlayerDead) { StopCollect(); collectCoroutine = ((MonoBehaviour)CustomCompanyManager.Instance).StartCoroutine(CollectCoroutine(callBack)); } } public static void StopCollect() { if (collectCoroutine != null) { ((MonoBehaviour)CustomCompanyManager.Instance).StopCoroutine(collectCoroutine); collectCoroutine = null; } Setting.bCollecting = false; } public static bool TryGetAllScrapNames(out List<string> names) { names = new List<string>(); if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.localPlayerController == (Object)null || !GameNetworkManager.Instance.gameHasStarted) { return false; } GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (!((Object)(object)val == (Object)null) && val.itemProperties.isScrap && !val.isInShipRoom && val.grabbable) { string itemName = val.itemProperties.itemName; names.Add(itemName); } } names = names.Distinct().ToList(); return true; } public static void LoadConfig() { Config = Utility.DeepCopy(CustomCompanyConfig.BehaviourConfig.CollectScrapConfig); } public static void SaveConfig() { CustomCompanyConfig.BehaviourConfig.CollectScrapConfig = Utility.DeepCopy(Config); CustomCompanyConfig.SaveBehaviourConfig(); } private static IEnumerator CollectCoroutine(Action callBack) { Setting.bCollecting = true; PlayerControllerB player = StartOfRound.Instance.localPlayerController; GrabbableObject[] allObj = Object.FindObjectsOfType<GrabbableObject>(); GrabbableObject[] array = allObj; foreach (GrabbableObject item in array) { if (CkeckTarget(item)) { Log.LogInfo(string.Format("等待丢弃操作结束...{0} 当前准备抓取的物品 {1}", Traverse.Create((object)player).Field<bool>("throwingObject").Value, item.itemProperties.itemName)); yield return (object)new WaitUntil((Func<bool>)(() => !Traverse.Create((object)player).Field<bool>("throwingObject").Value)); Log.LogInfo("开始抓取飞船物品:" + item.itemProperties.itemName); NetworkObjectReference obj = new NetworkObjectReference(((NetworkBehaviour)item).NetworkObject); Traverse.Create((object)player).Field<GrabbableObject>("currentlyGrabbingObject").Value = item; item.InteractItem(); player.twoHanded = item.itemProperties.twoHanded; PlayerControllerB obj2 = player; obj2.carryWeight += Mathf.Clamp(item.itemProperties.weight - 1f, 0f, 10f); item.parentObject = player.localItemHolder; Utility.CallMethod(player, "GrabObjectServerRpc", BindingFlags.Instance | BindingFlags.NonPublic, obj); Log.LogInfo($"等待抓取操作结束... 当前准备丢弃的物品 {player.currentlyHeldObjectServer}"); yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)player.currentlyHeldObjectServer == (Object)(object)item)); Log.LogInfo("开始丢弃手持物品:" + item.itemProperties.itemName); player.isHoldingObject = true; player.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true); } } collectCoroutine = null; Setting.bCollecting = false; callBack?.Invoke(); yield return null; } private static bool CkeckTarget(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return false; } if (!item.itemProperties.isScrap) { return false; } if (item.isInShipRoom) { return false; } if (item.isHeld) { return false; } if (!item.grabbable) { return false; } if (item.heldByPlayerOnServer) { return false; } if (Config.bIgnore && Config.ignoreList.Contains(item.itemProperties.itemName)) { return false; } if (Config.bTarget && !Config.targetList.Contains(item.itemProperties.itemName)) { return false; } return true; } } [Serializable] public class CollectScrapConfig { public List<string> targetList = new List<string>(); public bool bTarget; public List<string> ignoreList = new List<string>(); public bool bIgnore; } internal static class DamageCkeckBehaviour { public static void Check(PlayerControllerB __instance, int playerWhoHit) { if (Setting.bDmgCheck) { string playerUsername = __instance.playerUsername; string text = "神秘人"; if ((Object)(object)StartOfRound.Instance.allPlayerScripts[playerWhoHit] != (Object)null) { text = StartOfRound.Instance.allPlayerScripts[playerWhoHit].playerUsername; } string text2 = text + " 正在殴打 " + playerUsername + "!"; Plugin.Log.LogInfo("发送消息:" + text2); SendMessageBehaviour.Send(text2); } } } public static class ForceDisconnectBehaviour { public static void ForceDisconnec() { GameNetworkManager instance = GameNetworkManager.Instance; if (Object.op_Implicit((Object)(object)instance)) { instance.isDisconnecting = true; if (instance.isHostingGame) { instance.disallowConnection = true; } Utility.CallMethod(instance, "StartDisconnect", BindingFlags.Instance | BindingFlags.NonPublic); instance.SaveGame(); if ((Object)(object)NetworkManager.Singleton == (Object)null) { Debug.Log((object)"Server is not active; quitting to main menu"); Utility.CallMethod(instance, "ResetGameValuesToDefault", BindingFlags.Instance | BindingFlags.NonPublic); SceneManager.LoadScene("MainMenu"); } else { ((MonoBehaviour)instance).StartCoroutine((IEnumerator)Utility.CallMethod(instance, "DisconnectProcess", BindingFlags.Instance | BindingFlags.NonPublic)); } } } } internal static class KillEnemyBehaviour { private static Ray interactRay; private static RaycastHit hit; public static void Update(PlayerControllerB player) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) if (!Setting.bKillEnemy) { return; } interactRay = new Ray(((Component)player.gameplayCamera).transform.position, ((Component)player.gameplayCamera).transform.forward); if (Physics.Raycast(interactRay, ref hit, Setting.killEnemyDis, LayerMask.GetMask(new string[1] { "Enemies" }))) { EnemyAI componentInParent = ((Component)((RaycastHit)(ref hit)).transform).GetComponentInParent<EnemyAI>(); if ((Object)(object)componentInParent != (Object)null && ((ButtonControl)Keyboard.current.zKey).wasPressedThisFrame) { Plugin.Log.LogInfo("击杀敌人:" + ((Object)componentInParent).name); componentInParent.KillEnemyServerRpc(Setting.bDestroyEnemy); } } } } internal static class NightVisionBehaviour { private static bool bOn; private static Color tempColor; private static float tempRange; private static float tempIntensity; public static void Update(PlayerControllerB player) { if (Setting.bNightVision) { On(player); } else { Off(player); } } public static void On(PlayerControllerB player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!bOn) { bOn = true; player.nightVision.color = new Color(1f, 1f, 1f, 1f); player.nightVision.range = 5000f; player.nightVision.intensity = 1000f; } } public static void Off(PlayerControllerB player) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (bOn) { bOn = false; player.nightVision.color = tempColor; player.nightVision.range = tempRange; player.nightVision.intensity = tempIntensity; } } } internal static class SendMessageBehaviour { public static void Send(string message, int playerId = -1, string color = "red") { string text = "<color=" + color + ">" + message + "</color>"; HUDManager.Instance.AddTextToChatOnServer(text, playerId); } } public static class TeleportPlayerBehaviour { private static ShipTeleporter shipTeleporter; private static Camera cmr; private static Coroutine coroutine; internal static CustomLog Log => Plugin.Log; public static void TeleportPlayer() { if (coroutine != null) { ((MonoBehaviour)CustomCompanyManager.Instance).StopCoroutine(coroutine); coroutine = null; } coroutine = ((MonoBehaviour)CustomCompanyManager.Instance).StartCoroutine(TeleportPlayerSync()); } private static IEnumerator TeleportPlayerSync() { ShipTeleporter teleporter = GetShipTeleporter(); if (Object.op_Implicit((Object)(object)teleporter) && Object.op_Implicit((Object)(object)Setting.curTarget)) { int num = SearchForPlayerInRadar(); StartOfRound.Instance.mapScreen.SwitchRadarTargetAndSync(num); yield return (object)new WaitForSeconds(0.15f); yield return (object)new WaitUntil((Func<bool>)(() => StartOfRound.Instance.mapScreen.targetTransformIndex == num)); teleporter.PressTeleportButtonOnLocalClient(); } else { Log.LogInfo("传送器为空!"); yield return null; } } private static ShipTeleporter GetShipTeleporter() { if ((Object)(object)shipTeleporter != (Object)null) { return shipTeleporter; } ShipTeleporter[] array = Object.FindObjectsOfType<ShipTeleporter>(); ShipTeleporter val = null; ShipTeleporter[] array2 = array; foreach (ShipTeleporter val2 in array2) { if (!val2.isInverseTeleporter) { val = val2; break; } } shipTeleporter = val; return shipTeleporter; } private static int SearchForPlayerInRadar() { int result = -1; for (int i = 0; i < StartOfRound.Instance.mapScreen.radarTargets.Count(); i++) { if (!((Object)(object)((Component)StartOfRound.Instance.mapScreen.radarTargets[i].transform).gameObject.GetComponent<PlayerControllerB>() != (Object)(object)Setting.curTarget)) { result = i; break; } } return result; } } [Serializable] public class CleanShipConfig : ICloneable { public StrVector3 bigItemPos = new StrVector3(-3.3f, 0.5f, -15.8f); public StrVector3 smallItemPos = new StrVector3(-3.3f, 0.5f, -12.7f); public StrVector3 shovelPos = new StrVector3(5f, 0.5f, -16f); public StrVector3 lightPos = new StrVector3(2.9f, 0.5f, -15.6f); public StrVector3 stunPos = new StrVector3(-4.3f, 0.5f, -14f); public StrVector3 sprPos = new StrVector3(2.9f, 0.5f, -12.7f); public StrVector3 keyPos = new StrVector3(9.5f, 0.5f, -16f); public StrVector3 bagPos = new StrVector3(5f, 0.5f, -11.7f); public StrVector3 radarPos = new StrVector3(-0.8f, 0.5f, -12.7f); public StrVector3 otherPos = new StrVector3(6.8f, 0.5f, -11.9f); public StrVector3 gunPos = new StrVector3(10f, 0.5f, -11.9f); public StrVector3 ammoPos = new StrVector3(9f, 0.5f, -11.9f); public List<CleanShipCustomItem> customItems = new List<CleanShipCustomItem>(); public object Clone() { throw new NotImplementedException(); } public bool TryGet(string name, out StrVector3 v3) { CleanShipCustomItem cleanShipCustomItem = customItems.FirstOrDefault((CleanShipCustomItem itemInfo) => !string.IsNullOrEmpty(itemInfo.name) && itemInfo.name.Equals(name)); v3 = cleanShipCustomItem?.pos ?? null; return cleanShipCustomItem != null; } } [Serializable] public class CleanShipCustomItem { public StrVector3 pos; public string name = string.Empty; public CleanShipCustomItem() { pos = new StrVector3(); } } [Serializable] public class StrVector3 { [SerializeField] private float x; [SerializeField] private float y; [SerializeField] private float z; public string X { get { return x.ToString("F2"); } set { x = (float.TryParse(value, out var result) ? result : 0f); } } public string Y { get { return y.ToString("F2"); } set { y = (float.TryParse(value, out var result) ? result : 0f); } } public string Z { get { return z.ToString("F2"); } set { z = (float.TryParse(value, out var result) ? result : 0f); } } public StrVector3(string _x, string _y, string _z) { x = (float.TryParse(_x, out var result) ? result : 0f); y = (float.TryParse(_y, out var result2) ? result2 : 0f); z = (float.TryParse(_z, out var result3) ? result3 : 0f); } public StrVector3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } public StrVector3() { } public Vector3 ToVector3() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } } public static class CleanShipBehaviour { public static CleanShipConfig CleanShipConfig; private static Coroutine tidyItem_crt; internal static CustomLog Log => Plugin.Log; private static IEnumerator SortCoroutine(Action callBack) { Setting.bCleaning = true; GameObject ship = GameObject.Find("/Environment/HangarShip"); PlayerControllerB player = RoundManager.Instance.playersManager.localPlayerController; GrabbableObject[] componentsInChildren = ((Component)ship.transform).GetComponentsInChildren<GrabbableObject>(); foreach (GrabbableObject item in componentsInChildren) { if (!player.isInHangarShipRoom) { break; } if (item.isHeld || item.heldByPlayerOnServer || (Setting.bOnlyCustom && !IsCustom(item))) { continue; } Vector3 cfgPos = GetTidyTargetPos(item); Vector3 targetPos = item.GetItemFloorPosition(cfgPos); Vector3 offsetTargetPos = GetVector3_OffsetXZ(targetPos, Setting.cleanOffset); if (!(Vector3.Distance(((Component)item).transform.position, targetPos) <= Setting.cleanOffset)) { Log.LogInfo(string.Format("等待丢弃操作结束...{0} 当前准备抓取的物品 {1}", Traverse.Create((object)player).Field<bool>("throwingObject").Value, item.itemProperties.itemName)); yield return (object)new WaitUntil((Func<bool>)(() => !Traverse.Create((object)player).Field<bool>("throwingObject").Value)); Log.LogInfo("开始抓取飞船物品:" + item.itemProperties.itemName); NetworkObjectReference obj = new NetworkObjectReference(((NetworkBehaviour)item).NetworkObject); Traverse.Create((object)player).Field<GrabbableObject>("currentlyGrabbingObject").Value = item; item.InteractItem(); player.twoHanded = item.itemProperties.twoHanded; PlayerControllerB obj2 = player; obj2.carryWeight += Mathf.Clamp(item.itemProperties.weight - 1f, 0f, 10f); item.parentObject = player.localItemHolder; Utility.CallMethod(player, "GrabObjectServerRpc", BindingFlags.Instance | BindingFlags.NonPublic, obj); Log.LogInfo($"等待抓取操作结束... 当前准备丢弃的物品 {player.currentlyHeldObjectServer}"); yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)player.currentlyHeldObjectServer == (Object)(object)item)); Log.LogInfo("开始丢弃飞船物品:" + item.itemProperties.itemName); player.isHoldingObject = true; player.DiscardHeldObject(true, (NetworkObject)null, offsetTargetPos, false); } } Setting.bCleaning = false; callBack?.Invoke(); tidyItem_crt = null; } private static Vector3 GetTidyTargetPos(GrabbableObject obj) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) if (Setting.bRandomTidy) { return new Vector3(Random.Range(-3f, 9f), 0.5f, Random.Range(-15.8f, -12.7f)); } if (CleanShipConfig.TryGet(obj.itemProperties.itemName, out var v)) { return v.ToVector3(); } if (obj is Shovel) { return CleanShipConfig.shovelPos.ToVector3(); } if (obj is FlashlightItem) { return CleanShipConfig.lightPos.ToVector3(); } if (obj is StunGrenadeItem) { return CleanShipConfig.stunPos.ToVector3(); } if (obj is SprayPaintItem) { return CleanShipConfig.sprPos.ToVector3(); } if (obj is KeyItem) { return CleanShipConfig.keyPos.ToVector3(); } if (obj is JetpackItem) { return CleanShipConfig.bagPos.ToVector3(); } if (obj is RadarBoosterItem) { return CleanShipConfig.radarPos.ToVector3(); } if (obj is ShotgunItem) { return CleanShipConfig.gunPos.ToVector3(); } if (obj is GunAmmo) { return CleanShipConfig.ammoPos.ToVector3(); } if (obj.itemProperties.twoHanded && obj.itemProperties.isScrap) { return CleanShipConfig.bigItemPos.ToVector3(); } if (!obj.itemProperties.twoHanded && obj.itemProperties.isScrap) { return CleanShipConfig.smallItemPos.ToVector3(); } return CleanShipConfig.otherPos.ToVector3(); } private static bool IsCustom(GrabbableObject obj) { if (CleanShipConfig.TryGet(obj.itemProperties.itemName, out var _)) { return true; } return false; } private static Vector3 GetVector3_OffsetXZ(Vector3 v3, float offset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Random.insideUnitCircle * offset; return new Vector3(v3.x + val.x, v3.y, v3.z + val.y); } public static void StartSort(Action callBack) { if (!((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) && !StartOfRound.Instance.localPlayerController.isPlayerDead) { StopSort(); tidyItem_crt = ((MonoBehaviour)CustomCompanyManager.Instance).StartCoroutine(SortCoroutine(callBack)); } } public static void StopSort() { if (tidyItem_crt != null) { ((MonoBehaviour)CustomCompanyManager.Instance).StopCoroutine(tidyItem_crt); tidyItem_crt = null; } if (Setting.bCleaning) { Setting.bCleaning = false; } } public static bool TryGetShipItemNames(out List<string> names) { names = new List<string>(); if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) { return false; } GameObject val = GameObject.Find("/Environment/HangarShip"); PlayerControllerB localPlayerController = RoundManager.Instance.playersManager.localPlayerController; GrabbableObject[] componentsInChildren = ((Component)val.transform).GetComponentsInChildren<GrabbableObject>(); foreach (GrabbableObject val2 in componentsInChildren) { string itemName = val2.itemProperties.itemName; names.Add(itemName); } names = names.Distinct().ToList(); return true; } public static void LoadConfig() { CleanShipConfig = Utility.DeepCopy(CustomCompanyConfig.BehaviourConfig.CleanShipConfig); } public static void SaveConfig() { BehaviourConfig behaviourConfig = CustomCompanyConfig.BehaviourConfig; behaviourConfig.CleanShipConfig = Utility.DeepCopy(CleanShipConfig); CustomCompanyConfig.SaveBehaviourConfig(); } } public static class NoclipBehaviour { public static void Update() { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) if (!Setting.bNoclip) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (!Object.op_Implicit((Object)(object)localPlayerController)) { return; } Collider component = (Collider)(object)((Component)localPlayerController).GetComponent<CharacterController>(); if (!Object.op_Implicit((Object)(object)component)) { return; } Transform transform = ((Component)localPlayerController).transform; component.enabled = !Object.op_Implicit((Object)(object)transform); if (!component.enabled) { bool isPressed = ((ButtonControl)Keyboard.current.wKey).isPressed; bool isPressed2 = ((ButtonControl)Keyboard.current.aKey).isPressed; bool isPressed3 = ((ButtonControl)Keyboard.current.sKey).isPressed; bool isPressed4 = ((ButtonControl)Keyboard.current.dKey).isPressed; bool isPressed5 = ((ButtonControl)Keyboard.current.spaceKey).isPressed; bool isPressed6 = ((ButtonControl)Keyboard.current.leftCtrlKey).isPressed; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0f, 0f); if (isPressed) { val += transform.forward; } if (isPressed3) { val -= transform.forward; } if (isPressed2) { val -= transform.right; } if (isPressed4) { val += transform.right; } if (isPressed5) { val.y += transform.up.y; } if (isPressed6) { val.y -= transform.up.y; } Transform transform2 = ((Component)localPlayerController).transform; transform2.position += val * (Setting.noclipSpeed * Time.deltaTime); } } } }
BepInEx/plugins/LitJSON.dll
Decompiled 9 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CLSCompliant(true)] [assembly: AssemblyTitle("LitJson")] [assembly: AssemblyDescription("LitJSON library")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LitJSON")] [assembly: AssemblyCopyright("The authors disclaim copyright to this source code")] [assembly: AssemblyTrademark("")] [assembly: AssemblyFileVersion("0.19.0.0")] [assembly: AssemblyInformationalVersion("0.19.0+Branch.develop.Sha.d0afd60354c01246bf747821439d7a176a376ae3")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.19.0.0")] namespace LitJson; public enum JsonType { None, Object, Array, String, Int, Long, Double, Boolean } public interface IJsonWrapper : IList, ICollection, IEnumerable, IOrderedDictionary, IDictionary { bool IsArray { get; } bool IsBoolean { get; } bool IsDouble { get; } bool IsInt { get; } bool IsLong { get; } bool IsObject { get; } bool IsString { get; } bool GetBoolean(); double GetDouble(); int GetInt(); JsonType GetJsonType(); long GetLong(); string GetString(); void SetBoolean(bool val); void SetDouble(double val); void SetInt(int val); void SetJsonType(JsonType type); void SetLong(long val); void SetString(string val); string ToJson(); void ToJson(JsonWriter writer); } public class JsonData : IJsonWrapper, IList, ICollection, IEnumerable, IOrderedDictionary, IDictionary, IEquatable<JsonData> { private IList<JsonData> inst_array; private bool inst_boolean; private double inst_double; private int inst_int; private long inst_long; private IDictionary<string, JsonData> inst_object; private string inst_string; private string json; private JsonType type; private IList<KeyValuePair<string, JsonData>> object_list; public int Count => EnsureCollection().Count; public bool IsArray => type == JsonType.Array; public bool IsBoolean => type == JsonType.Boolean; public bool IsDouble => type == JsonType.Double; public bool IsInt => type == JsonType.Int; public bool IsLong => type == JsonType.Long; public bool IsObject => type == JsonType.Object; public bool IsString => type == JsonType.String; public ICollection<string> Keys { get { EnsureDictionary(); return inst_object.Keys; } } int ICollection.Count => Count; bool ICollection.IsSynchronized => EnsureCollection().IsSynchronized; object ICollection.SyncRoot => EnsureCollection().SyncRoot; bool IDictionary.IsFixedSize => EnsureDictionary().IsFixedSize; bool IDictionary.IsReadOnly => EnsureDictionary().IsReadOnly; ICollection IDictionary.Keys { get { EnsureDictionary(); IList<string> list = new List<string>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Key); } return (ICollection)list; } } ICollection IDictionary.Values { get { EnsureDictionary(); IList<JsonData> list = new List<JsonData>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Value); } return (ICollection)list; } } bool IJsonWrapper.IsArray => IsArray; bool IJsonWrapper.IsBoolean => IsBoolean; bool IJsonWrapper.IsDouble => IsDouble; bool IJsonWrapper.IsInt => IsInt; bool IJsonWrapper.IsLong => IsLong; bool IJsonWrapper.IsObject => IsObject; bool IJsonWrapper.IsString => IsString; bool IList.IsFixedSize => EnsureList().IsFixedSize; bool IList.IsReadOnly => EnsureList().IsReadOnly; object IDictionary.this[object key] { get { return EnsureDictionary()[key]; } set { if (!(key is string)) { throw new ArgumentException("The key has to be a string"); } JsonData value2 = ToJsonData(value); this[(string)key] = value2; } } object IOrderedDictionary.this[int idx] { get { EnsureDictionary(); return object_list[idx].Value; } set { EnsureDictionary(); JsonData value2 = ToJsonData(value); KeyValuePair<string, JsonData> keyValuePair = object_list[idx]; inst_object[keyValuePair.Key] = value2; KeyValuePair<string, JsonData> value3 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value2); object_list[idx] = value3; } } object IList.this[int index] { get { return EnsureList()[index]; } set { EnsureList(); JsonData value2 = ToJsonData(value); this[index] = value2; } } public JsonData this[string prop_name] { get { EnsureDictionary(); return inst_object[prop_name]; } set { EnsureDictionary(); KeyValuePair<string, JsonData> keyValuePair = new KeyValuePair<string, JsonData>(prop_name, value); if (inst_object.ContainsKey(prop_name)) { for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == prop_name) { object_list[i] = keyValuePair; break; } } } else { object_list.Add(keyValuePair); } inst_object[prop_name] = value; json = null; } } public JsonData this[int index] { get { EnsureCollection(); if (type == JsonType.Array) { return inst_array[index]; } return object_list[index].Value; } set { EnsureCollection(); if (type == JsonType.Array) { inst_array[index] = value; } else { KeyValuePair<string, JsonData> keyValuePair = object_list[index]; KeyValuePair<string, JsonData> value2 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value); object_list[index] = value2; inst_object[keyValuePair.Key] = value; } json = null; } } public bool ContainsKey(string key) { EnsureDictionary(); return inst_object.Keys.Contains(key); } public JsonData() { } public JsonData(bool boolean) { type = JsonType.Boolean; inst_boolean = boolean; } public JsonData(double number) { type = JsonType.Double; inst_double = number; } public JsonData(int number) { type = JsonType.Int; inst_int = number; } public JsonData(long number) { type = JsonType.Long; inst_long = number; } public JsonData(object obj) { if (obj is bool) { type = JsonType.Boolean; inst_boolean = (bool)obj; return; } if (obj is double) { type = JsonType.Double; inst_double = (double)obj; return; } if (obj is int) { type = JsonType.Int; inst_int = (int)obj; return; } if (obj is long) { type = JsonType.Long; inst_long = (long)obj; return; } if (obj is string) { type = JsonType.String; inst_string = (string)obj; return; } throw new ArgumentException("Unable to wrap the given object with JsonData"); } public JsonData(string str) { type = JsonType.String; inst_string = str; } public static implicit operator JsonData(bool data) { return new JsonData(data); } public static implicit operator JsonData(double data) { return new JsonData(data); } public static implicit operator JsonData(int data) { return new JsonData(data); } public static implicit operator JsonData(long data) { return new JsonData(data); } public static implicit operator JsonData(string data) { return new JsonData(data); } public static explicit operator bool(JsonData data) { if (data.type != JsonType.Boolean) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_boolean; } public static explicit operator double(JsonData data) { if (data.type != JsonType.Double) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_double; } public static explicit operator int(JsonData data) { if (data.type != JsonType.Int && data.type != JsonType.Long) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } if (data.type != JsonType.Int) { return (int)data.inst_long; } return data.inst_int; } public static explicit operator long(JsonData data) { if (data.type != JsonType.Long && data.type != JsonType.Int) { throw new InvalidCastException("Instance of JsonData doesn't hold a long"); } if (data.type != JsonType.Long) { return data.inst_int; } return data.inst_long; } public static explicit operator string(JsonData data) { if (data.type != JsonType.String) { throw new InvalidCastException("Instance of JsonData doesn't hold a string"); } return data.inst_string; } void ICollection.CopyTo(Array array, int index) { EnsureCollection().CopyTo(array, index); } void IDictionary.Add(object key, object value) { JsonData value2 = ToJsonData(value); EnsureDictionary().Add(key, value2); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>((string)key, value2); object_list.Add(item); json = null; } void IDictionary.Clear() { EnsureDictionary().Clear(); object_list.Clear(); json = null; } bool IDictionary.Contains(object key) { return EnsureDictionary().Contains(key); } IDictionaryEnumerator IDictionary.GetEnumerator() { return ((IOrderedDictionary)this).GetEnumerator(); } void IDictionary.Remove(object key) { EnsureDictionary().Remove(key); for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == (string)key) { object_list.RemoveAt(i); break; } } json = null; } IEnumerator IEnumerable.GetEnumerator() { return EnsureCollection().GetEnumerator(); } bool IJsonWrapper.GetBoolean() { if (type != JsonType.Boolean) { throw new InvalidOperationException("JsonData instance doesn't hold a boolean"); } return inst_boolean; } double IJsonWrapper.GetDouble() { if (type != JsonType.Double) { throw new InvalidOperationException("JsonData instance doesn't hold a double"); } return inst_double; } int IJsonWrapper.GetInt() { if (type != JsonType.Int) { throw new InvalidOperationException("JsonData instance doesn't hold an int"); } return inst_int; } long IJsonWrapper.GetLong() { if (type != JsonType.Long) { throw new InvalidOperationException("JsonData instance doesn't hold a long"); } return inst_long; } string IJsonWrapper.GetString() { if (type != JsonType.String) { throw new InvalidOperationException("JsonData instance doesn't hold a string"); } return inst_string; } void IJsonWrapper.SetBoolean(bool val) { type = JsonType.Boolean; inst_boolean = val; json = null; } void IJsonWrapper.SetDouble(double val) { type = JsonType.Double; inst_double = val; json = null; } void IJsonWrapper.SetInt(int val) { type = JsonType.Int; inst_int = val; json = null; } void IJsonWrapper.SetLong(long val) { type = JsonType.Long; inst_long = val; json = null; } void IJsonWrapper.SetString(string val) { type = JsonType.String; inst_string = val; json = null; } string IJsonWrapper.ToJson() { return ToJson(); } void IJsonWrapper.ToJson(JsonWriter writer) { ToJson(writer); } int IList.Add(object value) { return Add(value); } void IList.Clear() { EnsureList().Clear(); json = null; } bool IList.Contains(object value) { return EnsureList().Contains(value); } int IList.IndexOf(object value) { return EnsureList().IndexOf(value); } void IList.Insert(int index, object value) { EnsureList().Insert(index, value); json = null; } void IList.Remove(object value) { EnsureList().Remove(value); json = null; } void IList.RemoveAt(int index) { EnsureList().RemoveAt(index); json = null; } IDictionaryEnumerator IOrderedDictionary.GetEnumerator() { EnsureDictionary(); return new OrderedDictionaryEnumerator(object_list.GetEnumerator()); } void IOrderedDictionary.Insert(int idx, object key, object value) { string text = (string)key; JsonData value2 = (this[text] = ToJsonData(value)); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>(text, value2); object_list.Insert(idx, item); } void IOrderedDictionary.RemoveAt(int idx) { EnsureDictionary(); inst_object.Remove(object_list[idx].Key); object_list.RemoveAt(idx); } private ICollection EnsureCollection() { if (type == JsonType.Array) { return (ICollection)inst_array; } if (type == JsonType.Object) { return (ICollection)inst_object; } throw new InvalidOperationException("The JsonData instance has to be initialized first"); } private IDictionary EnsureDictionary() { if (type == JsonType.Object) { return (IDictionary)inst_object; } if (type != 0) { throw new InvalidOperationException("Instance of JsonData is not a dictionary"); } type = JsonType.Object; inst_object = new Dictionary<string, JsonData>(); object_list = new List<KeyValuePair<string, JsonData>>(); return (IDictionary)inst_object; } private IList EnsureList() { if (type == JsonType.Array) { return (IList)inst_array; } if (type != 0) { throw new InvalidOperationException("Instance of JsonData is not a list"); } type = JsonType.Array; inst_array = new List<JsonData>(); return (IList)inst_array; } private JsonData ToJsonData(object obj) { if (obj == null) { return null; } if (obj is JsonData) { return (JsonData)obj; } return new JsonData(obj); } private static void WriteJson(IJsonWrapper obj, JsonWriter writer) { if (obj == null) { writer.Write(null); } else if (obj.IsString) { writer.Write(obj.GetString()); } else if (obj.IsBoolean) { writer.Write(obj.GetBoolean()); } else if (obj.IsDouble) { writer.Write(obj.GetDouble()); } else if (obj.IsInt) { writer.Write(obj.GetInt()); } else if (obj.IsLong) { writer.Write(obj.GetLong()); } else if (obj.IsArray) { writer.WriteArrayStart(); foreach (JsonData item in (IEnumerable)obj) { WriteJson(item, writer); } writer.WriteArrayEnd(); } else { if (!obj.IsObject) { return; } writer.WriteObjectStart(); foreach (DictionaryEntry item2 in (IDictionary)obj) { writer.WritePropertyName((string)item2.Key); WriteJson((JsonData)item2.Value, writer); } writer.WriteObjectEnd(); } } public int Add(object value) { JsonData value2 = ToJsonData(value); json = null; return EnsureList().Add(value2); } public bool Remove(object obj) { json = null; if (IsObject) { JsonData value = null; if (inst_object.TryGetValue((string)obj, out value)) { if (inst_object.Remove((string)obj)) { return object_list.Remove(new KeyValuePair<string, JsonData>((string)obj, value)); } return false; } throw new KeyNotFoundException("The specified key was not found in the JsonData object."); } if (IsArray) { return inst_array.Remove(ToJsonData(obj)); } throw new InvalidOperationException("Instance of JsonData is not an object or a list."); } public void Clear() { if (IsObject) { ((IDictionary)this).Clear(); } else if (IsArray) { ((IList)this).Clear(); } } public bool Equals(JsonData x) { if (x == null) { return false; } if (x.type != type && ((x.type != JsonType.Int && x.type != JsonType.Long) || (type != JsonType.Int && type != JsonType.Long))) { return false; } switch (type) { case JsonType.None: return true; case JsonType.Object: return inst_object.Equals(x.inst_object); case JsonType.Array: return inst_array.Equals(x.inst_array); case JsonType.String: return inst_string.Equals(x.inst_string); case JsonType.Int: if (x.IsLong) { if (x.inst_long < int.MinValue || x.inst_long > int.MaxValue) { return false; } return inst_int.Equals((int)x.inst_long); } return inst_int.Equals(x.inst_int); case JsonType.Long: if (x.IsInt) { if (inst_long < int.MinValue || inst_long > int.MaxValue) { return false; } return x.inst_int.Equals((int)inst_long); } return inst_long.Equals(x.inst_long); case JsonType.Double: return inst_double.Equals(x.inst_double); case JsonType.Boolean: return inst_boolean.Equals(x.inst_boolean); default: return false; } } public JsonType GetJsonType() { return type; } public void SetJsonType(JsonType type) { if (this.type != type) { switch (type) { case JsonType.Object: inst_object = new Dictionary<string, JsonData>(); object_list = new List<KeyValuePair<string, JsonData>>(); break; case JsonType.Array: inst_array = new List<JsonData>(); break; case JsonType.String: inst_string = null; break; case JsonType.Int: inst_int = 0; break; case JsonType.Long: inst_long = 0L; break; case JsonType.Double: inst_double = 0.0; break; case JsonType.Boolean: inst_boolean = false; break; } this.type = type; } } public string ToJson() { if (json != null) { return json; } StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter); jsonWriter.Validate = false; WriteJson(this, jsonWriter); json = stringWriter.ToString(); return json; } public void ToJson(JsonWriter writer) { bool validate = writer.Validate; writer.Validate = false; WriteJson(this, writer); writer.Validate = validate; } public override string ToString() { return type switch { JsonType.Array => "JsonData array", JsonType.Boolean => inst_boolean.ToString(), JsonType.Double => inst_double.ToString(), JsonType.Int => inst_int.ToString(), JsonType.Long => inst_long.ToString(), JsonType.Object => "JsonData object", JsonType.String => inst_string, _ => "Uninitialized JsonData", }; } } internal class OrderedDictionaryEnumerator : IDictionaryEnumerator, IEnumerator { private IEnumerator<KeyValuePair<string, JsonData>> list_enumerator; public object Current => Entry; public DictionaryEntry Entry { get { KeyValuePair<string, JsonData> current = list_enumerator.Current; return new DictionaryEntry(current.Key, current.Value); } } public object Key => list_enumerator.Current.Key; public object Value => list_enumerator.Current.Value; public OrderedDictionaryEnumerator(IEnumerator<KeyValuePair<string, JsonData>> enumerator) { list_enumerator = enumerator; } public bool MoveNext() { return list_enumerator.MoveNext(); } public void Reset() { list_enumerator.Reset(); } } public class JsonException : ApplicationException { public JsonException() { } internal JsonException(ParserToken token) : base($"Invalid token '{token}' in input string") { } internal JsonException(ParserToken token, Exception inner_exception) : base($"Invalid token '{token}' in input string", inner_exception) { } internal JsonException(int c) : base($"Invalid character '{(char)c}' in input string") { } internal JsonException(int c, Exception inner_exception) : base($"Invalid character '{(char)c}' in input string", inner_exception) { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception inner_exception) : base(message, inner_exception) { } } internal struct PropertyMetadata { public MemberInfo Info; public bool IsField; public Type Type; } internal struct ArrayMetadata { private Type element_type; private bool is_array; private bool is_list; public Type ElementType { get { if (element_type == null) { return typeof(JsonData); } return element_type; } set { element_type = value; } } public bool IsArray { get { return is_array; } set { is_array = value; } } public bool IsList { get { return is_list; } set { is_list = value; } } } internal struct ObjectMetadata { private Type element_type; private bool is_dictionary; private IDictionary<string, PropertyMetadata> properties; public Type ElementType { get { if (element_type == null) { return typeof(JsonData); } return element_type; } set { element_type = value; } } public bool IsDictionary { get { return is_dictionary; } set { is_dictionary = value; } } public IDictionary<string, PropertyMetadata> Properties { get { return properties; } set { properties = value; } } } internal delegate void ExporterFunc(object obj, JsonWriter writer); public delegate void ExporterFunc<T>(T obj, JsonWriter writer); internal delegate object ImporterFunc(object input); public delegate TValue ImporterFunc<TJson, TValue>(TJson input); public delegate IJsonWrapper WrapperFactory(); public class JsonMapper { private static readonly int max_nesting_depth; private static readonly IFormatProvider datetime_format; private static readonly IDictionary<Type, ExporterFunc> base_exporters_table; private static readonly IDictionary<Type, ExporterFunc> custom_exporters_table; private static readonly object custom_exporters_table_lock; private static readonly IDictionary<Type, IDictionary<Type, ImporterFunc>> base_importers_table; private static readonly IDictionary<Type, IDictionary<Type, ImporterFunc>> custom_importers_table; private static readonly object custom_importers_table_lock; private static readonly IDictionary<Type, ArrayMetadata> array_metadata; private static readonly object array_metadata_lock; private static readonly IDictionary<Type, IDictionary<Type, MethodInfo>> conv_ops; private static readonly object conv_ops_lock; private static readonly IDictionary<Type, ObjectMetadata> object_metadata; private static readonly object object_metadata_lock; private static readonly IDictionary<Type, IList<PropertyMetadata>> type_properties; private static readonly object type_properties_lock; private static readonly JsonWriter static_writer; private static readonly object static_writer_lock; static JsonMapper() { custom_exporters_table_lock = new object(); custom_importers_table_lock = new object(); array_metadata_lock = new object(); conv_ops_lock = new object(); object_metadata_lock = new object(); type_properties_lock = new object(); static_writer_lock = new object(); max_nesting_depth = 100; array_metadata = new Dictionary<Type, ArrayMetadata>(); conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>>(); object_metadata = new Dictionary<Type, ObjectMetadata>(); type_properties = new Dictionary<Type, IList<PropertyMetadata>>(); static_writer = new JsonWriter(); datetime_format = DateTimeFormatInfo.InvariantInfo; base_exporters_table = new Dictionary<Type, ExporterFunc>(); custom_exporters_table = new Dictionary<Type, ExporterFunc>(); base_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>(); custom_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>(); RegisterBaseExporters(); RegisterBaseImporters(); } private static void AddArrayMetadata(Type type) { if (array_metadata.ContainsKey(type)) { return; } ArrayMetadata value = default(ArrayMetadata); value.IsArray = type.IsArray; if (type.GetInterface("System.Collections.IList") != null) { value.IsList = true; } PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name != "Item")) { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(int)) { value.ElementType = propertyInfo.PropertyType; } } } lock (array_metadata_lock) { try { array_metadata.Add(type, value); } catch (ArgumentException) { } } } private static void AddObjectMetadata(Type type) { if (object_metadata.ContainsKey(type)) { return; } ObjectMetadata value = default(ObjectMetadata); if (type.GetInterface("System.Collections.IDictionary") != null) { value.IsDictionary = true; } value.Properties = new Dictionary<string, PropertyMetadata>(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.Name == "Item") { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(string)) { value.ElementType = propertyInfo.PropertyType; } } else { PropertyMetadata value2 = default(PropertyMetadata); value2.Info = propertyInfo; value2.Type = propertyInfo.PropertyType; value.Properties.Add(propertyInfo.Name, value2); } } FieldInfo[] fields = type.GetFields(); foreach (FieldInfo fieldInfo in fields) { PropertyMetadata value3 = default(PropertyMetadata); value3.Info = fieldInfo; value3.IsField = true; value3.Type = fieldInfo.FieldType; value.Properties.Add(fieldInfo.Name, value3); } lock (object_metadata_lock) { try { object_metadata.Add(type, value); } catch (ArgumentException) { } } } private static void AddTypeProperties(Type type) { if (type_properties.ContainsKey(type)) { return; } IList<PropertyMetadata> list = new List<PropertyMetadata>(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name == "Item")) { PropertyMetadata item = default(PropertyMetadata); item.Info = propertyInfo; item.IsField = false; list.Add(item); } } FieldInfo[] fields = type.GetFields(); foreach (FieldInfo info in fields) { PropertyMetadata item2 = default(PropertyMetadata); item2.Info = info; item2.IsField = true; list.Add(item2); } lock (type_properties_lock) { try { type_properties.Add(type, list); } catch (ArgumentException) { } } } private static MethodInfo GetConvOp(Type t1, Type t2) { lock (conv_ops_lock) { if (!conv_ops.ContainsKey(t1)) { conv_ops.Add(t1, new Dictionary<Type, MethodInfo>()); } } if (conv_ops[t1].ContainsKey(t2)) { return conv_ops[t1][t2]; } MethodInfo method = t1.GetMethod("op_Implicit", new Type[1] { t2 }); lock (conv_ops_lock) { try { conv_ops[t1].Add(t2, method); return method; } catch (ArgumentException) { return conv_ops[t1][t2]; } } } private static object ReadValue(Type inst_type, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd) { return null; } Type underlyingType = Nullable.GetUnderlyingType(inst_type); Type type = underlyingType ?? inst_type; if (reader.Token == JsonToken.Null) { if (inst_type.IsClass || underlyingType != null) { return null; } throw new JsonException($"Can't assign null to an instance of type {inst_type}"); } if (reader.Token == JsonToken.Double || reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean) { Type type2 = reader.Value.GetType(); if (type.IsAssignableFrom(type2)) { return reader.Value; } lock (custom_importers_table_lock) { if (custom_importers_table.TryGetValue(type2, out var value) && value.TryGetValue(type, out var value2)) { return value2(reader.Value); } } if (base_importers_table.TryGetValue(type2, out var value3) && value3.TryGetValue(type, out var value4)) { return value4(reader.Value); } if (type.IsEnum) { return Enum.ToObject(type, reader.Value); } MethodInfo convOp = GetConvOp(type, type2); if (convOp != null) { return convOp.Invoke(null, new object[1] { reader.Value }); } throw new JsonException($"Can't assign value '{reader.Value}' (type {type2}) to type {inst_type}"); } object obj = null; if (reader.Token == JsonToken.ArrayStart) { AddArrayMetadata(inst_type); ArrayMetadata arrayMetadata = array_metadata[inst_type]; if (!arrayMetadata.IsArray && !arrayMetadata.IsList) { throw new JsonException($"Type {inst_type} can't act as an array"); } IList list; Type elementType; if (!arrayMetadata.IsArray) { list = (IList)Activator.CreateInstance(inst_type); elementType = arrayMetadata.ElementType; } else { list = new ArrayList(); elementType = inst_type.GetElementType(); } list.Clear(); while (true) { object obj2 = ReadValue(elementType, reader); if (obj2 == null && reader.Token == JsonToken.ArrayEnd) { break; } list.Add(obj2); } if (arrayMetadata.IsArray) { int count = list.Count; obj = Array.CreateInstance(elementType, count); for (int i = 0; i < count; i++) { ((Array)obj).SetValue(list[i], i); } } else { obj = list; } } else if (reader.Token == JsonToken.ObjectStart) { AddObjectMetadata(type); ObjectMetadata objectMetadata = object_metadata[type]; obj = Activator.CreateInstance(type); while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } string text = (string)reader.Value; if (objectMetadata.Properties.ContainsKey(text)) { PropertyMetadata propertyMetadata = objectMetadata.Properties[text]; if (propertyMetadata.IsField) { ((FieldInfo)propertyMetadata.Info).SetValue(obj, ReadValue(propertyMetadata.Type, reader)); continue; } PropertyInfo propertyInfo = (PropertyInfo)propertyMetadata.Info; if (propertyInfo.CanWrite) { propertyInfo.SetValue(obj, ReadValue(propertyMetadata.Type, reader), null); } else { ReadValue(propertyMetadata.Type, reader); } } else if (!objectMetadata.IsDictionary) { if (!reader.SkipNonMembers) { throw new JsonException($"The type {inst_type} doesn't have the property '{text}'"); } ReadSkip(reader); } else { ((IDictionary)obj).Add(text, ReadValue(objectMetadata.ElementType, reader)); } } } return obj; } private static IJsonWrapper ReadValue(WrapperFactory factory, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd || reader.Token == JsonToken.Null) { return null; } IJsonWrapper jsonWrapper = factory(); if (reader.Token == JsonToken.String) { jsonWrapper.SetString((string)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Double) { jsonWrapper.SetDouble((double)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Int) { jsonWrapper.SetInt((int)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Long) { jsonWrapper.SetLong((long)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Boolean) { jsonWrapper.SetBoolean((bool)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.ArrayStart) { jsonWrapper.SetJsonType(JsonType.Array); while (true) { IJsonWrapper jsonWrapper2 = ReadValue(factory, reader); if (jsonWrapper2 == null && reader.Token == JsonToken.ArrayEnd) { break; } jsonWrapper.Add(jsonWrapper2); } } else if (reader.Token == JsonToken.ObjectStart) { jsonWrapper.SetJsonType(JsonType.Object); while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } string key = (string)reader.Value; jsonWrapper[key] = ReadValue(factory, reader); } } return jsonWrapper; } private static void ReadSkip(JsonReader reader) { ToWrapper(() => new JsonMockWrapper(), reader); } private static void RegisterBaseExporters() { base_exporters_table[typeof(byte)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((byte)obj)); }; base_exporters_table[typeof(char)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToString((char)obj)); }; base_exporters_table[typeof(DateTime)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToString((DateTime)obj, datetime_format)); }; base_exporters_table[typeof(decimal)] = delegate(object obj, JsonWriter writer) { writer.Write((decimal)obj); }; base_exporters_table[typeof(sbyte)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((sbyte)obj)); }; base_exporters_table[typeof(short)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((short)obj)); }; base_exporters_table[typeof(ushort)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((ushort)obj)); }; base_exporters_table[typeof(uint)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToUInt64((uint)obj)); }; base_exporters_table[typeof(ulong)] = delegate(object obj, JsonWriter writer) { writer.Write((ulong)obj); }; base_exporters_table[typeof(DateTimeOffset)] = delegate(object obj, JsonWriter writer) { writer.Write(((DateTimeOffset)obj).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz", datetime_format)); }; } private static void RegisterBaseImporters() { ImporterFunc importer = (object input) => Convert.ToByte((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(byte), importer); importer = (object input) => Convert.ToUInt64((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(ulong), importer); importer = (object input) => Convert.ToInt64((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(long), importer); importer = (object input) => Convert.ToSByte((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(sbyte), importer); importer = (object input) => Convert.ToInt16((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(short), importer); importer = (object input) => Convert.ToUInt16((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(ushort), importer); importer = (object input) => Convert.ToUInt32((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(uint), importer); importer = (object input) => Convert.ToSingle((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(float), importer); importer = (object input) => Convert.ToDouble((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(double), importer); importer = (object input) => Convert.ToDecimal((double)input); RegisterImporter(base_importers_table, typeof(double), typeof(decimal), importer); importer = (object input) => Convert.ToSingle((double)input); RegisterImporter(base_importers_table, typeof(double), typeof(float), importer); importer = (object input) => Convert.ToUInt32((long)input); RegisterImporter(base_importers_table, typeof(long), typeof(uint), importer); importer = (object input) => Convert.ToChar((string)input); RegisterImporter(base_importers_table, typeof(string), typeof(char), importer); importer = (object input) => Convert.ToDateTime((string)input, datetime_format); RegisterImporter(base_importers_table, typeof(string), typeof(DateTime), importer); importer = (object input) => DateTimeOffset.Parse((string)input, datetime_format); RegisterImporter(base_importers_table, typeof(string), typeof(DateTimeOffset), importer); } private static void RegisterImporter(IDictionary<Type, IDictionary<Type, ImporterFunc>> table, Type json_type, Type value_type, ImporterFunc importer) { if (!table.ContainsKey(json_type)) { table.Add(json_type, new Dictionary<Type, ImporterFunc>()); } table[json_type][value_type] = importer; } private static void WriteValue(object obj, JsonWriter writer, bool writer_is_private, int depth) { if (depth > max_nesting_depth) { throw new JsonException($"Max allowed object depth reached while trying to export from type {obj.GetType()}"); } if (obj == null) { writer.Write(null); return; } if (obj is IJsonWrapper) { if (writer_is_private) { writer.TextWriter.Write(((IJsonWrapper)obj).ToJson()); } else { ((IJsonWrapper)obj).ToJson(writer); } return; } if (obj is string) { writer.Write((string)obj); return; } if (obj is double) { writer.Write((double)obj); return; } if (obj is float) { writer.Write((float)obj); return; } if (obj is int) { writer.Write((int)obj); return; } if (obj is bool) { writer.Write((bool)obj); return; } if (obj is long) { writer.Write((long)obj); return; } if (obj is Array) { writer.WriteArrayStart(); foreach (object item in (Array)obj) { WriteValue(item, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IList) { writer.WriteArrayStart(); foreach (object item2 in (IList)obj) { WriteValue(item2, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IDictionary dictionary) { writer.WriteObjectStart(); foreach (DictionaryEntry item3 in dictionary) { string property_name = ((item3.Key is string text) ? text : Convert.ToString(item3.Key, CultureInfo.InvariantCulture)); writer.WritePropertyName(property_name); WriteValue(item3.Value, writer, writer_is_private, depth + 1); } writer.WriteObjectEnd(); return; } Type type = obj.GetType(); lock (custom_exporters_table_lock) { if (custom_exporters_table.TryGetValue(type, out var value)) { value(obj, writer); return; } } if (base_exporters_table.TryGetValue(type, out var value2)) { value2(obj, writer); return; } if (obj is Enum) { Type underlyingType = Enum.GetUnderlyingType(type); if (underlyingType == typeof(long)) { writer.Write((long)obj); } else if (underlyingType == typeof(uint)) { writer.Write((uint)obj); } else if (underlyingType == typeof(ulong)) { writer.Write((ulong)obj); } else if (underlyingType == typeof(ushort)) { writer.Write((ushort)obj); } else if (underlyingType == typeof(short)) { writer.Write((short)obj); } else if (underlyingType == typeof(byte)) { writer.Write((byte)obj); } else if (underlyingType == typeof(sbyte)) { writer.Write((sbyte)obj); } else { writer.Write((int)obj); } return; } AddTypeProperties(type); IList<PropertyMetadata> list = type_properties[type]; writer.WriteObjectStart(); foreach (PropertyMetadata item4 in list) { if (item4.IsField) { writer.WritePropertyName(item4.Info.Name); WriteValue(((FieldInfo)item4.Info).GetValue(obj), writer, writer_is_private, depth + 1); continue; } PropertyInfo propertyInfo = (PropertyInfo)item4.Info; if (propertyInfo.CanRead) { writer.WritePropertyName(item4.Info.Name); WriteValue(propertyInfo.GetValue(obj, null), writer, writer_is_private, depth + 1); } } writer.WriteObjectEnd(); } public static string ToJson(object obj) { lock (static_writer_lock) { static_writer.Reset(); WriteValue(obj, static_writer, writer_is_private: true, 0); return static_writer.ToString(); } } public static void ToJson(object obj, JsonWriter writer) { WriteValue(obj, writer, writer_is_private: false, 0); } public static JsonData ToObject(JsonReader reader) { return (JsonData)ToWrapper(() => new JsonData(), reader); } public static JsonData ToObject(TextReader reader) { JsonReader reader2 = new JsonReader(reader); return (JsonData)ToWrapper(() => new JsonData(), reader2); } public static JsonData ToObject(string json) { return (JsonData)ToWrapper(() => new JsonData(), json); } public static T ToObject<T>(JsonReader reader) { return (T)ReadValue(typeof(T), reader); } public static T ToObject<T>(TextReader reader) { JsonReader reader2 = new JsonReader(reader); return (T)ReadValue(typeof(T), reader2); } public static T ToObject<T>(string json) { JsonReader reader = new JsonReader(json); return (T)ReadValue(typeof(T), reader); } public static object ToObject(string json, Type ConvertType) { JsonReader reader = new JsonReader(json); return ReadValue(ConvertType, reader); } public static IJsonWrapper ToWrapper(WrapperFactory factory, JsonReader reader) { return ReadValue(factory, reader); } public static IJsonWrapper ToWrapper(WrapperFactory factory, string json) { JsonReader reader = new JsonReader(json); return ReadValue(factory, reader); } public static void RegisterExporter<T>(ExporterFunc<T> exporter) { ExporterFunc value = delegate(object obj, JsonWriter writer) { exporter((T)obj, writer); }; lock (custom_exporters_table_lock) { custom_exporters_table[typeof(T)] = value; } } public static void RegisterImporter<TJson, TValue>(ImporterFunc<TJson, TValue> importer) { ImporterFunc importer2 = (object input) => importer((TJson)input); lock (custom_importers_table_lock) { RegisterImporter(custom_importers_table, typeof(TJson), typeof(TValue), importer2); } } public static void UnregisterExporters() { lock (custom_exporters_table_lock) { custom_exporters_table.Clear(); } } public static void UnregisterImporters() { lock (custom_importers_table_lock) { custom_importers_table.Clear(); } } } public class JsonMockWrapper : IJsonWrapper, IList, ICollection, IEnumerable, IOrderedDictionary, IDictionary { public bool IsArray => false; public bool IsBoolean => false; public bool IsDouble => false; public bool IsInt => false; public bool IsLong => false; public bool IsObject => false; public bool IsString => false; bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; object IList.this[int index] { get { return null; } set { } } int ICollection.Count => 0; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => null; bool IDictionary.IsFixedSize => true; bool IDictionary.IsReadOnly => true; ICollection IDictionary.Keys => null; ICollection IDictionary.Values => null; object IDictionary.this[object key] { get { return null; } set { } } object IOrderedDictionary.this[int idx] { get { return null; } set { } } public bool GetBoolean() { return false; } public double GetDouble() { return 0.0; } public int GetInt() { return 0; } public JsonType GetJsonType() { return JsonType.None; } public long GetLong() { return 0L; } public string GetString() { return ""; } public void SetBoolean(bool val) { } public void SetDouble(double val) { } public void SetInt(int val) { } public void SetJsonType(JsonType type) { } public void SetLong(long val) { } public void SetString(string val) { } public string ToJson() { return ""; } public void ToJson(JsonWriter writer) { } int IList.Add(object value) { return 0; } void IList.Clear() { } bool IList.Contains(object value) { return false; } int IList.IndexOf(object value) { return -1; } void IList.Insert(int i, object v) { } void IList.Remove(object value) { } void IList.RemoveAt(int index) { } void ICollection.CopyTo(Array array, int index) { } IEnumerator IEnumerable.GetEnumerator() { return null; } void IDictionary.Add(object k, object v) { } void IDictionary.Clear() { } bool IDictionary.Contains(object key) { return false; } void IDictionary.Remove(object key) { } IDictionaryEnumerator IDictionary.GetEnumerator() { return null; } IDictionaryEnumerator IOrderedDictionary.GetEnumerator() { return null; } void IOrderedDictionary.Insert(int i, object k, object v) { } void IOrderedDictionary.RemoveAt(int i) { } } public enum JsonToken { None, ObjectStart, PropertyName, ObjectEnd, ArrayStart, ArrayEnd, Int, Long, Double, String, Boolean, Null } public class JsonReader { private static readonly IDictionary<int, IDictionary<int, int[]>> parse_table; private Stack<int> automaton_stack; private int current_input; private int current_symbol; private bool end_of_json; private bool end_of_input; private Lexer lexer; private bool parser_in_string; private bool parser_return; private bool read_started; private TextReader reader; private bool reader_is_owned; private bool skip_non_members; private object token_value; private JsonToken token; public bool AllowComments { get { return lexer.AllowComments; } set { lexer.AllowComments = value; } } public bool AllowSingleQuotedStrings { get { return lexer.AllowSingleQuotedStrings; } set { lexer.AllowSingleQuotedStrings = value; } } public bool SkipNonMembers { get { return skip_non_members; } set { skip_non_members = value; } } public bool EndOfInput => end_of_input; public bool EndOfJson => end_of_json; public JsonToken Token => token; public object Value => token_value; static JsonReader() { parse_table = PopulateParseTable(); } public JsonReader(string json_text) : this(new StringReader(json_text), owned: true) { } public JsonReader(TextReader reader) : this(reader, owned: false) { } private JsonReader(TextReader reader, bool owned) { if (reader == null) { throw new ArgumentNullException("reader"); } parser_in_string = false; parser_return = false; read_started = false; automaton_stack = new Stack<int>(); automaton_stack.Push(65553); automaton_stack.Push(65543); lexer = new Lexer(reader); end_of_input = false; end_of_json = false; skip_non_members = true; this.reader = reader; reader_is_owned = owned; } private static IDictionary<int, IDictionary<int, int[]>> PopulateParseTable() { IDictionary<int, IDictionary<int, int[]>> result = new Dictionary<int, IDictionary<int, int[]>>(); TableAddRow(result, ParserToken.Array); TableAddCol(result, ParserToken.Array, 91, 91, 65549); TableAddRow(result, ParserToken.ArrayPrime); TableAddCol(result, ParserToken.ArrayPrime, 34, 65550, 65551, 93); TableAddCol(result, ParserToken.ArrayPrime, 91, 65550, 65551, 93); TableAddCol(result, ParserToken.ArrayPrime, 93, 93); TableAddCol(result, ParserToken.ArrayPrime, 123, 65550, 65551, 93); TableAddCol(result, ParserToken.ArrayPrime, 65537, 65550, 65551, 93); TableAddCol(result, ParserToken.ArrayPrime, 65538, 65550, 65551, 93); TableAddCol(result, ParserToken.ArrayPrime, 65539, 65550, 65551, 93); TableAddCol(result, ParserToken.ArrayPrime, 65540, 65550, 65551, 93); TableAddRow(result, ParserToken.Object); TableAddCol(result, ParserToken.Object, 123, 123, 65545); TableAddRow(result, ParserToken.ObjectPrime); TableAddCol(result, ParserToken.ObjectPrime, 34, 65546, 65547, 125); TableAddCol(result, ParserToken.ObjectPrime, 125, 125); TableAddRow(result, ParserToken.Pair); TableAddCol(result, ParserToken.Pair, 34, 65552, 58, 65550); TableAddRow(result, ParserToken.PairRest); TableAddCol(result, ParserToken.PairRest, 44, 44, 65546, 65547); TableAddCol(result, ParserToken.PairRest, 125, 65554); TableAddRow(result, ParserToken.String); TableAddCol(result, ParserToken.String, 34, 34, 65541, 34); TableAddRow(result, ParserToken.Text); TableAddCol(result, ParserToken.Text, 91, 65548); TableAddCol(result, ParserToken.Text, 123, 65544); TableAddRow(result, ParserToken.Value); TableAddCol(result, ParserToken.Value, 34, 65552); TableAddCol(result, ParserToken.Value, 91, 65548); TableAddCol(result, ParserToken.Value, 123, 65544); TableAddCol(result, ParserToken.Value, 65537, 65537); TableAddCol(result, ParserToken.Value, 65538, 65538); TableAddCol(result, ParserToken.Value, 65539, 65539); TableAddCol(result, ParserToken.Value, 65540, 65540); TableAddRow(result, ParserToken.ValueRest); TableAddCol(result, ParserToken.ValueRest, 44, 44, 65550, 65551); TableAddCol(result, ParserToken.ValueRest, 93, 65554); return result; } private static void TableAddCol(IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken row, int col, params int[] symbols) { parse_table[(int)row].Add(col, symbols); } private static void TableAddRow(IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken rule) { parse_table.Add((int)rule, new Dictionary<int, int[]>()); } private void ProcessNumber(string number) { int result2; long result3; ulong result4; if ((number.IndexOf('.') != -1 || number.IndexOf('e') != -1 || number.IndexOf('E') != -1) && double.TryParse(number, NumberStyles.Any, CultureInfo.InvariantCulture, out var result)) { token = JsonToken.Double; token_value = result; } else if (int.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2)) { token = JsonToken.Int; token_value = result2; } else if (long.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out result3)) { token = JsonToken.Long; token_value = result3; } else if (ulong.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out result4)) { token = JsonToken.Long; token_value = result4; } else { token = JsonToken.Int; token_value = 0; } } private void ProcessSymbol() { if (current_symbol == 91) { token = JsonToken.ArrayStart; parser_return = true; } else if (current_symbol == 93) { token = JsonToken.ArrayEnd; parser_return = true; } else if (current_symbol == 123) { token = JsonToken.ObjectStart; parser_return = true; } else if (current_symbol == 125) { token = JsonToken.ObjectEnd; parser_return = true; } else if (current_symbol == 34) { if (parser_in_string) { parser_in_string = false; parser_return = true; return; } if (token == JsonToken.None) { token = JsonToken.String; } parser_in_string = true; } else if (current_symbol == 65541) { token_value = lexer.StringValue; } else if (current_symbol == 65539) { token = JsonToken.Boolean; token_value = false; parser_return = true; } else if (current_symbol == 65540) { token = JsonToken.Null; parser_return = true; } else if (current_symbol == 65537) { ProcessNumber(lexer.StringValue); parser_return = true; } else if (current_symbol == 65546) { token = JsonToken.PropertyName; } else if (current_symbol == 65538) { token = JsonToken.Boolean; token_value = true; parser_return = true; } } private bool ReadToken() { if (end_of_input) { return false; } lexer.NextToken(); if (lexer.EndOfInput) { Close(); return false; } current_input = lexer.Token; return true; } public void Close() { if (end_of_input) { return; } end_of_input = true; end_of_json = true; if (reader_is_owned) { using (reader) { } } reader = null; } public bool Read() { if (end_of_input) { return false; } if (end_of_json) { end_of_json = false; automaton_stack.Clear(); automaton_stack.Push(65553); automaton_stack.Push(65543); } parser_in_string = false; parser_return = false; token = JsonToken.None; token_value = null; if (!read_started) { read_started = true; if (!ReadToken()) { return false; } } while (true) { if (parser_return) { if (automaton_stack.Peek() == 65553) { end_of_json = true; } return true; } current_symbol = automaton_stack.Pop(); ProcessSymbol(); if (current_symbol == current_input) { if (!ReadToken()) { break; } continue; } int[] array; try { array = parse_table[current_symbol][current_input]; } catch (KeyNotFoundException inner_exception) { throw new JsonException((ParserToken)current_input, inner_exception); } if (array[0] != 65554) { for (int num = array.Length - 1; num >= 0; num--) { automaton_stack.Push(array[num]); } } } if (automaton_stack.Peek() != 65553) { throw new JsonException("Input doesn't evaluate to proper JSON text"); } if (parser_return) { return true; } return false; } } internal enum Condition { InArray, InObject, NotAProperty, Property, Value } internal class WriterContext { public int Count; public bool InArray; public bool InObject; public bool ExpectingValue; public int Padding; } public class JsonWriter { private static readonly NumberFormatInfo number_format; private WriterContext context; private Stack<WriterContext> ctx_stack; private bool has_reached_end; private char[] hex_seq; private int indentation; private int indent_value; private StringBuilder inst_string_builder; private bool pretty_print; private bool validate; private bool lower_case_properties; private TextWriter writer; public int IndentValue { get { return indent_value; } set { indentation = indentation / indent_value * value; indent_value = value; } } public bool PrettyPrint { get { return pretty_print; } set { pretty_print = value; } } public TextWriter TextWriter => writer; public bool Validate { get { return validate; } set { validate = value; } } public bool LowerCaseProperties { get { return lower_case_properties; } set { lower_case_properties = value; } } static JsonWriter() { number_format = NumberFormatInfo.InvariantInfo; } public JsonWriter() { inst_string_builder = new StringBuilder(); writer = new StringWriter(inst_string_builder); Init(); } public JsonWriter(StringBuilder sb) : this(new StringWriter(sb)) { } public JsonWriter(TextWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } this.writer = writer; Init(); } private void DoValidation(Condition cond) { if (!context.ExpectingValue) { context.Count++; } if (!validate) { return; } if (has_reached_end) { throw new JsonException("A complete JSON symbol has already been written"); } switch (cond) { case Condition.InArray: if (!context.InArray) { throw new JsonException("Can't close an array here"); } break; case Condition.InObject: if (!context.InObject || context.ExpectingValue) { throw new JsonException("Can't close an object here"); } break; case Condition.NotAProperty: if (context.InObject && !context.ExpectingValue) { throw new JsonException("Expected a property"); } break; case Condition.Property: if (!context.InObject || context.ExpectingValue) { throw new JsonException("Can't add a property here"); } break; case Condition.Value: if (!context.InArray && (!context.InObject || !context.ExpectingValue)) { throw new JsonException("Can't add a value here"); } break; } } private void Init() { has_reached_end = false; hex_seq = new char[4]; indentation = 0; indent_value = 4; pretty_print = false; validate = true; lower_case_properties = false; ctx_stack = new Stack<WriterContext>(); context = new WriterContext(); ctx_stack.Push(context); } private static void IntToHex(int n, char[] hex) { for (int i = 0; i < 4; i++) { int num = n % 16; if (num < 10) { hex[3 - i] = (char)(48 + num); } else { hex[3 - i] = (char)(65 + (num - 10)); } n >>= 4; } } private void Indent() { if (pretty_print) { indentation += indent_value; } } private void Put(string str) { if (pretty_print && !context.ExpectingValue) { for (int i = 0; i < indentation; i++) { writer.Write(' '); } } writer.Write(str); } private void PutNewline() { PutNewline(add_comma: true); } private void PutNewline(bool add_comma) { if (add_comma && !context.ExpectingValue && context.Count > 1) { writer.Write(','); } if (pretty_print && !context.ExpectingValue) { writer.Write(Environment.NewLine); } } private void PutString(string str) { Put(string.Empty); writer.Write('"'); int length = str.Length; for (int i = 0; i < length; i++) { switch (str[i]) { case '\n': writer.Write("\\n"); continue; case '\r': writer.Write("\\r"); continue; case '\t': writer.Write("\\t"); continue; case '"': case '\\': writer.Write('\\'); writer.Write(str[i]); continue; case '\f': writer.Write("\\f"); continue; case '\b': writer.Write("\\b"); continue; } if (str[i] >= ' ' && str[i] <= '~') { writer.Write(str[i]); continue; } IntToHex(str[i], hex_seq); writer.Write("\\u"); writer.Write(hex_seq); } writer.Write('"'); } private void Unindent() { if (pretty_print) { indentation -= indent_value; } } public override string ToString() { if (inst_string_builder == null) { return string.Empty; } return inst_string_builder.ToString(); } public void Reset() { has_reached_end = false; ctx_stack.Clear(); context = new WriterContext(); ctx_stack.Push(context); if (inst_string_builder != null) { inst_string_builder.Remove(0, inst_string_builder.Length); } } public void Write(bool boolean) { DoValidation(Condition.Value); PutNewline(); Put(boolean ? "true" : "false"); context.ExpectingValue = false; } public void Write(decimal number) { DoValidation(Condition.Value); PutNewline(); Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } public void Write(double number) { DoValidation(Condition.Value); PutNewline(); string text = Convert.ToString(number, number_format); Put(text); if (text.IndexOf('.') == -1 && text.IndexOf('E') == -1) { writer.Write(".0"); } context.ExpectingValue = false; } public void Write(float number) { DoValidation(Condition.Value); PutNewline(); string str = Convert.ToString(number, number_format); Put(str); context.ExpectingValue = false; } public void Write(int number) { DoValidation(Condition.Value); PutNewline(); Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } public void Write(long number) { DoValidation(Condition.Value); PutNewline(); Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } public void Write(string str) { DoValidation(Condition.Value); PutNewline(); if (str == null) { Put("null"); } else { PutString(str); } context.ExpectingValue = false; } [CLSCompliant(false)] public void Write(ulong number) { DoValidation(Condition.Value); PutNewline(); Put(Convert.ToString(number, number_format)); context.ExpectingValue = false; } public void WriteArrayEnd() { DoValidation(Condition.InArray); PutNewline(add_comma: false); ctx_stack.Pop(); if (ctx_stack.Count == 1) { has_reached_end = true; } else { context = ctx_stack.Peek(); context.ExpectingValue = false; } Unindent(); Put("]"); } public void WriteArrayStart() { DoValidation(Condition.NotAProperty); PutNewline(); Put("["); context = new WriterContext(); context.InArray = true; ctx_stack.Push(context); Indent(); } public void WriteObjectEnd() { DoValidation(Condition.InObject); PutNewline(add_comma: false); ctx_stack.Pop(); if (ctx_stack.Count == 1) { has_reached_end = true; } else { context = ctx_stack.Peek(); context.ExpectingValue = false; } Unindent(); Put("}"); } public void WriteObjectStart() { DoValidation(Condition.NotAProperty); PutNewline(); Put("{"); context = new WriterContext(); context.InObject = true; ctx_stack.Push(context); Indent(); } public void WritePropertyName(string property_name) { DoValidation(Condition.Property); PutNewline(); string text = ((property_name == null || !lower_case_properties) ? property_name : property_name.ToLowerInvariant()); PutString(text); if (pretty_print) { if (text.Length > context.Padding) { context.Padding = text.Length; } for (int num = context.Padding - text.Length; num >= 0; num--) { writer.Write(' '); } writer.Write(": "); } else { writer.Write(':'); } context.ExpectingValue = true; } } internal class FsmContext { public bool Return; public int NextState; public Lexer L; public int StateStack; } internal class Lexer { private delegate bool StateHandler(FsmContext ctx); private static readonly int[] fsm_return_table; private static readonly StateHandler[] fsm_handler_table; private bool allow_comments; private bool allow_single_quoted_strings; private bool end_of_input; private FsmContext fsm_context; private int input_buffer; private int input_char; private TextReader reader; private int state; private StringBuilder string_buffer; private string string_value; private int token; private int unichar; public bool AllowComments { get { return allow_comments; } set { allow_comments = value; } } public bool AllowSingleQuotedStrings { get { return allow_single_quoted_strings; } set { allow_single_quoted_strings = value; } } public bool EndOfInput => end_of_input; public int Token => token; public string StringValue => string_value; static Lexer() { PopulateFsmTables(out fsm_handler_table, out fsm_return_table); } public Lexer(TextReader reader) { allow_comments = true; allow_single_quoted_strings = true; input_buffer = 0; string_buffer = new StringBuilder(128); state = 1; end_of_input = false; this.reader = reader; fsm_context = new FsmContext(); fsm_context.L = this; } private static int HexValue(int digit) { switch (digit) { case 65: case 97: return 10; case 66: case 98: return 11; case 67: case 99: return 12; case 68: case 100: return 13; case 69: case 101: return 14; case 70: case 102: return 15; default: return digit - 48; } } private static void PopulateFsmTables(out StateHandler[] fsm_handler_table, out int[] fsm_return_table) { fsm_handler_table = new StateHandler[28] { State1, State2, State3, State4, State5, State6, State7, State8, State9, State10, State11, State12, State13, State14, State15, State16, State17, State18, State19, State20, State21, State22, State23, State24, State25, State26, State27, State28 }; fsm_return_table = new int[28] { 65542, 0, 65537, 65537, 0, 65537, 0, 65537, 0, 0, 65538, 0, 0, 0, 65539, 0, 0, 65540, 65541, 65542, 0, 0, 65541, 65542, 0, 0, 0, 0 }; } private static char ProcessEscChar(int esc_char) { switch (esc_char) { case 34: case 39: case 47: case 92: return Convert.ToChar(esc_char); case 110: return '\n'; case 116: return '\t'; case 114: return '\r'; case 98: return '\b'; case 102: return '\f'; default: return '?'; } } private static bool State1(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char == 32 || (ctx.L.input_char >= 9 && ctx.L.input_char <= 13)) { continue; } if (ctx.L.input_char >= 49 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 3; return true; } switch (ctx.L.input_char) { case 34: ctx.NextState = 19; ctx.Return = true; return true; case 44: case 58: case 91: case 93: case 123: case 125: ctx.NextState = 1; ctx.Return = true; return true; case 45: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 2; return true; case 48: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 4; return true; case 102: ctx.NextState = 12; return true; case 110: ctx.NextState = 16; return true; case 116: ctx.NextState = 9; return true; case 39: if (!ctx.L.allow_single_quoted_strings) { return false; } ctx.L.input_char = 34; ctx.NextState = 23; ctx.Return = true; return true; case 47: if (!ctx.L.allow_comments) { return false; } ctx.NextState = 25; return true; default: return false; } } return true; } private static bool State2(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char >= 49 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 3; return true; } if (ctx.L.input_char == 48) { ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 4; return true; } return false; } private static bool State3(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char >= 48 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); continue; } if (ctx.L.input_char == 32 || (ctx.L.input_char >= 9 && ctx.L.input_char <= 13)) { ctx.Return = true; ctx.NextState = 1; return true; } switch (ctx.L.input_char) { case 44: case 93: case 125: ctx.L.UngetChar(); ctx.Return = true; ctx.NextState = 1; return true; case 46: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 5; return true; case 69: case 101: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 7; return true; default: return false; } } return true; } private static bool State4(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 32 || (ctx.L.input_char >= 9 && ctx.L.input_char <= 13)) { ctx.Return = true; ctx.NextState = 1; return true; } switch (ctx.L.input_char) { case 44: case 93: case 125: ctx.L.UngetChar(); ctx.Return = true; ctx.NextState = 1; return true; case 46: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 5; return true; case 69: case 101: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 7; return true; default: return false; } } private static bool State5(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char >= 48 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 6; return true; } return false; } private static bool State6(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char >= 48 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); continue; } if (ctx.L.input_char == 32 || (ctx.L.input_char >= 9 && ctx.L.input_char <= 13)) { ctx.Return = true; ctx.NextState = 1; return true; } switch (ctx.L.input_char) { case 44: case 93: case 125: ctx.L.UngetChar(); ctx.Return = true; ctx.NextState = 1; return true; case 69: case 101: ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 7; return true; default: return false; } } return true; } private static bool State7(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char >= 48 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 8; return true; } int num = ctx.L.input_char; if (num == 43 || num == 45) { ctx.L.string_buffer.Append((char)ctx.L.input_char); ctx.NextState = 8; return true; } return false; } private static bool State8(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char >= 48 && ctx.L.input_char <= 57) { ctx.L.string_buffer.Append((char)ctx.L.input_char); continue; } if (ctx.L.input_char == 32 || (ctx.L.input_char >= 9 && ctx.L.input_char <= 13)) { ctx.Return = true; ctx.NextState = 1; return true; } int num = ctx.L.input_char; if (num == 44 || num == 93 || num == 125) { ctx.L.UngetChar(); ctx.Return = true; ctx.NextState = 1; return true; } return false; } return true; } private static bool State9(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 114) { ctx.NextState = 10; return true; } return false; } private static bool State10(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 117) { ctx.NextState = 11; return true; } return false; } private static bool State11(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 101) { ctx.Return = true; ctx.NextState = 1; return true; } return false; } private static bool State12(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 97) { ctx.NextState = 13; return true; } return false; } private static bool State13(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 108) { ctx.NextState = 14; return true; } return false; } private static bool State14(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 115) { ctx.NextState = 15; return true; } return false; } private static bool State15(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 101) { ctx.Return = true; ctx.NextState = 1; return true; } return false; } private static bool State16(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 117) { ctx.NextState = 17; return true; } return false; } private static bool State17(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 108) { ctx.NextState = 18; return true; } return false; } private static bool State18(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 108) { ctx.Return = true; ctx.NextState = 1; return true; } return false; } private static bool State19(FsmContext ctx) { while (ctx.L.GetChar()) { switch (ctx.L.input_char) { case 34: ctx.L.UngetChar(); ctx.Return = true; ctx.NextState = 20; return true; case 92: ctx.StateStack = 19; ctx.NextState = 21; return true; } ctx.L.string_buffer.Append((char)ctx.L.input_char); } return true; } private static bool State20(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 34) { ctx.Return = true; ctx.NextState = 1; return true; } return false; } private static bool State21(FsmContext ctx) { ctx.L.GetChar(); switch (ctx.L.input_char) { case 117: ctx.NextState = 22; return true; case 34: case 39: case 47: case 92: case 98: case 102: case 110: case 114: case 116: ctx.L.string_buffer.Append(ProcessEscChar(ctx.L.input_char)); ctx.NextState = ctx.StateStack; return true; default: return false; } } private static bool State22(FsmContext ctx) { int num = 0; int num2 = 4096; ctx.L.unichar = 0; while (ctx.L.GetChar()) { if ((ctx.L.input_char >= 48 && ctx.L.input_char <= 57) || (ctx.L.input_char >= 65 && ctx.L.input_char <= 70) || (ctx.L.input_char >= 97 && ctx.L.input_char <= 102)) { ctx.L.unichar += HexValue(ctx.L.input_char) * num2; num++; num2 /= 16; if (num == 4) { ctx.L.string_buffer.Append(Convert.ToChar(ctx.L.unichar)); ctx.NextState = ctx.StateStack; return true; } continue; } return false; } return true; } private static bool State23(FsmContext ctx) { while (ctx.L.GetChar()) { switch (ctx.L.input_char) { case 39: ctx.L.UngetChar(); ctx.Return = true; ctx.NextState = 24; return true; case 92: ctx.StateStack = 23; ctx.NextState = 21; return true; } ctx.L.string_buffer.Append((char)ctx.L.input_char); } return true; } private static bool State24(FsmContext ctx) { ctx.L.GetChar(); if (ctx.L.input_char == 39) { ctx.L.input_char = 34; ctx.Return = true; ctx.NextState = 1; return true; } return false; } private static bool State25(FsmContext ctx) { ctx.L.GetChar(); switch (ctx.L.input_char) { case 42: ctx.NextState = 27; return true; case 47: ctx.NextState = 26; return true; default: return false; } } private static bool State26(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char == 10) { ctx.NextState = 1; return true; } } return true; } private static bool State27(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char == 42) { ctx.NextState = 28; return true; } } return true; } private static bool State28(FsmContext ctx) { while (ctx.L.GetChar()) { if (ctx.L.input_char != 42) { if (ctx.L.input_char == 47) { ctx.NextState = 1; return true; } ctx.NextState = 27; return true; } } return true; } private bool GetChar() { if ((input_char = NextChar()) != -1) { return true; } end_of_input = true; return false; } private int NextChar() { if (input_buffer != 0) { int result = input_buffer; input_buffer = 0; return result; } return reader.Read(); } public bool NextToken() { fsm_context.Return = false; while (true) { if (!fsm_handler_table[state - 1](fsm_context)) { throw new JsonException(input_char); } if (end_of_input) { return false; } if (fsm_context.Return) { break; } state = fsm_context.NextState; } string_value = string_buffer.ToString(); string_buffer.Remove(0, string_buffer.Length); token = fsm_return_table[state - 1]; if (token == 65542) { token = input_char; } state = fsm_context.NextState; return true; } private void UngetChar() { input_buffer = input_char; } } internal enum ParserToken { None = 65536, Number, True, False, Null, CharSeq, Char, Text, Object, ObjectPrime, Pair, PairRest, Array, ArrayPrime, Value, ValueRest, String, End, Epsilon }