Decompiled source of Zen ModLib v1.1.18

plugins\Zen.ModLib.dll

Decompiled 6 days 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.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
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 Zen.Compatibility;
using Zen.Config;
using Zen.Controls;
using Zen.Lib;
using Zen.Logging;

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

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Zen
{
	[BepInPlugin("ZenDragon.Zen.ModLib", "Zen.ModLib", "1.1.18")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class ModLib : ZenMod<ModLib>
	{
		private const string PluginName = "Zen.ModLib";

		private const string PluginVersion = "1.1.18";

		public const string PluginGUID = "ZenDragon.Zen.ModLib";

		public static ModLibConfigs Configs { get; private set; }

		private ModLib()
		{
			Configs = new ModLibConfigs(((BaseUnityPlugin)this).Config);
		}

		protected override void Setup()
		{
			base.RunOnServer = true;
			base.RequireGamepadRemap = Configs.ForceGamepadRemap.Value;
		}

		protected override void TitleScene(bool isFirstBoot)
		{
		}

		protected override void WorldStart()
		{
		}

		protected override void Shutdown()
		{
			base.Log.Message("Shutting down", 0u);
		}
	}
	public class ModLibConfigs
	{
		internal readonly ConfigEntry<bool> DebugAll;

		internal readonly ConfigEntry<KeyCode> InteractAltKey;

		internal readonly ConfigEntry<bool> ForceGamepadRemap;

		internal readonly ConfigEntry<int> ConfigThrashWarningLimit;

		internal readonly ConfigEntry<bool> SanitizeData;

		internal ModLibConfigs(ConfigFile configFile)
		{
			Zen.Config.Config.File = configFile;
			DebugAll = Zen.Config.Config.Define(isAdmin: false, "_Debug", "Enable All Logs", defaultValue: false, "Enable all debug flags for all ZenMods. Caution this will slowdown performance! Useful only for internal testing.");
			InteractAltKey = Zen.Config.Config.Define<KeyCode>(isAdmin: false, "Input", "Alternate Interact Key", (KeyCode)113, "Key to use for alternative interaction instead of Shift + E");
			InteractAltKey.SettingChanged += delegate
			{
				ZenMod<ModLib>.Instance.RefreshInputs();
			};
			ForceGamepadRemap = Zen.Config.Config.Define(isAdmin: false, "Input", "Force Gamepad Remap", defaultValue: false, "Normally ZenMods request gamepad remapping as needed on a per mod basis.\r\nSet this to true to force the extended gamepad remap to always be applied. [restart required]");
			ConfigThrashWarningLimit = Zen.Config.Config.Define(isAdmin: false, "Diagnostics", "Config Thrashing Warning Limit", 100, Zen.Config.Config.AcceptRange(0, 1000), "Upper limit before triggering a warning in the logs that config files are being thrashed. \r\nThis happens when mods like ConfigWatcher are spaming IO operations and constantly reloading config files.\r\nYou really should investigate the cause of any thrashing alerts triggered by this.\r\nIt means your config files are being reloaded constantly in the background, that can hurt performance.\r\nA few times is no big deal, but if it's happening constantly, you should investigate the cause.\r\nSet to 0 to disable the alert if you don't care about the performance impact from mods that are repeatedly hammering IO.");
			SanitizeData = Zen.Config.Config.Define(isAdmin: false, "Diagnostics", "Sanitize Data", defaultValue: true, "Sanitize item and recipe data to ensure they are properly indexed.\r\nSome mods do not properly register their custom items with all required indexes.");
		}
	}
}
namespace Zen.Logging
{
	public class Log
	{
		private static readonly LogLevel LogLevels;

		private readonly ManualLogSource _logger;

		private readonly ConfigEntry<bool> _config;

		public static bool IsEnabled => ZenMod.Instance.Log.Enabled;

		private bool Enabled
		{
			get
			{
				if (!_config.Value)
				{
					return ModLib.Configs.DebugAll.Value;
				}
				return true;
			}
		}

		static Log()
		{
			//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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ConfigFile val = (ConfigFile)AccessTools.Property(typeof(ConfigFile), "CoreConfig").GetValue(null);
				ConfigEntry<LogLevel> val2 = default(ConfigEntry<LogLevel>);
				if (!val.TryGetEntry<LogLevel>("Logging.Disk", "LogLevels", ref val2))
				{
					throw new Exception("Logging.Disk LogLevels config info missing");
				}
				ConfigEntry<LogLevel> val3 = default(ConfigEntry<LogLevel>);
				if (!val.TryGetEntry<LogLevel>("Logging.Console", "LogLevels", ref val3))
				{
					throw new Exception("Logging.Console LogLevels config info missing");
				}
				LogLevels = (LogLevel)(val2.Value | val3.Value);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)ex.Message);
				Debug.LogWarning((object)"Falling back to default log levels");
				LogLevels = (LogLevel)23;
			}
		}

		internal Log(ManualLogSource logger)
		{
			_logger = logger;
			_config = Zen.Config.Config.Define(isAdmin: false, "_Debug", "Enable Logging", defaultValue: false, "Generate additional debug information in the logs");
		}

		private static string Format(object data, uint stackDepth)
		{
			MethodBase? method = new StackTrace((int)(stackDepth + 2)).GetFrame(0).GetMethod();
			string arg = method.DeclaringType?.Name;
			string name = method.Name;
			return $"{arg}.{name}: {data}";
		}

		public static void Debug(object data, ushort stackDepth = 0)
		{
			ZenMod.Instance.Log.Debug(data, (uint)(stackDepth + 1));
		}

		public void Debug(object data, uint stackDepth = 0u)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (Enabled && ((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)32))
			{
				_logger.LogDebug((object)Format(data, stackDepth));
			}
		}

		public static void Info(object data, ushort stackDepth = 0)
		{
			ZenMod.Instance.Log.Info(data, (uint)(stackDepth + 1));
		}

		public void Info(object data, uint stackDepth = 0u)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (Enabled && ((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)16))
			{
				_logger.LogInfo((object)Format(data, stackDepth));
			}
		}

		public static void Message(object data, ushort stackDepth = 0)
		{
			ZenMod.Instance.Log.Message(data, (uint)(stackDepth + 1));
		}

		public void Message(object data, uint stackDepth = 0u)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)8))
			{
				_logger.LogMessage(data);
			}
		}

		public static void Warning(object data, ushort stackDepth = 0)
		{
			ZenMod.Instance.Log.Warning(data, (uint)(stackDepth + 1));
		}

		public void Warning(object data, uint stackDepth = 0u)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)4))
			{
				_logger.LogWarning((object)Format(data, stackDepth));
			}
		}

		public static void Error(object data, ushort stackDepth = 0)
		{
			ZenMod.Instance.Log.Error(data, (uint)(stackDepth + 1));
		}

		public void Error(object data, uint stackDepth = 0u)
		{
			_logger.LogError((object)Format(data, stackDepth));
		}

		public static void Fatal(object data, ushort stackDepth = 0)
		{
			ZenMod.Instance.Log.Fatal(data, (uint)(stackDepth + 1));
		}

		public void Fatal(object data, uint stackDepth = 0u)
		{
			_logger.LogFatal((object)Format(data, stackDepth));
		}
	}
}
namespace Zen.Lib
{
	public static class AssetIO
	{
		public static Sprite LoadSprite(string resourceName, Assembly? assembly = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0036: Expected O, but got Unknown
			Log.Info("Loading sprite from resource: " + resourceName, 0);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, LoadResource(resourceName, assembly ?? Assembly.GetCallingAssembly()));
			return CreateSprite(val);
		}

		public static Sprite LoadSpriteFromFile(string filePath)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002a: Expected O, but got Unknown
			Log.Info("Loading sprite from file: " + filePath, 0);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, File.ReadAllBytes(filePath));
			return CreateSprite(val);
		}

		private static Sprite CreateSprite(Texture2D texture)
		{
			//IL_0031: 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)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			return Sprite.Create(texture, val, val2);
		}

		private static byte[] LoadResource(string resourceName, Assembly? assembly = null)
		{
			if ((object)assembly == null)
			{
				assembly = Assembly.GetCallingAssembly();
			}
			Type type = ((object)ZenMod.GetInstance(assembly)).GetType();
			using Stream stream = assembly.GetManifestResourceStream(type.Namespace + ".Resources." + resourceName);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}
	}
	internal static class Cleanup
	{
		public static void External(ZenMod mod)
		{
			if (mod is ModLib)
			{
				ConfigTomlTypeConverterEntries();
			}
			JotunnConfigs(((BaseUnityPlugin)mod).Config);
		}

		private static void JotunnConfigs(ConfigFile configFile)
		{
			Log.Debug("Remove config entries from Jotunn cache", 1);
			Dictionary<ConfigEntryBase, object> dictionary = (Dictionary<ConfigEntryBase, object>)AccessTools.Field(typeof(SynchronizationManager), "localValues").GetValue(SynchronizationManager.Instance);
			foreach (ConfigDefinition key2 in configFile.Keys)
			{
				ConfigEntryBase key = configFile[key2];
				dictionary.Remove(key);
			}
		}

		private static void ConfigTomlTypeConverterEntries()
		{
			Log.Debug("Removing TomlTypeConverter Entry: StringList", 1);
			((Dictionary<Type, TypeConverter>)AccessTools.Property(typeof(TomlTypeConverter), "TypeConverters").GetValue(null)).Remove(typeof(StringList));
		}
	}
	public class MissingInstanceException : Exception
	{
		[CompilerGenerated]
		private Assembly <assembly>P;

		public Assembly Assembly => <assembly>P;

		public MissingInstanceException(Assembly assembly)
		{
			<assembly>P = assembly;
			base..ctor($"Mod instance not found for assembly {<assembly>P.FullName} HashCode: {<assembly>P.GetHashCode():X}");
		}
	}
	public class MissingItemException : Exception
	{
		[CompilerGenerated]
		private string <itemName>P;

		[CompilerGenerated]
		private Vector3 <position>P;

		public string ItemName => <itemName>P;

		public Vector3 Position => <position>P;

		public MissingItemException(string itemName, Vector3 position)
		{
			//IL_0008: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			<itemName>P = itemName;
			<position>P = position;
			base..ctor($"Item not found in ObjectDB. Did you remove a mod? {<position>P} {<itemName>P}");
		}
	}
	public static class CharacterExt
	{
		public static HudData? GetHudData(this Character c)
		{
			if (!EnemyHud.instance.m_huds.TryGetValue(c, out var value))
			{
				return null;
			}
			return value;
		}
	}
	public static class ColorExt
	{
		public static string Hex(this Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new UIColor.ZColor(color).ToString();
		}
	}
	public static class FireplaceExt
	{
		public static float FuelTimeRemaining(this Fireplace fireplace, out float fuel)
		{
			if (!fireplace.m_nview.IsValid())
			{
				fuel = 0f;
				return 0f;
			}
			fuel = fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f);
			float timeRemaining = Seasons.GetTimeRemaining(fireplace);
			if (!(timeRemaining >= 0f))
			{
				return fuel * fireplace.m_secPerFuel;
			}
			return timeRemaining;
		}

		public static float FuelTimeRemaining(this Fireplace fireplace)
		{
			float fuel;
			return fireplace.FuelTimeRemaining(out fuel);
		}

		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.RealToGameTimeFuel(fuel.Value * fireplace.m_secPerFuel).Days;
		}

		public static int FuelDaysMax(this Fireplace fireplace)
		{
			return UI.RealToGameTimeFuel(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;
		}
	}
	public static class GameObjectExt
	{
		public static string GetPrefabName(this GameObject gameObject)
		{
			return Utils.GetPrefabName(((Object)gameObject).name);
		}
	}
	public static class HudExt
	{
		private static void SendHoverItemsMessage(Hud hud, object arg)
		{
			((Component)hud).SendMessage("UpdateHoverIcons", arg, (SendMessageOptions)1);
		}

		public static void UpdateHoverIcons(this Hud hud, params (Sprite Icon, string Label)[] elements)
		{
			SendHoverItemsMessage(hud, elements);
		}

		public static void UpdateHoverIcons(this Hud hud, params (string prefabName, string Label)[] elements)
		{
			SendHoverItemsMessage(hud, elements);
		}

		public static void UpdateHoverIcons(this Hud hud, params Sprite[] sprites)
		{
			SendHoverItemsMessage(hud, sprites);
		}

		public static void UpdateHoverIcons(this Hud hud, params string[] prefabNames)
		{
			SendHoverItemsMessage(hud, prefabNames);
		}
	}
	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
	{
		[CompilerGenerated]
		private sealed class <AsTuple>d__0<TKey, TValue> : IEnumerable<(TKey Key, TValue Value)>, IEnumerable, IEnumerator<(TKey Key, TValue Value)>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private (TKey Key, TValue Value) <>2__current;

			private int <>l__initialThreadId;

			private Dictionary<TKey, TValue> self;

			public Dictionary<TKey, TValue> <>3__self;

			private Dictionary<TKey, TValue>.Enumerator <>7__wrap1;

			(TKey, TValue) IEnumerator<(TKey, TValue)>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AsTuple>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(Dictionary<TKey, TValue>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = self.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap1.MoveNext())
					{
						KeyValuePair<TKey, TValue> current = <>7__wrap1.Current;
						<>2__current = (current.Key, current.Value);
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap1 = default(Dictionary<TKey, TValue>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<(TKey Key, TValue Value)> IEnumerable<(TKey, TValue)>.GetEnumerator()
			{
				<AsTuple>d__0<TKey, TValue> <AsTuple>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<AsTuple>d__ = this;
				}
				else
				{
					<AsTuple>d__ = new <AsTuple>d__0<TKey, TValue>(0);
				}
				<AsTuple>d__.self = <>3__self;
				return <AsTuple>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<(TKey, TValue)>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<AsTuple>d__0<, >))]
		public static IEnumerable<(TKey Key, TValue Value)> AsTuple<TKey, TValue>(this Dictionary<TKey, TValue> self)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AsTuple>d__0<TKey, TValue>(-2)
			{
				<>3__self = self
			};
		}

		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 InputExtStr
	{
		private static readonly Dictionary<GamepadInput, string> ButtonActionStringCache = new Dictionary<GamepadInput, string>();

		public static string ToActionString(this GamepadInput gamepadButton)
		{
			//IL_0005: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			if (ButtonActionStringCache.TryGetValue(gamepadButton, out string value))
			{
				return value;
			}
			return ButtonActionStringCache[gamepadButton] = ZInput.instance.GetBoundActionString(gamepadButton, (FloatRange?)null);
		}

		public static string ToSpriteString(this GamepadInput gamepadButton)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			string key = gamepadButton.ToActionString();
			if (ZInput.s_gamepadSpriteMap.TryGetValue(key, out var value))
			{
				string text = value["xbox"];
				return "<sprite=\"xbox\" name=\"" + text + "\">";
			}
			return string.Empty;
		}

		public static string ToDisplayText(this KeyCode keycode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected I4, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected I4, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			string text;
			if ((int)keycode <= 44)
			{
				if ((int)keycode <= 13)
				{
					if ((int)keycode != 0)
					{
						if ((int)keycode != 13)
						{
							goto IL_0129;
						}
						text = "$button_return";
					}
					else
					{
						text = "$menu_none";
					}
				}
				else if ((int)keycode != 32)
				{
					if ((int)keycode != 44)
					{
						goto IL_0129;
					}
					text = ",";
				}
				else
				{
					text = "$button_space";
				}
			}
			else if ((int)keycode <= 271)
			{
				if ((int)keycode != 46)
				{
					if ((int)keycode != 271)
					{
						goto IL_0129;
					}
					text = "$button_return";
				}
				else
				{
					text = ".";
				}
			}
			else
			{
				switch (keycode - 303)
				{
				case 1:
					goto IL_00f1;
				case 0:
					goto IL_00f9;
				case 5:
					goto IL_0101;
				case 4:
					goto IL_0109;
				case 3:
					goto IL_0111;
				case 2:
					goto IL_0119;
				}
				switch (keycode - 323)
				{
				case 0:
					break;
				case 1:
					goto IL_00a6;
				case 2:
					goto IL_00b1;
				case 3:
					goto IL_00b9;
				case 4:
					goto IL_00c1;
				default:
					goto IL_0129;
				}
				text = "$button_mouse0";
			}
			goto IL_0137;
			IL_00f1:
			text = "$button_lshift";
			goto IL_0137;
			IL_0109:
			text = "$button_ralt";
			goto IL_0137;
			IL_0129:
			text = ((object)(KeyCode)(ref keycode)).ToString();
			goto IL_0137;
			IL_00b9:
			text = "Mouse-3";
			goto IL_0137;
			IL_00c1:
			text = "Mouse-4";
			goto IL_0137;
			IL_00f9:
			text = "$button_rshift";
			goto IL_0137;
			IL_00b1:
			text = "$button_mouse2";
			goto IL_0137;
			IL_0137:
			string text2 = text;
			return Localization.instance.Localize(text2);
			IL_00a6:
			text = "$button_mouse1";
			goto IL_0137;
			IL_0119:
			text = "$button_rctrl";
			goto IL_0137;
			IL_0101:
			text = "$button_lalt";
			goto IL_0137;
			IL_0111:
			text = "$button_lctrl";
			goto IL_0137;
		}
	}
	public static class InventoryGridExt
	{
		public static void ShowAmountText(this InventoryGrid grid, bool isVisible, Vector2i pos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			grid.ShowAmountText(isVisible, pos.x * (pos.y + 1));
		}

		public static void ShowAmountText(this InventoryGrid grid, bool isVisible, int index = -1)
		{
			InventoryGrid grid2 = grid;
			if (grid2.m_elements.Count == 0)
			{
				return;
			}
			if (grid2.m_elements.Count < index)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			Timing.NextFrame(delegate
			{
				Log.Info($"Show grid element amount: {isVisible} at index: {index}", 0);
				if (index == -1)
				{
					CollectionExtensions.Do<Element>((IEnumerable<Element>)grid2.m_elements, (Action<Element>)delegate(Element element)
					{
						((Component)element.m_amount).gameObject.SetActive(isVisible);
					});
				}
				else
				{
					((Component)grid2.m_elements[index].m_amount).gameObject.SetActive(isVisible);
				}
			});
		}
	}
	public static class InventoryGuiExt
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass1_0
		{
			public GameObject btn;
		}

		private static bool _isRestoringStackAllButton;

		public static void ShowStackAllButton(this InventoryGui self, bool show)
		{
			<>c__DisplayClass1_0 CS$<>8__locals0 = new <>c__DisplayClass1_0();
			Log.Info($"Show StackAll button: {show}", 0);
			CS$<>8__locals0.btn = ((Component)self.m_stackAllButton).gameObject;
			CS$<>8__locals0.btn.SetActive(show);
			if (!show && !_isRestoringStackAllButton)
			{
				Timing.StartCoroutine(Restore());
			}
			[IteratorStateMachine(typeof(<>c__DisplayClass1_0.<<ShowStackAllButton>g__Restore|0>d))]
			IEnumerator Restore()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass1_0.<<ShowStackAllButton>g__Restore|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}
	}
	public static class ItemDataExt
	{
		public static bool TryGetRecipe(this ItemDrop itemDrop, out Recipe recipe)
		{
			return itemDrop.m_itemData.TryGetRecipe(out recipe);
		}

		public static bool TryGetRecipe(this ItemData item, out Recipe recipe)
		{
			return Object.op_Implicit((Object)(object)(recipe = ObjectDB.instance.GetRecipe(item)));
		}

		public static ItemType GetItemType(this ItemData? item)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return (ItemType)(((??)item?.m_shared.m_itemType) ?? 0);
		}

		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))
			{
				GameObject val = default(GameObject);
				if (!ObjectDB.instance.TryGetItemPrefab(item.m_shared, ref val))
				{
					throw new Exception("Missing dropPrefab and sharedData index for " + item.GetName());
				}
				return ((Object)val).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 ItemData item)
		{
			return StringExtensionMethods.GetStableHashCode(item.GetPrefabName());
		}

		public static int GetStableHashCode(this ItemDrop itemDrop)
		{
			return StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(((Object)itemDrop).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)
		{
			if (Object.op_Implicit((Object)(object)itemStand.m_guardianPower))
			{
				return Object.op_Implicit((Object)(object)((Component)itemStand).GetComponentInParent<BossStone>());
			}
			return false;
		}

		public static bool IsAutoAttach(this ItemStand itemStand)
		{
			return itemStand.m_autoAttach;
		}

		public static bool CanBeRemoved(this ItemStand itemStand)
		{
			return itemStand.m_canBeRemoved;
		}
	}
	public static class MaterialExt
	{
		private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor");

		private static readonly int Metallic = Shader.PropertyToID("_Metallic");

		private static readonly int Glossiness = Shader.PropertyToID("_Glossiness");

		public static void SetMetalic(this Material mat, float range)
		{
			mat.SetFloat(Metallic, range);
		}

		public static void SetGlossiness(this Material mat, float range)
		{
			mat.SetFloat(Glossiness, range);
		}

		public static void SetGlow(this Material mat, float intensity)
		{
			//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)
			mat.SetEmission(Color.white * intensity);
		}

		public static void SetEmission(this Material mat, Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			mat.SetColor(EmissionColor, color);
		}
	}
	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 PrefabManagerExt
	{
		public static CraftingStation? GetCraftingStation(this PrefabManager prefabManager, string stationName)
		{
			string internalName = CraftingStations.GetInternalName(stationName);
			GameObject prefab = prefabManager.GetPrefab(internalName);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return null;
			}
			return prefab.GetComponent<CraftingStation>();
		}
	}
	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, params string[] words)
		{
			return Localization.instance.Localize(s, words);
		}

		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");

		public static bool IsPlayerCreated(this ZDO zdo)
		{
			if (zdo.IsValid())
			{
				return zdo.GetLong(ZDOVars.s_creator, 0L) != 0;
			}
			return false;
		}

		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.", 0);
				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.", 0);
			}
			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.", 0);
			}
			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 ItemData? GetItemData(this ZDO zdo, string itemPrefabName, int index = -1)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (Utility.IsNullOrWhiteSpace(itemPrefabName))
			{
				return null;
			}
			ItemData val = new ItemData();
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemPrefabName);
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				throw new MissingItemException(itemPrefabName, zdo.GetPosition());
			}
			val.m_dropPrefab = itemPrefab;
			val.m_shared = itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared;
			if (index > -1)
			{
				ItemDrop.LoadFromZDO(index, val, zdo);
			}
			else
			{
				ItemDrop.LoadFromZDO(val, zdo);
			}
			return val;
		}
	}
	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, 1);
			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 ZNetViewExt
	{
	}
	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, 0);
			}
		}
	}
	public interface IRedecorate
	{
		void OnRedecorateBefore();

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

		private 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 const float UpdateDelay = 0.1f;

		private static float _lastUpdateTime;

		private event Action? UpdateBuildHints;

		private event Action? UpdateCombatHints;

		private event Action? UpdateBowHints;

		private event Action? UpdateInventoryHints;

		private event Action? UpdateBarberHints;

		private event Action? UpdateFishingHints;

		private event Action? UpdateRadialHints;

		internal void RemoveAll()
		{
			foreach (var value in _allHints.Values)
			{
				Object.Destroy((Object)(object)value.Keyboard);
				Object.Destroy((Object)(object)value.Gamepad);
			}
			_allHints.Clear();
			this.UpdateBuildHints = null;
			this.UpdateCombatHints = null;
			this.UpdateBowHints = null;
			this.UpdateInventoryHints = null;
			this.UpdateBarberHints = null;
			this.UpdateFishingHints = null;
			this.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(ZenMod.CallingInstance, hintType, action.Name, index, startVisible);
		}

		public static void Create(HintType hintType, string hintName, int index = -1, bool startVisible = false)
		{
			Create(ZenMod.CallingInstance, hintType, hintName, index, startVisible);
		}

		private static void Create(ZenMod mod, HintType hintType, string hintName, int index = -1, bool startVisible = false)
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			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);
			mod.KeyHint._allHints.Add(hintName, value);
			Localization.instance.Localize(hintRoot.transform);
		}

		public static void SetEvent(HintType hintType, Action action)
		{
			KeyHint keyHint = ZenMod.CallingInstance.KeyHint;
			switch (hintType)
			{
			case HintType.Build:
				keyHint.UpdateBuildHints += action;
				break;
			case HintType.Combat:
				keyHint.UpdateCombatHints += action;
				break;
			case HintType.Bow:
				keyHint.UpdateBowHints += action;
				break;
			case HintType.Inventory:
				keyHint.UpdateInventoryHints += action;
				break;
			case HintType.Barber:
				keyHint.UpdateBarberHints += action;
				break;
			case HintType.Fishing:
				keyHint.UpdateFishingHints += action;
				break;
			case HintType.Radial:
				keyHint.UpdateRadialHints += action;
				break;
			default:
				throw new ArgumentOutOfRangeException("hintType", hintType, "Unknown hint type.");
			}
		}

		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, 0);
					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))
			{
				return;
			}
			_lastUpdateTime = Time.time;
			if (__instance.m_buildHints.activeSelf)
			{
				InvokeHint(HintType.Build, (KeyHint hint) => hint.UpdateBuildHints);
			}
			if (__instance.m_inventoryHints.activeSelf)
			{
				InvokeHint(HintType.Inventory, (KeyHint hint) => hint.UpdateInventoryHints);
			}
			if (__instance.m_combatHints.activeSelf)
			{
				InvokeHint(HintType.Combat, (KeyHint hint) => hint.UpdateCombatHints);
			}
			if (__instance.m_combatHints.activeSelf && ((Humanoid)(object)Player.m_localPlayer).IsUsingRangedWeapon())
			{
				InvokeHint(HintType.Bow, (KeyHint hint) => hint.UpdateBowHints);
			}
			if (__instance.m_fishingHints.activeSelf)
			{
				InvokeHint(HintType.Fishing, (KeyHint hint) => hint.UpdateFishingHints);
			}
			if (__instance.m_barberHints.activeSelf)
			{
				InvokeHint(HintType.Barber, (KeyHint hint) => hint.UpdateBarberHints);
			}
			if (__instance.m_radialHints.activeSelf)
			{
				InvokeHint(HintType.Radial, (KeyHint hint) => hint.UpdateRadialHints);
			}
		}

		private static void InvokeHint(HintType hintType, Func<KeyHint, Action?> eventSelector)
		{
			Func<KeyHint, Action?> eventSelector2 = eventSelector;
			_activeType = hintType;
			foreach (Action item in ZenMod.Instances.Values.Select((ZenMod mod) => eventSelector2(mod.KeyHint)))
			{
				item?.Invoke();
			}
		}
	}
	public class Hotload
	{
		private readonly HashSet<Object> _hotloadObjects = new HashSet<Object>();

		internal bool IsPrefabInitInvoked { get; private set; }

		public event Func<IEnumerable<Object>>? PrefabInit;

		internal Hotload()
		{
		}

		public void Track(Object obj)
		{
			Log.Info($"Track: {obj.name} << {((object)obj).GetType()}", 0);
			_hotloadObjects.Add(obj);
		}

		public void Untrack(Object obj)
		{
			if (_hotloadObjects.Contains(obj))
			{
				Log.Debug($"Untrack: {obj.name} @ {((object)obj).GetType()}", 0);
				_hotloadObjects.Remove(obj);
			}
		}

		internal void RestoreAll()
		{
			Log.Info("Restoring all hot-tracked modded objects to their original state", 0);
			foreach (Object hotloadObject in _hotloadObjects)
			{
				Log.Info($"Remove: {hotloadObject.name} >> {((object)hotloadObject).GetType()}", 0);
				Object.Destroy(hotloadObject);
			}
		}

		internal void PrefabInitInvoke()
		{
			if (IsPrefabInitInvoked)
			{
				throw new Exception("PrefabInitInvoke already invoked");
			}
			Log.Info("Prefab Init", 0);
			foreach (Object item in this.PrefabInit?.Invoke() ?? Array.Empty<Object>())
			{
				Track(item);
			}
			IsPrefabInitInvoked = true;
		}
	}
	public class Tally : Tally<string>
	{
	}
	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, IEqualityComparer<KeyValuePair<T, int>>? comparer = null)
		{
			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, comparer);
			IEnumerable<KeyValuePair<T, int>> second = other.Except<KeyValuePair<T, int>>(this, comparer);
			hashSet = new HashSet<T>();
			foreach (T item in from item in first.Union<KeyValuePair<T, int>>(second, comparer)
				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 class TerminalCtrl
	{
		private readonly List<string> _commands = new List<string>();

		public string Prefix { get; private set; }

		internal TerminalCtrl(string prefix)
		{
			Prefix = prefix + "_";
		}

		public ConsoleCommand CreateCommand(string name, string description, bool isCheat, Action<string[]> action)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			Action<string[]> action2 = action;
			string text = Prefix + name;
			_commands.Add(text);
			Log.Info("Terminal command added: " + text, 0);
			return new ConsoleCommand(text, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				action2(args.Args);
			}, isCheat, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		internal void Shutdown()
		{
			foreach (string command in _commands)
			{
				Terminal.commands.Remove(command.ToLower());
			}
			_commands.Clear();
		}
	}
	public static class Timing
	{
		[CompilerGenerated]
		private sealed class <_Delay>d__15 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public float delay;

			public Action action;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <_Delay>d__15(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					action();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <_EndOfFrame>d__17 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Action action;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <_EndOfFrame>d__17(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					action();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <_SkipFrames>d__16 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public int frames;

			public Action action;

			private int <i>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <_SkipFrames>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < frames)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				action();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <_When>d__14 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Func<bool> condition;

			public Action action;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <_When>d__14(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitUntil(condition);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					action();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static Coroutine StartCoroutine(IEnumerator coroutine)
		{
			return ((MonoBehaviour)ZenMod.CallingInstance).StartCoroutine(coroutine);
		}

		public static void StopCoroutine(Coroutine? coroutine)
		{
			if (coroutine != null)
			{
				((MonoBehaviour)ZenMod.CallingInstance).StopCoroutine(coroutine);
			}
		}

		public static Coroutine SkipFrames(this MonoBehaviour component, int frames, Action action)
		{
			return component.StartCoroutine(_SkipFrames(frames, action));
		}

		public static Coroutine SkipFrames(int frames, Action action)
		{
			return ((MonoBehaviour)(object)ZenMod.CallingInstance).SkipFrames(frames, action);
		}

		public static Coroutine NextFrame(this MonoBehaviour component, Action action)
		{
			return component.StartCoroutine(_SkipFrames(1, action));
		}

		public static Coroutine NextFrame(Action action)
		{
			return ((MonoBehaviour)(object)ZenMod.CallingInstance).NextFrame(action);
		}

		public static Coroutine EndOfFrame(this MonoBehaviour component, Action action)
		{
			return component.StartCoroutine(_EndOfFrame(action));
		}

		public static Coroutine EndOfFrame(Action action)
		{
			return ((MonoBehaviour)(object)ZenMod.CallingInstance).EndOfFrame(action);
		}

		public static Coroutine Delay(this MonoBehaviour component, float seconds, Action action)
		{
			return component.StartCoroutine(_Delay(seconds, action));
		}

		public static Coroutine Delay(float seconds, Action action)
		{
			return ((MonoBehaviour)(object)ZenMod.CallingInstance).Delay(seconds, action);
		}

		public static Coroutine When(this MonoBehaviour component, Func<bool> condition, Action action)
		{
			return component.StartCoroutine(_When(condition, action));
		}

		public static Coroutine When(Func<bool> condition, Action action)
		{
			return ((MonoBehaviour)(object)ZenMod.CallingInstance).When(condition, action);
		}

		public static Coroutine WhenNot(this MonoBehaviour component, Func<bool> condition, Action action)
		{
			Func<bool> condition2 = condition;
			return component.StartCoroutine(_When(() => !condition2(), action));
		}

		public static Coroutine WhenNot(Func<bool> condition, Action action)
		{
			return ((MonoBehaviour)(object)ZenMod.CallingInstance).WhenNot(condition, action);
		}

		[IteratorStateMachine(typeof(<_When>d__14))]
		private static IEnumerator _When(Func<bool> condition, Action action)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <_When>d__14(0)
			{
				condition = condition,
				action = action
			};
		}

		[IteratorStateMachine(typeof(<_Delay>d__15))]
		private static IEnumerator _Delay(float delay, Action action)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <_Delay>d__15(0)
			{
				delay = delay,
				action = action
			};
		}

		[IteratorStateMachine(typeof(<_SkipFrames>d__16))]
		private static IEnumerator _SkipFrames(int frames, Action action)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <_SkipFrames>d__16(0)
			{
				frames = frames,
				action = action
			};
		}

		[IteratorStateMachine(typeof(<_EndOfFrame>d__17))]
		private static IEnumerator _EndOfFrame(Action action)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <_EndOfFrame>d__17(0)
			{
				action = action
			};
		}
	}
	public static class UI
	{
		public static string PromptUseItem => Prompt("1-8");

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

		public static 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 Material CleanImageTransparency => ((Graphic)Minimap.instance.m_pingImageObject).material;

		internal static CanvasScaler? CanvasScaler { get; set; }

		public static float ScaleFactor
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)CanvasScaler))
				{
					return 1f;
				}
				return CanvasScaler.scaleFactor;
			}
		}

		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 dayMin = 0f)
		{
			float num = seconds / (float)EnvMan.instance.m_dayLengthSec;
			return TimeSpan.FromDays((num <= 0f) ? 0f : (num + dayMin));
		}

		public static TimeSpan RealToGameTimeFuel(float seconds)
		{
			return RealToGameTime(seconds, 0.51f);
		}

		public static string RemainingTimeText(float seconds, float secPerFuel = -1f)
		{
			bool num = secPerFuel > (float)EnvMan.instance.m_dayLengthSec;
			TimeSpan timeSpan = (num ? RealToGameTimeFuel(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 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;
		}

		public static string InsertInteractAlt(string hoverText, string label)
		{
			string pattern = "^(" + PromptInteract.RegexPattern() + ".*)$";
			string text = PromptInteractAlt + " " + label;
			return Regex.Replace(hoverText, pattern, "$1\n" + text, RegexOptions.Multiline);
		}

		public static string CreateMeter(float value, float max, int length)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			int num = (int)(Mathf.Clamp01(Mathf.Ceil(value) / max) * (float)length);
			int num2 = length - num;
			UIColor.ZColor minorInfo = UIColor.MinorInfo;
			Color color = minorInfo.Color * 0.5f;
			color.a = 1f;
			UIColor.ZColor zColor = new UIColor.ZColor(color);
			string text = string.Format("{0}<color={1}>", " ", minorInfo) + new string('▔', num) + "</color>";
			if (num2 > 0)
			{
				text = text + $"<color={zColor}>" + new string('▔', num2) + "</color>";
			}
			return "\n" + text;
		}
	}
	public static class UIColor
	{
		public readonly struct ZColor : IEquatable<ZColor>
		{
			public readonly string Hex;

			public readonly Color Color;

			public ZColor(Color color)
			{
				//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)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Color = color;
				Hex = ColorUtility.ToHtmlStringRGBA(Color);
			}

			public static implicit operator Color(ZColor color)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return color.Color;
			}

			public static implicit operator ZColor(Color color)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return new ZColor(color);
			}

			public static implicit operator ZColor(Color32 color)
			{
				//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 new ZColor(Color32.op_Implicit(color));
			}

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

			public bool Equals(ZColor other)
			{
				//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_000a: Unknown result type (might be due to invalid IL or missing references)
				Color color = Color;
				return ((Color)(ref color)).Equals(other.Color);
			}

			public override bool Equals(object? obj)
			{
				if (obj is ZColor other)
				{
					return Equals(other);
				}
				return false;
			}

			public override int GetHashCode()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Color color = Color;
				return ((object)(Color)(ref color)).GetHashCode();
			}
		}

		public static readonly ZColor ValheimOrange = (ZColor)new Color(1f, 0.631f, 0.235f, 1f);

		public static readonly ZColor ValheimYellow = (ZColor)new Color(1f, 0.889f, 0f, 1f);

		public static readonly ZColor ValheimBeige = (ZColor)new Color(0.8529f, 0.725f, 0.5331f, 1f);

		public static readonly ZColor White = Color.white;

		public static readonly ZColor Black = Color.black;

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

		public static readonly ZColor DarkGray = (ZColor)new Color32((byte)79, (byte)79, (byte)79, byte.MaxValue);

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

		public static readonly ZColor Orange = (ZColor)new Color(1f, 0.5f, 0f, 1f);

		public static readonly ZColor Yellow = (ZColor)new Color(1f, 1f, 0f);

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

		public static readonly ZColor Blue = (ZColor)new Color32((byte)0, (byte)0, byte.MaxValue, byte.MaxValue);

		public static readonly ZColor Green = (ZColor)new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue);

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

		public static readonly ZColor LightOrange = (ZColor)new Color32(byte.MaxValue, (byte)153, (byte)0, byte.MaxValue);

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

		public static readonly ZColor LightRed = (ZColor)new Color32(byte.MaxValue, (byte)102, (byte)102, byte.MaxValue);

		public static readonly ZColor LightBlue = (ZColor)new Color(0f, 0.5f, 1f);

		public static readonly ZColor LightGreen = (ZColor)new Color32((byte)102, byte.MaxValue, (byte)102, byte.MaxValue);

		public static readonly ZColor LightPurple = (ZColor)new Color32((byte)221, (byte)136, byte.MaxValue, byte.MaxValue);

		public static readonly ZColor MinorInfo = Gray;

		public static readonly ZColor MajorInfo = ValheimOrange;
	}
	public abstract class ZenMod<T> : ZenMod where T : ZenMod<T>
	{
		public new static T Instance { get; private set; }

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

		public static TerminalCtrl Terminal => Instance.TerminalCtrl;

		public static Hotload Hotload => Instance._hotload;

		public static bool IsHeadless => (int)SystemInfo.graphicsDeviceType == 4;

		public static bool IsOnServerAlso => ModCompatibility.IsModuleOnServer((BaseUnityPlugin)(object)Instance);

		public static bool IsOnServerAndAllClients
		{
			get
			{
				//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)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Invalid comparison between Unknown and I4
				if (!IsOnServerAlso)
				{
					return false;
				}
				CompatibilityLevel enforceModOnClients = ((MemberInfo)((object)Instance).GetType()).GetCustomAttribute<NetworkCompatibilityAttribute>().EnforceModOnClients;
				if (enforceModOnClients - 2 <= 1)
				{
					return true;
				}
				return false;
			}
		}

		protected ZenMod()
		{
			if (Object.op_Implicit((Object)(object)Instance))
			{
				throw new Exception($"Instance {typeof(T)} is already loaded. There can be only one!");
			}
			Instance = (T)this;
		}
	}
	public abstract class ZenMod : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <InvokeGetSyncConfigs>d__77 : IEnumerable<Action>, IEnumerable, IEnumerator<Action>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Action <>2__current;

			private int <>l__initialThreadId;

			private Func<Action?> @event;

			public Func<Action?> <>3__event;

			private Delegate[] <>7__wrap1;

			private int <>7__wrap2;

			Action IEnumerator<Action>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InvokeGetSyncConfigs>d__77(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0073;
				}
				<>1__state = -1;
				<>7__wrap1 = @event?.GetInvocationList() ?? Array.Empty<Delegate>();
				<>7__wrap2 = 0;
				goto IL_0081;
				IL_0081:
				if (<>7__wrap2 < <>7__wrap1.Length)
				{
					Action action = ((Func<Action>)<>7__wrap1[<>7__wrap2])();
					if (action != null)
					{
						<>2__current = action;
						<>1__state = 1;
						return true;
					}
					goto IL_0073;
				}
				<>7__wrap1 = null;
				return false;
				IL_0073:
				<>7__wrap2++;
				goto IL_0081;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Action> IEnumerable<Action>.GetEnumerator()
			{
				<InvokeGetSyncConfigs>d__77 <InvokeGetSyncConfigs>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<InvokeGetSyncConfigs>d__ = this;
				}
				else
				{
					<InvokeGetSyncConfigs>d__ = new <InvokeGetSyncConfigs>d__77(0);
				}
				<InvokeGetSyncConfigs>d__.@event = <>3__event;
				return <InvokeGetSyncConfigs>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Action>)this).GetEnumerator();
			}
		}

		public const string AuthorName = "ZenDragon";

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

		private static bool _requireGamepadRemap;

		private bool _loadedOnce;

		private readonly Assembly _assembly;

		private readonly Harmony _harmony;

		private protected readonly Hotload _hotload = new Hotload();

		internal static readonly Dictionary<Assembly, ZenMod> Instances = new Dictionary<Assembly, ZenMod>();

		private readonly List<Action> _craftingSyncConfigs = new List<Action>();

		private readonly List<Action> _prefabSyncConfigs = new List<Action>();

		protected virtual GameVersion? RequiredValheimVersion => null;

		internal TerminalCtrl TerminalCtrl { get; }

		internal KeyHint KeyHint { get; } = new KeyHint();


		internal HashSet<ActionString> RegisteredActionStrings { get; } = new HashSet<ActionString>();


		internal Log Log { get; }

		protected bool RunOnServer { get; set; }

		protected internal bool RequireGamepadRemap
		{
			get
			{
				return _requireGamepadRemap;
			}
			protected set
			{
				if (value)
				{
					if (!ZenMod<ModLib>.IsHeadless)
					{
						Log.Message("Requires extended controls. Gamepad remap will be applied.", 0u);
					}
					_requireGamepadRemap = value;
				}
			}
		}

		public bool IsScriptEngine
		{
			get
			{
				if (!Utility.IsNullOrWhiteSpace(((BaseUnityPlugin)this).Info.Location))
				{
					return ((BaseUnityPlugin)this).Info.Location.Contains("scripts");
				}
				return true;
			}
		}

		protected bool IsInitialized { get; private set; }

		internal static ZenMod Instance
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (!Instances.TryGetValue(Assembly.GetCallingAssembly(), out ZenMod value))
				{
					return GetInstance(Assembly.GetExecutingAssembly());
				}
				return value;
			}
		}

		internal static ZenMod ExecInstance
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return GetInstance(Assembly.GetExecutingAssembly());
			}
		}

		internal static ZenMod CallingInstance
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return GetInstance(Assembly.GetCallingAssembly());
			}
		}

		public event Action? RegisterInputs;

		public event Func<Action?>? RegisterCraftingItems;

		public event Func<Action?>? PrefabsRegistered;

		public event Action<string>? LanguageChanged;

		public event Action? ConfigSync;

		public static T GetInstance<T>() where T : ZenMod
		{
			return (T)GetInstance(typeof(T).Assembly);
		}

		internal static ZenMod GetInstance(Assembly assembly)
		{
			if (!Instances.TryGetValue(assembly, out ZenMod value))
			{
				throw new MissingInstanceException(assembly);
			}
			return value;
		}

		protected abstract void Setup();

		protected abstract void TitleScene(bool isFirstBoot);

		protected abstract void WorldStart();

		protected abstract void Shutdown();

		protected virtual void HotRestore()
		{
		}

		protected ZenMod()
		{
			Game.isModded = true;
			_assembly = ((object)this).GetType().Assembly;
			if (Instances.ContainsKey(_assembly))
			{
				throw new Exception($"Mod instance {((object)this).GetType()} already exists, there can be only one.");
			}
			Instances.Add(_assembly, this);
			_harmony = Harmony.CreateAndPatchAll(_assembly, (string)null);
			Zen.Config.Config.File = ((BaseUnityPlugin)this).Config;
			Log = new Log(((BaseUnityPlugin)this).Logger);
			if (IsScriptEngine)
			{
				Log.Warning("------------------------------", 0u);
				Log.Warning($"Type: {((object)this).GetType()}", 0u);
				Log.Warning("Assembly: " + _assembly.GetName().Name, 0u);
				Log.Warning($"Assembly Hash: {_assembly.GetHashCode():X}", 0u);
				Log.Warning("------------------------------", 0u);
			}
			TerminalCtrl = new TerminalCtrl(((BaseUnityPlugin)this).Info.Metadata.Name);
			Zen.Config.Config.Define(isAdmin: false, "_Author", "Website", "https://github.com/ZenDragonX/ZenMods_Valheim/wiki", "ZenDragon\nLike my mods?");
		}

		protected 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if (RequiredValheimVersion.HasValue)
			{
				GameVersion? requiredValheimVersion = RequiredValheimVersion;
				GameVersion currentVersion = Version.CurrentVersion;
				if (!requiredValheimVersion.HasValue || requiredValheimVersion.GetValueOrDefault() != currentVersion)
				{
					Log.Error($"Valheim version mismatch. Required: {RequiredValheimVersion} Current: {Version.CurrentVersion}", 0u);
					AbortInit();
					return;
				}
			}
			RegisterEventHandlers();
			InitConfigs();
			Setup();
			PreInit();
			if (IsScriptEngine)
			{
				DebugAddTranslations();
			}
		}

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

		protected virtual bool IsSysReady()
		{
			bool flag = Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer);
			bool flag2 = Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsDedicated();
			if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return flag2 || flag;
			}
			return false;
		}

		private void CheckInit()
		{
			Log.Debug("CheckInit", 0u);
			if (!IsSysReady())
			{
				return;
			}
			if (ZNet.instance.IsDedicated())
			{
				if (!RunOnServer)
				{
					Log.Message("Server mode: ConfigSync", 0u);
					AbortInit();
					return;
				}
				Log.Message("Server mode: Active", 0u);
			}
			((MonoBehaviour)this).CancelInvoke("CheckInit");
			if (!_loadedOnce)
			{
				OnLanguageChange();
				OnInputLayoutChanged();
			}
			UI.CanvasScaler = ((Component)Hud.instance).GetComponent<GuiScaler>().m_canvasScaler;
			Log.Info("Reload Configs", 0u);
			((BaseUnityPlugin)this).Config.Reload();
			if (!_hotload.IsPrefabInitInvoked && IsScriptEngine)
			{
				_hotload.PrefabInitInvoke();
				Log.Warning("Hot restoring existing objects", 0u);
				HotRestore();
			}
			Log.Info("World Start", 0u);
			WorldStart();
			IsInitialized = true;
			_loadedOnce = true;
		}

		private void AbortInit()
		{
			((MonoBehaviour)this).CancelInvoke("CheckInit");
			_harmony.UnpatchSelf();
		}

		private void DebugAddTranslations()
		{
			if (!IsScriptEngine)
			{
				Log.Warning("Not running as script! Skipping debug add translations", 0u);
				return;
			}
			Timing.EndOfFrame(delegate
			{
				Log.Debug("Assembly: " + ((object)this).GetType().Assembly.GetName().Name, 0u);
				Log.Debug("Assembly Location: " + ((object)this).GetType().Assembly.Location, 0u);
				Log.Debug("Type: " + ((object)this).GetType(), 0u);
				Log.Debug("Name: " + ((BaseUnityPlugin)this).Info.Met