Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Mantle v0.1.29
plugins/Mantle/Mantle.Core.dll
Decompiled 5 hours agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ExtraPotions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2026 ExtraPotions")] [assembly: AssemblyFileVersion("0.1.29.0")] [assembly: AssemblyInformationalVersion("0.1.29+fatal: not a git repository (or any of the parent directories): .git")] [assembly: AssemblyProduct("Mantle.Core")] [assembly: AssemblyTitle("Mantle.Core")] [assembly: AssemblyVersion("0.1.29.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Mantle.Trinkets { public static class KillGain { public static float Calculate(float fraction, float effectiveMaximum, float targetMultiplier) { if (!Finite(fraction) || fraction <= 0f || fraction > 0.1f || !Finite(effectiveMaximum) || effectiveMaximum <= 0f || !Finite(targetMultiplier) || targetMultiplier <= 0f) { return 0f; } double num = (double)fraction * (double)effectiveMaximum * (double)targetMultiplier; if (!(num <= 3.4028234663852886E+38)) { return 0f; } return (float)num; } internal static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } public static class KillEligibility { public static bool IsEligible(bool serverValidated, bool unambiguousAttribution, bool hasNativeTrinket, bool isPlayer, bool isTamed, bool isHostile, float targetMultiplier, long creditedKiller, long recipient) { if (serverValidated && unambiguousAttribution && hasNativeTrinket && !isPlayer && !isTamed && isHostile && KillGain.Finite(targetMultiplier) && targetMultiplier > 0f && creditedKiller != 0L) { return creditedKiller == recipient; } return false; } } public sealed class DeathCreditLedger { private readonly HashSet<string> deaths = new HashSet<string>(StringComparer.Ordinal); private readonly int capacity; private readonly object gate = new object(); public int Count { get { lock (gate) { return deaths.Count; } } } public DeathCreditLedger(int capacity = 1000000) { if (capacity <= 0) { throw new ArgumentOutOfRangeException("capacity"); } this.capacity = capacity; } public bool TryClaim(string deathId, long killer) { if (string.IsNullOrWhiteSpace(deathId) || deathId.Length > 256 || killer == 0L) { return false; } lock (gate) { return deaths.Count < capacity && deaths.Add(deathId); } } public void Clear() { lock (gate) { deaths.Clear(); } } } public enum TrinketPreset { Native, Conservative, Custom } public sealed class TrinketRow { public string PrefabId { get; } public float Threshold { get; } public float Duration { get; } public float KillFraction { get; } public IReadOnlyDictionary<string, float> Effects { get; } public TrinketRow(string prefabId, float threshold, float duration, float killFraction, IReadOnlyDictionary<string, float> effects) { PrefabId = prefabId; Threshold = threshold; Duration = duration; KillFraction = killFraction; Dictionary<string, float> dictionary = new Dictionary<string, float>(StringComparer.Ordinal); if (effects != null) { foreach (KeyValuePair<string, float> effect in effects) { dictionary.Add(effect.Key, effect.Value); } } Effects = new ReadOnlyDictionary<string, float>(dictionary); } public TrinketRow WithKillFraction(float fraction) { return new TrinketRow(PrefabId, Threshold, Duration, fraction, Effects); } } public sealed class TrinketTable { private static readonly HashSet<string> nativeIds = new HashSet<string>(NativeIds, StringComparer.Ordinal); public static IReadOnlyList<string> NativeIds { get; } = Array.AsReadOnly(new string[15] { "TrinketBronzeHealth", "TrinketBronzeStamina", "TrinketChitinSwim", "TrinketIronHealth", "TrinketIronStamina", "TrinketSilverDamage", "TrinketSilverResist", "TrinketBlackDamageHealth", "TrinketBlackStamina", "TrinketCarapaceEitr", "TrinketScaleStaminaDamage", "TrinketFlametalEitr", "TrinketFlametalStaminaHealth", "TrinketBloodGoldHealth", "TrinketBloodGoldStamina" }); public IReadOnlyDictionary<string, TrinketRow> Rows { get; } private TrinketTable(Dictionary<string, TrinketRow> rows) { Rows = new ReadOnlyDictionary<string, TrinketRow>(rows); } public bool TryGet(string prefabId, out TrinketRow row) { row = null; if (prefabId != null) { return Rows.TryGetValue(prefabId, out row); } return false; } public static bool TryCreateNative(IEnumerable<TrinketRow> rows, out TrinketTable table, out string error) { return TryCreate(rows, null, out table, out error); } public static bool TryCreateCustom(IEnumerable<TrinketRow> rows, TrinketTable native, out TrinketTable table, out string error) { if (native == null) { table = null; error = "Native trinket data is unavailable."; return false; } return TryCreate(rows, native, out table, out error); } public static TrinketTable ForPreset(TrinketPreset preset, TrinketTable native, TrinketTable custom = null) { if (native == null) { return null; } switch (preset) { case TrinketPreset.Custom: return custom ?? native; default: return native; case TrinketPreset.Conservative: { Dictionary<string, TrinketRow> dictionary = new Dictionary<string, TrinketRow>(StringComparer.Ordinal); foreach (KeyValuePair<string, TrinketRow> row in native.Rows) { dictionary.Add(row.Key, row.Value.WithKillFraction(0.05f)); } return new TrinketTable(dictionary); } } } private static bool TryCreate(IEnumerable<TrinketRow> source, TrinketTable native, out TrinketTable table, out string error) { table = null; error = null; if (source == null) { error = "A complete trinket table is required."; return false; } Dictionary<string, TrinketRow> dictionary = new Dictionary<string, TrinketRow>(StringComparer.Ordinal); foreach (TrinketRow item in source) { if (item == null || item.PrefabId == null || !nativeIds.Contains(item.PrefabId)) { error = "Unknown native trinket prefab."; return false; } if (dictionary.ContainsKey(item.PrefabId)) { error = "Duplicate trinket prefab: " + item.PrefabId; return false; } if (!InRange(item.Threshold, 1f, 200f) || !InRange(item.Duration, 0.1f, 300f) || !InRange(item.KillFraction, 0f, 0.1f) || (native == null && item.KillFraction != 0f)) { error = "Invalid threshold, duration or kill fraction: " + item.PrefabId; return false; } if (item.Effects.Count == 0 || item.Effects.Count > 24) { error = "Native effect fields are required: " + item.PrefabId; return false; } TrinketRow row = null; if (native != null && (!native.TryGet(item.PrefabId, out row) || row.Effects.Count != item.Effects.Count)) { error = "Effect fields must match the native trinket: " + item.PrefabId; return false; } foreach (KeyValuePair<string, float> effect in item.Effects) { if (!ValidEffect(effect.Key, effect.Value) || (row != null && !row.Effects.ContainsKey(effect.Key))) { error = "Invalid or unknown effect field: " + item.PrefabId + "/" + effect.Key; return false; } } dictionary.Add(item.PrefabId, item); } if (dictionary.Count != NativeIds.Count) { error = "A trinket table must contain all 15 native prefabs."; return false; } table = new TrinketTable(dictionary); return true; } private static bool InRange(float value, float minimum, float maximum) { if (KillGain.Finite(value) && value >= minimum) { return value <= maximum; } return false; } private static bool ValidEffect(string field, float value) { switch (field) { case "m_healthUpFront": case "m_staminaUpFront": case "m_eitrUpFront": return InRange(value, 0f, 200f); case "m_skillLevelModifier2": case "m_skillLevelModifier": return InRange(value, 0f, 30f); case "m_addArmor": return InRange(value, 0f, 40f); case "m_eitrRegenMultiplier": case "m_staminaRegenMultiplier": case "m_healthRegenMultiplier": return InRange(value, 1f, 2f); case "m_timedBlockBonus": return InRange(value, 0f, 1f); case "m_swimStaminaUseModifier": case "m_blockStaminaUseModifier": case "m_runStaminaDrainModifier": case "m_attackStaminaUseModifier": return InRange(value, -1f, 0f); case "m_speedModifier": case "m_swimSpeedModifier": return InRange(value, 0f, 0.5f); case "m_percentigeDamageModifiers.m_blunt": case "m_percentigeDamageModifiers.m_slash": case "m_percentigeDamageModifiers.m_pierce": return InRange(value, 0f, 1f); case "resistance.Blunt": case "resistance.Slash": case "resistance.Pierce": return ValidResistance(value); default: return false; } } private static bool ValidResistance(float value) { if (InRange(value, 0f, 8f)) { return value == (float)(int)value; } return false; } } } namespace Mantle.Tackle { public static class BaitRule { public static bool Matches(bool equipableAmmo, bool nonEquipableAmmo, string ammoType, string rodAmmoType) { if (!equipableAmmo && !nonEquipableAmmo) { return false; } if (string.IsNullOrEmpty(rodAmmoType)) { return nonEquipableAmmo; } return ammoType == rodAmmoType; } } } namespace Mantle.Compatibility { public static class SlowJoinWait { public readonly struct Step { public float Deadline { get; } public bool Holding { get; } public bool GiveUp { get; } public bool LogSlow { get; } public Step(float deadline, bool holding, bool giveUp, bool logSlow) { Deadline = deadline; Holding = holding; GiveUp = giveUp; LogSlow = logSlow; } } public const float QuietSeconds = 60f; public const float CeilingSeconds = 300f; public const float FormerTimeoutSeconds = 20f; public const int BacklogBytes = 65536; public static Step Advance(float greeted, float deadline, float now, int queuedBytes, bool slowLogged) { return Advance(greeted, deadline, now, queuedBytes, slowLogged, -1); } public static Step Advance(float greeted, float deadline, float now, int queuedBytes, bool slowLogged, int previousQueuedBytes) { float num = greeted + 300f; bool flag = !(now >= deadline) && !(now >= num) && previousQueuedBytes > 65536 && queuedBytes >= 0 && queuedBytes < previousQueuedBytes; float num2 = (flag ? Math.Min(num, Math.Max(deadline, now + 60f)) : deadline); bool flag2 = now >= num2 || now >= num; bool holding = !flag2 && queuedBytes > 65536; return new Step(num2, holding, flag2, flag && !slowLogged && now - greeted > 20f); } public static string[] NoAnswerLines(float seconds) { string text = seconds.ToString("0", CultureInfo.InvariantCulture); return new string[7] { "Your game did not answer this server's mod check in " + text + " seconds (mods missing, or a very slow connection).", "Tu juego no respondió a la comprobación de mods de este servidor en " + text + " segundos (faltan mods, o la conexión es muy lenta).", "Votre jeu n'a pas répondu à la vérification des mods de ce serveur en " + text + " secondes (mods manquants, ou connexion très lente).", "Dein Spiel hat die Mod-Prüfung dieses Servers innerhalb von " + text + " Sekunden nicht beantwortet (Mods fehlen, oder die Verbindung ist sehr langsam).", "Твоя игра не ответила на проверку модов этого сервера за " + text + " с (моды отсутствуют или соединение очень медленное).", "你的游戏未在 " + text + " 秒内回应此服务器的模组检查(缺少模组,或连接非常慢)。", "게임이 " + text + "초 안에 이 서버의 모드 확인에 응답하지 않았습니다(모드가 없거나 연결이 매우 느립니다)." }; } public static string ServerRuns(string title, string version) { string text = title + " " + version; return "This server runs " + text + ". / Este servidor ejecuta " + text + ". / Ce serveur utilise " + text + ". / Dieser Server verwendet " + text + ". / Этот сервер использует " + text + ". / 此服务器运行 " + text + "。 / 이 서버는 " + text + "을(를) 실행합니다."; } } public static class StatusRowRoom { public const float Margin = 8f; public static int PerRow(int nativePerRow, float firstCenter, float cell, float rowTop, float rowBottom, float left, float right, float top, float bottom) { int num = Math.Max(1, nativePerRow); if (cell <= 0f || bottom <= rowTop || top >= rowBottom || left >= firstCenter + cell * 0.5f) { return num; } float num2 = firstCenter - cell * 0.5f - (right + 8f); if (num2 < 0f) { return 1; } return Math.Max(1, Math.Min(num, 1 + (int)Math.Floor(num2 / cell))); } public static bool Overlaps(float left, float right, float bottom, float top, float otherLeft, float otherRight, float otherBottom, float otherTop) { if (left <= otherRight && otherLeft <= right && bottom <= otherTop) { return otherBottom <= top; } return false; } } public sealed class StatusRowHold { public const int ReleaseFrames = 2; private bool holding; private int lastOpenFrame; public bool Holding(bool windowOpen, int frame) { if (windowOpen) { holding = true; lastOpenFrame = frame; return true; } if (holding && frame - lastOpenFrame <= 2 && frame >= lastOpenFrame) { return true; } holding = false; return false; } public void Reset() { holding = false; } } public static class VersionFloor { public static string OldestAccepted(string version) { Version version2 = new Version(version); return version2.Major + "." + version2.Minor + ".0"; } } } namespace Mantle.Accessories { public static class AccessoryCatalog { private const string Workbench = "piece_workbench"; private const string Forge = "forge"; private const string GaldrTable = "piece_magetable"; public static IReadOnlyList<AccessoryEntry> All { get; } = new List<AccessoryEntry> { Mantles("Mantle_BoneBand", AccessorySlot.Ring, "Bone Band", "A band of polished bone, bound with a strip of leather.", 0.2f, "piece_workbench", 1, "BoneFragments:6, LeatherScraps:2", new AccessoryStats(0f, 5f)), Mantles("Mantle_CopperRing", AccessorySlot.Ring, "Copper Ring", "A plain copper ring set with a chip of amber.", 0.2f, "forge", 1, "Copper:3, Amber:1", new AccessoryStats(10f)), Mantles("Mantle_IronRing", AccessorySlot.Ring, "Iron Ring", "A heavy iron ring, its inside smeared with blood.", 0.3f, "forge", 2, "Iron:3, Bloodbag:2", new AccessoryStats(0f, 0f, 0f, 10f)), Mantles("Mantle_SilverRing", AccessorySlot.Ring, "Silver Ring", "A silver ring as cold as the glands it was cooled in.", 0.2f, "forge", 3, "Silver:3, FreezeGland:2", new AccessoryStats(0f, 0f, 0f, 0f, 5f)), Mantles("Mantle_BlackMetalRing", AccessorySlot.Ring, "Black Metal Ring", "A black metal ring stitched through with needle wire.", 0.3f, "forge", 4, "BlackMetal:3, Needle:3", new AccessoryStats(0f, 0f, 0f, 0f, 0f, -10f)), Mantles("Mantle_EitrRing", AccessorySlot.Ring, "Eitr Ring", "A silver ring that hums with refined eitr.", 0.2f, "piece_magetable", 1, "Eitr:3, Silver:2", new AccessoryStats(0f, 0f, 15f)), Mantles("Mantle_LeatherBelt", AccessorySlot.Belt, "Leather Belt", "A sturdy belt of deer hide and leather scraps.", 1f, "piece_workbench", 1, "DeerHide:4, LeatherScraps:4", new AccessoryStats(0f, 0f, 0f, 0f, 0f, 0f, 25f)), Mantles("Mantle_TrollHideBelt", AccessorySlot.Belt, "Troll Hide Belt", "A thick troll hide belt with a bronze buckle.", 1.5f, "piece_workbench", 2, "TrollHide:3, Bronze:1", new AccessoryStats(0f, 0f, 0f, 0f, 0f, 0f, 40f)), Mantles("Mantle_LoxBelt", AccessorySlot.Belt, "Lox Belt", "A broad belt of lox pelt, reinforced with black metal.", 2f, "piece_workbench", 3, "LoxPelt:3, BlackMetal:2", new AccessoryStats(0f, 5f, 0f, 0f, 0f, 0f, 60f)), new AccessoryEntry("BeltStrength", AccessorySlot.Belt, new AccessoryStats(0f, 0f, 0f, 0f, 0f, 0f, 150f)) }; private static AccessoryEntry Mantles(string id, AccessorySlot slot, string name, string look, float weight, string station, int level, string cost, AccessoryStats stats) { return new AccessoryEntry(id, slot, stats, new AccessoryRecipe(station, level, cost), name, look, weight, enabled: true, builtIn: true); } } public sealed class StatLine { public string Key { get; } public string Number { get; } public StatLine(string key, string number) { Key = key; Number = number; } } public static class AccessoryDescription { public static IReadOnlyList<StatLine> Lines(AccessoryStats stats) { List<StatLine> list = new List<StatLine>(); Add(list, "stat_max_health", stats.MaxHealth); Add(list, "stat_max_stamina", stats.MaxStamina); Add(list, "stat_max_eitr", stats.MaxEitr); Add(list, "stat_carry", stats.Carry); Add(list, "stat_stamina_regen", stats.StaminaRegenPercent); Add(list, "stat_move_speed", stats.MoveSpeedPercent); Add(list, (stats.AttackStaminaPercent < 0f) ? "stat_attack_stamina_less" : "stat_attack_stamina_more", stats.AttackStaminaPercent); return list; } private static void Add(List<StatLine> lines, string key, float value) { if (value != 0f) { lines.Add(new StatLine(key, Math.Abs(value).ToString("0.##", CultureInfo.InvariantCulture))); } } } public enum AccessorySlot { Ring, Belt } public sealed class AccessoryRecipe { public string Station { get; } public int Level { get; } public string Cost { get; } public AccessoryRecipe(string station, int level, string cost) { Station = station; Level = level; Cost = cost; } } public sealed class AccessoryEntry { public string Id { get; } public AccessorySlot Slot { get; } public AccessoryStats Stats { get; } public AccessoryRecipe Recipe { get; } public string Name { get; } public string Look { get; } public float Weight { get; } public bool Enabled { get; } public bool BuiltIn { get; } public AccessoryEntry(string id, AccessorySlot slot, AccessoryStats stats, AccessoryRecipe recipe = null, string name = null, string look = null, float weight = 0f, bool enabled = true, bool builtIn = false) { Id = id; Slot = slot; Stats = stats ?? AccessoryStats.None; Recipe = recipe; Name = name; Look = look; Weight = weight; Enabled = enabled; BuiltIn = builtIn; } public AccessoryEntry With(AccessoryOverride change) { AccessoryRecipe recipe = Recipe; if (BuiltIn && (change.Station != null || change.Level.HasValue || change.Cost != null)) { recipe = new AccessoryRecipe(change.Station ?? Recipe.Station, change.Level ?? Recipe.Level, change.Cost ?? Recipe.Cost); } return new AccessoryEntry(Id, BuiltIn ? Slot : (change.Slot ?? Slot), change.ApplyTo(Stats), recipe, Name, Look, Weight, change.Enabled ?? Enabled, BuiltIn); } } public sealed class AccessoryOverride { public string Id { get; set; } public AccessorySlot? Slot { get; set; } public bool? Enabled { get; set; } public string Station { get; set; } public int? Level { get; set; } public string Cost { get; set; } public float? MaxHealth { get; set; } public float? MaxStamina { get; set; } public float? MaxEitr { get; set; } public float? StaminaRegenPercent { get; set; } public float? MoveSpeedPercent { get; set; } public float? AttackStaminaPercent { get; set; } public float? Carry { get; set; } public AccessoryStats ApplyTo(AccessoryStats stats) { return new AccessoryStats(MaxHealth ?? stats.MaxHealth, MaxStamina ?? stats.MaxStamina, MaxEitr ?? stats.MaxEitr, StaminaRegenPercent ?? stats.StaminaRegenPercent, MoveSpeedPercent ?? stats.MoveSpeedPercent, AttackStaminaPercent ?? stats.AttackStaminaPercent, Carry ?? stats.Carry); } } public sealed class AccessoryRegistry { private readonly Dictionary<string, AccessoryEntry> entries = new Dictionary<string, AccessoryEntry>(StringComparer.OrdinalIgnoreCase); public static AccessoryRegistry Current { get; private set; } = new AccessoryRegistry(); public IReadOnlyCollection<AccessoryEntry> All => entries.Values; public static AccessoryRegistry Build(IEnumerable<AccessoryEntry> builtIn, IEnumerable<AccessoryOverride> overrides, ICollection<string> warnings = null) { AccessoryRegistry accessoryRegistry = new AccessoryRegistry(); foreach (AccessoryEntry item in builtIn) { accessoryRegistry.entries[item.Id] = item; } foreach (AccessoryOverride item2 in overrides ?? Array.Empty<AccessoryOverride>()) { if (!string.IsNullOrWhiteSpace(item2.Id)) { string text = item2.Id.Trim(); if (accessoryRegistry.entries.TryGetValue(text, out AccessoryEntry value)) { accessoryRegistry.entries[value.Id] = value.With(item2); } else if (item2.Slot.HasValue) { accessoryRegistry.entries[text] = new AccessoryEntry(text, item2.Slot.Value, item2.ApplyTo(AccessoryStats.None), null, null, null, 0f, item2.Enabled ?? true); } else { warnings?.Add(text + ": not one of Mantle's items; add slot: ring or slot: belt to tag it"); } } } return accessoryRegistry; } public static void Load(AccessoryRegistry registry) { Current = registry ?? new AccessoryRegistry(); } public AccessoryEntry Find(string prefab) { if (prefab == null || !entries.TryGetValue(prefab, out AccessoryEntry value)) { return null; } return value; } public AccessorySlot? SlotOf(string prefab) { AccessoryEntry accessoryEntry = Find(prefab); if (accessoryEntry == null || !accessoryEntry.Enabled) { return null; } return accessoryEntry.Slot; } public AccessoryStats Total(IEnumerable<KeyValuePair<AccessorySlot, string>> inCells) { AccessoryStats accessoryStats = AccessoryStats.None; foreach (KeyValuePair<AccessorySlot, string> inCell in inCells) { accessoryStats = Add(accessoryStats, inCell.Key, inCell.Value); } return accessoryStats; } public AccessoryStats Add(AccessoryStats total, AccessorySlot cell, string prefab) { AccessoryEntry accessoryEntry = Find(prefab); if (accessoryEntry == null || !accessoryEntry.Enabled || accessoryEntry.Slot != cell) { return total; } return total.Plus(accessoryEntry.Stats); } } public sealed class AccessoryStats { public static readonly AccessoryStats None = new AccessoryStats(); public float MaxHealth { get; } public float MaxStamina { get; } public float MaxEitr { get; } public float StaminaRegenPercent { get; } public float MoveSpeedPercent { get; } public float AttackStaminaPercent { get; } public float Carry { get; } public bool IsNone { get { if (MaxHealth == 0f && MaxStamina == 0f && MaxEitr == 0f && StaminaRegenPercent == 0f && MoveSpeedPercent == 0f && AttackStaminaPercent == 0f) { return Carry == 0f; } return false; } } public float StaminaRegenAdd => StaminaRegenPercent / 100f; public AccessoryStats(float maxHealth = 0f, float maxStamina = 0f, float maxEitr = 0f, float staminaRegenPercent = 0f, float moveSpeedPercent = 0f, float attackStaminaPercent = 0f, float carry = 0f) { MaxHealth = maxHealth; MaxStamina = maxStamina; MaxEitr = maxEitr; StaminaRegenPercent = staminaRegenPercent; MoveSpeedPercent = moveSpeedPercent; AttackStaminaPercent = attackStaminaPercent; Carry = carry; } public float SpeedAdd(float baseSpeed) { return baseSpeed * MoveSpeedPercent / 100f; } public float AttackStaminaAdd(float baseUse) { return baseUse * AttackStaminaPercent / 100f; } public float AttackStaminaApplied(float baseUse, float current, bool minZero) { float num = current + AttackStaminaAdd(baseUse); if (!minZero || !(num < 0f)) { return num; } return 0f; } public AccessoryStats Plus(AccessoryStats other) { return new AccessoryStats(MaxHealth + other.MaxHealth, MaxStamina + other.MaxStamina, MaxEitr + other.MaxEitr, StaminaRegenPercent + other.StaminaRegenPercent, MoveSpeedPercent + other.MoveSpeedPercent, AttackStaminaPercent + other.AttackStaminaPercent, Carry + other.Carry); } public override bool Equals(object obj) { if (obj is AccessoryStats accessoryStats && MaxHealth == accessoryStats.MaxHealth && MaxStamina == accessoryStats.MaxStamina && MaxEitr == accessoryStats.MaxEitr && StaminaRegenPercent == accessoryStats.StaminaRegenPercent && MoveSpeedPercent == accessoryStats.MoveSpeedPercent && AttackStaminaPercent == accessoryStats.AttackStaminaPercent) { return Carry == accessoryStats.Carry; } return false; } public override int GetHashCode() { return MaxHealth.GetHashCode() ^ (MaxStamina.GetHashCode() * 31) ^ (Carry.GetHashCode() * 17) ^ (MaxEitr.GetHashCode() * 13); } public override string ToString() { return $"hp {MaxHealth}, stamina {MaxStamina}, eitr {MaxEitr}, regen {StaminaRegenPercent}%, speed {MoveSpeedPercent}%, attack {AttackStaminaPercent}%, carry {Carry}"; } } }
plugins/Mantle/Mantle.dll
Decompiled 5 hours 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.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExtraPotions.Mantle.Embedded.BundlePrefabs; using ExtraPotions.Mantle.Embedded.Charter; using ExtraPotions.Mantle.Embedded.ConfigReload; using ExtraPotions.Mantle.Embedded.EliteCraftingLink; using ExtraPotions.Mantle.Embedded.Hotkeys; using ExtraPotions.Mantle.Embedded.ItemCopies; using ExtraPotions.Mantle.Embedded.PatchGuard; using ExtraPotions.Mantle.Embedded.PlateColumn; using ExtraPotions.Mantle.Embedded.SyncedConfig; using ExtraPotions.Mantle.Embedded.YamlConfig; using ExtraPotions.Meadworks.Contracts; using ExtraPotions.Meadworks.Crucible; using ExtraPotions.Meadworks.Crucible.UI; using ExtraPotions.Meadworks.OriginalArt; using HarmonyLib; using Jotunn.Utils; using MagicaCloth2; using Mantle.Accessories; using Mantle.Backpacks; using Mantle.Compatibility; using Mantle.Consume; using Mantle.Core; using Mantle.Crafting; using Mantle.Elite; using Mantle.Interop; using Mantle.Layout; using Mantle.Look; using Mantle.Panels; using Mantle.Presentation; using Mantle.Protection; using Mantle.Ring; using Mantle.Settings; using Mantle.Slots; using Mantle.Tackle; using Mantle.Trinkets; using Mantle.Worn; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.RepresentationModel; using YamlDotNet.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ExtraPotions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2026 ExtraPotions")] [assembly: AssemblyFileVersion("0.1.29.0")] [assembly: AssemblyInformationalVersion("0.1.29+fatal: not a git repository (or any of the parent directories): .git")] [assembly: AssemblyProduct("Mantle")] [assembly: AssemblyTitle("Mantle")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.29.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExtraPotions.Meadworks.OriginalArt { internal static class OriginalItemArt { [Serializable] private sealed class Catalog { public Entry[] assets; public Surface[] materials; } [Serializable] private sealed class Entry { public string id; public string[] prefabs; } [Serializable] private sealed class Surface { public string id; public string nativePrefab; } private static AssetBundle bundle; private static Dictionary<string, string> ids; private static Dictionary<string, string> nativeMaterials; private static readonly List<Material> ownedMaterials = new List<Material>(); private static readonly Dictionary<string, GameObject> models = new Dictionary<string, GameObject>(StringComparer.Ordinal); private static void Load() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if ((Object)(object)bundle != (Object)null) { return; } Assembly assembly = typeof(OriginalItemArt).Assembly; string platform = (((int)Application.platform == 13 || (int)Application.platform == 43) ? "linux" : "windows"); string text = assembly.GetManifestResourceNames().Single((string n) => n.EndsWith(".original-items." + platform, StringComparison.Ordinal)); using (Stream stream = assembly.GetManifestResourceStream(text)) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); bundle = AssetBundle.LoadFromMemory(memoryStream.ToArray()); } if ((Object)(object)bundle == (Object)null) { throw new InvalidOperationException("Original item art bundle did not load: " + text); } using Stream stream2 = assembly.GetManifestResourceStream("MeadWorks.OriginalItems.catalog.json"); using StreamReader streamReader = new StreamReader(stream2); ids = new Dictionary<string, string>(StringComparer.Ordinal); Catalog catalog = JsonConvert.DeserializeObject<Catalog>(streamReader.ReadToEnd()); if (catalog == null || catalog.assets == null || catalog.assets.Length == 0) { throw new InvalidDataException("Original item catalog contains no assets"); } nativeMaterials = new Dictionary<string, string>(StringComparer.Ordinal); Surface[] array = catalog.materials ?? Array.Empty<Surface>(); foreach (Surface surface in array) { if (!string.IsNullOrEmpty(surface.nativePrefab)) { nativeMaterials.Add(surface.id, surface.nativePrefab); } } Entry[] assets = catalog.assets; foreach (Entry entry in assets) { ids.Add(entry.id, entry.id); string[] array2 = entry.prefabs ?? Array.Empty<string>(); foreach (string text2 in array2) { if (text2 != entry.id) { ids.Add(text2, entry.id); } } } } internal static Sprite Icon(string prefab) { if (MeadworksHeadless.IsHeadless) { return null; } Load(); if (!ids.TryGetValue(prefab, out string value)) { throw new KeyNotFoundException("Original icon missing: " + prefab); } return bundle.LoadAsset<Sprite>(value + "_icon") ?? throw new InvalidDataException("Original icon sprite missing: " + value); } internal static GameObject Model(ZNetScene scene, string prefab) { if (MeadworksHeadless.IsHeadless) { return null; } GameObject val = (((Object)(object)scene != (Object)null) ? (scene.GetPrefab("SerpentScale") ?? scene.GetPrefab("TrollHide")) : null); if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab("SerpentScale") ?? ObjectDB.instance.GetItemPrefab("TrollHide"); } return ModelCore(val, prefab, scene); } internal static GameObject Model(GameObject native, string prefab) { if (MeadworksHeadless.IsHeadless) { return null; } return ModelCore(native, prefab, ZNetScene.instance); } private static bool ActiveBelowRoot(Renderer renderer, Transform root) { Transform val = ((Component)renderer).transform; while ((Object)(object)val != (Object)(object)root) { if (!((Component)val).gameObject.activeSelf) { return false; } val = val.parent; } return true; } internal static Material NativeBaseMaterial(GameObject source) { Material? obj = (((Object)(object)source != (Object)null) ? (from renderer in source.GetComponentsInChildren<Renderer>(true) where (renderer is MeshRenderer || renderer is SkinnedMeshRenderer) && renderer.enabled && ActiveBelowRoot(renderer, source.transform) select renderer).SelectMany((Renderer renderer) => renderer.sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material candidate) => (Object)(object)candidate != (Object)null && (Object)(object)candidate.shader != (Object)null && ((Object)candidate.shader).name.IndexOf("Snow", StringComparison.OrdinalIgnoreCase) < 0 && candidate.renderQueue <= 2500 && candidate.HasProperty("_MainTex") && (Object)(object)candidate.GetTexture("_MainTex") != (Object)null)) : null); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("Native opaque base material with albedo unavailable: " + (((Object)(object)source != (Object)null) ? ((Object)source).name : "<null>")); } return obj; } private static GameObject ModelCore(GameObject native, string prefab, ZNetScene scene) { Load(); if (!ids.TryGetValue(prefab, out string value)) { throw new KeyNotFoundException("Original model missing: " + prefab); } if (models.TryGetValue(value, out GameObject value2) && (Object)(object)value2 != (Object)null) { return value2; } GameObject obj = bundle.LoadAsset<GameObject>(value) ?? throw new InvalidDataException("Original model prefab missing: " + value); Material nativeMaterial = NativeBaseMaterial(native); GameObject val = Object.Instantiate<GameObject>(obj); ((Object)val).name = value; val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); Dictionary<Material, Material> dress = new Dictionary<Material, Material>(); Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer obj2 in componentsInChildren) { obj2.sharedMaterials = ((IEnumerable<Material>)obj2.sharedMaterials).Select((Func<Material, Material>)delegate(Material original) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) if (dress.TryGetValue(original, out Material value3)) { return value3; } Material val2 = nativeMaterial; if (nativeMaterials.TryGetValue(((Object)original).name.Replace(" (Instance)", ""), out string value4)) { GameObject val3 = (((Object)(object)scene != (Object)null) ? scene.GetPrefab(value4) : null); if ((Object)(object)val3 == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val3 = ObjectDB.instance.GetItemPrefab(value4); } val2 = NativeBaseMaterial(val3); } Material val4 = new Material(val2) { name = "MW_" + ((Object)original).name }; if (val4.HasProperty("_MainTex")) { val4.SetTexture("_MainTex", original.mainTexture); } if (val4.HasProperty("_Color")) { val4.SetColor("_Color", original.color); } val4.mainTextureScale = Vector2.one; val4.mainTextureOffset = Vector2.zero; if (val4.HasProperty("_BumpMap")) { val4.SetTexture("_BumpMap", (Texture)null); } string[] array = new string[3] { "_MetallicGlossMap", "_EmissionMap", "_StyleTex" }; foreach (string text in array) { if (val4.HasProperty(text)) { val4.SetTexture(text, (Texture)null); } } if (val4.HasProperty("_UseStyles")) { val4.SetFloat("_UseStyles", 0f); } val4.DisableKeyword("_USESTYLES_ON"); if (val4.HasProperty("_Glossiness")) { val4.SetFloat("_Glossiness", original.GetFloat("_Glossiness")); } if (val4.HasProperty("_Metallic")) { val4.SetFloat("_Metallic", original.GetFloat("_Metallic")); } if (val4.HasProperty("_MetalGloss")) { val4.SetFloat("_MetalGloss", 0f); } if (val4.HasProperty("_EmissionColor") && original.IsKeywordEnabled("_EMISSION")) { val4.EnableKeyword("_EMISSION"); val4.SetColor("_EmissionColor", original.GetColor("_EmissionColor")); } else if (val4.HasProperty("_EmissionColor")) { val4.DisableKeyword("_EMISSION"); val4.SetColor("_EmissionColor", Color.black); } ownedMaterials.Add(val4); dress.Add(original, val4); return val4; }).ToArray(); } models[value] = val; return val; } internal static GameObject Instantiate(ZNetScene scene, string prefab, Transform parent) { GameObject val = Model(scene, prefab); if ((Object)(object)val == (Object)null) { return null; } GameObject obj = Object.Instantiate<GameObject>(val, parent, false); ((Object)obj).name = "meadworks_original_model"; obj.SetActive(true); return obj; } internal static GameObject Instantiate(GameObject nativeMaterialItem, string prefab, Transform parent) { GameObject val = Model(nativeMaterialItem, prefab); if ((Object)(object)val == (Object)null) { return null; } GameObject obj = Object.Instantiate<GameObject>(val, parent, false); ((Object)obj).name = "meadworks_original_model"; obj.SetActive(true); return obj; } internal static void Shutdown() { foreach (GameObject value in models.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } models.Clear(); foreach (Material ownedMaterial in ownedMaterials) { if ((Object)(object)ownedMaterial != (Object)null) { Object.Destroy((Object)(object)ownedMaterial); } } ownedMaterials.Clear(); if ((Object)(object)bundle != (Object)null) { bundle.Unload(false); } bundle = null; ids = null; nativeMaterials = null; } } } namespace ExtraPotions.Mantle.Embedded.YamlConfig { public sealed class YamlFileHub { private readonly string modName; private readonly ManualLogSource log; private readonly ExtraPotions.Mantle.Embedded.Charter.Charter? charter; private readonly List<YamlFileSet> sets = new List<YamlFileSet>(); private readonly YamlFileStore store; private readonly YamlFileWatcher watcher; private bool loaded; public IReadOnlyList<YamlFileSet> Sets => sets; public bool IsAuthor => charter?.IsAuthor ?? true; public bool IsLocked { get { if (charter != null && charter.IsBound) { return !charter.MayAmend; } return false; } } public bool SuppressWriteBack { get; set; } public Func<bool> CanApply { get; set; } = () => true; public event Action<YamlFileSet>? Applied; public YamlFileHub(string modName, ManualLogSource log, IEnumerable<string> searchFolders, ExtraPotions.Mantle.Embedded.Charter.Charter? charter) { this.modName = modName; this.log = log; this.charter = charter; store = new YamlFileStore(modName, log, searchFolders); watcher = new YamlFileWatcher(store, sets, ReloadFromDisk, log, modName); } public YamlFileSet Register(YamlFileSet set) { if (sets.Any((YamlFileSet s) => string.Equals(s.SyncKey, set.SyncKey, StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException(modName + ": a YAML file set with sync key '" + set.SyncKey + "' is already registered"); } sets.Add(set); if (charter != null) { Article<List<string>> channel = new Article<List<string>>(charter, set.SyncKey, new List<string>()); set.Channel = channel; channel.Changed += delegate { Receive(set, YamlFileList.Unflatten(channel.Value)); }; } return set; } public void LoadAll() { loaded = true; foreach (YamlFileSet set in sets) { LoadSet(set); } watcher.Start(); } public void ApplyAll() { if (!CanApply()) { log.LogDebug((object)(modName + ": YAML apply skipped, the game is not ready")); return; } foreach (YamlFileSet set in sets) { Apply(set); } } public bool TryBuild(YamlFileSet set, IReadOnlyDictionary<string, string> files, out YamlModel model, string context) { model = set.CreateModel(); model.LoadAll(files); foreach (string warning in model.Warnings) { log.LogWarning((object)(modName + ": " + warning)); } if (model.Errors.Count == 0) { return true; } log.LogError((object)$"{modName}: {set.MainFileName} ({context}) has {model.Errors.Count} error(s), the previous configuration stays:"); foreach (string error in model.Errors) { log.LogError((object)(modName + ": " + error)); } return false; } public void Replace(YamlFileSet set, IReadOnlyDictionary<string, string> files, bool saveToDisk) { if (TryBuild(set, files, out YamlModel _, "editor")) { Publish(set, files, saveToDisk); } } public void HookGame(Harmony harmony, int applyPriority) { YamlGameHooks.Install(this, harmony, applyPriority); } internal void LoadFromHook() { if (loaded) { return; } try { LoadAll(); } catch (Exception arg) { log.LogError((object)$"{modName}: loading YAML files failed: {arg}"); } } internal void ApplyFromHook() { try { ApplyAll(); } catch (Exception arg) { log.LogError((object)$"{modName}: applying YAML files failed: {arg}"); } } private void LoadSet(YamlFileSet set) { Dictionary<string, string> dictionary = store.ReadOrCreate(set); watcher.TakeSnapshot(set); YamlModel model; if (dictionary.Count == 0) { if (set.Enabled()) { log.LogWarning((object)(modName + ": no " + set.FilePattern + " found in " + string.Join(" or ", store.SearchFolders))); } } else if (TryBuild(set, dictionary, out model, "startup")) { Publish(set, dictionary, writeBack: false); } } private void ReloadFromDisk(YamlFileSet set) { Dictionary<string, string> dictionary = store.Read(store.Discover(set)); watcher.TakeSnapshot(set); YamlModel model; if (dictionary.Count == 0) { log.LogWarning((object)(modName + ": every " + set.FilePattern + " file is gone, keeping the loaded configuration")); } else if (TryBuild(set, dictionary, out model, "reload")) { Publish(set, dictionary, writeBack: false); log.LogInfo((object)(modName + ": " + set.MainFileName + " reloaded" + (IsAuthor ? "" : ", not applied, remote configuration active"))); } } private void Publish(YamlFileSet set, IReadOnlyDictionary<string, string> files, bool writeBack) { bool suppressWriteBack = SuppressWriteBack; SuppressWriteBack = suppressWriteBack || !writeBack; try { if (set.Channel == null) { Receive(set, files); } else { set.Channel.Assign(YamlFileList.Flatten(files)); } } finally { SuppressWriteBack = suppressWriteBack; } } private void Receive(YamlFileSet set, IReadOnlyDictionary<string, string> files) { if (!TryBuild(set, files, out YamlModel model, "received")) { foreach (KeyValuePair<string, string> file in files) { log.LogWarning((object)(modName + ": content of " + file.Key + ":\n" + file.Value)); } return; } set.Files = files; set.Current = model; if (CanApply()) { Apply(set); } if (IsAuthor && !SuppressWriteBack) { store.WriteAll(files); watcher.TakeSnapshot(set); } } private void Apply(YamlFileSet set) { if (set.Current == null || !set.Enabled()) { return; } try { set.Apply(set.Current); this.Applied?.Invoke(set); } catch (Exception arg) { log.LogError((object)$"{modName}: applying {set.MainFileName} failed: {arg}"); } } } internal static class YamlFileList { public static List<string> Flatten(IReadOnlyDictionary<string, string> files) { List<string> list = new List<string>(files.Count * 2); foreach (KeyValuePair<string, string> file in files) { list.Add(file.Key); list.Add(file.Value); } return list; } public static Dictionary<string, string> Unflatten(List<string>? list) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); int num = 0; while (list != null && num + 1 < list.Count) { dictionary[list[num]] = list[num + 1]; num += 2; } return dictionary; } } public sealed class YamlFileSet { internal int ReloadPending; public string FilePattern { get; } public string MainFileName { get; } public string SyncKey { get; } public Func<YamlModel> CreateModel { get; } public Action<YamlModel> Apply { get; } public Func<bool> Enabled { get; set; } = () => true; public Func<byte[]?>? DefaultContent { get; set; } public Func<string> EditorLabel { get; set; } public IReadOnlyDictionary<string, string> Files { get; internal set; } = new Dictionary<string, string>(); public YamlModel? Current { get; internal set; } internal Article<List<string>>? Channel { get; set; } internal Dictionary<string, DateTime> Snapshot { get; } = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase); public YamlFileSet(string filePattern, string syncKey, Func<YamlModel> createModel, Action<YamlModel> apply) { FilePattern = filePattern; MainFileName = filePattern.Replace("*", ""); SyncKey = syncKey; CreateModel = createModel; Apply = apply; EditorLabel = () => "Edit " + MainFileName; } } internal sealed class YamlFileStore { private readonly string modName; private readonly ManualLogSource log; private readonly List<string> searchFolders; public IReadOnlyList<string> SearchFolders => searchFolders; public YamlFileStore(string modName, ManualLogSource log, IEnumerable<string> searchFolders) { this.modName = modName; this.log = log; this.searchFolders = searchFolders.ToList(); } public List<string> Discover(YamlFileSet set) { Regex nameFilter = new Regex("^" + Regex.Escape(set.FilePattern).Replace("\\*", ".*") + "$", RegexOptions.IgnoreCase); List<string> list = new List<string>(); foreach (string item in searchFolders.Where(Directory.Exists)) { list.AddRange(from p in Directory.GetFiles(item, set.FilePattern) where nameFilter.IsMatch(Path.GetFileName(p)) select p); } return list.OrderBy((string p) => (!string.Equals(Path.GetFileName(p), set.MainFileName, StringComparison.OrdinalIgnoreCase)) ? 1 : 0).ThenBy<string, string>(Path.GetFileName, StringComparer.OrdinalIgnoreCase).ToList(); } public Dictionary<string, string> Read(IEnumerable<string> paths) { Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string path in paths) { try { dictionary[path] = File.ReadAllText(path); } catch (Exception ex) { log.LogError((object)(modName + ": reading " + path + " failed: " + ex.Message)); } } return dictionary; } public Dictionary<string, string> ReadOrCreate(YamlFileSet set) { Dictionary<string, string> dictionary = Read(Discover(set)); if (dictionary.Count <= 0) { return WriteDefault(set); } return dictionary; } public Dictionary<string, DateTime> WriteTimes(YamlFileSet set) { Dictionary<string, DateTime> dictionary = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase); foreach (string item in Discover(set)) { dictionary[item] = File.GetLastWriteTimeUtc(item); } return dictionary; } public void WriteAll(IReadOnlyDictionary<string, string> files) { foreach (KeyValuePair<string, string> file in files) { WriteAtomic(file.Key, file.Value); } } private Dictionary<string, string> WriteDefault(YamlFileSet set) { byte[] array = set.DefaultContent?.Invoke(); if (array == null || searchFolders.Count == 0) { return new Dictionary<string, string>(); } string text = Path.Combine(searchFolders[0], set.MainFileName); try { Directory.CreateDirectory(searchFolders[0]); File.WriteAllBytes(text, array); log.LogInfo((object)(modName + ": wrote default " + text)); } catch (Exception ex) { log.LogError((object)(modName + ": writing default " + text + " failed: " + ex.Message)); return new Dictionary<string, string>(); } return Read(new string[1] { text }); } private void WriteAtomic(string path, string content) { try { if (!File.Exists(path) || !(File.ReadAllText(path) == content)) { ReplaceThroughTempFile(path, content); log.LogInfo((object)(modName + ": wrote " + path)); } } catch (Exception ex) { log.LogError((object)(modName + ": writing " + path + " failed: " + ex.Message)); } } private static void ReplaceThroughTempFile(string path, string content) { string text = path + ".tmp"; File.WriteAllText(text, content, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(path)) { File.Replace(text, path, null); } else { File.Move(text, path); } } } internal sealed class YamlFileWatcher { private const int PollMilliseconds = 5000; private readonly YamlFileStore store; private readonly IReadOnlyList<YamlFileSet> sets; private readonly Action<YamlFileSet> reload; private readonly ManualLogSource log; private readonly string modName; private Timer? timer; public YamlFileWatcher(YamlFileStore store, IReadOnlyList<YamlFileSet> sets, Action<YamlFileSet> reload, ManualLogSource log, string modName) { this.store = store; this.sets = sets; this.reload = reload; this.log = log; this.modName = modName; } public void Start() { if (timer == null) { timer = new Timer(delegate { Poll(); }, null, 5000, 5000); } } public void TakeSnapshot(YamlFileSet set) { Dictionary<string, DateTime> dictionary = store.WriteTimes(set); lock (set.Snapshot) { set.Snapshot.Clear(); foreach (KeyValuePair<string, DateTime> item in dictionary) { set.Snapshot[item.Key] = item.Value; } } } private void Poll() { try { foreach (YamlFileSet set in sets.Where(HasChanged)) { if (Interlocked.CompareExchange(ref set.ReloadPending, 1, 0) == 0) { ThreadingHelper.SynchronizingObject.BeginInvoke((Action)delegate { Reload(set); }, null); } } } catch (Exception ex) { log.LogError((object)(modName + ": watching YAML files failed: " + ex.Message)); } } private bool HasChanged(YamlFileSet set) { Dictionary<string, DateTime> dictionary = store.WriteTimes(set); lock (set.Snapshot) { DateTime value; return dictionary.Count != set.Snapshot.Count || dictionary.Any((KeyValuePair<string, DateTime> pair) => !set.Snapshot.TryGetValue(pair.Key, out value) || value != pair.Value); } } private void Reload(YamlFileSet set) { try { reload(set); } catch (Exception arg) { log.LogError((object)$"{modName}: reloading {set.MainFileName} failed: {arg}"); } finally { Interlocked.Exchange(ref set.ReloadPending, 0); } } } internal static class YamlGameHooks { private static class Patches { public static void AfterMenuStart() { LoadHooked(); } public static void AfterNetworkStart(ZNet __instance) { if (__instance.IsServer() && __instance.IsDedicated()) { LoadHooked(); } } public static void AfterRespawnRequest(Game __instance) { object obj = firstSpawnField?.GetValue(__instance); if (obj is bool && (bool)obj) { ApplyHooked(); } } } private static readonly List<YamlFileHub> hooked = new List<YamlFileHub>(); private static readonly FieldInfo? firstSpawnField = AccessTools.Field(typeof(Game), "m_firstSpawn"); private static bool patched; public static void Install(YamlFileHub hub, Harmony harmony, int applyPriority) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown if (!hooked.Contains(hub)) { hooked.Add(hub); } if (!patched) { patched = true; harmony.Patch((MethodBase)AccessTools.Method(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "AfterMenuStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(ZNet), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "AfterNetworkStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); HarmonyMethod val = new HarmonyMethod(typeof(Patches), "AfterRespawnRequest", (Type[])null) { priority = applyPriority }; harmony.Patch((MethodBase)AccessTools.Method(typeof(Game), "RequestRespawn", (Type[])null, (Type[])null), (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void LoadHooked() { foreach (YamlFileHub item in hooked) { item.LoadFromHook(); } } private static void ApplyHooked() { foreach (YamlFileHub item in hooked) { item.ApplyFromHook(); } } } public sealed class YamlGroupTable { private readonly Dictionary<string, List<string>> members = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, List<string>> parents = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); public IReadOnlyCollection<string> Names => members.Keys; public bool IsGroup(string name) { return members.ContainsKey(name); } public void Add(string group, IEnumerable<string> names) { if (!members.TryGetValue(group, out List<string> value)) { value = new List<string>(); members.Add(group, value); } foreach (string name in names) { value.Add(name); if (!parents.TryGetValue(name, out List<string> value2)) { value2 = new List<string>(); parents.Add(name, value2); } value2.Add(group); } } public IReadOnlyList<string> Resolve(string name) { List<string> list = new List<string>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); Queue<string> queue = new Queue<string>(); queue.Enqueue(name); while (queue.Count > 0) { if (!parents.TryGetValue(queue.Dequeue(), out List<string> value)) { continue; } foreach (string item in value) { if (hashSet.Add(item)) { list.Add(item); queue.Enqueue(item); } } } return list; } public IReadOnlyList<string> Expand(string group) { List<string> result = new List<string>(); HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase); Expand(group, seen, result); return result; } private void Expand(string name, HashSet<string> seen, List<string> result) { if (!seen.Add(name)) { return; } if (!members.TryGetValue(name, out List<string> value)) { result.Add(name); return; } foreach (string item in value) { Expand(item, seen, result); } } } public abstract class YamlModel { private static readonly IDeserializer Parser = new DeserializerBuilder().Build(); private string? currentFile; public List<string> Errors { get; } = new List<string>(); public List<string> Warnings { get; } = new List<string>(); protected YamlGroupTable Groups { get; } = new YamlGroupTable(); public void Load(string yamlText) { ReadText(yamlText); Verify(); } public void LoadAll(IEnumerable<KeyValuePair<string, string>> files) { foreach (KeyValuePair<string, string> file in files) { currentFile = Path.GetFileName(file.Key); ReadText(file.Value); } currentFile = null; Verify(); } public IReadOnlyList<string> ResolveGroups(string name) { return Groups.Resolve(name); } protected abstract void Read(YamlNode root); protected virtual void Verify() { } protected void ReadGroups(YamlNode root, string key = "groups") { foreach (KeyValuePair<string, YamlNode> entry in root.Get(key).Entries) { if (entry.Value.TryStringList(out List<string> items)) { Groups.Add(entry.Key, items); } } } internal void AddError(string message) { Errors.Add(WithFile(message)); } internal void AddWarning(string message) { Warnings.Add(WithFile(message)); } private string WithFile(string message) { if (currentFile != null) { return currentFile + ": " + message; } return message; } private void ReadText(string yamlText) { if (TryParse(yamlText, out object graph) && graph != null) { if (!(graph is IDictionary<object, object>)) { AddError("the file must be a map of keys at the top level, not " + ((graph is IList<object>) ? "a list" : "a single value")); return; } YamlNode yamlNode = new YamlNode(this, graph, ""); Read(yamlNode); yamlNode.WarnUnknownKeys(); } } private bool TryParse(string yamlText, out object? graph) { try { graph = Parser.Deserialize<object>(yamlText.TrimStart('\ufeff')); return true; } catch (Exception ex) { AddError("invalid YAML: " + ex.Message + ((ex.InnerException == null) ? "" : (" (" + ex.InnerException.Message + ")"))); graph = null; return false; } } } public enum YamlNodeKind { Scalar, List, Map, Null, Missing } public sealed class YamlNode { private readonly YamlModel model; private readonly object? value; private List<KeyValuePair<string, YamlNode>>? mapEntries; private Dictionary<string, YamlNode>? mapLookup; private List<YamlNode>? listItems; private HashSet<string>? askedKeys; private bool visited; private bool shapeReported; public string Path { get; } public YamlNodeKind Kind { get; } public string? Text { get { if (Kind != YamlNodeKind.Scalar) { return null; } return Convert.ToString(value, CultureInfo.InvariantCulture); } } public int Count => Kind switch { YamlNodeKind.Map => MapEntries.Count, YamlNodeKind.List => ListItems.Count, _ => 0, }; public IReadOnlyList<KeyValuePair<string, YamlNode>> Entries { get { if (!ExpectShape(YamlNodeKind.Map, "a map")) { return Array.Empty<KeyValuePair<string, YamlNode>>(); } visited = true; AskedKeys.UnionWith(MapEntries.Select<KeyValuePair<string, YamlNode>, string>((KeyValuePair<string, YamlNode> e) => e.Key)); return MapEntries; } } public IReadOnlyList<YamlNode> Items { get { if (!ExpectShape(YamlNodeKind.List, "a list")) { return Array.Empty<YamlNode>(); } return ListItems; } } private HashSet<string> AskedKeys => askedKeys ?? (askedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)); private List<KeyValuePair<string, YamlNode>> MapEntries { get { if (mapEntries == null) { BuildMap(); } return mapEntries; } } private Dictionary<string, YamlNode> MapLookup { get { if (mapLookup == null) { BuildMap(); } return mapLookup; } } private List<YamlNode> ListItems { get { if (listItems == null) { IList<object> source = (IList<object>)value; listItems = source.Select((object item, int i) => new YamlNode(model, item, $"{Path}[{i}]")).ToList(); } return listItems; } } internal YamlNode(YamlModel model, object? value, string path, YamlNodeKind kind) { this.model = model; this.value = value; Path = path; Kind = kind; } internal YamlNode(YamlModel model, object? value, string path) : this(model, value, path, KindOf(value)) { } public YamlNode Get(string key) { string path = (string.IsNullOrEmpty(Path) ? key : (Path + "." + key)); if (!ExpectShape(YamlNodeKind.Map, "a map")) { return new YamlNode(model, null, path, YamlNodeKind.Missing); } visited = true; AskedKeys.Add(key); if (!MapLookup.TryGetValue(key, out YamlNode result)) { return new YamlNode(model, null, path, YamlNodeKind.Missing); } return result; } public bool Is(string keyword) { if (Kind == YamlNodeKind.Scalar) { return string.Equals(Text.Trim(), keyword, StringComparison.OrdinalIgnoreCase); } return false; } public void Error(string message) { model.AddError(Prefixed(message)); } public void Warn(string message) { model.AddWarning(Prefixed(message)); } public void WarnUnknownKeys() { if (Kind == YamlNodeKind.Map && visited) { List<string> list = (from e in MapEntries select e.Key into k where !AskedKeys.Contains(k) select k).ToList(); if (list.Count > 0) { Warn("unknown keys " + string.Join(", ", list)); } { foreach (KeyValuePair<string, YamlNode> mapEntry in MapEntries) { mapEntry.Value.WarnUnknownKeys(); } return; } } if (Kind == YamlNodeKind.List && listItems != null) { listItems.ForEach(delegate(YamlNode item) { item.WarnUnknownKeys(); }); } } private string Prefixed(string message) { if (!string.IsNullOrEmpty(Path)) { return Path + ": " + message; } return message; } private void BuildMap() { mapEntries = new List<KeyValuePair<string, YamlNode>>(); mapLookup = new Dictionary<string, YamlNode>(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair<object, object> item in (IDictionary<object, object>)value) { string text = Convert.ToString(item.Key, CultureInfo.InvariantCulture) ?? ""; string path = (string.IsNullOrEmpty(Path) ? text : (Path + "." + text)); YamlNode yamlNode = new YamlNode(model, item.Value, path); if (mapLookup.ContainsKey(text)) { yamlNode.Warn("duplicate key (differs only in case), ignored"); continue; } mapLookup.Add(text, yamlNode); mapEntries.Add(new KeyValuePair<string, YamlNode>(text, yamlNode)); } } private bool ExpectShape(YamlNodeKind wanted, string description) { if (Kind == wanted) { return true; } if (Kind != YamlNodeKind.Missing && !shapeReported) { shapeReported = true; Error((Kind == YamlNodeKind.Null) ? ("expected " + description + " but the key has no value") : ("expected " + description + ", found " + Describe(Kind))); } return false; } private static string Describe(YamlNodeKind kind) { return kind switch { YamlNodeKind.Scalar => "a single value", YamlNodeKind.List => "a list", YamlNodeKind.Map => "a map", _ => "nothing", }; } private static YamlNodeKind KindOf(object? value) { if (value != null) { if (!(value is IDictionary<object, object>)) { if (value is IList<object>) { return YamlNodeKind.List; } return YamlNodeKind.Scalar; } return YamlNodeKind.Map; } return YamlNodeKind.Null; } public bool TryInt(out int result) { return TryScalar<int>(out result); } public bool TryFloat(out float result) { return TryScalar<float>(out result); } public bool TryBool(out bool result) { return TryScalar<bool>(out result); } public bool TryString(out string result) { return TryScalar<string>(out result); } public bool TryEnum<T>(out T result) where T : struct, Enum { return TryScalar<T>(out result); } public bool TryList<T>(out List<T> items) { items = new List<T>(); if (!ExpectShape(YamlNodeKind.List, "a list of " + YamlScalarParser.Plural<T>())) { return false; } bool result = true; foreach (YamlNode listItem in ListItems) { if (listItem.TryScalar<T>(out var result2)) { items.Add(result2); } else { result = false; } } return result; } public bool TryStringList(out List<string> items) { if (Kind == YamlNodeKind.Scalar) { items = new List<string> { Text }; return true; } return TryList(out items); } private bool TryScalar<T>(out T result) { result = default(T); if (!ExpectShape(YamlNodeKind.Scalar, YamlScalarParser.Describe(typeof(T)))) { return false; } if (YamlScalarParser.TryParse(Text, typeof(T), out object result2)) { result = (T)result2; return true; } Error("'" + Text + "' is not " + YamlScalarParser.Describe(typeof(T))); return false; } } internal static class YamlScalarParser { private static readonly string[] TrueWords = new string[4] { "true", "yes", "on", "1" }; private static readonly string[] FalseWords = new string[4] { "false", "no", "off", "0" }; public static bool TryParse(string text, Type type, out object? result) { string text2 = text.Trim(); result = null; if (type == typeof(string)) { result = text; return true; } if (type == typeof(int)) { int result3; bool result2 = int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out result3); result = result3; return result2; } if (type == typeof(float)) { float result5; bool result4 = float.TryParse(text2, NumberStyles.Float, CultureInfo.InvariantCulture, out result5); result = result5; return result4; } if (!(type == typeof(bool))) { return TryParseEnum(text2, type, out result); } return TryParseBool(text2, out result); } public static string Describe(Type type) { if (type == typeof(int)) { return "an integer"; } if (type == typeof(float)) { return "a number"; } if (type == typeof(bool)) { return "true or false"; } if (!type.IsEnum) { return "text"; } return "one of " + string.Join(", ", Enum.GetNames(type)); } public static string Plural<T>() { if (!(typeof(T) == typeof(int))) { if (!(typeof(T) == typeof(float))) { if (!(typeof(T) == typeof(bool))) { if (!typeof(T).IsEnum) { return "text values"; } return "names (" + string.Join(", ", Enum.GetNames(typeof(T))) + ")"; } return "true/false values"; } return "numbers"; } return "integers"; } private static bool TryParseBool(string text, out object? result) { if (TrueWords.Contains<string>(text, StringComparer.OrdinalIgnoreCase)) { result = true; return true; } result = false; return FalseWords.Contains<string>(text, StringComparer.OrdinalIgnoreCase); } private static bool TryParseEnum(string text, Type type, out object? result) { if (!type.IsEnum) { throw new NotSupportedException("YamlNode cannot read values of type " + type.Name); } string text2 = Enum.GetNames(type).FirstOrDefault((string n) => string.Equals(n, text, StringComparison.OrdinalIgnoreCase)); result = ((text2 == null) ? null : Enum.Parse(type, text2)); return text2 != null; } } } namespace ExtraPotions.Mantle.Embedded.WindowInput { public static class GameWindow { private sealed class Entry { public Func<bool> IsOpen; public Action Close; } private static readonly List<Entry> windows = new List<Entry>(); public static bool AnyOpen { get { foreach (Entry window in windows) { if (Open(window)) { return true; } } return false; } } public static void Install(Harmony harmony) { WindowPatches.Install(harmony); } public static void Add(Func<bool> isOpen, Action close) { windows.Add(new Entry { IsOpen = isOpen, Close = close }); } public static bool CloseOpen() { bool result = false; foreach (Entry window in windows) { if (Open(window)) { window.Close(); result = true; } } return result; } private static bool Open(Entry window) { try { return window.IsOpen(); } catch (Exception) { return false; } } } internal static class WindowPatches { private static bool patched; public static void Install(Harmony harmony) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown if (!patched) { patched = true; Postfix(harmony, AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null), "NoPlayerInput"); Postfix(harmony, AccessTools.Method(typeof(PlayerController), "InInventoryEtc", (Type[])null, (Type[])null), "InWindow"); Postfix(harmony, AccessTools.Method(typeof(GameCamera), "UpdateMouseCapture", (Type[])null, (Type[])null), "FreeCursor"); Postfix(harmony, AccessTools.Method(typeof(ZInput), "GetMouseScrollWheel", (Type[])null, (Type[])null), "NoZoom"); harmony.Patch((MethodBase)AccessTools.Method(typeof(Menu), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(WindowPatches), "Escape", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void Postfix(Harmony harmony, MethodInfo target, string patch) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown harmony.Patch((MethodBase)target, (HarmonyMethod)null, new HarmonyMethod(typeof(WindowPatches), patch, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void NoPlayerInput(ref bool __result) { if (__result && GameWindow.AnyOpen) { __result = false; } } private static void InWindow(ref bool __result) { if (!__result && GameWindow.AnyOpen) { __result = true; } } private static void FreeCursor() { if (GameWindow.AnyOpen && !Menu.IsVisible()) { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } } private static void NoZoom(ref float __result) { if (__result != 0f && GameWindow.AnyOpen) { __result = 0f; } } private static bool Escape(Menu __instance) { if ((Object)(object)__instance.m_root == (Object)null || ((Component)__instance.m_root).gameObject.activeSelf || !ZInput.GetKeyDown((KeyCode)27, true)) { return true; } return !GameWindow.CloseOpen(); } } } namespace ExtraPotions.Mantle.Embedded.SyncedConfig { public sealed class SyncedConfiguration { public ExtraPotions.Mantle.Embedded.Charter.Charter Sync { get; } public ConfigFile Config { get; } public ManualLogSource Log { get; } public YamlFileHub Yaml { get; } public IReadOnlyList<string> SearchPaths { get; } public IDisposable? ConfigWatcher { get; private set; } public bool IsLocked { get { if (Sync.IsBound) { return !Sync.MayAmend; } return false; } } public bool IsAdmin => Sync.IsSteward; public bool IsAuthor => Sync.IsAuthor; public SyncedConfiguration(BaseUnityPlugin plugin, ManualLogSource log, string title, string version, string? oldestAccepted = null, bool mandatory = true) { Config = plugin.Config; Log = log; string gUID = plugin.Info.Metadata.GUID; Sync = new ExtraPotions.Mantle.Embedded.Charter.Charter(gUID, title, version, oldestAccepted, mandatory); SearchPaths = new string[2] { Path.GetDirectoryName(Config.ConfigFilePath) ?? Paths.ConfigPath, Path.GetDirectoryName(((object)plugin).GetType().Assembly.Location) ?? Paths.PluginPath }; Yaml = new YamlFileHub(title, Log, SearchPaths, Sync); } public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, bool synced = true, AcceptableValueBase? acceptableValues = null, params object[] tags) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return Bind(section, key, defaultValue, new ConfigDescription(description, acceptableValues, tags), synced); } public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription description, bool synced = true) { ConfigEntry<T> val = Config.Bind<T>(section, key, defaultValue, description); Sync.Clause<T>(val, !synced); return val; } public Clause<T> Add<T>(ConfigEntry<T> entry, bool synced = true) { return Sync.Clause<T>(entry, !synced); } public ConfigEntry<bool> BindLocking(string section, string key, bool defaultValue, string description) { ConfigEntry<bool> val = Config.Bind<bool>(section, key, defaultValue, description); Sync.Binding(val); return val; } public YamlFileSet AddYaml(YamlFileSet set) { return Yaml.Register(set); } public void Finish(Harmony harmony, int yamlApplyPriority = 400) { ExtraPotions.Mantle.Embedded.Charter.Charter.Install(harmony); ConfigWatcher = ConfigReloader.Setup(Config, Log, saveNow: true, Sync.HoldsServerValue, Sync.ReloadKeepingServerValues); if (Yaml.Sets.Count > 0) { Yaml.HookGame(harmony, yamlApplyPriority); } } public static Func<byte[]?> EmbeddedResource(Assembly assembly, string resourceName) { return delegate { using Stream stream = assembly.GetManifestResourceStream(resourceName); if (stream != null) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } return (byte[]?)null; }; } } } namespace ExtraPotions.Mantle.Embedded.PlateColumn { internal static class BoxContainer { public const string Name = "PlateColumn_boxes"; private const string PanelBackground = "Bkg"; public static bool Is(Transform? t, Transform panel) { if ((Object)(object)t != (Object)null && (Object)(object)t.parent == (Object)(object)panel) { return ((Object)t).name == "PlateColumn_boxes"; } return false; } public static RectTransform Get(RectTransform panel) { Transform obj = ((Transform)panel).Find("PlateColumn_boxes"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if ((Object)(object)val == (Object)null) { val = Make(panel); } PlaceAfterBackground((Transform)(object)panel, (Transform)(object)val); if (!PlateParts.Carries(((Component)val).gameObject, typeof(SeatWatch))) { ((Component)val).gameObject.AddComponent<SeatWatch>(); } return val; } private static RectTransform Make(RectTransform panel) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0043: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown GameObject val = new GameObject("PlateColumn_boxes", new Type[1] { typeof(RectTransform) }); val.layer = ((Component)panel).gameObject.layer; RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)panel, false); val2.anchorMin = Vector2.one; val2.anchorMax = Vector2.one; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(8f, -6f); val2.sizeDelta = new Vector2(64f, 64f); Stack(val); return val2; } private static void Stack(GameObject go) { VerticalLayoutGroup obj = go.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f; ((LayoutGroup)obj).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; go.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; } private static void PlaceAfterBackground(Transform panel, Transform boxes) { Transform val = panel.Find("Bkg"); if (!((Object)(object)val == (Object)null)) { int siblingIndex = val.GetSiblingIndex(); int siblingIndex2 = boxes.GetSiblingIndex(); if (siblingIndex2 != siblingIndex + 1) { boxes.SetSiblingIndex((siblingIndex2 < siblingIndex) ? siblingIndex : (siblingIndex + 1)); } } } } internal sealed class BoxStack { private readonly RectTransform panel; public RectTransform Boxes { get; } public GamePlates Game { get; } private BoxStack(RectTransform panel, RectTransform boxes, GamePlates game) { this.panel = panel; Boxes = boxes; Game = game; } public static BoxStack? Ready(InventoryGui gui) { GamePlates gamePlates = (MantleOwner.LaysOutInventory ? GamePlates.Find(gui) : null); if (gamePlates == null) { return null; } BoxStack boxStack = new BoxStack(gui.m_player, BoxContainer.Get(gui.m_player), gamePlates); boxStack.Adopt(); BoxStyle.Apply(gamePlates.Armor); BoxStyle.Apply(gamePlates.Weight); Seats.Seat(boxStack.panel, boxStack.Boxes, gamePlates.Armor, 100); Seats.Seat(boxStack.panel, boxStack.Boxes, gamePlates.Weight, 300); Seats.SeatGuests(boxStack.panel, boxStack.Boxes); gamePlates.Tip(gui); boxStack.Order(); return boxStack; } public void Order() { Seats.Arrange(panel, Boxes); } private void Adopt() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown List<Transform> list = new List<Transform>(); foreach (Transform item in (Transform)panel) { Transform val = item; if (ColumnLayout.IsMember(val)) { list.Add(val); } } foreach (Transform item2 in list) { item2.SetParent((Transform)(object)Boxes, false); } } } internal static class BoxStyle { private const float IconSize = 30f; private const float IconAloneSize = 40f; private const float IconTop = 6f; private const float TextHeight = 22f; private const float TextSide = 4f; private const float TextBottom = 4f; private const float FontMin = 10f; private const float FontMax = 16f; public static void Apply(RectTransform box) { Image val = PlateParts.BackgroundOf((Transform)(object)box); if ((Object)(object)val == (Object)null || Skin.IsBox(val.sprite)) { return; } TMP_Text componentInChildren = ((Component)box).GetComponentInChildren<TMP_Text>(true); Transform val2 = PlateParts.ChildHolding((Transform)(object)box, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.transform : null); Image val3 = PlateParts.IconOf((Transform)(object)box, val2); Frame(box); Background(val); if ((Object)(object)val3 != (Object)null) { Icon(val3); } if ((Object)(object)componentInChildren != (Object)null) { RectTransform val4 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null); if (val4 != null) { Caption(componentInChildren, val4); } } } public static void IconAlone(Image icon) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_005a: Unknown result type (might be due to invalid IL or missing references) RectTransform rectTransform = ((Graphic)icon).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 0.5f); rectTransform.anchorMax = new Vector2(0.5f, 0.5f); rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.sizeDelta = new Vector2(40f, 40f); rectTransform.anchoredPosition = Vector2.zero; } private static void Frame(RectTransform box) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) box.anchorMin = new Vector2(0f, 1f); box.anchorMax = new Vector2(0f, 1f); box.pivot = new Vector2(0.5f, 0.5f); box.sizeDelta = new Vector2(64f, 64f); ((Transform)box).localScale = Vector3.one; } private static void Background(Image image) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) Stretch(((Graphic)image).rectTransform); image.sprite = Skin.Box; image.type = (Type)1; image.fillCenter = true; image.pixelsPerUnitMultiplier = 1f; image.preserveAspect = false; ((Graphic)image).color = Color.white; ((Graphic)image).material = null; ((Graphic)image).raycastTarget = true; ((Transform)((Graphic)image).rectTransform).SetSiblingIndex(0); } private static void Icon(Image icon) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0065: Unknown result type (might be due to invalid IL or missing references) RectTransform rectTransform = ((Graphic)icon).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.sizeDelta = new Vector2(30f, 30f); rectTransform.anchoredPosition = new Vector2(0f, -6f); icon.type = (Type)0; icon.preserveAspect = true; ((Transform)rectTransform).SetSiblingIndex(1); } private static void Caption(TMP_Text text, RectTransform line) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) line.anchorMin = new Vector2(0f, 0f); line.anchorMax = new Vector2(1f, 0f); line.pivot = new Vector2(0.5f, 0f); line.sizeDelta = new Vector2(-8f, 22f); line.anchoredPosition = new Vector2(0f, 4f); if ((Object)(object)text.rectTransform != (Object)(object)line) { Stretch(text.rectTransform); } text.alignment = (TextAlignmentOptions)514; text.enableAutoSizing = true; text.fontSizeMin = 10f; text.fontSizeMax = 16f; text.textWrappingMode = (TextWrappingModes)0; text.margin = Vector4.zero; } private static void Stretch(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } } public static class Column { public const int ArmorRank = 100; public const int WeightRank = 300; public const float Left = 8f; public const float BoxSize = 64f; public const float Spacing = 6f; public const float Top = 6f; public static bool Active => MantleOwner.LaysOutInventory; public static bool Arrange(InventoryGui gui) { return BoxStack.Ready(gui) != null; } public static RectTransform? Boxes(InventoryGui gui) { return BoxStack.Ready(gui)?.Boxes; } public static Plate? Add(InventoryGui gui, PlateSpec spec) { BoxStack boxStack = BoxStack.Ready(gui); if (boxStack == null) { return null; } string text = ColumnLayout.NameOf(spec); Transform obj = ((Transform)boxStack.Boxes).Find(text); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); Plate plate = ((val != null) ? PlateCopy.Wrap(val) : PlateCopy.Make(boxStack.Game.Armor, spec, text, (Transform?)(object)boxStack.Boxes)); if (plate != null) { PlateTips.Set(gui, plate.Rect, spec.Topic, spec.Tip); boxStack.Order(); } return plate; } public static void BoxesIn(RectTransform boxes, List<RectTransform> into) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown into.Clear(); Transform parent = ((Transform)boxes).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); foreach (Transform item in (Transform)boxes) { Transform val2 = item; object obj; if ((Object)(object)val != (Object)null) { RectTransform val3 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null); if (val3 != null) { obj = Seats.BoxOf(val, val3); goto IL_004c; } } obj = ((val2 is RectTransform) ? val2 : null); goto IL_004c; IL_004c: RectTransform val4 = (RectTransform)obj; if ((Object)(object)val4 != (Object)null) { into.Add(val4); } } } public static bool DressTooltip(InventoryGui gui, UITooltip tooltip) { GameObject val = TipTemplate.For(gui); if ((Object)(object)val == (Object)null || (Object)(object)tooltip == (Object)null) { return false; } tooltip.m_tooltipPrefab = val; return true; } } internal static class ColumnLayout { private const string PlatePrefix = "PlateColumn_plate_"; private const string SeatMark = "_seat_"; private const int RankDigits = 4; private const string LegacyTrash = "OpenKeep_trash"; private const int LegacyTrashRank = 200; public static string NameOf(PlateSpec spec) { return string.Format("{0}{1:D4}_{2}", "PlateColumn_plate_", spec.Rank, spec.Id); } public static string SeatName(int rank, string occupant) { return string.Format("{0}{1:D4}{2}{3}", "PlateColumn_plate_", Mathf.Clamp(rank, 0, 9999), "_seat_", occupant); } public static bool IsMember(Transform t) { return RankOf(((Object)t).name).HasValue; } public static string? OccupantOf(string name) { int num = "PlateColumn_plate_".Length + 4; if (name.Length <= num + "_seat_".Length || !name.StartsWith("PlateColumn_plate_", StringComparison.Ordinal)) { return null; } if (string.CompareOrdinal(name, num, "_seat_", 0, "_seat_".Length) != 0) { return null; } return name.Substring(num + "_seat_".Length); } public static List<RectTransform> Sorted(Transform parent) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown List<KeyValuePair<string, RectTransform>> list = new List<KeyValuePair<string, RectTransform>>(); foreach (Transform item in parent) { Transform val = item; RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null); if (val2 != null) { string text = KeyOf(val); if (text != null) { list.Add(new KeyValuePair<string, RectTransform>(text, val2)); } } } list.Sort((KeyValuePair<string, RectTransform> a, KeyValuePair<string, RectTransform> b) => string.CompareOrdinal(a.Key, b.Key)); return list.ConvertAll((KeyValuePair<string, RectTransform> pair) => pair.Value); } private static string? KeyOf(Transform t) { string name = ((Object)t).name; int? num = RankOf(name); if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); return $"{valueOrDefault:D4}{name}"; } return null; } private static int? RankOf(string name) { if (name == "OpenKeep_trash") { return 200; } if (!name.StartsWith("PlateColumn_plate_", StringComparison.Ordinal) || name.Length < "PlateColumn_plate_".Length + 4) { return null; } if (!int.TryParse(name.Substring("PlateColumn_plate_".Length, 4), out var result)) { return null; } return result; } } internal sealed class ColumnWatch : MonoBehaviour { private int seen = int.MinValue; private void LateUpdate() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown int num = Shape(((Component)this).transform); if (num != seen) { seen = num; LayoutRebuilder.MarkLayoutForRebuild((RectTransform)((Component)this).transform); } } public static int Shape(Transform boxes) { int num = boxes.childCount; for (int i = 0; i < boxes.childCount; i++) { num = num * 31 + (((Component)boxes.GetChild(i)).gameObject.activeSelf ? 1 : 0); } return num; } } public static class EmbeddedSprite { public static Sprite? Load(Assembly assembly, string resource, string spriteName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) byte[] array = Read(assembly, resource); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true) { filterMode = (FilterMode)2, wrapMode = (TextureWrapMode)1 }; if (array == null || !Decode(val, array)) { Object.Destroy((Object)(object)val); return null; } Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = spriteName; return obj; } private static bool Decode(Texture2D texture, byte[] png) { MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }); if (methodInfo != null) { return (bool)methodInfo.Invoke(null, new object[3] { texture, png, true }); } return false; } private static byte[]? Read(Assembly assembly, string resource) { using Stream stream = assembly.GetManifestResourceStream(resource); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } } internal sealed class GamePlates { private const string ArmorTopic = "Armor"; private const string ArmorTip = "The armor of everything you wear. It reduces the damage of every hit you take."; private const string WeightTopic = "Carry weight"; private const string WeightTip = "What you carry, out of the most you can carry. Over it you are encumbered and cannot run."; public RectTransform Armor { get; } public RectTransform Weight { get; } private GamePlates(RectTransform armor, RectTransform weight) { Armor = armor; Weight = weight; } public static GamePlates? Find(InventoryGui gui) { if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_player == (Object)null || (Object)(object)gui.m_armor == (Object)null || (Object)(object)gui.m_weight == (Object)null) { return null; } RectTransform val = PlateOf(gui.m_player, gui.m_armor.transform); RectTransform val2 = PlateOf(gui.m_player, gui.m_weight.transform); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val == (Object)(object)val2) { return null; } return new GamePlates(val, val2); } public void Tip(InventoryGui gui) { PlateTips.SetIfMissing(gui, Armor, "Armor", "The armor of everything you wear. It reduces the damage of every hit you take."); PlateTips.SetIfMissing(gui, Weight, "Carry weight", "What you carry, out of the most you can carry. Over it you are encumbered and cannot run."); } private static RectTransform? PlateOf(RectTransform panel, Transform text) { Transform val = text; while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)panel && !BoxContainer.Is(val.parent, (Transform)(object)panel)) { val = val.parent; } return (RectTransform?)(object)((val is RectTransform) ? val : null); } } internal sealed class Guests { private const string BoxPart = "armor_icon"; private static readonly List<Canvas> Canvases = new List<Canvas>(); public static readonly Guests[] Known = new Guests[3] { new Guests("Jewelcrafting Synergy", 110), new Guests("Trash", 125), new Guests("CoinPocketUI", 200) }; public string Name { get; } public int Rank { get; } public string Seat { get; } private Guests(string name, int rank) { Name = name; Rank = rank; Seat = ColumnLayout.SeatName(rank, name); } public static bool LooksLikeBox(Transform box) { return (Object)(object)box.Find("armor_icon") != (Object)null; } public static void Lift(RectTransform box, Canvas root) { ((Component)box).GetComponentsInChildren<Canvas>(true, Canvases); foreach (Canvas canvase in Canvases) { if (canvase.overrideSorting && canvase.sortingOrder <= root.sortingOrder) { canvase.sortingOrder = root.sortingOrder + 1; } } Canvases.Clear(); } public static void Dress(RectTransform box) { MonoBehaviour[] components = ((Component)box).GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val in components) { if ((Object)(object)val != (Object)null && ((object)val).GetType().FullName == typeof(PlateTip).FullName) { Object.Destroy((Object)(object)val); } } } } internal static class HudContainer { public const string Name = "PlateColumn_hudboxes"; public static RectTransform? Get() { GameObject val = (((Object)(object)Minimap.instance != (Object)null) ? Minimap.instance.m_smallRoot : null); if ((Object)(object)val == (Object)null) { return null; } Transform obj = val.transform.Find("PlateColumn_hudboxes"); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (val2 == null) { return Make(val.transform); } HorizontalLayoutGroup component = ((Component)val2).GetComponent<HorizontalLayoutGroup>(); if (component != null) { Object.DestroyImmediate((Object)(object)component); Shape(val2); } return val2; } private static RectTransform Make(Transform small) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0037: 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_0046: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PlateColumn_hudboxes", new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(small, false); Shape(val2); ContentSizeFitter obj = val.AddComponent<ContentSizeFitter>(); FitMode horizontalFit = (FitMode)2; obj.verticalFit = (FitMode)2; obj.horizontalFit = horizontalFit; val.AddComponent<ColumnWatch>(); return val2; } private static void Shape(RectTransform column) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); column.anchorMax = val; column.anchorMin = val; column.pivot = new Vector2(0f, 1f); column.anchoredPosition = new Vector2(6f, 0f); ((Transform)column).localScale = Vector3.one * 0.7f; VerticalLayoutGroup obj = ((Component)column).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false); ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth; } } public static class HudRow { public const float Scale = 0.7f; public const float Gap = 6f; public static Plate? Add(InventoryGui gui, PlateSpec spec) { if (!Column.Active) { return null; } RectTransform val = HudContainer.Get(); BoxStack boxStack = (((Object)(object)val != (Object)null) ? BoxStack.Ready(gui) : null); if ((Object)(object)val == (Object)null || boxStack == null) { return null; } string text = ColumnLayout.NameOf(spec); Transform obj = ((Transform)val).Find(text); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); Plate? obj2 = ((val2 != null) ? PlateCopy.Wrap(val2) : Make(boxStack, spec, text, val)); if (obj2 != null) { Order(val); } return obj2; } public static RectTransform? Container() { if (!Column.Active) { return null; } return HudContainer.Get(); } public static Sprite? WeightIcon(InventoryGui gui) { GamePlates gamePlates = GamePlates.Find(gui); Plate plate = ((gamePlates != null) ? PlateCopy.Wrap(gamePlates.Weight) : null); if (plate == null) { return null; } return plate.Icon.sprite; } private static Plate? Make(BoxStack stack, PlateSpec spec, string name, RectTransform row) { Plate plate = PlateCopy.Make(stack.Game.Armor, spec, name, (Transform?)(object)row); if (plate != null) { Graphic[] componentsInChildren = ((Component)plate.Rect).GetComponentsInChildren<Graphic>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].raycastTarget = false; } } return plate; } private static void Order(RectTransform row) { List<RectTransform> list = ColumnLayout.Sorted((Transform)(object)row); for (int i = 0; i < list.Count; i++) { if (((Transform)list[i]).GetSiblingIndex() != i) { ((Transform)list[i]).SetSiblingIndex(i); } } LayoutRebuilder.ForceRebuildLayoutImmediate(row); } } internal static class LinkBounds { public static Vector3[]? Of(TMP_Text text, string id) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) TMP_TextInfo textInfo = text.textInfo; for (int i = 0; i < textInfo.linkCount; i++) { TMP_LinkInfo link = textInfo.linkInfo[i]; if (((TMP_LinkInfo)(ref link)).GetLinkID() == id) { return Corners(text, link); } } return null; } private static Vector3[]? Corners(TMP_Text text, TMP_LinkInfo link) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) TMP_TextInfo textInfo = text.textInfo; int linkTextfirstCharacterIndex = link.linkTextfirstCharacterIndex; if (link.linkTextLength <= 0 || linkTextfirstCharacterIndex < 0 || linkTextfirstCharacterIndex >= textInfo.characterCount) { return null; } TMP_CharacterInfo val = textInfo.characterInfo[linkTextfirstCharacterIndex]; Vector3 val2 = val.bottomLeft; Vector3 val3 = val.topRight; int num = Mathf.Min(linkTextfirstCharacterIndex + link.linkTextLength, textInfo.characterCount); for (int i = linkTextfirstCharacterIndex + 1; i < num && textInfo.characterInfo[i].lineNumber == val.lineNumber; i++) { val2 = Vector3.Min(val2, textInfo.characterInfo[i].bottomLeft); val3 = Vector3.Max(val3, textInfo.characterInfo[i].topRight); } Transform transform = text.transform; return (Vector3[]?)(object)new Vector3[4] { transform.TransformPoint(new Vector3(val2.x, val2.y)), transform.TransformPoint(new Vector3(val2.x, val3.y)), transform.TransformPoint(new Vector3(val3.x, val3.y)), transform.TransformPoint(new Vector3(val3.x, val2.y)) }; } } public sealed class LinkTips : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerMoveHandler, IPointerExitHandler { private const float ShowDelay = 0.3f; private readonly Dictionary<string, KeyValuePair<string, string>> tips = new Dictionary<string, KeyValuePair<string, string>>(); private GameObject? prefab; private TMP_Text? text; private Camera? eventCamera; private Vector2 pointer; private bool inside; private string hovered = ""; private float showAt = -1f; private GameObject? box; public static LinkTips? On(InventoryGui gui, TMP_Text text) { GameObject val = TipTemplate.For(gui); if ((Object)(object)val == (Object)null || (Object)(object)text == (Object)null) { return null; } LinkTips linkTips = ((Component)text).GetComponent<LinkTips>(); if ((Object)(object)linkTips == (Object)null) { linkTips = ((Component)text).gameObject.AddComponent<LinkTips>(); } linkTips.prefab = val; linkTips.text = text; ((Graphic)text).raycastTarget = true; return linkTips; } public void Set(string id, string topic, string words) { tips[id] = new KeyValuePair<string, string>(topic, words); } public void Clear() { tips.Clear(); Hide(); } public void OnPointerEnter(PointerEventData eventData) { inside = true; Track(eventData); } public void OnPointerMove(PointerEventData eventData) { Track(eventData); } public void OnPointerExit(PointerEventData eventData) { inside = false; Hide(); } private void Track(PointerEventData eventData) { //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) pointer = eventData.position; eventCamera = eventData.enterEventCamera; } private void Update() { string text = (inside ? LinkAt() : ""); if (text != hovered) { Hide(); hovered = text; showAt = ((text.Length > 0) ? (Time.unscaledTime + 0.3f) : (-1f)); } if (showAt >= 0f && Time.unscaledTime >= showAt) { showAt = -1f; Show(); } } private string LinkAt() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null) { return ""; } int num = TMP_TextUtilities.FindIntersectingLink(text, Vector2.op_Implicit(pointer), eventCamera); if (num < 0 || num >= text.textInfo.linkCount) { return ""; } string linkID = ((TMP_LinkInfo)(ref text.textInfo.linkInfo[num])).GetLinkID(); if (!tips.ContainsKey(linkID)) { return ""; } return linkID; } private void Show() { if (!((Object)(object)text == (Object)null) && tips.TryGetValue(hovered, out KeyValuePair<string, string> value)) { Vector3[] array = LinkBounds.Of(text, hovered); if (array != null) { UITooltip.HideTooltip(); box = TipBox.Show(prefab, ((Graphic)text).canvas, array, value.Key, value.Value); } } } private void OnDisable() { inside = false; Hide(); } private void Hide() { hovered = ""; showAt = -1f; if ((Object)(object)box != (Object)null) { Object.Destroy((Object)(object)box); box = null; } } } internal static class MantleOwner { private const string Guid = "com.meadworks.mantle"; private static bool looked; private static ConfigEntry<bool>? enabled; public static bool LaysOutInventory { get { if (!looked) { looked = true; enabled = Find(); } if (enabled != null) { return enabled.Value; } return false; } } private static ConfigEntry<bool>? Find() { if (!Chainloader.PluginInfos.TryGetValue("com.meadworks.mantle", out var value) || (Object)(object)value.Instance == (Object)null) { return null; } ConfigEntry<bool> result = default(ConfigEntry<bool>); if (!value.Instance.Config.TryGetEntry<bool>("1. Inventory", "Enabled", ref result)) { return null; } return result; } } public sealed class Plate { public RectTransform Rect { get; } public Image Icon { get; } public TMP_Text? Text { get; } public Plate(RectTransform rect, Image icon, TMP_Text? text) { Rect = rect; Icon = icon; Text = text; } } internal static class PlateCopy { public static Plate? Make(RectTransform source, PlateSpec spec, string name, Transform? parent = null) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, (Transform)(((Object)(object)parent != (Object)null) ? ((object)parent) : ((object)((Transform)source).parent)), false); ((Object)val).name = name; Transform transform = val.transform; TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true); Transform val2 = PlateParts.ChildHolding(transform, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.transform : null); Image background = PlateParts.BackgroundOf(transform); Image val3 = PlateParts.IconOf(transform, val2); if ((Object)(object)val3 == (Object)null) { Object.DestroyImmediate((Object)(object)val); return null; } Strip(val, background, val3, spec.WithText ? val2 : null); TMP_Text text = (spec.WithText ? componentInChildren : null); Dress(val3, text, spec); val.SetActive(true); return new Plate((RectTransform)transform, val3, text); } public static Plate? Wrap(RectTransform box) { TMP_Text componentInChildren = ((Component)box).GetComponentInChildren<TMP_Text>(true); Image val = PlateParts.IconOf((Transform)(object)box, PlateParts.ChildHolding((Transform)(object)box, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.transform : null)); if (!((Object)(object)val != (Object)null)) { return null; } return new Plate(box, val, componentInChildren); } private static void Dress(Image icon, TMP_Text? text, PlateSpec spec) { if ((Object)(object)spec.Icon != (Object)null) { icon.sprite = spec.Icon; } if ((Object)(object)text != (Object)null) { text.text = ""; } else { BoxStyle.IconAlone(icon); } } private static void Strip(GameObject go, Image? background, Image icon, Transform? keptText) { Transform transform = go.transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if ((!((Object)(object)background != (Object)null) || !((Object)(object)child == (Object)(object)((Component)background).transform)) && !((Object)(object)child == (Object)(object)((Component)icon).transform) && !((Object)(object)child == (Object)(object)keptText)) { Object.DestroyImmediate((Object)(object)((Component)child).gameObject); } } Behaviour[] components = go.GetComponents<Behaviour>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } } } internal static class PlateParts { public static Transform? ChildHolding(Transform parent, Transform? part) { Transform val = part; while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)parent) { val = val.parent; } return val; } public static Image? BackgroundOf(Transform box) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_003c: 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_0036: 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) Image result = null; float num = 0f; foreach (Transform item in box) { Image component = ((Component)item).GetComponent<Image>(); RectTransform val2 = (RectTransform)((item is RectTransform) ? item : null); Rect val3 = (Rect)((val2 != null) ? val2.rect : default(Rect)); if ((Object)(object)component != (Object)null && ((Rect)(ref val3)).width * ((Rect)(ref val3)).height > num) { result = component; num = ((Rect)(ref val3)).width * ((Rect)(ref val3)).height; } } return result; } public static Image? IconOf(Transform box, Transform? textChild) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown Image val = BackgroundOf(box); foreach (Transform item in box) { Transform val2 = item; Image component = ((Component)val2).GetComponent<Image>(); if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)val && (Object)(object)val2 != (Object)(object)textChild) { return component; } } return null; } public static bool Carries(GameObject go, Type type) { MonoBehaviour[] components = go.GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val in components) { if ((Object)(object)val != (Object)null && ((object)val).GetType().FullName == type.FullName) { return true; } } return false; } } public sealed class PlateSpec { public string Id { get; } public int Rank { get; } public Sprite? Icon { get; } public bool WithText { get; } public string Topic { get; } public string Tip { get; } public PlateSpec(string id, int rank, Sprite? icon, bool withText, string topic, string tip) { Id = id; Rank = Mathf.Clamp(rank, 0, 9999); Icon = icon; WithText = withText; Topic = topic; Tip = tip; } } internal sealed class PlateTip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private const float ShowDelay = 0.5f; public GameObject? Prefab; public string Topic = ""; public string Text = ""; private float showAt = -1f; private GameObject? box; public void OnPointerEnter(PointerEventData eventData) { UITooltip[] components = ((Component)this).GetComponents<UITooltip>(); for (int i = 0; i < components.Length; i++) { Object.Destroy((Object)(object)components[i]); } UITooltip.HideTooltip(); showAt = Time.unscaledTime + 0.5f; } public void OnPointerExit(PointerEventData eventData) { Hide(); } private void Update() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if (showAt >= 0f && Time.unscaledTime >= showAt) { showAt = -1f; box = TipBox.Show(Prefab, (RectTransform)((Component)this).transform, Topic, Text); } } private void OnDisable() { Hide(); } private void Hide() { showAt = -1f; if ((Object)(object)box != (Object)null) { Object.Destroy((Object)(object)box); box = null; } } } internal static class PlateTips { public static void Set(InventoryGui gui, RectTransform box, string topic, string text) { PlateTip plateTip = ((Component)box).GetComponent<PlateTip>(); if ((Object)(object)plateTip == (Object)null) { GameObject val = TipTemplate.For(gui); if ((Object)(object)val == (Object)null) { return; } plateTip = ((Component)box).gameObject.AddComponent<PlateTip>(); plateTip.Prefab = val; } plateTip.Topic = topic; plateTip.Text = text; } public static void SetIfMissing(InventoryGui gui, RectTransform box, string topic, string text) { if (!PlateParts.Carries(((Component)box).gameObject, typeof(PlateTip))) { Set(gui, box, topic, text); } } } internal static class Seats { public static bool Seat(RectTransform panel, RectTransform boxes, RectTransform box, int rank) { bool result = MoveOut(panel, boxes, box); if ((Object)(object)((Transform)box).parent != (Object)(object)panel) { return result; } string text = ColumnLayout.SeatName(rank, ((Object)box).name); if ((Object)(object)((Transform)boxes).Find(text) != (Object)null) { return result; } Make(boxes, text, box); return true; } public static bool SeatGuests(RectTransform panel, RectTransform boxes) { bool flag = false; Guests[] known = Guests.Known; foreach (Guests guests in known) { if ((Object)(object)((Transform)boxes).Find(guests.Seat) == (Object)null) { Transform obj = ((Transform)panel).Find(guests.Name); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (val != null && Guests.LooksLikeBox((Transform)(object)val)) { Guests.Dress(val); flag |= Seat(panel, boxes, val, guests.Rank); } } } return flag; } public static void Arrange(RectTransform panel, RectTransform boxes) { List<RectTransform> list = ColumnLayout.Sorted((Transform)(object)boxes); for (int i = 0; i < list.Count; i++) { if (ColumnLayout.OccupantOf(((Object)list[i]).name) == null) { BoxStyle.Apply(list[i]); } if (((Transform)list[i]).GetSiblingIndex() != i) { ((Transform)list[i]).SetSiblingIndex(i); } } List<KeyValuePair<RectTransform, string>> list2 = new List<KeyValuePair<RectTransform, string>>(); Collect(boxes, list2); Follow(panel, list2); LayoutRebuilder.ForceRebuildLayoutImmediate(boxes); Pin(panel, boxes, list2); } public static void Collect(RectTransform boxes, List<KeyValuePair<RectTransform, string>> into) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown into.Clear(); foreach (Transform item in (Transform)boxes) { Transform val = item; RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null); if (val2 != null) { string text = ColumnLayout.OccupantOf(((Object)val).name); if (text != null) { into.Add(new KeyValuePair<RectTransform, string>(val2, text)); } } } } public static RectTransform? BoxOf(RectTransform panel, RectTransform member) { string text = ColumnLayout.OccupantOf(((Object)member).name); if (text != null) { Transform obj = ((Transform)panel).Find(text); return (RectTransform?)(object)((obj is RectTransform) ? obj : null); } return member; } public static bool Follow(RectTransform panel, List<KeyValuePair<RectTransform, string>> seats) { bool flag = false; foreach (KeyValuePair<RectTransform, string> seat in seats) { if ((Object)(object)seat.Key != (Object)null) { bool num = flag; RectTransform key = seat.Key; Transform obj = ((Transform)panel).Find(seat.Value); flag = num | Follow(key, (RectTransform?)(object)((obj is RectTransform) ? obj : null)); } } return flag; } public static void Pin(RectTransform panel, RectTransform boxes, List<KeyValuePair<RectTransform, string>> seats) { foreach (KeyValuePair<RectTransform, string> seat in seats) { if ((Object)(object)seat.Key != (Object)null && ((Component)seat.Key).gameObject.activeSelf) { Transform obj = ((Transform)panel).Find(seat.Value); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (val != null) { Pin(panel, boxes, seat.Key, val); } } } } private static bool Follow(RectTransform seat, RectTransform? box) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)box != (Object)null && ((Component)box).gameObject.activeSelf; bool flag2 = ((Component)seat).gameObject.activeSelf != flag; if (flag2) { ((Component)seat).gameObject.SetActive(flag); } if ((Object)(object)box == (Object)null) { return flag2; } Rect rect = box.rect; Vector2 val = Vector2.Scale(((Rect)(ref rect)).size, Vector2.op_Implicit(((Transform)box).localScale)); Vector2 val2 = seat.sizeDelta - val; if (((Vector2)(ref val2)).sqrMagnitude > 0.01f) { seat.sizeDelta = val; flag2 = true; } return flag2; } private static void Pin(RectTransform panel, RectTransform boxes, RectTransform seat, RectTransform box) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing
plugins/Mantle/YamlDotNet.dll
Decompiled 5 hours 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.Text; using System.Text.RegularExpressions; using System.Threading; using Microsoft.CodeAnalysis; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; 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.Schemas; 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("13.7.1.0")] [assembly: AssemblyInformationalVersion("13.7.1")] [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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("13.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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 YamlDotNet { internal sealed class CultureInfoAdapter : CultureInfo { private readonly IFormatProvider provider; public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) : base(baseCulture.Name) { this.provider = provider; } public override object GetFormat(Type formatType) { return provider.GetFormat(formatType); } } internal static class ReflectionExtensions { private static readonly Func<PropertyInfo, bool> IsInstance = (PropertyInfo property) => !(property.GetMethod ?? property.SetMethod).IsStatic; private static readonly Func<PropertyInfo, bool> IsInstancePublic = (PropertyInfo property) => IsInstance(property) && (property.GetMethod ?? property.SetMethod).IsPublic; public static Type? BaseType(this Type type) { return type.GetTypeInfo().BaseType; } public static bool IsValueType(this Type type) { return type.GetTypeInfo().IsValueType; } public static bool IsGenericType(this Type type) { return type.GetTypeInfo().IsGenericType; } public static bool IsGenericTypeDefinition(this Type type) { return type.GetTypeInfo().IsGenericTypeDefinition; } public static bool IsInterface(this Type type) { return type.GetTypeInfo().IsInterface; } public static bool IsEnum(this Type type) { return type.GetTypeInfo().IsEnum; } public static bool HasDefaultConstructor(this Type type, bool allowPrivateConstructors) { TypeInfo typeInfo = type.GetTypeInfo(); if (!typeInfo.IsValueType) { return typeInfo.DeclaredConstructors.Any((ConstructorInfo c) => (c.IsPublic || (allowPrivateConstructors && c.IsPrivate)) && !c.IsStatic && c.GetParameters().Length == 0); } return true; } public static bool IsAssignableFrom(this Type type, Type source) { return type.IsAssignableFrom(source.GetTypeInfo()); } public static bool IsAssignableFrom(this Type type, TypeInfo source) { return type.GetTypeInfo().IsAssignableFrom(source); } public static TypeCode GetTypeCode(this Type type) { if (type.IsEnum()) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { return TypeCode.Boolean; } if (type == typeof(char)) { return TypeCode.Char; } if (type == typeof(sbyte)) { return TypeCode.SByte; } if (type == typeof(byte)) { return TypeCode.Byte; } if (type == typeof(short)) { return TypeCode.Int16; } if (type == typeof(ushort)) { return TypeCode.UInt16; } if (type == typeof(int)) { return TypeCode.Int32; } if (type == typeof(uint)) { return TypeCode.UInt32; } if (type == typeof(long)) { return TypeCode.Int64; } if (type == typeof(ulong)) { return TypeCode.UInt64; } if (type == typeof(float)) { return TypeCode.Single; } if (type == typeof(double)) { return TypeCode.Double; } if (type == typeof(decimal)) { return TypeCode.Decimal; } if (type == typeof(DateTime)) { return TypeCode.DateTime; } if (type == typeof(string)) { return TypeCode.String; } return TypeCode.Object; } public static bool IsDbNull(this object value) { return value?.GetType()?.FullName == "System.DBNull"; } public static Type[] GetGenericArguments(this Type type) { return type.GetTypeInfo().GenericTypeArguments; } public static PropertyInfo? GetPublicProperty(this Type type, string name) { return type.GetRuntimeProperty(name); } public static FieldInfo? GetPublicStaticField(this Type type, string name) { return type.GetRuntimeField(name); } public static IEnumerable<PropertyInfo> GetProperties(this Type type, bool includeNonPublic) { Func<PropertyInfo, bool> predicate = (includeNonPublic ? IsInstance : IsInstancePublic); if (!type.IsInterface()) { return type.GetRuntimeProperties().Where(predicate); } return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetRuntimeProperties().Where(predicate)); } public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type) { return type.GetProperties(includeNonPublic: false); } public static IEnumerable<FieldInfo> GetPublicFields(this Type type) { return from f in type.GetRuntimeFields() where !f.IsStatic && f.IsPublic select f; } public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type) { return from m in type.GetRuntimeMethods() where m.IsPublic && m.IsStatic select m; } public static MethodInfo GetPrivateStaticMethod(this Type type, string name) { return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => !m.IsPublic && m.IsStatic && m.Name.Equals(name)) ?? throw new MissingMethodException("Expected to find a method named '" + name + "' in '" + type.FullName + "'."); } public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) { return type.GetRuntimeMethods().FirstOrDefault(delegate(MethodInfo m) { if (m.IsPublic && m.IsStatic && m.Name.Equals(name)) { ParameterInfo[] parameters = m.GetParameters(); if (parameters.Length == parameterTypes.Length) { return parameters.Zip(parameterTypes, (ParameterInfo pi, Type pt) => pi.ParameterType == pt).All((bool r) => r); } return false; } return false; }); } public static MethodInfo? GetPublicInstanceMethod(this Type type, string name) { return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => m.IsPublic && !m.IsStatic && m.Name.Equals(name)); } public static MethodInfo? GetGetMethod(this PropertyInfo property, bool nonPublic) { MethodInfo methodInfo = property.GetMethod; if (!nonPublic && !methodInfo.IsPublic) { methodInfo = null; } return methodInfo; } public static MethodInfo GetSetMethod(this PropertyInfo property) { return property.SetMethod; } public static IEnumerable<Type> GetInterfaces(this Type type) { return type.GetTypeInfo().ImplementedInterfaces; } public static Exception Unwrap(this TargetInvocationException ex) { return ex.InnerException; } public static bool IsInstanceOf(this Type type, object o) { if (!(o.GetType() == type)) { return o.GetType().GetTypeInfo().IsSubclassOf(type); } return true; } public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo member) { List<Attribute> list = new List<Attribute>(); Type type = member.DeclaringType; while (type != null) { type.GetPublicProperty(member.Name); list.AddRange(member.GetCustomAttributes(typeof(TAttribute))); type = type.BaseType(); } return list.ToArray(); } } internal static class PropertyInfoExtensions { public static object? ReadValue(this PropertyInfo property, object target) { return property.GetValue(target, null); } } internal static class StandardRegexOptions { public const RegexOptions Compiled = RegexOptions.Compiled; } } 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; internal bool ignoreFields; internal bool includeNonPublicProperties; internal Settings settings; internal YamlFormatter yamlFormatter = YamlFormatter.Default; 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"); settings = new Settings(); } public TBuilder IgnoreFields() { ignoreFields = true; return Self; } public TBuilder IncludeNonPublicProperties() { includeNonPublicProperties = true; return Self; } public TBuilder EnablePrivateConstructors() { settings.AllowPrivateConstructors = 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(TagName 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) { if (typeConverter == null) { throw new ArgumentNullException("typeConverter"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter.GetType(), (Nothing _) => typeConverter)); return Self; } public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter { if (typeConverterFactory == null) { throw new ArgumentNullException("typeConverterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory(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 { if (typeInspectorFactory == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory(inner))); return Self; } public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector { if (typeInspectorFactory == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory(wrapped, inner))); return Self; } public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector { return WithoutTypeInspector(typeof(TTypeInspector)); } public TBuilder WithoutTypeInspector(Type inspectorType) { if (inspectorType == null) { throw new ArgumentNullException("inspectorType"); } typeInspectorFactories.Remove(inspectorType); return Self; } public TBuilder WithYamlFormatter(YamlFormatter formatter) { yamlFormatter = formatter ?? throw new ArgumentNullException("formatter"); 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; [Flags] public enum DefaultValuesHandling { Preserve = 0, OmitNull = 1, OmitDefaults = 2, OmitEmptyCollections = 4 } 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 T Deserialize<T>(IParser parser) { return (T)Deserialize(parser, typeof(T)); } public object? Deserialize(string input) { return Deserialize(input, typeof(object)); } public object? Deserialize(TextReader input) { return Deserialize(input, typeof(object)); } public object? Deserialize(IParser parser) { return Deserialize(parser, 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 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 Lazy<IObjectFactory> objectFactory; private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories; private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories; private readonly Dictionary<TagName, Type> tagMappings; private readonly Dictionary<Type, Type> typeMappings; private readonly ITypeConverter typeConverter; private bool ignoreUnmatched; private bool duplicateKeyChecking; private bool attemptUnknownTypeDeserialization; protected override DeserializerBuilder Self => this; public DeserializerBuilder() : base((ITypeResolver)new StaticTypeResolver()) { typeMappings = new Dictionary<Type, Type>(); objectFactory = new Lazy<IObjectFactory>(() => new DefaultObjectFactory(typeMappings, settings), isThreadSafe: true); tagMappings = new Dictionary<TagName, Type> { { FailsafeSchema.Tags.Map, typeof(Dictionary<object, object>) }, { FailsafeSchema.Tags.Str, typeof(string) }, { JsonSchema.Tags.Bool, typeof(bool) }, { JsonSchema.Tags.Float, typeof(double) }, { JsonSchema.Tags.Int, typeof(int) }, { DefaultSchema.Tags.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.Value) }, { typeof(YamlSerializableNodeDeserializer), (Nothing _) => new YamlSerializableNodeDeserializer(objectFactory.Value) }, { typeof(TypeConverterNodeDeserializer), (Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters()) }, { typeof(NullNodeDeserializer), (Nothing _) => new NullNodeDeserializer() }, { typeof(ScalarNodeDeserializer), (Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, yamlFormatter) }, { typeof(ArrayNodeDeserializer), (Nothing _) => new ArrayNodeDeserializer() }, { typeof(DictionaryNodeDeserializer), (Nothing _) => new DictionaryNodeDeserializer(objectFactory.Value, duplicateKeyChecking) }, { typeof(CollectionNodeDeserializer), (Nothing _) => new CollectionNodeDeserializer(objectFactory.Value) }, { typeof(EnumerableNodeDeserializer), (Nothing _) => new EnumerableNodeDeserializer() }, { typeof(ObjectNodeDeserializer), (Nothing _) => new ObjectNodeDeserializer(objectFactory.Value, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter) } }; nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver> { { typeof(MappingNodeTypeResolver), (Nothing _) => new MappingNodeTypeResolver(typeMappings) }, { 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() } }; typeConverter = new ReflectionTypeConverter(); } internal ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = new WritablePropertiesTypeInspector(typeResolver, includeNonPublicProperties); if (!ignoreFields) { typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector); } return typeInspectorFactories.BuildComponentChain(typeInspector); } public DeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization() { attemptUnknownTypeDeserialization = true; return this; } public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory) { if (objectFactory == null) { throw new ArgumentNullException("objectFactory"); } this.objectFactory = new Lazy<IObjectFactory>(() => objectFactory, isThreadSafe: true); 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) { if (nodeDeserializer == null) { throw new ArgumentNullException("nodeDeserializer"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer.GetType(), (Nothing _) => nodeDeserializer)); return this; } public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer { if (nodeDeserializerFactory == null) { throw new ArgumentNullException("nodeDeserializerFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory(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 WithTypeDiscriminatingNodeDeserializer(Action<ITypeDiscriminatingNodeDeserializerOptions> configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1) { TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions(); configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions); TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength); return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s) { s.Before<DictionaryNodeDeserializer>(); }); } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver) { return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w) { w.OnTop(); }); } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) { if (nodeTypeResolver == null) { throw new ArgumentNullException("nodeTypeResolver"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver.GetType(), (Nothing _) => nodeTypeResolver)); return this; } public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver { if (nodeTypeResolverFactory == null) { throw new ArgumentNullException("nodeTypeResolverFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory(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(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } 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 WithTypeMapping<TInterface, TConcrete>() where TConcrete : TInterface { Type typeFromHandle = typeof(TInterface); Type typeFromHandle2 = typeof(TConcrete); if (!typeFromHandle.IsAssignableFrom(typeFromHandle2)) { throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'."); } if (typeMappings.ContainsKey(typeFromHandle)) { typeMappings[typeFromHandle] = typeFromHandle2; } else { typeMappings.Add(typeFromHandle, typeFromHandle2); } return this; } public DeserializerBuilder WithoutTagMapping(TagName tag) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (!tagMappings.Remove(tag)) { throw new KeyNotFoundException($"Tag '{tag}' is not registered"); } return this; } public DeserializerBuilder IgnoreUnmatchedProperties() { ignoreUnmatched = true; return this; } public DeserializerBuilder WithDuplicateKeyChecking() { duplicateKeyChecking = true; return this; } public IDeserializer Build() { return Deserializer.FromValueDeserializer(BuildValueDeserializer()); } public IValueDeserializer BuildValueDeserializer() { return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter)); } } 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 AnchorName Alias { get; } public bool NeedsExpansion { get; set; } public AliasEventInfo(IObjectDescriptor source, AnchorName alias) : base(source) { if (alias.IsEmpty) { throw new ArgumentNullException("alias"); } Alias = alias; } } public class ObjectEventInfo : EventInfo { public AnchorName Anchor { get; set; } public TagName 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 { AnchorName GetAlias(object target); } public interface IDeserializer { T Deserialize<T>(string input); T Deserialize<T>(TextReader input); T Deserialize<T>(IParser parser); object? Deserialize(string input); object? Deserialize(TextReader input); object? Deserialize(IParser parser); object? Deserialize(string input, Type type); object? Deserialize(TextReader input, Type type); 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 IObjectAccessor { void Set(string name, object target, object value); object? Read(string name, object target); } 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); object? CreatePrimitive(Type type); bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments); Type GetValueType(Type type); void ExecuteOnDeserializing(object value); void ExecuteOnDeserialized(object value); void ExecuteOnSerializing(object value); void ExecuteOnSerialized(object value); } 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 { string Serialize(object? graph); string Serialize(object? graph, Type type); void Serialize(TextWriter writer, 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 Clear() { entries.Clear(); } 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) { return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TArgument, TComponent> factory) => factory(argumentBuilder(inner))); } public static List<TComponent> BuildComponentList<TComponent>(this LazyComponentRegistrationList<Nothing, TComponent> registrations) { return registrations.Select((Func<Nothing, TComponent> factory) => factory(default(Nothing))).ToList(); } public static List<TComponent> BuildComponentList<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TArgument argument) { return registrations.Select((Func<TArgument, TComponent> factory) => factory(argument)).ToList(); } } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct 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 string Serialize(object? graph) { using StringWriter stringWriter = new StringWriter(); Serialize(stringWriter, graph); return stringWriter.ToString(); } public string Serialize(object? graph, Type type) { using StringWriter stringWriter = new StringWriter(); Serialize(stringWriter, graph, type); return stringWriter.ToString(); } public void Serialize(TextWriter writer, object? graph) { Serialize(new Emitter(writer, emitterSettings), graph); } 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) { 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, default(Nothing)); } 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, emitter); void NestedObjectSerializer(object? v, Type? t) { SerializeValue(emitter, 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, TagName> tagMappings = new Dictionary<Type, TagName>(); private readonly IObjectFactory objectFactory; private int maximumRecursion = 50; private EmitterSettings emitterSettings = EmitterSettings.Default; private DefaultValuesHandling defaultValuesHandlingConfiguration; private ScalarStyle defaultScalarStyle; private bool quoteNecessaryStrings; private bool quoteYaml1_1Strings; 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, new DefaultObjectFactory()) }, { typeof(CommentsObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor) } }; eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { { typeof(TypeAssigningEventEmitter), (IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: false, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter) } }; objectFactory = new DefaultObjectFactory(); objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, objectFactory); } public SerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false) { quoteNecessaryStrings = true; this.quoteYaml1_1Strings = quoteYaml1_1Strings; return this; } public SerializerBuilder WithDefaultScalarStyle(ScalarStyle style) { defaultScalarStyle = style; return this; } 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 { if (eventEmitterFactory == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory(inner))); return Self; } public SerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter { if (eventEmitterFactory == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory(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(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(type, out var 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, settings, objectFactory); WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter), 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).WithoutAnchorName(); return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w) { w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>(); }).WithTypeConverter(new YamlDotNet.Serialization.Converters.DateTimeConverter(DateTimeKind.Utc, null, true)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc) { loc.InsteadOf<TypeAssigningEventEmitter>(); }); } public SerializerBuilder WithNewLine(string newLine) { emitterSettings = emitterSettings.WithNewLine(newLine); return this; } 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> { if (objectGraphVisitor == null) { throw new ArgumentNullException("objectGraphVisitor"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable<IYamlTypeConverter> _) => objectGraphVisitor)); return this; } public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing> { if (objectGraphVisitorFactory == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> _) => objectGraphVisitorFactory(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> { if (objectGraphVisitorFactory == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory(args))); return this; } public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter> { if (objectGraphVisitorFactory == null) { throw new ArgumentNullException("objectGraphVisitorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<IEmitter> wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory(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 SerializerBuilder WithIndentedSequences() { emitterSettings = emitterSettings.WithIndentedSequences(); 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()); } internal ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver, includeNonPublicProperties); if (!ignoreFields) { typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector); } return typeInspectorFactories.BuildComponentChain(typeInspector); } } public class Settings { public bool AllowPrivateConstructors { get; set; } } public abstract class StaticBuilderSkeleton<TBuilder> where TBuilder : StaticBuilderSkeleton<TBuilder> { internal INamingConvention namingConvention = NullNamingConvention.Instance; internal ITypeResolver typeResolver; internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories; internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories; internal bool includeNonPublicProperties; internal Settings settings; internal YamlFormatter yamlFormatter = YamlFormatter.Default; protected abstract TBuilder Self { get; } internal StaticBuilderSkeleton(ITypeResolver typeResolver) { typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter> { { typeof(YamlDotNet.Serialization.Converters.GuidConverter), (Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false) } }; typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>(); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); settings = new Settings(); } 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(TagName tag, Type type); public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter) { return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w) { w.OnTop(); }); } public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) { if (typeConverter == null) { throw new ArgumentNullException("typeConverter"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter.GetType(), (Nothing _) => typeConverter)); return Self; } public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter { if (typeConverterFactory == null) { throw new ArgumentNullException("typeConverterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory(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 { if (typeInspectorFactory == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory(inner))); return Self; } public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector { if (typeInspectorFactory == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory(wrapped, inner))); return Self; } public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector { return WithoutTypeInspector(typeof(TTypeInspector)); } public TBuilder WithoutTypeInspector(Type inspectorType) { if (inspectorType == null) { throw new ArgumentNullException("inspectorType"); } typeInspectorFactories.Remove(inspectorType); return Self; } public TBuilder WithYamlFormatter(YamlFormatter formatter) { yamlFormatter = formatter ?? throw new ArgumentNullException("formatter"); return Self; } protected IEnumerable<IYamlTypeConverter> BuildTypeConverters() { return typeConverterFactories.BuildComponentList(); } } public abstract class StaticContext { public virtual bool IsKnownType(Type type) { throw new NotImplementedException(); } public virtual ITypeResolver GetTypeResolver() { throw new NotImplementedException(); } public virtual StaticObjectFactory GetFactory() { throw new NotImplementedException(); } public virtual ITypeInspector GetTypeInspector() { throw new NotImplementedException(); } } public sealed class StaticDeserializerBuilder : StaticBuilderSkeleton<StaticDeserializerBuilder> { private readonly StaticContext context; private readonly StaticObjectFactory factory; private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories; private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories; private readonly Dictionary<TagName, Type> tagMappings; private readonly ITypeConverter typeConverter; private readonly Dictionary<Type, Type> typeMappings; private bool ignoreUnmatched; private bool duplicateKeyChecking; private bool attemptUnknownTypeDeserialization; protected override StaticDeserializerBuilder Self => this; public StaticDeserializerBuilder(StaticContext context) : base(context.GetTypeResolver()) { this.context = context; factory = context.GetFactory(); typeMappings = new Dictionary<Type, Type>(); tagMappings = new Dictionary<TagName, Type> { { FailsafeSchema.Tags.Map, typeof(Dictionary<object, object>) }, { FailsafeSchema.Tags.Str, typeof(string) }, { JsonSchema.Tags.Bool, typeof(bool) }, { JsonSchema.Tags.Float, typeof(double) }, { JsonSchema.Tags.Int, typeof(int) }, { DefaultSchema.Tags.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)); nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer> { { typeof(YamlConvertibleNodeDeserializer), (Nothing _) => new YamlConvertibleNodeDeserializer(factory) }, { typeof(YamlSerializableNodeDeserializer), (Nothing _) => new YamlSerializableNodeDeserializer(factory) }, { typeof(TypeConverterNodeDeserializer), (Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters()) }, { typeof(NullNodeDeserializer), (Nothing _) => new NullNodeDeserializer() }, { typeof(ScalarNodeDeserializer), (Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, yamlFormatter) }, { typeof(StaticArrayNodeDeserializer), (Nothing _) => new StaticArrayNodeDeserializer(factory) }, { typeof(StaticDictionaryNodeDeserializer), (Nothing _) => new StaticDictionaryNodeDeserializer(factory, duplicateKeyChecking) }, { typeof(StaticCollectionNodeDeserializer), (Nothing _) => new StaticCollectionNodeDeserializer(factory) }, { typeof(ObjectNodeDeserializer), (Nothing _) => new ObjectNodeDeserializer(factory, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter) } }; nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver> { { typeof(MappingNodeTypeResolver), (Nothing _) => new MappingNodeTypeResolver(typeMappings) }, { 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() } }; typeConverter = new NullTypeConverter(); } internal ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = context.GetTypeInspector(); return typeInspectorFactories.BuildComponentChain(typeInspector); } public StaticDeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization() { attemptUnknownTypeDeserialization = true; return this; } public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer) { return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> w) { w.OnTop(); }); } public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where) { if (nodeDeserializer == null) { throw new ArgumentNullException("nodeDeserializer"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer.GetType(), (Nothing _) => nodeDeserializer)); return this; } public StaticDeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer { if (nodeDeserializerFactory == null) { throw new ArgumentNullException("nodeDeserializerFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory(wrapped))); return this; } public StaticDeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer { return WithoutNodeDeserializer(typeof(TNodeDeserializer)); } public StaticDeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType) { if (nodeDeserializerType == null) { throw new ArgumentNullException("nodeDeserializerType"); } nodeDeserializerFactories.Remove(nodeDeserializerType); return this; } public StaticDeserializerBuilder WithTypeDiscriminatingNodeDeserializer(Action<ITypeDiscriminatingNodeDeserializerOptions> configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1) { TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions(); configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions); TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength); return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s) { s.Before<DictionaryNodeDeserializer>(); }); } public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver) { return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w) { w.OnTop(); }); } public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) { if (nodeTypeResolver == null) { throw new ArgumentNullException("nodeTypeResolver"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver.GetType(), (Nothing _) => nodeTypeResolver)); return this; } public StaticDeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver { if (nodeTypeResolverFactory == null) { throw new ArgumentNullException("nodeTypeResolverFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory(wrapped))); return this; } public StaticDeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver { return WithoutNodeTypeResolver(typeof(TNodeTypeResolver)); } public StaticDeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType) { if (nodeTypeResolverType == null) { throw new ArgumentNullException("nodeTypeResolverType"); } nodeTypeResolverFactories.Remove(nodeTypeResolverType); return this; } public override StaticDeserializerBuilder WithTagMapping(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } 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 StaticDeserializerBuilder WithTypeMapping<TInterface, TConcrete>() where TConcrete : TInterface { Type typeFromHandle = typeof(TInterface); Type typeFromHandle2 = typeof(TConcrete); if (!typeFromHandle.IsAssignableFrom(typeFromHandle2)) { throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'."); } if (typeMappings.ContainsKey(typeFromHandle)) { typeMappings[typeFromHandle] = typeFromHandle2; } else { typeMappings.Add(typeFromHandle, typeFromHandle2); } return this; } public StaticDeserializerBuilder WithoutTagMapping(TagName tag) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (!tagMappings.Remove(tag)) { throw new KeyNotFoundException($"Tag '{tag}' is not registered"); } return this; } public StaticDeserializerBuilder IgnoreUnmatchedProperties() { ignoreUnmatched = true; return this; } public StaticDeserializerBuilder WithDuplicateKeyChecking() { duplicateKeyChecking = true; return this; } public IDeserializer Build() { return Deserializer.FromValueDeserializer(BuildValueDeserializer()); } public IValueDeserializer BuildValueDeserializer() { return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter)); } } public sealed class StaticSerializerBuilder : StaticBuilderSkeleton<StaticSerializerBuilder> { 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) { 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, default(Nothing)); } 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, emitter); void NestedObjectSerializer(object? v, Type? t) { SerializeValue(emitter, v, t); } } } private readonly StaticContext context; private readonly StaticObjectFactory factory; 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, TagName> tagMappings = new Dictionary<Type, TagName>(); private int maximumRecursion = 50; private EmitterSettings emitterSettings = EmitterSettings.Default; private DefaultValuesHandling defaultValuesHandlingConfiguration; private bool quoteNecessaryStrings; private bool quoteYaml1_1Strings; private ScalarStyle defaultScalarStyle; protected override StaticSerializerBuilder Self => this; public StaticSerializerBuilder(StaticContext context) : base((ITypeResolver)new DynamicTypeResolver()) { this.context = context; factory = context.GetFactory(); 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)); 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, factory) }, { typeof(CommentsObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor) } }; eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { { typeof(TypeAssigningEventEmitter), (IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: false, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter) } }; objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, factory); } public StaticSerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false) { quoteNecessaryStrings = true; this.quoteYaml1_1Strings = quoteYaml1_1Strings; return this; } public StaticSerializerBuilder WithQuotingNecessaryStrings() { quoteNecessaryStrings = true; return this; } public StaticSerializerBuilder WithDefaultScalarStyle(ScalarStyle style) { defaultScalarStyle = style; return this; } public StaticSerializerBuilder 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 StaticSerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter { return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w) { w.OnTop(); }); } public StaticSerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter { if (eventEmitterFactory == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory(inner))); return Self; } public StaticSerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter { if (eventEmitterFactory == null) { throw new ArgumentNullException("eventEmitterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory(wrapped, inner))); return Self; } public StaticSerializerBuilder WithoutEventEmitter<TEventEmitter>() where TEventEmitter : IEventEmitter { return WithoutEventEmitter(typeof(TEventEmitter)); } public StaticSerializerBuilder WithoutEventEmitter(Type eventEmitterType) { if (eventEmitterType == null) { throw new ArgumentNullException("eventEmitterType"); } eventEmitterFactories.Remove(eventEmitterType); return this; } public override StaticSerializerBuilder WithTagMapping(TagName tag, Type type) { if (tag.IsEmpty) { throw new ArgumentException("Non-specific tags cannot be maped"); } if (type == null) { throw new ArgumentNullException("type"); } if (tagMappings.TryGetValue(type, out var value)) { throw new ArgumentException($"Type already has a registered tag '{value}' for type '{type.FullName}'", "type"); } tagMappings.Add(type, tag); return this; } public StaticSerializerBuilder 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 StaticSerializerBuilder EnsureRoundtrip() { objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention, settings, factory); WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings, quoteNecessaryStrings), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc) { loc.InsteadOf<TypeAssigningEventEmitter>(); }); return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc) { loc.OnBottom(); }); } public StaticSerializerBuilder 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 StaticSerializerBuilder EmitDefaults() { return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve); } public StaticSerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration) { defaultValuesHandlingConfiguration = configuration; return this; } public StaticSerializerBuilder JsonCompatible() { emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue).WithoutAnchorName(); return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w) { w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>(); }).WithTypeConverter(new YamlDotNet.Serialization.Converters.DateTimeConverter(DateTimeKind.Utc, null, true)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc) { loc.InsteadOf<TypeAssigningEventEmitter>(); }); } public StaticSerializerBuilder WithNewLine(string newLine) { emitterSettings = emitterSettings.WithNewLine(newLine); return this; } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing> { return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w) { w.OnTop(); }); } public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor, A