Decompiled source of GC Client v1.7.0

GC_Client.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GC.Client.AutoDoor;
using GC.Client.CarryLimit;
using GC.Client.CartCollect;
using GC.Client.Compare;
using GC.Client.Compass;
using GC.Client.DungeonMap;
using GC.Client.MassHarvest;
using GC.Client.PortalGuard;
using GC.Client.QuickTake;
using GC.Client.Sort;
using GC.Client.Trash;
using GC.Shared;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: <37f69a44-49ab-4fd2-ab96-bf7462024aca>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <37f69a44-49ab-4fd2-ab96-bf7462024aca>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <37f69a44-49ab-4fd2-ab96-bf7462024aca>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("Gorduan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: AssemblyInformationalVersion("1.7.0+c9d5288b96ac31e780ee94b8f27fd48c2d248dff")]
[assembly: AssemblyProduct("GC_Client")]
[assembly: AssemblyTitle("GC_Client")]
[assembly: <02fd42c7-9979-487e-9c2f-76661a523373>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <02fd42c7-9979-487e-9c2f-76661a523373>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <02fd42c7-9979-487e-9c2f-76661a523373>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <5ee8f811-bd99-4463-b934-5528eb07a3d5>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <5ee8f811-bd99-4463-b934-5528eb07a3d5>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <5ee8f811-bd99-4463-b934-5528eb07a3d5>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <197c1f94-b781-4c1b-9076-9b8adab7750f>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <197c1f94-b781-4c1b-9076-9b8adab7750f>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <197c1f94-b781-4c1b-9076-9b8adab7750f>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <c1acd51f-b3b7-4440-a8e6-6769e04434a6>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <c1acd51f-b3b7-4440-a8e6-6769e04434a6>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <c1acd51f-b3b7-4440-a8e6-6769e04434a6>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <e3727a32-ffa0-41ce-99c9-4ddf745169a4>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <e3727a32-ffa0-41ce-99c9-4ddf745169a4>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <e3727a32-ffa0-41ce-99c9-4ddf745169a4>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <34a107b2-9b31-4213-baee-ba0bef277eac>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <34a107b2-9b31-4213-baee-ba0bef277eac>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <34a107b2-9b31-4213-baee-ba0bef277eac>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <fdaea21d-170e-4e2a-aeef-01470ca17251>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <fdaea21d-170e-4e2a-aeef-01470ca17251>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <fdaea21d-170e-4e2a-aeef-01470ca17251>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <64de2ee8-d827-423f-b586-6bad830e8e99>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <64de2ee8-d827-423f-b586-6bad830e8e99>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <64de2ee8-d827-423f-b586-6bad830e8e99>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <23849cb3-d487-4266-a2a8-10a7a6b42c46>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <23849cb3-d487-4266-a2a8-10a7a6b42c46>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <23849cb3-d487-4266-a2a8-10a7a6b42c46>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: <eaccbbd9-7910-4348-b0e5-99fc37b2a7bf>IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: <eaccbbd9-7910-4348-b0e5-99fc37b2a7bf>IgnoresAccessChecksTo("assembly_utils")]
[assembly: <eaccbbd9-7910-4348-b0e5-99fc37b2a7bf>IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class <37f69a44-49ab-4fd2-ab96-bf7462024aca>IgnoresAccessChecksToAttribute : Attribute
	{
		public <37f69a44-49ab-4fd2-ab96-bf7462024aca>IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace GC.Client
{
	internal static class <02fd42c7-9979-487e-9c2f-76661a523373>ClientPlugin
	{
		internal static ManualLogSource Log;

		internal static GcModule? Module;

		internal static bool Allowed
		{
			get
			{
				if (Module != null)
				{
					return Module.Allowed;
				}
				return true;
			}
		}

		internal static bool OnServer
		{
			get
			{
				if (Module != null)
				{
					return Module.OnServer;
				}
				return false;
			}
		}
	}
}
namespace GC.Client.ModDungeonKarte
{
	[BepInPlugin("gorduan.gc.dungeonkarte", "GC_DungeonKarte", "1.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static GcModule Module;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Module = GcKern.Register((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger, GcMod.Info);
			<02fd42c7-9979-487e-9c2f-76661a523373>ClientPlugin.Log = ((BaseUnityPlugin)this).Logger;
			<02fd42c7-9979-487e-9c2f-76661a523373>ClientPlugin.Module = Module;
			Harmony harmony = new Harmony("gorduan.gc.dungeonkarte");
			GC.Client.DungeonMap.Plugin.Init(((BaseUnityPlugin)this).Config, harmony);
			Module.TakeOverOldSettings();
			GcHooks.DungeonMapLargeOpen = () => GC.Client.DungeonMap.Plugin.View != null && GC.Client.DungeonMap.Plugin.View.LargeOpen;
			GcMod.PatchAll(harmony);
			Module.MenuGroup((Func<string, string>)((string key) => GcLoc.Get("gccm_" + key, Array.Empty<object>())), (string)null).Main("dungeonmap", (ConfigEntryBase)(object)GC.Client.DungeonMap.Plugin.Enabled, (Func<bool>)(() => GC.Client.DungeonMap.Plugin.Blocked), "GC_DungeonMap", (Func<string>)null, 0.0, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null).Sub("dungeonmap_size", (ConfigEntryBase)(object)GC.Client.DungeonMap.Plugin.SmallSize, 20.0, " px", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("dungeonmap_zoom", (ConfigEntryBase)(object)GC.Client.DungeonMap.Plugin.SmallZoom, 0.5, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("dungeonmap_minimap", (ConfigEntryBase)(object)GC.Client.DungeonMap.Plugin.HideVanillaMinimap, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null);
		}

		private void Update()
		{
			if (!Gc.IsHeadless)
			{
				Module.Guard("Dungeon-Karte", (Action)GC.Client.DungeonMap.Plugin.Update);
			}
		}
	}
	internal static class GcMod
	{
		public const string Id = "dungeonkarte";

		public const string Guid = "gorduan.gc.dungeonkarte";

		public const string Name = "GC_DungeonKarte";

		public const string Version = "1.7.0";

		public const int Stufe = 3;

		public static readonly Type[] PatchTypes = new Type[3]
		{
			typeof(MapModePatch),
			typeof(MenuEscPatch),
			typeof(PlayerSavePatch)
		};

		public static readonly List<string> FailedPatches = new List<string>();

		public static GcModInfo Info => new GcModInfo
		{
			Id = "dungeonkarte",
			Guid = "gorduan.gc.dungeonkarte",
			Name = "GC_DungeonKarte",
			Version = "1.7.0",
			Stufe = 3,
			Seite = (GcSeite)0,
			Braucht = Array.Empty<string>(),
			Partner = Array.Empty<string>(),
			Fremd = Array.Empty<string>(),
			AlteConfig = "gorduan.gc_client.cfg",
			Ausgleich = 0f
		};

		public static void PatchAll(Harmony harmony)
		{
			Type[] patchTypes = PatchTypes;
			foreach (Type type in patchTypes)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					FailedPatches.Add(type.Name);
					Logger.CreateLogSource("GC_DungeonKarte").LogError((object)$"Patch {type.FullName} nicht eingespielt, diese Funktion fehlt: {arg}");
				}
			}
		}
	}
}
namespace GC.Client.DungeonMap
{
	internal static class Plugin
	{
		public const string Guid = "gorduan.gc_dungeonmap";

		public const string ModName = "GC_DungeonMap";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> SmallSize;

		internal static ConfigEntry<float> SmallZoom;

		internal static ConfigEntry<Vector2> SmallOffset;

		internal static ConfigEntry<bool> HideVanillaMinimap;

		internal static MapView? View;

		internal static bool Blocked => Chainloader.PluginInfos.ContainsKey("gorduan.gc_dungeonmap");

		internal static bool On
		{
			get
			{
				if (Enabled.Value && !Blocked)
				{
					return <02fd42c7-9979-487e-9c2f-76661a523373>ClientPlugin.Allowed;
				}
				return false;
			}
		}

		internal static void Init(ConfigFile Config, Harmony harmony)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Log = <02fd42c7-9979-487e-9c2f-76661a523373>ClientPlugin.Log;
			Enabled = Gc.Bind<bool>(Config, "9 - DungeonMap", "Enabled", true, "Funktion ein- oder ausschalten (auch im Menü GC Option).", (AcceptableValueBase)null);
			SmallSize = Gc.Bind<float>(Config, "9 - DungeonMap - Interface", "SmallMapSize", 240f, "Größe der kleinen Dungeon-Karte in Pixeln.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(120f, 500f));
			SmallZoom = Gc.Bind<float>(Config, "9 - DungeonMap - Interface", "SmallMapPixelsPerMeter", 3f, "Maßstab der kleinen Karte (Pixel pro Meter).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f));
			SmallOffset = Gc.Bind<Vector2>(Config, "9 - DungeonMap - Interface", "SmallMapOffset", new Vector2(-24f, -24f), "Abstand der kleinen Karte von der oberen rechten Bildschirmecke.", (AcceptableValueBase)null);
			HideVanillaMinimap = Gc.Bind<bool>(Config, "9 - DungeonMap - Interface", "HideVanillaMinimapInDungeon", true, "Im Dungeon die normale Minimap ausblenden.", (AcceptableValueBase)null);
		}

		internal static void Update()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)GUIManager.CustomGUIBack == (Object)null)
			{
				View?.Hide();
				View = null;
				return;
			}
			if (!On || Gc.IsHeadless || Game.m_noMap)
			{
				View?.Hide();
				return;
			}
			if (View == null)
			{
				View = new MapView();
			}
			View.Tick(localPlayer);
		}
	}
	[HarmonyPatch(typeof(Minimap), "SetMapMode")]
	internal static class MapModePatch
	{
		private static bool Prefix(MapMode mode)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			if (!Plugin.On || Game.m_noMap || (int)mode != 2 || (Object)(object)Player.m_localPlayer == (Object)null || !((Character)Player.m_localPlayer).InInterior() || Plugin.View == null)
			{
				return true;
			}
			Plugin.View.ToggleLarge();
			return false;
		}
	}
	[HarmonyPatch(typeof(Menu), "Update")]
	internal static class MenuEscPatch
	{
		private static bool Prefix(Menu __instance)
		{
			MapView view = Plugin.View;
			if (view == null || (Object)(object)__instance.m_root == (Object)null || ((Component)__instance.m_root).gameObject.activeSelf || !ZInput.GetKeyDown((KeyCode)27, true))
			{
				return true;
			}
			if (view.LargeOpen)
			{
				view.CloseLarge();
			}
			return view.EscFrame != Time.frameCount;
		}
	}
	internal sealed class DungeonData
	{
		public string Key = "";

		public Vector3 Origin;

		public List<Room> Rooms = new List<Room>();

		public Dictionary<Room, string> RoomKeys = new Dictionary<Room, string>();

		public HashSet<string> Explored = new HashSet<string>();
	}
	internal sealed class MapView
	{
		private const string DataPrefix = "gc_dmap_";

		private static readonly Color RoomColor = new Color(0.82f, 0.72f, 0.52f, 0.95f);

		private static readonly Color CurrentColor = new Color(1f, 0.85f, 0.45f, 1f);

		private static readonly Color OtherFloorColor = new Color(0.82f, 0.72f, 0.52f, 0.25f);

		private static readonly Color DoorColor = new Color(0.25f, 0.15f, 0.07f, 1f);

		private GameObject? small;

		private RectTransform? smallContent;

		private GameObject? large;

		private RectTransform? largeContent;

		private Image? smallPlayer;

		private Image? largePlayer;

		private readonly Dictionary<Room, Image> smallRooms = new Dictionary<Room, Image>();

		private readonly Dictionary<Room, Image> largeRooms = new Dictionary<Room, Image>();

		private DungeonData? current;

		private float nextScan;

		private float nextTick;

		private bool minimapHidden;

		private bool dirty = true;

		private static Sprite? arrow;

		public bool LargeOpen
		{
			get
			{
				if ((Object)(object)large != (Object)null)
				{
					return large.activeSelf;
				}
				return false;
			}
		}

		public int EscFrame { get; private set; } = -10;

		public void CloseLarge()
		{
			if ((Object)(object)large != (Object)null)
			{
				large.SetActive(false);
			}
			EscFrame = Time.frameCount;
		}

		public void Hide()
		{
			if ((Object)(object)small != (Object)null)
			{
				small.SetActive(false);
			}
			if ((Object)(object)large != (Object)null)
			{
				large.SetActive(false);
			}
			RestoreMinimap();
		}

		public void ToggleLarge()
		{
			Build();
			bool active = !large.activeSelf;
			large.SetActive(active);
			dirty = true;
		}

		public void Tick(Player player)
		{
			if (!((Character)player).InInterior())
			{
				if (current != null)
				{
					Save(player);
					current = null;
				}
				Hide();
				return;
			}
			Build();
			if (large.activeSelf && Input.GetKeyDown((KeyCode)27))
			{
				CloseLarge();
			}
			if (Plugin.HideVanillaMinimap.Value && (Object)(object)Minimap.instance != (Object)null && (Object)(object)Minimap.instance.m_smallRoot != (Object)null && Minimap.instance.m_smallRoot.activeSelf)
			{
				Minimap.instance.m_smallRoot.SetActive(false);
				minimapHidden = true;
			}
			small.SetActive(true);
			if (Time.time >= nextScan || current == null)
			{
				nextScan = Time.time + 3f;
				Scan(player);
			}
			if (current != null)
			{
				if (Time.time >= nextTick)
				{
					nextTick = Time.time + 0.25f;
					Explore(player);
				}
				Draw(player);
			}
		}

		private void RestoreMinimap()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			if (minimapHidden && (Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 1)
			{
				Minimap.instance.m_smallRoot.SetActive(true);
			}
			minimapHidden = false;
		}

		private void Scan(Player player)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			DungeonGenerator val = (from g in Object.FindObjectsByType<DungeonGenerator>((FindObjectsSortMode)0)
				where (Object)(object)g != (Object)null && ((Component)g).transform.position.y > 2000f
				orderby Utils.DistanceXZ(((Component)g).transform.position, position)
				select g).FirstOrDefault();
			if ((Object)(object)val == (Object)null || Utils.DistanceXZ(((Component)val).transform.position, position) > 400f)
			{
				return;
			}
			Vector3 origin = ((Component)val).transform.position;
			string arg = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldName() : "world");
			string text = $"{arg}_{Mathf.RoundToInt(origin.x)}_{Mathf.RoundToInt(origin.z)}";
			if (current == null || current.Key != text)
			{
				if (current != null)
				{
					Save(player);
				}
				current = new DungeonData
				{
					Key = text,
					Origin = origin
				};
				Load(player);
				ClearImages();
			}
			List<Room> list = (from r in Object.FindObjectsByType<Room>((FindObjectsSortMode)0)
				where (Object)(object)r != (Object)null && ((Component)r).transform.position.y > 2000f && Utils.DistanceXZ(((Component)r).transform.position, origin) < 400f
				select r).ToList();
			if (list.Count != current.Rooms.Count)
			{
				current.Rooms = list;
				current.RoomKeys = list.ToDictionary((Room r) => r, (Room r) => RoomKey(r, origin));
				dirty = true;
			}
		}

		private static string RoomKey(Room room, Vector3 origin)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)room).transform.position - origin;
			return $"{Mathf.RoundToInt(val.x)}:{Mathf.RoundToInt(val.y)}:{Mathf.RoundToInt(val.z)}";
		}

		private static bool Inside(Room room, Vector3 point)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)room).transform.InverseTransformPoint(point);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor((float)((Vector3Int)(ref room.m_size)).x * 0.5f + 0.5f, (float)((Vector3Int)(ref room.m_size)).y * 0.5f + 1f, (float)((Vector3Int)(ref room.m_size)).z * 0.5f + 0.5f);
			if (Mathf.Abs(val.x) <= val2.x && Mathf.Abs(val.y) <= val2.y)
			{
				return Mathf.Abs(val.z) <= val2.z;
			}
			return false;
		}

		private void Explore(Player player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 point = ((Component)player).transform.position + Vector3.up;
			foreach (Room room in current.Rooms)
			{
				if ((Object)(object)room != (Object)null && Inside(room, point) && current.Explored.Add(current.RoomKeys[room]))
				{
					dirty = true;
				}
			}
		}

		private void Load(Player player)
		{
			if (player.m_customData.TryGetValue("gc_dmap_" + current.Key, out var value))
			{
				string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				foreach (string item in array)
				{
					current.Explored.Add(item);
				}
			}
		}

		public void Save(Player player)
		{
			if (current != null && current.Explored.Count != 0)
			{
				player.m_customData["gc_dmap_" + current.Key] = string.Join(",", current.Explored);
			}
		}

		private void ClearImages()
		{
			foreach (Image item in smallRooms.Values.Concat(largeRooms.Values))
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
				}
			}
			smallRooms.Clear();
			largeRooms.Clear();
			dirty = true;
		}

		private void Draw(Player player)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			DungeonData dungeonData = current;
			float y = ((Component)player).transform.position.y;
			Room here = ((IEnumerable<Room>)dungeonData.Rooms).FirstOrDefault((Func<Room, bool>)((Room r) => (Object)(object)r != (Object)null && Inside(r, ((Component)player).transform.position + Vector3.up)));
			if (dirty)
			{
				dirty = false;
				foreach (Room room in dungeonData.Rooms)
				{
					if (!((Object)(object)room == (Object)null) && dungeonData.RoomKeys.TryGetValue(room, out string value) && dungeonData.Explored.Contains(value))
					{
						if (!smallRooms.ContainsKey(room))
						{
							smallRooms[room] = CreateRoom(smallContent, room);
						}
						if (!largeRooms.ContainsKey(room))
						{
							largeRooms[room] = CreateRoom(largeContent, room);
						}
					}
				}
				FitLarge(dungeonData);
			}
			float value2 = Plugin.SmallZoom.Value;
			Place(smallRooms, value2, dungeonData, here, y);
			smallContent.anchoredPosition = -MapPoint(((Component)player).transform.position, dungeonData.Origin) * value2;
			PlacePlayer(smallPlayer, player, Vector2.zero);
			if (large.activeSelf)
			{
				float x = ((Transform)largeContent).localScale.x;
				Place(largeRooms, 1f, dungeonData, here, y);
				PlacePlayer(largePlayer, player, largeContent.anchoredPosition + MapPoint(((Component)player).transform.position, dungeonData.Origin) * x);
			}
		}

		private static Vector2 MapPoint(Vector3 world, Vector3 origin)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(world.x - origin.x, world.z - origin.z);
		}

		private static void Place(Dictionary<Room, Image> images, float zoom, DungeonData data, Room? here, float playerY)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Room, Image> image in images)
			{
				Room key = image.Key;
				Image value = image.Value;
				if ((Object)(object)key == (Object)null || (Object)(object)value == (Object)null)
				{
					continue;
				}
				RectTransform rectTransform = ((Graphic)value).rectTransform;
				rectTransform.anchoredPosition = MapPoint(((Component)key).transform.position, data.Origin) * zoom;
				rectTransform.sizeDelta = new Vector2((float)((Vector3Int)(ref key.m_size)).x, (float)((Vector3Int)(ref key.m_size)).z) * zoom;
				((Transform)rectTransform).localEulerAngles = new Vector3(0f, 0f, 0f - ((Component)key).transform.eulerAngles.y);
				bool flag = Mathf.Abs(((Component)key).transform.position.y - playerY) < (float)((Vector3Int)(ref key.m_size)).y * 0.5f + 3f;
				((Graphic)value).color = (((Object)(object)key == (Object)(object)here) ? CurrentColor : (flag ? RoomColor : OtherFloorColor));
				foreach (Transform item in (Transform)rectTransform)
				{
					((RectTransform)item).sizeDelta = Vector2.one * Mathf.Max(3f, zoom * 1.5f);
				}
			}
		}

		private static Image CreateRoom(RectTransform parent, Room room)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Room", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)component).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			rectTransform.anchorMax = val2;
			rectTransform.anchorMin = val2;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			RoomConnection[] connections = room.GetConnections();
			foreach (RoomConnection val3 in connections)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					Vector3 val4 = ((Component)room).transform.InverseTransformPoint(((Component)val3).transform.position);
					GameObject val5 = new GameObject("Door", new Type[2]
					{
						typeof(RectTransform),
						typeof(Image)
					});
					val5.transform.SetParent(val.transform, false);
					Image component2 = val5.GetComponent<Image>();
					((Graphic)component2).color = DoorColor;
					((Graphic)component2).raycastTarget = false;
					RectTransform rectTransform2 = ((Graphic)component2).rectTransform;
					((Vector2)(ref val2))..ctor(Mathf.Clamp01(0.5f + val4.x / Mathf.Max(1f, (float)((Vector3Int)(ref room.m_size)).x)), Mathf.Clamp01(0.5f + val4.z / Mathf.Max(1f, (float)((Vector3Int)(ref room.m_size)).z)));
					rectTransform2.anchorMax = val2;
					rectTransform2.anchorMin = val2;
					rectTransform2.anchoredPosition = Vector2.zero;
				}
			}
			return component;
		}

		private void FitLarge(DungeonData data)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			if (largeRooms.Count == 0)
			{
				return;
			}
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue);
			foreach (Room key in largeRooms.Keys)
			{
				if (!((Object)(object)key == (Object)null))
				{
					Vector2 val4 = MapPoint(((Component)key).transform.position, data.Origin);
					float num = (float)Mathf.Max(((Vector3Int)(ref key.m_size)).x, ((Vector3Int)(ref key.m_size)).z) * 0.75f;
					val = Vector2.Min(val, val4 - Vector2.one * num);
					val2 = Vector2.Max(val2, val4 + Vector2.one * num);
				}
			}
			Rect rect = ((RectTransform)large.transform).rect;
			Vector2 val5 = ((Rect)(ref rect)).size - new Vector2(80f, 120f);
			Vector2 val6 = val2 - val;
			float num2 = Mathf.Clamp(Mathf.Min(val5.x / Mathf.Max(1f, val6.x), val5.y / Mathf.Max(1f, val6.y)), 1f, 12f);
			((Transform)largeContent).localScale = Vector3.one * num2;
			largeContent.anchoredPosition = -((val + val2) * 0.5f) * num2;
		}

		private static void PlacePlayer(Image marker, Player player, Vector2 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			((Graphic)marker).rectTransform.anchoredPosition = position;
			((Transform)((Graphic)marker).rectTransform).localEulerAngles = new Vector3(0f, 0f, 0f - ((Component)player).transform.eulerAngles.y);
			((Component)marker).transform.SetAsLastSibling();
		}

		private void Build()
		{
			//IL_0069: 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)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)small != (Object)null) || !((Object)(object)large != (Object)null))
			{
				Transform parent = (((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null) ? Hud.instance.m_rootObject.transform : GUIManager.CustomGUIBack.transform);
				small = CreateFrame("GC_DungeonMap_Small", parent, new Vector2(1f, 1f), Plugin.SmallOffset.Value, Vector2.one * Plugin.SmallSize.Value, out smallContent, out smallPlayer);
				small.transform.SetAsFirstSibling();
				large = CreateFrame("GC_DungeonMap_Large", GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(1000f, 760f), out largeContent, out largePlayer);
				((Graphic)GcUi.CreateLabel(large.transform, GcLoc.Get("gcdm_title", Array.Empty<object>()), new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(20f, -60f), new Vector2(-20f, -10f), 30, (TextAnchor)4, (Color?)GUIManager.Instance.ValheimOrange, true)).raycastTarget = false;
				large.SetActive(false);
				small.SetActive(false);
			}
		}

		private static GameObject CreateFrame(string name, Transform parent, Vector2 anchor, Vector2 position, Vector2 size, out RectTransform content, out Image player)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(RectMask2D)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = (val2.anchorMin = (val2.anchorMax = anchor));
			val2.pivot = anchor;
			val2.anchoredPosition = position;
			val2.sizeDelta = size;
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.08f, 0.06f, 0.04f, 0.85f);
			((Graphic)component).raycastTarget = false;
			Sprite sprite = GUIManager.Instance.GetSprite("panel_interior_bkg_128");
			if ((Object)(object)sprite != (Object)null)
			{
				component.sprite = sprite;
				component.type = (Type)1;
			}
			GameObject val6 = new GameObject("Content", new Type[1] { typeof(RectTransform) });
			val6.transform.SetParent(val.transform, false);
			content = (RectTransform)val6.transform;
			RectTransform obj = content;
			RectTransform obj2 = content;
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			obj2.anchorMax = val3;
			obj.anchorMin = val3;
			content.pivot = new Vector2(0.5f, 0.5f);
			content.sizeDelta = Vector2.zero;
			GameObject val7 = new GameObject("Player", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val7.transform.SetParent(val.transform, false);
			player = val7.GetComponent<Image>();
			player.sprite = Arrow();
			((Graphic)player).color = Color.white;
			((Graphic)player).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)player).rectTransform;
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			rectTransform.anchorMax = val3;
			rectTransform.anchorMin = val3;
			rectTransform.sizeDelta = new Vector2(18f, 18f);
			return val;
		}

		private static Sprite Arrow()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)arrow != (Object)null)
			{
				return arrow;
			}
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num = (float)(32 - i) * 0.45f;
					bool flag = i > 2 && Mathf.Abs((float)j - 16f) < (float)(32 - i) * 0.5f && (i >= 10 || !(Mathf.Abs((float)j - 16f) < num * 0.45f));
					val.SetPixel(j, i, flag ? new Color(1f, 0.3f, 0.2f, 1f) : new Color(0f, 0f, 0f, 0f));
				}
			}
			val.Apply();
			arrow = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f));
			return arrow;
		}
	}
	[HarmonyPatch(typeof(Player), "Save")]
	internal static class PlayerSavePatch
	{
		private static void Prefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && Plugin.View != null && ((Character)__instance).InInterior())
			{
				Plugin.View.Save(__instance);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class <02fd42c7-9979-487e-9c2f-76661a523373>IgnoresAccessChecksToAttribute : Attribute
	{
		public <02fd42c7-9979-487e-9c2f-76661a523373>IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace GC.Client
{
	internal static class <5ee8f811-bd99-4463-b934-5528eb07a3d5>ClientPlugin
	{
		internal static ManualLogSource Log;

		internal static GcModule? Module;

		internal static bool Allowed
		{
			get
			{
				if (Module != null)
				{
					return Module.Allowed;
				}
				return true;
			}
		}

		internal static bool OnServer
		{
			get
			{
				if (Module != null)
				{
					return Module.OnServer;
				}
				return false;
			}
		}
	}
}
namespace GC.Client.ModEinsammeln
{
	[BepInPlugin("gorduan.gc.einsammeln", "GC_Einsammeln", "1.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static GcModule Module;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Module = GcKern.Register((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger, GcMod.Info);
			<5ee8f811-bd99-4463-b934-5528eb07a3d5>ClientPlugin.Log = ((BaseUnityPlugin)this).Logger;
			<5ee8f811-bd99-4463-b934-5528eb07a3d5>ClientPlugin.Module = Module;
			Harmony harmony = new Harmony("gorduan.gc.einsammeln");
			GC.Client.CartCollect.Plugin.Init(((BaseUnityPlugin)this).Config, harmony);
			Module.TakeOverOldSettings();
			GcMod.PatchAll(harmony);
			Module.MenuGroup((Func<string, string>)((string key) => GcLoc.Get("gccm_" + key, Array.Empty<object>())), (string)null).Main("cartcollect", (ConfigEntryBase)(object)GC.Client.CartCollect.Plugin.Enabled, (Func<bool>)(() => GC.Client.CartCollect.Plugin.Blocked), "GC_CartCollect", (Func<string>)null, 0.0, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null).Sub("cartcollect_range", (ConfigEntryBase)(object)GC.Client.CartCollect.Plugin.Range, 1.0, " m", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("cartcollect_matching", (ConfigEntryBase)(object)GC.Client.CartCollect.Plugin.OnlyMatching, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("cartcollect_ships", (ConfigEntryBase)(object)GC.Client.CartCollect.Plugin.IncludeShips, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("cartcollect_pulling", (ConfigEntryBase)(object)GC.Client.CartCollect.Plugin.OnlyWhilePulling, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("cartcollect_key", (ConfigEntryBase)(object)GC.Client.CartCollect.Plugin.ToggleKey, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null);
		}

		private void Update()
		{
			if (!Gc.IsHeadless)
			{
				Module.Guard("Einsammeln", (Action)GC.Client.CartCollect.Plugin.Update);
			}
		}
	}
	internal static class GcMod
	{
		public const string Id = "einsammeln";

		public const string Guid = "gorduan.gc.einsammeln";

		public const string Name = "GC_Einsammeln";

		public const string Version = "1.7.0";

		public const int Stufe = 3;

		public static readonly Type[] PatchTypes = new Type[1] { typeof(GC.Client.CartCollect.PickupPatch) };

		public static readonly List<string> FailedPatches = new List<string>();

		public static GcModInfo Info
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				GcModInfo val = new GcModInfo();
				val.Id = "einsammeln";
				val.Guid = "gorduan.gc.einsammeln";
				val.Name = "GC_Einsammeln";
				val.Version = "1.7.0";
				val.Stufe = 3;
				val.Seite = (GcSeite)0;
				val.Braucht = Array.Empty<string>();
				val.Partner = Array.Empty<string>();
				val.Fremd = new string[1] { "gorduan.guilds_vehicle" };
				val.AlteConfig = "gorduan.gc_client.cfg";
				val.Ausgleich = 0f;
				return val;
			}
		}

		public static void PatchAll(Harmony harmony)
		{
			Type[] patchTypes = PatchTypes;
			foreach (Type type in patchTypes)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					FailedPatches.Add(type.Name);
					Logger.CreateLogSource("GC_Einsammeln").LogError((object)$"Patch {type.FullName} nicht eingespielt, diese Funktion fehlt: {arg}");
				}
			}
		}
	}
}
namespace GC.Client.CartCollect
{
	internal static class Plugin
	{
		public const string Guid = "gorduan.gc_cartcollect";

		public const string ModName = "GC_CartCollect";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log = null;

		internal static ConfigEntry<bool> Enabled = null;

		internal static ConfigEntry<float> Range = null;

		internal static ConfigEntry<bool> OnlyMatching = null;

		internal static ConfigEntry<bool> IncludeShips = null;

		internal static ConfigEntry<bool> OnlyWhilePulling = null;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey = null;

		internal static bool paused;

		internal static MethodInfo? canUseCargo;

		private static bool cargoCheckFailed;

		private static readonly Collider[] Hits = (Collider[])(object)new Collider[64];

		internal static bool Blocked => Chainloader.PluginInfos.ContainsKey("gorduan.gc_cartcollect");

		internal static bool On
		{
			get
			{
				if (Enabled.Value && !Blocked)
				{
					return <5ee8f811-bd99-4463-b934-5528eb07a3d5>ClientPlugin.Allowed;
				}
				return false;
			}
		}

		internal static void Init(ConfigFile Config, Harmony harmony)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			Log = <5ee8f811-bd99-4463-b934-5528eb07a3d5>ClientPlugin.Log;
			Enabled = Gc.Bind<bool>(Config, "5 - CartCollect", "Enabled", true, "Funktion ein- oder ausschalten (auch im Menü GC Option).", (AcceptableValueBase)null);
			Range = Gc.Bind<float>(Config, "5 - CartCollect", "Range", 10f, "Suchradius in Metern um den Spieler.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f));
			OnlyMatching = Gc.Bind<bool>(Config, "5 - CartCollect", "OnlyMatchingItems", true, "Nur Items, die im Fahrzeug schon liegen (Holz zu Holz, Stein zu Stein). Aus = alles, was Platz hat.", (AcceptableValueBase)null);
			IncludeShips = Gc.Bind<bool>(Config, "5 - CartCollect", "IncludeShips", true, "Auch Schiffe mit Laderaum befüllen.", (AcceptableValueBase)null);
			OnlyWhilePulling = Gc.Bind<bool>(Config, "5 - CartCollect", "OnlyWhilePulling", false, "Karren nur befüllen, während du ihn ziehst.", (AcceptableValueBase)null);
			ToggleKey = Gc.Bind<KeyboardShortcut>(Config, "5 - CartCollect", "PauseKey", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Optionale Taste, um die Funktion kurz an- und auszuschalten.", (AcceptableValueBase)null);
			if (Chainloader.PluginInfos.ContainsKey("gorduan.guilds_vehicle"))
			{
				Type type = AccessTools.TypeByName("GuildVehicle.VehicleAPI");
				canUseCargo = ((type == null) ? null : AccessTools.Method(type, "CanUseCargo", new Type[2]
				{
					typeof(ZNetView),
					typeof(Player)
				}, (Type[])null));
			}
		}

		internal static void Update()
		{
			if (On && (Object)(object)Player.m_localPlayer != (Object)null && Gc.Down(ToggleKey))
			{
				paused = !paused;
				Gc.Center(GcLoc.Get(paused ? "gcc_paused" : "gcc_resumed", Array.Empty<object>()));
			}
		}

		internal static Container? FindTarget(Player player, ItemData item)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if (cargoCheckFailed)
			{
				return null;
			}
			int mask = LayerMask.GetMask(new string[3] { "vehicle", "piece", "item" });
			int num = Physics.OverlapSphereNonAlloc(((Component)player).transform.position, Range.Value, Hits, mask);
			Container val = null;
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				Container componentInParent = ((Component)Hits[i]).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent == (Object)(object)val)
				{
					continue;
				}
				Vagon componentInParent2 = ((Component)componentInParent).GetComponentInParent<Vagon>();
				Ship componentInParent3 = ((Component)componentInParent).GetComponentInParent<Ship>();
				if (((Object)(object)componentInParent2 == (Object)null && ((Object)(object)componentInParent3 == (Object)null || !IncludeShips.Value)) || ((Object)(object)componentInParent2 != (Object)null && OnlyWhilePulling.Value && !componentInParent2.IsAttached((Character)(object)player)))
				{
					continue;
				}
				ZNetView nview = componentInParent.m_nview;
				if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner() || componentInParent.IsInUse() || Gc.IsAutoLocked(componentInParent) || !CargoAllowed(((Object)(object)componentInParent2 != (Object)null) ? ((Component)componentInParent2).GetComponent<ZNetView>() : ((Component)componentInParent3).GetComponent<ZNetView>(), player))
				{
					continue;
				}
				componentInParent.Load();
				Inventory inventory = componentInParent.GetInventory();
				if (inventory != null && inventory.CanAddItem(item, -1) && (!OnlyMatching.Value || inventory.ContainsItemByName(item.m_shared.m_name)))
				{
					float num3 = Vector3.Distance(((Component)player).transform.position, ((Component)componentInParent).transform.position);
					if (num3 < num2)
					{
						val = componentInParent;
						num2 = num3;
					}
				}
			}
			return val;
		}

		private static bool CargoAllowed(ZNetView? vehicle, Player player)
		{
			if (canUseCargo == null || (Object)(object)vehicle == (Object)null)
			{
				return true;
			}
			try
			{
				object obj = canUseCargo.Invoke(null, new object[2] { vehicle, player });
				return obj is bool && (bool)obj;
			}
			catch (Exception ex)
			{
				canUseCargo = null;
				cargoCheckFailed = true;
				Log.LogWarning((object)("Einsammeln: Die Prüfung von Guilds_Vehicle (VehicleAPI.CanUseCargo) schlug fehl, Einsammeln ins Fahrzeug bleibt bis zum Neustart aus (" + ex.GetBaseException().Message + ")."));
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "Pickup")]
	internal static class PickupPatch
	{
		[HarmonyPriority(600)]
		private static bool Prefix(Humanoid __instance, GameObject go, bool autoPickupDelay, ref bool __result)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.On || Plugin.paused || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)go == (Object)null)
			{
				return true;
			}
			Player val = (Player)__instance;
			ItemDrop component = go.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || ((Character)val).IsTeleporting() || !component.CanPickup(autoPickupDelay))
			{
				return true;
			}
			component.Load();
			ItemData itemData = component.m_itemData;
			if (itemData.m_shared.m_questItem || itemData.m_shared.m_maxStackSize <= 1 || itemData.m_customData.Count > 0)
			{
				return true;
			}
			if ((Object)(object)component.m_nview == (Object)null || !component.m_nview.IsValid() || !component.m_nview.IsOwner())
			{
				return true;
			}
			Container val2 = Plugin.FindTarget(val, itemData);
			if ((Object)(object)val2 == (Object)null)
			{
				return true;
			}
			int stack = itemData.m_stack;
			string name = itemData.m_shared.m_name;
			Inventory inventory = val2.GetInventory();
			int num = inventory.NrOfItemsIncludingStacks();
			inventory.AddItem(itemData.Clone());
			int num2 = inventory.NrOfItemsIncludingStacks() - num;
			if (num2 <= 0)
			{
				return true;
			}
			if (num2 >= stack)
			{
				ZNetScene.instance.Destroy(go);
			}
			else
			{
				itemData.m_stack = stack - num2;
				component.Save();
			}
			((Humanoid)val).m_pickupEffects.Create(((Component)val).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)val).GetZDOID());
			Gc.TopLeft(GcLoc.Get("gcc_stored", new object[3]
			{
				num2,
				Localization.instance.Localize(name),
				Localization.instance.Localize(val2.m_name)
			}));
			__result = true;
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class <5ee8f811-bd99-4463-b934-5528eb07a3d5>IgnoresAccessChecksToAttribute : Attribute
	{
		public <5ee8f811-bd99-4463-b934-5528eb07a3d5>IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace GC.Client
{
	internal static class <197c1f94-b781-4c1b-9076-9b8adab7750f>ClientPlugin
	{
		internal static ManualLogSource Log;

		internal static GcModule? Module;

		internal static bool Allowed
		{
			get
			{
				if (Module != null)
				{
					return Module.Allowed;
				}
				return true;
			}
		}

		internal static bool OnServer
		{
			get
			{
				if (Module != null)
				{
					return Module.OnServer;
				}
				return false;
			}
		}
	}
}
namespace GC.Client.QuickTake
{
	internal static class Plugin
	{
		public const string Guid = "gorduan.gc_quicktake";

		public const string ModName = "GC_QuickTake";

		public const string Version = "1.1.0";

		internal static ManualLogSource Log = null;

		internal static ConfigEntry<bool> Enabled = null;

		internal static ConfigEntry<KeyCode> Modifier = null;

		internal static Container? RequestedFor;

		internal static float RequestedAt = -100f;

		internal static Container? Waiting;

		internal static float WaitingSince;

		internal static bool Blocked => Chainloader.PluginInfos.ContainsKey("gorduan.gc_quicktake");

		internal static bool On
		{
			get
			{
				if (Enabled.Value && !Blocked)
				{
					return <197c1f94-b781-4c1b-9076-9b8adab7750f>ClientPlugin.Allowed;
				}
				return false;
			}
		}

		internal static void Init(ConfigFile Config, Harmony harmony)
		{
			Log = <197c1f94-b781-4c1b-9076-9b8adab7750f>ClientPlugin.Log;
			Enabled = Gc.Bind<bool>(Config, "3 - QuickTake", "Enabled", true, "Kiste mit Umschalt+E leeren, ohne sie zu öffnen (auch im Menü GC Option).", (AcceptableValueBase)null);
			Modifier = Gc.Bind<KeyCode>(Config, "3 - QuickTake", "TakeAllModifier", (KeyCode)304, "Diese Taste halten und eine Kiste benutzen (E): alles nehmen statt öffnen.", (AcceptableValueBase)null);
		}

		internal static void Update()
		{
			if ((Object)(object)Waiting == (Object)null)
			{
				return;
			}
			Container waiting = Waiting;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)waiting == (Object)null || (Object)(object)waiting.m_nview == (Object)null || !waiting.m_nview.IsValid() || (Object)(object)localPlayer == (Object)null)
			{
				Waiting = null;
				return;
			}
			if (!waiting.m_nview.IsOwner())
			{
				if (Time.time - WaitingSince > 3f)
				{
					Waiting = null;
					Gc.Center(GcLoc.Get("gcq_timeout", Array.Empty<object>()));
				}
				return;
			}
			Waiting = null;
			if (!waiting.IsInUse())
			{
				waiting.Load();
				Inventory inventory = waiting.GetInventory();
				int num = inventory.NrOfItemsIncludingStacks();
				InventoryGui instance = InventoryGui.instance;
				Container currentContainer = instance.m_currentContainer;
				instance.m_currentContainer = waiting;
				try
				{
					instance.OnTakeAll();
				}
				finally
				{
					instance.m_currentContainer = currentContainer;
				}
				int num2 = num - inventory.NrOfItemsIncludingStacks();
				Gc.TopLeft((num2 > 0) ? GcLoc.Get("gcq_taken", new object[2]
				{
					Localization.instance.Localize(waiting.m_name),
					num2
				}) : GcLoc.Get("gcq_nothing", Array.Empty<object>()));
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	internal static class ContainerInteractPatch
	{
		[HarmonyPriority(0)]
		private static void Prefix(Container __instance, Humanoid character, bool hold, bool __runOriginal)
		{
			//IL_0025: 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)
			if (!((Object)(object)character != (Object)(object)Player.m_localPlayer || hold))
			{
				Plugin.RequestedFor = null;
				if (__runOriginal && Plugin.On && (int)Plugin.Modifier.Value != 0 && Input.GetKey(Plugin.Modifier.Value) && !Gc.TextInputActive() && !((Character)character).IsRunning() && __instance.GetInventory() != null && __instance.GetInventory().NrOfItems() > 0)
				{
					Plugin.RequestedFor = __instance;
					Plugin.RequestedAt = Time.time;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Container), "RPC_OpenResponse")]
	internal static class OpenResponsePatch
	{
		[HarmonyPriority(0)]
		private static bool Prefix(Container __instance, bool granted, bool __runOriginal)
		{
			if (!Plugin.On || (Object)(object)Plugin.RequestedFor != (Object)(object)__instance || Time.time - Plugin.RequestedAt > 3f || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return true;
			}
			Plugin.RequestedFor = null;
			if (!__runOriginal)
			{
				return false;
			}
			if (!granted)
			{
				return true;
			}
			Plugin.Waiting = __instance;
			Plugin.WaitingSince = Time.time;
			return false;
		}
	}
}
namespace GC.Client.ModKisteLeeren
{
	[BepInPlugin("gorduan.gc.kisteleeren", "GC_KisteLeeren", "1.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static GcModule Module;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Module = GcKern.Register((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger, GcMod.Info);
			<197c1f94-b781-4c1b-9076-9b8adab7750f>ClientPlugin.Log = ((BaseUnityPlugin)this).Logger;
			<197c1f94-b781-4c1b-9076-9b8adab7750f>ClientPlugin.Module = Module;
			Harmony harmony = new Harmony("gorduan.gc.kisteleeren");
			GC.Client.QuickTake.Plugin.Init(((BaseUnityPlugin)this).Config, harmony);
			Module.TakeOverOldSettings();
			GcMod.PatchAll(harmony);
			Module.MenuGroup((Func<string, string>)((string key) => GcLoc.Get("gccm_" + key, Array.Empty<object>())), (string)null).Main("quicktake", (ConfigEntryBase)(object)GC.Client.QuickTake.Plugin.Enabled, (Func<bool>)(() => GC.Client.QuickTake.Plugin.Blocked), "GC_QuickTake", (Func<string>)null, 0.0, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null).Sub("quicktake_key", (ConfigEntryBase)(object)GC.Client.QuickTake.Plugin.Modifier, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null);
		}

		private void Update()
		{
			if (!Gc.IsHeadless)
			{
				Module.Guard("Kiste leeren", (Action)GC.Client.QuickTake.Plugin.Update);
			}
		}
	}
	internal static class GcMod
	{
		public const string Id = "kisteleeren";

		public const string Guid = "gorduan.gc.kisteleeren";

		public const string Name = "GC_KisteLeeren";

		public const string Version = "1.7.0";

		public const int Stufe = 2;

		public static readonly Type[] PatchTypes = new Type[2]
		{
			typeof(ContainerInteractPatch),
			typeof(OpenResponsePatch)
		};

		public static readonly List<string> FailedPatches = new List<string>();

		public static GcModInfo Info => new GcModInfo
		{
			Id = "kisteleeren",
			Guid = "gorduan.gc.kisteleeren",
			Name = "GC_KisteLeeren",
			Version = "1.7.0",
			Stufe = 2,
			Seite = (GcSeite)0,
			Braucht = Array.Empty<string>(),
			Partner = Array.Empty<string>(),
			Fremd = Array.Empty<string>(),
			AlteConfig = "gorduan.gc_client.cfg",
			Ausgleich = 0f
		};

		public static void PatchAll(Harmony harmony)
		{
			Type[] patchTypes = PatchTypes;
			foreach (Type type in patchTypes)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					FailedPatches.Add(type.Name);
					Logger.CreateLogSource("GC_KisteLeeren").LogError((object)$"Patch {type.FullName} nicht eingespielt, diese Funktion fehlt: {arg}");
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class <197c1f94-b781-4c1b-9076-9b8adab7750f>IgnoresAccessChecksToAttribute : Attribute
	{
		public <197c1f94-b781-4c1b-9076-9b8adab7750f>IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace GC.Client
{
	internal static class <c1acd51f-b3b7-4440-a8e6-6769e04434a6>ClientPlugin
	{
		internal static ManualLogSource Log;

		internal static GcModule? Module;

		internal static bool Allowed
		{
			get
			{
				if (Module != null)
				{
					return Module.Allowed;
				}
				return true;
			}
		}

		internal static bool OnServer
		{
			get
			{
				if (Module != null)
				{
					return Module.OnServer;
				}
				return false;
			}
		}
	}
}
namespace GC.Client.ModKompass
{
	[BepInPlugin("gorduan.gc.kompass", "GC_Kompass", "1.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static GcModule Module;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Module = GcKern.Register((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger, GcMod.Info);
			<c1acd51f-b3b7-4440-a8e6-6769e04434a6>ClientPlugin.Log = ((BaseUnityPlugin)this).Logger;
			<c1acd51f-b3b7-4440-a8e6-6769e04434a6>ClientPlugin.Module = Module;
			Harmony harmony = new Harmony("gorduan.gc.kompass");
			GC.Client.Compass.Plugin.Init(((BaseUnityPlugin)this).Config, harmony);
			Module.TakeOverOldSettings();
			GcMod.PatchAll(harmony);
			Module.MenuGroup((Func<string, string>)((string key) => GcLoc.Get("gccm_" + key, Array.Empty<object>())), (string)null).Main("compass", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.Enabled, (Func<bool>)null, "", (Func<string>)null, 0.0, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null).Sub("compass_focus_key", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.FocusModifier, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_width", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.WidthPercent, 5.0, " %", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_fov", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.FieldOfView, 15.0, "°", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_offset", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.OffsetY, 10.0, " px", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_scale", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.Scale, 0.1, " ×", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_range", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.MaxDistance, 250.0, " m", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_names", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.OtherNames, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_name_range", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.NameDistance, 25.0, " m", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_distance", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.ShowDistance, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_checked", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.ShowChecked, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_players", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.ShowPlayers, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null)
				.Sub("compass_icons", (ConfigEntryBase)(object)GC.Client.Compass.Plugin.Icons, 0.0, "", (Func<bool>)null, "", (Func<bool>)null, (Func<bool>)null, (Func<string>)null);
		}
	}
	internal static class GcMod
	{
		public const string Id = "kompass";

		public const string Guid = "gorduan.gc.kompass";

		public const string Name = "GC_Kompass";

		public const string Version = "1.7.0";

		public const int Stufe = 1;

		public static readonly Type[] PatchTypes = new Type[4]
		{
			typeof(CameraPatch),
			typeof(FocusClickPatch),
			typeof(FocusDoubleClickPatch),
			typeof(MapColorPatch)
		};

		public static readonly List<string> FailedPatches = new List<string>();

		public static GcModInfo Info
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				GcModInfo val = new GcModInfo();
				val.Id = "kompass";
				val.Guid = "gorduan.gc.kompass";
				val.Name = "GC_Kompass";
				val.Version = "1.7.0";
				val.Stufe = 1;
				val.Seite = (GcSeite)0;
				val.Braucht = Array.Empty<string>();
				val.Partner = new string[1] { "dungeonkarte" };
				val.Fremd = Array.Empty<string>();
				val.AlteConfig = "gorduan.gc_client.cfg";
				val.Ausgleich = 0f;
				return val;
			}
		}

		public static void PatchAll(Harmony harmony)
		{
			Type[] patchTypes = PatchTypes;
			foreach (Type type in patchTypes)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					FailedPatches.Add(type.Name);
					Logger.CreateLogSource("GC_Kompass").LogError((object)$"Patch {type.FullName} nicht eingespielt, diese Funktion fehlt: {arg}");
				}
			}
		}
	}
}
namespace GC.Client.Compass
{
	internal enum NameMode
	{
		Always,
		Near,
		Never
	}
	internal enum IconStyle
	{
		MapIcon,
		Dot
	}
	internal static class Plugin
	{
		internal static ManualLogSource Log = null;

		internal static ConfigEntry<bool> Enabled = null;

		internal static ConfigEntry<KeyCode> FocusModifier = null;

		internal static ConfigEntry<int> WidthPercent = null;

		internal static ConfigEntry<int> FieldOfView = null;

		internal static ConfigEntry<int> OffsetY = null;

		internal static ConfigEntry<float> Scale = null;

		internal static ConfigEntry<int> MaxDistance = null;

		internal static ConfigEntry<NameMode> OtherNames = null;

		internal static ConfigEntry<int> NameDistance = null;

		internal static ConfigEntry<bool> ShowDistance = null;

		internal static ConfigEntry<bool> ShowChecked = null;

		internal static ConfigEntry<bool> ShowPlayers = null;

		internal static ConfigEntry<IconStyle> Icons = null;

		internal static CompassView? View;

		private static string lastError = "";

		internal static bool On
		{
			get
			{
				if (Enabled.Value)
				{
					return <c1acd51f-b3b7-4440-a8e6-6769e04434a6>ClientPlugin.Allowed;
				}
				return false;
			}
		}

		internal static bool FocusKeyHeld
		{
			get
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if (On && !Game.m_noMap && (int)FocusModifier.Value != 0)
				{
					return Input.GetKey(FocusModifier.Value);
				}
				return false;
			}
		}

		internal static void Init(ConfigFile Config, Harmony harmony)
		{
			Log = <c1acd51f-b3b7-4440-a8e6-6769e04434a6>ClientPlugin.Log;
			Enabled = Gc.Bind<bool>(Config, "11 - Compass", "Enabled", true, "Kompass oben am Bildschirm (auch im Menü GC Option).", (AcceptableValueBase)null);
			FocusModifier = Gc.Bind<KeyCode>(Config, "11 - Compass", "FocusModifier", (KeyCode)308, "Diese Taste halten und auf der großen Karte eine Markierung anklicken: wird zum Ziel (golden). Nochmal klicken oder auf eine leere Stelle klicken hebt das Ziel auf.", (AcceptableValueBase)null);
			WidthPercent = Gc.Bind<int>(Config, "11 - Compass", "WidthPercent", 50, "Breite des Kompasses in Prozent der Bildschirmbreite.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 100));
			FieldOfView = Gc.Bind<int>(Config, "11 - Compass", "FieldOfView", 180, "So viel Grad zeigt die Leiste (180 = von West bis Ost, wenn du nach Norden schaust).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(90, 360));
			OffsetY = Gc.Bind<int>(Config, "11 - Compass", "OffsetY", 10, "Abstand vom oberen Bildschirmrand in Pixeln. Boss- und Raid-Leiste schieben den Kompass zusätzlich nach unten.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 600));
			Scale = Gc.Bind<float>(Config, "11 - Compass", "Scale", 1f, "Größe von Symbolen und Schrift.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f));
			MaxDistance = Gc.Bind<int>(Config, "11 - Compass", "MaxDistance", 2000, "Andere Markierungen bis zu dieser Entfernung in Metern zeigen. Ziel und Pings immer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(250, 20000));
			OtherNames = Gc.Bind<NameMode>(Config, "11 - Compass", "OtherNames", NameMode.Near, "Namen anderer Markierungen: Always, Near (bis NameDistance) oder Never. Ziel und Pings zeigen ihren Namen immer.", (AcceptableValueBase)null);
			NameDistance = Gc.Bind<int>(Config, "11 - Compass", "NameDistance", 300, "Bis zu dieser Entfernung in Metern zeigen andere Markierungen ihren Namen (OtherNames = Near).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(25, 5000));
			ShowDistance = Gc.Bind<bool>(Config, "11 - Compass", "ShowDistance", true, "Entfernung bei Ziel und Pings anzeigen.", (AcceptableValueBase)null);
			ShowChecked = Gc.Bind<bool>(Config, "11 - Compass", "ShowChecked", false, "Auf der Karte abgehakte (durchgestrichene) Markierungen zeigen. Das Ziel wird immer gezeigt.", (AcceptableValueBase)null);
			ShowPlayers = Gc.Bind<bool>(Config, "11 - Compass", "ShowPlayers", true, "Mitspieler zeigen, die auf der Karte sichtbar sind.", (AcceptableValueBase)null);
			Icons = Gc.Bind<IconStyle>(Config, "11 - Compass", "IconStyle", IconStyle.MapIcon, "Symbole: MapIcon (Kartensymbol) oder Dot (Punkt).", (AcceptableValueBase)null);
			Enabled.SettingChanged += delegate
			{
				Focus.RefreshMap();
			};
		}

		internal static void Tick(GameCamera camera)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			if (Gc.IsHeadless)
			{
				return;
			}
			try
			{
				Player localPlayer = Player.m_localPlayer;
				Focus.Tick(localPlayer);
				if (!On || !((Object)(object)localPlayer != (Object)null) || !((Object)(object)Hud.instance != (Object)null) || !((Object)(object)Hud.instance.m_rootObject != (Object)null) || !Hud.instance.IsVisible() || ((Character)localPlayer).InIntro() || GameCamera.InFreeFly() || ((Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2) || GcHooks.IsDungeonMapLargeOpen())
				{
					View?.Hide();
					return;
				}
				if (View == null)
				{
					View = new CompassView();
				}
				View.Draw(localPlayer, camera);
			}
			catch (Exception ex)
			{
				View?.Hide();
				string text = ex.GetType().Name + "|" + ex.TargetSite?.Name + "|" + ex.Message;
				if (text != lastError)
				{
					lastError = text;
					Log.LogError((object)$"Kompass: {ex}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "LateUpdate")]
	internal static class CameraPatch
	{
		private static void Postfix(GameCamera __instance)
		{
			Plugin.Tick(__instance);
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	internal static class FocusClickPatch
	{
		[HarmonyPriority(800)]
		private static bool Prefix(Minimap __instance)
		{
			if (!Plugin.FocusKeyHeld)
			{
				return true;
			}
			__instance.HidePinTextInput(false);
			PinData val = Focus.PinAtCursor(__instance);
			if (val != null)
			{
				Focus.Toggle(val);
			}
			else if (Focus.Active)
			{
				Focus.Remove();
			}
			else
			{
				Gc.TopLeft(GcLoc.Get("gcc_no_pin", Array.Empty<object>()));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapDblClick")]
	internal static class FocusDoubleClickPatch
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !Plugin.FocusKeyHeld;
		}
	}
	[HarmonyPatch(typeof(Minimap), "UpdatePins")]
	internal static class MapColorPatch
	{
		private static void Postfix()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			PinData pin = Focus.Pin;
			if (Plugin.On && pin != null)
			{
				if ((Object)(object)pin.m_iconElement != (Object)null)
				{
					((Graphic)pin.m_iconElement).color = CompassView.FocusColor;
				}
				if (pin.m_NamePinData != null && (Object)(object)pin.m_NamePinData.PinNameText != (Object)null)
				{
					((Graphic)pin.m_NamePinData.PinNameText).color = CompassView.FocusColor;
				}
			}
		}
	}
	internal static class Focus
	{
		private const string DataPrefix = "gc_compass_focus_";

		internal static PinData? Pin;

		private static bool active;

		private static PinType type;

		private static string name = "";

		private static Vector3 position;

		private static bool everFound;

		private static float searchUntil;

		private static float nextSearch;

		private static Game? game;

		private static Player? owner;

		private static bool loaded;

		internal static bool Active => active;

		internal static void Tick(Player? player)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Invalid comparison between Unknown and I4
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Invalid comparison between Unknown and I4
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if (Game.instance != game)
			{
				game = Game.instance;
				Pin = null;
				active = false;
				owner = null;
				loaded = false;
			}
			Minimap instance = Minimap.instance;
			if ((Object)(object)player == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			if (player != owner)
			{
				owner = player;
				if (!loaded)
				{
					loaded = true;
					Load(player);
				}
				else
				{
					Save();
				}
			}
			if (!active || !Plugin.On)
			{
				return;
			}
			if (Pin != null)
			{
				if (!instance.m_pins.Contains(Pin) || Pin.m_type != type || Pin.m_name != name)
				{
					Pin = null;
				}
				else if ((int)type != 10 && Utils.DistanceXZ(Pin.m_pos, position) > 1f)
				{
					position = Pin.m_pos;
					Save();
				}
			}
			if (Pin == null && Time.time >= nextSearch)
			{
				nextSearch = Time.time + 0.5f;
				Pin = Find(instance);
				if (Pin != null)
				{
					everFound = true;
					instance.m_pinUpdateRequired = true;
				}
				else if ((int)type != 10 && (everFound || Time.time > searchUntil))
				{
					Clear();
				}
			}
		}

		internal static PinData? PinAtCursor(Minimap map)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = map.ScreenToWorldPoint(ZInput.pointerPosition);
			float num = map.PinInteractRadius;
			PinData result = null;
			foreach (PinData pin in map.m_pins)
			{
				if (Selectable(pin) && !((Object)(object)pin.m_uiElement == (Object)null) && ((Component)pin.m_uiElement).gameObject.activeInHierarchy)
				{
					float num2 = Utils.DistanceXZ(val, pin.m_pos);
					if (num2 < num)
					{
						num = num2;
						result = pin;
					}
				}
			}
			return result;
		}

		internal static bool Selectable(PinData pin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			PinType val = pin.m_type;
			switch (val - 7)
			{
			case 0:
			case 5:
			case 6:
				return false;
			case 1:
				return (Object)(object)pin.m_icon != (Object)null;
			default:
				return true;
			}
		}

		internal static void Toggle(PinData pin)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (active && Pin == pin)
			{
				Remove();
				return;
			}
			Pin = pin;
			active = true;
			everFound = true;
			type = pin.m_type;
			name = pin.m_name;
			position = pin.m_pos;
			Save();
			RefreshMap();
			Gc.TopLeft(GcLoc.Get("gcc_focus_set", new object[1] { CompassView.PinName(pin, fallback: true) }));
		}

		internal static void Remove()
		{
			Clear();
			Gc.TopLeft(GcLoc.Get("gcc_focus_clear", Array.Empty<object>()));
		}

		internal static void RefreshMap()
		{
			if ((Object)(object)Minimap.instance != (Object)null)
			{
				Minimap.instance.m_pinUpdateRequired = true;
			}
		}

		private static void Clear()
		{
			active = false;
			Pin = null;
			Save();
			RefreshMap();
		}

		private static PinData? Find(Minimap map)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			foreach (PinData pin in map.m_pins)
			{
				if (pin.m_type == type && pin.m_name == name && ((int)type == 10 || Utils.DistanceXZ(pin.m_pos, position) < 1f))
				{
					return pin;
				}
			}
			return null;
		}

		private static string Key()
		{
			return "gc_compass_focus_" + ZNet.instance.GetWorldUID().ToString(CultureInfo.InvariantCulture);
		}

		private static void Load(Player player)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			active = false;
			Pin = null;
			everFound = false;
			searchUntil = Time.time + 20f;
			if (player.m_customData.TryGetValue(Key(), out var value))
			{
				string[] array = value.Split(new char[1] { ';' }, 4);
				if (array.Length == 4 && int.TryParse(array[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
				{
					type = (PinType)result;
					position = new Vector3(result2, 0f, result3);
					name = array[3];
					active = true;
				}
			}
		}

		private static void Save()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected I4, but got Unknown
			if (!((Object)(object)owner == (Object)null) && !((Object)(object)ZNet.instance == (Object)null))
			{
				if (!active)
				{
					owner.m_customData.Remove(Key());
					return;
				}
				owner.m_customData[Key()] = string.Join(";", ((int)type).ToString(CultureInfo.InvariantCulture), position.x.ToString("R", CultureInfo.InvariantCulture), position.z.ToString("R", CultureInfo.InvariantCulture), name);
			}
		}
	}
	internal sealed class CompassView
	{
		private sealed class Marker
		{
			public Image Icon;

			public Image Plate;

			public Text Label;
		}

		private struct Item
		{
			public PinData? Pin;

			public Sprite? Icon;

			public string Name;

			public Color Color;

			public float Distance;

			public float Rel;

			public bool Focus;

			public bool Faded;

			public float X;

			public float Fade;

			public Marker? Marker;
		}

		private sealed class FarFirstComparer : IComparer<Item>
		{
			public int Compare(Item a, Item b)
			{
				return b.Distance.CompareTo(a.Distance);
			}
		}

		private sealed class HighlightComparer : IComparer<Item>
		{
			public int Compare(Item a, Item b)
			{
				if (a.Focus == b.Focus)
				{
					return b.Distance.CompareTo(a.Distance);
				}
				if (!a.Focus)
				{
					return -1;
				}
				return 1;
			}
		}

		internal static readonly Color FocusColor = new Color(1f, 0.8f, 0.2f, 1f);

		private static readonly Color PingColor = new Color(0.45f, 0.62f, 1f, 1f);

		private static readonly Color NorthColor = new Color(1f, 0.6f, 0.35f, 1f);

		private static readonly Color MinorColor = new Color(0.85f, 0.85f, 0.85f, 1f);

		private static readonly Color PlateColor = new Color(0f, 0f, 0f, 0.6f);

		private const float NearDistance = 50f;

		private const int MaxNormals = 80;

		private const float RowLabel = -12f;

		private const float RowIcon = -37f;

		private const float RowLine = -55f;

		private const float RowLetters = -69f;

		private const float RowLabel1 = -92f;

		private const float RowLabel2 = -115f;

		private static readonly FarFirstComparer FarFirst = new FarFirstComparer();

		private static readonly HighlightComparer HighlightOrder = new HighlightComparer();

		private GameObject? root;

		private RectTransform rootRect;

		private RectTransform normalLayer;

		private RectTransform highlightLayer;

		private Image band;

		private Image line;

		private Image center;

		private Image leftEnd;

		private Image rightEnd;

		private readonly Text[] letters = (Text[])(object)new Text[8];

		private readonly Image[] ticks = (Image[])(object)new Image[16];

		private readonly List<Marker> normalPool = new List<Marker>();

		private readonly List<Marker> highlightPool = new List<Marker>();

		private readonly List<Item> normals = new List<Item>();

		private readonly List<Item> highlights = new List<Item>();

		private readonly List<WorldTextInstance> pings = new List<WorldTextInstance>();

		private readonly List<Vector2>[] taken = new List<Vector2>[3]
		{
			new List<Vector2>(),
			new List<Vector2>(),
			new List<Vector2>()
		};

		private readonly List<RectTransform> blockers = new List<RectTransform>();

		private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

		private Vector3 layoutKey = new Vector3(-1f, -1f, -1f);

		private float rowLabel0;

		private float rowLabel1;

		private float rowLabel2;

		private Sprite? pingSprite;

		private static bool widthWarned;

		private static readonly string[] BossParts = new string[2] { "Health", "Name" };

		private const string LeashBarHud = "GC_LeashBar";

		private const string LeashBarGrid = "GC_LeashBarGrid";

		private RectTransform? leashBarHud;

		private RectTransform? leashBarGrid;

		private float nextLeashBarSearch;

		private static readonly Dictionary<Vector3, string> LocationNames = new Dictionary<Vector3, string>();

		private static readonly Dictionary<Vector3, string> LocationScan = new Dictionary<Vector3, string>();

		private static float nextLocationScan;

		public void Hide()
		{
			if ((Object)(object)root != (Object)null && root.activeSelf)
			{
				root.SetActive(false);
			}
		}

		public void Draw(Player player, GameCamera camera)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Build();
			if (!root.activeSelf)
			{
				root.SetActive(true);
			}
			float value = Plugin.Scale.Value;
			Layout(value);
			Rect rect = rootRect.rect;
			float num = ((Rect)(ref rect)).width * 0.5f;
			if (num <= 1f)
			{
				root.SetActive(false);
				return;
			}
			float halfFov = (float)Mathf.Clamp(Plugin.FieldOfView.Value, 30, 360) * 0.5f;
			float y = ((Component)camera).transform.eulerAngles.y;
			rowLabel0 = -12f * value;
			rowLabel1 = -92f * value;
			rowLabel2 = -115f * value;
			DrawDial(y, num, halfFov, value);
			Collect(player, y, halfFov);
			DrawNormals(num, halfFov, value);
			DrawHighlights(num, halfFov, value);
		}

		private void Build()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)root != (Object)null))
			{
				normalPool.Clear();
				highlightPool.Clear();
				pingSprite = null;
				layoutKey = new Vector3(-1f, -1f, -1f);
				root = new GameObject("GC_Compass", new Type[2]
				{
					typeof(RectTransform),
					typeof(CanvasGroup)
				});
				root.transform.SetParent(Hud.instance.m_rootObject.transform, false);
				root.transform.SetAsFirstSibling();
				CanvasGroup component = root.GetComponent<CanvasGroup>();
				component.blocksRaycasts = false;
				component.interactable = false;
				rootRect = (RectTransform)root.transform;
				rootRect.pivot = new Vector2(0.5f, 1f);
				band = CreateImage(root.transform, "Band", Sprites.Band);
				band.preserveAspect = false;
				((Graphic)band).color = new Color(0f, 0f, 0f, 0.35f);
				line = CreateImage(root.transform, "Line", null);
				((Graphic)line).color = new Color(1f, 1f, 1f, 0.85f);
				leftEnd = CreateImage(root.transform, "LeftEnd", Sprites.Triangle);
				((Transform)((Graphic)leftEnd).rectTransform).localEulerAngles = new Vector3(0f, 0f, 180f);
				((Graphic)leftEnd).color = ((Graphic)line).color;
				rightEnd = CreateImage(root.transform, "RightEnd", Sprites.Triangle);
				((Graphic)rightEnd).color = ((Graphic)line).color;
				for (int i = 0; i < ticks.Length; i++)
				{
					ticks[i] = CreateImage(root.transform, "Tick", null);
				}
				center = CreateImage(root.transform, "Center", null);
				((Graphic)center).color = new Color(1f, 1f, 1f, 0.95f);
				string[] array = new string[8] { "n", "ne", "e", "se", "s", "sw", "w", "nw" };
				for (int j = 0; j < letters.Length; j++)
				{
					letters[j] = CreateText(root.transform, GUIManager.Instance.NorseBold);
					letters[j].text = GcLoc.Get("gcc_dir_" + array[j], Array.Empty<object>());
				}
				normalLayer = CreateLayer("Markers");
				highlightLayer = CreateLayer("Highlights");
				root.SetActive(false);
			}
		}

		private RectTransform CreateLayer(string name)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(root.transform, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			Vector2 offsetMin = (val2.offsetMax = Vector2.zero);
			val2.offsetMin = offsetMin;
			return val2;
		}

		private static Image CreateImage(Transform parent, string name, Sprite? sprite)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			component.sprite = sprite;
			((Graphic)component).raycastTarget = false;
			component.preserveAspect = (Object)(object)sprite != (Object)null;
			RectTransform rectTransform = ((Graphic)component).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			rectTransform.anchorMax = val2;
			rectTransform.anchorMin = val2;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			return component;
		}

		private static Text CreateText(Transform parent, Font font)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Text component = GUIManager.Instance.CreateText("", parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), Vector2.zero, font, 14, Color.white, true, Color.black, 300f, 30f, false).GetComponent<Text>();
			component.alignment = (TextAnchor)4;
			component.horizontalOverflow = (HorizontalWrapMode)1;
			component.verticalOverflow = (VerticalWrapMode)1;
			component.supportRichText = true;
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private Marker GetMarker(List<Marker> pool, RectTransform layer, int index)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			while (pool.Count <= index)
			{
				Marker marker = new Marker
				{
					Plate = CreateImage((Transform)(object)layer, "Plate", null),
					Label = CreateText((Transform)(object)layer, GUIManager.Instance.AveriaSerifBold),
					Icon = CreateImage((Transform)(object)layer, "Icon", null)
				};
				((Graphic)marker.Plate).color = PlateColor;
				Show((Graphic)(object)marker.Plate, show: false);
				Show((Graphic)(object)marker.Label, show: false);
				pool.Add(marker);
			}
			return pool[index];
		}

		private static void Show(Graphic graphic, bool show)
		{
			if (((Component)graphic).gameObject.activeSelf != show)
			{
				((Component)graphic).gameObject.SetActive(show);
			}
		}

		private static void HideFrom(List<Marker> pool, int start)
		{
			for (int i = start; i < pool.Count; i++)
			{
				Show((Graphic)(object)pool[i].Icon, show: false);
				Show((Graphic)(object)pool[i].Plate, show: false);
				Show((Graphic)(object)pool[i].Label, show: false);
			}
		}

		private static void Place(Graphic graphic, float x, float y, float width, float height)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = graphic.rectTransform;
			rectTransform.anchoredPosition = new Vector2(x, y);
			rectTransform.sizeDelta = new Vector2(width, height);
		}

		private void Layout(float s)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor((float)Plugin.WidthPercent.Value, s, 0f);
			if (val != layoutKey)
			{
				layoutKey = val;
				Stretch(s);
			}
			Rect rect = rootRect.rect;
			if (((Rect)(ref rect)).width <= 2f && MoveToCanvas())
			{
				Stretch(s);
			}
			float num = 0f - BlockerOffset(Plugin.OffsetY.Value);
			if (!Mathf.Approximately(rootRect.anchoredPosition.y, num))
			{
				rootRect.anchoredPosition = new Vector2(0f, num);
			}
		}

		private void Stretch(float s)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Mathf.Clamp(Plugin.WidthPercent.Value, 10, 100) / 100f;
			rootRect.anchorMin = new Vector2(0.5f - num / 2f, 1f);
			rootRect.anchorMax = new Vector2(0.5f + num / 2f, 1f);
			rootRect.sizeDelta = new Vector2(0f, 130f * s);
		}

		private unsafe bool MoveToCanvas()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Transform)rootRect).parent;
			Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
			RectTransform val2 = ((!((Object)(object)componentInParent != (Object)null)) ? ((RectTransform)null) : ((RectTransform)((Component)componentInParent.rootCanvas).transform));
			Rect rect;
			if (!widthWarned)
			{
				widthWarned = true;
				string text = ((Object)val).name;
				Transform parent = ((Transform)val).parent;
				while ((Object)(object)parent != (Object)null)
				{
					text = ((Object)parent).name + "/" + text;
					parent = parent.parent;
				}
				ManualLogSource log = Plugin.Log;
				string arg = text;
				object arg2 = val.rect;
				object arg3;
				if (!((Object)(object)val2 != (Object)null))
				{
					arg3 = "-";
				}
				else
				{
					string name = ((Object)val2).name;
					rect = val2.rect;
					arg3 = name + " " + ((obje

GC_Kern.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DeepTip;
using GC.Kern;
using GC.Kern.ModCheck;
using GC.Kern.Progression;
using GC.Shared;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("Gorduan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+c9d5288b96ac31e780ee94b8f27fd48c2d248dff")]
[assembly: AssemblyProduct("GC_Kern")]
[assembly: AssemblyTitle("GC_Kern")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GC.Kern
{
	[HarmonyPatch(typeof(Localization), "SetLanguage")]
	internal static class LanguageKeepPatch
	{
		private static void Prefix(Localization __instance, out Dictionary<string, string>? __state)
		{
			__state = ((__instance.m_translations != null) ? new Dictionary<string, string>(__instance.m_translations) : null);
		}

		private static void Postfix(Localization __instance, Dictionary<string, string>? __state)
		{
			if (__state == null || __instance.m_translations == null)
			{
				return;
			}
			int num = 0;
			foreach (KeyValuePair<string, string> item in __state)
			{
				if (!__instance.m_translations.ContainsKey(item.Key))
				{
					__instance.m_translations[item.Key] = item.Value;
					num++;
				}
			}
			if (num > 0)
			{
				__instance.m_cache.EvictAll();
				KernPlugin.Log.LogInfo((object)$"Sprachwechsel: {num} Texte anderer Mods wiederhergestellt.");
			}
		}
	}
	internal static class ModSwitch
	{
		internal enum State
		{
			Loaded,
			Failed,
			Off,
			OtherProcess,
			NotLoaded
		}

		internal sealed class Mod
		{
			public string Guid = "";

			public string Name = "";

			public string Version = "";

			public string Location = "";

			public string Package = "";

			public string PackageVersion = "";

			public string Namespace = "";

			public string PackageName = "";

			public State State;

			public string Reason = "";

			public string[] HardDeps = Array.Empty<string>();

			public bool Protected;

			public string Search = "";
		}

		internal sealed class Profile
		{
			public string Name = "";

			public string File = "";

			public HashSet<string> Off = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		}

		[Serializable]
		private sealed class ManifestJson
		{
			public string name = "";

			public string version_number = "";
		}

		private const string DataAll = "GC.ModSchalter.All";

		private const string DataSkipped = "GC.ModSchalter.Skipped";

		private const string DataProtected = "GC.ModSchalter.Protected";

		private const string DataFile = "GC.ModSchalter.File";

		private const string KernGuid = "gorduan.gc.kern";

		private static List<Mod>? catalog;

		private static HashSet<string>? wanted;

		private static HashSet<string> skippedAtStart = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal static bool PatcherActive => AppDomain.CurrentDomain.GetData("GC.ModSchalter.File") is string;

		internal static string Folder => Path.Combine(Paths.ConfigPath, "GC_Kern");

		private static string ListFile => (AppDomain.CurrentDomain.GetData("GC.ModSchalter.File") as string) ?? Path.Combine(Folder, "aus.txt");

		private static string ProfileFolder => Path.Combine(Folder, "profile");

		internal static IReadOnlyList<Mod> Catalog => catalog ?? (catalog = BuildCatalog());

		private static HashSet<string> Wanted => wanted ?? (wanted = ReadList(ListFile));

		internal static bool RestartNeeded
		{
			get
			{
				if (!PatcherActive)
				{
					return false;
				}
				HashSet<string> hashSet = new HashSet<string>(from m in Catalog
					where !m.Protected
					select m.Guid, StringComparer.OrdinalIgnoreCase);
				hashSet.IntersectWith(Wanted);
				return !hashSet.SetEquals(skippedAtStart);
			}
		}

		internal static string LastError { get; private set; } = "";

		internal static bool IsWantedOff(Mod mod)
		{
			if (!mod.Protected)
			{
				return Wanted.Contains(mod.Guid);
			}
			return false;
		}

		internal static Mod? Find(string guid)
		{
			return Catalog.FirstOrDefault((Mod m) => string.Equals(m.Guid, guid, StringComparison.OrdinalIgnoreCase));
		}

		private static List<Mod> BuildCatalog()
		{
			ImportModMenu();
			AppDomain currentDomain = AppDomain.CurrentDomain;
			List<PluginInfo> list = (currentDomain.GetData("GC.ModSchalter.All") as List<PluginInfo>) ?? new List<PluginInfo>();
			List<PluginInfo> list2 = (currentDomain.GetData("GC.ModSchalter.Skipped") as List<PluginInfo>) ?? new List<PluginInfo>();
			skippedAtStart = new HashSet<string>(list2.Select((PluginInfo info) => info.Metadata.GUID), StringComparer.OrdinalIgnoreCase);
			Dictionary<string, Mod> byGuid = new Dictionary<string, Mod>(StringComparer.OrdinalIgnoreCase);
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				Add(value, (!((Object)(object)value.Instance != (Object)null)) ? State.Failed : State.Loaded, "");
			}
			foreach (PluginInfo item in list2)
			{
				Add(item, State.Off, "");
			}
			foreach (PluginInfo item2 in list)
			{
				if (!byGuid.ContainsKey(item2.Metadata.GUID))
				{
					var (state, reason) = NotLoaded(item2);
					Add(item2, state, reason);
				}
			}
			HashSet<string> hashSet = new HashSet<string>((currentDomain.GetData("GC.ModSchalter.Protected") as string[]) ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase);
			if (hashSet.Count == 0)
			{
				hashSet = Protected(byGuid);
			}
			foreach (Mod value2 in byGuid.Values)
			{
				value2.Protected = hashSet.Contains(value2.Guid);
			}
			return byGuid.Values.OrderBy<Mod, string>((Mod m) => m.Name, StringComparer.OrdinalIgnoreCase).ToList();
			void Add(PluginInfo info, State state2, string reason2)
			{
				string gUID = info.Metadata.GUID;
				if (!byGuid.ContainsKey(gUID))
				{
					Mod mod = new Mod
					{
						Guid = gUID,
						Name = info.Metadata.Name,
						Version = info.Metadata.Version.ToString(),
						Location = (info.Location ?? ""),
						State = state2,
						Reason = reason2,
						HardDeps = (from d in info.Dependencies
							where (d.Flags & 1) > 0
							select d.DependencyGUID).ToArray()
					};
					FindPackage(mod);
					mod.Search = string.Join(" ", mod.Name, mod.Guid, mod.Package).ToLowerInvariant();
					byGuid[gUID] = mod;
				}
			}
		}

		private static (State, string) NotLoaded(PluginInfo info)
		{
			string[] array = info.Processes.Select((BepInProcess p) => p.ProcessName).ToArray();
			if (array.Length != 0 && !array.Any((string p) => string.Equals(Path.GetFileNameWithoutExtension(p), Paths.ProcessName, StringComparison.OrdinalIgnoreCase)))
			{
				return (State.OtherProcess, string.Join(", ", array));
			}
			string text = Chainloader.DependencyErrors.FirstOrDefault((string line) => line.Contains(info.Metadata.GUID) || line.Contains("[" + info.Metadata.Name));
			if (text == null)
			{
				return (State.NotLoaded, "");
			}
			return (State.Failed, text);
		}

		private static HashSet<string> Protected(Dictionary<string, Mod> byGuid)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "gorduan.gc.kern" };
			Queue<string> queue = new Queue<string>(hashSet);
			while (queue.Count > 0)
			{
				if (!byGuid.TryGetValue(queue.Dequeue(), out Mod value))
				{
					continue;
				}
				string[] hardDeps = value.HardDeps;
				foreach (string item in hardDeps)
				{
					if (hashSet.Add(item))
					{
						queue.Enqueue(item);
					}
				}
			}
			return hashSet;
		}

		private static void FindPackage(Mod mod)
		{
			try
			{
				string text = Path.GetFullPath(Paths.PluginPath).TrimEnd('\\', '/');
				string text2 = ((mod.Location.Length > 0) ? Path.GetDirectoryName(Path.GetFullPath(mod.Location)) : null);
				while (text2 != null && text2.Length > text.Length && text2.StartsWith(text, StringComparison.OrdinalIgnoreCase))
				{
					string path = Path.Combine(text2, "manifest.json");
					if (File.Exists(path))
					{
						ManifestJson manifestJson = JsonUtility.FromJson<ManifestJson>(File.ReadAllText(path));
						mod.Package = Path.GetFileName(text2);
						mod.PackageName = manifestJson?.name ?? "";
						mod.PackageVersion = manifestJson?.version_number ?? "";
						int num = mod.Package.IndexOf('-');
						if (num > 0 && string.Equals(mod.Package.Substring(num + 1), mod.PackageName, StringComparison.OrdinalIgnoreCase))
						{
							mod.Namespace = mod.Package.Substring(0, num);
						}
						break;
					}
					text2 = Path.GetDirectoryName(text2);
				}
			}
			catch
			{
			}
		}

		internal static List<Mod> SetOff(Mod start, bool off)
		{
			List<Mod> list = new List<Mod>();
			if (!PatcherActive || start.Protected)
			{
				return list;
			}
			Queue<Mod> queue = new Queue<Mod>();
			queue.Enqueue(start);
			while (queue.Count > 0)
			{
				Mod mod = queue.Dequeue();
				if (mod.Protected || Wanted.Contains(mod.Guid) == off)
				{
					continue;
				}
				if (off)
				{
					Wanted.Add(mod.Guid);
				}
				else
				{
					Wanted.Remove(mod.Guid);
				}
				list.Add(mod);
				IEnumerable<Mod> enumerable2;
				if (!off)
				{
					IEnumerable<Mod> enumerable = (from other in mod.HardDeps.Select(Find)
						where other != null
						select other).Cast<Mod>();
					enumerable2 = enumerable;
				}
				else
				{
					enumerable2 = Catalog.Where((Mod other) => other.HardDeps.Contains<string>(mod.Guid, StringComparer.OrdinalIgnoreCase));
				}
				foreach (Mod item in enumerable2)
				{
					queue.Enqueue(item);
				}
			}
			if (!Save())
			{
				list.Clear();
			}
			return list;
		}

		internal static void AllOn()
		{
			Wanted.Clear();
			Save();
		}

		private static HashSet<string> WithDependents(IEnumerable<string> off)
		{
			HashSet<string> hashSet = new HashSet<string>(off, StringComparer.OrdinalIgnoreCase);
			bool flag = true;
			while (flag)
			{
				flag = false;
				foreach (Mod item in Catalog)
				{
					if (!item.Protected && !hashSet.Contains(item.Guid) && item.HardDeps.Any(hashSet.Contains))
					{
						hashSet.Add(item.Guid);
						flag = true;
					}
				}
			}
			return hashSet;
		}

		internal static List<Mod> Dependents(Mod mod)
		{
			return Catalog.Where((Mod other) => !IsWantedOff(other) && other.HardDeps.Contains<string>(mod.Guid, StringComparer.OrdinalIgnoreCase)).ToList();
		}

		internal static List<string> MissingDeps(Mod mod)
		{
			return (from guid in mod.HardDeps.Where(delegate(string guid)
				{
					Mod mod2 = Find(guid);
					return mod2 == null || IsWantedOff(mod2);
				})
				select Find(guid)?.Name ?? guid).ToList();
		}

		private static bool Save()
		{
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(ListFile));
				List<string> list = new List<string> { "# Im Menü GC Option ausgeschaltete Mods, eine GUID je Zeile. Datei löschen = alle wieder an." };
				list.AddRange(Wanted.OrderBy<string, string>((string g) => g, StringComparer.OrdinalIgnoreCase));
				File.WriteAllLines(ListFile, list, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
				LastError = "";
				return true;
			}
			catch (Exception ex)
			{
				LastError = ex.Message;
				wanted = ReadList(ListFile);
				return false;
			}
		}

		private static HashSet<string> ReadList(string file)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			try
			{
				if (File.Exists(file))
				{
					string[] array = File.ReadAllLines(file);
					for (int i = 0; i < array.Length; i++)
					{
						string text = array[i].Trim();
						if (text.Length > 0 && !text.StartsWith("#", StringComparison.Ordinal))
						{
							hashSet.Add(text);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("GC_Kern: " + file + " nicht lesbar: " + ex.Message));
			}
			return hashSet;
		}

		internal static List<Profile> Profiles()
		{
			List<Profile> list = new List<Profile>();
			if (!Directory.Exists(ProfileFolder))
			{
				return list;
			}
			foreach (string item in Directory.GetFiles(ProfileFolder, "*.txt").OrderBy<string, string>((string f) => f, StringComparer.OrdinalIgnoreCase))
			{
				list.Add(new Profile
				{
					Name = Path.GetFileNameWithoutExtension(item),
					File = item,
					Off = ReadList(item)
				});
			}
			return list;
		}

		private static HashSet<string> Known(IEnumerable<string> guids)
		{
			HashSet<string> hashSet = new HashSet<string>(from m in Catalog
				where !m.Protected
				select m.Guid, StringComparer.OrdinalIgnoreCase);
			hashSet.IntersectWith(guids);
			return hashSet;
		}

		internal static bool IsCurrent(Profile profile)
		{
			return Known(profile.Off).SetEquals(Known(Wanted));
		}

		internal static int MissingIn(Profile profile)
		{
			return profile.Off.Count((string guid) => Find(guid) == null);
		}

		internal static string CleanName(string name)
		{
			return new string((from c in name.Trim()
				where Array.IndexOf(Path.GetInvalidFileNameChars(), c) < 0
				select c).ToArray()).Trim().TrimEnd('.');
		}

		internal static bool SaveProfile(string name)
		{
			return WriteProfile(name, Wanted);
		}

		internal static bool WriteProfile(string name, IEnumerable<string> off)
		{
			string text = CleanName(name);
			if (text.Length == 0)
			{
				return false;
			}
			try
			{
				Directory.CreateDirectory(ProfileFolder);
				List<string> list = new List<string> { "# GC Option, Mod-Profil „" + text + "“: diese Mods aus, alle anderen an." };
				list.AddRange(off.OrderBy<string, string>((string g) => g, StringComparer.OrdinalIgnoreCase));
				File.WriteAllLines(Path.Combine(ProfileFolder, text + ".txt"), list, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
				LastError = "";
				return true;
			}
			catch (Exception ex)
			{
				LastError = ex.Message;
				return false;
			}
		}

		internal static string FreeName(string name)
		{
			HashSet<string> hashSet = new HashSet<string>(from p in Profiles()
				select p.Name, StringComparer.OrdinalIgnoreCase);
			string text = CleanName(name);
			string text2 = text;
			int num = 2;
			while (hashSet.Contains(text2))
			{
				text2 = $"{text} ({num})";
				num++;
			}
			return text2;
		}

		internal static int ApplyProfile(Profile profile)
		{
			HashSet<string> hashSet = new HashSet<string>(Wanted, StringComparer.OrdinalIgnoreCase);
			Wanted.Clear();
			Wanted.UnionWith(WithDependents(Known(profile.Off)));
			if (!Save())
			{
				wanted = hashSet;
				return -1;
			}
			return MissingIn(profile);
		}

		internal static bool DeleteProfile(Profile profile)
		{
			try
			{
				string text = Path.Combine(ProfileFolder, "geloescht");
				Directory.CreateDirectory(text);
				string destFileName = Path.Combine(text, Path.GetFileNameWithoutExtension(profile.File) + "-" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".txt");
				File.Move(profile.File, destFileName);
				LastError = "";
				return true;
			}
			catch (Exception ex)
			{
				LastError = ex.Message;
				return false;
			}
		}

		internal static string ProfileText(Profile profile)
		{
			return "# GC Option, Mod-Profil „" + profile.Name + "“\n" + string.Join("\n", profile.Off.OrderBy<string, string>((string g) => g, StringComparer.OrdinalIgnoreCase)) + "\n";
		}

		internal static HashSet<string> ParseGuids(string text)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string[] array = text.Replace("\r", "").Split('\n');
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length > 0 && !text2.StartsWith("#", StringComparison.Ordinal) && text2.IndexOf(' ') < 0)
				{
					hashSet.Add(text2);
				}
			}
			return hashSet;
		}

		private static void ImportModMenu()
		{
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "ModMenu");
				if (!Directory.Exists(text))
				{
					return;
				}
				string text2 = Path.Combine(text, "disabled.txt");
				if (File.Exists(text2) && DateTime.Now - File.GetLastWriteTime(text2) < TimeSpan.FromDays(30.0) && !File.Exists(ListFile))
				{
					Directory.CreateDirectory(Path.GetDirectoryName(ListFile));
					File.Copy(text2, ListFile);
					Debug.Log((object)"GC_Kern: ausgeschaltete Mods aus Mod Menu übernommen.");
				}
				string path = Path.Combine(text, "profiles");
				if (Directory.Exists(path) && !Directory.Exists(ProfileFolder))
				{
					Directory.CreateDirectory(ProfileFolder);
					string[] files = Directory.GetFiles(path, "*.txt");
					foreach (string text3 in files)
					{
						File.Copy(text3, Path.Combine(ProfileFolder, Path.GetFileName(text3)));
					}
					Debug.Log((object)"GC_Kern: Profile aus Mod Menu übernommen.");
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("GC_Kern: Mod Menu nicht übernommen: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Ragdoll), "Awake")]
	internal static class RagdollScalePatch
	{
		private static void Postfix(Ragdoll __instance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				float num = component.GetZDO().GetFloat(GcKeys.RagdollScaleHash, 0f);
				if (num > 0f)
				{
					((Component)__instance).transform.localScale = Vector3.one * num;
				}
			}
		}
	}
	internal static class VPlusOptions
	{
		private static ConfigFile? config;

		private static GcMenu? menu;

		private static bool dirty;

		private static MethodInfo? reapply;

		private static PropertyInfo? readyForEdit;

		internal static void Register(GcMenu gcMenu)
		{
			if (!Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.valheim_plus", out var value) || (Object)(object)value.Instance == (Object)null)
			{
				return;
			}
			menu = gcMenu;
			config = value.Instance.Config;
			reapply = AccessTools.Method(AccessTools.TypeByName("ValheimPlus.Configurations.BepInExConfig"), "ReapplyPatches", new Type[1] { typeof(string) }, (Type[])null);
			readyForEdit = AccessTools.Property(AccessTools.TypeByName("ValheimPlus.Configurations.ConfigurationManagerWatcher"), "ReadyForEdit");
			if (reapply == null)
			{
				KernPlugin.Log.LogWarning((object)"ValheimPlus: BepInExConfig.ReapplyPatches nicht gefunden. Änderungen im Menü wirken erst nach dem nächsten Start.");
			}
			config.SettingChanged += delegate(object _, SettingChangedEventArgs e)
			{
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					dirty = true;
				}
				object obj;
				if (e == null)
				{
					obj = null;
				}
				else
				{
					ConfigEntryBase changedSetting = e.ChangedSetting;
					obj = ((changedSetting != null) ? changedSetting.Definition.Key : null);
				}
				if ((string?)obj == "enabled")
				{
					Build();
				}
			};
			Build();
			gcMenu.Closed += OnClosed;
		}

		private static void Build()
		{
			if (config == null || menu == null)
			{
				return;
			}
			GcMenuSection gcMenuSection = menu.Section("gc_vplus", 60, (string key) => GcLoc.Get("gck_vplus_" + key), "");
			int num = 0;
			int num2 = 0;
			foreach (IGrouping<string, ConfigDefinition> item in (from d in config.Keys
				group d by d.Section).OrderBy<IGrouping<string, ConfigDefinition>, string>((IGrouping<string, ConfigDefinition> g) => g.Key, StringComparer.OrdinalIgnoreCase))
			{
				List<ConfigEntryBase> list = item.Select((ConfigDefinition d) => config[d]).Where(Supported).ToList();
				if (list.Count == 0)
				{
					continue;
				}
				Dictionary<string, string> descriptions = list.ToDictionary<ConfigEntryBase, string, string>((ConfigEntryBase e) => e.Definition.Key, delegate(ConfigEntryBase e)
				{
					ConfigDescription description = e.Description;
					return ((description != null) ? description.Description : null) ?? "";
				}, StringComparer.Ordinal);
				string title = item.Key;
				GcMenuGroup gcMenuGroup = gcMenuSection.Group("vplus_" + item.Key, () => title, (string key) => Text(key, descriptions), "");
				ConfigEntryBase enabled = ((IEnumerable<ConfigEntryBase>)list).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase e) => e.Definition.Key == "enabled" && e.SettingType == typeof(bool)));
				if (enabled != null)
				{
					gcMenuGroup.Main("enabled", enabled, null, "", null, 0.0, "", () => (Object)(object)ZNet.instance == (Object)null || IsOn(enabled), Locked);
					num2++;
					if (!IsOn(enabled))
					{
						num++;
						continue;
					}
				}
				foreach (ConfigEntryBase item2 in list)
				{
					if (item2 != enabled)
					{
						if (enabled != null)
						{
							gcMenuGroup.Sub(item2.Definition.Key, item2, 0.0, "", null, "", null, Locked);
						}
						else
						{
							gcMenuGroup.Main(item2.Definition.Key, item2, null, "", null, 0.0, "", null, Locked);
						}
						num2++;
					}
				}
				num++;
			}
			KernPlugin.Log.LogDebug((object)$"ValheimPlus im Menü GC Option: {num} Abschnitte, {num2} Zeilen.");
		}

		private static bool IsOn(ConfigEntryBase entry)
		{
			object boxedValue = entry.BoxedValue;
			bool flag = default(bool);
			int num;
			if (boxedValue is bool)
			{
				flag = (bool)boxedValue;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static bool Locked()
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return true;
			}
			try
			{
				return readyForEdit != null && readyForEdit.GetValue(null, null) is bool flag && !flag;
			}
			catch
			{
				return false;
			}
		}

		private static bool Supported(ConfigEntryBase entry)
		{
			Type settingType = entry.SettingType;
			if (settingType.IsEnum)
			{
				return !settingType.IsDefined(typeof(FlagsAttribute), inherit: false);
			}
			if (!(settingType == typeof(bool)) && !(settingType == typeof(int)) && !(settingType == typeof(float)) && !(settingType == typeof(KeyboardShortcut)))
			{
				return settingType == typeof(KeyCode);
			}
			return true;
		}

		private static string Text(string key, Dictionary<string, string> descriptions)
		{
			if (key.StartsWith("t_", StringComparison.Ordinal) && key.EndsWith("_name", StringComparison.Ordinal))
			{
				return key.Substring(2, key.Length - 7);
			}
			if (key.StartsWith("t_", StringComparison.Ordinal) && key.EndsWith("_desc", StringComparison.Ordinal))
			{
				string key2 = key.Substring(2, key.Length - 7);
				if (!descriptions.TryGetValue(key2, out string value))
				{
					return "";
				}
				return FirstSentences(value);
			}
			if (key.StartsWith("enum_", StringComparison.Ordinal))
			{
				return key.Substring(5);
			}
			return key;
		}

		private static string FirstSentences(string text)
		{
			string text2 = text.Replace("\r", " ").Replace("\n", " ").Trim();
			int num = -1;
			int i = 0;
			int num2 = 0;
			for (; i < text2.Length; i++)
			{
				if (text2[i] == '.' && (i + 1 == text2.Length || text2[i + 1] == ' ') && ++num2 == 2)
				{
					num = i + 1;
					break;
				}
			}
			if (num <= 0)
			{
				return text2;
			}
			return text2.Substring(0, num);
		}

		private static void OnClosed()
		{
			if (!dirty || (Object)(object)ZNet.instance != (Object)null)
			{
				return;
			}
			dirty = false;
			try
			{
				reapply?.Invoke(null, new object[1] { "Einstellungen in GC Option geändert" });
			}
			catch (Exception ex)
			{
				KernPlugin.Log.LogWarning((object)("ValheimPlus konnte die Änderungen nicht neu anwenden: " + ex.Message));
			}
		}
	}
}
namespace GC.Kern.ModCheck
{
	internal static class Plugin
	{
		public const string Guid = "gorduan.gc_modcheck";

		public const string ModName = "GC_ModCheck";

		public const string Version = "1.0.0";

		internal const string Rpc = "GC_Kern_ServerInfo_v1";

		internal static ManualLogSource Log = null;

		internal static ConfigEntry<bool> Enabled = null;

		internal static ConfigEntry<bool> ShowOnFailure = null;

		internal static ConfigEntry<bool> ShowOnJoinIfMissing = null;

		internal static ConfigEntry<string> HiddenOnServer = null;

		internal static ConfigEntry<string> IgnoreClientOnly = null;

		internal static List<ModInfo>? ServerMods;

		internal static Report? LastReport;

		internal static HashSet<string> OptionalOnServer = new HashSet<string>(StringComparer.Ordinal);

		internal static bool Blocked => Chainloader.PluginInfos.ContainsKey("gorduan.gc_modcheck");

		internal static bool On
		{
			get
			{
				if (Enabled.Value)
				{
					return !Blocked;
				}
				return false;
			}
		}

		internal static void Init(ConfigFile Config)
		{
			Log = KernPlugin.Log;
			Enabled = Gc.Bind(Config, "5 - ModCheck", "Enabled", value: true, "Funktion ein- oder ausschalten (auch im Menü GC Option).");
			ShowOnFailure = Gc.Bind(Config, "5 - ModCheck", "ShowOnFailedConnection", value: true, "Nach einer fehlgeschlagenen Verbindung das Vergleichsfenster im Hauptmenü zeigen.");
			ShowOnJoinIfMissing = Gc.Bind(Config, "5 - ModCheck", "ShowOnJoinIfMissing", value: true, "Nach erfolgreichem Beitritt das Fenster zeigen, wenn dir Mods des Servers fehlen.");
			HiddenOnServer = Gc.Bind(Config, "5 - ModCheck - Server", "HiddenGuids", "", "Nur Server: kommagetrennte Plugin-GUIDs, die nicht an Spieler gemeldet werden (reine Server-Mods).");
			IgnoreClientOnly = Gc.Bind(Config, "5 - ModCheck - Client", "ClientOnlyGuids", "", "Kommagetrennte GUIDs eigener Client-Mods, die nicht als 'nur bei dir' gelistet werden.");
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ConsoleCommand());
		}

		internal static List<ModInfo> LocalMods()
		{
			List<ModInfo> list = new List<ModInfo>();
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				string package = "";
				try
				{
					string directoryName = Path.GetDirectoryName(value.Location);
					string text = ((directoryName != null) ? Path.GetFileName(directoryName) : null);
					if (text != null && !text.Equals("plugins", StringComparison.OrdinalIgnoreCase))
					{
						package = text;
					}
				}
				catch
				{
				}
				list.Add(new ModInfo(value.Metadata.GUID, value.Metadata.Name, value.Metadata.Version.ToString(), package));
			}
			return list.OrderBy<ModInfo, string>((ModInfo mod) => mod.Name, StringComparer.OrdinalIgnoreCase).ToList();
		}

		internal static ZPackage BuildPackage()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			HashSet<string> hidden = Gc.ParseList(HiddenOnServer.Value);
			List<ModInfo> list = (from mod in LocalMods()
				where IsGc(mod.Guid) || (On && !hidden.Contains(mod.Guid))
				select mod).ToList();
			ZPackage val = new ZPackage();
			val.Write(list.Count);
			foreach (ModInfo item in list)
			{
				val.Write(item.Guid);
				val.Write(item.Name);
				val.Write(item.Version);
				val.Write(item.Package);
			}
			val.Write(Math.Max(1, GcKern.HighestLocalStufe));
			val.Write(On);
			val.Write(GcKern.Modules.Count);
			foreach (GcModule module in GcKern.Modules)
			{
				val.Write(module.Info.Guid);
				val.Write((int)module.Info.Seite);
			}
			return val;
		}

		internal static bool IsGc(string guid)
		{
			if (!(guid == "gorduan.gc.kern"))
			{
				return guid.StartsWith("gorduan.gc.", StringComparison.Ordinal);
			}
			return true;
		}

		internal static void Receive(ZPackage pkg)
		{
			List<ModInfo> list = new List<ModInfo>();
			int num = pkg.ReadInt();
			for (int i = 0; i < num; i++)
			{
				list.Add(new ModInfo(pkg.ReadString(), pkg.ReadString(), pkg.ReadString(), pkg.ReadString()));
			}
			int num2 = 5;
			bool flag = true;
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			try
			{
				num2 = pkg.ReadInt();
				flag = pkg.ReadBool();
				int num3 = pkg.ReadInt();
				for (int j = 0; j < num3; j++)
				{
					string item = pkg.ReadString();
					if (pkg.ReadInt() == 0)
					{
						hashSet.Add(item);
					}
				}
			}
			catch
			{
			}
			OptionalOnServer = hashSet;
			GcServerInfo gcServerInfo = new GcServerInfo
			{
				Stufe = num2
			};
			foreach (ModInfo item2 in list)
			{
				gcServerInfo.Guids.Add(item2.Guid);
			}
			GcKern.Server = gcServerInfo;
			Log.LogInfo((object)$"Server: {list.Count} Mods, Stufe {num2} ({GcKern.StufeName(num2)}).");
			ServerMods = list;
			if (!On || !flag)
			{
				return;
			}
			HashSet<string> ignoreClientOnly = Gc.ParseList(IgnoreClientOnly.Value);
			LastReport = Report.Create(list, LocalMods(), ignoreClientOnly, hashSet);
			Log.LogInfo((object)$"Server meldet {list.Count} Mods. Fehlend: {LastReport.Missing.Count}, andere Version: {LastReport.Different.Count}, nur hier: {LastReport.ClientOnly.Count}.");
			string[] array = LastReport.ToText().Split('\n');
			foreach (string text in array)
			{
				if (text.Trim().Length > 0)
				{
					Log.LogInfo((object)text);
				}
			}
		}
	}
	internal sealed class ModInfo
	{
		public string Guid { get; }

		public string Name { get; }

		public string Version { get; }

		public string Package { get; }

		public ModInfo(string guid, string name, string version, string package)
		{
			Guid = guid;
			Name = name;
			Version = version;
			Package = package;
		}

		public string Describe()
		{
			if (Package.Length <= 0)
			{
				return Name + " " + Version + "  (" + Guid + ")";
			}
			return Name + " " + Version + "  [" + Package + "]";
		}
	}
	internal sealed class Report
	{
		public List<ModInfo> Missing = new List<ModInfo>();

		public List<(ModInfo Server, ModInfo Client)> Different = new List<(ModInfo, ModInfo)>();

		public List<ModInfo> ClientOnly = new List<ModInfo>();

		public bool HasProblems
		{
			get
			{
				if (Missing.Count <= 0)
				{
					return Different.Count > 0;
				}
				return true;
			}
		}

		public static Report Create(List<ModInfo> server, List<ModInfo> client, HashSet<string> ignoreClientOnly, HashSet<string> optional)
		{
			Report report = new Report();
			Dictionary<string, ModInfo> dictionary = (from mod in client
				group mod by mod.Guid).ToDictionary((IGrouping<string, ModInfo> group) => group.Key, (IGrouping<string, ModInfo> group) => group.First());
			Dictionary<string, ModInfo> dictionary2 = (from mod in server
				group mod by mod.Guid).ToDictionary((IGrouping<string, ModInfo> group) => group.Key, (IGrouping<string, ModInfo> group) => group.First());
			foreach (ModInfo item in server)
			{
				if (!optional.Contains(item.Guid))
				{
					if (!dictionary.TryGetValue(item.Guid, out var value))
					{
						report.Missing.Add(item);
					}
					else if (value.Version != item.Version)
					{
						report.Different.Add((item, value));
					}
				}
			}
			foreach (ModInfo item2 in client)
			{
				if (!dictionary2.ContainsKey(item2.Guid) && !ignoreClientOnly.Contains(item2.Guid))
				{
					report.ClientOnly.Add(item2);
				}
			}
			return report;
		}

		public string ToText()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(GcLoc.Get("gcm_title"));
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(GcLoc.Get("gcm_missing", Missing.Count));
			foreach (ModInfo item in Missing)
			{
				stringBuilder.AppendLine("- " + item.Describe());
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(GcLoc.Get("gcm_different", Different.Count));
			foreach (var (modInfo, modInfo2) in Different)
			{
				stringBuilder.AppendLine("- " + GcLoc.Get("gcm_version_line", modInfo.Name, modInfo.Version, modInfo2.Version) + ((modInfo.Package.Length > 0) ? ("  [" + modInfo.Package + "]") : ""));
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(GcLoc.Get("gcm_client_only", ClientOnly.Count));
			foreach (ModInfo item2 in ClientOnly)
			{
				stringBuilder.AppendLine("- " + item2.Describe());
			}
			return stringBuilder.ToString();
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	internal static class NewConnectionPatch
	{
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			peer.m_rpc.Register<ZPackage>("GC_Kern_ServerInfo_v1", (Action<ZRpc, ZPackage>)delegate(ZRpc _, ZPackage pkg)
			{
				if (!ZNet.instance.IsServer())
				{
					Plugin.Receive(pkg);
				}
			});
			if (__instance.IsServer())
			{
				peer.m_rpc.Invoke("GC_Kern_ServerInfo_v1", new object[1] { Plugin.BuildPackage() });
			}
			else
			{
				Plugin.ServerMods = null;
				Plugin.LastReport = null;
				GcKern.Server = null;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnDestroy")]
	internal static class ServerInfoResetPatch
	{
		private static void Postfix()
		{
			GcKern.Server = null;
		}
	}
	[HarmonyPatch(typeof(ZNet), "Awake")]
	internal static class SessionResetPatch
	{
		private static void Prefix()
		{
			Plugin.ServerMods = null;
			Plugin.LastReport = null;
			SpawnPatch.shown = false;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	internal static class ConnectErrorPatch
	{
		private static void Postfix()
		{
			if (Plugin.On && Plugin.ShowOnFailure.Value && Plugin.LastReport != null)
			{
				ReportWindow.Show(Plugin.LastReport);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class SpawnPatch
	{
		internal static bool shown;

		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !shown && Plugin.On && Plugin.ShowOnJoinIfMissing.Value && Plugin.LastReport != null && Plugin.LastReport.Missing.Count > 0)
			{
				shown = true;
				ReportWindow.Show(Plugin.LastReport);
			}
		}
	}
	internal class ConsoleCommand : ConsoleCommand
	{
		public override string Name => "modcheck";

		public override string Help => "GC_Kern: Mod-Abgleich mit dem Server anzeigen";

		public override void Run(string[] args)
		{
			if (Plugin.LastReport == null)
			{
				Console.instance.Print("Keine Serverliste empfangen (Server ohne GC_Kern, Mod-Abgleich aus oder nicht verbunden).");
			}
			else
			{
				ReportWindow.Show(Plugin.LastReport);
			}
		}
	}
	internal static class ReportWindow
	{
		private static GameObject? window;

		private static Text? header;

		private static Text? body;

		private static string text = "";

		public static void Show(Report report)
		{
			if (!Gc.IsHeadless && GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null))
			{
				Build();
				text = report.ToText();
				header.text = GcLoc.Get(report.HasProblems ? "gcm_header_problems" : "gcm_header_ok");
				body.text = Colorize(report);
				bool activeSelf = window.activeSelf;
				window.SetActive(true);
				window.transform.SetAsLastSibling();
				if (!activeSelf)
				{
					GUIManager.BlockInput(true);
				}
			}
		}

		private static string Colorize(Report report)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("<color=#ff8866><b>" + GcLoc.Get("gcm_missing", report.Missing.Count) + "</b></color>");
			foreach (ModInfo item in report.Missing)
			{
				stringBuilder.AppendLine("  • " + item.Describe());
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("<color=#ffd166><b>" + GcLoc.Get("gcm_different", report.Different.Count) + "</b></color>");
			foreach (var (modInfo, modInfo2) in report.Different)
			{
				stringBuilder.AppendLine("  • " + GcLoc.Get("gcm_version_line", modInfo.Name, modInfo.Version, modInfo2.Version));
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("<color=#9fd3ff><b>" + GcLoc.Get("gcm_client_only", report.ClientOnly.Count) + "</b></color>");
			foreach (ModInfo item2 in report.ClientOnly)
			{
				stringBuilder.AppendLine("  • " + item2.Describe());
			}
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("<i>" + GcLoc.Get("gcm_note") + "</i>");
			return stringBuilder.ToString();
		}

		private static void Build()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)window != (Object)null)
			{
				return;
			}
			window = GcUi.CreateWindow("GC_ModCheck_Window", 900f, 620f, out header, out RectTransform inner);
			RectTransform val = GcUi.CreateScroll((Transform)(object)inner, 820f, 440f);
			body = GUIManager.Instance.CreateText("", (Transform)(object)val, new Vector2(0f, 1f), new Vector2(1f, 1f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 780f, 0f, true).GetComponent<Text>();
			body.supportRichText = true;
			body.horizontalOverflow = (HorizontalWrapMode)0;
			body.verticalOverflow = (VerticalWrapMode)1;
			GcUi.CreateButton(window.transform, GcLoc.Get("gcm_copy"), new Vector2(0.5f, 0f), new Vector2(-130f, 44f), 240f, 44f, delegate
			{
				GUIUtility.systemCopyBuffer = text;
				Gc.Center(GcLoc.Get("gcm_copied"));
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					header.text = GcLoc.Get("gcm_copied");
				}
			});
			GcUi.CreateButton(window.transform, GcLoc.Get("gcm_close"), new Vector2(0.5f, 0f), new Vector2(130f, 44f), 200f, 44f, delegate
			{
				window.SetActive(false);
				GUIManager.BlockInput(false);
			});
		}
	}
}
namespace GC.Kern.Progression
{
	internal static class BossScaling
	{
		internal static readonly string[] BossKeys = new string[8] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader", "defeated_frozenking_p3" };

		internal const string EpicLootGuid = "randyknapp.mods.epicloot";

		internal const float EpicLootPercent = 10f;

		internal static ConfigEntry<bool> Automatic = null;

		internal static ConfigEntry<float> PercentPerBoss = null;

		private static int count;

		private static float nextCount;

		private static Player? countedFor;

		private static float spawnedAt;

		private static bool announced;

		internal static int Count => count;

		internal static float Factor
		{
			get
			{
				if (!((Object)(object)Player.m_localPlayer != (Object)null))
				{
					return 1f;
				}
				return 1f + Percent() / 100f * (float)count;
			}
		}

		internal static bool OnGcServer
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					if (!ZNet.instance.IsServer())
					{
						return GcKern.Server != null;
					}
					return true;
				}
				return false;
			}
		}

		internal static bool Active
		{
			get
			{
				if (count > 0 && (Object)(object)Player.m_localPlayer != (Object)null && OnGcServer)
				{
					return Percent() > 0f;
				}
				return false;
			}
		}

		internal static void Init(ConfigFile config)
		{
			Automatic = Gc.BindSynced(config, "13 - Boss Progression", "Automatic", value: true, "Prozent je besiegtem Hauptboss automatisch: der höchste Ausgleichswert der laufenden GC-Mods (z. B. Tiere 5), mit EpicLoot mindestens 10, ohne erleichternde Mods 0 (wie Valheim). Aus: es gilt PercentPerBoss.");
			PercentPerBoss = Gc.BindSynced(config, "13 - Boss Progression", "PercentPerBoss", 5f, "Gegner und Bosse haben je besiegtem Hauptboss (Eikthyr, Ältester, Bonemass, Moder, Yagluth, Königin, Fader, Kall Mandefimbul) so viel Prozent mehr Leben und machen so viel mehr Schaden, addiert. Gilt nur, wenn Automatic aus ist. Es zählt der eigene Fortschritt jedes Spielers (mit World Advancement Progression seine privaten Schlüssel, mit Guilds_Progress samt Gilden-Fortschritt, ohne diese Mods die Welt).", (AcceptableValueBase?)(object)new AcceptableValueRange<float>(0f, 100f));
		}

		internal static float Percent()
		{
			if (!Automatic.Value)
			{
				return Mathf.Max(0f, PercentPerBoss.Value);
			}
			float num = (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot") ? 10f : 0f);
			foreach (GcModule module in GcKern.Modules)
			{
				if (module.Info.Ausgleich > num && module.On)
				{
					num = module.Info.Ausgleich;
				}
			}
			return num;
		}

		internal static string Source()
		{
			if (!Automatic.Value)
			{
				return "";
			}
			float num = 0f;
			string result = "";
			if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot"))
			{
				num = 10f;
				result = "EpicLoot";
			}
			foreach (GcModule module in GcKern.Modules)
			{
				if (module.Info.Ausgleich > num && module.On)
				{
					num = module.Info.Ausgleich;
					string text = "gck_mod_" + module.Info.Id;
					string text2 = GcLoc.Get(text);
					result = ((text2 == text) ? module.Info.Name : text2);
				}
			}
			return result;
		}

		internal static bool IsFoe(Character? character)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if ((Object)(object)character == (Object)null || character.IsPlayer() || character.IsTamed())
			{
				return false;
			}
			Faction faction = character.GetFaction();
			if ((int)faction != 0 && (int)faction != 11)
			{
				return (int)faction != 12;
			}
			return false;
		}

		internal static bool Ours(Character? character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			if ((Object)(object)character == (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			ZNetView nview = character.m_nview;
			if (!character.IsPlayer() && character.IsTamed() && (Object)(object)nview != (Object)null && nview.IsValid())
			{
				return nview.IsOwner();
			}
			return false;
		}

		private static int CountBosses()
		{
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return 0;
			}
			int num = 0;
			string[] bossKeys = BossKeys;
			foreach (string text in bossKeys)
			{
				if (instance.GetGlobalKey(text))
				{
					num++;
				}
			}
			return num;
		}

		internal static void Tick()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				countedFor = null;
				count = 0;
				return;
			}
			float time = Time.time;
			if ((Object)(object)localPlayer != (Object)(object)countedFor)
			{
				countedFor = localPlayer;
				spawnedAt = time;
				announced = false;
				count = CountBosses();
				nextCount = time + 2f;
			}
			else
			{
				if (time < nextCount)
				{
					return;
				}
				nextCount = time + 2f;
				int num = CountBosses();
				bool flag = announced || time - spawnedAt > 15f;
				if (num > count && flag && OnGcServer)
				{
					float num2 = Percent();
					if (num2 > 0f)
					{
						string text = Mathf.RoundToInt(num2 * (float)(num - count)).ToString();
						string text2 = Mathf.RoundToInt(num2 * (float)num).ToString();
						MessageHud instance = MessageHud.instance;
						if (instance != null)
						{
							instance.ShowMessage((MessageType)2, GcLoc.Get("gcbp_stronger", text, text2), 0, (Sprite)null, false, true);
						}
					}
				}
				announced = flag;
				count = num;
			}
		}

		internal static string Note()
		{
			string text = Mathf.RoundToInt(Percent()).ToString();
			string text2 = (((Object)(object)Player.m_localPlayer != (Object)null) ? GcLoc.Get("gcsv_bossscale_now", text, count.ToString(), Mathf.RoundToInt(Percent() * (float)count).ToString()) : GcLoc.Get("gcsv_bossscale_rule", text));
			string text3 = Source();
			if (text3.Length <= 0)
			{
				return text2;
			}
			return text2 + " " + GcLoc.Get("gck_bossscale_source", text3);
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class BossScalingDealtPatch
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			if (hit != null && BossScaling.Active && BossScaling.IsFoe(__instance))
			{
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker != (Object)null && (Object)(object)attacker != (Object)(object)__instance && BossScaling.Ours(attacker))
				{
					hit.ApplyModifier(1f / BossScaling.Factor);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class BossScalingTakenPatch
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			if (hit != null && BossScaling.Active && BossScaling.Ours(__instance))
			{
				Character attacker = hit.GetAttacker();
				if ((Object)(object)attacker != (Object)null && (Object)(object)attacker != (Object)(object)__instance && BossScaling.IsFoe(attacker))
				{
					hit.ApplyModifier(BossScaling.Factor);
				}
			}
		}
	}
}
namespace GC.Shared
{
	public enum GcTaming
	{
		Normal,
		Blocked,
		SimpleAI
	}
	public static class GcHooks
	{
		public static Func<bool>? DungeonMapLargeOpen;

		public static Func<bool>? PortalGuardActive;

		public static Action<TeleportWorld, string>? PortalRename;

		public static Func<int, float>? SpeciesMaxLevel;

		public static Func<float>? SpeciesEffectCap;

		public static Func<Character, Character, bool>? SpeciesEnemyForOrder;

		public static Func<Character, GcTaming>? SpeciesTaming;

		public static Func<bool>? CourierOn;

		public static Func<Player, ItemData, bool>? CourierWhistle;

		public static Func<string>? CourierTooltip;

		public static Func<Procreation, float?>? MateLevel;

		public static int RedCraft;

		public static bool IsDungeonMapLargeOpen()
		{
			try
			{
				return DungeonMapLargeOpen != null && DungeonMapLargeOpen();
			}
			catch
			{
				return false;
			}
		}

		public static bool IsPortalGuardActive()
		{
			try
			{
				return PortalGuardActive != null && PortalGuardActive();
			}
			catch
			{
				return false;
			}
		}

		public static bool IsCourierOn()
		{
			try
			{
				return CourierOn != null && CourierOn();
			}
			catch
			{
				return false;
			}
		}

		public static float? GetMateLevel(Procreation parent)
		{
			try
			{
				return MateLevel?.Invoke(parent);
			}
			catch
			{
				return null;
			}
		}

		public static void Leave(ref int depth)
		{
			depth = Math.Max(0, depth - 1);
		}

		public static int CountUsable(Inventory inventory, string name)
		{
			RedCraft++;
			try
			{
				return inventory.CountItems(name, -1, true);
			}
			finally
			{
				Leave(ref RedCraft);
			}
		}
	}
	public enum GcSeite
	{
		Spieler,
		ServerOptional,
		Alle
	}
	public sealed class GcModInfo
	{
		public string Id = "";

		public string Guid = "";

		public string Name = "";

		public string Version = "";

		public int Stufe = 1;

		public GcSeite Seite;

		public string[] Braucht = Array.Empty<string>();

		public string[] Partner = Array.Empty<string>();

		public string[] Fremd = Array.Empty<string>();

		public string AlteConfig = "";

		public float Ausgleich;
	}
	public sealed class GcServerInfo
	{
		public int Stufe;

		public HashSet<string> Guids = new HashSet<string>(StringComparer.Ordinal);
	}
	public sealed class GcModule
	{
		private readonly HashSet<string> reported = new HashSet<string>();

		public Func<bool>? IsOn;

		public BaseUnityPlugin Plugin { get; }

		public ManualLogSource Log { get; }

		public GcModInfo Info { get; }

		public ConfigFile Config => Plugin.Config;

		public bool FreshConfig { get; }

		public bool Allowed => GcKern.Allowed(Info);

		public bool OnServer => GcKern.ServerHas(Info.Guid);

		public bool On
		{
			get
			{
				try
				{
					return Allowed && (IsOn == null || IsOn());
				}
				catch
				{
					return false;
				}
			}
		}

		internal GcModule(BaseUnityPlugin plugin, ManualLogSource log, GcModInfo info, bool freshConfig)
		{
			Plugin = plugin;
			Log = log;
			Info = info;
			FreshConfig = freshConfig;
		}

		public GcMenuGroup MenuGroup(Func<string, string> text, string? titleKey = null)
		{
			return GcKern.MenuGroup(this, text, titleKey);
		}

		public void TakeOverOldSettings()
		{
			if (!FreshConfig || Info.AlteConfig.Length == 0)
			{
				return;
			}
			string[] array = Info.AlteConfig.Split(new char[2] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				string path = Path.Combine(Paths.ConfigPath, text);
				if (!File.Exists(path))
				{
					continue;
				}
				bool saveOnConfigSet = Config.SaveOnConfigSet;
				try
				{
					Dictionary<string, string> dictionary = GcCfgFile.Read(path);
					int num = 0;
					Config.SaveOnConfigSet = false;
					foreach (ConfigDefinition item in Config.Keys.ToList())
					{
						if (dictionary.TryGetValue(GcCfgFile.Key(item.Section, item.Key), out var value))
						{
							ConfigEntryBase obj = Config[item];
							string serializedValue = obj.GetSerializedValue();
							obj.SetSerializedValue(value);
							if (obj.GetSerializedValue() != serializedValue)
							{
								num++;
							}
						}
					}
					Config.SaveOnConfigSet = saveOnConfigSet;
					Config.Save();
					Log.LogInfo((object)$"Einstellungen aus {text} übernommen: {num} Werte weichen vom Standard ab.");
				}
				catch (Exception ex)
				{
					Config.SaveOnConfigSet = saveOnConfigSet;
					Log.LogWarning((object)("Einstellungen aus " + text + " konnten nicht übernommen werden: " + ex.Message));
				}
			}
		}

		public void Guard(string part, Action action)
		{
			try
			{
				action();
			}
			catch (Exception arg)
			{
				if (reported.Add(part))
				{
					Log.LogWarning((object)$"{part}: {arg}");
				}
			}
		}

		public bool Has(string id)
		{
			return GcKern.ModLoaded(id);
		}
	}
	public static class GcKern
	{
		public const string Guid = "gorduan.gc.kern";

		public const string Name = "GC_Kern";

		public const string Version = "1.2.0";

		public const string GuidPrefix = "gorduan.gc.";

		public static readonly string[] OldPackages = new string[3] { "gorduan.gc_server", "gorduan.gc_client", "gorduan.valheimplusplus" };

		private static readonly List<GcModule> modules = new List<GcModule>();

		private static readonly Dictionary<int, GcMenuSection> sections = new Dictionary<int, GcMenuSection>();

		internal static ConfigEntry<int>? StufeSetting;

		public static IReadOnlyList<GcModule> Modules => modules;

		public static GcServerInfo? Server { get; internal set; }

		public static int HighestLocalStufe
		{
			get
			{
				if (modules.Count != 0)
				{
					return modules.Max((GcModule m) => m.Info.Stufe);
				}
				return 0;
			}
		}

		public static int ServerStufe
		{
			get
			{
				ZNet instance = ZNet.instance;
				if ((Object)(object)instance == (Object)null || instance.IsServer() || Server == null)
				{
					return 6;
				}
				int num = StufeSetting?.Value ?? 0;
				if (num <= 0)
				{
					return Math.Max(1, Server.Stufe);
				}
				return num;
			}
		}

		public static GcModule Register(BaseUnityPlugin plugin, ManualLogSource log, GcModInfo info)
		{
			bool freshConfig = !File.Exists(plugin.Config.ConfigFilePath);
			GcModule gcModule = new GcModule(plugin, log, info, freshConfig);
			modules.Add(gcModule);
			if (((object)plugin).GetType().Assembly != typeof(GcKern).Assembly)
			{
				GcLoc.AddAssembly(((object)plugin).GetType().Assembly, info.Name, log);
			}
			GcDeepTip.RegisterMod(((object)plugin).GetType().Assembly, ((object)plugin).GetType().Namespace ?? "", info.Name);
			log.LogInfo((object)$"{info.Name} {info.Version} angemeldet: Stufe {info.Stufe}, {SeiteText(info.Seite)}.");
			return gcModule;
		}

		public static bool IsLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}

		public static bool ModLoaded(string id)
		{
			return IsLoaded("gorduan.gc." + id);
		}

		internal static bool Allowed(GcModInfo info)
		{
			if (info.Seite == GcSeite.Alle || info.Stufe <= 0)
			{
				return true;
			}
			if (info.Seite == GcSeite.ServerOptional && ServerHas(info.Guid))
			{
				return true;
			}
			return info.Stufe <= ServerStufe;
		}

		internal static bool ServerHas(string guid)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if (instance.IsServer())
			{
				return IsLoaded(guid);
			}
			if (Server != null)
			{
				return Server.Guids.Contains(guid);
			}
			return false;
		}

		public static string StufeName(int stufe)
		{
			return GcLoc.Get("gck_stufe" + stufe);
		}

		public static string SeiteText(GcSeite seite)
		{
			return seite switch
			{
				GcSeite.Spieler => "nur Spieler", 
				GcSeite.ServerOptional => "Spieler, Server optional", 
				_ => "Server und alle Spieler", 
			};
		}

		internal static GcMenuSection Section(int stufe)
		{
			if (!sections.TryGetValue(stufe, out GcMenuSection value))
			{
				string id = ((stufe == 0) ? "gc_kern" : ("gc_stufe" + stufe));
				int order = ((stufe == 0) ? 90 : (stufe * 10));
				value = KernPlugin.Menu.Section(id, order, (string key) => GcLoc.Get((stufe == 0) ? ("gck_kern_" + key) : ("gck_stufe" + stufe + "_" + key)), "");
				sections[stufe] = value;
			}
			return value;
		}

		internal static GcMenuGroup MenuGroup(GcModule module, Func<string, string> text, string? ownTitleKey = null)
		{
			GcModInfo info = module.Info;
			string titleKey = ownTitleKey ?? ("gck_mod_" + info.Id);
			Func<string> title = delegate
			{
				string text2 = GcLoc.Get(titleKey);
				return (!(text2 == titleKey)) ? text2 : info.Name;
			};
			GcMenuGroup gcMenuGroup = Section(info.Stufe).Group(titleKey, title, text, info.Guid, () => module.Allowed);
			gcMenuGroup.ModId = info.Id;
			return gcMenuGroup;
		}
	}
	internal static class GcCfgFile
	{
		public static string Key(string section, string key)
		{
			return section.Trim() + "\u0001" + key.Trim();
		}

		public static Dictionary<string, string> Read(string path)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
			string section = "";
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0 || text.StartsWith("#", StringComparison.Ordinal))
				{
					continue;
				}
				if (text.StartsWith("[", StringComparison.Ordinal) && text.EndsWith("]", StringComparison.Ordinal))
				{
					section = text.Substring(1, text.Length - 2).Trim();
					continue;
				}
				int num = text.IndexOf('=');
				if (num > 0)
				{
					dictionary[Key(section, text.Substring(0, num))] = text.Substring(num + 1).Trim();
				}
			}
			return dictionary;
		}
	}
	[BepInPlugin("gorduan.gc.kern", "GC_Kern", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("gorduan.gc_server")]
	[BepInIncompatibility("gorduan.gc_client")]
	[BepInIncompatibility("gorduan.valheimplusplus")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class KernPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static GcModule Module;

		internal static GcMenu Menu;

		internal static ConfigEntry<KeyboardShortcut>? MenuKey;

		private void Awake()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Module = GcKern.Register((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger, new GcModInfo
			{
				Id = "kern",
				Guid = "gorduan.gc.kern",
				Name = "GC_Kern",
				Version = "1.2.0",
				Stufe = 0,
				Seite = GcSeite.Spieler,
				AlteConfig = "gorduan.gc_server.cfg"
			});
			GcLoc.Init("GC_Kern", ((BaseUnityPlugin)this).Logger);
			GcKern.StufeSetting = Gc.BindSynced(((BaseUnityPlugin)this).Config, "1 - Server", "SpielerStufe", 0, "Bis zu welcher Stufe Mods, die nur beim Spieler laufen, auf diesem Server wirken dürfen (1 Sehr Vanilla, 2 Vanilla, 3 Vanilla+, 4 GC leicht, 5 GC). 0 = automatisch: die höchste Stufe der GC-Mods auf dem Server.", (AcceptableValueBase?)(object)new AcceptableValueRange<int>(0, 5));
			Plugin.Init(((BaseUnityPlugin)this).Config);
			BossScaling.Init(((BaseUnityPlugin)this).Config);
			MenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2 - Menue", "Taste", KeyboardShortcut.Empty, "Taste für das Menü GC Option, im Hauptmenü und im Spiel (nicht im Chat oder in der Konsole). Leer = nur über den Knopf.");
			Module.TakeOverOldSettings();
			Menu = new GcMenu(Log, GcMenu.UiText(""));
			Harmony val = new Harmony("gorduan.gc.kern");
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(KernPlugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				try
				{
					val.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Patch {type.FullName} nicht eingespielt, diese Funktion fehlt: {arg}");
				}
			}
			Module.MenuGroup(KernText).Main("stufe", (ConfigEntryBase)(object)GcKern.StufeSetting, null, "", StufeNote, 1.0).Main("bossscale", (ConfigEntryBase)(object)BossScaling.Automatic, null, "", BossScaling.Note)
				.Sub("bossscale_percent", (ConfigEntryBase)(object)BossScaling.PercentPerBoss, 1.0, " %", null, "", null, () => BossScaling.Automatic.Value, () => GcLoc.Get("gck_bossscale_auto_locked"))
				.Main("modcheck", (ConfigEntryBase)(object)Plugin.Enabled, () => Plugin.Blocked, "GC_ModCheck")
				.Sub("modcheck_failure", (ConfigEntryBase)(object)Plugin.ShowOnFailure)
				.Sub("modcheck_join", (ConfigEntryBase)(object)Plugin.ShowOnJoinIfMissing)
				.Main("menukey", (ConfigEntryBase)(object)MenuKey);
			Log.LogInfo((object)"GC_Kern 1.2.0 geladen.");
		}

		private static string KernText(string key)
		{
			string text = GcLoc.Get("gck_" + key);
			if (!(text != "gck_" + key))
			{
				return GcLoc.Get("gcsv_" + key);
			}
			return text;
		}

		private static string StufeNote()
		{
			ZNet instance = ZNet.instance;
			int num;
			if ((Object)(object)instance != (Object)null && !instance.IsServer())
			{
				num = GcKern.ServerStufe;
			}
			else
			{
				int num2 = GcKern.StufeSetting?.Value ?? 0;
				num = ((num2 > 0) ? num2 : Math.Max(1, GcKern.HighestLocalStufe));
			}
			if (num < 6)
			{
				return GcLoc.Get("gck_stufe_now", num, GcKern.StufeName(num));
			}
			return GcLoc.Get("gck_stufe_now_free");
		}

		private void Start()
		{
			Menu.LogBlocked();
			if (!Gc.IsHeadless)
			{
				Module.Guard("ValheimPlus im Menü", delegate
				{
					VPlusOptions.Register(Menu);
				});
			}
			foreach (GcModule module in GcKern.Modules)
			{
				string[] partner = module.Info.Partner;
				foreach (string text in partner)
				{
					if (!GcKern.ModLoaded(text))
					{
						Log.LogInfo((object)(module.Info.Name + ": Partner gorduan.gc." + text + " fehlt, die Mod läuft ohne dessen Teil."));
					}
				}
			}
		}

		private void Update()
		{
			if (!Gc.IsHeadless)
			{
				Module.Guard("Menü-Taste", delegate
				{
					Menu.CheckHotkey();
				});
				Module.Guard("Menü", delegate
				{
					Menu.Update();
				});
				Module.Guard("Boss-Fortschritt", BossScaling.Tick);
			}
		}
	}
	public sealed class GcMenuSection
	{
		private readonly List<object> groups;

		private readonly Func<string, string> text;

		internal GcMenuSection(Dictionary<string, object> data, Func<string, string> text)
		{
			groups = (List<object>)data["groups"];
			this.text = text;
		}

		public GcMenuGroup Group(string id)
		{
			List<object> list = new List<object>();
			Func<string, string> t = text;
			groups.Add(new Dictionary<string, object>
			{
				["id"] = id,
				["title"] = (Func<string>)(() => t("group_" + id)),
				["items"] = list
			});
			return new GcMenuGroup(list, text);
		}

		public GcMenuGroup Group(string id, Func<string> title, Func<string, string> groupText, string guid, Func<bool>? allowed = null)
		{
			List<object> list = new List<object>();
			Dictionary<string, object> dictionary = new Dictionary<string, object>
			{
				["id"] = id,
				["title"] = title,
				["items"] = list,
				["guid"] = guid
			};
			if (allowed != null)
			{
				dictionary["allowed"] = allowed;
			}
			groups.Add(dictionary);
			return new GcMenuGroup(list, groupText);
		}
	}
	public sealed class GcMenuGroup
	{
		private readonly List<object> items;

		private readonly Func<string, string> text;

		internal string? ModId;

		internal GcMenuGroup(List<object> items, Func<string, string> text)
		{
			this.items = items;
			this.text = text;
		}

		public GcMenuGroup Main(string key, ConfigEntryBase entry, Func<bool>? blocked = null, string oldMod = "", Func<string>? note = null, double step = 0.0, string unit = "", Func<bool>? requires = null, Func<bool>? locked = null, Func<string>? lockedText = null)
		{
			return Add(key, entry, 0, blocked, oldMod, note, step, unit, requires, locked, lockedText);
		}

		public GcMenuGroup Sub(string key, ConfigEntryBase entry, double step = 0.0, string unit = "", Func<bool>? blocked = null, string oldMod = "", Func<bool>? requires = null, Func<bool>? locked = null, Func<string>? lockedText = null)
		{
			return Add(key, entry, 1, blocked, oldMod, null, step, unit, requires, locked, lockedText);
		}

		private GcMenuGroup Add(string key, ConfigEntryBase entry, int level, Func<bool>? blocked, string oldMod, Func<string>? note, double step, string unit, Func<bool>? requires, Func<bool>? locked, Func<string>? lockedText)
		{
			Func<string, string> t = text;
			Dictionary<string, object> dictionary = new Dictionary<string, object>
			{
				["key"] = key,
				["entry"] = entry,
				["name"] = (Func<string>)(() => t("t_" + key + "_name")),
				["desc"] = (Func<string>)(() => t("t_" + key + "_desc")),
				["enumText"] = (Func<string, string>)((string value) => t("enum_" + value)),
				["level"] = level,
				["step"] = step,
				["unit"] = unit,
				["oldMod"] = oldMod
			};
			if (blocked != null)
			{
				dictionary["blocked"] = blocked;
			}
			if (note != null)
			{
				dictionary["note"] = note;
			}
			if (requires != null)
			{
				dictionary["requires"] = requires;
			}
			if (locked != null)
			{
				dictionary["locked"] = locked;
			}
			if (lockedText != null)
			{
				dictionary["lockedText"] = lockedText;
			}
			if (ModId != null)
			{
				GcDeepTip.Value("gc_" + ModId + "_" + key, () => GcDeepTip.Format(entry, unit, (string value) => t("enum_" + value)));
				dictionary["deeptip"] = ((level != 0) ? new string[1] { "gc." + ModId + "." + key } : new string[2]
				{
					"gc." + ModId + "." + key,
					"gc." + ModId
				});
			}
			items.Add(dictionary);
			return this;
		}
	}
	public sealed class GcMenu
	{
		private sealed class Row
		{
			public Dictionary<string, object> Item;

			public ConfigEntryBase Entry;

			public string Guid = "";

			public Func<bool>? Allowed;

			public int Level;

			public bool Server;

			public GameObject Root;

			public Row? Parent;

			public readonly List<Row> Subs = new List<Row>();

			public Text Name;

			public Text Description;

			public Text Scope;

			public string BaseDescription = "";

			public EditorKind Kind;

			public Button? Main;

			public Text? MainLabel;

			public Button? Minus;

			public Button? Plus;

			public InputField? Input;

			public bool InputError;

			public object[]? Choices;

			public bool Foreign;

			public ForeignMod? Mod;

			public SyncKind Sync;

			public bool ReadOnly;

			public Func<bool>? ReadOnlyCheck;

			public object? SyncTag;

			public string Search = "";

			public Button? Reset;

			public bool HideDefault;

			public bool Editable;

			public bool Visible;
		}

		private sealed class Block
		{
			public GameObject Header;

			public readonly List<Row> Rows = new List<Row>();

			public readonly List<Block> Children = new List<Block>();
		}

		private enum SyncKind
		{
			Local,
			Jotunn,
			ServerSync
		}

		private sealed class ForeignEntry
		{
			public ConfigEntryBase Entry;

			public string Name = "";

			public string Section = "";

			public string Description = "";

			public SyncKind Sync;

			public Func<bool>? ReadOnlyCheck;

			public bool HideDefault;

			public bool Advanced;

			public int Order;

			public int Index;

			public string Search = "";
		}

		private sealed class ForeignGroup
		{
			public GameObject Header;

			public readonly List<Row> Rows = new List<Row>();
		}

		private sealed class ForeignMod
		{
			public string Guid = "";

			public string Name = "";

			public string Version = "";

			public bool HasSync;

			public readonly List<ForeignEntry> Entries = new List<ForeignEntry>();

			public string Search = "";

			public GameObject Header;

			public Text HeaderLabel;

			public GameObject Body;

			public bool Built;

			public readonly List<Row> Rows = new List<Row>();

			public GameObject? ClientHeader;

			public GameObject? ServerHeader;

			public readonly List<ForeignGroup> ClientGroups = new List<ForeignGroup>();

			public readonly List<ForeignGroup> ServerGroups = new List<ForeignGroup>();
		}

		private enum View
		{
			Settings,
			Mods,
			Profiles
		}

		private sealed class ModRow
		{
			public ModSwitch.Mod Mod;

			public GameObject Root;

			public Toggle Toggle;

			public Text Title;

			public Text Sub;

			public Text Status;
		}

		private sealed class ProfileRow
		{
			public ModSwitch.Profile Profile;

			public GameObject Root;

			public Text Info;

			public Button Load;

			public Button Overwrite;

			public Button Delete;

			public string Pending = "";

			public float PendingUntil;
		}

		private enum EditorKind
		{
			Toggle,
			Cycle,
			Key,
			Number,
			Text,
			ReadOnly
		}

		public const string SharedSlot = "GC.Options.Registry.v2";

		public const string ButtonName = "GC_OptionButton_v2";

		private static readonly Color OnColor = new Color(0.45f, 0.95f, 0.45f);

		private static readonly Color OffColor = new Color(1f, 0.45f, 0.4f);

		private static readonly Color MutedColor = new Color(0.78f, 0.72f, 0.62f);

		private static readonly Color ValueColor = new Color(1f, 0.85f, 0.55f);

		private static readonly Color LockedColor = new Color(0.6f, 0.58f, 0.55f);

		private static readonly KeyCode[] Modifiers;

		private static KeyCode[]? allKeys;

		private static MethodInfo? syncMethod;

		private readonly ManualLogSource log;

		private readonly Func<string, string> ui;

		private readonly bool canHost;

		private readonly List<object> registry;

		private readonly List<Dictionary<string, object>> ownSections = new List<Dictionary<string, object>>();

		private readonly List<Row> rows = new List<Row>();

		private readonly List<Block> sections = new List<Block>();

		private GameObject? window;

		private RectTransform? content;

		private Toggle? showServer;

		private static bool serverRulesShown;

		private InputField? searchField;

		private string query = "";

		private string pendingQuery = "";

		private float queryAt = -1f;

		private bool focusSearch;

		private InputField? typingField;

		private int typingFrame = -10;

		private Vector2 builtSize;

		private int builtForeign;

		private bool wide;

		private int closedFrame = -10;

		private int pendingUnblocks;

		private GameObject? emptyHint;

		private Text? emptyLabel;

		private Text? hintLabel;

		private Button? menuButton;

		private int builtShape = -1;

		private float nextRefresh;

		private Row? capturing;

		private KeyCode capturedModifier;

		private bool openedFromPause;

		private int captureFrame = -1;

		private string lastError = "";

		private const float WindowMargin = 40f;

		private const float MaxWindowWidth = 1800f;

		private const float WideWidth = 1400f;

		private const float TopBarHeight = 92f;

		private const float SearchWidth = 420f;

		private const float NameWidth = 340f;

		private static readonly Color ErrorColor;

		private Button? mainMenuButton;

		private static readonly Vector3[] MenuCorners;

		private int fitButtons = -1;

		private int fitHeight;

		private float nextFit;

		private static readonly Color SubHeaderColor;

		private static readonly Color SectionColor;

		private readonly List<ForeignMod> foreignMods = new List<ForeignMod>();

		private GameObject? foreignHeader;

		private static readonly HashSet<string> ExpandedMods;

		private const string VPlusGuid = "org.bepinex.plugins.valheim_plus";

		private static readonly Dictionary<Type, FieldInfo?> LocalBaseFields;

		private readonly HashSet<string> searchClosed = new HashSet<string>(StringComparer.Ordinal);

		private const int AutoOpenLimit = 6;

		private const int DeepSearchLength = 3;

		private const float TabWidth = 190f;

		private static readonly Color GoodColor;

		private static readonly Color WarnColor;

		private static View lastView;

		private View view;

		private RectTransform? innerRect;

		private readonly List<(View View, Text? Label)> tabs = new List<(View, Text)>();

		private GameObject? settingsArea;

		private GameObject? settingsTools;

		private GameObject? modsArea;

		private GameObject? modsTools;

		private RectTransform? modsContent;

		private GameObject? modsNoPatcher;

		private InputField? modsSearch;

		private string modsQuery = "";

		private Text? modsStatus;

		private string modsMessage = "";

		private readonly List<ModRow> modRows = new List<ModRow>();

		private GameObject? profilesArea;

		private GameObject? profilesTools;

		private RectTransform? profilesContent;

		private GameObject? profilesEmpty;

		private InputField? profileName;

		private Text? profilesStatus;

		private Text? profileSaveLabel;

		private string profilesMessage = "";

		private string savePending = "";

		private float savePendingUntil;

		private readonly List<ProfileRow> profileRows = new List<ProfileRow>();

		private bool pausedByKey;

		private static readonly Dictionary<ConfigEntryBase, (bool Has, double Min, double Max)> Ranges;

		public static bool HoldsInput
		{
			get
			{
				if (KernPlugin.Menu != null)
				{
					if (!KernPlugin.Menu.IsOpen)
					{
						return Time.frameCount <= KernPlugin.Menu.closedFrame + 1;
					}
					return true;
				}
				return false;
			}
		}

		public bool IsOpen
		{
			get
			{
				if ((Object)(object)window != (Object)null)
				{
					return window.activeSelf;
				}
				return false;
			}
		}

		public static bool CanChangeServer
		{
			get
			{
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					return false;
				}
				if (ZNet.instance.IsServer())
				{
					return true;
				}
				if (SynchronizationManager.Instance != null)
				{
					return SynchronizationManager.Instance.PlayerIsAdmin;
				}
				return false;
			}
		}

		public event Action? Closed;

		public GcMenu(ManualLogSource log, Func<string, string> ui, bool canHost = true)
		{
			this.log = log;
			this.ui = ui;
			this.canHost = canHost;
			registry = SharedRegistry();
		}

		public static Func<string, string> UiText(string ownPrefix)
		{
			return delegate(string name)
			{
				if (ownPrefix.Length > 0)
				{
					string text = GcLoc.Get(ownPrefix + name);
					if (text != ownPrefix + name)
					{
						return text;
					}
				}
				return GcLoc.Get("gco_" + name);
			};
		}

		public static bool CanChangeServerSetting(string guid)
		{
			if (CanChangeServer)
			{
				return ModOnServer(guid);
			}
			return false;
		}

		private static bool ModOnServer(string guid)
		{
			try
			{
				return guid.Length == 0 || ModCompatibility.IsModuleOnServer(guid);
			}
			catch
			{
				return false;
			}
		}

		private static List<object> SharedRegistry()
		{
			AppDomain currentDomain = AppDomain.CurrentDomain;
			lock (typeof(object))
			{
				List<object> list = currentDomain.GetData("GC.Options.Registry.v2") as List<object>;
				if (list == null)
				{
					list = new List<object>();
					currentDomain.SetData("GC.Options.Registry.v2", list);
				}
				return list;
			}
		}

		public GcMenuSection Section(string id, int order, Func<string, string> text, string guid)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>
			{
				["id"] = id,
				["order"] = order,
				["guid"] = guid,
				["title"] = (Func<string>)(() => text("title")),
				["groups"] = new List<object>()
			};
			object value;
			lock (registry)
			{
				registry.RemoveAll((object o) => o is Dictionary<string, object> dictionary2 && dictionary2.TryGetValue("id", out value) && value is string text2 && text2 == id);
				registry.Add(dictionary);
			}
			ownSections.RemoveAll((Dictionary<string, object> d) => d.TryGetValue("id", out value) && value is string text2 && text2 == id);
			ownSections.Add(dictionary);
			return new GcMenuSection(dictionary, text);
		}

		public void LogBlocked()
		{
			foreach (Dictionary<string, object> ownSection in ownSections)
			{
				foreach (Dictionary<string, object> item in Children(ownSection, "groups"))
				{
					foreach (Dictionary<string, object> item2 in Children(item, "items"))
					{
						if (item2.TryGetValue("blocked", out var value) && value is Func<bool> f && Call(f))
						{
							log.LogWarning((object)("Alte Einzelmod " + Str(item2, "oldMod") + " ist noch installiert. Die Funktion '" + Str(item2, "key") + "' bleibt aus, bis die alte Mod entfernt ist."));
						}
					}
				}
			}
		}

		private static List<Dictionary<string, object>> Children(Dictionary<string, object> data, string key)
		{
			if (data.TryGetValue(key, out object value) && value is List<object> list)
			{
				lock (list)
				{
					return list.OfType<Dictionary<string, object>>().ToList();
				}
			}
			return new List<Dictionary<string, object>>();
		}

		private static string Str(Dictionary<string, object> data, string key)
		{
			if (!data.TryGetValue(key, out object value) || !(value is string result))
			{
				return "";
			}
			return result;
		}

		private static int Int(Dictionary<string, object> data, string key, int fallback)
		{
			if (data.TryGetValue(key, out object value) && value is int)
			{
				return (int)value;
			}
			return fallback;
		}

		private static string TextOf(Dictionary<string, object> data, string key)
		{
			try
			{
				object value;
				return (data.TryGetValue(key, out value) && value is Func<string> func) ? (func() ?? "") : "";
			}
			catch
			{
				return "";
			}
		}

		private static bool Call(Func<bool> f)
		{
			try
			{
				return f();
			}
			catch
			{
				return false;
			}
		}

		private List<Dictionary<string, object>> Sections()
		{
			lock (registry)
			{
				return (from s in registry.OfType<Dictionary<string, object>>()
					orderby Int(s, "order", 100)
					select s).ToList();
			}
		}

		private void LogError(string where, Exception e)
		{
			string text = where + ": " + e.Message;
			if (text != lastError)
			{
				lastError = text;
				log.LogError((object)$"Menü GC Option, {text}\n{e}");
			}
		}

		public void Update()
		{
			if (Gc.IsHeadless || !canHost)
			{
				return;
			}
			while (pendingUnblocks > 0 && Time.frameCount > closedFrame)
			{
				pendingUnblocks--;
				GUIManager.BlockInput(false);
			}
			try
			{
				EnsurePauseButton();
				EnsureMainMenuButton();
				FitMainMenu();
				if (!IsOpen)
				{
					return;
				}
				if (capturing != null)
				{
					Capture();
					return;
				}
				if (focusSearch && (Object)(object)searchField != (Object)null)
				{
					focusSearch = false;
					((Selectable)searchField).Select();
					searchField.ActivateInputField();
				}
				InputField val = Typing();
				if ((Object)(object)val != (Object)null)
				{
					typingField = val;
					typingFrame = Time.frameCount;
				}
				if (Input.GetKeyDown((KeyCode)27) && (Time.frameCount - typingFrame > 1 || !((Object)(object)typingField != (Object)null) || !((Object)(object)typingField != (Object)(object)searchField) || !((Object)(object)typingField != (Object)(object)modsSearch)))
				{
					Hide();
					return;
				}
				if (queryAt >= 0f && Time.unscaledTime >= queryAt)
				{
					queryAt = -1f;
					if (pendingQuery != query)
					{
						query = pendingQuery;
						searchClosed.Clear();
						Refresh();
					}
				}
				if (Time.unscaledTime >= nextRefresh)
				{
					nextRefresh = Time.unscaledTime + 0.5f;
					if (Shape() != builtShape)
					{
						RebuildOpen();
					}
					else
					{
						Refresh();
					}
				}
			}
			catch (Exception e)
			{
				LogError("Update", e);
			}
		}

		public bool Show()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen)
			{
				return true;
			}
			if (Gc.IsHeadless || GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return false;
			}
			capturing = null;
			capturedModifier = (KeyCode)0;
			try
			{
				if ((Object)(object)window != (Object)null && (WindowSize() != builtSize || ForeignCount() != builtForeign))
				{
					Object.Destroy((Object)(object)window);
					window = null;
					builtShape = -1;
				}
				Build();
				ClearSearch();
				SwitchView(lastView);
				focusSearch = view == View.Settings;
			}
			catch (Exception e)
			{
				LogError("Aufbau", e);
				if ((Object)(object)window != (Object)null)
				{
					Object.Destroy((Object)(object)window);
				}
				window = null;
				builtShape = -1;
				return false;
			}
			window.SetActive(true);
			window.transform.SetAsLastSibling();
			GUIManager.BlockInput(true);
			return true;
		}

		public void Hide()
		{
			capturing = null;
			if (IsOpen)
			{
				window.SetActive(false);
				closedFrame = Time.frameCount;
				pendingUnblocks++;
				try
				{
					this.Closed?.Invoke();
				}
				catch (Exception e)
				{
					LogError("Schließen", e);
				}
				if (openedFromPause)
				{
					if ((Object)(object)Menu.instance != (Object)null)
					{
						Menu.instance.Show();
					}
					else
					{
						Game.Unpause();
					}
				}
				else if (pausedByKey)
				{
					Game.Unpause();
				}
			}
			openedFromPause = false;
			pausedByKey = false;
		}

		private int Shape()
		{
			return Sections().Sum((Dictionary<string, object> s) => 1000 + Children(s, "groups").Sum((Dictionary<string, object> g) => 1 + Children(g, "items").Count));
		}

		private void Build()
		{
			//IL_006e: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			int num = Shape();
			if ((Object)(object)window != (Object)null && num == builtShape)
			{
				return;
			}
			if ((Object)(object)window != (Object)null)
			{
				Object.Destroy((Object)(object)window);
				window = null;
			}
			builtShape = -1;
			rows.Clear();
			sections.Clear();
			foreignMods.Clear();
			foreignHeader = null;
			Vector2 val = (builtSize = WindowSize());
			builtForeign = ForeignCount();
			wide = val.x >= 1400f;
			window = GcUi.CreateWindow("GC_Option_Window", val.x, val.y, out Text header, out RectTransform inner);
			header.text = ui("title");
			innerRect = inner;
			modsArea = (modsTools = (profilesArea = (profilesTools = null)));
			modsContent = (profilesContent = null);
			modRows.Clear();
			profileRows.Clear();
			BuildTopBar(inner);
			BuildModsTools(inner);
			BuildProfilesTools(inner);
			GameObject val2 = new GameObject("ScrollArea", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent((Transform)(object)inner, false);
			RectTransform val3 = (RectTransform)val2.transform;
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.offsetMin = Vector2.zero;
			val3.offsetMax = new Vector2(0f, -92f);
			settingsArea = val2;
			content = GcUi.CreateScroll((Transform)(object)val3, val.x - 88f, val.y - 172f - 92f);
			emptyHint = HintRow((Transform)(object)content, ui("nothing"), out Text label);
			emptyLabel = label;
			HashSet<ConfigEntryBase> hashSet = new HashSet<ConfigEntryBase>();
			foreach (Dictionary<string, object> item in Sections())
			{
				string text = Str(item, "guid");
				string text2 = TextOf(item, "title");
				Block block = new Block
				{
					Header = Header((Transform)(object)content, text2, 28, GUIManager.Instance.ValheimOrange, norse: true, 46f)
				};
				sections.Add(block);
				foreach (Dictionary<string, object> item2 in Children(item, "groups"))
				{
					List<Dictionary<string, object>> list = Children(item2, "items");
					if (list.Count == 0)
					{
						continue;
					}
					string text3 = TextOf(item2, "title");
					Block block2 = new Block
					{
						Header = Header((Transform)(object)content, text3, 22, new Color(1f, 0.75f, 0.4f), norse: false, 34f)
					};
					block.Children.Add(block2);
					string text4 = Str(item2, "guid");
					object value;
					Func<bool> allowed = (item2.TryGetValue("allowed", out value) ? (value as Func<bool>) : null);
					Row row = null;
					foreach (Dictionary<string, object> item3 in list)
					{
						Row row2 = CreateRow(item3, (text4.Length > 0) ? text4 : text, (Transform)(object)content);
						if (row2 != null)
						{
							hashSet.Add(row2.Entry);
							row2.Allowed = allowed;
							row2.Search = SearchText(TextOf(item3, "name"), TextOf(item3, "desc"), text3, text2, row2.Entry.Definition.Key, row2.Guid, ModuleName(row2.Guid));
							if (row2.Level == 0)
							{
								row = row2;
							}
							else if (row != null)
							{
								row2.Parent = row;
								row.Subs.Add(row2);
							}
							rows.Add(row2);
							block2.Rows.Add(row2);
						}
					}
				}
			}
			BuildForeign(hashSet);
			hintLabel = GcUi.CreateLabel(window.transform, ui("hint_config"), new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(44f, 64f), new Vector2(-44f, 86f), 15, (TextAnchor)4, MutedColor);
			((Graphic)hintLabel).raycastTarget = false;
			GcUi.CreateButton(window.transform, ui("close"), new Vector2(0.5f, 0f), new Vector2(0f, 38f), 200f, 42f, Hide);
			builtShape = num;
		}

		private static string ModuleName(string guid)
		{
			return GcKern.Modules.FirstOrDefault((GcModule m) => m.Info.Guid == guid)?.Info.Name ?? "";
		}

		private static Vector2 WindowSize()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			? val2;
			if ((Object)(object)GUIManager.CustomGUIFront != (Object)null)
			{
				Transform transform = GUIManager.CustomGUIFront.transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val != null)
				{
					Rect rect = val.rect;
					if (((Rect)(ref rect)).width > 0f)
					{
						rect = val.rect;
						val2 = ((Rect)(ref rect)).size;
						goto IL_0054;
					}
				}
			}
			val2 = new Vector2(1920f, 1080f);
			goto IL_0054;
			IL_0054:
			Vector2 val3 = (Vector2)val2;
			float num = Mathf.Clamp(val3.x - 80f, Mathf.Min(900f, val3.x), 1800f);
			float num2 = Mathf.Max(val3.y - 80f, Mathf.Min(640f, val3.y));
			return new Vector2(Mathf.Round(num), Mathf.Round(num2));
		}

		private void BuildTopBar(RectTransform inner)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0039: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			BuildTabs(inner);
			settingsTools = ToolRow(inner, "SettingsTools");
			RectTransform val = (RectTransform)settingsTools.transform;
			GameObject val2 = GUIManager.Instance.CreateInputField((Transform)(object)val, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, (ContentType)0, ui("search"), 18, 420f, 34f);
			((Object)val2).name = "Search";
			RectTransform val3 = (RectTransform)val2.transform;
			val3.pivot = new Vector2(0f, 1f);
			val3.anchoredPosition = new Vector2(16f, 0f);
			searchField = val2.GetComponent<InputField>();
			searchField.lineType = (LineType)0;
			((UnityEvent<string>)(object)searchField.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
			{
				pendingQuery = NormalizeSearch(text);
				queryAt = Time.unscaledTime + 0.2f;
			});
			GameObject val4 = GUIManager.Instance.CreateToggle((Transform)(object)val, 28f, 28f);
			((Object)val4).name = "ShowServer";
			RectTransform val5 = (RectTransform)val4.transform;
			((Transform)val5).SetParent((Transform)(object)val, false);
			((Transform)val5).localScale = Vector3.one;
			Vector2 val6 = default(Vector2);
			((Vector2)(ref val6))..ctor(0f, 1f);
			val5.anchorMax = val6;
			val5.anchorMin = val6;
			val5.pivot = new Vector2(0f, 1f);
			val5.anchoredPosition = new Vector2(468f, -3f);
			Transform obj = val4.transform.Find("Background");
			RectTransform val7 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (val7 != null)
			{
				Vector2 val8 = default(Vector2);
				((Vector2)(ref val8))..ctor(0.5f, 0.5f);
				val7.pivot = val8;
				val6 = (val7.anchorMin = (val7.anchorMax = val8));
				val7.anchoredPosition = Vector2.zero;
			}
			Transform obj2 = val4.transform.Find("Label");
			Text val11 = ((obj2 != null) ? ((Component)obj2).GetComponent<Text>() : null);
			if ((Object)(object)val11 != (Object)null)
			{
				val11.text = ui("show_server");
				val11.font = GUIManager.Instance.AveriaSerifBold;
				val11.fontSize = 18;
				((Graphic)val11).color = MutedColor;
				val11.alignment = (TextAnchor)3;
				val11.horizontalOverflow = (HorizontalWrapMode)1;
				RectTransform rectTransform = ((Graphic)val11).rectTransform;
				rectTransform.anchorMin = new Vector2(1f, 0f);
				rectTransform.anchorMax = new Vector2(1f, 1f);
				rectTransform.pivot = new Vector2(0f, 0.5f);
				rectTransform.offsetMin = new Vector2(12f, 0f);
				rectTransform.offsetMax = new Vector2(612f, 0f);
				((Shadow)((Component)val11).gameObject.AddComponent<Outline>()).effectColor = Color.black;
			}
			showServer = val4.GetComponent<Toggle>();
			showServer.isOn = serverRulesShown;
			((UnityEvent<bool>)(object)showServer.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on)
			{
				serverRulesShown = on;
				Refresh();
			});
		}

		private void ClearSearch()
		{
			query = (pendingQuery = "");
			queryAt = -1f;
			searchClosed.Clear();
			if ((Object)(object)searchField != (Object)null && searchField.text.Length > 0)
			{
				searchField.text = "";
			}
			queryAt = -1f;
		}

		private static string NormalizeSearch(string text)
		{
			return text.Trim().ToLowerInvariant();
		}

		private static string SearchText(params string[] parts)
		{
			return string.Join(" ", parts).ToLowerInvariant();
		}

		private static InputField? Typing()
		{
			GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			InputField val2 = default(InputField);
			if (!((Object)(object)val != (Object)null) || !val.TryGetComponent<InputField>(ref val2) || !val2.isFocused)
			{
				return null;
			}
			return val2;
		}

		private GameObject Header(Transform parent, string text, int size, Color color, bool norse, float height)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			GameObject val = new GameObject("Header", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.minHeight = height;
			component.preferredHeight = height;
			((Graphic)GcUi.CreateLabel(val.transform, text, Vector2.zero, Vector2.one, new Vector2(4f, 0f), Vector2.zero, size, (TextAnchor)6, color, norse)).raycastTarget = false;
			return val;
		}

		private GameObject HintRow(Transform parent, string text, out Text label)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Hint", new Type[2]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup)
			});
			val.transform.SetParent(parent, false);
			VerticalLayoutGroup component = val.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((LayoutGroup)component).padding = new RectOffset(8, 8, 16, 16);
			label = FlowText(val.transform, text, 18, MutedColor);
			return val;
		}

		private static Text FlowText(Transform parent, string text, int size, Color color)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			Text component = instance.CreateText(text, parent, new Vector2(0f, 1f), new Vector2(1f, 1f), Vector2.zero, instance.AveriaSerifBold, size, color, true, Color.black, 100f, 20f, false).GetComponent<Text>();
			component.alignment = (TextAnchor)0;
			component.horizontalOverflow = (HorizontalWrapMode)0;
			component.verticalOverflow = (VerticalWrapMode)1;
			component.supportRichText = true;
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private Row? CreateRow(Dictionary<string, object> item, string guid, Transform parent, ForeignEntry? foreign = null)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Expected O, but got Unknown
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Expected O, but got Unknown
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			if (item.TryGetValue("entry", out object value))
			{
				ConfigEntryBase val = (ConfigEntryBase)((value is ConfigEntryBase) ? value : null);
				if (val != null)
				{
					object[] choices = Choices(val);
					EditorKind editorKind = KindOf(val.SettingType, choices);
					int num = ((Int(item, "level", 0) > 0) ? 1 : 0);
					GameObject val2 = new GameObject("Row", new Type[3]
					{
						typeof(RectTransform),
						typeof(HorizontalLayoutGroup),
						typeof(LayoutElement)
					});
					val2.transform.SetParent(parent, false);
					HorizontalLayoutGroup component = val2.GetComponent<HorizontalLayoutGroup>();
					((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
					((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
					((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
					((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
					((LayoutGroup)component).childAlignment = (TextAnchor)3;
					((HorizontalOrVerticalLayoutGroup)component).spacing = 12f;
					((LayoutGroup)component).padding = new RectOffset(10 + num * 36, 4, (num == 0) ? 8 : 4, (num == 0) ? 8 : 4);
					

patchers/GC_ModSchalter_Client.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("Gorduan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+c9d5288b96ac31e780ee94b8f27fd48c2d248dff")]
[assembly: AssemblyProduct("GC_ModSchalter")]
[assembly: AssemblyTitle("GC_ModSchalter_Client")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GC.Patcher
{
	public static class ModSchalter
	{
		public const string KernGuid = "gorduan.gc.kern";

		private static readonly string[] OldPackages = new string[3] { "gorduan.gc_server", "gorduan.gc_client", "gorduan.valheimplusplus" };

		public const string DataInstalled = "GC.ModSchalter.Installed";

		public const string DataBest = "GC.ModSchalter.Best";

		public const string DataAll = "GC.ModSchalter.All";

		public const string DataSkipped = "GC.ModSchalter.Skipped";

		public const string DataProtected = "GC.ModSchalter.Protected";

		public const string DataFile = "GC.ModSchalter.File";

		private static readonly ManualLogSource Log = Logger.CreateLogSource("GC_ModSchalter");

		public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>();

		public static string ListFile => Path.Combine(Path.Combine(Paths.ConfigPath, "GC_Kern"), "aus.txt");

		private static Version Own => typeof(ModSchalter).Assembly.GetName().Version;

		public static void Patch(AssemblyDefinition assembly)
		{
		}

		public static void Initialize()
		{
			AppDomain currentDomain = AppDomain.CurrentDomain;
			if (!(currentDomain.GetData("GC.ModSchalter.Best") is Version version) || Own > version)
			{
				currentDomain.SetData("GC.ModSchalter.Best", Own);
			}
		}

		public static void Finish()
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			AppDomain currentDomain = AppDomain.CurrentDomain;
			object data = currentDomain.GetData("GC.ModSchalter.Installed");
			bool flag = default(bool);
			int num;
			if (data is bool)
			{
				flag = (bool)data;
				num = 1;
			}
			else
			{
				num = 0;
			}
			if (((uint)num & (flag ? 1u : 0u)) != 0 || (currentDomain.GetData("GC.ModSchalter.Best") is Version version && Own < version))
			{
				return;
			}
			currentDomain.SetData("GC.ModSchalter.Installed", true);
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(TypeLoader), "FindPluginTypes", (Type[])null, (Type[])null).MakeGenericMethod(typeof(PluginInfo));
				new Harmony("gorduan.gc.modschalter").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ModSchalter), "FindPluginTypesPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				currentDomain.SetData("GC.ModSchalter.File", ListFile);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Konnte sich nicht in BepInEx einhängen, alle Mods laden: {arg}");
			}
		}

		private static void FindPluginTypesPostfix(string cacheName, Dictionary<string, List<PluginInfo>> __result)
		{
			if (cacheName != "chainloader" || __result == null)
			{
				return;
			}
			try
			{
				List<PluginInfo> list = __result.Values.SelectMany((List<PluginInfo> result) => result).ToList();
				AppDomain.CurrentDomain.SetData("GC.ModSchalter.All", list);
				HashSet<string> hashSet = ReadList(ListFile);
				if (hashSet.Count == 0)
				{
					return;
				}
				if (!list.Any((PluginInfo info) => string.Equals(info.Metadata.GUID, "gorduan.gc.kern", StringComparison.OrdinalIgnoreCase)))
				{
					Log.LogWarning((object)"GC_Kern fehlt: aus.txt gilt nicht, alle Mods laden.");
					return;
				}
				if (list.Any((PluginInfo info) => OldPackages.Contains<string>(info.Metadata.GUID, StringComparer.OrdinalIgnoreCase)))
				{
					Log.LogWarning((object)"Ein altes GC-Sammelpaket liegt noch im Ordner, GC_Kern startet dann nicht: aus.txt gilt nicht, alle Mods laden.");
					return;
				}
				HashSet<string> hashSet2 = Protected(list);
				List<PluginInfo> list2 = new List<PluginInfo>();
				PropertyInfo propertyInfo = AccessTools.Property(typeof(PluginInfo), "Location");
				foreach (KeyValuePair<string, List<PluginInfo>> item in __result.ToList())
				{
					foreach (PluginInfo item2 in item.Value.ToList())
					{
						if (hashSet.Contains(item2.Metadata.GUID) && !hashSet2.Contains(item2.Metadata.GUID))
						{
							propertyInfo?.SetValue(item2, item.Key, null);
							item.Value.Remove(item2);
							list2.Add(item2);
							Log.LogMessage((object)$"Im Menü GC Option ausgeschaltet, wird nicht geladen: [{item2}]");
						}
					}
					if (item.Value.Count == 0)
					{
						__result.Remove(item.Key);
					}
				}
				AppDomain.CurrentDomain.SetData("GC.ModSchalter.Skipped", list2);
				AppDomain.CurrentDomain.SetData("GC.ModSchalter.Protected", hashSet2.ToArray());
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Ausgeschaltete Mods nicht gefiltert, alle Mods laden: {arg}");
			}
		}

		private static HashSet<string> Protected(List<PluginInfo> all)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, PluginInfo> dictionary = new Dictionary<string, PluginInfo>(StringComparer.OrdinalIgnoreCase);
			foreach (PluginInfo item in all)
			{
				dictionary[item.Metadata.GUID] = item;
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "gorduan.gc.kern" };
			Queue<string> queue = new Queue<string>(hashSet);
			while (queue.Count > 0)
			{
				if (!dictionary.TryGetValue(queue.Dequeue(), out var value))
				{
					continue;
				}
				foreach (BepInDependency dependency in value.Dependencies)
				{
					if ((dependency.Flags & 1) != 0 && hashSet.Add(dependency.DependencyGUID))
					{
						queue.Enqueue(dependency.DependencyGUID);
					}
				}
			}
			return hashSet;
		}

		public static HashSet<string> ReadList(string file)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			if (!File.Exists(file))
			{
				return hashSet;
			}
			string[] array = File.ReadAllLines(file);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0 && !text.StartsWith("#", StringComparison.Ordinal))
				{
					hashSet.Add(text);
				}
			}
			return hashSet;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}