Decompiled source of ValheimEnforcerFixed v0.6.2

plugins/ValheimEnforcer.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using ValheimEnforcer.common;
using ValheimEnforcer.modules;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValheimEnforcer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimEnforcer")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.6.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.6.1.0")]
namespace ValheimEnforcer
{
	internal class ValConfig
	{
		[CompilerGenerated]
		private sealed class <OnClientReceiveCharacter>d__33 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZPackage package;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnClientReceiveCharacter>d__33(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				DataObjects.Character playerCharacter = DataObjects.yamldeserializer.Deserialize<DataObjects.Character>(package.ReadString());
				Logger.LogDebug("Recieved Player character data from server.");
				CharacterManager.SetPlayerCharacter(playerCharacter);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <OnClientReceiveConfiscatedItems>d__35 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZPackage package;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnClientReceiveConfiscatedItems>d__35(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				List<DataObjects.PackedItem> list = DataObjects.yamldeserializer.Deserialize<List<DataObjects.PackedItem>>(package.ReadString());
				Logger.LogInfo($"Received {list.Count} confiscated item(s) returned from server.");
				foreach (DataObjects.PackedItem item in list)
				{
					Logger.LogInfo($"Adding returned confiscated item: {item.prefabName} x{item.m_stack}");
					item.AddToInventory(((Humanoid)Player.m_localPlayer).m_inventory, use_position: false);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <OnServerRecieveCharacter>d__32 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZPackage package;

			public long sender;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnServerRecieveCharacter>d__32(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				DataObjects.Character character = DataObjects.yamldeserializer.Deserialize<DataObjects.Character>(package.ReadString());
				Logger.LogInfo($"Recieved Player data update for {sender} - {character.Name}|{character.HostID}");
				WritePlayerCharacterToSave(character.HostID, character);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <OnServerReturnConfiscatedReceive>d__34 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnServerReturnConfiscatedReceive>d__34(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<bool> UpdateLoadedModsOnStartup;

		public static ConfigEntry<bool> AutoAddModsToRequired;

		public static ConfigEntry<bool> RemoveNontrackedItemsFromJoiningPlayers;

		public static ConfigEntry<bool> AddMissingItemsFromPlayerServerSave;

		public static ConfigEntry<bool> PreventExternalSkillRaises;

		public static ConfigEntry<bool> NewCharactersSkillsCleared;

		public static ConfigEntry<bool> NewCharactersRemoveExtraItems;

		public static ConfigEntry<bool> NewCharacterSetSkillsToZero;

		public static ConfigEntry<bool> newCharacterClearCustomData;

		public static ConfigEntry<bool> PreventExternalCustomDataChanges;

		public static ConfigEntry<bool> ValidateItemCustomData;

		public static ConfigEntry<bool> ValidateItemDurability;

		public static ConfigEntry<bool> InternalStorageMode;

		internal const string ModsFileName = "Mods.yaml";

		internal const string ValheimEnforcer = "ValheimEnforcer";

		internal const string CharacterFolder = "Characters";

		internal static string ModsConfigFilePath = Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Mods.yaml");

		internal static string CharacterFilePath = Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Characters");

		internal static CustomRPC CharacterSaveRPC;

		internal static CustomRPC ReturnConfiscatedItemsRPC;

		public ValConfig(ConfigFile cf)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0059: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_0085: Expected O, but got Unknown
			cfg = cf;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(cf);
			Logger.SetDebugLogging(EnableDebugMode.Value);
			SetupMainFileWatcher();
			CharacterSaveRPC = NetworkManager.Instance.AddRPC("VENFORCE_CHAR", new CoroutineHandler(OnServerRecieveCharacter), new CoroutineHandler(OnClientReceiveCharacter));
			ReturnConfiscatedItemsRPC = NetworkManager.Instance.AddRPC("VENFORCE_RETURN_CONFISCATED", new CoroutineHandler(OnServerReturnConfiscatedReceive), new CoroutineHandler(OnClientReceiveConfiscatedItems));
			SynchronizationManager.Instance.AddInitialSynchronization(CharacterSaveRPC, (Func<ZNetPeer, ZPackage>)SendSavedCharacter);
			LoadYamlConfigs(new Dictionary<string, Action<string>> { { ModsConfigFilePath, CreateModsFile } });
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			EnableDebugMode.SettingChanged += Logger.EnableDebugLogging;
			Logger.CheckEnableDebugLogging();
			UpdateLoadedModsOnStartup = BindServerConfig("Mods", "UpdateLoadedModsOnStartup", value: true, "Whether or not the mod configuration file will update its loaded mods once they are detected.");
			AutoAddModsToRequired = BindServerConfig("Mods", "AutoAddModsToRequired", value: true, "If true, automatically adds mods not found in the optional, admin, or server-only mod lists.");
			RemoveNontrackedItemsFromJoiningPlayers = BindServerConfig("Player Sync", "RemoveNontrackedItemsFromJoiningPlayers", value: true, "If enabled, any items that are not tracked by the server will be removed from joining player's inventories.");
			AddMissingItemsFromPlayerServerSave = BindServerConfig("Player Sync", "AddMissingItemsFromPlayerServerSave", value: true, "If enabled, any items the player does not have that are listed on the server will be given to the player when joining");
			PreventExternalSkillRaises = BindServerConfig("Player Sync", "PreventExternalSkillRaises", value: true, "If enabled, player skill gains outside of the server are removed when connecting.");
			NewCharactersSkillsCleared = BindServerConfig("Player Sync", "NewCharactersSkillsCleared", value: false, "If enabled, new characters that have no existing character file will have all skills set to 0.");
			NewCharactersRemoveExtraItems = BindServerConfig("Player Sync", "NewCharactersRemoveExtraItems", value: false, "If enabled, new characters that have no existing character file will have all items removed except for starting items.");
			NewCharacterSetSkillsToZero = BindServerConfig("Player Sync", "NewCharacterSetSkillsToZero", value: true, "If enabled, new characters will have their skills set to zero. Prevents players from raising skills before connecting.");
			PreventExternalCustomDataChanges = BindServerConfig("Player Sync", "PreventExternalCustomDataChanges", value: true, "If enabled, tracks player custom data. Warning: custom data can be large and can impact how other mods function.");
			newCharacterClearCustomData = BindServerConfig("Player Sync", "newCharacterClearCustomData", value: true, "If enabled, new characters will have their custom data cleared.");
			ValidateItemCustomData = BindServerConfig("Player Sync", "ValidateItemCustomData", value: true, "If enabled, custom data on items will be validated.");
			ValidateItemDurability = BindServerConfig("Player Sync", "ValidateItemDurability", value: true, "If enabled, item durability will be validated");
			InternalStorageMode = BindServerConfig("Advanced", "InternalStorageMode", value: false, "If enabled, player character data will be stored within your world. Enables full portability of the world without having to synchronize configurations.", null, advanced: true);
		}

		internal static void WritePlayerCharacterToSave(string id, DataObjects.Character character)
		{
			if (InternalStorageMode.Value)
			{
				Logger.LogInfo("Saving character with internal storage mode.");
				InternalDataStore.SaveAccountCharacter(character);
			}
			Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Characters"));
			string text = Path.Combine(Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Characters", id)).FullName, character.Name + ".yaml");
			Logger.LogInfo("Writing to " + text);
			File.WriteAllText(text, DataObjects.yamlserializer.Serialize((object)character));
		}

		internal static DataObjects.Character LoadCharacterFromSave(string id, string name)
		{
			if (InternalStorageMode.Value)
			{
				Logger.LogInfo("Loading character from internal storage system.");
				DataObjects.Character accountCharacter = InternalDataStore.GetAccountCharacter(id, name);
				if (accountCharacter == null)
				{
					Logger.LogDebug("No character file found for player with " + id + "-" + name + " is this character new?");
				}
				return accountCharacter;
			}
			string path = Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Characters", id, name + ".yaml");
			if (!File.Exists(path))
			{
				Logger.LogDebug("No character file found for player with " + id + "-" + name + " is this character new?");
				return null;
			}
			string text = File.ReadAllText(path);
			return DataObjects.yamldeserializer.Deserialize<DataObjects.Character>(text);
		}

		public static string GetSecondaryConfigDirectoryPath()
		{
			return Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "ValheimEnforcer")).FullName;
		}

		internal void LoadYamlConfigs(Dictionary<string, Action<string>> configFilesToFind)
		{
			string[] files = Directory.GetFiles(GetSecondaryConfigDirectoryPath());
			List<string> list = new List<string>();
			List<string> list2 = configFilesToFind.Keys.ToList();
			string[] array = files;
			foreach (string text in array)
			{
				if (list2.Contains(text))
				{
					list.Add(text);
					Logger.LogDebug("Found config: " + text);
				}
			}
			foreach (KeyValuePair<string, Action<string>> item in configFilesToFind)
			{
				if (!list.Contains(item.Key))
				{
					configFilesToFind[item.Key](item.Key);
					list.Add(item.Key);
				}
			}
			foreach (string item2 in list)
			{
				string fileName = Path.GetFileName(item2);
				Logger.LogDebug("Setting filewatcher for " + fileName);
				SetupFileWatcher(fileName);
			}
		}

		private void SetupFileWatcher(string filtername)
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
			fileSystemWatcher.Path = GetSecondaryConfigDirectoryPath();
			fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
			fileSystemWatcher.Filter = filtername;
			fileSystemWatcher.Changed += UpdateConfigFileOnChange;
			fileSystemWatcher.Created += UpdateConfigFileOnChange;
			fileSystemWatcher.Renamed += UpdateConfigFileOnChange;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private static void UpdateConfigFileOnChange(object sender, FileSystemEventArgs e)
		{
			if (!SynchronizationManager.Instance.PlayerIsAdmin)
			{
				Logger.LogInfo("Player is not an admin, and not allowed to change local configuration. Ignoring.");
			}
			else if (File.Exists(e.FullPath))
			{
				string yamlstring = File.ReadAllText(e.FullPath);
				FileInfo fileInfo = new FileInfo(e.FullPath);
				Logger.LogDebug("Filewatch changes from: (" + fileInfo.Name + ") " + fileInfo.FullName);
				if (fileInfo.Name == "Mods.yaml")
				{
					Logger.LogDebug("Triggering Mod Settings update.");
					ModManager.UpdateModSettingConfigs(yamlstring);
				}
			}
		}

		private static void CreateModsFile(string filepath)
		{
			Logger.LogDebug("Loot config missing, recreating.");
			using StreamWriter streamWriter = new StreamWriter(filepath);
			string value = "#################################################\n# Valheim Enforcer - Required, Admin and Optional Mods\n#################################################\n";
			streamWriter.WriteLine(value);
			streamWriter.WriteLine(ModManager.GetDefaultConfig());
		}

		internal static ZPackage SendSavedCharacter(ZNetPeer peer)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			string endPointString = peer.m_socket.GetEndPointString();
			Logger.LogInfo("Sending saved character data to player " + peer.m_playerName + " with ID: " + endPointString);
			ZPackage val = new ZPackage();
			if (InternalStorageMode.Value)
			{
				Logger.LogInfo("Using internal storage mode to send character data.");
				DataObjects.Character accountCharacter = InternalDataStore.GetAccountCharacter(endPointString, peer.m_playerName);
				if (accountCharacter == null)
				{
					Logger.LogInfo("No character data found for player " + peer.m_playerName + " with ID: " + endPointString + ", no character data will be sent.");
					return new ZPackage();
				}
				string text = DataObjects.yamlserializer.Serialize((object)accountCharacter);
				val.Write(text);
				return val;
			}
			string text2 = Path.Combine(Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Characters", endPointString ?? ""), peer.m_playerName + ".yaml");
			if (!File.Exists(text2))
			{
				Logger.LogInfo("path: " + text2 + " does not exist, no character data will be sent.");
				return new ZPackage();
			}
			string text3 = File.ReadAllText(text2);
			val.Write(text3);
			return val;
		}

		[IteratorStateMachine(typeof(<OnServerRecieveCharacter>d__32))]
		public static IEnumerator OnServerRecieveCharacter(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnServerRecieveCharacter>d__32(0)
			{
				sender = sender,
				package = package
			};
		}

		[IteratorStateMachine(typeof(<OnClientReceiveCharacter>d__33))]
		public static IEnumerator OnClientReceiveCharacter(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnClientReceiveCharacter>d__33(0)
			{
				package = package
			};
		}

		[IteratorStateMachine(typeof(<OnServerReturnConfiscatedReceive>d__34))]
		public static IEnumerator OnServerReturnConfiscatedReceive(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnServerReturnConfiscatedReceive>d__34(0);
		}

		[IteratorStateMachine(typeof(<OnClientReceiveConfiscatedItems>d__35))]
		public static IEnumerator OnClientReceiveConfiscatedItems(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnClientReceiveConfiscatedItems>d__35(0)
			{
				package = package
			};
		}

		internal static ZPackage SendCharacterAsZpackage(DataObjects.Character chara)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			string text = DataObjects.yamlserializer.Serialize((object)chara);
			ZPackage val = new ZPackage();
			val.Write(text);
			return val;
		}

		internal static void SetupMainFileWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
			fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
			fileSystemWatcher.Path = Path.GetDirectoryName(cfg.ConfigFilePath);
			fileSystemWatcher.Filter = "MidnightsFX.ImpactfulSkills.cfg";
			fileSystemWatcher.Changed += OnConfigFileChanged;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
		{
			if (ZNet.instance.IsServer())
			{
				Logger.LogInfo("Configuration file has been changed, reloading settings.");
				cfg.Reload();
			}
		}

		public static ConfigEntry<List<string>> BindServerConfig(string catagory, string key, List<string> value, string description, bool advanced = false)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			return cfg.Bind<List<string>>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float[]> BindServerConfig(string catagory, string key, float[] value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float[]>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<int> BindServerConfig(string catagory, string key, int value, string description, bool advanced = false, int valmin = 0, int valmax = 150)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<int>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void EnableDebugLogging(object sender, EventArgs e)
		{
			CheckEnableDebugLogging();
		}

		public static void CheckEnableDebugLogging()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void SetDebugLogging(bool state)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (state)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				ValheimEnforcer.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				ValheimEnforcer.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				ValheimEnforcer.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				ValheimEnforcer.Log.LogError((object)message);
			}
		}
	}
	[BepInPlugin("MidnightsFX.ValheimEnforcer", "ValheimEnforcer", "0.6.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class ValheimEnforcer : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.ValheimEnforcer";

		public const string PluginName = "ValheimEnforcer";

		public const string PluginVersion = "0.6.1";

		internal static ManualLogSource Log;

		internal ValConfig cfg;

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		public static AssetBundle EmbeddedResourceBundle;

		public void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("ValheimEnforcer.assets.vebundle", typeof(ValheimEnforcer).Assembly);
			PrefabManager.OnPrefabsRegistered += ModManager.SetModsActive;
			PrefabManager.OnPrefabsRegistered += InternalDataStore.InstanciateOrLinkMetadataRegistry;
			PrefabManager.OnVanillaPrefabsAvailable += ModManager.SetModsActive;
			GUIManager.OnCustomGUIAvailable += ModManager.AddErrorMessageDetailsForMenu;
			InternalDataStore.RegisterMetadataHolder();
			TerminalCommands.AddCommands();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}
}
namespace ValheimEnforcer.modules
{
	internal static class CharacterManager
	{
		[HarmonyPatch(typeof(Player), "Save")]
		public static class SaveSync
		{
			[HarmonyPrefix]
			[HarmonyPriority(600)]
			private static void PlayerSave(Player __instance)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				if (!((Scene)(ref activeScene)).name.Equals("main"))
				{
					return;
				}
				string text = "";
				string text2 = "";
				DataObjects.Character character = null;
				if (PlayerCharacter != null)
				{
					character = PlayerCharacter;
					text = PlayerCharacter.HostID;
					text2 = PlayerCharacter.Name;
				}
				else
				{
					text = GetPlayerID(__instance);
					text2 = __instance.GetPlayerName();
				}
				Logger.LogDebug("Saving character for player " + text2 + " with id " + text);
				if (PlayerCharacter == null)
				{
					character = ValConfig.LoadCharacterFromSave(text, text2);
				}
				if (character == null)
				{
					Logger.LogWarning("Attempted to save character for player " + text2 + " with ID " + text + " but no existing character data was found. Creating new character data.");
					character = new DataObjects.Character
					{
						Name = text2,
						HostID = text,
						SkillLevels = ((Character)__instance).GetSkills().GetSkillList().ToDictionary((Skill skill) => skill.m_info.m_skill, (Skill skill) => skill.m_level),
						ConfiscatedItems = null
					};
					foreach (ItemData item in ((Humanoid)__instance).GetInventory().GetAllItems().ToList())
					{
						character.AddItemToPlayerItems(item);
					}
					if (ValConfig.PreventExternalCustomDataChanges.Value)
					{
						character.PlayerCustomData = __instance.m_customData;
					}
				}
				else
				{
					Logger.LogDebug("Existing character data found for player " + text2 + " with ID " + text + ". Updating character data with current player information.");
					character.SkillLevels = ((Character)__instance).GetSkills().GetSkillList().ToDictionary((Skill skill) => skill.m_info.m_skill, (Skill skill) => skill.m_level);
					Logger.LogDebug("Updated player skills for " + text2 + " with ID " + text + ".");
					if (ValConfig.PreventExternalCustomDataChanges.Value)
					{
						character.PlayerCustomData = __instance.m_customData;
						Logger.LogDebug("Updated player custom data.");
					}
					character.PlayerItems.Clear();
					foreach (ItemData item2 in ((Humanoid)__instance).GetInventory().GetAllItems().ToList())
					{
						character.AddItemToPlayerItems(item2);
					}
					Logger.LogDebug("Updated player Items for " + text2 + " with ID " + text + ".");
				}
				if (character == null)
				{
					Logger.LogWarning("Savable character was null, not sending network updates.");
					return;
				}
				ValConfig.WritePlayerCharacterToSave(text, character);
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.GetServerPeer() != null)
				{
					Logger.LogDebug("Sending updated character data to server.");
					ValConfig.CharacterSaveRPC.SendPackage(ZNet.instance.GetServerPeer().m_uid, ValConfig.SendCharacterAsZpackage(character));
				}
			}
		}

		[HarmonyPatch(typeof(Game), "SpawnPlayer")]
		public static class LoadAndValidatePlayerPatch
		{
			[HarmonyPostfix]
			[HarmonyPriority(800)]
			private static void PlayerSpawn(Game __instance)
			{
				LoadAndValidatePlayer(Player.m_localPlayer);
			}
		}

		[HarmonyPatch(typeof(Player))]
		public static class LoadPlayerCustomData
		{
			[HarmonyPostfix]
			[HarmonyPriority(800)]
			[HarmonyPatch("Load")]
			private static void Postfix(Player __instance)
			{
				DataObjects.Character character = null;
				string id;
				string name;
				if (PlayerCharacter != null)
				{
					character = PlayerCharacter;
					id = PlayerCharacter.HostID;
					name = PlayerCharacter.Name;
				}
				else
				{
					id = GetPlayerID(__instance);
					name = __instance.GetPlayerName();
				}
				if (PlayerCharacter == null)
				{
					character = ValConfig.LoadCharacterFromSave(id, name);
				}
				if (character == null)
				{
					if (ValConfig.PreventExternalCustomDataChanges.Value && ValConfig.newCharacterClearCustomData.Value)
					{
						__instance.m_customData.Clear();
					}
				}
				else if (ValConfig.PreventExternalCustomDataChanges.Value)
				{
					__instance.m_customData = character.PlayerCustomData;
					Logger.LogDebug("Set player custom data.");
				}
			}
		}

		internal static DataObjects.Character PlayerCharacter = null;

		internal static List<string> staringAllowedPrefabs = new List<string> { "ArmorRagsChest", "ArmorRagsLegs", "Torch" };

		internal static void SetPlayerCharacter(DataObjects.Character character)
		{
			if (character != null)
			{
				Logger.LogDebug("Set character from Saved server data");
				PlayerCharacter = character;
			}
		}

		internal static string GetPlayerID(Player player)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_007f: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerInfo> playerList = ZNet.instance.GetPlayerList();
			string text = "";
			foreach (PlayerInfo item in playerList)
			{
				Logger.LogDebug($"Checking player {item.m_characterID} with ID {item.m_userInfo.m_id.m_userID} against local player {((Character)player).m_nview.GetZDO().m_uid}");
				if (item.m_characterID == ((Character)player).m_nview.GetZDO().m_uid)
				{
					text = item.m_userInfo.m_id.m_userID;
					break;
				}
			}
			if (text.Length < 1)
			{
				string playerName = player.GetPlayerName();
				foreach (PlayerInfo item2 in playerList)
				{
					if (item2.m_name == playerName)
					{
						text = item2.m_userInfo.m_id.m_userID;
						Logger.LogDebug("Matched player " + playerName + " by name to ID " + text);
						break;
					}
				}
			}
			if (text.Length < 1)
			{
				Logger.LogWarning("Failed to find matching player ID for local player " + player.GetPlayerName() + ". Defaulting to ZDO UID as player ID.");
				text = ((object)(ZDOID)(ref ((Character)player).m_nview.GetZDO().m_uid)).ToString();
			}
			if (text.Contains(":"))
			{
				Logger.LogDebug("Player ID contained invalid character : removing.");
				text = text.Split(new char[1] { ':' })[0];
			}
			return text;
		}

		private static void LoadAndValidatePlayer(Player player)
		{
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			string text;
			string text2;
			if (PlayerCharacter != null)
			{
				text = PlayerCharacter.HostID;
				text2 = PlayerCharacter.Name;
			}
			else
			{
				text = GetPlayerID(player);
				text2 = player.GetPlayerName();
			}
			Logger.LogInfo("Player " + text2 + " with ID " + text + " validating character data.");
			DataObjects.Character savableChar = PlayerCharacter;
			if (savableChar == null)
			{
				Logger.LogInfo("No existing character data found for player " + text2 + " with ID " + text + ". Attempting to load from local save.");
				savableChar = ValConfig.LoadCharacterFromSave(text, text2);
				if (savableChar == null)
				{
					if (ValConfig.NewCharactersSkillsCleared.Value)
					{
						Logger.LogInfo("New character save for player " + text2 + " with ID " + text + ", skills set to zero.");
						((Character)player).GetSkills().CheatResetSkill("all");
					}
					savableChar = new DataObjects.Character
					{
						Name = player.GetPlayerName(),
						HostID = text,
						SkillLevels = ((Character)player).GetSkills().GetSkillList().ToDictionary((Skill skill) => skill.m_info.m_skill, (Skill skill) => skill.m_level)
					};
					if (ValConfig.NewCharacterSetSkillsToZero.Value)
					{
						Logger.LogInfo("Setting new character skills to zero.");
						foreach (SkillType item3 in savableChar.SkillLevels.Keys.ToList())
						{
							savableChar.SkillLevels[item3] = 0f;
						}
					}
					if (ValConfig.NewCharactersRemoveExtraItems.Value)
					{
						Logger.LogInfo("New character save for player " + text2 + " with ID " + text + ", checking to removing non-starter items.");
						List<ItemData> removeItems = new List<ItemData>();
						((Humanoid)player).m_inventory.GetAllItems().ForEach(delegate(ItemData item)
						{
							if (!staringAllowedPrefabs.Contains(((Object)item.m_dropPrefab).name))
							{
								Logger.LogInfo($"Removing non-starter item {((Object)item.m_dropPrefab).name}x{item.m_stack} from new player {savableChar.Name}");
								savableChar.AddConfiscatedItem(item);
								removeItems.Add(item);
							}
							if (item.m_quality > 1)
							{
								Logger.LogInfo($"Removing high quality item {((Object)item.m_dropPrefab).name}x{item.m_stack} with quality {item.m_quality} from new player {savableChar.Name}");
								savableChar.AddConfiscatedItem(item);
								removeItems.Add(item);
							}
						});
						foreach (ItemData item4 in removeItems)
						{
							((Humanoid)player).UnequipItem(item4, true);
							((Humanoid)player).GetInventory().RemoveItem(item4);
						}
					}
					foreach (ItemData item5 in ((Humanoid)player).GetInventory().GetAllItems().ToList())
					{
						savableChar.AddItemToPlayerItems(item5);
						if (ValConfig.ValidateItemCustomData.Value)
						{
							item5.m_customData.Clear();
						}
					}
				}
			}
			if (ValConfig.RemoveNontrackedItemsFromJoiningPlayers.Value)
			{
				new List<ItemData>();
				foreach (KeyValuePair<ItemData, DataObjects.ItemValidatorResult> item6 in ValidateItems(((Humanoid)player).m_inventory.GetAllItems(), savableChar))
				{
					if (!item6.Value.Validated)
					{
						Logger.LogInfo($"Removing item {((Object)item6.Key.m_dropPrefab).name}x{item6.Key.m_stack} from player {savableChar.Name}. Validation message: {item6.Value.ValidationMessage}");
						savableChar.AddConfiscatedItem(item6.Key);
						((Humanoid)player).UnequipItem(item6.Key, true);
						((Humanoid)player).GetInventory().RemoveItem(item6.Key);
					}
				}
			}
			if (ValConfig.AddMissingItemsFromPlayerServerSave.Value)
			{
				Logger.LogDebug("Checking to restore player items.");
				List<Tuple<string, int>> list = new List<Tuple<string, int>>();
				foreach (ItemData allItem in ((Humanoid)player).m_inventory.GetAllItems())
				{
					list.Add(new Tuple<string, int>(((Object)allItem.m_dropPrefab).name, allItem.m_stack));
				}
				foreach (DataObjects.PackedItem playerItem in savableChar.PlayerItems)
				{
					Tuple<string, int> item2 = new Tuple<string, int>(playerItem.prefabName, playerItem.m_stack);
					if (!list.Contains(item2))
					{
						Logger.LogInfo($"Adding missing item to players inventory: {playerItem.prefabName}x{playerItem.m_stack}");
						playerItem.AddToInventory(((Humanoid)player).GetInventory(), use_position: false);
					}
				}
			}
			Logger.LogDebug("Validated player items.");
			if (ValConfig.PreventExternalSkillRaises.Value)
			{
				((Character)player).GetSkills().GetSkillList().ForEach(delegate(Skill skill)
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Unknown result type (might be due to invalid IL or missing references)
					if (savableChar.SkillLevels.TryGetValue(skill.m_info.m_skill, out var value) && skill.m_level > value)
					{
						Logger.LogInfo($"Removing external skill gains for {skill.m_info.m_skill} from {value} to {skill.m_level} from player {savableChar.Name}");
						skill.m_level = value;
					}
				});
			}
			Logger.LogDebug("Validated player skills.");
			PlayerCharacter = savableChar;
			ValConfig.WritePlayerCharacterToSave(text, savableChar);
			if (ZNet.instance.GetServerPeer() != null)
			{
				ValConfig.CharacterSaveRPC.SendPackage(ZNet.instance.GetServerPeer().m_uid, ValConfig.SendCharacterAsZpackage(savableChar));
			}
		}

		internal static Dictionary<ItemData, DataObjects.ItemValidatorResult> ValidateItems(List<ItemData> playerItems, DataObjects.Character savedChar)
		{
			Dictionary<ItemData, DataObjects.ItemValidatorResult> dictionary = new Dictionary<ItemData, DataObjects.ItemValidatorResult>();
			Logger.LogInfo($"Player Items: {playerItems.Count} | SavedCharacter Items: {savedChar.PlayerItems.Count}");
			foreach (ItemData playerItem in playerItems)
			{
				Logger.LogDebug("Checking player item: " + ((Object)playerItem.m_dropPrefab).name);
				DataObjects.ValidationSummary validationSummary = new DataObjects.ValidationSummary();
				dictionary.Add(playerItem, new DataObjects.ItemValidatorResult
				{
					CharacterItemRef = playerItem
				});
				foreach (DataObjects.PackedItem playerItem2 in savedChar.PlayerItems)
				{
					if (!(playerItem2.prefabName == ((Object)playerItem.m_dropPrefab).name) || playerItem2.m_stack != playerItem.m_stack)
					{
						continue;
					}
					validationSummary.NameAndStackMatch = true;
					int num = playerItem2.m_quality;
					if (num == 0)
					{
						num = 1;
					}
					if (num == playerItem.m_quality)
					{
						validationSummary.QualityMatch = true;
					}
					if (ValConfig.ValidateItemDurability.Value && playerItem2.m_durability != playerItem.m_durability)
					{
						validationSummary.DurabilityMatch = false;
						Logger.LogDebug($"Item {((Object)playerItem.m_dropPrefab).name} durability mismatch. Expected {playerItem2.m_durability} got {playerItem.m_durability}");
					}
					else
					{
						validationSummary.DurabilityMatch = true;
					}
					validationSummary.CustomDataMatch = true;
					if (ValConfig.ValidateItemCustomData.Value)
					{
						foreach (KeyValuePair<string, string> customDatum in playerItem.m_customData)
						{
							if (playerItem2.m_customdata.ContainsKey(customDatum.Key) && playerItem2.m_customdata[customDatum.Key] != customDatum.Value)
							{
								validationSummary.CustomDataMatch = false;
								Logger.LogDebug("Item " + ((Object)playerItem.m_dropPrefab).name + " custom data mismatch on key " + customDatum.Key + ". Expected " + playerItem2.m_customdata[customDatum.Key] + " got " + customDatum.Value);
							}
						}
					}
					if (validationSummary.IsValid())
					{
						Logger.LogDebug("Item " + ((Object)playerItem.m_dropPrefab).name + " passed validation checks against saved character data.");
						dictionary[playerItem].SavedItemRef = playerItem2;
						dictionary[playerItem].Validated = true;
						break;
					}
				}
				dictionary[playerItem].ValidationResult = validationSummary;
				if (!validationSummary.IsValid())
				{
					dictionary[playerItem].ValidationMessage = "Item " + ((Object)playerItem.m_dropPrefab).name + " failed validation checks against saved character data. " + $"Stack Match: {validationSummary.NameAndStackMatch}, " + $"Quality Match: {validationSummary.QualityMatch}, " + $"Custom Data Match: {validationSummary.CustomDataMatch}, " + $"Durability Match: {validationSummary.DurabilityMatch}";
				}
			}
			return dictionary;
		}
	}
	internal static class TerminalCommands
	{
		internal class ListPlayers : ConsoleCommand
		{
			public override string Name => "Enforcer-List-Players";

			public override bool IsCheat => true;

			public override string Help => "Enforcer-List-Players - Provides a full list of all accounts and Player names stored.";

			public override void Run(string[] args)
			{
				if (ValConfig.InternalStorageMode.Value)
				{
					foreach (KeyValuePair<string, List<string>> item in InternalDataStore.GetAccountRegistry())
					{
						Logger.LogInfo("Account:" + item.Key);
						foreach (string item2 in item.Value)
						{
							Logger.LogInfo("   " + item2);
						}
					}
					return;
				}
				foreach (string item3 in Directory.GetFiles(Path.Combine(Paths.ConfigPath, "ValheimEnforcer", "Characters")).ToList())
				{
					List<string> list = Directory.GetFiles(item3).ToList();
					Logger.LogInfo("Account:" + item3.Split(new char[1] { '/' }).Last());
					foreach (string item4 in list)
					{
						Logger.LogInfo("   " + item4.Split(new char[1] { '/' }).Last());
					}
				}
			}
		}

		internal class ListPlayerConfiscatedItems : ConsoleCommand
		{
			public override string Name => "Enforcer-List-Confiscated";

			public override bool IsCheat => true;

			public override string Help => "Gets a list of confiscated items, specific to a player/character. Format: enforcer-list-confiscated 99999999 TerryTheTerrible";

			public override void Run(string[] args)
			{
				if (args.Length != 2)
				{
					Logger.LogInfo("Account ID and playername are required. Ensure your command follows the format: enforcer-list-confiscated 99999999 TerryTheTerrible");
					return;
				}
				string id = args[0];
				string name = args[1];
				DataObjects.Character character = ValConfig.LoadCharacterFromSave(id, name);
				if (character.ConfiscatedItems.Count == 0)
				{
					Logger.LogInfo("Player does not have any confiscated items.");
					return;
				}
				Logger.LogInfo($"Found {character.ConfiscatedItems.Count} confiscated items.");
				foreach (DataObjects.PackedItem confiscatedItem in character.ConfiscatedItems)
				{
					Logger.LogInfo($"  {confiscatedItem.prefabName} x {confiscatedItem.m_stack}");
				}
			}
		}

		internal class ClearPlayerConfiscatedItems : ConsoleCommand
		{
			public override string Name => "Enforcer-Clear-Confiscated";

			public override bool IsCheat => true;

			public override string Help => "Clears any confiscated items listed for the specified player Format: enforcer-retrieve-confiscated 99999999 TerryTheTerrible all";

			public override void Run(string[] args)
			{
				if (args.Length != 3)
				{
					Logger.LogInfo("Account ID and playername are required. Ensure your command follows the format: enforcer-retrieve-confiscated 99999999 TerryTheTerrible all");
					return;
				}
				string id = args[0];
				string name = args[1];
				string text = args[2];
				DataObjects.Character character = ValConfig.LoadCharacterFromSave(id, name);
				if (character == null)
				{
					Logger.LogInfo("Character was not found for the specified account.");
					return;
				}
				if (character.ConfiscatedItems.Count == 0)
				{
					Logger.LogInfo("Player does not have any confiscated items.");
					return;
				}
				character.ConfiscatedItems.Clear();
				ValConfig.WritePlayerCharacterToSave(id, character);
				Logger.LogInfo($"Found {character.ConfiscatedItems.Count} confiscated items.");
				if (string.Compare(text, "all", ignoreCase: true) == 0)
				{
					Logger.LogInfo("Providing all confiscated items.");
					foreach (DataObjects.PackedItem confiscatedItem in character.ConfiscatedItems)
					{
						confiscatedItem.AddToInventory(((Humanoid)Player.m_localPlayer).m_inventory, use_position: false);
					}
					character.ConfiscatedItems.Clear();
					return;
				}
				foreach (DataObjects.PackedItem confiscatedItem2 in character.ConfiscatedItems)
				{
					_ = confiscatedItem2;
					List<string> list = text.Split(new char[1] { ',' }).ToList();
					foreach (DataObjects.PackedItem confiscatedItem3 in character.ConfiscatedItems)
					{
						if (list.Contains(confiscatedItem3.prefabName))
						{
							Logger.LogInfo("Providing " + confiscatedItem3.prefabName);
							confiscatedItem3.AddToInventory(((Humanoid)Player.m_localPlayer).m_inventory, use_position: false);
						}
					}
				}
			}
		}

		internal class RestorePlayerConfiscatedItems : ConsoleCommand
		{
			public override string Name => "Enforcer-Admin-Take-Confiscated";

			public override bool IsCheat => true;

			public override string Help => "Gives you player confiscated items, use either item prefab or 'all'. Format: enforcer-admin-take-confiscated 99999999 TerryTheTerrible all";

			public override void Run(string[] args)
			{
				if (args.Length != 3)
				{
					Logger.LogInfo("Account ID and playername are required. Ensure your command follows the format: enforcer-admin-take-confiscated 99999999 TerryTheTerrible all");
					return;
				}
				string id = args[0];
				string name = args[1];
				string text = args[2];
				DataObjects.Character character = ValConfig.LoadCharacterFromSave(id, name);
				if (character == null)
				{
					Logger.LogInfo("Character was not found for the specified account.");
					return;
				}
				if (character.ConfiscatedItems.Count == 0)
				{
					Logger.LogInfo("Player does not have any confiscated items.");
					return;
				}
				Logger.LogInfo($"Found {character.ConfiscatedItems.Count} confiscated items.");
				if (string.Compare(text, "all", ignoreCase: true) == 0)
				{
					Logger.LogInfo("Providing all confiscated items.");
					foreach (DataObjects.PackedItem confiscatedItem in character.ConfiscatedItems)
					{
						confiscatedItem.AddToInventory(((Humanoid)Player.m_localPlayer).m_inventory, use_position: false);
					}
					character.ConfiscatedItems.Clear();
					return;
				}
				foreach (DataObjects.PackedItem confiscatedItem2 in character.ConfiscatedItems)
				{
					_ = confiscatedItem2;
					List<string> list = text.Split(new char[1] { ',' }).ToList();
					foreach (DataObjects.PackedItem confiscatedItem3 in character.ConfiscatedItems)
					{
						if (list.Contains(confiscatedItem3.prefabName))
						{
							Logger.LogInfo("Providing " + confiscatedItem3.prefabName);
							confiscatedItem3.AddToInventory(((Humanoid)Player.m_localPlayer).m_inventory, use_position: false);
						}
					}
				}
				ValConfig.WritePlayerCharacterToSave(character.HostID, character);
			}
		}

		internal class ReturnPlayerConfiscatedItems : ConsoleCommand
		{
			public override string Name => "Enforcer-Return-Confiscated";

			public override bool IsCheat => true;

			public override string Help => "Sends confiscated items to a connected player via RPC. Use 'all' or comma-separated prefab names. Format: Enforcer-Return-Confiscated 99999999 TerryTheTerrible all";

			public override void Run(string[] args)
			{
				//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02fc: Expected O, but got Unknown
				if (args.Length != 3)
				{
					Logger.LogInfo("Account ID, player name, and item filter are required. Ensure your command follows the format: Enforcer-Return-Confiscated 99999999 TerryTheTerrible all");
					return;
				}
				string text = args[0];
				string text2 = args[1];
				string text3 = args[2];
				DataObjects.Character character = ValConfig.LoadCharacterFromSave(text, text2);
				if (character == null)
				{
					Logger.LogInfo("Character was not found for the specified account.");
					return;
				}
				if (character.ConfiscatedItems.Count == 0)
				{
					Logger.LogInfo("Player does not have any confiscated items.");
					return;
				}
				List<DataObjects.PackedItem> list;
				if (string.Compare(text3, "all", ignoreCase: true) == 0)
				{
					list = new List<DataObjects.PackedItem>(character.ConfiscatedItems);
					character.ConfiscatedItems.Clear();
				}
				else
				{
					List<string> targetPrefabs = (from s in text3.Split(new char[1] { ',' })
						select s.Trim()).ToList();
					list = character.ConfiscatedItems.Where((DataObjects.PackedItem i) => targetPrefabs.Contains(i.prefabName)).ToList();
					character.ConfiscatedItems.RemoveAll((DataObjects.PackedItem i) => targetPrefabs.Contains(i.prefabName));
				}
				if (list.Count == 0)
				{
					Logger.LogInfo("No matching confiscated items found for the specified filter.");
					return;
				}
				if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerName() == text2)
				{
					Logger.LogInfo("Local player is the target, returning player items.");
					foreach (DataObjects.PackedItem item in list)
					{
						Logger.LogInfo("Providing " + item.prefabName);
						item.AddToInventory(((Humanoid)Player.m_localPlayer).m_inventory, use_position: false);
					}
					ValConfig.WritePlayerCharacterToSave(text, character);
					return;
				}
				ZNetPeer val = null;
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					foreach (ZNetPeer peer in ZNet.instance.GetPeers())
					{
						if (!(peer.m_playerName != text2))
						{
							string text4 = peer.m_socket.GetEndPointString();
							if (text4.Contains(":"))
							{
								text4 = text4.Split(new char[1] { ':' })[0];
							}
							if (text4 == text)
							{
								val = peer;
								break;
							}
						}
					}
					if (val == null)
					{
						foreach (ZNetPeer peer2 in ZNet.instance.GetPeers())
						{
							if (peer2.m_playerName == text2)
							{
								val = peer2;
								break;
							}
						}
					}
				}
				if (val == null)
				{
					Logger.LogInfo("Player " + text2 + " is not currently connected. Moving items to player inventory save so they are restored on next login.");
					foreach (DataObjects.PackedItem item2 in list)
					{
						character.PlayerItems.Add(item2);
					}
					ValConfig.WritePlayerCharacterToSave(text, character);
				}
				else
				{
					ValConfig.WritePlayerCharacterToSave(text, character);
					Logger.LogInfo($"Sending {list.Count} confiscated item(s) to player {text2}.");
					ZPackage val2 = new ZPackage();
					val2.Write(DataObjects.yamlserializer.Serialize((object)list));
					ValConfig.ReturnConfiscatedItemsRPC.SendPackage(val.m_uid, val2);
				}
			}
		}

		internal static void AddCommands()
		{
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ListPlayers());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ListPlayerConfiscatedItems());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RestorePlayerConfiscatedItems());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ReturnPlayerConfiscatedItems());
		}
	}
	internal static class InternalDataStore
	{
		private static ZDO MetadataRegistry;

		internal static void SaveAccountCharacter(DataObjects.Character character)
		{
			InstanciateOrLinkMetadataRegistry();
			UpdateAccountRegistry(character.HostID, character.Name);
			string @string = MetadataRegistry.GetString(character.HostID, (string)null);
			if (@string != null)
			{
				DataObjects.CharacterSaveData characterSaveData = DataObjects.yamldeserializer.Deserialize<DataObjects.CharacterSaveData>(@string);
				if (characterSaveData.SavedCharacters.ContainsKey(character.Name))
				{
					characterSaveData.SavedCharacters[character.Name] = character;
				}
				else
				{
					characterSaveData.SavedCharacters.Add(character.Name, character);
				}
				string text = DataObjects.yamlserializer.Serialize((object)characterSaveData);
				MetadataRegistry.Set(character.HostID, text);
			}
			else
			{
				DataObjects.CharacterSaveData characterSaveData2 = new DataObjects.CharacterSaveData
				{
					SavedCharacters = new Dictionary<string, DataObjects.Character> { { character.Name, character } }
				};
				string text2 = DataObjects.yamlserializer.Serialize((object)characterSaveData2);
				MetadataRegistry.Set(character.HostID, text2);
			}
		}

		internal static DataObjects.Character GetAccountCharacter(string accountID, string characterName)
		{
			InstanciateOrLinkMetadataRegistry();
			string @string = MetadataRegistry.GetString(accountID, (string)null);
			if (@string != null)
			{
				Logger.LogDebug("Character data found " + accountID + "-" + characterName + ".");
				DataObjects.CharacterSaveData characterSaveData = DataObjects.yamldeserializer.Deserialize<DataObjects.CharacterSaveData>(@string);
				if (characterSaveData.SavedCharacters.ContainsKey(characterName))
				{
					return characterSaveData.SavedCharacters[characterName];
				}
			}
			return null;
		}

		internal static DataObjects.CharacterSaveData GetAccountData(string accountID)
		{
			InstanciateOrLinkMetadataRegistry();
			string @string = MetadataRegistry.GetString(accountID, (string)null);
			if (@string != null)
			{
				return DataObjects.yamldeserializer.Deserialize<DataObjects.CharacterSaveData>(@string);
			}
			return null;
		}

		internal static void RegisterMetadataHolder()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			CustomPrefab val = new CustomPrefab(ValheimEnforcer.EmbeddedResourceBundle.LoadAsset<GameObject>("VE_METADATA"), false);
			PrefabManager.Instance.AddPrefab(val);
		}

		internal static void InstanciateOrLinkMetadataRegistry()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (MetadataRegistry != null)
			{
				return;
			}
			string text = default(string);
			if (ZoneSystem.instance.GetGlobalKey(DataObjects.CustomDataKey ?? "", ref text))
			{
				string[] array = text.Split(new char[1] { ' ' });
				if (array.Length == 2 && long.TryParse(array[0], out var result) && uint.TryParse(array[1], out var result2))
				{
					ZDOID val = default(ZDOID);
					((ZDOID)(ref val))..ctor(result, result2);
					MetadataRegistry = ZDOMan.instance.GetZDO(val);
				}
			}
			long sessionID = ZDOMan.GetSessionID();
			ZDO val2 = ZDOMan.instance.CreateNewZDO(Vector3.zero, 0);
			val2.Persistent = true;
			val2.SetOwner(sessionID);
			MetadataRegistry = val2;
			ZoneSystem.instance.SetGlobalKey($"{DataObjects.CustomDataKey} {((ZDOID)(ref MetadataRegistry.m_uid)).UserID} {((ZDOID)(ref MetadataRegistry.m_uid)).ID}");
			Logger.LogInfo($"Hooking up Metadata Registry. SessionID:{sessionID} ZDO:{val2.m_uid}");
			Logger.LogInfo($"Setting globalkey: {DataObjects.CustomDataKey} {((ZDOID)(ref MetadataRegistry.m_uid)).UserID} {((ZDOID)(ref MetadataRegistry.m_uid)).ID}");
		}

		internal static void UpdateAccountRegistry(string accountID, string chara = null)
		{
			InstanciateOrLinkMetadataRegistry();
			string @string = MetadataRegistry.GetString("VE_ACCOUNTS", (string)null);
			if (@string != null)
			{
				Dictionary<string, List<string>> dictionary = DataObjects.yamldeserializer.Deserialize<Dictionary<string, List<string>>>(@string);
				if (!dictionary.ContainsKey(accountID))
				{
					if (chara != null)
					{
						dictionary[accountID] = new List<string> { chara };
					}
					else
					{
						dictionary[accountID] = new List<string>();
					}
					string text = DataObjects.yamlserializer.Serialize((object)dictionary);
					MetadataRegistry.Set("VE_ACCOUNTS", text);
				}
			}
			else
			{
				List<string> list = new List<string>();
				if (chara != null)
				{
					list.Add(chara);
				}
				Dictionary<string, List<string>> dictionary2 = new Dictionary<string, List<string>> { { accountID, list } };
				string text2 = DataObjects.yamlserializer.Serialize((object)dictionary2);
				MetadataRegistry.Set("VE_ACCOUNTS", text2);
			}
		}

		internal static Dictionary<string, List<string>> GetAccountRegistry()
		{
			InstanciateOrLinkMetadataRegistry();
			string @string = MetadataRegistry.GetString("VE_ACCOUNTS", (string)null);
			if (@string != null)
			{
				return DataObjects.yamldeserializer.Deserialize<Dictionary<string, List<string>>>(@string);
			}
			return new Dictionary<string, List<string>>();
		}
	}
	internal static class ModManager
	{
		internal static class ValidateMods
		{
			[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
			public static class ZNet_OnNewConnection_Patch
			{
				[HarmonyPrefix]
				[HarmonyPriority(800)]
				private static void Prefix(ZNet __instance, ZNetPeer peer)
				{
					Logger.LogDebug("New Connection, register VE Mod Sync RPC.");
					peer.m_rpc.Register<ZPackage>("RPC_ReceiveModVersionData", (Action<ZRpc, ZPackage>)RPC_ReceiveModVersionData);
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake")]
		public static class ZNet_RPC_ClientHandshake_Patch
		{
			[HarmonyPrefix]
			[HarmonyPriority(800)]
			private static void Prefix(ZNet __instance, ZRpc rpc)
			{
				if (ZNetExtension.IsClientInstance(__instance))
				{
					Logger.LogDebug("Client sending mod version data to server");
					rpc.Invoke("RPC_ReceiveModVersionData", new object[1] { ModSettings.ToZPackage() });
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_ServerHandshake")]
		public static class ZNet_RPC_ServerHandshake_Patch
		{
			[HarmonyPrefix]
			[HarmonyPriority(800)]
			private static void Prefix(ZNet __instance, ZRpc rpc)
			{
				if (__instance.IsServer())
				{
					Logger.LogDebug("Server sending mod version data to client");
					rpc.Invoke("RPC_ReceiveModVersionData", new object[1] { ModSettings.ToZPackage() });
				}
			}
		}

		public class JotunnDetailDisconnectExpansion : MonoBehaviour
		{
			private GameObject ContentView;

			private Text HeaderText;

			private Text FooterText;

			private static string HeaderMessage = "";

			private static string FooterMessage = "";

			private bool textset;

			public void UpdateErrorText(string header, string footer)
			{
				Logger.LogDebug("Set Error results " + header + " " + footer);
				HeaderMessage = header;
				FooterMessage = footer;
				textset = false;
			}

			public void Update()
			{
				if ((Object)(object)GUIManager.CustomGUIFront == (Object)null)
				{
					return;
				}
				Transform val = GUIManager.CustomGUIFront.transform.Find("CompatibilityWindow(Clone)/Scroll View/Viewport/Content");
				if ((Object)(object)val == (Object)null)
				{
					textset = false;
				}
				else if (!textset)
				{
					((Component)GUIManager.CustomGUIFront.transform.Find("CompatibilityWindow(Clone)/Scroll View")).GetComponent<ScrollRect>().scrollSensitivity = 1000f;
					ContentView = ((Component)val).gameObject;
					Transform val2 = ContentView.transform.Find("Failed Connection Text");
					if ((Object)(object)val2 != (Object)null)
					{
						HeaderText = ((Component)val2).GetComponent<Text>();
					}
					else
					{
						Logger.LogDebug("Could not find HeaderText");
					}
					Transform val3 = ContentView.transform.Find("Error Messages Text");
					if ((Object)(object)val3 != (Object)null)
					{
						FooterText = ((Component)val3).GetComponent<Text>();
					}
					else
					{
						Logger.LogDebug("Could not find FooterText");
					}
					HeaderText.text = "<color=#FFA13C>Failed Connection:</color>\n" + HeaderMessage;
					FooterText.text = "<color=#FFA13C>Further Steps:</color>\n" + FooterMessage;
					Logger.LogDebug("Set error results. H:" + HeaderMessage + " F:" + FooterMessage);
					textset = true;
				}
			}
		}

		internal static Dictionary<string, BaseUnityPlugin> ActiveMods = new Dictionary<string, BaseUnityPlugin>();

		internal static DataObjects.Mods ModSettings { get; set; }

		internal static JotunnDetailDisconnectExpansion DetailsUpdater { get; set; }

		internal static void SetModsActive()
		{
			ActiveMods.Clear();
			ActiveMods = BepInExUtils.GetPlugins(true);
			ModSettings = new DataObjects.Mods();
			Logger.LogDebug($"Detected {ActiveMods.Keys.Count} mods.");
			LoadConfig(File.ReadAllText(ValConfig.ModsConfigFilePath));
			ModSettings.ActiveMods.Clear();
			foreach (KeyValuePair<string, BaseUnityPlugin> activeMod in ActiveMods)
			{
				if (!ModSettings.ActiveMods.ContainsKey(activeMod.Key))
				{
					Logger.LogDebug("Adding Mod " + activeMod.Key + " not found in modlist");
					ModSettings.ActiveMods.Add(activeMod.Key, new DataObjects.Mod
					{
						EnforceVersion = true,
						Version = activeMod.Value.Info.Metadata.Version.ToString(),
						PluginID = activeMod.Value.Info.Metadata.GUID,
						Name = activeMod.Value.Info.Metadata.Name
					});
				}
				Logger.LogDebug($"Found active mod: {activeMod.Key} v{activeMod.Value.Info.Metadata.Version}");
				string currentVersion = activeMod.Value.Info.Metadata.Version.ToString();
				if (ModSettings.RequiredMods.ContainsKey(activeMod.Key))
				{
					UpdateModVersionIfChanged(ModSettings.RequiredMods, activeMod.Key, currentVersion);
				}
				else if (ModSettings.AdminOnlyMods.ContainsKey(activeMod.Key))
				{
					UpdateModVersionIfChanged(ModSettings.AdminOnlyMods, activeMod.Key, currentVersion);
				}
				else if (ModSettings.OptionalMods.ContainsKey(activeMod.Key))
				{
					UpdateModVersionIfChanged(ModSettings.OptionalMods, activeMod.Key, currentVersion);
				}
				else if (ModSettings.ServerOnlyMods.ContainsKey(activeMod.Key))
				{
					UpdateModVersionIfChanged(ModSettings.ServerOnlyMods, activeMod.Key, currentVersion);
				}
				else if (ValConfig.AutoAddModsToRequired.Value)
				{
					Logger.LogDebug("Automatically adding " + activeMod.Key + " as a required mod.");
					ModSettings.RequiredMods.Add(activeMod.Key, new DataObjects.Mod
					{
						EnforceVersion = false,
						Version = activeMod.Value.Info.Metadata.Version.ToString(),
						PluginID = activeMod.Value.Info.Metadata.GUID,
						Name = activeMod.Value.Info.Metadata.Name
					});
				}
			}
			if (ValConfig.UpdateLoadedModsOnStartup.Value)
			{
				Logger.LogDebug("Updated Mods.yaml.");
				File.WriteAllText(ValConfig.ModsConfigFilePath, DataObjects.yamlserializer.Serialize((object)ModSettings));
			}
		}

		private static void UpdateModVersionIfChanged(Dictionary<string, DataObjects.Mod> modList, string key, string currentVersion)
		{
			if (modList[key].Version != currentVersion)
			{
				Logger.LogInfo("Updating version for " + key + ": " + modList[key].Version + " -> " + currentVersion);
				modList[key].Version = currentVersion;
			}
		}

		internal static void UpdateModSettingConfigs(string yamlstring)
		{
			try
			{
				ModSettings = DataObjects.yamldeserializer.Deserialize<DataObjects.Mods>(yamlstring);
			}
			catch
			{
				Logger.LogWarning("Failed to deserialize mod configurations.");
			}
		}

		internal static bool ValidateModlist(DataObjects.Mods CheckingMods, DataObjects.Mods AuthoratativeMods, bool isAdmin, out string summay, out string details)
		{
			summay = "";
			details = "";
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<string> list3 = AuthoratativeMods.RequiredMods.Keys.Distinct().ToList();
			Logger.LogDebug($"Validating modlist of {CheckingMods.ActiveMods.Count} mods isAdmin? {isAdmin}");
			foreach (KeyValuePair<string, DataObjects.Mod> activeMod in CheckingMods.ActiveMods)
			{
				list3.Remove(activeMod.Key);
				if (AuthoratativeMods.RequiredMods.ContainsKey(activeMod.Key))
				{
					if (!AuthoratativeMods.RequiredMods[activeMod.Key].EnforceVersion || AuthoratativeMods.RequiredMods[activeMod.Key].Version == activeMod.Value.Version)
					{
						continue;
					}
					list2.Add(activeMod.Key);
				}
				if (AuthoratativeMods.AdminOnlyMods.ContainsKey(activeMod.Key))
				{
					if (!isAdmin || !AuthoratativeMods.AdminOnlyMods[activeMod.Key].EnforceVersion || AuthoratativeMods.AdminOnlyMods[activeMod.Key].Version == activeMod.Value.Version)
					{
						continue;
					}
					list2.Add(activeMod.Key);
				}
				if (AuthoratativeMods.OptionalMods.ContainsKey(activeMod.Key))
				{
					if (!AuthoratativeMods.OptionalMods[activeMod.Key].EnforceVersion || AuthoratativeMods.OptionalMods[activeMod.Key].Version == activeMod.Value.Version)
					{
						continue;
					}
					list2.Add(activeMod.Key);
				}
				list.Add(activeMod.Key);
			}
			if (list2.Count > 0)
			{
				Logger.LogWarning("Mods version mismatch with the server found:");
				summay = "A Mod mismatch was detected. Ensure you have the correct versions and are only using allowed mods.";
			}
			if (list3.Count > 0)
			{
				string text = "\nMissing required mods: " + string.Join(", ", list3);
				summay += text;
				Logger.LogWarning(text);
			}
			if (list.Count > 0)
			{
				string text2 = "\nNon-allowed mods found: " + string.Join(", ", list);
				summay += text2;
				Logger.LogWarning(text2);
			}
			if (list2.Count > 0 || list3.Count > 0 || list.Count > 0)
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("\n<b>ValheimEnforcer - Mod Validation Failed</b>");
				if (list2.Count > 0)
				{
					stringBuilder.AppendLine("\n<b>Version Mismatches:</b>");
					foreach (string item in list2)
					{
						stringBuilder.AppendLine("  • " + item);
					}
				}
				if (list3.Count > 0)
				{
					stringBuilder.AppendLine("\n<b>Missing Required Mods:</b>");
					foreach (string item2 in list3)
					{
						stringBuilder.AppendLine("  • " + item2);
					}
				}
				if (list.Count > 0)
				{
					stringBuilder.AppendLine("\n<b>Non-Allowed Mods:</b>");
					foreach (string item3 in list)
					{
						stringBuilder.AppendLine("  • " + item3);
					}
				}
				string text3 = stringBuilder.ToString();
				details = text3;
				return false;
			}
			Logger.LogInfo("Client mod list validated successfully.");
			return true;
		}

		internal static void LoadConfig(string yaml)
		{
			ModSettings = DataObjects.yamldeserializer.Deserialize<DataObjects.Mods>(yaml);
		}

		internal static string GetDefaultConfig()
		{
			if (ModSettings != null)
			{
				return DataObjects.yamlserializer.Serialize((object)ModSettings);
			}
			return DataObjects.yamlserializer.Serialize((object)new DataObjects.Mods());
		}

		private static void RPC_ReceiveModVersionData(ZRpc sender, ZPackage data)
		{
			Logger.LogDebug("Received mod version data from " + sender.m_socket.GetEndPointString());
			string endPointString = sender.m_socket.GetEndPointString();
			if (!ZNet.instance.IsServer())
			{
				DataObjects.Mods mods = new DataObjects.Mods().FromZPackage(data);
				Logger.LogDebug($"Client received server mod data: Required: {mods.RequiredMods.Count}, Optional: {mods.OptionalMods.Count}, AdminOnly: {mods.AdminOnlyMods.Count} mods");
				if (!ValidateModlist(ModSettings, mods, SynchronizationManager.Instance.PlayerIsAdmin, out var summay, out var details))
				{
					DetailsUpdater.UpdateErrorText(summay, details);
					Logger.LogWarning("Mod compatibility check failed for client.");
				}
				return;
			}
			DataObjects.Mods mods2 = new DataObjects.Mods().FromZPackage(data);
			bool flag = ZNet.instance.IsAdmin(sender.m_socket.GetHostName());
			Logger.LogDebug($"Server received server mod data from {endPointString} Admin?{flag}: Required: {mods2.RequiredMods.Count}, Optional: {mods2.OptionalMods.Count}, AdminOnly: {mods2.AdminOnlyMods.Count} mods");
			if (!ValidateModlist(mods2, ModSettings, flag, out var summay2, out var _))
			{
				Logger.LogWarning("Mod compatibility check failed for client at " + endPointString + "\n" + summay2);
				sender.Invoke("Error", new object[1] { 3 });
			}
		}

		internal static void AddErrorMessageDetailsForMenu()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name.Equals("start"))
			{
				DetailsUpdater = GUIManager.CustomGUIFront.AddComponent<JotunnDetailDisconnectExpansion>();
			}
		}
	}
}
namespace ValheimEnforcer.common
{
	internal static class DataObjects
	{
		public class Mod
		{
			public string PluginID { get; set; }

			public string Version { get; set; }

			public string Name { get; set; }

			[DefaultValue(false)]
			public bool EnforceVersion { get; set; }

			[DefaultValue("Minor")]
			public string VersionStrictness { get; set; } = "Minor";

		}

		public class Mods
		{
			public Dictionary<string, Mod> ActiveMods { get; set; } = new Dictionary<string, Mod>();


			public Dictionary<string, Mod> RequiredMods { get; set; } = new Dictionary<string, Mod>();


			public Dictionary<string, Mod> OptionalMods { get; set; } = new Dictionary<string, Mod>();


			public Dictionary<string, Mod> AdminOnlyMods { get; set; } = new Dictionary<string, Mod>();


			public Dictionary<string, Mod> ServerOnlyMods { get; set; } = new Dictionary<string, Mod>();


			public ZPackage ToZPackage()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				string text = yamlserializer.Serialize((object)this);
				ZPackage val = new ZPackage();
				val.Write(text);
				return val;
			}

			public Mods FromZPackage(ZPackage incoming)
			{
				Mods mods = yamldeserializer.Deserialize<Mods>(incoming.ReadString());
				ActiveMods = mods.ActiveMods;
				RequiredMods = mods.RequiredMods;
				OptionalMods = mods.OptionalMods;
				AdminOnlyMods = mods.AdminOnlyMods;
				ServerOnlyMods = mods.ServerOnlyMods;
				return mods;
			}
		}

		public class ItemValidatorResult
		{
			public PackedItem SavedItemRef { get; set; }

			public ItemData CharacterItemRef { get; set; }

			[DefaultValue(false)]
			public bool Validated { get; set; }

			public string ValidationMessage { get; set; }

			public ValidationSummary ValidationResult { get; set; }
		}

		public class ValidationSummary
		{
			[DefaultValue(false)]
			public bool NameAndStackMatch { get; set; }

			[DefaultValue(false)]
			public bool QualityMatch { get; set; }

			[DefaultValue(false)]
			public bool CustomDataMatch { get; set; }

			[DefaultValue(false)]
			public bool DurabilityMatch { get; set; }

			public bool IsValid()
			{
				if (NameAndStackMatch && QualityMatch && CustomDataMatch)
				{
					return DurabilityMatch;
				}
				return false;
			}
		}

		[Serializable]
		public class PackedItem
		{
			public string prefabName { get; set; }

			public int m_stack { get; set; }

			public float m_durability { get; set; }

			public int m_quality { get; set; }

			[DefaultValue(0)]
			public int m_variant { get; set; }

			[DefaultValue(0)]
			public int m_worldlevel { get; set; }

			[DefaultValue(0L)]
			public long m_crafterID { get; set; }

			[DefaultValue("")]
			public string m_crafterName { get; set; }

			public Dictionary<string, string> m_customdata { get; set; }

			[DefaultValue(false)]
			public bool m_equipped { get; set; }

			public Vector2i m_gridpos { get; set; }

			public void AddToInventory(Inventory inv, bool use_position)
			{
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				ZNetView.m_forceDisableInit = true;
				GameObject obj = Object.Instantiate<GameObject>(Cache.GetPrefab<GameObject>(prefabName));
				ZNetView.m_forceDisableInit = false;
				ItemDrop component = obj.GetComponent<ItemDrop>();
				component.m_itemData.m_stack = m_stack;
				component.m_itemData.m_durability = m_durability;
				if (m_quality == 0)
				{
					component.m_itemData.m_quality = 1;
				}
				else
				{
					component.m_itemData.m_quality = m_quality;
				}
				component.m_itemData.m_variant = m_variant;
				component.m_itemData.m_worldLevel = m_worldlevel;
				component.m_itemData.m_crafterID = m_crafterID;
				if (m_crafterName == null)
				{
					component.m_itemData.m_crafterName = "";
				}
				else
				{
					component.m_itemData.m_crafterName = m_crafterName;
				}
				component.m_itemData.m_customData = m_customdata;
				component.m_itemData.m_pickedUp = true;
				if (use_position)
				{
					component.m_itemData.m_gridPos = m_gridpos;
					inv.AddItem(component.m_itemData, component.m_itemData.m_stack, m_gridpos.x, m_gridpos.y);
				}
				else
				{
					inv.AddItem(component.m_itemData);
				}
				Object.Destroy((Object)(object)obj);
			}
		}

		public class CharacterSaveData
		{
			public Dictionary<string, Character> SavedCharacters = new Dictionary<string, Character>();
		}

		public class AccountEntries
		{
			public Dictionary<string, List<string>> AccountCharacterEntries = new Dictionary<string, List<string>>();
		}

		public class Character
		{
			public string Name { get; set; }

			public string HostID { get; set; }

			public Dictionary<SkillType, float> SkillLevels { get; set; } = new Dictionary<SkillType, float>();


			public Dictionary<string, string> PlayerCustomData { get; set; } = new Dictionary<string, string>();


			public List<PackedItem> PlayerItems { get; set; } = new List<PackedItem>();


			public List<PackedItem> ConfiscatedItems { get; set; } = new List<PackedItem>();


			public void AddItemToPlayerItems(ItemData item)
			{
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				if (PlayerItems == null)
				{
					PlayerItems = new List<PackedItem>();
				}
				Logger.LogDebug($"Adding saved item {((Object)item.m_dropPrefab).name} with quality - {item.m_quality}");
				PlayerItems.Add(new PackedItem
				{
					prefabName = ((Object)item.m_dropPrefab).name,
					m_stack = item.m_stack,
					m_durability = Mathf.Clamp(item.m_durability, 0f, item.m_shared.m_maxDurability),
					m_quality = item.m_quality,
					m_variant = item.m_variant,
					m_worldlevel = item.m_worldLevel,
					m_crafterID = item.m_crafterID,
					m_crafterName = item.m_crafterName,
					m_customdata = item.m_customData,
					m_equipped = item.m_equipped,
					m_gridpos = item.m_gridPos
				});
			}

			public void AddConfiscatedItem(ItemData item)
			{
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				if (ConfiscatedItems == null)
				{
					ConfiscatedItems = new List<PackedItem>();
				}
				ConfiscatedItems.Add(new PackedItem
				{
					prefabName = ((Object)item.m_dropPrefab).name,
					m_stack = item.m_stack,
					m_durability = item.m_durability,
					m_quality = item.m_quality,
					m_variant = item.m_variant,
					m_worldlevel = item.m_worldLevel,
					m_crafterID = item.m_crafterID,
					m_crafterName = item.m_crafterName,
					m_customdata = item.m_customData,
					m_equipped = item.m_equipped,
					m_gridpos = item.m_gridPos
				});
			}
		}

		public static IDeserializer yamldeserializer = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();

		public static ISerializer yamlserializer = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).ConfigureDefaultValuesHandling((DefaultValuesHandling)2).Build();

		public static readonly string CustomDataKey = "VE_CUSTOM_DATA";
	}
}

plugins/YamlDotNet.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.CodeAnalysis;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("16.0.0.0")]
[assembly: AssemblyInformationalVersion("16.0.0")]
[assembly: AssemblyTitle("YamlDotNet")]
[assembly: AssemblyDescription("The YamlDotNet library.")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("YamlDotNet")]
[assembly: AssemblyCopyright("Copyright (c) Antoine Aubry and contributors 2008 - 2019")]
[assembly: AssemblyTrademark("")]
[assembly: CLSCompliant(true)]
[assembly: InternalsVisibleTo("YamlDotNet.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010065e52a453dde5c5b4be5bbe2205755727fce80244b79b894faf8793d80f7db9a96d360b51c220782db32aacee4cb5b8a91bee33aeec700e1f21895c4baadef501eeeac609220d1651603b378173811ee5bb6a002df973d38821bd2fef820c00c174a69faec326a1983b570f07ec66147026b9c8753465de3a8d0c44b613b02af")]
[assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")]
[assembly: AssemblyVersion("16.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace YamlDotNet
{
	internal sealed class CultureInfoAdapter : CultureInfo
	{
		private readonly IFormatProvider provider;

		public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider)
			: base(baseCulture.Name)
		{
			this.provider = provider;
		}

		public override object? GetFormat(Type formatType)
		{
			return provider.GetFormat(formatType);
		}
	}
	internal static class PropertyInfoExtensions
	{
		public static object? ReadValue(this PropertyInfo property, object target)
		{
			return property.GetValue(target, null);
		}
	}
	internal static class ReflectionExtensions
	{
		private static readonly Func<PropertyInfo, bool> IsInstance = (PropertyInfo property) => !(property.GetMethod ?? property.SetMethod).IsStatic;

		private static readonly Func<PropertyInfo, bool> IsInstancePublic = (PropertyInfo property) => IsInstance(property) && (property.GetMethod ?? property.SetMethod).IsPublic;

		private static readonly ConcurrentDictionary<Type, bool> typesHaveNullContext = new ConcurrentDictionary<Type, bool>();

		public static Type? BaseType(this Type type)
		{
			return type.GetTypeInfo().BaseType;
		}

		public static bool IsValueType(this Type type)
		{
			return type.GetTypeInfo().IsValueType;
		}

		public static bool IsGenericType(this Type type)
		{
			return type.GetTypeInfo().IsGenericType;
		}

		public static bool IsGenericTypeDefinition(this Type type)
		{
			return type.GetTypeInfo().IsGenericTypeDefinition;
		}

		public static bool IsInterface(this Type type)
		{
			return type.GetTypeInfo().IsInterface;
		}

		public static bool IsEnum(this Type type)
		{
			return type.GetTypeInfo().IsEnum;
		}

		public static bool IsRequired(this MemberInfo member)
		{
			return member.GetCustomAttributes(inherit: true).Any((object x) => x.GetType().FullName == "System.Runtime.CompilerServices.RequiredMemberAttribute");
		}

		public static bool HasDefaultConstructor(this Type type, bool allowPrivateConstructors)
		{
			BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
			if (allowPrivateConstructors)
			{
				bindingFlags |= BindingFlags.NonPublic;
			}
			if (!type.IsValueType)
			{
				return type.GetConstructor(bindingFlags, null, Type.EmptyTypes, null) != null;
			}
			return true;
		}

		public static bool IsAssignableFrom(this Type type, Type source)
		{
			return type.IsAssignableFrom(source.GetTypeInfo());
		}

		public static bool IsAssignableFrom(this Type type, TypeInfo source)
		{
			return type.GetTypeInfo().IsAssignableFrom(source);
		}

		public static TypeCode GetTypeCode(this Type type)
		{
			if (type.IsEnum())
			{
				type = Enum.GetUnderlyingType(type);
			}
			if (type == typeof(bool))
			{
				return TypeCode.Boolean;
			}
			if (type == typeof(char))
			{
				return TypeCode.Char;
			}
			if (type == typeof(sbyte))
			{
				return TypeCode.SByte;
			}
			if (type == typeof(byte))
			{
				return TypeCode.Byte;
			}
			if (type == typeof(short))
			{
				return TypeCode.Int16;
			}
			if (type == typeof(ushort))
			{
				return TypeCode.UInt16;
			}
			if (type == typeof(int))
			{
				return TypeCode.Int32;
			}
			if (type == typeof(uint))
			{
				return TypeCode.UInt32;
			}
			if (type == typeof(long))
			{
				return TypeCode.Int64;
			}
			if (type == typeof(ulong))
			{
				return TypeCode.UInt64;
			}
			if (type == typeof(float))
			{
				return TypeCode.Single;
			}
			if (type == typeof(double))
			{
				return TypeCode.Double;
			}
			if (type == typeof(decimal))
			{
				return TypeCode.Decimal;
			}
			if (type == typeof(DateTime))
			{
				return TypeCode.DateTime;
			}
			if (type == typeof(string))
			{
				return TypeCode.String;
			}
			return TypeCode.Object;
		}

		public static bool IsDbNull(this object value)
		{
			return value?.GetType()?.FullName == "System.DBNull";
		}

		public static Type[] GetGenericArguments(this Type type)
		{
			return type.GetTypeInfo().GenericTypeArguments;
		}

		public static PropertyInfo? GetPublicProperty(this Type type, string name)
		{
			return type.GetRuntimeProperty(name);
		}

		public static FieldInfo? GetPublicStaticField(this Type type, string name)
		{
			return type.GetRuntimeField(name);
		}

		public static IEnumerable<PropertyInfo> GetProperties(this Type type, bool includeNonPublic)
		{
			Func<PropertyInfo, bool> predicate = (includeNonPublic ? IsInstance : IsInstancePublic);
			if (!type.IsInterface())
			{
				return type.GetRuntimeProperties().Where(predicate);
			}
			return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetRuntimeProperties().Where(predicate));
		}

		public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type)
		{
			return type.GetProperties(includeNonPublic: false);
		}

		public static IEnumerable<FieldInfo> GetPublicFields(this Type type)
		{
			return from f in type.GetRuntimeFields()
				where !f.IsStatic && f.IsPublic
				select f;
		}

		public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type)
		{
			return from m in type.GetRuntimeMethods()
				where m.IsPublic && m.IsStatic
				select m;
		}

		public static MethodInfo GetPrivateStaticMethod(this Type type, string name)
		{
			string name2 = name;
			return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => !m.IsPublic && m.IsStatic && m.Name.Equals(name2)) ?? throw new MissingMethodException("Expected to find a method named '" + name2 + "' in '" + type.FullName + "'.");
		}

		public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes)
		{
			string name2 = name;
			Type[] parameterTypes2 = parameterTypes;
			return type.GetRuntimeMethods().FirstOrDefault(delegate(MethodInfo m)
			{
				if (m.IsPublic && m.IsStatic && m.Name.Equals(name2))
				{
					ParameterInfo[] parameters = m.GetParameters();
					if (parameters.Length == parameterTypes2.Length)
					{
						return parameters.Zip(parameterTypes2, (ParameterInfo pi, Type pt) => pi.ParameterType == pt).All((bool r) => r);
					}
					return false;
				}
				return false;
			});
		}

		public static MethodInfo? GetPublicInstanceMethod(this Type type, string name)
		{
			string name2 = name;
			return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => m.IsPublic && !m.IsStatic && m.Name.Equals(name2));
		}

		public static MethodInfo? GetGetMethod(this PropertyInfo property, bool nonPublic)
		{
			MethodInfo methodInfo = property.GetMethod;
			if (!nonPublic && !methodInfo.IsPublic)
			{
				methodInfo = null;
			}
			return methodInfo;
		}

		public static MethodInfo? GetSetMethod(this PropertyInfo property)
		{
			return property.SetMethod;
		}

		public static IEnumerable<Type> GetInterfaces(this Type type)
		{
			return type.GetTypeInfo().ImplementedInterfaces;
		}

		public static bool IsInstanceOf(this Type type, object o)
		{
			if (!(o.GetType() == type))
			{
				return o.GetType().GetTypeInfo().IsSubclassOf(type);
			}
			return true;
		}

		public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo member)
		{
			List<Attribute> list = new List<Attribute>();
			Type type = member.DeclaringType;
			string name = member.Name;
			while (type != null)
			{
				PropertyInfo publicProperty = type.GetPublicProperty(name);
				if (publicProperty != null)
				{
					list.AddRange(publicProperty.GetCustomAttributes(typeof(TAttribute)));
				}
				type = type.BaseType();
			}
			return list.ToArray();
		}

		public static bool AcceptsNull(this MemberInfo member)
		{
			bool result = true;
			if (typesHaveNullContext.GetOrAdd(member.DeclaringType, delegate(Type t)
			{
				object[] customAttributes2 = t.GetCustomAttributes(inherit: true);
				return customAttributes2.Any((object x) => x.GetType().FullName == "System.Runtime.CompilerServices.NullableContextAttribute");
			}))
			{
				object[] customAttributes = member.GetCustomAttributes(inherit: true);
				result = customAttributes.Any((object x) => x.GetType().FullName == "System.Runtime.CompilerServices.NullableAttribute");
			}
			return result;
		}
	}
	internal static class StandardRegexOptions
	{
		public const RegexOptions Compiled = RegexOptions.Compiled;
	}
}
namespace YamlDotNet.Serialization
{
	public abstract class BuilderSkeleton<TBuilder> where TBuilder : BuilderSkeleton<TBuilder>
	{
		internal INamingConvention namingConvention = NullNamingConvention.Instance;

		internal INamingConvention enumNamingConvention = NullNamingConvention.Instance;

		internal ITypeResolver typeResolver;

		internal readonly YamlAttributeOverrides overrides;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		internal bool ignoreFields;

		internal bool includeNonPublicProperties;

		internal Settings settings;

		internal YamlFormatter yamlFormatter = YamlFormatter.Default;

		protected abstract TBuilder Self { get; }

		internal BuilderSkeleton(ITypeResolver typeResolver)
		{
			overrides = new YamlAttributeOverrides();
			typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter>
			{
				{
					typeof(YamlDotNet.Serialization.Converters.GuidConverter),
					(Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false)
				},
				{
					typeof(SystemTypeConverter),
					(Nothing _) => new SystemTypeConverter()
				}
			};
			typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>();
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			settings = new Settings();
		}

		public TBuilder IgnoreFields()
		{
			ignoreFields = true;
			return Self;
		}

		public TBuilder IncludeNonPublicProperties()
		{
			includeNonPublicProperties = true;
			return Self;
		}

		public TBuilder EnablePrivateConstructors()
		{
			settings.AllowPrivateConstructors = true;
			return Self;
		}

		public TBuilder WithNamingConvention(INamingConvention namingConvention)
		{
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
			return Self;
		}

		public TBuilder WithEnumNamingConvention(INamingConvention enumNamingConvention)
		{
			this.enumNamingConvention = enumNamingConvention;
			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;
		}

		public TBuilder WithYamlFormatter(YamlFormatter formatter)
		{
			yamlFormatter = formatter ?? throw new ArgumentNullException("formatter");
			return Self;
		}

		protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
		{
			return typeConverterFactories.BuildComponentList();
		}
	}
	public delegate TComponent WrapperFactory<TComponentBase, TComponent>(TComponentBase wrapped) where TComponent : TComponentBase;
	public delegate TComponent WrapperFactory<TArgument, TComponentBase, TComponent>(TComponentBase wrapped, TArgument argument) where TComponent : TComponentBase;
	[Flags]
	public enum DefaultValuesHandling
	{
		Preserve = 0,
		OmitNull = 1,
		OmitDefaults = 2,
		OmitEmptyCollections = 4
	}
	public sealed class Deserializer : IDeserializer
	{
		private readonly IValueDeserializer valueDeserializer;

		public Deserializer()
			: this(new DeserializerBuilder().BuildValueDeserializer())
		{
		}

		private Deserializer(IValueDeserializer valueDeserializer)
		{
			this.valueDeserializer = valueDeserializer ?? throw new ArgumentNullException("valueDeserializer");
		}

		public static Deserializer FromValueDeserializer(IValueDeserializer valueDeserializer)
		{
			return new Deserializer(valueDeserializer);
		}

		public T Deserialize<T>(string input)
		{
			using StringReader input2 = new StringReader(input);
			return Deserialize<T>(input2);
		}

		public T Deserialize<T>(TextReader input)
		{
			return Deserialize<T>(new Parser(input));
		}

		public T Deserialize<T>(IParser parser)
		{
			return (T)Deserialize(parser, typeof(T));
		}

		public object? Deserialize(string input)
		{
			return Deserialize(input, typeof(object));
		}

		public object? Deserialize(TextReader input)
		{
			return Deserialize(input, typeof(object));
		}

		public object? Deserialize(IParser parser)
		{
			return Deserialize(parser, typeof(object));
		}

		public object? Deserialize(string input, Type type)
		{
			using StringReader input2 = new StringReader(input);
			return Deserialize(input2, type);
		}

		public object? Deserialize(TextReader input, Type type)
		{
			return Deserialize(new Parser(input), type);
		}

		public object? Deserialize(IParser parser, Type type)
		{
			if (parser == null)
			{
				throw new ArgumentNullException("parser");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			YamlDotNet.Core.Events.StreamStart @event;
			bool flag = parser.TryConsume<YamlDotNet.Core.Events.StreamStart>(out @event);
			YamlDotNet.Core.Events.DocumentStart event2;
			bool flag2 = parser.TryConsume<YamlDotNet.Core.Events.DocumentStart>(out event2);
			object result = null;
			if (!parser.Accept<YamlDotNet.Core.Events.DocumentEnd>(out var _) && !parser.Accept<YamlDotNet.Core.Events.StreamEnd>(out var _))
			{
				using SerializerState serializerState = new SerializerState();
				result = valueDeserializer.DeserializeValue(parser, type, serializerState, valueDeserializer);
				serializerState.OnDeserialization();
			}
			if (flag2)
			{
				parser.Consume<YamlDotNet.Core.Events.DocumentEnd>();
			}
			if (flag)
			{
				parser.Consume<YamlDotNet.Core.Events.StreamEnd>();
			}
			return result;
		}
	}
	public sealed class DeserializerBuilder : BuilderSkeleton<DeserializerBuilder>
	{
		private Lazy<IObjectFactory> objectFactory;

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<TagName, Type> tagMappings;

		private readonly Dictionary<Type, Type> typeMappings;

		private readonly ITypeConverter typeConverter;

		private bool ignoreUnmatched;

		private bool duplicateKeyChecking;

		private bool attemptUnknownTypeDeserialization;

		private bool enforceNullability;

		private bool caseInsensitivePropertyMatching;

		private bool enforceRequiredProperties;

		protected override DeserializerBuilder Self => this;

		public DeserializerBuilder()
			: base((ITypeResolver)new StaticTypeResolver())
		{
			typeMappings = new Dictionary<Type, Type>();
			objectFactory = new Lazy<IObjectFactory>(() => new DefaultObjectFactory(typeMappings, settings), isThreadSafe: true);
			tagMappings = new Dictionary<TagName, Type>
			{
				{
					FailsafeSchema.Tags.Map,
					typeof(Dictionary<object, object>)
				},
				{
					FailsafeSchema.Tags.Str,
					typeof(string)
				},
				{
					JsonSchema.Tags.Bool,
					typeof(bool)
				},
				{
					JsonSchema.Tags.Float,
					typeof(double)
				},
				{
					JsonSchema.Tags.Int,
					typeof(int)
				},
				{
					DefaultSchema.Tags.Timestamp,
					typeof(DateTime)
				}
			};
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone()));
			typeInspectorFactories.Add(typeof(ReadableAndWritablePropertiesTypeInspector), (ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner));
			nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer>
			{
				{
					typeof(YamlConvertibleNodeDeserializer),
					(Nothing _) => new YamlConvertibleNodeDeserializer(objectFactory.Value)
				},
				{
					typeof(YamlSerializableNodeDeserializer),
					(Nothing _) => new YamlSerializableNodeDeserializer(objectFactory.Value)
				},
				{
					typeof(TypeConverterNodeDeserializer),
					(Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters())
				},
				{
					typeof(NullNodeDeserializer),
					(Nothing _) => new NullNodeDeserializer()
				},
				{
					typeof(ScalarNodeDeserializer),
					(Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, BuildTypeInspector(), yamlFormatter, enumNamingConvention)
				},
				{
					typeof(ArrayNodeDeserializer),
					(Nothing _) => new ArrayNodeDeserializer(enumNamingConvention, BuildTypeInspector())
				},
				{
					typeof(DictionaryNodeDeserializer),
					(Nothing _) => new DictionaryNodeDeserializer(objectFactory.Value, duplicateKeyChecking)
				},
				{
					typeof(CollectionNodeDeserializer),
					(Nothing _) => new CollectionNodeDeserializer(objectFactory.Value, enumNamingConvention, BuildTypeInspector())
				},
				{
					typeof(EnumerableNodeDeserializer),
					(Nothing _) => new EnumerableNodeDeserializer()
				},
				{
					typeof(ObjectNodeDeserializer),
					(Nothing _) => new ObjectNodeDeserializer(objectFactory.Value, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter, enumNamingConvention, enforceNullability, caseInsensitivePropertyMatching, enforceRequiredProperties, BuildTypeConverters())
				},
				{
					typeof(FsharpListNodeDeserializer),
					(Nothing _) => new FsharpListNodeDeserializer(BuildTypeInspector(), enumNamingConvention)
				}
			};
			nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver>
			{
				{
					typeof(MappingNodeTypeResolver),
					(Nothing _) => new MappingNodeTypeResolver(typeMappings)
				},
				{
					typeof(YamlConvertibleTypeResolver),
					(Nothing _) => new YamlConvertibleTypeResolver()
				},
				{
					typeof(YamlSerializableTypeResolver),
					(Nothing _) => new YamlSerializableTypeResolver()
				},
				{
					typeof(TagNodeTypeResolver),
					(Nothing _) => new TagNodeTypeResolver(tagMappings)
				},
				{
					typeof(PreventUnknownTagsNodeTypeResolver),
					(Nothing _) => new PreventUnknownTagsNodeTypeResolver()
				},
				{
					typeof(DefaultContainersNodeTypeResolver),
					(Nothing _) => new DefaultContainersNodeTypeResolver()
				}
			};
			typeConverter = new ReflectionTypeConverter();
		}

		public ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = new WritablePropertiesTypeInspector(typeResolver, includeNonPublicProperties);
			if (!ignoreFields)
			{
				typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector);
			}
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}

		public DeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization()
		{
			attemptUnknownTypeDeserialization = true;
			return this;
		}

		public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory)
		{
			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 WithTypeDiscriminatingNodeDeserializer(Action<ITypeDiscriminatingNodeDeserializerOptions> configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1)
		{
			TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions();
			configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions);
			TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength);
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
			{
				s.Before<DictionaryNodeDeserializer>();
			});
		}

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver)
		{
			return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w)
			{
				w.OnTop();
			});
		}

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where)
		{
			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 WithCaseInsensitivePropertyMatching()
		{
			caseInsensitivePropertyMatching = true;
			return this;
		}

		public DeserializerBuilder WithEnforceNullability()
		{
			enforceNullability = true;
			return this;
		}

		public DeserializerBuilder WithEnforceRequiredMembers()
		{
			enforceRequiredProperties = true;
			return this;
		}

		public DeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver
		{
			return WithoutNodeTypeResolver(typeof(TNodeTypeResolver));
		}

		public DeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType)
		{
			if (nodeTypeResolverType == null)
			{
				throw new ArgumentNullException("nodeTypeResolverType");
			}
			nodeTypeResolverFactories.Remove(nodeTypeResolverType);
			return this;
		}

		public override DeserializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(tag, out Type value))
			{
				throw new ArgumentException($"Type already has a registered type '{value.FullName}' for tag '{tag}'", "tag");
			}
			tagMappings.Add(tag, type);
			return this;
		}

		public DeserializerBuilder WithTypeMapping<TInterface, TConcrete>() where TConcrete : TInterface
		{
			Type typeFromHandle = typeof(TInterface);
			Type typeFromHandle2 = typeof(TConcrete);
			if (!typeFromHandle.IsAssignableFrom(typeFromHandle2))
			{
				throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'.");
			}
			if (typeMappings.ContainsKey(typeFromHandle))
			{
				typeMappings[typeFromHandle] = typeFromHandle2;
			}
			else
			{
				typeMappings.Add(typeFromHandle, typeFromHandle2);
			}
			return this;
		}

		public DeserializerBuilder WithoutTagMapping(TagName tag)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (!tagMappings.Remove(tag))
			{
				throw new KeyNotFoundException($"Tag '{tag}' is not registered");
			}
			return this;
		}

		public DeserializerBuilder IgnoreUnmatchedProperties()
		{
			ignoreUnmatched = true;
			return this;
		}

		public DeserializerBuilder WithDuplicateKeyChecking()
		{
			duplicateKeyChecking = true;
			return this;
		}

		public IDeserializer Build()
		{
			return Deserializer.FromValueDeserializer(BuildValueDeserializer());
		}

		public IValueDeserializer BuildValueDeserializer()
		{
			return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter, enumNamingConvention, BuildTypeInspector()));
		}
	}
	public sealed class EmissionPhaseObjectGraphVisitorArgs
	{
		private readonly IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors;

		public IObjectGraphVisitor<IEmitter> InnerVisitor { get; private set; }

		public IEventEmitter EventEmitter { get; private set; }

		public ObjectSerializer NestedObjectSerializer { get; private set; }

		public IEnumerable<IYamlTypeConverter> TypeConverters { get; private set; }

		public EmissionPhaseObjectGraphVisitorArgs(IObjectGraphVisitor<IEmitter> innerVisitor, IEventEmitter eventEmitter, IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors, IEnumerable<IYamlTypeConverter> typeConverters, ObjectSerializer nestedObjectSerializer)
		{
			InnerVisitor = innerVisitor ?? throw new ArgumentNullException("innerVisitor");
			EventEmitter = eventEmitter ?? throw new ArgumentNullException("eventEmitter");
			this.preProcessingPhaseVisitors = preProcessingPhaseVisitors ?? throw new ArgumentNullException("preProcessingPhaseVisitors");
			TypeConverters = typeConverters ?? throw new ArgumentNullException("typeConverters");
			NestedObjectSerializer = nestedObjectSerializer ?? throw new ArgumentNullException("nestedObjectSerializer");
		}

		public T GetPreProcessingPhaseObjectGraphVisitor<T>() where T : IObjectGraphVisitor<Nothing>
		{
			return preProcessingPhaseVisitors.OfType<T>().Single();
		}
	}
	public abstract class EventInfo
	{
		public IObjectDescriptor Source { get; }

		protected EventInfo(IObjectDescriptor source)
		{
			Source = source ?? throw new ArgumentNullException("source");
		}
	}
	public class AliasEventInfo : EventInfo
	{
		public AnchorName Alias { get; }

		public bool NeedsExpansion { get; set; }

		public AliasEventInfo(IObjectDescriptor source, AnchorName alias)
			: base(source)
		{
			if (alias.IsEmpty)
			{
				throw new ArgumentNullException("alias");
			}
			Alias = alias;
		}
	}
	public class ObjectEventInfo : EventInfo
	{
		public AnchorName Anchor { get; set; }

		public TagName Tag { get; set; }

		protected ObjectEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class ScalarEventInfo : ObjectEventInfo
	{
		public string RenderedValue { get; set; }

		public ScalarStyle Style { get; set; }

		public bool IsPlainImplicit { get; set; }

		public bool IsQuotedImplicit { get; set; }

		public ScalarEventInfo(IObjectDescriptor source)
			: base(source)
		{
			Style = source.ScalarStyle;
			RenderedValue = string.Empty;
		}
	}
	public sealed class MappingStartEventInfo : ObjectEventInfo
	{
		public bool IsImplicit { get; set; }

		public MappingStyle Style { get; set; }

		public MappingStartEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class MappingEndEventInfo : EventInfo
	{
		public MappingEndEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class SequenceStartEventInfo : ObjectEventInfo
	{
		public bool IsImplicit { get; set; }

		public SequenceStyle Style { get; set; }

		public SequenceStartEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class SequenceEndEventInfo : EventInfo
	{
		public SequenceEndEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public interface IAliasProvider
	{
		AnchorName GetAlias(object target);
	}
	public interface IDeserializer
	{
		T Deserialize<T>(string input);

		T Deserialize<T>(TextReader input);

		T Deserialize<T>(IParser parser);

		object? Deserialize(string input);

		object? Deserialize(TextReader input);

		object? Deserialize(IParser parser);

		object? Deserialize(string input, Type type);

		object? Deserialize(TextReader input, Type type);

		object? Deserialize(IParser parser, Type type);
	}
	public interface IEventEmitter
	{
		void Emit(AliasEventInfo eventInfo, IEmitter emitter);

		void Emit(ScalarEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingStartEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingEndEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter);
	}
	public interface INamingConvention
	{
		string Apply(string value);

		string Reverse(string value);
	}
	public interface INodeDeserializer
	{
		bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value, ObjectDeserializer rootDeserializer);
	}
	public interface INodeTypeResolver
	{
		bool Resolve(NodeEvent? nodeEvent, ref Type currentType);
	}
	public interface IObjectAccessor
	{
		void Set(string name, object target, object value);

		object? Read(string name, object target);
	}
	public interface IObjectDescriptor
	{
		object? Value { get; }

		Type Type { get; }

		Type StaticType { get; }

		ScalarStyle ScalarStyle { get; }
	}
	public static class ObjectDescriptorExtensions
	{
		public static object NonNullValue(this IObjectDescriptor objectDescriptor)
		{
			return objectDescriptor.Value ?? throw new InvalidOperationException("Attempted to use a IObjectDescriptor of type '" + objectDescriptor.Type.FullName + "' whose Value is null at a point whete it is invalid to do so. This may indicate a bug in YamlDotNet.");
		}
	}
	public interface IObjectFactory
	{
		object Create(Type type);

		object? CreatePrimitive(Type type);

		bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments);

		Type GetValueType(Type type);

		void ExecuteOnDeserializing(object value);

		void ExecuteOnDeserialized(object value);

		void ExecuteOnSerializing(object value);

		void ExecuteOnSerialized(object value);
	}
	public interface IObjectGraphTraversalStrategy
	{
		void Traverse<TContext>(IObjectDescriptor graph, IObjectGraphVisitor<TContext> visitor, TContext context, ObjectSerializer serializer);
	}
	public interface IObjectGraphVisitor<TContext>
	{
		bool Enter(IPropertyDescriptor? propertyDescriptor, IObjectDescriptor value, TContext context, ObjectSerializer serializer);

		bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, TContext context, ObjectSerializer serializer);

		bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, TContext context, ObjectSerializer serializer);

		void VisitScalar(IObjectDescriptor scalar, TContext context, ObjectSerializer serializer);

		void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, TContext context, ObjectSerializer serializer);

		void VisitMappingEnd(IObjectDescriptor mapping, TContext context, ObjectSerializer serializer);

		void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, TContext context, ObjectSerializer serializer);

		void VisitSequenceEnd(IObjectDescriptor sequence, TContext context, ObjectSerializer serializer);
	}
	public interface IPropertyDescriptor
	{
		string Name { get; }

		bool AllowNulls { get; }

		bool CanWrite { get; }

		Type Type { get; }

		Type? TypeOverride { get; set; }

		int Order { get; set; }

		ScalarStyle ScalarStyle { get; set; }

		bool Required { get; }

		Type? ConverterType { get; }

		T? GetCustomAttribute<T>() where T : Attribute;

		IObjectDescriptor Read(object target);

		void Write(object target, object? value);
	}
	public interface IRegistrationLocationSelectionSyntax<TBaseRegistrationType>
	{
		void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void Before<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void After<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void OnTop();

		void OnBottom();
	}
	public interface ITrackingRegistrationLocationSelectionSyntax<TBaseRegistrationType>
	{
		void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;
	}
	public interface ISerializer
	{
		string Serialize(object? graph);

		string Serialize(object? graph, Type type);

		void Serialize(TextWriter writer, object? graph);

		void Serialize(TextWriter writer, object? graph, Type type);

		void Serialize(IEmitter emitter, object? graph);

		void Serialize(IEmitter emitter, object? graph, Type type);
	}
	public interface ITypeInspector
	{
		IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container);

		IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched, bool caseInsensitivePropertyMatching);

		string GetEnumName(Type enumType, string name);

		string GetEnumValue(object enumValue);
	}
	public interface ITypeResolver
	{
		Type Resolve(Type staticType, object? actualValue);
	}
	public interface IValueDeserializer
	{
		object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer);
	}
	public interface IValuePromise
	{
		event Action<object?> ValueAvailable;
	}
	public interface IValueSerializer
	{
		void SerializeValue(IEmitter emitter, object? value, Type? type);
	}
	public interface IYamlConvertible
	{
		void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer);

		void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer);
	}
	public delegate object? ObjectDeserializer(Type type);
	public delegate void ObjectSerializer(object? value, Type? type = null);
	[Obsolete("Please use IYamlConvertible instead")]
	public interface IYamlSerializable
	{
		void ReadYaml(IParser parser);

		void WriteYaml(IEmitter emitter);
	}
	public interface IYamlTypeConverter
	{
		bool Accepts(Type type);

		object? ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer);

		void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer);
	}
	internal sealed class LazyComponentRegistrationList<TArgument, TComponent> : IEnumerable<Func<TArgument, TComponent>>, IEnumerable
	{
		public sealed class LazyComponentRegistration
		{
			public readonly Type ComponentType;

			public readonly Func<TArgument, TComponent> Factory;

			public LazyComponentRegistration(Type componentType, Func<TArgument, TComponent> factory)
			{
				ComponentType = componentType;
				Factory = factory;
			}
		}

		public sealed class TrackingLazyComponentRegistration
		{
			public readonly Type ComponentType;

			public readonly Func<TComponent, TArgument, TComponent> Factory;

			public TrackingLazyComponentRegistration(Type componentType, Func<TComponent, TArgument, TComponent> factory)
			{
				ComponentType = componentType;
				Factory = factory;
			}
		}

		private class RegistrationLocationSelector : IRegistrationLocationSelectionSyntax<TComponent>
		{
			private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations;

			private readonly LazyComponentRegistration newRegistration;

			public RegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, LazyComponentRegistration newRegistration)
			{
				this.registrations = registrations;
				this.newRegistration = newRegistration;
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>()
			{
				if (newRegistration.ComponentType != typeof(TRegistrationType))
				{
					registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				}
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries[index] = newRegistration;
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.After<TRegistrationType>()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				int num = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries.Insert(num + 1, newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.Before<TRegistrationType>()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries.Insert(index, newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.OnBottom()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				registrations.entries.Add(newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.OnTop()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				registrations.entries.Insert(0, newRegistration);
			}
		}

		private class TrackingRegistrationLocationSelector : ITrackingRegistrationLocationSelectionSyntax<TComponent>
		{
			private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations;

			private readonly TrackingLazyComponentRegistration newRegistration;

			public TrackingRegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, TrackingLazyComponentRegistration newRegistration)
			{
				this.registrations = registrations;
				this.newRegistration = newRegistration;
			}

			void ITrackingRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>()
			{
				if (newRegistration.ComponentType != typeof(TRegistrationType))
				{
					registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				}
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				Func<TArgument, TComponent> innerComponentFactory = registrations.entries[index].Factory;
				registrations.entries[index] = new LazyComponentRegistration(newRegistration.ComponentType, (TArgument arg) => newRegistration.Factory(innerComponentFactory(arg), arg));
			}
		}

		private readonly List<LazyComponentRegistration> entries = new List<LazyComponentRegistration>();

		public int Count => entries.Count;

		public IEnumerable<Func<TArgument, TComponent>> InReverseOrder
		{
			get
			{
				int i = entries.Count - 1;
				while (i >= 0)
				{
					yield return entries[i].Factory;
					int num = i - 1;
					i = num;
				}
			}
		}

		public LazyComponentRegistrationList<TArgument, TComponent> Clone()
		{
			LazyComponentRegistrationList<TArgument, TComponent> lazyComponentRegistrationList = new LazyComponentRegistrationList<TArgument, TComponent>();
			foreach (LazyComponentRegistration entry in entries)
			{
				lazyComponentRegistrationList.entries.Add(entry);
			}
			return lazyComponentRegistrationList;
		}

		public void Clear()
		{
			entries.Clear();
		}

		public void Add(Type componentType, Func<TArgument, TComponent> factory)
		{
			entries.Add(new LazyComponentRegistration(componentType, factory));
		}

		public void Remove(Type componentType)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (entries[i].ComponentType == componentType)
				{
					entries.RemoveAt(i);
					return;
				}
			}
			throw new KeyNotFoundException("A component registration of type '" + componentType.FullName + "' was not found.");
		}

		public IRegistrationLocationSelectionSyntax<TComponent> CreateRegistrationLocationSelector(Type componentType, Func<TArgument, TComponent> factory)
		{
			return new RegistrationLocationSelector(this, new LazyComponentRegistration(componentType, factory));
		}

		public ITrackingRegistrationLocationSelectionSyntax<TComponent> CreateTrackingRegistrationLocationSelector(Type componentType, Func<TComponent, TArgument, TComponent> factory)
		{
			return new TrackingRegistrationLocationSelector(this, new TrackingLazyComponentRegistration(componentType, factory));
		}

		public IEnumerator<Func<TArgument, TComponent>> GetEnumerator()
		{
			return entries.Select((LazyComponentRegistration e) => e.Factory).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		private int IndexOfRegistration(Type registrationType)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (registrationType == entries[i].ComponentType)
				{
					return i;
				}
			}
			return -1;
		}

		private void EnsureNoDuplicateRegistrationType(Type componentType)
		{
			if (IndexOfRegistration(componentType) != -1)
			{
				throw new InvalidOperationException("A component of type '" + componentType.FullName + "' has already been registered.");
			}
		}

		private int EnsureRegistrationExists<TRegistrationType>()
		{
			int num = IndexOfRegistration(typeof(TRegistrationType));
			if (num == -1)
			{
				throw new InvalidOperationException("A component of type '" + typeof(TRegistrationType).FullName + "' has not been registered.");
			}
			return num;
		}
	}
	internal static class LazyComponentRegistrationListExtensions
	{
		public static TComponent BuildComponentChain<TComponent>(this LazyComponentRegistrationList<TComponent, TComponent> registrations, TComponent innerComponent)
		{
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TComponent, TComponent> factory) => factory(inner));
		}

		public static TComponent BuildComponentChain<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TComponent innerComponent, Func<TComponent, TArgument> argumentBuilder)
		{
			Func<TComponent, TArgument> argumentBuilder2 = argumentBuilder;
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TArgument, TComponent> factory) => factory(argumentBuilder2(inner)));
		}

		public static List<TComponent> BuildComponentList<TComponent>(this LazyComponentRegistrationList<Nothing, TComponent> registrations)
		{
			return registrations.Select((Func<Nothing, TComponent> factory) => factory(default(Nothing))).ToList();
		}

		public static List<TComponent> BuildComponentList<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TArgument argument)
		{
			TArgument argument2 = argument;
			return registrations.Select((Func<TArgument, TComponent> factory) => factory(argument2)).ToList();
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct Nothing
	{
	}
	public sealed class ObjectDescriptor : IObjectDescriptor
	{
		public object? Value { get; private set; }

		public Type Type { get; private set; }

		public Type StaticType { get; private set; }

		public ScalarStyle ScalarStyle { get; private set; }

		public ObjectDescriptor(object? value, Type type, Type staticType)
			: this(value, type, staticType, ScalarStyle.Any)
		{
		}

		public ObjectDescriptor(object? value, Type type, Type staticType, ScalarStyle scalarStyle)
		{
			Value = value;
			Type = type ?? throw new ArgumentNullException("type");
			StaticType = staticType ?? throw new ArgumentNullException("staticType");
			ScalarStyle = scalarStyle;
		}
	}
	public delegate IObjectGraphTraversalStrategy ObjectGraphTraversalStrategyFactory(ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion);
	public sealed class PropertyDescriptor : IPropertyDescriptor
	{
		private readonly IPropertyDescriptor baseDescriptor;

		public bool AllowNulls => baseDescriptor.AllowNulls;

		public string Name { get; set; }

		public bool Required => baseDescriptor.Required;

		public Type Type => baseDescriptor.Type;

		public Type? TypeOverride
		{
			get
			{
				return baseDescriptor.TypeOverride;
			}
			set
			{
				baseDescriptor.TypeOverride = value;
			}
		}

		public Type? ConverterType => baseDescriptor.ConverterType;

		public int Order { get; set; }

		public ScalarStyle ScalarStyle
		{
			get
			{
				return baseDescriptor.ScalarStyle;
			}
			set
			{
				baseDescriptor.ScalarStyle = value;
			}
		}

		public bool CanWrite => baseDescriptor.CanWrite;

		public PropertyDescriptor(IPropertyDescriptor baseDescriptor)
		{
			this.baseDescriptor = baseDescriptor;
			Name = baseDescriptor.Name;
		}

		public void Write(object target, object? value)
		{
			baseDescriptor.Write(target, value);
		}

		public T? GetCustomAttribute<T>() where T : Attribute
		{
			return baseDescriptor.GetCustomAttribute<T>();
		}

		public IObjectDescriptor Read(object target)
		{
			return baseDescriptor.Read(target);
		}
	}
	public sealed class Serializer : ISerializer
	{
		private readonly IValueSerializer valueSerializer;

		private readonly EmitterSettings emitterSettings;

		public Serializer()
			: this(new SerializerBuilder().BuildValueSerializer(), EmitterSettings.Default)
		{
		}

		private Serializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings)
		{
			this.valueSerializer = valueSerializer ?? throw new ArgumentNullException("valueSerializer");
			this.emitterSettings = emitterSettings ?? throw new ArgumentNullException("emitterSettings");
		}

		public static Serializer FromValueSerializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings)
		{
			return new Serializer(valueSerializer, emitterSettings);
		}

		public string Serialize(object? graph)
		{
			using StringWriter stringWriter = new StringWriter();
			Serialize(stringWriter, graph);
			return stringWriter.ToString();
		}

		public string Serialize(object? graph, Type type)
		{
			using StringWriter stringWriter = new StringWriter();
			Serialize(stringWriter, graph, type);
			return stringWriter.ToString();
		}

		public void Serialize(TextWriter writer, object? graph)
		{
			Serialize(new Emitter(writer, emitterSettings), graph);
		}

		public void Serialize(TextWriter writer, object? graph, Type type)
		{
			Serialize(new Emitter(writer, emitterSettings), graph, type);
		}

		public void Serialize(IEmitter emitter, object? graph)
		{
			if (emitter == null)
			{
				throw new ArgumentNullException("emitter");
			}
			EmitDocument(emitter, graph, null);
		}

		public void Serialize(IEmitter emitter, object? graph, Type type)
		{
			if (emitter == null)
			{
				throw new ArgumentNullException("emitter");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			EmitDocument(emitter, graph, type);
		}

		private void EmitDocument(IEmitter emitter, object? graph, Type? type)
		{
			emitter.Emit(new YamlDotNet.Core.Events.StreamStart());
			emitter.Emit(new YamlDotNet.Core.Events.DocumentStart());
			valueSerializer.SerializeValue(emitter, graph, type);
			emitter.Emit(new YamlDotNet.Core.Events.DocumentEnd(isImplicit: true));
			emitter.Emit(new YamlDotNet.Core.Events.StreamEnd());
		}
	}
	public sealed class SerializerBuilder : BuilderSkeleton<SerializerBuilder>
	{
		private class ValueSerializer : IValueSerializer
		{
			private readonly IObjectGraphTraversalStrategy traversalStrategy;

			private readonly IEventEmitter eventEmitter;

			private readonly IEnumerable<IYamlTypeConverter> typeConverters;

			private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

			private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

			public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable<IYamlTypeConverter> typeConverters, LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories)
			{
				this.traversalStrategy = traversalStrategy;
				this.eventEmitter = eventEmitter;
				this.typeConverters = typeConverters;
				this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories;
				this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories;
			}

			public void SerializeValue(IEmitter emitter, object? value, Type? type)
			{
				IEmitter emitter2 = emitter;
				Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object));
				Type staticType = type ?? typeof(object);
				ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType);
				List<IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters);
				IObjectGraphVisitor<IEmitter> visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor<IEmitter> inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, NestedObjectSerializer));
				foreach (IObjectGraphVisitor<Nothing> item in preProcessingPhaseObjectGraphVisitors)
				{
					traversalStrategy.Traverse(graph, item, default(Nothing), NestedObjectSerializer);
				}
				traversalStrategy.Traverse(graph, visitor, emitter2, NestedObjectSerializer);
				void NestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter2, v, t);
				}
			}
		}

		private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory;

		private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<IEventEmitter, IEventEmitter> eventEmitterFactories;

		private readonly IDictionary<Type, TagName> tagMappings = new Dictionary<Type, TagName>();

		private readonly IObjectFactory objectFactory;

		private int maximumRecursion = 50;

		private EmitterSettings emitterSettings = EmitterSettings.Default;

		private DefaultValuesHandling defaultValuesHandlingConfiguration;

		private ScalarStyle defaultScalarStyle;

		private bool quoteNecessaryStrings;

		private bool quoteYaml1_1Strings;

		protected override SerializerBuilder Self => this;

		public SerializerBuilder()
			: base((ITypeResolver)new DynamicTypeResolver())
		{
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone()));
			preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> { 
			{
				typeof(AnchorAssigner),
				(IEnumerable<IYamlTypeConverter> typeConverters) => new AnchorAssigner(typeConverters)
			} };
			emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>
			{
				{
					typeof(CustomSerializationObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer)
				},
				{
					typeof(AnchorAssigningObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor<AnchorAssigner>())
				},
				{
					typeof(DefaultValuesObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor, new DefaultObjectFactory())
				},
				{
					typeof(CommentsObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor)
				}
			};
			eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { 
			{
				typeof(TypeAssigningEventEmitter),
				(IEventEmitter inner) => new TypeAssigningEventEmitter(inner, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention, BuildTypeInspector())
			} };
			objectFactory = new DefaultObjectFactory();
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, objectFactory);
		}

		public SerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false)
		{
			quoteNecessaryStrings = true;
			this.quoteYaml1_1Strings = quoteYaml1_1Strings;
			return this;
		}

		public SerializerBuilder WithDefaultScalarStyle(ScalarStyle style)
		{
			defaultScalarStyle = style;
			return this;
		}

		public SerializerBuilder WithMaximumRecursion(int maximumRecursion)
		{
			if (maximumRecursion <= 0)
			{
				throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer.");
			}
			this.maximumRecursion = maximumRecursion;
			return this;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter
		{
			return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, ITypeInspector, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter
		{
			return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			Func<IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			return WithEventEmitter((IEventEmitter e, ITypeInspector _) => eventEmitterFactory2(e), where);
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, ITypeInspector, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			Func<IEventEmitter, ITypeInspector, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			if (eventEmitterFactory2 == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory2(inner, BuildTypeInspector())));
			return Self;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			if (eventEmitterFactory2 == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory2(wrapped, inner)));
			return Self;
		}

		public SerializerBuilder WithoutEventEmitter<TEventEmitter>() where TEventEmitter : IEventEmitter
		{
			return WithoutEventEmitter(typeof(TEventEmitter));
		}

		public SerializerBuilder WithoutEventEmitter(Type eventEmitterType)
		{
			if (eventEmitterType == null)
			{
				throw new ArgumentNullException("eventEmitterType");
			}
			eventEmitterFactories.Remove(eventEmitterType);
			return this;
		}

		public override SerializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(type, out var value))
			{
				throw new ArgumentException($"Type already has a registered tag '{value}' for type '{type.FullName}'", "type");
			}
			tagMappings.Add(type, tag);
			return this;
		}

		public SerializerBuilder WithoutTagMapping(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!tagMappings.Remove(type))
			{
				throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered");
			}
			return this;
		}

		public SerializerBuilder EnsureRoundtrip()
		{
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention, settings, objectFactory);
			WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention, BuildTypeInspector()), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
			return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc)
			{
				loc.OnBottom();
			});
		}

		public SerializerBuilder DisableAliases()
		{
			preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner));
			emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor));
			return this;
		}

		[Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)]
		public SerializerBuilder EmitDefaults()
		{
			return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve);
		}

		public SerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration)
		{
			defaultValuesHandlingConfiguration = configuration;
			return this;
		}

		public SerializerBuilder JsonCompatible()
		{
			emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue).WithoutAnchorName();
			return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>();
			}).WithTypeConverter(new DateTime8601Converter(ScalarStyle.DoubleQuoted)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter, enumNamingConvention, BuildTypeInspector()), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
		}

		public SerializerBuilder WithNewLine(string newLine)
		{
			emitterSettings = emitterSettings.WithNewLine(newLine);
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<IEnumerable<IYamlTypeConverter>, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			TObjectGraphVisitor objectGraphVisitor2 = objectGraphVisitor;
			if (objectGraphVisitor2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitor");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable<IYamlTypeConverter> _) => objectGraphVisitor2));
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<IEnumerable<IYamlTypeConverter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			Func<IEnumerable<IYamlTypeConverter>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable<IYamlTypeConverter> typeConverters) => objectGraphVisitorFactory2(typeConverters)));
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> _) => objectGraphVisitorFactory2(wrapped)));
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			WrapperFactory<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> typeConverters) => objectGraphVisitorFactory2(wrapped, typeConverters)));
			return this;
		}

		public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithoutPreProcessingPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor));
		}

		public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor(Type objectGraphVisitorType)
		{
			if (objectGraphVisitorType == null)
			{
				throw new ArgumentNullException("objectGraphVisitorType");
			}
			preProcessingPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType);
			return this;
		}

		public SerializerBuilder WithObjectGraphTraversalStrategyFactory(ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory)
		{
			this.objectGraphTraversalStrategyFactory = objectGraphTraversalStrategyFactory;
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			return WithEmissionPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(args)));
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<IEmitter> wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(wrapped, args)));
			return this;
		}

		public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			return WithoutEmissionPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor));
		}

		public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor(Type objectGraphVisitorType)
		{
			if (objectGraphVisitorType == null)
			{
				throw new ArgumentNullException("objectGraphVisitorType");
			}
			emissionPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType);
			return this;
		}

		public SerializerBuilder WithIndentedSequences()
		{
			emitterSettings = emitterSettings.WithIndentedSequences();
			return this;
		}

		public ISerializer Build()
		{
			return Serializer.FromValueSerializer(BuildValueSerializer(), emitterSettings);
		}

		public IValueSerializer BuildValueSerializer()
		{
			IEnumerable<IYamlTypeConverter> typeConverters = BuildTypeConverters();
			ITypeInspector typeInspector = BuildTypeInspector();
			IObjectGraphTraversalStrategy traversalStrategy = objectGraphTraversalStrategyFactory(typeInspector, typeResolver, typeConverters, maximumRecursion);
			IEventEmitter eventEmitter = eventEmitterFactories.BuildComponentChain(new WriterEventEmitter());
			return new ValueSerializer(traversalStrategy, eventEmitter, typeConverters, preProcessingPhaseObjectGraphVisitorFactories.Clone(), emissionPhaseObjectGraphVisitorFactories.Clone());
		}

		public ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver, includeNonPublicProperties);
			if (!ignoreFields)
			{
				typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector);
			}
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}
	}
	public class Settings
	{
		public bool AllowPrivateConstructors { get; set; }
	}
	public abstract class StaticBuilderSkeleton<TBuilder> where TBuilder : StaticBuilderSkeleton<TBuilder>
	{
		internal INamingConvention namingConvention = NullNamingConvention.Instance;

		internal INamingConvention enumNamingConvention = NullNamingConvention.Instance;

		internal ITypeResolver typeResolver;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		internal bool includeNonPublicProperties;

		internal Settings settings;

		internal YamlFormatter yamlFormatter = YamlFormatter.Default;

		protected abstract TBuilder Self { get; }

		internal StaticBuilderSkeleton(ITypeResolver typeResolver)
		{
			typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter> { 
			{
				typeof(YamlDotNet.Serialization.Converters.GuidConverter),
				(Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false)
			} };
			typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>();
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			settings = new Settings();
		}

		public TBuilder WithNamingConvention(INamingConvention namingConvention)
		{
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
			return Self;
		}

		public TBuilder WithEnumNamingConvention(INamingConvention enumNamingConvention)
		{
			this.enumNamingConvention = enumNamingConvention ?? throw new ArgumentNullException("enumNamingConvention");
			return Self;
		}

		public TBuilder WithTypeResolver(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			return Self;
		}

		public abstract TBuilder WithTagMapping(TagName tag, Type type);

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter)
		{
			return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where)
		{
			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;
		}

		public TBuilder WithYamlFormatter(YamlFormatter formatter)
		{
			yamlFormatter = formatter ?? throw new ArgumentNullException("formatter");
			return Self;
		}

		protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
		{
			return typeConverterFactories.BuildComponentList();
		}
	}
	public abstract class StaticContext
	{
		public virtual bool IsKnownType(Type type)
		{
			throw new NotImplementedException();
		}

		public virtual ITypeResolver GetTypeResolver()
		{
			throw new NotImplementedException();
		}

		public virtual StaticObjectFactory GetFactory()
		{
			throw new NotImplementedException();
		}

		public virtual ITypeInspector GetTypeInspector()
		{
			throw new NotImplementedException();
		}
	}
	public sealed class StaticDeserializerBuilder : StaticBuilderSkeleton<StaticDeserializerBuilder>
	{
		private readonly StaticContext context;

		private readonly StaticObjectFactory factory;

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<TagName, Type> tagMappings;

		private readonly ITypeConverter typeConverter;

		private readonly Dictionary<Type, Type> typeMappings;

		private bool ignoreUnmatched;

		private bool duplicateKeyChecking;

		private bool attemptUnknownTypeDeserialization;

		private bool enforceNullability;

		private bool caseInsensitivePropertyMatching;

		protected override StaticDeserializerBuilder Self => this;

		public StaticDeserializerBuilder(StaticContext context)
			: base(context.GetTypeResolver())
		{
			this.context = context;
			factory = context.GetFactory();
			typeMappings = new Dictionary<Type, Type>();
			tagMappings = new Dictionary<TagName, Type>
			{
				{
					FailsafeSchema.Tags.Map,
					typeof(Dictionary<object, object>)
				},
				{
					FailsafeSchema.Tags.Str,
					typeof(string)
				},
				{
					JsonSchema.Tags.Bool,
					typeof(bool)
				},
				{
					JsonSchema.Tags.Float,
					typeof(double)
				},
				{
					JsonSchema.Tags.Int,
					typeof(int)
				},
				{
					DefaultSchema.Tags.Timestamp,
					typeof(DateTime)
				}
			};
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer>
			{
				{
					typeof(YamlConvertibleNodeDeserializer),
					(Nothing _) => new YamlConvertibleNodeDeserializer(factory)
				},
				{
					typeof(YamlSerializableNodeDeserializer),
					(Nothing _) => new YamlSerializableNodeDeserializer(factory)
				},
				{
					typeof(TypeConverterNodeDeserializer),
					(Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters())
				},
				{
					typeof(NullNodeDeserializer),
					(Nothing _) => new NullNodeDeserializer()
				},
				{
					typeof(ScalarNodeDeserializer),
					(Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, BuildTypeInspector(), yamlFormatter, enumNamingConvention)
				},
				{
					typeof(StaticArrayNodeDeserializer),
					(Nothing _) => new StaticArrayNodeDeserializer(factory)
				},
				{
					typeof(StaticDictionaryNodeDeserializer),
					(Nothing _) => new StaticDictionaryNodeDeserializer(factory, duplicateKeyChecking)
				},
				{
					typeof(StaticCollectionNodeDeserializer),
					(Nothing _) => new StaticCollectionNodeDeserializer(factory)
				},
				{
					typeof(ObjectNodeDeserializer),
					(Nothing _) => new ObjectNodeDeserializer(factory, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter, enumNamingConvention, enforceNullability, caseInsensitivePropertyMatching, enforceRequiredProperties: false, BuildTypeConverters())
				}
			};
			nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver>
			{
				{
					typeof(MappingNodeTypeResolver),
					(Nothing _) => new MappingNodeTypeResolver(typeMappings)
				},
				{
					typeof(YamlConvertibleTypeResolver),
					(Nothing _) => new YamlConvertibleTypeResolver()
				},
				{
					typeof(YamlSerializableTypeResolver),
					(Nothing _) => new YamlSerializableTypeResolver()
				},
				{
					typeof(TagNodeTypeResolver),
					(Nothing _) => new TagNodeTypeResolver(tagMappings)
				},
				{
					typeof(PreventUnknownTagsNodeTypeResolver),
					(Nothing _) => new PreventUnknownTagsNodeTypeResolver()
				},
				{
					typeof(DefaultContainersNodeTypeResolver),
					(Nothing _) => new DefaultContainersNodeTypeResolver()
				}
			};
			typeConverter = new NullTypeConverter();
		}

		public ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = context.GetTypeInspector();
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}

		public StaticDeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization()
		{
			attemptUnknownTypeDeserialization = true;
			return this;
		}

		public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer)
		{
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> w)
			{
				w.OnTop();
			});
		}

		public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where)
		{
			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 StaticDeserializerBuilder 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 StaticDeserializerBuilder WithCaseInsensitivePropertyMatching()
		{
			caseInsensitivePropertyMatching = true;
			return this;
		}

		public StaticDeserializerBuilder WithEnforceNullability()
		{
			enforceNullability = true;
			return this;
		}

		public StaticDeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer
		{
			return WithoutNodeDeserializer(typeof(TNodeDeserializer));
		}

		public StaticDeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType)
		{
			if (nodeDeserializerType == null)
			{
				throw new ArgumentNullException("nodeDeserializerType");
			}
			nodeDeserializerFactories.Remove(nodeDeserializerType);
			return this;
		}

		public StaticDeserializerBuilder WithTypeDiscriminatingNodeDeserializer(Action<ITypeDiscriminatingNodeDeserializerOptions> configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1)
		{
			TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions();
			configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions);
			TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength);
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
			{
				s.Before<DictionaryNodeDeserializer>();
			});
		}

		public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver)
		{
			return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w)
			{
				w.OnTop();
			});
		}

		public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where)
		{
			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 StaticDeserializerBuilder 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 StaticDeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver
		{
			return WithoutNodeTypeResolver(typeof(TNodeTypeResolver));
		}

		public StaticDeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType)
		{
			if (nodeTypeResolverType == null)
			{
				throw new ArgumentNullException("nodeTypeResolverType");
			}
			nodeTypeResolverFactories.Remove(nodeTypeResolverType);
			return this;
		}

		public override StaticDeserializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(tag, out Type value))
			{
				throw new ArgumentException($"Type already has a registered type '{value.FullName}' for tag '{tag}'", "tag");
			}
			tagMappings.Add(tag, type);
			return this;
		}

		public StaticDeserializerBuilder WithTypeMapping<TInterface, TConcrete>() where TConcrete : TInterface
		{
			Type typeFromHandle = typeof(TInterface);
			Type typeFromHandle2 = typeof(TConcrete);
			if (!typeFromHandle.IsAssignableFrom(typeFromHandle2))
			{
				throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'.");
			}
			if (typeMappings.ContainsKey(typeFromHandle))
			{
				typeMappings[typeFromHandle] = typeFromHandle2;
			}
			else
			{
				typeMappings.Add(typeFromHandle, typeFromHandle2);
			}
			return this;
		}

		public StaticDeserializerBuilder WithoutTagMapping(TagName tag)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (!tagMappings.Remove(tag))
			{
				throw new KeyNotFoundException($"Tag '{tag}' is not registered");
			}
			return this;
		}

		public StaticDeserializerBuilder IgnoreUnmatchedProperties()
		{
			ignoreUnmatched = true;
			return this;
		}

		public StaticDeserializerBuilder WithDuplicateKeyChecking()
		{
			duplicateKeyChecking = true;
			return this;
		}

		public IDeserializer Build()
		{
			return Deserializer.FromValueDeserializer(BuildValueDeserializer());
		}

		public IValueDeserializer BuildValueDeserializer()
		{
			return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter, enumNamingConvention, BuildTypeInspector()));
		}
	}
	public sealed class StaticSerializerBuilder : StaticBuilderSkeleton<StaticSerializerBuilder>
	{
		private class ValueSerializer : IValueSerializer
		{
			private readonly IObjectGraphTraversalStrategy traversalStrategy;

			private readonly IEventEmitter eventEmitter;

			private readonly IEnumerable<IYamlTypeConverter> typeConverters;

			private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

			private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

			public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable<IYamlTypeConverter> typeConverters, LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories)
			{
				this.traversalStrategy = traversalStrategy;
				this.eventEmitter = eventEmitter;
				this.typeConverters = typeConverters;
				this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories;
				this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories;
			}

			public void SerializeValue(IEmitter emitter, object? value, Type? type)
			{
				IEmitter emitter2 = emitter;
				Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object));
				Type staticType = type ?? typeof(object);
				ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType);
				List<IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters);
				foreach (IObjectGraphVisitor<Nothing> item in preProcessingPhaseObjectGraphVisitors)
				{
					traversalStrategy.Traverse(graph, item, default(Nothing), NestedObjectSerializer);
				}
				IObjectGraphVisitor<IEmitter> visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor<IEmitter> inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, NestedObjectSerializer));
				traversalStrategy.Traverse(graph, visitor, emitter2, NestedObjectSerializer);
				void NestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter2, v, t);
				}
			}
		}

		private readonly StaticContext context;

		private readonly StaticObjectFactory factory;

		private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory;

		private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<IEventE