Decompiled source of Better Cartography Table v0.3.0

BetterCartographyTable.dll

Decompiled 3 weeks 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.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterCartographyTable.Extensions;
using BetterCartographyTable.Managers;
using BetterCartographyTable.Model;
using BetterCartographyTable.UI;
using Guilds;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn.Utils;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
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: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("BetterCartographyTable")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ffe7c756b6cc3df0b284adeaba7f13f1df03c8e4")]
[assembly: AssemblyProduct("BetterCartographyTable")]
[assembly: AssemblyTitle("BetterCartographyTable")]
[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;
		}
	}
}
namespace BetterCartographyTable
{
	[BepInPlugin("nbusseneau.BetterCartographyTable", "BetterCartographyTable", "0.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string ModGUID = "nbusseneau.BetterCartographyTable";

		private const string ModName = "BetterCartographyTable";

		private const string ModVersion = "0.3.0";

		private static ConfigEntry<KeyboardShortcut> modifierKey;

		private static ConfigEntry<Color> publicPinsColor;

		public static ManualLogSource Logger;

		public static KeyboardShortcut ModifierKey => modifierKey.Value;

		public static bool IsModifierKeyPushed
		{
			get
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: 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_0023: Unknown result type (might be due to invalid IL or missing references)
				KeyboardShortcut value = modifierKey.Value;
				if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
				{
					value = modifierKey.Value;
					return ((KeyboardShortcut)(ref value)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
				}
				return false;
			}
		}

		public static Color PublicPinsColor => publicPinsColor.Value;

		public void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			Localizer.Load();
			Logger = ((BaseUnityPlugin)this).Logger;
			modifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "Modifier key", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Modifier key to use for interacting with public or guild pins on the cartography table.");
			publicPinsColor = ((BaseUnityPlugin)this).Config.Bind<Color>("UI", "Public pins color", Color.green, "Color to use for public pins.");
			SetUpConfigWatcher();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			new Harmony("nbusseneau.BetterCartographyTable").PatchAll(executingAssembly);
		}

		public void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetUpConfigWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath));
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				return;
			}
			try
			{
				Logger.LogDebug((object)"Attempting to reload configuration...");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				Logger.LogError((object)("There was an issue loading " + ((BaseUnityPlugin)this).Config.ConfigFilePath));
			}
		}
	}
}
namespace BetterCartographyTable.UI
{
	public static class InteractionManagerUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static PopupButtonCallback <0>__Pop;
		}

		private static string header;

		private static string text;

		private static string Header => header ?? (header = Localization.instance.Localize("$MapTableToggleMode_PopupHeader"));

		private static string Text => text ?? (text = Localization.instance.Localize("$MapTableToggleMode_PopupText"));

		public static void ShowToggleModePopup(Action onYesCallback)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			string obj = Header;
			string obj2 = Text;
			PopupButtonCallback val = delegate
			{
				OnYes(onYesCallback);
			};
			object obj3 = <>O.<0>__Pop;
			if (obj3 == null)
			{
				PopupButtonCallback val2 = UnifiedPopup.Pop;
				<>O.<0>__Pop = val2;
				obj3 = (object)val2;
			}
			UnifiedPopup.Push((PopupBase)new YesNoPopup(obj, obj2, val, (PopupButtonCallback)obj3, true));
		}

		private static void OnYes(Action onYesCallback)
		{
			onYesCallback();
			UnifiedPopup.Pop();
		}
	}
	public static class MinimapManagerUI
	{
		private static float yOffset;

		private static GameObject AddPinKeyHint { get; set; }

		private static GameObject CrossOffPinKeyHint { get; set; }

		private static GameObject RemovePinKeyHint { get; set; }

		private static GameObject ModifierKeyHint { get; set; }

		private static Toggle PublicPinsToggle { get; set; }

		private static Toggle GuildPinsToggle { get; set; }

		private static bool ArePublicPinsDisplayed { get; set; }

		private static bool AreGuildPinsDisplayed { get; set; }

		public static void OnAwake()
		{
			//IL_0023: 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)
			Minimap.instance.m_sharedMapHint.SetText("$PinsToggle_SharedExploration");
			yOffset = Minimap.instance.m_sharedMapHint.transform.position.y - ((Component)Minimap.instance.m_publicPosition).transform.position.y;
			PublicPinsToggle = CreateNewPinToggle(Minimap.instance.m_sharedMapHint, "PublicPins", "$PinsToggle_PublicPins", OnPublicPinsToggle, yOffset);
			GuildPinsToggle = CreateNewPinToggle(Minimap.instance.m_sharedMapHint, "GuildPins", "$PinsToggle_GuildPins", OnGuildPinsToggle, 2f * yOffset);
			Transform transform = Minimap.instance.m_hints[0].transform;
			AddPinKeyHint = ((Component)transform.Find("keyboard_hints/AddPin")).gameObject;
			CrossOffPinKeyHint = ((Component)transform.Find("keyboard_hints/CrossOffPin")).gameObject;
			RemovePinKeyHint = ((Component)transform.Find("keyboard_hints/RemovePin")).gameObject;
			ModifierKeyHint = CreateModifierKeyHint(AddPinKeyHint);
		}

		public static void OnStart()
		{
			ArePublicPinsDisplayed = true;
			AreGuildPinsDisplayed = true;
		}

		public static void ShowModifierKeyHintAndPinToggle(SharingMode mode)
		{
			ModifierKeyHint.SetActive(true);
			Toggle val = null;
			switch (mode)
			{
			case SharingMode.Public:
				val = PublicPinsToggle;
				break;
			case SharingMode.Guild:
				val = GuildPinsToggle;
				break;
			}
			val.isOn = true;
			((Component)((Component)val).transform.parent).gameObject.SetActive(true);
		}

		public static void HideModifierKeyHintAndPinToggles()
		{
			ModifierKeyHint.SetActive(false);
			if (!MinimapManager.PublicPins.Any())
			{
				((Component)((Component)PublicPinsToggle).transform.parent).gameObject.SetActive(false);
			}
			if (!MinimapManager.GuildPins.Any())
			{
				((Component)((Component)GuildPinsToggle).transform.parent).gameObject.SetActive(false);
			}
		}

		public static void OnUpdatePins()
		{
			UpdateKeyHints();
			UpdatePins();
		}

		private static void UpdateKeyHints()
		{
			if (ModifierKeyHint.activeInHierarchy)
			{
				if (InteractionManager.CurrentMapTableMode == SharingMode.Public)
				{
					ModifierKeyHint.SetText("$KeyHint_PublicModifierKey");
				}
				else if (InteractionManager.CurrentMapTableMode == SharingMode.Guild)
				{
					ModifierKeyHint.SetText("$KeyHint_GuildModifierKey");
				}
			}
			if (!Plugin.IsModifierKeyPushed)
			{
				AddPinKeyHint.SetActive(true);
				CrossOffPinKeyHint.SetText("$hud_crossoffpin");
				if (InteractionManager.IsInteracting)
				{
					RemovePinKeyHint.SetText("$KeyHint_RemovePrivatePin");
				}
				else
				{
					RemovePinKeyHint.SetText("$hud_removepin");
				}
			}
			else if (Plugin.IsModifierKeyPushed && InteractionManager.CurrentMapTableMode == SharingMode.Public)
			{
				AddPinKeyHint.SetActive(false);
				CrossOffPinKeyHint.SetText("$KeyHint_TogglePublic");
				RemovePinKeyHint.SetText("$KeyHint_RemovePublicPin");
			}
			else if (Plugin.IsModifierKeyPushed && InteractionManager.CurrentMapTableMode == SharingMode.Guild)
			{
				AddPinKeyHint.SetActive(false);
				CrossOffPinKeyHint.SetText("$KeyHint_ToggleGuild");
				RemovePinKeyHint.SetText("$KeyHint_RemoveGuildPin");
			}
		}

		private static void UpdatePins()
		{
			//IL_0027: 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)
			foreach (SharablePinData publicPin in MinimapManager.PublicPins)
			{
				publicPin.SetVisibility(ArePublicPinsDisplayed);
				if (ArePublicPinsDisplayed)
				{
					publicPin.SetColor(Plugin.PublicPinsColor);
				}
			}
			foreach (SharablePinData guildPin in MinimapManager.GuildPins)
			{
				guildPin.SetVisibility(AreGuildPinsDisplayed);
				if (AreGuildPinsDisplayed)
				{
					guildPin.SetColor(GuildsManager.CurrentGuildColor);
				}
			}
		}

		private static void OnPublicPinsToggle(bool isOn)
		{
			ArePublicPinsDisplayed = isOn;
		}

		private static void OnGuildPinsToggle(bool isOn)
		{
			AreGuildPinsDisplayed = isOn;
		}

		private static Toggle CreateNewPinToggle(GameObject original, string namePrefix, string labelText, UnityAction<bool> callback, float YOffset = 0f)
		{
			//IL_002b: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(original, original.transform.parent);
			val.transform.position = new Vector3(val.transform.position.x, val.transform.position.y + YOffset, val.transform.position.z);
			((Object)val).name = namePrefix + "Panel";
			((Object)val.transform.Find("PublicPosition")).name = namePrefix + "Position";
			val.SetText(labelText);
			Toggle componentInChildren = val.GetComponentInChildren<Toggle>();
			((UnityEventBase)componentInChildren.onValueChanged).SetPersistentListenerState(0, (UnityEventCallState)0);
			((UnityEvent<bool>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				callback.Invoke(value);
			});
			val.SetActive(true);
			return componentInChildren;
		}

		private static GameObject CreateModifierKeyHint(GameObject original)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(original, original.transform.parent);
			((Object)val).name = "ModifierKey";
			val.transform.SetAsFirstSibling();
			Object.Destroy((Object)(object)((Component)val.transform.Find("keyboard_hint")).gameObject);
			GameObject obj = Object.Instantiate<GameObject>(((Component)KeyHints.m_instance.m_buildHints.transform.Find("Keyboard/AltPlace/key_bkg")).gameObject, val.transform);
			((Object)obj).name = "key_bkg";
			KeyboardShortcut modifierKey = Plugin.ModifierKey;
			string text = ((object)(KeyboardShortcut)(ref modifierKey)).ToString();
			obj.SetText(text);
			val.SetActive(false);
			return val;
		}
	}
}
namespace BetterCartographyTable.Patches
{
	public static class GamePatches
	{
		[HarmonyPatch(typeof(Game), "Start")]
		private class RegisterGuildOnGameStart
		{
			private static void Postfix()
			{
				GuildsManager.OnGameStart();
			}
		}
	}
	public static class MapTablePatches
	{
		[HarmonyPatch(typeof(MapTable), "Start")]
		private class RegisterCustomZDODataRPCsOnMapTableStart
		{
			private static void Postfix(MapTable __instance)
			{
				__instance.OnStart();
			}
		}

		[HarmonyPatch]
		private class StartInteractionOnMapTableUse
		{
			private static IEnumerable<MethodInfo> TargetMethods()
			{
				return new <>z__ReadOnlyArray<MethodInfo>(new MethodInfo[3]
				{
					AccessTools.DeclaredMethod(typeof(MapTable), "OnRead", new Type[3]
					{
						typeof(Switch),
						typeof(Humanoid),
						typeof(ItemData)
					}, (Type[])null),
					AccessTools.DeclaredMethod(typeof(MapTable), "OnRead", new Type[4]
					{
						typeof(Switch),
						typeof(Humanoid),
						typeof(ItemData),
						typeof(bool)
					}, (Type[])null),
					AccessTools.DeclaredMethod(typeof(MapTable), "OnWrite", (Type[])null, (Type[])null)
				});
			}

			private static bool Prefix(MapTable __instance, Switch caller, Humanoid user, ItemData item, ref bool __result)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				bool result = false;
				bool num = item != null;
				bool flag = !__instance.m_nview.IsValid();
				if (num || flag)
				{
					__result = false;
					return result;
				}
				if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false))
				{
					__result = true;
					return result;
				}
				if (__instance != null)
				{
					InteractionManager.OnMapTableUse(__instance, user);
				}
				__result = true;
				return result;
			}
		}

		[HarmonyPatch]
		private class ReplaceMapTableHoverText
		{
			private static IEnumerable<MethodInfo> TargetMethods()
			{
				return new <>z__ReadOnlyArray<MethodInfo>(new MethodInfo[2]
				{
					AccessTools.DeclaredMethod(typeof(MapTable), "GetReadHoverText", (Type[])null, (Type[])null),
					AccessTools.DeclaredMethod(typeof(MapTable), "GetWriteHoverText", (Type[])null, (Type[])null)
				});
			}

			private static void Postfix(MapTable __instance, ref string __result)
			{
				if (__instance != null)
				{
					string hoverText = InteractionManager.GetHoverText(__instance);
					__result = Localization.instance.Localize(hoverText);
				}
			}
		}
	}
	public static class MinimapPatches
	{
		[HarmonyPatch(typeof(Minimap), "Awake")]
		private class InjectSharablePinsAndCreatePinToggles
		{
			private static void Postfix()
			{
				MinimapManager.OnAwake();
				MinimapManagerUI.OnAwake();
			}
		}

		[HarmonyPatch(typeof(Minimap), "Start")]
		private class ResetTogglesVisiblityOnStart
		{
			private static void Postfix()
			{
				MinimapManagerUI.OnStart();
			}
		}

		[HarmonyPatch(typeof(Minimap), "SetMapMode")]
		private class HandleInteractionsOnMapModeChange
		{
			private static bool isNoMapModeEnabled;

			private static void Prefix(MapMode mode)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				bool num = (int)mode == 2;
				isNoMapModeEnabled = Game.m_noMap;
				if (num && InteractionManager.IsInteracting && isNoMapModeEnabled)
				{
					Game.m_noMap = false;
				}
				if (!num)
				{
					InteractionManager.OnMapClose();
				}
			}

			private static void Postfix()
			{
				if (isNoMapModeEnabled)
				{
					Game.m_noMap = true;
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "AddPin")]
		private class InjectSharablePinsAndSharablePinDataInAddPin
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Expected O, but got Unknown
				return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Newobj, (object)AccessTools.Constructor(typeof(PinData), (Type[])null, false), (string)null)
				}).ThrowIfInvalid("Could not patch PinData constructor in Minimap.AddPin(...)").SetOperandAndAdvance((object)AccessTools.Constructor(typeof(SharablePinData), (Type[])null, false))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(List<PinData>), "Add", (Type[])null, (Type[])null), (string)null)
					})
					.ThrowIfInvalid("Could not patch List<PinData>.Add(...) method in Minimap.AddPin(...)")
					.SetOperandAndAdvance((object)AccessTools.Method(typeof(SharablePins), "Add", (Type[])null, (Type[])null))
					.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdatePins")]
		private class UpdateUIOnUpdatePins
		{
			private static void Postfix()
			{
				MinimapManagerUI.OnUpdatePins();
			}
		}

		[HarmonyPatch(typeof(Minimap), "OnMapDblClick")]
		private class InterceptOnMapDblClick
		{
			private static bool Prefix()
			{
				return InteractionManager.OnMapDblClick();
			}
		}

		[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
		private class InterceptOnMapLeftClick
		{
			private static bool Prefix()
			{
				InteractionManager.OnMapLeftClick();
				return false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "OnMapRightClick")]
		private class InterceptOnMapRightClick
		{
			private static bool Prefix()
			{
				InteractionManager.OnMapRightClick();
				return false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "GetMapData")]
		private class InjectPrivatePinsInGetMapData
		{
			private static List<PinData> privatePins;

			private static void Prefix()
			{
				privatePins = ((IEnumerable<PinData>)MinimapManager.PrivatePins).ToList();
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: 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_0035: Expected O, but got Unknown
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Expected O, but got Unknown
				return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Minimap), "m_pins"), (string)null)
				}).ThrowIfInvalid("Could not inject pins replacement in Minimap.GetMapData()").SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InjectPrivatePinsInGetMapData), "privatePins"))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Minimap), "m_pins"), (string)null)
					})
					.ThrowIfInvalid("Could not inject pins replacement in Minimap.GetMapData()")
					.SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InjectPrivatePinsInGetMapData), "privatePins"))
					.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(Minimap), "GetSharedMapData")]
		private class InjectPublicPinsInGetSharedMapData
		{
			private static List<PinData> publicPins;

			private static void Prefix()
			{
				publicPins = ((IEnumerable<PinData>)MinimapManager.PublicPins).ToList();
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: 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_0035: Expected O, but got Unknown
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Expected O, but got Unknown
				return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Minimap), "m_pins"), (string)null)
				}).ThrowIfInvalid("Could not inject pins replacement in Minimap.GetSharedMapData()").SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InjectPublicPinsInGetSharedMapData), "publicPins"))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Minimap), "m_pins"), (string)null)
					})
					.ThrowIfInvalid("Could not inject pins replacement in Minimap.GetSharedMapData()")
					.SetAndAdvance(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InjectPublicPinsInGetSharedMapData), "publicPins"))
					.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(Minimap), "AddSharedMapData")]
		private class TruncateAddSharedMapData
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: 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_0022: Expected O, but got Unknown
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected O, but got Unknown
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Expected O, but got Unknown
				return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_1, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_I4_2, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
				}).ThrowIfInvalid("Could not truncate Minimap.AddSharedMapData()").SetAndAdvance(OpCodes.Ldloc_3, (object)null)
					.SetAndAdvance(OpCodes.Ret, (object)null)
					.InstructionEnumeration();
			}
		}
	}
	public static class PlayerPatches
	{
		[HarmonyPatch(typeof(Player), "Save")]
		public static class SaveSharedPinsOnPlayerSave
		{
			private static void Prefix()
			{
				PlayerSaveManager.OnSave();
			}
		}

		[HarmonyPatch(typeof(Player), "Load")]
		public static class LoadSharedPinsOnPlayerLoad
		{
			private static void Postfix()
			{
				PlayerSaveManager.OnLoad();
			}
		}
	}
}
namespace BetterCartographyTable.Model
{
	public enum PinEvent
	{
		Add,
		ToggleChecked,
		Remove
	}
	public class SharablePinData : PinData, IEquatable<PinData>
	{
		private static readonly HashSet<PinType> sharablePinTypes = new HashSet<PinType>
		{
			(PinType)0,
			(PinType)1,
			(PinType)2,
			(PinType)3,
			(PinType)6,
			(PinType)9,
			(PinType)14,
			(PinType)15,
			(PinType)16
		};

		public SharingMode SharingMode { get; set; }

		public bool IsSharable => sharablePinTypes.Contains(base.m_type);

		public bool IsPrivate => SharingMode == SharingMode.Private;

		public bool IsPublic => SharingMode == SharingMode.Public;

		public bool IsGuild => SharingMode == SharingMode.Guild;

		public bool IsShared => !IsPrivate;

		public bool IsMapTablePin(MapTable mapTable)
		{
			var (flag, flag2) = mapTable.GetModes();
			if (!flag || !IsPublic)
			{
				if (flag2)
				{
					return IsGuild;
				}
				return false;
			}
			return true;
		}

		public void ToggleChecked()
		{
			base.m_checked = !base.m_checked;
		}

		public override string ToString()
		{
			//IL_0025: 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)
			return string.Format("{0} {1} {2} {3} {4} {5}L {6}", SharingMode, base.m_name, base.m_pos, base.m_checked ? "⦻" : "⭘", base.m_author, base.m_ownerID, Enum.GetName(typeof(PinType), base.m_type));
		}

		public void SetVisibility(bool isVisible)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			RectTransform uiElement = base.m_uiElement;
			if (uiElement != null)
			{
				GameObject gameObject = ((Component)uiElement).gameObject;
				if (gameObject != null)
				{
					gameObject.SetActive(isVisible);
				}
			}
			if ((int)Minimap.instance.m_mode != 2)
			{
				return;
			}
			PinNameData namePinData = base.m_NamePinData;
			if (namePinData == null)
			{
				return;
			}
			GameObject pinNameGameObject = namePinData.PinNameGameObject;
			if (pinNameGameObject != null)
			{
				GameObject gameObject2 = pinNameGameObject.gameObject;
				if (gameObject2 != null)
				{
					gameObject2.SetActive(isVisible);
				}
			}
		}

		public void SetColor(Color color)
		{
			//IL_000b: 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)
			Image iconElement = base.m_iconElement;
			if (iconElement != null)
			{
				((Graphic)iconElement).color = color;
			}
			PinNameData namePinData = base.m_NamePinData;
			TMP_Text val = ((namePinData != null) ? namePinData.PinNameText : null);
			if (val != null)
			{
				((Graphic)val).color = color;
			}
		}

		public ZPackage ToZPackage()
		{
			//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_000c: Expected O, but got Unknown
			//IL_0011: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			ZPackageExtensions.Write(val, this);
			return ZPackageExtensions.GetCompressed(val);
		}

		public bool Equals(PinData other)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (other == null)
			{
				return false;
			}
			if ((object)this == other)
			{
				return true;
			}
			return ((Vector3)(ref base.m_pos)).Equals(other.m_pos);
		}

		public override bool Equals(object obj)
		{
			return Equals((PinData)((obj is PinData) ? obj : null));
		}

		public static bool operator ==(SharablePinData a, PinData b)
		{
			if ((object)a != b)
			{
				return a?.Equals(b) ?? false;
			}
			return true;
		}

		public static bool operator !=(SharablePinData a, PinData b)
		{
			return !(a == b);
		}

		public override int GetHashCode()
		{
			return ((object)(Vector3)(ref base.m_pos)).GetHashCode();
		}
	}
	public class SharablePins : List<PinData>
	{
		public IEnumerable<SharablePinData> AsSharable => this.Cast<SharablePinData>();

		public IEnumerable<SharablePinData> PrivatePins => AsSharable.Where((SharablePinData p) => p.IsPrivate);

		public IEnumerable<SharablePinData> SharedPins => AsSharable.Where((SharablePinData p) => p.IsShared);

		public IEnumerable<SharablePinData> PublicPins => AsSharable.Where((SharablePinData p) => p.IsPublic);

		public IEnumerable<SharablePinData> GuildPins => AsSharable.Where((SharablePinData p) => p.IsGuild);

		public ZPackage ToZPackage()
		{
			return AsSharable.ToZPackage();
		}

		public new void Add(PinData pin)
		{
			if (!Contains(pin))
			{
				pin.m_ownerID = 0L;
				base.Add(pin);
			}
		}
	}
	public static class IEnumerableSharablePinDataExtensions
	{
		public static ZPackage ToZPackage(this IEnumerable<SharablePinData> pins)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(pins.Count());
			long playerID = Player.m_localPlayer.GetPlayerID();
			string networkUserId = PrivilegeManager.GetNetworkUserId();
			foreach (SharablePinData pin in pins)
			{
				val.Write(pin, playerID, networkUserId);
			}
			return val.GetCompressed();
		}
	}
	public enum SharingMode
	{
		Private,
		Public,
		Guild
	}
}
namespace BetterCartographyTable.Managers
{
	public static class GuildsManager
	{
		private static readonly Color fallbackColor = new Color(1f, 61f / 85f, 49f / 136f);

		private static Color? color = null;

		public static bool IsEnabled => API.IsLoaded();

		public static string CurrentGuildName { get; private set; }

		public static Color CurrentGuildColor => (Color)(((??)color) ?? LazySetGuildColor());

		private static Guild GetCurrentGuild()
		{
			if (!IsEnabled)
			{
				return null;
			}
			return API.GetOwnGuild();
		}

		public static void OnGameStart()
		{
			if (!IsEnabled)
			{
				return;
			}
			Guild currentGuild = GetCurrentGuild();
			if (currentGuild != null)
			{
				Register(currentGuild);
			}
			API.RegisterOnGuildJoined(delegate(Guild guild, PlayerReference player)
			{
				if (player == PlayerReference.forOwnPlayer())
				{
					Register(guild);
				}
			});
			API.RegisterOnGuildLeft(delegate(Guild _, PlayerReference player)
			{
				if (player == PlayerReference.forOwnPlayer())
				{
					Unregister();
				}
			});
		}

		private static void Register(Guild guild)
		{
			CurrentGuildName = guild.Name;
		}

		private static void Unregister()
		{
			CurrentGuildName = null;
			color = null;
			MinimapManager.RemovePins(MinimapManager.GuildPins);
		}

		private static Color LazySetGuildColor()
		{
			//IL_002a: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			Guild currentGuild = GetCurrentGuild();
			Color val = default(Color);
			if (currentGuild != null && ColorUtility.TryParseHtmlString(currentGuild.General.color, ref val))
			{
				color = val;
				return val;
			}
			return fallbackColor;
		}
	}
	public static class InteractionManager
	{
		private static MapTable currentMapTable;

		private static MapTable CurrentMapTable
		{
			get
			{
				return currentMapTable;
			}
			set
			{
				currentMapTable = value;
				CurrentMapTableMode = value?.RetrieveModeFromZDO();
			}
		}

		public static bool IsInteracting => currentMapTable != null;

		public static SharingMode? CurrentMapTableMode { get; private set; }

		public static void OnMapTableUse(MapTable mapTable, Humanoid user)
		{
			if (!IsInteracting)
			{
				if (!HasAccess(mapTable))
				{
					((Character)user).Message((MessageType)2, Localization.instance.Localize("$piece_noaccess"), 0, (Sprite)null);
					return;
				}
				if (Plugin.IsModifierKeyPushed && GuildsManager.IsEnabled)
				{
					TryToggleMode(mapTable, user);
					return;
				}
				CurrentMapTable = mapTable;
				MinimapManager.ReplaceMinimapPinsWithTablePins(CurrentMapTable);
				CurrentMapTable.SyncVanillaSharedData();
				CurrentMapTable.StartListeningForPinEvents();
				MinimapManager.OpenMap(mapTable);
			}
		}

		private static bool HasAccess(MapTable mapTable)
		{
			bool result = false;
			(bool isPublic, bool isGuild) modes = mapTable.GetModes();
			bool item = modes.isPublic;
			bool item2 = modes.isGuild;
			string text = mapTable.RetrieveOwnerFromZDO();
			bool flag = text != null && GuildsManager.CurrentGuildName == text;
			if (item || (item2 && flag))
			{
				result = true;
			}
			return result;
		}

		private static void TryToggleMode(MapTable mapTable, Humanoid user)
		{
			if (mapTable.RetrievePinsFromZDO().Any())
			{
				InteractionManagerUI.ShowToggleModePopup(delegate
				{
					DoToggleMode(mapTable, user);
				});
			}
			else
			{
				DoToggleMode(mapTable, user);
			}
		}

		private static void DoToggleMode(MapTable mapTable, Humanoid user)
		{
			var (flag, flag2) = mapTable.GetModes();
			if (flag)
			{
				if (!string.IsNullOrEmpty(GuildsManager.CurrentGuildName))
				{
					mapTable.RestrictToGuild(GuildsManager.CurrentGuildName);
				}
				else
				{
					((Character)user).Message((MessageType)2, Localization.instance.Localize("$MapTableToggleMode_GuildRequired"), 0, (Sprite)null);
				}
			}
			else if (flag2)
			{
				mapTable.MakePublic();
			}
		}

		public static string GetHoverText(MapTable mapTable)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			bool flag = mapTable.RetrieveModeFromZDO() == SharingMode.Guild;
			string text = mapTable.RetrieveOwnerFromZDO();
			string text2 = mapTable.m_name + "\n";
			text2 += (flag ? ("$MapTableHoverText_RestrictedToGuild: " + text) : "$MapTableHoverText_Public");
			if (!HasAccess(mapTable))
			{
				return text2;
			}
			text2 += "\n[<color=yellow><b>$KEY_Use</b></color>] $piece_use";
			if (!GuildsManager.IsEnabled)
			{
				return text2;
			}
			string arg = (flag ? "$MapTableHoverText_MakePublic" : "$MapTableHoverText_RestrictToGuild");
			return text2 + $"\n[<b><color=yellow>{Plugin.ModifierKey}</color> + <color=yellow>$KEY_Use</color></b>] {arg}";
		}

		public static void OnMapClose()
		{
			if (IsInteracting)
			{
				CurrentMapTable.SyncVanillaSharedData();
				CurrentMapTable.ReplaceTablePinsWithMinimapPins();
				CurrentMapTable.StopListeningForPinEvents();
				MinimapManager.OnMapClose();
				CurrentMapTable = null;
			}
		}

		public static bool OnMapDblClick()
		{
			bool result = true;
			if (Plugin.IsModifierKeyPushed)
			{
				result = false;
			}
			return result;
		}

		public static void OnMapLeftClick()
		{
			MinimapManager.HidePinTextInput();
			SharablePinData closestPinToMouse = MinimapManager.GetClosestPinToMouse();
			if ((object)closestPinToMouse == null)
			{
				return;
			}
			if (!Plugin.IsModifierKeyPushed && closestPinToMouse.IsPrivate)
			{
				closestPinToMouse.ToggleChecked();
			}
			else if (IsInteracting && closestPinToMouse.IsSharable)
			{
				bool flag = closestPinToMouse.IsMapTablePin(CurrentMapTable);
				bool num = Plugin.IsModifierKeyPushed && closestPinToMouse.IsPrivate;
				bool flag2 = !Plugin.IsModifierKeyPushed && flag;
				bool flag3 = Plugin.IsModifierKeyPushed && flag;
				if (num)
				{
					closestPinToMouse.SharingMode = CurrentMapTableMode.Value;
					CurrentMapTable.SendPinEvent(closestPinToMouse, PinEvent.Add);
				}
				else if (flag2)
				{
					closestPinToMouse.ToggleChecked();
					CurrentMapTable.SendPinEvent(closestPinToMouse, PinEvent.ToggleChecked);
				}
				else if (flag3)
				{
					closestPinToMouse.SharingMode = SharingMode.Private;
					CurrentMapTable.SendPinEvent(closestPinToMouse, PinEvent.Remove);
				}
			}
		}

		public static void OnMapRightClick()
		{
			MinimapManager.HidePinTextInput();
			SharablePinData closestPinToMouse = MinimapManager.GetClosestPinToMouse();
			if ((object)closestPinToMouse == null)
			{
				return;
			}
			if (!Plugin.IsModifierKeyPushed && closestPinToMouse.IsPrivate)
			{
				MinimapManager.RemovePin(closestPinToMouse);
			}
			else if (IsInteracting && closestPinToMouse.IsSharable)
			{
				bool flag = closestPinToMouse.IsMapTablePin(CurrentMapTable);
				bool num = Plugin.IsModifierKeyPushed && closestPinToMouse.IsPrivate;
				bool flag2 = !Plugin.IsModifierKeyPushed && flag;
				bool flag3 = Plugin.IsModifierKeyPushed && flag;
				if (!(num || flag2) && flag3)
				{
					MinimapManager.RemovePin(closestPinToMouse);
					CurrentMapTable.SendPinEvent(closestPinToMouse, PinEvent.Remove);
				}
			}
		}
	}
	public static class MinimapManager
	{
		private static SharablePins Pins { get; } = new SharablePins();


		public static IEnumerable<SharablePinData> PrivatePins => Pins.PrivatePins;

		public static IEnumerable<SharablePinData> SharedPins => Pins.SharedPins;

		public static IEnumerable<SharablePinData> PublicPins => Pins.PublicPins;

		public static IEnumerable<SharablePinData> GuildPins => Pins.GuildPins;

		public static void OnAwake()
		{
			Minimap.instance.m_pins = Pins;
		}

		public static IEnumerable<SharablePinData> GetPinsForMode(SharingMode mode)
		{
			return mode switch
			{
				SharingMode.Public => PublicPins, 
				SharingMode.Guild => GuildPins, 
				_ => Array.Empty<SharablePinData>(), 
			};
		}

		public static void ReplaceMinimapPinsWithTablePins(MapTable mapTable)
		{
			RemovePins(GetPinsForMode(mapTable.RetrieveModeFromZDO()));
			AddPins(mapTable.RetrievePinsFromZDO());
		}

		public static void RemoveTablePins(MapTable mapTable)
		{
			RemovePins(mapTable.RetrievePinsFromZDO());
		}

		public static void AddPins(IEnumerable<SharablePinData> pins)
		{
			pins.ToList().ForEach(delegate(SharablePinData pin)
			{
				Minimap.instance.AddPin(pin);
			});
		}

		public static void RemovePins(IEnumerable<SharablePinData> pins)
		{
			pins.ToList().ForEach(delegate(SharablePinData pin)
			{
				Minimap.instance.RemovePin((PinData)(object)pin);
			});
		}

		public static void RemovePin(SharablePinData pin)
		{
			Minimap.instance.RemovePin((PinData)(object)pin);
		}

		public static void HandlePinEvent(ZPackage zPackage, PinEvent pinEvent)
		{
			zPackage = zPackage.GetDecompressed();
			SharablePinData pin = zPackage.ReadSharablePin();
			SharablePinData sharablePinData = Pins.AsSharable.SingleOrDefault((SharablePinData p) => pin.Equals((PinData)(object)p));
			bool flag = (object)sharablePinData == null && pinEvent == PinEvent.Add;
			bool flag2 = (object)sharablePinData != null && pinEvent == PinEvent.ToggleChecked;
			bool flag3 = (object)sharablePinData != null && pinEvent == PinEvent.Remove;
			if (flag)
			{
				Minimap.instance.AddPin(pin);
				return;
			}
			if (flag2)
			{
				sharablePinData.ToggleChecked();
				return;
			}
			if (flag3)
			{
				Minimap.instance.RemovePin((PinData)(object)sharablePinData);
				return;
			}
			string text = string.Format("Invalid minimap state: cannot handle the received PinEvent given the current minimap data.\r\n{0}.{1} | pin: {2} | isAdd: {3} | isUpdate: {4} | isRemove: {5}", "MinimapManager", "HandlePinEvent", pin, flag, flag2, flag3);
			Plugin.Logger.LogError((object)text);
		}

		public static void OpenMap(MapTable mapTable)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			MinimapManagerUI.ShowModifierKeyHintAndPinToggle(mapTable.RetrieveModeFromZDO());
			Minimap.instance.ShowPointOnMap(((Component)mapTable).transform.position);
		}

		public static void OnMapClose()
		{
			MinimapManagerUI.HideModifierKeyHintAndPinToggles();
		}

		public static void HidePinTextInput()
		{
			Minimap.instance.HidePinTextInput(false);
		}

		public static SharablePinData GetClosestPinToMouse()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Minimap.instance.ScreenToWorldPoint(Input.mousePosition);
			float num = Minimap.instance.m_removeRadius * (Minimap.instance.m_largeZoom * 2f);
			return (SharablePinData)(object)Minimap.instance.GetClosestPin(val, num, true);
		}
	}
	public static class PlayerSaveManager
	{
		private const string pinsKey = "nbusseneau.BetterCartographyTable.Pins";

		private static string PinsKey => string.Format("{0}.{1}", "nbusseneau.BetterCartographyTable.Pins", ZNet.instance.GetWorldUID());

		public static void OnSave()
		{
			if (Player.m_localPlayer != null)
			{
				StorePinsInPlayerSavefile(MinimapManager.SharedPins);
			}
		}

		private static void StorePinsInPlayerSavefile(IEnumerable<SharablePinData> pins)
		{
			string @base = pins.ToZPackage().GetBase64();
			Player.m_localPlayer.m_customData[PinsKey] = @base;
		}

		public static void OnLoad()
		{
			if (Player.m_localPlayer != null)
			{
				MinimapManager.AddPins(RetrievePinsFromPlayerSavefile());
			}
		}

		private static IEnumerable<SharablePinData> RetrievePinsFromPlayerSavefile()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (!Player.m_localPlayer.m_customData.ContainsKey(PinsKey))
			{
				return Array.Empty<SharablePinData>();
			}
			return ZPackageExtensions.GetDecompressed(new ZPackage(Player.m_localPlayer.m_customData[PinsKey])).ReadSharablePinList();
		}
	}
}
namespace BetterCartographyTable.Extensions
{
	public static class GameObjectExtensions
	{
		public static void SetText(this GameObject gameObject, string text)
		{
			TextMeshProUGUI componentInChildren = gameObject.GetComponentInChildren<TextMeshProUGUI>();
			string text2 = Localization.instance.Localize(text);
			((TMP_Text)componentInChildren).SetText(text2);
		}
	}
	public static class MapTableExtensions
	{
		private const string pinsZDOKey = "nbusseneau.BetterCartographyTable.MapTable.Pins";

		private const string storePinsInZDORPCName = "nbusseneau.BetterCartographyTable.RPC_StorePinsInZDO";

		private const string modeZDOKey = "nbusseneau.BetterCartographyTable.MapTable.Mode";

		private const string storeModeInZDORPCName = "nbusseneau.BetterCartographyTable.RPC_StoreModeInZDO";

		private const string ownerZDOKey = "nbusseneau.BetterCartographyTable.MapTable.Owner";

		private const string storeOwnerInZDORPCName = "nbusseneau.BetterCartographyTable.RPC_StoreOwnerInZDO";

		private const string onPinEventRPCName = "nbusseneau.BetterCartographyTable.RPC_OnPinEvent";

		public static void OnStart(this MapTable mapTable)
		{
			mapTable.m_nview.Register<ZPackage>("nbusseneau.BetterCartographyTable.RPC_StorePinsInZDO", (Action<long, ZPackage>)delegate(long _, ZPackage zPackage)
			{
				mapTable.RPC_StorePinsInZDO(zPackage);
			});
			mapTable.m_nview.Register<int>("nbusseneau.BetterCartographyTable.RPC_StoreModeInZDO", (Action<long, int>)delegate(long _, int mode)
			{
				mapTable.RPC_StoreModeInZDO(mode);
			});
			mapTable.m_nview.Register<string>("nbusseneau.BetterCartographyTable.RPC_StoreOwnerInZDO", (Action<long, string>)delegate(long _, string owner)
			{
				mapTable.RPC_StoreOwnerInZDO(owner);
			});
		}

		public static void MakePublic(this MapTable mapTable)
		{
			MinimapManager.RemoveTablePins(mapTable);
			mapTable.StorePinsInZDO(Array.Empty<SharablePinData>());
			mapTable.StoreModeInZDO(SharingMode.Public);
			mapTable.StoreOwnerInZDO(string.Empty);
		}

		public static void RestrictToGuild(this MapTable mapTable, string guildName)
		{
			MinimapManager.RemoveTablePins(mapTable);
			mapTable.StorePinsInZDO(Array.Empty<SharablePinData>());
			mapTable.StoreModeInZDO(SharingMode.Guild);
			mapTable.StoreOwnerInZDO(guildName);
		}

		public static void ReplaceTablePinsWithMinimapPins(this MapTable mapTable)
		{
			IEnumerable<SharablePinData> pinsForMode = MinimapManager.GetPinsForMode(mapTable.RetrieveModeFromZDO());
			mapTable.StorePinsInZDO(pinsForMode);
		}

		private static void StorePinsInZDO(this MapTable mapTable, IEnumerable<SharablePinData> pins)
		{
			ZPackage val = pins.ToZPackage();
			if (mapTable.m_nview.IsOwner())
			{
				mapTable.m_nview.GetZDO().Set("nbusseneau.BetterCartographyTable.MapTable.Pins", val.GetArray());
				return;
			}
			mapTable.m_nview.InvokeRPC("nbusseneau.BetterCartographyTable.RPC_StorePinsInZDO", new object[1] { val });
		}

		private static void RPC_StorePinsInZDO(this MapTable mapTable, ZPackage zPackage)
		{
			if (mapTable.m_nview.IsOwner())
			{
				mapTable.m_nview.GetZDO().Set("nbusseneau.BetterCartographyTable.MapTable.Pins", zPackage.GetArray());
			}
		}

		public static IEnumerable<SharablePinData> RetrievePinsFromZDO(this MapTable mapTable)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			byte[] byteArray = mapTable.m_nview.GetZDO().GetByteArray("nbusseneau.BetterCartographyTable.MapTable.Pins", (byte[])null);
			if (byteArray != null)
			{
				byteArray = Utils.Decompress(byteArray);
				return ZPackageExtensions.ReadSharablePinList(new ZPackage(byteArray));
			}
			return Array.Empty<SharablePinData>();
		}

		public static (bool isPublic, bool isGuild) GetModes(this MapTable mapTable)
		{
			SharingMode num = mapTable.RetrieveModeFromZDO();
			bool item = num == SharingMode.Public;
			bool item2 = num == SharingMode.Guild;
			return (item, item2);
		}

		private static void StoreModeInZDO(this MapTable mapTable, SharingMode mode)
		{
			if (mapTable.m_nview.IsOwner())
			{
				mapTable.m_nview.GetZDO().Set("nbusseneau.BetterCartographyTable.MapTable.Mode", (int)mode);
				return;
			}
			mapTable.m_nview.InvokeRPC("nbusseneau.BetterCartographyTable.RPC_StoreModeInZDO", new object[1] { (int)mode });
		}

		private static void RPC_StoreModeInZDO(this MapTable mapTable, int mode)
		{
			if (mapTable.m_nview.IsOwner())
			{
				mapTable.m_nview.GetZDO().Set("nbusseneau.BetterCartographyTable.MapTable.Mode", mode);
			}
		}

		public static SharingMode RetrieveModeFromZDO(this MapTable mapTable)
		{
			return (SharingMode)mapTable.m_nview.GetZDO().GetInt("nbusseneau.BetterCartographyTable.MapTable.Mode", 1);
		}

		private static void StoreOwnerInZDO(this MapTable mapTable, string owner)
		{
			if (mapTable.m_nview.IsOwner())
			{
				mapTable.m_nview.GetZDO().Set("nbusseneau.BetterCartographyTable.MapTable.Owner", owner);
				return;
			}
			mapTable.m_nview.InvokeRPC("nbusseneau.BetterCartographyTable.RPC_StoreOwnerInZDO", new object[1] { owner });
		}

		private static void RPC_StoreOwnerInZDO(this MapTable mapTable, string owner)
		{
			if (mapTable.m_nview.IsOwner())
			{
				mapTable.m_nview.GetZDO().Set("nbusseneau.BetterCartographyTable.MapTable.Owner", owner);
			}
		}

		public static string RetrieveOwnerFromZDO(this MapTable mapTable)
		{
			return mapTable.m_nview.GetZDO().GetString("nbusseneau.BetterCartographyTable.MapTable.Owner", (string)null);
		}

		public static void SyncVanillaSharedData(this MapTable mapTable)
		{
			mapTable.RetrieveExploredMapFromZDO();
			mapTable.StoreExploredMapAndPublicPinsInZDO();
		}

		private static void RetrieveExploredMapFromZDO(this MapTable mapTable)
		{
			byte[] byteArray = mapTable.m_nview.GetZDO().GetByteArray(ZDOVars.s_data, (byte[])null);
			if (byteArray != null)
			{
				byteArray = Utils.Decompress(byteArray);
				Minimap.instance.AddSharedMapData(byteArray);
			}
		}

		private static void StoreExploredMapAndPublicPinsInZDO(this MapTable mapTable)
		{
			byte[] array = mapTable.m_nview.GetZDO().GetByteArray(ZDOVars.s_data, (byte[])null);
			if (array != null)
			{
				array = Utils.Decompress(array);
			}
			ZPackage mapData = mapTable.GetMapData(array);
			mapTable.m_nview.InvokeRPC("MapData", new object[1] { mapData });
		}

		public static void StartListeningForPinEvents(this MapTable mapTable)
		{
			mapTable.m_nview.Register<ZPackage, int>("nbusseneau.BetterCartographyTable.RPC_OnPinEvent", (Action<long, ZPackage, int>)RPC_OnPinEvent);
		}

		public static void StopListeningForPinEvents(this MapTable mapTable)
		{
			mapTable.m_nview.Unregister("nbusseneau.BetterCartographyTable.RPC_OnPinEvent");
		}

		public static void SendPinEvent(this MapTable mapTable, SharablePinData pin, PinEvent pinEvent)
		{
			mapTable.m_nview.InvokeRPC(ZNetView.Everybody, "nbusseneau.BetterCartographyTable.RPC_OnPinEvent", new object[2]
			{
				pin.ToZPackage(),
				(int)pinEvent
			});
			mapTable.ReplaceTablePinsWithMinimapPins();
		}

		private static void RPC_OnPinEvent(long senderId, ZPackage zPackage, int pinEventInt)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZDOID zDOID = ((Character)Player.m_localPlayer).GetZDOID();
			long userID = ((ZDOID)(ref zDOID)).UserID;
			if (senderId != userID)
			{
				MinimapManager.HandlePinEvent(zPackage, (PinEvent)pinEventInt);
			}
		}
	}
	public static class MinimapExtensions
	{
		public static SharablePinData AddPin(this Minimap minimap, SharablePinData pin)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return minimap.AddPin(((PinData)pin).m_pos, ((PinData)pin).m_type, ((PinData)pin).m_name, save: true, ((PinData)pin).m_checked, ((PinData)pin).m_ownerID, ((PinData)pin).m_author, pin.SharingMode);
		}

		private static SharablePinData AddPin(this Minimap minimap, Vector3 pos, PinType type, string name, bool save, bool isChecked, long ownerID = 0L, string author = "", SharingMode sharingMode = SharingMode.Private)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SharablePinData obj = (SharablePinData)(object)minimap.AddPin(pos, type, name, save, isChecked, ownerID, author);
			obj.SharingMode = sharingMode;
			return obj;
		}
	}
	public static class ZPackageExtensions
	{
		public static ZPackage GetCompressed(this ZPackage zPackage)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return new ZPackage(Utils.Compress(zPackage.GetArray()));
		}

		public static ZPackage GetDecompressed(this ZPackage zPackage)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return new ZPackage(Utils.Decompress(zPackage.GetArray()));
		}

		public static SharablePinData ReadSharablePin(this ZPackage zPackage)
		{
			//IL_000f: 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_001b: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			long ownerID = zPackage.ReadLong();
			string name = zPackage.ReadString();
			Vector3 pos = zPackage.ReadVector3();
			PinType type = (PinType)zPackage.ReadInt();
			bool @checked = zPackage.ReadBool();
			string author = zPackage.ReadString();
			SharingMode sharingMode = (SharingMode)zPackage.ReadInt();
			return new SharablePinData
			{
				m_name = name,
				m_type = type,
				m_pos = pos,
				m_ownerID = ownerID,
				m_author = author,
				m_checked = @checked,
				SharingMode = sharingMode
			};
		}

		public static List<SharablePinData> ReadSharablePinList(this ZPackage zPackage)
		{
			List<SharablePinData> list = new List<SharablePinData>();
			int num = zPackage.ReadInt();
			for (int i = 0; i < num; i++)
			{
				SharablePinData item = zPackage.ReadSharablePin();
				list.Add(item);
			}
			return list;
		}

		public static void Write(this ZPackage zPackage, SharablePinData pin, long currentPlayerID, string networkUserId)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected I4, but got Unknown
			long num = ((((PinData)pin).m_ownerID != 0L) ? ((PinData)pin).m_ownerID : currentPlayerID);
			string text = ((string.IsNullOrEmpty(((PinData)pin).m_author) && num == currentPlayerID) ? networkUserId : ((PinData)pin).m_author);
			zPackage.Write(num);
			zPackage.Write(((PinData)pin).m_name);
			zPackage.Write(((PinData)pin).m_pos);
			zPackage.Write((int)((PinData)pin).m_type);
			zPackage.Write(((PinData)pin).m_checked);
			zPackage.Write(text);
			zPackage.Write((int)pin.SharingMode);
		}

		public static void Write(this ZPackage zPackage, SharablePinData pin)
		{
			long playerID = Player.m_localPlayer.GetPlayerID();
			string networkUserId = PrivilegeManager.GetNetworkUserId();
			zPackage.Write(pin, playerID, networkUserId);
		}
	}
}
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

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

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Guilds
{
	[PublicAPI]
	internal static class API
	{
		public delegate void AchievementCompleted(PlayerReference player, string achievment);

		public delegate void GuildJoined(Guild guild, PlayerReference player);

		public delegate void GuildLeft(Guild guild, PlayerReference player);

		public delegate void GuildCreated(Guild guild);

		public delegate void GuildDeleted(Guild guild);

		public static bool IsLoaded()
		{
			return false;
		}

		public static Guild? GetPlayerGuild(PlayerReference player)
		{
			return null;
		}

		public static Guild? GetPlayerGuild(Player player)
		{
			return GetPlayerGuild(PlayerReference.fromPlayer(player));
		}

		public static Guild? GetOwnGuild()
		{
			return GetPlayerGuild(PlayerReference.forOwnPlayer());
		}

		public static Guild? GetGuild(string name)
		{
			return null;
		}

		public static Guild? GetGuild(int id)
		{
			return null;
		}

		public static List<Guild> GetGuilds()
		{
			return new List<Guild>();
		}

		public static PlayerReference GetGuildLeader(Guild guild)
		{
			return guild.Members.FirstOrDefault<KeyValuePair<PlayerReference, GuildMember>>((KeyValuePair<PlayerReference, GuildMember> r) => r.Value.rank == Ranks.Leader).Key;
		}

		public static Guild? CreateGuild(string name, PlayerReference leader)
		{
			return null;
		}

		public static bool DeleteGuild(Guild guild)
		{
			return false;
		}

		public static bool RenameGuild(Guild guild, string newName)
		{
			return true;
		}

		public static bool SaveGuild(Guild guild)
		{
			return false;
		}

		public static bool AddPlayerToGuild(PlayerReference player, Guild guild)
		{
			if (GetPlayerGuild(player) == null)
			{
				guild.Members.Add(player, new GuildMember());
				SaveGuild(guild);
				return true;
			}
			return false;
		}

		public static bool RemovePlayerFromGuild(PlayerReference player)
		{
			Guild playerGuild = GetPlayerGuild(player);
			if (playerGuild != null)
			{
				playerGuild.Members.Remove(player);
				SaveGuild(playerGuild);
				return true;
			}
			return false;
		}

		public static Ranks GetPlayerRank(PlayerReference player)
		{
			return GetPlayerGuild(player)?.Members[player].rank ?? Ranks.Leader;
		}

		public static bool UpdatePlayerRank(PlayerReference player, Ranks newRank)
		{
			Guild playerGuild = GetPlayerGuild(player);
			if (playerGuild != null)
			{
				GuildMember guildMember = playerGuild.Members[player];
				guildMember.rank = newRank;
				playerGuild.Members[player] = guildMember;
				SaveGuild(playerGuild);
				return true;
			}
			return false;
		}

		public static IEnumerable<PlayerReference> GetOnlinePlayers(Guild? guild = null)
		{
			HashSet<PlayerReference> hashSet = new HashSet<PlayerReference>(ZNet.instance.m_players.Select(PlayerReference.fromPlayerInfo));
			if (guild != null)
			{
				return guild.Members.Keys.Where(hashSet.Contains);
			}
			foreach (PlayerReference item in GetGuilds().SelectMany((Guild g) => g.Members.Keys))
			{
				hashSet.Remove(item);
			}
			return hashSet;
		}

		public static Guild? GetOwnAppliedGuild()
		{
			return GetPlayerAppliedGuild(PlayerReference.forOwnPlayer());
		}

		public static Guild? GetPlayerAppliedGuild(PlayerReference player)
		{
			return null;
		}

		public static bool ApplyToGuild(PlayerReference player, string description, Guild guild)
		{
			RemovePlayerApplication(player);
			guild.Applications[player] = new Application
			{
				description = description
			};
			return SaveGuild(guild);
		}

		public static bool RemovePlayerApplication(PlayerReference player, Guild? guild = null)
		{
			Guild playerAppliedGuild = GetPlayerAppliedGuild(player);
			if (playerAppliedGuild != null && (guild == null || playerAppliedGuild == guild))
			{
				playerAppliedGuild.Applications.Remove(player);
				return SaveGuild(playerAppliedGuild);
			}
			return true;
		}

		public static void RegisterCustomData(Type type)
		{
		}

		public static T? GetCustomData<T>(Guild guild) where T : class
		{
			return null;
		}

		public static void SetCustomData<T>(Guild guild, T customData) where T : class
		{
		}

		public static void IncreaseAchievementProgress(Guild guild, string achievement, float increment = 1f)
		{
		}

		public static void RegisterOnAchievementCompleted(AchievementCompleted callback)
		{
		}

		public static void RegisterAchievement(string name, AchievementConfig config)
		{
		}

		internal static AchievementConfig? GetAchievementConfig(string achievement)
		{
			return null;
		}

		internal static IEnumerable<KeyValuePair<string, AchievementConfig>> AllAchievementConfigs()
		{
			return Array.Empty<KeyValuePair<string, AchievementConfig>>();
		}

		public static Sprite? GetGuildIcon(Guild guild)
		{
			return null;
		}

		public static Sprite? GetGuildIconById(int iconId)
		{
			return null;
		}

		public static int GetAchievementStage(Guild guild, AchievementConfig achievement)
		{
			return 0;
		}

		public static void RegisterOnGuildJoined(GuildJoined callback)
		{
		}

		public static void RegisterOnGuildLeft(GuildLeft callback)
		{
		}

		public static void RegisterOnGuildCreated(GuildCreated callback)
		{
		}

		public static void RegisterOnGuildDeleted(GuildDeleted callback)
		{
		}
	}
	[PublicAPI]
	internal class Guild
	{
		public string Name = "";

		public GuildGeneral General = new GuildGeneral();

		public Dictionary<PlayerReference, GuildMember> Members = new Dictionary<PlayerReference, GuildMember>();

		public Dictionary<PlayerReference, Application> Applications = new Dictionary<PlayerReference, Application>();

		public Dictionary<string, AchievementData> Achievements = new Dictionary<string, AchievementData>();

		public CustomData customData = new CustomData();
	}
	[PublicAPI]
	internal class GuildMember
	{
		public Ranks rank = Ranks.Member;

		public DateTime lastOnline = DateTime.Now;

		public Dictionary<int, Dictionary<string, int>> contribution = new Dictionary<int, Dictionary<string, int>>();
	}
	[PublicAPI]
	internal class GuildGeneral
	{
		public int id = 0;

		public string description = "";

		public int icon = 1;

		public int level = 0;

		public string color = "";
	}
	[PublicAPI]
	internal class Application
	{
		public DateTime applied = DateTime.Now;

		public string description = "";
	}
	[PublicAPI]
	internal class AchievementData
	{
		public float? progress = 0f;

		public List<DateTime> completed = new List<DateTime>();
	}
	[PublicAPI]
	internal class CustomData
	{
		internal Dictionary<Type, object> data = new Dictionary<Type, object>();

		internal Dictionary<string, object> unknown = new Dictionary<string, object>();
	}
	[PublicAPI]
	internal class AchievementConfig
	{
		public string name = "";

		public string description = "";

		public List<float> progress = new List<float> { 1f };

		public List<int>? guild = null;

		public List<int> level = new List<int>();

		public string icon = "";

		public bool first;

		public Dictionary<string, string> config = new Dictionary<string, string>();

		public T getConfigValue<T>(string name, T defaultValue = default(T))
		{
			return defaultValue;
		}
	}
	[PublicAPI]
	[TypeConverter(typeof(PlayerReferenceTypeConverter))]
	internal struct PlayerReference
	{
		public string id;

		public string name;

		public static PlayerReference fromPlayerInfo(PlayerInfo playerInfo)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			PlayerReference result = default(PlayerReference);
			result.id = (Utility.IsNullOrWhiteSpace(playerInfo.m_host) ? PrivilegeManager.GetNetworkUserId() : (playerInfo.m_host.Contains("_") ? playerInfo.m_host : ("Steam_" + playerInfo.m_host)));
			result.name = playerInfo.m_name ?? "";
			return result;
		}

		public static PlayerReference fromPlayer(Player player)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Player player2 = player;
			return ((Object)(object)player2 == (Object)(object)Player.m_localPlayer) ? forOwnPlayer() : fromPlayerInfo(((IEnumerable<PlayerInfo>)ZNet.instance.m_players).FirstOrDefault((Func<PlayerInfo, bool>)((PlayerInfo info) => info.m_characterID == ((Character)player2).GetZDOID())));
		}

		public static PlayerReference forOwnPlayer()
		{
			PlayerReference result = default(PlayerReference);
			result.id = PrivilegeManager.GetNetworkUserId();
			result.name = Game.instance.GetPlayerProfile().GetName();
			return result;
		}

		public static bool operator !=(PlayerReference a, PlayerReference b)
		{
			return !(a == b);
		}

		public static bool operator ==(PlayerReference a, PlayerReference b)
		{
			return a.id == b.id && a.name == b.name;
		}

		public bool Equals(PlayerReference other)
		{
			return this == other;
		}

		public override bool Equals(object? obj)
		{
			return obj is PlayerReference other && Equals(other);
		}

		public override int GetHashCode()
		{
			return (id.GetHashCode() * 397) ^ name.GetHashCode();
		}

		public override string ToString()
		{
			return id + ":" + name;
		}

		public static PlayerReference fromString(string str)
		{
			string[] array = str.Split(new char[1] { ':' });
			PlayerReference result = default(PlayerReference);
			result.id = array[0];
			result.name = array[1];
			return result;
		}
	}
	internal class PlayerReferenceTypeConverter : System.ComponentModel.TypeConverter
	{
		public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object? value)
		{
			return PlayerReference.fromString(value?.ToString() ?? ":");
		}
	}
	internal enum Toggle
	{
		On = 1,
		Off = 0
	}
	internal enum Ranks
	{
		Leader,
		Coleader,
		Officer,
		Member
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<b89b921d-8954-4084-bd4d-1feb826a594e>Embedded]
	internal sealed class <b89b921d-8954-4084-bd4d-1feb826a594e>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<b89b921d-8954-4084-bd4d-1feb826a594e>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<b89b921d-8954-4084-bd4d-1feb826a594e>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace LocalizationManager
{
	[<f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>Nullable(0)]
	[PublicAPI]
	[<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(1)]
	internal class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		[<f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out var value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out var value2))
			{
				text = value2.Aggregate(text, [<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(0)] (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, [<f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>Nullable(new byte[] { 2, 1, 1 })] Func<T, string> convertConfigValue = null)
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = [<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(0)] [return: <f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>Nullable(1)] (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += [<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(0)] (object _, EventArgs _) =>
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1];
				if (dictionary.ContainsKey(text))
				{
					Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
				}
				else
				{
					dictionary[text] = item;
				}
			}
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.ContainsKey(language))
				{
					text2 = File.ReadAllText(dictionary[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text2 = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text2 == null && dictionary.ContainsKey("English"))
			{
				text2 = File.ReadAllText(dictionary["English"]);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			new Harmony("org.bepinex.helpers.LocalizationManager").Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		[return: <f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>Nullable(2)]
		private static byte[] LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		[<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(2)]
		public static byte[] ReadEmbeddedFileBytes([<f6f8ff5f-fa45-43ba-9489-b740a9e7c98b>Nullable(1)] string resourceFileName, Assembly containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault([<bb5e3e5e-5c47-485a-88ef-ea5afd7f01c7>NullableContext(0)] (string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		internal ITypeResolver typeResolver;

		internal readonly YamlAttributeOverrides overrides;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		private bool ignoreFields;

		private bool includeNonPublicProperties;

		protected abstract TBuilder Self { get; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<TagName, Type> tagMappings;

		private readonly Dictionary<Type, Type> typeMappings;

		private bool ignoreUnmatched;

		protected override DeserializerBuilder Self => this;

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

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

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

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

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

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

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

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

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

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

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

		public Des