Please disclose if your mod was created primarily 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 Player Heads v1.0.0
PlayerHeads.dll
Decompiled 2 years 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.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using ItemDataManager; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: Guid("31FCF677-3252-4ECF-B90E-75CFE82F4673")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyProduct("PlayerHeads")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("PlayerHeads")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyCompany("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<e721b0cd-10c1-4e24-8c73-9a1129ebbc2f>Embedded] internal sealed class <e721b0cd-10c1-4e24-8c73-9a1129ebbc2f>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<e721b0cd-10c1-4e24-8c73-9a1129ebbc2f>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <80340ad1-2154-4fe2-862a-57bf07667148>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <80340ad1-2154-4fe2-862a-57bf07667148>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <80340ad1-2154-4fe2-862a-57bf07667148>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<e721b0cd-10c1-4e24-8c73-9a1129ebbc2f>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContextAttribute : Attribute { public readonly byte Flag; public <22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContextAttribute(byte P_0) { Flag = P_0; } } [<e721b0cd-10c1-4e24-8c73-9a1129ebbc2f>Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [CompilerGenerated] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ItemDataManager { [PublicAPI] public abstract class ItemData { private string key; internal static WeakReference<ItemInfo> constructingInfo = null; [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0 })] internal WeakReference<ItemInfo> info; private static readonly FieldInfo parameterInfoClassImpl = AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl"); private static Dictionary<Type, Dictionary<string, FieldInfo>> serializedFields = new Dictionary<Type, Dictionary<string, FieldInfo>>(); public string CustomDataKey { get; private set; } protected virtual bool AllowStackingIdenticalValues { get; set; } public string Value { get { if (!Item.m_customData.TryGetValue(CustomDataKey, out var value)) { return ""; } return value; } set { Item.m_customData[CustomDataKey] = value; } } public string Key { get { return key; } internal set { key = value; CustomDataKey = ItemInfo.dataKey(ItemInfo.classKey(GetType(), Key)); } } public bool IsCloned => Info.isCloned.Contains(CustomDataKey); public bool IsAlive { get { ItemInfo target; return (info ?? constructingInfo).TryGetTarget(out target); } } public ItemData Item => Info.ItemData; public ItemInfo Info { get { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (!(info ?? constructingInfo).TryGetTarget(out var target)) { return new ItemInfo(new ItemData()); } return target; } } public virtual void FirstLoad() { } public virtual void Load() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown Dictionary<string, FieldInfo> dictionary = fetchSerializedFields(); if (dictionary == null || dictionary.Count <= 0 || Value == "") { return; } List<object> list = new List<object>(); string[] array = Value.Split(new char[1] { '|' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); if (array2.Length == 2 && dictionary.TryGetValue(array2[0], out var value)) { ZPackage val = new ZPackage(array2[1]); ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); parameterInfoClassImpl.SetValue(parameterInfo, value.FieldType); list.Clear(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, val, ref list); if (list.Count > 0) { value.SetValue(this, list[0]); } } } } public virtual void Save() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown Dictionary<string, FieldInfo> dictionary = fetchSerializedFields(); if (dictionary == null || dictionary.Count <= 0) { return; } StringBuilder stringBuilder = new StringBuilder(); foreach (FieldInfo value in dictionary.Values) { ZPackage val = new ZPackage(); ZRpc.Serialize(new object[1] { value.GetValue(this) }, ref val); stringBuilder.Append(value.Name); stringBuilder.Append(':'); stringBuilder.Append(val.GetBase64()); stringBuilder.Append('|'); } int length = stringBuilder.Length - 1; stringBuilder.Length = length; Value = stringBuilder.ToString(); } public virtual void Unload() { } public virtual void Upgraded() { } [<22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContext(2)] public virtual string TryStack(ItemData data) { if (!AllowStackingIdenticalValues || !(data?.Value == Value)) { return null; } return Value; } private Dictionary<string, FieldInfo> fetchSerializedFields() { Type type = GetType(); if (serializedFields.TryGetValue(type, out var value)) { return value; } return serializedFields[type] = (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where f.GetCustomAttributes(typeof(SerializeField), inherit: true).Length != 0 select f).ToDictionary((FieldInfo f) => f.Name, (FieldInfo f) => f); } } public sealed class StringItemData : ItemData { } [PublicAPI] public class ItemInfo : IEnumerable<ItemData>, IEnumerable { public static HashSet<Type> ForceLoadTypes; [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] internal static string _modGuid; private static Dictionary<Type, HashSet<Type>> typeInheritorsCache; private static HashSet<string> knownTypes; private Dictionary<string, ItemData> data = new Dictionary<string, ItemData>(); [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0 })] private WeakReference<ItemInfo> selfReference; internal HashSet<string> isCloned = new HashSet<string>(); [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] private static ItemData awakeningItem; [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] private static ItemData checkingForStackableItemData; [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0, 0 })] private static Dictionary<string, string> newValuesOnStackable; [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] private static ItemData currentlyUpgradingItem; internal static string modGuid => _modGuid ?? (_modGuid = ((Func<string>)delegate { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); return val.Info.Metadata.GUID; })()); public string Mod => modGuid; public ItemData ItemData { get; private set; } [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public string this[string key] { [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] get { return Get<StringItemData>(key)?.Value; } [param: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] set { GetOrCreate<StringItemData>(key).Value = value ?? ""; } } internal static void addTypeToInheritorsCache(Type type, string typeKey) { if (!knownTypes.Contains(typeKey)) { knownTypes.Add(typeKey); Type type2 = type; while ((object)type2 != null) { AddInterfaces(type2); type2 = type2.BaseType; } } void AddInterfaces(Type baseType) { if (!typeInheritorsCache.TryGetValue(baseType, out var value)) { HashSet<Type> hashSet2 = (typeInheritorsCache[baseType] = new HashSet<Type>()); value = hashSet2; } value.Add(type); Type[] interfaces = baseType.GetInterfaces(); foreach (Type baseType2 in interfaces) { AddInterfaces(baseType2); } } } internal static string classKey(Type type, string key) { string text = type.FullName + ((type.Assembly != Assembly.GetExecutingAssembly()) ? ("," + type.Assembly.GetName().Name) : ""); addTypeToInheritorsCache(type, text); return text + ((key == "") ? "" : ("#" + key)); } internal static string dataKey(string key) { return modGuid + "#" + key; } internal ItemInfo(ItemData itemData) { ItemData = itemData; string text = dataKey(""); List<string> list = ItemData.m_customData.Keys.ToList(); foreach (string item in list) { if (!item.StartsWith(text)) { continue; } string text2 = item.Substring(text.Length); string[] array = text2.Split(new char[1] { '#' }, 2); if (!knownTypes.Contains(array[0])) { Type type = Type.GetType(array[0]); if ((object)type != null && typeof(ItemData).IsAssignableFrom(type)) { addTypeToInheritorsCache(type, array[0]); } } } } public T GetOrCreate<T>(string key = "") where T : ItemData, new() { return Add<T>(key) ?? Get<T>(key); } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public T Add<T>(string key = "") where T : ItemData, new() { string key2 = classKey(typeof(T), key); string key3 = dataKey(key2); if (ItemData.m_customData.ContainsKey(key3) || (awakeningItem != ItemData && data.ContainsKey(key2))) { return null; } ItemData.m_customData[key3] = ""; ItemDataManager.ItemData.constructingInfo = selfReference ?? (selfReference = new WeakReference<ItemInfo>(this)); T val = new T { info = selfReference, Key = key }; data[key2] = val; val.Value = ""; val.FirstLoad(); return val; } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public T Get<T>(string key = "") where T : class { if (!typeInheritorsCache.TryGetValue(typeof(T), out var value)) { if (!typeof(ItemData).IsAssignableFrom(typeof(T)) || typeof(T) == typeof(ItemData)) { throw new Exception("Trying to get value from ItemDataManager for class not inheriting from ItemData"); } return null; } foreach (Type item in value) { string key2 = classKey(item, key); if (data.TryGetValue(key2, out var value2)) { return (T)(object)value2; } if (awakeningItem != ItemData) { string key3 = dataKey(key2); if (ItemData.m_customData.ContainsKey(key3)) { return (T)(object)constructDataObj(key2); } } } return null; } public Dictionary<string, T> GetAll<T>() where T : ItemData { LoadAll(); return data.Values.Where((ItemData o) => o is T).ToDictionary((ItemData o) => o.Key, (ItemData o) => (T)o); } public bool Remove(string key = "") { return Remove<StringItemData>(key); } public bool Remove<T>(string key = "") where T : ItemData { string key2 = classKey(typeof(T), key); string key3 = dataKey(key2); if (ItemData.m_customData.Remove(key3)) { if (data.TryGetValue(key2, out var value)) { value.Unload(); data.Remove(key2); } return true; } return false; } public bool Remove<T>(T itemData) where T : ItemData { return Remove<T>(itemData.Key); } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] private ItemData constructDataObj(string key) { string[] array = key.Split(new char[1] { '#' }, 2); Type type = Type.GetType(array[0]); if ((object)type == null || !typeof(ItemData).IsAssignableFrom(type)) { return null; } ItemDataManager.ItemData.constructingInfo = selfReference ?? (selfReference = new WeakReference<ItemInfo>(this)); ItemData itemData = (ItemData)Activator.CreateInstance(type); data[key] = itemData; itemData.info = selfReference; itemData.Key = ((array.Length > 1) ? array[1] : ""); itemData.Load(); return itemData; } public void Save() { foreach (ItemData value in data.Values) { value.Save(); } } public void LoadAll() { if (awakeningItem == ItemData) { return; } string text = dataKey(""); List<string> list = ItemData.m_customData.Keys.ToList(); foreach (string item in list) { if (item.StartsWith(text)) { string key = item.Substring(text.Length); if (!data.ContainsKey(key)) { constructDataObj(key); } } } } public IEnumerator<ItemData> GetEnumerator() { LoadAll(); return data.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static void SavePrefix(ItemData __instance) { SaveItem(__instance); } private static void SaveInventoryPrefix(Inventory __instance) { foreach (ItemData item in __instance.m_inventory) { SaveItem(item); } } private static void SaveItem(ItemData item) { if (ItemExtensions.itemInfo.TryGetValue(item, out var value)) { value.Save(); } } [<22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContext(2)] [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0, 0 })] public Dictionary<string, string> IsStackableWithOtherInfo(ItemInfo info) { LoadAll(); Dictionary<string, string> dictionary = new Dictionary<string, string>(); if (info != null) { info.LoadAll(); HashSet<string> hashSet = new HashSet<string>(info.data.Keys.Intersect(data.Keys)); foreach (string item in hashSet) { string text = data[item].TryStack(info.data[item]); if (text == null) { return null; } dictionary[item] = text; } foreach (KeyValuePair<string, ItemData> datum in info.data) { if (!dictionary.ContainsKey(datum.Key)) { string text2 = info.data[datum.Key].TryStack(null); if (text2 == null) { return null; } dictionary[datum.Key] = text2; } } } foreach (KeyValuePair<string, ItemData> datum2 in data) { if (!dictionary.ContainsKey(datum2.Key)) { string text3 = data[datum2.Key].TryStack(null); if (text3 == null) { return null; } dictionary[datum2.Key] = text3; } } return dictionary.ToDictionary((KeyValuePair<string, string> kv) => dataKey(kv.Key), (KeyValuePair<string, string> kv) => kv.Value); } [<22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContext(2)] private static void RegisterForceLoadedTypesAddItem(ItemData __result) { awakeningItem = null; if (__result != null) { RegisterForceLoadedTypes(__result); } } private static void RegisterForceLoadedTypes(ItemData itemData) { foreach (Type forceLoadType in ForceLoadTypes) { string key = classKey(forceLoadType, ""); string key2 = dataKey(key); if (itemData.m_customData.ContainsKey(key2)) { itemData.Data().constructDataObj(key); } } } private static void ItemDropAwake(ItemDrop __instance) { GameObject dropPrefab = __instance.m_itemData.m_dropPrefab; if (dropPrefab != null && ItemExtensions.itemInfo.TryGetValue(dropPrefab.GetComponent<ItemDrop>().m_itemData, out var value)) { __instance.m_itemData.Data().isCloned = new HashSet<string>(value.data.Values.Select((ItemData i) => i.CustomDataKey)); } } private static void ItemDropAwakeDelayed(ItemDrop __instance) { if (!ZNetView.m_forceDisableInit) { RegisterForceLoadedTypes(__instance.m_itemData); } } private static void ItemDataClonePrefix(ItemData __instance, ItemData __result) { SaveItem(__instance); } private static void ItemDataClonePostfix(ItemData __instance, ItemData __result) { if (ItemExtensions.itemInfo.TryGetValue(__instance, out var value)) { __result.Data().isCloned = new HashSet<string>(value.data.Values.Select((ItemData i) => i.CustomDataKey)); } } private static void ItemDataClonePostfixDelayed(ItemData __result) { RegisterForceLoadedTypes(__result); } private static void RegisterForceLoadedTypesOnPlayerLoaded(Player __instance) { foreach (Food food in __instance.m_foods) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(food.m_name); if (itemPrefab.GetComponent<ItemDrop>().m_itemData == food.m_item) { food.m_item = food.m_item.Clone(); food.m_item.m_dropPrefab = itemPrefab; } RegisterForceLoadedTypes(food.m_item); } } private static void SaveCheckingForStackableItemData(ItemData item) { checkingForStackableItemData = item; } private static void ResetCheckingForStackableItemData() { checkingForStackableItemData = null; } private static IEnumerable<CodeInstruction> CheckStackableInFindFreeStackMethods(IEnumerable<CodeInstruction> instructionsEnumerable) { CodeInstruction[] instructions = instructionsEnumerable.ToArray(); Label target = (Label)instructions.First((CodeInstruction i) => i.opcode == OpCodes.Br || i.opcode == OpCodes.Br_S).operand; CodeInstruction targetedInstr = instructions.First((CodeInstruction i) => i.labels.Contains(target)); Label? label = default(Label?); CodeInstruction lastBranch = instructions.Reverse().First((CodeInstruction i) => CodeInstructionExtensions.Branches(i, ref label) && targetedInstr.labels.Contains(label.Value)); CodeInstruction loadingInstruction = null; int j = 0; while (j < instructions.Length) { yield return instructions[j]; if (loadingInstruction == null && instructions[j].opcode == OpCodes.Call && ((MethodInfo)instructions[j].operand).Name == "get_Current") { loadingInstruction = instructions[j + 1].Clone(); loadingInstruction.opcode = new Dictionary<OpCode, OpCode> { { OpCodes.Stloc_0, OpCodes.Ldloc_0 }, { OpCodes.Stloc_1, OpCodes.Ldloc_1 }, { OpCodes.Stloc_2, OpCodes.Ldloc_2 }, { OpCodes.Stloc_3, OpCodes.Ldloc_3 }, { OpCodes.Stloc_S, OpCodes.Ldloc_S } }[loadingInstruction.opcode]; } if (instructions[j] == lastBranch) { yield return loadingInstruction; yield return new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.DeclaredField(typeof(ItemInfo), "checkingForStackableItemData")); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckItemDataIsStackableFindFree", (Type[])null, (Type[])null)); yield return new CodeInstruction(OpCodes.Brfalse, (object)target); } int num = j + 1; j = num; } } private static bool CheckItemDataIsStackableFindFree(ItemData item, [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] ItemData target) { if (target == null) { return true; } Dictionary<string, string> dictionary = IsStackable(item, target); if (dictionary != null) { newValuesOnStackable = dictionary; return true; } return false; } private static void ResetNewValuesOnStackable() { newValuesOnStackable = null; } [<22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContext(2)] private static void ApplyNewValuesOnStackable(ItemData __result) { if (__result == null || newValuesOnStackable == null) { return; } foreach (KeyValuePair<string, string> item in newValuesOnStackable) { __result.m_customData[item.Key] = item.Value; } } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0, 0 })] private static Dictionary<string, string> IsStackable(ItemData a, ItemData b) { ItemInfo itemInfo = a.Data(); if (itemInfo != null) { return itemInfo.IsStackableWithOtherInfo(b.Data()); } ItemInfo itemInfo2 = b.Data(); if (itemInfo2 != null) { return itemInfo2.IsStackableWithOtherInfo(null); } return new Dictionary<string, string>(); } private static bool CheckItemDataStackableAddItem(Inventory __instance, ItemData item, int x, int y, [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0, 0 })] ref Dictionary<string, string> __state, ref bool __result) { ItemData itemAt = __instance.GetItemAt(x, y); if (itemAt != null) { Dictionary<string, string> dictionary = IsStackable(item, itemAt); if (dictionary == null) { __result = false; return false; } __state = dictionary; } return true; } private static void ApplyCustomItemDataStackableAddItem(Inventory __instance, int x, int y, [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0, 0 })] Dictionary<string, string> __state, bool __result) { if (!__result || __state == null) { return; } foreach (KeyValuePair<string, string> item in __state) { __instance.GetItemAt(x, y).m_customData[item.Key] = item.Value; } } private static void ApplyCustomItemDataStackableAutoStack(ItemDrop item, Dictionary<string, string> customData) { item.m_itemData.m_customData = customData; } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 2, 0, 0 })] private static Dictionary<string, string> IsStackableItemDrop(ItemDrop drop, ItemData item) { return IsStackable(drop.m_itemData, item); } private static IEnumerable<CodeInstruction> HandleAutostackableItems(IEnumerable<CodeInstruction> instructionList, ILGenerator ilg) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown List<CodeInstruction> list = instructionList.ToList(); FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ItemData), "m_stack"); FieldInfo fieldInfo2 = AccessTools.DeclaredField(typeof(ItemDrop), "m_itemData"); Label? label = default(Label?); for (int i = 0; i < list.Count; i++) { if (!CodeInstructionExtensions.StoresField(list[i], fieldInfo)) { continue; } for (int num = i; num > 0; num--) { if (CodeInstructionExtensions.Branches(list[num], ref label)) { for (int num2 = num; num2 > 0; num2--) { if (CodeInstructionExtensions.LoadsField(list[num2], fieldInfo2, false)) { LocalBuilder localBuilder = ilg.DeclareLocal(typeof(Dictionary<string, string>)); LocalBuilder localBuilder2 = ilg.DeclareLocal(typeof(ItemData)); list.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "ApplyCustomItemDataStackableAutoStack", (Type[])null, (Type[])null))); list.Insert(i + 1, new CodeInstruction(OpCodes.Ldloc, (object)localBuilder.LocalIndex)); list.Insert(i + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(num + 1, new CodeInstruction(OpCodes.Brfalse, (object)label)); list.Insert(num + 1, new CodeInstruction(OpCodes.Stloc, (object)localBuilder.LocalIndex)); list.Insert(num + 1, new CodeInstruction(OpCodes.Dup, (object)localBuilder.LocalIndex)); list.Insert(num + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "IsStackableItemDrop", (Type[])null, (Type[])null))); list.Insert(num + 1, new CodeInstruction(OpCodes.Ldloc, (object)localBuilder2.LocalIndex)); list.Insert(num + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(num2 + 1, new CodeInstruction(OpCodes.Stloc, (object)localBuilder2.LocalIndex)); list.Insert(num2 + 1, new CodeInstruction(OpCodes.Dup, (object)null)); return list; } } } } } throw new Exception("Found no stack store in a branch"); } private static IEnumerable<CodeInstruction> TransferCustomItemDataOnUpgrade(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { MethodInfo itemDeleter = AccessTools.DeclaredMethod(typeof(Inventory), "RemoveItem", new Type[1] { typeof(ItemData) }, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Callvirt && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)itemDeleter)) { yield return new CodeInstruction(OpCodes.Dup, (object)null); yield return new CodeInstruction(OpCodes.Stsfld, (object)AccessTools.DeclaredField(typeof(ItemInfo), "currentlyUpgradingItem")); } yield return instruction; } } private static void ResetCurrentlyUpgradingItem() { currentlyUpgradingItem = null; } private static void CopyCustomDataFromUpgradedItem(ItemDrop item) { if (currentlyUpgradingItem != null) { item.m_itemData.m_customData = currentlyUpgradingItem.m_customData; ItemInfo itemInfo = currentlyUpgradingItem.Data(); ItemExtensions.itemInfo.Remove(currentlyUpgradingItem); ItemExtensions.itemInfo.Add(item.m_itemData, itemInfo); item.m_itemData.m_quality = currentlyUpgradingItem.m_quality + 1; item.m_itemData.m_variant = currentlyUpgradingItem.m_variant; itemInfo.ItemData = item.m_itemData; itemInfo.LoadAll(); foreach (ItemData value in itemInfo.data.Values) { value.Upgraded(); } currentlyUpgradingItem = null; awakeningItem = null; return; } GameObject dropPrefab = item.m_itemData.m_dropPrefab; if (dropPrefab == null || item.m_itemData.m_customData.Count != 0) { return; } ZNetView component = ((Component)item).GetComponent<ZNetView>(); ZDO val = ((Object.op_Implicit((Object)(object)component) && component.IsValid()) ? component.GetZDO() : null); if (val != null && val.GetInt(ZDOVars.s_dataCount, -1) != -1) { return; } item.m_itemData.m_customData = new Dictionary<string, string>(dropPrefab.GetComponent<ItemDrop>().m_itemData.m_customData); if (val == null) { return; } int num = 0; val.Set(ZDOVars.s_dataCount, item.m_itemData.m_customData.Count, false); foreach (KeyValuePair<string, string> customDatum in item.m_itemData.m_customData) { val.Set($"data_{num}", customDatum.Key); val.Set($"data__{num++}", customDatum.Value); } } private static IEnumerable<CodeInstruction> ImportCustomDataOnUpgrade(IEnumerable<CodeInstruction> instructionList) { List<CodeInstruction> list = instructionList.ToList(); foreach (CodeInstruction instruction in list) { yield return instruction; if (instruction.opcode == OpCodes.Stfld && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.DeclaredField(typeof(ItemData), "m_dropPrefab"))) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "CopyCustomDataFromUpgradedItem", (Type[])null, (Type[])null)); } } } private static void TrackAwakeningItem(ItemDrop __instance) { if (ZNetView.m_forceDisableInit) { awakeningItem = __instance.m_itemData; } } static ItemInfo() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_0189: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_01f8: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_025a: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Expected O, but got Unknown //IL_030a: Expected O, but got Unknown //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Expected O, but got Unknown //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Expected O, but got Unknown //IL_039c: Expected O, but got Unknown //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Expected O, but got Unknown //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Expected O, but got Unknown //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Expected O, but got Unknown //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Expected O, but got Unknown //IL_0591: Unknown result type (might be due to invalid IL or missing references) //IL_059f: Expected O, but got Unknown //IL_059f: Expected O, but got Unknown //IL_05de: Unknown result type (might be due to invalid IL or missing references) //IL_05eb: Expected O, but got Unknown //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_0644: Unknown result type (might be due to invalid IL or missing references) //IL_0651: Expected O, but got Unknown //IL_0651: Expected O, but got Unknown //IL_0690: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Expected O, but got Unknown ForceLoadTypes = new HashSet<Type>(); typeInheritorsCache = new Dictionary<Type, HashSet<Type>>(); knownTypes = new HashSet<string>(); awakeningItem = null; Harmony val = new Harmony("org.bepinex.helpers.ItemDataManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "Save", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveInventoryPrefix", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); foreach (MethodInfo item in from m in typeof(ItemData).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == "SaveToZDO" select m) { val.Patch((MethodBase)item, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SavePrefix", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[4] { typeof(ItemData), typeof(int), typeof(int), typeof(int) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckItemDataStackableAddItem", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ApplyCustomItemDataStackableAddItem", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "CanAddItem", new Type[2] { typeof(ItemData), typeof(int) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveCheckingForStackableItemData", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ItemInfo), "ResetCheckingForStackableItemData", (Type[])null), (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveCheckingForStackableItemData", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ItemInfo), "ResetCheckingForStackableItemData", (Type[])null), (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "FindFreeStackSpace", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckStackableInFindFreeStackMethods", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Inventory), "FindFreeStackItem", (Type[])null, (Type[])null); HarmonyMethod val2 = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckStackableInFindFreeStackMethods", (Type[])null, (Type[])null)); val.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ResetNewValuesOnStackable", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ApplyNewValuesOnStackable", (Type[])null, (Type[])null)), val2, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemDrop), "AutoStackItems", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "HandleAutostackableItems", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(InventoryGui), "DoCrafting", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "TransferCustomItemDataOnUpgrade", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ResetCurrentlyUpgradingItem", (Type[])null, (Type[])null)), (HarmonyMethod)null); foreach (MethodInfo item2 in from m in typeof(ItemData).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == "LoadFromZDO" select m) { val.Patch((MethodBase)item2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "RegisterForceLoadedTypes", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Player), "Load", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "RegisterForceLoadedTypesOnPlayerLoaded", (Type[])null, (Type[])null), 700, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[7] { typeof(string), typeof(int), typeof(int), typeof(int), typeof(long), typeof(string), typeof(bool) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "RegisterForceLoadedTypesAddItem", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(ItemDrop), "Awake", (Type[])null, (Type[])null); HarmonyMethod val3 = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "TrackAwakeningItem", (Type[])null, (Type[])null)); val2 = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ImportCustomDataOnUpgrade", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null); val.Patch((MethodBase)methodInfo2, val3, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDropAwake", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), val2, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemDrop), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDropAwakeDelayed", (Type[])null, (Type[])null), 799, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemData), "Clone", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDataClonePrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDataClonePostfix", (Type[])null, (Type[])null), 500, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemData), "Clone", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDataClonePostfixDelayed", (Type[])null, (Type[])null), 499, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } [PublicAPI] public class ForeignItemInfo : IEnumerable<object>, IEnumerable { private readonly object foreignItemInfo; public string Mod => ((string)foreignItemInfo.GetType().GetProperty("Mod")?.GetValue(foreignItemInfo)) ?? ""; public ItemData ItemData { get; private set; } [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public string this[string key] { [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] get { object obj = foreignItemInfo.GetType().InvokeMember("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty, null, foreignItemInfo, new object[1] { key }); if (obj != null) { return (string)obj.GetType().GetProperty("Value")?.GetValue(obj); } return null; } [param: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] set { foreignItemInfo.GetType().GetMethod("set_Item", BindingFlags.Instance | BindingFlags.Public)?.Invoke(foreignItemInfo, new object[2] { key, value }); } } internal ForeignItemInfo(ItemData itemData, object foreignItemInfo) { ItemData = itemData; this.foreignItemInfo = foreignItemInfo; } public T GetOrCreate<T>(string key = "") where T : class, new() { return Add<T>(key) ?? Get<T>(key); } [<22ecf125-600a-46c2-ba6c-33c5f2be77c4>NullableContext(2)] private object call([<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(0)] string name, [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 0, 2 })] object[] values, [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 0, 2 })] Type[] args, Type generic = null) { MethodInfo[] methods = foreignItemInfo.GetType().GetMethods(); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && (from p in methodInfo.GetParameters() select (!p.ParameterType.IsGenericParameter) ? p.ParameterType : null).SequenceEqual(args) && (object)generic != null == methodInfo.IsGenericMethod) { MethodInfo methodInfo2 = methodInfo; if ((object)generic != null) { methodInfo2 = methodInfo2.MakeGenericMethod(generic); } return methodInfo2.Invoke(foreignItemInfo, values); } } return null; } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public T Add<T>(string key = "") where T : class, new() { return call("Add", new object[1] { key }, new Type[1] { typeof(string) }, typeof(T)) as T; } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public T Get<T>(string key = "") where T : class { return call("Get", new object[1] { key }, new Type[1] { typeof(string) }, typeof(T)) as T; } public Dictionary<string, T> GetAll<T>() where T : class { return ((call("GetAll", Array.Empty<object>(), Array.Empty<Type>(), typeof(T)) as T) as Dictionary<string, T>) ?? new Dictionary<string, T>(); } public bool Remove(string key = "") { return (call("Add", new object[1] { key }, new Type[1] { typeof(string) }) as bool?).GetValueOrDefault(); } public bool Remove<T>(string key = "") where T : class { return (call("Remove", new object[1] { key }, new Type[1] { typeof(string) }, typeof(T)) as bool?).GetValueOrDefault(); } public bool Remove<T>(T itemData) where T : class { return (call("Remove", new object[1] { itemData }, new Type[1], typeof(T)) as bool?).GetValueOrDefault(); } public void Save() { call("Save", Array.Empty<object>(), Array.Empty<Type>()); } public void LoadAll() { call("LoadAll", Array.Empty<object>(), Array.Empty<Type>()); } public IEnumerator<object> GetEnumerator() { return (IEnumerator<object>)((call("GetEnumerator", Array.Empty<object>(), Array.Empty<Type>()) as IEnumerator<object>) ?? ((object)new List<object>().GetEnumerator())); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [PublicAPI] public static class ItemExtensions { internal static readonly ConditionalWeakTable<ItemData, ItemInfo> itemInfo = new ConditionalWeakTable<ItemData, ItemInfo>(); [<80340ad1-2154-4fe2-862a-57bf07667148>Nullable(new byte[] { 0, 0, 0, 0, 2 })] private static readonly ConditionalWeakTable<ItemData, Dictionary<string, ForeignItemInfo>> foreignItemInfo = new ConditionalWeakTable<ItemData, Dictionary<string, ForeignItemInfo>>(); public static ItemInfo Data(this ItemData item) { if (itemInfo.TryGetValue(item, out var value)) { return value; } itemInfo.Add(item, value = new ItemInfo(item)); return value; } [return: <80340ad1-2154-4fe2-862a-57bf07667148>Nullable(2)] public static ForeignItemInfo Data(this ItemData item, string mod) { Dictionary<string, ForeignItemInfo> orCreateValue = ItemExtensions.foreignItemInfo.GetOrCreateValue(item); if (orCreateValue.TryGetValue(mod, out var value)) { return value; } if (!Chainloader.PluginInfos.TryGetValue(mod, out var value2)) { return null; } object obj = ((object)value2.Instance).GetType().Assembly.GetType(typeof(ItemExtensions).FullName)?.GetMethod("Data", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, Array.Empty<ParameterModifier>())?.Invoke(null, new object[1] { item }); if (obj != null) { return orCreateValue[mod] = new ForeignItemInfo(item, obj); } Debug.LogWarning((object)("Mod " + mod + " has an " + typeof(ItemExtensions).FullName + " class, but no Data(ItemDrop.ItemData) method could be called on it.")); return orCreateValue[mod] = null; } } } namespace PlayerHeads { [BepInPlugin("kg.PlayerHeads", "kg.PlayerHeads", "1.0.0")] public class PlayerHeads : BaseUnityPlugin { public class PlayerHead : ItemData { [SerializeField] private string Nickname; public string Name => Nickname; protected override bool AllowStackingIdenticalValues { get; set; } = true; public void Assign(string name) { Nickname = name; Save(); } public string Description() { return Localization.instance.Localize("$playerhead_belongs <color=#FF0000>" + Nickname + "</color>"); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { [UsedImplicitly] private static void Postfix(ZNetScene __instance) { __instance.m_namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)PlayerHeadObj).name)] = PlayerHeadObj; } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Patch { [UsedImplicitly] private static void Postfix(ObjectDB __instance) { __instance.m_items.Add(PlayerHeadObj); __instance.m_itemByHash[StringExtensionMethods.GetStableHashCode(((Object)PlayerHeadObj).name)] = PlayerHeadObj; } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDB_Awake_Patch2 { [UsedImplicitly] private static void Postfix(ObjectDB __instance) { __instance.m_items.Add(PlayerHeadObj); __instance.m_itemByHash[StringExtensionMethods.GetStableHashCode(((Object)PlayerHeadObj).name)] = PlayerHeadObj; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float) })] private static class ItemDrop__Patch { [UsedImplicitly] private static void Postfix(ItemData item, bool crafting, ref string __result) { PlayerHead playerHead = item.Data().Get<PlayerHead>(); if (playerHead != null && !crafting) { __result = playerHead.Description(); } } } [HarmonyPatch(typeof(ItemDrop), "Start")] private static class ItemDrop_GetHoverText_Patch { [UsedImplicitly] private static void Postfix(ItemDrop __instance) { PlayerHead playerHead = __instance.m_itemData.Data().Get<PlayerHead>(); if (playerHead != null) { __instance.m_itemData.m_shared.m_name = "<color=red>" + playerHead.Name + "</color>'s $playerhead_head"; } } } [HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")] private static class InventoryGrid_CreateItemTooltip_Patch { [UsedImplicitly] private static void Prefix(ItemData item) { PlayerHead playerHead = item.Data().Get<PlayerHead>(); if (playerHead != null) { item.m_shared.m_name = "<color=red>" + playerHead.Name + "</color>'s $playerhead_head"; } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] private static class DeathHook { [UsedImplicitly] private static void Prefix(Character __instance, long sender, HitData hit) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !(__instance.GetHealth() <= 0f)) { Character attacker = hit.GetAttacker(); LastHitByPlayer = Object.op_Implicit((Object)(object)attacker) && attacker.IsPlayer(); } } [UsedImplicitly] private static void Postfix(Character __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __instance.GetHealth() <= 0f && LastHitByPlayer) { LastHitByPlayer = false; CreateHead(Game.instance.m_playerProfile.m_playerName); } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] private static class DeathHook2 { [UsedImplicitly] private static void Postfix(Character __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __instance.GetHealth() <= 0f && LastHitByPlayer) { LastHitByPlayer = false; CreateHead(Game.instance.m_playerProfile.m_playerName); } } } private const string GUID = "kg.PlayerHeads"; private const string VERSION = "1.0.0"; private static AssetBundle asset; private static GameObject PlayerHeadObj; private static bool LastHitByPlayer; private void Awake() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) Localizer.Load(); asset = GetAssetBundle("kgplayerheads"); PlayerHeadObj = asset.LoadAsset<GameObject>("PlayerHead_IDM"); PlayerHeadObj.GetComponent<ItemDrop>().m_itemData.Data().Add<PlayerHead>().Assign("Unknown"); new Harmony("kg.PlayerHeads").PatchAll(); } private static AssetBundle GetAssetBundle(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); using Stream stream = executingAssembly.GetManifestResourceStream(name); return AssetBundle.LoadFromStream(stream); } private static void CreateHead(string withName) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) PlayerHeadObj.GetComponent<ItemDrop>().m_itemData.Data().Get<PlayerHead>().Assign(withName); GameObject val = Object.Instantiate<GameObject>(PlayerHeadObj, ((Component)Player.m_localPlayer).transform.position + Vector3.up * 2f, Quaternion.identity); Vector3 insideUnitSphere = Random.insideUnitSphere; if (insideUnitSphere.y < 0f) { insideUnitSphere.y = 0f - insideUnitSphere.y; } val.GetComponent<Rigidbody>().AddForce(insideUnitSphere * 5f, (ForceMode)2); } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<06a10024-decc-4f12-8806-2c7968842ec9>Embedded] internal sealed class <06a10024-decc-4f12-8806-2c7968842ec9>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [<06a10024-decc-4f12-8806-2c7968842ec9>Embedded] internal sealed class <3c16f5f3-58f6-4e07-a241-1a62ddebad83>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <3c16f5f3-58f6-4e07-a241-1a62ddebad83>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <3c16f5f3-58f6-4e07-a241-1a62ddebad83>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [<06a10024-decc-4f12-8806-2c7968842ec9>Embedded] internal sealed class <cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContextAttribute : Attribute { public readonly byte Flag; public <cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace LocalizationManager { [PublicAPI] [<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(1)] [<3c16f5f3-58f6-4e07-a241-1a62ddebad83>Nullable(0)] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; [<3c16f5f3-58f6-4e07-a241-1a62ddebad83>Nullable(2)] private static BaseUnityPlugin _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, [<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<3c16f5f3-58f6-4e07-a241-1a62ddebad83>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null) { if (convertConfigValue == null) { convertConfigValue = [<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] [return: <3c16f5f3-58f6-4e07-a241-1a62ddebad83>Nullable(1)] (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += [<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] (object _, EventArgs _) => { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static void Load() { LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> dictionary = (from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f).ToDictionary([<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] (string f) => Path.GetFileNameWithoutExtension(f).Split(new char[1] { '.' })[1], [<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] (string f) => f); byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text = null; if (language != "English") { if (dictionary.ContainsKey(language)) { text = File.ReadAllText(dictionary[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text = Encoding.UTF8.GetString(array2); } } } if (text == null && dictionary.ContainsKey("English")) { text = File.ReadAllText(dictionary["English"]); } if (text != null) { foreach (KeyValuePair<string, string> item in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>()) { dictionary2[item.Key] = item.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair<string, string> item2 in dictionary2) { UpdatePlaceholderText(__instance, item2.Key); } } static Localizer() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string> { ".json", ".yml" }; new Harmony("org.bepinex.helpers.LocalizationManager").Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [return: <3c16f5f3-58f6-4e07-a241-1a62ddebad83>Nullable(2)] private static byte[] LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } [<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(2)] public static byte[] ReadEmbeddedFileBytes([<3c16f5f3-58f6-4e07-a241-1a62ddebad83>Nullable(1)] string resourceFileName, Assembly containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<cf28477a-ea64-4f53-8025-c5f78d9a6085>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Microsoft.CodeAnalysis { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] 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; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } } namespace System.Collections.Generic { internal static class DeconstructionExtensions { public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value) { key = pair.Key; value = pair.Value; } } } namespace YamlDotNet { internal sealed class CultureInfoAdapter : CultureInfo { private readonly IFormatProvider provider; public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) : base(baseCulture.LCID) { this.provider = provider; } public override object? GetFormat(Type? formatType) { return provider.GetFormat(formatType); } } internal static class ReflectionExtensions { private static readonly FieldInfo? RemoteStackTraceField = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); public static Type? BaseType(this Type type) { return type.BaseType; } public static bool IsValueType(this Type type) { return type.IsValueType; } public static bool IsGenericType(this Type type) { return type.IsGenericType; } public static bool IsGenericTypeDefinition(this Type type) { return type.IsGenericTypeDefinition; } public static bool IsInterface(this Type type) { return type.IsInterface; } public static bool IsEnum(this Type type) { return type.IsEnum; } public static bool IsDbNull(this object value) { return value is DBNull; } public static bool HasDefaultConstructor(this Type type) { if (!type.IsValueType) { return type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null) != null; } return true; } public static TypeCode GetTypeCode(this Type type) { return Type.GetTypeCode(type); } public static PropertyInfo? GetPublicProperty(this Type type, string name) { return type.GetProperty(name); } public static FieldInfo? GetPublicStaticField(this Type type, string name) { return type.GetField(name, BindingFlags.Static | BindingFlags.Public); } public static IEnumerable<PropertyInfo> GetProperties(this Type type, bool includeNonPublic) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public; if (includeNonPublic) { bindingFlags |= BindingFlags.NonPublic; } if (!type.IsInterface) { return type.GetProperties(bindingFlags); } return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetProperties(bindingFlags)); } public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type) { return type.GetProperties(includeNonPublic: false); } public static IEnumerable<FieldInfo> GetPublicFields(this Type type) { return type.GetFields(BindingFlags.Instance | BindingFlags.Public); } public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type) { return type.GetMethods(BindingFlags.Static | BindingFlags.Public); } public static MethodInfo GetPrivateStaticMethod(this Type type, string name) { return type.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic) ?? 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.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, parameterTypes, null); } public static MethodInfo? GetPublicInstanceMethod(this Type type, string name) { return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public); } public static Exception Unwrap(this TargetInvocationException ex) { Exception innerException = ex.InnerException; if (innerException == null) { return ex; } if (RemoteStackTraceField != null) { RemoteStackTraceField.SetValue(innerException, innerException.StackTrace + "\r\n"); } return innerException; } public static bool IsInstanceOf(this Type type, object o) { return type.IsInstanceOfType(o); } public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo property) { return Attribute.GetCustomAttributes(property, typeof(TAttribute)); } } internal 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 { internal abstract class BuilderSkeleton<TBuilder> where TBuilder : BuilderSkeleton<TBuilder> { internal INamingConvention namingConvention = NullNamingConvention.Instance; internal ITypeResolver typeResolver; internal readonly YamlAttributeOverrides overrides; internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories; internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories; private bool ignoreFields; private bool includeNonPublicProperties; protected abstract TBuilder Self { get; } internal BuilderSkeleton(ITypeResolver typeResolver) { overrides = new YamlAttributeOverrides(); typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter> { { typeof(YamlDotNet.Serialization.Converters.GuidConverter), (Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false) }, { typeof(SystemTypeConverter), (Nothing _) => new SystemTypeConverter() } }; typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>(); this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver"); } internal ITypeInspector BuildTypeInspector() { ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver, includeNonPublicProperties); if (!ignoreFields) { typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector); } return typeInspectorFactories.BuildComponentChain(typeInspector); } public TBuilder IgnoreFields() { ignoreFields = true; return Self; } public TBuilder IncludeNonPublicProperties() { includeNonPublicProperties = 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) { IYamlTypeConverter typeConverter2 = typeConverter; if (typeConverter2 == null) { throw new ArgumentNullException("typeConverter"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2)); return Self; } public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter { WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory2 = typeConverterFactory; if (typeConverterFactory2 == null) { throw new ArgumentNullException("typeConverterFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(wrapped))); return Self; } public TBuilder WithoutTypeConverter<TYamlTypeConverter>() where TYamlTypeConverter : IYamlTypeConverter { return WithoutTypeConverter(typeof(TYamlTypeConverter)); } public TBuilder WithoutTypeConverter(Type converterType) { if (converterType == null) { throw new ArgumentNullException("converterType"); } typeConverterFactories.Remove(converterType); return Self; } public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory) where TTypeInspector : ITypeInspector { return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> w) { w.OnTop(); }); } public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory, Action<IRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector { Func<ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner))); return Self; } public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector { WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory; if (typeInspectorFactory2 == null) { throw new ArgumentNullException("typeInspectorFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(wrapped, inner))); return Self; } public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector { return WithoutTypeInspector(typeof(TTypeInspector)); } public TBuilder WithoutTypeInspector(Type inspectorType) { if (inspectorType == null) { throw new ArgumentNullException("inspectorType"); } typeInspectorFactories.Remove(inspectorType); return Self; } protected IEnumerable<IYamlTypeConverter> BuildTypeConverters() { return typeConverterFactories.BuildComponentList(); } } internal delegate TComponent WrapperFactory<TComponentBase, TComponent>(TComponentBase wrapped) where TComponent : TComponentBase; internal delegate TComponent WrapperFactory<TArgument, TComponentBase, TComponent>(TComponentBase wrapped, TArgument argument) where TComponent : TComponentBase; [Flags] internal enum DefaultValuesHandling { Preserve = 0, OmitNull = 1, OmitDefaults = 2, OmitEmptyCollections = 4 } internal sealed class Deserializer : IDeserializer { private readonly IValueDeserializer valueDeserializer; public Deserializer() : this(new DeserializerBuilder().BuildValueDeserializer()) { } private Deserializer(IValueDeserializer valueDeserializer) { this.valueDeserializer = valueDeserializer ?? throw new ArgumentNullException("valueDeserializer"); } public static Deserializer FromValueDeserializer(IValueDeserializer valueDeserializer) { return new Deserializer(valueDeserializer); } public T Deserialize<T>(string input) { using StringReader input2 = new StringReader(input); return Deserialize<T>(input2); } public T Deserialize<T>(TextReader input) { return Deserialize<T>(new Parser(input)); } public object? Deserialize(TextReader input) { return Deserialize(input, typeof(object)); } public object? Deserialize(string input, Type type) { using StringReader input2 = new StringReader(input); return Deserialize(input2, type); } public object? Deserialize(TextReader input, Type type) { return Deserialize(new Parser(input), type); } public T Deserialize<T>(IParser parser) { return (T)Deserialize(parser, typeof(T)); } public object? Deserialize(IParser parser) { return Deserialize(parser, typeof(object)); } public object? Deserialize(IParser parser, Type type) { if (parser == null) { throw new ArgumentNullException("parser"); } if (type == null) { throw new ArgumentNullException("type"); } YamlDotNet.Core.Events.StreamStart @event; bool flag = parser.TryConsume<YamlDotNet.Core.Events.StreamStart>(out @event); YamlDotNet.Core.Events.DocumentStart event2; bool flag2 = parser.TryConsume<YamlDotNet.Core.Events.DocumentStart>(out event2); object result = null; if (!parser.Accept<YamlDotNet.Core.Events.DocumentEnd>(out var _) && !parser.Accept<YamlDotNet.Core.Events.StreamEnd>(out var _)) { using SerializerState serializerState = new SerializerState(); result = valueDeserializer.DeserializeValue(parser, type, serializerState, valueDeserializer); serializerState.OnDeserialization(); } if (flag2) { parser.Consume<YamlDotNet.Core.Events.DocumentEnd>(); } if (flag) { parser.Consume<YamlDotNet.Core.Events.StreamEnd>(); } return result; } } internal 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 bool ignoreUnmatched; protected override DeserializerBuilder Self => this; public DeserializerBuilder() : base((ITypeResolver)new StaticTypeResolver()) { typeMappings = new Dictionary<Type, Type>(); objectFactory = new Lazy<IObjectFactory>(() => new DefaultObjectFactory(typeMappings), 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() }, { typeof(ArrayNodeDeserializer), (Nothing _) => new ArrayNodeDeserializer() }, { typeof(DictionaryNodeDeserializer), (Nothing _) => new DictionaryNodeDeserializer(objectFactory.Value) }, { typeof(CollectionNodeDeserializer), (Nothing _) => new CollectionNodeDeserializer(objectFactory.Value) }, { typeof(EnumerableNodeDeserializer), (Nothing _) => new EnumerableNodeDeserializer() }, { typeof(ObjectNodeDeserializer), (Nothing _) => new ObjectNodeDeserializer(objectFactory.Value, BuildTypeInspector(), ignoreUnmatched) } }; 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() } }; } public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory) { IObjectFactory objectFactory2 = objectFactory; if (objectFactory2 == null) { throw new ArgumentNullException("objectFactory"); } this.objectFactory = new Lazy<IObjectFactory>(() => objectFactory2, 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) { INodeDeserializer nodeDeserializer2 = nodeDeserializer; if (nodeDeserializer2 == null) { throw new ArgumentNullException("nodeDeserializer"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2)); return this; } public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer { WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory2 = nodeDeserializerFactory; if (nodeDeserializerFactory2 == null) { throw new ArgumentNullException("nodeDeserializerFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(wrapped))); return this; } public DeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer { return WithoutNodeDeserializer(typeof(TNodeDeserializer)); } public DeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType) { if (nodeDeserializerType == null) { throw new ArgumentNullException("nodeDeserializerType"); } nodeDeserializerFactories.Remove(nodeDeserializerType); return this; } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver) { return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w) { w.OnTop(); }); } public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) { INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver; if (nodeTypeResolver2 == null) { throw new ArgumentNullException("nodeTypeResolver"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2)); return this; } public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver { WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory2 = nodeTypeResolverFactory; if (nodeTypeResolverFactory2 == null) { throw new ArgumentNullException("nodeTypeResolverFactory"); } if (where == null) { throw new ArgumentNullException("where"); } where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(wrapped))); return this; } public DeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver { return WithoutNodeTypeResolver(typeof(TNodeTypeResolver)); } public DeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType) { if (nodeTypeResolverType == null) { throw new ArgumentNullException("nodeTypeResolverType"); } nodeTypeResolverFactories.Remove(nodeTypeResolverType); return this; } public override DeserializerBuilder WithTagMapping(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 IDeserializer Build() { return Deserializer.FromValueDeserializer(BuildValueDeserializer()); } public IValueDeserializer BuildValueDeserializer() { return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList())); } } internal 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(); } } internal abstract class EventInfo { public IObjectDescriptor Source { get; } protected EventInfo(IObjectDescriptor source) { Source = source ?? throw new ArgumentNullException("source"); } } internal 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; } } internal class ObjectEventInfo : EventInfo { public AnchorName Anchor { get; set; } public TagName Tag { get; set; } protected ObjectEventInfo(IObjectDescriptor source) : base(source) { } } internal 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; } } internal sealed class MappingStartEventInfo : ObjectEventInfo { public bool IsImplicit { get; set; } public MappingStyle Style { get; set; } public MappingStartEventInfo(IObjectDescriptor source) : base(source) { } } internal sealed class MappingEndEventInfo : EventInfo { public MappingEndEventInfo(IObjectDescriptor source) : base(source) { } } internal sealed class SequenceStartEventInfo : ObjectEventInfo { public bool IsImplicit { get; set; } public SequenceStyle Style { get; set; } public SequenceStartEventInfo(IObjectDescriptor source) : base(source) { } } internal sealed class SequenceEndEventInfo : EventInfo { public SequenceEndEventInfo(IObjectDescriptor source) : base(source) { } } internal interface IAliasProvider { AnchorName GetAlias(object target); } internal interface IDeserializer { T Deserialize<T>(string input); T Deserialize<T>(TextReader input); object? Deserialize(TextReader input); object? Deserialize(string input, Type type); object? Deserialize(TextReader input, Type type); T Deserialize<T>(IParser parser); object? Deserialize(IParser parser); object? Deserialize(IParser parser, Type type); } internal 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); } internal interface INamingConvention { string Apply(string value); } internal interface INodeDeserializer { bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value); } internal interface INodeTypeResolver { bool Resolve(NodeEvent? nodeEvent, ref Type currentType); } internal interface IObjectDescriptor { object? Value { get; } Type Type { get; } Type StaticType { get; } ScalarStyle ScalarStyle { get; } } internal 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."); } } internal interface IObjectFactory { object Create(Type type); } internal interface IObjectGraphTraversalStrategy { void Traverse<TContext>(IObjectDescriptor graph, IObjectGraphVisitor<TContext> visitor, TContext context); } internal 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); } internal 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); } internal 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(); } internal interface ITrackingRegistrationLocationSelectionSyntax<TBaseRegistrationType> { void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType; } internal interface ISerializer { void Serialize(TextWriter writer, object graph); string Serialize(object graph); void Serialize(TextWriter writer, object graph, Type type); void Serialize(IEmitter emitter, object graph); void Serialize(IEmitter emitter, object graph, Type type); } internal interface ITypeInspector { IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container); IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched); } internal interface ITypeResolver { Type Resolve(Type staticType, object? actualValue); } internal interface IValueDeserializer { object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer); } internal interface IValuePromise { event Action<object?> ValueAvailable; } internal interface IValueSerializer { void SerializeValue(IEmitter emitter, object? value, Type? type); } internal interface IYamlConvertible { void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer); void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer); } internal delegate object? ObjectDeserializer(Type type); internal delegate void ObjectSerializer(object? value, Type? type = null); [Obsolete("Please use IYamlConvertible instead")] internal interface IYamlSerializable { void ReadYaml(IParser parser); void WriteYaml(IEmitter emitter); } internal 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);