Decompiled source of ByTheBook v0.3.0
ByTheBook.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using ByTheBook.AIActions; using ByTheBook.Dialog; using ByTheBook.SyncDisks; using ByTheBook.Upgrades; using ByTheBook.Utils; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using JsonDiffPatch; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using SOD.Common; using SOD.Common.Helpers.SyncDiskObjects; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("ByTheBook")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A collection of modifications for the more scrupulous detective.")] [assembly: AssemblyFileVersion("0.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0+be475945c19324a86183bea081ddb0446c806131")] [assembly: AssemblyProduct("ByTheBook")] [assembly: AssemblyTitle("ByTheBook")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ByTheBook { [BepInPlugin("ByTheBook", "ByTheBook", "0.3.0")] public class ByTheBookPlugin : BasePlugin { public static ManualLogSource Logger; public static ByTheBookPlugin Instance { get; private set; } public override void Load() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (!((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, (ConfigDescription)null).Value) { ManualLogSource log = ((BasePlugin)this).Log; val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ByTheBook"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is disabled."); } log.LogInfo(val); return; } Instance = this; Logger = ((BasePlugin)this).Log; ManualLogSource log2 = ((BasePlugin)this).Log; val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ByTheBook"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!"); } log2.LogInfo(val); RegisterTypes(); TryMigrateLegacyConfig(out var legacyPrice, out var legacyGuardTier); ((BasePlugin)this).Config.Bind<int>("SyncDisk", "guard-pass-max-chance-social-credit-level", legacyGuardTier.GetValueOrDefault(3), "Scales guest-pass success chance against the game's social credit thresholds. Higher tier (1-8) = stricter (lower chance)."); ((BasePlugin)this).Config.Bind<int>("SyncDisk", "private-eye-cost", legacyPrice.GetValueOrDefault(500), "Purchase price for the Private Eye License sync disk."); ((BasePlugin)this).Config.Bind<int>("EnabledSideEffects", "social-credit-penalty-divisor", 150, "Divisor used to scale pursuit social credit penalty: deduction = total fines / divisor."); ((BasePlugin)this).Config.Bind<int>("EnabledSideEffects", "social-credit-penalty-cap", 100, "Maximum social credit deducted once at the start of a pursuit episode."); PrivateEyeDisk.Register(); PerformHarmonyPatches(); } private void TryMigrateLegacyConfig(out int? legacyPrice, out int? legacyGuardTier) { //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Expected O, but got Unknown legacyPrice = null; legacyGuardTier = null; try { string configFilePath = ((BasePlugin)this).Config.ConfigFilePath; if (string.IsNullOrWhiteSpace(configFilePath) || !File.Exists(configFilePath)) { return; } string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "btb_migrated_0_3_0"); if (File.Exists(savestoreDirectoryPath)) { return; } List<string> list = File.ReadAllLines(configFilePath).ToList(); string text = null; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < list.Count; i++) { string text2 = list[i]; string text3 = text2.Trim(); if (text3.StartsWith("[") && text3.EndsWith("]")) { text = text3.Substring(1, text3.Length - 2); } else { if (string.IsNullOrWhiteSpace(text3) || text3.StartsWith("#") || text == null) { continue; } if (string.Equals(text, "SyncDiskCosts", StringComparison.OrdinalIgnoreCase) && text3.StartsWith("private-eye", StringComparison.OrdinalIgnoreCase)) { int num = text2.IndexOf('='); if (num > -1 && int.TryParse(text2.Substring(num + 1).Trim(), out var result)) { legacyPrice = result; } } if (string.Equals(text, "SyncDisks", StringComparison.OrdinalIgnoreCase) && text3.StartsWith("guard-pass-max-chance-social-credit-level", StringComparison.OrdinalIgnoreCase)) { int num2 = text2.IndexOf('='); if (num2 > -1 && int.TryParse(text2.Substring(num2 + 1).Trim(), out var result2)) { legacyGuardTier = result2; } } } } text = null; bool flag = false; for (int j = 0; j < list.Count; j++) { string text4 = list[j].Trim(); if (text4.StartsWith("[") && text4.EndsWith("]")) { text = text4.Substring(1, text4.Length - 2); flag = string.Equals(text, "SyncDiskCosts", StringComparison.OrdinalIgnoreCase); if (flag) { hashSet.Add(j); } } else if (!string.IsNullOrWhiteSpace(text4) && text != null) { if (flag) { hashSet.Add(j); } else if (string.Equals(text, "SyncDisks", StringComparison.OrdinalIgnoreCase) && text4.StartsWith("guard-pass-max-chance-social-credit-level", StringComparison.OrdinalIgnoreCase)) { hashSet.Add(j); } } } if (hashSet.Count > 0) { List<string> list2 = new List<string>(list.Count - hashSet.Count); for (int k = 0; k < list.Count; k++) { if (!hashSet.Contains(k)) { list2.Add(list[k]); } } File.WriteAllLines(configFilePath, list2); } File.WriteAllText(savestoreDirectoryPath, "by-the-book migration 0.3.0 completed"); } catch (Exception ex) { ManualLogSource log = ((BasePlugin)this).Log; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Config migration skipped due to error: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogWarning(val); } } private void PerformHarmonyPatches() { //IL_0005: 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: Expected O, but got Unknown new Harmony("ByTheBook").PatchAll(); ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ByTheBook"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is patched!"); } log.LogInfo(val); } private void RegisterTypes() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown ClassInjector.RegisterTypeInIl2Cpp<ByTheBookDialogManager>(); ManualLogSource log = ((BasePlugin)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ByTheBook"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has added custom types!"); } log.LogInfo(val); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ByTheBook"; public const string PLUGIN_NAME = "ByTheBook"; public const string PLUGIN_VERSION = "0.3.0"; } } namespace ByTheBook.Utils { public static class MurderControllerExtensionMethods { public static Murder? GetLatestMurder(this MurderController controller) { if (controller.activeMurders.Count == 0) { return null; } return controller.activeMurders[controller.activeMurders.Count - 1]; } } } namespace ByTheBook.Upgrades { public class ByTheBookUpgradeManager { private static ByTheBookUpgradeManager _instance; public static ByTheBookUpgradeManager Instance { get { if (_instance == null) { _instance = new ByTheBookUpgradeManager(); } return _instance; } } public bool GuardGuestPassEnabled { get; private set; } public bool CrimeSceneGuestPassEnabled { get; private set; } public bool CrimePursuitSocialCreditEnabled { get; private set; } public void SetGuardGuestPass(bool enabled) { if (GuardGuestPassEnabled != enabled) { GuardGuestPassEnabled = enabled; PrivateEyeUpgradeStatusChanged(enabled); } } public void SetCrimeSceneGuestPass(bool enabled) { CrimeSceneGuestPassEnabled = enabled; } public void SetCrimePursuitSocialCredit(bool enabled) { CrimePursuitSocialCreditEnabled = enabled; } private void PrivateEyeUpgradeStatusChanged(bool enabled) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown ManualLogSource log = ((BasePlugin)ByTheBookPlugin.Instance).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PrivateEyeUpgradeStatusChanged to: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(enabled); } log.LogInfo(val); List<Citizen> list = ((IEnumerable<Citizen>)Resources.FindObjectsOfTypeAll<Citizen>()).Where((Citizen citizen) => ((Actor)citizen).isEnforcer).ToList(); ManualLogSource log2 = ((BasePlugin)ByTheBookPlugin.Instance).Log; val = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" enforcers to enabled dialog."); } log2.LogInfo(val); foreach (Citizen item in list) { if (enabled) { EvidenceWitness evidenceEntry = ((Actor)item).evidenceEntry; if (evidenceEntry != null) { evidenceEntry.AddDialogOption((DataKey)4, GuardGuestPassDialogPreset.Instance, (SideJob)null, (NewRoom)null, (InteractionDialogInstance)null, false, true); } } else { EvidenceWitness evidenceEntry2 = ((Actor)item).evidenceEntry; if (evidenceEntry2 != null) { evidenceEntry2.RemoveDialogOption((DataKey)4, GuardGuestPassDialogPreset.Instance, (SideJob)null, (NewRoom)null); } } } } public bool IsCrimeSceneGuestPassEnabled() { if (!Game.Instance.giveAllUpgrades) { return CrimeSceneGuestPassEnabled; } return true; } public bool IsCrimePursuitSocialCreditEnabled() { if (!Game.Instance.giveAllUpgrades) { return CrimePursuitSocialCreditEnabled; } return true; } } } namespace ByTheBook.SyncDisks { internal static class PrivateEyeDisk { private const string DiskDisplayName = "Private Eye License"; private const string Effect1Name = "Detective Consultant"; private const string Effect1Description = "The Enforcer on duty at a crime scene may be asked for a guest pass after they have canvased the scene. Higher social credit increases odds of success."; private const string Upgrade1Description = "You will always receive a guest pass (if required) when entering a crime scene."; private const string SideEffectDescription = "You're on the side of the law now. If caught (persued) doing illegal activities your social credit score will be reduced based on the size of your current fine."; private static int _effectId_GuardGuestPass; private static int _sideEffectId_SocialCreditPenalty; private static OptionIds _optionIds; private static SyncDisk _syncDisk; private static ConfigEntry<int> _priceConfig; private static ConfigEntry<bool> _enableSideEffectConfig; private static bool _legacyDdsAdded; public static void Register() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) _priceConfig = ((BasePlugin)ByTheBookPlugin.Instance).Config.Bind<int>("SyncDisk", "private-eye-cost", 500, "Purchase price for the Private Eye License sync disk."); _enableSideEffectConfig = ((BasePlugin)ByTheBookPlugin.Instance).Config.Bind<bool>("EnabledSideEffects", "private-eye", true, "Enable side effect: social credit penalty when pursued while fines are active."); SyncDiskBuilder val = Lib.SyncDisks.Builder("Private Eye License", "ByTheBook", true).SetPrice(_priceConfig.Value).SetManufacturer((Manufacturer)1) .SetRarity((Rarity)1) .AddSaleLocation((SyncDiskSaleLocation[])(object)new SyncDiskSaleLocation[1] { (SyncDiskSaleLocation)19 }) .AddEffect("Detective Consultant", "The Enforcer on duty at a crime scene may be asked for a guest pass after they have canvased the scene. Higher social credit increases odds of success.", ref _effectId_GuardGuestPass, (string)null) .AddUpgradeOption(new Options("You will always receive a guest pass (if required) when entering a crime scene."), ref _optionIds); if (_enableSideEffectConfig.Value) { val.AddSideEffect("Crime pursuit social credit penalty", "You're on the side of the law now. If caught (persued) doing illegal activities your social credit score will be reduced based on the size of your current fine.", ref _sideEffectId_SocialCreditPenalty); } _syncDisk = val.CreateAndRegister(); Lib.SyncDisks.OnAfterSyncDiskInstalled += OnAfterSyncDiskInstalled; Lib.SyncDisks.OnAfterSyncDiskUpgraded += OnAfterSyncDiskUpgraded; Lib.SyncDisks.OnAfterSyncDiskUninstalled += OnAfterSyncDiskUninstalled; } internal static void AddLegacyDdsStrings() { if (!_legacyDdsAdded) { Lib.DdsStrings.AddOrUpdateEntries("evidence.syncdisks", new(string, string)[5] { ("private-eye", "Private Eye License"), ("private-eye_effect1_name", "Detective Consultant"), ("private-eye_effect1_description", "The Enforcer on duty at a crime scene may be asked for a guest pass after they have canvased the scene. Higher social credit increases odds of success."), ("private-eye_upgrade1_description", "You will always receive a guest pass (if required) when entering a crime scene."), ("private-eye_side-effect_description", "You're on the side of the law now. If caught (persued) doing illegal activities your social credit score will be reduced based on the size of your current fine.") }); _legacyDdsAdded = true; } } private static bool IsOurDisk(SyncDisk disk) { if (disk != null) { return disk.Name == "Private Eye License"; } return false; } private static void OnAfterSyncDiskInstalled(object sender, SyncDiskArgs e) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (IsOurDisk(e.SyncDisk)) { if (e.Effect.HasValue && e.Effect.Value.Id == _effectId_GuardGuestPass) { ByTheBookUpgradeManager.Instance.SetGuardGuestPass(enabled: true); } if (_enableSideEffectConfig.Value) { ByTheBookUpgradeManager.Instance.SetCrimePursuitSocialCredit(enabled: true); } } } private static void OnAfterSyncDiskUpgraded(object sender, SyncDiskArgs e) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (IsOurDisk(e.SyncDisk) && e.UpgradeOption.HasValue) { int id = e.UpgradeOption.Value.Id; if (id == _optionIds.Option1Id || id == _optionIds.Option2Id || id == _optionIds.Option3Id) { ByTheBookUpgradeManager.Instance.SetCrimeSceneGuestPass(enabled: true); } } } private static void OnAfterSyncDiskUninstalled(object sender, SyncDiskArgs e) { if (IsOurDisk(e.SyncDisk)) { ByTheBookUpgradeManager.Instance.SetGuardGuestPass(enabled: false); ByTheBookUpgradeManager.Instance.SetCrimeSceneGuestPass(enabled: false); if (_enableSideEffectConfig.Value) { ByTheBookUpgradeManager.Instance.SetCrimePursuitSocialCredit(enabled: false); } } } } } namespace ByTheBook.Patches { internal class DDSLoaderPatches { [HarmonyPatch(typeof(Toolbox), "Start")] public class Toolbox_Start { private static List<DirectoryInfo> directoryInfos; private static List<DirectoryInfo> DdsDirectoryInfo { get { if (directoryInfos == null) { directoryInfos = (from dirPath in Directory.GetDirectories(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ".."), "BTBDDS", SearchOption.AllDirectories) select new DirectoryInfo(dirPath)).ToList(); } return directoryInfos; } } public static void Postfix() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Expected O, but got Unknown //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Expected O, but got Unknown //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Expected O, but got Unknown //IL_0615: Unknown result type (might be due to invalid IL or missing references) //IL_061c: Expected O, but got Unknown bool flag = default(bool); string text10 = default(string); string text11 = default(string); string text12 = default(string); string text13 = default(string); int num = default(int); bool flag2 = default(bool); string text14 = default(string); foreach (DirectoryInfo item in DdsDirectoryInfo) { string path = Path.Combine(item.FullName, "DDS", "Trees"); string path2 = Path.Combine(item.FullName, "DDS", "Messages"); string path3 = Path.Combine(item.FullName, "DDS", "Blocks"); string[] files; if (Directory.Exists(path3)) { files = Directory.GetFiles(path3, "*.block"); foreach (string text in files) { try { DDSBlockSave val = JsonUtility.FromJson<DDSBlockSave>(File.ReadAllText(text)); Toolbox.Instance.allDDSBlocks.Add(((DDSComponent)val).id, val); } catch (Exception ex) { ManualLogSource log = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); } log.LogError(val2); ((BasePlugin)ByTheBookPlugin.Instance).Log.LogError((object)ex); } } files = Directory.GetFiles(path3, "*.block_patch"); foreach (string text2 in files) { try { DDSBlockSave val3 = JsonUtility.FromJson<DDSBlockSave>(CreatePatchedJson(text2)); Toolbox.Instance.allDDSBlocks[((DDSComponent)val3).id] = val3; } catch (Exception ex2) { ManualLogSource log2 = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2); } log2.LogError(val2); ((BasePlugin)ByTheBookPlugin.Instance).Log.LogError((object)ex2); } } } if (Directory.Exists(path2)) { files = Directory.GetFiles(path2, "*.msg"); foreach (string text3 in files) { try { DDSMessageSave val4 = JsonUtility.FromJson<DDSMessageSave>(File.ReadAllText(text3)); Toolbox.Instance.allDDSMessages.Add(((DDSComponent)val4).id, val4); } catch (Exception ex3) { ManualLogSource log3 = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text3); } log3.LogError(val2); ((BasePlugin)ByTheBookPlugin.Instance).Log.LogError((object)ex3); } } files = Directory.GetFiles(path2, "*.msg_patch"); foreach (string text4 in files) { try { DDSMessageSave val5 = JsonUtility.FromJson<DDSMessageSave>(CreatePatchedJson(text4)); Toolbox.Instance.allDDSMessages[((DDSComponent)val5).id] = val5; } catch (Exception ex4) { ManualLogSource log4 = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text4); } log4.LogError(val2); ((BasePlugin)ByTheBookPlugin.Instance).Log.LogError((object)ex4); } } } if (Directory.Exists(path)) { files = Directory.GetFiles(path, "*.tree"); foreach (string text5 in files) { try { DDSTreeSave val6 = JsonUtility.FromJson<DDSTreeSave>(File.ReadAllText(text5)); val6.messageRef = new Dictionary<string, DDSMessageSettings>(); Enumerator<DDSMessageSettings> enumerator2 = val6.messages.GetEnumerator(); while (enumerator2.MoveNext()) { DDSMessageSettings current2 = enumerator2.Current; val6.messageRef.Add(current2.instanceID, current2); } Toolbox.Instance.allDDSTrees.Add(((DDSComponent)val6).id, val6); } catch (Exception ex5) { ManualLogSource log5 = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text5); } log5.LogError(val2); ((BasePlugin)ByTheBookPlugin.Instance).Log.LogError((object)ex5); } } files = Directory.GetFiles(path, "*.tree_patch"); foreach (string text6 in files) { try { DDSTreeSave val7 = JsonUtility.FromJson<DDSTreeSave>(CreatePatchedJson(text6)); val7.messageRef = new Dictionary<string, DDSMessageSettings>(); Enumerator<DDSMessageSettings> enumerator2 = val7.messages.GetEnumerator(); while (enumerator2.MoveNext()) { DDSMessageSettings current3 = enumerator2.Current; val7.messageRef.Add(current3.instanceID, current3); } Toolbox.Instance.allDDSTrees[((DDSComponent)val7).id] = val7; } catch (Exception ex6) { ManualLogSource log6 = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text6); } log6.LogError(val2); ((BasePlugin)ByTheBookPlugin.Instance).Log.LogError((object)ex6); } } } ManualLogSource log7 = ((BasePlugin)ByTheBookPlugin.Instance).Log; BepInExInfoLogInterpolatedStringHandler val8 = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val8).AppendLiteral("Loaded DDS Content and Patches For: "); ((BepInExLogInterpolatedStringHandler)val8).AppendFormatted<string>(item.Parent.Name); } log7.LogInfo(val8); string text7 = Path.Combine(item.FullName, "Strings", Game.Instance.language); string text8 = Path.Combine(item.FullName, "Strings", "English"); string text9 = (Directory.Exists(text7) ? text7 : (Directory.Exists(text8) ? text8 : "")); if (!(text9 != "")) { continue; } files = Directory.GetFiles(text9, "*.csv", SearchOption.AllDirectories); foreach (string path4 in files) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path4); string[] array = File.ReadAllLines(path4); for (int j = 0; j < array.Length; j++) { Strings.ParseLine(array[j].Trim(), ref text10, ref text11, ref text12, ref text13, ref num, ref flag2, ref text14, true); Strings.LoadIntoDictionary(fileNameWithoutExtension, Strings.stringTable[fileNameWithoutExtension].Count + 1, text10, text12.Replace("\\r\\n", "\r\n"), text13, num, flag2); } } ManualLogSource log8 = ((BasePlugin)ByTheBookPlugin.Instance).Log; val8 = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val8).AppendLiteral("Loaded String Content For: "); ((BepInExLogInterpolatedStringHandler)val8).AppendFormatted<string>(item.Parent.Name); } log8.LogInfo(val8); } } private static string CreatePatchedJson(string patchPath) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown FileInfo fileInfo = new FileInfo(patchPath); DirectoryInfo directoryInfo = new DirectoryInfo(fileInfo.DirectoryName); JToken val = JToken.Parse(File.ReadAllText(Path.Combine(Application.streamingAssetsPath, "DDS", directoryInfo.Name, fileInfo.Name.Split("_")[0]))); PatchDocument val2 = PatchDocument.Parse(File.ReadAllText(patchPath)); ((AbstractPatcher<JToken>)new JsonPatcher()).Patch(ref val, val2); return ((object)val).ToString(); } } } public class DebugPatches { } internal class DialogControllerPatches { [HarmonyPatch(typeof(DialogController), "ExecuteDialog")] public class DialogExecuteHook { private static readonly Random random = new Random(Guid.NewGuid().GetHashCode()); private static readonly int GUARD_PASS_MAX_CHANCE_SOCIAL_LEVEL = Math.Clamp(((BasePlugin)ByTheBookPlugin.Instance).Config.Bind<int>("SyncDisk", "guard-pass-max-chance-social-credit-level", 3, "Scales guest-pass success chance against the game's social credit thresholds. Higher tier (1-8) = stricter (lower chance).").Value, 1, 8); [HarmonyPrefix] public static void Prefix(DialogOption dialog, Interactable saysTo, NewNode where, Actor saidBy, ForceSuccess forceSuccess, ref bool __runOriginal) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown if (!((SoCustomComparison)(object)((dialog != null) ? dialog.preset : null) == (SoCustomComparison)(object)GuardGuestPassDialogPreset.Instance)) { return; } object obj; if (saysTo == null) { obj = null; } else { InteractableController controller = saysTo.controller; obj = ((controller != null) ? ((Component)controller).GetComponentInParent<Citizen>() : null); } Citizen val = (Citizen)obj; ManualLogSource logger = ByTheBookPlugin.Logger; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Executing Dialog: "); object obj2; if (dialog == null) { obj2 = null; } else { DialogPreset preset = dialog.preset; obj2 = ((preset != null) ? ((Object)preset).name : null); } ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>((string)obj2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" executed by: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>((saidBy != null) ? ((Object)saidBy).name : null); } logger.LogDebug(val2); if ((Object)(object)val != (Object)null) { bool flag2 = false; BepInExInfoLogInterpolatedStringHandler val3; if ((int)forceSuccess != 1) { if ((int)forceSuccess == 2) { flag2 = false; } else { double num = Convert.ToDouble(GameplayController.Instance.GetSocialCreditThresholdForLevel(GUARD_PASS_MAX_CHANCE_SOCIAL_LEVEL)); double num2 = Math.Clamp(Convert.ToDouble(GameplayController.Instance.socialCredit), 1.0, num + 1.0); double num3 = 0.99 - Math.Clamp(num2 / num, 0.0, 0.75); double num4 = random.NextDouble(); flag2 = num4 >= num3; if (ByTheBookUpgradeManager.Instance.IsCrimeSceneGuestPassEnabled()) { flag2 = true; } ManualLogSource logger2 = ByTheBookPlugin.Logger; val3 = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("GuardIssueGuestPass rolled: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(num4); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" - required: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(num3); } logger2.LogInfo(val3); } } else { flag2 = true; } ManualLogSource logger3 = ByTheBookPlugin.Logger; val3 = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("GuardIssueGuestPass - success?: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<bool>(flag2); } logger3.LogInfo(val3); ByTheBookDialogManager.Instance.IssueGuardGuestPass(val, saysTo, where, saidBy, flag2, dialog.roomRef, dialog.jobRef); } __runOriginal = false; } } [HarmonyPatch(typeof(DialogController), "TestSpecialCaseAvailability")] public class DialogControllerSpecialCaseHook { [HarmonyPostfix] public static void Postfix(ref bool __result, DialogPreset preset, Citizen saysTo, SideJob jobRef) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (!__result && (int)preset.specialCase == 100) { __result = IsEnforcerGuardingLatestMurderScene(saysTo); ManualLogSource log = ((BasePlugin)ByTheBookPlugin.Instance).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GuardGuestPass special case: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(__result); } log.LogInfo(val); } } private static bool IsEnforcerGuardingLatestMurderScene(Citizen saysTo) { if (!ByTheBookUpgradeManager.Instance.GuardGuestPassEnabled) { return false; } Murder latestMurder = MurderController.Instance.GetLatestMurder(); if (latestMurder == null || !((Actor)saysTo).isEnforcer) { return false; } EnforcerCall val = default(EnforcerCall); if (GameplayController.Instance.enforcerCalls.TryGetValue(latestMurder.location, ref val)) { return val.guard == ((Human)saysTo).humanID; } return false; } } } internal class InteractablePatches { [HarmonyPatch(typeof(Interactable), "UpdateCurrentActions")] public class InteractableHook { [HarmonyPostfix] public static void Postfix(Interactable __instance) { Human val = ((__instance != null) ? __instance.belongsTo : null); InteractableCurrentAction val2 = default(InteractableCurrentAction); if (!((Object)(object)val == (Object)null) && !((Object)(object)((Actor)val).ai == (Object)null) && ((Actor)val).isEnforcer && !((Actor)val).isDead && !((Actor)val).ai.ko && !((Object)(object)__instance.speechController == (Object)null) && (SoCustomComparison)(object)ByTheBookDialogManager.Instance.TalkToAction != (SoCustomComparison)null && ((__instance == null) ? null : __instance.currentActions?.TryGetValue((InteractionKey)1, ref val2)).GetValueOrDefault() && val2.currentAction.interactionName == "Take Print") { ((BasePlugin)ByTheBookPlugin.Instance).Log.LogDebug((object)"Set TalkTo action on guard."); val2.currentAction.action = ByTheBookDialogManager.Instance.TalkToAction; val2.currentAction.interactionName = "Talk To"; val2.currentAction.specialCase = (SpecialCase)0; } } } } internal class LoadingPatches { [HarmonyPatch(typeof(AssetLoader), "GetAllActions")] public class AssetLoaderGetAllActionsHook { private static bool presetsLoaded; [HarmonyPostfix] public static void Postfix(List<AIActionPreset> __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown ManualLogSource logger = ByTheBookPlugin.Logger; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(34, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetLoaderGetAllActionsHook Post."); } logger.LogDebug(val); if (!presetsLoaded) { LoadActions(__result); presetsLoaded = true; } } private static void LoadActions(List<AIActionPreset> data) { data.Add(SeekOutDetectiveAction.Instance); } } [HarmonyPatch(typeof(AssetLoader), "GetAllPresets")] public class AssetLoaderGetAllPresetsHook { private static bool presetsLoaded; [HarmonyPostfix] public static void Postfix(List<ScriptableObject> __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown ManualLogSource logger = ByTheBookPlugin.Logger; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(34, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AssetLoaderGetAllPresetsHook Post."); } logger.LogDebug(val); if (!presetsLoaded) { LoadSyncDisks(__result); LoadDialogs(__result); presetsLoaded = true; } } private static void LoadSyncDisks(List<ScriptableObject> data) { } private static void LoadDialogs(List<ScriptableObject> data) { data.Add((ScriptableObject)(object)GuardGuestPassDialogPreset.Instance); } private static void LoadGoals(List<ScriptableObject> data) { data.Add((ScriptableObject)(object)SeekOutDetectiveGoal.Instance); } } [HarmonyPatch(typeof(Toolbox), "LoadAll")] public class ToolboxLoadAllHook { private static bool presetsLoaded; [HarmonyPostfix] [HarmonyPriority(0)] public static void Postfix() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown ManualLogSource logger = ByTheBookPlugin.Logger; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(21, 0, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Toolbox Post LoadAll."); } logger.LogDebug(val); if (!presetsLoaded) { PrivateEyeDisk.AddLegacyDdsStrings(); presetsLoaded = true; } DeduplicatePoliceAutomatSyncDisks(); } private static void DeduplicatePoliceAutomatSyncDisks() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown bool flag = default(bool); foreach (MenuPreset item in ((IEnumerable<MenuPreset>)Resources.FindObjectsOfTypeAll<MenuPreset>()).Where((MenuPreset preset) => ((SoCustomComparison)preset).GetPresetName() == "PoliceAutomat").ToList()) { try { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); List<SyncDiskPreset> val = new List<SyncDiskPreset>(); Enumerator<SyncDiskPreset> enumerator2 = item.syncDisks.GetEnumerator(); while (enumerator2.MoveNext()) { SyncDiskPreset current2 = enumerator2.Current; string text = ((current2 != null) ? ((Object)current2).name : null) ?? ((current2 != null) ? ((SoCustomComparison)current2).presetName : null); if (text != null && hashSet.Add(text)) { val.Add(current2); } } if (val.Count != item.syncDisks.Count) { item.syncDisks.Clear(); enumerator2 = val.GetEnumerator(); while (enumerator2.MoveNext()) { SyncDiskPreset current3 = enumerator2.Current; item.syncDisks.Add(current3); } ManualLogSource logger = ByTheBookPlugin.Logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(55, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Deduplicated PoliceAutomat sync disks: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(val.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" unique entries."); } logger.LogInfo(val2); } } catch { } } } } } internal class PlayerPatches { [HarmonyPatch(typeof(Actor), "AddPersuedBy")] public class ActorPersuedByHook { private static readonly int CRIME_PENALTY_DIVISOR = Math.Clamp(((BasePlugin)ByTheBookPlugin.Instance).Config.Bind<int>("EnabledSideEffects", "social-credit-penalty-divisor", 150, "Divisor used to scale pursuit social credit penalty: deduction = total fines / divisor.").Value, 1, int.MaxValue); private static readonly int MAXIMUM_SOCIAL_CREDIT_PENALTY = Math.Clamp(((BasePlugin)ByTheBookPlugin.Instance).Config.Bind<int>("EnabledSideEffects", "social-credit-penalty-cap", 100, "Maximum social credit deducted once at the start of a pursuit episode.").Value, 0, int.MaxValue); [HarmonyPrefix] public static void Prefix(Actor __instance) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown if (!__instance.isPlayer || !ByTheBookUpgradeManager.Instance.IsCrimePursuitSocialCreditEnabled() || ((Actor)Player.Instance).persuedBy.Count != 0 || !(Player.Instance.persuedProgress <= 0f)) { return; } int num = 0; Enumerator<StatusInstance, List<StatusCount>> enumerator = StatusController.Instance.activeStatusCounts.Values.GetEnumerator(); while (enumerator.MoveNext()) { Enumerator<StatusCount> enumerator2 = enumerator.Current.GetEnumerator(); while (enumerator2.MoveNext()) { StatusCount current = enumerator2.Current; num += current.GetPenaltyAmount(); } } ManualLogSource log = ((BasePlugin)ByTheBookPlugin.Instance).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Calculated Total Penalty: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num); } log.LogInfo(val); int num2 = Math.Min(num / CRIME_PENALTY_DIVISOR, MAXIMUM_SOCIAL_CREDIT_PENALTY); if (num2 > 0) { ManualLogSource log2 = ((BasePlugin)ByTheBookPlugin.Instance).Log; val = new BepInExInfoLogInterpolatedStringHandler(86, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Player persued while bounty active. Deducting "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" social credit. (totalFines/150 max 100)"); } log2.LogInfo(val); GameplayController.Instance.AddSocialCredit(-num2, true, "Someone caught you doing illegal activities!"); } } } [HarmonyPatch(typeof(Player), "OnGameLocationChange")] public class PlayerLocationChangeHook { [HarmonyPrefix] public static void Prefix() { if (ByTheBookUpgradeManager.Instance.IsCrimeSceneGuestPassEnabled() && ((Actor)Player.Instance).currentGameLocation.isCrimeScene && !((Actor)Player.Instance).currentGameLocation.isOutside) { GameplayController.Instance.AddGuestPass(((Actor)Player.Instance).currentGameLocation.thisAsAddress, 2f); } } } } internal static class TalkToInjection { public static bool Verbose = false; public static bool Silent = true; public static readonly string TalkToUIName = "Talk To"; public static readonly string InspectUIName = "Inspect"; internal static void Log(string msg) { if (!Silent) { Debug.Log(Object.op_Implicit(msg)); } } internal static void VLog(string msg) { if (!Silent && Verbose) { Debug.Log(Object.op_Implicit(msg)); } } public static bool IsOnDutyCrimeSceneResponder(Human target, out string why) { //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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Invalid comparison between Unknown and I4 why = "no gameplay controller"; if ((Object)(object)target == (Object)null) { why = "no target"; return false; } GameplayController instance = GameplayController._instance; if ((Object)(object)instance == (Object)null) { return false; } int humanID = target.humanID; Dictionary<NewGameLocation, EnforcerCall> enforcerCalls = instance.enforcerCalls; if (enforcerCalls == null || enforcerCalls.Count == 0) { why = "no enforcer calls"; return false; } bool flag = false; Enumerator<NewGameLocation, EnforcerCall> enumerator = enforcerCalls.GetEnumerator(); while (enumerator.MoveNext()) { EnforcerCall value = enumerator.Current.Value; if (value == null || !value.isCrimeScene) { continue; } flag = true; EnforcerCallState state = value.state; if ((int)state != 1 && (int)state != 2) { continue; } if (value.guard == humanID) { why = "guard match"; return true; } List<int> response = value.response; if (response == null) { continue; } for (int i = 0; i < response.Count; i++) { if (response[i] == humanID) { why = "responder match"; return true; } } } if (!flag) { why = "no crime-scene calls"; return false; } why = "crime-scene calls found, but guard/responder mismatch"; return false; } private static int GetInteractableId(Interactable inter) { if (inter == null) { return 0; } return inter.id; } private static string Normalize(string s) { if (string.IsNullOrEmpty(s)) { return string.Empty; } s = Regex.Replace(s, "\\s+", " "); return s.Trim().ToLowerInvariant(); } internal static string GetActionUiName(InteractionAction ia, InteractableCurrentAction ica) { string text = ((ica != null) ? ica.overrideInteractionName : null); if (!string.IsNullOrEmpty(text)) { return text; } if (ia == null) { return string.Empty; } return ia.interactionName; } private static bool LooksLikeTalkTo(string labelOrKey) { string text = Normalize(labelOrKey); if (!(text == "talk to") && !(text == "talkto")) { return text == "talk"; } return true; } private static bool LooksLikeInspect(string labelOrKey) { return Normalize(labelOrKey) == "inspect"; } public static bool TryFindTalkTo(Interactable inter, out InteractableCurrentAction found, out InteractionKey key) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected I4, but got Unknown found = null; key = (InteractionKey)0; if (inter == null || inter.currentActions == null) { return false; } Enumerator<InteractionKey, InteractableCurrentAction> enumerator = inter.currentActions.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<InteractionKey, InteractableCurrentAction> current = enumerator.Current; InteractableCurrentAction value = current.Value; InteractionAction val = ((value != null) ? value.currentAction : null); if (val != null && (LooksLikeTalkTo(GetActionUiName(val, value)) || LooksLikeTalkTo(val.interactionName))) { found = value; key = (InteractionKey)(int)current.Key; return true; } } return false; } public static bool TryFindInspect(Interactable inter, out InteractableCurrentAction found, out InteractionKey key) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected I4, but got Unknown found = null; key = (InteractionKey)0; if (inter == null || inter.currentActions == null) { return false; } Enumerator<InteractionKey, InteractableCurrentAction> enumerator = inter.currentActions.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<InteractionKey, InteractableCurrentAction> current = enumerator.Current; InteractableCurrentAction value = current.Value; InteractionAction val = ((value != null) ? value.currentAction : null); if (val != null && (LooksLikeInspect(GetActionUiName(val, value)) || LooksLikeInspect(val.interactionName))) { found = value; key = (InteractionKey)(int)current.Key; return true; } } return false; } public static bool ForceEnable(InteractableCurrentAction ica) { if (ica == null) { return false; } bool result = false; if (!ica.enabled) { ica.enabled = true; result = true; } if (!ica.display) { ica.display = true; result = true; } return result; } public static void RefreshHud() { InteractionController instance = InteractionController._instance; if (!((Object)(object)instance == (Object)null)) { instance.UpdateInteractionText(); instance.UpdateInteractionIcons(); } } public static void DumpActions(Interactable inter, string tag) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if (!Verbose || inter == null || inter.currentActions == null || inter.currentActions.Count == 0) { return; } StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(30, 2, stringBuilder2); handler.AppendLiteral("[BTB][ACTIONS-DUMP "); handler.AppendFormatted(tag); handler.AppendLiteral("] inter#"); handler.AppendFormatted(GetInteractableId(inter)); handler.AppendLiteral(" { "); stringBuilder3.Append(ref handler); int num = 0; Enumerator<InteractionKey, InteractableCurrentAction> enumerator = inter.currentActions.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<InteractionKey, InteractableCurrentAction> current = enumerator.Current; InteractionKey key = current.Key; InteractableCurrentAction value = current.Value; InteractionAction val = ((value != null) ? value.currentAction : null); string actionUiName = GetActionUiName(val, value); object obj; if (val != null) { InteractionKey keyOverride = val.keyOverride; obj = ((object)(InteractionKey)(ref keyOverride)).ToString(); } else { obj = "none"; } string value2 = (string)obj; object obj2; if (val != null) { SpecialCase specialCase = val.specialCase; obj2 = ((object)(SpecialCase)(ref specialCase)).ToString(); } else { obj2 = "none"; } string value3 = (string)obj2; stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(61, 7, stringBuilder2); handler.AppendLiteral("#"); handler.AppendFormatted(num); handler.AppendLiteral(":"); handler.AppendFormatted<InteractionKey>(key); handler.AppendLiteral(" => ui='"); handler.AppendFormatted(actionUiName); handler.AppendLiteral("', keyOverride="); handler.AppendFormatted(value2); handler.AppendLiteral(", specialCase="); handler.AppendFormatted(value3); handler.AppendLiteral(", enabled="); handler.AppendFormatted(value != null && value.enabled); handler.AppendLiteral(", display="); handler.AppendFormatted(value != null && value.display); handler.AppendLiteral("; "); stringBuilder4.Append(ref handler); num++; } stringBuilder.Append(" }"); VLog(stringBuilder.ToString()); } public static void DumpLookSnapshot(Interactable inter, Human target) { if (!Verbose) { return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[BTB][LOOK-SNAPSHOT] "); if (inter == null) { stringBuilder.Append("no current interactable."); VLog(stringBuilder.ToString()); return; } string value = "none"; if ((Object)(object)target != (Object)null) { value = $"{target.humanID}:{target.citizenName}"; } StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(14, 2, stringBuilder2); handler.AppendLiteral("inter#"); handler.AppendFormatted(GetInteractableId(inter)); handler.AppendLiteral(", actor="); handler.AppendFormatted(value); stringBuilder3.Append(ref handler); string why; bool value2 = IsOnDutyCrimeSceneResponder(target, out why); stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(36, 2, stringBuilder2); handler.AppendLiteral(", onDutyCrimeSceneResponder="); handler.AppendFormatted(value2); handler.AppendLiteral(" (why: "); handler.AppendFormatted(why); handler.AppendLiteral(")"); stringBuilder4.Append(ref handler); VLog(stringBuilder.ToString()); DumpActions(inter, "PRE-INJECT"); } } [HarmonyPatch(typeof(Interactable), "UpdateCurrentActions")] internal static class Interactable_UpdateCurrentActions_Patch { [HarmonyPostfix] private static void Postfix(Interactable __instance) { Human val = null; Actor val2 = ((__instance != null) ? __instance.isActor : null); if ((Object)(object)val2 != (Object)null) { val = (Human)(object)((val2 is Human) ? val2 : null); } if ((Object)(object)val == (Object)null) { if (TalkToInjection.Verbose) { TalkToInjection.DumpActions(__instance, "PRE-INJECT"); } return; } TalkToInjection.DumpLookSnapshot(__instance, val); string why; bool flag = TalkToInjection.IsOnDutyCrimeSceneResponder(val, out why); if (!TalkToInjection.TryFindTalkTo(__instance, out InteractableCurrentAction found, out InteractionKey _)) { TalkToInjection.VLog($"[BTB][ACTIONS-REFRESH] No 'Talk To' slot found (why: {why}). inter#{__instance.id}"); } else if (flag) { bool flag2 = TalkToInjection.ForceEnable(found); TalkToInjection.VLog($"[BTB][ACTIONS-REFRESH] {(flag2 ? "Forced enable/display" : "Already enabled")} for 'Talk To' (on-duty: {why}). inter#{__instance.id}"); if (TalkToInjection.TryFindInspect(__instance, out InteractableCurrentAction found2, out InteractionKey _)) { bool flag3 = TalkToInjection.ForceEnable(found2); TalkToInjection.VLog($"[BTB][ACTIONS-REFRESH] {(flag3 ? "Forced enable/display" : "Already enabled")} for 'Inspect' (on-duty: {why}). inter#{__instance.id}"); if (flag3) { TalkToInjection.RefreshHud(); } } if (flag2) { TalkToInjection.RefreshHud(); } } else { TalkToInjection.VLog($"[BTB][ACTIONS-REFRESH] Target is NOT on-duty responder (why: {why}). No injection. inter#{__instance.id}"); } } } [HarmonyPatch(typeof(InteractionController), "OnPlayerLookAtInteractableChange")] internal static class InteractionController_OnPlayerLookAtInteractableChange_Patch { [HarmonyPostfix] private static void Postfix(InteractionController __instance) { InteractableController val = ((__instance != null) ? __instance.currentLookingAtInteractable : null); Interactable obj = (((Object)(object)val != (Object)null) ? val.interactable : null); Human target = null; Actor val2 = ((obj != null) ? obj.isActor : null); if ((Object)(object)val2 != (Object)null) { target = (Human)(object)((val2 is Human) ? val2 : null); } TalkToInjection.DumpLookSnapshot(obj, target); TalkToInjection.RefreshHud(); } } [HarmonyPatch(typeof(InteractionController), "SetCurrentPlayerInteraction")] internal static class InteractionController_SetCurrentPlayerInteraction_Patch { [HarmonyPrefix] private static void Prefix(InteractionController __instance, InteractionKey key, Interactable newInteractable, InteractableCurrentAction newCurrentAction, bool fpsItem, int forcePriority) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) object obj = newInteractable; if (obj == null) { if (__instance == null) { obj = null; } else { InteractableController currentLookingAtInteractable = __instance.currentLookingAtInteractable; obj = ((currentLookingAtInteractable != null) ? currentLookingAtInteractable.interactable : null); } } Interactable val = (Interactable)obj; if (val != null) { InteractableCurrentAction val2 = newCurrentAction; if (val2 == null && val.currentActions != null) { val.currentActions.TryGetValue(key, ref val2); } string actionUiName = TalkToInjection.GetActionUiName((val2 != null) ? val2.currentAction : null, val2); if (!string.IsNullOrEmpty(actionUiName) && (actionUiName.Equals(TalkToInjection.TalkToUIName) || NormalizeStatic(actionUiName))) { Actor isActor = val.isActor; Human val3 = (Human)(object)((isActor is Human) ? isActor : null); string text = (((Object)(object)val3 != (Object)null) ? $"{val3.humanID}:{val3.citizenName}" : "unknown"); TalkToInjection.Log("[BTB][INTERACT] Selecting '" + actionUiName + "' on " + text); } } static bool NormalizeStatic(string s) { string text2 = Regex.Replace(s ?? string.Empty, "\\s+", " ").Trim().ToLowerInvariant(); if (!(text2 == "talk to")) { return text2 == "talkto"; } return true; } } } } namespace ByTheBook.Dialog { public enum ByTheBookDialogSpecialCases { GuardGuestPass = 100 } public class ByTheBookDialogManager : Object { public const string DDS_BLOCKS_DICTIONARY = "dds.blocks"; private static ByTheBookDialogManager __instance; private AIActionPreset __talkTo; public static ByTheBookDialogManager Instance { get { if (__instance == null) { __instance = new ByTheBookDialogManager(ClassInjector.DerivedConstructorPointer<ByTheBookDialogManager>()); } return __instance; } } public AIActionPreset TalkToAction { get { if ((SoCustomComparison)(object)__talkTo == (SoCustomComparison)null) { __talkTo = ((IEnumerable<AIActionPreset>)Resources.FindObjectsOfTypeAll<AIActionPreset>()).Where((AIActionPreset preset) => ((SoCustomComparison)preset).presetName == "TalkTo").LastOrDefault(); } return __talkTo; } } public ByTheBookDialogManager(IntPtr ptr) : base(ptr) { } public void IssueGuardGuestPass(Citizen saysTo, Interactable saysToInteractable, NewNode where, Actor saidBy, bool success, NewRoom roomRef, SideJob jobRef) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = ((BasePlugin)ByTheBookPlugin.Instance).Log; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(79, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("IssueGuardGuestPass function called. Citizen?: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((saysTo != null) ? ((Human)saysTo).GetFirstName() : null); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" with SpeechController exists?: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)((saysTo != null) ? ((Actor)saysTo).speechController : null) != (Object)null); } log.LogDebug(val); if (success) { if (saysTo != null) { SpeechController speechController = ((Actor)saysTo).speechController; if (speechController != null) { DialogPreset instance = GuardGuestPassDialogPreset.Instance; AISpeechPreset instance2 = GuardGuestPassAISuccessResponsePreset.Instance; speechController.Speak("dds.blocks", "a3caf795-6987-4e72-9d19-c6d2fc94a7fe", false, false, false, 0f, false, default(Color), (Human)null, false, false, (SideJob)null, instance, instance2, (Interactable)null, (InteractionDialogInstance)null); } } if (MurderController.Instance.activeMurders.Count > 0) { Murder val2 = MurderController.Instance.activeMurders[MurderController.Instance.activeMurders.Count - 1]; if (!val2.location.isOutside && !val2.location.isLobby) { GameplayController.Instance.AddGuestPass(val2.location.thisAsAddress, 2f); } } } else if (saysTo != null) { SpeechController speechController2 = ((Actor)saysTo).speechController; if (speechController2 != null) { DialogPreset instance = GuardGuestPassDialogPreset.Instance; AISpeechPreset instance2 = GuardGuestPassAIFailureResponsePreset.Instance; speechController2.Speak("dds.blocks", "16e1892c-2ded-4f8b-a38d-a6f2322358db", false, false, false, 0f, false, default(Color), (Human)null, false, false, (SideJob)null, instance, instance2, (Interactable)null, (InteractionDialogInstance)null); } } if (saysTo != null) { EvidenceWitness evidenceEntry = ((Actor)saysTo).evidenceEntry; if (evidenceEntry != null) { evidenceEntry.RemoveDialogOption((DataKey)4, GuardGuestPassDialogPreset.Instance, (SideJob)null, (NewRoom)null); } } } } public class GuardGuestPassDialogPreset { public const string NAME = "guard-guest-pass"; private static DialogPreset _instance; public static DialogPreset Instance { get { if ((SoCustomComparison)(object)_instance == (SoCustomComparison)null) { _instance = ScriptableObject.CreateInstance<DialogPreset>(); Init(_instance); } return _instance; } } private static void Init(DialogPreset instance) { ((SoCustomComparison)instance).presetName = "guard-guest-pass"; ((Object)instance).name = ((SoCustomComparison)instance).presetName; instance.affectChanceIfRestrained = 0f; instance.baseChance = 1f; instance.cost = 0; instance.displayAsIllegal = false; instance.isJobDetails = false; instance.specialCase = (SpecialCase)100; instance.telephoneCallOption = false; instance.hospitalDecisionOption = false; instance.ignoreActiveJobRequirement = true; instance.inputBox = (InputSetting)0; instance.msgID = "b0bde6bb-0803-4e23-b441-8ceb16c87133"; instance.tiedToKey = (DataKey)4; List<AISpeechPreset> val = new List<AISpeechPreset>(); val.Add(GuardGuestPassAISuccessResponsePreset.Instance); val.Add(GuardGuestPassAIFailureResponsePreset.Instance); instance.responses = val; instance.defaultOption = true; instance.removeAfterSaying = true; instance.dailyReplenish = true; } } public class GuardGuestPassAISuccessResponsePreset { public const string NAME = "guard-guest-pass-response"; public const string DDS_STRING_ID = "a3caf795-6987-4e72-9d19-c6d2fc94a7fe"; private static AISpeechPreset _instance; public static AISpeechPreset Instance { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (_instance == null) { _instance = new AISpeechPreset(ClassInjector.DerivedConstructorPointer<AISpeechPreset>()); _instance.endsDialog = true; _instance.onlyIfEnfocerOnDuty = true; _instance.ddsMessageID = "38da3c6d-3065-434b-992a-0cc190d39dd7"; } return _instance; } } } public class GuardGuestPassAIFailureResponsePreset { public const string NAME = "guard-guest-pass-response-fail"; public const string DDS_STRING_ID = "16e1892c-2ded-4f8b-a38d-a6f2322358db"; private static AISpeechPreset _instance; public static AISpeechPreset Instance { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (_instance == null) { _instance = new AISpeechPreset(ClassInjector.DerivedConstructorPointer<AISpeechPreset>()); _instance.endsDialog = true; _instance.onlyIfEnfocerOnDuty = true; _instance.ddsMessageID = "38da3c6d-3065-434b-992a-0cc190d39dd7"; } return _instance; } } } } namespace ByTheBook.AIActions { public class SeekOutDetectiveGoal { public const string NAME = "by-the-book-seek-detective-goal"; private static AIGoalPreset _instance; public static AIGoalPreset Instance { get { if ((SoCustomComparison)(object)_instance == (SoCustomComparison)null) { _instance = ScriptableObject.CreateInstance<AIGoalPreset>(); Init(_instance); } return _instance; } } private static void Init(AIGoalPreset instance) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) ((SoCustomComparison)instance).presetName = "by-the-book-seek-detective-goal"; ((Object)instance).name = ((SoCustomComparison)instance).presetName; instance.startingGoal = true; instance.appliesTo = (StartingGoal)0; instance.category = (GoalCategory)2; instance.completable = true; instance.basePriority = 11; AddSeekOutDetectiveGoalSetup(instance.actionsSetup); instance.validBetweenHours = new Vector2(0f, 23.5f); instance.dontUpdateGoalPriorityWhileActive = true; instance.rainFactor = (RainFactor)0; instance.affectPriorityOverTime = true; instance.locationOption = (LocationOption)0; instance.actionSource = (GoalActionSource)0; instance.roomOption = (RoomOption)0; } private static void AddSeekOutDetectiveGoalSetup(List<GoalActionSetup> goalSetupList) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown GoalActionSetup val = new GoalActionSetup { condition = (ActionCondition)2 }; val.actions.Add(SeekOutDetectiveAction.Instance); goalSetupList.Add(val); } private static void AddSeekOutDetectiveGoalModifiers(List<GoalModifierRule> modifierRules) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown List<CharacterTrait> val = new List<CharacterTrait>(); int num = 0; int num2 = 0; while (num < 3 && num2 < Toolbox.Instance.allCharacterTraits.Count) { CharacterTrait val2 = Toolbox.Instance.allCharacterTraits[num2]; if (((SoCustomComparison)val2).presetName == "Char-Trusting" || ((SoCustomComparison)val2).presetName == "Char-Friendly" || ((SoCustomComparison)val2).presetName == "Char-Honest") { val.Add(val2); num++; } num2++; } GoalModifierRule val3 = new GoalModifierRule { rule = (RuleType)0, traitList = val, mustPassForApplication = true, priorityMultiplier = 0f }; modifierRules.Add(val3); } } public class SeekOutDetectiveAction { public const string NAME = "by-the-book-seek-detective"; private static AIActionPreset _instance; public static AIActionPreset Instance { get { if ((SoCustomComparison)(object)_instance == (SoCustomComparison)null) { _instance = ScriptableObject.CreateInstance<AIActionPreset>(); Init(_instance); } return _instance; } } private static void Init(AIActionPreset instance) { //IL_0017: 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_002c: 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_003f: Expected O, but got Unknown ((SoCustomComparison)instance).presetName = "by-the-book-seek-detective"; ((Object)instance).name = ((SoCustomComparison)instance).presetName; AutomaticAction val = new AutomaticAction { forcedAction = ByTheBookDialogManager.Instance.TalkToAction, proximityCheck = true, additionalDelay = 0f }; instance.forcedActionsOnArrival.Add(val); instance.dontUpdateGoalPriorityWhileActive = true; instance.inputPriority = 11; instance.debug = true; instance.defaultKey = (InteractionKey)0; instance.actionLocation = (ActionLocation)15; instance.facePlayerWhileTalkingTo = true; instance.facing = (ActionFacingDirection)10; instance.runIfSeesPlayer = true; instance.completeOnSeeIllegal = true; instance.searchSetting = (FindSetting)1; instance.onUsePointBusy = (ActionBusy)1; instance.holsterCurrentItemOnAction = true; instance.disableConversationTriggers = true; instance.exitConversationOnActivate = true; } } }
JsonDiffPatch.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Tavis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v1.4", FrameworkDisplayName = "")] [assembly: AssemblyCompany("JsonDiffPatch")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Library for diffing and RFC 6902 patching json.net json objects - forked from Tavis.JsonPatch, with an addition of json diff code by Ian Mercer, with additional partial array LCS diff by JC Dickinson")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("JsonDiffPatch")] [assembly: AssemblyTitle("JsonDiffPatch")] [assembly: AssemblyVersion("1.0.0.0")] namespace Tavis { public class JsonPointer { private readonly IReadOnlyList<string> _Tokens; public JsonPointer ParentPointer { get { if (_Tokens.Count == 0) { return null; } string[] array = new string[_Tokens.Count - 1]; for (int i = 0; i < _Tokens.Count - 1; i++) { array[i] = _Tokens[i]; } return new JsonPointer(array); } } public JsonPointer(string pointer) { _Tokens = pointer.Split(new char[1] { '/' }).Skip(1).Select(Decode) .ToArray(); } internal JsonPointer(IReadOnlyList<string> tokens) { _Tokens = tokens; } private string Decode(string token) { return Uri.UnescapeDataString(token).Replace("~1", "/").Replace("~0", "~"); } public bool IsNewPointer() { return _Tokens[_Tokens.Count - 1] == "-"; } public JToken Find(JToken sample) { if (_Tokens.Count == 0) { return sample; } try { JToken val = sample; foreach (string item in _Tokens.Select((string t) => t.Replace("~1", "/").Replace("~0", "~"))) { if (val is JArray) { val = val[(object)Convert.ToInt32(item)]; continue; } val = val[(object)item]; if (val != null) { continue; } throw new ArgumentException("Cannot find " + item); } return val; } catch (Exception innerException) { throw new ArgumentException("Failed to dereference pointer", innerException); } } public override string ToString() { return "/" + string.Join("/", _Tokens); } } } namespace JsonDiffPatch { public abstract class AbstractPatcher<TDoc> where TDoc : class { public virtual void Patch(ref TDoc target, PatchDocument document) { foreach (Operation operation in document.Operations) { target = ApplyOperation(operation, target); } } public virtual TDoc ApplyOperation(Operation operation, TDoc target) { if (operation is AddOperation) { Add((AddOperation)operation, target); } else if (operation is CopyOperation) { Copy((CopyOperation)operation, target); } else if (operation is MoveOperation) { Move((MoveOperation)operation, target); } else if (operation is RemoveOperation) { Remove((RemoveOperation)operation, target); } else if (operation is ReplaceOperation) { target = Replace((ReplaceOperation)operation, target) ?? target; } else if (operation is TestOperation) { Test((TestOperation)operation, target); } return target; } protected abstract void Add(AddOperation operation, TDoc target); protected abstract void Copy(CopyOperation operation, TDoc target); protected abstract void Move(MoveOperation operation, TDoc target); protected abstract void Remove(RemoveOperation operation, TDoc target); protected abstract TDoc Replace(ReplaceOperation operation, TDoc target); protected abstract void Test(TestOperation operation, TDoc target); } public class AddOperation : Operation { public JToken Value { get; private set; } public AddOperation() { } public AddOperation(JsonPointer path, JToken value) : base(path) { Value = value; } public override void Write(JsonWriter writer) { writer.WriteStartObject(); Operation.WriteOp(writer, "add"); Operation.WritePath(writer, base.Path); Operation.WriteValue(writer, Value); writer.WriteEndObject(); } public override void Read(JObject jOperation) { base.Path = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("path"))); Value = jOperation.GetValue("value"); } } internal class ArrayLcs { public class BackTrackResult { public List<object> sequence { get; set; } = new List<object>(); public List<int> indices1 { get; set; } = new List<int>(); public List<int> indices2 { get; set; } = new List<int>(); } private readonly Func<object, object, bool> _matchObject; private Func<object[], object[], int, int, IDictionary, bool> _match; public ArrayLcs(Func<object, object, bool> matchObject) { _matchObject = matchObject; _match = (object[] array1, object[] array2, int index1, int index2, IDictionary context) => _matchObject(array1[index1], array2[index2]); } private int[][] LengthMatrix(object[] array1, object[] array2, IDictionary context) { int num = array1.Length; int num2 = array2.Length; int[][] array3 = new int[num + 1][]; for (int i = 0; i < array3.Length; i++) { array3[i] = Enumerable.Repeat(0, num2 + 1).ToArray(); } for (int j = 1; j < num + 1; j++) { for (int k = 1; k < num2 + 1; k++) { if (_match(array1, array2, j - 1, k - 1, context)) { array3[j][k] = 1 + array3[j - 1][k - 1]; } else { array3[j][k] = Math.Max(array3[j - 1][k], array3[j][k - 1]); } } } return array3; } private BackTrackResult backtrack(int[][] matrix, object[] array1, object[] array2, int index1, int index2, IDictionary context) { if (index1 == 0 || index2 == 0) { return new BackTrackResult(); } if (_match(array1, array2, index1 - 1, index2 - 1, context)) { BackTrackResult backTrackResult = backtrack(matrix, array1, array2, index1 - 1, index2 - 1, context); backTrackResult.sequence.Add(array1[index1 - 1]); backTrackResult.indices1.Add(index1 - 1); backTrackResult.indices2.Add(index2 - 1); return backTrackResult; } if (matrix[index1][index2 - 1] > matrix[index1 - 1][index2]) { return backtrack(matrix, array1, array2, index1, index2 - 1, context); } return backtrack(matrix, array1, array2, index1 - 1, index2, context); } public BackTrackResult Get(object[] array1, object[] array2, IDictionary context) { context = context ?? new Dictionary<string, object>(); int[][] matrix = LengthMatrix(array1, array2, context); return backtrack(matrix, array1, array2, array1.Length, array2.Length, context); } } public class CopyOperation : Operation { public JsonPointer FromPath { get; private set; } public CopyOperation() { } public CopyOperation(JsonPointer path, JsonPointer fromPath) : base(path) { FromPath = fromPath; } public override void Write(JsonWriter writer) { writer.WriteStartObject(); Operation.WriteOp(writer, "copy"); Operation.WritePath(writer, base.Path); Operation.WriteFromPath(writer, FromPath); writer.WriteEndObject(); } public override void Read(JObject jOperation) { base.Path = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("path"))); FromPath = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("from"))); } } public class JsonDiffer { private class MatchesKey : IEqualityComparer<KeyValuePair<string, JToken>> { public static MatchesKey Instance = new MatchesKey(); public bool Equals(KeyValuePair<string, JToken> x, KeyValuePair<string, JToken> y) { return x.Key.Equals(y.Key); } public int GetHashCode(KeyValuePair<string, JToken> obj) { return obj.Key.GetHashCode(); } } internal static string Extend(string path, string extension) { return path + "/" + EncodeKey(extension); } private static string EncodeKey(string key) { return key.Replace("~", "~0").Replace("/", "~1"); } private static Operation Build(string op, string path, string key, JToken value) { if (string.IsNullOrEmpty(key)) { return Operation.Parse("{ 'op' : '" + op + "' , path: '" + path + "', value: " + ((value == null) ? "null" : value.ToString((Formatting)0, Array.Empty<JsonConverter>())) + "}"); } return Operation.Parse("{ op : '" + op + "' , path : '" + Extend(path, key) + "' , value : " + ((value == null) ? "null" : value.ToString((Formatting)0, Array.Empty<JsonConverter>())) + "}"); } internal static Operation Add(string path, string key, JToken value) { return Build("add", path, key, value); } internal static Operation Remove(string path, string key) { return Build("remove", path, key, null); } internal static Operation Replace(string path, string key, JToken value) { return Build("replace", path, key, value); } internal static IEnumerable<Operation> CalculatePatch(JToken left, JToken right, bool useIdToDetermineEquality, string path = "") { if (left.Type != right.Type) { yield return Replace(path, "", right); } else if ((int)left.Type == 2) { Operation operation2 = null; foreach (Operation operation in ProcessArray(left, right, path, useIdToDetermineEquality)) { RemoveOperation removeOperation = operation2 as RemoveOperation; AddOperation addOperation = operation as AddOperation; if (removeOperation != null && addOperation != null && addOperation.Path.ToString() == removeOperation.Path.ToString()) { yield return Replace(addOperation.Path.ToString(), "", addOperation.Value); operation2 = null; continue; } if (operation2 != null) { yield return operation2; } operation2 = operation; } if (operation2 != null) { yield return operation2; } } else if ((int)left.Type == 1) { IOrderedEnumerable<KeyValuePair<string, JToken>> lprops = ((IDictionary<string, JToken>)left).OrderBy((KeyValuePair<string, JToken> p) => p.Key); IOrderedEnumerable<KeyValuePair<string, JToken>> rprops = ((IDictionary<string, JToken>)right).OrderBy((KeyValuePair<string, JToken> p) => p.Key); foreach (KeyValuePair<string, JToken> item in lprops.Except(rprops, MatchesKey.Instance)) { yield return Remove(path, item.Key); } foreach (KeyValuePair<string, JToken> item2 in rprops.Except(lprops, MatchesKey.Instance)) { yield return Add(path, item2.Key, item2.Value); } var enumerable = from k in lprops.Select((KeyValuePair<string, JToken> x) => x.Key).Intersect(rprops.Select((KeyValuePair<string, JToken> y) => y.Key)) select new { key = k, left = left[(object)k], right = right[(object)k] }; foreach (var item3 in enumerable) { string path2 = path + "/" + EncodeKey(item3.key); foreach (Operation item4 in CalculatePatch(item3.left, item3.right, useIdToDetermineEquality, path2)) { yield return item4; } } } else if (!(((object)left).ToString() == ((object)right).ToString())) { yield return Replace(path, "", right); } } private static IEnumerable<Operation> ProcessArray(JToken left, JToken right, string path, bool useIdPropertyToDetermineEquality) { CustomCheckEqualityComparer comparer = new CustomCheckEqualityComparer(useIdPropertyToDetermineEquality, (IEqualityComparer<JToken>)new JTokenEqualityComparer()); int commonHead = 0; int commonTail = 0; JToken[] array1 = ((IEnumerable<JToken>)left).ToArray(); int len1 = array1.Length; JToken[] array2 = ((IEnumerable<JToken>)right).ToArray(); int len2; for (len2 = array2.Length; commonHead < len1 && commonHead < len2 && comparer.Equals(array1[commonHead], array2[commonHead]); commonHead++) { foreach (Operation item in CalculatePatch(array1[commonHead], array2[commonHead], useIdPropertyToDetermineEquality, path + "/" + commonHead)) { yield return item; } } for (; commonTail + commonHead < len1 && commonTail + commonHead < len2 && comparer.Equals(array1[len1 - 1 - commonTail], array2[len2 - 1 - commonTail]); commonTail++) { int num = len1 - 1 - commonTail; int num2 = len2 - 1 - commonTail; foreach (Operation item2 in CalculatePatch(array1[num], array2[num2], useIdPropertyToDetermineEquality, path + "/" + num)) { yield return item2; } } if (commonHead == 0 && commonTail == 0 && len2 > 0 && len1 > 0) { yield return new ReplaceOperation(new JsonPointer(path), (JToken)new JArray((object[])array2)); yield break; } JToken[] leftMiddle = array1.Skip(commonHead).Take(array1.Length - commonTail - commonHead).ToArray(); JToken[] rightMiddle = array2.Skip(commonHead).Take(array2.Length - commonTail - commonHead).ToArray(); if (leftMiddle.Length == rightMiddle.Length) { for (int k = 0; k < leftMiddle.Length; k++) { foreach (Operation item3 in CalculatePatch(leftMiddle[k], rightMiddle[k], useIdPropertyToDetermineEquality, $"{path}/{commonHead + k}")) { yield return item3; } } yield break; } JToken[] array3 = leftMiddle; for (int k = 0; k < array3.Length; k++) { _ = array3[k]; yield return new RemoveOperation(new JsonPointer($"{path}/{commonHead}")); } for (int k = 0; k < rightMiddle.Length; k++) { yield return new AddOperation(new JsonPointer($"{path}/{commonHead + k}"), rightMiddle[k]); } } public PatchDocument Diff(JToken from, JToken to, bool useIdPropertyToDetermineEquality) { return new PatchDocument(CalculatePatch(from, to, useIdPropertyToDetermineEquality).ToArray()); } } internal class CustomCheckEqualityComparer : IEqualityComparer<JToken> { private readonly bool _enableIdCheck; private readonly IEqualityComparer<JToken> _inner; public CustomCheckEqualityComparer(bool enableIdCheck, IEqualityComparer<JToken> inner) { _enableIdCheck = enableIdCheck; _inner = inner; } public bool Equals(JToken x, JToken y) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if (_enableIdCheck && (int)x.Type == 1 && (int)y.Type == 1) { JToken val = x[(object)"id"]; JToken val2 = y[(object)"id"]; string text = ((val != null) ? Extensions.Value<string>((IEnumerable<JToken>)val) : null); string text2 = ((val2 != null) ? Extensions.Value<string>((IEnumerable<JToken>)val2) : null); if (text != null && text == text2) { return true; } } return _inner.Equals(x, y); } public int GetHashCode(JToken obj) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (_enableIdCheck && (int)obj.Type == 1) { JToken val = obj[(object)"id"]; string text = ((val != null && val.HasValues) ? Extensions.Value<string>((IEnumerable<JToken>)val) : null); if (text != null) { return text.GetHashCode() + _inner.GetHashCode(obj); } } return _inner.GetHashCode(obj); } public static bool HaveEqualIds(JToken x, JToken y) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((int)x.Type == 1 && (int)y.Type == 1) { JToken val = x[(object)"id"]; JToken val2 = y[(object)"id"]; string text = ((val != null) ? Extensions.Value<string>((IEnumerable<JToken>)val) : null); string text2 = ((val2 != null) ? Extensions.Value<string>((IEnumerable<JToken>)val2) : null); if (text != null) { return text == text2; } return false; } return false; } } public class JsonPatcher : AbstractPatcher<JToken> { protected override JToken Replace(ReplaceOperation operation, JToken target) { operation.Path.ToString().Replace("~1", "/").Replace("~0", "~"); JToken val = operation.Path.Find(target); if (val.Parent == null) { return operation.Value; } val.Replace(operation.Value); return null; } protected override void Add(AddOperation operation, JToken target) { JToken val = null; JObject val2 = null; string text = operation.Path.ParentPointer.ToString(); int startIndex = ((text == "/") ? text.Length : (text.Length + 1)); string text2 = operation.Path.ToString().Substring(startIndex).Replace("~1", "/") .Replace("~0", "~"); try { JToken obj = operation.Path.ParentPointer.Find(target); JArray val3 = (JArray)(object)((obj is JArray) ? obj : null); bool flag = operation.Path.IsNewPointer(); if (!(val3 == null || flag)) { val3.Insert(int.Parse(text2), operation.Value); return; } val = (JToken)((!flag) ? ((object)operation.Path.Find(target)) : ((object)/*isinst with value type is only supported in some contexts*/)); } catch (ArgumentException) { JToken obj2 = operation.Path.ParentPointer.Find(target); val2 = (JObject)(object)((obj2 is JObject) ? obj2 : null); } if (val == null && val2 != null) { val2.Add(text2, operation.Value); } else if (val is JArray) { ((JArray)((val is JArray) ? val : null)).Add(operation.Value); } else if (val.Parent is JProperty) { JContainer parent = val.Parent; ((JProperty)((parent is JProperty) ? parent : null)).Value = operation.Value; } } protected override void Remove(RemoveOperation operation, JToken target) { JToken val = operation.Path.Find(target); if (val.Parent is JProperty) { ((JToken)val.Parent).Remove(); } else { val.Remove(); } } protected override void Move(MoveOperation operation, JToken target) { if (operation.Path.ToString().StartsWith(operation.FromPath.ToString())) { throw new ArgumentException("To path cannot be below from path"); } JToken value = operation.FromPath.Find(target); Remove(new RemoveOperation(operation.FromPath), target); Add(new AddOperation(operation.Path, value), target); } protected override void Test(TestOperation operation, JToken target) { if (!((object)operation.Path.Find(target)).Equals((object?)target)) { throw new InvalidOperationException("Value at " + operation.Path.ToString() + " does not match."); } } protected override void Copy(CopyOperation operation, JToken target) { JToken value = operation.FromPath.Find(target); Add(new AddOperation(operation.Path, value), target); } } public class MoveOperation : Operation { public JsonPointer FromPath { get; private set; } public MoveOperation() { } public MoveOperation(JsonPointer path, JsonPointer fromPath) : base(path) { FromPath = fromPath; } public override void Write(JsonWriter writer) { writer.WriteStartObject(); Operation.WriteOp(writer, "move"); Operation.WritePath(writer, base.Path); Operation.WriteFromPath(writer, FromPath); writer.WriteEndObject(); } public override void Read(JObject jOperation) { base.Path = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("path"))); FromPath = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("from"))); } } public abstract class Operation { public JsonPointer Path { get; protected set; } public Operation() { } public Operation(JsonPointer path) { Path = path; } public abstract void Write(JsonWriter writer); protected static void WriteOp(JsonWriter writer, string op) { writer.WritePropertyName("op"); writer.WriteValue(op); } protected static void WritePath(JsonWriter writer, JsonPointer pointer) { writer.WritePropertyName("path"); writer.WriteValue(pointer.ToString()); } protected static void WriteFromPath(JsonWriter writer, JsonPointer pointer) { writer.WritePropertyName("from"); writer.WriteValue(pointer.ToString()); } protected static void WriteValue(JsonWriter writer, JToken value) { writer.WritePropertyName("value"); value.WriteTo(writer, Array.Empty<JsonConverter>()); } protected static string[] SplitPath(string path) { return path.Split(new char[1] { '/' }).Skip(1).ToArray(); } public abstract void Read(JObject jOperation); public static Operation Parse(string json) { return Build(JObject.Parse(json)); } public static Operation Build(JObject jOperation) { Operation operation = PatchDocument.CreateOperation((string)jOperation["op"]); operation.Read(jOperation); return operation; } } public class PatchDocument { private readonly List<Operation> _Operations = new List<Operation>(); public IReadOnlyCollection<Operation> Operations => _Operations; public PatchDocument(params Operation[] operations) { _Operations.AddRange(operations); } public void AddOperation(Operation operation) { _Operations.Add(operation); } public static PatchDocument Load(Stream document) { return Parse(new StreamReader(document).ReadToEnd()); } public static PatchDocument Load(JArray document) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) PatchDocument patchDocument = new PatchDocument(); if (document != null) { foreach (JObject item in ((IEnumerable)(object)((JToken)document).Children()).Cast<JObject>()) { Operation operation = Operation.Build(item); patchDocument.AddOperation(operation); } } return patchDocument; } public static PatchDocument Parse(string jsondocument) { JToken obj = JToken.Parse(jsondocument); return Load((JArray)(object)((obj is JArray) ? obj : null)); } public static Operation CreateOperation(string op) { return op switch { "add" => new AddOperation(), "copy" => new CopyOperation(), "move" => new MoveOperation(), "remove" => new RemoveOperation(), "replace" => new ReplaceOperation(), "test" => new TestOperation(), _ => null, }; } public MemoryStream ToStream() { MemoryStream memoryStream = new MemoryStream(); CopyToStream(memoryStream, (Formatting)1); memoryStream.Flush(); memoryStream.Position = 0L; return memoryStream; } public void CopyToStream(Stream stream, Formatting formatting = 1) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) JsonTextWriter val = new JsonTextWriter((TextWriter)new StreamWriter(stream)); ((JsonWriter)val).Formatting = formatting; ((JsonWriter)val).WriteStartArray(); foreach (Operation operation in Operations) { operation.Write((JsonWriter)(object)val); } ((JsonWriter)val).WriteEndArray(); ((JsonWriter)val).Flush(); } public override string ToString() { return ToString((Formatting)1); } public string ToString(Formatting formatting) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) using MemoryStream memoryStream = new MemoryStream(); CopyToStream(memoryStream, formatting); memoryStream.Position = 0L; using StreamReader streamReader = new StreamReader(memoryStream, Encoding.UTF8); return streamReader.ReadToEnd(); } } public class RemoveOperation : Operation { public RemoveOperation() { } public RemoveOperation(JsonPointer path) : base(path) { } public override void Write(JsonWriter writer) { writer.WriteStartObject(); Operation.WriteOp(writer, "remove"); Operation.WritePath(writer, base.Path); writer.WriteEndObject(); } public override void Read(JObject jOperation) { base.Path = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("path"))); } } public class ReplaceOperation : Operation { public JToken Value { get; private set; } public ReplaceOperation() { } public ReplaceOperation(JsonPointer path, JToken value) : base(path) { Value = value; } public override void Write(JsonWriter writer) { writer.WriteStartObject(); Operation.WriteOp(writer, "replace"); Operation.WritePath(writer, base.Path); Operation.WriteValue(writer, Value); writer.WriteEndObject(); } public override void Read(JObject jOperation) { base.Path = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("path"))); Value = jOperation.GetValue("value"); } } public class TestOperation : Operation { public JToken Value { get; private set; } public TestOperation() { } public TestOperation(JsonPointer path, JToken value) : base(path) { Value = value; } public override void Write(JsonWriter writer) { writer.WriteStartObject(); Operation.WriteOp(writer, "test"); Operation.WritePath(writer, base.Path); Operation.WriteValue(writer, Value); writer.WriteEndObject(); } public override void Read(JObject jOperation) { base.Path = new JsonPointer(Operation.SplitPath((string)jOperation.GetValue("path"))); Value = jOperation.GetValue("value"); } } }
Newtonsoft.Json.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Data; using System.Data.SqlTypes; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Runtime.Versioning; using System.Security; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Bson; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq.JsonPath; using Newtonsoft.Json.Schema; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] [assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")] [assembly: CLSCompliant(true)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Newtonsoft")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © James Newton-King 2008")] [assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")] [assembly: AssemblyFileVersion("13.0.3.27908")] [assembly: AssemblyInformationalVersion("13.0.3+0a2e291c0d9c0c7675d445703e51750363a549ef")] [assembly: AssemblyProduct("Json.NET")] [assembly: AssemblyTitle("Json.NET .NET 6.0")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyVersion("13.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Newtonsoft.Json { public enum ConstructorHandling { Default, AllowNonPublicDefaultConstructor } public enum DateFormatHandling { IsoDateFormat, MicrosoftDateFormat } public enum DateParseHandling { None, DateTime, DateTimeOffset } public enum DateTimeZoneHandling { Local, Utc, Unspecified, RoundtripKind } public class DefaultJsonNameTable : JsonNameTable { private class Entry { internal readonly string Value; internal readonly int HashCode; internal Entry Next; internal Entry(string value, int hashCode, Entry next) { Value = value; HashCode = hashCode; Next = next; } } private static readonly int HashCodeRandomizer; private int _count; private Entry[] _entries; private int _mask = 31; static DefaultJsonNameTable() { HashCodeRandomizer = Environment.TickCount; } public DefaultJsonNameTable() { _entries = new Entry[_mask + 1]; } public override string? Get(char[] key, int start, int length) { if (length == 0) { return string.Empty; } int num = length + HashCodeRandomizer; num += (num << 7) ^ key[start]; int num2 = start + length; for (int i = start + 1; i < num2; i++) { num += (num << 7) ^ key[i]; } num -= num >> 17; num -= num >> 11; num -= num >> 5; int num3 = Volatile.Read(ref _mask); int num4 = num & num3; for (Entry entry = _entries[num4]; entry != null; entry = entry.Next) { if (entry.HashCode == num && TextEquals(entry.Value, key, start, length)) { return entry.Value; } } return null; } public string Add(string key) { if (key == null) { throw new ArgumentNullException("key"); } int length = key.Length; if (length == 0) { return string.Empty; } int num = length + HashCodeRandomizer; for (int i = 0; i < key.Length; i++) { num += (num << 7) ^ key[i]; } num -= num >> 17; num -= num >> 11; num -= num >> 5; for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next) { if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal)) { return entry.Value; } } return AddEntry(key, num); } private string AddEntry(string str, int hashCode) { int num = hashCode & _mask; Entry entry = new Entry(str, hashCode, _entries[num]); _entries[num] = entry; if (_count++ == _mask) { Grow(); } return entry.Value; } private void Grow() { Entry[] entries = _entries; int num = _mask * 2 + 1; Entry[] array = new Entry[num + 1]; for (int i = 0; i < entries.Length; i++) { Entry entry = entries[i]; while (entry != null) { int num2 = entry.HashCode & num; Entry next = entry.Next; entry.Next = array[num2]; array[num2] = entry; entry = next; } } _entries = array; Volatile.Write(ref _mask, num); } private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length) { if (str1.Length != str2Length) { return false; } for (int i = 0; i < str1.Length; i++) { if (str1[i] != str2[str2Start + i]) { return false; } } return true; } } [Flags] public enum DefaultValueHandling { Include = 0, Ignore = 1, Populate = 2, IgnoreAndPopulate = 3 } public enum FloatFormatHandling { String, Symbol, DefaultValue } public enum FloatParseHandling { Double, Decimal } public enum Formatting { None, Indented } public interface IArrayPool<T> { T[] Rent(int minimumLength); void Return(T[]? array); } public interface IJsonLineInfo { int LineNumber { get; } int LinePosition { get; } bool HasLineInfo(); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonArrayAttribute : JsonContainerAttribute { private bool _allowNullItems; public bool AllowNullItems { get { return _allowNullItems; } set { _allowNullItems = value; } } public JsonArrayAttribute() { } public JsonArrayAttribute(bool allowNullItems) { _allowNullItems = allowNullItems; } public JsonArrayAttribute(string id) : base(id) { } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] public sealed class JsonConstructorAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public abstract class JsonContainerAttribute : Attribute { internal bool? _isReference; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; private Type? _namingStrategyType; private object[]? _namingStrategyParameters; public string? Id { get; set; } public string? Title { get; set; } public string? Description { get; set; } public Type? ItemConverterType { get; set; } public object[]? ItemConverterParameters { get; set; } public Type? NamingStrategyType { get { return _namingStrategyType; } set { _namingStrategyType = value; NamingStrategyInstance = null; } } public object[]? NamingStrategyParameters { get { return _namingStrategyParameters; } set { _namingStrategyParameters = value; NamingStrategyInstance = null; } } internal NamingStrategy? NamingStrategyInstance { get; set; } public bool IsReference { get { return _isReference.GetValueOrDefault(); } set { _isReference = value; } } public bool ItemIsReference { get { return _itemIsReference.GetValueOrDefault(); } set { _itemIsReference = value; } } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling.GetValueOrDefault(); } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling.GetValueOrDefault(); } set { _itemTypeNameHandling = value; } } protected JsonContainerAttribute() { } protected JsonContainerAttribute(string id) { Id = id; } } public static class JsonConvert { public static readonly string True = "true"; public static readonly string False = "false"; public static readonly string Null = "null"; public static readonly string Undefined = "undefined"; public static readonly string PositiveInfinity = "Infinity"; public static readonly string NegativeInfinity = "-Infinity"; public static readonly string NaN = "NaN"; public static Func<JsonSerializerSettings>? DefaultSettings { get; set; } public static string ToString(DateTime value) { return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); } public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) { DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling); using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(DateTimeOffset value) { return ToString(value, DateFormatHandling.IsoDateFormat); } public static string ToString(DateTimeOffset value, DateFormatHandling format) { using StringWriter stringWriter = StringUtils.CreateStringWriter(64); stringWriter.Write('"'); DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture); stringWriter.Write('"'); return stringWriter.ToString(); } public static string ToString(bool value) { if (!value) { return False; } return True; } public static string ToString(char value) { return ToString(char.ToString(value)); } public static string ToString(Enum value) { return value.ToString("D"); } public static string ToString(int value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(short value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ushort value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(uint value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(long value) { return value.ToString(null, CultureInfo.InvariantCulture); } private static string ToStringInternal(BigInteger value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(ulong value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(float value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value))) { return text; } if (floatFormatHandling == FloatFormatHandling.DefaultValue) { if (nullable) { return Null; } return "0.0"; } return quoteChar + text + quoteChar; } public static string ToString(double value) { return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); } internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) { return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); } private static string EnsureDecimalPlace(double value, string text) { if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1) { return text; } return text + ".0"; } private static string EnsureDecimalPlace(string text) { if (StringUtils.IndexOf(text, '.') != -1) { return text; } return text + ".0"; } public static string ToString(byte value) { return value.ToString(null, CultureInfo.InvariantCulture); } [CLSCompliant(false)] public static string ToString(sbyte value) { return value.ToString(null, CultureInfo.InvariantCulture); } public static string ToString(decimal value) { return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); } public static string ToString(Guid value) { return ToString(value, '"'); } internal static string ToString(Guid value, char quoteChar) { string text = value.ToString("D", CultureInfo.InvariantCulture); string text2 = quoteChar.ToString(CultureInfo.InvariantCulture); return text2 + text + text2; } public static string ToString(TimeSpan value) { return ToString(value, '"'); } internal static string ToString(TimeSpan value, char quoteChar) { return ToString(value.ToString(), quoteChar); } public static string ToString(Uri? value) { if (value == null) { return Null; } return ToString(value, '"'); } internal static string ToString(Uri value, char quoteChar) { return ToString(value.OriginalString, quoteChar); } public static string ToString(string? value) { return ToString(value, '"'); } public static string ToString(string? value, char delimiter) { return ToString(value, delimiter, StringEscapeHandling.Default); } public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling) { if (delimiter != '"' && delimiter != '\'') { throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter"); } return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling); } public static string ToString(object? value) { if (value == null) { return Null; } return ConvertUtils.GetTypeCode(value.GetType()) switch { PrimitiveTypeCode.String => ToString((string)value), PrimitiveTypeCode.Char => ToString((char)value), PrimitiveTypeCode.Boolean => ToString((bool)value), PrimitiveTypeCode.SByte => ToString((sbyte)value), PrimitiveTypeCode.Int16 => ToString((short)value), PrimitiveTypeCode.UInt16 => ToString((ushort)value), PrimitiveTypeCode.Int32 => ToString((int)value), PrimitiveTypeCode.Byte => ToString((byte)value), PrimitiveTypeCode.UInt32 => ToString((uint)value), PrimitiveTypeCode.Int64 => ToString((long)value), PrimitiveTypeCode.UInt64 => ToString((ulong)value), PrimitiveTypeCode.Single => ToString((float)value), PrimitiveTypeCode.Double => ToString((double)value), PrimitiveTypeCode.DateTime => ToString((DateTime)value), PrimitiveTypeCode.Decimal => ToString((decimal)value), PrimitiveTypeCode.DBNull => Null, PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), PrimitiveTypeCode.Guid => ToString((Guid)value), PrimitiveTypeCode.Uri => ToString((Uri)value), PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), _ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), }; } [DebuggerStepThrough] public static string SerializeObject(object? value) { return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static string SerializeObject(object? value, Formatting formatting) { return SerializeObject(value, formatting, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static string SerializeObject(object? value, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return SerializeObject(value, null, formatting, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, JsonSerializerSettings? settings) { return SerializeObject(value, null, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); return SerializeObjectInternal(value, type, jsonSerializer); } [DebuggerStepThrough] public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings) { return SerializeObject(value, null, formatting, settings); } [DebuggerStepThrough] public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); jsonSerializer.Formatting = formatting; return SerializeObjectInternal(value, type, jsonSerializer); } private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer) { StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture); using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter)) { jsonTextWriter.Formatting = jsonSerializer.Formatting; jsonSerializer.Serialize(jsonTextWriter, value, type); } return stringWriter.ToString(); } [DebuggerStepThrough] public static object? DeserializeObject(string value) { return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static object? DeserializeObject(string value, JsonSerializerSettings settings) { return DeserializeObject(value, null, settings); } [DebuggerStepThrough] public static object? DeserializeObject(string value, Type type) { return DeserializeObject(value, type, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static T? DeserializeObject<T>(string value) { return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null); } [DebuggerStepThrough] public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject) { return DeserializeObject<T>(value); } [DebuggerStepThrough] public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings) { return DeserializeObject<T>(value, settings); } [DebuggerStepThrough] public static T? DeserializeObject<T>(string value, params JsonConverter[] converters) { return (T)DeserializeObject(value, typeof(T), converters); } [DebuggerStepThrough] public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings) { return (T)DeserializeObject(value, typeof(T), settings); } [DebuggerStepThrough] public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters) { JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings { Converters = converters } : null); return DeserializeObject(value, type, settings); } public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings) { ValidationUtils.ArgumentNotNull(value, "value"); JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); if (!jsonSerializer.IsCheckAdditionalContentSet()) { jsonSerializer.CheckAdditionalContent = true; } using JsonTextReader reader = new JsonTextReader(new StringReader(value)); return jsonSerializer.Deserialize(reader, type); } [DebuggerStepThrough] public static void PopulateObject(string value, object target) { PopulateObject(value, target, null); } public static void PopulateObject(string value, object target, JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); using JsonReader jsonReader = new JsonTextReader(new StringReader(value)); jsonSerializer.Populate(jsonReader, target); if (settings == null || !settings.CheckAdditionalContent) { return; } while (jsonReader.Read()) { if (jsonReader.TokenType != JsonToken.Comment) { throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object."); } } } public static string SerializeXmlNode(XmlNode? node) { return SerializeXmlNode(node, Formatting.None); } public static string SerializeXmlNode(XmlNode? node, Formatting formatting) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); return SerializeObject(node, formatting, xmlNodeConverter); } public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter { OmitRootObject = omitRootObject }; return SerializeObject(node, formatting, xmlNodeConverter); } public static XmlDocument? DeserializeXmlNode(string value) { return DeserializeXmlNode(value, null); } public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName) { return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false); } public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute) { return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false); } public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters; return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter); } public static string SerializeXNode(XObject? node) { return SerializeXNode(node, Formatting.None); } public static string SerializeXNode(XObject? node, Formatting formatting) { return SerializeXNode(node, formatting, omitRootObject: false); } public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter { OmitRootObject = omitRootObject }; return SerializeObject(node, formatting, xmlNodeConverter); } public static XDocument? DeserializeXNode(string value) { return DeserializeXNode(value, null); } public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName) { return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false); } public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute) { return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false); } public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters) { XmlNodeConverter xmlNodeConverter = new XmlNodeConverter(); xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName; xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute; xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters; return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter); } } public abstract class JsonConverter { public virtual bool CanRead => true; public virtual bool CanWrite => true; public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer); public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer); public abstract bool CanConvert(Type objectType); } public abstract class JsonConverter<T> : JsonConverter { public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T)))) { throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T))); } WriteJson(writer, (T)value, serializer); } public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer); public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { bool flag = existingValue == null; if (!flag && !(existingValue is T)) { throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T))); } return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer); } public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer); public sealed override bool CanConvert(Type objectType) { return typeof(T).IsAssignableFrom(objectType); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonConverterAttribute : Attribute { private readonly Type _converterType; public Type ConverterType => _converterType; public object[]? ConverterParameters { get; } public JsonConverterAttribute(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } _converterType = converterType; } public JsonConverterAttribute(Type converterType, params object[] converterParameters) : this(converterType) { ConverterParameters = converterParameters; } } public class JsonConverterCollection : Collection<JsonConverter> { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonDictionaryAttribute : JsonContainerAttribute { public JsonDictionaryAttribute() { } public JsonDictionaryAttribute(string id) : base(id) { } } [Serializable] public class JsonException : Exception { public JsonException() { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception? innerException) : base(message, innerException) { } public JsonException(SerializationInfo info, StreamingContext context) : base(info, context) { } internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message) { message = JsonPosition.FormatMessage(lineInfo, path, message); return new JsonException(message); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class JsonExtensionDataAttribute : Attribute { public bool WriteData { get; set; } public bool ReadData { get; set; } public JsonExtensionDataAttribute() { WriteData = true; ReadData = true; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonIgnoreAttribute : Attribute { } public abstract class JsonNameTable { public abstract string? Get(char[] key, int start, int length); } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] public sealed class JsonObjectAttribute : JsonContainerAttribute { private MemberSerialization _memberSerialization; internal MissingMemberHandling? _missingMemberHandling; internal Required? _itemRequired; internal NullValueHandling? _itemNullValueHandling; public MemberSerialization MemberSerialization { get { return _memberSerialization; } set { _memberSerialization = value; } } public MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling.GetValueOrDefault(); } set { _missingMemberHandling = value; } } public NullValueHandling ItemNullValueHandling { get { return _itemNullValueHandling.GetValueOrDefault(); } set { _itemNullValueHandling = value; } } public Required ItemRequired { get { return _itemRequired.GetValueOrDefault(); } set { _itemRequired = value; } } public JsonObjectAttribute() { } public JsonObjectAttribute(MemberSerialization memberSerialization) { MemberSerialization = memberSerialization; } public JsonObjectAttribute(string id) : base(id) { } } internal enum JsonContainerType { None, Object, Array, Constructor } internal struct JsonPosition { private static readonly char[] SpecialCharacters = new char[18] { '.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t', '\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029' }; internal JsonContainerType Type; internal int Position; internal string? PropertyName; internal bool HasIndex; public JsonPosition(JsonContainerType type) { Type = type; HasIndex = TypeHasIndex(type); Position = -1; PropertyName = null; } internal int CalculateLength() { switch (Type) { case JsonContainerType.Object: return PropertyName.Length + 5; case JsonContainerType.Array: case JsonContainerType.Constructor: return MathUtils.IntLength((ulong)Position) + 2; default: throw new ArgumentOutOfRangeException("Type"); } } internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer) { switch (Type) { case JsonContainerType.Object: { string propertyName = PropertyName; if (propertyName.IndexOfAny(SpecialCharacters) != -1) { sb.Append("['"); if (writer == null) { writer = new StringWriter(sb); } JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer); sb.Append("']"); } else { if (sb.Length > 0) { sb.Append('.'); } sb.Append(propertyName); } break; } case JsonContainerType.Array: case JsonContainerType.Constructor: sb.Append('['); sb.Append(Position); sb.Append(']'); break; } } internal static bool TypeHasIndex(JsonContainerType type) { if (type != JsonContainerType.Array) { return type == JsonContainerType.Constructor; } return true; } internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition) { int num = 0; if (positions != null) { for (int i = 0; i < positions.Count; i++) { num += positions[i].CalculateLength(); } } if (currentPosition.HasValue) { num += currentPosition.GetValueOrDefault().CalculateLength(); } StringBuilder stringBuilder = new StringBuilder(num); StringWriter writer = null; char[] buffer = null; if (positions != null) { foreach (JsonPosition position in positions) { position.WriteTo(stringBuilder, ref writer, ref buffer); } } currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer); return stringBuilder.ToString(); } internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message) { if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal)) { message = message.Trim(); if (!message.EndsWith('.')) { message += "."; } message += " "; } message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path); if (lineInfo != null && lineInfo.HasLineInfo()) { message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition); } message += "."; return message; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class JsonPropertyAttribute : Attribute { internal NullValueHandling? _nullValueHandling; internal DefaultValueHandling? _defaultValueHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal ObjectCreationHandling? _objectCreationHandling; internal TypeNameHandling? _typeNameHandling; internal bool? _isReference; internal int? _order; internal Required? _required; internal bool? _itemIsReference; internal ReferenceLoopHandling? _itemReferenceLoopHandling; internal TypeNameHandling? _itemTypeNameHandling; public Type? ItemConverterType { get; set; } public object[]? ItemConverterParameters { get; set; } public Type? NamingStrategyType { get; set; } public object[]? NamingStrategyParameters { get; set; } public NullValueHandling NullValueHandling { get { return _nullValueHandling.GetValueOrDefault(); } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling.GetValueOrDefault(); } set { _defaultValueHandling = value; } } public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling.GetValueOrDefault(); } set { _referenceLoopHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling.GetValueOrDefault(); } set { _objectCreationHandling = value; } } public TypeNameHandling TypeNameHandling { get { return _typeNameHandling.GetValueOrDefault(); } set { _typeNameHandling = value; } } public bool IsReference { get { return _isReference.GetValueOrDefault(); } set { _isReference = value; } } public int Order { get { return _order.GetValueOrDefault(); } set { _order = value; } } public Required Required { get { return _required.GetValueOrDefault(); } set { _required = value; } } public string? PropertyName { get; set; } public ReferenceLoopHandling ItemReferenceLoopHandling { get { return _itemReferenceLoopHandling.GetValueOrDefault(); } set { _itemReferenceLoopHandling = value; } } public TypeNameHandling ItemTypeNameHandling { get { return _itemTypeNameHandling.GetValueOrDefault(); } set { _itemTypeNameHandling = value; } } public bool ItemIsReference { get { return _itemIsReference.GetValueOrDefault(); } set { _itemIsReference = value; } } public JsonPropertyAttribute() { } public JsonPropertyAttribute(string propertyName) { PropertyName = propertyName; } } public abstract class JsonReader : IAsyncDisposable, IDisposable { protected internal enum State { Start, Complete, Property, ObjectStart, Object, ArrayStart, Array, Closed, PostValue, ConstructorStart, Constructor, Error, Finished } private JsonToken _tokenType; private object? _value; internal char _quoteChar; internal State _currentState; private JsonPosition _currentPosition; private CultureInfo? _culture; private DateTimeZoneHandling _dateTimeZoneHandling; private int? _maxDepth; private bool _hasExceededMaxDepth; internal DateParseHandling _dateParseHandling; internal FloatParseHandling _floatParseHandling; private string? _dateFormatString; private List<JsonPosition>? _stack; protected State CurrentState => _currentState; public bool CloseInput { get; set; } public bool SupportMultipleContent { get; set; } public virtual char QuoteChar { get { return _quoteChar; } protected internal set { _quoteChar = value; } } public DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling; } set { if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind) { throw new ArgumentOutOfRangeException("value"); } _dateTimeZoneHandling = value; } } public DateParseHandling DateParseHandling { get { return _dateParseHandling; } set { if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset) { throw new ArgumentOutOfRangeException("value"); } _dateParseHandling = value; } } public FloatParseHandling FloatParseHandling { get { return _floatParseHandling; } set { if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal) { throw new ArgumentOutOfRangeException("value"); } _floatParseHandling = value; } } public string? DateFormatString { get { return _dateFormatString; } set { _dateFormatString = value; } } public int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; } } public virtual JsonToken TokenType => _tokenType; public virtual object? Value => _value; public virtual Type? ValueType => _value?.GetType(); public virtual int Depth { get { int num = _stack?.Count ?? 0; if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None) { return num; } return num + 1; } } public virtual string Path { get { if (_currentPosition.Type == JsonContainerType.None) { return string.Empty; } JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null); return JsonPosition.BuildPath(_stack, currentPosition); } } public CultureInfo Culture { get { return _culture ?? CultureInfo.InvariantCulture; } set { _culture = value; } } ValueTask IAsyncDisposable.DisposeAsync() { try { Dispose(disposing: true); return default(ValueTask); } catch (Exception exception) { return ValueTask.FromException(exception); } } public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync(); } public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (TokenType == JsonToken.PropertyName) { await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } if (JsonTokenUtils.IsStartToken(TokenType)) { int depth = Depth; while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth) { } } } internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken) { if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))) { throw CreateUnexpectedEndException(); } } public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean()); } public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes()); } internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken) { List<byte> buffer = new List<byte>(); do { if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))) { SetToken(JsonToken.None); } } while (!ReadArrayElementIntoByteArrayReportDone(buffer)); byte[] array = buffer.ToArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime()); } public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset()); } public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal()); } public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(ReadAsDouble()); } public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32()); } public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken)) { return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString()); } internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken) { bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (flag) { flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } return flag; } internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken) { JsonToken tokenType = TokenType; if (tokenType == JsonToken.None || tokenType == JsonToken.Comment) { return MoveToContentFromNonContentAsync(cancellationToken); } return AsyncUtils.True; } private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken) { JsonToken tokenType; do { if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))) { return false; } tokenType = TokenType; } while (tokenType == JsonToken.None || tokenType == JsonToken.Comment); return true; } internal JsonPosition GetPosition(int depth) { if (_stack != null && depth < _stack.Count) { return _stack[depth]; } return _currentPosition; } protected JsonReader() { _currentState = State.Start; _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; _dateParseHandling = DateParseHandling.DateTime; _floatParseHandling = FloatParseHandling.Double; _maxDepth = 64; CloseInput = true; } private void Push(JsonContainerType value) { UpdateScopeWithFinishedValue(); if (_currentPosition.Type == JsonContainerType.None) { _currentPosition = new JsonPosition(value); return; } if (_stack == null) { _stack = new List<JsonPosition>(); } _stack.Add(_currentPosition); _currentPosition = new JsonPosition(value); if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth) { return; } _hasExceededMaxDepth = true; throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth)); } private JsonContainerType Pop() { JsonPosition currentPosition; if (_stack != null && _stack.Count > 0) { currentPosition = _currentPosition; _currentPosition = _stack[_stack.Count - 1]; _stack.RemoveAt(_stack.Count - 1); } else { currentPosition = _currentPosition; _currentPosition = default(JsonPosition); } if (_maxDepth.HasValue && Depth <= _maxDepth) { _hasExceededMaxDepth = false; } return currentPosition.Type; } private JsonContainerType Peek() { return _currentPosition.Type; } public abstract bool Read(); public virtual int? ReadAsInt32() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is int) { return (int)value; } int num; if (value is BigInteger bigInteger) { num = (int)bigInteger; } else { try { num = Convert.ToInt32(value, CultureInfo.InvariantCulture); } catch (Exception ex) { throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex); } } SetToken(JsonToken.Integer, num, updateIndex: false); return num; } case JsonToken.String: { string s = (string)Value; return ReadInt32String(s); } default: throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal int? ReadInt32String(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (int.TryParse(s, NumberStyles.Integer, Culture, out var result)) { SetToken(JsonToken.Integer, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual string? ReadAsString() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.String: return (string)Value; default: if (JsonTokenUtils.IsPrimitiveToken(contentToken)) { object value = Value; if (value != null) { string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture)); SetToken(JsonToken.String, text, updateIndex: false); return text; } } throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } public virtual byte[]? ReadAsBytes() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.StartObject: { ReadIntoWrappedTypeObject(); byte[] array2 = ReadAsBytes(); ReaderReadAndAssert(); if (TokenType != JsonToken.EndObject) { throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } SetToken(JsonToken.Bytes, array2, updateIndex: false); return array2; } case JsonToken.String: { string text = (string)Value; Guid g; byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray())); SetToken(JsonToken.Bytes, array3, updateIndex: false); return array3; } case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Bytes: if (Value is Guid guid) { byte[] array = guid.ToByteArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } return (byte[])Value; case JsonToken.StartArray: return ReadArrayIntoByteArray(); default: throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal byte[] ReadArrayIntoByteArray() { List<byte> list = new List<byte>(); do { if (!Read()) { SetToken(JsonToken.None); } } while (!ReadArrayElementIntoByteArrayReportDone(list)); byte[] array = list.ToArray(); SetToken(JsonToken.Bytes, array, updateIndex: false); return array; } private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer) { switch (TokenType) { case JsonToken.None: throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); case JsonToken.Integer: buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); return false; case JsonToken.EndArray: return true; case JsonToken.Comment: return false; default: throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } public virtual double? ReadAsDouble() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is double) { return (double)value; } double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger)); SetToken(JsonToken.Float, num, updateIndex: false); return num; } case JsonToken.String: return ReadDoubleString((string)Value); default: throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal double? ReadDoubleString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual bool? ReadAsBoolean() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L)); SetToken(JsonToken.Boolean, flag, updateIndex: false); return flag; } case JsonToken.String: return ReadBooleanString((string)Value); case JsonToken.Boolean: return (bool)Value; default: throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal bool? ReadBooleanString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (bool.TryParse(s, out var result)) { SetToken(JsonToken.Boolean, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual decimal? ReadAsDecimal() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Integer: case JsonToken.Float: { object value = Value; if (value is decimal) { return (decimal)value; } decimal num; if (value is BigInteger bigInteger) { num = (decimal)bigInteger; } else { try { num = Convert.ToDecimal(value, CultureInfo.InvariantCulture); } catch (Exception ex) { throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex); } } SetToken(JsonToken.Float, num, updateIndex: false); return num; } case JsonToken.String: return ReadDecimalString((string)Value); default: throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal decimal? ReadDecimalString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result)) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success) { SetToken(JsonToken.Float, result, updateIndex: false); return result; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTime? ReadAsDateTime() { switch (GetContentToken()) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTimeOffset dateTimeOffset) { SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false); } return (DateTime)Value; case JsonToken.String: return ReadDateTimeString((string)Value); default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); } } internal DateTime? ReadDateTimeString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } public virtual DateTimeOffset? ReadAsDateTimeOffset() { JsonToken contentToken = GetContentToken(); switch (contentToken) { case JsonToken.None: case JsonToken.Null: case JsonToken.EndArray: return null; case JsonToken.Date: if (Value is DateTime dateTime) { SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false); } return (DateTimeOffset)Value; case JsonToken.String: { string s = (string)Value; return ReadDateTimeOffsetString(s); } default: throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken)); } } internal DateTimeOffset? ReadDateTimeOffsetString(string? s) { if (StringUtils.IsNullOrEmpty(s)) { SetToken(JsonToken.Null, null, updateIndex: false); return null; } if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) { SetToken(JsonToken.Date, dt, updateIndex: false); return dt; } SetToken(JsonToken.String, s, updateIndex: false); throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s)); } internal void ReaderReadAndAssert() { if (!Read()) { throw CreateUnexpectedEndException(); } } internal JsonReaderException CreateUnexpectedEndException() { return JsonReaderException.Create(this, "Unexpected end when reading JSON."); } internal void ReadIntoWrappedTypeObject() { ReaderReadAndAssert(); if (Value != null && Value.ToString() == "$type") { ReaderReadAndAssert(); if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal)) { ReaderReadAndAssert(); if (Value.ToString() == "$value") { return; } } } throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject)); } public void Skip() { if (TokenType == JsonToken.PropertyName) { Read(); } if (JsonTokenUtils.IsStartToken(TokenType)) { int depth = Depth; while (Read() && depth < Depth) { } } } protected void SetToken(JsonToken newToken) { SetToken(newToken, null, updateIndex: true); } protected void SetToken(JsonToken newToken, object? value) { SetToken(newToken, value, updateIndex: true); } protected void SetToken(JsonToken newToken, object? value, bool updateIndex) { _tokenType = newToken; _value = value; switch (newToken) { case JsonToken.StartObject: _currentState = State.ObjectStart; Push(JsonContainerType.Object); break; case JsonToken.StartArray: _currentState = State.ArrayStart; Push(JsonContainerType.Array); break; case JsonToken.StartConstructor: _currentState = State.ConstructorStart; Push(JsonContainerType.Constructor); break; case JsonToken.EndObject: ValidateEnd(JsonToken.EndObject); break; case JsonToken.EndArray: ValidateEnd(JsonToken.EndArray); break; case JsonToken.EndConstructor: ValidateEnd(JsonToken.EndConstructor); break; case JsonToken.PropertyName: _currentState = State.Property; _currentPosition.PropertyName = (string)value; break; case JsonToken.Raw: case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: case JsonToken.Undefined: case JsonToken.Date: case JsonToken.Bytes: SetPostValueState(updateIndex); break; case JsonToken.Comment: break; } } internal void SetPostValueState(bool updateIndex) { if (Peek() != 0 || SupportMultipleContent) { _currentState = State.PostValue; } else { SetFinished(); } if (updateIndex) { UpdateScopeWithFinishedValue(); } } private void UpdateScopeWithFinishedValue() { if (_currentPosition.HasIndex) { _currentPosition.Position++; } } private void ValidateEnd(JsonToken endToken) { JsonContainerType jsonContainerType = Pop(); if (GetTypeForCloseToken(endToken) != jsonContainerType) { throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType)); } if (Peek() != 0 || SupportMultipleContent) { _currentState = State.PostValue; } else { SetFinished(); } } protected void SetStateBasedOnCurrent() { JsonContainerType jsonContainerType = Peek(); switch (jsonContainerType) { case JsonContainerType.Object: _currentState = State.Object; break; case JsonContainerType.Array: _currentState = State.Array; break; case JsonContainerType.Constructor: _currentState = State.Constructor; break; case JsonContainerType.None: SetFinished(); break; default: throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType)); } } private void SetFinished() { _currentState = ((!SupportMultipleContent) ? State.Finished : State.Start); } private JsonContainerType GetTypeForCloseToken(JsonToken token) { return token switch { JsonToken.EndObject => JsonContainerType.Object, JsonToken.EndArray => JsonContainerType.Array, JsonToken.EndConstructor => JsonContainerType.Constructor, _ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), }; } void IDisposable.Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_currentState != State.Closed && disposing) { Close(); } } public virtual void Close() { _currentState = State.Closed; _tokenType = JsonToken.None; _value = null; } internal void ReadAndAssert() { if (!Read()) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter) { if (!ReadForType(contract, hasConverter)) { throw JsonSerializationException.Create(this, "Unexpected end when reading JSON."); } } internal bool ReadForType(JsonContract? contract, bool hasConverter) { if (hasConverter) { return Read(); } switch (contract?.InternalReadType ?? ReadType.Read) { case ReadType.Read: return ReadAndMoveToContent(); case ReadType.ReadAsInt32: ReadAsInt32(); break; case ReadType.ReadAsInt64: { bool result = ReadAndMoveToContent(); if (TokenType == JsonToken.Undefined) { throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long))); } return result; } case ReadType.ReadAsDecimal: ReadAsDecimal(); break; case ReadType.ReadAsDouble: ReadAsDouble(); break; case ReadType.ReadAsBytes: ReadAsBytes(); break; case ReadType.ReadAsBoolean: ReadAsBoolean(); break; case ReadType.ReadAsString: ReadAsString(); break; case ReadType.ReadAsDateTime: ReadAsDateTime(); break; case ReadType.ReadAsDateTimeOffset: ReadAsDateTimeOffset(); break; default: throw new ArgumentOutOfRangeException(); } return TokenType != JsonToken.None; } internal bool ReadAndMoveToContent() { if (Read()) { return MoveToContent(); } return false; } internal bool MoveToContent() { JsonToken tokenType = TokenType; while (tokenType == JsonToken.None || tokenType == JsonToken.Comment) { if (!Read()) { return false; } tokenType = TokenType; } return true; } private JsonToken GetContentToken() { JsonToken tokenType; do { if (!Read()) { SetToken(JsonToken.None); return JsonToken.None; } tokenType = TokenType; } while (tokenType == JsonToken.Comment); return tokenType; } } [Serializable] public class JsonReaderException : JsonException { public int LineNumber { get; } public int LinePosition { get; } public string? Path { get; } public JsonReaderException() { } public JsonReaderException(string message) : base(message) { } public JsonReaderException(string message, Exception innerException) : base(message, innerException) { } public JsonReaderException(SerializationInfo info, StreamingContext context) : base(info, context) { } public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonReaderException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonReaderException(message, path, lineNumber, linePosition, ex); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonRequiredAttribute : Attribute { } [Serializable] public class JsonSerializationException : JsonException { public int LineNumber { get; } public int LinePosition { get; } public string? Path { get; } public JsonSerializationException() { } public JsonSerializationException(string message) : base(message) { } public JsonSerializationException(string message, Exception innerException) : base(message, innerException) { } public JsonSerializationException(SerializationInfo info, StreamingContext context) : base(info, context) { } public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException) : base(message, innerException) { Path = path; LineNumber = lineNumber; LinePosition = linePosition; } internal static JsonSerializationException Create(JsonReader reader, string message) { return Create(reader, message, null); } internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex) { return Create(reader as IJsonLineInfo, reader.Path, message, ex); } internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex) { message = JsonPosition.FormatMessage(lineInfo, path, message); int lineNumber; int linePosition; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } else { lineNumber = 0; linePosition = 0; } return new JsonSerializationException(message, path, lineNumber, linePosition, ex); } } public class JsonSerializer { internal TypeNameHandling _typeNameHandling; internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling; internal PreserveReferencesHandling _preserveReferencesHandling; internal ReferenceLoopHandling _referenceLoopHandling; internal MissingMemberHandling _missingMemberHandling; internal ObjectCreationHandling _objectCreationHandling; internal NullValueHandling _nullValueHandling; internal DefaultValueHandling _defaultValueHandling; internal ConstructorHandling _constructorHandling; internal MetadataPropertyHandling _metadataPropertyHandling; internal JsonConverterCollection? _converters; internal IContractResolver _contractResolver; internal ITraceWriter? _traceWriter; internal IEqualityComparer? _equalityComparer; internal ISerializationBinder _serializationBinder; internal StreamingContext _context; private IReferenceResolver? _referenceResolver; private Formatting? _formatting; private DateFormatHandling? _dateFormatHandling; private DateTimeZoneHandling? _dateTimeZoneHandling; private DateParseHandling? _dateParseHandling; private FloatFormatHandling? _floatFormatHandling; private FloatParseHandling? _floatParseHandling; private StringEscapeHandling? _stringEscapeHandling; private CultureInfo _culture; private int? _maxDepth; private bool _maxDepthSet; private bool? _checkAdditionalContent; private string? _dateFormatString; private bool _dateFormatStringSet; public virtual IReferenceResolver? ReferenceResolver { get { return GetReferenceResolver(); } set { if (value == null) { throw new ArgumentNullException("value", "Reference resolver cannot be null."); } _referenceResolver = value; } } [Obsolete("Binder is obsolete. Use SerializationBinder instead.")] public virtual SerializationBinder Binder { get { if (_serializationBinder is SerializationBinder result) { return result; } if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter) { return serializationBinderAdapter.SerializationBinder; } throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set."); } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value); } } public virtual ISerializationBinder SerializationBinder { get { return _serializationBinder; } set { if (value == null) { throw new ArgumentNullException("value", "Serialization binder cannot be null."); } _serializationBinder = value; } } public virtual ITraceWriter? TraceWriter { get { return _traceWriter; } set { _traceWriter = value; } } public virtual IEqualityComparer? EqualityComparer { get { return _equalityComparer; } set { _equalityComparer = value; } } public virtual TypeNameHandling TypeNameHandling { get { return _typeNameHandling; } set { if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) { throw new ArgumentOutOfRangeException("value"); } _typeNameHandling = value; } } [Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")] public virtual FormatterAssemblyStyle TypeNameAssemblyFormat { get { return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling; } set { if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value; } } public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling { get { return _typeNameAssemblyFormatHandling; } set { if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full) { throw new ArgumentOutOfRangeException("value"); } _typeNameAssemblyFormatHandling = value; } } public virtual PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling; } set { if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) { throw new ArgumentOutOfRangeException("value"); } _preserveReferencesHandling = value; } } public virtual ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling; } set { if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) { throw new ArgumentOutOfRangeException("value"); } _referenceLoopHandling = value; } } public virtual MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling; } set { if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) { throw new ArgumentOutOfRangeException("value"); } _missingMemberHandling = value; } } public virtual NullValueHandling NullValueHandling { get { return _nullValueHandling; } set { if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _nullValueHandling = value; } } public virtual DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling; } set { if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) { throw new ArgumentOutOfRangeException("value"); } _defaultValueHandling = value; } } public virtual ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling; } set { if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) { throw new ArgumentOutOfRangeException("value"); } _objectCreationHandling = value; } } public virtual ConstructorHandling ConstructorHandling { get { return _constructorHandling; } set { if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) { throw new ArgumentOutOfRangeException("value"); } _constructorHandling = value; } } public virtual MetadataPropertyHandling MetadataPropertyHandling { get { return _metadataPropertyHandling; } set { if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore) { throw new ArgumentOutOfRangeException("value"); } _metadataPropertyHandling = value; } } public virtual JsonConverterCollection Converters { get { if (_converters == null) { _converters = new JsonConverterCollection(); } return _converters; } } public virtual IContractResolver ContractResolver { get { return _contractResolver; } set { _contractResolver = value ?? DefaultContractResolver.Instance; } } public virtual StreamingContext Context { get { return _context; } set { _context = value; } } public virtual Formatting Formatting { get { return _formatting.GetValueOrDefault(); } set { _formatting = value; } } public virtual DateFormatHandling DateFormatHandling { get { return _dateFormatHandling.GetValueOrDefault(); } set { _dateFormatHandling = value; } } public virtual DateTimeZoneHandling DateTimeZoneHandling { get { return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind; } set { _dateTimeZoneHandling = value; } } public virtual DateParseHandling DateParseHandling { get { return _dateParseHandling ?? DateParseHandling.DateTime; } set { _dateParseHandling = value; } } public virtual FloatParseHandling FloatParseHandling { get { return _floatParseHandling.GetValueOrDefault(); } set { _floatParseHandling = value; } } public virtual FloatFormatHandling FloatFormatHandling { get { return _floatFormatHandling.GetValueOrDefault(); } set { _floatFormatHandling = value; } } public virtual StringEscapeHandling StringEscapeHandling { get { return _stringEscapeHandling.GetValueOrDefault(); } set { _stringEscapeHandling = value; } } public virtual string DateFormatString { get { return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; } set { _dateFormatString = value; _dateFormatStringSet = true; } } public virtual CultureInfo Culture { get { return _culture ?? JsonSerializerSettings.DefaultCulture; } set { _culture = value; } } public virtual int? MaxDepth { get { return _maxDepth; } set { if (value <= 0) { throw new ArgumentException("Value must be positive.", "value"); } _maxDepth = value; _maxDepthSet = true; } } public virtual bool CheckAdditionalContent { get { return _checkAdditionalContent.GetValueOrDefault(); } set { _checkAdditionalContent = value; } } public virtual event EventHandler<ErrorEventArgs>? Error; internal bool IsCheckAdditionalContentSet() { return _checkAdditionalContent.HasValue; } public JsonSerializer() { _referenceLoopHandling = ReferenceLoopHandling.Error; _missingMemberHandling = MissingMemberHandling.Ignore; _nullValueHandling = NullValueHandling.Include; _defaultValueHandling = DefaultValueHandling.Include; _objectCreationHandling = ObjectCreationHandling.Auto; _preserveReferencesHandling = PreserveReferencesHandling.None; _constructorHandling = ConstructorHandling.Default; _typeNameHandling = TypeNameHandling.None; _metadataPropertyHandling = MetadataPropertyHandling.Default; _context = JsonSerializerSettings.DefaultContext; _serializationBinder = DefaultSerializationBinder.Instance; _culture = JsonSerializerSettings.DefaultCulture; _contractResolver = DefaultContractResolver.Instance; } public static JsonSerializer Create() { return new JsonSerializer(); } public static JsonSerializer Create(JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = Create(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } public static JsonSerializer CreateDefault() { return Create(JsonConvert.DefaultSettings?.Invoke()); } public static JsonSerializer CreateDefault(JsonSerializerSettings? settings) { JsonSerializer jsonSerializer = CreateDefault(); if (settings != null) { ApplySerializerSettings(jsonSerializer, settings); } return jsonSerializer; } private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings) { if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) { for (int i = 0; i < settings.Converters.Count; i++) { serializer.Converters.Insert(i, settings.Converters[i]); } } if (settings._typeNameHandling.HasValue) { serializer.TypeNameHandling = settings.TypeNameHandling; } if (settings._metadataPropertyHandling.HasValue) { serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling; } if (settings._typeNameAssemblyFormatHandling.HasValue) { serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling; } if (settings._preserveReferencesHandling.HasValue) { serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; } if (settings._referenceLoopHandling.HasValue) { serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; } if (settings._missingMemberHandling.HasValue) { serializer.MissingMemberHandling = settings.MissingMemberHandling; } if (settings._objectCreationHandling.HasValue) { serializer.ObjectCreationHandling = settings.ObjectCreationHandling; } if (settings._nullValueHandling.HasValue) { serializer.NullValueHandling = settings.NullValueHandling; } if (settings._defaultValueHandling.HasValue) { serializer.DefaultValueHandling = settings.DefaultValueHandling; } if (settings._constructorHandling.HasValue) { serializer.ConstructorHandling = settings.ConstructorHandling; } if (settings._context.HasValue) { serializer.Context = settings.Context; } if (settings._checkAdditionalContent.HasValue) { serializer._checkAdditionalContent = settings._checkAdditionalContent; } if (settings.Error != null) { serializer.Error += settings.Error; } if (settings.ContractResolver != null) { serializer.ContractResolver = settings.ContractResolver; } if (settings.ReferenceResolverProvider != null) { serializer.ReferenceResolver = settings.ReferenceResolverProvider(); } if (settings.TraceWriter != null) { serializer.TraceWriter = settings.TraceWriter; } if (settings.EqualityComparer != null) { serializer.EqualityComparer = settings.EqualityComparer; } if (settings.SerializationBinder != null) { serializer.SerializationBinder = settings.SerializationBinder; } if (settings._formatting.HasValue) { serializer._formatting = settings._formatting; } if (settings._dateFormatHandling.HasValue) { serializer._dateFormatHandling = settings._dateFormatHandling; } if (settings._dateTimeZoneHandling.HasValue) { serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling; } if (settings._dateParseHandling.HasValue) { serializer._dateParseHandling = settings._dateParseHandling; } if (settings._dateFormatStringSet) { serializer._dateFormatString = settings._dateFormatString; serializer._dateFormatStringSet = settings._dateFormatStringSet; } if (settings._floatFormatHandling.HasValue) { serializer._floatFormatHandling = settings._floatFormatHandling; } if (settings._floatParseHandling.HasValue) { serializer._floatParseHandling = settings._floatParseHandling; } if (settings._stringEscapeHandling.HasValue) { serializer._stringEscapeHandling = settings._stringEscapeHandling; } if (settings._culture != null) { serializer._culture = settings._culture; } if (settings._maxDepthSet) { serializer._maxDepth = settings._maxDepth; serializer._maxDepthSet = settings._maxDepthSet; } } [DebuggerStepThrough] public void Populate(TextReader reader, object target) { Populate(new JsonTextReader(reader), target); } [DebuggerStepThrough] public void Populate(JsonReader reader, object target) { PopulateInternal(reader, target); } internal virtual void PopulateInternal(JsonReader reader, object target) { ValidationUtils.ArgumentNotNull(reader, "reader"); ValidationUtils.ArgumentNotNull(target, "target"); SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null); new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); } [DebuggerStepThrough] public object? Deserialize(JsonReader reader) { return Deserialize(reader, null); } [DebuggerStepThrough] public object? Deserialize(TextReader reader, Type objectType) { return Deserialize(new JsonTextReader(reader), objectType); } [DebuggerStepThrough] public T? Deserialize<T>(JsonReader reader) { return (T)Deserialize(reader, typeof(T)); } [DebuggerStepThrough] public object? Deserialize(JsonReader reader, Type? objectType) { return DeserializeInternal(reader, objectType); } internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType) { ValidationUtils.ArgumentNotNull(reader, "reader"); SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString); TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null); object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent); if (traceJsonReader != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null); } ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString); return result; } internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString) { if (_culture != null && !_culture.Equals(reader.Culture)) { previousCulture = reader.Culture; reader.Culture = _culture; } else { previousCulture = null; } if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling) { previousDateTimeZoneHandling = reader.DateTimeZoneHandling; reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } else { previousDateTimeZoneHandling = null; } if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling) { previousDateParseHandling = reader.DateParseHandling; reader.DateParseHandling = _dateParseHandling.GetValueOrDefault(); } else { previousDateParseHandling = null; } if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling) { previousFloatParseHandling = reader.FloatParseHandling; reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault(); } else { previousFloatParseHandling = null; } if (_maxDepthSet && reader.MaxDepth != _maxDepth) { previousMaxDepth = reader.MaxDepth; reader.MaxDepth = _maxDepth; } else { previousMaxDepth = null; } if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString) { previousDateFormatString = reader.DateFormatString; reader.DateFormatString = _dateFormatString; } else { previousDateFormatString = null; } if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver) { jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable(); } } private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString) { if (previousCulture != null) { reader.Culture = previousCulture; } if (previousDateTimeZoneHandling.HasValue) { reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault(); } if (previousDateParseHandling.HasValue) { reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault(); } if (previousFloatParseHandling.HasValue) { reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault(); } if (_maxDepthSet) { reader.MaxDepth = previousMaxDepth; } if (_dateFormatStringSet) { reader.DateFormatString = previousDateFormatString; } if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable()) { jsonTextReader.PropertyNameTable = null; } } public void Serialize(TextWriter textWriter, object? value) { Serialize(new JsonTextWriter(textWriter), value); } public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType) { SerializeInternal(jsonWriter, value, objectType); } public void Serialize(TextWriter textWriter, object? value, Type objectType) { Serialize(new JsonTextWriter(textWriter), value, objectType); } public void Serialize(JsonWriter jsonWriter, object? value) { SerializeInternal(jsonWriter, value, null); } private TraceJsonReader CreateTraceJsonReader(JsonReader reader) { TraceJsonReader traceJsonReader = new TraceJsonReader(reader); if (reader.TokenType != 0) { traceJsonReader.WriteCurrentToken(); } return traceJsonReader; } internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType) { ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); Formatting? formatting = null; if (_formatting.HasValue && jsonWriter.Formatting != _formatting) { formatting = jsonWriter.Formatting; jsonWriter.Formatting = _formatting.GetValueOrDefault(); } DateFormatHandling? dateFormatHandling = null; if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling) { dateFormatHandling = jsonWriter.DateFormatHandling; jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault(); } DateTimeZoneHandling? dateTimeZoneHandling = null; if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling) { dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling; jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault(); } FloatFormatHandling? floatFormatHandling = null; if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling) { floatFormatHandling = jsonWriter.FloatFormatHandling; jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault(); } StringEscapeHandling? stringEscapeHandling = null; if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling) { stringEscapeHandling = jsonWriter.StringEscapeHandling; jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault(); } CultureInfo cultureInfo = null; if (_culture != null && !_culture.Equals(jsonWriter.Culture)) { cultureInfo = jsonWriter.Culture; jsonWriter.Culture = _culture; } string dateFormatString = null; if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString) { dateFormatString = jsonWriter.DateFormatString; jsonWriter.DateFormatString = _dateFormatString; } TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null); new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType); if (traceJsonWriter != null) { TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null); } if (formatting.HasValue) { jsonWriter.Formatting = formatting.GetValueOrDefault(); } if (dateFormatHandling.HasValue) { jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault(); } if (dateTimeZoneHandling.HasValue) { jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault(); } if (floatFormatHandling.HasValue) { jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault(); } if (stringEscapeHandling.HasValue) { jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault(); } if (_dateFormatStringSet) { jsonWriter.DateFormatString = dateFormatString; } if (cultureInfo != null) { jsonWriter.Culture = cultureInfo; } } internal IReferenceResolver GetReferenceResolver() { if (_referenceResolver == null) { _referenceResolver = new DefaultReferenceResolver(); } return _referenceResolver; } internal JsonConverter? GetMatchingConverter(Type type) { return GetMatchingConverter(_converters, type); } internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType) { if (converters != null) { for (int i = 0; i < converters.Count; i++) { JsonConverter jsonConverter = converters[i]; if (jsonConverter.CanConvert(objectType)) { return jsonConverter; } } } return null; } internal void OnError(ErrorEventArgs e) { this.Error?.Invoke(this, e); } } public class JsonSerializerSettings { internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error; internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore; internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include; internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include; internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto; internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default; internal static readonly StreamingContext DefaultContext; internal const Formatting DefaultFormatting = Formatting.None; internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat; internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime; internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double; internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String; internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default; internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple; internal static readonly CultureInfo DefaultCulture; internal const bool DefaultCheckAdditionalContent = false; internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; internal const int DefaultMaxDepth = 64; internal Formatting? _formatting; internal DateFormatHandling? _dateFormatHandling; internal DateTimeZoneHandling? _dateTimeZoneHandling; internal DateParseHandling? _dateParseHandling; internal FloatFormatHandling? _floatFormatHandling; internal FloatParseHandling? _floatParseHandling; internal StringEscapeHandling? _stringEscapeHandling; internal CultureInfo? _culture; internal bool? _checkAdditionalContent; internal int? _maxDepth; internal bool _maxDepthSet; internal string? _dateFormatString; internal bool _dateFormatStringSet; internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling; internal DefaultValueHandling? _defaultValueHandling; internal PreserveReferencesHandling? _preserveReferencesHandling; internal NullValueHandling? _nullValueHandling; internal ObjectCreationHandling? _objectCreationHandling; internal MissingMemberHandling? _missingMemberHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal StreamingContext? _context; internal ConstructorHandling? _constructorHandling; internal TypeNameHandling? _typeNameHandling; internal MetadataPropertyHandling? _metadataPropertyHandling; public ReferenceLoopHandling ReferenceLoopHandling { get { return _referenceLoopHandling.GetValueOrDefault(); } set { _referenceLoopHandling = value; } } public MissingMemberHandling MissingMemberHandling { get { return _missingMemberHandling.GetValueOrDefault(); } set { _missingMemberHandling = value; } } public ObjectCreationHandling ObjectCreationHandling { get { return _objectCreationHandling.GetValueOrDefault(); } set { _objectCreationHandling = value; } } public NullValueHandling NullValueHandling { get { return _nullValueHandling.GetValueOrDefault(); } set { _nullValueHandling = value; } } public DefaultValueHandling DefaultValueHandling { get { return _defaultValueHandling.GetValueOrDefault(); } set { _defaultValueHandling = value; } } public IList<JsonConverter> Converters { get; set; } public PreserveReferencesHandling PreserveReferencesHandling { get { return _preserveReferencesHandling.GetValueOrDefault(); } set { _preserveReferencesHandling = value; } } public TypeNameHandling TypeNameHandling { get { return _typeNameHandling.GetValueOrDefault(); } set { _typeNameHandling = value; } } public MetadataPropertyHandling MetadataPropertyHandling { get { return _metadataPropertyHandling.GetValueOrDefault(); } set { _metadataPropertyHandling = value; } } [Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")] public FormatterAssemblyStyle TypeNameAssemblyFormat { get { return (FormatterAssemblyStyle)TypeNameAssemblyFormatHandling; } set { TypeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value; } } public TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling { get { return _typeNameAssemblyFormatHandling.GetValueOrDefault(); } set { _typeNameAssemblyFormatHandling = value; } } public ConstructorHandling ConstructorHandling { get { return _constructorHandling.GetValueOrDefault(); } set { _constructorHandling = value; } } public IContractResolver? ContractResolver { get; set; } public IEqualityComparer? EqualityComparer { get; set; } [Obsolete("Refer