Decompiled source of Legendary Recipe Definer v1.0.3
plugins/LegendaryRecipeDefiner.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using PotionCraft.ManagersSystem; using PotionCraft.ManagersSystem.Potion.Entities; using PotionCraft.ManagersSystem.SaveLoad; using PotionCraft.ObjectBased; using PotionCraft.ObjectBased.AlchemyMachine; using PotionCraft.ObjectBased.AlchemyMachine.Settings; using PotionCraft.ObjectBased.AlchemyMachineProduct; using PotionCraft.ObjectBased.UIElements.Bookmarks; using PotionCraft.ObjectBased.UIElements.Books; using PotionCraft.ObjectBased.UIElements.Books.RecipeBook; using PotionCraft.ObjectBased.UIElements.FinishLegendarySubstanceMenu; using PotionCraft.QuestSystem.DesiredItems; using PotionCraft.SaveFileSystem; using PotionCraft.ScriptableObjects; using PotionCraft.ScriptableObjects.AlchemyMachineProducts; using PotionCraft.Settings; using PotionCraft.Utils.CustomAnimator; using UnityEngine; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("LegendaryRecipeDefiner")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LegendaryRecipeDefiner")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("92e81ed6-c52c-46a2-b007-7dbcacf5ee64")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace LegendaryRecipeDefiner; [BepInPlugin("fgvb.potioncraft.legendaryrecipedefiner", "LegendaryRecipeDefiner", "1.0.3.0")] public class LegendaryRecipeDefiner : BaseUnityPlugin { [Serializable] public enum MachinePart { Unknown = -1, RightRetort, RightDripper, RhombusVessel, TriangularVessel, RightFurnace, DoubleVessel, FloorVessel, LeftDripper, LeftRetort, SpiralVessel, LeftFurnace, TripletVesselLeft, TripletVesselCenter, TripletVesselRight, Last } [Serializable] public class LRDSettings { public string entry = "recipes_1.0"; public bool error_off_entry = false; public bool allow_less_ingredients = true; public bool allow_more_ingredients = true; public bool allow_no_ingredients = true; } [Serializable] public class SerializedUpdate { public MachinePart part; public List<string> components; public SerializedUpdate() { part = MachinePart.Unknown; components = new List<string>(); } public SerializedUpdate(MachinePart part__, List<string> components__) { part = part__; components = components__; } } [Serializable] public class SerializedRecipe { public string name = ""; public List<SerializedUpdate> recipe = new List<SerializedUpdate>(); } [Serializable] public class SerializedRecipeList { public List<SerializedRecipe> recipes = new List<SerializedRecipe>(); } [Serializable] public class SerializedSafeBookmark { public float positionX; public float positionY; public int prefabIndex; public bool isMirrored; public int index; public SerializedSafeBookmark() { positionX = -1f; positionY = -1f; prefabIndex = -1; isMirrored = false; index = -1; } public SerializedSafeBookmark(float x, float y, int prefab, bool mirrored, int rail) { positionX = x; positionY = y; prefabIndex = prefab; isMirrored = mirrored; index = rail; } public SerializedBookmark ToDefault(ref int rail) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) SerializedBookmark val = new SerializedBookmark(); val.position = new Vector2(positionX, positionY); val.prefabIndex = prefabIndex; val.isMirrored = isMirrored; rail = index; return val; } } [Serializable] public class SerializedSavedRecipe { public SerializedRecipe content = null; public SerializedSafeBookmark mark = new SerializedSafeBookmark(); } [Serializable] public class SerializedSafeLedgeTargetData { public bool isItemOnLedge = false; public float ledgePositionX = 0f; public float ledgePositionY = 0f; public int itemIndexOnLedge = -1; public SerializedSafeLedgeTargetData() { } public SerializedSafeLedgeTargetData(bool _isItemOnLedge, Vector2 ledgePosition, int _itemIndexOnLedge) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) isItemOnLedge = _isItemOnLedge; ledgePositionX = ledgePosition.x; ledgePositionY = ledgePosition.y; itemIndexOnLedge = _itemIndexOnLedge; } public static SerializedLedgeTargetData SafeToNormal(SerializedSafeLedgeTargetData value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) SerializedLedgeTargetData val = new SerializedLedgeTargetData(); val.isItemOnLedge = value.isItemOnLedge; val.ledgePosition = new Vector2(value.ledgePositionX, value.ledgePositionY); val.itemIndexOnLedge = value.itemIndexOnLedge; return val; } } [Serializable] public class SerializedSafeItemFromInventory { public string typeName = ""; public float positionX = -1f; public float positionY = 0f; public float eulerAnglesX = 0f; public float eulerAnglesY = 0f; public float eulerAnglesZ = 0f; public string inventoryItemName = ""; public List<SerializedSafeLedgeTargetData> ledgeDataList = null; public string data = ""; public SerializedSafeItemFromInventory() { } public SerializedSafeItemFromInventory(string _typeName, Vector2 position, Vector3 eulerAngles, string _inventoryItemName, List<SerializedLedgeTargetData> _ledgeDataList, string _data) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) typeName = _typeName; positionX = position.x; positionY = position.y; eulerAnglesX = eulerAngles.x; eulerAnglesY = eulerAngles.y; eulerAnglesZ = eulerAngles.z; inventoryItemName = _inventoryItemName; if (_ledgeDataList != null) { ledgeDataList = new List<SerializedSafeLedgeTargetData>(); foreach (SerializedLedgeTargetData _ledgeData in _ledgeDataList) { ledgeDataList.Add(new SerializedSafeLedgeTargetData(_ledgeData.isItemOnLedge, _ledgeData.ledgePosition, _ledgeData.itemIndexOnLedge)); } } data = _data; } public static SerializedItemFromInventory SafeToNormal(SerializedSafeItemFromInventory value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) SerializedItemFromInventory val = new SerializedItemFromInventory(); val.typeName = value.typeName; val.position = new Vector2(value.positionX, value.positionY); val.eulerAngles = new Vector3(value.eulerAnglesX, value.eulerAnglesY, value.eulerAnglesZ); val.inventoryItemName = value.inventoryItemName; val.ledgeDataList = new List<SerializedLedgeTargetData>(); if (value.ledgeDataList != null) { foreach (SerializedSafeLedgeTargetData ledgeData in value.ledgeDataList) { val.ledgeDataList.Add(SerializedSafeLedgeTargetData.SafeToNormal(ledgeData)); } } val.data = value.data; return val; } } [Serializable] public class SafeColor { public float r = 0f; public float g = 0f; public float b = 0f; public float a = 1f; public SafeColor() { } public SafeColor(Color color) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) r = color.r; g = color.g; b = color.b; a = color.a; } public Color ToColor() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return new Color(r, g, b, a); } } [Serializable] public class SafeColorList { public List<SafeColor> colorsList = new List<SafeColor>(); } [Serializable] public class SafeSkinSettings { public string currentIconName = string.Empty; public SafeColor currentIconColor1; public SafeColor currentIconColor2; public SafeColor currentIconColor3; public SafeColor currentIconColor4; public string currentCustomTitle = string.Empty; public bool isCurrentTitleCustom; public string currentDescription = string.Empty; public bool isCurrentIconCustom; public bool isCurrentIconColor1Custom; public bool isCurrentIconColor2Custom; public bool isCurrentIconColor3Custom; public bool isCurrentIconColor4Custom; public int colorsCount; public SafeSkinSettings() { } public SafeSkinSettings(SerializedAlchemyMachineProductSkinSettings settings) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) currentIconName = settings.currentIconName; currentIconColor1 = new SafeColor(settings.currentIconColor1); currentIconColor2 = new SafeColor(settings.currentIconColor2); currentIconColor3 = new SafeColor(settings.currentIconColor3); currentIconColor4 = new SafeColor(settings.currentIconColor4); currentCustomTitle = settings.currentCustomTitle; isCurrentTitleCustom = settings.isCurrentTitleCustom; currentDescription = settings.currentDescription; isCurrentIconCustom = settings.isCurrentIconCustom; isCurrentIconColor1Custom = settings.isCurrentIconColor1Custom; isCurrentIconColor2Custom = settings.isCurrentIconColor2Custom; isCurrentIconColor3Custom = settings.isCurrentIconColor3Custom; isCurrentIconColor4Custom = settings.isCurrentIconColor4Custom; colorsCount = settings.colorsCount; } public SerializedAlchemyMachineProductSkinSettings ToSettings() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) SerializedAlchemyMachineProductSkinSettings val = new SerializedAlchemyMachineProductSkinSettings(); val.currentIconName = currentIconName; val.currentIconColor1 = currentIconColor1.ToColor(); val.currentIconColor2 = currentIconColor2.ToColor(); val.currentIconColor3 = currentIconColor3.ToColor(); val.currentIconColor4 = currentIconColor4.ToColor(); val.currentCustomTitle = currentCustomTitle; val.isCurrentTitleCustom = isCurrentTitleCustom; val.currentDescription = currentDescription; val.isCurrentIconCustom = isCurrentIconCustom; val.isCurrentIconColor1Custom = isCurrentIconColor1Custom; val.isCurrentIconColor2Custom = isCurrentIconColor2Custom; val.isCurrentIconColor3Custom = isCurrentIconColor3Custom; val.isCurrentIconColor4Custom = isCurrentIconColor4Custom; val.colorsCount = colorsCount; return val; } } [Serializable] public class SafeComponentList { public List<SerializedRecipeReagent> components = new List<SerializedRecipeReagent>(); public List<AlchemyMachineSlot> componentsSlots = new List<AlchemyMachineSlot>(); } [Serializable] public class SerializedSafeRecipeData { public string name = ""; public List<SafeColorList> colorsList = null; public SafeSkinSettings skinSettings = null; public SafeComponentList usedComponents = null; public RecipeBookPageContentType type; public SerializedSafeRecipeData() { } public SerializedSafeRecipeData(SerializedAlchemyMachineProductRecipeData data) { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) name = data.name; colorsList = new List<SafeColorList>(); foreach (ColorsList colors in data.colorsList) { SafeColorList safeColorList = new SafeColorList(); foreach (Color color in colors.colors) { safeColorList.colorsList.Add(new SafeColor(color)); } colorsList.Add(safeColorList); } skinSettings = new SafeSkinSettings(data.skinSettings); usedComponents = new SafeComponentList(); usedComponents.components = data.usedComponents.GetComponents(); usedComponents.componentsSlots = data.usedComponents.GetComponentsSlots(); type = data.GetRecipeBookPageContentType(); } public SerializedAlchemyMachineProductRecipeData ToData() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) SerializedAlchemyMachineProductRecipeData val = new SerializedAlchemyMachineProductRecipeData(type); val.name = name; val.colorsList = new List<ColorsList>(); foreach (SafeColorList colors in colorsList) { ColorsList val2 = new ColorsList(); foreach (SafeColor colors2 in colors.colorsList) { val2.colors.Add(colors2.ToColor()); } val.colorsList.Add(val2); } val.skinSettings = skinSettings.ToSettings(); val.usedComponents = new SerializedCompositeAlchemySubstanceComponents(usedComponents.components, usedComponents.componentsSlots); return val; } } [Serializable] public class SerializedState { public List<SerializedSavedRecipe> recipes = new List<SerializedSavedRecipe>(); public SerializedSafeItemFromInventory currentMachineContent = null; public SerializedSafeRecipeData currentMachineRecipe = null; public SerializedRecipe previousRecipe = null; public bool productChanged = false; } public class PartUpdate { public MachinePart partID = MachinePart.Unknown; public PotionEffect[] effects = (PotionEffect[])(object)new PotionEffect[0]; public AlchemyMachineProduct product = null; public PartUpdate() { } public PartUpdate(MachinePart partID__, PotionEffect[] effects__, AlchemyMachineProduct product__ = null) { partID = partID__; effects = effects__; product = product__; } } public const string pluginGuid = "fgvb.potioncraft.legendaryrecipedefiner"; public const string pluginName = "LegendaryRecipeDefiner"; public const string pluginVersion = "1.0.3.0"; protected static string current_directory = ""; protected static string currentLoadedFile = ""; protected static string currentSavedFile = ""; private static string stringToBeSaved = ""; private static IDeserializer deserializer; private static ISerializer serializer; private static int lastMinimum = -1; private static bool hasSubstanceLoadedExternally = false; private static LRDSettings settings = null; public static LRDSettings Settings => settings; public static LegendaryRecipeDefiner Instance { get; set; } = null; private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)Instance)) { Instance = this; Harmony.CreateAndPatchAll(typeof(LegendaryRecipeDefiner), (string)null); deserializer = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); serializer = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); current_directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); CreateStructure(); VerifyDataIntegrity(); } } private static void CreateStructure() { string path = current_directory + "/settings.yml"; if (!File.Exists(path)) { File.WriteAllText(path, serializer.Serialize((object)new LRDSettings())); } string config = File.ReadAllText(path); settings = ParseConfig(config); path = current_directory + "/Recipe Blueprints"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); string[] files = Directory.GetFiles(current_directory, "*.yml", SearchOption.TopDirectoryOnly); string[] array = files; foreach (string text in array) { string text2 = text.Substring(text.LastIndexOf('\\') + 1); if (text2 != "settings.yml") { File.Move(text, path + "/" + text2); } } } path = current_directory + "/Saved Recipes"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } private static void VerifyDataIntegrity() { string path = current_directory + "/Recipe Blueprints"; string[] files = Directory.GetFiles(path, "*.json", SearchOption.AllDirectories); string[] array = files; foreach (string text in array) { SerializedRecipeList serializedRecipeList = deserializer.Deserialize<SerializedRecipeList>(File.ReadAllText(text)); string path2 = text.Substring(0, text.LastIndexOf(".")) + ".yml"; File.WriteAllText(path2, serializer.Serialize((object)serializedRecipeList)); File.Delete(text); } path = current_directory + "/Saved Recipes"; files = Directory.GetFiles(path, "*.json", SearchOption.AllDirectories); string[] array2 = files; foreach (string text2 in array2) { SerializedState serializedState = deserializer.Deserialize<SerializedState>(File.ReadAllText(text2)); string path3 = text2.Substring(0, text2.LastIndexOf(".")) + ".yml"; File.WriteAllText(path3, serializer.Serialize((object)serializedState)); File.Delete(text2); } } public static LRDSettings ParseConfig(string config) { return deserializer.Deserialize<LRDSettings>(config); } public static InventoryItem GetMachinePart(LegendaryRecipe recipe, MachinePart partID) { return (InventoryItem)(partID switch { MachinePart.Unknown => null, MachinePart.RightRetort => recipe.rightRetort, MachinePart.RightDripper => recipe.rightDripper, MachinePart.RhombusVessel => recipe.rhombusVessel, MachinePart.TriangularVessel => recipe.triangularVessel, MachinePart.RightFurnace => recipe.rightFurnace, MachinePart.DoubleVessel => recipe.doubleVessel, MachinePart.FloorVessel => recipe.floorVessel, MachinePart.LeftDripper => recipe.leftDripper, MachinePart.LeftRetort => recipe.leftRetort, MachinePart.SpiralVessel => recipe.spiralVessel, MachinePart.LeftFurnace => recipe.leftFurnace, MachinePart.TripletVesselLeft => recipe.tripletVesselLeft, MachinePart.TripletVesselCenter => recipe.tripletVesselCenter, MachinePart.TripletVesselRight => recipe.tripletVesselRight, _ => null, }); } public static void SetMachinePart(LegendaryRecipe recipe, MachinePart partID, InventoryItem value) { switch (partID) { case MachinePart.Unknown: break; case MachinePart.RightRetort: recipe.rightRetort = value; break; case MachinePart.RightDripper: recipe.rightDripper = value; break; case MachinePart.RhombusVessel: recipe.rhombusVessel = value; break; case MachinePart.TriangularVessel: recipe.triangularVessel = value; break; case MachinePart.RightFurnace: recipe.rightFurnace = value; break; case MachinePart.DoubleVessel: recipe.doubleVessel = value; break; case MachinePart.FloorVessel: recipe.floorVessel = value; break; case MachinePart.LeftDripper: recipe.leftDripper = value; break; case MachinePart.LeftRetort: recipe.leftRetort = value; break; case MachinePart.SpiralVessel: recipe.spiralVessel = value; break; case MachinePart.LeftFurnace: recipe.leftFurnace = value; break; case MachinePart.TripletVesselLeft: recipe.tripletVesselLeft = value; break; case MachinePart.TripletVesselCenter: recipe.tripletVesselCenter = value; break; case MachinePart.TripletVesselRight: recipe.tripletVesselRight = value; break; } } public static List<string> ProductToList(InventoryItem product) { if ((Object)(object)product == (Object)null) { return new List<string>(); } List<string> list = new List<string>(); list.Add(((Object)((product is AlchemyMachineProduct) ? product : null)).name); return list; } public static List<string> PotionToElementsList(InventoryItem item) { if ((Object)(object)item == (Object)null) { return new List<string>(); } List<string> list = new List<string>(); PotionEffect[] effects = ((DesiredItemPotionEffectsScriptableObject)((item is DesiredItemPotionEffectsScriptableObject) ? item : null)).effects; foreach (PotionEffect val in effects) { list.Add(((Object)val).name); } return list; } public static SerializedRecipe SerializeRecipe(string name) { LegendaryRecipe byName = LegendaryRecipe.GetByName(name, false, true); if ((Object)(object)byName == (Object)null || name == "") { return null; } SerializedRecipe serializedRecipe = new SerializedRecipe(); serializedRecipe.name = name; serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.RightRetort, PotionToElementsList(byName.rightRetort))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.RightDripper, PotionToElementsList(byName.rightDripper))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.RhombusVessel, PotionToElementsList(byName.rhombusVessel))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.TriangularVessel, PotionToElementsList(byName.triangularVessel))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.RightFurnace, ProductToList(byName.rightFurnace))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.DoubleVessel, PotionToElementsList(byName.doubleVessel))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.FloorVessel, PotionToElementsList(byName.floorVessel))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.LeftDripper, PotionToElementsList(byName.leftDripper))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.LeftRetort, PotionToElementsList(byName.leftRetort))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.SpiralVessel, PotionToElementsList(byName.spiralVessel))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.LeftFurnace, ProductToList(byName.leftFurnace))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.TripletVesselLeft, PotionToElementsList(byName.tripletVesselLeft))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.TripletVesselCenter, PotionToElementsList(byName.tripletVesselCenter))); serializedRecipe.recipe.Add(new SerializedUpdate(MachinePart.TripletVesselRight, PotionToElementsList(byName.tripletVesselRight))); return serializedRecipe; } public static void CreateNewLegendaryRecipe(string name, PartUpdate[] updates) { } public static void ChangeLegendaryRecipeSelect(string name, PartUpdate[] updates) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown LegendaryRecipe byName = LegendaryRecipe.GetByName(name, false, true); if ((Object)(object)byName == (Object)null) { if (name != "") { CreateNewLegendaryRecipe(name, updates); } return; } foreach (PartUpdate partUpdate in updates) { if (partUpdate.partID == MachinePart.RightFurnace || partUpdate.partID == MachinePart.LeftFurnace) { SetMachinePart(byName, partUpdate.partID, (InventoryItem)(object)partUpdate.product); continue; } if (partUpdate.effects == null || partUpdate.effects.Length == 0) { SetMachinePart(byName, partUpdate.partID, null); continue; } PotionEffect[] effects = (PotionEffect[])((partUpdate.effects.Length <= 5) ? ((Array)partUpdate.effects) : ((Array)new PotionEffect[5] { partUpdate.effects[0], partUpdate.effects[1], partUpdate.effects[2], partUpdate.effects[3], partUpdate.effects[4] })); InventoryItem machinePart = GetMachinePart(byName, partUpdate.partID); if (Object.op_Implicit((Object)(object)((machinePart is DesiredItemPotionEffectsScriptableObject) ? machinePart : null))) { InventoryItem machinePart2 = GetMachinePart(byName, partUpdate.partID); ((DesiredItemPotionEffectsScriptableObject)((machinePart2 is DesiredItemPotionEffectsScriptableObject) ? machinePart2 : null)).effects = effects; } else if (settings.allow_more_ingredients) { DesiredItemPotionEffectsScriptableObject val = (DesiredItemPotionEffectsScriptableObject)ScriptableObject.CreateInstance(typeof(DesiredItemPotionEffectsScriptableObject)); val.effects = effects; val.noMoreEffects = true; SetMachinePart(byName, partUpdate.partID, (InventoryItem)(object)val); } } } public static void DeserializeRecipes(string yamlLocation) { if (!File.Exists(yamlLocation)) { if (settings.error_off_entry) { Debug.LogError((object)("No alternative recipe YAML could be found at " + yamlLocation + ".")); } return; } SerializedRecipeList serializedRecipeList = deserializer.Deserialize<SerializedRecipeList>(File.ReadAllText(yamlLocation)); List<PartUpdate> list = new List<PartUpdate>(); List<PotionEffect> list2 = new List<PotionEffect>(); foreach (SerializedRecipe recipe in serializedRecipeList.recipes) { bool[] array = new bool[14]; if (recipe.recipe != null) { foreach (SerializedUpdate item in recipe.recipe) { if (item.part == MachinePart.Unknown) { continue; } if (item.part == MachinePart.RightFurnace || item.part == MachinePart.LeftFurnace) { string text = ((item.components.Count > 0) ? item.components[0] : null); list.Add(new PartUpdate(item.part, null, (text == null || text == "") ? null : AlchemyMachineProduct.GetByName(text, false, true))); } else { foreach (string component in item.components) { list2.Add(PotionEffect.GetByName(component, true, true, (List<PotionEffect>)null)); } list.Add(new PartUpdate(item.part, list2.ToArray())); list2.Clear(); } array[(int)item.part] = true; } } for (int i = 0; i < 14; i++) { if (!array[i]) { list.Add(new PartUpdate((MachinePart)i, null)); } } if (list.Count > 0) { ChangeLegendaryRecipeSelect(recipe.name, list.ToArray()); list.Clear(); } } } [HarmonyPatch(typeof(AlchemyMachineObject), "GetSuitableLegendaryRecipe")] [HarmonyPrefix] private static bool PreLegendaryCheck() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) AlchemyMachineObject alchemyMachine = Managers.Ingredient.alchemyMachineSubManager.alchemyMachine; LegendaryRecipe val = null; foreach (LegendaryRecipe allLegendaryRecipe in LegendaryRecipe.allLegendaryRecipes) { bool flag = false; for (int i = 0; i < alchemyMachine.slots.Length; i++) { AlchemyMachineSlot val2 = (AlchemyMachineSlot)i; if (!alchemyMachine.IsSuitableItemInSlot(allLegendaryRecipe.DesiredItemPerSlot(val2), val2)) { flag = true; break; } } if (!flag) { val = allLegendaryRecipe; break; } } if (Object.op_Implicit((Object)(object)val) && alchemyMachine.tooFewIngredients != 0 && settings.allow_less_ingredients) { lastMinimum = alchemyMachine.tooFewIngredients; alchemyMachine.tooFewIngredients = 0; } else if (!Object.op_Implicit((Object)(object)val) && alchemyMachine.tooFewIngredients == 0) { alchemyMachine.tooFewIngredients = lastMinimum; } return Object.op_Implicit((Object)(object)val); } [HarmonyPatch(typeof(AlchemyMachineObject), "OnBrewAnimationDone")] [HarmonyPostfix] private static void PostBrew() { AlchemyMachineObject alchemyMachine = Managers.Ingredient.alchemyMachineSubManager.alchemyMachine; if (alchemyMachine.tooFewIngredients == 0) { alchemyMachine.tooFewIngredients = lastMinimum; } } public static void AddSavedRecipes(SerializedState state) { foreach (SerializedSavedRecipe recipe in state.recipes) { int rail = -1; recipe.mark.ToDefault(ref rail); SerializedRecipe content = recipe.content; RecipeBook instance = RecipeBook.Instance; IRecipeBookPageContent value = SerializedRecipe.DeserializeRecipe(content); instance.savedRecipes[rail] = value; instance.UpdateBookmarkIcon(rail); } } public static void RemoveSavedRecipes(List<IRecipeBookPageContent> removedRecipes) { foreach (IRecipeBookPageContent removedRecipe in removedRecipes) { RecipeBook.Instance.EraseRecipe(removedRecipe); } } [HarmonyPatch(typeof(SaveLoadManager), "LoadFile")] [HarmonyPrefix] private static bool BeforeFileLoad(File saveFile) { DeserializeRecipes(current_directory + "/Recipe Blueprints/" + settings.entry + ".yml"); string text = saveFile.url.Substring(saveFile.url.LastIndexOf('/') + 1); currentLoadedFile = text.Substring(0, text.Length - 7); return true; } [HarmonyPatch(typeof(SaveLoadManager), "SaveProgressToPool")] [HarmonyPrefix] private static void BeforeFileSave() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Expected O, but got Unknown int num = -1; List<IRecipeBookPageContent> savedRecipes = RecipeBook.Instance.savedRecipes; List<IRecipeBookPageContent> list = new List<IRecipeBookPageContent>(); List<SerializedSavedRecipe> list2 = new List<SerializedSavedRecipe>(); foreach (IRecipeBookPageContent item in savedRecipes) { num++; if (item == null) { continue; } RecipeBookPageContentType recipeBookPageContentType = item.GetRecipeBookPageContentType(); RecipeBookPageContentType val = recipeBookPageContentType; if (val - 2 <= 1) { BookmarkControllersGroupController bookmarkControllersGroupController = ((Book)RecipeBook.Instance).bookmarkControllersGroupController; Bookmark bookmarkByIndex = bookmarkControllersGroupController.GetBookmarkByIndex(num); if (((Component)bookmarkByIndex).gameObject.activeSelf) { SerializedSavedRecipe serializedSavedRecipe = new SerializedSavedRecipe(); SerializedBookmark serialized = bookmarkByIndex.GetSerialized(); serializedSavedRecipe.content = item.GetSerializedRecipe(); serializedSavedRecipe.mark = new SerializedSafeBookmark(serialized.position.x, serialized.position.y, serialized.prefabIndex, serialized.isMirrored, num); list.Add(item); list2.Add(serializedSavedRecipe); } else { ((Component)bookmarkByIndex).gameObject.SetActive(true); } } } SerializedState serializedState = new SerializedState(); serializedState.recipes = list2; if ((Object)(object)Managers.Ingredient.alchemyMachineSubManager.alchemyMachine != (Object)null) { serializedState.previousRecipe = ((FinishLegendarySubstanceWindow.Instance.previousAlchemyMachineProductRecipe == null) ? null : FinishLegendarySubstanceWindow.Instance.previousAlchemyMachineProductRecipe.GetSerializedRecipe()); serializedState.productChanged = FinishLegendarySubstanceWindow.Instance.alchemyMachineProductChangedAfterSavingRecipe; if ((Object)(object)Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.alchemyMachineBox.resultItemSpawner.SpawnedItem != (Object)null) { SerializedItemFromInventory serializedItemFromInventory = ((ItemFromInventory)Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.alchemyMachineBox.resultItemSpawner.SpawnedItem).GetSerializedItemFromInventory(); serializedState.currentMachineContent = new SerializedSafeItemFromInventory(serializedItemFromInventory.typeName, serializedItemFromInventory.position, serializedItemFromInventory.eulerAngles, serializedItemFromInventory.inventoryItemName, serializedItemFromInventory.ledgeDataList, serializedItemFromInventory.data); serializedState.currentMachineRecipe = new SerializedSafeRecipeData((SerializedAlchemyMachineProductRecipeData)Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.alchemyMachineBox.resultItemSpawner.SpawnedInventoryItem.GetSerializedRecipeData().Clone()); AlchemyMachineProductItem spawnedItem = Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.alchemyMachineBox.resultItemSpawner.SpawnedItem; ((ItemFromInventory)spawnedItem).DestroyItem(); Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.alchemyMachineBox.resultItemSpawner.SpawnedInventoryItem = null; } FinishLegendarySubstanceWindow.Instance.previousAlchemyMachineProductRecipe = null; FinishLegendarySubstanceWindow.Instance.alchemyMachineProductChangedAfterSavingRecipe = true; FinishLegendarySubstanceWindow.Instance.Show(false, true); } string text = serializer.Serialize((object)serializedState); stringToBeSaved = text; RemoveSavedRecipes(list); } [HarmonyPatch(typeof(SaveLoadManager), "SaveProgressToPool")] [HarmonyPostfix] private static void OnFileSave(File __result) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 int num = -1; List<IRecipeBookPageContent> savedRecipes = RecipeBook.Instance.savedRecipes; foreach (IRecipeBookPageContent item in savedRecipes) { num++; if (item != null) { RecipeBookPageContentType recipeBookPageContentType = item.GetRecipeBookPageContentType(); RecipeBookPageContentType val = recipeBookPageContentType; if (val - 2 <= 1) { ((Component)((Book)RecipeBook.Instance).bookmarkControllersGroupController.GetBookmarkByIndex(num)).gameObject.SetActive(false); } } } string text = __result.url.Substring(__result.url.LastIndexOf('/') + 1); currentSavedFile = text.Substring(0, text.Length - 7); string path = current_directory + "/Saved Recipes/" + settings.entry + " - " + currentSavedFile + ".yml"; File.WriteAllText(path, stringToBeSaved); SerializedState serializedState = deserializer.Deserialize<SerializedState>(stringToBeSaved); AddSavedRecipes(serializedState); if ((Object)(object)Managers.Ingredient.alchemyMachineSubManager.alchemyMachine != (Object)null) { Managers.SaveLoad.SelectedProgressState.previousAlchemyMachineProductRecipe = serializedState.previousRecipe; Managers.SaveLoad.SelectedProgressState.alchemyMachineProductChangedAfterSavingRecipe = serializedState.productChanged; if (serializedState.currentMachineContent != null) { Managers.SaveLoad.SelectedProgressState.serializedCurrentAlchemyMachineProduct = serializedState.currentMachineRecipe.ToData(); Managers.SaveLoad.SelectedProgressState.withSpawnedProduct = true; SerializedItemFromInventory val2 = SerializedSafeItemFromInventory.SafeToNormal(serializedState.currentMachineContent); AlchemyMachineProductItem.SpawnFromSerializedData(val2, (RoomIndex)3); Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.brewAnimationMainController.StartAnimation(); Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.brewAnimationMainController.progressTime = Settings<BrewAnimationControllerSettings>.Asset.totalAnimationTime - 0.1f; hasSubstanceLoadedExternally = true; Managers.Ingredient.alchemyMachineSubManager.alchemyMachine.alchemyMachineBox.resultItemSpawner.OnLoad(); hasSubstanceLoadedExternally = false; } FinishLegendarySubstanceWindow.Instance.OnLoad(); } } [HarmonyPatch(typeof(RecipeBook), "OnLoad")] [HarmonyPostfix] private static void PostRecipeInit() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 int num = -1; List<IRecipeBookPageContent> savedRecipes = RecipeBook.Instance.savedRecipes; foreach (IRecipeBookPageContent item in savedRecipes) { num++; if (item != null) { RecipeBookPageContentType recipeBookPageContentType = item.GetRecipeBookPageContentType(); RecipeBookPageContentType val = recipeBookPageContentType; if (val - 2 <= 1) { ((Component)((Book)RecipeBook.Instance).bookmarkControllersGroupController.GetBookmarkByIndex(num)).gameObject.SetActive(false); } } } string path = current_directory + "/Saved Recipes/" + settings.entry + " - " + currentLoadedFile + ".yml"; if (File.Exists(path)) { SerializedState state = deserializer.Deserialize<SerializedState>(File.ReadAllText(path)); AddSavedRecipes(state); } } [HarmonyPatch(typeof(ResultItemSpawner), "OnLoad")] [HarmonyPrefix] private static void PreLegendarySpawn() { if (hasSubstanceLoadedExternally) { return; } string path = current_directory + "/Saved Recipes/" + settings.entry + " - " + currentLoadedFile + ".yml"; if (!File.Exists(path)) { return; } SerializedState serializedState = deserializer.Deserialize<SerializedState>(File.ReadAllText(path)); if ((Object)(object)Managers.Ingredient.alchemyMachineSubManager.alchemyMachine != (Object)null) { Managers.SaveLoad.SelectedProgressState.previousAlchemyMachineProductRecipe = serializedState.previousRecipe; Managers.SaveLoad.SelectedProgressState.alchemyMachineProductChangedAfterSavingRecipe = serializedState.productChanged; if (serializedState.currentMachineContent != null) { Managers.SaveLoad.SelectedProgressState.withSpawnedProduct = true; Managers.SaveLoad.SelectedProgressState.serializedCurrentAlchemyMachineProduct = serializedState.currentMachineRecipe.ToData(); SerializedItemFromInventory val = SerializedSafeItemFromInventory.SafeToNormal(serializedState.currentMachineContent); AlchemyMachineProductItem.SpawnFromSerializedData(val, (RoomIndex)3); } } } [HarmonyPatch(typeof(File), "Remove")] [HarmonyPostfix] private static void PostSaveDelete(File __instance) { string text = __instance.url.Substring(__instance.url.LastIndexOf('/') + 1); string text2 = text.Substring(0, text.Length - 7); string path = current_directory + "/Saved Recipes/" + settings.entry + " - " + text2 + ".yml"; if (File.Exists(path)) { File.Delete(path); } } [HarmonyPatch(typeof(AlchemyMachineObject), "GetIngredientsCount")] [HarmonyPostfix] private static void PostIngredientCheck(ref int __result) { if (__result == 0 && settings.allow_no_ingredients) { __result = 1; } } }
plugins/YamlDotNet.dll
Decompiled 2 months 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.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using Microsoft.CodeAnalysis; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("8.1.2.0")] [assembly: AssemblyInformationalVersion("8.1.2")] [assembly: AssemblyTitle("YamlDotNet")] [assembly: AssemblyDescription("The YamlDotNet library.")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("YamlDotNet")] [assembly: AssemblyCopyright("Copyright (c) Antoine Aubry and contributors 2008 - 2019")] [assembly: AssemblyTrademark("")] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("YamlDotNet.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010065e52a453dde5c5b4be5bbe2205755727fce80244b79b894faf8793d80f7db9a96d360b51c220782db32aacee4cb5b8a91bee33aeec700e1f21895c4baadef501eeeac609220d1651603b378173811ee5bb6a002df973d38821bd2fef820c00c174a69faec326a1983b570f07ec66147026b9c8753465de3a8d0c44b613b02af")] [assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")] [assembly: AssemblyVersion("8.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 System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } } namespace YamlDotNet { internal static class StandardRegexOptions { public const RegexOptions Compiled = RegexOptions.Compiled; } internal static class ReflectionExtensions { private static readonly FieldInfo? remoteStackTraceField = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); public static Type? BaseType(this Type type) { return type.BaseType; } public static bool IsValueType(this Type type) { return type.IsValueType; } public static bool IsGenericType(this Type type) { return type.IsGenericType; } public static bool IsInterface(this Type type) { return type.IsInterface; } public static bool IsEnum(this Type type) { return type.IsEnum; } public static bool IsDbNull(this object value) { return value is DBNull; } public static bool HasDefaultConstructor(this Type type) { if (!type.IsValueType) { return type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null) != null; } return true; } public static TypeCode GetTypeCode(this Type type) { return Type.GetTypeCode(type); } public static PropertyInfo? GetPublicProperty(this Type type, string name) { return type.GetProperty(name); } public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type) { BindingFlags instancePublic = BindingFlags.Instance | BindingFlags.Public; if (!type.IsInterface) { return type.GetProperties(instancePublic); } return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetProperties(instancePublic)); } public static IEnumerable<FieldInfo> GetPublicFields(this Type type) { return type.GetFields(BindingFlags.Instance | BindingFlags.Public); } public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type) { return type.GetMethods(BindingFlags.Static | BindingFlags.Public); } public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) { return type.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, parameterTypes, null); } public static MethodInfo? GetPublicInstanceMethod(this Type type, string name) { return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public); } public static Exception Unwrap(this TargetInvocationException ex) { Exception innerException = ex.InnerException; if (innerException == null) { return ex; } if (remoteStackTraceField != null) { remoteStackTraceField.SetValue(innerException, innerException.StackTrace + "\r\n"); } return innerException; } public static bool IsInstanceOf(this Type type, object o) { return type.IsInstanceOfType(o); } public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo property) { return Attribute.GetCustomAttributes(property, typeof(TAttribute)); } } internal sealed class CultureInfoAdapter : CultureInfo { private readonly IFormatProvider provider; public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) : base(baseCulture.LCID) { this.provider = provider; } public override object? GetFormat(Type? formatType) { return provider.GetFormat(formatType); } } internal static class PropertyInfoExtensions { public static object? ReadValue(this PropertyInfo property, object target) { return property.GetValue(target, null); } } } namespace YamlDotNet.Serialization { public abstract class BuilderSkeleton<TBuilder> where TBuilder : BuilderSkeleton<TBuilder> { internal INamingConvention namingConvention = NullNamingConvention.Instance; internal ITypeResolver typeResolver; internal readonly YamlAttributeOverrides overrides; internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories; internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories; private bool ignoreFields; protected abstract TBuilder Self { get; } internal BuilderSkeleton(ITypeResolver typeResolver) { overrides = new YamlAttributeOverrides(); typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter> { { typeof(YamlDotNet.Serialization.Converters.GuidConverter), (Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false) }, { typeof(SystemTypeConverter), (Nothing _) => new SystemTypeConverter() } }; typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>(); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); } internal ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver); if (!ignoreFields) { typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector); } return typeInspectorFactories.BuildComponentChain(typeInspector); } public TBuilder IgnoreFields() { ignoreFields = true; return Self; } public TBuilder WithNamingConvention(INamingConvention namingConvention) { this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention"); return Self; } public TBuilder WithTypeResolver(ITypeResolver typeResolver) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); return Self; } public abstract TBuilder WithTagMapping(string tag, Type type); public TBuilder WithAttributeOverride<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute) { overrides.Add(propertyAccessor, attribute); return Self; } public TBuilder WithAttributeOverride(Type type, string member, Attribute attribute) { overrides.Add(type, member, attribute); return Self; } public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter) { return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w) { w.OnTop(); }); } public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) { IYamlTypeConverter typeConverter2 = typeConverter; if (typeConverter2 == null) { throw new ArgumentNullException("typeConverter"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2)); return Self; } public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter { WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory2 = typeConverterFactory; if (typeConverterFactory2 == null) { throw new ArgumentNullException("typeConverterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(wrapped))); return Self; } public TBuilder WithoutTypeConverter<TYamlTypeConverter>() where TYamlTypeConverter : IYamlTypeConverter { return WithoutTypeConverter(typeof(TYamlTypeConverter)); } public TBuilder WithoutTypeConverter(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } typeConverterFactories.Remove(converterType); return Self; } public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory) where TTypeInspector : ITypeInspector { return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> w) { w.OnTop(); }); } public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory, Action<IRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector { Func<ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner))); return Self; } public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector { WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(wrapped, inner))); return Self; } public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector { return WithoutTypeInspector(typeof(ITypeInspector)); } public TBuilder WithoutTypeInspector(Type inspectorType) { if (inspectorType == null) { throw new ArgumentNullException("inspectorType"); } typeInspectorFactories.Remove(inspectorType); return Self; } protected IEnumerable<IYamlTypeConverter> BuildTypeConverters() { return typeConverterFactories.BuildComponentList(); } } public delegate TComponent WrapperFactory<TComponentBase, TComponent>(TComponentBase wrapped) where TComponent : TComponentBase; public delegate TComponent WrapperFactory<TArgument, TComponentBase, TComponent>(TComponentBase wrapped, TArgument argument) where TComponent : TComponentBase; public enum DefaultValuesHandling { Preserve, OmitNull, OmitDefaults } public sealed class Deserializer : IDeserializer { private readonly IValueDeserializer valueDeserializer; public Deserializer() : this(new DeserializerBuilder().BuildValueDeserializer()) { } private Deserializer(IValueDeserializer valueDeserializer) { this.valueDeserializer = valueDeserializer ?? throw new ArgumentNullException("valueDeserializer"); } public static Deserializer FromValueDeserializer(IValueDeserializer valueDeserializer) { return new Deserializer(valueDeserializer); } public T Deserialize<T>(string input) { using StringReader input2 = new StringReader(input); return Deserialize<T>(input2); } public T Deserialize<T>(TextReader input) { return Deserialize<T>(new Parser(input)); } public object? Deserialize(TextReader input) { return Deserialize(input, typeof(object)); } public object? Deserialize(string input, Type type) { using StringReader input2 = new StringReader(input); return Deserialize(input2, type); } public object? Deserialize(TextReader input, Type type) { return Deserialize(new Parser(input), type); } public T Deserialize<T>(IParser parser) { return (T)Deserialize(parser, typeof(T)); } public object? Deserialize(IParser parser) { return Deserialize(parser, typeof(object)); } public object? Deserialize(IParser parser, Type type) { if (parser == null) { throw new ArgumentNullException("parser"); } if (type == null) { throw new ArgumentNullException("type"); } YamlDotNet.Core.Events.StreamStart @event; bool flag = parser.TryConsume<YamlDotNet.Core.Events.StreamStart>(out @event); YamlDotNet.Core.Events.DocumentStart event2; bool flag2 = parser.TryConsume<YamlDotNet.Core.Events.DocumentStart>(out event2); object result = null; if (!parser.Accept<YamlDotNet.Core.Events.DocumentEnd>(out var _) && !parser.Accept<YamlDotNet.Core.Events.StreamEnd>(out var _)) { using SerializerState serializerState = new SerializerState(); result = valueDeserializer.DeserializeValue(parser, type, serializerState, valueDeserializer); serializerState.OnDeserialization(); } if (flag2) { parser.Consume<YamlDotNet.Core.Events.DocumentEnd>(); } if (flag) { parser.Consume<YamlDotNet.Core.Events.StreamEnd>(); } return result; } } public sealed class DeserializerBuilder : BuilderSkeleton<DeserializerBuilder> { private IObjectFactory objectFactory = new DefaultObjectFactory(); private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories; private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories; private readonly Dictionary<string, Type> tagMappings; private bool ignoreUnmatched; protected override DeserializerBuilder Self => this; public DeserializerBuilder() : base((ITypeResolver)new StaticTypeResolver()) { tagMappings = new Dictionary<string, Type> { { "tag:yaml.org,2002:map", typeof(Dictionary<object, object>) }, { "tag:yaml.org,2002:bool", typeof(bool) }, { "tag:yaml.org,2002:float", typeof(double) }, { "tag:yaml.org,2002:int", typeof(int) }, { "tag:yaml.org,2002:str", typeof(string) }, { "tag:yaml.org,2002:timestamp", typeof(DateTime) } }; typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner)); typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner); typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner)); typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone())); typeInspectorFactories.Add(typeof(ReadableAndWritablePropertiesTypeInspector), (ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner)); nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer> { { typeof(YamlConvertibleNodeDeserializer), (Nothing _) => new YamlConvertibleNodeDeserializer(objectFactory) }, { typeof(YamlSerializableNodeDeserializer), (Nothing _) => new YamlSerializableNodeDeserializer(objectFactory) }, { typeof(TypeConverterNodeDeserializer), (Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters()) }, { typeof(NullNodeDeserializer), (Nothing _) => new NullNodeDeserializer() }, { typeof(ScalarNodeDeserializer), (Nothing _) => new ScalarNodeDeserializer() }, { typeof(ArrayNodeDeserializer), (Nothing _) => new ArrayNodeDeserializer() }, { typeof(DictionaryNodeDeserializer), (Nothing _) => new DictionaryNodeDeserializer(objectFactory) }, { typeof(CollectionNodeDeserializer), (Nothing _) => new CollectionNodeDeserializer(objectFactory) }, { typeof(EnumerableNodeDeserializer), (Nothing _) => new EnumerableNodeDeserializer() }, { typeof(ObjectNodeDeserializer), (Nothing _) => new ObjectNodeDeserializer(objectFactory, BuildTypeInspector(), ignoreUnmatched) } }; nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver> { { typeof(YamlConvertibleTypeResolver), (Nothing _) => new YamlConvertibleTypeResolver() }, { typeof(YamlSerializableTypeResolver), (Nothing _) => new YamlSerializableTypeResolver() }, { typeof(TagNodeTypeResolver), (Nothing _) => new TagNodeTypeResolver(tagMappings) }, { typeof(PreventUnknownTagsNodeTypeResolver), (Nothing _) => new PreventUnknownTagsNodeTypeResolver() }, { typeof(DefaultContainersNodeTypeResolver), (Nothing _) => new DefaultContainersNodeTypeResolver() } }; } public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory) { this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory"); return this; } public DeserializerBuilder WithObjectFactory(Func<Type, object> objectFactory) { if (objectFactory == null) { throw new ArgumentNullException("objectFactory"); } return WithObjectFactory(new LambdaObjectFactory(objectFactory)); } public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer) { return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> w) { w.OnTop(); }); } public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where) { INodeDeserializer nodeDeserializer2 = nodeDeserializer; if (nodeDeserializer2 == null) { throw new ArgumentNullException("nodeDeserializer"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2)); return this; } public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer { WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory2 = nodeDeserializerFactory; if (nodeDeserializerFactory2 == null) { throw new ArgumentNullException("nodeDeserializerFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(wrapped))); return this; } public DeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer { return WithoutNodeDeserializer(typeof(TNodeDeserializer)); } public DeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType) { if (nodeDeserializerType == null) { throw new ArgumentNullException("nodeDeserializerType"); } nodeDeserializerFactories.Remove(nodeDeserializerType); return this; } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver) { return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w) { w.OnTop(); }); } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) { INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver; if (nodeTypeResolver2 == null) { throw new ArgumentNullException("nodeTypeResolver"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2)); return this; } public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver { WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory2 = nodeTypeResolverFactory; if (nodeTypeResolverFactory2 == null) { throw new ArgumentNullException("nodeTypeResolverFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(wrapped))); return this; } public DeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver { return WithoutNodeTypeResolver(typeof(TNodeTypeResolver)); } public DeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType) { if (nodeTypeResolverType == null) { throw new ArgumentNullException("nodeTypeResolverType"); } nodeTypeResolverFactories.Remove(nodeTypeResolverType); return this; } public override DeserializerBuilder WithTagMapping(string tag, Type type) { if (tag == null) { throw new ArgumentNullException("tag"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(tag, out Type value)) { throw new ArgumentException("Type already has a registered type '" + value.FullName + "' for tag '" + tag + "'", "tag"); } tagMappings.Add(tag, type); return this; } public DeserializerBuilder WithoutTagMapping(string tag) { if (tag == null) { throw new ArgumentNullException("tag"); } if (!tagMappings.Remove(tag)) { throw new KeyNotFoundException("Tag '" + tag + "' is not registered"); } return this; } public DeserializerBuilder IgnoreUnmatchedProperties() { ignoreUnmatched = true; return this; } public IDeserializer Build() { return Deserializer.FromValueDeserializer(BuildValueDeserializer()); } public IValueDeserializer BuildValueDeserializer() { return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList())); } } public sealed class EmissionPhaseObjectGraphVisitorArgs { private readonly IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors; public IObjectGraphVisitor<IEmitter> InnerVisitor { get; private set; } public IEventEmitter EventEmitter { get; private set; } public ObjectSerializer NestedObjectSerializer { get; private set; } public IEnumerable<IYamlTypeConverter> TypeConverters { get; private set; } public EmissionPhaseObjectGraphVisitorArgs(IObjectGraphVisitor<IEmitter> innerVisitor, IEventEmitter eventEmitter, IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors, IEnumerable<IYamlTypeConverter> typeConverters, ObjectSerializer nestedObjectSerializer) { InnerVisitor = innerVisitor ?? throw new ArgumentNullException("innerVisitor"); EventEmitter = eventEmitter ?? throw new ArgumentNullException("eventEmitter"); this.preProcessingPhaseVisitors = preProcessingPhaseVisitors ?? throw new ArgumentNullException("preProcessingPhaseVisitors"); TypeConverters = typeConverters ?? throw new ArgumentNullException("typeConverters"); NestedObjectSerializer = nestedObjectSerializer ?? throw new ArgumentNullException("nestedObjectSerializer"); } public T GetPreProcessingPhaseObjectGraphVisitor<T>() where T : IObjectGraphVisitor<Nothing> { return preProcessingPhaseVisitors.OfType<T>().Single(); } } public abstract class EventInfo { public IObjectDescriptor Source { get; } protected EventInfo(IObjectDescriptor source) { Source = source ?? throw new ArgumentNullException("source"); } } public class AliasEventInfo : EventInfo { public string Alias { get; } public AliasEventInfo(IObjectDescriptor source, string alias) : base(source) { Alias = alias ?? throw new ArgumentNullException("alias"); } } public class ObjectEventInfo : EventInfo { public string? Anchor { get; set; } public string? Tag { get; set; } protected ObjectEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class ScalarEventInfo : ObjectEventInfo { public string RenderedValue { get; set; } public ScalarStyle Style { get; set; } public bool IsPlainImplicit { get; set; } public bool IsQuotedImplicit { get; set; } public ScalarEventInfo(IObjectDescriptor source) : base(source) { Style = source.ScalarStyle; RenderedValue = string.Empty; } } public sealed class MappingStartEventInfo : ObjectEventInfo { public bool IsImplicit { get; set; } public MappingStyle Style { get; set; } public MappingStartEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class MappingEndEventInfo : EventInfo { public MappingEndEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class SequenceStartEventInfo : ObjectEventInfo { public bool IsImplicit { get; set; } public SequenceStyle Style { get; set; } public SequenceStartEventInfo(IObjectDescriptor source) : base(source) { } } public sealed class SequenceEndEventInfo : EventInfo { public SequenceEndEventInfo(IObjectDescriptor source) : base(source) { } } public interface IAliasProvider { string? GetAlias(object target); } public interface IDeserializer { T Deserialize<T>(string input); T Deserialize<T>(TextReader input); object? Deserialize(TextReader input); object? Deserialize(string input, Type type); object? Deserialize(TextReader input, Type type); T Deserialize<T>(IParser parser); object? Deserialize(IParser parser); object? Deserialize(IParser parser, Type type); } public interface IEventEmitter { void Emit(AliasEventInfo eventInfo, IEmitter emitter); void Emit(ScalarEventInfo eventInfo, IEmitter emitter); void Emit(MappingStartEventInfo eventInfo, IEmitter emitter); void Emit(MappingEndEventInfo eventInfo, IEmitter emitter); void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter); void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter); } public interface INamingConvention { string Apply(string value); } public interface INodeDeserializer { bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value); } public interface INodeTypeResolver { bool Resolve(NodeEvent? nodeEvent, ref Type currentType); } public interface IObjectDescriptor { object? Value { get; } Type Type { get; } Type StaticType { get; } ScalarStyle ScalarStyle { get; } } public static class ObjectDescriptorExtensions { public static object NonNullValue(this IObjectDescriptor objectDescriptor) { return objectDescriptor.Value ?? throw new InvalidOperationException("Attempted to use a IObjectDescriptor of type '" + objectDescriptor.Type.FullName + "' whose Value is null at a point whete it is invalid to do so. This may indicate a bug in YamlDotNet."); } } public interface IObjectFactory { object Create(Type type); } public interface IObjectGraphTraversalStrategy { void Traverse<TContext>(IObjectDescriptor graph, IObjectGraphVisitor<TContext> visitor, TContext context); } public interface IObjectGraphVisitor<TContext> { bool Enter(IObjectDescriptor value, TContext context); bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, TContext context); bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, TContext context); void VisitScalar(IObjectDescriptor scalar, TContext context); void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, TContext context); void VisitMappingEnd(IObjectDescriptor mapping, TContext context); void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, TContext context); void VisitSequenceEnd(IObjectDescriptor sequence, TContext context); } public interface IPropertyDescriptor { string Name { get; } bool CanWrite { get; } Type Type { get; } Type? TypeOverride { get; set; } int Order { get; set; } ScalarStyle ScalarStyle { get; set; } T GetCustomAttribute<T>() where T : Attribute; IObjectDescriptor Read(object target); void Write(object target, object? value); } public interface IRegistrationLocationSelectionSyntax<TBaseRegistrationType> { void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType; void Before<TRegistrationType>() where TRegistrationType : TBaseRegistrationType; void After<TRegistrationType>() where TRegistrationType : TBaseRegistrationType; void OnTop(); void OnBottom(); } public interface ITrackingRegistrationLocationSelectionSyntax<TBaseRegistrationType> { void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType; } public interface ISerializer { void Serialize(TextWriter writer, object graph); string Serialize(object graph); void Serialize(TextWriter writer, object graph, Type type); void Serialize(IEmitter emitter, object graph); void Serialize(IEmitter emitter, object graph, Type type); } public interface ITypeInspector { IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container); IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched); } public interface ITypeResolver { Type Resolve(Type staticType, object? actualValue); } public interface IValueDeserializer { object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer); } public interface IValuePromise { event Action<object?> ValueAvailable; } public interface IValueSerializer { void SerializeValue(IEmitter emitter, object? value, Type? type); } public interface IYamlConvertible { void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer); void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer); } public delegate object? ObjectDeserializer(Type type); public delegate void ObjectSerializer(object? value, Type? type = null); [Obsolete("Please use IYamlConvertible instead")] public interface IYamlSerializable { void ReadYaml(IParser parser); void WriteYaml(IEmitter emitter); } public interface IYamlTypeConverter { bool Accepts(Type type); object? ReadYaml(IParser parser, Type type); void WriteYaml(IEmitter emitter, object? value, Type type); } internal sealed class LazyComponentRegistrationList<TArgument, TComponent> : IEnumerable<Func<TArgument, TComponent>>, IEnumerable { public sealed class LazyComponentRegistration { public readonly Type ComponentType; public readonly Func<TArgument, TComponent> Factory; public LazyComponentRegistration(Type componentType, Func<TArgument, TComponent> factory) { ComponentType = componentType; Factory = factory; } } public sealed class TrackingLazyComponentRegistration { public readonly Type ComponentType; public readonly Func<TComponent, TArgument, TComponent> Factory; public TrackingLazyComponentRegistration(Type componentType, Func<TComponent, TArgument, TComponent> factory) { ComponentType = componentType; Factory = factory; } } private class RegistrationLocationSelector : IRegistrationLocationSelectionSyntax<TComponent> { private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations; private readonly LazyComponentRegistration newRegistration; public RegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, LazyComponentRegistration newRegistration) { this.registrations = registrations; this.newRegistration = newRegistration; } void IRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>() { if (newRegistration.ComponentType != typeof(TRegistrationType)) { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); } int index = registrations.EnsureRegistrationExists<TRegistrationType>(); registrations.entries[index] = newRegistration; } void IRegistrationLocationSelectionSyntax<TComponent>.After<TRegistrationType>() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); int num = registrations.EnsureRegistrationExists<TRegistrationType>(); registrations.entries.Insert(num + 1, newRegistration); } void IRegistrationLocationSelectionSyntax<TComponent>.Before<TRegistrationType>() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); int index = registrations.EnsureRegistrationExists<TRegistrationType>(); registrations.entries.Insert(index, newRegistration); } void IRegistrationLocationSelectionSyntax<TComponent>.OnBottom() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); registrations.entries.Add(newRegistration); } void IRegistrationLocationSelectionSyntax<TComponent>.OnTop() { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); registrations.entries.Insert(0, newRegistration); } } private class TrackingRegistrationLocationSelector : ITrackingRegistrationLocationSelectionSyntax<TComponent> { private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations; private readonly TrackingLazyComponentRegistration newRegistration; public TrackingRegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, TrackingLazyComponentRegistration newRegistration) { this.registrations = registrations; this.newRegistration = newRegistration; } void ITrackingRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>() { if (newRegistration.ComponentType != typeof(TRegistrationType)) { registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType); } int index = registrations.EnsureRegistrationExists<TRegistrationType>(); Func<TArgument, TComponent> innerComponentFactory = registrations.entries[index].Factory; registrations.entries[index] = new LazyComponentRegistration(newRegistration.ComponentType, (TArgument arg) => newRegistration.Factory(innerComponentFactory(arg), arg)); } } private readonly List<LazyComponentRegistration> entries = new List<LazyComponentRegistration>(); public int Count => entries.Count; public IEnumerable<Func<TArgument, TComponent>> InReverseOrder { get { int i = entries.Count - 1; while (i >= 0) { yield return entries[i].Factory; int num = i - 1; i = num; } } } public LazyComponentRegistrationList<TArgument, TComponent> Clone() { LazyComponentRegistrationList<TArgument, TComponent> lazyComponentRegistrationList = new LazyComponentRegistrationList<TArgument, TComponent>(); foreach (LazyComponentRegistration entry in entries) { lazyComponentRegistrationList.entries.Add(entry); } return lazyComponentRegistrationList; } public void Add(Type componentType, Func<TArgument, TComponent> factory) { entries.Add(new LazyComponentRegistration(componentType, factory)); } public void Remove(Type componentType) { for (int i = 0; i < entries.Count; i++) { if (entries[i].ComponentType == componentType) { entries.RemoveAt(i); return; } } throw new KeyNotFoundException("A component registration of type '" + componentType.FullName + "' was not found."); } public IRegistrationLocationSelectionSyntax<TComponent> CreateRegistrationLocationSelector(Type componentType, Func<TArgument, TComponent> factory) { return new RegistrationLocationSelector(this, new LazyComponentRegistration(componentType, factory)); } public ITrackingRegistrationLocationSelectionSyntax<TComponent> CreateTrackingRegistrationLocationSelector(Type componentType, Func<TComponent, TArgument, TComponent> factory) { return new TrackingRegistrationLocationSelector(this, new TrackingLazyComponentRegistration(componentType, factory)); } public IEnumerator<Func<TArgument, TComponent>> GetEnumerator() { return entries.Select((LazyComponentRegistration e) => e.Factory).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private int IndexOfRegistration(Type registrationType) { for (int i = 0; i < entries.Count; i++) { if (registrationType == entries[i].ComponentType) { return i; } } return -1; } private void EnsureNoDuplicateRegistrationType(Type componentType) { if (IndexOfRegistration(componentType) != -1) { throw new InvalidOperationException("A component of type '" + componentType.FullName + "' has already been registered."); } } private int EnsureRegistrationExists<TRegistrationType>() { int num = IndexOfRegistration(typeof(TRegistrationType)); if (num == -1) { throw new InvalidOperationException("A component of type '" + typeof(TRegistrationType).FullName + "' has not been registered."); } return num; } } internal static class LazyComponentRegistrationListExtensions { public static TComponent BuildComponentChain<TComponent>(this LazyComponentRegistrationList<TComponent, TComponent> registrations, TComponent innerComponent) { return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TComponent, TComponent> factory) => factory(inner)); } public static TComponent BuildComponentChain<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TComponent innerComponent, Func<TComponent, TArgument> argumentBuilder) { Func<TComponent, TArgument> argumentBuilder2 = argumentBuilder; return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TArgument, TComponent> factory) => factory(argumentBuilder2(inner))); } public static List<TComponent> BuildComponentList<TComponent>(this LazyComponentRegistrationList<Nothing, TComponent> registrations) { return registrations.Select((Func<Nothing, TComponent> factory) => factory(Nothing.Instance)).ToList(); } public static List<TComponent> BuildComponentList<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TArgument argument) { TArgument argument2 = argument; return registrations.Select((Func<TArgument, TComponent> factory) => factory(argument2)).ToList(); } } public sealed class Nothing { public static readonly Nothing Instance = new Nothing(); private Nothing() { } } public sealed class ObjectDescriptor : IObjectDescriptor { public object? Value { get; private set; } public Type Type { get; private set; } public Type StaticType { get; private set; } public ScalarStyle ScalarStyle { get; private set; } public ObjectDescriptor(object? value, Type type, Type staticType) : this(value, type, staticType, ScalarStyle.Any) { } public ObjectDescriptor(object? value, Type type, Type staticType, ScalarStyle scalarStyle) { Value = value; Type = type ?? throw new ArgumentNullException("type"); StaticType = staticType ?? throw new ArgumentNullException("staticType"); ScalarStyle = scalarStyle; } } public delegate IObjectGraphTraversalStrategy ObjectGraphTraversalStrategyFactory(ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion); public sealed class PropertyDescriptor : IPropertyDescriptor { private readonly IPropertyDescriptor baseDescriptor; public string Name { get; set; } public Type Type => baseDescriptor.Type; public Type? TypeOverride { get { return baseDescriptor.TypeOverride; } set { baseDescriptor.TypeOverride = value; } } public int Order { get; set; } public ScalarStyle ScalarStyle { get { return baseDescriptor.ScalarStyle; } set { baseDescriptor.ScalarStyle = value; } } public bool CanWrite => baseDescriptor.CanWrite; public PropertyDescriptor(IPropertyDescriptor baseDescriptor) { this.baseDescriptor = baseDescriptor; Name = baseDescriptor.Name; } public void Write(object target, object? value) { baseDescriptor.Write(target, value); } public T GetCustomAttribute<T>() where T : Attribute { return baseDescriptor.GetCustomAttribute<T>(); } public IObjectDescriptor Read(object target) { return baseDescriptor.Read(target); } } public sealed class Serializer : ISerializer { private readonly IValueSerializer valueSerializer; private readonly EmitterSettings emitterSettings; public Serializer() : this(new SerializerBuilder().BuildValueSerializer(), EmitterSettings.Default) { } private Serializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings) { this.valueSerializer = valueSerializer ?? throw new ArgumentNullException("valueSerializer"); this.emitterSettings = emitterSettings ?? throw new ArgumentNullException("emitterSettings"); } public static Serializer FromValueSerializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings) { return new Serializer(valueSerializer, emitterSettings); } public void Serialize(TextWriter writer, object graph) { Serialize(new Emitter(writer, emitterSettings), graph); } public string Serialize(object graph) { using StringWriter stringWriter = new StringWriter(); Serialize(stringWriter, graph); return stringWriter.ToString(); } public void Serialize(TextWriter writer, object graph, Type type) { Serialize(new Emitter(writer, emitterSettings), graph, type); } public void Serialize(IEmitter emitter, object graph) { if (emitter == null) { throw new ArgumentNullException("emitter"); } EmitDocument(emitter, graph, null); } public void Serialize(IEmitter emitter, object graph, Type type) { if (emitter == null) { throw new ArgumentNullException("emitter"); } if (type == null) { throw new ArgumentNullException("type"); } EmitDocument(emitter, graph, type); } private void EmitDocument(IEmitter emitter, object graph, Type? type) { emitter.Emit(new YamlDotNet.Core.Events.StreamStart()); emitter.Emit(new YamlDotNet.Core.Events.DocumentStart()); valueSerializer.SerializeValue(emitter, graph, type); emitter.Emit(new YamlDotNet.Core.Events.DocumentEnd(isImplicit: true)); emitter.Emit(new YamlDotNet.Core.Events.StreamEnd()); } } public sealed class SerializerBuilder : BuilderSkeleton<SerializerBuilder> { private class ValueSerializer : IValueSerializer { private readonly IObjectGraphTraversalStrategy traversalStrategy; private readonly IEventEmitter eventEmitter; private readonly IEnumerable<IYamlTypeConverter> typeConverters; private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories; public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable<IYamlTypeConverter> typeConverters, LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories) { this.traversalStrategy = traversalStrategy; this.eventEmitter = eventEmitter; this.typeConverters = typeConverters; this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories; this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories; } public void SerializeValue(IEmitter emitter, object? value, Type? type) { IEmitter emitter2 = emitter; Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object)); Type staticType = type ?? typeof(object); ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType); List<IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters); foreach (IObjectGraphVisitor<Nothing> item in preProcessingPhaseObjectGraphVisitors) { traversalStrategy.Traverse(graph, item, null); } IObjectGraphVisitor<IEmitter> visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor<IEmitter> inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, nestedObjectSerializer)); traversalStrategy.Traverse(graph, visitor, emitter2); void nestedObjectSerializer(object? v, Type? t) { SerializeValue(emitter2, v, t); } } } private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory; private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories; private readonly LazyComponentRegistrationList<IEventEmitter, IEventEmitter> eventEmitterFactories; private readonly IDictionary<Type, string> tagMappings = new Dictionary<Type, string>(); private int maximumRecursion = 50; private EmitterSettings emitterSettings = EmitterSettings.Default; private DefaultValuesHandling defaultValuesHandlingConfiguration; protected override SerializerBuilder Self => this; public SerializerBuilder() : base((ITypeResolver)new DynamicTypeResolver()) { typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner)); typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner); typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner)); typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone())); preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> { { typeof(AnchorAssigner), (IEnumerable<IYamlTypeConverter> typeConverters) => new AnchorAssigner(typeConverters) } }; emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> { { typeof(CustomSerializationObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer) }, { typeof(AnchorAssigningObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor<AnchorAssigner>()) }, { typeof(DefaultValuesObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor) } }; eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { { typeof(TypeAssigningEventEmitter), (IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: false, tagMappings) } }; objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention); } public SerializerBuilder WithMaximumRecursion(int maximumRecursion) { if (maximumRecursion <= 0) { throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer."); } this.maximumRecursion = maximumRecursion; return this; } public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter { return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w) { w.OnTop(); }); } public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter { Func<IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory; if (eventEmitterFactory2 == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory2(inner))); return Self; } public SerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter { WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory; if (eventEmitterFactory2 == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory2(wrapped, inner))); return Self; } public SerializerBuilder WithoutEventEmitter<TEventEmitter>() where TEventEmitter : IEventEmitter { return WithoutEventEmitter(typeof(TEventEmitter)); } public SerializerBuilder WithoutEventEmitter(Type eventEmitterType) { if (eventEmitterType == null) { throw new ArgumentNullException("eventEmitterType"); } eventEmitterFactories.Remove(eventEmitterType); return this; } public override SerializerBuilder WithTagMapping(string tag, Type type) { if (tag == null) { throw new ArgumentNullException("tag"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(type, out string value)) { throw new ArgumentException("Type already has a registered tag '" + value + "' for type '" + type.FullName + "'", "type"); } tagMappings.Add(type, tag); return this; } public SerializerBuilder WithoutTagMapping(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!tagMappings.Remove(type)) { throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered"); } return this; } public SerializerBuilder EnsureRoundtrip() { objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention); WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc) { loc.InsteadOf<TypeAssigningEventEmitter>(); }); return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc) { loc.OnBottom(); }); } public SerializerBuilder DisableAliases() { preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner)); emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor)); return this; } [Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)] public SerializerBuilder EmitDefaults() { return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve); } public SerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration) { defaultValuesHandlingConfiguration = configuration; return this; } public SerializerBuilder JsonCompatible() { emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue); return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w) { w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>(); }).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc) { loc.InsteadOf<TypeAssigningEventEmitter>(); }); } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing> { return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w) { w.OnTop(); }); } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing> { TObjectGraphVisitor objectGraphVisitor2 = objectGraphVisitor; if (objectGraphVisitor2 == null) { throw new ArgumentNullException("objectGraphVisitor"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable<IYamlTypeConverter> _) => objectGraphVisitor2)); return this; } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing> { WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> _) => objectGraphVisitorFactory2(wrapped))); return this; } public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<Nothing> { return WithoutPreProcessingPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor)); } public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor(Type objectGraphVisitorType) { if (objectGraphVisitorType == null) { throw new ArgumentNullException("objectGraphVisitorType"); } preProcessingPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType); return this; } public SerializerBuilder WithObjectGraphTraversalStrategyFactory(ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory) { this.objectGraphTraversalStrategyFactory = objectGraphTraversalStrategyFactory; return this; } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter> { return WithEmissionPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>> w) { w.OnTop(); }); } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter> { Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(args))); return this; } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter> { WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory; if (objectGraphVisitorFactory2 == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<IEmitter> wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(wrapped, args))); return this; } public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter> { return WithoutEmissionPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor)); } public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor(Type objectGraphVisitorType) { if (objectGraphVisitorType == null) { throw new ArgumentNullException("objectGraphVisitorType"); } emissionPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType); return this; } public ISerializer Build() { return Serializer.FromValueSerializer(BuildValueSerializer(), emitterSettings); } public IValueSerializer BuildValueSerializer() { IEnumerable<IYamlTypeConverter> typeConverters = BuildTypeConverters(); ITypeInspector typeInspector = BuildTypeInspector(); IObjectGraphTraversalStrategy traversalStrategy = objectGraphTraversalStrategyFactory(typeInspector, typeResolver, typeConverters, maximumRecursion); IEventEmitter eventEmitter = eventEmitterFactories.BuildComponentChain(new WriterEventEmitter()); return new ValueSerializer(traversalStrategy, eventEmitter, typeConverters, preProcessingPhaseObjectGraphVisitorFactories.Clone(), emissionPhaseObjectGraphVisitorFactories.Clone()); } } public sealed class StreamFragment : IYamlConvertible { private readonly List<ParsingEvent> events = new List<ParsingEvent>(); public IList<ParsingEvent> Events => events; void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer) { events.Clear(); int num = 0; do { if (!parser.MoveNext()) { throw new InvalidOperationException("The parser has reached the end before deserialization completed."); } ParsingEvent current = parser.Current; events.Add(current); num += current.NestingIncrease; } while (num > 0); } void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer) { foreach (ParsingEvent @event in events) { emitter.Emit(@event); } } } public sealed class TagMappings { private readonly IDictionary<string, Type> mappings; public TagMappings() { mappings = new Dictionary<string, Type>(); } public TagMappings(IDictionary<string, Type> mappings) { this.mappings = new Dictionary<string, Type>(mappings); } public void Add(string tag, Type mapping) { mappings.Add(tag, mapping); } internal Type? GetMapping(string tag) { if (!mappings.TryGetValue(tag, out Type value)) { return null; } return value; } } public sealed class YamlAttributeOverrides { private struct AttributeKey { public readonly Type AttributeType; public readonly string PropertyName; public AttributeKey(Type attributeType, string propertyName) { AttributeType = attributeType; PropertyName = propertyName; } public override bool Equals(object? obj) { if (obj is AttributeKey attributeKey && AttributeType.Equals(attributeKey.AttributeType)) { return PropertyName.Equals(attributeKey.PropertyName); } return false; } public override int GetHashCode() { return YamlDotNet.Core.HashCode.CombineHashCodes(AttributeType.GetHashCode(), PropertyName.GetHashCode()); } } private sealed class AttributeMapping { public readonly Type RegisteredType; public readonly Attribute Attribute; public AttributeMapping(Type registeredType, Attribute attribute) { RegisteredType = registeredType; Attribute = attribute; } public override bool Equals(object? obj) { if (obj is AttributeMapping attributeMapping && RegisteredType.Equals(attributeMapping.RegisteredType)) { return Attribute.Equals(attributeMapping.Attribute); } return false; } public override int GetHashCode() { return YamlDotNet.Core.HashCode.CombineHashCodes(RegisteredType.GetHashCode(), Attribute.GetHashCode()); } public int Matches(Type matchType) { int num = 0; Type type = matchType; while (type != null) { num++; if (type == RegisteredType) { return num; } type = type.BaseType(); } if (matchType.GetInterfaces().Contains(RegisteredType)) { return num; } return 0; } } private readonly Dictionary<AttributeKey, List<AttributeMapping>> overrides = new Dictionary<AttributeKey, List<AttributeMapping>>(); public T? GetAttribute<T>(Type type, string member) where T : Attribute { if (overrides.TryGetValue(new AttributeKey(typeof(T), member), out List<AttributeMapping> value)) { int num = 0; AttributeMapping attributeMapping = null; foreach (AttributeMapping item in value) { int num2 = item.Matches(type); if (num2 > num) { num = num2; attributeMapping = item; } } if (num > 0) { return (T)attributeMapping.Attribute; } } return null; } public void Add(Type type, string member, Attribute attribute) { AttributeMapping item = new AttributeMapping(type, attribute); AttributeKey key = new AttributeKey(attribute.GetType(), member); if (!overrides.TryGetValue(key, out List<AttributeMapping> value)) { value = new List<AttributeMapping>(); overrides.Add(key, value); } else if (value.Contains(item)) { throw new InvalidOperationException($"Attribute ({attribute}) already set for Type {type.FullName}, Member {member}"); } value.Add(item); } public void Add<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute) { PropertyInfo propertyInfo = propertyAccessor.AsProperty(); Add(typeof(TClass), propertyInfo.Name, attribute); } public YamlAttributeOverrides Clone() { YamlAttributeOverrides yamlAttributeOverrides = new YamlAttributeOverrides(); foreach (KeyValuePair<AttributeKey, List<AttributeMapping>> @override in overrides) { foreach (AttributeMapping item in @override.Value) { yamlAttributeOverrides.Add(item.RegisteredType, @override.Key.PropertyName, item.Attribute); } } return yamlAttributeOverrides; } } public sealed class YamlAttributeOverridesInspector : TypeInspectorSkeleton { public sealed class OverridePropertyDescriptor : IPropertyDescriptor { private readonly IPropertyDescriptor baseDescriptor; private readonly YamlAttributeOverrides overrides; private readonly Type classType; public string Name => baseDescriptor.Name; public bool CanWrite => baseDescriptor.CanWrite; public Type Type => baseDescriptor.Type; public Type? TypeOverride { get { return baseDescriptor.TypeOverride; } set { baseDescriptor.TypeOverride = value; } } public int Order { get { return baseDescriptor.Order; } set { baseDescriptor.Order = value; } } public ScalarStyle ScalarStyle { get { return baseDescriptor.ScalarStyle; } set { baseDescriptor.ScalarStyle = value; } } public OverridePropertyDescriptor(IPropertyDescriptor baseDescriptor, YamlAttributeOverrides overrides, Type classType) { this.baseDescriptor = baseDescriptor; this.overrides = overrides; this.classType = classType; } public void Write(object target, object? value) { baseDescriptor.Write(target, value); } public T GetCustomAttribute<T>() where T : Attribute { return overrides.GetAttribute<T>(classType, Name) ?? baseDescriptor.GetCustomAttribute<T>(); } public IObjectDescriptor Read(object target) { return baseDescriptor.Read(target); } } private readonly ITypeInspector innerTypeDescriptor; private readonly YamlAttributeOverrides overrides; public YamlAttributeOverridesInspector(ITypeInspector innerTypeDescriptor, YamlAttributeOverrides overrides) { this.innerTypeDescriptor = innerTypeDescriptor; this.overrides = overrides; } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { Type type2 = type; IEnumerable<IPropertyDescriptor> enumerable = innerTypeDescriptor.GetProperties(type2, container); if (overrides != null) { enumerable = enumerable.Select((Func<IPropertyDescriptor, IPropertyDescriptor>)((IPropertyDescriptor p) => new OverridePropertyDescriptor(p, overrides, type2))); } return enumerable; } } public sealed class YamlAttributesTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; public YamlAttributesTypeInspector(ITypeInspector innerTypeDescriptor) { this.innerTypeDescriptor = innerTypeDescriptor; } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { return from p in (from p in innerTypeDescriptor.GetProperties(type, container) where p.GetCustomAttribute<YamlIgnoreAttribute>() == null select p).Select((Func<IPropertyDescriptor, IPropertyDescriptor>)delegate(IPropertyDescriptor p) { PropertyDescriptor propertyDescriptor = new PropertyDescriptor(p); YamlMemberAttribute customAttribute = p.GetCustomAttribute<YamlMemberAttribute>(); if (customAttribute != null) { if (customAttribute.SerializeAs != null) { propertyDescriptor.TypeOverride = customAttribute.SerializeAs; } propertyDescriptor.Order = customAttribute.Order; propertyDescriptor.ScalarStyle = customAttribute.ScalarStyle; if (customAttribute.Alias != null) { propertyDescriptor.Name = customAttribute.Alias; } } return propertyDescriptor; }) orderby p.Order select p; } } internal static class YamlFormatter { public static readonly NumberFormatInfo NumberFormat = new NumberFormatInfo { CurrencyDecimalSeparator = ".", CurrencyGroupSeparator = "_", CurrencyGroupSizes = new int[1] { 3 }, CurrencySymbol = string.Empty, CurrencyDecimalDigits = 99, NumberDecimalSeparator = ".", NumberGroupSeparator = "_", NumberGroupSizes = new int[1] { 3 }, NumberDecimalDigits = 99, NaNSymbol = ".nan", PositiveInfinitySymbol = ".inf", NegativeInfinitySymbol = "-.inf" }; public static string FormatNumber(object number) { return Convert.ToString(number, NumberFormat); } public static string FormatNumber(double number) { return number.ToString("G17", NumberFormat); } public static string FormatNumber(float number) { return number.ToString("G17", NumberFormat); } public static string FormatBoolean(object boolean) { if (!boolean.Equals(true)) { return "false"; } return "true"; } public static string FormatDateTime(object dateTime) { return ((DateTime)dateTime).ToString("o", CultureInfo.InvariantCulture); } public static string FormatTimeSpan(object timeSpan) { return ((TimeSpan)timeSpan).ToString(); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class YamlIgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class YamlMemberAttribute : Attribute { private DefaultValuesHandling? defaultValuesHandling; public Type? SerializeAs { get; set; } public int Order { get; set; } public string? Alias { get; set; } public bool ApplyNamingConventions { get; set; } public ScalarStyle ScalarStyle { get; set; } public DefaultValuesHandling DefaultValuesHandling { get { return defaultValuesHandling.GetValueOrDefault(); } set { defaultValuesHandling = value; } } public bool IsDefaultValuesHandlingSpecified => defaultValuesHandling.HasValue; public YamlMemberAttribute() { ScalarStyle = ScalarStyle.Any; ApplyNamingConventions = true; } public YamlMemberAttribute(Type serializeAs) : this() { SerializeAs = serializeAs ?? throw new ArgumentNullException("serializeAs"); } } } namespace YamlDotNet.Serialization.ValueDeserializers { public sealed class AliasValueDeserializer : IValueDeserializer { private sealed class AliasState : Dictionary<string, ValuePromise>, IPostDeserializationCallback { public void OnDeserialization() { foreach (ValuePromise value in base.Values) { if (!value.HasValue) { YamlDotNet.Core.Events.AnchorAlias alias = value.Alias; throw new AnchorNotFoundException(alias.Start, alias.End, "Anchor '" + alias.Value + "' not found"); } } } } private sealed class ValuePromise : IValuePromise { private object? value; public readonly YamlDotNet.Core.Events.AnchorAlias? Alias; public bool HasValue { get; private set; } public object? Value { get { if (!HasValue) { throw new InvalidOperationException("Value not set"); } return value; } set { if (HasValue) { throw new InvalidOperationException("Value already set"); } HasValue = true; this.value = value; this.ValueAvailable?.Invoke(value); } } public event Action<object?>? ValueAvailable; public ValuePromise(YamlDotNet.Core.Events.AnchorAlias alias) { Alias = alias; } public ValuePromise(object? value) { HasValue = true; this.value = value; } } private readonly IValueDeserializer innerDeserializer; public AliasValueDeserializer(IValueDeserializer innerDeserializer) { this.innerDeserializer = innerDeserializer ?? throw new ArgumentNullException("innerDeserializer"); } public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) { if (parser.TryConsume<YamlDotNet.Core.Events.AnchorAlias>(out var @event)) { AliasState aliasState = state.Get<AliasState>(); if (!aliasState.TryGetValue(@event.Value, out ValuePromise value)) { value = new ValuePromise(@event); aliasState.Add(@event.Value, value); } if (!value.HasValue) { return value; } return value.Value; } string text = null; if (parser.Accept<NodeEvent>(out var event2) && !string.IsNullOrEmpty(event2.Anchor)) { text = event2.Anchor; } object obj = innerDeserializer.DeserializeValue(parser, expectedType, state, nestedObjectDeserializer); if (text != null) { AliasState aliasState2 = state.Get<AliasState>(); if (!aliasState2.TryGetValue(text, out ValuePromise value2)) { aliasState2.Add(text, new ValuePromise(obj)); } else if (!value2.HasValue) { value2.Value = obj; } else { aliasState2[text] = new ValuePromise(obj); } } return obj; } } public sealed class NodeValueDeserializer : IValueDeserializer { private readonly IList<INodeDeserializer> deserializers; private readonly IList<INodeTypeResolver> typeResolvers; public NodeValueDeserializer(IList<INodeDeserializer> deserializers, IList<INodeTypeResolver> typeResolvers) { this.deserializers = deserializers ?? throw new ArgumentNullException("deserializers"); this.typeResolvers = typeResolvers ?? throw new ArgumentNullException("typeResolvers"); } public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) { IValueDeserializer nestedObjectDeserializer2 = nestedObjectDeserializer; SerializerState state2 = state; parser.Accept<NodeEvent>(out var @event); Type typeFromEvent = GetTypeFromEvent(@event, expectedType); try { foreach (INodeDeserializer deserializer in deserializers) { if (deserializer.Deserialize(parser, typeFromEvent, (IParser r, Type t) => nestedObjectDeserializer2.DeserializeValue(r, t, state2, nestedObjectDeserializer2), out object value)) { return YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(value, expectedType); } } } catch (YamlException) { throw; } catch (Exception innerException) { throw new YamlException(@event?.Start ?? Mark.Empty, @event?.End ?? Mark.Empty, "Exception during deserialization", innerException); } throw new YamlException(@event?.Start ?? Mark.Empty, @event?.End ?? Mark.Empty, "No node deserializer was able to deserialize the node into type " + expectedType.AssemblyQualifiedName); } private Type GetTypeFromEvent(NodeEvent? nodeEvent, Type currentType) { using (IEnumerator<INodeTypeResolver> enumerator = typeResolvers.GetEnumerator()) { while (enumerator.MoveNext() && !enumerator.Current.Resolve(nodeEvent, ref currentType)) { } } return currentType; } } } namespace YamlDotNet.Serialization.Utilities { public interface IPostDeserializationCallback { void OnDeserialization(); } internal sealed class ObjectAnchorCollection { private readonly IDictionary<string, object> objectsByAnchor = new Dictionary<string, object>(); private readonly IDictionary<object, string> anchorsByObject = new Dictionary<object, string>(); public object this[string anchor] { get { if (objectsByAnchor.TryGetValue(anchor, out object value)) { return value; } throw new AnchorNotFoundException("The anchor '" + anchor + "' does not exists"); } } public void Add(string anchor, object @object) { objectsByAnchor.Add(anchor, @object); if (@object != null) { anchorsByObject.Add(@object, anchor); } } public bool TryGetAnchor(object @object, [MaybeNullWhen(false)] out string? anchor) { return anchorsByObject.TryGetValue(@object, out anchor); } } internal static class ReflectionUtility { public static Type? GetImplementedGenericInterface(Type type, Type genericInterfaceType) { foreach (Type implementedInterface in GetImplementedInterfaces(type)) { if (implementedInterface.IsGenericType() && implementedInterface.GetGenericTypeDefinition() == genericInterfaceType) { return implementedInterface; } } return null; } public static IEnumerable<Type> GetImplementedInterfaces(Type type) { if (type.IsInterface()) { yield return type; } Type[] interfaces = type.GetInterfaces(); for (int i = 0; i < interfaces.Length; i++) { yield return interfaces[i]; } } } public sealed class SerializerState : IDisposable { private readonly IDictionary<Type, object> items = new Dictionary<Type, object>(); public T Get<T>() where T : class, new() { if (!items.TryGetValue(typeof(T), out object value)) { value = new T(); items.Add(typeof(T), value); } return (T)value; } public void OnDeserialization() { foreach (IPostDeserializationCallback item in items.Values.OfType<IPostDeserializationCallback>()) { item.OnDeserialization(); } } public void Dispose() { foreach (IDisposable item in items.Values.OfType<IDisposable>()) { item.Dispose(); } } } internal static class StringExtensions { private static string ToCamelOrPascalCase(string str, Func<char, char> firstLetterTransform) { string text = Regex.Replace(str, "([_\\-])(?<char>[a-z])", (Match match) => match.Groups["char"].Value.ToUpperInvariant(), RegexOptions.IgnoreCase); return firstLetterTransform(text[0]) + text.Substring(1); } public static string ToCamelCase(this string str) { return ToCamelOrPascalCase(str, char.ToLowerInvariant); } public static string ToPascalCase(this string str) { return ToCamelOrPascalCase(str, char.ToUpperInvariant); } public static string FromCamelCase(this string str, string separator) { string separator2 = separator; str = char.ToLower(str[0]) + str.Substring(1); str = Regex.Replace(str.ToCamelCase(), "(?<char>[A-Z])", (Match match) => separator2 + match.Groups["char"].Value.ToLowerInvariant()); return str; } } public static class TypeConverter { [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")] public static void RegisterTypeConverter<TConvertible, TConverter>() where TConverter : System.ComponentModel.TypeConverter { if (!TypeDescriptor.GetAttributes(typeof(TConvertible)).OfType<TypeConverterAttribute>().Any((TypeConverterAttribute a) => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName)) { TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter))); } } public static T ChangeType<T>(object? value) { return (T)ChangeType(value, typeof(T)); } public static T ChangeType<T>(object? value, IFormatProvider provider) { return (T)ChangeType(value, typeof(T), provider); } public static T ChangeType<T>(object? value, CultureInfo culture) { return (T)ChangeType(value, typeof(T), culture); } public static object? ChangeType(object? value, Type destinationType) { return ChangeType(value, destinationType, CultureInfo.InvariantCulture); } public static object? ChangeType(object? value, Type destinationType, IFormatProvider provider) { return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider)); } public static object? ChangeType(object? value, Type destinationType, CultureInfo culture) { if (value == null || value.IsDbNull()) { if (!destinationType.IsValueType()) { return null; } return Activator.CreateInstance(destinationType); } Type type = value.GetType(); if (destinationType == type || destinationType.IsAssignableFrom(type)) { return value; } if (destinationType.IsGenericType() && destinationType.GetGenericTypeDefinition() == typeof(Nullable<>)) { Type destinationType2 = destinationType.GetGenericArguments()[0]; object obj = ChangeType(value, destinationType2, culture); return Activator.CreateInstance(destinationType, obj); } if (destinationType.IsEnum()) { if (!(value is string value2)) { return value; } return Enum.Parse(destinationType, value2, ignoreCase: true); } if (destinationType == typeof(bool)) { if ("0".Equals(value)) { return false; } if ("1".Equals(value)) { return true; } } System.ComponentModel.TypeConverter converter = TypeDescriptor.GetConverter(type); if (converter != null && converter.CanConvertTo(destinationType)) { return converter.ConvertTo(null, culture, value, destinationType); } System.ComponentModel.TypeConverter converter2 = TypeDescriptor.GetConverter(destinationType); if (converter2 != null && converter2.CanConvertFrom(type)) { return converter2.ConvertFrom(null, culture, value); } Type[] array = new Type[2] { type, destinationType }; for (int i = 0; i < array.Length; i++) { foreach (MethodInfo publicStaticMethod2 in array[i].GetPublicStaticMethods()) { if (!publicStaticMethod2.IsSpecialName || (!(publicStaticMethod2.Name == "op_Implicit") && !(publicStaticMethod2.Name == "op_Explicit")) || !destinationType.IsAssignableFrom(publicStaticMethod2.ReturnParameter.ParameterType)) { continue; } ParameterInfo[] parameters = publicStaticMethod2.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(type)) { try { return publicStaticMethod2.Invoke(null, new object[1] { value }); } catch (TargetInvocationException ex) { throw ex.Unwrap(); } } } } if (type == typeof(string)) { try { MethodInfo publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string), typeof(IFormatProvider)); if (publicStaticMethod != null) { return publicStaticMethod.Invoke(null, new object[2] { value, culture }); } publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string)); if (publicStaticMethod != null) { return publicStaticMethod.Invoke(null, new object[1] { value }); } } catch (TargetInvocationException ex2) { throw ex2.Unwrap(); } } if (destinationType == typeof(TimeSpan)) { return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture)); } return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture); } } } namespace YamlDotNet.Serialization.TypeResolvers { public sealed class DynamicTypeResolver : ITypeResolver { public Type Resolve(Type staticType, object? actualValue) { if (actualValue == null) { return staticType; } return actualValue.GetType(); } } public sealed class StaticTypeResolver : ITypeResolver { public Type Resolve(Type staticType, object? actualValue) { return staticType; } } } namespace YamlDotNet.Serialization.TypeInspectors { public sealed class CachedTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; private readonly ConcurrentDictionary<Type, List<IPropertyDescriptor>> cache = new ConcurrentDictionary<Type, List<IPropertyDescriptor>>(); public CachedTypeInspector(ITypeInspector innerTypeDescriptor) { this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor"); } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { object container2 = container; return cache.GetOrAdd(type, (Type t) => innerTypeDescriptor.GetProperties(t, container2).ToList()); } } public sealed class CompositeTypeInspector : TypeInspectorSkeleton { private readonly IEnumerable<ITypeInspector> typeInspectors; public CompositeTypeInspector(params ITypeInspector[] typeInspectors) : this((IEnumerable<ITypeInspector>)typeInspectors) { } public CompositeTypeInspector(IEnumerable<ITypeInspector> typeInspectors) { this.typeInspectors = typeInspectors?.ToList() ?? throw new ArgumentNullException("typeInspectors"); } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { Type type2 = type; object container2 = container; return typeInspectors.SelectMany((ITypeInspector i) => i.GetProperties(type2, container2)); } } public sealed class NamingConventionTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; private readonly INamingConvention namingConvention; public NamingConventionTypeInspector(ITypeInspector innerTypeDescriptor, INamingConvention namingConvention) { this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor"); this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention"); } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { return innerTypeDescriptor.GetProperties(type, container).Select(delegate(IPropertyDescriptor p) { YamlMemberAttribute customAttribute = p.GetCustomAttribute<YamlMemberAttribute>(); return (customAttribute != null && !customAttribute.ApplyNamingConventions) ? p : new PropertyDescriptor(p) { Name = namingConvention.Apply(p.Name) }; }); } } public sealed class ReadableAndWritablePropertiesTypeInspector : TypeInspectorSkeleton { private readonly ITypeInspector innerTypeDescriptor; public ReadableAndWritablePropertiesTypeInspector(ITypeInspector innerTypeDescriptor) { this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor"); } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { return from p in innerTypeDescriptor.GetProperties(type, container) where p.CanWrite select p; } } public sealed class ReadableFieldsTypeInspector : TypeInspectorSkeleton { private sealed class ReflectionFieldDescriptor : IPropertyDescriptor { private readonly FieldInfo fieldInfo; private readonly ITypeResolver typeResolver; public string Name => fieldInfo.Name; public Type Type => fieldInfo.FieldType; public Type? TypeOverride { get; set; } public int Order { get; set; } public bool CanWrite => !fieldInfo.IsInitOnly; public ScalarStyle ScalarStyle { get; set; } public ReflectionFieldDescriptor(FieldInfo fieldInfo, ITypeResolver typeResolver) { this.fieldInfo = fieldInfo; this.typeResolver = typeResolver; ScalarStyle = ScalarStyle.Any; } public void Write(object target, object? value) { fieldInfo.SetValue(target, value); } public T GetCustomAttribute<T>() where T : Attribute { return (T)fieldInfo.GetCustomAttributes(typeof(T), inherit: true).FirstOrDefault(); } public IObjectDescriptor Read(object target) { object value = fieldInfo.GetValue(target); Type type = TypeOverride ?? typeResolver.Resolve(Type, value); return new ObjectDescriptor(value, type, Type, ScalarStyle); } } private readonly ITypeResolver typeResolver; public ReadableFieldsTypeInspector(ITypeResolver typeResolver) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { return type.GetPublicFields().Select((Func<FieldInfo, IPropertyDescriptor>)((FieldInfo p) => new ReflectionFieldDescriptor(p, typeResolver))); } } public sealed class ReadablePropertiesTypeInspector : TypeInspectorSkeleton { private sealed class ReflectionPropertyDescriptor : IPropertyDescriptor { private readonly PropertyInfo propertyInfo; private readonly ITypeResolver typeResolver; public string Name => propertyInfo.Name; public Type Type => propertyInfo.PropertyType; public Type? TypeOverride { get; set; } public int Order { get; set; } public bool CanWrite => propertyInfo.CanWrite; public ScalarStyle ScalarStyle { get; set; } public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver) { this.propertyInfo = propertyInfo ?? throw new ArgumentNullException("propertyInfo"); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); ScalarStyle = ScalarStyle.Any; } public void Write(object target, object? value) { propertyInfo.SetValue(target, value, null); } public T GetCustomAttribute<T>() where T : Attribute { return (T)propertyInfo.GetAllCustomAttributes<T>().FirstOrDefault(); } public IObjectDescriptor Read(object target) { object obj = propertyInfo.ReadValue(target); Type type = TypeOverride ?? typeResolver.Resolve(Type, obj); return new ObjectDescriptor(obj, type, Type, ScalarStyle); } } private readonly ITypeResolver typeResolver; public ReadablePropertiesTypeInspector(ITypeResolver typeResolver) { this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); } private static bool IsValidProperty(PropertyInfo property) { if (property.CanRead) { return property.GetGetMethod().GetParameters().Length == 0; } return false; } public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container) { return type.GetPublicProperties().Where(IsValidProperty).Select((Func<PropertyInfo, IPropertyDescriptor>)((PropertyInfo p) => new ReflectionPropertyDescriptor(p, typeResolver))); } } public abstract class TypeInspectorSkeleton : ITypeInspector { public abstract IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container); public IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched) { string name2 = name; IEnumerable<IPropertyDescriptor> enumerable = from p in GetProperties(type, container) where p.Name == name2 select p; using IEnumerator<IPropertyDescriptor> enumerator = enumerable.GetEnumerator(); if (!enumerator.MoveNext()) { if (ignoreUnmatched) { return null; } throw new SerializationException("Property '" + name2 + "' not found on type '" + type.FullName + "'."); } IPropertyDescriptor current = enumerator.Current; if (enumerator.MoveNext()) { throw new SerializationException("Multiple properties with the name/alias '" + name2 + "' already exists on type '" + type.FullName + "', maybe you're misusing YamlAlias or maybe you are using the wrong naming convention? The matching properties are: " + string.Join(", ", enumerable.Select((IPropertyDescriptor p) => p.Name).ToArray())); } return current; } } } namespace YamlDotNet.Serialization.ObjectGraphVisitors { public sealed class AnchorAssigner : PreProcessingPhaseObjectGraphVisitorSkeleton, IAliasProvider { private class AnchorAssignment { public string? Anchor; } private readonly IDictionary<object, AnchorAssignment> assignments = new Dictionary<object, AnchorAssignment>(); private uint nextId; public AnchorAssigner(IEnumerable<IYamlTypeConverter> typeConverters) : base(typeConverters) { } protected override bool Enter(IObjectDescriptor value) { if (value.Value != null && assignments.TryGetValue(value.Value, out AnchorAssignment value2)) { if (value2.Anchor == null) { value2.Anchor = "o" + nextId.ToString(CultureInfo.InvariantCulture); nextId++; } return false; } return true; } protected override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value) { return true; } protected override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) { return true; } protected override void VisitScalar(IObjectDescriptor scalar) { } protected override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) { VisitObject(mapping); } protected override void VisitMappingEnd(IObjectDescriptor mapping) { } protected override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType) { VisitObject(sequence); } protected override void VisitSequenceEnd(IObjectDescriptor sequence) { } private void VisitObject(IObjectDescriptor value) { if (value.Value != null) { assignments.Add(value.Value, new AnchorAssignment()); } } string? IAliasProvider.GetAlias(object target) { if (target != null && assignments.TryGetValue(target, out AnchorAssignment value)) { return value.Anchor; } return null; } } public sealed class AnchorAssigningObjectGraphVisitor : ChainedObjectGraphVisitor { private readonly IEventEmitter eventEmitter; private readonly IAliasProvider aliasProvider; private readonly HashSet<string> emittedAliases = new HashSet<string>(); public AnchorAssigningObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor, IEventEmitter eventEmitter, IAliasProvider aliasProvider) : base(nextVisitor) { this.eventEmitter = eventEmitter; this.aliasProvider = aliasProvider; } public override bool Enter(IObjectDescriptor value, IEmitter context) { if (value.Value != null) { string alias = aliasProvider.GetAlias(value.Value); if (alias != null && !emittedAliases.Add(alias)) { eventEmitter.Emit(new AliasEventInfo(value, alias), context); return false; } } return base.Enter(value, context); } public override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, IEmitter context) { string alias = aliasProvider.GetAlias(mapping.NonNullValue()); eventEmitter.Emit(new MappingStartEventInfo(mapping) { Anchor = alias }, context); } public override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, IEmitter context) { string alias = aliasProvider.GetAlias(sequence.NonNullValue()); eventEmitter.Emit(new SequenceStartEventInfo(sequence) { Anchor = alias }, context); } public override void VisitScalar(IObjectDescriptor scalar, IEmitter context) { ScalarEventInfo scalarEventInfo = new ScalarEventInfo(scalar); if (scalar.Value != null) { scalarEventInfo.Anchor = aliasProvider.GetAlias(scalar.Value); } eventEmitter.Emit(scalarEventInfo, context); } } public abstract class ChainedObjectGraphVisitor : IObjectGraphVisitor<IEmitter> { private readonly IObjectGraphVisitor<IEmitter> nextVisitor; protected ChainedObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor) { this.nextVisitor = nextVisitor; } public virtual bool Enter(IObjectDescriptor value, IEmitter context) { return nextVisitor.Enter(value, context); } public virtual bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, IEmitter context) { return nextVisitor.EnterMapping(key, value, context); } public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context) { return next