Decompiled source of ValheimVanillaPlus v1.1.1

ValheimVanillaPlus.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GUIFramework;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ValheimVanillaPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+88e31bfbf99a2ba0d56ab24f1b430dab3fb5f139")]
[assembly: AssemblyProduct("ValheimVanillaPlus")]
[assembly: AssemblyTitle("ValheimVanillaPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
[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;
		}
	}
}
namespace ValheimVanillaPlus
{
	internal static class BatchTransfer
	{
		private static readonly FieldInfo CurrentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

		private static readonly FieldInfo DragGo = AccessTools.Field(typeof(InventoryGui), "m_dragGo");

		private static readonly FieldInfo MoveEffects = AccessTools.Field(typeof(InventoryGui), "m_moveItemEffects");

		internal static bool Handle(InventoryGui gui, InventoryGrid grid, ItemData item, bool drop)
		{
			if (!VanillaPlusPlugin.BatchTransferOn)
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || item == null || item.m_shared.m_questItem)
			{
				return false;
			}
			object? obj = DragGo?.GetValue(gui);
			if ((Object)((obj is GameObject) ? obj : null) != (Object)null)
			{
				return false;
			}
			Inventory inventory = grid.GetInventory();
			object? obj2 = CurrentContainer?.GetValue(gui);
			Container val = (Container)((obj2 is Container) ? obj2 : null);
			if (!drop && (Object)(object)val == (Object)null)
			{
				return false;
			}
			List<ItemData> list = SameItems(localPlayer, inventory, item);
			if (drop)
			{
				int num = 0;
				foreach (ItemData item2 in list)
				{
					if (((Humanoid)localPlayer).DropItem(inventory, item2, item2.m_stack))
					{
						num++;
					}
				}
				Done(gui, localPlayer, num, $"Dropped {num} stack{S(num)} of {Name(item)}");
				return true;
			}
			Inventory val2 = ((inventory == val.GetInventory()) ? ((Humanoid)localPlayer).GetInventory() : val.GetInventory());
			int num2 = 0;
			foreach (ItemData item3 in list)
			{
				int stack = item3.m_stack;
				val2.MoveItemToThis(inventory, item3);
				if (!inventory.ContainsItem(item3) || item3.m_stack < stack)
				{
					num2++;
				}
			}
			Done(gui, localPlayer, num2, (num2 > 0) ? $"Moved {num2} stack{S(num2)} of {Name(item)}" : "No room");
			return true;
		}

		private static List<ItemData> SameItems(Player p, Inventory inv, ItemData clicked)
		{
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData allItem in inv.GetAllItems())
			{
				if (!(allItem.m_shared.m_name != clicked.m_shared.m_name) && !allItem.m_shared.m_questItem && (!allItem.m_equipped || allItem == clicked))
				{
					list.Add(allItem);
				}
			}
			if (clicked.m_equipped)
			{
				((Humanoid)p).RemoveEquipAction(clicked);
				((Humanoid)p).UnequipItem(clicked, true);
			}
			return list;
		}

		private static void Done(InventoryGui gui, Player p, int count, string msg)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			if (count > 0)
			{
				object? obj = MoveEffects?.GetValue(gui);
				EffectList val = (EffectList)((obj is EffectList) ? obj : null);
				if (val != null)
				{
					val.Create(((Component)gui).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
			((Character)p).Message((MessageType)1, msg, 0, (Sprite)null, false);
		}

		private static string Name(ItemData item)
		{
			return Localization.instance.Localize(item.m_shared.m_name);
		}

		private static string S(int n)
		{
			if (n != 1)
			{
				return "s";
			}
			return "";
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
	internal static class BatchTransfer_Click
	{
		private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod)
		{
			//IL_0042: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if (ZInput.IsExclusiveGamepadActive())
			{
				return true;
			}
			if ((Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) && Input.GetKey(VanillaPlusPlugin.BatchMoveKey.Value))
			{
				return !BatchTransfer.Handle(__instance, grid, item, drop: true);
			}
			if ((int)mod == 0 && Input.GetKey(VanillaPlusPlugin.BatchMoveKey.Value))
			{
				return !BatchTransfer.Handle(__instance, grid, item, drop: false);
			}
			return true;
		}
	}
	internal static class ChestTracker
	{
		internal enum Kind
		{
			Loot,
			PlayerBuilt,
			Tombstone
		}

		internal struct Entry
		{
			public Kind Kind;

			public ZNetView View;
		}

		private static readonly Dictionary<Container, Entry> Known = new Dictionary<Container, Entry>();

		private static readonly List<Container> Dead = new List<Container>();

		private static bool _scanned;

		private static int _sincePrune;

		internal static void Register(Container c)
		{
			Kind kind = (((Object)(object)((Component)c).GetComponent<TombStone>() != (Object)null) ? Kind.Tombstone : (((Object)(object)((Component)c).GetComponentInParent<Piece>() != (Object)null) ? Kind.PlayerBuilt : Kind.Loot));
			Known[c] = new Entry
			{
				Kind = kind,
				View = ((Component)c).GetComponentInParent<ZNetView>()
			};
			if (++_sincePrune >= 200)
			{
				Prune();
			}
		}

		internal static Dictionary<Container, Entry> All()
		{
			if (!_scanned)
			{
				_scanned = true;
				Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
				foreach (Container val in array)
				{
					if (!Known.ContainsKey(val))
					{
						Register(val);
					}
				}
			}
			return Known;
		}

		private static void Prune()
		{
			_sincePrune = 0;
			foreach (Container key in Known.Keys)
			{
				if ((Object)(object)key == (Object)null)
				{
					Dead.Add(key);
				}
			}
			foreach (Container item in Dead)
			{
				Known.Remove(item);
			}
			Dead.Clear();
		}
	}
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ChestTracker_Register
	{
		private static void Postfix(Container __instance)
		{
			ChestTracker.Register(__instance);
		}
	}
	internal static class Storage
	{
		private static readonly MethodInfo CheckAccess = AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null);

		private static readonly FieldInfo CurrentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

		private static readonly List<Container> Cache = new List<Container>();

		private static float _cacheUntil;

		private static readonly HashSet<ItemType> Weapons = new HashSet<ItemType>
		{
			(ItemType)3,
			(ItemType)14,
			(ItemType)22,
			(ItemType)4,
			(ItemType)5,
			(ItemType)20
		};

		private static readonly HashSet<ItemType> Armor = new HashSet<ItemType>
		{
			(ItemType)6,
			(ItemType)7,
			(ItemType)11,
			(ItemType)12,
			(ItemType)17,
			(ItemType)18,
			(ItemType)24
		};

		private static readonly HashSet<ItemType> Tools = new HashSet<ItemType>
		{
			(ItemType)19,
			(ItemType)15
		};

		private static readonly HashSet<ItemType> Ammo = new HashSet<ItemType>
		{
			(ItemType)9,
			(ItemType)23
		};

		public static List<Container> Chests(Player p)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < _cacheUntil)
			{
				Cache.RemoveAll((Container c) => (Object)(object)c == (Object)null);
				return Cache;
			}
			_cacheUntil = Time.unscaledTime + 0.5f;
			Cache.Clear();
			if ((Object)(object)p == (Object)null)
			{
				return Cache;
			}
			Vector3 pos = ((Component)p).transform.position;
			float value = VanillaPlusPlugin.StorageRange.Value;
			long playerID = p.GetPlayerID();
			Container val = (Container)(((Object)(object)InventoryGui.instance != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			foreach (KeyValuePair<Container, ChestTracker.Entry> item in ChestTracker.All())
			{
				Container key = item.Key;
				if (!((Object)(object)key == (Object)null) && item.Value.Kind == ChestTracker.Kind.PlayerBuilt)
				{
					ZNetView view = item.Value.View;
					if (!((Object)(object)view == (Object)null) && view.IsValid() && !(Vector3.Distance(pos, ((Component)key).transform.position) > value) && (!key.IsInUse() || !((Object)(object)key != (Object)(object)val)) && (!key.m_checkGuardStone || PrivateArea.CheckAccess(((Component)key).transform.position, 0f, false, false)) && (!(CheckAccess != null) || (bool)CheckAccess.Invoke(key, new object[1] { playerID })))
					{
						Cache.Add(key);
					}
				}
			}
			Cache.Sort(delegate(Container a, Container b)
			{
				//IL_0006: 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_0016: 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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val2 = ((Component)a).transform.position - pos;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				val2 = ((Component)b).transform.position - pos;
				return sqrMagnitude.CompareTo(((Vector3)(ref val2)).sqrMagnitude);
			});
			return Cache;
		}

		public static void Invalidate()
		{
			_cacheUntil = 0f;
		}

		public static void Own(Container c)
		{
			ZNetView componentInParent = ((Component)c).GetComponentInParent<ZNetView>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.IsValid() && !componentInParent.IsOwner())
			{
				componentInParent.ClaimOwnership();
			}
		}

		public static string Key(ItemData it)
		{
			return $"{it.m_shared.m_name}|{it.m_quality}|{it.m_variant}";
		}

		public static int Move(Inventory from, Inventory to, ItemData item, int amount)
		{
			int num = 0;
			int num2 = 0;
			int x;
			int y;
			int room;
			while (amount > 0 && item.m_stack > 0 && from.ContainsItem(item) && num2++ < 64 && FindSlot(to, item, out x, out y, out room))
			{
				int num3 = Mathf.Min(amount, Mathf.Min(room, item.m_stack));
				int stack = item.m_stack;
				bool flag = num3 >= stack;
				to.MoveItemToThis(from, item, num3, x, y);
				int num4 = (flag ? stack : (stack - item.m_stack));
				if (num4 <= 0)
				{
					break;
				}
				num += num4;
				amount -= num4;
				if (flag)
				{
					break;
				}
			}
			return num;
		}

		private static bool FindSlot(Inventory inv, ItemData item, out int x, out int y, out int room)
		{
			int maxStackSize = item.m_shared.m_maxStackSize;
			if (maxStackSize > 1)
			{
				foreach (ItemData allItem in inv.GetAllItems())
				{
					if (allItem.m_shared.m_name == item.m_shared.m_name && allItem.m_quality == item.m_quality && allItem.m_variant == item.m_variant && allItem.m_stack < maxStackSize && allItem.m_worldLevel == item.m_worldLevel)
					{
						x = allItem.m_gridPos.x;
						y = allItem.m_gridPos.y;
						room = maxStackSize - allItem.m_stack;
						return true;
					}
				}
			}
			for (int i = 0; i < inv.GetHeight(); i++)
			{
				for (int j = 0; j < inv.GetWidth(); j++)
				{
					if (inv.GetItemAt(j, i) == null)
					{
						x = j;
						y = i;
						room = maxStackSize;
						return true;
					}
				}
			}
			x = (y = (room = 0));
			return false;
		}

		public static bool Kept(ItemData item)
		{
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			//IL_0080: 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_0099: Invalid comparison between Unknown and I4
			ItemType itemType = item.m_shared.m_itemType;
			if (VanillaPlusPlugin.StorageKeepArmor.Value && Armor.Contains(itemType))
			{
				return true;
			}
			if (VanillaPlusPlugin.StorageKeepWeapons.Value && Weapons.Contains(itemType))
			{
				return true;
			}
			if (VanillaPlusPlugin.StorageKeepTools.Value && Tools.Contains(itemType))
			{
				return true;
			}
			if (VanillaPlusPlugin.StorageKeepFood.Value && (int)itemType == 2)
			{
				return true;
			}
			if (VanillaPlusPlugin.StorageKeepAmmo.Value && Ammo.Contains(itemType))
			{
				return true;
			}
			if (VanillaPlusPlugin.StorageKeepTrophies.Value && (int)itemType == 13)
			{
				return true;
			}
			return NeverStored(item);
		}

		private static bool NeverStored(ItemData item)
		{
			string text = VanillaPlusPlugin.StorageNeverStore.Value ?? "";
			if (text.Trim().Length == 0)
			{
				return false;
			}
			string input = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : "");
			string input2 = Localization.instance.Localize(item.m_shared.m_name);
			string[] array = text.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length != 0)
				{
					Regex regex = new Regex("^" + Regex.Escape(text2).Replace("\\*", ".*") + "$", RegexOptions.IgnoreCase);
					if (regex.IsMatch(input) || regex.IsMatch(input2))
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	internal static class StorageWindow
	{
		private class Row
		{
			public string Key;

			public string Name;

			public ItemData Sample;

			public int Total;

			public int Where;

			public List<(Container c, ItemData item)> Sources = new List<(Container, ItemData)>();
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__Contents;
		}

		public static bool IsOpen;

		public static bool Typing;

		private const int WindowId = 31378;

		private const string SearchControl = "vanillaplus_storagesearch";

		private static Rect _rect = new Rect(600f, 80f, 600f, 640f);

		private static Vector2 _size = new Vector2(600f, 680f);

		private static readonly Vector2 MinSize = new Vector2(520f, 300f);

		private static bool _placed;

		private static bool _moved;

		private static Vector2 _scroll;

		private static string _search = "";

		private static int _page;

		private static int _category;

		private static int _sort;

		private static string _status = "";

		private static float _statusUntil;

		private static GUIStyle _rich;

		private static GUIStyle _count;

		private static GUISkin _styleSkin;

		private static readonly string[] Pages = new string[2] { "Chests (take)", "My inventory (store)" };

		private static readonly string[] Categories = new string[6] { "All", "Materials", "Food & meads", "Weapons & tools", "Armor", "Other" };

		private static readonly string[] Sorts = new string[2] { "Name", "Count" };

		public static void Toggle()
		{
			IsOpen = !IsOpen;
			if (IsOpen)
			{
				MenuWindow.IsOpen = false;
				Storage.Invalidate();
			}
		}

		public static void Draw()
		{
			//IL_0070: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Invalid comparison between Unknown and I4
			if (!IsOpen)
			{
				Typing = false;
				SavePosition();
				return;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null || !VanillaPlusPlugin.StorageOn)
			{
				IsOpen = false;
				return;
			}
			if (!_placed)
			{
				_placed = true;
				_size = new Vector2(Mathf.Max(MinSize.x, VanillaPlusPlugin.StorageWidth.Value), Mathf.Max(MinSize.y, VanillaPlusPlugin.StorageHeight.Value));
				((Rect)(ref _rect)).width = _size.x;
				((Rect)(ref _rect)).x = Mathf.Clamp(VanillaPlusPlugin.StorageX.Value, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _rect)).width));
				((Rect)(ref _rect)).y = Mathf.Clamp(VanillaPlusPlugin.StorageY.Value, 0f, Mathf.Max(0f, (float)Screen.height - 200f));
			}
			GUISkin skin = GUI.skin;
			GUISkin val = MenuTheme.Current(skin);
			if ((Object)(object)val != (Object)null)
			{
				GUI.skin = val;
			}
			if (_rich == null || (Object)(object)_styleSkin != (Object)(object)GUI.skin)
			{
				_styleSkin = GUI.skin;
				_rich = new GUIStyle(GUI.skin.label)
				{
					richText = true
				};
				_count = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)5,
					fontStyle = (FontStyle)1
				};
			}
			((Rect)(ref _rect)).width = _size.x;
			((Rect)(ref _rect)).height = Mathf.Min(_size.y, (float)Screen.height - ((Rect)(ref _rect)).y - 20f);
			Vector2 position = ((Rect)(ref _rect)).position;
			Rect rect = _rect;
			object obj = <>O.<0>__Contents;
			if (obj == null)
			{
				WindowFunction val2 = Contents;
				<>O.<0>__Contents = val2;
				obj = (object)val2;
			}
			_rect = GUILayout.Window(31378, rect, (WindowFunction)obj, "Storage — all nearby chests", Array.Empty<GUILayoutOption>());
			if (((Rect)(ref _rect)).position != position)
			{
				_moved = true;
			}
			if (_moved && (int)Event.current.rawType == 1)
			{
				SavePosition();
			}
			GUI.skin = skin;
		}

		private static void SavePosition()
		{
			if (_moved)
			{
				_moved = false;
				VanillaPlusPlugin.StorageX.Value = Mathf.Round(((Rect)(ref _rect)).x);
				VanillaPlusPlugin.StorageY.Value = Mathf.Round(((Rect)(ref _rect)).y);
			}
		}

		private static void Contents(int id)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Invalid comparison between Unknown and I4
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (WindowResize.Handle(31378, _rect, ref _size, MinSize, new Vector2((float)Screen.width - ((Rect)(ref _rect)).x - 4f, (float)Screen.height - ((Rect)(ref _rect)).y - 4f)))
			{
				VanillaPlusPlugin.StorageWidth.Value = Mathf.Round(_size.x);
				VanillaPlusPlugin.StorageHeight.Value = Mathf.Round(_size.y);
			}
			List<Container> list = Storage.Chests(localPlayer);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(string.Format("{0} chest{1} within", list.Count, (list.Count == 1) ? "" : "s"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			float num = GUILayout.HorizontalSlider(VanillaPlusPlugin.StorageRange.Value, 5f, 100f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
			num = Mathf.Round(num);
			if (!Mathf.Approximately(num, VanillaPlusPlugin.StorageRange.Value))
			{
				VanillaPlusPlugin.StorageRange.Value = num;
				Storage.Invalidate();
				RangePreview.Show(num);
			}
			GUILayout.Label($"{num:0} m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) });
			GUILayout.FlexibleSpace();
			if (GUILayout.Button($"Close ({VanillaPlusPlugin.StorageKey.Value})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
			{
				IsOpen = false;
			}
			GUILayout.EndHorizontal();
			int num2 = GUILayout.Toolbar(_page, Pages, Array.Empty<GUILayoutOption>());
			if (num2 != _page)
			{
				_page = num2;
				_scroll = Vector2.zero;
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
			GUI.SetNextControlName("vanillaplus_storagesearch");
			_search = GUILayout.TextField(_search ?? "", 40, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("x", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }))
			{
				_search = "";
				GUI.FocusControl((string)null);
			}
			GUILayout.Label("Sort:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) });
			_sort = GUILayout.Toolbar(_sort, Sorts, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			GUILayout.EndHorizontal();
			if ((int)Event.current.type == 7)
			{
				Typing = GUI.GetNameOfFocusedControl() == "vanillaplus_storagesearch";
			}
			_category = GUILayout.Toolbar(_category, Categories, Array.Empty<GUILayoutOption>());
			if (_page == 1)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Store everything (keeps equipped items and the keep rules in the menu)", Array.Empty<GUILayoutOption>()))
				{
					StoreEverything(localPlayer, list);
				}
				GUILayout.EndHorizontal();
			}
			List<Row> list2 = Filter((_page == 0) ? ChestRows(list) : InventoryRows(localPlayer));
			_scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>());
			if (list2.Count == 0)
			{
				GUILayout.Label((_page != 0) ? "Nothing to store." : ((list.Count == 0) ? "No usable chests in range." : "Nothing matches."), Array.Empty<GUILayoutOption>());
			}
			foreach (Row item in list2)
			{
				DrawRow(localPlayer, list, item);
			}
			GUILayout.EndScrollView();
			GUILayout.Label((Time.unscaledTime < _statusUntil) ? _status : string.Format("{0} item type{1}", list2.Count, (list2.Count == 1) ? "" : "s"), Array.Empty<GUILayoutOption>());
			WindowResize.Draw(_rect);
			GUI.DragWindow();
		}

		private static List<Row> ChestRows(List<Container> chests)
		{
			Dictionary<string, Row> dictionary = new Dictionary<string, Row>();
			foreach (Container chest in chests)
			{
				HashSet<string> hashSet = new HashSet<string>();
				foreach (ItemData allItem in chest.GetInventory().GetAllItems())
				{
					string text = Storage.Key(allItem);
					if (!dictionary.TryGetValue(text, out var value))
					{
						Row obj = new Row
						{
							Key = text,
							Name = NameOf(allItem),
							Sample = allItem
						};
						value = obj;
						dictionary[text] = obj;
					}
					value.Total += allItem.m_stack;
					value.Sources.Add((chest, allItem));
					if (hashSet.Add(text))
					{
						value.Where++;
					}
				}
			}
			return dictionary.Values.ToList();
		}

		private static List<Row> InventoryRows(Player p)
		{
			Dictionary<string, Row> dictionary = new Dictionary<string, Row>();
			foreach (ItemData allItem in ((Humanoid)p).GetInventory().GetAllItems())
			{
				if (!allItem.m_equipped)
				{
					string key = Storage.Key(allItem);
					if (!dictionary.TryGetValue(key, out var value))
					{
						Row obj = new Row
						{
							Key = key,
							Name = NameOf(allItem),
							Sample = allItem
						};
						value = obj;
						dictionary[key] = obj;
					}
					value.Total += allItem.m_stack;
					value.Sources.Add((null, allItem));
				}
			}
			return dictionary.Values.ToList();
		}

		private static List<Row> Filter(List<Row> rows)
		{
			string s = (_search ?? "").Trim();
			IEnumerable<Row> source = rows;
			if (s.Length > 0)
			{
				source = source.Where((Row r) => r.Name.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)(object)r.Sample.m_dropPrefab != (Object)null && ((Object)r.Sample.m_dropPrefab).name.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0));
			}
			if (_category > 0)
			{
				source = source.Where((Row r) => CategoryOf(r.Sample) == _category);
			}
			source = ((_sort == 1) ? (from r in source
				orderby r.Total descending, r.Name
				select r) : source.OrderBy((Row r) => r.Name));
			return source.ToList();
		}

		private static int CategoryOf(ItemData it)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected I4, but got Unknown
			ItemType itemType = it.m_shared.m_itemType;
			switch (itemType - 1)
			{
			case 0:
				return 1;
			case 1:
				return 2;
			case 2:
			case 3:
			case 4:
			case 8:
			case 13:
			case 14:
			case 18:
			case 19:
			case 21:
			case 22:
				return 3;
			case 5:
			case 6:
			case 10:
			case 11:
			case 16:
			case 17:
			case 23:
				return 4;
			default:
				return 5;
			}
		}

		private static string NameOf(ItemData it)
		{
			string text = Localization.instance.Localize(it.m_shared.m_name);
			if (it.m_shared.m_maxQuality <= 1)
			{
				return text;
			}
			return $"{text} (lvl {it.m_quality})";
		}

		private static void DrawRow(Player p, List<Container> chests, Row row)
		{
			//IL_004a: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_0075: 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_0084: 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)
			GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
			Sprite icon = row.Sample.GetIcon();
			Rect rect = GUILayoutUtility.GetRect(28f, 28f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(28f),
				GUILayout.Height(28f)
			});
			if ((Object)(object)icon != (Object)null && (Object)(object)icon.texture != (Object)null && (int)Event.current.type == 7)
			{
				Rect textureRect = icon.textureRect;
				Texture2D texture = icon.texture;
				GUI.DrawTextureWithTexCoords(rect, (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height));
			}
			string text = ((_page == 0) ? string.Format("  <color=#888888>in {0} chest{1}</color>", row.Where, (row.Where == 1) ? "" : "s") : "");
			GUILayout.Label(row.Name + text, _rich, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) });
			GUILayout.Label(row.Total.ToString(), _count, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(55f),
				GUILayout.Height(28f)
			});
			int num = Mathf.Max(1, row.Sample.m_shared.m_maxStackSize);
			if (_page == 0)
			{
				if (GUILayout.Button("1", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(34f),
					GUILayout.Height(26f)
				}))
				{
					Take(p, row, 1);
				}
				if (num > 1 && GUILayout.Button("Stack", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(52f),
					GUILayout.Height(26f)
				}))
				{
					Take(p, row, num);
				}
				if (GUILayout.Button("All", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(40f),
					GUILayout.Height(26f)
				}))
				{
					Take(p, row, row.Total);
				}
			}
			else
			{
				if (GUILayout.Button("Store stack", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(85f),
					GUILayout.Height(26f)
				}))
				{
					Store(p, chests, row, num);
				}
				if (GUILayout.Button("Store all", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(75f),
					GUILayout.Height(26f)
				}))
				{
					Store(p, chests, row, row.Total);
				}
			}
			GUILayout.EndHorizontal();
		}

		private static void Take(Player p, Row row, int amount)
		{
			int num = 0;
			Inventory inventory = ((Humanoid)p).GetInventory();
			foreach (var (val, val2) in row.Sources)
			{
				if (amount <= 0)
				{
					break;
				}
				if (!((Object)(object)val == (Object)null))
				{
					Storage.Own(val);
					int num2 = Storage.Move(val.GetInventory(), inventory, val2, amount);
					num += num2;
					amount -= num2;
					if ((num2 != 0 || val.GetInventory().ContainsItem(val2)) && num2 == 0)
					{
						break;
					}
				}
			}
			Status((num > 0) ? ($"Took {num} {row.Name}" + ((amount > 0) ? " (inventory full)" : "")) : "Inventory full");
		}

		private static int Store(Player p, List<Container> chests, Row row, int amount)
		{
			if (chests.Count == 0)
			{
				Status("No usable chests in range");
				return 0;
			}
			Inventory inventory = ((Humanoid)p).GetInventory();
			int num = 0;
			string name = row.Sample.m_shared.m_name;
			List<Container> list = Holding(chests, row);
			if (list.Count == 0)
			{
				Status(row.Name + ": no chest assigned");
				return 0;
			}
			List<Container> list2 = list.OrderByDescending((Container c) => c.GetInventory().GetAllItems().All((ItemData i) => i.m_shared.m_name == name)).ToList();
			foreach (ItemData item in row.Sources.Select(((Container c, ItemData item) s) => s.item).ToList())
			{
				foreach (Container item2 in list2)
				{
					if (amount <= 0 || !inventory.ContainsItem(item))
					{
						break;
					}
					Storage.Own(item2);
					int num2 = Storage.Move(inventory, item2.GetInventory(), item, Mathf.Min(amount, item.m_stack));
					num += num2;
					amount -= num2;
				}
				if (amount <= 0)
				{
					break;
				}
			}
			Status((num > 0) ? ($"Stored {num} {row.Name}" + ((amount > 0) ? " (chest full)" : "")) : (row.Name + ": chest full"));
			return num;
		}

		private static List<Container> Holding(List<Container> chests, Row row)
		{
			return chests.Where((Container c) => c.GetInventory().GetAllItems().Any((ItemData i) => Storage.Key(i) == row.Key)).ToList();
		}

		private static void StoreEverything(Player p, List<Container> chests)
		{
			bool keepHotbar = VanillaPlusPlugin.StorageKeepHotbar.Value;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			foreach (Row item in InventoryRows(p))
			{
				if (Storage.Kept(item.Sample))
				{
					continue;
				}
				List<(Container, ItemData)> list = item.Sources.Where(((Container c, ItemData item) s) => !keepHotbar || s.item.m_gridPos.y != 0).ToList();
				if (list.Count == 0)
				{
					continue;
				}
				item.Sources = list;
				int num4 = list.Sum<(Container, ItemData)>(((Container c, ItemData item) s) => s.item.m_stack);
				if (Holding(chests, item).Count == 0)
				{
					num3++;
					continue;
				}
				int num5 = Store(p, chests, item, num4);
				if (num5 > 0)
				{
					num++;
				}
				if (num5 < num4)
				{
					num2++;
				}
			}
			Status(string.Format("Stored {0} item type{1}", num, (num == 1) ? "" : "s") + ((num2 > 0) ? $", {num2} left (chest full)" : "") + ((num3 > 0) ? $", {num3} left (no chest assigned)" : ""));
		}

		private static void Status(string s)
		{
			_status = s;
			_statusUntil = Time.unscaledTime + 4f;
			Storage.Invalidate();
		}
	}
	internal static class StoreAll
	{
		private static readonly FieldInfo CurrentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

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

		public static void DrawButton()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (!VanillaPlusPlugin.StoreAllOn)
			{
				return;
			}
			InventoryGui instance = InventoryGui.instance;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null || !InventoryGui.IsVisible() || !instance.IsContainerOpen())
			{
				return;
			}
			object? obj = CurrentContainer?.GetValue(instance);
			Container val = (Container)((obj is Container) ? obj : null);
			if (val != null && !((Object)(object)val == (Object)null))
			{
				instance.m_container.GetWorldCorners(Corners);
				if (GUI.Button(new Rect(Corners[0].x, (float)Screen.height - Corners[0].y + 6f, 150f, 30f), "Store all"))
				{
					int num = Move(localPlayer, val);
					((Character)localPlayer).Message((MessageType)2, string.Format("Stored {0} stack{1}", num, (num == 1) ? "" : "s"), 0, (Sprite)null, false);
				}
			}
		}

		private static int Move(Player p, Container chest)
		{
			Inventory inventory = ((Humanoid)p).GetInventory();
			Inventory inventory2 = chest.GetInventory();
			int num = 0;
			foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
			{
				if (!item.m_equipped && !Storage.Kept(item) && (!VanillaPlusPlugin.StorageKeepHotbar.Value || item.m_gridPos.y != 0))
				{
					int stack = item.m_stack;
					inventory2.MoveItemToThis(inventory, item);
					if (!inventory.GetAllItems().Contains(item) || item.m_stack < stack)
					{
						num++;
					}
				}
			}
			return num;
		}
	}
	internal static class ColorPicker
	{
		private class Receiver : TextReceiver
		{
			private readonly ConfigEntry<string> _entry;

			public readonly string EmptyText;

			public Receiver(ConfigEntry<string> entry, string emptyText)
			{
				_entry = entry;
				EmptyText = emptyText;
			}

			public string GetText()
			{
				return (_entry.Value ?? "").Trim().TrimStart(new char[1] { '#' });
			}

			public void SetText(string text)
			{
				_entry.Value = (text ?? "").Trim().TrimStart(new char[1] { '#' });
			}
		}

		private static readonly FieldRef<TextInput, TextReceiver> Queued = AccessTools.FieldRefAccess<TextInput, TextReceiver>("m_queuedSign");

		private static readonly string[] Palette = new string[12]
		{
			"FF4040", "FF8C1A", "FFE64D", "8CFF59", "33CC55", "4DCCFF", "4D6BFF", "CC66FF", "FF66CC", "FFFFFF",
			"AAAAAA", "000000"
		};

		private static Receiver _open;

		private static Receiver _placedFor;

		private static GUIStyle _swatch;

		private static GUIStyle _rich;

		private static GUISkin _styleSkin;

		public static void Open(string title, ConfigEntry<string> entry, string emptyText)
		{
			if (!((Object)(object)TextInput.instance == (Object)null))
			{
				MenuWindow.IsOpen = false;
				_open = new Receiver(entry, emptyText);
				TextInput.instance.RequestText((TextReceiver)(object)_open, title, 20);
			}
		}

		public static void DrawPanel()
		{
			//IL_0071: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00a2: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Invalid comparison between Unknown and I4
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			TextInput instance = TextInput.instance;
			if (_open == null || (Object)(object)instance == (Object)null || !TextInput.IsVisible() || (object)Queued.Invoke(instance) != _open)
			{
				return;
			}
			GuiInputField inputField = instance.m_inputField;
			if ((Object)(object)inputField == (Object)null)
			{
				return;
			}
			if (_swatch == null || (Object)(object)_styleSkin != (Object)(object)GUI.skin)
			{
				_styleSkin = GUI.skin;
				_rich = new GUIStyle(GUI.skin.label)
				{
					richText = true,
					wordWrap = true
				};
				_swatch = new GUIStyle
				{
					margin = new RectOffset(2, 2, 3, 3)
				};
				GUIStyleState normal = _swatch.normal;
				GUIStyleState hover = _swatch.hover;
				Texture2D val = (_swatch.active.background = Texture2D.whiteTexture);
				Texture2D background = (hover.background = val);
				normal.background = background;
			}
			Rect val3 = PanelPlace.Beside(instance.m_panel, 372f, 236f, 270f);
			if (_placedFor != _open)
			{
				_placedFor = _open;
				VanillaPlusPlugin.Log.LogInfo((object)$"Color panel at {val3} on a {Screen.width}x{Screen.height} screen");
			}
			string text = (((TMP_InputField)inputField).text ?? "").Trim().TrimStart(new char[1] { '#' });
			Color color;
			bool flag = TryColor(text, out color);
			GUILayout.BeginArea(val3, GUI.skin.box);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Rect rect = GUILayoutUtility.GetRect(46f, 20f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(46f),
				GUILayout.Height(20f)
			});
			if (flag && (int)Event.current.type == 7)
			{
				Color color2 = GUI.color;
				GUI.color = new Color(color.r, color.g, color.b, 1f);
				GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color2;
			}
			GUILayout.Label((text.Length == 0) ? ("<b>No color</b> (" + _open.EmptyText + ")") : (flag ? ("<b>" + text + "</b>") : ("<b>" + text + "</b>  <color=#ffb030>not a color</color>")), _rich, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			int num = Mathf.Clamp(Mathf.FloorToInt((((Rect)(ref val3)).width - 16f) / 30f), 1, Palette.Length);
			Color backgroundColor = default(Color);
			for (int i = 0; i < Palette.Length; i++)
			{
				if (i % num == 0)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				}
				ColorUtility.TryParseHtmlString("#" + Palette[i], ref backgroundColor);
				GUI.backgroundColor = backgroundColor;
				if (GUILayout.Button("", _swatch, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(26f),
					GUILayout.Height(22f)
				}))
				{
					Set((TMP_InputField)(object)inputField, Palette[i], focus: true);
				}
				if (i % num == num - 1 || i == Palette.Length - 1)
				{
					GUILayout.EndHorizontal();
				}
			}
			GUI.backgroundColor = Color.white;
			Color val4 = (flag ? color : Color.white);
			float num2 = Channel("R", val4.r);
			float num3 = Channel("G", val4.g);
			float num4 = Channel("B", val4.b);
			if (num2 != val4.r || num3 != val4.g || num4 != val4.b)
			{
				Set((TMP_InputField)(object)inputField, ColorUtility.ToHtmlStringRGB(new Color(num2, num3, num4)), focus: false);
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Hex  #", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			string text2 = GUILayout.TextField(text, 20, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			if (text2 != text)
			{
				Set((TMP_InputField)(object)inputField, text2.Trim().TrimStart(new char[1] { '#' }), focus: false);
			}
			GUILayout.EndHorizontal();
			if (GUILayout.Button("No color (" + _open.EmptyText + ")", Array.Empty<GUILayoutOption>()))
			{
				Set((TMP_InputField)(object)inputField, "", focus: true);
			}
			GUILayout.Label("<color=#999999>A color name (white, red, ...) works too. OK saves it.</color>", _rich, Array.Empty<GUILayoutOption>());
			GUILayout.EndArea();
		}

		private static void Set(TMP_InputField f, string text, bool focus)
		{
			f.text = text;
			if (focus)
			{
				f.ActivateInputField();
				f.stringPosition = text.Length;
				f.selectionStringAnchorPosition = text.Length;
				f.selectionStringFocusPosition = text.Length;
			}
		}

		private static float Channel(string name, float v)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"{name} {Mathf.RoundToInt(v * 255f)}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			v = GUILayout.HorizontalSlider(v, 0f, 1f, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			return Mathf.Round(v * 255f) / 255f;
		}

		private static bool TryColor(string text, out Color color)
		{
			//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)
			color = Color.white;
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			if (!ColorUtility.TryParseHtmlString("#" + text, ref color))
			{
				return ColorUtility.TryParseHtmlString(text, ref color);
			}
			return true;
		}
	}
	internal static class ConfigBackup
	{
		private const string BeforeImport = "_before-import";

		private static List<string> _cache = new List<string>();

		private static float _cacheTime = -999f;

		public static string ExportRoot => Path.Combine(Paths.ConfigPath, "ValheimVanillaPlus-exports");

		private static string CfgFile => VanillaPlusPlugin.ConfigFilePath;

		private static string WaypointsFile => Waypoints.FilePath;

		private static string DeathsFile => DeathLog.FilePath;

		public static string Export(string suffix = "")
		{
			VanillaPlusPlugin.SaveConfig();
			string text = Path.Combine(ExportRoot, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + suffix);
			Directory.CreateDirectory(text);
			File.Copy(CfgFile, Path.Combine(text, Path.GetFileName(CfgFile)), overwrite: true);
			if (File.Exists(WaypointsFile))
			{
				File.Copy(WaypointsFile, Path.Combine(text, Path.GetFileName(WaypointsFile)), overwrite: true);
			}
			if (File.Exists(DeathsFile))
			{
				File.Copy(DeathsFile, Path.Combine(text, Path.GetFileName(DeathsFile)), overwrite: true);
			}
			VanillaPlusPlugin.Log.LogInfo((object)("Config exported to " + text));
			Invalidate();
			return Path.GetFileName(text);
		}

		public static List<string> Exports()
		{
			if (Time.unscaledTime - _cacheTime < 2f)
			{
				return _cache;
			}
			_cacheTime = Time.unscaledTime;
			_cache = (Directory.Exists(ExportRoot) ? (from d in Directory.GetDirectories(ExportRoot)
				where File.Exists(Path.Combine(d, Path.GetFileName(CfgFile)))
				orderby d descending
				select d).Select(Path.GetFileName).ToList() : new List<string>());
			return _cache;
		}

		private static void Invalidate()
		{
			_cacheTime = -999f;
		}

		public static bool HasWaypoints(string name)
		{
			return File.Exists(Path.Combine(ExportRoot, name, Path.GetFileName(WaypointsFile)));
		}

		public static string Import(string name)
		{
			string text = Path.Combine(ExportRoot, name);
			string text2 = Path.Combine(text, Path.GetFileName(CfgFile));
			if (!File.Exists(text2))
			{
				return null;
			}
			string text3 = Export("_before-import");
			File.Copy(text2, CfgFile, overwrite: true);
			string text4 = Path.Combine(text, Path.GetFileName(WaypointsFile));
			if (File.Exists(text4))
			{
				File.Copy(text4, WaypointsFile, overwrite: true);
			}
			string text5 = Path.Combine(text, Path.GetFileName(DeathsFile));
			if (File.Exists(text5))
			{
				File.Copy(text5, DeathsFile, overwrite: true);
			}
			VanillaPlusPlugin.ReloadConfig();
			Waypoints.Reload();
			DeathLog.Load();
			VanillaPlusPlugin.Log.LogInfo((object)("Config imported from " + text + " (what you had is saved as " + text3 + ")"));
			Invalidate();
			return text3;
		}

		public static void Delete(string name)
		{
			string text = Path.Combine(ExportRoot, name);
			if (Directory.Exists(text))
			{
				Directory.Delete(text, recursive: true);
			}
			VanillaPlusPlugin.Log.LogInfo((object)("Config backup deleted: " + text));
			Invalidate();
		}

		public static void OpenFolder()
		{
			Directory.CreateDirectory(ExportRoot);
			Process.Start("explorer.exe", "\"" + ExportRoot + "\"");
		}
	}
	internal static class HotkeyEditor
	{
		private static ConfigFile _listedFor;

		private static readonly List<ConfigEntryBase> Entries = new List<ConfigEntryBase>();

		private static ConfigEntryBase _waiting;

		private static float _quietUntil;

		private static readonly KeyCode[] Modifiers;

		public static bool Busy
		{
			get
			{
				if (_waiting == null)
				{
					return Time.unscaledTime < _quietUntil;
				}
				return true;
			}
		}

		private static List<ConfigEntryBase> List(ConfigFile config)
		{
			if (_listedFor == config)
			{
				return Entries;
			}
			_listedFor = config;
			Entries.Clear();
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config)
			{
				ConfigEntryBase value = item.Value;
				if (!(value.SettingType != typeof(KeyboardShortcut)) || !(value.SettingType != typeof(KeyCode)))
				{
					ConfigDescription description = value.Description;
					if (((description != null) ? description.Description : null) == null || !value.Description.Description.StartsWith("No longer used"))
					{
						Entries.Add(value);
					}
				}
			}
			return Entries;
		}

		public static void Capture()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0018: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0069: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (_waiting == null)
			{
				return;
			}
			Event current = Event.current;
			if ((int)current.type != 4 || (int)current.keyCode == 0)
			{
				return;
			}
			KeyCode keyCode = current.keyCode;
			current.Use();
			if ((int)keyCode == 27)
			{
				Stop();
			}
			else if (_waiting.SettingType == typeof(KeyCode))
			{
				_waiting.BoxedValue = keyCode;
				Stop();
			}
			else
			{
				if (IsModifier(keyCode))
				{
					return;
				}
				List<KeyCode> list = new List<KeyCode>();
				KeyCode[] modifiers = Modifiers;
				foreach (KeyCode val in modifiers)
				{
					if (Input.GetKey(val))
					{
						list.Add(val);
					}
				}
				_waiting.BoxedValue = (object)new KeyboardShortcut(keyCode, list.ToArray());
				Stop();
			}
		}

		private static void Stop()
		{
			_waiting = null;
			_quietUntil = Time.unscaledTime + 0.3f;
		}

		private static bool IsModifier(KeyCode k)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (Array.IndexOf(Modifiers, k) < 0 && (int)k != 310 && (int)k != 309 && (int)k != 311 && (int)k != 312)
			{
				return (int)k == 313;
			}
			return true;
		}

		public static void Draw(ConfigFile config)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("   Hotkeys (click one, then press the new key; Esc cancels):", Array.Empty<GUILayoutOption>());
			foreach (ConfigEntryBase item in List(config))
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("      " + Name(item), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) });
				bool flag = _waiting == item;
				if (GUILayout.Button(flag ? "Press a key…" : Shown(item), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(110f) }))
				{
					_waiting = (flag ? null : item);
				}
				if (GUILayout.Button("None", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
				{
					item.BoxedValue = ((item.SettingType == typeof(KeyCode)) ? ((object)(KeyCode)0) : ((object)KeyboardShortcut.Empty));
					if (flag)
					{
						_waiting = null;
					}
				}
				if (GUILayout.Button("Default", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) }))
				{
					item.BoxedValue = item.DefaultValue;
					if (flag)
					{
						_waiting = null;
					}
				}
				GUILayout.EndHorizontal();
			}
		}

		private unsafe static string Shown(ConfigEntryBase entry)
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			object boxedValue = entry.BoxedValue;
			if (boxedValue is KeyboardShortcut val)
			{
				if ((int)((KeyboardShortcut)(ref val)).MainKey != 0)
				{
					return ((object)(*(KeyboardShortcut*)(&val))/*cast due to .constrained prefix*/).ToString();
				}
				return "(none)";
			}
			if (!(boxedValue is KeyCode val2))
			{
				return boxedValue?.ToString() ?? "";
			}
			if ((int)val2 != 0)
			{
				return ((object)(*(KeyCode*)(&val2))/*cast due to .constrained prefix*/).ToString();
			}
			return "(none)";
		}

		private static string Name(ConfigEntryBase entry)
		{
			string text = Words(entry.Definition.Key);
			string section = entry.Definition.Section;
			if (section == "Hotkeys")
			{
				return text;
			}
			return section + ": " + text.ToLowerInvariant();
		}

		private static string Words(string camel)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < camel.Length; i++)
			{
				char c = camel[i];
				if (i > 0 && char.IsUpper(c) && !char.IsUpper(camel[i - 1]))
				{
					stringBuilder.Append(' ');
					stringBuilder.Append(char.ToLowerInvariant(c));
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}

		static HotkeyEditor()
		{
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Modifiers = (KeyCode[])(object)array;
		}
	}
	internal enum MenuThemeMode
	{
		Classic,
		Dark,
		Light,
		Valheim
	}
	internal static class MenuTheme
	{
		private struct Palette
		{
			public Color Window;

			public Color Box;

			public Color Button;

			public Color ButtonHover;

			public Color ButtonActive;

			public Color Selected;

			public Color Field;

			public Color Text;

			public Color TextDim;
		}

		private static GUISkin _dark;

		private static GUISkin _light;

		private static GUISkin _game;

		private static bool _gameLook;

		private static float _gameRetryAt;

		private static readonly Palette DarkColors = new Palette
		{
			Window = new Color(0.11f, 0.12f, 0.14f, 0.97f),
			Box = new Color(0.16f, 0.17f, 0.2f),
			Button = new Color(0.22f, 0.24f, 0.28f),
			ButtonHover = new Color(0.29f, 0.32f, 0.37f),
			ButtonActive = new Color(0.18f, 0.4f, 0.62f),
			Selected = new Color(0.2f, 0.45f, 0.7f),
			Field = new Color(0.07f, 0.08f, 0.09f),
			Text = new Color(0.92f, 0.93f, 0.95f),
			TextDim = new Color(0.65f, 0.67f, 0.7f)
		};

		private static readonly Palette LightColors = new Palette
		{
			Window = new Color(0.95f, 0.95f, 0.96f, 0.98f),
			Box = new Color(0.88f, 0.89f, 0.91f),
			Button = new Color(0.82f, 0.84f, 0.87f),
			ButtonHover = new Color(0.75f, 0.78f, 0.83f),
			ButtonActive = new Color(0.55f, 0.7f, 0.9f),
			Selected = new Color(0.45f, 0.63f, 0.88f),
			Field = Color.white,
			Text = new Color(0.1f, 0.11f, 0.13f),
			TextDim = new Color(0.35f, 0.37f, 0.4f)
		};

		private static readonly Palette WoodColors = new Palette
		{
			Window = new Color(0.13f, 0.09f, 0.06f, 0.97f),
			Box = new Color(0.08f, 0.06f, 0.04f, 0.85f),
			Button = new Color(0.3f, 0.2f, 0.11f),
			ButtonHover = new Color(0.4f, 0.27f, 0.14f),
			ButtonActive = new Color(0.52f, 0.34f, 0.15f),
			Selected = new Color(0.58f, 0.38f, 0.16f),
			Field = new Color(0.06f, 0.04f, 0.03f),
			Text = new Color(1f, 0.97f, 0.9f),
			TextDim = new Color(0.75f, 0.7f, 0.62f)
		};

		public static GUISkin Current(GUISkin baseSkin)
		{
			return (GUISkin)(VanillaPlusPlugin.MenuThemeSetting.Value switch
			{
				MenuThemeMode.Dark => _dark ?? (_dark = Build(baseSkin, DarkColors)), 
				MenuThemeMode.Light => _light ?? (_light = Build(baseSkin, LightColors)), 
				MenuThemeMode.Valheim => _game ?? (_game = Build(baseSkin, WoodColors)), 
				_ => null, 
			});
		}

		public static void Update()
		{
			if ((Object)(object)_game == (Object)null || _gameLook || Time.unscaledTime < _gameRetryAt)
			{
				return;
			}
			_gameRetryAt = Time.unscaledTime + 2f;
			try
			{
				_gameLook = ApplyGameLook(_game);
			}
			catch (Exception ex)
			{
				_gameLook = true;
				VanillaPlusPlugin.Log.LogWarning((object)("Valheim theme: couldn't read the game's interface, using plain colors (" + ex.GetType().Name + ": " + ex.Message + ")"));
			}
		}

		private static GUISkin Build(GUISkin baseSkin, Palette c)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			//IL_00a7: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: 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_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: 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_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: 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_02bf: 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_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			GUISkin val = Object.Instantiate<GUISkin>(baseSkin);
			((Object)val).name = "VanillaPlusTheme";
			Flat(val.window, c.Window, c.Window, c.Window, c.Text);
			val.window.onNormal.background = val.window.normal.background;
			val.window.onNormal.textColor = c.Text;
			val.window.fontStyle = (FontStyle)1;
			Flat(val.box, c.Box, c.Box, c.Box, c.Text);
			Flat(val.button, c.Button, c.ButtonHover, c.ButtonActive, c.Text);
			val.button.onNormal.background = Tex(c.Selected);
			val.button.onNormal.textColor = Color.white;
			val.button.onHover.background = Tex(c.Selected);
			val.button.onHover.textColor = Color.white;
			val.button.onActive.background = Tex(c.ButtonActive);
			val.button.onActive.textColor = Color.white;
			Flat(val.textField, c.Field, c.Field, c.Field, c.Text);
			val.textField.focused.background = Tex(c.Field);
			val.textField.focused.textColor = c.Text;
			val.settings.cursorColor = c.Text;
			GUIStyle[] array = (GUIStyle[])(object)new GUIStyle[2] { val.label, val.toggle };
			foreach (GUIStyle val2 in array)
			{
				GUIStyleState normal = val2.normal;
				GUIStyleState hover = val2.hover;
				Color val3 = (val2.active.textColor = c.Text);
				Color textColor = (hover.textColor = val3);
				normal.textColor = textColor;
				GUIStyleState onNormal = val2.onNormal;
				GUIStyleState onHover = val2.onHover;
				val3 = (val2.onActive.textColor = c.Text);
				textColor = (onHover.textColor = val3);
				onNormal.textColor = textColor;
			}
			Flat(val.horizontalSlider, c.Field, c.Field, c.Field, c.Text);
			Flat(val.horizontalSliderThumb, c.Selected, c.ButtonActive, c.ButtonActive, c.Text);
			val.horizontalSliderThumb.fixedWidth = 12f;
			Flat(val.verticalScrollbar, c.Box, c.Box, c.Box, c.Text);
			Flat(val.verticalScrollbarThumb, c.Button, c.ButtonHover, c.ButtonActive, c.Text);
			val.toggle.onNormal.textColor = c.Text;
			val.label.normal.textColor = c.Text;
			val.box.normal.textColor = c.TextDim;
			return val;
		}

		private static void Flat(GUIStyle s, Color normal, Color hover, Color active, Color text)
		{
			//IL_0006: 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_0024: 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_0042: 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_0060: 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)
			s.normal.background = Tex(normal);
			s.normal.textColor = text;
			s.hover.background = Tex(hover);
			s.hover.textColor = text;
			s.active.background = Tex(active);
			s.active.textColor = text;
			s.focused.background = Tex(normal);
			s.focused.textColor = text;
		}

		private static Texture2D Tex(Color c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}

		private static bool ApplyGameLook(GUISkin skin)
		{
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Invalid comparison between Unknown and I4
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: 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_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Expected O, but got Unknown
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: 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_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: 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_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0606: Expected O, but got Unknown
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Expected O, but got Unknown
			TextInput instance = TextInput.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_panel == (Object)null)
			{
				return false;
			}
			Button val = ((IEnumerable<Button>)instance.m_panel.GetComponentsInChildren<Button>(true)).FirstOrDefault((Func<Button, bool>)((Button b) => !((Object)b).name.EndsWith("_ClearButton")));
			Image val2 = (Image)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			TMP_Text val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentsInChildren<TMP_Text>(true).FirstOrDefault() : null);
			GuiInputField inputField = instance.m_inputField;
			Image val4 = (Image)(((Object)(object)inputField != (Object)null) ? (((object)((Component)inputField).GetComponent<Image>()) ?? ((object)/*isinst with value type is only supported in some contexts*/)) : null);
			Image val5 = PanelImage(instance.m_panel, val2, val4);
			Dictionary<Texture, Texture2D> dictionary = new Dictionary<Texture, Texture2D>();
			try
			{
				Font val6 = GameFont(((Object)(object)val3 != (Object)null) ? val3.font : null);
				if ((Object)(object)val6 != (Object)null)
				{
					skin.font = val6;
					GUIStyle[] array = (GUIStyle[])(object)new GUIStyle[6] { skin.label, skin.button, skin.toggle, skin.textField, skin.box, skin.window };
					foreach (GUIStyle obj in array)
					{
						obj.font = null;
						obj.fontSize = 13;
					}
				}
				Texture2D val7 = (((Object)(object)val2 != (Object)null) ? Copy(val2.sprite, ((Graphic)val2).color * Tint(val, 0), dictionary) : null);
				if ((Object)(object)val7 != (Object)null)
				{
					Texture2D val8;
					Texture2D background;
					if ((int)((Selectable)val).transition == 2)
					{
						SpriteState spriteState = ((Selectable)val).spriteState;
						val8 = Copy(((SpriteState)(ref spriteState)).highlightedSprite, ((Graphic)val2).color, dictionary) ?? val7;
						spriteState = ((Selectable)val).spriteState;
						background = Copy(((SpriteState)(ref spriteState)).pressedSprite, ((Graphic)val2).color, dictionary) ?? val8;
					}
					else
					{
						val8 = Copy(val2.sprite, ((Graphic)val2).color * Tint(val, 1), dictionary) ?? val7;
						background = Copy(val2.sprite, ((Graphic)val2).color * Tint(val, 2), dictionary) ?? val8;
					}
					Color val9 = (((Object)(object)val3 != (Object)null) ? Opaque(((Graphic)val3).color) : skin.button.normal.textColor);
					GUIStyle button = skin.button;
					button.normal.background = val7;
					button.focused.background = val7;
					button.hover.background = val8;
					button.active.background = background;
					button.onNormal.background = background;
					button.onHover.background = background;
					button.onActive.background = background;
					button.onFocused.background = background;
					GUIStyleState normal = button.normal;
					Color textColor = (button.focused.textColor = val9);
					normal.textColor = textColor;
					GUIStyleState hover = button.hover;
					textColor = (button.active.textColor = Color.Lerp(val9, Color.white, 0.5f));
					hover.textColor = textColor;
					GUIStyleState onNormal = button.onNormal;
					GUIStyleState onHover = button.onHover;
					GUIStyleState onActive = button.onActive;
					Color val12 = (button.onFocused.textColor = Color.white);
					Color val13 = (onActive.textColor = val12);
					textColor = (onHover.textColor = val13);
					onNormal.textColor = textColor;
					button.border = Border(val2.sprite, val7);
					button.padding = new RectOffset(Mathf.Max(6, button.border.left / 2), Mathf.Max(6, button.border.right / 2), 3, 3);
				}
				Texture2D val16 = (((Object)(object)val4 != (Object)null) ? Copy(val4.sprite, ((Graphic)val4).color, dictionary) : null);
				if ((Object)(object)val16 != (Object)null)
				{
					GUIStyle textField = skin.textField;
					GUIStyleState normal2 = textField.normal;
					GUIStyleState hover2 = textField.hover;
					GUIStyleState active = textField.active;
					Texture2D val17 = (textField.focused.background = val16);
					Texture2D val19 = (active.background = val17);
					Texture2D background2 = (hover2.background = val19);
					normal2.background = background2;
					textField.border = Border(val4.sprite, val16);
					textField.padding = new RectOffset(Mathf.Max(4, textField.border.left / 2), Mathf.Max(4, textField.border.right / 2), 3, 3);
					if ((Object)(object)((TMP_InputField)inputField).textComponent != (Object)null)
					{
						Color val22 = Opaque(((Graphic)((TMP_InputField)inputField).textComponent).color);
						GUIStyleState normal3 = textField.normal;
						GUIStyleState hover3 = textField.hover;
						GUIStyleState active2 = textField.active;
						Color val12 = (textField.focused.textColor = val22);
						Color val13 = (active2.textColor = val12);
						Color textColor = (hover3.textColor = val13);
						normal3.textColor = textColor;
						skin.settings.cursorColor = val22;
					}
				}
				Texture2D val26 = (((Object)(object)val5 != (Object)null) ? Copy(val5.sprite, ((Graphic)val5).color, dictionary) : null);
				if ((Object)(object)val26 != (Object)null)
				{
					GUIStyle window = skin.window;
					GUIStyleState normal4 = window.normal;
					GUIStyleState onNormal2 = window.onNormal;
					GUIStyleState hover4 = window.hover;
					GUIStyleState active3 = window.active;
					Texture2D val27 = (window.focused.background = val26);
					Texture2D val17 = (active3.background = val27);
					Texture2D val19 = (hover4.background = val17);
					Texture2D background2 = (onNormal2.background = val19);
					normal4.background = background2;
					window.border = Border(val5.sprite, val26);
					RectOffset padding = window.padding;
					window.padding = new RectOffset(Mathf.Max(padding.left, window.border.left / 2 + 6), Mathf.Max(padding.right, window.border.right / 2 + 6), Mathf.Max(padding.top, window.border.top / 2 + 16), Mathf.Max(padding.bottom, window.border.bottom / 2 + 6));
				}
				VanillaPlusPlugin.Log.LogInfo((object)("Valheim theme: font " + (((Object)(object)val6 != (Object)null) ? ((Object)val6).name : "not found") + ", button " + Describe(val7) + ", text field " + Describe(val16) + ", window " + Describe(val26)));
				return true;
			}
			finally
			{
				foreach (Texture2D value in dictionary.Values)
				{
					if ((Object)(object)value != (Object)null)
					{
						Object.Destroy((Object)(object)value);
					}
				}
			}
		}

		private static string Describe(Texture2D t)
		{
			if (!((Object)(object)t != (Object)null))
			{
				return "plain color";
			}
			return $"{((Texture)t).width}x{((Texture)t).height}";
		}

		private static Image PanelImage(GameObject panel, Image button, Image field)
		{
			//IL_0074: 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)
			Image component = panel.GetComponent<Image>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null)
			{
				return component;
			}
			Image result = null;
			float num = 0f;
			Image[] componentsInChildren = panel.GetComponentsInChildren<Image>(true);
			foreach (Image val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)(object)button) && !((Object)(object)val == (Object)(object)field) && !((Object)(object)val.sprite == (Object)null) && !((Object)(object)((Component)val).GetComponentInParent<Button>() != (Object)null))
				{
					Rect rect = ((Graphic)val).rectTransform.rect;
					float num2 = Mathf.Abs(((Rect)(ref rect)).width * ((Rect)(ref rect)).height);
					if (num2 > num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}

		private static Font GameFont(TMP_FontAsset tmp)
		{
			Font[] source = Resources.FindObjectsOfTypeAll<Font>();
			return ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name == "AveriaSerifLibre-Bold")) ?? (((Object)(object)tmp != (Object)null) ? tmp.sourceFontFile : null) ?? ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.StartsWith("AveriaSerifLibre"))) ?? ((IEnumerable<Font>)source).FirstOrDefault((Func<Font, bool>)((Font f) => ((Object)f).name.StartsWith("Averia")));
		}

		private static Color Tint(Button b, int state)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0049: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			if ((Object)(object)b == (Object)null || (int)((Selectable)b).transition != 1)
			{
				return Color.white;
			}
			ColorBlock colors = ((Selectable)b).colors;
			Color val = (Color)(state switch
			{
				2 => ((ColorBlock)(ref colors)).pressedColor, 
				1 => ((ColorBlock)(ref colors)).highlightedColor, 
				_ => ((ColorBlock)(ref colors)).normalColor, 
			}) * ((ColorBlock)(ref colors)).colorMultiplier;
			val.a = Mathf.Clamp01(val.a);
			return val;
		}

		private static Color Opaque(Color c)
		{
			//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_000c: 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)
			return new Color(c.r, c.g, c.b, 1f);
		}

		private static RectOffset Border(Sprite s, Texture2D copy)
		{
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			Vector4 border = s.border;
			int num = Mathf.Max(0, ((Texture)copy).width / 2 - 1);
			int num2 = Mathf.Max(0, ((Texture)copy).height / 2 - 1);
			return new RectOffset(Mathf.Min((int)border.x, num), Mathf.Min((int)border.z, num), Mathf.Min((int)border.w, num2), Mathf.Min((int)border.y, num2));
		}

		private static Texture2D Copy(Sprite s, Color tint, Dictionary<Texture, Texture2D> sheets)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00a1: 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_0173: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s == (Object)null || (Object)(object)s.texture == (Object)null)
			{
				return null;
			}
			if (s.packed && ((int)s.packingMode == 0 || (int)s.packingRotation != 0))
			{
				return null;
			}
			Texture2D texture = s.texture;
			if (!sheets.TryGetValue((Texture)(object)texture, out var value))
			{
				RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
				RenderTexture active = RenderTexture.active;
				try
				{
					Graphics.Blit((Texture)(object)texture, temporary);
					RenderTexture.active = temporary;
					value = new Texture2D(((Texture)texture).width, ((Texture)texture).height, (TextureFormat)4, false);
					value.ReadPixels(new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), 0, 0);
					value.Apply();
				}
				finally
				{
					RenderTexture.active = active;
					RenderTexture.ReleaseTemporary(temporary);
				}
				sheets[(Texture)(object)texture] = value;
			}
			Rect textureRect = s.textureRect;
			int num = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref textureRect)).x), 0, ((Texture)value).width - 1);
			int num2 = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref textureRect)).y), 0, ((Texture)value).height - 1);
			int num3 = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref textureRect)).width), 1, ((Texture)value).width - num);
			int num4 = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref textureRect)).height), 1, ((Texture)value).height - num2);
			Color[] pixels = value.GetPixels(num, num2, num3, num4);
			if (tint != Color.white)
			{
				for (int i = 0; i < pixels.Length; i++)
				{
					ref Color reference = ref pixels[i];
					reference *= tint;
				}
			}
			Texture2D val = new Texture2D(num3, num4, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61,
				wrapMode = (TextureWrapMode)1
			};
			val.SetPixels(pixels);
			val.Apply();
			return val;
		}
	}
	internal static class MenuWindow
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DrawContents;
		}

		public static bool IsOpen;

		private const int WindowId = 31377;

		private static Rect _rect = new Rect(40f, 80f, 520f, 0f);

		private static Vector2 _size = new Vector2(520f, 620f);

		private static readonly Vector2 MinSize = new Vector2(440f, 300f);

		private static Vector2 _scroll;

		private static GUIStyle _header;

		private static readonly string[] Tabs = new string[7] { "Interface", "Crafting", "Items", "Vision", "World", "Stats", "More" };

		private static int _tab;

		private static bool _placed;

		private static bool _moved;

		private static GUISkin _headerSkin;

		private static List<string> _backups = new List<string>();

		private static string _deleteArmed;

		private static float _deleteArmedAt;

		private const string SearchControl = "vanillaplus_search";

		private static string _search = "";

		private static string _section = "";

		public static bool Typing;

		public static bool Searching => !string.IsNullOrEmpty(_search?.Trim());

		public static string SearchText => (_search ?? "").Trim();

		public static void Draw()
		{
			//IL_0055: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Invalid comparison between Unknown and I4
			if (!IsOpen)
			{
				Typing = false;
				SavePosition();
				return;
			}
			if (!_placed)
			{
				_placed = true;
				_size = new Vector2(Mathf.Max(MinSize.x, VanillaPlusPlugin.MenuWidth.Value), Mathf.Max(MinSize.y, VanillaPlusPlugin.MenuHeight.Value));
				((Rect)(ref _rect)).width = _size.x;
				((Rect)(ref _rect)).x = Mathf.Clamp(VanillaPlusPlugin.MenuX.Value, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _rect)).width));
				((Rect)(ref _rect)).y = Mathf.Clamp(VanillaPlusPlugin.MenuY.Value, 0f, Mathf.Max(0f, (float)Screen.height - 200f));
			}
			GUISkin skin = GUI.skin;
			GUISkin val = MenuTheme.Current(skin);
			if ((Object)(object)val != (Object)null)
			{
				GUI.skin = val;
			}
			if (_header == null || (Object)(object)_headerSkin != (Object)(object)GUI.skin)
			{
				_headerSkin = GUI.skin;
				_header = new GUIStyle(GUI.skin.label)
				{
					fontStyle = (FontStyle)1,
					fontSize = 14
				};
			}
			Vector2 position = ((Rect)(ref _rect)).position;
			((Rect)(ref _rect)).width = _size.x;
			((Rect)(ref _rect)).height = Mathf.Min(_size.y, (float)Screen.height - ((Rect)(ref _rect)).y - 20f);
			Rect rect = _rect;
			object obj = <>O.<0>__DrawContents;
			if (obj == null)
			{
				WindowFunction val2 = DrawContents;
				<>O.<0>__DrawContents = val2;
				obj = (object)val2;
			}
			_rect = GUILayout.Window(31377, rect, (WindowFunction)obj, "Valheim Vanilla Plus 1.1.1", Array.Empty<GUILayoutOption>());
			if (((Rect)(ref _rect)).position != position)
			{
				_moved = true;
			}
			if (_moved && (int)Event.current.rawType == 1)
			{
				SavePosition();
			}
			GUI.skin = skin;
		}

		private static void SavePosition()
		{
			if (_moved)
			{
				_moved = false;
				VanillaPlusPlugin.MenuX.Value = Mathf.Round(((Rect)(ref _rect)).x);
				VanillaPlusPlugin.MenuY.Value = Mathf.Round(((Rect)(ref _rect)).y);
			}
		}

		private static void DrawContents(int id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Invalid comparison between Unknown and I4
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: 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_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			if (WindowResize.Handle(31377, _rect, ref _size, MinSize, new Vector2((float)Screen.width - ((Rect)(ref _rect)).x - 4f, (float)Screen.height - ((Rect)(ref _rect)).y - 4f)))
			{
				VanillaPlusPlugin.MenuWidth.Value = Mathf.Round(_size.x);
				VanillaPlusPlugin.MenuHeight.Value = Mathf.Round(_size.y);
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Theme:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
			int num = GUILayout.Toolbar((int)VanillaPlusPlugin.MenuThemeSetting.Value, new string[4] { "Classic", "Dark", "Light", "Valheim" }, Array.Empty<GUILayoutOption>());
			if (num != (int)VanillaPlusPlugin.MenuThemeSetting.Value)
			{
				VanillaPlusPlugin.MenuThemeSetting.Value = (MenuThemeMode)num;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) });
			GUI.SetNextControlName("vanillaplus_search");
			_search = GUILayout.TextField(_search ?? "", 40, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("✕", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }))
			{
				_search = "";
				GUI.FocusControl((string)null);
			}
			GUILayout.EndHorizontal();
			if ((int)Event.current.type == 7)
			{
				Typing = GUI.GetNameOfFocusedControl() == "vanillaplus_search" || HotkeyEditor.Busy;
			}
			if (!Searching)
			{
				int num2 = GUILayout.Toolbar(_tab, Tabs, Array.Empty<GUILayoutOption>());
				if (num2 != _tab)
				{
					_tab = num2;
					_scroll = Vector2.zero;
				}
			}
			_scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>());
			if (Searching)
			{
				for (int i = 0; i < Tabs.Length; i++)
				{
					DrawTab(i);
				}
			}
			else
			{
				DrawTab(_tab);
			}
			GUILayout.EndScrollView();
			if (GUILayout.Button($"Close ({VanillaPlusPlugin.MenuKey.Value})", Array.Empty<GUILayoutOption>()))
			{
				IsOpen = false;
			}
			WindowResize.Draw(_rect);
			GUI.DragWindow();
		}

		private static void DrawTab(int i)
		{
			_section = Tabs[i];
			switch (i)
			{
			case 0:
				InterfaceTab();
				break;
			case 1:
				CraftingTab();
				break;
			case 2:
				ItemsTab();
				break;
			case 3:
				VisionTab();
				break;
			case 4:
				WorldTab();
				break;
			case 5:
				if (Show(null))
				{
					PlayerStats.Draw(Player.m_localPlayer);
					DeathLog.DrawMenu();
				}
				break;
			case 6:
				MoreTab();
				break;
			}
		}

		private static void WorldTab()
		{
			//IL_0101: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Header("Map");
			if (VanillaPlusPlugin.GodModeLoaded)
			{
				Lbl("Valheim God Mode is installed: its map reveal is used instead of this one.");
			}
			Toggle(VanillaPlusPlugin.RevealMap, "Reveal the whole world map (removes the map fog; not saved)");
			Header("Waypoints");
			if (VanillaPlusPlugin.GodModeLoaded)
			{
				Lbl("Valheim God Mode is installed: its waypoints are used instead of these.");
			}
			Toggle(VanillaPlusPlugin.WaypointsEnabled, "Waypoints");
			Toggle(VanillaPlusPlugin.WaypointOnScreen, "   ...show on screen (name + distance)");
			Slider(VanillaPlusPlugin.WaypointRange, "   On-screen range (m, 0 = any)", 0f, 5000f, "0");
			Toggle(VanillaPlusPlugin.WaypointMapPins, "   ...show as map pins (not saved)");
			Toggle(VanillaPlusPlugin.WaypointDeath, "   ...add a 'Last death' waypoint when I die");
			Toggle(VanillaPlusPlugin.WaypointPinMarkers, "   ...also show markers for the pins I place on the map");
			if (Show("pins I place on the map"))
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("      for these pin icons:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) });
				PinType[] icons = Waypoints.Icons;
				foreach (PinType type in icons)
				{
					if (IconButton(Waypoints.PinSprite(type), Waypoints.MarkerIcon(type), ""))
					{
						Waypoints.ToggleMarkerIcon(type);
					}
				}
				GUILayout.Label(VanillaPlusPlugin.WaypointPinMarkers.Value ? $"  {Waypoints.MarkerPinCount()} pins shown" : "", Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				Lbl("      Cross a pin out on the map to hide its marker.");
			}
			if ((Object)(object)localPlayer != (Object)null && Btn("Add waypoint here"))
			{
				Waypoints.AddHere(localPlayer);
			}
			if (!((Object)(object)localPlayer != (Object)null) || !Show(null))
			{
				return;
			}
			foreach (Waypoint item in new List<Waypoint>(Waypoints.ForThisWorld()))
			{
				float num = Vector3.Distance(((Component)localPlayer).transform.position, item.Pos);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				bool flag = Waypoints.IsDeath(item);
				if (IconButton(Waypoints.PinSprite((PinType)(flag ? 4 : ((int)item.Icon))), on: false, flag ? "" : "Click for the next pin icon") && !flag)
				{
					Waypoints.NextIcon(item);
				}
				GUILayout.Label($"{item.Name}  ({num:0} m {WorldInfo.Compass(((Component)localPlayer).transform.position, item.Pos)})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (GUILayout.Button("Map", Array.Empty<GUILayoutOption>()))
				{
					Waypoints.ShowOnMap(item);
				}
				if (GUILayout.Button("Rename", Array.Empty<GUILayoutOption>()))
				{
					Waypoints.Rename(item);
				}
				if (GUILayout.Button("Delete", Array.Empty<GUILayoutOption>()))
				{
					Waypoints.Delete(item);
				}
				GUILayout.EndHorizontal();
			}
		}

		private static bool IconButton(Sprite sprite, bool on, string tip)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0041: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_00ef: 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_012d: 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_017d: 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_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_009d: 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)
			Rect rect = GUILayoutUtility.GetRect(28f, 26f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(28f),
				GUIL