Decompiled source of LootGoblinsHeim v1.0.37

DarwinAwards/DarwinAwards.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DarwinAwards")]
[assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/DarwinAwards")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DarwinAwards")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("AED068DF-D021-4229-BBA8-6C61CB0385F6")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace DarwinAwards
{
	[BepInPlugin("org.bepinex.plugins.darwinawards", "Darwin Awards", "1.0.6")]
	[BepInIncompatibility("org.bepinex.plugins.valheim_plus")]
	public class DarwinAwards : BaseUnityPlugin
	{
		private enum Toggle
		{
			On = 1,
			Off = 0
		}

		public enum Font
		{
			Arial,
			AveriaSansLibre_Bold,
			AveriaSansLibre_BoldItalic,
			AveriaSansLibre_Italic,
			AveriaSansLibre_Light,
			AveriaSansLibre_LightItalic,
			AveriaSansLibre_Regular,
			AveriaSerifLibre_Bold,
			AveriaSerifLibre_BoldItalic,
			AveriaSerifLibre_Italic,
			AveriaSerifLibre_Light,
			AveriaSerifLibre_Regular,
			CONSOLA,
			Norse,
			Norsebold,
			OpenSans_Bold,
			OpenSans_BoldItalic,
			OpenSans_ExtraBold,
			OpenSans_ExtraBoldItalic,
			OpenSans_Italic,
			OpenSans_Light,
			OpenSans_LightItalic,
			OpenSans_Regular,
			OpenSans_SemiBold,
			OpenSans_SemiBoldItalic,
			prstart,
			prstartk,
			rune
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public bool? Browsable = false;
		}

		[HarmonyPatch(typeof(Game), "Start")]
		private class AddRPCs
		{
			private static void Postfix()
			{
				ZRoutedRpc.instance.Register<string, string>("DarwinAwards IDied", (Action<long, string, string>)onReceivedDeath);
			}
		}

		[HarmonyPatch(typeof(Character), "SetHealth")]
		private class InterceptDeath
		{
			private static void Prefix(Character __instance, float health)
			{
				//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Invalid comparison between Unknown and I4
				if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer) || !(__instance.GetHealth() > 0f) || !(health <= 0f))
				{
					return;
				}
				if (__instance.IsSwimming())
				{
					BroadcastDeath(getRandomText("death by drowning"));
				}
				else
				{
					if (SaveCauseOfDeath.deathHit == null)
					{
						return;
					}
					HashSet<string> hashSet = new HashSet<string>();
					if ((Object)(object)SaveCauseOfDeath.deathHit.GetAttacker() != (Object)null)
					{
						if (SaveCauseOfDeath.deathHit.GetAttacker().IsBoss())
						{
							hashSet.Add("death by boss");
						}
						else if (SaveCauseOfDeath.deathHit.GetAttacker().IsPlayer())
						{
							hashSet.Add("death by player");
						}
						else
						{
							hashSet.Add("death by creature");
						}
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_blunt > 0f)
					{
						hashSet.Add("death by blunt");
						hashSet.Add("death by physical");
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_pierce > 0f)
					{
						hashSet.Add("death by pierce");
						hashSet.Add("death by physical");
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_slash > 0f)
					{
						hashSet.Add("death by slash");
						hashSet.Add("death by physical");
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_fire > 0f)
					{
						hashSet.Add("death by fire");
						hashSet.Add("death by elemental");
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_frost > 0f)
					{
						hashSet.Add("death by frost");
						hashSet.Add("death by elemental");
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_lightning > 0f)
					{
						hashSet.Add("death by lightning");
						hashSet.Add("death by elemental");
					}
					if (SaveCauseOfDeath.deathHit.m_damage.m_poison > 0f)
					{
						hashSet.Add("death by poison");
						hashSet.Add("death by elemental");
					}
					if ((int)SaveCauseOfDeath.deathHit.m_skill == 13)
					{
						hashSet.Add("death by tree");
					}
					if (SetGravityFlag.fallDamageTaken)
					{
						hashSet.Add("death by gravity");
					}
					if (SetFreezingFlag.freezingDamageTaken)
					{
						hashSet.Add("death by frost");
					}
					Character attacker = SaveCauseOfDeath.deathHit.GetAttacker();
					if (attacker != null)
					{
						BroadcastDeath(getRandomEnemyText(attacker.GetHoverName(), hashSet.ToArray()));
					}
					else
					{
						BroadcastDeath(getRandomText(hashSet.ToArray()));
					}
				}
			}
		}

		[HarmonyPatch(typeof(SE_Stats), "UpdateStatusEffect")]
		public class SetFreezingFlag
		{
			public static bool freezingDamageTaken;

			private static void Prefix(SE_Stats __instance)
			{
				if (((Object)__instance).name == "Freezing")
				{
					freezingDamageTaken = true;
				}
			}

			private static void Finalizer()
			{
				freezingDamageTaken = false;
			}
		}

		[HarmonyPatch(typeof(Character), "UpdateGroundContact")]
		public class SetGravityFlag
		{
			public static bool fallDamageTaken;

			private static void Prefix()
			{
				fallDamageTaken = true;
			}

			private static void Finalizer()
			{
				fallDamageTaken = false;
			}
		}

		[HarmonyPatch(typeof(ImpactEffect), "OnCollisionEnter")]
		public class SetTreeFlag
		{
			public static bool hitByTree;

			private static void Prefix(ImpactEffect __instance)
			{
				if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<TreeLog>()))
				{
					hitByTree = true;
				}
			}

			private static void Finalizer()
			{
				hitByTree = false;
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		public class HitByTree
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				if (SetTreeFlag.hitByTree)
				{
					Player val = (Player)(object)((__instance is Player) ? __instance : null);
					if (val != null && ((Character)val).GetHealth() > 0f)
					{
						hit.m_skill = (SkillType)13;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private class SaveCauseOfDeath
		{
			public static HitData? deathHit;

			private static void Prefix(HitData hit)
			{
				deathHit = hit;
			}

			private static void Finalizer()
			{
				deathHit = null;
			}
		}

		public struct DeathText
		{
			public string category;

			public string text;

			public DeathText()
			{
				category = null;
				text = null;
			}
		}

		private const string ModName = "Darwin Awards";

		private const string ModVersion = "1.0.6";

		private const string ModGUID = "org.bepinex.plugins.darwinawards";

		private static ConfigEntry<Toggle> serverConfigLocked = null;

		public static ConfigEntry<Vector2> deathLogAnchor = null;

		public static ConfigEntry<int> numberOfDeaths = null;

		public static ConfigEntry<uint> timerForDeaths = null;

		public static ConfigEntry<int> fontSize = null;

		public static ConfigEntry<Font> font = null;

		private static ConfigEntry<string> webhookURL = null;

		private static ConfigEntry<string> webhookUsername = null;

		public static readonly ManualLogSource MLLogger = Logger.CreateLogSource("Darwin Awards");

		private static readonly ConfigSync configSync = new ConfigSync("Darwin Awards")
		{
			DisplayName = "Darwin Awards",
			CurrentVersion = "1.0.6",
			MinimumRequiredVersion = "1.0.6"
		};

		private static readonly CustomSyncedValue<string> deathTexts = new CustomSyncedValue<string>(configSync, "deathTexts", readDeathTexts(), 0);

		private static Dictionary<string, List<string>> deathTextDict = new Dictionary<string, List<string>>();

		private static string configDir => Paths.ConfigPath;

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
			((OwnConfigEntryBase)configSync.AddConfigEntry<T>(val)).SynchronizedConfig = synchronizedSetting;
			return val;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		public void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, new ConfigDescription("If on, only server admins can change the configuration.", (AcceptableValueBase)null, Array.Empty<object>()));
			configSync.AddLockingConfigEntry<Toggle>(serverConfigLocked);
			numberOfDeaths = config("1 - General", "Number of deaths", 3, new ConfigDescription("Number of deaths to display at the same time. Set this to 0, to disable the death log.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 25), Array.Empty<object>()), synchronizedSetting: false);
			timerForDeaths = config("1 - General", "Timer for deaths", 30u, new ConfigDescription("Time in seconds the deaths are displayed. 0 means no time limit.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			timerForDeaths.SettingChanged += Display.CheckDeathTimes;
			deathLogAnchor = config<Vector2>("1 - General", "Position of the death log", new Vector2(700f, 220f), new ConfigDescription("Position of the death log.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			deathLogAnchor.SettingChanged += Display.AnchorDeathLog;
			font = config("1 - General", "Font of the death log", Font.AveriaSansLibre_Bold, new ConfigDescription("Name of the font that should be used for your death log. Has to be installed on your computer to work.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
			font.SettingChanged += Display.UpdateFont;
			fontSize = config("1 - General", "Font size of the death log", 14, new ConfigDescription("Font size to be used for your death log.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 32), Array.Empty<object>()), synchronizedSetting: false);
			fontSize.SettingChanged += Display.UpdateFont;
			webhookURL = config("2 - Webhook", "Discord Webhook URL", "", new ConfigDescription("Discord API endpoint to announce deaths.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes()
			}), synchronizedSetting: false);
			webhookUsername = config("2 - Webhook", "Username  to use for Discord", "Darwin", new ConfigDescription("Username to be used for death related posts to Discord.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes()
			}), synchronizedSetting: false);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			new Harmony("org.bepinex.plugins.darwinawards").PatchAll(executingAssembly);
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(configDir, "AwardCategories.yml");
			fileSystemWatcher.Created += deathTextsFileEvent;
			fileSystemWatcher.Changed += deathTextsFileEvent;
			fileSystemWatcher.Renamed += deathTextsFileEvent;
			fileSystemWatcher.Deleted += deathTextsFileEvent;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			((CustomSyncedValueBase)deathTexts).ValueChanged += ReadYamlFile;
			ReadYamlFile();
			Display.FillIconMap();
			MLLogger.LogInfo((object)"Loading complete");
		}

		private static void onReceivedDeath(long senderId, string category, string text)
		{
			DeathText text2 = new DeathText();
			text2.category = category;
			text2.text = text;
			Display.AddText(text2);
			if (ZNet.instance.IsServer() && webhookURL.Value != "")
			{
				PostToDiscord(text);
			}
		}

		private static void BroadcastDeath(DeathText text)
		{
			if (webhookURL.Value != "")
			{
				PostToDiscord(text.text);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "DarwinAwards IDied", new object[2] { text.category, text.text });
		}

		private static void ReadYamlFile()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			try
			{
				deathTextDict = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, List<string>>>(deathTexts.Value) ?? new Dictionary<string, List<string>>();
				MLLogger.LogInfo((object)"ReadYamlFile complete");
			}
			catch (Exception ex)
			{
				MLLogger.LogError((object)"ReadYamlFile error");
				MLLogger.LogError((object)ex.Message);
				MLLogger.LogError((object)ex.StackTrace);
			}
		}

		private static void deathTextsFileEvent(object s, EventArgs e)
		{
			deathTexts.AssignLocalValue(readDeathTexts());
		}

		private static string readDeathTexts()
		{
			string text = configDir;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			string text2 = text + directorySeparatorChar + "AwardCategories.yml";
			if (File.Exists(text2))
			{
				return File.ReadAllText(text2);
			}
			Debug.LogWarning((object)("AwardCategories.yml for Darwin Awards is missing at " + text2));
			return "";
		}

		private static DeathText getRandomText(params string[] categories)
		{
			return selectRandomText((from t in listAllTexts(categories)
				where !t.text.Contains("{enemy}")
				select t).ToList());
		}

		private static DeathText getRandomEnemyText(string enemy, params string[] categories)
		{
			DeathText result = selectRandomText(listAllTexts(categories).ToList());
			result.text = result.text.Replace("{enemy}", enemy);
			return result;
		}

		private static List<DeathText> listAllTexts(params string[] categories)
		{
			List<DeathText> list = new List<DeathText>();
			if (Random.Range(1, 4) == 1 && deathTextDict.TryGetValue("general", out List<string> value))
			{
				list.AddRange(value.Select((string t) => new DeathText
				{
					category = "general",
					text = t
				}));
			}
			foreach (string s in categories)
			{
				if (deathTextDict.TryGetValue(s, out List<string> value2))
				{
					list.AddRange(value2.Select((string t) => new DeathText
					{
						category = s,
						text = t
					}));
				}
			}
			return list.Where((DeathText t) => t.text != "").ToList();
		}

		private static DeathText selectRandomText(List<DeathText> possibleTexts)
		{
			DeathText deathText;
			if (possibleTexts.Count != 0)
			{
				deathText = possibleTexts[Random.Range(0, possibleTexts.Count)];
			}
			else
			{
				DeathText deathText2 = new DeathText();
				deathText2.category = "general";
				deathText2.text = "R.I.P. {player}";
				deathText = deathText2;
			}
			DeathText result = deathText;
			result.text = result.text.Replace("{player}", ((Character)Player.m_localPlayer).GetHoverName());
			return result;
		}

		private static void PostToDiscord(string content)
		{
			string content2 = content;
			if (content2 == "" || webhookURL.Value == "")
			{
				MLLogger.LogWarning((object)("Cant post to discord, content:" + content2 + "; webhookURL: " + webhookURL.Value));
				return;
			}
			try
			{
				WebRequest discordAPI = WebRequest.Create(webhookURL.Value);
				discordAPI.Method = "POST";
				discordAPI.ContentType = "application/json";
				discordAPI.GetRequestStreamAsync().ContinueWith(delegate(Task<Stream> t)
				{
					using StreamWriter streamWriter = new StreamWriter(t.Result);
					string text = "{\"content\":\"" + escape(content2) + "\"" + ((webhookUsername.Value == "") ? "" : (", \"username\":\"" + escape(webhookUsername.Value) + "\"")) + "}";
					streamWriter.WriteAsync(text).ContinueWith((Task _) => discordAPI.GetResponseAsync());
					MLLogger.LogInfo((object)("Posted: " + text));
				});
			}
			catch (Exception ex)
			{
				MLLogger.LogError((object)"Cant post to discord");
				MLLogger.LogError((object)ex.Message);
				MLLogger.LogError((object)ex.StackTrace);
				throw;
			}
			static string escape(string s)
			{
				return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
			}
		}
	}
	public static class Display
	{
		[HarmonyPatch(typeof(Hud), "Awake")]
		public class AddDeathList
		{
			private static void Postfix(Hud __instance)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Expected O, but got Unknown
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0206: Unknown result type (might be due to invalid IL or missing references)
				//IL_020c: Unknown result type (might be due to invalid IL or missing references)
				deaths = new GameObject("deaths", new Type[1] { typeof(RectTransform) });
				deaths.AddComponent<DragNDrop>();
				deaths.transform.SetParent(__instance.m_rootObject.transform);
				deaths.transform.localPosition = Vector2.op_Implicit(DarwinAwards.deathLogAnchor.Value);
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0f, 0.5f);
				linePrefab = new GameObject("death line", new Type[1] { typeof(RectTransform) });
				linePrefab.SetActive(false);
				linePrefab.transform.localPosition = Vector3.zero;
				RectTransform val2 = (RectTransform)linePrefab.transform;
				val2.pivot = val;
				val2.anchorMin = val;
				val2.anchorMax = val;
				val2.sizeDelta = new Vector2((float)(300 * DarwinAwards.fontSize.Value) / 14f, 200f);
				Text obj = linePrefab.AddComponent<Text>();
				obj.font = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font x) => ((Object)x).name == DarwinAwards.font.Value.ToString().Replace("_", "-")));
				obj.fontSize = DarwinAwards.fontSize.Value;
				obj.alignment = (TextAnchor)3;
				obj.lineSpacing = 0.8f;
				Outline obj2 = linePrefab.AddComponent<Outline>();
				((Shadow)obj2).effectColor = Color.black;
				((Shadow)obj2).effectDistance = new Vector2(1f, -1f);
				GameObject val3 = new GameObject("Death Icon");
				val3.transform.SetParent(linePrefab.transform);
				val3.AddComponent<Image>();
				RectTransform component = val3.GetComponent<RectTransform>();
				component.sizeDelta = new Vector2((float)(DarwinAwards.fontSize.Value + 2), (float)(DarwinAwards.fontSize.Value + 2));
				component.anchoredPosition = new Vector2((float)(-(DarwinAwards.fontSize.Value + 2)) / 16f * 20f, 0f);
				component.pivot = val;
				component.anchorMin = val;
				component.anchorMax = val;
			}
		}

		private static GameObject? deaths;

		private static GameObject linePrefab = null;

		private static readonly Dictionary<string, Sprite> iconMap = new Dictionary<string, Sprite>();

		public static void FillIconMap()
		{
			iconMap.Add("general", Helper.loadSprite("death-skull.png"));
			iconMap.Add("death by fire", Helper.loadSprite("fire.png"));
			iconMap.Add("death by poison", Helper.loadSprite("poison-bottle.png"));
			iconMap.Add("death by frost", Helper.loadSprite("death-skull.png"));
			iconMap.Add("death by lightning", Helper.loadSprite("lightning.png"));
			iconMap.Add("death by elemental", Helper.loadSprite("minerals.png"));
			iconMap.Add("death by tree", Helper.loadSprite("treedeath.png"));
			iconMap.Add("death by pierce", Helper.loadSprite("pierced-body.png"));
			iconMap.Add("death by slash", Helper.loadSprite("slash.png"));
			iconMap.Add("death by blunt", Helper.loadSprite("blunt.png"));
			iconMap.Add("death by physical", Helper.loadSprite("physical.png"));
			iconMap.Add("death by gravity", Helper.loadSprite("fall.png"));
			iconMap.Add("death by drowning", Helper.loadSprite("drowning.png"));
			iconMap.Add("death by player", Helper.loadSprite("skull-crack.png"));
			iconMap.Add("death by creature", Helper.loadSprite("monsterdeath.png"));
			iconMap.Add("death by boss", Helper.loadSprite("bossdeath.png"));
		}

		public static void AddText(DarwinAwards.DeathText text)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(linePrefab, deaths.transform);
			val.SetActive(true);
			((RectTransform)val.transform).anchoredPosition = new Vector2(0f, (float)DarwinAwards.fontSize.Value / 14f * 25f * (float)(deaths.transform.childCount - 1));
			val.GetComponent<Text>().text = text.text;
			val.AddComponent<SaveTime>();
			if (DarwinAwards.timerForDeaths.Value != 0)
			{
				val.AddComponent<TimedDestruction>().Trigger((float)DarwinAwards.timerForDeaths.Value);
			}
			((Component)val.transform.Find("Death Icon")).GetComponent<Image>().sprite = iconMap[text.category];
			if (deaths.transform.childCount > DarwinAwards.numberOfDeaths.Value)
			{
				for (int i = 1; i < deaths.transform.childCount; i++)
				{
					((RectTransform)((Component)deaths.transform.GetChild(i)).transform).anchoredPosition = new Vector2(0f, (float)DarwinAwards.fontSize.Value / 14f * 25f * (float)(i - 1));
				}
				Object.Destroy((Object)(object)((Component)deaths.transform.GetChild(0)).gameObject);
			}
		}

		public static void CheckDeathTimes(object sender, EventArgs e)
		{
			if (deaths == null)
			{
				return;
			}
			for (int i = 0; i < deaths.transform.childCount; i++)
			{
				Transform child = deaths.transform.GetChild(i);
				if (DarwinAwards.timerForDeaths.Value != 0 && ((Component)child).GetComponent<SaveTime>().timeCreated + (float)DarwinAwards.timerForDeaths.Value < Time.fixedTime)
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
					continue;
				}
				TimedDestruction component = ((Component)deaths.transform.GetChild(i)).GetComponent<TimedDestruction>();
				if (component != null)
				{
					((MonoBehaviour)component).CancelInvoke("DestroyNow");
				}
				if (DarwinAwards.timerForDeaths.Value != 0)
				{
					TimedDestruction obj = (Object.op_Implicit((Object)(object)component) ? component : ((Component)child).gameObject.AddComponent<TimedDestruction>());
					if (obj != null)
					{
						obj.Trigger((float)DarwinAwards.timerForDeaths.Value - (Time.fixedTime - ((Component)child).GetComponent<SaveTime>().timeCreated));
					}
				}
			}
		}

		public static void AnchorDeathLog(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (deaths != null)
			{
				deaths.transform.localPosition = Vector2.op_Implicit(DarwinAwards.deathLogAnchor.Value);
				((Component)deaths.transform).GetComponent<DragNDrop>().SetPosition(deaths.transform.position);
			}
		}

		public static void UpdateFont(object sender, EventArgs e)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			if (deaths != null)
			{
				Text component = linePrefab.GetComponent<Text>();
				component.font = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font x) => ((Object)x).name == DarwinAwards.font.Value.ToString().Replace("_", "-")));
				component.fontSize = DarwinAwards.fontSize.Value;
				((Graphic)component).rectTransform.sizeDelta = new Vector2((float)(300 * DarwinAwards.fontSize.Value) / 14f, 200f);
				RectTransform val = (RectTransform)linePrefab.transform.Find("Death Icon");
				val.sizeDelta = new Vector2((float)(DarwinAwards.fontSize.Value + 2), (float)(DarwinAwards.fontSize.Value + 2));
				val.anchoredPosition = new Vector2((float)(-(DarwinAwards.fontSize.Value + 2)) / 16f * 20f, 0f);
				for (int i = 0; i < deaths.transform.childCount; i++)
				{
					Text component2 = ((Component)deaths.transform.GetChild(i)).GetComponent<Text>();
					component2.font = component.font;
					component2.fontSize = component.fontSize;
					((Graphic)component2).rectTransform.sizeDelta = new Vector2((float)(300 * DarwinAwards.fontSize.Value) / 14f, 200f);
					RectTransform val2 = (RectTransform)((Component)component2).transform.Find("Death Icon");
					val2.sizeDelta = new Vector2((float)(DarwinAwards.fontSize.Value + 2), (float)(DarwinAwards.fontSize.Value + 2));
					val2.anchoredPosition = new Vector2((float)(-(DarwinAwards.fontSize.Value + 2)) / 16f * 20f, 0f);
					((Graphic)component2).rectTransform.anchoredPosition = new Vector2(0f, (float)DarwinAwards.fontSize.Value / 14f * 25f * (float)i);
				}
				((Component)deaths.transform).GetComponent<DragNDrop>().SetPosition(deaths.transform.position);
			}
		}
	}
	public class DragNDrop : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler
	{
		public RectTransform target;

		public bool shouldReturn;

		private bool isMouseDown;

		private Vector3 startMousePosition;

		private Vector3 startPosition;

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			target = (RectTransform)((Component)this).transform;
		}

		private void Update()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (isMouseDown)
			{
				Vector3 val = Input.mousePosition - startMousePosition;
				Vector3 position = startPosition + val;
				SetPosition(position);
			}
		}

		public void SetPosition(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 sizeDelta = target.sizeDelta;
			position.x = Mathf.Clamp(position.x, sizeDelta.x / 2f, (float)Screen.width - sizeDelta.x / 2f);
			position.y = Mathf.Clamp(position.y, sizeDelta.y / 2f, (float)Screen.height - sizeDelta.y / 2f);
			((Transform)target).position = position;
			DarwinAwards.deathLogAnchor.Value = Vector2.op_Implicit(((Transform)target).localPosition);
		}

		public void OnPointerDown(PointerEventData dt)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			isMouseDown = true;
			startPosition = ((Transform)target).position;
			((Transform)target).position = startPosition;
			startMousePosition = Input.mousePosition;
		}

		public void OnPointerUp(PointerEventData dt)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			isMouseDown = false;
			if (shouldReturn)
			{
				((Transform)target).position = startPosition;
				DarwinAwards.deathLogAnchor.Value = Vector2.op_Implicit(((Transform)target).localPosition);
			}
		}
	}
	public static class Helper
	{
		private static byte[] ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Assembly.GetExecutingAssembly().GetManifestResourceStream("DarwinAwards." + name)?.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static Texture2D loadTexture(string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name));
			return val;
		}

		public static Sprite loadSprite(string name, int width = 64, int height = 64)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
		}
	}
	public class SaveTime : MonoBehaviour
	{
		public float timeCreated;

		public void Awake()
		{
			timeCreated = Time.fixedTime;
		}
	}
}

DarwinAwards/YamlDotNet.dll

Decompiled 10 months 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.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.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("11.2.1.0")]
[assembly: AssemblyInformationalVersion("11.2.1")]
[assembly: AssemblyTitle("YamlDotNet")]
[assembly: AssemblyDescription("The YamlDotNet library.")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("YamlDotNet")]
[assembly: AssemblyCopyright("Copyright (c) Antoine Aubry and contributors 2008 - 2019")]
[assembly: AssemblyTrademark("")]
[assembly: CLSCompliant(true)]
[assembly: InternalsVisibleTo("YamlDotNet.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010065e52a453dde5c5b4be5bbe2205755727fce80244b79b894faf8793d80f7db9a96d360b51c220782db32aacee4cb5b8a91bee33aeec700e1f21895c4baadef501eeeac609220d1651603b378173811ee5bb6a002df973d38821bd2fef820c00c174a69faec326a1983b570f07ec66147026b9c8753465de3a8d0c44b613b02af")]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyVersion("11.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
}
namespace System.Collections.Generic
{
	internal static class DeconstructionExtensions
	{
		public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value)
		{
			key = pair.Key;
			value = pair.Value;
		}
	}
}
namespace YamlDotNet
{
	internal sealed class CultureInfoAdapter : CultureInfo
	{
		private readonly IFormatProvider provider;

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

		public override object? GetFormat(Type? formatType)
		{
			return provider.GetFormat(formatType);
		}
	}
	internal static class ReflectionExtensions
	{
		private static readonly FieldInfo? RemoteStackTraceField = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic);

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

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

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

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

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

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

		public static bool IsDbNull(this object value)
		{
			return value is DBNull;
		}

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

		public static TypeCode GetTypeCode(this Type type)
		{
			return Type.GetTypeCode(type);
		}

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

		public static FieldInfo? GetPublicStaticField(this Type type, string name)
		{
			return type.GetField(name, BindingFlags.Static | BindingFlags.Public);
		}

		public static IEnumerable<PropertyInfo> GetProperties(this Type type, bool includeNonPublic)
		{
			BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
			if (includeNonPublic)
			{
				bindingFlags |= BindingFlags.NonPublic;
			}
			if (!type.IsInterface)
			{
				return type.GetProperties(bindingFlags);
			}
			return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetProperties(bindingFlags));
		}

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

		public static IEnumerable<FieldInfo> GetPublicFields(this Type type)
		{
			return type.GetFields(BindingFlags.Instance | BindingFlags.Public);
		}

		public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type)
		{
			return type.GetMethods(BindingFlags.Static | BindingFlags.Public);
		}

		public static MethodInfo GetPrivateStaticMethod(this Type type, string name)
		{
			return type.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic) ?? throw new MissingMethodException("Expected to find a method named '" + name + "' in '" + type.FullName + "'.");
		}

		public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes)
		{
			return type.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, parameterTypes, null);
		}

		public static MethodInfo? GetPublicInstanceMethod(this Type type, string name)
		{
			return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public);
		}

		public static Exception Unwrap(this TargetInvocationException ex)
		{
			Exception innerException = ex.InnerException;
			if (innerException == null)
			{
				return ex;
			}
			if (RemoteStackTraceField != null)
			{
				RemoteStackTraceField.SetValue(innerException, innerException.StackTrace + "\r\n");
			}
			return innerException;
		}

		public static bool IsInstanceOf(this Type type, object o)
		{
			return type.IsInstanceOfType(o);
		}

		public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo property)
		{
			return Attribute.GetCustomAttributes(property, typeof(TAttribute));
		}
	}
	internal static class PropertyInfoExtensions
	{
		public static object? ReadValue(this PropertyInfo property, object target)
		{
			return property.GetValue(target, null);
		}
	}
	internal static class StandardRegexOptions
	{
		public const RegexOptions Compiled = RegexOptions.Compiled;
	}
}
namespace YamlDotNet.Serialization
{
	public abstract class BuilderSkeleton<TBuilder> where TBuilder : BuilderSkeleton<TBuilder>
	{
		internal INamingConvention namingConvention = NullNamingConvention.Instance;

		internal ITypeResolver typeResolver;

		internal readonly YamlAttributeOverrides overrides;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		private bool ignoreFields;

		private bool includeNonPublicProperties;

		protected abstract TBuilder Self { get; }

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

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

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

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

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

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

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

		public TBuilder WithAttributeOverride<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute)
		{
			overrides.Add(propertyAccessor, attribute);
			return Self;
		}

		public TBuilder WithAttributeOverride(Type type, string member, Attribute attribute)
		{
			overrides.Add(type, member, attribute);
			return Self;
		}

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

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where)
		{
			IYamlTypeConverter typeConverter2 = typeConverter;
			if (typeConverter2 == null)
			{
				throw new ArgumentNullException("typeConverter");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2));
			return Self;
		}

		public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter
		{
			WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory2 = typeConverterFactory;
			if (typeConverterFactory2 == null)
			{
				throw new ArgumentNullException("typeConverterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(wrapped)));
			return Self;
		}

		public TBuilder WithoutTypeConverter<TYamlTypeConverter>() where TYamlTypeConverter : IYamlTypeConverter
		{
			return WithoutTypeConverter(typeof(TYamlTypeConverter));
		}

		public TBuilder WithoutTypeConverter(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			typeConverterFactories.Remove(converterType);
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory) where TTypeInspector : ITypeInspector
		{
			return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory, Action<IRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			Func<ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner)));
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(wrapped, inner)));
			return Self;
		}

		public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector
		{
			return WithoutTypeInspector(typeof(TTypeInspector));
		}

		public TBuilder WithoutTypeInspector(Type inspectorType)
		{
			if (inspectorType == null)
			{
				throw new ArgumentNullException("inspectorType");
			}
			typeInspectorFactories.Remove(inspectorType);
			return Self;
		}

		protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
		{
			return typeConverterFactories.BuildComponentList();
		}
	}
	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 object? Deserialize(TextReader input)
		{
			return Deserialize(input, typeof(object));
		}

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

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

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

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

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

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<TagName, Type> tagMappings;

		private readonly Dictionary<Type, Type> typeMappings;

		private bool ignoreUnmatched;

		protected override DeserializerBuilder Self => this;

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

		public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory)
		{
			IObjectFactory objectFactory2 = objectFactory;
			if (objectFactory2 == null)
			{
				throw new ArgumentNullException("objectFactory");
			}
			this.objectFactory = new Lazy<IObjectFactory>(() => objectFactory2, isThreadSafe: true);
			return this;
		}

		public DeserializerBuilder WithObjectFactory(Func<Type, object> objectFactory)
		{
			if (objectFactory == null)
			{
				throw new ArgumentNullException("objectFactory");
			}
			return WithObjectFactory(new LambdaObjectFactory(objectFactory));
		}

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

		public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where)
		{
			INodeDeserializer nodeDeserializer2 = nodeDeserializer;
			if (nodeDeserializer2 == null)
			{
				throw new ArgumentNullException("nodeDeserializer");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2));
			return this;
		}

		public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer
		{
			WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory2 = nodeDeserializerFactory;
			if (nodeDeserializerFactory2 == null)
			{
				throw new ArgumentNullException("nodeDeserializerFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(wrapped)));
			return this;
		}

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

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

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

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where)
		{
			INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver;
			if (nodeTypeResolver2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolver");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2));
			return this;
		}

		public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver
		{
			WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory2 = nodeTypeResolverFactory;
			if (nodeTypeResolverFactory2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolverFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(wrapped)));
			return this;
		}

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

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

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

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

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

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

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

		public IValueDeserializer BuildValueDeserializer()
		{
			return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList()));
		}
	}
	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);

		object? Deserialize(TextReader input);

		object? Deserialize(string input, Type type);

		object? Deserialize(TextReader input, Type type);

		T Deserialize<T>(IParser parser);

		object? Deserialize(IParser parser);

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

		void Emit(ScalarEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingStartEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingEndEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter);
	}
	public interface INamingConvention
	{
		string Apply(string value);
	}
	public interface INodeDeserializer
	{
		bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value);
	}
	public interface INodeTypeResolver
	{
		bool Resolve(NodeEvent? nodeEvent, ref Type currentType);
	}
	public interface IObjectDescriptor
	{
		object? Value { get; }

		Type Type { get; }

		Type StaticType { get; }

		ScalarStyle ScalarStyle { get; }
	}
	public static class ObjectDescriptorExtensions
	{
		public static object NonNullValue(this IObjectDescriptor objectDescriptor)
		{
			return objectDescriptor.Value ?? throw new InvalidOperationException("Attempted to use a IObjectDescriptor of type '" + objectDescriptor.Type.FullName + "' whose Value is null at a point whete it is invalid to do so. This may indicate a bug in YamlDotNet.");
		}
	}
	public interface IObjectFactory
	{
		object Create(Type type);
	}
	public interface IObjectGraphTraversalStrategy
	{
		void Traverse<TContext>(IObjectDescriptor graph, IObjectGraphVisitor<TContext> visitor, TContext context);
	}
	public interface IObjectGraphVisitor<TContext>
	{
		bool Enter(IObjectDescriptor value, TContext context);

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

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

		void VisitScalar(IObjectDescriptor scalar, TContext context);

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

		void VisitMappingEnd(IObjectDescriptor mapping, TContext context);

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

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

		bool CanWrite { get; }

		Type Type { get; }

		Type? TypeOverride { get; set; }

		int Order { get; set; }

		ScalarStyle ScalarStyle { get; set; }

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

		IObjectDescriptor Read(object target);

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

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

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

		void OnTop();

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

		string Serialize(object graph);

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

		void Serialize(IEmitter emitter, object graph);

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

		IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched);
	}
	public interface ITypeResolver
	{
		Type Resolve(Type staticType, object? actualValue);
	}
	public interface IValueDeserializer
	{
		object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer);
	}
	public interface IValuePromise
	{
		event Action<object?> ValueAvailable;
	}
	public interface IValueSerializer
	{
		void SerializeValue(IEmitter emitter, object? value, Type? type);
	}
	public interface IYamlConvertible
	{
		void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer);

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

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

		object? ReadYaml(IParser parser, Type type);

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

			public readonly Func<TArgument, TComponent> Factory;

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

		public sealed class TrackingLazyComponentRegistration
		{
			public readonly Type ComponentType;

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

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

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

			private readonly LazyComponentRegistration newRegistration;

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

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

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

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

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

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

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

			private readonly TrackingLazyComponentRegistration newRegistration;

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

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

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

		public int Count => entries.Count;

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

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

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

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

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

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

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

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

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

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

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

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

		public static List<TComponent> BuildComponentList<TComponent>(this LazyComponentRegistrationList<Nothing, TComponent> registrations)
		{
			return registrations.Select((Func<Nothing, TComponent> factory) => factory(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 string Name { get; set; }

		public Type Type => baseDescriptor.Type;

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

		public int Order { get; set; }

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

		public bool CanWrite => baseDescriptor.CanWrite;

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

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

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

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

		private readonly EmitterSettings emitterSettings;

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

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

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

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

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

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

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

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

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

			private readonly IEventEmitter eventEmitter;

			private readonly IEnumerable<IYamlTypeConverter> typeConverters;

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

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

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

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

		private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory;

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

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

		private readonly LazyComponentRegistrationList<IEventEmitter, IEventEmitter> eventEmitterFactories;

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

		private int maximumRecursion = 50;

		private EmitterSettings emitterSettings = EmitterSettings.Default;

		private DefaultValuesHandling defaultValuesHandlingConfiguration;

		protected override SerializerBuilder Self => this;

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

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

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

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

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

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

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

		public override SerializerBuilder WithTagMapping(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);
			WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
			return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc)
			{
				loc.OnBottom();
			});
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public 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 sealed class StreamFragment : IYamlConvertible
	{
		private readonly List<ParsingEvent> events = new List<ParsingEvent>();

		public IList<ParsingEvent> Events => events;

		void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
		{
			events.Clear();
			int num = 0;
			do
			{
				if (!parser.MoveNext())
				{
					throw new InvalidOperationException("The parser has reached the end before deserialization completed.");
				}
				ParsingEvent current = parser.Current;
				events.Add(current);
				num += current.NestingIncrease;
			}
			while (num > 0);
		}

		void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
		{
			foreach (ParsingEvent @event in events)
			{
				emitter.Emit(@event);
			}
		}
	}
	public sealed class TagMappings
	{
		private readonly IDictionary<string, Type> mappings;

		public TagMappings()
		{
			mappings = new Dictionary<string, Type>();
		}

		public TagMappings(IDictionary<string, Type> mappings)
		{
			this.mappings = new Dictionary<string, Type>(mappings);
		}

		public void Add(string tag, Type mapping)
		{
			mappings.Add(tag, mapping);
		}

		internal Type? GetMapping(string tag)
		{
			if (!mappings.TryGetValue(tag, out Type value))
			{
				return null;
			}
			return value;
		}
	}
	public sealed class YamlAttributeOverrides
	{
		private struct AttributeKey
		{
			public readonly Type AttributeType;

			public readonly string PropertyName;

			public AttributeKey(Type attributeType, string propertyName)
			{
				AttributeType = attributeType;
				PropertyName = propertyName;
			}

			public override bool Equals(object? obj)
			{
				if (obj is AttributeKey attributeKey && AttributeType.Equals(attributeKey.AttributeType))
				{
					return PropertyName.Equals(attributeKey.PropertyName);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return YamlDotNet.Core.HashCode.CombineHashCodes(AttributeType.GetHashCode(), PropertyName.GetHashCode());
			}
		}

		private sealed class AttributeMapping
		{
			public readonly Type RegisteredType;

			public readonly Attribute Attribute;

			public AttributeMapping(Type registeredType, Attribute attribute)
			{
				RegisteredType = registeredType;
				Attribute = attribute;
			}

			public override bool Equals(object? obj)
			{
				if (obj is AttributeMapping attributeMapping && RegisteredType.Equals(attributeMapping.RegisteredType))
				{
					return Attribute.Equals(attributeMapping.Attribute);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return YamlDotNet.Core.HashCode.CombineHashCodes(RegisteredType.GetHashCode(), Attribute.GetHashCode());
			}

			public int Matches(Type matchType)
			{
				int num = 0;
				Type type = matchType;
				while (type != null)
				{
					num++;
					if (type == RegisteredType)
					{
						return num;
					}
					type = type.BaseType();
				}
				if (matchType.GetInterfaces().Contains(RegisteredType))
				{
					return num;
				}
				return 0;
			}
		}

		private readonly Dictionary<AttributeKey, List<AttributeMapping>> overrides = new Dictionary<AttributeKey, List<AttributeMapping>>();

		public T? GetAttribute<T>(Type type, string member) where T : Attribute
		{
			if (overrides.TryGetValue(new AttributeKey(typeof(T), member), out List<AttributeMapping> value))
			{
				int num = 0;
				AttributeMapping attributeMapping = null;
				foreach (AttributeMapping item in value)
				{
					int num2 = item.Matches(type);
					if (num2 > num)
					{
						num = num2;
						attributeMapping = item;
					}
				}
				if (num > 0)
				{
					return (T)attributeMapping.Attribute;
				}
			}
			return null;
		}

		public void Add(Type type, string member, Attribute attribute)
		{
			AttributeMapping item = new AttributeMapping(type, attribute);
			AttributeKey key = new AttributeKey(attribute.GetType(), member);
			if (!overrides.TryGetValue(key, out List<AttributeMapping> value))
			{
				value = new List<AttributeMapping>();
				overrides.Add(key, value);
			}
			else if (value.Contains(item))
			{
				throw new InvalidOperationException($"Attribute ({attribute}) already set for Type {type.FullName}, Member {member}");
			}
			value.Add(item);
		}

		public YamlAttributeOverrides Clone()
		{
			YamlAttributeOverrides yamlAttributeOverrides = new YamlAttributeOverrides();
			foreach (KeyValuePair<AttributeKey, List<AttributeMapping>> @override in overrides)
			{
				foreach (AttributeMapping item in @override.Value)
				{
					yamlAttributeOverrides.Add(item.RegisteredType, @override.Key.PropertyName, item.Attribute);
				}
			}
			return yamlAttributeOverrides;
		}

		public void Add<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute)
		{
			PropertyInfo propertyInfo = propertyAccessor.AsProperty();
			Add(typeof(TClass), propertyInfo.Name, attribute);
		}
	}
	public sealed class YamlAttributeOverridesInspector : TypeInspectorSkeleton
	{
		public sealed class OverridePropertyDescriptor : IPropertyDescriptor
		{
			private readonly IPropertyDescriptor baseDescriptor;

			private readonly YamlAttributeOverrides overrides;

			private readonly Type classType;

			public string Name => baseDescriptor.Name;

			public bool CanWrite => baseDescriptor.CanWrite;

			public Type Type => baseDescriptor.Type;

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

			public int Order
			{
				get
				{
					return baseDescriptor.Order;
				}
				set
				{
					baseDescriptor.Order = value;
				}
			}

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

			public OverridePropertyDescriptor(IPropertyDescriptor baseDescriptor, YamlAttributeOverrides overrides, Type classType)
			{
				this.baseDescriptor = baseDescriptor;
				this.overrides = overrides;
				this.classType = classType;
			}

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

			public T GetCustomAttribute<T>() where T : Attribute
			{
				return overrides.GetAttribute<T>(classType, Name) ?? baseDescriptor.GetCustomAttribute<T>();
			}

			public IObjectDescriptor Read(object target)
			{
				return baseDescriptor.Read(target);
			}
		}

		private readonly ITypeInspector innerTypeDescriptor;

		private readonly YamlAttributeOverrides overrides;

		public YamlAttributeOverridesInspector(ITypeInspector innerTypeDescriptor, YamlAttributeOverrides overrides)
		{
			this.innerTypeDescriptor = innerTypeDescriptor;
			this.overrides = overrides;
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			Type type2 = type;
			IEnumerable<IPropertyDescriptor> enumerable = innerTypeDescriptor.GetProperties(type2, container);
			if (overrides != null)
			{
				enumerable = enumerable.Select((Func<IPropertyDescriptor, IPropertyDescriptor>)((IPropertyDescriptor p) => new OverridePropertyDescriptor(p, overrides, type2)));
			}
			return enumerable;
		}
	}
	public sealed class YamlAttributesTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		public YamlAttributesTypeInspector(ITypeInspector innerTypeDescriptor)
		{
			this.innerTypeDescriptor = innerTypeDescriptor;
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return from p in (from p in innerTypeDescriptor.GetProperties(type, container)
					where p.GetCustomAttribute<YamlIgnoreAttribute>() == null
					select p).Select((Func<IPropertyDescriptor, IPropertyDescriptor>)delegate(IPropertyDescriptor p)
				{
					PropertyDescriptor propertyDescriptor = new PropertyDescriptor(p);
					YamlMemberAttribute customAttribute = p.GetCustomAttribute<YamlMemberAttribute>();
					if (customAttribute != null)
					{
						if (customAttribute.SerializeAs != null)
						{
							propertyDescriptor.TypeOverride = customAttribute.SerializeAs;
						}
						propertyDescriptor.Order = customAttribute.Order;
						propertyDescriptor.ScalarStyle = customAttribute.ScalarStyle;
						if (customAttribute.Alias != null)
						{
							propertyDescriptor.Name = customAttribute.Alias;
						}
					}
					return propertyDescriptor;
				})
				orderby p.Order
				select p;
		}
	}
	internal static class YamlFormatter
	{
		public static readonly NumberFormatInfo NumberFormat = new NumberFormatInfo
		{
			CurrencyDecimalSeparator = ".",
			CurrencyGroupSeparator = "_",
			CurrencyGroupSizes = new int[1] { 3 },
			CurrencySymbol = string.Empty,
			CurrencyDecimalDigits = 99,
			NumberDecimalSeparator = ".",
			NumberGroupSeparator = "_",
			NumberGroupSizes = new int[1] { 3 },
			NumberDecimalDigits = 99,
			NaNSymbol = ".nan",
			PositiveInfinitySymbol = ".inf",
			NegativeInfinitySymbol = "-.inf"
		};

		public static string FormatNumber(object number)
		{
			return Convert.ToString(number, NumberFormat);
		}

		public static string FormatNumber(double number)
		{
			return number.ToString("G17", NumberFormat);
		}

		public static string FormatNumber(float number)
		{
			return number.ToString("G17", NumberFormat);
		}

		public static string FormatBoolean(object boolean)
		{
			if (!boolean.Equals(true))
			{
				return "false";
			}
			return "true";
		}

		public static string FormatDateTime(object dateTime)
		{
			return ((DateTime)dateTime).ToString("o", CultureInfo.InvariantCulture);
		}

		public static string FormatTimeSpan(object timeSpan)
		{
			return ((TimeSpan)timeSpan).ToString();
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class YamlIgnoreAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class YamlMemberAttribute : Attribute
	{
		private DefaultValuesHandling? defaultValuesHandling;

		public string? Description { get; set; }

		public Type? SerializeAs { get; set; }

		public int Order { get; set; }

		public string? Alias { get; set; }

		public bool ApplyNamingConventions { get; set; }

		public ScalarStyle ScalarStyle { get; set; }

		public DefaultValuesHandling DefaultValuesHandling
		{
			get
			{
				return defaultValuesHandling.GetValueOrDefault();
			}
			set
			{
				defaultValuesHandling = value;
			}
		}

		public bool IsDefaultValuesHandlingSpecified => defaultValuesHandling.HasValue;

		public YamlMemberAttribute()
		{
			ScalarStyle = ScalarStyle.Any;
			ApplyNamingConventions = true;
		}

		public YamlMemberAttribute(Type serializeAs)
			: this()
		{
			SerializeAs = serializeAs ?? throw new ArgumentNullException("serializeAs");
		}
	}
}
namespace YamlDotNet.Serialization.ValueDeserializers
{
	public sealed class AliasValueDeserializer : IValueDeserializer
	{
		private sealed class AliasState : Dictionary<AnchorName, ValuePromise>, IPostDeserializationCallback
		{
			public void OnDeserialization()
			{
				foreach (ValuePromise value in base.Values)
				{
					if (!value.HasValue)
					{
						YamlDotNet.Core.Events.AnchorAlias alias = value.Alias;
						throw new AnchorNotFoundException(alias.Start, alias.End, $"Anchor '{alias.Value}' not found");
					}
				}
			}
		}

		private sealed class ValuePromise : IValuePromise
		{
			private object? value;

			public readonly YamlDotNet.Core.Events.AnchorAlias? Alias;

			public bool HasValue { get; private set; }

			public object? Value
			{
				get
				{
					if (!HasValue)
					{
						throw new InvalidOperationException("Value not set");
					}
					return value;
				}
				set
				{
					if (HasValue)
					{
						throw new InvalidOperationException("Value already set");
					}
					HasValue = true;
					this.value = value;
					this.ValueAvailable?.Invoke(value);
				}
			}

			public event Action<object?>? ValueAvailable;

			public ValuePromise(YamlDotNet.Core.Events.AnchorAlias alias)
			{
				Alias = alias;
			}

			public ValuePromise(object? value)
			{
				HasValue = true;
				this.value = value;
			}
		}

		private readonly IValueDeserializer innerDeserializer;

		public AliasValueDeserializer(IValueDeserializer innerDeserializer)
		{
			this.innerDeserializer = innerDeserializer ?? throw new ArgumentNullException("innerDeserializer");
		}

		public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
		{
			if (parser.TryConsume<YamlDotNet.Core.Events.AnchorAlias>(out var @event))
			{
				if (!state.Get<AliasState>().TryGetValue(@event.Value, out ValuePromise value))
				{
					throw new AnchorNotFoundException(@event.Start, @event.End, $"Alias ${@event.Value} cannot precede anchor declaration");
				}
				if (!value.HasValue)
				{
					return value;
				}
				return value.Value;
			}
			AnchorName anchorName = AnchorName.Empty;
			if (parser.Accept<NodeEvent>(out var event2) && !event2.Anchor.IsEmpty)
			{
				anchorName = event2.Anchor;
				AliasState aliasState = state.Get<AliasState>();
				if (!aliasState.ContainsKey(anchorName))
				{
					aliasState[anchorName] = new ValuePromise(new YamlDotNet.Core.Events.AnchorAlias(anchorName));
				}
			}
			object obj = innerDeserializer.DeserializeValue(parser, expectedType, state, nestedObjectDeserializer);
			if (!anchorName.IsEmpty)
			{
				AliasState aliasState2 = state.Get<AliasState>();
				if (!aliasState2.TryGetValue(anchorName, out ValuePromise value2))
				{
					aliasState2.Add(anchorName, new ValuePromise(obj));
				}
				else if (!value2.HasValue)
				{
					value2.Value = obj;
				}
				else
				{
					aliasState2[anchorName] = new ValuePromise(obj);
				}
			}
			return obj;
		}
	}
	public sealed class NodeValueDeserializer : IValueDeserializer
	{
		private readonly IList<INodeDeserializer> deserializers;

		private readonly IList<INodeTypeResolver> typeResolvers;

		public NodeValueDeserializer(IList<INodeDeserializer> deserializers, IList<INodeTypeResolver> typeResolvers)
		{
			this.deserializers = deserializers ?? throw new ArgumentNullException("deserializers");
			this.typeResolvers = typeResolvers ?? throw new ArgumentNullException("typeResolvers");
		}

		public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
		{
			IValueDeserializer nestedObjectDeserializer2 = nestedObjectDeserializer;
			SerializerState state2 = state;
			parser.Accept<NodeEvent>(out var @event);
			Type typeFromEvent = GetTypeFromEvent(@event, expectedType);
			try
			{
				foreach (INodeDeserializer deserializer in deserializers)
				{
					if (deserializer.Deserialize(parser, typeFromEvent, (IParser r, Type t) => nestedObjectDeserializer2.DeserializeValue(r, t, state2, nestedObjectDeserializer2), out object value))
					{
						return YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(value, expectedType);
					}
				}
			}
			catch (YamlException)
			{
				throw;
			}
			catch (Exception innerException)
			{
				throw new YamlException(@event?.Start ?? Mark.Empty, @event?.End ?? Mark.Empty, "Exception during deserialization", innerException);
			}
			throw new YamlException(@event?.Start ?? Mark.Empty, @event?.End ?? Mark.Empty, "No node deserializer was able to deserialize the node into type " + expectedType.AssemblyQualifiedName);
		}

		private Type GetTypeFromEvent(NodeEvent? nodeEvent, Type currentType)
		{
			using (IEnumerator<INodeTypeResolver> enumerator = typeResolvers.GetEnumerator())
			{
				while (enumerator.MoveNext() && !enumerator.Current.Resolve(nodeEvent, ref currentType))
				{
				}
			}
			return currentType;
		}
	}
}
namespace YamlDotNet.Serialization.Utilities
{
	public interface IPostDeserializationCallback
	{
		void OnDeserialization();
	}
	internal sealed class ObjectAnchorCollection
	{
		private readonly IDictionary<string, object> objectsByAnchor = new Dictionary<string, object>();

		private readonly IDictionary<object, string> anchorsByObject = new Dictionary<object, string>();

		public object this[string anchor]
		{
			get
			{
				if (objectsByAnchor.TryGetValue(anchor, out object value))
				{
					return value;
				}
				throw new AnchorNotFoundException("The anchor '" + anchor + "' does not exists");
			}
		}

		public void Add(string anchor, object @object)
		{
			objectsByAnchor.Add(anchor, @object);
			if (@object != null)
			{
				anchorsByObject.Add(@object, anchor);
			}
		}

		public bool TryGetAnchor(object @object, [MaybeNullWhen(false)] out string? anchor)
		{
			return anchorsByObject.TryGetValue(@object, out anchor);
		}
	}
	internal static class ReflectionUtility
	{
		public static Type? GetImplementedGenericInterface(Type type, Type genericInterfaceType)
		{
			foreach (Type implementedInterface in GetImplementedInterfaces(type))
			{
				if (implementedInterface.IsGenericType() && implementedInterface.GetGenericTypeDefinition() == genericInterfaceType)
				{
					return implementedInterface;
				}
			}
			return null;
		}

		public static IEnumerable<Type> GetImplementedInterfaces(Type type)
		{
			if (type.IsInterface())
			{
				yield return type;
			}
			Type[] interfaces = type.GetInterfaces();
			for (int i = 0; i < interfaces.Length; i++)
			{
				yield return interfaces[i];
			}
		}
	}
	public sealed class SerializerState : IDisposable
	{
		private readonly IDictionary<Type, object> items = new Dictionary<Type, object>();

		public T Get<T>() where T : class, new()
		{
			if (!items.TryGetValue(typeof(T), out object value))
			{
				value = new T();
				items.Add(typeof(T), value);
			}
			return (T)value;
		}

		public void OnDeserialization()
		{
			foreach (IPostDeserializationCallback item in items.Values.OfType<IPostDeserializationCallback>())
			{
				item.OnDeserialization();
			}
		}

		public void Dispose()
		{
			foreach (IDisposable item in items.Values.OfType<IDisposable>())
			{
				item.Dispose();
			}
		}
	}
	internal static class StringExtensions
	{
		private static string ToCamelOrPascalCase(string str, Func<char, char> firstLetterTransform)
		{
			string text = Regex.Replace(str, "([_\\-])(?<char>[a-z])", (Match match) => match.Groups["char"].Value.ToUpperInvariant(), RegexOptions.IgnoreCase);
			return firstLetterTransform(text[0]) + text.Substring(1);
		}

		public static string ToCamelCase(this string str)
		{
			return ToCamelOrPascalCase(str, char.ToLowerInvariant);
		}

		public static string ToPascalCase(this string str)
		{
			return ToCamelOrPascalCase(str, char.ToUpperInvariant);
		}

		public static string FromCamelCase(this string str, string separator)
		{
			string separator2 = separator;
			str = char.ToLower(str[0]) + str.Substring(1);
			str = Regex.Replace(str.ToCamelCase(), "(?<char>[A-Z])", (Match match) => separator2 + match.Groups["char"].Value.ToLowerInvariant());
			return str;
		}
	}
	public static class TypeConverter
	{
		public static T ChangeType<T>(object? value)
		{
			return (T)ChangeType(value, typeof(T));
		}

		public static T ChangeType<T>(object? value, IFormatProvider provider)
		{
			return (T)ChangeType(value, typeof(T), provider);
		}

		public static T ChangeType<T>(object? value, CultureInfo culture)
		{
			return (T)ChangeType(value, typeof(T), culture);
		}

		public static object? ChangeType(object? value, Type destinationType)
		{
			return ChangeType(value, destinationType, CultureInfo.InvariantCulture);
		}

		public static object? ChangeType(object? value, Type destinationType, IFormatProvider provider)
		{
			return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider));
		}

		public static object? ChangeType(object? value, Type destinationType, CultureInfo culture)
		{
			if (value == null || value.IsDbNull())
			{
				if (!destinationType.IsValueType())
				{
					return null;
				}
				return Activator.CreateInstance(destinationType);
			}
			Type type = value.GetType();
			if (destinationType == type || destinationType.IsAssignableFrom(type))
			{
				return value;
			}
			if (destinationType.IsGenericType() && destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				Type destinationType2 = destinationType.GetGenericArguments()[0];
				object obj = ChangeType(value, destinationType2, culture);
				return Activator.CreateInstance(destinationType, obj);
			}
			if (destinationType.IsEnum())
			{
				if (!(value is string value2))
				{
					return value;
				}
				return Enum.Parse(destinationType, value2, ignoreCase: true);
			}
			if (destinationType == typeof(bool))
			{
				if ("0".Equals(value))
				{
					return false;
				}
				if ("1".Equals(value))
				{
					return true;
				}
			}
			System.ComponentModel.TypeConverter converter = TypeDescriptor.GetConverter(type);
			if (converter != null && converter.CanConvertTo(destinationType))
			{
				return converter.ConvertTo(null, culture, value, destinationType);
			}
			System.ComponentModel.TypeConverter converter2 = TypeDescriptor.GetConverter(destinationType);
			if (converter2 != null && converter2.CanConvertFrom(type))
			{
				return converter2.ConvertFrom(null, culture, value);
			}
			Type[] array = new Type[2] { type, destinationType };
			for (int i = 0; i < array.Length; i++)
			{
				foreach (MethodInfo publicStaticMethod2 in array[i].GetPublicStaticMethods())
				{
					if (!publicStaticMethod2.IsSpecialName || (!(publicStaticMethod2.Name == "op_Implicit") && !(publicStaticMethod2.Name == "op_Explicit")) || !destinationType.IsAssignableFrom(publicStaticMethod2.ReturnParameter.ParameterType))
					{
						continue;
					}
					ParameterInfo[] parameters = publicStaticMethod2.GetParameters();
					if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(type))
					{
						try
						{
							return publicStaticMethod2.Invoke(null, new object[1] { value });
						}
						catch (TargetInvocationException ex)
						{
							throw ex.Unwrap();
						}
					}
				}
			}
			if (type == typeof(string))
			{
				try
				{
					MethodInfo publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string), typeof(IFormatProvider));
					if (publicStaticMethod != null)
					{
						return publicStaticMethod.Invoke(null, new object[2] { value, culture });
					}
					publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string));
					if (publicStaticMethod != null)
					{
						return publicStaticMethod.Invoke(null, new object[1] { value });
					}
				}
				catch (TargetInvocationException ex2)
				{
					throw ex2.Unwrap();
				}
			}
			if (destinationType == typeof(TimeSpan))
			{
				return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture));
			}
			return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture);
		}

		[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
		public static void RegisterTypeConverter<TConvertible, TConverter>() where TConverter : System.ComponentModel.TypeConverter
		{
			if (!TypeDescriptor.GetAttributes(typeof(TConvertible)).OfType<TypeConverterAttribute>().Any((TypeConverterAttribute a) => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName))
			{
				TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter)));
			}
		}
	}
}
namespace YamlDotNet.Serialization.TypeResolvers
{
	public sealed class DynamicTypeResolver : ITypeResolver
	{
		public Type Resolve(Type staticType, object? actualValue)
		{
			if (actualValue == null)
			{
				return staticType;
			}
			return actualValue.GetType();
		}
	}
	public sealed class StaticTypeResolver : ITypeResolver
	{
		public Type Resolve(Type staticType, object? actualValue)
		{
			return staticType;
		}
	}
}
namespace YamlDotNet.Serialization.TypeInspectors
{
	public sealed class CachedTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		private readonly ConcurrentDictionary<Type, List<IPropertyDescriptor>> cache = new ConcurrentDictionary<Type, List<IPropertyDescriptor>>();

		public CachedTypeInspector(ITypeInspector innerTypeDescriptor)
		{
			this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			object container2 = container;
			return cache.GetOrAdd(type, (Type t) => innerTypeDescriptor.GetProperties(t, container2).ToList());
		}
	}
	public sealed class CompositeTypeInspector : TypeInspectorSkeleton
	{
		private readonly IEnumerable<ITypeInspector> typeInspectors;

		public CompositeTypeInspector(params ITypeInspector[] typeInspectors)
			: this((IEnumerable<ITypeInspector>)typeInspectors)
		{
		}

		public CompositeTypeInspector(IEnumerable<ITypeInspector> typeInspectors)
		{
			this.typeInspectors = typeInspectors?.ToList() ?? throw new ArgumentNullException("typeInspectors");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			Type type2 = type;
			object container2 = container;
			return typeInspectors.SelectMany((ITypeInspector i) => i.GetProperties(type2, container2));
		}
	}
	public sealed class NamingConventionTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		private readonly INamingConvention namingConvention;

		public NamingConventionTypeInspector(ITypeInspector innerTypeDescriptor, INamingConvention namingConvention)
		{
			this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return innerTypeDescriptor.GetProperties(type, container).Select(delegate(IPropertyDescriptor p)
			{
				YamlMemberAttribute customAttribute = p.GetCustomAttribute<YamlMemberAttribute>();
				return (customAttribute != null && !customAttribute.ApplyNamingConventions) ? p : new PropertyDescriptor(p)
				{
					Name = namingConvention.Apply(p.Name)
				};
			});
		}
	}
	public sealed class ReadableAndWritablePropertiesTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		public ReadableAndWritablePropertiesTypeInspector(ITypeInspector innerTypeDescriptor)
		{
			this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return from p in innerTypeDescriptor.GetProperties(type, container)
				where p.CanWrite
				select p;
		}
	}
	public sealed class ReadableFieldsTypeInspector : TypeInspectorSkeleton
	{
		private sealed class ReflectionFieldDescriptor : IPropertyDescriptor
		{
			private readonly FieldInfo fieldInfo;

			private readonly ITypeResolver typeResolver;

			public string Name => fieldInfo.Name;

			public Type Type => fieldInfo.FieldType;

			public Type? TypeOverride { get; set; }

			public int Order { get; set; }

			public bool CanWrite => !fieldInfo.IsInitOnly;

			public ScalarStyle ScalarStyle { get; set; }

			public ReflectionFieldDescriptor(FieldInfo fieldInfo, ITypeResolver typeResolver)
			{
				this.fieldInfo = fieldInfo;
				this.typeResolver = typeResolver;
				ScalarStyle = ScalarStyle.Any;
			}

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

			public T GetCustomAttribute<T>() where T : Attribute
			{
				return (T)fieldInfo.GetCustomAttributes(typeof(T), inherit: true).FirstOrDefault();
			}

			public IObjectDescriptor Read(object target)
			{
				object value = fieldInfo.GetValue(target);
				Type type = TypeOverride ?? typeResolver.Resolve(Type, value);
				return new ObjectDescriptor(value, type, Type, ScalarStyle);
			}
		}

		private readonly ITypeResolver typeResolver;

		public ReadableFieldsTypeInspector(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return type.GetPublicFields().Select((Func<FieldInfo, IPropertyDescriptor>)((FieldInfo p) => new ReflectionFieldDescriptor(p, typeResolver)));
		}
	}
	public sealed class ReadablePropertiesTypeInspector : TypeInspectorSkeleton
	{
		private sealed class ReflectionPropertyDescriptor : IPropertyDescriptor
		{
			private readonly PropertyInfo propertyInfo;

			private readonly ITypeResolver typeResolver;

			public string Name => propertyInfo.Name;

			public Type Type => propertyInfo.PropertyType;

			public Type? TypeOverride { get; set; }

			public int Order { get; set; }

			public bool CanWrite => propertyInfo.CanWrite;

			public ScalarStyle ScalarStyle { get; set; }

			public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver)
			{
				this.propertyInfo = propertyInfo ?? throw new ArgumentNullException("propertyInfo");
				this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
				ScalarStyle = ScalarStyle.Any;
			}

			public void Write(object target, object? value)
			{
				propertyInfo.SetValue(target, value, null);
			}

			public T GetCustomAttribute<T>() where T : Attribute
			{
				return (T)propertyInfo.GetAllCustomAttributes<T>().FirstOrDefault();
			}

			public IObjectDescriptor Read(object target)
			{
				object obj = propertyInfo.ReadValue(target);
				Type type = TypeOverride ?? typeResolver.Resolve(Type, obj);
				return new ObjectDescriptor(obj, type, Type, ScalarStyle);
			}
		}

		private readonly ITypeResolver typeResolver;

		private readonly bool includeNonPublicProperties;

		public ReadablePropertiesTypeInspector(ITypeResolver typeResolver)
			: this(typeResolver, includeNonPublicProperties: false)
		{
		}

		public ReadablePropertiesTypeInspector(ITypeResolver typeResolver, bool includeNonPublicProperties)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			this.includeNonPublicProperties = includeNonPublicProperties;
		}

		private static bool IsValidProperty(PropertyInfo property)
		{
			if (property.CanRead)
			{
				return property.GetGetMethod(nonPublic: true).GetParameters().Length == 0;
			}
			return false;
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return type.GetProperties(includeNonPublicProperties).Where(IsValidProperty).Select((Func<PropertyInfo, IPropertyDescriptor>)((PropertyInfo p) => new ReflectionPropertyDescriptor(p, typeResolver)));
		}
	}
	public abstract class TypeInspectorSkeleton : ITypeInspector
	{
		public abstract IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container);

		public IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched)
		{
			string name2 = name;
			IEnumerable<IPropertyDescriptor> enumerable = from p in GetProperties(type, container)
				where p.Name == name2
				select p;
			using IEnumerator<IPropertyDescriptor> enumerator = enumerable.GetEnumerator();
			if (!enumerator.MoveNext())
			{
				if (ignoreUnmatched)
				{
					return null;
				}
				throw new SerializationException("Property '" + name2 + "' not found on type '" + type.FullName + "'.");
			}
			IPropertyDescriptor current = enumerator.Current;
			if (enumerator.MoveNext())
			{
				throw new SerializationException("Multiple properties with the name/alias '" + name2 + "' already exists on type '" + type.FullName + "', maybe you're misusing YamlAlias or maybe you are using the wrong naming convention? The matching properties are: " + string.Join(", ", enumerable.Select((IPropertyDescriptor p) => p.Name).ToArray()));
			}
			return current;
		}
	}
}
namespace YamlDotNet.Serialization.Schemas
{
	public sealed class FailsafeSchema
	{
		public static class Tags
		{
			public static readonly TagName Map = new TagName("tag:yaml.org,2002:map");

			public static readonly TagName Seq = new TagName("tag:yaml.org,2002:seq");

			public static readonly TagName Str = new TagName("tag:yaml.org,2002:str");
		}
	}
	public sealed class JsonSchema
	{
		public static class Tags
		{
			public static readonly TagName Null = new TagName("tag:yaml.org,2002:null");

			public static readonly TagName Bool = new TagName("tag:yaml.org,2002:bool");

			public static readonly TagName Int = new TagName("tag:yaml.org,2002:int");

			public static readonly TagName Float = new TagName("tag:yaml.org,2002:float");
		}
	}
	public sealed class CoreSchema
	{
		public static class Tags
		{
		}
	}
	public sealed class DefaultSchema
	{
		public stat

EpicLoot/AdventureBackpacksAPI.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: Guid("997CB563-FCC7-44B7-8F71-069747D27CC5")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyProduct("AdventureBackpacks")]
[assembly: AssemblyCompany("Vapok Gaming")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("A Valheim Mod for adding progression multiple backpacks as an item/utility gear addition.")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyTitle("AdventureBackpacks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdventureBackpacks.API
{
	[PublicAPI]
	public class ABAPI
	{
		public struct Backpack
		{
			public string Name;

			public ItemData ItemData;

			public Inventory Inventory;

			public BackpackDefinition Definition;
		}

		public class BackpackDefinition
		{
			public GameObject BackPackGo;

			public AssetBundle AssetBundle;

			public string PrefabName;

			public string ItemName;

			public string ConfigSection = "";

			public string CraftingTable;

			public int StationLevel;

			public int MaxRequiredStationLevel;

			public readonly List<RecipeIngredient> RecipeIngredients = new List<RecipeIngredient>();

			public readonly List<RecipeIngredient> UpgradeIngredients = new List<RecipeIngredient>();

			public readonly List<DropTarget> DropsFrom = new List<DropTarget>();

			public readonly Dictionary<BackpackBiomes, KeyValuePair<StatusEffect, int>> EffectsToApply = new Dictionary<BackpackBiomes, KeyValuePair<StatusEffect, int>>();

			public Dictionary<int, Vector2> BackpackSizeByQuality = new Dictionary<int, Vector2>();

			public StatusEffect ItemSetStatusEffect;

			public float WeightMultiplier;

			public int CarryBonus;

			public float SpeedMod;

			public bool EnableFreezing;

			public BackpackBiomes BackpackBiome;

			public BackpackDefinition()
			{
			}

			public BackpackDefinition(GameObject backPackGo)
			{
				BackPackGo = backPackGo;
			}

			public BackpackDefinition(AssetBundle assetBundle, string prefabName)
			{
				AssetBundle = assetBundle;
				PrefabName = prefabName;
			}
		}

		public struct DropTarget
		{
			public string Creature;

			public int Min;

			public int? Max;

			public float Chance;

			public DropTarget(string creature, float chance, int min = 1, int? max = null)
			{
				Creature = creature;
				Chance = chance;
				Min = min;
				Max = max;
			}
		}

		public struct EffectDefinition
		{
			public readonly string Name;

			public readonly string LocalizedName;

			public readonly string EffectName;

			public readonly string Description;

			public readonly StatusEffect StatusEffect;

			public EffectDefinition(string name, string localizedName, string effectName, string description, StatusEffect statusEffect)
			{
				Name = name;
				LocalizedName = localizedName;
				EffectName = effectName;
				Description = description;
				StatusEffect = statusEffect;
			}
		}

		public struct RecipeIngredient
		{
			public string ItemPrefabName;

			public int Quantity;

			public RecipeIngredient(string itemPrefabName, int quantity)
			{
				ItemPrefabName = itemPrefabName;
				Quantity = quantity;
			}
		}

		public static bool IsLoaded()
		{
			return false;
		}

		public static bool IsBackpack(ItemData itemData)
		{
			return false;
		}

		public static bool IsBackpackEquipped(Player player)
		{
			return false;
		}

		public static bool CanOpenBackpack(Player player)
		{
			return false;
		}

		public static bool IsThisBackpackEquipped(Player player, ItemData itemData)
		{
			return false;
		}

		public static Backpack? GetEquippedBackpack(Player player)
		{
			return null;
		}

		public static Backpack? GetBackpack(ItemData itemData)
		{
			return null;
		}

		public static HashSet<StatusEffect> GetActiveBackpackStatusEffects()
		{
			return null;
		}

		public static HashSet<StatusEffect> GetRegisterdStatusEffects()
		{
			return null;
		}

		public static void OpenBackpack(Player player, InventoryGui gui)
		{
		}

		public static void RegisterEffect(EffectDefinition effectDefinition)
		{
		}

		public static void RegisterBackpack(BackpackDefinition definition)
		{
		}
	}
	[Flags]
	public enum BackpackBiomes : uint
	{
		None = 0u,
		Meadows = 1u,
		BlackForest = 2u,
		Swamp = 4u,
		Mountains = 8u,
		Plains = 0x10u,
		Mistlands = 0x20u,
		Ashlands = 0x40u,
		DeepNorth = 0x80u,
		EffectBiome1 = 0x100000u,
		EffectBiome2 = 0x200000u,
		EffectBiome3 = 0x400000u,
		EffectBiome4 = 0x800000u,
		EffectBiome5 = 0x1000000u
	}
}

EpicLoot/AnimationSpeedManager.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AnimationSpeedManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AnimationSpeedManager")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("B3A6D52C-449A-4665-9FD0-BB48C8CF2CDF")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class AnimationSpeedManager
{
	public delegate double Handler(Character character, double speed);

	private static readonly Harmony harmony = new Harmony("AnimationSpeedManager");

	private static bool hasMarkerPatch = false;

	private static readonly MethodInfo method = AccessTools.DeclaredMethod(typeof(CharacterAnimEvent), "CustomFixedUpdate", (Type[])null, (Type[])null);

	private static int index = 0;

	private static bool changed = false;

	private static Handler[][] handlers = Array.Empty<Handler[]>();

	private static readonly Dictionary<int, List<Handler>> handlersPriorities = new Dictionary<int, List<Handler>>();

	[PublicAPI]
	public static void Add(Handler handler, int priority = 400)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		if (!hasMarkerPatch)
		{
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "markerPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null);
			hasMarkerPatch = true;
		}
		if (!handlersPriorities.TryGetValue(priority, out List<Handler> value))
		{
			handlersPriorities.Add(priority, value = new List<Handler>());
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "wrapper", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		value.Add(handler);
		handlers = (from kv in handlersPriorities
			orderby kv.Key
			select kv.Value.ToArray()).ToArray();
	}

	private static void wrapper(Character ___m_character, Animator ___m_animator)
	{
		Character ___m_character2 = ___m_character;
		double num = (double)___m_animator.speed * 10000000.0 % 100.0;
		if ((!(num > 10.0) || !(num < 30.0)) && !(___m_animator.speed <= 0.001f))
		{
			double num2 = ___m_animator.speed;
			double num3 = handlers[index++].Aggregate(num2, (double current, Handler handler) => handler(___m_character2, current));
			if (num3 != num2)
			{
				___m_animator.speed = (float)(num3 - num3 % 1E-05);
				changed = true;
			}
		}
	}

	private static void markerPatch(Animator ___m_animator)
	{
		if (changed)
		{
			double num = (double)___m_animator.speed * 10000000.0 % 100.0;
			if ((num < 10.0 || num > 30.0) ? true : false)
			{
				___m_animator.speed += 1.9E-06f;
			}
			changed = false;
		}
		index = 0;
	}
}

EpicLoot/AugaAPI.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using JetBrains.Annotations;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AugaAPI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Auga")]
[assembly: AssemblyCopyright("Copyright © Randy Knapp 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("bcc7dd31-d943-4684-800e-176a97dddb8f")]
[assembly: AssemblyFileVersion("1.5")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: CompilationRelaxations(8)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.0")]
[module: UnverifiableCode]
namespace Auga;

[PublicAPI]
public static class API
{
	public static string RedText = "#CD2121";

	public static string Red = "#AD1616";

	public static string Brown1 = "#EAE1D9";

	public static string Brown2 = "#D1C9C2";

	public static string Brown3 = "#A39689";

	public static string Brown4 = "#706457";

	public static string Brown5 = "#2E2620";

	public static string Brown6 = "#EAE1D9";

	public static string Brown7 = "#181410";

	public static string Blue = "#216388";

	public static string LightBlue = "#1AACEF";

	public static string Gold = "#B98A12";

	public static string BrightGold = "#EAA800";

	public static string BrightestGold = "#FFBF1B";

	public static string GoldDark = "#755608";

	public static string Green = "#1B9B37";

	[UsedImplicitly]
	public static bool IsLoaded()
	{
		return false;
	}

	[UsedImplicitly]
	public static Font GetBoldFont()
	{
		return null;
	}

	[UsedImplicitly]
	public static Font GetSemiBoldFont()
	{
		return null;
	}

	[UsedImplicitly]
	public static Font GetRegularFont()
	{
		return null;
	}

	[UsedImplicitly]
	public static Sprite GetItemBackgroundSprite()
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject Panel_Create(Transform parent, Vector2 size, string name, bool withCornerDecoration)
	{
		return null;
	}

	[UsedImplicitly]
	public static Button SmallButton_Create(Transform parent, string name, string labelText)
	{
		return null;
	}

	[UsedImplicitly]
	public static Button MediumButton_Create(Transform parent, string name, string labelText)
	{
		return null;
	}

	[UsedImplicitly]
	public static Button FancyButton_Create(Transform parent, string name, string labelText)
	{
		return null;
	}

	[UsedImplicitly]
	public static Button SettingsButton_Create(Transform parent, string name, string labelText)
	{
		return null;
	}

	[UsedImplicitly]
	public static Button DiamondButton_Create(Transform parent, string name, [CanBeNull] Sprite icon)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject Divider_CreateSmall(Transform parent, string name, float width = -1f)
	{
		return null;
	}

	[UsedImplicitly]
	public static Tuple<GameObject, GameObject> Divider_CreateMedium(Transform parent, string name, float width = -1f)
	{
		return null;
	}

	[UsedImplicitly]
	public static Tuple<GameObject, GameObject> Divider_CreateLarge(Transform parent, string name, float width = -1f)
	{
		return null;
	}

	[UsedImplicitly]
	public static void Button_SetTextColors(Button button, Color normal, Color highlighted, Color pressed, Color selected, Color disabled, Color baseTextColor)
	{
	}

	[UsedImplicitly]
	public static void Button_OverrideTextColor(Button button, Color color)
	{
	}

	[UsedImplicitly]
	public static void Tooltip_MakeSimpleTooltip(GameObject obj)
	{
	}

	[UsedImplicitly]
	public static void Tooltip_MakeItemTooltip(GameObject obj, ItemData item)
	{
	}

	[UsedImplicitly]
	public static void Tooltip_MakeFoodTooltip(GameObject obj, Food food)
	{
	}

	[UsedImplicitly]
	public static void Tooltip_MakeStatusEffectTooltip(GameObject obj, StatusEffect statusEffect)
	{
	}

	[UsedImplicitly]
	public static void Tooltip_MakeSkillTooltip(GameObject obj, Skill skill)
	{
	}

	[UsedImplicitly]
	public static bool PlayerPanel_HasTab(string tabID)
	{
		return false;
	}

	[UsedImplicitly]
	public static PlayerPanelTabData PlayerPanel_AddTab(string tabID, Sprite tabIcon, string tabTitleText, Action<int> onTabSelected)
	{
		return null;
	}

	[UsedImplicitly]
	public static bool PlayerPanel_IsTabActive(GameObject tabButton)
	{
		return false;
	}

	[UsedImplicitly]
	public static Button PlayerPanel_GetTabButton(int index)
	{
		return null;
	}

	[UsedImplicitly]
	public static bool Workbench_HasWorkbenchTab(string tabID)
	{
		return false;
	}

	[UsedImplicitly]
	public static WorkbenchTabData Workbench_AddWorkbenchTab(string tabID, Sprite tabIcon, string tabTitleText, Action<int> onTabSelected)
	{
		return null;
	}

	[UsedImplicitly]
	public static WorkbenchTabData Workbench_AddVanillaWorkbenchTab(string tabID, Sprite tabIcon, string tabTitleText, Action<int> onTabSelected)
	{
		return null;
	}

	[UsedImplicitly]
	public static bool Workbench_IsTabActive(GameObject tabButton)
	{
		return false;
	}

	[UsedImplicitly]
	public static Button Workbench_GetCraftingTabButton()
	{
		return null;
	}

	[UsedImplicitly]
	public static Button Workbench_GetUpgradeTabButton()
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject Workbench_CreateNewResultsPanel()
	{
		return null;
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, Text t, object s, bool localize = true)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, Text t, object s, bool localize, bool overwrite)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, object a, bool localize = true)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, object a, bool localize, bool overwrite)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, object a, object b, bool localize = true)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, object a, object b, bool localize, bool overwrite)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, object a, object b, object parenthetical, bool localize = true)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddLine(GameObject tooltipTextBoxGO, object a, object b, object parenthetical, bool localize, bool overwrite)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddUpgradeLine(GameObject tooltipTextBoxGO, object label, object value1, object value2, string color2, bool localize = true)
	{
	}

	[UsedImplicitly]
	public static void TooltipTextBox_AddUpgradeLine(GameObject tooltipTextBoxGO, object label, object value1, object value2, string color2, bool localize, bool overwrite)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_AddItemTooltipCreatedListener(Action<GameObject, ItemData> listener)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_AddFoodTooltipCreatedListener(Action<GameObject, Food> listener)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_AddStatusEffectTooltipCreatedListener(Action<GameObject, StatusEffect> listener)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_AddSkillTooltipCreatedListener(Action<GameObject, Skill> listener)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_AddItemStatPreprocessor(Func<ItemData, string, string, Tuple<string, string>> itemStatPreprocessor)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_ClearTextBoxes(GameObject complexTooltipGO)
	{
	}

	[UsedImplicitly]
	public static GameObject ComplexTooltip_AddTwoColumnTextBox(GameObject complexTooltipGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject ComplexTooltip_AddCenteredTextBox(GameObject complexTooltipGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject ComplexTooltip_AddUpgradeLabels(GameObject complexTooltipGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject ComplexTooltip_AddUpgradeTwoColumnTextBox(GameObject complexTooltipGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject ComplexTooltip_AddCheckBoxTextBox(GameObject complexTooltipGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject ComplexTooltip_AddDivider(GameObject complexTooltipGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetTopic(GameObject complexTooltipGO, string topic)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetSubtitle(GameObject complexTooltipGO, string topic)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetDescription(GameObject complexTooltipGO, string desc)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetIcon(GameObject complexTooltipGO, Sprite icon)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_EnableDescription(GameObject complexTooltipGO, bool enabled)
	{
	}

	[UsedImplicitly]
	public static string ComplexTooltip_GenerateItemSubtext(GameObject complexTooltipGO, ItemData item)
	{
		return string.Empty;
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetItem(GameObject complexTooltipGO, ItemData item, int quality = -1, int variant = -1)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetItemNoTextBoxes(GameObject complexTooltipGO, ItemData item, int quality = -1, int variant = -1)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetFood(GameObject complexTooltipGO, Food food)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetStatusEffect(GameObject complexTooltipGO, StatusEffect statusEffect)
	{
	}

	[UsedImplicitly]
	public static void ComplexTooltip_SetSkill(GameObject complexTooltipGO, Skill skill)
	{
	}

	[UsedImplicitly]
	public static Image RequirementsPanel_GetIcon(GameObject requirementsPanelGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static GameObject[] RequirementsPanel_RequirementList(GameObject requirementsPanelGO)
	{
		return null;
	}

	[UsedImplicitly]
	public static void RequirementsPanel_SetWires(GameObject requirementsPanelGO, RequirementWireState[] wireStates, bool canCraft)
	{
	}

	[UsedImplicitly]
	public static TMP_Text CustomVariantPanel_Enable(string buttonLabel, Action<bool> onShow)
	{
		return null;
	}

	[UsedImplicitly]
	public static void CustomVariantPanel_SetButtonLabel(string buttonLabel)
	{
	}

	[UsedImplicitly]
	public static void CustomVariantPanel_Disable()
	{
	}
}
public enum RequirementWireState
{
	Absent,
	Have,
	DontHave
}
public class PlayerPanelTabData
{
	public int Index;

	public TMP_Text TabTitle;

	public GameObject TabButtonGO;

	public GameObject ContentGO;
}
public class WorkbenchTabData
{
	public int Index;

	public TMP_Text TabTitle;

	public GameObject TabButtonGO;

	public GameObject RequirementsPanelGO;

	public GameObject ItemInfoGO;
}

EpicLoot/CreatureLevelControlAPI.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CreatureLevelControlAPI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CreatureLevelControlAPI")]
[assembly: AssemblyTitle("CreatureLevelControlAPI")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CreatureLevelControl
{
	[PublicAPI]
	public static class API
	{
		public static bool IsLoaded()
		{
			return false;
		}

		public static bool IsEnabled()
		{
			return false;
		}

		public static bool IsInfusionEnabled()
		{
			return false;
		}

		public static bool IsExtraEffectEnabled()
		{
			return false;
		}

		public static bool IsAffixEnabled()
		{
			return false;
		}

		public static int GetWorldLevel()
		{
			return 0;
		}

		public static float[] LevelProbabilities(Character? character, int worldLevel, bool includeZoneBonusLevel)
		{
			return new float[3] { 89f, 10f, 1f };
		}

		public static int LevelRand(Character character)
		{
			if (character.IsBoss() || Random.Range(0, 10) != 0)
			{
				return 1;
			}
			return (Random.Range(0, 10) != 0) ? 2 : 3;
		}

		public static bool HasAffixBoss(Character character)
		{
			return false;
		}

		public static BossAffix GetAffixBoss(Character character)
		{
			return (BossAffix)0;
		}

		public static void SetAffixBoss(Character character, BossAffix affix)
		{
		}

		public static bool HasExtraEffectCreature(Character character)
		{
			return false;
		}

		public static CreatureExtraEffect GetExtraEffectCreature(Character character)
		{
			return (CreatureExtraEffect)0;
		}

		public static void SetExtraEffectCreature(Character character)
		{
		}

		public static void SetExtraEffectCreature(Character character, CreatureExtraEffect effect)
		{
		}

		public static bool HasInfusionCreature(Character character)
		{
			return false;
		}

		public static CreatureInfusion GetInfusionCreature(Character character)
		{
			return (CreatureInfusion)0;
		}

		public static void SetInfusionCreature(Character character)
		{
		}

		public static void SetInfusionCreature(Character character, CreatureInfusion infusion)
		{
		}

		public static Character? GetTwinBoss(Character boss)
		{
			return null;
		}

		public static bool DropItemOnDeath(ItemData item)
		{
			return !item.m_shared.m_questItem && !item.m_equipped;
		}
	}
}

EpicLoot/EpicLoot-UnityLib.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("EpicLoot-UnityLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Randy Knapp Mods")]
[assembly: AssemblyProduct("EpicLoot-UnityLib")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fb508e8d-0c64-4ec6-b746-f668f510296f")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EpicLoot_UnityLib
{
	public class AugmentUI : EnchantingTableUIPanelBase
	{
		public delegate List<InventoryItemListElement> GetAugmentableItemsDelegate();

		public delegate List<Tuple<string, bool>> GetAugmentableEffectsDelegate(ItemData item);

		public delegate string GetAvailableEffectsDelegate(ItemData item, int augmentIndex);

		public delegate List<InventoryItemListElement> GetAugmentCostDelegate(ItemData item, int augmentIndex);

		public delegate GameObject AugmentItemDelegate(ItemData item, int augmentIndex);

		public Text AvailableEffectsText;

		public Text AvailableEffectsHeader;

		public Scrollbar AvailableEffectsScrollbar;

		public List<Toggle> AugmentSelectors;

		[Header("Cost")]
		public Text CostLabel;

		public MultiSelectItemList CostList;

		public static GetAugmentableItemsDelegate GetAugmentableItems;

		public static GetAugmentableEffectsDelegate GetAugmentableEffects;

		public static GetAvailableEffectsDelegate GetAvailableEffects;

		public static GetAugmentCostDelegate GetAugmentCost;

		public static AugmentItemDelegate AugmentItem;

		private int _augmentIndex;

		private GameObject _choiceDialog;

		public override void Awake()
		{
			base.Awake();
			for (int i = 0; i < AugmentSelectors.Count; i++)
			{
				((UnityEvent<bool>)(object)AugmentSelectors[i].onValueChanged).AddListener((UnityAction<bool>)OnAugmentSelectorToggled);
			}
		}

		[UsedImplicitly]
		public void OnEnable()
		{
			_augmentIndex = -1;
			foreach (Toggle augmentSelector in AugmentSelectors)
			{
				augmentSelector.isOn = false;
			}
			if ((Object)(object)AvailableEffectsHeader != (Object)null)
			{
				int num = 2;
				Tuple<float, float> featureCurrentValue = EnchantingTableUI.instance.SourceTable.GetFeatureCurrentValue(EnchantingFeature.Augment);
				if (!float.IsNaN(featureCurrentValue.Item1))
				{
					num = (int)featureCurrentValue.Item1;
				}
				string text = ((num > 2) ? "<color=#EAA800>" : "");
				string text2 = ((num > 2) ? "</color>" : "");
				AvailableEffectsHeader.text = Localization.instance.Localize("$mod_epicloot_augment_availableeffects " + text + "($mod_epicloot_augment_choices)" + text2, new string[1] { num.ToString() });
			}
			OnAugmentIndexChanged();
			List<InventoryItemListElement> source = GetAugmentableItems();
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
			DeselectAll();
		}

		public override void Update()
		{
			base.Update();
			if (!_locked && ZInput.IsGamepadActive())
			{
				if (ZInput.GetButtonDown("JoyButtonY"))
				{
					int num = AugmentSelectors.Count((Toggle x) => ((Behaviour)x).isActiveAndEnabled);
					int index = (_augmentIndex + 1) % num;
					AugmentSelectors[index].isOn = true;
					ZInput.ResetButtonStatus("JoyButtonY");
				}
				if ((Object)(object)AvailableEffectsScrollbar != (Object)null)
				{
					float joyRightStickY = ZInput.GetJoyRightStickY();
					if (Mathf.Abs(joyRightStickY) > 0.5f)
					{
						AvailableEffectsScrollbar.value = Mathf.Clamp01(AvailableEffectsScrollbar.value + joyRightStickY * -0.1f);
					}
				}
			}
			if (!((Object)(object)_choiceDialog != (Object)null) || _choiceDialog.activeSelf)
			{
				return;
			}
			Unlock();
			Object.Destroy((Object)(object)_choiceDialog);
			_choiceDialog = null;
			Cancel();
			AvailableItems.ForeachElement(delegate(int i, MultiSelectItemListElement e)
			{
				if (e.IsSelected())
				{
					e.SetItem(e.GetListElement());
					e.Refresh();
				}
			});
			RefreshAugmentSelectors();
			OnAugmentIndexChanged();
		}

		public void OnAugmentSelectorToggled(bool isOn)
		{
			if (isOn)
			{
				for (int i = 0; i < AugmentSelectors.Count; i++)
				{
					if (AugmentSelectors[i].isOn)
					{
						SelectAugmentIndex(i);
						break;
					}
				}
			}
			else if (!AugmentSelectors.Any((Toggle x) => x.isOn))
			{
				SelectAugmentIndex(-1);
			}
		}

		public void SelectAugmentIndex(int index)
		{
			if (index != _augmentIndex)
			{
				_augmentIndex = index;
				OnAugmentIndexChanged();
			}
		}

		public void OnAugmentIndexChanged()
		{
			Tuple<InventoryItemListElement, int> singleSelectedItem = AvailableItems.GetSingleSelectedItem<InventoryItemListElement>();
			if (singleSelectedItem?.Item1.GetItem() == null)
			{
				((Selectable)MainButton).interactable = false;
				AvailableEffectsText.text = "";
				((Behaviour)CostLabel).enabled = false;
				CostList.SetItems(new List<IListElement>());
				_augmentIndex = -1;
				{
					foreach (Toggle augmentSelector in AugmentSelectors)
					{
						augmentSelector.isOn = false;
					}
					return;
				}
			}
			if (_augmentIndex < 0)
			{
				AvailableEffectsText.text = string.Empty;
				((Behaviour)CostLabel).enabled = false;
				CostList.SetItems(new List<IListElement>());
				((Selectable)MainButton).interactable = false;
				return;
			}
			ItemData item = singleSelectedItem.Item1.GetItem();
			string text = GetAvailableEffects(item, _augmentIndex);
			AvailableEffectsText.text = text;
			ScrollEnchantInfoToTop();
			((Behaviour)CostLabel).enabled = true;
			List<InventoryItemListElement> list = GetAugmentCost(item, _augmentIndex);
			CostList.SetItems(list.Cast<IListElement>().ToList());
			Tuple<float, float> featureCurrentValue = EnchantingTableUI.instance.SourceTable.GetFeatureCurrentValue(EnchantingFeature.Augment);
			float num = (float.IsNaN(featureCurrentValue.Item2) ? 0f : featureCurrentValue.Item2);
			if (num > 0f)
			{
				CostLabel.text = Localization.instance.Localize($"$mod_epicloot_augmentcost <color=#EAA800>(-{num}% $item_coins!)</color>");
			}
			else
			{
				CostLabel.text = Localization.instance.Localize("$mod_epicloot_augmentcost");
			}
			bool flag = EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(list);
			bool flag2 = EnchantingTableUI.instance.SourceTable.IsFeatureUnlocked(EnchantingFeature.Augment);
			((Selectable)MainButton).interactable = flag2 && flag && _augmentIndex >= 0;
		}

		private void ScrollEnchantInfoToTop()
		{
			AvailableEffectsScrollbar.value = 1f;
		}

		protected override void DoMainAction()
		{
			Tuple<InventoryItemListElement, int> singleSelectedItem = AvailableItems.GetSingleSelectedItem<InventoryItemListElement>();
			if (singleSelectedItem?.Item1.GetItem() == null)
			{
				Cancel();
				return;
			}
			ItemData item = singleSelectedItem.Item1.GetItem();
			List<InventoryItemListElement> list = GetAugmentCost(item, _augmentIndex);
			Player localPlayer = Player.m_localPlayer;
			if (!localPlayer.NoCostCheat())
			{
				if (!EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(list))
				{
					Debug.LogError((object)"[Augment Item] ERROR: Tried to augment item but could not afford the cost. This should not happen!");
					return;
				}
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				foreach (InventoryItemListElement item3 in list)
				{
					ItemData item2 = item3.GetItem();
					inventory.RemoveItem(item2.m_shared.m_name, item2.m_stack, -1, true);
				}
			}
			if ((Object)(object)_choiceDialog != (Object)null)
			{
				Object.Destroy((Object)(object)_choiceDialog);
			}
			_choiceDialog = AugmentItem(item, _augmentIndex);
			Lock();
		}

		protected override void OnSelectedItemsChanged()
		{
			ItemData val = AvailableItems.GetSingleSelectedItem<InventoryItemListElement>()?.Item1.GetItem();
			List<Tuple<string, bool>> list = GetAugmentableEffects(val);
			if (list.Count > AugmentSelectors.Count)
			{
				Debug.LogError((object)$"[Epic Loot] ERROR: Too many magic effects to show! (Max: {AugmentSelectors.Count})");
			}
			for (int i = 0; i < AugmentSelectors.Count; i++)
			{
				Toggle val2 = AugmentSelectors[i];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				val2.SetIsOnWithoutNotify(i == 0);
				((Component)val2).gameObject.SetActive(val != null && i < list.Count);
				if (((Component)val2).gameObject.activeSelf)
				{
					Text componentInChildren = ((Component)val2).GetComponentInChildren<Text>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.text = list[i].Item1;
						((Selectable)val2).interactable = list[i].Item2;
					}
				}
			}
			if (val == null)
			{
				AvailableEffectsText.text = string.Empty;
			}
			_augmentIndex = 0;
			OnAugmentIndexChanged();
		}

		private void RefreshAugmentSelectors()
		{
			ItemData val = AvailableItems.GetSingleSelectedItem<InventoryItemListElement>()?.Item1.GetItem();
			List<Tuple<string, bool>> list = GetAugmentableEffects(val);
			for (int i = 0; i < AugmentSelectors.Count; i++)
			{
				Toggle val2 = AugmentSelectors[i];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				val2.SetIsOnWithoutNotify(i == _augmentIndex);
				((Component)val2).gameObject.SetActive(val != null && i < list.Count);
				if (((Component)val2).gameObject.activeSelf)
				{
					Text componentInChildren = ((Component)val2).GetComponentInChildren<Text>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.text = list[i].Item1;
						((Selectable)val2).interactable = list[i].Item2;
					}
				}
			}
		}

		public override bool CanCancel()
		{
			if (!base.CanCancel())
			{
				if ((Object)(object)_choiceDialog != (Object)null)
				{
					return _choiceDialog.activeSelf;
				}
				return false;
			}
			return true;
		}

		public override void Cancel()
		{
			base.Cancel();
			OnAugmentIndexChanged();
		}

		public override void Lock()
		{
			base.Lock();
			foreach (Toggle augmentSelector in AugmentSelectors)
			{
				((Selectable)augmentSelector).interactable = false;
			}
		}

		public override void Unlock()
		{
			base.Unlock();
			foreach (Toggle augmentSelector in AugmentSelectors)
			{
				((Selectable)augmentSelector).interactable = true;
			}
		}

		public override void DeselectAll()
		{
			AvailableItems.DeselectAll();
		}
	}
	[RequireComponent(typeof(CanvasGroup))]
	public class EnchantBonus : MonoBehaviour
	{
		public float Delay = 1f;

		public float FadeTime = 1f;

		private CanvasGroup _group;

		private Coroutine _coroutine;

		public void Awake()
		{
			_group = ((Component)this).GetComponent<CanvasGroup>();
			_group.alpha = 0f;
		}

		public void OnEnable()
		{
			_group.alpha = 0f;
		}

		public void OnDestroy()
		{
			if (_coroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_coroutine);
			}
		}

		public IEnumerator FadeOut()
		{
			yield return (object)new WaitForSeconds(Delay);
			while (_group.alpha > 0f)
			{
				CanvasGroup group = _group;
				group.alpha -= Time.deltaTime * (1f / FadeTime);
				yield return null;
			}
		}

		public void Show()
		{
			if (_coroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_coroutine);
			}
			_group.alpha = 1f;
			_coroutine = ((MonoBehaviour)this).StartCoroutine(FadeOut());
		}
	}
	public class FeatureStatus : MonoBehaviour
	{
		public delegate void MakeFeatureUnlockTooltipDelegate(GameObject obj);

		public delegate bool UpgradesActiveDelegate(EnchantingFeature feature, out bool featureActive);

		public EnchantingFeature Feature;

		public Transform UnlockedContainer;

		public Transform LockedContainer;

		public GameObject UnlockedLabel;

		public Image[] Stars;

		public Text ManyStarsLabel;

		public UITooltip Tooltip;

		public static MakeFeatureUnlockTooltipDelegate MakeFeatureUnlockTooltip;

		public static UpgradesActiveDelegate UpgradesActive;

		public void Awake()
		{
			if ((Object)(object)Tooltip != (Object)null)
			{
				MakeFeatureUnlockTooltip(((Component)Tooltip).gameObject);
			}
		}

		public void OnEnable()
		{
			if ((Object)(object)EnchantingTableUI.instance != (Object)null && (Object)(object)EnchantingTableUI.instance.SourceTable != (Object)null)
			{
				EnchantingTableUI.instance.SourceTable.OnFeatureLevelChanged += OnFeatureLevelChanged;
			}
			Refresh();
		}

		public void OnDisable()
		{
			if ((Object)(object)EnchantingTableUI.instance != (Object)null && (Object)(object)EnchantingTableUI.instance.SourceTable != (Object)null)
			{
				EnchantingTableUI.instance.SourceTable.OnFeatureLevelChanged -= OnFeatureLevelChanged;
			}
		}

		public void SetFeature(EnchantingFeature feature)
		{
			if (Feature != feature)
			{
				Feature = feature;
				Refresh();
			}
		}

		public void Refresh()
		{
			if ((Object)(object)EnchantingTableUI.instance == (Object)null || (Object)(object)EnchantingTableUI.instance.SourceTable == (Object)null)
			{
				return;
			}
			if (!EnchantingTableUI.instance.SourceTable.IsFeatureAvailable(Feature))
			{
				if ((Object)(object)UnlockedContainer != (Object)null)
				{
					((Component)UnlockedContainer).gameObject.SetActive(false);
				}
				if ((Object)(object)LockedContainer != (Object)null)
				{
					((Component)LockedContainer).gameObject.SetActive(false);
				}
				return;
			}
			bool featureActive;
			if (EnchantingTableUI.instance.SourceTable.IsFeatureLocked(Feature))
			{
				if ((Object)(object)UnlockedContainer != (Object)null)
				{
					((Component)UnlockedContainer).gameObject.SetActive(false);
				}
				if ((Object)(object)LockedContainer != (Object)null)
				{
					((Component)LockedContainer).gameObject.SetActive(true);
				}
			}
			else
			{
				if ((Object)(object)UnlockedContainer != (Object)null)
				{
					((Component)UnlockedContainer).gameObject.SetActive(true);
				}
				if ((Object)(object)LockedContainer != (Object)null)
				{
					((Component)LockedContainer).gameObject.SetActive(false);
				}
				int featureLevel = EnchantingTableUI.instance.SourceTable.GetFeatureLevel(Feature);
				if (featureLevel > Stars.Length)
				{
					for (int i = 0; i < Stars.Length; i++)
					{
						((Behaviour)Stars[i]).enabled = i == 0;
					}
					if ((Object)(object)ManyStarsLabel != (Object)null)
					{
						((Behaviour)ManyStarsLabel).enabled = true;
						ManyStarsLabel.text = $"×{featureLevel}";
					}
				}
				else
				{
					for (int j = 0; j < Stars.Length; j++)
					{
						((Component)Stars[j]).gameObject.SetActive(featureLevel > j && UpgradesActive(Feature, out featureActive));
					}
					if ((Object)(object)ManyStarsLabel != (Object)null)
					{
						((Behaviour)ManyStarsLabel).enabled = false;
					}
				}
				if ((Object)(object)UnlockedLabel != (Object)null)
				{
					UnlockedLabel.SetActive(featureLevel == 0);
				}
			}
			if ((Object)(object)Tooltip != (Object)null && UpgradesActive(Feature, out featureActive))
			{
				Tooltip.m_topic = Localization.instance.Localize(EnchantingTableUpgrades.GetFeatureName(Feature));
				StringBuilder stringBuilder = new StringBuilder();
				bool num = EnchantingTableUI.instance.SourceTable.IsFeatureLocked(Feature);
				int featureLevel2 = EnchantingTableUI.instance.SourceTable.GetFeatureLevel(Feature);
				int featureMaxLevel = EnchantingTableUpgrades.GetFeatureMaxLevel(Feature);
				if (num)
				{
					stringBuilder.AppendLine(Localization.instance.Localize("$mod_epicloot_currentlevel: <color=#AD1616><b>$mod_epicloot_featurelocked</b></color>"));
				}
				else if (featureLevel2 == 0)
				{
					stringBuilder.AppendLine(Localization.instance.Localize($"$mod_epicloot_currentlevel: <color=#1AACEF><b>$mod_epicloot_featureunlocked</b></color> / {featureMaxLevel}"));
				}
				else
				{
					stringBuilder.AppendLine(Localization.instance.Localize($"$mod_epicloot_currentlevel: <color=#EAA800><b>{featureLevel2}</b></color> / {featureMaxLevel}"));
				}
				if (!num && featureLevel2 > 0)
				{
					string featureUpgradeLevelDescription = EnchantingTableUpgrades.GetFeatureUpgradeLevelDescription(EnchantingTableUI.instance.SourceTable, Feature, featureLevel2);
					stringBuilder.AppendLine("<color=#EAA800>" + featureUpgradeLevelDescription + "</color>");
				}
				stringBuilder.AppendLine();
				stringBuilder.AppendLine(Localization.instance.Localize(EnchantingTableUpgrades.GetFeatureDescription(Feature)));
				Tooltip.m_text = Localization.instance.Localize(stringBuilder.ToString());
			}
		}

		private void OnFeatureLevelChanged(EnchantingFeature feature, int _)
		{
			if (((Behaviour)this).isActiveAndEnabled && feature == Feature)
			{
				Refresh();
			}
		}
	}
	public class DisenchantUI : EnchantingTableUIPanelBase
	{
		public delegate List<InventoryItemListElement> GetDisenchantItemsDelegate();

		public delegate List<InventoryItemListElement> GetDisenchantCostDelegate(ItemData item);

		public delegate List<InventoryItemListElement> DisenchantItemDelegate(ItemData item);

		public Text CostLabel;

		public MultiSelectItemList CostList;

		public EnchantBonus BonusPanel;

		public static GetDisenchantItemsDelegate GetDisenchantItems;

		public static GetDisenchantCostDelegate GetDisenchantCost;

		public static DisenchantItemDelegate DisenchantItem;

		[UsedImplicitly]
		public void OnEnable()
		{
			List<InventoryItemListElement> source = GetDisenchantItems();
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
			AvailableItems.DeselectAll();
		}

		protected override void DoMainAction()
		{
			Cancel();
			Tuple<IListElement, int> singleSelectedItem = AvailableItems.GetSingleSelectedItem<IListElement>();
			if (singleSelectedItem?.Item1.GetItem() == null)
			{
				return;
			}
			ItemData item = singleSelectedItem.Item1.GetItem();
			List<InventoryItemListElement> list = GetDisenchantCost(item);
			if (!EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(list))
			{
				return;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			foreach (InventoryItemListElement item3 in list)
			{
				ItemData item2 = item3.GetItem();
				inventory.RemoveItem(item2.m_shared.m_name, item2.m_stack, -1, true);
			}
			List<InventoryItemListElement> list2 = DisenchantItem(item);
			if (list2.Count > 0)
			{
				EnchantingTableUI.instance.PlayEnchantBonusSFX();
				BonusPanel.Show();
				EnchantingTableUIPanelBase.GiveItemsToPlayer(list2);
			}
			RefreshAvailableItems();
		}

		public void RefreshAvailableItems()
		{
			List<InventoryItemListElement> source = GetDisenchantItems();
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
			AvailableItems.DeselectAll();
			OnSelectedItemsChanged();
		}

		protected override void OnSelectedItemsChanged()
		{
			Tuple<InventoryItemListElement, int> singleSelectedItem = AvailableItems.GetSingleSelectedItem<InventoryItemListElement>();
			if (singleSelectedItem != null)
			{
				((Behaviour)CostLabel).enabled = true;
				List<InventoryItemListElement> list = GetDisenchantCost(singleSelectedItem.Item1.GetItem());
				CostList.SetItems(list.Cast<IListElement>().ToList());
				Tuple<float, float> featureCurrentValue = EnchantingTableUI.instance.SourceTable.GetFeatureCurrentValue(EnchantingFeature.Disenchant);
				int num = ((!float.IsNaN(featureCurrentValue.Item2)) ? ((int)featureCurrentValue.Item2) : 0);
				if (num > 0 && list.Count > 0)
				{
					CostLabel.text = Localization.instance.Localize("$mod_epicloot_disenchantcost <color=#EAA800>($mod_epicloot_disenchantcostreduction)</color>", new string[1] { num.ToString() });
				}
				else
				{
					CostLabel.text = Localization.instance.Localize("$mod_epicloot_disenchantcost");
				}
				bool flag = EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(list);
				bool flag2 = EnchantingTableUI.instance.SourceTable.IsFeatureUnlocked(EnchantingFeature.Disenchant);
				((Selectable)MainButton).interactable = flag2 && flag;
			}
			else
			{
				CostList.SetItems(new List<IListElement>());
				((Behaviour)CostLabel).enabled = false;
				((Selectable)MainButton).interactable = false;
			}
		}

		public override void DeselectAll()
		{
			AvailableItems.DeselectAll();
		}
	}
	public class EnchantingTable : MonoBehaviour, Hoverable, Interactable
	{
		public delegate bool UpgradesActiveDelegate(EnchantingFeature feature, out bool featureActive);

		public const float UseDistance = 2.7f;

		public const string DisplayNameLocID = "mod_epicloot_assets_enchantingtable";

		public const int FeatureUnavailableSentinel = -2;

		public const int FeatureLockedSentinel = -1;

		public const int FeatureLevelOne = 1;

		public GameObject EnchantingUIPrefab;

		public static UpgradesActiveDelegate UpgradesActive;

		private static readonly List<EnchantingFeatureUpgradeRequest> _upgradeRequests = new List<EnchantingFeatureUpgradeRequest>();

		private ZNetView _nview;

		private Player _interactingPlayer;

		public event Action<EnchantingFeature, int> OnFeatureLevelChanged;

		public event Action OnAnyFeatureLevelChanged;

		public bool Interact(Humanoid user, bool repeat, bool alt)
		{
			if (repeat || (Object)(object)user != (Object)(object)Player.m_localPlayer || !InUseDistance(user))
			{
				return false;
			}
			EnchantingTableUI.Show(EnchantingUIPrefab, this);
			_interactingPlayer = Player.m_localPlayer;
			return false;
		}

		public void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			_nview = ((Component)this).GetComponent<ZNetView>();
			if (!((Object)(object)_nview == (Object)null) && _nview.GetZDO() != null)
			{
				WearNTear component = ((Component)this).GetComponent<WearNTear>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_destroyedEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[2]
					{
						new EffectData
						{
							m_prefab = ZNetScene.instance.GetPrefab("vfx_SawDust")
						},
						new EffectData
						{
							m_prefab = ZNetScene.instance.GetPrefab("sfx_wood_destroyed")
						}
					};
					component.m_hitEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
					{
						new EffectData
						{
							m_prefab = ZNetScene.instance.GetPrefab("vfx_SawDust")
						}
					};
				}
				_nview.Register<ZDOID, int, int>("el.TableUpgradeRequest", (Action<long, ZDOID, int, int>)RPC_TableUpgradeRequest);
				_nview.Register<ZDOID, int, int, bool>("el.TableUpgradeResponse", (Method<ZDOID, int, int, bool>)RPC_TableUpgradeResponse);
				InitFeatureLevels();
			}
		}

		public void RequestTableUpgrade(EnchantingFeature feature, int toLevel, Action<bool> responseCallback)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			ZDOID uid = _nview.GetZDO().m_uid;
			_upgradeRequests.Add(new EnchantingFeatureUpgradeRequest
			{
				TableZDO = uid,
				Feature = feature,
				ToLevel = toLevel,
				ResponseCallback = responseCallback
			});
			_nview.InvokeRPC("el.TableUpgradeRequest", new object[3]
			{
				uid,
				(int)feature,
				toLevel
			});
		}

		private void RPC_TableUpgradeRequest(long sender, ZDOID tableZDO, int featureI, int toLevel)
		{
			//IL_0013: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			if (!_nview.IsOwner())
			{
				return;
			}
			GameObject val = ZNetScene.instance.FindInstance(tableZDO);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			EnchantingTable component = val.GetComponent<EnchantingTable>();
			if (!((Object)(object)component == (Object)null))
			{
				if (component.IsFeatureAvailable((EnchantingFeature)featureI) && toLevel == component.GetFeatureLevel((EnchantingFeature)featureI) + 1)
				{
					component.SetFeatureLevel((EnchantingFeature)featureI, toLevel);
					_nview.InvokeRPC(sender, "el.TableUpgradeResponse", new object[4] { tableZDO, featureI, toLevel, true });
					this.OnFeatureLevelChanged?.Invoke((EnchantingFeature)featureI, toLevel);
					this.OnAnyFeatureLevelChanged?.Invoke();
				}
				else
				{
					_nview.InvokeRPC(sender, "el.TableUpgradeResponse", new object[4] { tableZDO, featureI, toLevel, false });
				}
			}
		}

		private void RPC_TableUpgradeResponse(long sender, ZDOID tableZDO, int featureI, int toLevel, bool success)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			foreach (EnchantingFeatureUpgradeRequest item in _upgradeRequests.ToList())
			{
				if (!(item.TableZDO == tableZDO) || item.Feature != (EnchantingFeature)featureI || item.ToLevel != toLevel)
				{
					continue;
				}
				item.ResponseCallback(success);
				_upgradeRequests.Remove(item);
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					if (toLevel == 0)
					{
						((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$mod_epicloot_unlockmessage", new string[1] { EnchantingTableUpgrades.GetFeatureName((EnchantingFeature)featureI) }), 0, (Sprite)null);
					}
					else
					{
						((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$mod_epicloot_upgrademessage", new string[2]
						{
							EnchantingTableUpgrades.GetFeatureName((EnchantingFeature)featureI),
							toLevel.ToString()
						}), 0, (Sprite)null);
					}
				}
			}
		}

		public void Update()
		{
			if ((Object)(object)_interactingPlayer != (Object)null && (Object)(object)EnchantingTableUI.instance != (Object)null && ((Behaviour)EnchantingTableUI.instance).isActiveAndEnabled && !InUseDistance((Humanoid)(object)_interactingPlayer))
			{
				EnchantingTableUI.Hide();
				_interactingPlayer = null;
			}
		}

		public void Refresh()
		{
			this.OnAnyFeatureLevelChanged?.Invoke();
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public bool InUseDistance(Humanoid human)
		{
			//IL_0006: 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)
			return Vector3.Distance(((Component)human).transform.position, ((Component)this).transform.position) < 2.7f;
		}

		public string GetHoverText()
		{
			if (InUseDistance((Humanoid)(object)Player.m_localPlayer))
			{
				return Localization.instance.Localize("$mod_epicloot_assets_enchantingtable\n[<color=yellow><b>$KEY_Use</b></color>] $piece_use");
			}
			return Localization.instance.Localize("<color=#808080ff>$piece_toofar</color>");
		}

		public string GetHoverName()
		{
			return "mod_epicloot_assets_enchantingtable";
		}

		private string FormatFeatureName(string featureName)
		{
			return string.Format("el.et.v1." + featureName);
		}

		private void InitFeatureLevels()
		{
			foreach (EnchantingFeature value in Enum.GetValues(typeof(EnchantingFeature)))
			{
				string featureName = value.ToString();
				if (_nview.GetZDO().GetInt(FormatFeatureName(featureName), -888) == -888)
				{
					_nview.GetZDO().Set(FormatFeatureName(featureName), GetDefaultFeatureLevel(value) + 1);
				}
			}
		}

		private static int GetDefaultFeatureLevel(EnchantingFeature feature)
		{
			if (!UpgradesActive(feature, out var featureActive))
			{
				return 1;
			}
			if (!featureActive)
			{
				return -2;
			}
			if (!EnchantingTableUpgrades.Config.DefaultFeatureLevels.TryGetValue(feature, out var value))
			{
				return -2;
			}
			return value;
		}

		public void Reset()
		{
			foreach (EnchantingFeature value in Enum.GetValues(typeof(EnchantingFeature)))
			{
				SetFeatureLevel(value, GetDefaultFeatureLevel(value));
			}
		}

		public int GetFeatureLevel(EnchantingFeature feature)
		{
			if ((Object)(object)_nview == (Object)null || _nview.GetZDO() == null)
			{
				return -2;
			}
			if (!UpgradesActive(feature, out var featureActive))
			{
				return 1;
			}
			if (!featureActive)
			{
				return -2;
			}
			string featureName = feature.ToString();
			int @int = _nview.GetZDO().GetInt(FormatFeatureName(featureName), -2);
			_ = -2;
			if (@int != -2)
			{
				return @int - 1;
			}
			return -2;
		}

		public void SetFeatureLevel(EnchantingFeature feature, int level)
		{
			if (!((Object)(object)_nview == (Object)null))
			{
				int value;
				if (!UpgradesActive(feature, out var _))
				{
					level = 1;
				}
				else if (level > ((!EnchantingTableUpgrades.Config.MaximumFeatureLevels.TryGetValue(feature, out value)) ? 1 : value))
				{
					return;
				}
				string featureName = feature.ToString();
				_nview.GetZDO().Set(FormatFeatureName(featureName), level + 1);
				this.OnFeatureLevelChanged?.Invoke(feature, level);
				this.OnAnyFeatureLevelChanged?.Invoke();
			}
		}

		public bool IsFeatureAvailable(EnchantingFeature feature)
		{
			return GetFeatureLevel(feature) > -2;
		}

		public bool IsFeatureLocked(EnchantingFeature feature)
		{
			return GetFeatureLevel(feature) == -1;
		}

		public bool IsFeatureUnlocked(EnchantingFeature feature)
		{
			return GetFeatureLevel(feature) > -1;
		}

		public bool IsFeatureMaxLevel(EnchantingFeature feature)
		{
			return GetFeatureLevel(feature) == EnchantingTableUpgrades.GetFeatureMaxLevel(feature);
		}

		public List<InventoryItemListElement> GetFeatureUnlockCost(EnchantingFeature feature)
		{
			if (IsFeatureUnlocked(feature))
			{
				Debug.LogWarning((object)$"[EpicLoot] Warning: tried to get unlock cost for a feature that is already unlocked! ({feature})");
			}
			return EnchantingTableUpgrades.GetUpgradeCost(feature, 0);
		}

		public List<InventoryItemListElement> GetFeatureUpgradeCost(EnchantingFeature feature)
		{
			if (IsFeatureLocked(feature) || !IsFeatureAvailable(feature))
			{
				Debug.LogWarning((object)$"[EpicLoot] Warning: tried to get enchanting feature unlock cost for a feature that is locked or unavailable! ({feature})");
			}
			int featureLevel = GetFeatureLevel(feature);
			return EnchantingTableUpgrades.GetUpgradeCost(feature, featureLevel + 1);
		}

		public Tuple<float, float> GetFeatureValue(EnchantingFeature feature, int level)
		{
			if (!IsFeatureAvailable(feature))
			{
				return new Tuple<float, float>(float.NaN, float.NaN);
			}
			if (level < 0 || level > EnchantingTableUpgrades.GetFeatureMaxLevel(feature))
			{
				return new Tuple<float, float>(float.NaN, float.NaN);
			}
			List<float[]> list = feature switch
			{
				EnchantingFeature.Sacrifice => EnchantingTableUpgrades.Config.UpgradeValues.Sacrifice, 
				EnchantingFeature.ConvertMaterials => EnchantingTableUpgrades.Config.UpgradeValues.ConvertMaterials, 
				EnchantingFeature.Enchant => EnchantingTableUpgrades.Config.UpgradeValues.Enchant, 
				EnchantingFeature.Augment => EnchantingTableUpgrades.Config.UpgradeValues.Augment, 
				EnchantingFeature.Disenchant => EnchantingTableUpgrades.Config.UpgradeValues.Disenchant, 
				EnchantingFeature.Helheim => EnchantingTableUpgrades.Config.UpgradeValues.Helheim, 
				_ => throw new ArgumentOutOfRangeException("feature", feature, null), 
			};
			if (level >= list.Count)
			{
				return new Tuple<float, float>(float.NaN, float.NaN);
			}
			float[] array = list[level];
			if (array.Length == 1)
			{
				return new Tuple<float, float>(array[0], float.NaN);
			}
			if (array.Length >= 2)
			{
				return new Tuple<float, float>(array[0], array[1]);
			}
			return new Tuple<float, float>(float.NaN, float.NaN);
		}

		public Tuple<float, float> GetFeatureCurrentValue(EnchantingFeature feature)
		{
			return GetFeatureValue(feature, GetFeatureLevel(feature));
		}
	}
	public class EnchantingTableUI : MonoBehaviour
	{
		public delegate void AugaFixupDelegate(EnchantingTableUI ui);

		public delegate void TabActivationDelegate(EnchantingTableUI ui);

		public GameObject Root;

		public GameObject Scrim;

		public TabHandler TabHandler;

		public GameObject TabScrim;

		[Header("Content")]
		public EnchantingTableUIPanelBase[] Panels;

		[Header("Audio")]
		public AudioSource Audio;

		public AudioClip TabClickSFX;

		public AudioClip EnchantBonusSFX;

		public static AugaFixupDelegate AugaFixup;

		public static TabActivationDelegate TabActivation;

		private int _hiddenFrames;

		public EnchantingTable SourceTable { get; private set; }

		public static EnchantingTableUI instance { get; set; }

		public void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			instance = this;
			Localization.instance.Localize(((Component)this).transform);
			GameObject val = GameObject.Find("sfx_gui_button");
			if (Object.op_Implicit((Object)(object)val))
			{
				Audio.outputAudioMixerGroup = val.GetComponent<AudioSource>().outputAudioMixerGroup;
			}
			for (int i = 0; i < TabHandler.m_tabs.Count; i++)
			{
				Tab obj = TabHandler.m_tabs[i];
				obj.m_onClick.AddListener(new UnityAction(PlayTabSelectSFX));
				FeatureStatus component = ((Component)obj.m_button).gameObject.GetComponent<FeatureStatus>();
				if ((Object)(object)component != (Object)null)
				{
					component.SetFeature((EnchantingFeature)i);
				}
			}
			AugaFixup(this);
			TabActivation(this);
		}

		public static void Show(GameObject enchantingUiPrefab, EnchantingTable source)
		{
			if ((Object)(object)instance == (Object)null && (Object)(object)StoreGui.instance != (Object)null)
			{
				Transform parent = ((Component)StoreGui.instance).transform.parent;
				int siblingIndex = ((Component)StoreGui.instance).transform.GetSiblingIndex() + 1;
				Object.Instantiate<GameObject>(enchantingUiPrefab, parent).transform.SetSiblingIndex(siblingIndex);
			}
			if (!((Object)(object)instance == (Object)null))
			{
				instance.SourceTable = source;
				instance.Root.SetActive(true);
				instance.Scrim.SetActive(true);
				instance.SourceTable.Refresh();
				EnchantingTableUIPanelBase[] panels = instance.Panels;
				for (int i = 0; i < panels.Length; i++)
				{
					panels[i].DeselectAll();
				}
			}
		}

		public static void Hide()
		{
			if (!((Object)(object)instance == (Object)null))
			{
				instance.Root.SetActive(false);
				instance.Scrim.SetActive(false);
				instance.SourceTable = null;
			}
		}

		public static bool IsVisible()
		{
			if ((Object)(object)instance != (Object)null)
			{
				if (instance._hiddenFrames > 2)
				{
					if ((Object)(object)instance.Root != (Object)null)
					{
						return instance.Root.activeSelf;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		public static bool IsInTextInput()
		{
			if (!IsVisible())
			{
				return false;
			}
			InputField[] componentsInChildren = instance.Root.GetComponentsInChildren<InputField>(false);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (componentsInChildren[i].isFocused)
				{
					return true;
				}
			}
			return false;
		}

		public void Update()
		{
			if ((Object)(object)Root == (Object)null)
			{
				return;
			}
			if (!Root.activeSelf)
			{
				_hiddenFrames++;
				return;
			}
			_hiddenFrames = 0;
			if (((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || Menu.IsVisible() || ((Object)(object)TextViewer.instance != (Object)null && TextViewer.instance.IsVisible()) || ((Character)Player.m_localPlayer).InCutscene() || (!ZInput.GetButtonDown("JoyButtonB") && !Input.GetKeyDown((KeyCode)27) && !Input.GetKeyDown((KeyCode)9)))
			{
				return;
			}
			ZInput.ResetButtonStatus("JoyButtonB");
			ZInput.ResetButtonStatus("JoyJump");
			bool flag = false;
			EnchantingTableUIPanelBase[] panels = Panels;
			foreach (EnchantingTableUIPanelBase enchantingTableUIPanelBase in panels)
			{
				if (((Behaviour)enchantingTableUIPanelBase).isActiveAndEnabled && enchantingTableUIPanelBase.CanCancel())
				{
					enchantingTableUIPanelBase.Cancel();
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				Hide();
			}
		}

		public static void UpdateTabActivation()
		{
			TabActivation(instance);
		}

		public static void UpdateUpgradeActivation()
		{
			TabActivation(instance);
		}

		public void LockTabs()
		{
			TabScrim.SetActive(true);
		}

		public void UnlockTabs()
		{
			TabScrim.SetActive(false);
		}

		public void PlayTabSelectSFX()
		{
			Audio.PlayOneShot(TabClickSFX);
		}

		public void PlayEnchantBonusSFX()
		{
			Audio.PlayOneShot(EnchantBonusSFX);
		}
	}
	public abstract class EnchantingTableUIPanelBase : MonoBehaviour
	{
		public const float CountdownTime = 0.8f;

		public MultiSelectItemList AvailableItems;

		public Button MainButton;

		public GameObject LevelDisplay;

		public GuiBar ProgressBar;

		public AudioSource Audio;

		public AudioClip ProgressLoopSFX;

		public AudioClip CompleteSFX;

		protected bool _inProgress;

		protected float _countdown;

		protected Text _buttonLabel;

		protected TMP_Text _tmpButtonLabel;

		protected bool _useTMP;

		protected string _defaultButtonLabelText;

		protected bool _locked;

		protected abstract void DoMainAction();

		protected abstract void OnSelectedItemsChanged();

		public virtual void Awake()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			if ((Object)(object)AvailableItems != (Object)null)
			{
				AvailableItems.OnSelectedItemsChanged += OnSelectedItemsChanged;
				AvailableItems.GiveFocus(focused: true, 0);
			}
			if ((Object)(object)MainButton != (Object)null)
			{
				((UnityEvent)MainButton.onClick).AddListener(new UnityAction(OnMainButtonClicked));
				_buttonLabel = ((Component)MainButton).GetComponentInChildren<Text>();
				if ((Object)(object)_buttonLabel == (Object)null)
				{
					_tmpButtonLabel = ((Component)MainButton).GetComponentInChildren<TMP_Text>();
					_useTMP = true;
				}
				_defaultButtonLabelText = (_useTMP ? _tmpButtonLabel.text : _buttonLabel.text);
			}
			GameObject val = GameObject.Find("sfx_gui_button");
			if (Object.op_Implicit((Object)(object)val) && (Object)(object)Audio != (Object)null)
			{
				Audio.outputAudioMixerGroup = val.GetComponent<AudioSource>().outputAudioMixerGroup;
			}
		}

		protected virtual void OnMainButtonClicked()
		{
			if (_inProgress)
			{
				Cancel();
			}
			else
			{
				StartProgress();
			}
		}

		public virtual void DeselectAll()
		{
		}

		public virtual void Update()
		{
			if ((Object)(object)ProgressBar != (Object)null)
			{
				((Component)ProgressBar).gameObject.SetActive(_inProgress);
			}
			if ((Object)(object)LevelDisplay != (Object)null)
			{
				LevelDisplay.gameObject.SetActive(!_inProgress);
			}
			if (!_inProgress)
			{
				return;
			}
			if ((Object)(object)ProgressBar != (Object)null)
			{
				ProgressBar.SetValue(0.8f - _countdown);
			}
			_countdown -= Time.deltaTime;
			if (_countdown < 0f)
			{
				_inProgress = false;
				_countdown = 0f;
				if ((Object)(object)Audio != (Object)null)
				{
					Audio.loop = false;
					Audio.Stop();
				}
				DoMainAction();
				PlayCompleteSFX();
			}
		}

		private void PlayCompleteSFX()
		{
			AudioClip completeAudioClip = GetCompleteAudioClip();
			if ((Object)(object)Audio != (Object)null && (Object)(object)completeAudioClip != (Object)null)
			{
				Audio.PlayOneShot(completeAudioClip);
			}
		}

		protected virtual AudioClip GetCompleteAudioClip()
		{
			return CompleteSFX;
		}

		public virtual void StartProgress()
		{
			if (_useTMP)
			{
				_tmpButtonLabel.text = Localization.instance.Localize("$menu_cancel");
			}
			else
			{
				_buttonLabel.text = Localization.instance.Localize("$menu_cancel");
			}
			_inProgress = true;
			_countdown = 0.8f;
			if ((Object)(object)ProgressBar != (Object)null)
			{
				ProgressBar.SetMaxValue(0.8f);
			}
			if ((Object)(object)Audio != (Object)null)
			{
				Audio.loop = true;
				Audio.clip = ProgressLoopSFX;
				Audio.Play();
			}
			Lock();
		}

		public virtual bool CanCancel()
		{
			return _inProgress;
		}

		public virtual void Cancel()
		{
			if (_useTMP)
			{
				_tmpButtonLabel.text = Localization.instance.Localize(_defaultButtonLabelText);
			}
			else
			{
				_buttonLabel.text = Localization.instance.Localize(_defaultButtonLabelText);
			}
			_inProgress = false;
			_countdown = 0f;
			if ((Object)(object)Audio != (Object)null)
			{
				Audio.loop = false;
				Audio.Stop();
			}
			Unlock();
		}

		public virtual void Lock()
		{
			_locked = true;
			MultiSelectItemList[] componentsInChildren = ((Component)this).GetComponentsInChildren<MultiSelectItemList>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].Lock();
			}
			EnchantingTableUI.instance.LockTabs();
		}

		public virtual void Unlock()
		{
			_locked = false;
			MultiSelectItemList[] componentsInChildren = ((Component)this).GetComponentsInChildren<MultiSelectItemList>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].Unlock();
			}
			EnchantingTableUI.instance.UnlockTabs();
		}

		protected static bool LocalPlayerCanAffordCost(List<InventoryItemListElement> cost)
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer.NoCostCheat())
			{
				return true;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			foreach (InventoryItemListElement item2 in cost)
			{
				ItemData item = item2.GetItem();
				if (inventory.CountItems(item.m_shared.m_name, -1, true) < item.m_stack)
				{
					return false;
				}
			}
			return true;
		}

		protected static void GiveItemsToPlayer(List<InventoryItemListElement> sacrificeProducts)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00d2: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			foreach (InventoryItemListElement sacrificeProduct in sacrificeProducts)
			{
				ItemData item = sacrificeProduct.GetItem();
				do
				{
					ItemData val = item.Clone();
					val.m_stack = Mathf.Min(item.m_stack, item.m_shared.m_maxStackSize);
					item.m_stack -= val.m_stack;
					if (inventory.CanAddItem(val, -1))
					{
						inventory.AddItem(val);
						((Character)localPlayer).Message((MessageType)1, "$msg_added " + val.m_shared.m_name, val.m_stack, val.GetIcon());
					}
					else
					{
						ItemDrop val2 = ItemDrop.DropItem(val, val.m_stack, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + ((Component)localPlayer).transform.up, ((Component)localPlayer).transform.rotation);
						((Component)val2).GetComponent<Rigidbody>().velocity = Vector3.up * 5f;
						((Character)localPlayer).Message((MessageType)1, "$msg_dropped " + val2.m_itemData.m_shared.m_name + " $mod_epicloot_sacrifice_inventoryfullexplanation", val2.m_itemData.m_stack, val2.m_itemData.GetIcon());
					}
				}
				while (item.m_stack > 0);
			}
		}
	}
	public enum EnchantingFeature
	{
		Sacrifice,
		ConvertMaterials,
		Enchant,
		Augment,
		Disenchant,
		Helheim
	}
	[Serializable]
	public class ItemAmount
	{
		public string Item = "";

		public int Amount = 1;
	}
	[Serializable]
	public class EnchantingUpgradeCosts
	{
		public List<List<ItemAmount>> Sacrifice;

		public List<List<ItemAmount>> ConvertMaterials;

		public List<List<ItemAmount>> Enchant;

		public List<List<ItemAmount>> Augment;

		public List<List<ItemAmount>> Disenchant;

		public List<List<ItemAmount>> Helheim;
	}
	[Serializable]
	public class EnchantingFeatureValues
	{
		public List<float[]> Sacrifice;

		public List<float[]> ConvertMaterials;

		public List<float[]> Enchant;

		public List<float[]> Augment;

		public List<float[]> Disenchant;

		public List<float[]> Helheim;
	}
	[Serializable]
	public class EnchantingUpgradesConfig
	{
		public Dictionary<EnchantingFeature, int> DefaultFeatureLevels;

		public Dictionary<EnchantingFeature, int> MaximumFeatureLevels;

		public EnchantingUpgradeCosts UpgradeCosts;

		public EnchantingFeatureValues UpgradeValues;
	}
	public class EnchantingFeatureUpgradeRequest
	{
		public ZDOID TableZDO;

		public EnchantingFeature Feature;

		public int ToLevel;

		public Action<bool> ResponseCallback;
	}
	public static class EnchantingTableUpgrades
	{
		public static EnchantingUpgradesConfig Config;

		public static void InitializeConfig(EnchantingUpgradesConfig config)
		{
			Config = config;
		}

		public static string GetFeatureName(EnchantingFeature feature)
		{
			return (new string[6] { "$mod_epicloot_sacrifice", "$mod_epicloot_convertmaterials", "$mod_epicloot_enchant", "$mod_epicloot_augment", "$mod_epicloot_disenchant", "$mod_epicloot_helheim" })[(int)feature];
		}

		public static string GetFeatureDescription(EnchantingFeature feature)
		{
			return (new string[6] { "$mod_epicloot_featureinfo_sacrifice", "$mod_epicloot_featureinfo_convertmaterials", "$mod_epicloot_featureinfo_enchant", "$mod_epicloot_featureinfo_augment", "$mod_epicloot_featureinfo_disenchant", "$mod_epicloot_featureinfo_helheim" })[(int)feature];
		}

		public static string GetFeatureUpgradeLevelDescription(EnchantingTable table, EnchantingFeature feature, int level)
		{
			string[] array = new string[6] { "$mod_epicloot_featureupgrade_sacrifice", "$mod_epicloot_featureupgrade_convertmaterials", "$mod_epicloot_featureupgrade_enchant", "$mod_epicloot_featureupgrade_augment", "$mod_epicloot_featureupgrade_disenchant", "$mod_epicloot_featureupgrade_helheim" };
			Tuple<float, float> featureValue = table.GetFeatureValue(feature, level);
			return Localization.instance.Localize(array[(int)feature], new string[2]
			{
				featureValue.Item1.ToString("0.#"),
				featureValue.Item2.ToString("0.#")
			});
		}

		public static int GetFeatureMaxLevel(EnchantingFeature feature)
		{
			if (!Config.MaximumFeatureLevels.TryGetValue(feature, out var value))
			{
				return 1;
			}
			return value;
		}

		public static List<InventoryItemListElement> GetUpgradeCost(EnchantingFeature feature, int level)
		{
			List<InventoryItemListElement> list = new List<InventoryItemListElement>();
			List<List<ItemAmount>> list2 = feature switch
			{
				EnchantingFeature.Sacrifice => Config.UpgradeCosts.Sacrifice, 
				EnchantingFeature.ConvertMaterials => Config.UpgradeCosts.ConvertMaterials, 
				EnchantingFeature.Enchant => Config.UpgradeCosts.Enchant, 
				EnchantingFeature.Augment => Config.UpgradeCosts.Augment, 
				EnchantingFeature.Disenchant => Config.UpgradeCosts.Disenchant, 
				EnchantingFeature.Helheim => Config.UpgradeCosts.Helheim, 
				_ => throw new ArgumentOutOfRangeException("feature", feature, null), 
			};
			if (list2 == null)
			{
				return list;
			}
			if (level < 0 || level >= list2.Count)
			{
				Debug.LogWarning((object)$"[EpicLoot] Warning: tried to get enchanting feature upgrade cost for level that does not exist ({feature}, {level})");
				return list;
			}
			List<ItemAmount> list3 = list2[level];
			if (list3 == null)
			{
				return list;
			}
			foreach (ItemAmount item in list3)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Item);
				if ((Object)(object)itemPrefab == (Object)null)
				{
					Debug.LogWarning((object)$"[EpicLoot] Tried to add unknown item ({item.Item}) to upgrade cost for feature ({feature}, {level})");
					continue;
				}
				ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null)
				{
					Debug.LogWarning((object)$"[EpicLoot] Tried to add item without ItemDrop ({item.Item}) to upgrade cost for feature ({feature}, {level})");
					continue;
				}
				ItemData val = component.m_itemData.Clone();
				val.m_dropPrefab = itemPrefab;
				val.m_stack = item.Amount;
				list.Add(new InventoryItemListElement
				{
					Item = val
				});
			}
			return list;
		}
	}
	public class EnchantUI : EnchantingTableUIPanelBase
	{
		public delegate List<InventoryItemListElement> GetEnchantableItemsDelegate();

		public delegate string GetEnchantInfoDelegate(ItemData item, MagicRarityUnity rarity);

		public delegate List<InventoryItemListElement> GetEnchantCostDelegate(ItemData item, MagicRarityUnity rarity);

		public delegate GameObject EnchantItemDelegate(ItemData item, MagicRarityUnity rarity);

		public Text EnchantInfo;

		public Scrollbar EnchantInfoScrollbar;

		public List<Toggle> RarityButtons;

		[Header("Cost")]
		public Text CostLabel;

		public MultiSelectItemList CostList;

		public AudioClip[] EnchantCompleteSFX;

		public static GetEnchantableItemsDelegate GetEnchantableItems;

		public static GetEnchantInfoDelegate GetEnchantInfo;

		public static GetEnchantCostDelegate GetEnchantCost;

		public static EnchantItemDelegate EnchantItem;

		private ToggleGroup _toggleGroup;

		private MagicRarityUnity _rarity;

		private GameObject _successDialog;

		public override void Awake()
		{
			base.Awake();
			if (RarityButtons.Count > 0)
			{
				_toggleGroup = RarityButtons[0].group;
				_toggleGroup.EnsureValidState();
			}
			for (int i = 0; i < RarityButtons.Count; i++)
			{
				((UnityEvent<bool>)(object)RarityButtons[i].onValueChanged).AddListener((UnityAction<bool>)delegate(bool isOn)
				{
					if (isOn)
					{
						RefreshRarity();
					}
				});
			}
		}

		[UsedImplicitly]
		public void OnEnable()
		{
			_rarity = MagicRarityUnity.Magic;
			OnRarityChanged();
			RarityButtons[0].isOn = true;
			List<InventoryItemListElement> source = GetEnchantableItems();
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
		}

		public override void Update()
		{
			base.Update();
			if (!_locked && ZInput.IsGamepadActive())
			{
				if (ZInput.GetButtonDown("JoyButtonY"))
				{
					int index = (int)(_rarity + 1) % RarityButtons.Count;
					RarityButtons[index].isOn = true;
					ZInput.ResetButtonStatus("JoyButtonY");
				}
				if ((Object)(object)EnchantInfoScrollbar != (Object)null)
				{
					float joyRightStickY = ZInput.GetJoyRightStickY();
					if (Mathf.Abs(joyRightStickY) > 0.5f)
					{
						EnchantInfoScrollbar.value = Mathf.Clamp01(EnchantInfoScrollbar.value + joyRightStickY * -0.1f);
					}
				}
			}
			if ((Object)(object)_successDialog != (Object)null && !_successDialog.activeSelf)
			{
				Unlock();
				Object.Destroy((Object)(object)_successDialog);
				_successDialog = null;
			}
		}

		public void RefreshRarity()
		{
			MagicRarityUnity rarity = _rarity;
			for (int i = 0; i < RarityButtons.Count; i++)
			{
				if (RarityButtons[i].isOn)
				{
					_rarity = (MagicRarityUnity)i;
				}
			}
			if (rarity != _rarity)
			{
				OnRarityChanged();
			}
		}

		public void OnRarityChanged()
		{
			Tuple<InventoryItemListElement, int> singleSelectedItem = AvailableItems.GetSingleSelectedItem<InventoryItemListElement>();
			if (singleSelectedItem?.Item1.GetItem() == null)
			{
				((Selectable)MainButton).interactable = false;
				EnchantInfo.text = "";
				((Behaviour)CostLabel).enabled = false;
				CostList.SetItems(new List<IListElement>());
				return;
			}
			ItemData item = singleSelectedItem.Item1.GetItem();
			string text = GetEnchantInfo(item, _rarity);
			EnchantInfo.text = text;
			ScrollEnchantInfoToTop();
			((Behaviour)CostLabel).enabled = true;
			List<InventoryItemListElement> list = GetEnchantCost(item, _rarity);
			CostList.SetItems(list.Cast<IListElement>().ToList());
			bool flag = EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(list);
			bool flag2 = EnchantingTableUI.instance.SourceTable.IsFeatureUnlocked(EnchantingFeature.Enchant);
			((Selectable)MainButton).interactable = flag2 && flag;
		}

		private void ScrollEnchantInfoToTop()
		{
			EnchantInfoScrollbar.value = 1f;
		}

		protected override void DoMainAction()
		{
			Tuple<InventoryItemListElement, int> tuple = AvailableItems.GetSelectedItems<InventoryItemListElement>().FirstOrDefault();
			Cancel();
			if (tuple?.Item1.GetItem() == null)
			{
				return;
			}
			ItemData item = tuple.Item1.GetItem();
			List<InventoryItemListElement> list = GetEnchantCost(item, _rarity);
			Player localPlayer = Player.m_localPlayer;
			if (!localPlayer.NoCostCheat())
			{
				if (!EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(list))
				{
					Debug.LogError((object)"[Enchant Item] ERROR: Tried to enchant item but could not afford the cost. This should not happen!");
					return;
				}
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				foreach (InventoryItemListElement item3 in list)
				{
					ItemData item2 = item3.GetItem();
					inventory.RemoveItem(item2.m_shared.m_name, item2.m_stack, -1, true);
				}
			}
			if ((Object)(object)_successDialog != (Object)null)
			{
				Object.Destroy((Object)(object)_successDialog);
			}
			DeselectAll();
			Lock();
			_successDialog = EnchantItem(item, _rarity);
			RefreshAvailableItems();
		}

		protected override AudioClip GetCompleteAudioClip()
		{
			return EnchantCompleteSFX[(int)_rarity];
		}

		public void RefreshAvailableItems()
		{
			List<InventoryItemListElement> source = GetEnchantableItems();
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
			AvailableItems.DeselectAll();
			OnSelectedItemsChanged();
		}

		protected override void OnSelectedItemsChanged()
		{
			OnRarityChanged();
		}

		public override bool CanCancel()
		{
			if (!base.CanCancel())
			{
				if ((Object)(object)_successDialog != (Object)null)
				{
					return _successDialog.activeSelf;
				}
				return false;
			}
			return true;
		}

		public override void Cancel()
		{
			base.Cancel();
			if ((Object)(object)_successDialog != (Object)null && _successDialog.activeSelf)
			{
				Object.Destroy((Object)(object)_successDialog);
				_successDialog = null;
			}
			OnRarityChanged();
		}

		public override void Lock()
		{
			base.Lock();
			foreach (Toggle rarityButton in RarityButtons)
			{
				((Selectable)rarityButton).interactable = false;
			}
		}

		public override void Unlock()
		{
			base.Unlock();
			foreach (Toggle rarityButton in RarityButtons)
			{
				((Selectable)rarityButton).interactable = true;
			}
		}

		public override void DeselectAll()
		{
			AvailableItems.DeselectAll();
		}
	}
	public class FeatureStatus3D : MonoBehaviour
	{
		public EnchantingTable SourceTable;

		public EnchantingFeature Feature;

		public GameObject UnlockedObject;

		public GameObject[] LevelObjects;

		public void OnEnable()
		{
			SourceTable.OnAnyFeatureLevelChanged += Refresh;
			Refresh();
		}

		public void OnDisable()
		{
			SourceTable.OnAnyFeatureLevelChanged -= Refresh;
		}

		public void Refresh()
		{
			bool flag = SourceTable.IsFeatureAvailable(Feature) && SourceTable.IsFeatureUnlocked(Feature);
			if ((Object)(object)UnlockedObject != (Object)null)
			{
				UnlockedObject.SetActive(flag);
			}
			int featureLevel = SourceTable.GetFeatureLevel(Feature);
			for (int i = 0; i < LevelObjects.Length; i++)
			{
				GameObject val = LevelObjects[i];
				if (!((Object)(object)val == (Object)null))
				{
					val.SetActive(flag && featureLevel == i);
				}
			}
			if (flag && featureLevel >= LevelObjects.Length && (Object)(object)LevelObjects[LevelObjects.Length - 1] != (Object)null)
			{
				LevelObjects[LevelObjects.Length - 1].SetActive(true);
			}
		}
	}
	public interface IListElement
	{
		ItemData GetItem();

		int GetMax();

		string GetDisplayNameSuffix();
	}
	public class InventoryItemListElement : IListElement
	{
		public ItemData Item;

		public ItemData GetItem()
		{
			return Item;
		}

		public int GetMax()
		{
			return Item?.m_stack ?? 0;
		}

		public string GetDisplayNameSuffix()
		{
			return string.Empty;
		}
	}
	public class MultiSelectItemList : MonoBehaviour
	{
		public enum SortMode
		{
			Rarity,
			Name,
			Quantity
		}

		public delegate List<IListElement> SortByRarityDelegate(List<IListElement> items);

		public delegate List<IListElement> SortByNameDelegate(List<IListElement> items);

		public bool Multiselect = true;

		public bool Filterable = true;

		public bool Sortable = true;

		public bool ReadOnly;

		public Transform ListContainer;

		public MultiSelectItemListElement ElementPrefab;

		public Dropdown SortByDropdown;

		public InputField FilterByText;

		public Toggle SelectAllToggle;

		public static SortByRarityDelegate SortByRarity;

		public static SortByNameDelegate SortByName;

		private bool _locked;

		private bool _hasGamepadFocus;

		private ScrollRectEnsureVisible _scrollRectEnsureVisible;

		public event Action OnSelectedItemsChanged;

		public event Action OnItemsChanged;

		public void Awake()
		{
			ScrollRect componentInChildren = ((Component)this).GetComponentInChildren<ScrollRect>();
			_scrollRectEnsureVisible = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).GetComponent<ScrollRectEnsureVisible>() : null);
			if ((Object)(object)SelectAllToggle != (Object)null)
			{
				((UnityEvent<bool>)(object)SelectAllToggle.onValueChanged).AddListener((UnityAction<bool>)OnSelectAllToggled);
			}
			if ((Object)(object)SortByDropdown != (Object)null)
			{
				foreach (OptionData option in SortByDropdown.options)
				{
					option.text = Localization.instance.Localize(option.text);
				}
				((UnityEvent<int>)(object)SortByDropdown.onValueChanged).AddListener((UnityAction<int>)OnSortModeChanged);
			}
			if ((Object)(object)FilterByText != (Object)null)
			{
				((UnityEvent<string>)(object)FilterByText.onValueChanged).AddListener((UnityAction<string>)OnFilterChanged);
			}
			Refresh();
		}

		public void Update()
		{
			if (_locked || !HasGamepadFocus() || !ZInput.IsGamepadActive() || (Object)(object)ListContainer == (Object)null)
			{
				return;
			}
			int childCount = ListContainer.childCount;
			MultiSelectItemListElement focusedElement = GetFocusedElement();
			if ((Object)(object)focusedElement == (Object)null)
			{
				return;
			}
			int siblingIndex = ((Component)focusedElement).transform.GetSiblingIndex();
			GridLayoutGroup component = ((Component)ListContainer).GetComponent<GridLayoutGroup>();
			if ((Object)(object)((Component)ListContainer).GetComponent<VerticalLayoutGroup>() != (Object)null)
			{
				if (siblingIndex > 0 && ZInput.GetButtonDown("JoyLStickUp"))
				{
					focusedElement.GiveFocus(focused: false);
					MultiSelectItemListElement element = GetElement(siblingIndex - 1);
					element.GiveFocus(focused: true);
					CenterOnItem(element);
					ZInput.ResetButtonStatus("JoyLStickUp");
				}
				else if (siblingIndex < childCount - 1 && ZInput.GetButtonDown("JoyLStickDown"))
				{
					focusedElement.GiveFocus(focused: false);
					MultiSelectItemListElement element2 = GetElement(siblingIndex + 1);
					element2.GiveFocus(focused: true);
					CenterOnItem(element2);
					ZInput.ResetButtonStatus("JoyLStickDown");
				}
				else if (ZInput.GetButtonDown("JoyLStickLeft"))
				{
					ZInput.ResetButtonStatus("JoyLStickLeft");
				}
				else if (ZInput.GetButtonDown("JoyLStickRight"))
				{
					ZInput.ResetButtonStatus("JoyLStickRight");
				}
			}
			else if ((Object)(object)component != (Object)null)
			{
				int constraintCount = component.constraintCount;
				if (siblingIndex >= constraintCount && ZInput.GetButtonDown("JoyLStickUp"))
				{
					focusedElement.GiveFocus(focused: false);
					MultiSelectItemListElement element3 = GetElement(siblingIndex - constraintCount);
					element3.GiveFocus(focused: true);
					CenterOnItem(element3);
					ZInput.ResetButtonStatus("JoyLStickUp");
				}
				else if (siblingIndex < childCount - constraintCount && ZInput.GetButtonDown("JoyLStickDown"))
				{
					focusedElement.GiveFocus(focused: false);
					MultiSelectItemListElement element4 = GetElement(siblingIndex + constraintCount);
					element4.GiveFocus(focused: true);
					CenterOnItem(element4);
					ZInput.ResetButtonStatus("JoyLStickDown");
				}
				else if (siblingIndex % constraintCount > 0 && ZInput.GetButtonDown("JoyLStickLeft"))
				{
					focusedElement.GiveFocus(focused: false);
					MultiSelectItemListElement element5 = GetElement(siblingIndex - 1);
					element5.GiveFocus(focused: true);
					CenterOnItem(element5);
					ZInput.ResetButtonStatus("JoyLStickLeft");
				}
				else if (siblingIndex % constraintCount < constraintCount - 1 && siblingIndex < childCount - 1 && ZInput.GetButtonDown("JoyLStickRight"))
				{
					focusedElement.GiveFocus(focused: false);
					MultiSelectItemListElement element6 = GetElement(siblingIndex + 1);
					element6.GiveFocus(focused: true);
					CenterOnItem(element6);
					ZInput.ResetButtonStatus("JoyLStickRight");
				}
			}
			if (Multiselect && (Object)(object)SelectAllToggle != (Object)null && ZInput.GetButtonDown("JoyLStick"))
			{
				SelectAllToggle.isOn = !SelectAllToggle.isOn;
				ZInput.ResetButtonStatus("JoyLStick");
			}
			if (Sortable && (Object)(object)SortByDropdown != (Object)null && ZInput.GetButtonDown("JoyRStick"))
			{
				int value = SortByDropdown.value;
				int count = SortByDropdown.options.Count;
				value = (value + 1) % count;
				SortByDropdown.value = value;
				ZInput.ResetButtonStatus("JoyRStick");
			}
		}

		private void CenterOnItem(MultiSelectItemListElement element)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if ((Object)(object)_scrollRectEnsureVisible != (Object)null)
			{
				_scrollRectEnsureVisible.CenterOnItem((RectTransform)((Component)element).transform);
			}
		}

		private void OnFilterChanged(string _)
		{
			Refresh();
		}

		public void Refresh()
		{
			RefreshFilter();
			RefreshSelectAllToggle();
		}

		private void RefreshFilter()
		{
			if ((Object)(object)FilterByText != (Object)null && !Filterable && ((Component)FilterByText).gameObject.activeSelf)
			{
				((Component)FilterByText).gameObject.SetActive(false);
			}
			if (!Filterable || (Object)(object)FilterByText == (Object)null)
			{
				return;
			}
			string text = FilterByText.text;
			bool flag = string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text);
			string[] array = (flag ? Array.Empty<string>() : text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				MultiSelectItemListElement component = ((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>();
				string text2 = component.ItemName.text;
				text2 = new Regex("<[^>]*>").Replace(text2, string.Empty);
				bool active = flag;
				string[] array2 = array;
				foreach (string value in array2)
				{
					if (text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						active = true;
						break;
					}
				}
				((Component)component).gameObject.SetActive(active);
			}
		}

		public void RefreshSelectAllToggle()
		{
			if (!((Object)(object)SelectAllToggle != (Object)null))
			{
				return;
			}
			if (!Multiselect && ((Component)SelectAllToggle).gameObject.activeSelf)
			{
				((Component)SelectAllToggle).gameObject.SetActive(false);
				return;
			}
			bool isOnWithoutNotify = true;
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				if (!((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>().IsMaxSelected())
				{
					isOnWithoutNotify = false;
				}
			}
			SelectAllToggle.SetIsOnWithoutNotify(isOnWithoutNotify);
		}

		private void OnSelectAllToggled(bool _ = true)
		{
			if ((Object)(object)SelectAllToggle == (Object)null)
			{
				return;
			}
			if (SelectAllToggle.isOn)
			{
				ForeachElement(delegate(int _, MultiSelectItemListElement x)
				{
					x.SelectMaxQuantity(noSound: true);
				});
			}
			else
			{
				ForeachElement(delegate(int _, MultiSelectItemListElement x)
				{
					x.Deselect(noSound: true);
				});
			}
			RefreshSelectAllToggle();
		}

		private void OnSortModeChanged(int sortModeValue)
		{
			if (!Sortable || (Object)(object)SortByDropdown == (Object)null)
			{
				return;
			}
			Dictionary<IListElement, int> currentSelectionAmounts = GetCurrentSelectionAmounts();
			List<IListElement> items = currentSelectionAmounts.Keys.ToList();
			SortMode value = (SortMode)SortByDropdown.value;
			List<IListElement> list = SortItems(value, items);
			for (int i = 0; i < list.Count; i++)
			{
				Transform child = ListContainer.GetChild(i);
				IListElement listElement = list[i];
				MultiSelectItemListElement component = ((Component)child).GetComponent<MultiSelectItemListElement>();
				component.SuppressEvents = true;
				component.SetItem(listElement);
				if (currentSelectionAmounts.TryGetValue(listElement, out var value2))
				{
					component.SelectQuantity(value2, noSound: true);
				}
				component.SuppressEvents = false;
			}
			RefreshSelectAllToggle();
		}

		public Dictionary<IListElement, int> GetCurrentSelectionAmounts()
		{
			Dictionary<IListElement, int> dictionary = new Dictionary<IListElement, int>();
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				MultiSelectItemListElement component = ((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>();
				if ((Object)(object)component != (Object)null && component.GetItem() != null)
				{
					dictionary.Add(component.GetListElement(), component.GetSelectedQuantity());
				}
			}
			return dictionary;
		}

		private void MakeEnoughElements(int itemCount)
		{
			int childCount = ListContainer.childCount;
			if (childCount > itemCount)
			{
				for (int num = childCount - 1; num >= itemCount; num--)
				{
					Transform child = ListContainer.GetChild(num);
					((Component)child).GetComponent<MultiSelectItemListElement>().OnSelectionChanged -= OnElementSelectionChanged;
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
			else if (childCount < itemCount)
			{
				for (int i = childCount; i < itemCount; i++)
				{
					MultiSelectItemListElement multiSelectItemListElement = Object.Instantiate<MultiSelectItemListElement>(ElementPrefab, ListContainer);
					multiSelectItemListElement.SuppressEvents = true;
					multiSelectItemListElement.OnSelectionChanged += OnElementSelectionChanged;
				}
			}
		}

		public void SetItems(List<IListElement> items)
		{
			int count = items.Count;
			Dictionary<IListElement, int> currentSelectionAmounts = GetCurrentSelectionAmounts();
			MultiSelectItemListElement focusedElement = GetFocusedElement();
			MakeEnoughElements(count);
			List<IListElement> list = items;
			if (Sortable && (Object)(object)SortByDropdown != (Object)null)
			{
				SortMode value = (SortMode)SortByDropdown.value;
				list = SortItems(value, items);
			}
			bool flag = false;
			for (int i = 0; i < count; i++)
			{
				Transform child = ListContainer.GetChild(i);
				IListElement listElement = list[i];
				MultiSelectItemListElement component = ((Component)child).GetComponent<MultiSelectItemListElement>();
				component.SuppressEvents = true;
				component.SetItem(listElement);
				if (currentSelectionAmounts.TryGetValue(listElement, out var value2))
				{
					component.SelectQuantity(value2, noSound: true);
				}
				component.SuppressEvents = false;
				bool flag2 = HasGamepadFocus() && (((Object)(object)focusedElement == (Object)null && i == 0) || (Object)(object)component == (Object)(object)focusedElement);
				component.GiveFocus(flag2);
				if (flag2)
				{
					flag = true;
					CenterOnItem(component);
				}
			}
			if (HasGamepadFocus() && !flag && ListContainer.childCount > 0)
			{
				_hasGamepadFocus = false;
				GiveFocus(focused: true, 0);
				CenterOnItem(GetElement(0));
			}
			this.OnItemsChanged?.Invoke();
			this.OnSelectedItemsChanged?.Invoke();
			RefreshSelectAllToggle();
		}

		private void OnElementSelectionChanged(MultiSelectItemListElement element, bool isSelected, int selectedQuantity)
		{
			if (!Multiselect)
			{
				ForeachElement(delegate(int _, MultiSelectItemListElement x)
				{
					if ((Object)(object)x != (Object)(object)element)
					{
						x.SuppressEvents = true;
						x.Deselect(noSound: true);
						x.SuppressEvents = false;
					}
				});
			}
			this.OnSelectedItemsChanged?.Invoke();
			RefreshSelectAllToggle();
		}

		public List<IListElement> SortItems(SortMode mode, List<IListElement> items)
		{
			switch (mode)
			{
			case SortMode.Rarity:
				if (SortByRarity != null)
				{
					return SortByRarity(items);
				}
				return items.ToList();
			case SortMode.Name:
				if (SortByName != null)
				{
					return SortByName(items);
				}
				return (from x in items
					orderby Localization.instance.Localize(x.GetItem().m_shared.m_name), x.GetItem().m_stack descending
					select x).ToList();
			case SortMode.Quantity:
				return (from x in items
					orderby x.GetItem().m_stack descending, Localization.instance.Localize(x.GetItem().m_shared.m_name)
					select x).ToList();
			default:
				throw new ArgumentOutOfRangeException("mode", mode, null);
			}
		}

		public List<Tuple<T, int>> GetSelectedItems<T>()
		{
			List<Tuple<T, int>> list = new List<Tuple<T, int>>();
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				MultiSelectItemListElement component = ((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>();
				int selectedQuantity = component.GetSelectedQuantity();
				if (selectedQuantity > 0)
				{
					list.Add(new Tuple<T, int>((T)component.GetListElement(), selectedQuantity));
				}
			}
			return list;
		}

		public Tuple<T, int> GetSingleSelectedItem<T>()
		{
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				MultiSelectItemListElement component = ((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>();
				int selectedQuantity = component.GetSelectedQuantity();
				if (selectedQuantity > 0)
				{
					return new Tuple<T, int>((T)component.GetListElement(), selectedQuantity);
				}
			}
			return null;
		}

		public int GetFirstSelectedIndex()
		{
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				if (((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>().GetSelectedQuantity() > 0)
				{
					return i;
				}
			}
			return -1;
		}

		public void Lock()
		{
			_locked = true;
			if ((Object)(object)SortByDropdown != (Object)null)
			{
				((Selectable)SortByDropdown).interactable = false;
			}
			if ((Object)(object)FilterByText != (Object)null)
			{
				((Selectable)FilterByText).interactable = false;
			}
			if ((Object)(object)SelectAllToggle != (Object)null)
			{
				((Selectable)SelectAllToggle).interactable = false;
			}
			ForeachElement(delegate(int _, MultiSelectItemListElement e)
			{
				e.Lock();
			});
		}

		public void Unlock()
		{
			_locked = false;
			if ((Object)(object)SortByDropdown != (Object)null)
			{
				((Selectable)SortByDropdown).interactable = Sortable && !ReadOnly;
			}
			if ((Object)(object)FilterByText != (Object)null)
			{
				((Selectable)FilterByText).interactable = Filterable && !ReadOnly;
			}
			if ((Object)(object)SelectAllToggle != (Object)null)
			{
				((Selectable)SelectAllToggle).interactable = Multiselect && !ReadOnly;
			}
			ForeachElement(delegate(int _, MultiSelectItemListElement e)
			{
				e.Unlock();
			});
		}

		private MultiSelectItemListElement GetElement(int index)
		{
			Transform child = ListContainer.GetChild(index);
			if (!((Object)(object)child == (Object)null))
			{
				return ((Component)child).GetComponent<MultiSelectItemListElement>();
			}
			return null;
		}

		public void ForeachElement(Action<int, MultiSelectItemListElement> func)
		{
			if ((Object)(object)ListContainer == (Object)null)
			{
				return;
			}
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				MultiSelectItemListElement element = GetElement(i);
				if ((Object)(object)element != (Object)null)
				{
					func(i, element);
				}
			}
		}

		public void DeselectAll()
		{
			SuppressEvents(suppress: true);
			ForeachElement(delegate(int _, MultiSelectItemListElement e)
			{
				e.Deselect(noSound: true);
			});
			SuppressEvents(suppress: false);
			this.OnSelectedItemsChanged?.Invoke();
			RefreshSelectAllToggle();
		}

		public void SuppressEvents(bool suppress)
		{
			ForeachElement(delegate(int _, MultiSelectItemListElement e)
			{
				e.SuppressEvents = suppress;
			});
		}

		public void GiveFocus(bool focused, int tryFocusIndex)
		{
			if (_hasGamepadFocus == focused)
			{
				return;
			}
			_hasGamepadFocus = focused;
			int focusIndex = (focused ? Mathf.Clamp(tryFocusIndex, 0, ListContainer.childCount - 1) : (-1));
			ForeachElement(delegate(int i, MultiSelectItemListElement e)
			{
				bool flag = i == focusIndex;
				e.GiveFocus(flag);
				if (flag)
				{
					CenterOnItem(e);
				}
			});
		}

		public bool HasGamepadFocus()
		{
			return _hasGamepadFocus;
		}

		public MultiSelectItemListElement GetFocusedElement()
		{
			if ((Object)(object)ListContainer == (Object)null || !ZInput.IsGamepadActive())
			{
				return null;
			}
			int childCount = ListContainer.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = ListContainer.GetChild(i);
				if (!((Object)(object)child == (Object)null))
				{
					MultiSelectItemListElement component = ((Component)child).GetComponent<MultiSelectItemListElement>();
					if ((Object)(object)component != (Object)null && component.HasGamepadFocus())
					{
						return component;
					}
				}
			}
			return null;
		}

		public int GetItemCount()
		{
			if ((Object)(object)ListContainer == (Object)null)
			{
				return 0;
			}
			int childCount = ListContainer.childCount;
			int num = 0;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = ListContainer.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeSelf)
				{
					num++;
				}
			}
			return num;
		}

		public bool IsGrid()
		{
			if ((Object)(object)ListContainer != (Object)null)
			{
				return (Object)(object)((Component)ListContainer).GetComponent<GridLayoutGroup>() != (Object)null;
			}
			return false;
		}

		public void InitWithExistingItems()
		{
			for (int i = 0; i < ListContainer.childCount; i++)
			{
				((Component)ListContainer.GetChild(i)).GetComponent<MultiSelectItemListElement>().OnSelectionChanged += OnElementSelectionChanged;
			}
			DeselectAll();
			this.OnItemsChanged?.Invoke();
			this.OnSelectedItemsChanged?.Invoke();
			RefreshSelectAllToggle();
		}
	}
	public class MultiSelectItemListElement : MonoBehaviour
	{
		public delegate void SetMagicItemDelegate(MultiSelectItemListElement element, ItemData item, UITooltip tooltip);

		public const string TotalQuantityFormat = "/ {0}";

		public const string ReadOnlyQuantityFormat = "{0}";

		public Button MainButton;

		public Toggle SelectedToggle;

		public GameObject SelectedBackground;

		public Text ItemName;

		public Image MagicBG;

		public Image ItemIcon;

		public Text ItemTotalQuantity;

		public InputField ItemSelectedQuantity;

		public Button QuantityUpButton;

		public Button QuantityDownButton;

		public UITooltip Tooltip;

		public bool ReadOnly;

		public bool CheckPlayerInventory;

		public bool NoMax;

		public AudioSource Audio;

		public AudioClip OnClickSFX;

		public GameObject GamepadFocusIndicator;

		[NonSerialized]
		public bool SuppressEvents;

		public static SetMagicItemDelegate SetMagicItem;

		private IListElement _item;

		private int _selectedQuantity;

		private bool _locked;

		private bool _hasGamepadFocus;

		public event Action<MultiSelectItemListElement, bool, int> OnSelectionChanged;

		public void Awake()
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Expected O, but got Unknown
			if ((Object)(object)ItemIcon != (Object)null || (Object)(object)MagicBG != (Object)null)
			{
				Material material = ((Graphic)((Component)InventoryGui.instance.m_dragItemPrefab.transform.Find("icon")).GetComponent<Image>()).material;
				if ((Object)(object)material != (Object)null)
				{
					if ((Object)(object)ItemIcon != (Object)null)
					{
						((Graphic)ItemIcon).material = material;
					}
					if ((Object)(object)MagicBG != (Object)null)
					{
						((Graphic)MagicBG).material = material;
					}
				}
			}
			if ((Object)(object)Tooltip != (Object)null)
			{
				GameObject tooltipPrefab = StoreGui.instance.m_listElement.GetComponent<UITooltip>().m_tooltipPrefab;
				Tooltip.m_tooltipPrefab = tooltipPrefab;
			}
			if ((Object)(object)Audio != (Object)null)
			{
				GameObject val = GameObject.Find("sfx_gui_button");
				if ((Object)(object)val != (Object)null)
				{
					Audio.outputAudioMixerGroup = val.GetComponent<AudioSource>().outputAudioMixerGroup;
				}
			}
			if (!ReadOnly)
			{
				if ((Object)(object)MainButton != (Object)null)
				{
					((UnityEvent)MainButton.onClick).AddListener(new UnityAction(OnClicked));
				}
				if ((Object)(object)ItemSelectedQuantity != (Object)null)
				{
					((UnityEvent<string>)(object)ItemSelectedQuantity.onEndEdit).AddListener((UnityAction<string>)OnSelectedAmountChanged);
				}
				if ((Object)(object)SelectedToggle != (Object)null)
				{
					((UnityEvent<bool>)(object)SelectedToggle.onValueChanged).AddListener((UnityAction<bool>)OnSelectedToggleChanged);
				}
				if ((Object)(object)QuantityUpButton != (Object)null)
				{
					((UnityEvent)QuantityUpButton.onClick).AddListener(new UnityAction(OnQuantityUpButtonClicked));
				}
				if ((Object)(object)QuantityDownButton != (Object)null)
				{
					((UnityEvent)QuantityDownButton.onClick).AddListener(new UnityAction(OnQuantityDownButtonClicked));
				}
			}
			Refresh();
		}

		public void Update()
		{
			if (!_locked && ZInput.IsGamepadActive() && HasGamepadFocus() && !ReadOnly)
			{
				if (ZInput.GetButtonDown("JoyButtonA"))
				{
					OnClicked();
					ZInput.ResetButtonStatus("JoyButtonA");
				}
				else if (ZInput.GetButtonDown("JoyDPadUp"))
				{
					SelectQuantity(_selectedQuantity + 1, noSound: false);
					ZInput.ResetButtonStatus("JoyDPadUp");
				}
				else if (ZInput.GetButtonDown("JoyDPadDown"))
				{
					SelectQuantity(_selectedQuantity - 1, noSound: false);
					ZInput.ResetButtonStatus("JoyDPadDown");
				}
				else if (ZInput.GetButtonDown("JoyDPadLeft"))
				{
					ZInput.ResetButtonStatus("JoyDPadLeft");
				}
				else if (ZInput.GetButtonDown("JoyDPadRight"))
				{
					ZInput.ResetButtonStatus("JoyDPadRight");
				}
			}
			RefreshGamepadFocusIndicator();
		}

		private void OnClicked()
		{
			if (IsSelected())
			{
				Deselect(noSound: false);
			}
			else
			{
				SelectMaxQuantity(noSound: false);
			}
		}

		public void SelectMaxQuantity(bool noSound)
		{
			int quantity = ((NoMax || _item == null) ? 1 : (_item?.GetItem()?.m_stack).GetValueOrDefault());
			SelectQuantity(quantity, noSound);
		}

		public bool IsSelected()
		{
			return _selectedQuantity > 0;
		}

		public bool IsMaxSelected()
		{
			if (_item != null)
			{
				return _selectedQuantity >= _item.GetItem().m_stack;
			}
			return _selectedQuantity > 0;
		}

		private void OnSelectedAmountChanged(string typedInAmount)
		{
			if (!int.TryParse(typedInAmount, out var result))
			{
				Deselect(noSound: false);
			}
			else
			{
				SelectQuantity(result, noSound: false);
			}
		}

		private void OnSelectedToggleChanged(bool _)
		{
			if (SelectedToggle.isOn)
			{
				SelectMaxQuantity(noSound: true);
			}
			else
			{
				Deselect(noSound: true);
			}
		}

		private void OnQuantityUpButtonClicked()
		{
			SelectQuantity(_selectedQuantity + 1, noSound: false);
		}

		private void OnQuantityDownButtonClicked()
		{
			SelectQuantity(_selectedQuantity - 1, noSound: false);
		}

		public void SetItem(IListElement item)
		{
			bool num = _item == item;
			_item = item;
			if (_item?.GetItem() == null)
			{
				if ((Object)(object)MagicBG != (Object)null)
				{
					((Behaviour)MagicBG).enabled = false;
				}
				if ((Object)(object)ItemIcon != (Object)null)
				{
					ItemIcon.sprite = null;
				}
				if ((Object)(object)ItemName != (Object)null)
				{
					ItemName.text = "<no item>";
				}
				if ((Object)(object)Tooltip != (Object)null)
				{
					Tooltip.m_topic = string.Empty;
					Tooltip.m_text = string.Empty;
				}
			}
			else
			{
				if (SetMagicItem != null)
				{
					SetMagicItem(this, _item.GetItem(), Tooltip);
				}
				else
				{
					if ((Object)(object)MagicBG != (Object)null)
					{
						((Behaviour)MagicBG).enabled = false;
					}
					if ((Object)(object)ItemIcon != (Object)null)
					{
						ItemIcon.sprite = _item.GetItem().GetIcon();
					}
					if ((Object)(object)ItemName != (Object)null)
					{
						ItemName.text = Localization.instance.Localize(_item.GetItem().m_shared.m_name);
					}
					if ((Object)(object)Tooltip != (Object)null)
					{
						Tooltip.m_topic = Localization.instance.Localize(_item.GetItem().m_shared.m_name);
						Tooltip.m_text = Localization.instance.Localize(_item.GetItem().GetTooltip());
					}
				}
				if ((Object)(object)ItemName != (Object)null)
				{
					Text itemName = ItemName;
					itemName.text += _item.GetDisplayNameSuffix();
				}
			}
			if (!num)
			{
				Deselect(noSound: true);
			}
			RefreshGamepadFocusIndicator();
		}

		public void Deselect(bool noSound)
		{
			SelectQuantity(0, noSound);
		}

		public void SelectQuantity(int quantity, bool noSound)
		{
			int selectedQuantity = _selectedQuantity;
			if (_item == null)
			{
				_selectedQuantity = quantity;
			}
			else if (NoMax)
			{
				_selectedQuantity = Mathf.Clamp(quantity, 0, 999);
			}
			else if (_item.GetItem().m_shared.m_maxStackSize == 1)
			{
				_selectedQuantity = Mathf.Clamp(quantity, 0, 1);
			}
			else
			{
				_selectedQuantity = Mathf.Clamp(quantity, 0, _item.GetItem().m_stack);
			}
			if (!SuppressEvents && selectedQuantity != _selectedQuantity)
			{
				this.OnSelectionChanged?.Invoke(this, IsSelected(), _selectedQuantity);
			}
			if ((Object)(object)Audio != (Object)null && !ReadOnly && !noSound && selectedQuantity != _selectedQuantity)
			{
				Audio.PlayOneShot(OnClickSFX);
			}
			Refresh();
		}

		public void Refresh()
		{
			RefreshGamepadFocusIndicator();
			bool flag = _item != null && _item.GetItem().m_shared.m_maxStackSize > 1;
			if ((Object)(object)MainButton != (Object)null)
			{
				((Selectable)MainButton).interactable = !_locked;
			}
			if ((Object)(object)SelectedToggle != (Object)null)
			{
				((Selectable)SelectedToggle).interactable = !_locked;
				((Component)SelectedToggle).gameObject.SetActive(!ReadOnly);
				SelectedToggle.SetIsOnWithoutNotify(_selectedQuantity > 0);
			}
			if ((Object)(object)ItemSelectedQuantity != (Object)null)
			{
				((Selectable)ItemSelectedQuantity).interactable = !_locked;
				((Component)ItemSelectedQuantity).gameObject.SetActive(!ReadOnly && flag);
				ItemSelectedQuantity.text = _selectedQuantity.ToString();
			}
			if ((Object)(object)ItemTotalQuantity != (Object)null && _item != null)
			{
				((Component)ItemTotalQuantity).gameObject.SetActive(ReadOnly || flag);
				string text = string.Format(ReadOnly ? "{0}" : "/ {0}", _item.GetMax());
				if (CheckPlayerInventory && ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(_item.GetItem().m_shared.m_name, -1, true) < _item.GetItem().m_stack)
				{
					text = "<color=red>" + text + "</color>";
				}
				ItemTotalQuantity.text = text;
			}
			if ((Object)(object)QuantityUpButton != (Object)null)
			{
				((Selectable)QuantityUpButton).interactable = !_locked;
				((Component)QuantityUpButton).gameObject.SetActive(!ReadOnly && flag);
			}
			if ((Object)(object)QuantityDownButton != (Object)null)
			{
				((Selectable)QuantityDownButton).interactable = !_locked;
				((Component)QuantityDownButton).gameObject.SetActive(!ReadOnly && flag);
			}
			if ((Object)(object)SelectedBackground != (Object)null)
			{
				SelectedBackground.SetActive(!ReadOnly && _selectedQuantity > 0);
			}
			Localization.instance.Localize(((Component)this).transform);
		}

		public ItemData GetItem()
		{
			return _item.GetItem();
		}

		public IListElement GetListElement()
		{
			return _item;
		}

		public int GetSelectedQuantity()
		{
			return _selectedQuantity;
		}

		public void Lock()
		{
			_locked = true;
			Refresh();
		}

		public void Unlock()
		{
			_locked = false;
			Refresh();
		}

		public void GiveFocus(bool focused)
		{
			_hasGamepadFocus = focused;
			RefreshGamepadFocusIndicator();
		}

		private void RefreshGamepadFocusIndicator()
		{
			if (!((Object)(object)GamepadFocusIndicator == (Object)null))
			{
				GamepadFocusIndicator.SetActive(ZInput.IsGamepadActive() && _hasGamepadFocus);
			}
		}

		public bool HasGamepadFocus()
		{
			return _hasGamepadFocus;
		}
	}
	public class MultiSelectListFocusController : MonoBehaviour
	{
		public List<MultiSelectItemList> Lists = new List<MultiSelectItemList>();

		public GameObject[] SortHints;

		public GameObject[] SelectAllHints;

		public GameObject[] SelectHints;

		private int _focusedListIndex;

		private bool _gamepadWasEnabled;

		public void OnEnable()
		{
			_focusedListIndex = 0;
			for (int i = 0; i < Lists.Count; i++)
			{
				Lists[i].GiveFocus(i == _focusedListIndex, 0);
			}
			RefreshHints();
		}

		public void Update()
		{
			if (Lists.Count == 0)
			{
				return;
			}
			MultiSelectItemList multiSelectItemList = Lists[_focusedListIndex];
			int num = 0;
			int itemCount = multiSelectItemList.GetItemCount();
			while (itemCount == 0)
			{
				multiSelectItemList.GiveFocus(focused: false, 0);
				_focusedListIndex = (_focusedListIndex + 1) % Lists.Count;
				multiSelectItemList = Lists[_focusedListIndex];
				itemCount = multiSelectItemList.GetItemCount();
				if (multiSelectItemList.GetItemCount() > 0)
				{
					multiSelectItemList.GiveFocus(focused: true, 0);
					RefreshHints();
					break;
				}
				num++;
				if (num >= Lists.Count)
				{
					return;
				}
			}
			if (ZInput.IsGamepadActive())
			{
				int num2 = _focusedListIndex;
				if (ZInput.GetButtonDown("JoyTabLeft"))
				{
					num2 = Mathf.Max(_focusedListIndex - 1, 0);
					ZInput.ResetButtonStatus("JoyTabLeft");
				}
				else if (ZInput.GetButtonDown("JoyTabRight"))
				{
					num2 = Mathf.Min(_focusedListIndex + 1, Lists.Count - 1);
					ZInput.ResetButtonStatus("JoyTabRight");
				}
				if (num2 != _focusedListIndex)
				{
					int num3 = num2 - _focusedListIndex;
					if (Lists[num2].GetItemCount() == 0)
					{
						num2 = (num2 + num3 + Lists.Count) % Lists.Count;
					}
					if (Lists[num2].GetItemCount() == 0)
					{
						num2 = _focusedListIndex;
					}
				}
				FocusList(num2);
			}
			if (_gamepadWasEnabled != ZInput.IsGamepadActive())
			{
				RefreshHints();
			}
			_gamepadWasEnabled = ZInput.IsGamepadActive();
		}

		public void FocusList(int newFocusedIndex)
		{
			MultiSelectItemListElement focusedElement = Lists[_focusedListIndex].GetFocusedElement();
			int num = (((Object)(object)focusedElement != (Object)null) ? ((Component)focusedElement).transform.GetSiblingIndex() : (-1));
			if (newFocusedIndex != _focusedListIndex && newFocusedIndex >= 0 && newFocusedIndex < Lists.Count)
			{
				_focusedListIndex = newFocusedIndex;
				for (int i = 0; i < Lists.Count; i++)
				{
					bool flag = Lists[i].IsGrid();
					Lists[i].GiveFocus(i == _focusedListIndex, (!flag) ? num : 0);
				}
				RefreshHints();
			}
		}

		private void RefreshHints()
		{
			if (((Behaviour)this).isActiveAndEnabled && ZInput.IsGamepadActive() && Lists.Count != 0)
			{
				MultiSelectItemList multiSelectItemList = Lists[_focusedListIndex];
				GameObject[] sortHints = SortHints;
				for (int i = 0; i < sortHints.Length; i++)
				{
					sortHints[i].SetActive(multiSelectItemList.Sortable && (Object)(object)multiSelectItemList.SortByDropdown != (Object)null && ((Behaviour)multiSelectItemList.SortByDropdown).isActiveAndEnabled);
				}
				sortHints = SelectAllHints;
				for (int i = 0; i < sortHints.Length; i++)
				{
					sortHints[i].SetActive(multiSelectItemList.Multiselect && (Object)(object)multiSelectItemList.SelectAllToggle != (Object)null && ((Behaviour)multiSelectItemList.SelectAllToggle).isActiveAndEnabled);
				}
				sortHints = SelectHints;
				for (int i = 0; i < sortHints.Length; i++)
				{
					sortHints[i].SetActive(!multiSelectItemList.ReadOnly && (Object)(object)multiSelectItemList.GetFocusedElement() != (Object)null);
				}
			}
		}
	}
	[RequireComponent(typeof(Toggle))]
	public class PlaySoundOnChecked : MonoBehaviour
	{
		public AudioSource Audio;

		public AudioClip SFX;

		private Toggle _toggle;

		public void Awake()
		{
			_toggle = ((Component)this).GetComponent<Toggle>();
			((UnityEvent<bool>)(object)_toggle.onValueChanged).AddListener((UnityAction<bool>)OnToggleChanged);
		}

		public void OnDestroy()
		{
			((UnityEvent<bool>)(object)_toggle.onValueChanged).RemoveListener((UnityAction<bool>)OnToggleChanged);
		}

		private void OnToggleChanged(bool _)
		{
			if ((Object)(object)Audio != (Object)null && (Object)(object)SFX != (Object)null && _toggle.isOn)
			{
				Audio.PlayOneShot(SFX);
			}
		}
	}
	public enum MaterialConversionMode
	{
		Upgrade,
		Convert,
		Junk
	}
	public class ConversionRecipeCostUnity
	{
		public ItemData Item;

		public int Amount;
	}
	public class ConversionRecipeUnity : IListElement
	{
		public ItemData Product;

		public int Amount;

		public List<ConversionRecipeCostUnity> Cost;

		public ItemData GetItem()
		{
			return Product;
		}

		public string GetDisplayNameSuffix()
		{
			if (Amount <= 1)
			{
				return string.Empty;
			}
			return $" x{Amount}";
		}

		public int GetMax()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return 0;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			int num = int.MaxValue;
			foreach (ConversionRecipeCostUnity item in Cost)
			{
				int num2 = Mathf.FloorToInt((float)inventory.CountItems(item.Item.m_shared.m_name, -1, true) / (float)item.Amount);
				num = Mathf.Min(num, num2);
			}
			return num;
		}
	}
	public class ConvertUI : EnchantingTableUIPanelBase
	{
		public delegate List<ConversionRecipeUnity> GetConversionRecipesDelegate(int mode);

		public MultiSelectItemList Products;

		public List<Toggle> ModeButtons;

		[Header("Cost")]
		public Text CostLabel;

		public MultiSelectItemList CostList;

		public static GetConversionRecipesDelegate GetConversionRecipes;

		private Text _progressLabel;

		private ToggleGroup _toggleGroup;

		private MaterialConversionMode _mode;

		public override void Awake()
		{
			base.Awake();
			_progressLabel = ((Component)ProgressBar).gameObject.GetComponentInChildren<Text>();
			if (ModeButtons.Count > 0)
			{
				_toggleGroup = ModeButtons[0].group;
				_toggleGroup.EnsureValidState();
			}
			for (int i = 0; i < ModeButtons.Count; i++)
			{
				((UnityEvent<bool>)(object)ModeButtons[i].onValueChanged).AddListener((UnityAction<bool>)delegate(bool isOn)
				{
					if (isOn)
					{
						RefreshMode();
					}
				});
			}
		}

		[UsedImplicitly]
		public void OnEnable()
		{
			_mode = MaterialConversionMode.Upgrade;
			RefreshMode();
			List<ConversionRecipeUnity> source = GetConversionRecipes((int)_mode);
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
		}

		public override void Update()
		{
			base.Update();
			if (!_locked && ZInput.IsGamepadActive() && ZInput.GetButtonDown("JoyButtonY"))
			{
				int index = (int)(_mode + 1) % ModeButtons.Count;
				ModeButtons[index].isOn = true;
				ZInput.ResetButtonStatus("JoyButtonY");
			}
		}

		public void RefreshMode()
		{
			MaterialConversionMode mode = _mode;
			for (int i = 0; i < ModeButtons.Count; i++)
			{
				if (ModeButtons[i].isOn)
				{
					_mode = (MaterialConversionMode)i;
				}
			}
			if (mode != _mode)
			{
				OnModeChanged();
			}
		}

		public void OnModeChanged()
		{
			DeselectAll();
			RefreshAvailableItems();
			switch (_mode)
			{
			case MaterialConversionMode.Upgrade:
				CostLabel.text = Localization.instance.Localize("$mod_epicloot_upgradecost");
				_progressLabel.text = Localization.instance.Localize("$mod_epicloot_upgradeprogress");
				if (_useTMP)
				{
					_tmpButtonLabel.text = Localization.instance.Localize("$mod_epicloot_upgrade");
				}
				else
				{
					_buttonLabel.text = Localization.instance.Localize("$mod_epicloot_upgrade");
				}
				break;
			case MaterialConversionMode.Convert:
				CostLabel.text = Localization.instance.Localize("$mod_epicloot_convertcost");
				_progressLabel.text = Localization.instance.Localize("$mod_epicloot_convertprogress");
				if (_useTMP)
				{
					_tmpButtonLabel.text = Localization.instance.Localize("$mod_epicloot_convert");
				}
				else
				{
					_buttonLabel.text = Localization.instance.Localize("$mod_epicloot_convert");
				}
				break;
			case MaterialConversionMode.Junk:
				CostLabel.text = Localization.instance.Localize("$mod_epicloot_junkcost");
				_progressLabel.text = Localization.instance.Localize("$mod_epicloot_junkprogress");
				if (_useTMP)
				{
					_tmpButtonLabel.text = Localization.instance.Localize("$mod_epicloot_junk");
				}
				else
				{
					_buttonLabel.text = Localization.instance.Localize("$mod_epicloot_junk");
				}
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		protected override void DoMainAction()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			List<Tuple<ConversionRecipeUnity, int>> selectedItems = AvailableItems.GetSelectedItems<ConversionRecipeUnity>();
			List<InventoryItemListElement> conversionProducts = GetConversionProducts(selectedItems);
			List<InventoryItemListElement> conversionCost = GetConversionCost(selectedItems);
			Cancel();
			Player localPlayer = Player.m_localPlayer;
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			foreach (InventoryItemListElement item3 in conversionCost)
			{
				ItemData item = item3.GetItem();
				inventory.RemoveItem(item.m_shared.m_name, item.m_stack, -1, true);
			}
			foreach (InventoryItemListElement item4 in conversionProducts)
			{
				ItemData item2 = item4.GetItem();
				if (inventory.CanAddItem(item2, -1))
				{
					inventory.AddItem(item2);
					((Character)localPlayer).Message((MessageType)1, "$msg_added " + item2.m_shared.m_name, item2.m_stack, item2.GetIcon());
				}
				else
				{
					ItemDrop val = ItemDrop.DropItem(item2, item2.m_stack, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + ((Component)localPlayer).transform.up, ((Component)localPlayer).transform.rotation);
					((Component)val).GetComponent<Rigidbody>().velocity = Vector3.up * 5f;
					((Character)localPlayer).Message((MessageType)1, "$msg_dropped " + val.m_itemData.m_shared.m_name + " $mod_epicloot_sacrifice_inventoryfullexplanation", val.m_itemData.m_stack, val.m_itemData.GetIcon());
				}
			}
			DeselectAll();
			RefreshAvailableItems();
		}

		public static List<InventoryItemListElement> GetConversionProducts(List<Tuple<ConversionRecipeUnity, int>> selectedRecipes)
		{
			Dictionary<string, ItemData> dictionary = new Dictionary<string, ItemData>();
			foreach (Tuple<ConversionRecipeUnity, int> selectedRecipe in selectedRecipes)
			{
				ConversionRecipeUnity item = selectedRecipe.Item1;
				int item2 = selectedRecipe.Item2;
				if (dictionary.TryGetValue(item.Product.m_shared.m_name, out var value))
				{
					ItemData obj = value;
					obj.m_stack += item.Amount * item2;
				}
				else
				{
					value = item.Product.Clone();
					value.m_stack = item.Amount * item2;
					dictionary.Add(value.m_shared.m_name, value);
				}
			}
			return (from x in dictionary.Values
				orderby Localization.instance.Localize(x.m_shared.m_name)
				select new InventoryItemListElement
				{
					Item = x
				}).ToList();
		}

		public static List<InventoryItemListElement> GetConversionCost(List<Tuple<ConversionRecipeUnity, int>> selectedRecipes)
		{
			Dictionary<string, ItemData> dictionary = new Dictionary<string, ItemData>();
			foreach (Tuple<ConversionRecipeUnity, int> selectedRecipe in selectedRecipes)
			{
				ConversionRecipeUnity item = selectedRecipe.Item1;
				int item2 = selectedRecipe.Item2;
				foreach (ConversionRecipeCostUnity item3 in item.Cost)
				{
					if (dictionary.TryGetValue(item3.Item.m_shared.m_name, out var value))
					{
						ItemData obj = value;
						obj.m_stack += item3.Amount * item2;
					}
					else
					{
						value = item3.Item.Clone();
						value.m_stack = item3.Amount * item2;
						dictionary.Add(value.m_shared.m_name, value);
					}
				}
			}
			return (from x in dictionary.Values
				orderby Localization.instance.Localize(x.m_shared.m_name)
				select new InventoryItemListElement
				{
					Item = x
				}).ToList();
		}

		public void RefreshAvailableItems()
		{
			List<ConversionRecipeUnity> source = GetConversionRecipes((int)_mode);
			AvailableItems.SetItems(source.Cast<IListElement>().ToList());
			AvailableItems.DeselectAll();
			OnSelectedItemsChanged();
		}

		protected override void OnSelectedItemsChanged()
		{
			List<Tuple<ConversionRecipeUnity, int>> selectedItems = AvailableItems.GetSelectedItems<ConversionRecipeUnity>();
			List<InventoryItemListElement> conversionProducts = GetConversionProducts(selectedItems);
			Products.SetItems(conversionProducts.Cast<IListElement>().ToList());
			List<InventoryItemListElement> conversionCost = GetConversionCost(selectedItems);
			CostList.SetItems(conversionCost.Cast<IListElement>().ToList());
			Tuple<float, float> featureValue = EnchantingTableUI.instance.SourceTable.GetFeatureValue(EnchantingFeature.ConvertMaterials, 0);
			Tuple<float, float> featureCurrentValue = EnchantingTableUI.instance.SourceTable.GetFeatureCurrentValue(EnchantingFeature.ConvertMaterials);
			bool flag = false;
			if (_mode == MaterialConversionMode.Upgrade)
			{
				if (featureCurrentValue.Item1 < featureValue.Item1 && conversionProducts.Any((InventoryItemListElement x) => x.Item.m_shared.m_ammoType.EndsWith("MagicCraftingMaterial")))
				{
					flag = true;
				}
				if (featureCurrentValue.Item2 < featureValue.Item2 && conversionProducts.Any((InventoryItemListElement x) => x.Item.m_shared.m_ammoType.EndsWith("Runestone")))
				{
					flag = true;
				}
				if (flag && conversionCost.Count > 0)
				{
					CostLabel.text = Localization.instance.Localize("<color=#EAA800>($mod_epicloot_bonus)</color> $mod_epicloot_upgradecost");
				}
				else
				{
					CostLabel.text = Localization.instance.Localize("$mod_epicloot_upgradecost");
				}
			}
			bool flag2 = EnchantingTableUIPanelBase.LocalPlayerCanAffordCost(conversionCost);
			bool flag3 = EnchantingTableUI.instance.SourceTable.IsFeatureUnlocked(EnchantingFeat

EpicLoot/EpicLoot.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using AdventureBackpacks.API;
using Auga;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EpicLoot.BaseEL;
using EpicLoot.BaseEL.Abilities;
using EpicLoot.BaseEL.Adventure;
using EpicLoot.BaseEL.Adventure.Feature;
using EpicLoot.BaseEL.Common;
using EpicLoot.BaseEL.Crafting;
using EpicLoot.BaseEL.CraftingV2;
using EpicLoot.BaseEL.Data;
using EpicLoot.BaseEL.GatedItemType;
using EpicLoot.BaseEL.Healing;
using EpicLoot.BaseEL.LegendarySystem;
using EpicLoot.BaseEL.LootBeams;
using EpicLoot.BaseEL.MagicItemEffects;
using EpicLoot.BaseEL.Patching;
using EpicLoot.Skill;
using EpicLoot_UnityLib;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("EpicLoot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EpicLoot")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EpicLoot
{
	[BepInPlugin("com.lootgoblinsheim.epicloot", "LGH.EpicLoot", "0.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class EpicLoot : BaseUnityPlugin
	{
		public const string PluginGUID = "com.lootgoblinsheim.epicloot";

		public const string PluginName = "LGH.EpicLoot";

		public const string PluginVersion = "0.0.1";

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

		private EpicLootBase _epicLootBase;

		private void Awake()
		{
			Logger.LogInfo((object)"EpicLoot has landed");
			_epicLootBase = new EpicLootBase();
			_epicLootBase.Awake(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			Enchanting.AddEnchantingSkill();
		}

		private void Start()
		{
			_epicLootBase.Start();
		}

		private void Update()
		{
			_epicLootBase.Update();
		}

		private void OnDestroy()
		{
			_epicLootBase.OnDestroy();
		}
	}
}
namespace EpicLoot.Skill
{
	public static class Enchanting
	{
		public enum OperationType
		{
			Enchant,
			Disenchant,
			Augment,
			Convert,
			Sacrifice
		}

		public static EnchantingSkillConfig Config;

		public static SkillType SkillType;

		public static void AddEnchantingSkill()
		{
			//IL_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			//IL_0072: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = PrefabManager.Instance.GetPrefab("RunestoneMythic");
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogError((object)"RunestoneMythic prefab not exists");
			}
			SkillConfig val = new SkillConfig
			{
				Name = "$mod_epicloot_skill_name",
				Description = "$mod_epicloot_skill_description",
				Identifier = "mod_epicloot_skill_enchanting",
				Icon = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0],
				IncreaseStep = 1f
			};
			SkillType = SkillManager.Instance.AddSkill(val);
			Logger.LogInfo((object)$"Added skill {SkillType}");
		}

		public static void InitSkillConfig(EnchantingSkillConfig config)
		{
			Config = config;
		}

		public static float GetEnchantingSkillLevel()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return ((Character)Player.m_localPlayer).GetSkillLevel(SkillType);
		}

		public static void SuccessfulOperation(int targetRarity, OperationType operationType)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f;
			switch (operationType)
			{
			case OperationType.Enchant:
				num = Config.SuccessEnchantSkillMultiplier;
				break;
			case OperationType.Disenchant:
				num = Config.SuccessDisenchantSkillMultiplier;
				break;
			case OperationType.Augment:
				num = Config.SuccessAugmentationSkillMultiplier;
				break;
			case OperationType.Convert:
				num = Config.SuccessConvertSkillMultiplier;
				break;
			case OperationType.Sacrifice:
				num = Config.SuccessSacrificeSkillMultiplier;
				break;
			}
			float num2 = num * ((float)targetRarity + 1f);
			Logger.LogInfo((object)$"Raising Enchanting: {num2}; multiplier: {num}; targetRarity: {targetRarity}");
			((Character)Player.m_localPlayer).RaiseSkill(SkillType, num2);
		}

		public static MagicItemEffectDefinition.ValueDef GetSkillCappedValueDef(MagicItemEffectDefinition.ValueDef original, ItemRarity rarity)
		{
			if (original == null || Mathf.Approximately(original.MinValue, original.MaxValue))
			{
				return original;
			}
			float enchantingSkillLevel = GetEnchantingSkillLevel();
			int num = Config.EnchantLevels[(int)rarity];
			int num2 = 100 - num;
			float num3 = (original.MaxValue - original.MinValue) / 2f;
			float num4 = (enchantingSkillLevel - (float)num) / (float)num2;
			float num5 = num3 * num4;
			return new MagicItemEffectDefinition.ValueDef
			{
				MinValue = original.MinValue + num5,
				MaxValue = original.MinValue + num3 + num5,
				Increment = original.Increment
			};
		}

		public static bool AugmentAvailableForPlayerSkill(MagicItem magicItem)
		{
			float enchantingSkillLevel = GetEnchantingSkillLevel();
			ItemRarity rarity = magicItem.Rarity;
			return enchantingSkillLevel >= (float)Config.EnchantLevels[(int)rarity];
		}
	}
	[Serializable]
	public class EnchantingSkillConfig
	{
		public List<int> EnchantLevels = new List<int>();

		public float SuccessEnchantSkillMultiplier = 1f;

		public float SuccessDisenchantSkillMultiplier = 1f;

		public float SuccessAugmentationSkillMultiplier = 1f;

		public float SuccessConvertSkillMultiplier = 1f;

		public float SuccessSacrificeSkillMultiplier = 1f;
	}
}
namespace EpicLoot.BaseEL
{
	public class Assets
	{
		public AssetBundle AssetBundle;

		public Sprite EquippedSprite;

		public Sprite AugaEquippedSprite;

		public Sprite GenericSetItemSprite;

		public Sprite AugaSetItemSprite;

		public Sprite GenericItemBgSprite;

		public Sprite AugaItemBgSprite;

		public GameObject[] MagicItemLootBeamPrefabs = (GameObject[])(object)new GameObject[5];

		public readonly Dictionary<string, GameObject[]> CraftingMaterialPrefabs = new Dictionary<string, GameObject[]>();

		public Sprite SmallButtonEnchantOverlay;

		public AudioClip[] MagicItemDropSFX = (AudioClip[])(object)new AudioClip[5];

		public AudioClip ItemLoopSFX;

		public AudioClip AugmentItemSFX;

		public GameObject MerchantPanel;

		public Sprite MapIconTreasureMap;

		public Sprite MapIconBounty;

		public AudioClip AbandonBountySFX;

		public AudioClip DoubleJumpSFX;

		public GameObject DebugTextPrefab;

		public GameObject AbilityBar;

		public GameObject WelcomMessagePrefab;
	}
	[HarmonyPatch]
	public static class Attack_Patch
	{
		public static Attack ActiveAttack;

		[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		public static void Attack_DoMeleeAttack_Prefix(Attack __instance)
		{
			ActiveAttack = __instance;
		}

		[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
		[HarmonyPostfix]
		public static void Attack_DoMeleeAttack_Postfix()
		{
			ActiveAttack = null;
		}
	}
	public enum BossDropMode
	{
		Default,
		OnePerPlayerOnServer,
		OnePerPlayerNearBoss
	}
	public static class EpicLootDropsHelper
	{
		public static bool InstantDropsEnabled { get; set; }
	}
	[HarmonyPatch(typeof(CharacterDrop), "OnDeath")]
	public static class CharacterDrop_OnDeath_Patch
	{
		public static void Postfix(CharacterDrop __instance)
		{
			if (EpicLootDropsHelper.InstantDropsEnabled)
			{
				EpicLootBase.OnCharacterDeath(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Ragdoll), "Setup")]
	public static class Ragdoll_Setup_Patch
	{
		public static void Postfix(Ragdoll __instance, CharacterDrop characterDrop)
		{
			if (!((Object)(object)characterDrop == (Object)null) && !((Object)(object)characterDrop.m_character == (Object)null) && !characterDrop.m_character.IsPlayer() && EpicLootBase.CanCharacterDropLoot(characterDrop.m_character))
			{
				EpicLootDropsHelper.InstantDropsEnabled = false;
				string characterCleanName = EpicLootBase.GetCharacterCleanName(characterDrop.m_character);
				int level = characterDrop.m_character.GetLevel();
				__instance.m_nview.m_zdo.Set("characterName", characterCleanName);
				__instance.m_nview.m_zdo.Set("level", level);
			}
		}
	}
	[HarmonyPatch(typeof(Ragdoll), "SpawnLoot")]
	public static class Ragdoll_SpawnLoot_Patch
	{
		public static void Postfix(Ragdoll __instance, Vector3 center)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			string @string = __instance.m_nview.m_zdo.GetString("characterName", "");
			int @int = __instance.m_nview.m_zdo.GetInt("level", 0);
			if (!string.IsNullOrEmpty(@string))
			{
				EpicLootBase.OnCharacterDeath(@string, @int, center + Vector3.up * 0.75f);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	public static class CharacterDrop_GenerateDropList_DropsEnabled
	{
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "org.bepinex.plugins.creaturelevelcontrol" })]
		public static void Postfix(CharacterDrop __instance)
		{
			EpicLootDropsHelper.InstantDropsEnabled = __instance.m_dropsEnabled;
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	public static class CharacterDrop_GenerateDropList_Patch
	{
		public static void Prefix(CharacterDrop __instance)
		{
			if (!((Object)(object)__instance.m_character != (Object)null) || !__instance.m_character.IsBoss() || EpicLootBase.GetBossTrophyDropMode() == BossDropMode.Default)
			{
				return;
			}
			foreach (Drop drop in __instance.m_drops)
			{
				if (!((Object)(object)drop.m_prefab == (Object)null) && ((((Object)drop.m_prefab).name.Equals("Wishbone") && EpicLootBase.GetBossWishboneDropMode() != 0) || (((Object)drop.m_prefab).name.Equals("CryptKey") && EpicLootBase.GetBossCryptKeyDropMode() != 0)) && drop.m_onePerPlayer)
				{
					drop.m_onePerPlayer = false;
				}
			}
		}

		public static void Postfix(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Invalid comparison between Unknown and I4
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance.m_character != (Object)null) || !__instance.m_character.IsBoss() || EpicLootBase.GetBossTrophyDropMode() == BossDropMode.Default)
			{
				return;
			}
			for (int i = 0; i < __result.Count; i++)
			{
				GameObject key = __result[i].Key;
				ItemDrop component = key.GetComponent<ItemDrop>();
				if (!((Object)(object)component == (Object)null) && component.m_itemData != null && ((int)component.m_itemData.m_shared.m_itemType == 13 || ((Object)key).name.Equals("Wishbone") || ((Object)key).name.Equals("CryptKey")))
				{
					List<PlayerInfo> playerList = ZNet.instance.GetPlayerList();
					int num = EpicLootBase.GetBossTrophyDropMode() switch
					{
						BossDropMode.OnePerPlayerOnServer => playerList.Count, 
						BossDropMode.OnePerPlayerNearBoss => Math.Max(Player.GetPlayersInRangeXZ(((Component)__instance.m_character).transform.position, EpicLootBase.GetBossTrophyDropPlayerRange()), playerList.Count((PlayerInfo x) => Vector3.Distance(x.m_position, ((Component)__instance.m_character).transform.position) <= EpicLootBase.GetBossTrophyDropPlayerRange())), 
						_ => 1, 
					};
					EpicLootBase.Log($"Dropping trophies: {num} (mode={EpicLootBase.GetBossTrophyDropMode()})");
					__result[i] = new KeyValuePair<GameObject, int>(key, num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Container), "AddDefaultItems")]
	public static class Container_AddDefaultItems_Patch
	{
		public static void Postfix(Container __instance)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_piece == (Object)null)
			{
				return;
			}
			string text = ((Object)__instance.m_piece).name.Replace("(Clone)", "").Trim();
			List<LootTable> lootTable = LootRoller.GetLootTable(text);
			if (lootTable == null || lootTable.Count <= 0)
			{
				return;
			}
			List<ItemData> list = LootRoller.RollLootTable(lootTable, 1, ((Object)__instance.m_piece).name, ((Component)__instance).transform.position);
			object arg = list.Count;
			Vector3 position = ((Component)__instance).transform.position;
			EpicLootBase.Log(string.Format("Rolling on loot table: {0}, spawned {1} items at drop point({2}).", text, arg, ((Vector3)(ref position)).ToString("0")));
			foreach (ItemData item in list)
			{
				__instance.m_inventory.AddItem(item);
				EpicLootBase.Log("  - " + item.m_shared.m_name + (item.IsMagic() ? (": " + string.Join(", ", item.GetMagicItem().Effects.Select((MagicItemEffect x) => x.EffectType.ToString()))) : ""));
			}
		}
	}
	[HarmonyPatch(typeof(Hud), "Awake")]
	public static class Hud_Awake_Patch
	{
		public static void Postfix(Hud __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			((GameObject)Object.Instantiate((Object)(object)EpicLootBase.Assets.DebugTextPrefab, __instance.m_rootObject.transform, false)).AddComponent<DebugText>();
		}
	}
	public class DebugText : MonoBehaviour
	{
		public Text Label;

		private static DebugText _instance;

		public void Awake()
		{
			_instance = this;
			Label = ((Component)this).GetComponentInChildren<Text>();
			((Component)this).gameObject.SetActive(false);
		}

		public void OnDestroy()
		{
			_instance = null;
		}

		public static void SetText(string s)
		{
			_instance.Label.text = s;
		}
	}
	public class EpicLootBase
	{
		public const string PluginId = "randyknapp.mods.epicloot";

		public const string DisplayName = "Epic Loot";

		public const string Version = "0.9.37";

		private readonly ConfigSync _configSync = new ConfigSync("randyknapp.mods.epicloot")
		{
			DisplayName = "Epic Loot",
			CurrentVersion = "0.9.37",
			MinimumRequiredVersion = "0.9.35"
		};

		private static ConfigEntry<string> _setItemColor;

		private static ConfigEntry<string> _magicRarityColor;

		private static ConfigEntry<string> _rareRarityColor;

		private static ConfigEntry<string> _epicRarityColor;

		private static ConfigEntry<string> _legendaryRarityColor;

		private static ConfigEntry<int> _magicMaterialIconColor;

		private static ConfigEntry<int> _rareMaterialIconColor;

		private static ConfigEntry<int> _epicMaterialIconColor;

		private static ConfigEntry<int> _legendaryMaterialIconColor;

		public static ConfigEntry<bool> UseScrollingCraftDescription;

		public static ConfigEntry<bool> TransferMagicItemToCrafts;

		public static ConfigEntry<CraftingTabStyle> CraftingTabStyle;

		private static ConfigEntry<bool> _loggingEnabled;

		private static ConfigEntry<LogLevel> _logLevel;

		public static ConfigEntry<bool> UseGeneratedMagicItemNames;

		private static ConfigEntry<GatedItemTypeMode> _gatedItemTypeModeConfig;

		public static ConfigEntry<GatedBountyMode> BossBountyMode;

		private static ConfigEntry<BossDropMode> _bossTrophyDropMode;

		private static ConfigEntry<float> _bossTrophyDropPlayerRange;

		private static ConfigEntry<int> _andvaranautRange;

		public static ConfigEntry<bool> ShowEquippedAndHotbarItemsInSacrificeTab;

		private static ConfigEntry<bool> _adventureModeEnabled;

		private static ConfigEntry<bool> _serverConfigLocked;

		public static readonly ConfigEntry<string>[] AbilityKeyCodes = new ConfigEntry<string>[3];

		public static ConfigEntry<TextAnchor> AbilityBarAnchor;

		public static ConfigEntry<Vector2> AbilityBarPosition;

		public static ConfigEntry<TextAnchor> AbilityBarLayoutAlignment;

		public static ConfigEntry<float> AbilityBarIconSpacing;

		public static ConfigEntry<float> SetItemDropChance;

		public static ConfigEntry<float> GlobalDropRateModifier;

		public static ConfigEntry<float> ItemsToMaterialsDropRatio;

		public static ConfigEntry<bool> AlwaysShowWelcomeMessage;

		public static ConfigEntry<bool> OutputPatchedConfigFiles;

		public static ConfigEntry<bool> EnchantingTableUpgradesActive;

		public static ConfigEntry<bool> EnableLimitedBountiesInProgress;

		public static ConfigEntry<int> MaxInProgressBounties;

		public static ConfigEntry<EnchantingTabs> EnchantingTableActivatedTabs;

		public static Dictionary<string, CustomSyncedValue<string>> SyncedJsonFiles = new Dictionary<string, CustomSyncedValue<string>>();

		public static Dictionary<string, ConfigValue<string>> NonSyncedJsonFiles = new Dictionary<string, ConfigValue<string>>();

		public static readonly List<ItemType> AllowedMagicItemTypes = new List<ItemType>
		{
			(ItemType)6,
			(ItemType)7,
			(ItemType)11,
			(ItemType)17,
			(ItemType)18,
			(ItemType)4,
			(ItemType)3,
			(ItemType)14,
			(ItemType)22,
			(ItemType)5,
			(ItemType)19,
			(ItemType)15
		};

		public static readonly Dictionary<string, string> MagicItemColors = new Dictionary<string, string>
		{
			{ "Red", "#ff4545" },
			{ "Orange", "#ffac59" },
			{ "Yellow", "#ffff75" },
			{ "Green", "#80fa70" },
			{ "Teal", "#18e7a9" },
			{ "Blue", "#00abff" },
			{ "Indigo", "#709bba" },
			{ "Purple", "#d078ff" },
			{ "Pink", "#ff63d6" },
			{ "Gray", "#dbcadb" }
		};

		public static readonly Assets Assets = new Assets();

		public static readonly List<GameObject> RegisteredPrefabs = new List<GameObject>();

		public static readonly List<GameObject> RegisteredItemPrefabs = new List<GameObject>();

		public static readonly Dictionary<GameObject, PieceDef> RegisteredPieces = new Dictionary<GameObject, PieceDef>();

		private static readonly Dictionary<string, Action<ItemDrop>> _customItemSetupActions = new Dictionary<string, Action<ItemDrop>>();

		private static readonly Dictionary<string, Object> _assetCache = new Dictionary<string, Object>();

		public static bool AlwaysDropCheat = false;

		public const PinType BountyPinType = 800;

		public const PinType TreasureMapPinType = 801;

		public static bool HasAuga;

		public static bool HasAdventureBackpacks;

		public static bool AugaTooltipNoTextBoxes;

		private static EpicLootBase _instance;

		private Harmony _harmony;

		private float _worldLuckFactor;

		private static ConfigEntry<BossDropMode> _bossCryptKeyDropMode;

		private static ConfigEntry<float> _bossCryptKeyDropPlayerRange;

		private static ConfigEntry<BossDropMode> _bossWishboneDropMode;

		private static ConfigEntry<float> _bossWishboneDropPlayerRange;

		private ConfigFile Config;

		private ManualLogSource Logger;

		private float _lastUpdate;

		public static event Action AbilitiesInitialized;

		public static event Action LootTableLoaded;

		public void Awake(ConfigFile config, ManualLogSource logSource)
		{
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Expected O, but got Unknown
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			Config = config;
			Logger = logSource;
			_instance = this;
			_magicRarityColor = Config.Bind<string>("Item Colors", "Magic Rarity Color", "Blue", "The color of Magic rarity items, the lowest magic item tier. (Optional, use an HTML hex color starting with # to have a custom color.) Available options: Red, Orange, Yellow, Green, Teal, Blue, Indigo, Purple, Pink, Gray");
			_magicMaterialIconColor = Config.Bind<int>("Item Colors", "Magic Crafting Material Icon Index", 5, "Indicates the color of the icon used for magic crafting materials. A number between 0 and 9. Available options: 0=Red, 1=Orange, 2=Yellow, 3=Green, 4=Teal, 5=Blue, 6=Indigo, 7=Purple, 8=Pink, 9=Gray");
			_rareRarityColor = Config.Bind<string>("Item Colors", "Rare Rarity Color", "Yellow", "The color of Rare rarity items, the second magic item tier. (Optional, use an HTML hex color starting with # to have a custom color.) Available options: Red, Orange, Yellow, Green, Teal, Blue, Indigo, Purple, Pink, Gray");
			_rareMaterialIconColor = Config.Bind<int>("Item Colors", "Rare Crafting Material Icon Index", 2, "Indicates the color of the icon used for rare crafting materials. A number between 0 and 9. Available options: 0=Red, 1=Orange, 2=Yellow, 3=Green, 4=Teal, 5=Blue, 6=Indigo, 7=Purple, 8=Pink, 9=Gray");
			_epicRarityColor = Config.Bind<string>("Item Colors", "Epic Rarity Color", "Purple", "The color of Epic rarity items, the third magic item tier. (Optional, use an HTML hex color starting with # to have a custom color.) Available options: Red, Orange, Yellow, Green, Teal, Blue, Indigo, Purple, Pink, Gray");
			_epicMaterialIconColor = Config.Bind<int>("Item Colors", "Epic Crafting Material Icon Index", 7, "Indicates the color of the icon used for epic crafting materials. A number between 0 and 9. Available options: 0=Red, 1=Orange, 2=Yellow, 3=Green, 4=Teal, 5=Blue, 6=Indigo, 7=Purple, 8=Pink, 9=Gray");
			_legendaryRarityColor = Config.Bind<string>("Item Colors", "Legendary Rarity Color", "Teal", "The color of Legendary rarity items, the highest magic item tier. (Optional, use an HTML hex color starting with # to have a custom color.) Available options: Red, Orange, Yellow, Green, Teal, Blue, Indigo, Purple, Pink, Gray");
			_legendaryMaterialIconColor = Config.Bind<int>("Item Colors", "Legendary Crafting Material Icon Index", 4, "Indicates the color of the icon used for legendary crafting materials. A number between 0 and 9. Available options: 0=Red, 1=Orange, 2=Yellow, 3=Green, 4=Teal, 5=Blue, 6=Indigo, 7=Purple, 8=Pink, 9=Gray");
			_setItemColor = Config.Bind<string>("Item Colors", "Set Item Color", "#26ffff", "The color of set item text and the set item icon. Use a hex color, default is cyan");
			UseScrollingCraftDescription = Config.Bind<bool>("Crafting UI", "Use Scrolling Craft Description", true, "Changes the item description in the crafting panel to scroll instead of scale when it gets too long for the space.");
			CraftingTabStyle = Config.Bind<CraftingTabStyle>("Crafting UI", "Crafting Tab Style", global::EpicLoot.BaseEL.Crafting.CraftingTabStyle.HorizontalSquish, "Sets the layout style for crafting tabs, if you've got too many. Horizontal is the vanilla method, but might overlap other mods or run off the screen. HorizontalSquish makes the buttons narrower, works okay with 6 or 7 buttons. Vertical puts the tabs in a column to the left the crafting window. Angled tries to make more room at the top of the crafting panel by angling the tabs, works okay with 6 or 7 tabs.");
			ShowEquippedAndHotbarItemsInSacrificeTab = Config.Bind<bool>("Crafting UI", "ShowEquippedAndHotbarItemsInSacrificeTab", false, "If set to false, hides the items that are equipped or on your hotbar in the Sacrifice items list.");
			_loggingEnabled = Config.Bind<bool>("Logging", "Logging Enabled", false, "Enable logging");
			_logLevel = Config.Bind<LogLevel>("Logging", "Log Level", LogLevel.Info, "Only log messages of the selected level or higher");
			UseGeneratedMagicItemNames = Config.Bind<bool>("General", "Use Generated Magic Item Names", true, "If true, magic items uses special, randomly generated names based on their rarity, type, and magic effects.");
			_gatedItemTypeModeConfig = SyncedConfig("Balance", "Item Drop Limits", GatedItemTypeMode.BossKillUnlocksCurrentBiomeItems, "Sets how the drop system limits what item types can drop. Unlimited: no limits, exactly what's in the loot table will drop. BossKillUnlocksCurrentBiomeItems: items will drop for the current biome if the that biome's boss has been killed (Leather gear will drop once Eikthyr is killed). BossKillUnlocksNextBiomeItems: items will only drop for the current biome if the previous biome's boss is killed (Bronze gear will drop once Eikthyr is killed). PlayerMustKnowRecipe: (local world only) the item can drop if the player can craft it. PlayerMustHaveCraftedItem: (local world only) the item can drop if the player has already crafted it or otherwise picked it up. If an item type cannot drop, it will downgrade to an item of the same type and skill that the player has unlocked (i.e. swords will stay swords) according to iteminfo.json.");
			BossBountyMode = SyncedConfig("Balance", "Gated Bounty Mode", GatedBountyMode.Unlimited, "Sets whether available bounties are ungated or gated by boss kills.");
			_bossTrophyDropMode = SyncedConfig("Balance", "Boss Trophy Drop Mode", BossDropMode.OnePerPlayerNearBoss, "Sets bosses to drop a number of trophies equal to the number of players. Optionally set it to only include players within a certain distance, use 'Boss Trophy Drop Player Range' to set the range.");
			_bossTrophyDropPlayerRange = SyncedConfig("Balance", "Boss Trophy Drop Player Range", 100f, "Sets the range that bosses check when dropping multiple trophies using the OnePerPlayerNearBoss drop mode.");
			_bossCryptKeyDropMode = SyncedConfig("Balance", "Crypt Key Drop Mode", BossDropMode.OnePerPlayerNearBoss, "Sets bosses to drop a number of crypt keys equal to the number of players. Optionally set it to only include players within a certain distance, use 'Crypt Key Drop Player Range' to set the range.");
			_bossCryptKeyDropPlayerRange = SyncedConfig("Balance", "Crypt Key Drop Player Range", 100f, "Sets the range that bosses check when dropping multiple crypt keys using the OnePerPlayerNearBoss drop mode.");
			_bossWishboneDropMode = SyncedConfig("Balance", "Wishbone Drop Mode", BossDropMode.OnePerPlayerNearBoss, "Sets bosses to drop a number of wishbones equal to the number of players. Optionally set it to only include players within a certain distance, use 'Crypt Key Drop Player Range' to set the range.");
			_bossWishboneDropPlayerRange = SyncedConfig("Balance", "Wishbone Drop Player Range", 100f, "Sets the range that bosses check when dropping multiple wishbones using the OnePerPlayerNearBoss drop mode.");
			_adventureModeEnabled = SyncedConfig("Balance", "Adventure Mode Enabled", value: true, "Set to true to enable all the adventure mode features: secret stash, gambling, treasure maps, and bounties. Set to false to disable. This will not actually remove active treasure maps or bounties from your save.");
			_andvaranautRange = SyncedConfig("Balance", "Andvaranaut Range", 20, "Sets the range that Andvaranaut will locate a treasure chest.");
			_serverConfigLocked = SyncedConfig("Config Sync", "Lock Config", value: false, new ConfigDescription("[Server Only] The configuration is locked and may not be changed by clients once it has been synced from the server. Only valid for server config, will have no effect on clients.", (AcceptableValueBase)null, Array.Empty<object>()));
			SetItemDropChance = SyncedConfig("Balance", "Set Item Drop Chance", 0.15f, "The percent chance that a legendary item will be a set item. Min = 0, Max = 1");
			GlobalDropRateModifier = SyncedConfig("Balance", "Global Drop Rate Modifier", 1f, "A global percentage that modifies how likely items are to drop. 1 = Exactly what is in the loot tables will drop. 0 = Nothing will drop. 2 = The number of items in the drop table are twice as likely to drop (note, this doesn't double the number of items dropped, just doubles the relative chance for them to drop). Min = 0, Max = 4");
			ItemsToMaterialsDropRatio = SyncedConfig("Balance", "Items To Materials Drop Ratio", 0f, "Sets the chance that item drops are instead dropped as magic crafting materials. 0 = all items, no materials. 1 = all materials, no items. Values between 0 and 1 change the ratio of items to materials that drop. At 0.5, half of everything that drops would be items and the other half would be materials. Min = 0, Max = 1");
			TransferMagicItemToCrafts = SyncedConfig("Balance", "Transfer Enchants to Crafted Items", value: false, "When enchanted items are used as ingredients in recipes, transfer the highest enchant to the newly crafted item. Default: False.");
			AlwaysShowWelcomeMessage = Config.Bind<bool>("Debug", "AlwaysShowWelcomeMessage", false, "Just a debug flag for testing the welcome message, do not use.");
			OutputPatchedConfigFiles = Config.Bind<bool>("Debug", "OutputPatchedConfigFiles", false, "Just a debug flag for testing the patching system, do not use.");
			AbilityKeyCodes[0] = Config.Bind<string>("Abilities", "Ability Hotkey 1", "g", "Hotkey for Ability Slot 1.");
			AbilityKeyCodes[1] = Config.Bind<string>("Abilities", "Ability Hotkey 2", "h", "Hotkey for Ability Slot 2.");
			AbilityKeyCodes[2] = Config.Bind<string>("Abilities", "Ability Hotkey 3", "j", "Hotkey for Ability Slot 3.");
			AbilityBarAnchor = Config.Bind<TextAnchor>("Abilities", "Ability Bar Anchor", (TextAnchor)6, "The point on the HUD to anchor the ability bar. Changing this also changes the pivot of the ability bar to that corner. For reference: the ability bar size is 208 by 64.");
			AbilityBarPosition = Config.Bind<Vector2>("Abilities", "Ability Bar Position", new Vector2(150f, 170f), "The position offset from the Ability Bar Anchor at which to place the ability bar.");
			AbilityBarLayoutAlignment = Config.Bind<TextAnchor>("Abilities", "Ability Bar Layout Alignment", (TextAnchor)6, "The Ability Bar is a Horizontal Layout Group. This value indicates how the elements inside are aligned. Choices with 'Center' in them will keep the items centered on the bar, even if there are fewer than the maximum allowed. 'Left' will be left aligned, and similar for 'Right'.");
			AbilityBarIconSpacing = Config.Bind<float>("Abilities", "Ability Bar Icon Spacing", 8f, "The number of units between the icons on the ability bar.");
			EnchantingTableUpgradesActive = SyncedConfig("Enchanting Table", "Upgrades Active", value: true, "Toggles Enchanting Table Upgrade Capabilities. If false, enchanting table features will be unlocked set to Level 1");
			EnchantingTableActivatedTabs = SyncedConfig("Enchanting Table", "Table Features Active", EnchantingTabs.Sacrifice | EnchantingTabs.ConvertMaterials | EnchantingTabs.Enchant | EnchantingTabs.Augment | EnchantingTabs.Disenchant | EnchantingTabs.Upgrade, "Toggles Enchanting Table Feature on and off completely.");
			EnableLimitedBountiesInProgress = SyncedConfig("Bounty Management", "Enable Bounty Limit", value: false, "Toggles limiting bounties. Players unable to purchase if enabled and maximum bounty in-progress count is met");
			MaxInProgressBounties = SyncedConfig("Bounty Management", "Max Bounties Per Player", 5, "Max amount of in-progress bounties allowed per player.");
			_configSync.AddLockingConfigEntry<bool>(_serverConfigLocked);
			Assembly.GetExecutingAssembly();
			EIDFLegacy.CheckForExtendedItemFrameworkLoaded(_instance);
			EnchantingTableUpgradesActive.SettingChanged += delegate
			{
				EnchantingTableUI.UpdateUpgradeActivation();
			};
			EnchantingTableActivatedTabs.SettingChanged += delegate
			{
				EnchantingTableUI.UpdateTabActivation();
			};
			HasAdventureBackpacks = ABAPI.IsLoaded();
			LoadPatches();
			InitializeConfig();
			InitializeAbilities();
			PrintInfo();
			LoadAssets();
			EnchantingUIController.Initialize();
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "randyknapp.mods.epicloot");
			EpicLootBase.LootTableLoaded?.Invoke();
		}

		private static void LoadEmbeddedAssembly(Assembly assembly, string assemblyName)
		{
			Stream manifestResourceStream = assembly.GetManifestResourceStream(assembly.GetName().Name + "." + assemblyName);
			if (manifestResourceStream == null)
			{
				LogErrorForce("Could not load embedded assembly (" + assemblyName + ")!");
				return;
			}
			using (manifestResourceStream)
			{
				byte[] array = new byte[manifestResourceStream.Length];
				manifestResourceStream.Read(array, 0, array.Length);
				Assembly.Load(array);
			}
		}

		public void Start()
		{
			HasAuga = API.IsLoaded();
			if (HasAuga)
			{
				API.ComplexTooltip_AddItemTooltipCreatedListener((Action<GameObject, ItemData>)ExtendAugaTooltipForMagicItem);
				API.ComplexTooltip_AddItemStatPreprocessor((Func<ItemData, string, string, Tuple<string, string>>)AugaTooltipPreprocessor.PreprocessTooltipStat);
			}
		}

		public static void ExtendAugaTooltipForMagicItem(GameObject complexTooltip, ItemData item)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			API.ComplexTooltip_SetTopic(complexTooltip, Localization.instance.Localize(item.GetDecoratedName()));
			MagicItem magicItem;
			bool flag = item.IsMagic(out magicItem);
			bool flag2 = true;
			Transform val = complexTooltip.transform.Find("Tooltip/IconHeader/IconBkg/Item");
			if ((Object)(object)val == (Object)null)
			{
				val = complexTooltip.transform.Find("InventoryElement/icon");
				flag2 = false;
			}
			RectTransform val2 = null;
			if ((Object)(object)val != (Object)null)
			{
				Image component = ((Component)val).GetComponent<Image>();
				val2 = (RectTransform)((Component)val).transform.Find("magicItem");
				if ((Object)(object)val2 == (Object)null)
				{
					GameObject gameObject = ((Component)Object.Instantiate<Image>(component, flag2 ? ((Component)val).transform : ((Component)val).transform.parent)).gameObject;
					((Object)gameObject).name = "magicItem";
					gameObject.SetActive(true);
					val2 = (RectTransform)gameObject.transform;
					val2.anchorMin = Vector2.zero;
					val2.anchorMax = new Vector2(1f, 1f);
					val2.sizeDelta = Vector2.zero;
					val2.pivot = new Vector2(0.5f, 0.5f);
					val2.anchoredPosition = Vector2.zero;
					Image component2 = ((Component)val2).GetComponent<Image>();
					((Graphic)component2).color = Color.white;
					((Graphic)component2).raycastTarget = false;
					component2.sprite = GetMagicItemBgSprite();
					if (!flag2)
					{
						((Transform)val2).SetSiblingIndex(0);
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(flag);
			}
			if (item.IsMagicCraftingMaterial())
			{
				ItemRarity craftingMaterialRarity = item.GetCraftingMaterialRarity();
				API.ComplexTooltip_SetIcon(complexTooltip, item.m_shared.m_icons[GetRarityIconIndex(craftingMaterialRarity)]);
			}
			if (!flag)
			{
				return;
			}
			string colorString = magicItem.GetColorString();
			string itemTypeName = magicItem.GetItemTypeName(item.Extended());
			if ((Object)(object)val2 != (Object)null)
			{
				((Graphic)((Component)val2).GetComponent<Image>()).color = item.GetRarityColor();
			}
			API.ComplexTooltip_SetIcon(complexTooltip, item.GetIcon());
			string text = ((!item.IsLegendarySetItem()) ? ("<color=" + colorString + ">" + magicItem.GetRarityDisplay() + " " + itemTypeName + "</color>") : ("<color=" + GetSetItemColor() + ">$mod_epicloot_legendarysetlabel</color>, " + itemTypeName + "\n"));
			try
			{
				API.ComplexTooltip_SetSubtitle(complexTooltip, Localization.instance.Localize(text));
			}
			catch (Exception)
			{
				API.ComplexTooltip_SetSubtitle(complexTooltip, text);
			}
			if (!AugaTooltipNoTextBoxes && !((Object)complexTooltip).name.Contains("InventoryTooltip"))
			{
				API.ComplexTooltip_AddDivider(complexTooltip);
				string tooltip = magicItem.GetTooltip();
				GameObject obj = API.ComplexTooltip_AddTwoColumnTextBox(complexTooltip);
				tooltip = tooltip.Replace("\n\n", "");
				API.TooltipTextBox_AddLine(obj, (object)tooltip, true);
				if (magicItem.IsLegendarySetItem())
				{
					API.TooltipTextBox_AddLine(API.ComplexTooltip_AddTwoColumnTextBox(complexTooltip), (object)item.GetSetTooltip(), true);
				}
				try
				{
					API.ComplexTooltip_SetDescription(complexTooltip, Localization.instance.Localize(item.GetDescription()));
				}
				catch (Exception)
				{
					API.ComplexTooltip_SetDescription(complexTooltip, item.GetDescription());
				}
			}
		}

		private ConfigEntry<T> SyncedConfig<T>(string group, string configName, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return SyncedConfig(group, configName, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		private ConfigEntry<T> SyncedConfig<T>(string group, string configName, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = Config.Bind<T>(group, configName, value, description);
			((OwnConfigEntryBase)_configSync.AddConfigEntry<T>(val)).SynchronizedConfig = synchronizedSetting;
			return val;
		}

		public static void LoadPatches()
		{
			FilePatching.LoadAllPatches();
		}

		private static void LoadTranslations(IDictionary<string, object> translations)
		{
			if (translations == null)
			{
				LogErrorForce("Could not parse translations.json!");
				return;
			}
			foreach (KeyValuePair<string, string> item in Localization.instance.m_translations.Where((KeyValuePair<string, string> instanceMTranslation) => instanceMTranslation.Key.StartsWith("mod_epicloot_")).ToList())
			{
				Localization.instance.m_translations.Remove(item.Key);
			}
			foreach (KeyValuePair<string, object> translation in translations)
			{
				Localization.instance.AddWord(translation.Key, translation.Value.ToString());
			}
		}

		public static ConfigFile GetConfigObject()
		{
			return _instance.Config;
		}

		public static void InitializeConfig()
		{
			LoadJsonFile<IDictionary<string, object>>("translations.json", LoadTranslations, ConfigType.Nonsynced);
			LoadJsonFile<LootConfig>("loottables.json", LootRoller.Initialize, ConfigType.Synced);
			LoadJsonFile<MagicItemEffectsList>("magiceffects.json", MagicItemEffectDefinitions.Initialize, ConfigType.Synced);
			LoadJsonFile<ItemInfoConfig>("iteminfo.json", GatedItemTypeHelper.Initialize, ConfigType.Synced);
			LoadJsonFile<RecipesConfig>("recipes.json", RecipesHelper.Initialize, ConfigType.Synced);
			LoadJsonFile<EnchantingCostsConfig>("enchantcosts.json", EnchantCostsHelper.Initialize, ConfigType.Synced);
			LoadJsonFile<ItemNameConfig>("itemnames.json", MagicItemNames.Initialize, ConfigType.Synced);
			LoadJsonFile<AdventureDataConfig>("adventuredata.json", AdventureDataManager.Initialize, ConfigType.Synced);
			LoadJsonFile<LegendaryItemConfig>("legendaries.json", UniqueLegendaryHelper.Initialize, ConfigType.Synced);
			LoadJsonFile<AbilityConfig>("abilities.json", AbilityDefinitions.Initialize, ConfigType.Synced);
			LoadJsonFile<MaterialConversionsConfig>("materialconversions.json", MaterialConversions.Initialize, ConfigType.Synced);
			LoadJsonFile("enchantingupgrades.json", (Action<EnchantingUpgradesConfig>)EnchantingTableUpgrades.InitializeConfig, ConfigType.Synced, update: false);
			LoadJsonFile<EnchantingSkillConfig>("enchantingskill.json", Enchanting.InitSkillConfig, ConfigType.Synced);
			WatchNewPatchConfig();
		}

		public static void WatchNewPatchConfig()
		{
			Log("Watching For Files");
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(FilePatching.PatchesDirPath, "*.json");
			fileSystemWatcher.Created += ConsumeNewPatchFile;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			static void ConsumeNewPatchFile(object s, FileSystemEventArgs e)
			{
				if (e.ChangeType == WatcherChangeTypes.Created)
				{
					FileInfo fileInfo = new FileInfo(e.FullPath);
					if (fileInfo.Exists)
					{
						FilePatching.ProcessPatchFile(fileInfo);
						string sourceFile = fileInfo.Name;
						string[] array = (from u in FilePatching.PatchesPerFile.Values.SelectMany((List<Patch> l) => l).ToList()
							where u.SourceFile.Equals(sourceFile)
							select u into p
							select p.TargetFile).Distinct().ToArray();
						foreach (string text in array)
						{
							if (SyncedJsonFiles.ContainsKey(text))
							{
								SyncedJsonFiles[text].AssignLocalValue(LoadJsonText(text));
							}
							else
							{
								NonSyncedJsonFiles[text].AssignValue(LoadJsonText(text));
							}
							AddPatchFileWatcher(text, sourceFile);
						}
					}
				}
			}
		}

		private static void InitializeAbilities()
		{
			MagicEffectType.Initialize();
			EpicLootBase.AbilitiesInitialized?.Invoke();
		}

		public static void Log(string message)
		{
			if (_loggingEnabled.Value && _logLevel.Value <= LogLevel.Info)
			{
				_instance.Logger.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			if (_loggingEnabled.Value && _logLevel.Value <= LogLevel.Warning)
			{
				_instance.Logger.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			if (_loggingEnabled.Value && _logLevel.Value <= LogLevel.Error)
			{
				_instance.Logger.LogError((object)message);
			}
		}

		public static void LogWarningForce(string message)
		{
			_instance.Logger.LogWarning((object)message);
		}

		public static void LogErrorForce(string message)
		{
			_instance.Logger.LogError((object)message);
		}

		public void Update()
		{
			if (Time.time - _lastUpdate > 0.05f)
			{
				_lastUpdate = Time.time;
				EnchantingUIController.RefreshEnchantRarityButtons();
			}
		}

		private void LoadAssets()
		{
			AssetBundle val = AssetUtils.LoadAssetBundleFromResources("epicloot");
			Assets.AssetBundle = val;
			Assets.EquippedSprite = val.LoadAsset<Sprite>("Equipped");
			Assets.AugaEquippedSprite = val.LoadAsset<Sprite>("AugaEquipped");
			Assets.GenericSetItemSprite = val.LoadAsset<Sprite>("GenericSetItemMarker");
			Assets.AugaSetItemSprite = val.LoadAsset<Sprite>("AugaSetItem");
			Assets.GenericItemBgSprite = val.LoadAsset<Sprite>("GenericItemBg");
			Assets.AugaItemBgSprite = val.LoadAsset<Sprite>("AugaItemBG");
			Assets.SmallButtonEnchantOverlay = val.LoadAsset<Sprite>("SmallButtonEnchantOverlay");
			Assets.MagicItemLootBeamPrefabs[0] = val.LoadAsset<GameObject>("MagicLootBeam");
			Assets.MagicItemLootBeamPrefabs[1] = val.LoadAsset<GameObject>("RareLootBeam");
			Assets.MagicItemLootBeamPrefabs[2] = val.LoadAsset<GameObject>("EpicLootBeam");
			Assets.MagicItemLootBeamPrefabs[3] = val.LoadAsset<GameObject>("LegendaryLootBeam");
			Assets.MagicItemLootBeamPrefabs[4] = val.LoadAsset<GameObject>("MythicLootBeam");
			Assets.MagicItemDropSFX[0] = val.LoadAsset<AudioClip>("MagicItemDrop");
			Assets.MagicItemDropSFX[1] = val.LoadAsset<AudioClip>("RareItemDrop");
			Assets.MagicItemDropSFX[2] = val.LoadAsset<AudioClip>("EpicItemDrop");
			Assets.MagicItemDropSFX[3] = val.LoadAsset<AudioClip>("LegendaryItemDrop");
			Assets.MagicItemDropSFX[4] = val.LoadAsset<AudioClip>("MythicItemDrop");
			Assets.ItemLoopSFX = val.LoadAsset<AudioClip>("ItemLoop");
			Assets.AugmentItemSFX = val.LoadAsset<AudioClip>("AugmentItem");
			Assets.MerchantPanel = val.LoadAsset<GameObject>("MerchantPanel");
			Assets.MapIconTreasureMap = val.LoadAsset<Sprite>("TreasureMapIcon");
			Assets.MapIconBounty = val.LoadAsset<Sprite>("MapIconBounty");
			Assets.AbandonBountySFX = val.LoadAsset<AudioClip>("AbandonBounty");
			Assets.DoubleJumpSFX = val.LoadAsset<AudioClip>("DoubleJump");
			Assets.DebugTextPrefab = val.LoadAsset<GameObject>("DebugText");
			Assets.AbilityBar = val.LoadAsset<GameObject>("AbilityBar");
			Assets.WelcomMessagePrefab = val.LoadAsset<GameObject>("WelcomeMessage");
			LoadCraftingMaterialAssets(val, "Runestone");
			LoadCraftingMaterialAssets(val, "Shard");
			LoadCraftingMaterialAssets(val, "Dust");
			LoadCraftingMaterialAssets(val, "Reagent");
			LoadCraftingMaterialAssets(val, "Essence");
			LoadBuildPiece(val, "piece_enchanter", new PieceDef
			{
				Table = "_HammerPieceTable",
				CraftingStation = "piece_workbench",
				Resources = new List<RecipeRequirementConfig>
				{
					new RecipeRequirementConfig
					{
						item = "Stone",
						amount = 10
					},
					new RecipeRequirementConfig
					{
						item = "SurtlingCore",
						amount = 3
					},
					new RecipeRequirementConfig
					{
						item = "Copper",
						amount = 3
					}
				}
			});
			LoadBuildPiece(val, "piece_augmenter", new PieceDef
			{
				Table = "_HammerPieceTable",
				CraftingStation = "piece_workbench",
				Resources = new List<RecipeRequirementConfig>
				{
					new RecipeRequirementConfig
					{
						item = "Obsidian",
						amount = 10
					},
					new RecipeRequirementConfig
					{
						item = "Crystal",
						amount = 3
					},
					new RecipeRequirementConfig
					{
						item = "Bronze",
						amount = 3
					}
				}
			});
			LoadBuildPiece(val, "piece_enchantingtable", new PieceDef
			{
				Table = "_HammerPieceTable",
				CraftingStation = "piece_workbench",
				Resources = new List<RecipeRequirementConfig>
				{
					new RecipeRequirementConfig
					{
						item = "FineWood",
						amount = 10
					},
					new RecipeRequirementConfig
					{
						item = "SurtlingCore",
						amount = 1
					}
				}
			});
			LoadItem(val, "LeatherBelt");
			LoadItem(val, "SilverRing");
			LoadItem(val, "GoldRubyRing");
			LoadItem(val, "Andvaranaut", SetupAndvaranaut);
			LoadItem(val, "ForestToken");
			LoadItem(val, "IronBountyToken");
			LoadItem(val, "GoldBountyToken");
			LoadAllZNetAssets(val);
		}

		public static T LoadAsset<T>(string assetName) where T : Object
		{
			try
			{
				if (_assetCache.ContainsKey(assetName))
				{
					return (T)(object)_assetCache[assetName];
				}
				T val = Assets.AssetBundle.LoadAsset<T>(assetName);
				_assetCache.Add(assetName, (Object)(object)val);
				return val;
			}
			catch (Exception ex)
			{
				LogErrorForce("Error loading asset (" + assetName + "): " + ex.Message);
				return default(T);
			}
		}

		private static void LoadItem(AssetBundle assetBundle, string assetName, Action<ItemDrop> customSetupAction = null)
		{
			bool forceDisableInit = ZNetView.m_forceDisableInit;
			ZNetView.m_forceDisableInit = true;
			GameObject val = assetBundle.LoadAsset<GameObject>(assetName);
			ZNetView.m_forceDisableInit = forceDisableInit;
			RegisteredItemPrefabs.Add(val);
			RegisteredPrefabs.Add(val);
			if (customSetupAction != null)
			{
				_customItemSetupActions.Add(((Object)val).name, customSetupAction);
			}
		}

		private static void LoadBuildPiece(AssetBundle assetBundle, string assetName, PieceDef pieceDef)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(assetName);
			RegisteredPieces.Add(val, pieceDef);
			RegisteredPrefabs.Add(val);
		}

		private static void LoadCraftingMaterialAssets(AssetBundle assetBundle, string type)
		{
			GameObject[] array = (GameObject[])(object)new GameObject[5];
			foreach (ItemRarity value in Enum.GetValues(typeof(ItemRarity)))
			{
				string text = $"{type}{value}";
				GameObject val = assetBundle.LoadAsset<GameObject>(text);
				if ((Object)(object)val == (Object)null)
				{
					LogErrorForce("Tried to load asset " + text + " but it does not exist in the asset bundle!");
					continue;
				}
				array[(int)value] = val;
				RegisteredPrefabs.Add(val);
				RegisteredItemPrefabs.Add(val);
			}
			Assets.CraftingMaterialPrefabs.Add(type, array);
		}

		private void LoadAllZNetAssets(AssetBundle assetBundle)
		{
			Object[] array = assetBundle.LoadAllAssets();
			foreach (Object val in array)
			{
				GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null);
				if (val2 != null && (Object)(object)val2.GetComponent<ZNetView>() != (Object)null)
				{
					if (!_assetCache.ContainsKey(val.name))
					{
						_assetCache.Add(val.name, (Object)(object)val2);
					}
					if (!RegisteredPrefabs.Contains(val2))
					{
						RegisteredPrefabs.Add(val2);
					}
				}
			}
		}

		public void OnDestroy()
		{
			_instance = null;
		}

		public static void TryRegisterPrefabs(ZNetScene zNetScene)
		{
			if ((Object)(object)zNetScene == (Object)null || zNetScene.m_prefabs == null || zNetScene.m_prefabs.Count <= 0)
			{
				return;
			}
			foreach (GameObject registeredPrefab in RegisteredPrefabs)
			{
				if (!zNetScene.m_prefabs.Contains(registeredPrefab))
				{
					zNetScene.m_prefabs.Add(registeredPrefab);
				}
			}
		}

		public static void TryRegisterPieces(List<PieceTable> pieceTables, List<CraftingStation> craftingStations)
		{
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			foreach (KeyValuePair<GameObject, PieceDef> registeredPiece in RegisteredPieces)
			{
				GameObject key = registeredPiece.Key;
				if ((Object)(object)key == (Object)null)
				{
					LogError("Tried to register piece but prefab was null!");
					continue;
				}
				PieceDef pieceDef = registeredPiece.Value;
				if (pieceDef == null)
				{
					LogError($"Tried to register piece ({key}) but pieceDef was null!");
					continue;
				}
				Piece component = key.GetComponent<Piece>();
				if ((Object)(object)component == (Object)null)
				{
					LogError($"Tried to register piece ({key}) but Piece component was missing!");
					continue;
				}
				PieceTable val = pieceTables.Find((PieceTable x) => ((Object)x).name == pieceDef.Table);
				if ((Object)(object)val == (Object)null)
				{
					LogError(string.Format("Tried to register piece ({0}) but could not find piece table ({1}) (pieceTables({2})= {3})!", key, pieceDef.Table, pieceTables.Count, string.Join(", ", pieceTables.Select((PieceTable x) => ((Object)x).name))));
				}
				else
				{
					if (val.m_pieces.Contains(key))
					{
						continue;
					}
					val.m_pieces.Add(key);
					CraftingStation craftingStation = craftingStations.Find((CraftingStation x) => ((Object)x).name == pieceDef.CraftingStation);
					component.m_craftingStation = craftingStation;
					List<Requirement> list = new List<Requirement>();
					foreach (RecipeRequirementConfig resource in pieceDef.Resources)
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(resource.item);
						list.Add(new Requirement
						{
							m_resItem = itemPrefab.GetComponent<ItemDrop>(),
							m_amount = resource.amount
						});
					}
					component.m_resources = list.ToArray();
					StationExtension component2 = key.GetComponent<StationExtension>();
					if ((Object)(object)component2 != (Object)null && !string.IsNullOrEmpty(pieceDef.ExtendStation))
					{
						GameObject val2 = val.m_pieces.Find((GameObject x) => ((Object)x).name == pieceDef.ExtendStation);
						if ((Object)(object)val2 != (Object)null)
						{
							CraftingStation component3 = val2.GetComponent<CraftingStation>();
							component2.m_craftingStation = component3;
						}
						GameObject val3 = val.m_pieces.Find((GameObject x) => (Object)(object)x.GetComponent<StationExtension>() != (Object)null);
						if ((Object)(object)val3 != (Object)null)
						{
							StationExtension component4 = val3.GetComponent<StationExtension>();
							Piece component5 = val3.GetComponent<Piece>();
							component2.m_connectionPrefab = component4.m_connectionPrefab;
							component.m_placeEffect.m_effectPrefabs = component5.m_placeEffect.m_effectPrefabs.ToArray();
						}
						continue;
					}
					GameObject val4 = ((IEnumerable<GameObject>)val.m_pieces).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => ((Object)x).name == "piece_workshop"));
					if ((Object)(object)val4 != (Object)null)
					{
						Piece component6 = val4.GetComponent<Piece>();
						if (component6 != null)
						{
							component.m_placeEffect.m_effectPrefabs = component6.m_placeEffect.m_effectPrefabs.ToArray();
						}
					}
				}
			}
		}

		public static bool IsObjectDBReady()
		{
			if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0)
			{
				return (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null;
			}
			return false;
		}

		public static void TryRegisterItems()
		{
			if (!IsObjectDBReady())
			{
				return;
			}
			foreach (GameObject registeredItemPrefab in RegisteredItemPrefabs)
			{
				ItemDrop component = registeredItemPrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null && (component.m_itemData.IsMagicCraftingMaterial() || component.m_itemData.IsRunestone()))
				{
					ItemRarity rarity = component.m_itemData.GetRarity();
					if (component.m_itemData.IsMagicCraftingMaterial())
					{
						component.m_itemData.m_variant = GetRarityIconIndex(rarity);
					}
				}
			}
			foreach (GameObject registeredItemPrefab2 in RegisteredItemPrefabs)
			{
				if ((Object)(object)registeredItemPrefab2.GetComponent<ItemDrop>() != (Object)null && (Object)(object)ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(((Object)registeredItemPrefab2).name)) == (Object)null)
				{
					ObjectDB.instance.m_items.Add(registeredItemPrefab2);
				}
			}
			foreach (GameObject registeredItemPrefab3 in RegisteredItemPrefabs)
			{
				ItemDrop component2 = registeredItemPrefab3.GetComponent<ItemDrop>();
				if ((Object)(object)component2 != (Object)null && _customItemSetupActions.TryGetValue(((Object)registeredItemPrefab3).name, out var value))
				{
					value?.Invoke(component2);
				}
			}
			ObjectDB.instance.UpdateItemHashes();
			List<PieceTable> list = new List<PieceTable>();
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemDrop component3 = item.GetComponent<ItemDrop>();
				if ((Object)(object)component3 == (Object)null)
				{
					LogError($"An item without an ItemDrop ({item}) exists in ObjectDB.instance.m_items! Don't do this!");
					continue;
				}
				ItemData itemData = component3.m_itemData;
				if (itemData != null && (Object)(object)itemData.m_shared.m_buildPieces != (Object)null && !list.Contains(itemData.m_shared.m_buildPieces))
				{
					list.Add(itemData.m_shared.m_buildPieces);
				}
			}
			List<CraftingStation> list2 = new List<CraftingStation>();
			foreach (PieceTable item2 in list)
			{
				list2.AddRange(from x in item2.m_pieces
					where (Object)(object)x.GetComponent<CraftingStation>() != (Object)null
					select x.GetComponent<CraftingStation>());
			}
			TryRegisterPieces(list, list2);
			SetupStatusEffects();
		}

		public static void TryRegisterRecipes()
		{
			if (IsObjectDBReady())
			{
				RecipesHelper.SetupRecipes();
			}
		}

		private static void SetupAndvaranaut(ItemDrop prefab)
		{
			ItemData itemData = prefab.m_itemData;
			ItemData itemData2 = ObjectDB.instance.GetItemPrefab("Wishbone").GetComponent<ItemDrop>().m_itemData;
			StatusEffect equipStatusEffect = itemData2.m_shared.m_equipStatusEffect;
			SE_CustomFinder sE_CustomFinder = ScriptableObject.CreateInstance<SE_CustomFinder>();
			Utils.CopyFields(equipStatusEffect, sE_CustomFinder, typeof(SE_Finder));
			((Object)sE_CustomFinder).name = "CustomWishboneFinder";
			SE_CustomFinder sE_CustomFinder2 = ScriptableObject.CreateInstance<SE_CustomFinder>();
			Utils.CopyFields(sE_CustomFinder, sE_CustomFinder2, typeof(SE_CustomFinder));
			((Object)sE_CustomFinder2).name = "Andvaranaut";
			((StatusEffect)sE_CustomFinder2).m_name = "$mod_epicloot_item_andvaranaut";
			((StatusEffect)sE_CustomFinder2).m_icon = itemData.GetIcon();
			((StatusEffect)sE_CustomFinder2).m_tooltip = "$mod_epicloot_item_andvaranaut_tooltip";
			((StatusEffect)sE_CustomFinder2).m_startMessage = "$mod_epicloot_item_andvaranaut_startmsg";
			sE_CustomFinder2.RequiredComponentTypes = new List<Type> { typeof(TreasureMapChest) };
			sE_CustomFinder.DisallowedComponentTypes = new List<Type> { typeof(TreasureMapChest) };
			ObjectDB.instance.m_StatusEffects.Remove(equipStatusEffect);
			ObjectDB.instance.m_StatusEffects.Add((StatusEffect)(object)sE_CustomFinder2);
			ObjectDB.instance.m_StatusEffects.Add((StatusEffect)(object)sE_CustomFinder);
			itemData.m_shared.m_equipStatusEffect = (StatusEffect)(object)sE_CustomFinder2;
			itemData2.m_shared.m_equipStatusEffect = (StatusEffect)(object)sE_CustomFinder;
			MagicItem magicItem = new MagicItem
			{
				Rarity = ItemRarity.Epic,
				TypeNameOverride = "$mod_epicloot_item_andvaranaut_type"
			};
			magicItem.Effects.Add(new MagicItemEffect(MagicEffectType.Andvaranaut));
			prefab.m_itemData.SaveMagicItem(magicItem);
		}

		private static void SetupStatusEffects()
		{
			StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect("Lightning".GetHashCode());
			SE_Paralyzed sE_Paralyzed = ScriptableObject.CreateInstance<SE_Paralyzed>();
			Utils.CopyFields(statusEffect, sE_Paralyzed, typeof(StatusEffect));
			((Object)sE_Paralyzed).name = "Paralyze";
			((StatusEffect)sE_Paralyzed).m_name = "mod_epicloot_se_paralyze";
			ObjectDB.instance.m_StatusEffects.Add((StatusEffect)(object)sE_Paralyzed);
		}

		public static void LoadJsonFile<T>(string filename, Action<T> onFileLoad, ConfigType configType, bool update = false) where T : class
		{
			string text = LoadJsonText(filename);
			if (!update)
			{
				if (configType == ConfigType.Synced)
				{
					SyncedJsonFiles.Add(filename, new CustomSyncedValue<string>(_instance._configSync, filename, text, 0));
				}
				else
				{
					NonSyncedJsonFiles.Add(filename, new ConfigValue<string>(filename, text));
				}
			}
			if (configType == ConfigType.Synced)
			{
				((CustomSyncedValueBase)SyncedJsonFiles[filename]).ValueChanged += Process;
			}
			else
			{
				NonSyncedJsonFiles[filename].ValueChanged += Process;
			}
			Process();
			if (text == null)
			{
				return;
			}
			string assetPath = GetAssetPath(filename);
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(assetPath), Path.GetFileName(assetPath));
			fileSystemWatcher.Changed += ConsumeConfigFileEvent;
			fileSystemWatcher.Created += ConsumeConfigFileEvent;
			fileSystemWatcher.Renamed += ConsumeConfigFileEvent;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			for (int i = 0; i < FilePatching.PatchesPerFile.Where((KeyValuePair<string, List<Patch>> y) => y.Key.Equals(filename)).ToList().Count; i++)
			{
				List<string> list = FilePatching.PatchesPerFile.Where((KeyValuePair<string, List<Patch>> y) => y.Key.Equals(filename)).ToList()[i].Value.Select((Patch p) => p.SourceFile).Distinct().ToList();
				for (int j = 0; j < list.Count; j++)
				{
					string patchFile = list[j];
					AddPatchFileWatcher(filename, patchFile);
				}
			}
			void ConsumeConfigFileEvent(object s, FileSystemEventArgs e)
			{
				if (configType == ConfigType.Synced)
				{
					SyncedJsonFiles[filename].AssignLocalValue(LoadJsonText(filename));
				}
				else
				{
					NonSyncedJsonFiles[filename].AssignValue(LoadJsonText(filename));
				}
			}
			void Process()
			{
				T obj;
				try
				{
					obj = ((configType != 0) ? (string.IsNullOrEmpty(NonSyncedJsonFiles[filename].Value) ? null : JsonConvert.DeserializeObject<T>(NonSyncedJsonFiles[filename].Value)) : (string.IsNullOrEmpty(SyncedJsonFiles[filename].Value) ? null : JsonConvert.DeserializeObject<T>(SyncedJsonFiles[filename].Value)));
				}
				catch (Exception)
				{
					LogErrorForce("Could not parse file '" + filename + "'! Errors in JSON!");
					throw;
				}
				onFileLoad(obj);
			}
		}

		private static void AddPatchFileWatcher(string fileName, string patchFile)
		{
			string fullPatchFilename = Path.Combine(FilePatching.PatchesDirPath, patchFile);
			Log("[AddPatchFileWatcher] Full Patch File Name = " + fullPatchFilename);
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(fullPatchFilename), Path.GetFileName(fullPatchFilename));
			fileSystemWatcher.Changed += ConsumePatchFileEvent;
			fileSystemWatcher.Deleted += ConsumePatchFileEvent;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			void ConsumePatchFileEvent(object s, FileSystemEventArgs e)
			{
				FileInfo fileInfo = null;
				switch (e.ChangeType)
				{
				case WatcherChangeTypes.Deleted:
					Debug.Log((object)"Function Deleted");
					FilePatching.RemoveFilePatches(fileName, patchFile);
					break;
				case WatcherChangeTypes.Changed:
					Debug.Log((object)"Function Changed");
					FilePatching.RemoveFilePatches(fileName, patchFile);
					fileInfo = new FileInfo(fullPatchFilename);
					break;
				}
				if (fileInfo != null && fileInfo.Exists)
				{
					FilePatching.ProcessPatchFile(fileInfo);
				}
				SyncedJsonFiles[fileName].AssignLocalValue(LoadJsonText(fileName));
			}
		}

		public static string LoadJsonText(string filename)
		{
			string assetPath = GetAssetPath(filename);
			if (string.IsNullOrEmpty(assetPath))
			{
				return null;
			}
			string text = File.ReadAllText(assetPath);
			string text2 = FilePatching.ProcessConfigFile(filename, text);
			if (OutputPatchedConfigFiles.Value && text != text2)
			{
				File.WriteAllText(Path.Combine(Paths.ConfigPath, "EpicLoot", filename.Replace(".json", "_patched.json")), text2);
			}
			return text2;
		}

		public static string GenerateAssetPathAtAssembly(string assetName)
		{
			return Path.Combine(Path.GetDirectoryName(typeof(EpicLootBase).Assembly.Location) ?? string.Empty, assetName);
		}

		public static string GetAssetPath(string assetName)
		{
			string text = Path.Combine(Paths.PluginPath, "EpicLoot", assetName);
			if (!File.Exists(text))
			{
				text = GenerateAssetPathAtAssembly(assetName);
				if (!File.Exists(text))
				{
					LogErrorForce("Could not find asset (" + assetName + ")");
					return null;
				}
			}
			return text;
		}

		public static bool CanBeMagicItem(ItemData item)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (item != null && IsPlayerItem(item) && Nonstackable(item) && IsNotRestrictedItem(item))
			{
				return AllowedMagicItemTypes.Contains(item.m_shared.m_itemType);
			}
			return false;
		}

		public static Sprite GetMagicItemBgSprite()
		{
			if (!HasAuga)
			{
				return Assets.GenericItemBgSprite;
			}
			return Assets.AugaItemBgSprite;
		}

		public static Sprite GetEquippedSprite()
		{
			if (!HasAuga)
			{
				return Assets.EquippedSprite;
			}
			return Assets.AugaEquippedSprite;
		}

		public static Sprite GetSetItemSprite()
		{
			if (!HasAuga)
			{
				return Assets.GenericSetItemSprite;
			}
			return Assets.AugaSetItemSprite;
		}

		public static string GetMagicEffectPip(bool hasBeenAugmented)
		{
			if (!HasAuga)
			{
				if (!hasBeenAugmented)
				{
					return "◆";
				}
				return "◇";
			}
			if (!hasBeenAugmented)
			{
				return "♦";
			}
			return "♢";
		}

		private static bool IsNotRestrictedItem(ItemData item)
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null && LootRoller.Config.RestrictedItems.Contains(((Object)item.m_dropPrefab).name))
			{
				return false;
			}
			return !LootRoller.Config.RestrictedItems.Contains(item.m_shared.m_name);
		}

		private static bool Nonstackable(ItemData item)
		{
			return item.m_shared.m_maxStackSize == 1;
		}

		private static bool IsPlayerItem(ItemData item)
		{
			return item.m_shared.m_icons.Length != 0;
		}

		public static string GetCharacterCleanName(Character character)
		{
			return ((Object)character).name.Replace("(Clone)", "").Trim();
		}

		public static void OnCharacterDeath(CharacterDrop characterDrop)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (CanCharacterDropLoot(characterDrop.m_character))
			{
				string characterCleanName = GetCharacterCleanName(characterDrop.m_character);
				int level = characterDrop.m_character.GetLevel();
				Vector3 dropPoint = characterDrop.m_character.GetCenterPoint() + ((Component)characterDrop).transform.TransformVector(characterDrop.m_spawnOffset);
				OnCharacterDeath(characterCleanName, level, dropPoint);
			}
		}

		public static bool CanCharacterDropLoot(Character character)
		{
			if ((Object)(object)character != (Object)null)
			{
				return !character.IsTamed();
			}
			return false;
		}

		public static void OnCharacterDeath(string characterName, int level, Vector3 dropPoint)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			List<LootTable> lootTable = LootRoller.GetLootTable(characterName);
			if (lootTable != null && lootTable.Count > 0)
			{
				List<GameObject> list = LootRoller.RollLootTableAndSpawnObjects(lootTable, level, characterName, dropPoint);
				Log($"Rolling on loot table: {characterName} (lvl {level}), spawned {list.Count} items at drop point({dropPoint}).");
				DropItems(list, dropPoint);
				{
					foreach (GameObject item in list)
					{
						ItemData itemData = item.GetComponent<ItemDrop>().m_itemData;
						MagicItem magicItem = itemData.GetMagicItem();
						if (magicItem != null)
						{
							Log(string.Format("  - {0} <{1}>: {2}", itemData.m_shared.m_name, item.transform.position, string.Join(", ", magicItem.Effects.Select((MagicItemEffect x) => x.EffectType.ToString()))));
						}
					}
					return;
				}
			}
			Log($"Could not find loot table for: {characterName} (lvl {level})");
		}

		public static void DropItems(List<GameObject> loot, Vector3 centerPos, float dropHemisphereRadius = 0.5f)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject item in loot)
			{
				Vector3 val = Random.insideUnitSphere * dropHemisphereRadius;
				val.y = Mathf.Abs(val.y);
				item.transform.position = centerPos + val;
				item.transform.rotation = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
				Rigidbody component = item.GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					Vector3 insideUnitSphere = Random.insideUnitSphere;
					if ((double)insideUnitSphere.y < 0.0)
					{
						insideUnitSphere.y = 0f - insideUnitSphere.y;
					}
					component.AddForce(insideUnitSphere * 5f, (ForceMode)2);
				}
			}
		}

		private void PrintInfo()
		{
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Invalid comparison between Unknown and I4
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Invalid comparison between Unknown and I4
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Invalid comparison between Unknown and I4
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Invalid comparison between Unknown and I4
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Invalid comparison between Unknown and I4
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Invalid comparison between Unknown and I4
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			if (!Directory.Exists("C:\\Users\\rknapp\\Documents\\GitHub\\ValheimMods\\EpicLoot"))
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("# EpicLoot Data v0.9.37");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("*Author: RandyKnapp*");
			stringBuilder.AppendLine("*Source: [Github](https://github.com/RandyKnapp/ValheimMods/tree/main/EpicLoot)*");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("# Magic Effect Count Weights Per Rarity");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Each time a **MagicItem** is rolled a number of **MagicItemEffects** are added based on its **Rarity**. The percent chance to roll each number of effects is found on the following table. These values are hardcoded.");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("The raw weight value is shown first, followed by the calculated percentage chance in parentheses.");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("|Rarity|1|2|3|4|5|6|");
			stringBuilder.AppendLine("|--|--|--|--|--|--|--|");
			stringBuilder.AppendLine(GetMagicEffectCountTableLine(ItemRarity.Magic));
			stringBuilder.AppendLine(GetMagicEffectCountTableLine(ItemRarity.Rare));
			stringBuilder.AppendLine(GetMagicEffectCountTableLine(ItemRarity.Epic));
			stringBuilder.AppendLine(GetMagicEffectCountTableLine(ItemRarity.Legendary));
			stringBuilder.AppendLine();
			List<ItemRarity> list = new List<ItemRarity>();
			foreach (ItemRarity value3 in Enum.GetValues(typeof(ItemRarity)))
			{
				list.Add(value3);
			}
			List<SkillType> list2 = new List<SkillType>();
			foreach (SkillType value4 in Enum.GetValues(typeof(SkillType)))
			{
				if ((int)value4 != 0 && (int)value4 != 13 && (int)value4 != 100 && (int)value4 != 101 && (int)value4 != 102 && (int)value4 != 103 && (int)value4 != 999)
				{
					list2.Add(value4);
				}
			}
			stringBuilder.AppendLine("# MagicItemEffect List");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("The following lists all the built-in **MagicItemEffects**. MagicItemEffects are defined in `magiceffects.json` and are parsed and added to `MagicItemEffectDefinitions` on Awake. EpicLoot uses an string for the types of magic effects. You can add your own new types using your own identifiers.");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Listen to the event `MagicItemEffectDefinitions.OnSetupMagicItemEffectDefinitions` (which gets called in `EpicLoot.Awake`) to add your own using instances of MagicItemEffectDefinition.");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("  * **Display Text:** This text appears in the tooltip for the magic item, with {0:?} replaced with the rolled value for the effect, formatted using the shown C# string format.");
			stringBuilder.AppendLine("  * **Requirements:** A set of requirements.");
			stringBuilder.AppendLine("    * **Flags:** A set of predefined flags to check certain weapon properties. The list of flags is: `NoRoll, ExclusiveSelf, ItemHasPhysicalDamage, ItemHasElementalDamage, ItemUsesDurability, ItemHasNegativeMovementSpeedModifier, ItemHasBlockPower, ItemHasNoParryPower, ItemHasParryPower, ItemHasArmor, ItemHasBackstabBonus, ItemUsesStaminaOnAttack`");
			stringBuilder.AppendLine("    * **ExclusiveEffectTypes:** This effect may not be rolled on an item that has already rolled on of these effects");
			stringBuilder.AppendLine("    * **AllowedItemTypes:** This effect may only be rolled on items of a the types in this list. When this list is empty, this is usually done because this is a special effect type added programmatically  or currently not allowed to roll. Options are: `" + string.Join(", ", AllowedMagicItemTypes) + "`");
			stringBuilder.AppendLine("    * **ExcludedItemTypes:** This effect may only be rolled on items that are not one of the types on this list.");
			stringBuilder.AppendLine("    * **AllowedRarities:** This effect may only be rolled on an item of one of these rarities. Options are: `" + string.Join(", ", list) + "`");
			stringBuilder.AppendLine("    * **ExcludedRarities:** This effect may only be rolled on an item that is not of one of these rarities.");
			stringBuilder.AppendLine("    * **AllowedSkillTypes:** This effect may only be rolled on an item that uses one of these skill types. Options are: `" + string.Join(", ", list2) + "`");
			stringBuilder.AppendLine("    * **ExcludedSkillTypes:** This effect may only be rolled on an item that does not use one of these skill types.");
			stringBuilder.AppendLine("    * **AllowedItemNames:** This effect may only be rolled on an item with one of these names. Use the unlocalized shared name, i.e.: `$item_sword_iron`");
			stringBuilder.AppendLine("    * **ExcludedItemNames:** This effect may only be rolled on an item that does not have one of these names.");
			stringBuilder.AppendLine("    * **CustomFlags:** A set of any arbitrary strings for future use");
			stringBuilder.AppendLine("  * **Value Per Rarity:** This effect may only be rolled on items of a rarity included in this table. The value is rolled using a linear distribution between Min and Max and divisible by the Increment.");
			stringBuilder.AppendLine();
			foreach (KeyValuePair<string, MagicItemEffectDefinition> allDefinition in MagicItemEffectDefinitions.AllDefinitions)
			{
				MagicItemEffectDefinition value = allDefinition.Value;
				stringBuilder.AppendLine("## " + value.Type);
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("> **Display Text:** " + Localization.instance.Localize(value.DisplayText));
				stringBuilder.AppendLine("> ");
				if (value.Prefixes.Count > 0)
				{
					stringBuilder.AppendLine("> **Prefixes:** " + Localization.instance.Localize(string.Join(", ", value.Prefixes)));
				}
				if (value.Suffixes.Count > 0)
				{
					stringBuilder.AppendLine("> **Suffixes:** " + Localization.instance.Localize(string.Join(", ", value.Suffixes)));
				}
				if (value.Prefixes.Count > 0 || value.Suffixes.Count > 0)
				{
					stringBuilder.AppendLine("> ");
				}
				List<string> allowedItemTypes = value.GetAllowedItemTypes();
				stringBuilder.AppendLine("> **Allowed Item Types:** " + ((allowedItemTypes.Count == 0) ? "*None*" : string.Join(", ", allowedItemTypes)));
				stringBuilder.AppendLine("> ");
				stringBuilder.AppendLine("> **Requirements:**");
				stringBuilder.Append(value.Requirements);
				if (value.HasRarityValues())
				{
					stringBuilder.AppendLine("> ");
					stringBuilder.AppendLine("> **Value Per Rarity:**");
					stringBuilder.AppendLine("> ");
					stringBuilder.AppendLine("> |Rarity|Min|Max|Increment|");
					stringBuilder.AppendLine("> |--|--|--|--|");
					if (value.ValuesPerRarity.Magic != null)
					{
						MagicItemEffectDefinition.ValueDef magic = value.ValuesPerRarity.Magic;
						stringBuilder.AppendLine($"> |Magic|{magic.MinValue}|{magic.MaxValue}|{magic.Increment}|");
					}
					if (value.ValuesPerRarity.Rare != null)
					{
						MagicItemEffectDefinition.ValueDef rare = value.ValuesPerRarity.Rare;
						stringBuilder.AppendLine($"> |Rare|{rare.MinValue}|{rare.MaxValue}|{rare.Increment}|");
					}
					if (value.ValuesPerRarity.Epic != null)
					{
						MagicItemEffectDefinition.ValueDef epic = value.ValuesPerRarity.Epic;
						stringBuilder.AppendLine($"> |Epic|{epic.MinValue}|{epic.MaxValue}|{epic.Increment}|");
					}
					if (value.ValuesPerRarity.Legendary != null)
					{
						MagicItemEffectDefinition.ValueDef legendary = value.ValuesPerRarity.Legendary;
						stringBuilder.AppendLine($"> |Legendary|{legendary.MinValue}|{legendary.MaxValue}|{legendary.Increment}|");
					}
				}
				if (!string.IsNullOrEmpty(value.Comment))
				{
					stringBuilder.AppendLine("> ");
					stringBuilder.AppendLine("> ***Notes:*** *" + value.Comment + "*");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.AppendLine("# Item Sets");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Sets of loot drop data that can be referenced in the loot tables");
			foreach (KeyValuePair<string, LootItemSet> itemSet in LootRoller.ItemSets)
			{
				LootItemSet value2 = itemSet.Value;
				stringBuilder.AppendLine("## " + itemSet.Key);
				stringBuilder.AppendLine();
				WriteLootList(stringBuilder, 0, value2.Loot);
				stringBuilder.AppendLine();
			}
			stringBuilder.AppendLine("# Loot Tables");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("A list of every built-in loot table from the mod. The name of the loot table is the object name followed by a number signifying the level of the object.");
			foreach (KeyValuePair<string, List<LootTable>> lootTable in LootRoller.LootTables)
			{
				foreach (LootTable item in lootTable.Value)
				{
					stringBuilder.AppendLine("## " + lootTable.Key);
					stringBuilder.AppendLine();
					WriteLootTableDrops(stringBuilder, item);
					WriteLootTableItems(stringBuilder, item);
					stringBuilder.AppendLine();
				}
			}
			File.WriteAllText(Path.Combine("C:\\Users\\rknapp\\Documents\\GitHub\\ValheimMods\\EpicLoot", "info.md"), stringBuilder.ToString());
		}

		private static void WriteLootTableDrops(StringBuilder t, LootTable lootTable)
		{
			int num = ((lootTable.LeveledLoot != null && lootTable.LeveledLoot.Count > 0) ? lootTable.LeveledLoot.Max((LeveledLootDef x) => x.Level) : 0);
			int num2 = Mathf.Max(3, num);
			for (int i = 0; i < num2; i++)
			{
				int num3 = i + 1;
				List<KeyValuePair<int, float>> dropsForLevel = LootRoller.GetDropsForLevel(lootTable, num3, useNextHighestIfNotPresent: false);
				if (dropsForLevel == null || dropsForLevel.Count == 0)
				{
					continue;
				}
				float num4 = dropsForLevel.Sum((KeyValuePair<int, float> x) => x.Value);
				if (num4 > 0f)
				{
					t.AppendLine($"> | Drops (lvl {num3}) | Weight (Chance) |");
					t.AppendLine("> | -- | -- |");
					foreach (KeyValuePair<int, float> item in dropsForLevel)
					{
						int key = item.Key;
						float value = item.Value;
						float num5 = value / num4 * 100f;
						t.AppendLine($"> | {key} | {value} ({num5:0.#}%) |");
					}
				}
				t.AppendLine();
			}
		}

		private static void WriteLootTableItems(StringBuilder t, LootTable lootTable)
		{
			int num = ((lootTable.LeveledLoot != null && lootTable.LeveledLoot.Count > 0) ? lootTable.LeveledLoot.Max((LeveledLootDef x) => x.Level) : 0);
			int num2 = Mathf.Max(3, num);
			for (int i = 0; i < num2; i++)
			{
				int level = i + 1;
				LootDrop[] lootForLevel = LootRoller.GetLootForLevel(lootTable, level, useNextHighestIfNotPresent: false);
				if (!ArrayUtils.IsNullOrEmpty(lootForLevel))
				{
					WriteLootList(t, level, lootForLevel);
				}
			}
		}

		private static void WriteLootList(StringBuilder t, int level, LootDrop[] lootList)
		{
			string text = ((level > 0) ? $" (lvl {level})" : "");
			t.AppendLine("> | Items" + text + " | Weight (Chance) | Magic | Rare | Epic | Legendary |");
			t.AppendLine("> | -- | -- | -- | -- | -- | -- |");
			float num = lootList.Sum((LootDrop x) => x.Weight);
			foreach (LootDrop lootDrop in lootList)
			{
				float num2 = lootDrop.Weight / num * 100f;
				if (lootDrop.Rarity == null || lootDrop.Rarity.Length == 0)
				{
					t.AppendLine($"> | {lootDrop.Item} | {lootDrop.Weight} ({num2:0.#}%) | 1 (100%) | 0 (0%) | 0 (0%) | 0 (0%) |");
					continue;
				}
				float num3 = lootDrop.Rarity.Sum();
				float[] array = new float[4]
				{
					lootDrop.Rarity[0] / num3 * 100f,
					lootDrop.Rarity[1] / num3 * 100f,
					lootDrop.Rarity[2] / num3 * 100f,
					lootDrop.Rarity[3] / num3 * 100f
				};
				t.AppendLine($"> | {lootDrop.Item} | {lootDrop.Weight} ({num2:0.#}%) " + $"| {lootDrop.Rarity[0]} ({array[0]:0.#}%) " + $"| {lootDrop.Rarity[1]} ({array[1]:0.#}%) " + $"| {lootDrop.Rarity[2]:0.#} ({array[2]:0.#}%) " + $"| {lootDrop.Rarity[3]} ({array[3]:0.#}%) |");
			}
			t.AppendLine();
		}

		private static string GetMagicEffectCountTableLine(ItemRarity rarity)
		{
			List<KeyValuePair<int, float>> effectCountsPerRarity = LootRoller.GetEffectCountsPerRarity(rarity, useEnchantingUpgrades: false);
			float num = effectCountsPerRarity.Sum((KeyValuePair<int, float> x) => x.Value);
			string text = $"|{rarity}|";
			for (int j = 1; j <= 6; j++)
			{
				string text2 = " ";
				int i1 = j;
				if (effectCountsPerRarity.TryFind((KeyValuePair<int, float> x) => x.Key == i1, out var result))
				{
					float value = result.Value;
					float num2 = value / num * 100f;
					text2 = $"{value} ({num2:0.#}%)";
				}
				text = text + text2 + "|";
			}
			return text;
		}

		public static string GetSetItemColor()
		{
			return _setItemColor.Value;
		}

		public static string GetRarityDisplayName(ItemRarity rarity)
		{
			return rarity switch
			{
				ItemRarity.Magic => "$mod_epicloot_magic", 
				ItemRarity.Rare => "$mod_epicloot_rare", 
				ItemRarity.Epic => "$mod_epicloot_epic", 
				ItemRarity.Legendary => "$mod_epicloot_legendary", 
				ItemRarity.Mythic => "$mod_epicloot_mythic", 
				_ => "<non magic>", 
			};
		}

		public static string GetRarityColor(ItemRarity rarity)
		{
			return rarity switch
			{
				ItemRarity.Magic => GetColor(_magicRarityColor.Value), 
				ItemRarity.Rare => GetColor(_rareRarityColor.Value), 
				ItemRarity.Epic => GetColor(_epicRarityColor.Value), 
				ItemRarity.Legendary => GetColor(_legendaryRarityColor.Value), 
				ItemRarity.Mythic => GetColor("Orange"), 
				_ => "#FFFFFF", 
			};
		}

		public static Color GetRarityColorARGB(ItemRarity rarity)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			if (!ColorUtility.TryParseHtmlString(GetRarityColor(rarity), ref result))
			{
				return Color.white;
			}
			return result;
		}

		private static string GetColor(string configValue)
		{
			if (configValue.StartsWith("#"))
			{
				return configValue;
			}
			if (MagicItemColors.TryGetValue(configValue, out var value))
			{
				return value;
			}
			return "#000000";
		}

		public static int GetRarityIconIndex(ItemRarity rarity)
		{
			return rarity switch
			{
				ItemRarity.Magic => Mathf.Clamp(_magicMaterialIconColor.Value, 0, 9), 
				ItemRarity.Rare => Mathf.Clamp(_rareMaterialIconColor.Value, 0, 9), 
				ItemRarity.Epic => Mathf.Clamp(_epicMaterialIconColor.Value, 0, 9), 
				ItemRarity.Legendary => Mathf.Clamp(_legendaryMaterialIconColor.Value, 0, 9), 
				ItemRarity.Mythic => 1, 
				_ => throw new ArgumentOutOfRangeException("rarity", rarity, null), 
			};
		}

		public static AudioClip GetMagicItemDropSFX(ItemRarity rarity)
		{
			return Assets.MagicItemDropSFX[(int)rarity];
		}

		public static GatedItemTypeMode GetGatedItemTypeMode()
		{
			return _gatedItemTypeModeConfig.Value;
		}

		public static BossDropMode GetBossTrophyDropMode()
		{
			return _bossTrophyDropMode.Value;
		}

		public static float GetBossTrophyDropPlayerRange()
		{
			return _bossTrophyDropPlayerRange.Value;
		}

		public static float GetBossCryptKeyPlayerRange()
		{
			return _bossCryptKeyDropPlayerRange.Value;
		}

		public static BossDropMode GetBossCryptKeyDropMode()
		{
			return _bossCryptKeyDropMode.Value;
		}

		public static BossDropMode GetBossWishboneDropMode()
		{
			return _bossWishboneDropMode.Value;
		}

		public static float GetBossWishboneDropPlayerRange()
		{
			return _bossWishboneDropPlayerRange.Value;
		}

		public static int GetAndvaranautRange()
		{
			return _andvaranautRange.Value;
		}

		public static bool IsAdventureModeEnabled()
		{
			return _adventureModeEnabled.Value;
		}

		private static void GenerateTranslations()
		{
			string text = LoadJsonText("magiceffects.json");
			MagicItemEffectsList magicItemEffectsList = JsonConvert.DeserializeObject<MagicItemEffectsList>(text);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (MagicItemEffectDefinition magicItemEffect in magicItemEffectsList.MagicItemEffects)
			{
				if (string.IsNullOrEmpty(magicItemEffect.Description))
				{
					magicItemEffect.Description = magicItemEffect.DisplayText.Replace("display", "desc");
					text = text.Replace("\"DisplayText\" : \"" + magicItemEffect.DisplayText + "\"", "\"DisplayText\" : \"" + magicItemEffect.DisplayText + "\",\n      \"Description\" : \"" + magicItemEffect.Description + "\"");
					dictionary.Add(magicItemEffect.Description, "");
				}
			}
			File.WriteAllText(GenerateAssetPathAtAssembly("magiceffects_translated.json"), text);
			string path = GenerateAssetPathAtAssembly("new_translations.json");
			string contents = "{\n" + string.Join("\n", dictionary.Select((KeyValuePair<string, string> x) => "  \"" + x.Key + "\": \"" + x.Value + "\",")) + "\n}";
			File.WriteAllText(path, contents);
		}

		private static string Clean(string name)
		{
			return name.Replace("'", "").Replace(",", "").Trim()
				.Replace(" ", "_")
				.ToLowerInvariant();
		}

		private static void ReplaceValueList(List<string> values, string field, string label, MagicItemEffectDefinition effectDef, Dictionary<string, string> translations, ref string magicEffectsJson)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < values.Count; i++)
			{
				string text = values[i];
				string text2;
				if (text.StartsWith("$"))
				{
					text2 = text;
				}
				else
				{
					text2 = GetId(effectDef, $"{field}{i + 1}");
					AddTranslation(translations, text2, text);
				}
				list.Add(text2);
			}
			if (list.Count > 0)
			{
				string original = "\"" + label + "\": [ " + string.Join(", ", values.Select((string x) => "\"" + x + "\"")) + " ]";
				string locId = "\"" + label + "\": [\n        " + string.Join(",\n        ", list.Select((string x) => (!x.StartsWith("$")) ? ("\"$" + x + "\"") : ("\"" + x + "\""))) + "\n      ]";
				magicEffectsJson = ReplaceTranslation(magicEffectsJson, original, locId);
			}
		}

		private static string GetId(MagicItemEffectDefinition effectDef, string field)
		{
			return "mod_epicloot_me_" + effectDef.Type.ToLowerInvariant() + "_" + field.ToLowerInvariant();
		}

		private static void AddTranslation(Dictionary<string, string> translations, string key, string value)
		{
			translations.Add(key, value);
		}

		private static string ReplaceTranslation(string jsonFile, string original, string locId)
		{
			return jsonFile.Replace(original, locId);
		}

		private static string SetupTranslation(MagicItemEffectDefinition effectDef, string value, string field, string replaceFormat, Dictionary<string, string> translations, string jsonFile)
		{
			if (string.IsNullOrEmpty(value) || value.StartsWith("$"))
			{
				return jsonFile;
			}
			string id = GetId(effectDef, field);
			AddTranslation(translations, id, value);
			return ReplaceTranslation(jsonFile, string.Format(replaceFormat, value), string.Format(replaceFormat, "$" + id));
		}

		public static float GetWorldLuckFactor()
		{
			return _instance._worldLuckFactor;
		}

		public static void SetWorldLuckFactor(float luckFactor)
		{
			_instance._worldLuckFactor = luckFactor;
		}
	}
	public static class EpicLootAuga
	{
		public static Button ReplaceButton(Button button, bool icon = false, bool keepListeners = false)
		{
			return ReplaceButtonInternal(API.MediumButton_Create(((Component)button).transform.parent, ((Object)button).name, string.Empty), button, icon, keepListeners);
		}

		public static Button ReplaceButtonFancy(Button button, bool icon = false, bool keepListeners = false)
		{
			return ReplaceButtonInternal(API.FancyButton_Create(((Component)button).transform.parent, ((Object)button).name, string.Empty), button, icon, keepListeners);
		}

		private static Button ReplaceButtonInternal(Button newButton, Button button, bool icon, bool keepListeners)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if (icon)
			{
				Object.Destroy((Object)(object)((Component)((Component)newButton).GetComponentInChildren<TMP_Text>()).gameObject);
				((Object)Object.Instantiate<Transform>(((Component)button).transform.Find("Icon"), ((Component)newButton).transform)).name = "Icon";
			}
			else
			{
				string text = ((Component)button).GetComponentInChildren<Text>().text;
				((Component)newButton).GetComponentInChildren<TMP_Text>().text = text;
			}
			RectTransform val = (RectTransform)((Component)button).transform;
			RectTransform val2 = (RectTransform)((Component)newButton).transform;
			val2.anchorMin = val.anchorMin;
			val2.anchorMax = val.anchorMax;
			val2.pivot = val.pivot;
			val2.anchoredPosition = val.anchoredPosition;
			Rect rect = val.rect;
			val2.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width);
			if (keepListeners)
			{
				newButton.onClick = button.onClick;
				button.onClick = new ButtonClickedEvent();
			}
			UIGamePad component = ((Component)button).GetComponent<UIGamePad>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_hint != (Object)null)
			{
				component.m_hint.transform.SetParent(((Component)newButton).transform);
				UIGamePad obj = ((Component)newButton).gameObject.AddComponent<UIGamePad>();
				obj.m_keyCode = component.m_keyCode;
				obj.m_zinputKey = component.m_zinputKey;
				obj.m_hint = component.m_hint;
				obj.m_blockingElements = component.m_blockingElements.ToList();
			}
			Object.DestroyImmediate((Object)(object)((Component)button).gameObject);
			return newButton;
		}

		public static void MakeSimpleTooltip(GameObject obj)
		{
			API.Tooltip_MakeSimpleTooltip(obj);
		}

		public static void ReplaceBackground(GameObject obj, bool withCornerDecoration)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Object.Destroy((Object)(object)obj.GetComponent<Image>());
			RectTransform val = (RectTransform)API.Panel_Create(obj.transform, Vector2.one, "AugaBackground", withCornerDecoration).transform;
			((Transform)val).SetSiblingIndex(0);
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			val.pivot = new Vector2(0.5f, 0.5f);
			val.sizeDelta = new Vector2(40f, 40f);
		}

		public static void FixItemBG(GameObject obj)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			Transform val = obj.transform.Find("MagicBG");
			if ((Object)(object)val != (Object)null)
			{
				Image component = ((Component)val).GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					component.sprite = EpicLootBase.GetMagicItemBgSprite();
				}
			}
			bool flag = false;
			Transform val2 = obj.transform.Find("ItemBG");
			Image val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Image>() : null);
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = obj.GetComponent<Image>();
			}
			if ((Object)(object)val3 != (Object)null)
			{
				val3.sprite = API.GetItemBackgroundSprite();
				((Graphic)val3).color = new Color(0f, 0f, 0f, 0.5f);
				flag = true;
			}
			if (!flag)
			{
				Transform val4 = obj.transform.Find("Icon");
				if ((Object)(object)val4 != (Object)null)
				{
					Transform obj2 = Object.Instantiate<Transform>(val4, val4.parent);
					obj2.SetSiblingIndex(2);
					Image component2 = ((Component)obj2).GetComponent<Image>();
					component2.sprite = API.GetItemBackgroundSprite();
					((Graphic)component2).color = new Color(0f, 0f, 0f, 0.5f);
				}
			}
		}

		public static void FixListElementColors(GameObject obj)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Transform val = obj.transform.Find("Selected");
			if ((Object)(object)val != (Object)null)
			{
				Image component = ((Component)val).GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					Color color = default(Color);
					ColorUtility.TryParseHtmlString(API.Blue, ref color);
					((Graphic)component).color = color;
				}
			}
			Transform val2 = obj.transform.Find("Background");
			if ((Object)(object)val2 != (Object)null)
			{
				Image component2 = ((Component)val2).GetComponent<Image>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Graphic)component2).color = new Color(0f, 0f, 0f, 0.5f);
				}
			}
			Button component3 = obj.GetComponent<Button>();
			if ((Object)(object)component3 != (Object)null)
			{
				((Selectable)component3).colors = ColorBlock.defaultColorBlock;
			}
		}

		public static void FixFonts(GameObject obj)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text[] componentsInChildren = obj.GetComponentsInChildren<TMP_Text>(true);
			Color color = default(Color);
			Color color2 = default(Color);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (((Object)val.font).name == "Norsebold")
				{
					ColorUtility.TryParseHtmlString(API.Brown1, ref color);
					((Graphic)val).color = color;
					val.text = Localization.instance.Localize(val.text).ToUpperInvariant();
				}
				if (((Object)val).name == "Count" || ((Object)val).name == "RewardLabel" || ((Object)val).name.EndsWith("Count"))
				{
					ColorUtility.TryParseHtmlString(API.BrightGold, ref color2);
					((Graphic)val).color = color2;
				}
				val.text = val.text.Replace("<color=yellow>", "<color=" + API.BrightGold + ">");
			}
		}

		public static Button ReplaceVerticalLargeTab(Button button)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0049: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or

EpicLoot/Newtonsoft.Json.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("13.0.3.27908")]
[assembly: AssemblyInformationalVersion("13.0.3+0a2e291c0d9c0c7675d445703e51750363a549ef")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET .NET 4.5")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	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 System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	public class DefaultJsonNameTable : JsonNameTable
	{
		private class Entry
		{
			internal readonly string Value;

			internal readonly int HashCode;

			internal Entry Next;

			internal Entry(string value, int hashCode, Entry next)
			{
				Value = value;
				HashCode = hashCode;
				Next = next;
			}
		}

		private static readonly int HashCodeRandomizer;

		private int _count;

		private Entry[] _entries;

		private int _mask = 31;

		static DefaultJsonNameTable()
		{
			HashCodeRandomizer = Environment.TickCount;
		}

		public DefaultJsonNameTable()
		{
			_entries = new Entry[_mask + 1];
		}

		public override string? Get(char[] key, int start, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			num += (num << 7) ^ key[start];
			int num2 = start + length;
			for (int i = start + 1; i < num2; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			int num3 = Volatile.Read(ref _mask);
			int num4 = num & num3;
			for (Entry entry = _entries[num4]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
				{
					return entry.Value;
				}
			}
			return null;
		}

		public string Add(string key)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			int length = key.Length;
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			for (int i = 0; i < key.Length; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
				{
					return entry.Value;
				}
			}
			return AddEntry(key, num);
		}

		private string AddEntry(string str, int hashCode)
		{
			int num = hashCode & _mask;
			Entry entry = new Entry(str, hashCode, _entries[num]);
			_entries[num] = entry;
			if (_count++ == _mask)
			{
				Grow();
			}
			return entry.Value;
		}

		private void Grow()
		{
			Entry[] entries = _entries;
			int num = _mask * 2 + 1;
			Entry[] array = new Entry[num + 1];
			for (int i = 0; i < entries.Length; i++)
			{
				Entry entry = entries[i];
				while (entry != null)
				{
					int num2 = entry.HashCode & num;
					Entry next = entry.Next;
					entry.Next = array[num2];
					array[num2] = entry;
					entry = next;
				}
			}
			_entries = array;
			Volatile.Write(ref _mask, num);
		}

		private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
		{
			if (str1.Length != str2Length)
			{
				return false;
			}
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i] != str2[str2Start + i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[]? array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type? _namingStrategyType;

		private object[]? _namingStrategyParameters;

		public string? Id { get; set; }

		public string? Title { get; set; }

		public string? Description { get; set; }

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[]? NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy? NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		private static string ToStringInternal(BigInteger value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				if (nullable)
				{
					return Null;
				}
				return "0.0";
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (StringUtils.IndexOf(text, '.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string? value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string? value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value)
		{
			return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
		{
			StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		[DebuggerStepThrough]
		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (settings == null || !settings.CheckAdditionalContent)
			{
				return;
			}
			while (jsonReader.Read())
			{
				if (jsonReader.TokenType != JsonToken.Comment)
				{
					throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
				}
			}
		}

		public static string SerializeXmlNode(XmlNode? node)
		{
			return SerializeXmlNode(node, Formatting.None);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XmlDocument? DeserializeXmlNode(string value)
		{
			return DeserializeXmlNode(value, null);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
		}

		public static string SerializeXNode(XObject? node)
		{
			return SerializeXNode(node, Formatting.None);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting)
		{
			return SerializeXNode(node, formatting, omitRootObject: false);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XDocument? DeserializeXNode(string value)
		{
			return DeserializeXNode(value, null);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);

		public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	public abstract class JsonConverter<T> : JsonConverter
	{
		public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
			{
				throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			WriteJson(writer, (T)value, serializer);
		}

		public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);

		public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			bool flag = existingValue == null;
			if (!flag && !(existingValue is T))
			{
				throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
		}

		public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);

		public sealed override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[]? ConverterParameters { get; }

		public JsonConverterAttribute(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception? innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	public abstract class JsonNameTable
	{
		public abstract string? Get(char[] key, int start, int length);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal MissingMemberHandling? _missingMemberHandling;

		internal Required? _itemRequired;

		internal NullValueHandling? _itemNullValueHandling;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling.GetValueOrDefault();
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired.GetValueOrDefault();
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[18]
		{
			'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
			'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
		};

		internal JsonContainerType Type;

		internal int Position;

		internal string? PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					if (writer == null)
					{
						writer = new StringWriter(sb);
					}
					JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
					sb.Append("']");
				}
				else
				{
					if (sb.Length > 0)
					{
						sb.Append('.');
					}
					sb.Append(propertyName);
				}
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			if (type != JsonContainerType.Array)
			{
				return type == JsonContainerType.Constructor;
			}
			return true;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			StringWriter writer = null;
			char[] buffer = null;
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder, ref writer, ref buffer);
				}
			}
			currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType { get; set; }

		public object[]? NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling.GetValueOrDefault();
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order.GetValueOrDefault();
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required.GetValueOrDefault();
			}
			set
			{
				_required = value;
			}
		}

		public string? PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object? _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo? _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string? _dateFormatString;

		private List<JsonPosition>? _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string? DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object? Value => _value;

		public virtual Type? ValueType => _value?.GetType();

		public virtual int Depth
		{
			get
			{
				int num = _stack?.Count ?? 0;
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
		}

		public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TokenType == JsonToken.PropertyName)
			{
				await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
				{
				}
			}
		}

		internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
		{
			if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
			{
				throw CreateUnexpectedEndException();
			}
		}

		public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
		}

		public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
		}

		internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
		{
			List<byte> buffer = new List<byte>();
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(buffer));
			byte[] array = buffer.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
		}

		public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
		}

		public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
		}

		public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return Task.FromResult(ReadAsDouble());
		}

		public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
		}

		public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
		}

		internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
		{
			bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (flag)
			{
				flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			return flag;
		}

		internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType = TokenType;
			if (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				return MoveToContentFromNonContentAsync(cancellationToken);
			}
			return AsyncUtils.True;
		}

		private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType;
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					return false;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment);
			return true;
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			_maxDepth = 64;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
			{
				return;
			}
			_hasExceededMaxDepth = true;
			throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is int)
				{
					return (int)value;
				}
				int num;
				if (value is BigInteger bigInteger)
				{
					num = (int)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Integer, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string? ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken))
				{
					object value = Value;
					if (value != null)
					{
						string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
						SetToken(JsonToken.String, text, updateIndex: false);
						return text;
					}
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[]? ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.StartObject:
			{
				ReadIntoWrappedTypeObject();
				byte[] array2 = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array2, updateIndex: false);
				return array2;
			}
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if (Value is Guid guid)
				{
					byte[] array = guid.ToByteArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(list));
			byte[] array = list.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
		{
			switch (TokenType)
			{
			case JsonToken.None:
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			case JsonToken.Integer:
				buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
				return false;
			case JsonToken.EndArray:
				return true;
			case JsonToken.Comment:
				return false;
			default:
				throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is double)
				{
					return (double)value;
				}
				double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is decimal)
				{
					return (decimal)value;
				}
				decimal num;
				if (value is BigInteger bigInteger)
				{
					num = (decimal)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset dateTimeOffset)
				{
					SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
				return ReadDateTimeString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime dateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value != null && Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
		{
			if (!ReadForType(contract, hasConverter))
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadForType(JsonContract? contract, bool hasConverter)
		{
			if (hasConverter)
			{
				return Read();
			}
			switch (contract?.InternalReadType ?? ReadType.Read)
			{
			case ReadType.Read:
				return ReadAndMoveToContent();
			case ReadType.ReadAsInt32:
				ReadAsInt32();
				break;
			case ReadType.ReadAsInt64:
			{
				bool result = ReadAndMoveToContent();
				if (TokenType == JsonToken.Undefined)
				{
					throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
				}
				return result;
			}
			case ReadType.ReadAsDecimal:
				ReadAsDecimal();
				break;
			case ReadType.ReadAsDouble:
				ReadAsDouble();
				break;
			case ReadType.ReadAsBytes:
				ReadAsBytes();
				break;
			case ReadType.ReadAsBoolean:
				ReadAsBoolean();
				break;
			case ReadType.ReadAsString:
				ReadAsString();
				break;
			case ReadType.ReadAsDateTime:
				ReadAsDateTime();
				break;
			case ReadType.ReadAsDateTimeOffset:
				ReadAsDateTimeOffset();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return TokenType != JsonToken.None;
		}

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, path, lineNumber, linePosition, ex);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection? _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter? _traceWriter;

		internal IEqualityComparer? _equalityComparer;

		internal ISerializationBinder _serializationBinder;

		internal StreamingContext _context;

		private IReferenceResolver? _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string? _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver? ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public virtual SerializationBinder Binder
		{
			get
			{
				if (_serializationBinder is SerializationBinder result)
				{
					return result;
				}
				if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
			}
		}

		public virtual ISerializationBinder SerializationBinder
		{
			get
			{
				return _serializationBinder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = value;
			}
		}

		public virtual ITraceWriter? TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer? EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting.GetValueOrDefault();
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling.GetValueOrDefault();
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling.GetValueOrDefault();
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling.GetValueOrDefault();
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling.GetValueOrDefault();
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent.GetValueOrDefault();
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_serializationBinder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormatHandling.HasValue)
			{
				serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.SerializationBinder != null)
			{
				serializer.SerializationBinder = settings.SerializationBinder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		[DebuggerStepThrough]
		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		[DebuggerStepThrough]
		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		[DebuggerStepThrough]
		public object? Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		[DebuggerStepThrough]
		public T? Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader, Type? objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable();
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable())
			{
				jsonTextReader.PropertyNameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object? value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object? value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object? value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		private TraceJsonReader CreateTraceJsonReader(JsonReader reader)
		{
			TraceJsonReader traceJsonReader = new TraceJsonReader(reader);
			if (reader.TokenType != 0)
			{
				traceJsonReader.WriteCurrentToken();
			}
			return traceJsonReader;
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter? GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType)
		{
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal const int DefaultMaxDepth = 64;

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo? _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string? _dateFormatString;

		internal bool _dateFormatStringSet;

		internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling.GetValueOrDef

EpicLoot/ServerSync.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ServerSync")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServerSync")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E16C3332-50B4-4DA6-9E8A-A590C4E5CD49")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServerSync
{
	[PublicAPI]
	public abstract class OwnConfigEntryBase
	{
		public object? LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	public class SyncedConfigEntry<T> : OwnConfigEntryBase
	{
		public readonly ConfigEntry<T> SourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

		public T Value
		{
			get
			{
				return SourceConfig.Value;
			}
			set
			{
				SourceConfig.Value = value;
			}
		}

		public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
		{
			SourceConfig = sourceConfig;
		}

		public void AssignLocalValue(T value)
		{
			if (LocalBaseValue == null)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	public abstract class CustomSyncedValueBase
	{
		public object? LocalBaseValue;

		public readonly string Identifier;

		public readonly Type Type;

		private object? boxedValue;

		protected bool localIsOwner;

		public readonly int Priority;

		public object? BoxedValue
		{
			get
			{
				return boxedValue;
			}
			set
			{
				boxedValue = value;
				this.ValueChanged?.Invoke();
			}
		}

		public event Action? ValueChanged;

		protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
		{
			Priority = priority;
			Identifier = identifier;
			Type = type;
			configSync.AddCustomValue(this);
			localIsOwner = configSync.IsSourceOfTruth;
			configSync.SourceOfTruthChanged += delegate(bool truth)
			{
				localIsOwner = truth;
			};
		}
	}
	[PublicAPI]
	public sealed class CustomSyncedValue<T> : CustomSyncedValueBase
	{
		public T Value
		{
			get
			{
				return (T)base.BoxedValue;
			}
			set
			{
				base.BoxedValue = value;
			}
		}

		public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
			: base(configSync, identifier, typeof(T), priority)
		{
			Value = value;
		}

		public void AssignLocalValue(T value)
		{
			if (localIsOwner)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ReadOnly = false;
	}
	[PublicAPI]
	public class ConfigSync
	{
		[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
		private static class SnatchCurrentlyHandlingRPC
		{
			public static ZRpc? currentRpc;

			[HarmonyPrefix]
			private static void Prefix(ZRpc __instance)
			{
				currentRpc = __instance;
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		internal static class RegisterRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				foreach (ConfigSync configSync2 in configSyncs)
				{
					ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
					if (isServer)
					{
						configSync2.InitialSyncDone = true;
						Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
					}
				}
				if (isServer)
				{
					((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
				}
				static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
				{
					ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
					{
						new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = isAdmin
						}
					});
					ConfigSync configSync = configSyncs.First();
					if (configSync != null)
					{
						((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
					}
				}
				static IEnumerator WatchAdminListChanges()
				{
					MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
					SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					List<string> CurrentList = new List<string>(adminList.GetList());
					while (true)
					{
						yield return (object)new WaitForSeconds(30f);
						if (!adminList.GetList().SequenceEqual(CurrentList))
						{
							CurrentList = new List<string>(adminList.GetList());
							List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
							{
								string hostName = p.m_rpc.GetSocket().GetHostName();
								return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName }));
							}).ToList();
							List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
							SendAdmin(nonAdminPeer, isAdmin: false);
							SendAdmin(adminPeer, isAdmin: true);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class RegisterClientRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					return;
				}
				foreach (ConfigSync configSync in configSyncs)
				{
					peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
				}
			}
		}

		private class ParsedConfigs
		{
			public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();

			public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ResetConfigsOnShutdown
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ProcessingServerUpdate = true;
				foreach (ConfigSync configSync in configSyncs)
				{
					configSync.resetConfigsFromServer();
					configSync.IsSourceOfTruth = true;
					configSync.InitialSyncDone = false;
				}
				ProcessingServerUpdate = false;
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private class SendConfigsAfterLogin
		{
			private class BufferingSocket : ISocket
			{
				public volatile bool finished = false;

				public volatile int versionMatchQueued = -1;

				public readonly List<ZPackage> Package = new List<ZPackage>();

				public readonly ISocket Original;

				public BufferingSocket(ISocket original)
				{
					Original = original;
				}

				public bool IsConnected()
				{
					return Original.IsConnected();
				}

				public ZPackage Recv()
				{
					return Original.Recv();
				}

				public int GetSendQueueSize()
				{
					return Original.GetSendQueueSize();
				}

				public int GetCurrentSendRate()
				{
					return Original.GetCurrentSendRate();
				}

				public bool IsHost()
				{
					return Original.IsHost();
				}

				public void Dispose()
				{
					Original.Dispose();
				}

				public bool GotNewData()
				{
					return Original.GotNewData();
				}

				public void Close()
				{
					Original.Close();
				}

				public string GetEndPointString()
				{
					return Original.GetEndPointString();
				}

				public void GetAndResetStats(out int totalSent, out int totalRecv)
				{
					Original.GetAndResetStats(ref totalSent, ref totalRecv);
				}

				public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
				{
					Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
				}

				public ISocket Accept()
				{
					return Original.Accept();
				}

				public int GetHostPort()
				{
					return Original.GetHostPort();
				}

				public bool Flush()
				{
					return Original.Flush();
				}

				public string GetHostName()
				{
					return Original.GetHostName();
				}

				public void VersionMatch()
				{
					if (finished)
					{
						Original.VersionMatch();
					}
					else
					{
						versionMatchQueued = Package.Count;
					}
				}

				public void Send(ZPackage pkg)
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Expected O, but got Unknown
					int pos = pkg.GetPos();
					pkg.SetPos(0);
					int num = pkg.ReadInt();
					if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
					{
						ZPackage val = new ZPackage(pkg.GetArray());
						val.SetPos(pos);
						Package.Add(val);
					}
					else
					{
						pkg.SetPos(pos);
						Original.Send(pkg);
					}
				}
			}

			[HarmonyPriority(800)]
			[HarmonyPrefix]
			private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Invalid comparison between Unknown and I4
				if (__instance.IsServer())
				{
					BufferingSocket value = new BufferingSocket(rpc.GetSocket());
					AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value);
					object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
					ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (val != null && (int)ZNet.m_onlineBackend > 0)
					{
						AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value);
					}
					if (__state == null)
					{
						__state = new Dictionary<Assembly, BufferingSocket>();
					}
					__state[Assembly.GetExecutingAssembly()] = value;
				}
			}

			[HarmonyPostfix]
			private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
			{
				ZRpc rpc2 = rpc;
				ZNet __instance2 = __instance;
				Dictionary<Assembly, BufferingSocket> __state2 = __state;
				ZNetPeer peer;
				if (__instance2.IsServer())
				{
					object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
					peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (peer == null)
					{
						SendBufferedData();
					}
					else
					{
						((MonoBehaviour)__instance2).StartCoroutine(sendAsync());
					}
				}
				void SendBufferedData()
				{
					if (rpc2.GetSocket() is BufferingSocket bufferingSocket)
					{
						AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original);
						object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
						ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
						if (val != null)
						{
							AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
						}
					}
					BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()];
					bufferingSocket2.finished = true;
					for (int i = 0; i < bufferingSocket2.Package.Count; i++)
					{
						if (i == bufferingSocket2.versionMatchQueued)
						{
							bufferingSocket2.Original.VersionMatch();
						}
						bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
					}
					if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
					{
						bufferingSocket2.Original.VersionMatch();
					}
				}
				IEnumerator sendAsync()
				{
					foreach (ConfigSync configSync in configSyncs)
					{
						List<PackageEntry> entries = new List<PackageEntry>();
						if (configSync.CurrentVersion != null)
						{
							entries.Add(new PackageEntry
							{
								section = "Internal",
								key = "serverversion",
								type = typeof(string),
								value = configSync.CurrentVersion
							});
						}
						MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						entries.Add(new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2]
							{
								adminList,
								rpc2.GetSocket().GetHostName()
							}))
						});
						ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false);
						yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package));
					}
					SendBufferedData();
				}
			}
		}

		private class PackageEntry
		{
			public string section = null;

			public string key = null;

			public Type type = null;

			public object? value;
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
		private static class PreventSavingServerInfo
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, ref string __result)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase))
				{
					return true;
				}
				__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
				return false;
			}
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
		private static class PreventConfigRereadChangingValues
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, string value)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null)
				{
					return true;
				}
				try
				{
					ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
				}
				return false;
			}
		}

		private class InvalidDeserializationTypeException : Exception
		{
			public string expected = null;

			public string received = null;

			public string field = "";
		}

		public static bool ProcessingServerUpdate;

		public readonly string Name;

		public string? DisplayName;

		public string? CurrentVersion;

		public string? MinimumRequiredVersion;

		public bool ModRequired = false;

		private bool? forceConfigLocking;

		private bool isSourceOfTruth = true;

		private static readonly HashSet<ConfigSync> configSyncs;

		private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();

		private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();

		private static bool isServer;

		private static bool lockExempt;

		private OwnConfigEntryBase? lockedConfig = null;

		private const byte PARTIAL_CONFIGS = 1;

		private const byte FRAGMENTED_CONFIG = 2;

		private const byte COMPRESSED_CONFIG = 4;

		private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();

		private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();

		private static long packageCounter;

		public bool IsLocked
		{
			get
			{
				bool? flag = forceConfigLocking;
				bool num;
				if (!flag.HasValue)
				{
					if (lockedConfig == null)
					{
						goto IL_0052;
					}
					num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0;
				}
				else
				{
					num = flag.GetValueOrDefault();
				}
				if (!num)
				{
					goto IL_0052;
				}
				int result = ((!lockExempt) ? 1 : 0);
				goto IL_0053;
				IL_0053:
				return (byte)result != 0;
				IL_0052:
				result = 0;
				goto IL_0053;
			}
			set
			{
				forceConfigLocking = value;
			}
		}

		public bool IsAdmin => lockExempt || isSourceOfTruth;

		public bool IsSourceOfTruth
		{
			get
			{
				return isSourceOfTruth;
			}
			private set
			{
				if (value != isSourceOfTruth)
				{
					isSourceOfTruth = value;
					this.SourceOfTruthChanged?.Invoke(value);
				}
			}
		}

		public bool InitialSyncDone { get; private set; } = false;


		public event Action<bool>? SourceOfTruthChanged;

		private event Action? lockedConfigChanged;

		static ConfigSync()
		{
			ProcessingServerUpdate = false;
			configSyncs = new HashSet<ConfigSync>();
			lockExempt = false;
			packageCounter = 0L;
			RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle);
		}

		public ConfigSync(string name)
		{
			Name = name;
			configSyncs.Add(this);
			new VersionCheck(this);
		}

		public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			ConfigEntry<T> configEntry2 = configEntry;
			OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2);
			SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>;
			if (syncedEntry == null)
			{
				syncedEntry = new SyncedConfigEntry<T>(configEntry2);
				AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1]
				{
					new ConfigurationManagerAttributes()
				}.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray());
				configEntry2.SettingChanged += delegate
				{
					if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig)
					{
						Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2);
					}
				};
				allConfigs.Add(syncedEntry);
			}
			return syncedEntry;
		}

		public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible
		{
			if (lockedConfig != null)
			{
				throw new Exception("Cannot initialize locking ConfigEntry twice");
			}
			lockedConfig = AddConfigEntry<T>(lockingConfig);
			lockingConfig.SettingChanged += delegate
			{
				this.lockedConfigChanged?.Invoke();
			};
			return (SyncedConfigEntry<T>)lockedConfig;
		}

		internal void AddCustomValue(CustomSyncedValueBase customValue)
		{
			CustomSyncedValueBase customValue2 = customValue;
			if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue2.Identifier))
			{
				throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)");
			}
			allCustomValues.Add(customValue2);
			allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority));
			customValue2.ValueChanged += delegate
			{
				if (!ProcessingServerUpdate)
				{
					Broadcast(ZRoutedRpc.Everybody, customValue2);
				}
			};
		}

		private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package)
		{
			lockedConfigChanged += serverLockedSettingChanged;
			IsSourceOfTruth = false;
			if (HandleConfigSyncRPC(0L, package, clientUpdate: false))
			{
				InitialSyncDone = true;
			}
		}

		private void RPC_FromOtherClientConfigSync(long sender, ZPackage package)
		{
			HandleConfigSyncRPC(sender, package, clientUpdate: true);
		}

		private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			try
			{
				if (isServer && IsLocked)
				{
					ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc;
					object obj;
					if (currentRpc == null)
					{
						obj = null;
					}
					else
					{
						ISocket socket = currentRpc.GetSocket();
						obj = ((socket != null) ? socket.GetHostName() : null);
					}
					string text = (string)obj;
					if (text != null)
					{
						MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text }))))
						{
							return false;
						}
					}
				}
				cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv)
				{
					if (kv.Key < DateTimeOffset.Now.Ticks)
					{
						configValueCache.Remove(kv.Value);
						return true;
					}
					return false;
				});
				byte b = package.ReadByte();
				if ((b & 2u) != 0)
				{
					long num = package.ReadLong();
					string text2 = sender.ToString() + num;
					if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value))
					{
						value = new SortedDictionary<int, byte[]>();
						configValueCache[text2] = value;
						cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2));
					}
					int key = package.ReadInt();
					int num2 = package.ReadInt();
					value.Add(key, package.ReadByteArray());
					if (value.Count < num2)
					{
						return false;
					}
					configValueCache.Remove(text2);
					package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray());
					b = package.ReadByte();
				}
				ProcessingServerUpdate = true;
				if ((b & 4u) != 0)
				{
					byte[] buffer = package.ReadByteArray();
					MemoryStream stream = new MemoryStream(buffer);
					MemoryStream memoryStream = new MemoryStream();
					using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
					{
						deflateStream.CopyTo(memoryStream);
					}
					package = new ZPackage(memoryStream.ToArray());
					b = package.ReadByte();
				}
				if ((b & 1) == 0)
				{
					resetConfigsFromServer();
				}
				ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package);
				ConfigFile val2 = null;
				bool saveOnConfigSet = false;
				foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues)
				{
					if (!isServer && configValue.Key.LocalBaseValue == null)
					{
						configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue;
					}
					if (val2 == null)
					{
						val2 = configValue.Key.BaseConfig.ConfigFile;
						saveOnConfigSet = val2.SaveOnConfigSet;
						val2.SaveOnConfigSet = false;
					}
					configValue.Key.BaseConfig.BoxedValue = configValue.Value;
				}
				if (val2 != null)
				{
					val2.SaveOnConfigSet = saveOnConfigSet;
				}
				foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues)
				{
					if (!isServer)
					{
						CustomSyncedValueBase key2 = customValue.Key;
						if (key2.LocalBaseValue == null)
						{
							key2.LocalBaseValue = customValue.Key.BoxedValue;
						}
					}
					customValue.Key.BoxedValue = customValue.Value;
				}
				Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name));
				if (!isServer)
				{
					serverLockedSettingChanged();
				}
				return true;
			}
			finally
			{
				ProcessingServerUpdate = false;
			}
		}

		private ParsedConfigs ReadConfigsFromPackage(ZPackage package)
		{
			ParsedConfigs parsedConfigs = new ParsedConfigs();
			Dictionary<string, OwnConfigEntryBase> dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c);
			Dictionary<string, CustomSyncedValueBase> dictionary2 = allCustomValues.ToDictionary((CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c);
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				string text = package.ReadString();
				string text2 = package.ReadString();
				string text3 = package.ReadString();
				Type type = Type.GetType(text3);
				if (text3 == "" || type != null)
				{
					object obj;
					try
					{
						obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type));
					}
					catch (InvalidDeserializationTypeException ex)
					{
						Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected));
						continue;
					}
					OwnConfigEntryBase value2;
					if (text == "Internal")
					{
						CustomSyncedValueBase value;
						if (text2 == "serverversion")
						{
							if (obj?.ToString() != CurrentVersion)
							{
								Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown")));
							}
						}
						else if (text2 == "lockexempt")
						{
							if (obj is bool flag)
							{
								lockExempt = flag;
							}
						}
						else if (dictionary2.TryGetValue(text2, out value))
						{
							if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3)
							{
								parsedConfigs.customValues[value] = obj;
								continue;
							}
							Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName));
						}
					}
					else if (dictionary.TryGetValue(text + "_" + text2, out value2))
					{
						Type type2 = configType(value2.BaseConfig);
						if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3)
						{
							parsedConfigs.configValues[value2] = obj;
							continue;
						}
						Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName));
					}
					else
					{
						Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match."));
					}
					continue;
				}
				Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs"));
				return new ParsedConfigs();
			}
			return parsedConfigs;
		}

		private static bool isWritableConfig(OwnConfigEntryBase config)
		{
			OwnConfigEntryBase config2 = config;
			ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2));
			if (configSync == null)
			{
				return true;
			}
			return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt));
		}

		private void serverLockedSettingChanged()
		{
			foreach (OwnConfigEntryBase allConfig in allConfigs)
			{
				configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig);
			}
		}

		private void resetConfigsFromServer()
		{
			ConfigFile val = null;
			bool saveOnConfigSet = false;
			foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null))
			{
				if (val == null)
				{
					val = item.BaseConfig.ConfigFile;
					saveOnConfigSet = val.SaveOnConfigSet;
					val.SaveOnConfigSet = false;
				}
				item.BaseConfig.BoxedValue = item.LocalBaseValue;
				item.LocalBaseValue = null;
			}
			if (val != null)
			{
				val.SaveOnConfigSet = saveOnConfigSet;
			}
			foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null))
			{
				item2.BoxedValue = item2.LocalBaseValue;
				item2.LocalBaseValue = null;
			}
			lockedConfigChanged -= serverLockedSettingChanged;
			serverLockedSettingChanged();
		}

		private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package)
		{
			ZNetPeer peer2 = peer;
			ZRoutedRpc rpc = ZRoutedRpc.instance;
			if (rpc == null)
			{
				yield break;
			}
			byte[] data = package.GetArray();
			if (data != null && data.LongLength > 250000)
			{
				int fragments = (int)(1 + (data.LongLength - 1) / 250000);
				long packageIdentifier = ++packageCounter;
				int fragment = 0;
				while (fragment < fragments)
				{
					foreach (bool item in waitForQueue())
					{
						yield return item;
					}
					if (peer2.m_socket.IsConnected())
					{
						ZPackage fragmentedPackage = new ZPackage();
						fragmentedPackage.Write((byte)2);
						fragmentedPackage.Write(packageIdentifier);
						fragmentedPackage.Write(fragment);
						fragmentedPackage.Write(fragments);
						fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray());
						SendPackage(fragmentedPackage);
						if (fragment != fragments - 1)
						{
							yield return true;
						}
						int num = fragment + 1;
						fragment = num;
						continue;
					}
					break;
				}
				yield break;
			}
			foreach (bool item2 in waitForQueue())
			{
				yield return item2;
			}
			SendPackage(package);
			void SendPackage(ZPackage pkg)
			{
				string text = Name + " ConfigSync";
				if (isServer)
				{
					peer2.m_rpc.Invoke(text, new object[1] { pkg });
				}
				else
				{
					rpc.InvokeRoutedRPC(peer2.m_server ? 0 : peer2.m_uid, text, new object[1] { pkg });
				}
			}
			IEnumerable<bool> waitForQueue()
			{
				float timeout = Time.time + 30f;
				while (peer2.m_socket.GetSendQueueSize() > 20000)
				{
					if (Time.time > timeout)
					{
						Debug.Log((object)$"Disconnecting {peer2.m_uid} after 30 seconds config sending timeout");
						peer2.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 });
						ZNet.instance.Disconnect(peer2);
						break;
					}
					yield return false;
				}
			}
		}

		private IEnumerator sendZPackage(long target, ZPackage package)
		{
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return Enumerable.Empty<object>().GetEnumerator();
			}
			List<ZNetPeer> list = (List<ZNetPeer>)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance);
			if (target != ZRoutedRpc.Everybody)
			{
				list = list.Where((ZNetPeer p) => p.m_uid == target).ToList();
			}
			return sendZPackage(list, package);
		}

		private IEnumerator sendZPackage(List<ZNetPeer> peers, ZPackage package)
		{
			ZPackage package2 = package;
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				yield break;
			}
			byte[] rawData = package2.GetArray();
			if (rawData != null && rawData.LongLength > 10000)
			{
				ZPackage compressedPackage = new ZPackage();
				compressedPackage.Write((byte)4);
				MemoryStream output = new MemoryStream();
				using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal))
				{
					deflateStream.Write(rawData, 0, rawData.Length);
				}
				compressedPackage.Write(output.ToArray());
				package2 = compressedPackage;
			}
			List<IEnumerator<bool>> writers = (from peer in peers
				where peer.IsReady()
				select peer into p
				select distributeConfigToPeers(p, package2)).ToList();
			writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
			while (writers.Count > 0)
			{
				yield return null;
				writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
			}
		}

		private void Broadcast(long target, params ConfigEntryBase[] configs)
		{
			if (!IsLocked || isServer)
			{
				ZPackage package = ConfigsToPackage(configs);
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
				}
			}
		}

		private void Broadcast(long target, params CustomSyncedValueBase[] customValues)
		{
			if (!IsLocked || isServer)
			{
				ZPackage package = ConfigsToPackage(null, customValues);
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
				}
			}
		}

		private static OwnConfigEntryBase? configData(ConfigEntryBase config)
		{
			return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault();
		}

		public static SyncedConfigEntry<T>? ConfigData<T>(ConfigEntry<T> config)
		{
			return ((ConfigEntryBase)config).Description.Tags?.OfType<SyncedConfigEntry<T>>().SingleOrDefault();
		}

		private static T configAttribute<T>(ConfigEntryBase config)
		{
			return config.Description.Tags.OfType<T>().First();
		}

		private static Type configType(ConfigEntryBase config)
		{
			return configType(config.SettingType);
		}

		private static Type configType(Type type)
		{
			return type.IsEnum ? Enum.GetUnderlyingType(type) : type;
		}

		private static ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase>? configs = null, IEnumerable<CustomSyncedValueBase>? customValues = null, IEnumerable<PackageEntry>? packageEntries = null, bool partial = true)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>();
			List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>();
			ZPackage val = new ZPackage();
			val.Write((byte)(partial ? 1 : 0));
			val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0));
			foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>())
			{
				AddEntryToPackage(val, item);
			}
			foreach (CustomSyncedValueBase item2 in list2)
			{
				AddEntryToPackage(val, new PackageEntry
				{
					section = "Internal",
					key = item2.Identifier,
					type = item2.Type,
					value = item2.BoxedValue
				});
			}
			foreach (ConfigEntryBase item3 in list)
			{
				AddEntryToPackage(val, new PackageEntry
				{
					section = item3.Definition.Section,
					key = item3.Definition.Key,
					type = configType(item3),
					value = item3.BoxedValue
				});
			}
			return val;
		}

		private static void AddEntryToPackage(ZPackage package, PackageEntry entry)
		{
			package.Write(entry.section);
			package.Write(entry.key);
			package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type));
			AddValueToZPackage(package, entry.value);
		}

		private static string GetZPackageTypeString(Type type)
		{
			return type.AssemblyQualifiedName;
		}

		private static void AddValueToZPackage(ZPackage package, object? value)
		{
			Type type = value?.GetType();
			if (value is Enum)
			{
				value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture);
			}
			else
			{
				if (value is ICollection collection)
				{
					package.Write(collection.Count);
					{
						foreach (object item in collection)
						{
							AddValueToZPackage(package, item);
						}
						return;
					}
				}
				if ((object)type != null && type.IsValueType && !type.IsPrimitive)
				{
					FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					package.Write(fields.Length);
					FieldInfo[] array = fields;
					foreach (FieldInfo fieldInfo in array)
					{
						package.Write(GetZPackageTypeString(fieldInfo.FieldType));
						AddValueToZPackage(package, fieldInfo.GetValue(value));
					}
					return;
				}
			}
			ZRpc.Serialize(new object[1] { value }, ref package);
		}

		private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type)
		{
			if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum)
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				int num = package.ReadInt();
				if (num != fields.Length)
				{
					throw new InvalidDeserializationTypeException
					{
						received = $"(field count: {num})",
						expected = $"(field count: {fields.Length})"
					};
				}
				object uninitializedObject = FormatterServices.GetUninitializedObject(type);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					string text = package.ReadString();
					if (text != GetZPackageTypeString(fieldInfo.FieldType))
					{
						throw new InvalidDeserializationTypeException
						{
							received = text,
							expected = GetZPackageTypeString(fieldInfo.FieldType),
							field = fieldInfo.Name
						};
					}
					fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType));
				}
				return uninitializedObject;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				int num2 = package.ReadInt();
				IDictionary dictionary = (IDictionary)Activator.CreateInstance(type);
				Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments);
				FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
				FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic);
				for (int j = 0; j < num2; j++)
				{
					object obj = ReadValueWithTypeFromZPackage(package, type2);
					dictionary.Add(field.GetValue(obj), field2.GetValue(obj));
				}
				return dictionary;
			}
			if (type != typeof(List<string>) && type.IsGenericType)
			{
				Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]);
				if ((object)type3 != null && type3.IsAssignableFrom(type))
				{
					int num3 = package.ReadInt();
					object obj2 = Activator.CreateInstance(type);
					MethodInfo method = type3.GetMethod("Add");
					for (int k = 0; k < num3; k++)
					{
						method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) });
					}
					return obj2;
				}
			}
			ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo));
			AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type);
			List<object> source = new List<object>();
			ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source);
			return source.First();
		}
	}
	[PublicAPI]
	[HarmonyPatch]
	public class VersionCheck
	{
		private static readonly HashSet<VersionCheck> versionChecks;

		private static readonly Dictionary<string, string> notProcessedNames;

		public string Name;

		private string? displayName;

		private string? currentVersion;

		private string? minimumRequiredVersion;

		public bool ModRequired = true;

		private string? ReceivedCurrentVersion;

		private string? ReceivedMinimumRequiredVersion;

		private readonly List<ZRpc> ValidatedClients = new List<ZRpc>();

		private ConfigSync? ConfigSync;

		public string DisplayName
		{
			get
			{
				return displayName ?? Name;
			}
			set
			{
				displayName = value;
			}
		}

		public string CurrentVersion
		{
			get
			{
				return currentVersion ?? "0.0.0";
			}
			set
			{
				currentVersion = value;
			}
		}

		public string MinimumRequiredVersion
		{
			get
			{
				return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0");
			}
			set
			{
				minimumRequiredVersion = value;
			}
		}

		private static void PatchServerSync()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null));
			if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0)
			{
				return;
			}
			Harmony val = new Harmony("org.bepinex.helpers.ServerSync");
			foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) })
				where t.IsClass
				select t)
			{
				val.PatchAll(item);
			}
		}

		static VersionCheck()
		{
			versionChecks = new HashSet<VersionCheck>();
			notProcessedNames = new Dictionary<string, string>();
			typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1]
			{
				new Action(PatchServerSync)
			});
		}

		public VersionCheck(string name)
		{
			Name = name;
			ModRequired = true;
			versionChecks.Add(this);
		}

		public VersionCheck(ConfigSync configSync)
		{
			ConfigSync = configSync;
			Name = ConfigSync.Name;
			versionChecks.Add(this);
		}

		public void Initialize()
		{
			ReceivedCurrentVersion = null;
			ReceivedMinimumRequiredVersion = null;
			if (ConfigSync != null)
			{
				Name = ConfigSync.Name;
				DisplayName = ConfigSync.DisplayName;
				CurrentVersion = ConfigSync.CurrentVersion;
				MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion;
				ModRequired = ConfigSync.ModRequired;
			}
		}

		private bool IsVersionOk()
		{
			if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null)
			{
				return !ModRequired;
			}
			bool flag = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion);
			bool flag2 = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion);
			return flag && flag2;
		}

		private string ErrorClient()
		{
			if (ReceivedMinimumRequiredVersion == null)
			{
				return DisplayName + " is not installed on the server.";
			}
			return (new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)) ? (DisplayName + " may not be higher than version " + ReceivedCurrentVersion + ". You have version " + CurrentVersion + ".") : (DisplayName + " needs to be at least version " + ReceivedMinimumRequiredVersion + ". You have version " + CurrentVersion + ".");
		}

		private string ErrorServer(ZRpc rpc)
		{
			return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion;
		}

		private string Error(ZRpc? rpc = null)
		{
			return (rpc == null) ? ErrorClient() : ErrorServer(rpc);
		}

		private static VersionCheck[] GetFailedClient()
		{
			return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray();
		}

		private static VersionCheck[] GetFailedServer(ZRpc rpc)
		{
			ZRpc rpc2 = rpc;
			return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc2)).ToArray();
		}

		private static void Logout()
		{
			Game.instance.Logout(true, true);
			AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3);
		}

		private static void DisconnectClient(ZRpc rpc)
		{
			rpc.Invoke("Error", new object[1] { 3 });
		}

		private static void CheckVersion(ZRpc rpc, ZPackage pkg)
		{
			CheckVersion(rpc, pkg, null);
		}

		private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action<ZRpc, ZPackage>? original)
		{
			string text = pkg.ReadString();
			string text2 = pkg.ReadString();
			string text3 = pkg.ReadString();
			bool flag = false;
			foreach (VersionCheck versionCheck in versionChecks)
			{
				if (!(text != versionCheck.Name))
				{
					Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + "."));
					versionCheck.ReceivedMinimumRequiredVersion = text2;
					versionCheck.ReceivedCurrentVersion = text3;
					if (ZNet.instance.IsServer() && versionCheck.IsVersionOk())
					{
						versionCheck.ValidatedClients.Add(rpc);
					}
					flag = true;
				}
			}
			if (flag)
			{
				return;
			}
			pkg.SetPos(0);
			if (original != null)
			{
				original(rpc, pkg);
				if (pkg.GetPos() == 0)
				{
					notProcessedNames.Add(text, text3);
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[HarmonyPrefix]
		private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance)
		{
			VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient());
			if (array.Length == 0)
			{
				return true;
			}
			VersionCheck[] array2 = array;
			foreach (VersionCheck versionCheck in array2)
			{
				Debug.LogWarning((object)versionCheck.Error(rpc));
			}
			if (__instance.IsServer())
			{
				DisconnectClient(rpc);
			}
			else
			{
				Logout();
			}
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		[HarmonyPrefix]
		private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance)
		{
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			notProcessedNames.Clear();
			IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc);
			if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")))
			{
				object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")];
				Action<ZRpc, ZPackage> action = (Action<ZRpc, ZPackage>)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
				peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)delegate(ZRpc rpc, ZPackage pkg)
				{
					CheckVersion(rpc, pkg, action);
				});
			}
			else
			{
				peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)CheckVersion);
			}
			foreach (VersionCheck versionCheck in versionChecks)
			{
				versionCheck.Initialize();
				if (versionCheck.ModRequired || __instance.IsServer())
				{
					Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + "."));
					ZPackage val = new ZPackage();
					val.Write(versionCheck.Name);
					val.Write(versionCheck.MinimumRequiredVersion);
					val.Write(versionCheck.CurrentVersion);
					peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val });
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "Disconnect")]
		[HarmonyPrefix]
		private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance)
		{
			if (!__instance.IsServer())
			{
				return;
			}
			foreach (VersionCheck versionCheck in versionChecks)
			{
				versionCheck.ValidatedClients.Remove(peer.m_rpc);
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
		[HarmonyPostfix]
		private static void ShowConnectionError(FejdStartup __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3)
			{
				return;
			}
			bool flag = false;
			VersionCheck[] failedClient = GetFailedClient();
			if (failedClient.Length != 0)
			{
				string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error()));
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + text;
				flag = true;
			}
			foreach (KeyValuePair<string, string> item in notProcessedNames.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> kv) => kv.Key))
			{
				if (!__instance.m_connectionFailedError.text.Contains(item.Key))
				{
					TMP_Text connectionFailedError2 = __instance.m_connectionFailedError;
					connectionFailedError2.text = connectionFailedError2.text + "\nServer expects you to have " + item.Key + " (Version: " + item.Value + ") installed.";
					flag = true;
				}
			}
			if (flag)
			{
				RectTransform component = ((Component)__instance.m_connectionFailedPanel.transform.Find("Image")).GetComponent<RectTransform>();
				Vector2 sizeDelta = component.sizeDelta;
				sizeDelta.x = 675f;
				component.sizeDelta = sizeDelta;
				__instance.m_connectionFailedError.ForceMeshUpdate(false, false);
				float num = __instance.m_connectionFailedError.renderedHeight + 105f;
				RectTransform component2 = ((Component)((Component)component).transform.Find("ButtonOk")).GetComponent<RectTransform>();
				component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, component2.anchoredPosition.y - (num - component.sizeDelta.y) / 2f);
				sizeDelta = component.sizeDelta;
				sizeDelta.y = num;
				component.sizeDelta = sizeDelta;
			}
		}
	}
}

EpicLoot/System.Runtime.Serialization.dll

Decompiled 10 months ago
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Configuration;
using System.Runtime.Serialization.Diagnostics;
using System.Runtime.Serialization.Diagnostics.Application;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Json;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Xml.XPath;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Runtime.Serialization.dll")]
[assembly: AssemblyDescription("System.Runtime.Serialization.dll")]
[assembly: AssemblyDefaultAlias("System.Runtime.Serialization.dll")]
[assembly: AssemblyCompany("Mono development team")]
[assembly: AssemblyProduct("Mono Common Language Infrastructure")]
[assembly: AssemblyCopyright("(c) Various Mono authors")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.6.57.0")]
[assembly: AssemblyFileVersion("4.6.57.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile("../ecma.pub")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: ComCompatibleVersion(1, 0, 3300, 0)]
[assembly: SecurityCritical(SecurityCriticalScope.Explicit)]
[assembly: ComVisible(false)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.0.0")]
[module: UnverifiableCode]
internal static class SR
{
	internal static string GetString(string name, params object[] args)
	{
		return GetString(CultureInfo.InvariantCulture, name, args);
	}

	internal static string GetString(CultureInfo culture, string name, params object[] args)
	{
		return string.Format(culture, name, args);
	}

	internal static string GetString(string name)
	{
		return name;
	}

	internal static string GetString(CultureInfo culture, string name)
	{
		return name;
	}

	internal static string Format(string resourceFormat, params object[] args)
	{
		if (args != null)
		{
			return string.Format(CultureInfo.InvariantCulture, resourceFormat, args);
		}
		return resourceFormat;
	}

	internal static string Format(string resourceFormat, object p1)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1);
	}

	internal static string Format(string resourceFormat, object p1, object p2)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1, p2);
	}

	internal static string Format(string resourceFormat, object p1, object p2, object p3)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1, p2, p3);
	}
}
namespace System
{
	internal static class LocalAppContextSwitches
	{
		public static readonly bool DoNotUseTimeZoneInfo;

		public static readonly bool DoNotUseEcmaScriptV6EscapeControlCharacter;
	}
}
namespace System.Xml
{
	internal abstract class ArrayHelper<TArgument, TArray>
	{
		public TArray[] ReadArray(XmlDictionaryReader reader, TArgument localName, TArgument namespaceUri, int maxArrayLength)
		{
			TArray[][] array = null;
			TArray[] array2 = null;
			int num = 0;
			int num2 = 0;
			if (reader.TryGetArrayLength(out var count))
			{
				if (count > maxArrayLength)
				{
					XmlExceptionHelper.ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(reader, maxArrayLength);
				}
				if (count > 65535)
				{
					count = 65535;
				}
			}
			else
			{
				count = 32;
			}
			while (true)
			{
				array2 = new TArray[count];
				int i;
				int num3;
				for (i = 0; i < array2.Length; i += num3)
				{
					num3 = ReadArray(reader, localName, namespaceUri, array2, i, array2.Length - i);
					if (num3 == 0)
					{
						break;
					}
				}
				if (num2 > maxArrayLength - i)
				{
					XmlExceptionHelper.ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(reader, maxArrayLength);
				}
				num2 += i;
				if (i < array2.Length || reader.NodeType == XmlNodeType.EndElement)
				{
					break;
				}
				if (array == null)
				{
					array = new TArray[32][];
				}
				array[num++] = array2;
				count *= 2;
			}
			if (num2 != array2.Length || num > 0)
			{
				TArray[] array3 = new TArray[num2];
				int num4 = 0;
				for (int j = 0; j < num; j++)
				{
					Array.Copy(array[j], 0, array3, num4, array[j].Length);
					num4 += array[j].Length;
				}
				Array.Copy(array2, 0, array3, num4, num2 - num4);
				array2 = array3;
			}
			return array2;
		}

		public void WriteArray(XmlDictionaryWriter writer, string prefix, TArgument localName, TArgument namespaceUri, XmlDictionaryReader reader)
		{
			int count = ((!reader.TryGetArrayLength(out count)) ? 256 : Math.Min(count, 256));
			TArray[] array = new TArray[count];
			while (true)
			{
				int num = ReadArray(reader, localName, namespaceUri, array, 0, array.Length);
				if (num != 0)
				{
					WriteArray(writer, prefix, localName, namespaceUri, array, 0, num);
					continue;
				}
				break;
			}
		}

		protected abstract int ReadArray(XmlDictionaryReader reader, TArgument localName, TArgument namespaceUri, TArray[] array, int offset, int count);

		protected abstract void WriteArray(XmlDictionaryWriter writer, string prefix, TArgument localName, TArgument namespaceUri, TArray[] array, int offset, int count);
	}
	internal class BooleanArrayHelperWithString : ArrayHelper<string, bool>
	{
		public static readonly BooleanArrayHelperWithString Instance = new BooleanArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, bool[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, bool[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class BooleanArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, bool>
	{
		public static readonly BooleanArrayHelperWithDictionaryString Instance = new BooleanArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int16ArrayHelperWithString : ArrayHelper<string, short>
	{
		public static readonly Int16ArrayHelperWithString Instance = new Int16ArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, short[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, short[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int16ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, short>
	{
		public static readonly Int16ArrayHelperWithDictionaryString Instance = new Int16ArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int32ArrayHelperWithString : ArrayHelper<string, int>
	{
		public static readonly Int32ArrayHelperWithString Instance = new Int32ArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, int[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, int[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int32ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, int>
	{
		public static readonly Int32ArrayHelperWithDictionaryString Instance = new Int32ArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int64ArrayHelperWithString : ArrayHelper<string, long>
	{
		public static readonly Int64ArrayHelperWithString Instance = new Int64ArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, long[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, long[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int64ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, long>
	{
		public static readonly Int64ArrayHelperWithDictionaryString Instance = new Int64ArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class SingleArrayHelperWithString : ArrayHelper<string, float>
	{
		public static readonly SingleArrayHelperWithString Instance = new SingleArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, float[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, float[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class SingleArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, float>
	{
		public static readonly SingleArrayHelperWithDictionaryString Instance = new SingleArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DoubleArrayHelperWithString : ArrayHelper<string, double>
	{
		public static readonly DoubleArrayHelperWithString Instance = new DoubleArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, double[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, double[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DoubleArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, double>
	{
		public static readonly DoubleArrayHelperWithDictionaryString Instance = new DoubleArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DecimalArrayHelperWithString : ArrayHelper<string, decimal>
	{
		public static readonly DecimalArrayHelperWithString Instance = new DecimalArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, decimal[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, decimal[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DecimalArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, decimal>
	{
		public static readonly DecimalArrayHelperWithDictionaryString Instance = new DecimalArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DateTimeArrayHelperWithString : ArrayHelper<string, DateTime>
	{
		public static readonly DateTimeArrayHelperWithString Instance = new DateTimeArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, DateTime[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, DateTime[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DateTimeArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, DateTime>
	{
		public static readonly DateTimeArrayHelperWithDictionaryString Instance = new DateTimeArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class GuidArrayHelperWithString : ArrayHelper<string, Guid>
	{
		public static readonly GuidArrayHelperWithString Instance = new GuidArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, Guid[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, Guid[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class GuidArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, Guid>
	{
		public static readonly GuidArrayHelperWithDictionaryString Instance = new GuidArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class TimeSpanArrayHelperWithString : ArrayHelper<string, TimeSpan>
	{
		public static readonly TimeSpanArrayHelperWithString Instance = new TimeSpanArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class TimeSpanArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, TimeSpan>
	{
		public static readonly TimeSpanArrayHelperWithDictionaryString Instance = new TimeSpanArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class EncodingStreamWrapper : Stream
	{
		private enum SupportedEncoding
		{
			UTF8,
			UTF16LE,
			UTF16BE,
			None
		}

		private static readonly UTF8Encoding SafeUTF8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false);

		private static readonly UnicodeEncoding SafeUTF16 = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: false);

		private static readonly UnicodeEncoding SafeBEUTF16 = new UnicodeEncoding(bigEndian: true, byteOrderMark: false, throwOnInvalidBytes: false);

		private static readonly UTF8Encoding ValidatingUTF8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);

		private static readonly UnicodeEncoding ValidatingUTF16 = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: true);

		private static readonly UnicodeEncoding ValidatingBEUTF16 = new UnicodeEncoding(bigEndian: true, byteOrderMark: false, throwOnInvalidBytes: true);

		private const int BufferLength = 128;

		private static readonly byte[] encodingAttr = new byte[8] { 101, 110, 99, 111, 100, 105, 110, 103 };

		private static readonly byte[] encodingUTF8 = new byte[5] { 117, 116, 102, 45, 56 };

		private static readonly byte[] encodingUnicode = new byte[6] { 117, 116, 102, 45, 49, 54 };

		private static readonly byte[] encodingUnicodeLE = new byte[8] { 117, 116, 102, 45, 49, 54, 108, 101 };

		private static readonly byte[] encodingUnicodeBE = new byte[8] { 117, 116, 102, 45, 49, 54, 98, 101 };

		private SupportedEncoding encodingCode;

		private Encoding encoding;

		private Encoder enc;

		private Decoder dec;

		private bool isReading;

		private Stream stream;

		private char[] chars;

		private byte[] bytes;

		private int byteOffset;

		private int byteCount;

		private byte[] byteBuffer = new byte[1];

		public override bool CanRead
		{
			get
			{
				if (!isReading)
				{
					return false;
				}
				return stream.CanRead;
			}
		}

		public override bool CanSeek => false;

		public override bool CanWrite
		{
			get
			{
				if (isReading)
				{
					return false;
				}
				return stream.CanWrite;
			}
		}

		public override long Position
		{
			get
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
			}
			set
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
			}
		}

		public override bool CanTimeout => stream.CanTimeout;

		public override long Length => stream.Length;

		public override int ReadTimeout
		{
			get
			{
				return stream.ReadTimeout;
			}
			set
			{
				stream.ReadTimeout = value;
			}
		}

		public override int WriteTimeout
		{
			get
			{
				return stream.WriteTimeout;
			}
			set
			{
				stream.WriteTimeout = value;
			}
		}

		public EncodingStreamWrapper(Stream stream, Encoding encoding)
		{
			try
			{
				isReading = true;
				this.stream = new BufferedStream(stream);
				SupportedEncoding supportedEncoding = GetSupportedEncoding(encoding);
				SupportedEncoding supportedEncoding2 = ReadBOMEncoding(encoding == null);
				if (supportedEncoding != SupportedEncoding.None && supportedEncoding != supportedEncoding2)
				{
					ThrowExpectedEncodingMismatch(supportedEncoding, supportedEncoding2);
				}
				if (supportedEncoding2 == SupportedEncoding.UTF8)
				{
					FillBuffer(2);
					if (bytes[byteOffset + 1] == 63 && bytes[byteOffset] == 60)
					{
						FillBuffer(128);
						CheckUTF8DeclarationEncoding(bytes, byteOffset, byteCount, supportedEncoding2, supportedEncoding);
					}
					return;
				}
				EnsureBuffers();
				FillBuffer(254);
				SetReadDocumentEncoding(supportedEncoding2);
				CleanupCharBreak();
				int charCount = this.encoding.GetChars(bytes, byteOffset, byteCount, chars, 0);
				byteOffset = 0;
				byteCount = ValidatingUTF8.GetBytes(chars, 0, charCount, bytes, 0);
				if (bytes[1] == 63 && bytes[0] == 60)
				{
					CheckUTF8DeclarationEncoding(bytes, 0, byteCount, supportedEncoding2, supportedEncoding);
				}
				else if (supportedEncoding == SupportedEncoding.None)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
				}
			}
			catch (DecoderFallbackException innerException)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Invalid byte encoding."), innerException));
			}
		}

		private void SetReadDocumentEncoding(SupportedEncoding e)
		{
			EnsureBuffers();
			encodingCode = e;
			encoding = GetEncoding(e);
		}

		private static Encoding GetEncoding(SupportedEncoding e)
		{
			return e switch
			{
				SupportedEncoding.UTF8 => ValidatingUTF8, 
				SupportedEncoding.UTF16LE => ValidatingUTF16, 
				SupportedEncoding.UTF16BE => ValidatingBEUTF16, 
				_ => throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported."))), 
			};
		}

		private static Encoding GetSafeEncoding(SupportedEncoding e)
		{
			return e switch
			{
				SupportedEncoding.UTF8 => SafeUTF8, 
				SupportedEncoding.UTF16LE => SafeUTF16, 
				SupportedEncoding.UTF16BE => SafeBEUTF16, 
				_ => throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported."))), 
			};
		}

		private static string GetEncodingName(SupportedEncoding enc)
		{
			return enc switch
			{
				SupportedEncoding.UTF8 => "utf-8", 
				SupportedEncoding.UTF16LE => "utf-16LE", 
				SupportedEncoding.UTF16BE => "utf-16BE", 
				_ => throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported."))), 
			};
		}

		private static SupportedEncoding GetSupportedEncoding(Encoding encoding)
		{
			if (encoding == null)
			{
				return SupportedEncoding.None;
			}
			if (encoding.WebName == ValidatingUTF8.WebName)
			{
				return SupportedEncoding.UTF8;
			}
			if (encoding.WebName == ValidatingUTF16.WebName)
			{
				return SupportedEncoding.UTF16LE;
			}
			if (encoding.WebName == ValidatingBEUTF16.WebName)
			{
				return SupportedEncoding.UTF16BE;
			}
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported.")));
		}

		public EncodingStreamWrapper(Stream stream, Encoding encoding, bool emitBOM)
		{
			isReading = false;
			this.encoding = encoding;
			this.stream = new BufferedStream(stream);
			encodingCode = GetSupportedEncoding(encoding);
			if (encodingCode == SupportedEncoding.UTF8)
			{
				return;
			}
			EnsureBuffers();
			dec = ValidatingUTF8.GetDecoder();
			enc = this.encoding.GetEncoder();
			if (emitBOM)
			{
				byte[] preamble = this.encoding.GetPreamble();
				if (preamble.Length != 0)
				{
					this.stream.Write(preamble, 0, preamble.Length);
				}
			}
		}

		private SupportedEncoding ReadBOMEncoding(bool notOutOfBand)
		{
			int num = stream.ReadByte();
			int num2 = stream.ReadByte();
			int num3 = stream.ReadByte();
			int num4 = stream.ReadByte();
			if (num4 == -1)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
			}
			int preserve;
			SupportedEncoding result = ReadBOMEncoding((byte)num, (byte)num2, (byte)num3, (byte)num4, notOutOfBand, out preserve);
			EnsureByteBuffer();
			switch (preserve)
			{
			case 1:
				bytes[0] = (byte)num4;
				break;
			case 2:
				bytes[0] = (byte)num3;
				bytes[1] = (byte)num4;
				break;
			case 4:
				bytes[0] = (byte)num;
				bytes[1] = (byte)num2;
				bytes[2] = (byte)num3;
				bytes[3] = (byte)num4;
				break;
			}
			byteCount = preserve;
			return result;
		}

		private static SupportedEncoding ReadBOMEncoding(byte b1, byte b2, byte b3, byte b4, bool notOutOfBand, out int preserve)
		{
			SupportedEncoding result = SupportedEncoding.UTF8;
			preserve = 0;
			if (b1 == 60 && b2 != 0)
			{
				result = SupportedEncoding.UTF8;
				preserve = 4;
			}
			else if (b1 == byte.MaxValue && b2 == 254)
			{
				result = SupportedEncoding.UTF16LE;
				preserve = 2;
			}
			else if (b1 == 254 && b2 == byte.MaxValue)
			{
				result = SupportedEncoding.UTF16BE;
				preserve = 2;
			}
			else if (b1 == 0 && b2 == 60)
			{
				result = SupportedEncoding.UTF16BE;
				if (notOutOfBand && (b3 != 0 || b4 != 63))
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration is required for all non-UTF8 documents.")));
				}
				preserve = 4;
			}
			else if (b1 == 60 && b2 == 0)
			{
				result = SupportedEncoding.UTF16LE;
				if (notOutOfBand && (b3 != 63 || b4 != 0))
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration is required for all non-UTF8 documents.")));
				}
				preserve = 4;
			}
			else if (b1 == 239 && b2 == 187)
			{
				if (notOutOfBand && b3 != 191)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unrecognized Byte Order Mark.")));
				}
				preserve = 1;
			}
			else
			{
				preserve = 4;
			}
			return result;
		}

		private void FillBuffer(int count)
		{
			count -= byteCount;
			while (count > 0)
			{
				int num = stream.Read(bytes, byteOffset + byteCount, count);
				if (num != 0)
				{
					byteCount += num;
					count -= num;
					continue;
				}
				break;
			}
		}

		private void EnsureBuffers()
		{
			EnsureByteBuffer();
			if (chars == null)
			{
				chars = new char[128];
			}
		}

		private void EnsureByteBuffer()
		{
			if (bytes == null)
			{
				bytes = new byte[512];
				byteOffset = 0;
				byteCount = 0;
			}
		}

		private static void CheckUTF8DeclarationEncoding(byte[] buffer, int offset, int count, SupportedEncoding e, SupportedEncoding expectedEnc)
		{
			byte b = 0;
			int num = -1;
			int num2 = offset + Math.Min(count, 128);
			int num3 = 0;
			int num4 = 0;
			for (num3 = offset + 2; num3 < num2; num3++)
			{
				if (b != 0)
				{
					if (buffer[num3] == b)
					{
						b = 0;
					}
				}
				else if (buffer[num3] == 39 || buffer[num3] == 34)
				{
					b = buffer[num3];
				}
				else if (buffer[num3] == 61)
				{
					if (num4 == 1)
					{
						num = num3;
						break;
					}
					num4++;
				}
				else if (buffer[num3] == 63)
				{
					break;
				}
			}
			if (num == -1)
			{
				if (e != 0 && expectedEnc == SupportedEncoding.None)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
				}
				return;
			}
			if (num < 28)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Malformed XML declaration.")));
			}
			num3 = num - 1;
			while (IsWhitespace(buffer[num3]))
			{
				num3--;
			}
			if (!Compare(encodingAttr, buffer, num3 - encodingAttr.Length + 1))
			{
				if (e == SupportedEncoding.UTF8 || expectedEnc != SupportedEncoding.None)
				{
					return;
				}
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
			}
			for (num3 = num + 1; num3 < num2 && IsWhitespace(buffer[num3]); num3++)
			{
			}
			if (buffer[num3] != 39 && buffer[num3] != 34)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Malformed XML declaration.")));
			}
			b = buffer[num3];
			int num5 = num3++;
			for (; buffer[num3] != b && num3 < num2; num3++)
			{
			}
			if (buffer[num3] != b)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Malformed XML declaration.")));
			}
			int num6 = num5 + 1;
			int num7 = num3 - num6;
			SupportedEncoding supportedEncoding = e;
			if (num7 == encodingUTF8.Length && CompareCaseInsensitive(encodingUTF8, buffer, num6))
			{
				supportedEncoding = SupportedEncoding.UTF8;
			}
			else if (num7 == encodingUnicodeLE.Length && CompareCaseInsensitive(encodingUnicodeLE, buffer, num6))
			{
				supportedEncoding = SupportedEncoding.UTF16LE;
			}
			else if (num7 == encodingUnicodeBE.Length && CompareCaseInsensitive(encodingUnicodeBE, buffer, num6))
			{
				supportedEncoding = SupportedEncoding.UTF16BE;
			}
			else if (num7 == encodingUnicode.Length && CompareCaseInsensitive(encodingUnicode, buffer, num6))
			{
				if (e == SupportedEncoding.UTF8)
				{
					ThrowEncodingMismatch(SafeUTF8.GetString(buffer, num6, num7), SafeUTF8.GetString(encodingUTF8, 0, encodingUTF8.Length));
				}
			}
			else
			{
				ThrowEncodingMismatch(SafeUTF8.GetString(buffer, num6, num7), e);
			}
			if (e != supportedEncoding)
			{
				ThrowEncodingMismatch(SafeUTF8.GetString(buffer, num6, num7), e);
			}
		}

		private static bool CompareCaseInsensitive(byte[] key, byte[] buffer, int offset)
		{
			for (int i = 0; i < key.Length; i++)
			{
				if (key[i] != buffer[offset + i] && key[i] != char.ToLower((char)buffer[offset + i], CultureInfo.InvariantCulture))
				{
					return false;
				}
			}
			return true;
		}

		private static bool Compare(byte[] key, byte[] buffer, int offset)
		{
			for (int i = 0; i < key.Length; i++)
			{
				if (key[i] != buffer[offset + i])
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsWhitespace(byte ch)
		{
			if (ch != 32 && ch != 10 && ch != 9)
			{
				return ch == 13;
			}
			return true;
		}

		internal static ArraySegment<byte> ProcessBuffer(byte[] buffer, int offset, int count, Encoding encoding)
		{
			if (count < 4)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
			}
			try
			{
				SupportedEncoding supportedEncoding = GetSupportedEncoding(encoding);
				int preserve;
				SupportedEncoding supportedEncoding2 = ReadBOMEncoding(buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3], encoding == null, out preserve);
				if (supportedEncoding != SupportedEncoding.None && supportedEncoding != supportedEncoding2)
				{
					ThrowExpectedEncodingMismatch(supportedEncoding, supportedEncoding2);
				}
				offset += 4 - preserve;
				count -= 4 - preserve;
				if (supportedEncoding2 == SupportedEncoding.UTF8)
				{
					if (buffer[offset + 1] != 63 || buffer[offset] != 60)
					{
						return new ArraySegment<byte>(buffer, offset, count);
					}
					CheckUTF8DeclarationEncoding(buffer, offset, count, supportedEncoding2, supportedEncoding);
					return new ArraySegment<byte>(buffer, offset, count);
				}
				Encoding safeEncoding = GetSafeEncoding(supportedEncoding2);
				int num = Math.Min(count, 256);
				char[] array = new char[safeEncoding.GetMaxCharCount(num)];
				int charCount = safeEncoding.GetChars(buffer, offset, num, array, 0);
				byte[] array2 = new byte[ValidatingUTF8.GetMaxByteCount(charCount)];
				int count2 = ValidatingUTF8.GetBytes(array, 0, charCount, array2, 0);
				if (array2[1] == 63 && array2[0] == 60)
				{
					CheckUTF8DeclarationEncoding(array2, 0, count2, supportedEncoding2, supportedEncoding);
				}
				else if (supportedEncoding == SupportedEncoding.None)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
				}
				return new ArraySegment<byte>(ValidatingUTF8.GetBytes(GetEncoding(supportedEncoding2).GetChars(buffer, offset, count)));
			}
			catch (DecoderFallbackException innerException)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Invalid byte encoding."), innerException));
			}
		}

		private static void ThrowExpectedEncodingMismatch(SupportedEncoding expEnc, SupportedEncoding actualEnc)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("The expected encoding '{0}' does not match the actual encoding '{1}'.", GetEncodingName(expEnc), GetEncodingName(actualEnc))));
		}

		private static void ThrowEncodingMismatch(string declEnc, SupportedEncoding enc)
		{
			ThrowEncodingMismatch(declEnc, GetEncodingName(enc));
		}

		private static void ThrowEncodingMismatch(string declEnc, string docEnc)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("The encoding in the declaration '{0}' does not match the encoding of the document '{1}'.", declEnc, docEnc)));
		}

		public override void Close()
		{
			Flush();
			base.Close();
			stream.Close();
		}

		public override void Flush()
		{
			stream.Flush();
		}

		public override int ReadByte()
		{
			if (byteCount == 0 && encodingCode == SupportedEncoding.UTF8)
			{
				return stream.ReadByte();
			}
			if (Read(byteBuffer, 0, 1) == 0)
			{
				return -1;
			}
			return byteBuffer[0];
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			try
			{
				if (byteCount == 0)
				{
					if (encodingCode == SupportedEncoding.UTF8)
					{
						return stream.Read(buffer, offset, count);
					}
					byteOffset = 0;
					byteCount = stream.Read(bytes, byteCount, (chars.Length - 1) * 2);
					if (byteCount == 0)
					{
						return 0;
					}
					CleanupCharBreak();
					int charCount = encoding.GetChars(bytes, 0, byteCount, chars, 0);
					byteCount = Encoding.UTF8.GetBytes(chars, 0, charCount, bytes, 0);
				}
				if (byteCount < count)
				{
					count = byteCount;
				}
				Buffer.BlockCopy(bytes, byteOffset, buffer, offset, count);
				byteOffset += count;
				byteCount -= count;
				return count;
			}
			catch (DecoderFallbackException innerException)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Invalid byte encoding."), innerException));
			}
		}

		private void CleanupCharBreak()
		{
			int num = byteOffset + byteCount;
			if (byteCount % 2 != 0)
			{
				int num2 = stream.ReadByte();
				if (num2 < 0)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
				}
				bytes[num++] = (byte)num2;
				byteCount++;
			}
			int num3 = ((encodingCode != SupportedEncoding.UTF16LE) ? (bytes[num - 1] + (bytes[num - 2] << 8)) : (bytes[num - 2] + (bytes[num - 1] << 8)));
			if ((num3 & 0xDC00) != 56320 && num3 >= 55296 && num3 <= 56319)
			{
				int num4 = stream.ReadByte();
				int num5 = stream.ReadByte();
				if (num5 < 0)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
				}
				bytes[num++] = (byte)num4;
				bytes[num++] = (byte)num5;
				byteCount += 2;
			}
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
		}

		public override void WriteByte(byte b)
		{
			if (encodingCode == SupportedEncoding.UTF8)
			{
				stream.WriteByte(b);
				return;
			}
			byteBuffer[0] = b;
			Write(byteBuffer, 0, 1);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (encodingCode == SupportedEncoding.UTF8)
			{
				stream.Write(buffer, offset, count);
				return;
			}
			while (count > 0)
			{
				int num = ((chars.Length < count) ? chars.Length : count);
				int charCount = dec.GetChars(buffer, offset, num, chars, 0, flush: false);
				byteCount = enc.GetBytes(chars, 0, charCount, bytes, 0, flush: false);
				stream.Write(bytes, 0, byteCount);
				offset += num;
				count -= num;
			}
		}

		public override void SetLength(long value)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
		}
	}
	public interface IFragmentCapableXmlDictionaryWriter
	{
		bool CanFragment { get; }

		void StartFragment(Stream stream, bool generateSelfContainedTextFragment);

		void EndFragment();

		void WriteFragment(byte[] buffer, int offset, int count);
	}
	public interface IStreamProvider
	{
		Stream GetStream();

		void ReleaseStream(Stream stream);
	}
	public interface IXmlDictionary
	{
		bool TryLookup(string value, out XmlDictionaryString result);

		bool TryLookup(int key, out XmlDictionaryString result);

		bool TryLookup(XmlDictionaryString value, out XmlDictionaryString result);
	}
	internal enum PrefixHandleType
	{
		Empty,
		A,
		B,
		C,
		D,
		E,
		F,
		G,
		H,
		I,
		J,
		K,
		L,
		M,
		N,
		O,
		P,
		Q,
		R,
		S,
		T,
		U,
		V,
		W,
		X,
		Y,
		Z,
		Buffer,
		Max
	}
	internal class PrefixHandle
	{
		private XmlBufferReader bufferReader;

		private PrefixHandleType type;

		private int offset;

		private int length;

		private static string[] prefixStrings = new string[27]
		{
			"", "a", "b", "c", "d", "e", "f", "g", "h", "i",
			"j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
			"t", "u", "v", "w", "x", "y", "z"
		};

		private static byte[] prefixBuffer = new byte[26]
		{
			97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
			107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
			117, 118, 119, 120, 121, 122
		};

		public bool IsEmpty => type == PrefixHandleType.Empty;

		public bool IsXmlns
		{
			get
			{
				if (type != PrefixHandleType.Buffer)
				{
					return false;
				}
				if (length != 5)
				{
					return false;
				}
				byte[] buffer = bufferReader.Buffer;
				int num = offset;
				if (buffer[num] == 120 && buffer[num + 1] == 109 && buffer[num + 2] == 108 && buffer[num + 3] == 110)
				{
					return buffer[num + 4] == 115;
				}
				return false;
			}
		}

		public bool IsXml
		{
			get
			{
				if (type != PrefixHandleType.Buffer)
				{
					return false;
				}
				if (length != 3)
				{
					return false;
				}
				byte[] buffer = bufferReader.Buffer;
				int num = offset;
				if (buffer[num] == 120 && buffer[num + 1] == 109)
				{
					return buffer[num + 2] == 108;
				}
				return false;
			}
		}

		public PrefixHandle(XmlBufferReader bufferReader)
		{
			this.bufferReader = bufferReader;
		}

		public void SetValue(PrefixHandleType type)
		{
			this.type = type;
		}

		public void SetValue(PrefixHandle prefix)
		{
			type = prefix.type;
			offset = prefix.offset;
			length = prefix.length;
		}

		public void SetValue(int offset, int length)
		{
			switch (length)
			{
			case 0:
				SetValue(PrefixHandleType.Empty);
				return;
			case 1:
			{
				byte @byte = bufferReader.GetByte(offset);
				if (@byte >= 97 && @byte <= 122)
				{
					SetValue(GetAlphaPrefix(@byte - 97));
					return;
				}
				break;
			}
			}
			type = PrefixHandleType.Buffer;
			this.offset = offset;
			this.length = length;
		}

		public bool TryGetShortPrefix(out PrefixHandleType type)
		{
			type = this.type;
			return type != PrefixHandleType.Buffer;
		}

		public static string GetString(PrefixHandleType type)
		{
			return prefixStrings[(int)type];
		}

		public static PrefixHandleType GetAlphaPrefix(int index)
		{
			return (PrefixHandleType)(1 + index);
		}

		public static byte[] GetString(PrefixHandleType type, out int offset, out int length)
		{
			if (type == PrefixHandleType.Empty)
			{
				offset = 0;
				length = 0;
			}
			else
			{
				length = 1;
				offset = (int)(type - 1);
			}
			return prefixBuffer;
		}

		public string GetString(XmlNameTable nameTable)
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType);
			}
			return bufferReader.GetString(offset, length, nameTable);
		}

		public string GetString()
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType);
			}
			return bufferReader.GetString(offset, length);
		}

		public byte[] GetString(out int offset, out int length)
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType, out offset, out length);
			}
			offset = this.offset;
			length = this.length;
			return bufferReader.Buffer;
		}

		public int CompareTo(PrefixHandle that)
		{
			return GetString().CompareTo(that.GetString());
		}

		private bool Equals2(PrefixHandle prefix2)
		{
			PrefixHandleType prefixHandleType = type;
			PrefixHandleType prefixHandleType2 = prefix2.type;
			if (prefixHandleType != prefixHandleType2)
			{
				return false;
			}
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return true;
			}
			if (bufferReader == prefix2.bufferReader)
			{
				return bufferReader.Equals2(offset, length, prefix2.offset, prefix2.length);
			}
			return bufferReader.Equals2(offset, length, prefix2.bufferReader, prefix2.offset, prefix2.length);
		}

		private bool Equals2(string prefix2)
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType) == prefix2;
			}
			return bufferReader.Equals2(offset, length, prefix2);
		}

		private bool Equals2(XmlDictionaryString prefix2)
		{
			return Equals2(prefix2.Value);
		}

		public static bool operator ==(PrefixHandle prefix1, string prefix2)
		{
			return prefix1.Equals2(prefix2);
		}

		public static bool operator !=(PrefixHandle prefix1, string prefix2)
		{
			return !prefix1.Equals2(prefix2);
		}

		public static bool operator ==(PrefixHandle prefix1, XmlDictionaryString prefix2)
		{
			return prefix1.Equals2(prefix2);
		}

		public static bool operator !=(PrefixHandle prefix1, XmlDictionaryString prefix2)
		{
			return !prefix1.Equals2(prefix2);
		}

		public static bool operator ==(PrefixHandle prefix1, PrefixHandle prefix2)
		{
			return prefix1.Equals2(prefix2);
		}

		public static bool operator !=(PrefixHandle prefix1, PrefixHandle prefix2)
		{
			return !prefix1.Equals2(prefix2);
		}

		public override bool Equals(object obj)
		{
			if (!(obj is PrefixHandle prefixHandle))
			{
				return false;
			}
			return this == prefixHandle;
		}

		public override string ToString()
		{
			return GetString();
		}

		public override int GetHashCode()
		{
			return GetString().GetHashCode();
		}
	}
	internal enum StringHandleConstStringType
	{
		Type,
		Root,
		Item
	}
	internal class StringHandle
	{
		private enum StringHandleType
		{
			Dictionary,
			UTF8,
			EscapedUTF8,
			ConstString
		}

		private XmlBufferReader bufferReader;

		private StringHandleType type;

		private int key;

		private int offset;

		private int length;

		private static string[] constStrings = new string[3] { "type", "root", "item" };

		public bool IsEmpty
		{
			get
			{
				if (type == StringHandleType.UTF8)
				{
					return length == 0;
				}
				return Equals2(string.Empty);
			}
		}

		public bool IsXmlns
		{
			get
			{
				if (type == StringHandleType.UTF8)
				{
					if (length != 5)
					{
						return false;
					}
					byte[] buffer = bufferReader.Buffer;
					int num = offset;
					if (buffer[num] == 120 && buffer[num + 1] == 109 && buffer[num + 2] == 108 && buffer[num + 3] == 110)
					{
						return buffer[num + 4] == 115;
					}
					return false;
				}
				return Equals2("xmlns");
			}
		}

		public StringHandle(XmlBufferReader bufferReader)
		{
			this.bufferReader = bufferReader;
			SetValue(0, 0);
		}

		public void SetValue(int offset, int length)
		{
			type = StringHandleType.UTF8;
			this.offset = offset;
			this.length = length;
		}

		public void SetConstantValue(StringHandleConstStringType constStringType)
		{
			type = StringHandleType.ConstString;
			key = (int)constStringType;
		}

		public void SetValue(int offset, int length, bool escaped)
		{
			type = ((!escaped) ? StringHandleType.UTF8 : StringHandleType.EscapedUTF8);
			this.offset = offset;
			this.length = length;
		}

		public void SetValue(int key)
		{
			type = StringHandleType.Dictionary;
			this.key = key;
		}

		public void SetValue(StringHandle value)
		{
			type = value.type;
			key = value.key;
			offset = value.offset;
			length = value.length;
		}

		public void ToPrefixHandle(PrefixHandle prefix)
		{
			prefix.SetValue(offset, length);
		}

		public string GetString(XmlNameTable nameTable)
		{
			return type switch
			{
				StringHandleType.UTF8 => bufferReader.GetString(offset, length, nameTable), 
				StringHandleType.Dictionary => nameTable.Add(bufferReader.GetDictionaryString(key).Value), 
				StringHandleType.ConstString => nameTable.Add(constStrings[key]), 
				_ => bufferReader.GetEscapedString(offset, length, nameTable), 
			};
		}

		public string GetString()
		{
			return type switch
			{
				StringHandleType.UTF8 => bufferReader.GetString(offset, length), 
				StringHandleType.Dictionary => bufferReader.GetDictionaryString(key).Value, 
				StringHandleType.ConstString => constStrings[key], 
				_ => bufferReader.GetEscapedString(offset, length), 
			};
		}

		public byte[] GetString(out int offset, out int length)
		{
			switch (type)
			{
			case StringHandleType.UTF8:
				offset = this.offset;
				length = this.length;
				return bufferReader.Buffer;
			case StringHandleType.Dictionary:
			{
				byte[] array3 = bufferReader.GetDictionaryString(key).ToUTF8();
				offset = 0;
				length = array3.Length;
				return array3;
			}
			case StringHandleType.ConstString:
			{
				byte[] array2 = XmlConverter.ToBytes(constStrings[key]);
				offset = 0;
				length = array2.Length;
				return array2;
			}
			default:
			{
				byte[] array = XmlConverter.ToBytes(bufferReader.GetEscapedString(this.offset, this.length));
				offset = 0;
				length = array.Length;
				return array;
			}
			}
		}

		public bool TryGetDictionaryString(out XmlDictionaryString value)
		{
			if (type == StringHandleType.Dictionary)
			{
				value = bufferReader.GetDictionaryString(key);
				return true;
			}
			if (IsEmpty)
			{
				value = XmlDictionaryString.Empty;
				return true;
			}
			value = null;
			return false;
		}

		public override string ToString()
		{
			return GetString();
		}

		private bool Equals2(int key2, XmlBufferReader bufferReader2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader.Equals2(key, key2, bufferReader2), 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, bufferReader2.GetDictionaryString(key2).Value), 
				_ => GetString() == bufferReader.GetDictionaryString(key2).Value, 
			};
		}

		private bool Equals2(XmlDictionaryString xmlString2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader.Equals2(key, xmlString2), 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, xmlString2.ToUTF8()), 
				_ => GetString() == xmlString2.Value, 
			};
		}

		private bool Equals2(string s2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader.GetDictionaryString(key).Value == s2, 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, s2), 
				_ => GetString() == s2, 
			};
		}

		private bool Equals2(int offset2, int length2, XmlBufferReader bufferReader2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader2.Equals2(offset2, length2, bufferReader.GetDictionaryString(key).Value), 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, bufferReader2, offset2, length2), 
				_ => GetString() == bufferReader.GetString(offset2, length2), 
			};
		}

		private bool Equals2(StringHandle s2)
		{
			return s2.type switch
			{
				StringHandleType.Dictionary => Equals2(s2.key, s2.bufferReader), 
				StringHandleType.UTF8 => Equals2(s2.offset, s2.length, s2.bufferReader), 
				_ => Equals2(s2.GetString()), 
			};
		}

		public static bool operator ==(StringHandle s1, XmlDictionaryString xmlString2)
		{
			return s1.Equals2(xmlString2);
		}

		public static bool operator !=(StringHandle s1, XmlDictionaryString xmlString2)
		{
			return !s1.Equals2(xmlString2);
		}

		public static bool operator ==(StringHandle s1, string s2)
		{
			return s1.Equals2(s2);
		}

		public static bool operator !=(StringHandle s1, string s2)
		{
			return !s1.Equals2(s2);
		}

		public static bool operator ==(StringHandle s1, StringHandle s2)
		{
			return s1.Equals2(s2);
		}

		public static bool operator !=(StringHandle s1, StringHandle s2)
		{
			return !s1.Equals2(s2);
		}

		public int CompareTo(StringHandle that)
		{
			if (type == StringHandleType.UTF8 && that.type == StringHandleType.UTF8)
			{
				return bufferReader.Compare(offset, length, that.offset, that.length);
			}
			return string.Compare(GetString(), that.GetString(), StringComparison.Ordinal);
		}

		public override bool Equals(object obj)
		{
			if (!(obj is StringHandle stringHandle))
			{
				return false;
			}
			return this == stringHandle;
		}

		public override int GetHashCode()
		{
			return GetString().GetHashCode();
		}
	}
	public class UniqueId
	{
		private long idLow;

		private long idHigh;

		[SecurityCritical]
		private string s;

		private const int guidLength = 16;

		private const int uuidLength = 45;

		private static short[] char2val = new short[256]
		{
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 0, 16,
			32, 48, 64, 80, 96, 112, 128, 144, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 160, 176, 192,
			208, 224, 240, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 0, 1, 2, 3,
			4, 5, 6, 7, 8, 9, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 10, 11, 12, 13, 14,
			15, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256
		};

		private const string val2char = "0123456789abcdef";

		public int CharArrayLength
		{
			[SecuritySafeCritical]
			get
			{
				if (s != null)
				{
					return s.Length;
				}
				return 45;
			}
		}

		public bool IsGuid => (idLow | idHigh) != 0;

		public UniqueId()
			: this(Guid.NewGuid())
		{
		}

		public UniqueId(Guid guid)
			: this(guid.ToByteArray())
		{
		}

		public UniqueId(byte[] guid)
			: this(guid, 0)
		{
		}

		[SecuritySafeCritical]
		public unsafe UniqueId(byte[] guid, int offset)
		{
			if (guid == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("guid"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > guid.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", guid.Length)));
			}
			if (16 > guid.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.Runtime.Serialization.SR.GetString("Array too small.  Length of available data must be at least {0}.", 16), "guid"));
			}
			fixed (byte* ptr = &guid[offset])
			{
				idLow = UnsafeGetInt64(ptr);
				idHigh = UnsafeGetInt64(ptr + 8);
			}
		}

		[SecuritySafeCritical]
		public unsafe UniqueId(string value)
		{
			if (value == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
			}
			if (value.Length == 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(System.Runtime.Serialization.SR.GetString("UniqueId cannot be zero length.")));
			}
			fixed (char* chars = value)
			{
				UnsafeParse(chars, value.Length);
			}
			s = value;
		}

		[SecuritySafeCritical]
		public unsafe UniqueId(char[] chars, int offset, int count)
		{
			if (chars == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > chars.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", chars.Length)));
			}
			if (count < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (count > chars.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString("The specified size exceeds the remaining buffer space ({0} bytes).", chars.Length - offset)));
			}
			if (count == 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(System.Runtime.Serialization.SR.GetString("UniqueId cannot be zero length.")));
			}
			fixed (char* chars2 = &chars[offset])
			{
				UnsafeParse(chars2, count);
			}
			if (!IsGuid)
			{
				s = new string(chars, offset, count);
			}
		}

		[SecurityCritical]
		private unsafe int UnsafeDecode(short* char2val, char ch1, char ch2)
		{
			if ((ch1 | ch2) >= 128)
			{
				return 256;
			}
			return char2val[(int)ch1] | char2val[128 + ch2];
		}

		[SecurityCritical]
		private unsafe void UnsafeEncode(char* val2char, byte b, char* pch)
		{
			*pch = val2char[b >> 4];
			pch[1] = val2char[b & 0xF];
		}

		[SecurityCritical]
		private unsafe void UnsafeParse(char* chars, int charCount)
		{
			if (charCount != 45 || *chars != 'u' || chars[1] != 'r' || chars[2] != 'n' || chars[3] != ':' || chars[4] != 'u' || chars[5] != 'u' || chars[6] != 'i' || chars[7] != 'd' || chars[8] != ':' || chars[17] != '-' || chars[22] != '-' || chars[27] != '-' || chars[32] != '-')
			{
				return;
			}
			byte* ptr = stackalloc byte[16];
			int num = 0;
			fixed (short* ptr2 = char2val)
			{
				short* ptr3 = ptr2;
				num = UnsafeDecode(ptr3, chars[15], chars[16]);
				*ptr = (byte)num;
				int num2 = 0 | num;
				num = UnsafeDecode(ptr3, chars[13], chars[14]);
				ptr[1] = (byte)num;
				int num3 = num2 | num;
				num = UnsafeDecode(ptr3, chars[11], chars[12]);
				ptr[2] = (byte)num;
				int num4 = num3 | num;
				num = UnsafeDecode(ptr3, chars[9], chars[10]);
				ptr[3] = (byte)num;
				int num5 = num4 | num;
				num = UnsafeDecode(ptr3, chars[20], chars[21]);
				ptr[4] = (byte)num;
				int num6 = num5 | num;
				num = UnsafeDecode(ptr3, chars[18], chars[19]);
				ptr[5] = (byte)num;
				int num7 = num6 | num;
				num = UnsafeDecode(ptr3, chars[25], chars[26]);
				ptr[6] = (byte)num;
				int num8 = num7 | num;
				num = UnsafeDecode(ptr3, chars[23], chars[24]);
				ptr[7] = (byte)num;
				int num9 = num8 | num;
				num = UnsafeDecode(ptr3, chars[28], chars[29]);
				ptr[8] = (byte)num;
				int num10 = num9 | num;
				num = UnsafeDecode(ptr3, chars[30], chars[31]);
				ptr[9] = (byte)num;
				int num11 = num10 | num;
				num = UnsafeDecode(ptr3, chars[33], chars[34]);
				ptr[10] = (byte)num;
				int num12 = num11 | num;
				num = UnsafeDecode(ptr3, chars[35], chars[36]);
				ptr[11] = (byte)num;
				int num13 = num12 | num;
				num = UnsafeDecode(ptr3, chars[37], chars[38]);
				ptr[12] = (byte)num;
				int num14 = num13 | num;
				num = UnsafeDecode(ptr3, chars[39], chars[40]);
				ptr[13] = (byte)num;
				int num15 = num14 | num;
				num = UnsafeDecode(ptr3, chars[41], chars[42]);
				ptr[14] = (byte)num;
				int num16 = num15 | num;
				num = UnsafeDecode(ptr3, chars[43], chars[44]);
				ptr[15] = (byte)num;
				if ((num16 | num) >= 256)
				{
					return;
				}
				idLow = UnsafeGetInt64(ptr);
				idHigh = UnsafeGetInt64(ptr + 8);
			}
		}

		[SecuritySafeCritical]
		public unsafe int ToCharArray(char[] chars, int offset)
		{
			int charArrayLength = CharArrayLength;
			if (chars == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > chars.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", chars.Length)));
			}
			if (charArrayLength > chars.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("chars", System.Runtime.Serialization.SR.GetString("Array too small.  Must be able to hold at least {0}.", charArrayLength)));
			}
			if (s != null)
			{
				s.CopyTo(0, chars, offset, charArrayLength);
			}
			else
			{
				byte* ptr = stackalloc byte[16];
				UnsafeSetInt64(idLow, ptr);
				UnsafeSetInt64(idHigh, ptr + 8);
				fixed (char* ptr2 = &chars[offset])
				{
					*ptr2 = 'u';
					ptr2[1] = 'r';
					ptr2[2] = 'n';
					ptr2[3] = ':';
					ptr2[4] = 'u';
					ptr2[5] = 'u';
					ptr2[6] = 'i';
					ptr2[7] = 'd';
					ptr2[8] = ':';
					ptr2[17] = '-';
					ptr2[22] = '-';
					ptr2[27] = '-';
					ptr2[32] = '-';
					fixed (char* ptr3 = "0123456789abcdef")
					{
						char* ptr4 = ptr3;
						UnsafeEncode(ptr4, *ptr, ptr2 + 15);
						UnsafeEncode(ptr4, ptr[1], ptr2 + 13);
						UnsafeEncode(ptr4, ptr[2], ptr2 + 11);
						UnsafeEncode(ptr4, ptr[3], ptr2 + 9);
						UnsafeEncode(ptr4, ptr[4], ptr2 + 20);
						UnsafeEncode(ptr4, ptr[5], ptr2 + 18);
						UnsafeEncode(ptr4, ptr[6], ptr2 + 25);
						UnsafeEncode(ptr4, ptr[7], ptr2 + 23);
						UnsafeEncode(ptr4, ptr[8], ptr2 + 28);
						UnsafeEncode(ptr4, ptr[9], ptr2 + 30);
						UnsafeEncode(ptr4, ptr[10], ptr2 + 33);
						UnsafeEncode(ptr4, ptr[11], ptr2 + 35);
						UnsafeEncode(ptr4, ptr[12], ptr2 + 37);
						UnsafeEncode(ptr4, ptr[13], ptr2 + 39);
						UnsafeEncode(ptr4, ptr[14], ptr2 + 41);
						UnsafeEncode(ptr4, ptr[15], ptr2 + 43);
					}
				}
			}
			return charArrayLength;
		}

		public bool TryGetGuid(out Guid guid)
		{
			byte[] array = new byte[16];
			if (!TryGetGuid(array, 0))
			{
				guid = Guid.Empty;
				return false;
			}
			guid = new Guid(array);
			return true;
		}

		[SecuritySafeCritical]
		public unsafe bool TryGetGuid(byte[] buffer, int offset)
		{
			if (!IsGuid)
			{
				return false;
			}
			if (buffer == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > buffer.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", buffer.Length)));
			}
			if (16 > buffer.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("buffer", System.Runtime.Serialization.SR.GetString("Array too small.  Must be able to hold at least {0}.", 16)));
			}
			fixed (byte* ptr = &buffer[offset])
			{
				UnsafeSetInt64(idLow, ptr);
				UnsafeSetInt64(idHigh, ptr + 8);
			}
			return true;
		}

		[SecuritySafeCritical]
		public override string ToString()
		{
			if (s == null)
			{
				int charArrayLength = CharArrayLength;
				char[] array = new char[charArrayLength];
				ToCharArray(array, 0);
				s = new string(array, 0, charArrayLength);
			}
			return s;
		}

		public static bool operator ==(UniqueId id1, UniqueId id2)
		{
			if ((object)id1 == null && (object)id2 == null)
			{
				return true;
			}
			if ((object)id1 == null || (object)id2 == null)
			{
				return false;
			}
			if (id1.IsGuid && id2.IsGuid)
			{
				if (id1.idLow == id2.idLow)
				{
					return id1.idHigh == id2.idHigh;
				}
				return false;
			}
			return id1.ToString() == id2.ToString();
		}

		public static bool operator !=(UniqueId id1, UniqueId id2)
		{
			return !(id1 == id2);
		}

		public override bool Equals(object obj)
		{
			return this == obj as UniqueId;
		}

		public override int GetHashCode()
		{
			if (IsGuid)
			{
				long num = idLow ^ idHigh;
				return (int)(num >> 32) ^ (int)num;
			}
			return ToString().GetHashCode();
		}

		[SecurityCritical]
		private unsafe long UnsafeGetInt64(byte* pb)
		{
			int num = UnsafeGetInt32(pb);
			return ((long)UnsafeGetInt32(pb + 4) << 32) | (uint)num;
		}

		[SecurityCritical]
		private unsafe int UnsafeGetInt32(byte* pb)
		{
			return (((((pb[3] << 8) | pb[2]) << 8) | pb[1]) << 8) | *pb;
		}

		[SecurityCritical]
		private unsafe void UnsafeSetInt64(long value, byte* pb)
		{
			UnsafeSetInt32((int)value, pb);
			UnsafeSetInt32((int)(value >> 32), pb + 4);
		}

		[SecurityCritical]
		private unsafe void UnsafeSetInt32(int value, byte* pb)
		{
			*pb = (byte)value;
			value >>= 8;
			pb[1] = (byte)value;
			value >>= 8;
			pb[2] = (byte)value;
			value >>= 8;
			pb[3] = (byte)value;
		}
	}
	internal enum ValueHandleConstStringType
	{
		String,
		Number,
		Array,
		Object,
		Boolean,
		Null
	}
	internal static class ValueHandleLength
	{
		public const int Int8 = 1;

		public const int Int16 = 2;

		public const int Int32 = 4;

		public const int Int64 = 8;

		public const int UInt64 = 8;

		public const int Single = 4;

		public const int Double = 8;

		public const int Decimal = 16;

		public const int DateTime = 8;

		public const int TimeSpan = 8;

		public const int Guid = 16;

		public const int UniqueId = 16;
	}
	internal enum ValueHandleType
	{
		Empty,
		True,
		False,
		Zero,
		One,
		Int8,
		Int16,
		Int32,
		Int64,
		UInt64,
		Single,
		Double,
		Decimal,
		DateTime,
		TimeSpan,
		Guid,
		UniqueId,
		UTF8,
		EscapedUTF8,
		Base64,
		Dictionary,
		List,
		Char,
		Unicode,
		QName,
		ConstString
	}
	internal class ValueHandle
	{
		private XmlBufferReader bufferReader;

		private ValueHandleType type;

		private int offset;

		private int length;

		private static Base64Encoding base64Encoding;

		private static string[] constStrings = new string[6] { "string", "number", "array", "object", "boolean", "null" };

		private static Base64Encoding Base64Encoding
		{
			get
			{
				if (base64Encoding == null)
				{
					base64Encoding = new Base64Encoding();
				}
				return base64Encoding;
			}
		}

		public ValueHandle(XmlBufferReader bufferReader)
		{
			this.bufferReader = bufferReader;
			type = ValueHandleType.Empty;
		}

		public void SetConstantValue(ValueHandleConstStringType constStringType)
		{
			type = ValueHandleType.ConstString;
			offset = (int)constStringType;
		}

		public void SetValue(ValueHandleType type)
		{
			this.type = type;
		}

		public void SetDictionaryValue(int key)
		{
			SetValue(ValueHandleType.Dictionary, key, 0);
		}

		public void SetCharValue(int ch)
		{
			SetValue(ValueHandleType.Char, ch, 0);
		}

		public void SetQNameValue(int prefix, int key)
		{
			SetValue(ValueHandleType.QName, key, prefix);
		}

		public void SetValue(ValueHandleType type, int offset, int length)
		{
			this.type = type;
			this.offset = offset;
			this.length = length;
		}

		public bool IsWhitespace()
		{
			switch (type)
			{
			case ValueHandleType.UTF8:
				return bufferReader.IsWhitespaceUTF8(offset, length);
			case ValueHandleType.Dictionary:
				return bufferReader.IsWhitespaceKey(offset);
			case ValueHandleType.Char:
			{
				int @char = GetChar();
				if (@char > 65535)
				{
					return false;
				}
				return XmlConverter.IsWhitespace((char)@char);
			}
			case ValueHandleType.EscapedUTF8:
				return bufferReader.IsWhitespaceUTF8(offset, length);
			case ValueHandleType.Unicode:
				return bufferReader.IsWhitespaceUnicode(offset, length);
			case ValueHandleType.True:
			case ValueHandleType.False:
			case ValueHandleType.Zero:
			case ValueHandleType.One:
				return false;
			case ValueHandleType.ConstString:
				return constStrings[offset].Length == 0;
			default:
				return length == 0;
			}
		}

		public Type ToType()
		{
			switch (type)
			{
			case ValueHandleType.True:
			case ValueHandleType.False:
				return typeof(bool);
			case ValueHandleType.Zero:
			case ValueHandleType.One:
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				return typeof(int);
			case ValueHandleType.Int64:
				return typeof(long);
			case ValueHandleType.UInt64:
				return typeof(ulong);
			case ValueHandleType.Single:
				return typeof(float);
			case ValueHandleType.Double:
				return typeof(double);
			case ValueHandleType.Decimal:
				return typeof(decimal);
			case ValueHandleType.DateTime:
				return typeof(DateTime);
			case ValueHandleType.Empty:
			case ValueHandleType.UTF8:
			case ValueHandleType.EscapedUTF8:
			case ValueHandleType.Dictionary:
			case ValueHandleType.Char:
			case ValueHandleType.Unicode:
			case ValueHandleType.QName:
			case ValueHandleType.ConstString:
				return typeof(string);
			case ValueHandleType.Base64:
				return typeof(byte[]);
			case ValueHandleType.List:
				return typeof(object[]);
			case ValueHandleType.UniqueId:
				return typeof(UniqueId);
			case ValueHandleType.Guid:
				return typeof(Guid);
			case ValueHandleType.TimeSpan:
				return typeof(TimeSpan);
			default:
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
			}
		}

		public bool ToBoolean()
		{
			switch (type)
			{
			case ValueHandleType.False:
				return false;
			case ValueHandleType.True:
				return true;
			case ValueHandleType.UTF8:
				return XmlConverter.ToBoolean(bufferReader.Buffer, offset, length);
			case ValueHandleType.Int8:
				switch (GetInt8())
				{
				case 0:
					return false;
				case 1:
					return true;
				}
				break;
			}
			return XmlConverter.ToBoolean(GetString());
		}

		public int ToInt()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Zero:
				return 0;
			case ValueHandleType.One:
				return 1;
			case ValueHandleType.Int8:
				return GetInt8();
			case ValueHandleType.Int16:
				return GetInt16();
			case ValueHandleType.Int32:
				return GetInt32();
			case ValueHandleType.Int64:
			{
				long @int = GetInt64();
				if (@int >= int.MinValue && @int <= int.MaxValue)
				{
					return (int)@int;
				}
				break;
			}
			}
			if (valueHandleType == ValueHandleType.UInt64)
			{
				ulong uInt = GetUInt64();
				if (uInt <= int.MaxValue)
				{
					return (int)uInt;
				}
			}
			if (valueHandleType == ValueHandleType.UTF8)
			{
				return XmlConverter.ToInt32(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToInt32(GetString());
		}

		public long ToLong()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Zero:
				return 0L;
			case ValueHandleType.One:
				return 1L;
			case ValueHandleType.Int8:
				return GetInt8();
			case ValueHandleType.Int16:
				return GetInt16();
			case ValueHandleType.Int32:
				return GetInt32();
			case ValueHandleType.Int64:
				return GetInt64();
			case ValueHandleType.UInt64:
			{
				ulong uInt = GetUInt64();
				if (uInt <= long.MaxValue)
				{
					return (long)uInt;
				}
				break;
			}
			}
			if (valueHandleType == ValueHandleType.UTF8)
			{
				return XmlConverter.ToInt64(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToInt64(GetString());
		}

		public ulong ToULong()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Zero:
				return 0uL;
			case ValueHandleType.One:
				return 1uL;
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
			case ValueHandleType.Int64:
			{
				long num = ToLong();
				if (num >= 0)
				{
					return (ulong)num;
				}
				break;
			}
			}
			return valueHandleType switch
			{
				ValueHandleType.UInt64 => GetUInt64(), 
				ValueHandleType.UTF8 => XmlConverter.ToUInt64(bufferReader.Buffer, offset, length), 
				_ => XmlConverter.ToUInt64(GetString()), 
			};
		}

		public float ToSingle()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Single:
				return GetSingle();
			case ValueHandleType.Double:
			{
				double @double = GetDouble();
				if ((@double >= -3.4028234663852886E+38 && @double <= 3.4028234663852886E+38) || double.IsInfinity(@double) || double.IsNaN(@double))
				{
					return (float)@double;
				}
				break;
			}
			}
			return valueHandleType switch
			{
				ValueHandleType.Zero => 0f, 
				ValueHandleType.One => 1f, 
				ValueHandleType.Int8 => GetInt8(), 
				ValueHandleType.Int16 => GetInt16(), 
				ValueHandleType.UTF8 => XmlConverter.ToSingle(bufferReader.Buffer, offset, length), 
				_ => XmlConverter.ToSingle(GetString()), 
			};
		}

		public double ToDouble()
		{
			return type switch
			{
				ValueHandleType.Double => GetDouble(), 
				ValueHandleType.Single => GetSingle(), 
				ValueHandleType.Zero => 0.0, 
				ValueHandleType.One => 1.0, 
				ValueHandleType.Int8 => GetInt8(), 
				ValueHandleType.Int16 => GetInt16(), 
				ValueHandleType.Int32 => GetInt32(), 
				ValueHandleType.UTF8 => XmlConverter.ToDouble(bufferReader.Buffer, offset, length), 
				_ => XmlConverter.ToDouble(GetString()), 
			};
		}

		public decimal ToDecimal()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Decimal:
				return GetDecimal();
			case ValueHandleType.Zero:
				return 0m;
			case ValueHandleType.One:
				return 1m;
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
			case ValueHandleType.Int64:
				return ToLong();
			default:
				return valueHandleType switch
				{
					ValueHandleType.UInt64 => GetUInt64(), 
					ValueHandleType.UTF8 => XmlConverter.ToDecimal(bufferReader.Buffer, offset, length), 
					_ => XmlConverter.ToDecimal(GetString()), 
				};
			}
		}

		public DateTime ToDateTime()
		{
			if (type == ValueHandleType.DateTime)
			{
				return XmlConverter.ToDateTime(GetInt64());
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToDateTime(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToDateTime(GetString());
		}

		public UniqueId ToUniqueId()
		{
			if (type == ValueHandleType.UniqueId)
			{
				return GetUniqueId();
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToUniqueId(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToUniqueId(GetString());
		}

		public TimeSpan ToTimeSpan()
		{
			if (type == ValueHandleType.TimeSpan)
			{
				return new TimeSpan(GetInt64());
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToTimeSpan(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToTimeSpan(GetString());
		}

		public Guid ToGuid()
		{
			if (type == ValueHandleType.Guid)
			{
				return GetGuid();
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToGuid(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToGuid(GetString());
		}

		public override string ToString()
		{
			return GetString();
		}

		public byte[] ToByteArray()
		{
			if (type == ValueHandleType.Base64)
			{
				byte[] array = new byte[length];
				GetBase64(array, 0, length);
				return array;
			}
			if (type == ValueHandleType.UTF8 && length % 4 == 0)
			{
				try
				{
					int num = length / 4 * 3;
					if (length > 0 && bufferReader.Buffer[offset + length - 1] == 61)
					{
						num--;
						if (bufferReader.Buffer[offset + length - 2] == 61)
						{
							num--;
						}
					}
					byte[] array2 = new byte[num];
					int bytes = Base64Encoding.GetBytes(bufferReader.Buffer, offset, length, array2, 0);
					if (bytes != array2.Length)
					{
						byte[] array3 = new byte[bytes];
						Buffer.BlockCopy(array2, 0, array3, 0, bytes);
						array2 = array3;
					}
					return array2;
				}
				catch (FormatException)
				{
				}
			}
			try
			{
				return Base64Encoding.GetBytes(XmlConverter.StripWhitespace(GetString()));
			}
			catch (FormatException ex2)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(ex2.Message, ex2.InnerException));
			}
		}

		public string GetString()
		{
			ValueHandleType valueHandleType = type;
			if (valueHandleType == ValueHandleType.UTF8)
			{
				return GetCharsText();
			}
			switch (valueHandleType)
			{
			case ValueHandleType.False:
				return "false";
			case ValueHandleType.True:
				return "true";
			case ValueHandleType.Zero:
				return "0";
			case ValueHandleType.One:
				return "1";
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				return XmlConverter.ToString(ToInt());
			case ValueHandleType.Int64:
				return XmlConverter.ToString(GetInt64());
			case ValueHandleType.UInt64:
				return XmlConverter.ToString(GetUInt64());
			case ValueHandleType.Single:
				return XmlConverter.ToString(GetSingle());
			case ValueHandleType.Double:
				return XmlConverter.ToString(GetDouble());
			case ValueHandleType.Decimal:
				return XmlConverter.ToString(GetDecimal());
			case ValueHandleType.DateTime:
				return XmlConverter.ToString(ToDateTime());
			case ValueHandleType.Empty:
				return string.Empty;
			case ValueHandleType.UTF8:
				return GetCharsText();
			case ValueHandleType.Unicode:
				return GetUnicodeCharsText();
			case ValueHandleType.EscapedUTF8:
				return GetEscapedCharsText();
			case ValueHandleType.Char:
				return GetCharText();
			case ValueHandleType.Dictionary:
				return GetDictionaryString().Value;
			case ValueHandleType.Base64:
				return Base64Encoding.GetString(ToByteArray());
			case ValueHandleType.List:
				return XmlConverter.ToString(ToList());
			case ValueHandleType.UniqueId:
				return XmlConverter.ToString(ToUniqueId());
			case ValueHandleType.Guid:
				return XmlConverter.ToString(ToGuid());
			case ValueHandleType.TimeSpan:
				return XmlConverter.ToString(ToTimeSpan());
			case ValueHandleType.QName:
				return GetQNameDictionaryText();
			case ValueHandleType.ConstString:
				return constStrings[offset];
			default:
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
			}
		}

		public bool Equals2(string str, bool checkLower)
		{
			if (type != ValueHandleType.UTF8)
			{
				return GetString() == str;
			}
			if (length != str.Length)
			{
				return false;
			}
			byte[] buffer = bufferReader.Buffer;
			for (int i = 0; i < length; i++)
			{
				byte b = buffer[i + offset];
				if (b != str[i] && (!checkLower || char.ToLowerInvariant((char)b) != str[i]))
				{
					return false;
				}
			}
			return true;
		}

		public void Sign(XmlSigningNodeWriter writer)
		{
			switch (type)
			{
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				writer.WriteInt32Text(ToInt());
				break;
			case ValueHandleType.Int64:
				writer.WriteInt64Text(GetInt64());
				break;
			case ValueHandleType.UInt64:
				writer.WriteUInt64Text(GetUInt64());
				break;
			case ValueHandleType.Single:
				writer.WriteFloatText(GetSingle());
				break;
			case ValueHandleType.Double:
				writer.WriteDoubleText(GetDouble());
				break;
			case ValueHandleType.Decimal:
				writer.WriteDecimalText(GetDecimal());
				break;
			case ValueHandleType.DateTime:
				writer.WriteDateTimeText(ToDateTime());
				break;
			case ValueHandleType.UTF8:
				writer.WriteEscapedText(bufferReader.Buffer, offset, length);
				break;
			case ValueHandleType.Base64:
				writer.WriteBase64Text(bufferReader.Buffer, 0, bufferReader.Buffer, offset, length);
				break;
			case ValueHandleType.UniqueId:
				writer.WriteUniqueIdText(ToUniqueId());
				break;
			case ValueHandleType.Guid:
				writer.WriteGuidText(ToGuid());
				break;
			case ValueHandleType.TimeSpan:
				writer.WriteTimeSpanText(ToTimeSpan());
				break;
			default:
				writer.WriteEscapedText(GetString());
				break;
			case ValueHandleType.Empty:
				break;
			}
		}

		public object[] ToList()
		{
			return bufferReader.GetList(offset, length);
		}

		public object ToObject()
		{
			switch (type)
			{
			case ValueHandleType.True:
			case ValueHandleType.False:
				return ToBoolean();
			case ValueHandleType.Zero:
			case ValueHandleType.One:
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				return ToInt();
			case ValueHandleType.Int64:
				return ToLong();
			case ValueHandleType.UInt64:
				return GetUInt64();
			case ValueHandleType.Single:
				return ToSingle();
			case ValueHandleType.Double:
				return ToDouble();
			case ValueHandleType.Decimal:
				return ToDecimal();
			case ValueHandleType.DateTime:
				return ToDateTime();
			case ValueHandleType.Empty:
			case ValueHandleType.UTF8:
			case ValueHandleType.EscapedUTF8:
			case ValueHandleType.Dictionary:
			case ValueHandleType.Char:
			case ValueHandleType.Unicode:
			case ValueHandleType.ConstString:
				return ToString();
			case ValueHandleType.Base64:
				return ToByteArray();
			case ValueHandleType.List:
				return ToList();
			case ValueHandleType.UniqueId:
				return ToUniqueId();
			case ValueHandleType.Guid:
				return ToGuid();
			case ValueHandleType.TimeSpan:
				return ToTimeSpan();
			default:
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
			}
		}

		public bool TryReadBase64(byte[] buffer, int offset, int count, out int actual)
		{
			if (type == ValueHandleType.Base64)
			{
				actual = Math.Min(length, count);
				GetBase64(buffer, offset, actual);
				this.offset += actual;
				length -= actual;
				return true;
			}
			if (type == ValueHandleType.UTF8 && count >= 3 && length % 4 == 0)
			{
				try
				{
					int num = Math.Min(count / 3 * 4, length);
					actual = Base64Encoding.GetBytes(bufferReader.Buffer, this.offset, num, buffer, offset);
					this.offset += num;
					length -= num;
					return true;
				}
				catch (FormatException)
				{
				}
			}
			actual = 0;
			return false;
		}

		public bool TryReadChars(char[] chars, int offset, int count, out int actual)
		{
			if (type == ValueHandleType.Unicode)
			{
				return TryReadUnicodeChars(chars, offset, count, out actual);
			}
			if (type != ValueHandleType.UTF8)
			{
				actual = 0;
				return false;
			}
			int num = offset;
			int num2 = count;
			byte[] buffer = bufferReader.Buffer;
			int num3 = this.offset;
			int num4 = length;
			bool flag = false;
			while (true)
			{
				if (num2 > 0 && num4 > 0)
				{
					byte b = buffer[num3];
					if (b < 128)
					{
						chars[num] = (char)b;
						num3++;
						num4--;
						num++;
						num2--;
						continue;
					}
				}
				if (num2 == 0 || num4 == 0 || flag)
				{
					break;
				}
				UTF8Encoding uTF8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
				int chars2;
				int num5;
				try
				{
					if (num2 >= uTF8Encoding.GetMaxCharCount(num4) || num2 >= uTF8Encoding.GetCharCount(buffer, num3, num4))
					{
						chars2 = uTF8Encoding.GetChars(buffer, num3, num4, chars, num);
						num5 = num4;
					}
					else
					{
						Decoder decoder = uTF8Encoding.GetDecoder();
						num5 = Math.Min(num2, num4);
						chars2 = decoder.GetChars(buffer, num3, num5, chars, num);
						while (chars2 == 0)
						{
							if (num5 >= 3 && num2 < 2)
							{
								flag = true;
								break;
							}
							chars2 = decoder.GetChars(buffer, num3 + num5, 1, chars, num);
							num5++;
						}
						num5 = uTF8Encoding.GetByteCount(chars, num, chars2);
					}
				}
				catch (FormatException exception)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(buffer, num3, num4, exception));
				}
				num3 += num5;
				num4 -= num5;
				num += chars2;
				num2 -= chars2;
			}
			this.offset = num3;
			length = num4;
			actual = count - num2;
			return true;
		}

		private bool TryReadUnicodeChars(char[] chars, int offset, int count, out int actual)
		{
			int num = Math.Min(count, length / 2);
			for (int i = 0; i < num; i++)
			{
				chars[offset + i] = (char)bufferReader.GetInt16(this.offset + i * 2);
			}
			this.offset += num * 2;
			length -= num * 2;
			actual = num;
			return true;
		}

		public bool TryGetDictionaryString(out XmlDictionaryString value)
		{
			if (type == ValueHandleType.Dictionary)
			{
				value = GetDictionaryString();
				return true;
			}
			value = null;
			return false;
		}

		public bool TryGetByteArrayLength(out int length)
		{
			if (type == ValueHandleType.Base64)
			{
				length = this.length;
				return true;
			}
			length = 0;
			return false;
		}

		private string GetCharsText()
		{
			if (length == 1 && bufferReader.GetByte(offset) == 49)
			{
				return "1";
			}
			return bufferReader.GetString(offset, length);
		}

		private string GetUnicodeCharsText()
		{
			return bufferReader.GetUnicodeString(offset, length);
		}

		private string GetEscapedCharsText()
		{
			return bufferReader.GetEscapedString(offset, length);
		}

		private string GetCharText()
		{
			int @char = GetChar();
			if (@char > 65535)
			{
				SurrogateChar surrogateChar = new SurrogateChar(@char);
				return new string(new char[2] { surrogateChar.HighChar, surrogateChar.LowChar }, 0, 2);
			}
			return ((char)@char).ToString();
		}

		private int GetChar()
		{
			return offset;
		}

		private int GetInt8()
		{
			return bufferReader.GetInt8(offset);
		}

		private int GetInt16()
		{
			return bufferReader.GetInt16(offset);
		}

		private int GetInt32()
		{
			return bufferReader.GetInt32(offset);
		}

		private long GetInt64()
		{
			return bufferReader.GetInt64(offset);
		}

		private ulong GetUInt64()
		{
			return bufferReader.GetUInt64(offset);
		}

		private float GetSingle()
		{
			return bufferReader.GetSingle(offset);
		}

		private double GetDouble()
		{
			return bufferReader.GetDouble(offset);
		}

		private decimal GetDecimal()
		{
			return bufferReader.GetDecimal(offset);
		}

		private UniqueId GetUniqueId()
		{
			return bufferReader.GetUniqueId(offset);
		}

		private Guid GetGuid()
		{
			return bufferReader.GetGuid(offset);
		}

		private void GetBase64(byte[] buffer, int offset, int count)
		{
			bufferReader.GetBase64(this.offset, buffer, offset, count);
		}

		private XmlDictionaryString GetDictionaryString()
		{
			return bufferReader.GetDictionaryString(offset);
		}

		private string GetQNameDictionaryText()
		{
			return PrefixHandle.GetString(PrefixHandle.GetAlphaPrefix(length)) + ":" + bufferReader.GetDictionaryString(offset);
		}
	}
	internal abstract class XmlBaseReader : XmlDictionaryReader
	{
		protected enum QNameType
		{
			Normal,
			Xmlns
		}

		protected class XmlNode
		{
			protected enum XmlNodeFlags
			{
				None = 0,
				CanGetAttribute = 1,
				CanMoveToElement = 2,
				HasValue = 4,
				AtomicValue = 8,
				SkipValue = 0x10,
				HasContent = 0x20
			}

			private XmlNodeType nodeType;

			private PrefixHandle prefix;

			private StringHandle localName;

			private ValueHandle value;

			private Namespace ns;

			private bool hasValue;

			private bool canGetAttribute;

			private bool canMoveToElement;

			private ReadState readState;

			private XmlAttributeTextNode attributeTextNode;

			private bool exitScope;

			private int depthDelta;

			private bool isAtomicValue;

			private bool skipValue;

			private QNameType qnameType;

			private bool hasContent;

			private bool isEmptyElement;

			private char quoteChar;

			public bool HasValue => hasValue;

			public ReadState ReadState => readState;

			public StringHandle LocalName => localName;

			public PrefixHandle Prefix => prefix;

			public bool CanGetAttribute => canGetAttribute;

			public bool CanMoveToElement => canMoveToElement;

			public XmlAttributeTextNode AttributeText => attributeTextNode;

			public bool SkipValue => skipValue;

			public ValueHandle Value => value;

			public int DepthDelta => depthDelta;

			public bool HasContent => hasContent;

			public XmlNodeType NodeType
			{
				get
				{
					return nodeType;
				}
				set
				{
					nodeType = value;
				}
			}

			public QNameType QNameType
			{
				get
				{
					return qnameType;
				}
				set
				{
					qnameType = value;
				}
			}

			public Namespace Namespace
			{
				get
				{
					return ns;
				}
				set
				{
					ns = value;
				}
			}

			public bool IsAtomicValue
			{
				get
				{
					return isAtomicValue;
				}
				set
				{
					isAtomicValue = value;
				}
			}

			public bool ExitScope
			{
				get
				{
					return exitScope;
				}
				set
				{
					exitScope = value;
				}
			}

			public bool IsEmptyElement
			{
				get
				{
					return isEmptyElement;
				}
				set
				{
					isEmptyElement = value;
				}
			}

			public char QuoteChar
			{
				get
				{
					return quoteChar;
				}
				set
				{
					quoteChar = value;
				}
			}

			public string ValueAsString
			{
				get
				{
					if (qnameType == QNameType.Normal)
					{
						return Value.GetString();
					}
					return Namespace.Uri.GetString();
				}
			}

			protected XmlNode(XmlNodeType nodeType, PrefixHandle prefix, StringHandle localName, ValueHandle value, XmlNodeFlags nodeFlags, ReadState readState, XmlAttributeTextNode attributeTextNode, int depthDelta)
			{
				this.nodeType = nodeType;
				this.prefix = prefix;
				this.localName = localName;
				this.value = value;
				ns = NamespaceManager.EmptyNamespace;
				hasValue = (nodeFlags & XmlNodeFlags.HasValue) != 0;
				canGetAttribute = (nodeFlags & XmlNodeFlags.CanGetAttribute) != 0;
				canMoveToElement = (nodeFlags & XmlNodeFlags.CanMoveToElement) != 0;
				isAtomicValue = (nodeFlags & XmlNodeFlags.AtomicValue) != 0;
				skipValue = (nodeFlags & XmlNodeFlags.SkipValue) != 0;
				hasContent = (nodeFlags & XmlNodeFlags.HasContent) != 0;
				this.readState = readState;
				this.attributeTextNode = attributeTextNode;
				exitScope = nodeType == XmlNodeType.EndElement;
				this.depthDelta = depthDelta;
				isEmptyElement = false;
				quoteChar = '"';
				qnameType = QNameType.Normal;
			}

			public bool IsLocalName(string localName)
			{
				if (qnameType == QNameType.Normal)
				{
					return LocalName == localName;
				}
				return Namespace.Prefix == localName;
			}

			public bool IsLocalName(XmlDictionaryString localName)
			{
				if (qnameType == QNameType.Normal)
				{
					return LocalName == localName;
				}
				return Namespace.Prefix == localName;
			}

			public bool IsNamespaceUri(string ns)
			{
				if (qnameType == QNameType.Normal)
				{
					return Namespace.IsUri(ns);
				}
				return ns == "http://www.w3.org/2000/xmlns/";
			}

			public bool IsNamespaceUri(XmlDictionaryString ns)
			{
				if (qnameType == QNameType.Normal)
				{
					return Namespace.IsUri(ns);
				}
				return ns.Value == "http://www.w3.org/2000/xmlns/";
			}

			public bool IsLocalNameAndNamespaceUri(string localName, string ns)
			{
				if (qnameType == QNameType.Normal)
				{
					if (LocalName == localName)
					{
						return Namespace.IsUri(ns);
					}
					return false;
				}
				if (Namespace.Prefix == localName)
				{
					return ns == "http://www.w3.org/2000/xmlns/";
				}
				return false;
			}

			public bool IsLocalNameAndNamespaceUri(XmlDictionaryString localName, XmlDictionaryString ns)
			{
				if (qnameType == QNameType.Normal)
				{
					if (LocalName == localName)
					{
						return Namespace.IsUri(ns);
					}
					return false;
				}
				if (Namespace.Prefix == localName)
				{
					return ns.Value == "http://www.w3.org/2000/xmlns/";
				}
				return false;
			}

			public bool IsPrefixAndLocalName(string prefix, string localName)
			{
				if (qnameType == QNameType.Normal)
				{
					if (Prefix == prefix)
					{
						return LocalName == localName;
					}
					return false;
				}
				if (prefix == "xmlns")
				{
					return Namespace.Prefix == localName;
				}
				return false;
			}

			public bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName)
			{
				if (qnameType == QNameType.Normal)
				{
					return LocalName.TryGetDictionaryString(out localName);
				}
				localName = null;
				return false;
			}

			public bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString ns)
			{
				if (qnameType == QNameType.Normal)
				{
					return Namespace.Uri.TryGetDictionaryString(out ns);
				}
				ns = null;
				return false;
			}

			public bool TryGetValueAsDictionaryString(out XmlDictionaryString value)
			{
				if (qnameType == QNameType.Normal)
				{
					return Value.TryGetDictionaryString(out value);
				}
				value = null;
				return false;
			}
		}

		protected class XmlElementNode : XmlNode
		{
			private XmlEndElementNode endElementNode;

			private int bufferOffset;

			public int NameOffset;

			public int NameLength;

			public XmlEndElementNode EndElement => endElementNode;

			public int BufferOffset
			{
				get
				{
					return bufferOffset;
				}
				set
				{
					bufferOffset = value;
				}
			}

			public XmlElementNode(XmlBufferReader bufferReader)
				: this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader))
			{
			}

			private XmlElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.Element, prefix, localName, value, (XmlNodeFlags)33, ReadState.Interactive, null, -1)
			{
				endElementNode = new XmlEndElementNode(prefix, localName, value);
			}
		}

		protected class XmlAttributeNode : XmlNode
		{
			public XmlAttributeNode(XmlBufferReader bufferReader)
				: this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader))
			{
			}

			private XmlAttributeNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.Attribute, prefix, localName, value, (XmlNodeFlags)15, ReadState.Interactive, new XmlAttributeTextNode(prefix, localName, value), 0)
			{
			}
		}

		protected class XmlEndElementNode : XmlNode
		{
			public XmlEndElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.EndElement, prefix, localName, value, XmlNodeFlags.HasContent, ReadState.Interactive, null, -1)
			{
			}
		}

		protected class XmlTextNode : XmlNode
		{
			protected XmlTextNode(XmlNodeType nodeType, PrefixHandle prefix, StringHandle localName, ValueHandle value, XmlNodeFlags nodeFlags, ReadState readState, XmlAttributeTextNode attributeTextNode, int depthDelta)
				: base(nodeType, prefix, localName, value, nodeFlags, readState, attributeTextNode, depthDelta)
			{
			}
		}

		protected class XmlAtomicTextNode : XmlTextNode
		{
			public XmlAtomicTextNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Text, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), (XmlNodeFlags)60, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlComplexTextNode : XmlTextNode
		{
			public XmlComplexTextNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Text, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), (XmlNodeFlags)36, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlWhitespaceTextNode : XmlTextNode
		{
			public XmlWhitespaceTextNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Whitespace, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlCDataNode : XmlTextNode
		{
			public XmlCDataNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.CDATA, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), (XmlNodeFlags)36, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlAttributeTextNode : XmlTextNode
		{
			public XmlAttributeTextNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.Text, prefix, localName, value, (XmlNodeFlags)47, ReadState.Interactive, null, 1)
			{
			}
		}

		protected class XmlInitialNode : XmlNode
		{
			public XmlInitialNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.Initial, null, 0)
			{
			}
		}

		protected class XmlDeclarationNode : XmlNode
		{
			public XmlDeclarationNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.XmlDeclaration, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.CanGetAttribute, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlCommentNode : XmlNode
		{
			public XmlCommentNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Comment, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlEndOfFileNode : XmlNode
		{
			public XmlEndOfFileNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.EndOfFile, null, 0)
			{
			}
		}

		protected class XmlClosedNode : XmlNode
		{
			public XmlClosedNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.Closed, null, 0)
			{
			}
		}

		private class AttributeSorter : IComparer
		{
			private object[] indeces;

			private XmlAttributeNode[] attributeNodes;

			private int attributeCount;

			private int attributeIndex1;

			private int attributeIndex2;

			public bool Sort(XmlAttributeNode[] attributeNodes, int attributeCount)
			{
				attributeIndex1 = -1;
				attributeIndex2 = -1;
				this.attributeNodes = attributeNodes;
				this.attributeCount = attributeCount;
				bool result = Sort();
				this.attributeNodes = null;
				this.attributeCount = 0;
				return result;
			}

			public void GetIndeces(out int attributeIndex1, out int attributeIndex2)
			{
				attributeIndex1 = this.attributeIndex1;
				attributeIndex2 = this.attributeIndex2;
			}

			public void Close()
			{
				if (indeces != null && indeces.Length > 32)
				{
					indeces = null;
				}
			}

			private bool Sort()
			{
				if (indeces != null && indeces.Length == attributeCount && IsSorted())
				{
					return true;
				}
				object[] array = new object[attributeCount];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = i;
				}
				indeces = array;
				Array.Sort(indeces, 0, attributeCount, this);
				return IsSorted();
			}

			private bool IsSorted()
			{
				for (int i = 0; i < indeces.Length - 1; i++)
				{
					if (Compare(indeces[i], indeces[i + 1]) >= 0)
					{
						attributeIndex1 = (int)indeces[i];
						attributeIndex2 = (int)indeces[i + 1];
						return false;
					}
				}
				return true;
			}

			public int Compare(object obj1, object obj2)
			{
				int num = (int)obj1;
				int num2 = (int)obj2;
				XmlAttributeNode xmlAttributeNode = attributeNodes[num];
				XmlAttributeNode xmlAttributeNode2 = attributeNodes[num2];
				int num3 = CompareQNameType(xmlAttributeNode.QNameType, xmlAttributeNode2.QNameType);
				if (num3 == 0)
				{
					if (xmlAttributeNode.QNameType == QNameType.Normal)
					{
						num3 = xmlAttributeNode.LocalName.CompareTo(xmlAttributeNode2.LocalName);
						if (num3 == 0)
						{
							num3 = xmlAttributeNode.Namespace.Uri.CompareTo(xmlAttributeNode2.Namespace.Uri);
						}
					}
					else
					{
						num3 = xmlAttributeNode.Namespace.Prefix.CompareTo(xmlAttributeNode2.Namespace.Prefix);
					}
				}
				return num3;
			}

			public int CompareQNameType(QNameType type1, QNameType type2)
			{
				return type1 - type2;
			}
		}

		private class NamespaceManager
		{
			private class XmlAttribute
			{
				private XmlSpace space;

				private string lang;

				private int depth;

				public int Depth
				{
					get
					{
						return depth;
					}
					set
					{
						depth = value;
					}
				}

				public string XmlLang
				{
					get
					{
						return lang;
					}
					set
					{
						lang = value;
					}
				}

				public XmlSpace XmlSpace
				{
					get
					{
						return space;
					}
					set
					{
						space = value;
					}
				}
			}

			private XmlBufferReader bufferReader;

			private Namespace[] namespaces;

			private int nsCount;

			private int depth;

			private Namespace[] shortPrefixUri;

			private static Namespace emptyNamespace = new Namespace(XmlBufferReader.Empty);

			private static Nam

LootGoblinsHeimUtils.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using LootGoblinsUtils.Creatures;
using LootGoblinsUtils.Hooks;
using LootGoblinsUtils.Pieces;
using LootGoblinsUtils.Pieces.Configurators;
using LootGoblinsUtils.Pieces.Stations;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LootGoblinsHeimUtils")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LootGoblinsHeimUtils")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace LootGoblinsUtils
{
	public static class PluginConfiguration
	{
		public static ConfigEntry<float> FertilizingDuration;

		public static ConfigEntry<float> PlantGrowMinDuration;

		public static ConfigEntry<float> PlantGrowMaxDuration;

		public static ConfigEntry<bool> ReliableBlockToggle;

		public static void InitConfigs(BaseUnityPlugin plugin)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			FertilizingDuration = plugin.Config.Bind<float>("Defaults", "FertilizingDuration", 4500f, new ConfigDescription("Длительность роста продуктов", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), new object[1] { val }));
			PlantGrowMinDuration = plugin.Config.Bind<float>("Defaults", "PlantGrowMinDuration", 4000f, new ConfigDescription("Минимальная длительность роста растений", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), new object[1] { val }));
			PlantGrowMaxDuration = plugin.Config.Bind<float>("Defaults", "PlantGrowMaxDuration", 5000f, new ConfigDescription("Максимальная длительность роста растений", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), new object[1] { val }));
			ReliableBlockToggle = plugin.Config.Bind<bool>("Defaults", "ReliableBlockToggle", true, new ConfigDescription("Во включенном состоянии снижение урона блокированием работает даже если получено оглушение, что делает блокирование более предсказуемым", (AcceptableValueBase)null, new object[1] { val }));
		}
	}
	[BepInPlugin("com.lootgoblinsheim.utils", "LootGoblinsHeimUtils", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class LootGoblinsHeimUtilsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.lootgoblinsheim.utils";

		public const string PluginName = "LootGoblinsHeimUtils";

		public const string PluginVersion = "1.0.0";

		private readonly Harmony _harmony = new Harmony("com.lootgoblinsheim.utils");

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

		private static KeyboardShortcut ToggleShortcut;

		private static KeyboardShortcut ToggleLoggingShortcut;

		public static bool OptimizationsEnabled;

		public static bool LoggingEnabled;

		public static bool IsServer => (int)SystemInfo.graphicsDeviceType == 4;

		private void Awake()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInfo((object)"LootGoblinsHeimUtilsPlugin has landed ");
			ToggleShortcut = new KeyboardShortcut((KeyCode)304, (KeyCode[])(object)new KeyCode[1] { (KeyCode)116 });
			ToggleLoggingShortcut = new KeyboardShortcut((KeyCode)304, (KeyCode[])(object)new KeyCode[1] { (KeyCode)121 });
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			ProfilePatcher.Patch(_harmony);
			PluginConfiguration.InitConfigs((BaseUnityPlugin)(object)this);
			PrefabManager.OnVanillaPrefabsAvailable += Setup;
		}

		private void Update()
		{
			if (((KeyboardShortcut)(ref ToggleShortcut)).IsDown())
			{
				OptimizationsEnabled = !OptimizationsEnabled;
				((BaseUnityPlugin)this).Logger.LogMessage((object)$"OptimizationsEnabled set to {OptimizationsEnabled}");
			}
			if (((KeyboardShortcut)(ref ToggleLoggingShortcut)).IsDown())
			{
				LoggingEnabled = !LoggingEnabled;
				((BaseUnityPlugin)this).Logger.LogMessage((object)$"LoggingEnabled set to {LoggingEnabled}");
			}
		}

		private void LateUpdate()
		{
			if (OptimizationsEnabled)
			{
				ProfilePatcher.LateUpdate();
			}
		}

		private void CreatureManagerOnOnVanillaCreaturesAvailable()
		{
			CreatureDB.LoadCreatures();
			CreatureManager.OnVanillaCreaturesAvailable -= CreatureManagerOnOnVanillaCreaturesAvailable;
		}

		private void Setup()
		{
			Logger.LogInfo((object)"------------ LootGoblinsHeimUtilsPlugin start ------------");
			BushUtils.CacheDependencies();
			FarmersTable.Configure();
			FarmersTableExtensionT1.Configure();
			RaspberryBush.Setup();
			BlueberryBush.Setup();
			CloudberryBush.Setup();
			ThistleBush.Setup();
			Mushroom.Configure();
			MushroomYellow.Configure();
			Dandelion.Configure();
			Saplings.ReplaceRecipes();
			Logger.LogInfo((object)"------------ LootGoblinsHeimUtilsPlugin end ------------");
			PrefabManager.OnVanillaPrefabsAvailable -= Setup;
		}
	}
}
namespace LootGoblinsUtils.Submods.ReliableBlock
{
	[HarmonyPatch(typeof(Character), "AddStaggerDamage")]
	public static class Hook
	{
		public static void Postfix(ref bool __result)
		{
			if (PluginConfiguration.ReliableBlockToggle.Value)
			{
				__result = false;
			}
		}
	}
}
namespace LootGoblinsUtils.Pieces
{
	public static class BlueberryBush
	{
		public static void Setup()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			BushConfiguration bushConfiguration = new BushConfiguration();
			bushConfiguration.Name = "Blueberries";
			bushConfiguration.LocalizedBushName = "Куст черники";
			bushConfiguration.ReadyObjectName = "Berrys";
			bushConfiguration.FertilizerIcon = BushUtils.BlueberryBushIcon;
			bushConfiguration.NewBushModel = BushUtils.BlueberryBushModel;
			bushConfiguration.BushRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Blueberries", 5, 0, false),
				new RequirementConfig("BoneFragments", 3, 0, false)
			};
			bushConfiguration.FertilizerConfigs = new BushConfiguration.FertilizerConfig[2]
			{
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для черники",
					LocalizedDescription = "Добавьте в куст черники, чтобы запустить процесс роста",
					AmountProduced = 5,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[1]
					{
						new RequirementConfig("BoneFragments", 2, 0, false)
					}
				},
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для черники насыщенное",
					LocalizedDescription = "Добавьте в куст черники, чтобы запустить процесс роста. Увеличивает количество получаемого продукта",
					AmountProduced = 10,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
					{
						new RequirementConfig("BoneFragments", 2, 0, false),
						new RequirementConfig("Entrails", 1, 0, false)
					}
				}
			};
			bushConfiguration.Configure();
		}
	}
	public static class CloudberryBush
	{
		public static void Setup()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			BushConfiguration bushConfiguration = new BushConfiguration();
			bushConfiguration.Name = "Cloudberry";
			bushConfiguration.LocalizedBushName = "Куст морошки";
			bushConfiguration.ReadyObjectName = "Berrys";
			bushConfiguration.ColliderRadius = 0.7f;
			bushConfiguration.FertilizerIcon = BushUtils.CloudberryVisuals.Icon;
			bushConfiguration.NewBushModel = BushUtils.CloudberryVisuals.Model;
			bushConfiguration.BushRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Cloudberry", 5, 0, false),
				new RequirementConfig("Bloodbag", 2, 0, false)
			};
			bushConfiguration.FertilizerConfigs = new BushConfiguration.FertilizerConfig[2]
			{
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для морошки",
					LocalizedDescription = "Добавьте в куст морошки, чтобы запустить процесс роста",
					AmountProduced = 5,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[1]
					{
						new RequirementConfig("Bloodbag", 3, 0, false)
					}
				},
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для морошки насыщенное",
					LocalizedDescription = "Добавьте в куст морошки, чтобы запустить процесс роста. Увеличивает количество получаемого продукта",
					AmountProduced = 10,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
					{
						new RequirementConfig("Bloodbag", 3, 0, false),
						new RequirementConfig("Ooze", 1, 0, false)
					}
				}
			};
			bushConfiguration.Configure();
		}
	}
	public static class Dandelion
	{
		public const string PieceName = "$piece_dandelion_LG";

		public static void Configure()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			CustomLocalization localization = LootGoblinsHeimUtilsPlugin.Localization;
			string text = "Russian";
			string text2 = "$piece_dandelion_LG";
			localization.AddTranslation(ref text, ref text2, "Одуванчик");
			CustomLocalization localization2 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piece_dandelion_LG";
			localization2.AddTranslation(ref text, ref text2, "Dandelion");
			PlantConfiguration plantConfiguration = new PlantConfiguration();
			plantConfiguration.Name = "$piece_dandelion_LG";
			plantConfiguration.IconItemDropPrefabName = "Dandelion";
			plantConfiguration.PickablePrefabName = "Pickable_Dandelion";
			plantConfiguration.PieceRecipe = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Dandelion", 1, 0, false),
				new RequirementConfig("Resin", 1, 0, false)
			};
			plantConfiguration.Configure();
		}
	}
	public static class Mushroom
	{
		public const string PieceName = "$piece_mushroom_LG";

		public static void Configure()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			CustomLocalization localization = LootGoblinsHeimUtilsPlugin.Localization;
			string text = "Russian";
			string text2 = "$piece_mushroom_LG";
			localization.AddTranslation(ref text, ref text2, "Гриб");
			CustomLocalization localization2 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piece_mushroom_LG";
			localization2.AddTranslation(ref text, ref text2, "Mushroom");
			PlantConfiguration plantConfiguration = new PlantConfiguration();
			plantConfiguration.Name = "$piece_mushroom_LG";
			plantConfiguration.IconItemDropPrefabName = "Mushroom";
			plantConfiguration.PickablePrefabName = "Pickable_Mushroom";
			plantConfiguration.PieceRecipe = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Mushroom", 1, 0, false),
				new RequirementConfig("Resin", 2, 0, false)
			};
			plantConfiguration.Configure();
		}
	}
	public static class MushroomYellow
	{
		public const string PieceName = "$piece_mushroom_yellow_LG";

		public static void Configure()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			CustomLocalization localization = LootGoblinsHeimUtilsPlugin.Localization;
			string text = "Russian";
			string text2 = "$piece_mushroom_yellow_LG";
			localization.AddTranslation(ref text, ref text2, "Желтый гриб");
			CustomLocalization localization2 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piece_mushroom_yellow_LG";
			localization2.AddTranslation(ref text, ref text2, "Yellow Mushroom");
			PlantConfiguration plantConfiguration = new PlantConfiguration();
			plantConfiguration.Name = "$piece_mushroom_yellow_LG";
			plantConfiguration.IconItemDropPrefabName = "MushroomYellow";
			plantConfiguration.PickablePrefabName = "Pickable_Mushroom_yellow";
			plantConfiguration.PieceRecipe = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("MushroomYellow", 1, 0, false),
				new RequirementConfig("BoneFragments", 1, 0, false)
			};
			plantConfiguration.Configure();
		}
	}
	public static class RaspberryBush
	{
		public static void Setup()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			BushConfiguration bushConfiguration = new BushConfiguration();
			bushConfiguration.Name = "Raspberry";
			bushConfiguration.LocalizedBushName = "Малиновый куст";
			bushConfiguration.ReadyObjectName = "Berrys";
			bushConfiguration.FertilizerIcon = BushUtils.RaspberryBushIcon;
			bushConfiguration.NewBushModel = BushUtils.RaspberryBushModel;
			bushConfiguration.BushRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Raspberry", 5, 0, false),
				new RequirementConfig("Resin", 3, 0, false)
			};
			bushConfiguration.FertilizerConfigs = new BushConfiguration.FertilizerConfig[2]
			{
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для малины",
					LocalizedDescription = "Добавьте в малиновый куст, чтобы запустить процесс роста",
					AmountProduced = 5,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[1]
					{
						new RequirementConfig("Resin", 3, 0, false)
					}
				},
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для малины насыщенное",
					LocalizedDescription = "Добавьте в малиновый куст, чтобы запустить процесс роста. Увеличивает количество получаемого продукта",
					AmountProduced = 10,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
					{
						new RequirementConfig("Resin", 3, 0, false),
						new RequirementConfig("BoneFragments", 1, 0, false)
					}
				}
			};
			bushConfiguration.Configure();
		}
	}
	public static class Saplings
	{
		public static void ReplaceRecipes()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Expected O, but got Unknown
			PlantRecipeSwapper.SwapPieceRecipe("sapling_carrot", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("CarrotSeeds", 1, 0, false),
				new RequirementConfig("BoneFragments", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_seedcarrot", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Carrot", 1, 0, false),
				new RequirementConfig("BoneFragments", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_turnip", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("TurnipSeeds", 1, 0, false),
				new RequirementConfig("BoneFragments", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_seedturnip", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Turnip", 1, 0, false),
				new RequirementConfig("BoneFragments", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_onion", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("OnionSeeds", 1, 0, false),
				new RequirementConfig("Entrails", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_seedonion", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Onion", 1, 0, false),
				new RequirementConfig("Entrails", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_barley", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Barley", 1, 0, false),
				new RequirementConfig("Ooze", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("sapling_flax", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Flax", 1, 0, false),
				new RequirementConfig("Ooze", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("Beech_Sapling", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("BeechSeeds", 1, 0, false),
				new RequirementConfig("LeatherScraps", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("Birch_Sapling", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("BirchSeeds", 1, 0, false),
				new RequirementConfig("LeatherScraps", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("Oak_Sapling", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Acorn", 1, 0, false),
				new RequirementConfig("LeatherScraps", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("FirTree_Sapling", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("FirCone", 1, 0, false),
				new RequirementConfig("LeatherScraps", 1, 0, false)
			});
			PlantRecipeSwapper.SwapPieceRecipe("PineTree_Sapling", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("PineCone", 1, 0, false),
				new RequirementConfig("LeatherScraps", 1, 0, false)
			});
			Logger.LogInfo((object)"Saplings recipes replaced");
		}
	}
	public static class ThistleBush
	{
		public static void Setup()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			BushConfiguration bushConfiguration = new BushConfiguration();
			bushConfiguration.Name = "Thistle";
			bushConfiguration.LocalizedBushName = "Чертополох";
			bushConfiguration.ReadyObjectName = "bees";
			bushConfiguration.FertilizerIcon = BushUtils.thistleIcon;
			bushConfiguration.NewBushModel = BushUtils.thistleModel;
			bushConfiguration.BushRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Thistle", 5, 0, false),
				new RequirementConfig("BoneFragments", 3, 0, false)
			};
			bushConfiguration.FertilizerConfigs = new BushConfiguration.FertilizerConfig[2]
			{
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для чертополоха",
					LocalizedDescription = "Добавьте в чертополох, чтобы запустить процесс роста",
					AmountProduced = 5,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[1]
					{
						new RequirementConfig("BoneFragments", 2, 0, false)
					}
				},
				new BushConfiguration.FertilizerConfig
				{
					LocalizedName = "Удобрение для чертополоха насыщенное",
					LocalizedDescription = "Добавьте в чертополох, чтобы запустить процесс роста. Увеличивает количество получаемого продукта",
					AmountProduced = 10,
					RecipeRequirements = (RequirementConfig[])(object)new RequirementConfig[2]
					{
						new RequirementConfig("BoneFragments", 2, 0, false),
						new RequirementConfig("Entrails", 1, 0, false)
					}
				}
			};
			bushConfiguration.Configure();
		}
	}
}
namespace LootGoblinsUtils.Pieces.Stations
{
	public static class FarmersTable
	{
		public const string TableName = "$piece_farmersTable_LG";

		public const string PieceCategory = "$piececategory_farming";

		public static void Configure()
		{
			try
			{
				InnerSetup();
				Logger.LogInfo((object)"$piece_farmersTable_LG constructing completed");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)"$piece_farmersTable_LG constructing failed");
				Logger.LogError((object)ex);
			}
		}

		private static void InnerSetup()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			CustomLocalization localization = LootGoblinsHeimUtilsPlugin.Localization;
			string text = "Russian";
			string text2 = "$piece_farmersTable_LG";
			localization.AddTranslation(ref text, ref text2, "Столик фермера");
			CustomLocalization localization2 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piece_farmersTable_LG";
			localization2.AddTranslation(ref text, ref text2, "Farmers Table");
			CustomLocalization localization3 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "Russian";
			text2 = "$piececategory_farming";
			localization3.AddTranslation(ref text, ref text2, "Фермерство");
			CustomLocalization localization4 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piececategory_farming";
			localization4.AddTranslation(ref text, ref text2, "Farming");
			GameObject prefab = PrefabManager.Instance.GetPrefab("cauldron_ext5_mortarandpestle");
			GameObject gameObject = ((Component)ExposedGameObjectExtension.FindDeepChild(prefab, "new", (IterativeSearchType)1)).gameObject;
			Sprite icon = prefab.GetComponent<Piece>().m_icon;
			PieceManager.Instance.AddPieceCategory(PieceTables.Hammer, "$piececategory_farming");
			PieceConfig val = new PieceConfig();
			val.Name = Localization.instance.Localize("$piece_farmersTable_LG");
			val.PieceTable = PieceTables.Hammer;
			val.Category = Localization.instance.Localize("$piececategory_farming");
			val.Icon = icon;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("FineWood", 15, 0, true),
				new RequirementConfig("Bronze", 2, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece("$piece_farmersTable_LG", CraftingStations.Workbench, val2);
			GameObject val4 = Object.Instantiate<GameObject>(gameObject, val3.PiecePrefab.transform);
			val4.transform.localScale = new Vector3(1.8f, 1.8f, 1.3f);
			WearNTear component = val3.PiecePrefab.GetComponent<WearNTear>();
			component.m_broken = val4;
			component.m_new = val4;
			component.m_worn = val4;
			Object.Destroy((Object)(object)((Component)ExposedGameObjectExtension.FindDeepChild(val3.PiecePrefab, "New", (IterativeSearchType)1)).gameObject);
			Object.Destroy((Object)(object)((Component)ExposedGameObjectExtension.FindDeepChild(val3.PiecePrefab, "Worn", (IterativeSearchType)1)).gameObject);
			Object.Destroy((Object)(object)((Component)ExposedGameObjectExtension.FindDeepChild(val3.PiecePrefab, "Broken", (IterativeSearchType)1)).gameObject);
			CraftingStation component2 = val3.PiecePrefab.GetComponent<CraftingStation>();
			component2.m_name = "$piece_farmersTable_LG";
			component2.m_showBasicRecipies = false;
			PieceManager.Instance.AddPiece(val3);
		}
	}
	public static class FarmersTableExtensionT1
	{
		public const string TableName = "$piece_farmersTable_ext1_LG";

		public const string TableDescription = "$piece_farmersTable_ext1_description_LG";

		public const string PieceCategory = "$piececategory_farming";

		public static void Configure()
		{
			try
			{
				InnerSetup();
				Logger.LogInfo((object)"$piece_farmersTable_ext1_LG constructing completed");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)"$piece_farmersTable_ext1_LG constructing failed");
				Logger.LogError((object)ex);
			}
		}

		private static void InnerSetup()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			CustomLocalization localization = LootGoblinsHeimUtilsPlugin.Localization;
			string text = "Russian";
			string text2 = "$piece_farmersTable_ext1_LG";
			localization.AddTranslation(ref text, ref text2, "Фермерская сушилка для трав");
			CustomLocalization localization2 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piece_farmersTable_ext1_LG";
			localization2.AddTranslation(ref text, ref text2, "Farmer's Spice Rack");
			CustomLocalization localization3 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "Russian";
			text2 = "$piece_farmersTable_ext1_description_LG";
			localization3.AddTranslation(ref text, ref text2, "Улучшение столика фермера");
			CustomLocalization localization4 = LootGoblinsHeimUtilsPlugin.Localization;
			text = "English";
			text2 = "$piece_farmersTable_ext1_description_LG";
			localization4.AddTranslation(ref text, ref text2, "Farmer's Table improvement");
			PieceConfig val = new PieceConfig();
			val.Name = Localization.instance.Localize("$piece_farmersTable_ext1_LG");
			val.Description = Localization.instance.Localize("$piece_farmersTable_ext1_description_LG");
			val.PieceTable = PieceTables.Hammer;
			val.Category = Localization.instance.Localize("$piececategory_farming");
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[5]
			{
				new RequirementConfig("Dandelion", 10, 0, true),
				new RequirementConfig("Carrot", 5, 0, true),
				new RequirementConfig("Mushroom", 5, 0, true),
				new RequirementConfig("Thistle", 5, 0, true),
				new RequirementConfig("Turnip", 3, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece("$piece_farmersTable_ext1_LG", "cauldron_ext1_spice", val2);
			val3.PiecePrefab.GetComponent<StationExtension>().m_craftingStation = PieceManager.Instance.GetPiece("$piece_farmersTable_LG").PiecePrefab.GetComponent<CraftingStation>();
			PieceManager.Instance.AddPiece(val3);
		}
	}
}
namespace LootGoblinsUtils.Pieces.Configurators
{
	public class BushConfiguration : Configurable
	{
		public struct FertilizerConfig
		{
			public string LocalizedName;

			public string LocalizedDescription;

			public RequirementConfig[] RecipeRequirements;

			public int AmountProduced;
		}

		public string LocalizedBushName;

		public string ReadyObjectName;

		public float ColliderRadius;

		public Sprite FertilizerIcon;

		public RequirementConfig[] BushRequirements;

		public GameObject NewBushModel;

		public FertilizerConfig[] FertilizerConfigs;

		private string BushName => "piece_" + Name + "Bush_LG";

		private string FertilizerTierName(int tier)
		{
			return $"{Name}FertilizerT{tier}_LG";
		}

		protected override void Setup()
		{
			CustomPiece val = MakeNewPiece();
			Transform targetParentTransform = BushUtils.CleanupModel(val);
			Logger.LogInfo((object)(BushName + " CleanupModel complete"));
			GameObject val2 = BushUtils.SetupNewModel(NewBushModel, targetParentTransform);
			Logger.LogInfo((object)(BushName + " SetupNewModel complete"));
			CapsuleCollider obj = val2.GetComponent<CapsuleCollider>() ?? val2.AddComponent<CapsuleCollider>();
			obj.radius = ((ColliderRadius == 0f) ? 1.6f : ColliderRadius);
			((Collider)obj).isTrigger = true;
			Transform obj2 = ExposedGameObjectExtension.FindDeepChild(val2, ReadyObjectName, (IterativeSearchType)1);
			GameObject val3 = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if ((Object)(object)val3 == (Object)null)
			{
				Logger.LogWarning((object)(BushName + ".readyObject == null"));
			}
			else
			{
				val3.SetActive(false);
			}
			BushUtils.ConfigureFermenter(val.PiecePrefab.GetComponent<Fermenter>(), val3);
			PieceManager.Instance.AddPiece(val);
			MakeFertilizers();
		}

		private CustomPiece MakeNewPiece()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0040: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			PieceConfig val = new PieceConfig
			{
				Name = LocalizedBushName,
				PieceTable = PieceTables.Cultivator,
				Category = PieceCategories.Misc,
				Icon = FertilizerIcon,
				Requirements = BushRequirements
			};
			CustomPiece val2 = new CustomPiece(BushName, Fermenters.Fermenter, val);
			val2.Piece.m_craftingStation = null;
			val2.Piece.m_cultivatedGroundOnly = true;
			val2.Piece.m_groundOnly = true;
			val2.Piece.m_noClipping = false;
			Logger.LogInfo((object)(BushName + " newPiece setup complete"));
			return val2;
		}

		private void MakeFertilizers()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			for (int i = 0; i < FertilizerConfigs.Length; i++)
			{
				FertilizerConfig fertilizerConfig = FertilizerConfigs[i];
				BushUtils.MakeFertilizer(fertilizerConfig.LocalizedName, FertilizerTierName(i + 1), fertilizerConfig.LocalizedDescription, fertilizerConfig.RecipeRequirements, i + 1);
				FermenterConversionConfig val = new FermenterConversionConfig
				{
					ToItem = Name,
					FromItem = FertilizerTierName(i + 1),
					Station = BushName,
					ProducedItems = fertilizerConfig.AmountProduced
				};
				ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val));
			}
		}
	}
	public static class BushUtils
	{
		public struct VisualsGroup
		{
			public GameObject Prefab;

			public GameObject Model;

			public Sprite Icon;

			public VisualsGroup(string prefabName, string modelChildName)
			{
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				Prefab = PrefabManager.Instance.GetPrefab(prefabName);
				if ((Object)(object)Prefab == (Object)null)
				{
					Logger.LogWarning((object)("VisualsGroup.prefab[" + prefabName + "] is null"));
				}
				Model = ((Component)ExposedGameObjectExtension.FindDeepChild(Prefab, modelChildName, (IterativeSearchType)1)).gameObject;
				if ((Object)(object)Model == (Object)null)
				{
					Logger.LogWarning((object)("VisualsGroup.Model[" + modelChildName + " is null"));
				}
				Icon = RenderManager.Instance.Render(Prefab, RenderManager.IsometricRotation);
				if ((Object)(object)Icon == (Object)null)
				{
					Logger.LogWarning((object)("VisualsGroup.Icon[" + prefabName + " is null"));
				}
			}
		}

		private static GameObject _raspberryBushPrefab;

		public static GameObject RaspberryBushModel;

		public static Sprite RaspberryBushIcon;

		private static GameObject _blueberryBushPrefab;

		public static GameObject BlueberryBushModel;

		public static Sprite BlueberryBushIcon;

		public static VisualsGroup CloudberryVisuals;

		private static GameObject _thistlePrefab;

		public static GameObject thistleModel;

		public static Sprite thistleIcon;

		public static Sprite MeadIcon;

		public static void CacheDependencies()
		{
			//IL_0038: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			_raspberryBushPrefab = PrefabManager.Instance.GetPrefab("RaspberryBush");
			RaspberryBushModel = ((Component)ExposedGameObjectExtension.FindDeepChild(_raspberryBushPrefab, "model", (IterativeSearchType)1)).gameObject;
			RaspberryBushIcon = RenderManager.Instance.Render(_raspberryBushPrefab, RenderManager.IsometricRotation);
			_blueberryBushPrefab = PrefabManager.Instance.GetPrefab("BlueberryBush");
			BlueberryBushModel = ((Component)ExposedGameObjectExtension.FindDeepChild(_blueberryBushPrefab, "model", (IterativeSearchType)1)).gameObject;
			BlueberryBushIcon = RenderManager.Instance.Render(_blueberryBushPrefab, RenderManager.IsometricRotation);
			CloudberryVisuals = new VisualsGroup("CloudberryBush", "high");
			ExposedGameObjectExtension.FindDeepChild(CloudberryVisuals.Prefab, "Berrys", (IterativeSearchType)1).parent = CloudberryVisuals.Model.transform;
			_thistlePrefab = PrefabManager.Instance.GetPrefab("Pickable_Thistle");
			thistleModel = ((Component)ExposedGameObjectExtension.FindDeepChild(_thistlePrefab, "visual", (IterativeSearchType)1)).gameObject;
			thistleIcon = RenderManager.Instance.Render(_thistlePrefab, RenderManager.IsometricRotation);
			MeadIcon = PrefabManager.Instance.GetPrefab("MeadBaseTasty").GetComponent<ItemDrop>().m_itemData.GetIcon();
		}

		public static GameObject SetupNewModel(GameObject targetModel, Transform targetParentTransform)
		{
			GameObject obj = Object.Instantiate<GameObject>(targetModel, targetParentTransform);
			obj.layer = LayerMask.NameToLayer("Default_small");
			return obj;
		}

		public static Transform CleanupModel(CustomPiece newPiece)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ExposedGameObjectExtension.FindDeepChild(newPiece.PiecePrefab, "barrel", (IterativeSearchType)1);
			((Component)val).gameObject.SetActive(false);
			Object.Destroy((Object)(object)((Component)((Component)ExposedGameObjectExtension.FindDeepChild(newPiece.PiecePrefab, "_top", (IterativeSearchType)1)).transform.GetChild(0)).gameObject);
			foreach (Transform item in ExposedGameObjectExtension.FindDeepChild(newPiece.PiecePrefab, "_fermenting", (IterativeSearchType)1))
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			foreach (Transform item2 in ExposedGameObjectExtension.FindDeepChild(newPiece.PiecePrefab, "_ready", (IterativeSearchType)1))
			{
				Object.Destroy((Object)(object)((Component)item2).gameObject);
			}
			return val.parent;
		}

		public static void ConfigureFermenter(Fermenter fermenterComponent, [CanBeNull] GameObject readyObject)
		{
			fermenterComponent.m_conversion.Clear();
			fermenterComponent.m_fermentationDuration = PluginConfiguration.FertilizingDuration.Value;
			fermenterComponent.m_addedEffects = fermenterComponent.m_spawnEffects;
			fermenterComponent.m_tapEffects.m_effectPrefabs = Array.Empty<EffectData>();
			fermenterComponent.m_tapDelay = 0.1f;
			fermenterComponent.m_readyObject = readyObject;
		}

		public static void MakeFertilizer(string localizedName, string itemName, string description, RequirementConfig[] requirements, int minStationLevel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			ItemConfig val = new ItemConfig();
			val.Name = localizedName;
			val.Description = description;
			val.CraftingStation = "$piece_farmersTable_LG";
			val.MinStationLevel = minStationLevel;
			val.Icons = (Sprite[])(object)new Sprite[1] { MeadIcon };
			ItemConfig val2 = val;
			val2.Requirements = requirements;
			CustomItem val3 = new CustomItem(itemName, "Stone", val2);
			Object.Destroy((Object)(object)((Component)val3.ItemPrefab.transform.GetChild(0)).gameObject);
			Object.Instantiate<GameObject>(((Component)PrefabManager.Instance.GetPrefab("MeadBaseTasty").transform.GetChild(0)).gameObject, val3.ItemPrefab.transform);
			ItemManager.Instance.AddItem(val3);
		}
	}
	public abstract class Configurable
	{
		public string Name;

		public void Configure()
		{
			try
			{
				Setup();
				Logger.LogInfo((object)(Name + " constructing completed"));
			}
			catch (Exception ex)
			{
				Logger.LogError((object)(Name + " constructing failed"));
				Logger.LogError((object)ex);
			}
		}

		protected abstract void Setup();
	}
	public class PlantConfiguration : Configurable
	{
		public string IconItemDropPrefabName;

		public RequirementConfig[] PieceRecipe;

		public string PickablePrefabName;

		protected override void Setup()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			Sprite icon = PrefabManager.Instance.GetPrefab(IconItemDropPrefabName).GetComponent<ItemDrop>().m_itemData.GetIcon();
			PieceConfig val = new PieceConfig
			{
				Name = Localization.instance.Localize(Name),
				PieceTable = PieceTables.Cultivator,
				Category = PieceCategories.Misc,
				Icon = icon,
				Requirements = PieceRecipe
			};
			CustomPiece val2 = new CustomPiece(Name, "sapling_onion", val);
			GameObject val3 = PrefabManager.Instance.CreateClonedPrefab(PickablePrefabName + "_LG", PickablePrefabName);
			Transform child = val3.transform.GetChild(0);
			val3.GetComponent<Pickable>().m_amount = 5;
			Plant component = val2.PiecePrefab.GetComponent<Plant>();
			component.m_minScale = 1.2f;
			component.m_maxScale = 1.7f;
			component.m_growTime = PluginConfiguration.PlantGrowMinDuration.Value;
			component.m_growTimeMax = PluginConfiguration.PlantGrowMaxDuration.Value;
			component.m_name = Localization.instance.Localize(Name);
			component.m_grownPrefabs = (GameObject[])(object)new GameObject[1] { val3 };
			foreach (Transform item in val2.PiecePrefab.transform)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			GameObject gameObject = ((Component)Object.Instantiate<Transform>(child, val2.PiecePrefab.transform)).gameObject;
			((Object)gameObject).name = "healthy";
			gameObject.transform.localScale = Vector3.one * 0.5f;
			GameObject gameObject2 = ((Component)Object.Instantiate<Transform>(child, val2.PiecePrefab.transform)).gameObject;
			((Object)gameObject2).name = "unhealthy";
			gameObject2.transform.localScale = Vector3.one * 0.5f;
			GameObject gameObject3 = ((Component)Object.Instantiate<Transform>(child, val2.PiecePrefab.transform)).gameObject;
			((Object)gameObject3).name = "healthyGrown";
			GameObject gameObject4 = ((Component)Object.Instantiate<Transform>(child, val2.PiecePrefab.transform)).gameObject;
			((Object)gameObject4).name = "unhealthyGrown";
			component.m_healthy = gameObject;
			component.m_unhealthy = gameObject2;
			component.m_healthyGrown = gameObject3;
			component.m_unhealthyGrown = gameObject4;
			PieceManager.Instance.AddPiece(val2);
		}
	}
	public static class PlantRecipeSwapper
	{
		public static void SwapPieceRecipe(string prefabName, RequirementConfig[] requirementConfigs)
		{
			Piece component = PrefabManager.Instance.GetPrefab(prefabName).GetComponent<Piece>();
			Requirement[] array = requirementConfigs.Select((RequirementConfig req) => req.GetRequirement()).ToArray();
			Requirement[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				PrefabExtension.FixReferences((object)array2[i]);
			}
			component.m_resources = array.ToArray();
		}
	}
}
namespace LootGoblinsUtils.Hooks
{
	public static class Hooks
	{
		[HarmonyPatch(typeof(Fermenter), "GetHoverText")]
		public static class FermenterHoverText
		{
			public static bool Prefix(Fermenter __instance, ref string __result)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Expected I4, but got Unknown
				if (!((Object)((Component)__instance).gameObject).name.Contains("_LG"))
				{
					return true;
				}
				if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false))
				{
					__result = "Доступ запрещён";
					return false;
				}
				Piece component = ((Component)__instance).GetComponent<Piece>();
				TimeSpan timeSpan = TimeSpan.FromSeconds((int)((double)__instance.m_fermentationDuration - __instance.GetFermentationTime()));
				Status status = __instance.GetStatus();
				__result = (int)status switch
				{
					0 => Localization.instance.Localize(component.m_name + " ( Пусто )\n[<color=yellow><b>$KEY_Use</b></color>] Добавить удобрение"), 
					1 => $"{component.m_name} ( <color=blue>Рост</color> )\nОсталось: {timeSpan.Minutes} мин. {timeSpan.Seconds} сек.", 
					3 => component.m_name + " ( <color=green>Готово</color> )", 
					_ => component.m_name, 
				};
				return false;
			}
		}

		[HarmonyPatch(typeof(Fermenter), "UpdateCover")]
		public static class FermenterCoverSkip
		{
			private static bool Prefix(Fermenter __instance)
			{
				return !((Object)((Component)__instance).gameObject).name.Contains("_LG");
			}
		}
	}
	[HarmonyPatch(typeof(MonoUpdaters), "Update")]
	public class MonoUpdaterPatch
	{
		public static bool Prefix(MonoUpdaters __instance)
		{
			if (!LootGoblinsHeimUtilsPlugin.OptimizationsEnabled)
			{
				return true;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			MonoUpdaters.s_updateCount++;
			float deltaTime = Time.deltaTime;
			__instance.m_waterVolumeInstances.AddRange(WaterVolume.Instances);
			__instance.m_smokeInstances.AddRange(Smoke.Instances);
			__instance.m_zsfxInstances.AddRange(ZSFX.Instances);
			__instance.m_heightmapInstances.AddRange(Heightmap.Instances);
			__instance.m_visEquipmentInstances.AddRange(VisEquipment.Instances);
			__instance.m_footStepInstances.AddRange(FootStep.Instances);
			__instance.m_instanceRendererInstances.AddRange(InstanceRenderer.Instances);
			__instance.m_waterTriggerInstances.AddRange(WaterTrigger.Instances);
			stopwatch.Stop();
			stopwatch.Restart();
			if (__instance.m_waterVolumeInstances.Count > 0)
			{
				__instance.SafeCall((Action)WaterVolume.StaticUpdate);
				foreach (WaterVolume waterVolumeInstance in __instance.m_waterVolumeInstances)
				{
					waterVolumeInstance.Update1();
				}
				foreach (WaterVolume waterVolumeInstance2 in __instance.m_waterVolumeInstances)
				{
					waterVolumeInstance2.Update2();
				}
			}
			stopwatch.Stop();
			stopwatch.Restart();
			foreach (Smoke smokeInstance in __instance.m_smokeInstances)
			{
				smokeInstance.CustomUpdate(deltaTime);
			}
			foreach (ZSFX zsfxInstance in __instance.m_zsfxInstances)
			{
				zsfxInstance.CustomUpdate(deltaTime);
			}
			foreach (VisEquipment visEquipmentInstance in __instance.m_visEquipmentInstances)
			{
				visEquipmentInstance.CustomUpdate();
			}
			foreach (FootStep footStepInstance in __instance.m_footStepInstances)
			{
				footStepInstance.CustomUpdate(deltaTime);
			}
			foreach (InstanceRenderer instanceRendererInstance in __instance.m_instanceRendererInstances)
			{
				instanceRendererInstance.CustomUpdate();
			}
			foreach (WaterTrigger waterTriggerInstance in __instance.m_waterTriggerInstances)
			{
				waterTriggerInstance.CustomUpdate(deltaTime);
			}
			stopwatch.Stop();
			__instance.m_waterVolumeInstances.Clear();
			__instance.m_smokeInstances.Clear();
			__instance.m_zsfxInstances.Clear();
			__instance.m_heightmapInstances.Clear();
			__instance.m_visEquipmentInstances.Clear();
			__instance.m_footStepInstances.Clear();
			__instance.m_instanceRendererInstances.Clear();
			__instance.m_waterTriggerInstances.Clear();
			return false;
		}
	}
	[HarmonyPatch(typeof(MonoUpdaters), "FixedUpdate")]
	public class MonoUpdaterPatchFixed
	{
		public class SeparateUpdater<T>
		{
			private readonly Action<T, float> _updater;

			private readonly List<T> _targets;

			private bool _firstUpdated;

			private float _lastDt;

			public SeparateUpdater(Action<T, float> updater, List<T> targets)
			{
				_updater = updater;
				_targets = targets;
			}

			public void Update(float fixedDeltaTime)
			{
				foreach (T item in _firstUpdated ? _targets.Skip(Character.Instances.Count / 2) : _targets.Take(Character.Instances.Count / 2))
				{
					_updater(item, fixedDeltaTime + _lastDt);
				}
				_lastDt = fixedDeltaTime;
				_firstUpdated = !_firstUpdated;
			}
		}

		private static readonly SeparateUpdater<Character> CharacterUpdater = new SeparateUpdater<Character>(delegate(Character character, float dt)
		{
			character.CustomFixedUpdate(dt);
		}, Character.Instances);

		public static bool Prefix(MonoUpdaters __instance)
		{
			if (!LootGoblinsHeimUtilsPlugin.OptimizationsEnabled)
			{
				return true;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			Stopwatch stopwatch = Stopwatch.StartNew();
			MonoUpdaters.s_updateCount++;
			float fixedDeltaTime = Time.fixedDeltaTime;
			float time = Time.time;
			if (WaterVolume.Instances.Count > 0)
			{
				WaterVolume.StaticUpdate();
			}
			stopwatch.Stop();
			ProfilePatcher.PushUpdateTable("MonoUpdaters.WaterVolume", stopwatch.ElapsedTicks, instanceID);
			stopwatch.Restart();
			foreach (ZSyncTransform instance in ZSyncTransform.Instances)
			{
				instance.CustomFixedUpdate(fixedDeltaTime);
			}
			foreach (ZSyncAnimation instance2 in ZSyncAnimation.Instances)
			{
				instance2.CustomFixedUpdate();
			}
			foreach (Floating instance3 in Floating.Instances)
			{
				instance3.CustomFixedUpdate(fixedDeltaTime);
			}
			foreach (Ship instance4 in Ship.Instances)
			{
				instance4.CustomFixedUpdate(fixedDeltaTime, time);
			}
			foreach (Fish instance5 in Fish.Instances)
			{
				instance5.CustomFixedUpdate();
			}
			foreach (CharacterAnimEvent instance6 in CharacterAnimEvent.Instances)
			{
				instance6.CustomFixedUpdate();
			}
			stopwatch.Stop();
			ProfilePatcher.PushUpdateTable("MonoUpdaters.Instances", stopwatch.ElapsedTicks, instanceID);
			stopwatch.Restart();
			__instance.m_updateAITimer += fixedDeltaTime;
			if ((double)__instance.m_updateAITimer >= 0.0500000007450581)
			{
				foreach (BaseAI instance7 in BaseAI.Instances)
				{
					instance7.UpdateAI(0.05f);
				}
				foreach (MonsterAI instance8 in MonsterAI.Instances)
				{
					instance8.UpdateAI(0.05f);
				}
				foreach (AnimalAI instance9 in AnimalAI.Instances)
				{
					instance9.UpdateAI(0.05f);
				}
				__instance.m_updateAITimer -= 0.05f;
			}
			stopwatch.Stop();
			ProfilePatcher.PushUpdateTable("MonoUpdaters.AI", stopwatch.ElapsedTicks, instanceID);
			stopwatch.Restart();
			foreach (Humanoid instance10 in Humanoid.Instances)
			{
				instance10.CustomFixedUpdate();
			}
			stopwatch.Stop();
			ProfilePatcher.PushUpdateTable("MonoUpdaters.Humanoid", stopwatch.ElapsedTicks, instanceID);
			stopwatch.Restart();
			CharacterUpdater.Update(fixedDeltaTime);
			stopwatch.Stop();
			ProfilePatcher.PushUpdateTable("MonoUpdaters.Character", stopwatch.ElapsedTicks, instanceID);
			return false;
		}
	}
	public static class ProfilePatcher
	{
		private static HarmonyMethod _prefix = new HarmonyMethod(typeof(ProfilePatcher).GetMethod("Prefix"))
		{
			priority = 800
		};

		private static HarmonyMethod _postfixUpdate = new HarmonyMethod(typeof(ProfilePatcher).GetMethod("PostfixUpdate"))
		{
			priority = 0
		};

		private static HarmonyMethod _postfixFixedUpdate = new HarmonyMethod(typeof(ProfilePatcher).GetMethod("PostfixFixedUpdate"))
		{
			priority = 0
		};

		private static HarmonyMethod _postfixLateUpdate = new HarmonyMethod(typeof(ProfilePatcher).GetMethod("PostfixLateUpdate"))
		{
			priority = 0
		};

		private static HarmonyMethod _postfixCustomUpdate = new HarmonyMethod(typeof(ProfilePatcher).GetMethod("PostfixCustomUpdate"))
		{
			priority = 0
		};

		private static HarmonyMethod _postfixCustomFixedUpdate = new HarmonyMethod(typeof(ProfilePatcher).GetMethod("PostfixCustomFixedUpdate"))
		{
			priority = 0
		};

		public static Dictionary<string, List<long>> UpdateTable = new Dictionary<string, List<long>>();

		public static Dictionary<string, List<int>> InstanceCounter = new Dictionary<string, List<int>>();

		private static float _lastUpdateLate;

		private const float UpdateRate = 1f;

		public static void Patch(Harmony harmony)
		{
			PatchBody(harmony, _postfixFixedUpdate, "FixedUpdate");
		}

		private static void PatchBody(Harmony harmony, HarmonyMethod postfix, string methodName)
		{
			foreach (MethodInfo item in from x in Assembly.GetAssembly(typeof(Game)).DefinedTypes
				where x.DeclaredMethods.Any((MethodInfo t) => t.Name == methodName)
				select x.DeclaredMethods.First((MethodInfo m) => m.Name == methodName))
			{
				try
				{
					harmony.Patch((MethodBase)item, _prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				catch
				{
					Logger.LogWarning((object)("Cant patch [" + item.Name + "]"));
				}
			}
		}

		public static void Prefix(object __instance, out Stopwatch __state)
		{
			if (__instance == null)
			{
				__state = null;
				return;
			}
			__state = new Stopwatch();
			__state.Start();
		}

		public static void PostfixUpdate(object __instance, Stopwatch __state)
		{
			PostfixBody(__instance, __state, "Update");
		}

		public static void PostfixFixedUpdate(object __instance, Stopwatch __state)
		{
			PostfixBody(__instance, __state, "FixedUpdate");
		}

		public static void PostfixLateUpdate(object __instance, Stopwatch __state)
		{
			PostfixBody(__instance, __state, "LateUpdate");
		}

		public static void PostfixCustomUpdate(object __instance, Stopwatch __state)
		{
			PostfixBody(__instance, __state, "CustomUpdate");
		}

		public static void PostfixCustomFixedUpdate(object __instance, Stopwatch __state)
		{
			PostfixBody(__instance, __state, "CustomFixedUpdate");
		}

		public static void PushUpdateTable(string instanceName, long elapsed, int instanceId)
		{
			if (!LootGoblinsHeimUtilsPlugin.LoggingEnabled)
			{
				return;
			}
			if (InstanceCounter.TryGetValue(instanceName, out var value))
			{
				if (!value.Contains(instanceId))
				{
					value.Add(instanceId);
				}
			}
			else
			{
				InstanceCounter[instanceName] = new List<int> { instanceId };
			}
			if (UpdateTable.TryGetValue(instanceName, out var value2))
			{
				value2.Add(elapsed);
				return;
			}
			UpdateTable[instanceName] = new List<long> { elapsed };
		}

		public static void PostfixBody(object __instance, Stopwatch __state, string methodName)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (__state != null && __instance != null)
			{
				__state.Stop();
				string instanceName = "[" + __instance.GetType().Name + "]." + methodName;
				long elapsedTicks = __state.ElapsedTicks;
				try
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					PushUpdateTable(instanceName, elapsedTicks, instanceID);
				}
				catch
				{
					Logger.LogDebug((object)("One of " + methodName + " cant be pushed"));
				}
			}
		}

		private static void LogProfileInfo(string methodName)
		{
			List<long> list = UpdateTable[methodName];
			int count = InstanceCounter[methodName].Count;
			long num = list.Max();
			float num2 = (float)list.Sum() / 1f;
			float num3 = (float)list.Count / 1f;
			float num4 = num2 / 10000f;
			float num5 = num4 / (num3 * (float)count);
			string text = fss($"{methodName}[{count}]:", 45);
			string text2 = fss($"max: {num};", 11);
			string text3 = fss($"sumTicks:{num2};", 20);
			string text4 = fss($"sumMs:{num4:F};", 11);
			string text5 = fss($"sumMsPerUpdate:{num5:F};", 22);
			Logger.LogMessage((object)$"{text}\t {text2}\t {text3}\t {text4}\t {text5}\t count: {num3:0000}\t");
		}

		private static string fss(string target, int requiredLength)
		{
			int num = requiredLength - target.Length;
			if (num <= 0)
			{
				return target;
			}
			return target + new string(' ', num);
		}

		public static void LateUpdate()
		{
			if (!(Time.time > _lastUpdateLate + 1f))
			{
				return;
			}
			_lastUpdateLate = Time.time;
			Logger.LogMessage((object)"------------");
			foreach (KeyValuePair<string, List<long>> item in UpdateTable.OrderByDescending((KeyValuePair<string, List<long>> x) => x.Value.Sum() / (x.Value.Count * InstanceCounter[x.Key].Count)).Take(15))
			{
				LogProfileInfo(item.Key);
			}
			UpdateTable.Clear();
		}
	}
}
namespace LootGoblinsUtils.Creatures
{
	public static class CreatureDB
	{
		public static void LoadCreatures()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			CreatureConfig val = new CreatureConfig();
			CustomCreature val2 = new CustomCreature("LG_StormBoar", "Boar", val);
			GameObject prefab = val2.Prefab;
			Transform transform = prefab.transform;
			transform.localScale *= 2f;
			GameObject lightningUnitEffectCloned = FinePrefabs.LightningUnitEffectCloned;
			Object.Destroy((Object)(object)lightningUnitEffectCloned.GetComponent<ZNetView>());
			Object.Instantiate<GameObject>(lightningUnitEffectCloned, prefab.transform).transform.localPosition = Vector3.zero;
			Humanoid component = prefab.GetComponent<Humanoid>();
			((Character)component).m_name = "Штормовой Боров";
			((Character)component).m_health = 500f;
			float num = 1.3f;
			((Character)component).m_speed = ((Character)component).m_speed * num;
			((Character)component).m_turnSpeed = ((Character)component).m_turnSpeed * num;
			((Character)component).m_runSpeed = ((Character)component).m_runSpeed * num;
			((Character)component).m_runTurnSpeed = ((Character)component).m_runTurnSpeed * num;
			ItemDrop component2 = PrefabManager.Instance.GetPrefab("Eikthyr").GetComponent<Humanoid>().m_defaultItems[1].GetComponent<ItemDrop>();
			SharedData shared = component.m_defaultItems[0].GetComponent<ItemDrop>().m_itemData.m_shared;
			shared.m_damages.m_lightning = 20f;
			shared.m_attackForce = 100f;
			shared.m_attack.m_hitTerrain = true;
			shared.m_attack.m_attackRange = 20f;
			shared.m_attack.m_attackHeight = 2f;
			shared.m_attack.m_attackRayWidth = 2f;
			shared.m_attack.m_hitThroughWalls = true;
			shared.m_aiAttackRange = 15f;
			shared.m_aiAttackInterval = 5f;
			shared.m_aiAttackMaxAngle = 15f;
			shared.m_aiPrioritized = true;
			shared.m_startEffect = component2.m_itemData.m_shared.m_startEffect;
			shared.m_triggerEffect = component2.m_itemData.m_shared.m_triggerEffect;
			CreatureManager.Instance.AddCreature(val2);
		}
	}
	public static class ExplorerHelpers
	{
		public static void AttackSharedData()
		{
			JsonUtility.ToJson((object)GameObject.Find("LG_StormBoar(Clone)").GetComponent<Humanoid>().m_defaultItems[0].GetComponent<ItemDrop>().m_itemData.m_shared);
		}
	}
	public static class FinePrefabs
	{
		public static GameObject FireExplosionProjectile => PrefabManager.Instance.GetPrefab("staff_fireball_projectile");

		public static GameObject LightningUnitEffect => PrefabManager.Instance.GetPrefab("fx_Lightning");

		public static GameObject LightningUnitEffectCloned => PrefabManager.Instance.CreateClonedPrefab("LG_fx_lightning", "fx_Lightning");
	}
}