Decompiled source of ZenHoverItem v0.1.2

plugins\ZenHoverItem.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Valheim.SettingsGui;
using ZenModLib;
using ZenModLib.Controls;

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

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ZenModLib
{
	internal static class AssetIO
	{
		public static Sprite LoadSprite(string resourceName)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0030: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, LoadResource(resourceName));
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private static byte[] LoadResource(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			Type type = ((object)ZenPlugin.Instance).GetType();
			using Stream stream = executingAssembly.GetManifestResourceStream(type.Namespace + ".Resources." + resourceName);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}
	}
	[HarmonyPatch]
	internal static class Cleanup
	{
		public static void External()
		{
			ConfigTomlTypeConverterEntries();
			JotunnConfigs();
		}

		private static void JotunnConfigs()
		{
			ConfigFile config = ((BaseUnityPlugin)ZenPlugin.Instance).Config;
			Log.Debug("Remove config entries from Jotunn cache", "JotunnConfigs", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Cleanup.cs");
			Dictionary<ConfigEntryBase, object> dictionary = (Dictionary<ConfigEntryBase, object>)AccessTools.Field(typeof(SynchronizationManager), "localValues").GetValue(SynchronizationManager.Instance);
			foreach (ConfigDefinition key2 in config.Keys)
			{
				ConfigEntryBase key = config[key2];
				dictionary.Remove(key);
			}
		}

		private static void ConfigTomlTypeConverterEntries()
		{
			Log.Debug("Removing TomlTypeConverter Entry: StringList", "ConfigTomlTypeConverterEntries", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Cleanup.cs");
			((Dictionary<Type, TypeConverter>)AccessTools.Property(typeof(TomlTypeConverter), "TypeConverters").GetValue(null)).Remove(typeof(Config.StringList));
		}
	}
	public static class Config
	{
		public class StringList : List<string>
		{
			internal static readonly Tally<string> AccessCount;

			public static StringList Empty => new StringList();

			public StringList(params IEnumerable<string>[] collections)
			{
				foreach (IEnumerable<string> collection in collections)
				{
					AddRange(collection);
				}
			}

			public new string ToString()
			{
				return string.Join(", ", this);
			}

			public static StringList Parse(string? str)
			{
				if (str == null)
				{
					return Empty;
				}
				string[] source = str.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				return new StringList(source.Select((string s) => s.Trim()));
			}

			static StringList()
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				AccessCount = new Tally<string>();
				TomlTypeConverter.AddConverter(typeof(StringList), new TypeConverter
				{
					ConvertToString = (object obj, Type _) => ((StringList)obj).ToString(),
					ConvertToObject = delegate(string str, Type _)
					{
						CheckPerformance(str);
						return Parse(str);
						static void CheckPerformance(string s)
						{
							if (!string.IsNullOrEmpty(s))
							{
								AccessCount[s]++;
								if (AccessCount[s] > 2)
								{
									Log.Warning("Possible performance issue. (ConfigWatcher maybe?) " + $"ConvertToObject access count {AccessCount[s]} > {2}: \"{s}\"", ".cctor", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Config.cs");
								}
							}
						}
					}
				});
			}

			public IEnumerable<string[]> Split(char splitChar = ':', bool trim = true)
			{
				List<string[]> list = new List<string[]>();
				using List<string>.Enumerator enumerator = GetEnumerator();
				while (enumerator.MoveNext())
				{
					string[] array = enumerator.Current.Split(new char[1] { splitChar });
					if (trim)
					{
						array = array.Select((string s) => s.Trim()).ToArray();
					}
					list.Add(array);
				}
				return list;
			}

			public (string Name, string Value)[] ToTuple(char splitChar = ':')
			{
				return (from element in Split(splitChar)
					select (element[0], element[1])).ToArray();
			}

			public Requirement[] ToRequirements()
			{
				return ((IEnumerable<RequirementConfig>)ToRequirementConfigs()).Select((Func<RequirementConfig, Requirement>)((RequirementConfig config) => new Requirement
				{
					m_resItem = ObjectDB.instance.GetItemPrefab(config.Item).GetComponent<ItemDrop>(),
					m_amount = config.Amount,
					m_amountPerLevel = config.AmountPerLevel,
					m_recover = config.Recover
				})).ToArray();
			}

			public RequirementConfig[] ToRequirementConfigs()
			{
				return Split().Select<string[], RequirementConfig>((Func<string[], RequirementConfig>)((string[] element) => new RequirementConfig(element[0], int.Parse(element[1]), (element.Length > 2) ? int.Parse(element[2]) : 0, element.Length <= 3 || bool.Parse(element[3])))).ToArray();
			}
		}

		internal static AcceptableValueBase AcceptRange<T>(T min, T max) where T : IComparable
		{
			return (AcceptableValueBase)(object)new AcceptableValueRange<T>(min, max);
		}

		internal static AcceptableValueBase AcceptList<T>(params T[] list) where T : IEquatable<T>
		{
			return (AcceptableValueBase)(object)new AcceptableValueList<T>(list);
		}

		internal static ConfigEntry<T> DefineConfig<T>(bool isAdmin, string section, string key, T defaultValue, AcceptableValueBase? acceptableValues = null, string description = "")
		{
			//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_003a: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			return ((BaseUnityPlugin)ZenPlugin.Instance).Config.Bind<T>(section, key, defaultValue, new ConfigDescription((isAdmin ? "[Admin] " : "") + description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = isAdmin
			} }));
		}
	}
	public static class FireplaceExt
	{
		public static int FuelDays(this Fireplace fireplace, float? fuel = null)
		{
			float valueOrDefault = fuel.GetValueOrDefault();
			if (!fuel.HasValue)
			{
				valueOrDefault = fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f);
				fuel = valueOrDefault;
			}
			return UI.RealToGameTime(fuel.Value * fireplace.m_secPerFuel).Days;
		}

		public static int FuelDaysMax(this Fireplace fireplace)
		{
			return UI.RealToGameTime(fireplace.m_maxFuel * fireplace.m_secPerFuel).Days;
		}

		public static bool IsFuelDaysFull(this Fireplace fireplace, float? fuel = null)
		{
			if (fireplace.m_infiniteFuel)
			{
				return true;
			}
			int num = fireplace.FuelDays(fuel);
			if (num > 0)
			{
				return num >= fireplace.FuelDaysMax();
			}
			return false;
		}

		public static bool IsFuelDaysEmpty(this Fireplace fireplace, float? fuel = null)
		{
			if (!fireplace.m_infiniteFuel)
			{
				return fireplace.FuelDays(fuel) <= 0;
			}
			return false;
		}

		public static bool IsFuelEmpty(this Fireplace fireplace)
		{
			if (!fireplace.m_infiniteFuel)
			{
				return fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) <= 0f;
			}
			return false;
		}
	}
	internal static class HudExt
	{
		public static void UpdateHoverIcons(this Hud hud, params (Sprite Icon, string Label)[] elements)
		{
			((Component)hud).SendMessage("UpdateHoverIcons", (object)elements, (SendMessageOptions)1);
		}

		public static void UpdateHoverIcons(this Hud hud, params (string prefabName, string Label)[] elements)
		{
			((Component)hud).SendMessage("UpdateHoverIcons", (object)elements, (SendMessageOptions)1);
		}

		public static void UpdateHoverIcons(this Hud hud, params Sprite[] sprites)
		{
			((Component)hud).SendMessage("UpdateHoverIcons", (object)sprites, (SendMessageOptions)1);
		}

		public static void UpdateHoverIcons(this Hud hud, params string[] prefabNames)
		{
			((Component)hud).SendMessage("UpdateHoverIcons", (object)prefabNames, (SendMessageOptions)1);
		}
	}
	public static class HumanoidExt
	{
		public static MonoBehaviour? GetHoverInteractable(this Humanoid self)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			GameObject hoverObject = self.GetHoverObject();
			return (MonoBehaviour)(Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<Interactable>() : null);
		}

		public static bool IsUnarmed(this Humanoid self)
		{
			if (self.GetLeftItem() == null)
			{
				return self.GetRightItem() == null;
			}
			return false;
		}

		public static bool IsUsingRangedWeapon(this Humanoid self)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//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_0043: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			if (self.IsUnarmed())
			{
				return false;
			}
			ItemData currentWeapon = self.GetCurrentWeapon();
			AttackType attackType = currentWeapon.m_shared.m_attack.m_attackType;
			if (((int)attackType == 2 || (int)attackType == 5) ? true : false)
			{
				return true;
			}
			ItemType itemType = currentWeapon.m_shared.m_itemType;
			if ((int)itemType != 3 && (int)itemType != 14)
			{
				return (int)itemType != 22;
			}
			return false;
		}

		public static bool IsUsingTool(this Humanoid self, bool includeFishigRod)
		{
			if (!self.RightItem.IsItemType((ItemType)19) && !self.LeftItem.IsItemType((ItemType)19))
			{
				if (includeFishigRod)
				{
					return self.GetCurrentWeapon()?.GetName() == "$item_fishingrod";
				}
				return false;
			}
			return true;
		}

		public static bool IsUsingPickAxe(this Humanoid self)
		{
			if (!IsPickAxe(self.RightItem))
			{
				return IsPickAxe(self.LeftItem);
			}
			return true;
			static bool IsPickAxe(ItemData? item)
			{
				if (item != null)
				{
					return item.m_shared.m_damages.m_pickaxe > 0f;
				}
				return false;
			}
		}
	}
	public static class IEnumerableExt
	{
		public static IEnumerable<(T Item, int Index)> WithIndex<T>(this IEnumerable<T> self)
		{
			return self.Select((T obj, int index) => (obj, index));
		}
	}
	public static class ItemDataExt
	{
		public static bool IsItemType(this ItemData? item, ItemType type)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (item == null)
			{
				return false;
			}
			return item.m_shared.m_itemType == type;
		}

		public static bool IsStackable(this ItemData item)
		{
			return item.m_shared.m_maxStackSize > 1;
		}

		public static bool IsStackable(this ItemDrop item)
		{
			return item.m_itemData.m_shared.m_maxStackSize > 1;
		}

		public static string GetPrefabName(this ItemDrop itemDrop)
		{
			return Utils.GetPrefabName(((Object)itemDrop).name);
		}

		public static string GetPrefabName(this ItemData item)
		{
			if (!Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return ((Object)ObjectDB.instance.GetItemPrefab(item.m_shared)).name;
			}
			return ((Object)item.m_dropPrefab).name;
		}

		public static string GetName(this ItemData item)
		{
			return item.m_shared.m_name;
		}

		public static string GetName(this ItemDrop item)
		{
			return item.m_itemData.m_shared.m_name;
		}

		public static Sprite GetIcon(this ItemData item, int variant)
		{
			return item.m_shared.m_icons[variant];
		}

		public static Sprite GetIcon(this ItemDrop item)
		{
			return item.m_itemData.GetIcon();
		}

		public static Sprite GetIcon(this ItemDrop item, int variant)
		{
			return item.m_itemData.GetIcon(variant);
		}

		public static int GetStableHashCode(this ItemDrop item)
		{
			return StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(((Object)item).name));
		}

		public static bool IsEqual(this ItemData item, ItemData other)
		{
			if (!(((Object)item.m_dropPrefab).name == ((Object)other.m_dropPrefab).name) || !(item.GetName() == other.GetName()) || item.m_variant != other.m_variant || item.m_quality != other.m_quality || !Mathf.Approximately(item.m_durability, other.m_durability))
			{
				return false;
			}
			foreach (KeyValuePair<string, string> customDatum in item.m_customData)
			{
				if (!other.m_customData.TryGetValue(customDatum.Key, out var value))
				{
					return false;
				}
				if (value != customDatum.Value)
				{
					return false;
				}
			}
			return true;
		}

		public static bool HaveItemData(this Inventory inventory, ItemData itemData)
		{
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.IsEqual(itemData))
				{
					return true;
				}
			}
			return false;
		}

		public static void SwapItem(this Inventory thisInv, ItemData thisItem, Inventory otherInv, ItemData otherItem)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			Vector2i gridPos = thisItem.m_gridPos;
			Vector2i gridPos2 = otherItem.m_gridPos;
			bool equipped = thisItem.m_equipped;
			bool equipped2 = otherItem.m_equipped;
			thisInv.RemoveItem(thisItem);
			otherInv.RemoveItem(otherItem);
			thisInv.AddItem(otherItem, gridPos);
			otherInv.AddItem(thisItem, gridPos2);
			Player player = Player.m_localPlayer;
			if (equipped)
			{
				SwitchEquipped(thisItem, otherItem);
			}
			else if (equipped2)
			{
				SwitchEquipped(otherItem, thisItem);
			}
			void SwitchEquipped(ItemData a, ItemData b)
			{
				//IL_0013: 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)
				((Humanoid)player).UnequipItem(a, false);
				if (a.m_shared.m_itemType == b.m_shared.m_itemType || (a.IsWeapon() && b.IsWeapon()))
				{
					((Humanoid)player).EquipItem(b, false);
				}
			}
		}
	}
	public static class ItemStandExt
	{
		public static bool IsBossStone(this ItemStand itemStand)
		{
			return Object.op_Implicit((Object)(object)itemStand.m_guardianPower);
		}

		public static bool CanBeRemoved(this ItemStand itemStand)
		{
			return itemStand.m_canBeRemoved;
		}
	}
	public static class MathExt
	{
		public static bool InRange(this GameObject self, GameObject target, float range)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(self.transform.position - target.transform.position) < range * range;
		}

		public static bool InRange(this GameObject self, Vector3 target, float range)
		{
			//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)
			return Vector3.SqrMagnitude(self.transform.position - target) < range * range;
		}

		public static bool InRange(this MonoBehaviour self, Vector3 target, float range)
		{
			//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)
			return Vector3.SqrMagnitude(((Component)self).transform.position - target) < range * range;
		}

		public static bool InRange(this MonoBehaviour self, MonoBehaviour target, float range)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(((Component)self).transform.position - ((Component)target).transform.position) < range * range;
		}

		public static bool InRange(this MonoBehaviour self, GameObject target, float range)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(((Component)self).transform.position - target.transform.position) < range * range;
		}

		public static float DistanceToSqr(this GameObject self, Vector3 target)
		{
			//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)
			return Vector3.SqrMagnitude(self.transform.position - target);
		}

		public static float DistanceToSqr(this MonoBehaviour self, MonoBehaviour target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(((Component)self).transform.position - ((Component)target).transform.position);
		}

		public static float DistanceToSqr(this MonoBehaviour self, Vector3 target)
		{
			//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)
			return Vector3.SqrMagnitude(((Component)self).transform.position - target);
		}

		public static float DistanceToSqr(this Vector3 source, Vector3 target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(source - target);
		}

		public static float DistanceToXZ(this GameObject self, GameObject target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return self.transform.position.DistanceToXZ(target.transform.position);
		}

		public static float DistanceToXZ(this MonoBehaviour self, MonoBehaviour target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)self).transform.position.DistanceToXZ(((Component)target).transform.position);
		}

		public static float DistanceToXZ(this MonoBehaviour self, Vector3 target)
		{
			//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)
			return ((Component)self).transform.position.DistanceToXZ(target);
		}

		public static float DistanceToXZ(this Vector3 source, Vector3 target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = source;
			val.y = 0f;
			Vector3 val2 = val;
			val = target;
			val.y = 0f;
			return Vector3.Distance(val2, val);
		}

		public static float DistanceTo(this GameObject self, GameObject target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return self.transform.position.DistanceTo(target.transform.position);
		}

		public static float DistanceTo(this MonoBehaviour self, MonoBehaviour target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)self).transform.position.DistanceTo(((Component)target).transform.position);
		}

		public static float DistanceTo(this MonoBehaviour self, Vector3 target)
		{
			//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)
			return ((Component)self).transform.position.DistanceTo(target);
		}

		public static float DistanceTo(this Vector3 source, Vector3 target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(source, target);
		}

		public static bool Approximately(this Vector3 self, Vector3 other)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(self - other) < 0.0001f;
		}

		public static Vector3 XZY(this Vector3 self)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(self.x, self.z, self.y);
		}

		public static float DistanceToPlayer(this Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return position.DistanceToCharacter((Character)(object)Player.m_localPlayer);
		}

		public static float DistanceToCharacter(this Vector3 position, Character c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Sqrt(position.DistanceToCharacterSqr(c));
		}

		public static float DistanceToCharacterSqr(this Vector3 position, Character c)
		{
			//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)
			return Vector3.SqrMagnitude(((Component)c).transform.position - position);
		}

		public static float AngleFromPlayer(this Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return position.AngleFromCharacter((Character)(object)Player.m_localPlayer);
		}

		public static float AngleFromCharacter(this Vector3 position, Character c)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)c).transform;
			Vector3 val = position - transform.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.SignedAngle(transform.forward, normalized, Vector3.up);
		}

		public static float AngleFromCamera(this Vector3 position)
		{
			//IL_0010: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_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_002c: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)GameCamera.instance.m_camera).transform;
			Vector3 val = position - transform.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.SignedAngle(transform.forward, normalized, Vector3.up);
		}

		public static float AlignmentRatioTo(this Transform transform, Vector3 destPosition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = destPosition - transform.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return Vector3.Dot(transform.forward, normalized);
		}
	}
	public static class MessageHudExt
	{
		public static void ShowMessage(this MessageHud msgHud, long targetPeerID, MessageType type, string text)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected I4, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(targetPeerID, "ShowMessage", new object[2]
			{
				(int)type,
				text
			});
		}
	}
	public static class PlayerExt
	{
		public static bool IsReady(this Player? player)
		{
			if (Object.op_Implicit((Object)(object)player) && !((Character)player).IsDead())
			{
				return !((Character)player).IsTeleporting();
			}
			return false;
		}

		public static bool Is(this Player? player, Character other)
		{
			if (player.IsReady())
			{
				return (Object)(object)player == (Object)(object)other;
			}
			return false;
		}

		public static void SelectRepairTool(this Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			player.SetSelectedPiece(Vector2Int.zero);
		}

		public static void RemoveGuardianPower(this Player player)
		{
			player.m_guardianPower = string.Empty;
			player.m_guardianPowerHash = 0;
			player.m_guardianSE = null;
		}
	}
	public static class StringExt
	{
		public static string ToHumanString(this int num)
		{
			if (num >= 1000000)
			{
				if (num >= 1000000000)
				{
					return "∞";
				}
				return $"{Mathf.Round((float)num / 1000000f):0}M";
			}
			if (num >= 10000)
			{
				return $"{Mathf.Round((float)num / 1000f):0}K";
			}
			return num.ToString();
		}

		public static string Localize(this string? s)
		{
			return Localization.instance.Localize(s);
		}

		public static string ToProperCase(this string? str)
		{
			return str?[0].ToString().ToUpper() + str?.Substring(1).ToLower();
		}

		public static string RegexPattern(this string? pattern, bool localize = true)
		{
			return pattern.RegexPattern((string s) => s, localize);
		}

		public static string RegexPattern(this string? pattern, Func<string, string> func, bool localize = true)
		{
			return Regex.Escape(func(localize ? pattern.Localize() : (pattern ?? string.Empty)));
		}

		public static string GlyphFix(this string s, bool onlyIfGamepad = true)
		{
			if (!ZInput.IsGamepadActive() && onlyIfGamepad)
			{
				return s;
			}
			return s.Replace("[<color=yellow><b><sprite=", "<sprite=").Replace("\"></b></color>]", "\">");
		}
	}
	public static class WardAccessExt
	{
		public static bool CanAccessWard(this GameObject self, bool flash)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return self.transform.position.CanAccessWard(flash);
		}

		public static bool CanAccessWard(this MonoBehaviour self, bool flash)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)self).transform.position.CanAccessWard(flash);
		}

		public static bool CanAccessWard(this Vector3 self, bool flash)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return PrivateArea.CheckAccess(self, 0f, flash, false);
		}
	}
	public static class ZdoExt
	{
		private static readonly int ZdoKeyEpochStart = StringExtensionMethods.GetStableHashCode("Zen_EpochStart");

		private static bool HasEpoch(this ZDO zdo)
		{
			return zdo.GetEpoch() != 0.0;
		}

		private static double GetEpoch(this ZDO zdo)
		{
			return zdo.GetDouble(ZdoKeyEpochStart);
		}

		public static float GetAgeSeconds(this ZDO zdo)
		{
			return (float)(ZNet.instance.GetTimeSeconds() - zdo.GetEpoch());
		}

		public static void AccelerateAge(this ZDO zdo, float seconds)
		{
			if (!zdo.IsOwner())
			{
				Log.Error("Cannot age this ZDO, not owner.", "AccelerateAge", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Extensions\\ZdoExt.cs");
				return;
			}
			double value = Math.Max(zdo.GetEpoch() - (double)seconds, 0.0);
			zdo.Set(ZdoKeyEpochStart, value);
		}

		public static void RemoveEpoch(this ZDO zdo)
		{
			if (!zdo.IsOwner())
			{
				Log.Error("Cannot remove epoch time because not owner of this ZDO.", "RemoveEpoch", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Extensions\\ZdoExt.cs");
			}
			else
			{
				zdo.Set(ZdoKeyEpochStart, 0.0);
			}
		}

		public static void InitEpoch(this ZDO zdo)
		{
			if (!zdo.IsOwner())
			{
				Log.Error("Cannot init epoch time because not owner of this ZDO.", "InitEpoch", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Extensions\\ZdoExt.cs");
			}
			else if (!zdo.HasEpoch())
			{
				zdo.Set(ZdoKeyEpochStart, ZNet.instance.GetTimeSeconds());
			}
		}

		public static string GetPrefabName(this ZDO zdo)
		{
			return ((Object)ZNetScene.instance.GetPrefab(zdo.GetPrefab())).name;
		}

		public static double GetDouble(this ZDO zdo, string name, double defaultValue = 0.0)
		{
			return zdo.GetDouble(StringExtensionMethods.GetStableHashCode(name), defaultValue);
		}

		public static double GetDouble(this ZDO zdo, int hash, double defaultValue = 0.0)
		{
			long num = BitConverter.DoubleToInt64Bits(defaultValue);
			return BitConverter.Int64BitsToDouble(zdo.GetLong(hash, num));
		}

		public static void Set(this ZDO zdo, string name, double value)
		{
			zdo.Set(StringExtensionMethods.GetStableHashCode(name), value);
		}

		public static void Set(this ZDO zdo, int hash, double value)
		{
			long num = BitConverter.DoubleToInt64Bits(value);
			zdo.Set(hash, num);
		}
	}
	public static class ZInputExt
	{
		public static string Path(this GamepadInput g)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return ZInput.s_gamepadInputPathMap[g];
		}

		public static string Path(this MouseButton m)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ZInput.MouseButtonToPath(m, true);
		}

		public static string Path(this KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ZInput.KeyCodeToPath(k, false);
		}

		public static string Path(this Key k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ZInput.KeyToPath(k);
		}

		public static ButtonDef GetButtonDef(this ZInput self, ActionString actionString)
		{
			return self.GetButtonDef(actionString.Name);
		}

		public static bool RemoveButton(this ZInput self, string name)
		{
			if (!self.m_buttons.TryGetValue(name, out var value))
			{
				return false;
			}
			Log.Info("Remove Button: " + name, "RemoveButton", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Extensions\\ZInputExt.cs");
			self.UnsubscribeButton(value);
			self.m_buttons.Remove(value.Name);
			return true;
		}

		private static bool RemapToPath(this ButtonDef self, string newPath, bool? altKey = null, bool? showHints = null, bool? rebindable = null, float? repeatDelay = null, float? repeatInterval = null)
		{
			if (self.GetActionPath(true) == newPath && (!altKey.HasValue || altKey == self.AltKey) && (!showHints.HasValue || showHints == self.ShowHints) && (!rebindable.HasValue || rebindable == self.Rebindable) && (!repeatDelay.HasValue || Mathf.Approximately(repeatDelay.Value, self.m_repeatDelay)) && (!repeatInterval.HasValue || Mathf.Approximately(repeatInterval.Value, self.m_repeatInterval)))
			{
				return false;
			}
			self.Rebind(newPath);
			if (altKey.HasValue)
			{
				self.AltKey = altKey.Value;
			}
			if (showHints.HasValue)
			{
				self.ShowHints = showHints.Value;
			}
			if (rebindable.HasValue)
			{
				self.Rebindable = rebindable.Value;
			}
			if (repeatDelay.HasValue)
			{
				self.m_repeatDelay = repeatDelay.Value;
			}
			if (repeatInterval.HasValue)
			{
				self.m_repeatInterval = repeatInterval.Value;
			}
			return true;
		}

		public static bool RemapTo(this ButtonDef self, KeyCode newInput, bool? altKey = null, bool? showHints = null, bool? rebindable = null, float? repeatDelay = null, float? repeatInterval = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return self.RemapToPath(newInput.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public static bool RemapTo(this ButtonDef self, GamepadInput newInput, bool? altKey = null, bool? showHints = null, bool? rebindable = null, float? repeatDelay = null, float? repeatInterval = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return self.RemapToPath(newInput.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public static string GetGamepadPlatform(this ZInput zi)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_0024: 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_0028: Invalid comparison between Unknown and I4
			GamepadGlyphs currentGlyph = ZInput.CurrentGlyph;
			switch ((int)currentGlyph)
			{
			case 0:
			{
				GamepadType connectedGamepadType = ZInput.ConnectedGamepadType;
				return ((int)connectedGamepadType == 3) ? "xbox" : ((connectedGamepadType - 4 > 1) ? "xbox" : "ps5");
			}
			case 1:
				return "xbox";
			case 2:
				return "ps5";
			default:
				return "xbox";
			}
		}

		public static string GetGamepadSpriteName(this ZInput zi, GamepadInput gamepadInput, string platform)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			string key = zi.MapKeyFromPath(ZInput.s_gamepadInputPathMap[gamepadInput]);
			return ZInput.s_gamepadSpriteMap[key][platform];
		}

		public static string GetSpriteTag(this ZInput zi, GamepadInput gamepadInput)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			string gamepadPlatform = zi.GetGamepadPlatform();
			string gamepadSpriteName = zi.GetGamepadSpriteName(gamepadInput, gamepadPlatform);
			return "<sprite=\"" + gamepadPlatform + "\" name=\"" + gamepadSpriteName + "\">";
		}
	}
	public static class ZRoutedRpcExt
	{
		public static void Unregister(this ZRoutedRpc? zrpc, string name)
		{
			if (zrpc != null && zrpc.m_functions.Remove(StringExtensionMethods.GetStableHashCode(name)))
			{
				Log.Info("Unregistered RPC: " + name, "Unregister", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Extensions\\ZRoutedRpcExt.cs");
			}
		}
	}
	[HarmonyPatch]
	public static class FixVanilla
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Player), "AddUniqueKey")]
		private static IEnumerable<CodeInstruction> Player_AddUniqueKey_Transpiler(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(HashSet<string>), "Contains", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(FixVanilla), "HashSet_Contains_Intercept", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		private static bool HashSet_Contains_Intercept(HashSet<string> self, string? item)
		{
			Log.Info("Fixed: Player key can not be blank", "HashSet_Contains_Intercept", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\FixVanilla.cs");
			self.Remove(string.Empty);
			self.Remove(null);
			if (!Utility.IsNullOrWhiteSpace(item))
			{
				return self.Contains(item);
			}
			return true;
		}
	}
	public interface IRedecorate
	{
		void OnRedecorateBefore();

		void OnRedecorateAfter((Vector3 Position, Quaternion Rotation) before);
	}
	public enum HintType
	{
		Build,
		Combat,
		Bow,
		Inventory,
		Barber,
		Fishing,
		Radial
	}
	[HarmonyPatch]
	public static class KeyHint
	{
		private static HintType _activeType;

		private static readonly Dictionary<string, (GameObject Keyboard, GameObject Gamepad)> AllHints = new Dictionary<string, (GameObject, GameObject)>();

		private const string Section = "_SECTION_";

		private static readonly string[] ControlPaths = new string[2] { "Keyboard/_SECTION_/Text", "Gamepad/Text - _SECTION_" };

		private static float _lastUpdateTime;

		private const float _updateDelay = 0.1f;

		public static event Action? UpdateBuildHints;

		public static event Action? UpdateCombatHints;

		public static event Action? UpdateBowHints;

		public static event Action? UpdateInventoryHints;

		public static event Action? UpdateBarberHints;

		public static event Action? UpdateFishingHints;

		public static event Action? UpdateRadialHints;

		internal static void RemoveAll()
		{
			foreach (var value in AllHints.Values)
			{
				Object.Destroy((Object)(object)value.Keyboard);
				Object.Destroy((Object)(object)value.Gamepad);
			}
			AllHints.Clear();
			KeyHint.UpdateBuildHints = null;
			KeyHint.UpdateCombatHints = null;
			KeyHint.UpdateBowHints = null;
			KeyHint.UpdateInventoryHints = null;
			KeyHint.UpdateBarberHints = null;
			KeyHint.UpdateFishingHints = null;
			KeyHint.UpdateRadialHints = null;
		}

		private static GameObject GetHintRoot(HintType hintType)
		{
			return (GameObject)(hintType switch
			{
				HintType.Build => KeyHints.instance.m_buildHints, 
				HintType.Combat => KeyHints.instance.m_combatHints, 
				HintType.Bow => KeyHints.instance.m_combatHints, 
				HintType.Inventory => KeyHints.instance.m_inventoryHints, 
				HintType.Barber => KeyHints.instance.m_barberHints, 
				HintType.Fishing => KeyHints.instance.m_fishingHints, 
				HintType.Radial => KeyHints.instance.m_radialHints, 
				_ => throw new ArgumentOutOfRangeException("hintType", hintType, null), 
			});
		}

		public static void Create(HintType hintType, ActionString action, int index = -1, bool startVisible = false)
		{
			Create(hintType, action.Name, index, startVisible);
		}

		public static void Create(HintType hintType, string hintName, int index = -1, bool startVisible = false)
		{
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			GameObject hintRoot = GetHintRoot(hintType);
			(GameObject, GameObject) value = default((GameObject, GameObject));
			Transform val = hintRoot.transform.Find("Keyboard");
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val.GetChild(0)).gameObject, val);
			if (index >= 0)
			{
				val2.transform.SetSiblingIndex(index);
			}
			((Object)val2).name = hintName;
			((Component)val2.transform.Find("Text")).GetComponent<TMP_Text>().text = "$" + hintName;
			((Component)val2.transform.Find("key_bkg/Key")).GetComponent<TMP_Text>().text = "$KEY_" + hintName;
			value.Item1 = val2;
			val2.SetActive(startVisible);
			Transform val3 = hintRoot.transform.Find("Gamepad");
			GameObject val4 = Object.Instantiate<GameObject>(((Component)val3.GetChild(0)).gameObject, val3);
			if (index >= 0)
			{
				val4.transform.SetSiblingIndex(index);
			}
			((Object)val4).name = "Text - " + hintName;
			val4.GetComponent<TMP_Text>().text = "$" + hintName + "   <mspace=0.6em>$KEY_Joy" + hintName + "</mspace>";
			value.Item2 = val4;
			foreach (Transform item in val3)
			{
				((Object)item).name = ((Object)item).name.Replace("/", "-");
			}
			val4.SetActive(startVisible);
			AllHints.Add(hintName, value);
			Localization.instance.Localize(hintRoot.transform);
		}

		public static void SetVisible(ActionString action, bool isVisible)
		{
			SetVisible(_activeType, action.Name, isVisible);
		}

		public static void SetVisible(string hintName, bool isVisible)
		{
			SetVisible(_activeType, hintName, isVisible);
		}

		private static void SetVisible(HintType hintType, string hintName, bool isVisible, string[]? searchPaths = null)
		{
			string[] array = searchPaths ?? ControlPaths;
			foreach (string text in array)
			{
				bool flag = text.StartsWith("Gamepad");
				if (flag && hintName == "Copy")
				{
					SetVisible(hintType, "Copy Alt1-2", isVisible && ZInput.IsNonClassicFunctionality(), new string[1] { text });
					SetVisible(hintType, "Copy Default", isVisible && !ZInput.IsNonClassicFunctionality(), new string[1] { text });
					break;
				}
				string text2 = text.Replace("_SECTION_", hintName);
				Transform val = GetHintRoot(hintType).transform.Find(text2);
				if (!Object.op_Implicit((Object)(object)val))
				{
					Log.Error("Node not found: " + text2, "SetVisible", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\KeyHint.cs");
					break;
				}
				if (flag)
				{
					((Component)val).gameObject.SetActive(isVisible);
				}
				else
				{
					((Component)val.parent).gameObject.SetActive(isVisible);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(KeyHints), "UpdateHints")]
		private static void KeyHints_UpdateHints(KeyHints __instance)
		{
			if (__instance.m_keyHintsEnabled && (UI.IsOpen || !(Time.time < _lastUpdateTime + 0.1f)))
			{
				_lastUpdateTime = Time.time;
				if (__instance.m_buildHints.activeSelf)
				{
					_activeType = HintType.Build;
					KeyHint.UpdateBuildHints?.Invoke();
				}
				if (__instance.m_inventoryHints.activeSelf)
				{
					_activeType = HintType.Inventory;
					KeyHint.UpdateInventoryHints?.Invoke();
				}
				if (__instance.m_combatHints.activeSelf)
				{
					_activeType = HintType.Combat;
					KeyHint.UpdateCombatHints?.Invoke();
				}
				if (__instance.m_combatHints.activeSelf && ((Humanoid)(object)Player.m_localPlayer).IsUsingRangedWeapon())
				{
					_activeType = HintType.Bow;
					KeyHint.UpdateBowHints?.Invoke();
				}
				if (__instance.m_fishingHints.activeSelf)
				{
					_activeType = HintType.Fishing;
					KeyHint.UpdateFishingHints?.Invoke();
				}
				if (__instance.m_barberHints.activeSelf)
				{
					_activeType = HintType.Barber;
					KeyHint.UpdateBarberHints?.Invoke();
				}
				if (__instance.m_radialHints.activeSelf)
				{
					_activeType = HintType.Radial;
					KeyHint.UpdateRadialHints?.Invoke();
				}
			}
		}
	}
	internal static class Log
	{
		private static readonly LogLevel LogLevels;

		private static bool IsEnabled
		{
			get
			{
				if (Object.op_Implicit((Object)(object)ZenPlugin.Instance))
				{
					return ZenPlugin.IsLogEnabled.Value;
				}
				return false;
			}
		}

		private static ManualLogSource Logger => ZenPlugin.InstanceLogger;

		static Log()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<LogLevel> val = default(ConfigEntry<LogLevel>);
			if (!((ConfigFile)AccessTools.Property(typeof(ConfigFile), "CoreConfig").GetValue(null)).TryGetEntry<LogLevel>("Logging.Disk", "LogLevels", ref val))
			{
				throw new Exception("Log levels config info missing");
			}
			LogLevels = val.Value;
		}

		private static string Format(object data, string caller, string filePath)
		{
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
			return $"[{fileNameWithoutExtension}.{caller}] {data}";
		}

		public static void Debug(object data, [CallerMemberName] string caller = "", [CallerFilePath] string filePath = "")
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (IsEnabled && ((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)32))
			{
				Logger.LogDebug((object)Format(data, caller, filePath));
			}
		}

		public static void Info(object data, [CallerMemberName] string caller = "", [CallerFilePath] string filePath = "")
		{
			if (IsEnabled)
			{
				Logger.LogInfo((object)Format(data, caller, filePath));
			}
		}

		public static void Message(object data, [CallerMemberName] string caller = "", [CallerFilePath] string filePath = "")
		{
			Logger.LogMessage((object)Format(data, caller, filePath));
		}

		public static void Warning(object data, [CallerMemberName] string caller = "", [CallerFilePath] string filePath = "")
		{
			Logger.LogWarning((object)Format(data, caller, filePath));
		}

		public static void Error(object data, [CallerMemberName] string caller = "", [CallerFilePath] string filePath = "")
		{
			Logger.LogError((object)Format(data, caller, filePath));
		}

		public static void Fatal(object data, [CallerMemberName] string caller = "", [CallerFilePath] string filePath = "")
		{
			Logger.LogFatal((object)Format(data, caller, filePath));
		}
	}
	internal static class Secure
	{
		public static string Encrypt(string plainText, byte[] key, Encoding? encoding = null)
		{
			return Convert.ToBase64String(Encrypt((encoding ?? Encoding.UTF8).GetBytes(plainText), key).ToArray());
		}

		public static byte[] Encrypt(byte[] input, byte[] key)
		{
			using Aes aes = Aes.Create();
			aes.Key = key;
			using ICryptoTransform cryptoTransform = aes.CreateEncryptor();
			byte[] collection = cryptoTransform.TransformFinalBlock(input, 0, input.Length);
			List<byte> list = new List<byte>();
			list.AddRange(aes.IV);
			list.AddRange(collection);
			aes.Clear();
			return list.ToArray();
		}

		public static string Decrypt(string cipherBase64, byte[] key, Encoding? encoding = null)
		{
			byte[] bytes = Decrypt(Convert.FromBase64String(cipherBase64), key);
			return (encoding ?? Encoding.UTF8).GetString(bytes);
		}

		public static byte[] Decrypt(byte[] input, byte[] key)
		{
			try
			{
				using Aes aes = Aes.Create();
				aes.Key = key;
				aes.IV = input.Take(aes.BlockSize / 8).ToArray();
				byte[] array = input.Skip(aes.IV.Length).ToArray();
				using ICryptoTransform cryptoTransform = aes.CreateDecryptor();
				byte[] result = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
				aes.Clear();
				return result;
			}
			catch
			{
				return Array.Empty<byte>();
			}
		}

		public static byte[] GenerateAesKey()
		{
			using Aes aes = Aes.Create();
			return aes.Key;
		}

		public static byte[] DeriveKey(string password, byte[] salt, int iterations = 10000, int keyLength = 32)
		{
			using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, iterations);
			return rfc2898DeriveBytes.GetBytes(keyLength);
		}

		public static byte[] GenerateSalt(int saltLength = 32)
		{
			using RNGCryptoServiceProvider rNGCryptoServiceProvider = new RNGCryptoServiceProvider();
			byte[] array = new byte[saltLength];
			rNGCryptoServiceProvider.GetBytes(array);
			return array;
		}

		public static byte[] FromHexStringToBytes(this string hexString)
		{
			try
			{
				byte[] array = new byte[hexString.Length / 2];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
				}
				return array;
			}
			catch
			{
				throw new InvalidDataException("HexString is not valid for conversion to bytes");
			}
		}
	}
	public class Tally<T> : Dictionary<T, int>
	{
		public new int this[T key]
		{
			get
			{
				if (!TryGetValue(key, out var value))
				{
					return 0;
				}
				return value;
			}
			set
			{
				base[key] = value;
			}
		}

		public HashSet<T> Diff(Tally<T>? other)
		{
			HashSet<T> hashSet;
			if (other == null)
			{
				hashSet = new HashSet<T>();
				{
					foreach (T key in base.Keys)
					{
						hashSet.Add(key);
					}
					return hashSet;
				}
			}
			IEnumerable<KeyValuePair<T, int>> first = this.Except<KeyValuePair<T, int>>(other);
			IEnumerable<KeyValuePair<T, int>> second = other.Except<KeyValuePair<T, int>>(this);
			hashSet = new HashSet<T>();
			foreach (T item in from item in first.Union(second)
				select item.Key)
			{
				hashSet.Add(item);
			}
			return hashSet;
		}

		public IEnumerable<(T Key, int Amount)> Sorted()
		{
			return this.OrderByDescending(delegate(KeyValuePair<T, int> pair)
			{
				KeyValuePair<T, int> keyValuePair2 = pair;
				return keyValuePair2.Value;
			}).Select(delegate(KeyValuePair<T, int> pair)
			{
				KeyValuePair<T, int> keyValuePair = pair;
				T key = keyValuePair.Key;
				keyValuePair = pair;
				return (key, keyValuePair.Value);
			});
		}
	}
	public static class TallyExt
	{
		public static Tally<T> SumItems<T>(this Inventory inv, Func<ItemData, T> callback)
		{
			Tally<T> tally = new Tally<T>();
			foreach (ItemData allItem in inv.GetAllItems())
			{
				tally[callback(allItem)] += allItem.m_stack;
			}
			return tally;
		}

		public static Tally<string> SumItemsByName(this Inventory inv)
		{
			return inv.SumItems((ItemData item) => item.GetName());
		}

		public static Tally<string> SumItemsByPrefabName(this Inventory inv)
		{
			return inv.SumItems((ItemData item) => item.GetPrefabName());
		}
	}
	public static class TerminalCommand
	{
		private static readonly List<string> Commands = new List<string>();

		public static ConsoleCommand Create(string name, string description, bool isCheat, Action<string[]> action)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			Action<string[]> action2 = action;
			string text = ((BaseUnityPlugin)ZenPlugin.Instance).Info.Metadata.Name + "_" + name;
			Commands.Add(text);
			Log.Info("Terminal command added: " + text, "Create", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\TerminalCommand.cs");
			return new ConsoleCommand(text, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				action2(args.Args);
			}, isCheat, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		internal static void Cleanup()
		{
			foreach (string command in Commands)
			{
				Terminal.commands.Remove(command.ToLower());
			}
			Commands.Clear();
		}
	}
	public static class UIColor
	{
		public struct ZColor
		{
			public string Hex { get; }

			public Color Color { get; }

			public ZColor(Color32 c)
				: this(c.r, c.g, c.b, c.a)
			{
			}//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)


			public ZColor(byte r, byte g, byte b, byte a)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				Color = Color32.op_Implicit(new Color32(r, g, b, a));
				Hex = ColorUtility.ToHtmlStringRGBA(Color);
			}

			public override string ToString()
			{
				return "#" + Hex;
			}
		}

		public static readonly ZColor Gray = new ZColor(170, 170, 170, byte.MaxValue);

		public static readonly ZColor Teal = new ZColor(170, byte.MaxValue, 170, byte.MaxValue);

		public static readonly ZColor Red = new ZColor(204, 0, 0, byte.MaxValue);

		public static readonly ZColor Purple = new ZColor(147, 49, 189, byte.MaxValue);

		public static readonly ZColor Yellow = new ZColor(Color32.op_Implicit(Color.yellow));

		public static readonly ZColor Orange = new ZColor(byte.MaxValue, 165, 0, byte.MaxValue);

		public static readonly ZColor LightYellow = new ZColor(byte.MaxValue, byte.MaxValue, 170, byte.MaxValue);

		public static readonly ZColor MinorInfo = Gray;

		public static readonly ZColor MajorInfo = Orange;
	}
	public static class UI
	{
		public static readonly string PromptUseItem = Prompt("1-8");

		public static readonly string PromptInteract = Prompt("$KEY_Use");

		public static readonly string PromptInteractAlt = Prompt($"$KEY_{ControlInputs.InteractAlt}");

		public static bool IsBuildModeActive
		{
			get
			{
				if (!Hud.IsPieceSelectionVisible())
				{
					if (Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Hud.instance.m_buildHud))
					{
						return Hud.instance.m_buildHud.activeSelf;
					}
					return false;
				}
				return true;
			}
		}

		public static bool IsOpen
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)Game.instance) || !Object.op_Implicit((Object)(object)GameCamera.instance) || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					return true;
				}
				if (((Character)Player.m_localPlayer).TakeInput())
				{
					return IsBuildModeActive;
				}
				return true;
			}
		}

		public static string Prompt(string text)
		{
			return "[<color=yellow><b>" + text + "</b></color>]";
		}

		public static TimeSpan RealToGameTime(float seconds)
		{
			float num = seconds / (float)EnvMan.instance.m_dayLengthSec;
			return TimeSpan.FromDays((num <= 0f) ? 0f : (num + 0.51f));
		}

		public static string RemainingTimeText(float seconds, float secPerFuel = -1f)
		{
			bool num = secPerFuel > (float)EnvMan.instance.m_dayLengthSec;
			TimeSpan timeSpan = (num ? RealToGameTime(seconds) : TimeSpan.FromSeconds(seconds));
			string result = "None";
			if (num)
			{
				if (timeSpan.Days > 0)
				{
					result = $"{timeSpan.Days} day" + ((timeSpan.Days > 1) ? "s" : "");
				}
				else if (timeSpan.TotalSeconds > 0.0)
				{
					result = "Less than a day";
				}
			}
			else
			{
				double totalMinutes = timeSpan.TotalMinutes;
				if (totalMinutes > 0.0 && totalMinutes <= 1.0)
				{
					result = "Less than a minute";
				}
				else
				{
					totalMinutes = timeSpan.TotalMinutes;
					if (totalMinutes > 1.0 && totalMinutes < 60.0)
					{
						result = $"{timeSpan.Minutes + 1} minutes";
					}
				}
			}
			return result;
		}

		public static void HideStackAllButton()
		{
			Log.Info("Hiding StackAll button", "HideStackAllButton", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\UI.cs");
			((Component)InventoryGui.instance.m_stackAllButton).gameObject.SetActive(false);
			((MonoBehaviour)ZenPlugin.Instance).StartCoroutine(Restore());
			static IEnumerator Restore()
			{
				do
				{
					Log.Info("Restoring StackAll button visibility", "HideStackAllButton", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\UI.cs");
					yield return (object)new WaitWhile((Func<bool>)InventoryGui.IsVisible);
					yield return (object)new WaitForSeconds(0.5f);
				}
				while (InventoryGui.IsVisible());
				((Component)InventoryGui.instance.m_stackAllButton).gameObject.SetActive(true);
			}
		}

		public static Material AddValheimIconShadow(this Image image)
		{
			return ((Graphic)image).material = ((Graphic)Hud.instance.m_buildIcon).material;
		}

		public static Outline AddOutline(this GameObject gameObject)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return gameObject.AddOutline(1f, Color.black);
		}

		public static Outline AddOutline(this GameObject gameObject, float thickness, Color effectColor = default(Color))
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Outline orAddComponent = ExposedGameObjectExtension.GetOrAddComponent<Outline>(gameObject);
			((Shadow)orAddComponent).effectDistance = Vector2.one * thickness;
			((Shadow)orAddComponent).effectColor = ((effectColor == default(Color)) ? Color.black : effectColor);
			return orAddComponent;
		}
	}
	[BepInIncompatibility("org.bepinex.plugins.valheim_plus")]
	internal abstract class ZenPlugin : BaseUnityPlugin
	{
		private const string BitcoinAddr = "bc1q34lrc82dp73jhv9ylefz0gvmeqfn96e938p4pf";

		private const string HomeURL = "https://github.com/ZenDragonX/ZenMods_Valheim";

		private static readonly Harmony H = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);

		internal static ConfigEntry<bool> IsLogEnabled = null;

		private static bool _loadedOnce;

		private bool _initialized;

		public static ZenPlugin Instance { get; private set; } = null;


		internal static ManualLogSource InstanceLogger => ((BaseUnityPlugin)Instance).Logger;

		public static bool Initialized
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Instance) && Instance._initialized)
				{
					return Instance.IsSysReady;
				}
				return false;
			}
		}

		protected virtual GameVersion? ValheimVersion => null;

		protected virtual bool RunOnServer => false;

		protected virtual bool IsSysReady
		{
			get
			{
				if (!RunOnServer || !Object.op_Implicit((Object)(object)ZoneSystem.instance) || !Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsDedicated())
				{
					if (Object.op_Implicit((Object)(object)ZNet.instance) && Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
					{
						return Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront);
					}
					return false;
				}
				return true;
			}
		}

		public event Action? RegisterInputs;

		public event Action? RegisterCraftingItems;

		public event Action<string>? LanguageChanged;

		protected abstract void Setup();

		protected abstract void TitleScene(bool isFirstBoot);

		protected abstract void WorldStart();

		protected abstract void Shutdown();

		protected ZenPlugin()
		{
			Game.isModded = true;
			if (Object.op_Implicit((Object)(object)Instance))
			{
				throw new Exception($"There can be only one instance of {((object)this).GetType()}");
			}
			Instance = this;
		}

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (ValheimVersion.HasValue)
			{
				GameVersion? valheimVersion = ValheimVersion;
				GameVersion currentVersion = Version.CurrentVersion;
				if (!valheimVersion.HasValue || valheimVersion.GetValueOrDefault() != currentVersion)
				{
					Log.Error($"Valheim version mismatch. Required: {ValheimVersion} Current: {Version.CurrentVersion}", "Awake", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\ZenPlugin.cs");
					AbortInit();
					return;
				}
			}
			Config.DefineConfig(isAdmin: true, "_Author", "Donations Welcome", defaultValue: true, null, "Like My Mods?\nBitcoin: bc1q34lrc82dp73jhv9ylefz0gvmeqfn96e938p4pf\nWebsite: https://github.com/ZenDragonX/ZenMods_Valheim");
			IsLogEnabled = Config.DefineConfig(isAdmin: false, "_Debug", "Enable Logging", defaultValue: false);
			ZInput.OnInputLayoutChanged += OnInputLayoutChanged;
			SceneManager.sceneLoaded += OnSceneLoaded;
			PrefabManager.OnVanillaPrefabsAvailable += CraftingReady;
			Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnLanguageChange));
			Setup();
			PreInit();
			void CraftingReady()
			{
				this.RegisterCraftingItems?.Invoke();
				PrefabManager.OnVanillaPrefabsAvailable -= CraftingReady;
			}
		}

		private void OnLanguageChange()
		{
			string @string = PlayerPrefs.GetString("language", "English");
			this.LanguageChanged?.Invoke(@string);
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "start")
			{
				Config.StringList.AccessCount.Clear();
				KeyHint.RemoveAll();
				TitleScene(!_initialized);
				PreInit();
			}
		}

		private void OnInputLayoutChanged()
		{
			ControlSetup.Init();
			this.RegisterInputs?.Invoke();
		}

		private void PreInit()
		{
			_initialized = false;
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).CancelInvoke("CheckInit");
			((MonoBehaviour)this).InvokeRepeating("CheckInit", 1f, 1f);
		}

		private void OnDestroy()
		{
			Log.Info("Cleanup", "OnDestroy", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\ZenPlugin.cs");
			GUIManager.BlockInput(false);
			SceneManager.sceneLoaded -= OnSceneLoaded;
			ZInput.OnInputLayoutChanged -= OnInputLayoutChanged;
			Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(OnLanguageChange));
			Shutdown();
			((MonoBehaviour)this).StopAllCoroutines();
			ActionString.RemoveAll();
			KeyHint.RemoveAll();
			Cleanup.External();
			TerminalCommand.Cleanup();
			H.UnpatchSelf();
			Instance = null;
		}

		private void CheckInit()
		{
			Log.Debug("CheckInit", "CheckInit", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\ZenPlugin.cs");
			if (!IsSysReady || !Object.op_Implicit((Object)(object)ZoneSystem.instance))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsDedicated() && !RunOnServer)
			{
				Log.Info("Abort init. Running on server.", "CheckInit", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\ZenPlugin.cs");
				AbortInit();
				return;
			}
			((MonoBehaviour)this).CancelInvoke("CheckInit");
			if (!_loadedOnce)
			{
				OnLanguageChange();
				OnInputLayoutChanged();
			}
			Log.Info("Init complete - Game Start", "CheckInit", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\ZenPlugin.cs");
			WorldStart();
			_initialized = true;
			_loadedOnce = true;
		}

		private void AbortInit()
		{
			((MonoBehaviour)this).CancelInvoke("CheckInit");
			H.UnpatchSelf();
		}
	}
}
namespace ZenModLib.Controls
{
	public class ActionString
	{
		private enum InputMode
		{
			Keyboard,
			Gamepad
		}

		private static readonly string PluginName = ((BaseUnityPlugin)ZenPlugin.Instance).Info.Metadata.Name;

		private static readonly HashSet<ActionString> RegisteredActions = new HashSet<ActionString>();

		public readonly string NameShort;

		public readonly string Name;

		public readonly string Label;

		public ButtonDef? AliasKBM { get; private set; }

		public ButtonDef? AliasJoy { get; private set; }

		public static implicit operator string(ActionString input)
		{
			return input.ToString();
		}

		public ActionString(string actionName, string label, bool safeNamespace = true)
		{
			if (Utility.IsNullOrWhiteSpace(actionName))
			{
				throw new Exception("ActionString can not be empty or null.");
			}
			NameShort = actionName;
			Name = (safeNamespace ? (Regex.Replace(PluginName, "[^\\w]", "_") + "_" + actionName) : actionName);
			Label = Localization.instance.Localize(label);
			UpdateTranslationLabels();
			RegisteredActions.Add(this);
		}

		private void UpdateTranslationLabels()
		{
			if (!Utility.IsNullOrWhiteSpace(Label))
			{
				Localization.instance.AddWord(Name, Label);
				Localization.instance.AddWord("settings_" + Name.ToLower(), Label);
			}
		}

		private static void AddButton(string name, string path, bool altKey, bool showHints, bool rebindable, float repeatDelay, float repeatInterval)
		{
			if (ZInput.instance.m_buttons.TryGetValue(name, out var value))
			{
				Log.Info("Skip existing button: " + value.GetActionPath(true) + "\t" + value.Name, "AddButton", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Controls\\ActionString.cs");
				return;
			}
			if (rebindable && (path.StartsWith("<Keyboard>") || path.StartsWith("<Mouse>")))
			{
				string @string = PlayerPrefs.GetString("kbmBinding_" + name);
				if (!Utility.IsNullOrWhiteSpace(@string))
				{
					path = @string;
				}
			}
			Log.Info("Add Button: " + path + "\t" + name, "AddButton", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Controls\\ActionString.cs");
			ZInput.instance.AddButton(name, path, altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public void AddButton(GamepadInput input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			AddButton("Joy" + Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public void AddButton(MouseButton input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			AddButton(Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public void AddButton(KeyCode input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			AddButton(Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public void AddButton(Key input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			AddButton(Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval);
		}

		public void Alias(string existingName)
		{
			ButtonDef buttonDef = ZInput.instance.GetButtonDef(existingName);
			string actionPath = buttonDef.GetActionPath(true);
			if (actionPath.StartsWith("<Gamepad>"))
			{
				AliasJoy = buttonDef;
			}
			else if (actionPath.StartsWith("<Keyboard>") || actionPath.StartsWith("<Mouse>"))
			{
				AliasKBM = buttonDef;
			}
			Log.Info("Alias: " + buttonDef.GetActionPath(true) + "\t" + existingName + " -> " + Name, "Alias", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Controls\\ActionString.cs");
		}

		public override string ToString()
		{
			if (ZInput.IsGamepadActive())
			{
				if (AliasJoy == null)
				{
					return "Joy" + Name;
				}
				return AliasJoy.Name;
			}
			if (AliasKBM == null)
			{
				return Name;
			}
			return AliasKBM.Name;
		}

		public void RemoveButtons()
		{
			ZInput.instance.RemoveButton(Name);
			ZInput.instance.RemoveButton("Joy" + Name);
		}

		internal static void RemoveAll()
		{
			foreach (ActionString registeredAction in RegisteredActions)
			{
				registeredAction.RemoveButtons();
			}
		}
	}
	public static class ControlInputs
	{
		public static readonly ActionString InteractAlt = new ActionString("ZenModLib_InteractAltButton", "Alt interact", safeNamespace: false);

		public static string JoyAlt
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				if ((int)ZInput.InputLayout != 1)
				{
					return JoyTrigger;
				}
				return JoyBumper;
			}
		}

		public static string JoyTrigger
		{
			get
			{
				if (!ZInput.SwapTriggers)
				{
					return "JoyLTrigger";
				}
				return "JoyRTrigger";
			}
		}

		public static string JoyBumper
		{
			get
			{
				if (!ZInput.SwapTriggers)
				{
					return "JoyLBumper";
				}
				return "JoyRBumper";
			}
		}

		public static GamepadInput TriggerSwappedL
		{
			get
			{
				if (ZInput.SwapTriggers)
				{
					return (GamepadInput)18;
				}
				return (GamepadInput)17;
			}
		}

		public static GamepadInput BumperSwappedL
		{
			get
			{
				if (ZInput.SwapTriggers)
				{
					return (GamepadInput)16;
				}
				return (GamepadInput)15;
			}
		}

		public static GamepadInput TriggerSwappedR
		{
			get
			{
				if (ZInput.SwapTriggers)
				{
					return (GamepadInput)17;
				}
				return (GamepadInput)18;
			}
		}

		public static GamepadInput BumperSwappedR
		{
			get
			{
				if (ZInput.SwapTriggers)
				{
					return (GamepadInput)15;
				}
				return (GamepadInput)16;
			}
		}
	}
	internal static class ControlSetup
	{
		private static readonly List<MethodInfo> Success = new List<MethodInfo>();

		public static void Init()
		{
			Apply(GamepadFix.Remap_BasicDefaults);
			Apply(InteractAltButton.CreateInteractAlt);
		}

		private static void Apply(Func<bool> fix)
		{
			if (fix())
			{
				Log.Message("Success: " + fix.Method.Name, "Apply", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Controls\\ControlSetup.cs");
				Success.Add(fix.Method);
			}
		}

		internal static bool IsApplied(Func<bool> method)
		{
			return Success.Contains(method.Method);
		}
	}
	[HarmonyPatch]
	internal static class GamepadFix
	{
		internal static bool Remap_BasicDefaults()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			bool? showHints;
			if ((int)ZInput.InputLayout == 0)
			{
				if (!ZInput.instance.GetButtonDef("JoyGP").RemapTo((GamepadInput)8, true))
				{
					return false;
				}
			}
			else
			{
				ButtonDef buttonDef = ZInput.instance.GetButtonDef("JoyAltPlace");
				showHints = false;
				if (!buttonDef.RemapTo((GamepadInput)19, null, showHints))
				{
					return false;
				}
				GamepadInput newInput = (((int)ZInput.InputLayout == 1) ? ControlInputs.TriggerSwappedL : ControlInputs.BumperSwappedL);
				if (!ZInput.instance.GetButtonDef("JoyCrouch").RemapTo(newInput, false))
				{
					return false;
				}
			}
			if (!ZInput.instance.GetButtonDef("JoyHide").RemapTo((GamepadInput)3, false))
			{
				return false;
			}
			if (!ZInput.instance.GetButtonDef("JoySit").RemapTo((GamepadInput)19, false))
			{
				return false;
			}
			if (!ZInput.instance.GetButtonDef("JoyMap").RemapTo((GamepadInput)19, true))
			{
				return false;
			}
			ButtonDef buttonDef2 = ZInput.instance.GetButtonDef("JoyChat");
			showHints = false;
			if (!buttonDef2.RemapTo((GamepadInput)0, null, showHints))
			{
				return false;
			}
			return true;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Minimap), "Update")]
		private static IEnumerable<CodeInstruction> RemapJoyMap_Minimap_Update_Transpile(IEnumerable<CodeInstruction> codes)
		{
			bool alreadyPatched = false;
			foreach (CodeInstruction code in codes)
			{
				if (CodeInstructionExtensions.Is(code, OpCodes.Ldstr, (object)"JoyMap_DISABLED"))
				{
					alreadyPatched = true;
				}
				if (code.opcode == OpCodes.Ret && !alreadyPatched)
				{
					yield return CodeInstruction.Call(typeof(GamepadFix), "RemapJoyMap_Minimap", (Type[])null, (Type[])null);
				}
				if (CodeInstructionExtensions.Is(code, OpCodes.Ldstr, (object)"JoyMap"))
				{
					yield return new CodeInstruction(OpCodes.Ldstr, (object)"JoyMap_DISABLED");
				}
				else
				{
					yield return code;
				}
			}
		}

		private static void RemapJoyMap_Minimap()
		{
			if (ZInput.IsGamepadActive() && !UI.IsOpen && ZInput.GetButtonDown("JoyMap") && ZInput.GetButton(ControlInputs.JoyAlt))
			{
				ToggleMap();
			}
			static void ToggleMap()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected I4, but got Unknown
				Minimap instance = Minimap.instance;
				MapMode mode = instance.m_mode;
				switch ((int)mode)
				{
				case 0:
					instance.SetMapMode((MapMode)1);
					break;
				case 1:
					instance.SetMapMode((MapMode)2);
					break;
				case 2:
					instance.SetMapMode((MapMode)1);
					break;
				}
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Player), "Update")]
		private static IEnumerable<CodeInstruction> JoyAltHide_Player_Update_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Character), "InPlaceMode", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(GamepadFix), "Character_InPlaceMode_Intercept", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		private static bool Character_InPlaceMode_Intercept(Character _)
		{
			if (!Hud.IsPieceSelectionVisible() && !InventoryGui.IsVisible())
			{
				return Minimap.IsOpen();
			}
			return true;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Player), "Update")]
		private static IEnumerable<CodeInstruction> JoyAltPlace_Player_Update_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(ZInput), "GetButton", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ZInput), "GetButtonDown", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(ZInput), "GetButtonUp", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(GamepadFix), "JoyAltPlace_GetButton", (Type[])null, (Type[])null);
			MethodInfo methodInfo5 = AccessTools.Method(typeof(GamepadFix), "JoyAltPlace_GetButtonDown", (Type[])null, (Type[])null);
			MethodInfo methodInfo6 = AccessTools.Method(typeof(GamepadFix), "JoyAltPlace_GetButtonUp", (Type[])null, (Type[])null);
			codes = Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo4);
			codes = Transpilers.MethodReplacer(codes, (MethodBase)methodInfo2, (MethodBase)methodInfo5);
			codes = Transpilers.MethodReplacer(codes, (MethodBase)methodInfo3, (MethodBase)methodInfo6);
			return codes;
		}

		private static bool JoyAltPlace_GetButton(string name)
		{
			return JoyAltPlace_Intercept(name, (Func<string, bool>)ZInput.GetButton);
		}

		private static bool JoyAltPlace_GetButtonDown(string name)
		{
			return JoyAltPlace_Intercept(name, (Func<string, bool>)ZInput.GetButtonDown);
		}

		private static bool JoyAltPlace_GetButtonUp(string name)
		{
			return JoyAltPlace_Intercept(name, (Func<string, bool>)ZInput.GetButtonUp);
		}

		private static bool JoyAltPlace_Intercept(string name, Func<string, bool> getBtnFunc)
		{
			if (name != "JoyAltPlace")
			{
				return getBtnFunc(name);
			}
			if (UI.IsBuildModeActive)
			{
				return getBtnFunc(name);
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InventoryGui), "Show")]
		private static void Remap_BasicDefaults_InventoryGui_Show(ref bool __runOriginal)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (ControlSetup.IsApplied(Remap_BasicDefaults) && ZInput.IsGamepadActive() && (int)ZInput.InputLayout == 0)
			{
				bool button = ZInput.GetButton(ControlInputs.JoyAlt);
				if (ZInput.GetButton("JoyGP") && button)
				{
					__runOriginal = false;
					Player.m_localPlayer.StartGuardianPower();
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class InteractAltButton
	{
		public const string Name = "ZenModLib_InteractAltButton";

		public const string Label = "Alt interact";

		private static float _lastInteractTime;

		internal static bool CreateInteractAlt()
		{
			ActionString actionString = new ActionString("Initialized_CreateInteractAlt", string.Empty, safeNamespace: false);
			if (ZInput.instance.GetButtonDef(actionString.Name) != null)
			{
				return false;
			}
			actionString.AddButton((KeyCode)0);
			ZenPlugin.Instance.RegisterInputs += delegate
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				//IL_002d: 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_0032: 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)
				Log.Message("Register Inputs: InteractAlt", "CreateInteractAlt", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Controls\\InteractAltButton.cs");
				ControlInputs.InteractAlt.RemoveButtons();
				GamepadInput input = (((int)ZInput.InputLayout == 1) ? ControlInputs.TriggerSwappedL : ControlInputs.BumperSwappedL);
				ControlInputs.InteractAlt.AddButton(input);
				ButtonDef buttonDef = ZInput.instance.GetButtonDef("AutoRun");
				if (buttonDef.GetActionPath(true).ToUpper().EndsWith("Q"))
				{
					buttonDef.RemapTo((KeyCode)92);
				}
				ControlInputs.InteractAlt.AddButton((KeyCode)113);
			};
			return true;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Player), "SetControls")]
		private static IEnumerable<CodeInstruction> Player_SetControls_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Character), "SetCrouch", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(InteractAltButton), "SetCrouch_Intercept", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		private static void SetCrouch_Intercept(Player player, bool crouch)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (crouch && ZInput.IsGamepadActive() && (int)ZInput.InputLayout != 0)
			{
				if (player.IsHoveringValidObject())
				{
					crouch = false;
				}
				else if (Time.time < _lastInteractTime + 0.5f)
				{
					crouch = false;
				}
			}
			((Character)player).SetCrouch(crouch);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Player), "Interact")]
		private static IEnumerable<CodeInstruction> Player_Interact_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Interactable), "Interact", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(InteractAltButton), "Interact_Intercept", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		private static bool Interact_Intercept(Interactable self, Humanoid user, bool hold, bool alt)
		{
			if (alt)
			{
				_lastInteractTime = Time.time;
			}
			return self.Interact(user, hold, alt);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Player), "Update")]
		private static IEnumerable<CodeInstruction> Player_Update_Transpile_HandleAltInteract(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Player), "UpdateStats", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(InteractAltButton), "Player_UpdateStats_Intercept", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		private static void Player_UpdateStats_Intercept(Player player)
		{
			player.UpdateStats();
			CheckForInteraction(player);
		}

		private static void CheckForInteraction(Player player)
		{
			//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)
			if (!UI.IsOpen && !Hud.InRadial() && !((Character)player).IsTeleporting() && !((Character)player).IsDead() && !((Character)player).InDodge() && !((Character)player).IsRunning() && !(((Character)player).GetMoveDir() != Vector3.zero) && player.IsHoveringValidObject())
			{
				if (ZInput.GetButtonDown((string)ControlInputs.InteractAlt))
				{
					player.Interact(player.m_hovering, false, true);
				}
				else if (ZInput.GetButton((string)ControlInputs.InteractAlt) && ZInput.GetButtonPressedTimer((string)ControlInputs.InteractAlt) > 0.3f)
				{
					player.Interact(player.m_hovering, true, true);
				}
			}
		}

		private static bool IsHoveringValidObject(this Player player)
		{
			if (!Object.op_Implicit((Object)(object)player.m_hovering) || Utility.IsNullOrWhiteSpace(((TMP_Text)Hud.instance.m_hoverName).text))
			{
				return false;
			}
			if (!((TMP_Text)Hud.instance.m_hoverName).text.Contains(UI.PromptInteractAlt.Localize().GlyphFix()))
			{
				return false;
			}
			return true;
		}

		public static string InsertButtonText(string hoverText, string label)
		{
			string pattern = "^(" + UI.PromptInteract.RegexPattern() + ".*)$";
			string text = UI.PromptInteractAlt + " " + label;
			return Regex.Replace(hoverText, pattern, "$1\n" + text, RegexOptions.Multiline);
		}
	}
	[HarmonyPatch]
	public static class InteractAlt_FixVanilla
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Tameable), "GetHoverText")]
		private static IEnumerable<CodeInstruction> Tameable_GetHoverText_Transpile(IEnumerable<CodeInstruction> codes)
		{
			return Transpilers.Manipulator(Transpilers.Manipulator(codes, (Func<CodeInstruction, bool>)((CodeInstruction ci) => CodeInstructionExtensions.Is(ci, OpCodes.Ldstr, (object)"\n[<color=yellow><b>$KEY_AltKeys + $KEY_Use</b></color>] $hud_rename")), (Action<CodeInstruction>)delegate(CodeInstruction ci)
			{
				ci.operand = "\n[<color=yellow><b>$KEY_ZenModLib_InteractAltButton</b></color>] $hud_rename";
			}), (Func<CodeInstruction, bool>)((CodeInstruction ci) => CodeInstructionExtensions.Is(ci, OpCodes.Ldstr, (object)"\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $hud_rename")), (Action<CodeInstruction>)delegate(CodeInstruction ci)
			{
				ci.operand = "\n[<color=yellow><b>$KEY_ZenModLib_InteractAltButton</b></color>] $hud_rename";
			});
		}
	}
}
namespace ZenModLib.Compatibility
{
	[HarmonyPatch]
	internal static class MultiUserChest
	{
		[AttributeUsage(AttributeTargets.Class)]
		internal sealed class DisableAttribute : Attribute
		{
			public DisableAttribute(params Type[] types)
			{
				_disabledTypes = types;
			}
		}

		private static Type[] _disabledTypes = Array.Empty<Type>();

		[HarmonyBefore(new string[] { "com.maxsch.valheim.MultiUserChest" })]
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "Awake")]
		private static void Container_Awake(Container __instance)
		{
			Type[] disabledTypes = _disabledTypes;
			foreach (Type type in disabledTypes)
			{
				if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent(type)))
				{
					Disable(__instance);
				}
			}
		}

		internal static void Disable(Container container)
		{
			if (container.m_nview.IsOwner())
			{
				Log.Info("Disable Multi User Chest", "Disable", "C:\\Users\\joel\\Projects\\ValheimDev\\ModDev\\ZenModLib\\ZenModLib\\Compatibility\\MultiUserChest.cs");
				ZDO zDO = container.m_nview.GetZDO();
				if (!zDO.GetBool("MUC_Ignore", false))
				{
					zDO.Set("MUC_Ignore", true);
				}
			}
		}
	}
}
namespace ZenHoverItem
{
	internal static class Configs
	{
		public static ConfigEntry<bool> ShowHoverIcons;

		public static ConfigEntry<bool> ShowHoverIconForFuel;

		public static ConfigEntry<bool> ArmorStandShowHoverIcons;

		public static ConfigEntry<bool> ArmorStandShowHoverText;

		internal static void Init()
		{
			ShowHoverIcons = Config.DefineConfig(isAdmin: true, "General", "Show Hover Icons", defaultValue: true, null, "Display hover icons on the crosshair for important pieces such as containers? (Global)");
			ShowHoverIconForFuel = Config.DefineConfig(isAdmin: true, "General", "Show Hover Icon For Fuel", defaultValue: false, null, "Should the hover icon for fuelable things such as fireplaces, torches, and smelters be shown?\nTypically hover icons are for things you can consume or pickup.");
			ArmorStandShowHoverIcons = Config.DefineConfig(isAdmin: true, "Armor Stand", "Show Hover Icons", defaultValue: false, null, "Display the hover icons for armor stands");
			ArmorStandShowHoverText = Config.DefineConfig(isAdmin: true, "Armor Stand", "Show Hover Text", defaultValue: true, null, "Display the hover text for armor stands");
		}
	}
	public class HoverItemUI : MonoBehaviour
	{
		private class Element
		{
			private readonly Element _gridElement;

			public GameObject Node => _gridElement.m_go;

			public Image Icon => _gridElement.m_icon;

			public TMP_Text Label => _gridElement.m_amount;

			public Element(Element element)
			{
				_gridElement = element;
				((Component)_gridElement.m_durability).gameObject.SetActive(false);
				((Component)_gridElement.m_quality).gameObject.SetActive(false);
				((Component)_gridElement.m_queued).gameObject.SetActive(false);
				((Component)_gridElement.m_noteleport).gameObject.SetActive(false);
				((Component)_gridElement.m_food).gameObject.SetActive(false);
				_gridElement.m_selected.SetActive(false);
				((Component)Icon).gameObject.AddOutline();
				((Behaviour)_gridElement.m_equiped).enabled = false;
				Object.Destroy((Object)(object)element.m_go.GetComponent<Image>());
				Object.Destroy((Object)(object)element.m_go.GetComponent<Button>());
				Object.Destroy((Object)(object)((Component)element.m_go.transform.Find("binding")).gameObject);
				Object.Destroy((Object)(object)element.m_tooltip);
			}
		}

		public const int MaxIcons = 5;

		private const float DefaultScale = 0.8f;

		private const int IconSpacing = 4;

		private static readonly RectOffset PositionOffset = new RectOffset(76, 0, 0, 46);

		private GameObject _crosshairRootAnchor;

		private HorizontalLayoutGroup _layout;

		private readonly List<Element> _elements = new List<Element>();

		private bool _isDirty = true;

		internal static void Init()
		{
			((Component)Hud.instance).gameObject.AddComponent<HoverItemUI>().CreateStructure();
		}

		private void CreateStructure()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0040: 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)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_014b: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: 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_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			_crosshairRootAnchor = new GameObject("HoverItemUI");
			_crosshairRootAnchor.transform.SetParent(((Component)Hud.instance.m_crosshair).transform.parent, false);
			_crosshairRootAnchor.transform.localScale = Vector3.one * 0.8f;
			_crosshairRootAnchor.transform.localPosition = Vector3.zero;
			_layout = _crosshairRootAnchor.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)_layout).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)_layout).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)_layout).spacing = 4f;
			((LayoutGroup)_layout).padding = PositionOffset;
			((LayoutGroup)_layout).childAlignment = (TextAnchor)6;
			for (int i = 0; i < 5; i++)
			{
				GameObject val = Object.Instantiate<GameObject>(InventoryGui.instance.m_playerGrid.m_elementPrefab, _crosshairRootAnchor.transform);
				((Object)val).name = "Element_" + i;
				Element element = new Element
				{
					m_pos = new Vector2i(i, 0),
					m_go = val,
					m_icon = ((Component)val.transform.Find("icon")).GetComponent<Image>(),
					m_amount = ((Component)val.transform.Find("amount")).GetComponent<TMP_Text>(),
					m_quality = ((Component)val.transform.Find("quality")).GetComponent<TMP_Text>(),
					m_equiped = ((Component)val.transform.Find("equiped")).GetComponent<Image>(),
					m_queued = ((Component)val.transform.Find("queued")).GetComponent<Image>(),
					m_noteleport = ((Component)val.transform.Find("noteleport")).GetComponent<Image>(),
					m_food = ((Component)val.transform.Find("foodicon")).GetComponent<Image>(),
					m_selected = ((Component)val.transform.Find("selected")).gameObject,
					m_tooltip = val.GetComponent<UITooltip>(),
					m_durability = ((Component)val.transform.Find("durability")).GetComponent<GuiBar>()
				};
				_elements.Add(new Element(element));
			}
		}

		private static GameObject AttachShadedBkg(Transform parent)
		{
			//IL_0018: 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_002a: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0089: Expected O, but got Unknown
			GameObject val = new GameObject("ShadedPanel", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			val.transform.SetAsFirstSibling();
			((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.5f);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(320f, 110f);
			component.anchoredPosition = new Vector2(120f, -2f);
			return val;
		}

		internal static void Shutdown()
		{
			Hud instance = Hud.instance;
			Object.Destroy((Object)(object)((instance != null) ? ((Component)instance).GetComponent<HoverItemUI>() : null));
		}

		private void Update()
		{
			Clear();
		}

		private void OnDestroy()
		{
			Object.Destroy((Object)(object)_crosshairRootAnchor);
		}

		private void Clear()
		{
			if (!_isDirty)
			{
				return;
			}
			foreach (Element element in _elements)
			{
				element.Node.SetActive(false);
			}
			_isDirty = false;
		}

		public void UpdateHoverIcons(IEnumerable<Sprite?> icons)
		{
			UpdateHoverIcons(icons.Select((Sprite icon) => (icon, "")));
		}

		public void UpdateHoverIcons(IEnumerable<string?> prefabNames)
		{
			UpdateHoverIcons(prefabNames.Select((string prefabName) => (prefabName, "")));
		}

		public void UpdateHoverIcons(IEnumerable<(string? PrefabName, string Label)> elements)
		{
			UpdateHoverIcons(elements.Select<(string, string), (Sprite, string)>(((string PrefabName, string Label) e) => (Utility.IsNullOrWhiteSpace(e.PrefabName) ? null : ItemCache.Get(e.PrefabName).GetIcon(), e.Label)));
		}

		public void UpdateHoverIcons(IEnumerable<(Sprite? Icon, string Label)> elements)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			foreach (var (tuple2, index) in elements.WithIndex())
			{
				SetIcon(tuple2.Item1, index, tuple2.Item2);
			}
		}

		private void SetIcon(Sprite? icon, int index, string label, Vector2 offset = default(Vector2), bool flipX = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (Configs.ShowHoverIcons.Value)
			{
				if (flipX)
				{
					Vector3 localScale = _crosshairRootAnchor.transform.localScale;
					Transform transform = _crosshairRootAnchor.transform;
					Vector3 localScale2 = localScale;
					localScale2.x = 0f - localScale.x;
					transform.localScale = localScale2;
				}
				if (index < 5)
				{
					_elements[index].Node.SetActive(true);
					((Behaviour)_elements[index].Icon).enabled = Object.op_Implicit((Object)(object)icon);
					_elements[index].Icon.sprite = icon;
					((Behaviour)_elements[index].Label).enabled = label != "";
					_elements[index].Label.text = label;
				}
				_isDirty = true;
			}
		}
	}
	public static class ItemCache
	{
		private static readonly Dictionary<string, ItemDrop> PrefabCache = new Dictionary<string, ItemDrop>();

		public static ItemDrop Get(string prefabName)
		{
			prefabName = Utils.GetPrefabName(prefabName);
			if (!PrefabCache.TryGetValue(prefabName, out ItemDrop value))
			{
				return PrefabCache[prefabName] = ObjectDB.instance.GetItemPrefab(prefabName).GetComponent<ItemDrop>();
			}
			return value;
		}
	}
	[BepInPlugin("ZenDragon.ZenHoverItem", "ZenHoverItem", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : ZenPlugin
	{
		public const string PluginGUID = "ZenDragon.ZenHoverItem";

		public const string PluginName = "ZenHoverItem";

		public const string PluginVersion = "0.1.2";

		protected override void Setup()
		{
			Configs.Init();
		}

		protected ov