Decompiled source of SeidrChest v0.1.18

SeidrChest.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;
using neobotics.ModSdk;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SeidrChest")]
[assembly: AssemblyConfiguration("Deploy")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+942b359b707d27a4895cd56938640711a149a626")]
[assembly: AssemblyProduct("SeidrChest")]
[assembly: AssemblyTitle("SeidrChest")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace neobotics.ModSdk
{
	public class AudioHelper : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <Co_LoadAudio>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string filePath;

			public string[] audioFiles;

			public AudioHelper <>4__this;

			private UnityWebRequest <URL>5__2;

			private int <f>5__3;

			private string <clipUri>5__4;

			private string <clipName>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<URL>5__2 = null;
				<clipUri>5__4 = null;
				<clipName>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				AudioHelper audioHelper = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<URL>5__2 = null;
					Logging.GetLogger().Debug("Co_LoadAudio loading files from " + filePath);
					<f>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					if (<URL>5__2 != null)
					{
						try
						{
							AudioClip content = DownloadHandlerAudioClip.GetContent(<URL>5__2);
							audioHelper.audioClips.Add(<clipName>5__5.ToLower(), content);
						}
						catch (Exception ex)
						{
							Logging.GetLogger().Warning("Failed to load clip " + <clipUri>5__4 + ": " + ex.Message);
						}
					}
					else
					{
						Logging.GetLogger().Warning("Failed to get URL for " + <clipUri>5__4);
					}
					<clipUri>5__4 = null;
					<clipName>5__5 = null;
					<f>5__3++;
					break;
				}
				if (<f>5__3 < audioFiles.Length)
				{
					<clipUri>5__4 = new Uri(audioFiles[<f>5__3]).AbsoluteUri;
					<clipName>5__5 = audioFiles[<f>5__3].Substring(filePath.Length + 1);
					Logging.GetLogger().Debug("Loading audio clip " + <clipName>5__5);
					try
					{
						<URL>5__2 = UnityWebRequestMultimedia.GetAudioClip(<clipUri>5__4, (AudioType)0);
					}
					catch (Exception ex2)
					{
						Logging.GetLogger().Warning("Can't find audio resource: " + ex2.Message);
					}
					<>2__current = <URL>5__2.SendWebRequest();
					<>1__state = 1;
					return true;
				}
				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();
			}
		}

		private Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>();

		public void Awake()
		{
			Logging.GetLogger().Debug("AudioHelper.Awake");
			LoadAudioResources();
			ZRoutedRpc.instance.Register<Vector3, string>("NeoPlayClip", (Action<long, Vector3, string>)RPC_NeoPlayClip);
		}

		public void RPC_NeoPlayClip(long sender, Vector3 sourcePoint, string clipName)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Logging.GetLogger().Debug("AudioHelper.RPC_NeoPlayClip");
			if (ZNet.instance.IsDedicated())
			{
				return;
			}
			try
			{
				NeoPlayClip(sourcePoint, clipName);
			}
			catch (Exception e)
			{
				Logging.GetLogger().Error(e, stackTrace: false);
			}
		}

		public void Play(Vector3 sourcePoint, string clipName)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Logging.GetLogger().Debug("AudioHelper.Play");
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "NeoPlayClip", new object[2] { sourcePoint, clipName });
		}

		public void NeoPlayClip(Vector3 sourcePoint, string clipName)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			NeoPlayClip(sourcePoint, position, clipName);
		}

		public void NeoPlayClip(Vector3 sourcePoint, Vector3 targetPoint, string clipName)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Logging.GetLogger().Debug("AudioHelper.NeoPlayClip");
			Vector3 val = sourcePoint - targetPoint;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float num = (Vector3.Distance(sourcePoint, targetPoint) + 1f) / 10f;
			if (audioClips.TryGetValue(clipName.ToLower(), out var value))
			{
				AudioSource.PlayClipAtPoint(value, targetPoint + normalized * num, 1f);
			}
			else
			{
				Logging.GetLogger().Warning("Couldn't find audio clip for " + clipName);
			}
		}

		public float GetClipDuration(string clipName)
		{
			if (!audioClips.TryGetValue(clipName.ToLower(), out var value))
			{
				return -1f;
			}
			return value.length;
		}

		private void LoadAudioResources()
		{
			FileInfo fileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
			string[] array = new string[0];
			Dictionary<string, AudioType> obj = new Dictionary<string, AudioType>
			{
				{
					"*.wav",
					(AudioType)20
				},
				{
					"*.mp3",
					(AudioType)13
				}
			};
			string directoryName = fileInfo.DirectoryName;
			audioClips.Clear();
			Logging.GetLogger().Debug("LoadAudioResources");
			foreach (string key in obj.Keys)
			{
				array = CollectionExtensions.AddRangeToArray<string>(array, Directory.GetFiles(fileInfo.DirectoryName, key, SearchOption.TopDirectoryOnly));
			}
			((MonoBehaviour)this).StartCoroutine(Co_LoadAudio(directoryName, array));
		}

		[IteratorStateMachine(typeof(<Co_LoadAudio>d__8))]
		private IEnumerator Co_LoadAudio(string filePath, string[] audioFiles)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Co_LoadAudio>d__8(0)
			{
				<>4__this = this,
				filePath = filePath,
				audioFiles = audioFiles
			};
		}
	}
	internal class CircularList<T>
	{
		private List<T> circle;

		private int index;

		public int Index => index;

		public CircularList(List<T> source, T startingElement)
		{
			circle = new List<T>(source);
			index = circle.FindIndex((T x) => x.Equals(startingElement));
		}

		public T Next()
		{
			index = ((index < circle.Count - 1) ? (index + 1) : 0);
			return circle[index];
		}

		public T Previous()
		{
			index = ((index > 0) ? (index - 1) : (circle.Count - 1));
			return circle[index];
		}
	}
	public class ConfigMock
	{
		public bool Value { get; set; }
	}
	public class CrossPlatformRandom : Random
	{
		private const int LCG_MULTIPLIER = 134775813;

		private const int LCG_INCREMENT = 1;

		private int _seed;

		public float value => (float)NextDouble();

		public CrossPlatformRandom()
		{
			Random random = new Random();
			_seed = random.Next();
		}

		public CrossPlatformRandom(int seed)
		{
			_seed = seed;
		}

		public float Range(int min, int max)
		{
			return Next(min, max);
		}

		public float Range(float min, float max)
		{
			return Mathf.Lerp(min, max, (float)NextDouble());
		}

		private int GetNext()
		{
			_seed = _seed * 134775813 + 1;
			return _seed;
		}

		public override int Next()
		{
			return Next(int.MaxValue);
		}

		public override int Next(int maxValue)
		{
			if (maxValue < 0)
			{
				throw new ArgumentOutOfRangeException("maxValue is less than zero.");
			}
			return (int)((long)(uint)GetNext() * (long)(uint)maxValue >>> 32);
		}

		public override int Next(int minValue, int maxValue)
		{
			if (minValue > maxValue)
			{
				throw new ArgumentOutOfRangeException("minValue is greater than maxValue.");
			}
			return minValue + Next(maxValue - minValue);
		}

		public override double NextDouble()
		{
			return Sample();
		}

		protected override double Sample()
		{
			return (double)Next() / 2147483647.0;
		}
	}
	internal class CustomDataWrapper
	{
		private Dictionary<string, string> playerData;

		private Dictionary<string, string> Data { get; set; }

		public CustomDataWrapper(Dictionary<string, string> sourceData, string keyPrefix)
		{
			CustomDataWrapper customDataWrapper = this;
			playerData = sourceData;
			Data = new Dictionary<string, string>();
			sourceData.Keys.ToList().ForEach(delegate(string key)
			{
				if (key.StartsWith(keyPrefix))
				{
					customDataWrapper.Data.Add(key, sourceData[key]);
				}
			});
		}

		public void Add(string key, string value)
		{
			Data.Add(key, value);
			playerData.Add(key, value);
		}

		public bool Remove(string key)
		{
			return Data.Remove(key) & playerData.Remove(key);
		}

		public void Set(string key, string value)
		{
			if (Data.ContainsKey(key))
			{
				Data[key] = value;
			}
			else
			{
				Data.Add(key, value);
			}
			if (playerData.ContainsKey(key))
			{
				playerData[key] = value;
			}
			else
			{
				playerData.Add(key, value);
			}
		}

		public string Get(string key)
		{
			if (Data.ContainsKey(key))
			{
				return Data[key];
			}
			return null;
		}

		public bool ContainsKey(string key)
		{
			return Data.ContainsKey(key);
		}

		public void PreSaveSync()
		{
			foreach (KeyValuePair<string, string> datum in Data)
			{
				if (!playerData.ContainsKey(datum.Key))
				{
					playerData.Add(datum.Key, datum.Value);
				}
			}
		}
	}
	internal class DebugUtils
	{
		public static void ObjectInspector(object o)
		{
			if (o == null)
			{
				Debug.Log((object)"Object is null");
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			Type type = o.GetType();
			Debug.Log((object)(o.ToString() + " Type " + type.Name));
			PropertyInfo[] properties = type.GetProperties(bindingAttr);
			foreach (PropertyInfo propertyInfo in properties)
			{
				Debug.Log((object)$"{type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}");
			}
			FieldInfo[] fields = type.GetFields(bindingAttr);
			foreach (FieldInfo field in fields)
			{
				FieldPrinter(o, type, field);
			}
		}

		public static void MethodInspector(object o)
		{
			if (o == null)
			{
				Debug.Log((object)"Object is null");
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			Type type = o.GetType();
			Debug.Log((object)(o.ToString() + " Type " + type.Name));
			MethodInfo[] methods = type.GetMethods(bindingAttr);
			foreach (MethodInfo methodInfo in methods)
			{
				methodInfo.GetParameters();
				string arg = string.Join(", ", (from x in methodInfo.GetParameters()
					select x.ParameterType?.ToString() + " " + x.Name).ToArray());
				Debug.Log((object)$"{methodInfo.ReturnType} {methodInfo.Name} ({arg})");
			}
		}

		private static void ItemDataInspector(ItemData item)
		{
			ObjectInspector(item);
			ObjectInspector(item.m_shared);
		}

		private static void FieldPrinter(object o, Type t, FieldInfo field)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			try
			{
				if (field.FieldType == typeof(ItemData))
				{
					ItemData val = (ItemData)field.GetValue(o);
					if (val != null)
					{
						ItemDataInspector(val);
					}
					else
					{
						Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
					}
				}
				else if (field.FieldType == typeof(Transform))
				{
					Transform val2 = (Transform)field.GetValue(o);
					if ((Object)(object)val2 != (Object)null)
					{
						Debug.Log((object)("\tTransform.parent = " + ((Object)val2.parent).name));
					}
					else
					{
						Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
					}
				}
				else if (field.FieldType == typeof(EffectList))
				{
					EffectList val3 = (EffectList)field.GetValue(o);
					if (val3 != null)
					{
						Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}:");
						EffectData[] effectPrefabs = val3.m_effectPrefabs;
						foreach (EffectData val4 in effectPrefabs)
						{
							Debug.Log((object)("\tEffectData.m_prefab = " + ((Object)val4.m_prefab).name));
						}
					}
					else
					{
						Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
					}
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}");
				}
			}
			catch (Exception)
			{
				Debug.Log((object)("Exception accessing " + t?.Name + "." + field?.Name));
			}
		}

		public static void GameObjectInspector(GameObject go)
		{
			Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name));
			ObjectInspector(go);
			Component[] componentsInChildren = go.GetComponentsInChildren<Component>();
			foreach (Component val in componentsInChildren)
			{
				try
				{
					string obj = ((val != null) ? ((Object)val).name : null);
					object obj2;
					if (val == null)
					{
						obj2 = null;
					}
					else
					{
						Transform transform = val.transform;
						if (transform == null)
						{
							obj2 = null;
						}
						else
						{
							Transform parent = transform.parent;
							obj2 = ((parent != null) ? ((Object)parent).name : null);
						}
					}
					Debug.Log((object)("\n\nInspecting Component " + obj + " with parent " + (string?)obj2));
					ObjectInspector(val);
				}
				catch (Exception)
				{
				}
			}
		}

		public static void PrintList<T>(List<T> l)
		{
			foreach (T item in l)
			{
				Debug.Log((object)item.ToString());
			}
		}

		public static void ComponentInspector(Component c)
		{
			Debug.Log((object)("\n\nInspecting Component " + ((Object)c).name));
			ObjectInspector(c);
		}

		public static void EffectsInspector(EffectList e)
		{
			EffectData[] effectPrefabs = e.m_effectPrefabs;
			Debug.Log((object)$"Effect list has effects {e.HasEffects()} count {effectPrefabs.Length}");
			EffectData[] array = effectPrefabs;
			foreach (EffectData val in array)
			{
				Debug.Log((object)$"Effect Data {val} prefab name {((Object)val.m_prefab).name} prefab GameObject name {((Object)val.m_prefab.gameObject).name}");
			}
		}

		public static void PrintInventory()
		{
			foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
			{
				Debug.Log((object)allItem.m_shared.m_name);
			}
		}

		public static void PrintAllObjects()
		{
			ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x)
			{
				Debug.Log((object)("GameObject " + ((Object)x).name));
			});
		}

		public static void PrintAllCharacters()
		{
			Character.GetAllCharacters().ForEach(delegate(Character x)
			{
				Debug.Log((object)("Character " + ((Object)x).name));
			});
		}

		public static void PrintAllLayers()
		{
			string[] array = (from index in Enumerable.Range(0, 31)
				select LayerMask.LayerToName(index) into l
				where !string.IsNullOrEmpty(l)
				select l).ToArray();
			foreach (string text in array)
			{
				Debug.Log((object)("Layer " + text + " " + Convert.ToString(LayerMask.NameToLayer(text), 2).PadLeft(32, '0')));
			}
		}
	}
	public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase
	{
		private ConfigEntry<T> _entry;

		private EventHandler rootHandler;

		private Action<object, EventArgs> clientDelegate;

		private Logging Log;

		public ConfigEntry<T> ConfigEntry
		{
			get
			{
				return _entry;
			}
			set
			{
				_entry = value;
				if (_entry != null && rootHandler != null)
				{
					_entry.SettingChanged += rootHandler;
				}
				Name = ((ConfigEntryBase)_entry).Definition.Key;
				Section = ((ConfigEntryBase)_entry).Definition.Section;
				ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
				Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue);
			}
		}

		public T Value
		{
			get
			{
				return _entry.Value;
			}
			set
			{
				_entry.Value = value;
			}
		}

		public DelegatedConfigEntry(bool useServerDelegate = false)
			: this((Action<object, EventArgs>)null, useServerDelegate)
		{
		}

		public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false)
		{
			Log = Logging.GetLogger();
			Log.Trace("DelegatedConfigEntry");
			if (delegateHandler != null)
			{
				clientDelegate = delegateHandler;
			}
			if (useServerDelegate)
			{
				Log.Trace("Configuring server delegate");
				rootHandler = delegate(object s, EventArgs e)
				{
					ServerDelegate(s, e);
				};
				ServerConfiguration.ServerDelegatedEntries.Add(this);
			}
			else if (clientDelegate != null)
			{
				rootHandler = delegate(object s, EventArgs e)
				{
					clientDelegate(s, e);
				};
			}
		}

		private void ServerDelegate(object sender, EventArgs args)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			Logging.GetLogger().Trace("ServerDelegate");
			_entry.SettingChanged -= rootHandler;
			ZNet instance = ZNet.instance;
			bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null);
			if (flag.HasValue)
			{
				if (flag == false && ServerConfiguration.Instance.ReceivedServerValues)
				{
					if (ServerValue != null)
					{
						((ConfigEntryBase)_entry).SetSerializedValue(ServerValue);
						Log.Debug("Setting " + Name + " to server value " + ServerValue);
					}
				}
				else if (flag.GetValueOrDefault())
				{
					ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
					ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args);
				}
			}
			if (clientDelegate != null)
			{
				clientDelegate(sender, args);
			}
			_entry.SettingChanged += rootHandler;
		}

		public void EnableHandler(bool setActive)
		{
			if (setActive)
			{
				_entry.SettingChanged += rootHandler;
			}
			else
			{
				_entry.SettingChanged -= rootHandler;
			}
		}

		public bool IsKeyPressed()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
			{
				KeyboardShortcut value = val.Value;
				foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
				{
					if (!Input.GetKey(modifier))
					{
						return false;
					}
				}
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey))
				{
					return false;
				}
				return true;
			}
			Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
			return false;
		}

		public bool IsKeyDown()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
			{
				KeyboardShortcut value = val.Value;
				foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
				{
					if (!Input.GetKey(modifier))
					{
						return false;
					}
				}
				if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
				{
					return false;
				}
				return true;
			}
			Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
			return false;
		}

		public bool IsKeyReleased()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
			{
				KeyboardShortcut value = val.Value;
				foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
				{
					if (!Input.GetKeyUp(modifier))
					{
						return false;
					}
				}
				if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey))
				{
					return false;
				}
				return true;
			}
			Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
			return false;
		}
	}
	public class DelegatedConfigEntryBase
	{
		public string Name;

		public string Section;

		public string ServerValue;
	}
	internal class HarmonyHelper
	{
		public enum PatchType
		{
			Prefix,
			Postfix,
			Transpiler,
			Finalizer
		}

		private static Dictionary<string, string> detectionSet = new Dictionary<string, string>();

		private static Dictionary<string, string> unpatchMods = new Dictionary<string, string>();

		public static void GetDetectionSet(Dictionary<string, string> harmonyIds)
		{
			Logging logger = Logging.GetLogger();
			foreach (KeyValuePair<string, string> harmonyId in harmonyIds)
			{
				if (Harmony.HasAnyPatches(harmonyId.Key))
				{
					logger.Debug("Detected " + harmonyId.Value + " from Harmony");
					if (!detectionSet.ContainsKey(harmonyId.Key))
					{
						detectionSet.Add(harmonyId.Key, harmonyId.Value);
					}
				}
				else if (Chainloader.PluginInfos.ContainsKey(harmonyId.Key))
				{
					logger.Debug("Detected " + harmonyId.Value + " from BepInEx");
					if (!detectionSet.ContainsKey(harmonyId.Key))
					{
						detectionSet.Add(harmonyId.Key, harmonyId.Value);
					}
				}
			}
		}

		public static void AddToUnpatch(string key)
		{
			if (detectionSet.ContainsKey(key))
			{
				unpatchMods.Add(key, detectionSet[key]);
			}
		}

		public static void UnpatchMods(Harmony harmony)
		{
			Logging logger = Logging.GetLogger();
			foreach (KeyValuePair<string, string> unpatchMod in unpatchMods)
			{
				logger.Warning("Not compatible with " + unpatchMod.Value);
				Harmony.UnpatchID(unpatchMod.Key);
				detectionSet.Remove(unpatchMod.Key);
				logger.Warning("Disabled " + unpatchMod.Value);
			}
		}

		public static bool IsModDetected(string key)
		{
			return detectionSet.ContainsKey(key);
		}

		public static bool IsModNameDetected(string value)
		{
			return detectionSet.ContainsValue(value);
		}

		public static bool TryGetDetectedModName(string key, out string mod)
		{
			return detectionSet.TryGetValue(key, out mod);
		}

		public static bool TryGetDetectedModKey(string value, out string key)
		{
			key = null;
			foreach (string key2 in detectionSet.Keys)
			{
				if (detectionSet[key2] == value)
				{
					key = key2;
					return true;
				}
			}
			return false;
		}

		public static string AddAnonymousPatch(string baseMethodName, PatchType patchType, string modName, string patchMethodName = null)
		{
			string text = null;
			int num = 0;
			Logging logger = Logging.GetLogger();
			foreach (MethodBase item in Harmony.GetAllPatchedMethods().ToList())
			{
				MethodBaseExtensions.HasMethodBody(item);
				Patches patchInfo = Harmony.GetPatchInfo(item);
				ReadOnlyCollection<Patch> readOnlyCollection = patchInfo.Prefixes;
				switch (patchType)
				{
				case PatchType.Postfix:
					readOnlyCollection = patchInfo.Postfixes;
					break;
				case PatchType.Prefix:
					readOnlyCollection = patchInfo.Prefixes;
					break;
				case PatchType.Transpiler:
					readOnlyCollection = patchInfo.Transpilers;
					break;
				case PatchType.Finalizer:
					readOnlyCollection = patchInfo.Finalizers;
					break;
				}
				foreach (Patch item2 in readOnlyCollection)
				{
					if (!item2.owner.StartsWith("harmony-auto") || !(item.Name == baseMethodName))
					{
						continue;
					}
					if (patchMethodName != null)
					{
						if (item2.PatchMethod.Name == patchMethodName)
						{
							num++;
							text = item2.owner;
						}
					}
					else
					{
						num++;
						text = item2.owner;
					}
				}
				if (num == 1)
				{
					detectionSet.Add(text, modName);
					logger.Info($"Added unique anonymous {baseMethodName} {patchType}: {text} as {modName}");
				}
				else if (num > 1)
				{
					text = null;
					logger.Warning($"Found multiple anonymous {baseMethodName} {patchType} entries. Can't identify correct patch to remove or modify.");
				}
			}
			if (num == 0)
			{
				logger.Info("No patch found for " + modName);
			}
			return text;
		}
	}
	public class ImageHelper
	{
		private string resources;

		private bool isEmbedded;

		private Logging logger;

		public ImageHelper(string resourceLocation, bool embedded)
		{
			resources = resourceLocation;
			logger = Logging.GetLogger();
			isEmbedded = embedded;
		}

		public Sprite LoadSprite(string name, int width, int height, bool linear = false, float pixelsPerUnit = 100f)
		{
			logger.Debug("Reading image and creating sprite " + name);
			if (TryLoadImage(name, width, height, linear, out var image))
			{
				return LoadSprite(image, pixelsPerUnit);
			}
			return null;
		}

		public Sprite LoadSprite(Texture2D texture, float pixelsPerUnit = 100f)
		{
			return LoadSprite(texture, ((Object)texture).name, ((Texture)texture).width, ((Texture)texture).height, pixelsPerUnit);
		}

		public Sprite LoadSprite(Texture2D texture, string name, float width, float height, float pixelsPerUnit = 100f)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)texture == (Object)null)
			{
				return null;
			}
			if (Utility.IsNullOrWhiteSpace(name))
			{
				name = ((Object)texture).name;
			}
			logger.Debug("Creating sprite " + name + " from existing texture");
			Sprite obj = Sprite.Create(texture, new Rect(0f, 0f, width, height), Vector2.zero, pixelsPerUnit);
			if ((Object)(object)obj == (Object)null)
			{
				throw new ApplicationException("Can't create sprite " + name);
			}
			((Object)obj).name = name;
			return obj;
		}

		public bool TryLoadImage(string name, int width, int height, bool linear, out Texture2D image)
		{
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			image = null;
			logger.Debug("Loading " + name + " from " + resources);
			Stream stream = null;
			if (isEmbedded)
			{
				stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resources + "." + name);
			}
			else
			{
				char directorySeparatorChar = Path.DirectorySeparatorChar;
				string text = (Utility.IsNullOrWhiteSpace(resources) ? "/" : resources);
				if (!text.EndsWith("/"))
				{
					text += directorySeparatorChar;
				}
				string text2 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + text + name;
				text2 = text2.Replace('\\', directorySeparatorChar).Replace('/', directorySeparatorChar);
				try
				{
					logger.Debug("Reading file " + text2);
					stream = new FileStream(text2, FileMode.Open, FileAccess.Read);
				}
				catch (Exception ex)
				{
					logger.Warning("Error loading external resource. Using embedded resource: " + ex.Message);
					stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resources + "." + name);
				}
			}
			if (stream == null)
			{
				throw new FileNotFoundException("Can't find " + name + " in " + resources);
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, (int)stream.Length);
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, true, linear);
			logger.Debug("Loading image " + name);
			if (ImageConversion.LoadImage(val, array, false))
			{
				image = val;
				return true;
			}
			throw new FileLoadException("Can't load " + name);
		}
	}
	public class SpriteLoaderFromFile : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <LoadSpriteFromFile>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SpriteLoaderFromFile <>4__this;

			private UnityWebRequest <uwr>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<uwr>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Invalid comparison between Unknown and I4
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					int num = <>1__state;
					SpriteLoaderFromFile spriteLoaderFromFile = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<uwr>5__2 = UnityWebRequestTexture.GetTexture("file://" + spriteLoaderFromFile.filePath);
						<>1__state = -3;
						<>2__current = <uwr>5__2.SendWebRequest();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -3;
						if ((int)<uwr>5__2.result != 1)
						{
							Debug.LogError((object)("Error loading sprite: " + <uwr>5__2.error));
						}
						else
						{
							Texture2D content = DownloadHandlerTexture.GetContent(<uwr>5__2);
							Sprite sprite = Sprite.Create(content, new Rect(0f, 0f, (float)((Texture)content).width, (float)((Texture)content).height), new Vector2(0.5f, 0.5f));
							((Component)spriteLoaderFromFile).GetComponent<SpriteRenderer>().sprite = sprite;
						}
						<>m__Finally1();
						<uwr>5__2 = null;
						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;
				if (<uwr>5__2 != null)
				{
					((IDisposable)<uwr>5__2).Dispose();
				}
			}

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

		public string filePath;

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(LoadSpriteFromFile());
		}

		[IteratorStateMachine(typeof(<LoadSpriteFromFile>d__2))]
		private IEnumerator LoadSpriteFromFile()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadSpriteFromFile>d__2(0)
			{
				<>4__this = this
			};
		}
	}
	internal class InputCycler
	{
		private static InputCycler _instance;

		private bool useMouseWheel;

		private DelegatedConfigEntry<KeyboardShortcut> keyAdvance;

		private DelegatedConfigEntry<KeyboardShortcut> keyReferse;

		public static InputCycler Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new InputCycler();
				}
				return _instance;
			}
		}

		private InputCycler()
		{
		}

		public void Init(bool useMouseWheel, DelegatedConfigEntry<KeyboardShortcut> keyAdvance, DelegatedConfigEntry<KeyboardShortcut> keyReverse = null)
		{
			this.useMouseWheel = useMouseWheel;
			this.keyAdvance = keyAdvance;
			keyReferse = keyReverse;
		}
	}
	public class IterativeStopwatch : Stopwatch
	{
		private double startMillis;

		private Logging Log = Logging.GetLogger();

		public long Iterations { get; private set; }

		public double IterationMicroseconds { get; private set; }

		public double TotalElapsedMicroseconds { get; private set; }

		public double IterationMilliseconds { get; private set; }

		public double TotalElapsedMilliseconds { get; private set; }

		public double AverageMicroseconds { get; private set; }

		public double AverageMilliseconds { get; private set; }

		public IterativeStopwatch()
		{
			Iterations = 0L;
		}

		public new void Start()
		{
			startMillis = base.Elapsed.TotalMilliseconds;
			base.Start();
		}

		public new void Stop()
		{
			if (base.IsRunning)
			{
				base.Stop();
				Iterations++;
				IterationMilliseconds = base.Elapsed.TotalMilliseconds - startMillis;
				IterationMicroseconds = IterationMilliseconds * 1000.0;
				TotalElapsedMilliseconds = base.Elapsed.TotalMilliseconds;
				TotalElapsedMicroseconds = base.Elapsed.TotalMilliseconds * 1000.0;
				AverageMilliseconds = TotalElapsedMilliseconds / (double)Iterations;
				AverageMicroseconds = TotalElapsedMicroseconds / (double)Iterations;
			}
		}

		public new void Reset()
		{
			startMillis = 0.0;
			Iterations = 0L;
			base.Reset();
		}

		public new void Restart()
		{
			startMillis = 0.0;
			Iterations = 0L;
			base.Restart();
		}
	}
	public static class JsonHelper
	{
		[Serializable]
		private class JsonWrapper<T>
		{
			public T[] Items;
		}

		public static T[] FromJson<T>(string json)
		{
			return JsonUtility.FromJson<JsonWrapper<T>>(json).Items;
		}

		public static string ToJson<T>(T[] array)
		{
			return JsonUtility.ToJson((object)new JsonWrapper<T>
			{
				Items = array
			});
		}

		public static string ToJson<T>(T[] array, bool prettyPrint)
		{
			return JsonUtility.ToJson((object)new JsonWrapper<T>
			{
				Items = array
			}, prettyPrint);
		}
	}
	public class Logging
	{
		public enum LogLevels
		{
			Critical,
			Error,
			Warning,
			Info,
			Debug,
			Trace
		}

		private static Logging _logger;

		public LogLevels LogLevel { get; set; }

		public string ModName { get; set; }

		private Logging(LogLevels level, string name)
		{
			LogLevel = level;
			ModName = name;
		}

		public static Logging GetLogger(LogLevels level, string name)
		{
			if (_logger == null)
			{
				_logger = new Logging(level, name);
			}
			return _logger;
		}

		public static Logging GetLogger()
		{
			if (_logger == null)
			{
				throw new NullReferenceException("Logger not initialized");
			}
			return _logger;
		}

		public void Trace(string msg)
		{
			if (LogLevel >= LogLevels.Trace)
			{
				Debug.Log((object)Message(msg));
			}
		}

		public void Debug(string msg)
		{
			if (LogLevel >= LogLevels.Debug)
			{
				Debug.Log((object)Message(msg));
			}
		}

		public void Info(string msg)
		{
			if (LogLevel >= LogLevels.Info)
			{
				Debug.Log((object)Message(msg));
			}
		}

		public void Warning(string msg)
		{
			if (LogLevel >= LogLevels.Warning)
			{
				Debug.LogWarning((object)Message(msg));
			}
		}

		public void Error(string msg)
		{
			if (LogLevel >= LogLevels.Error)
			{
				Debug.LogWarning((object)Message(msg));
			}
		}

		public void Error(Exception e)
		{
			Error(e, stackTrace: false);
		}

		public void Error(Exception e, bool stackTrace)
		{
			if (LogLevel >= LogLevels.Error)
			{
				Warning(Message(e.Message));
				if (stackTrace)
				{
					Warning(e.StackTrace);
				}
			}
		}

		public void Critical(Exception e)
		{
			if (LogLevel >= LogLevels.Critical)
			{
				Debug(Message(e.Message));
				Error(e.StackTrace);
			}
		}

		private string Message(string msg)
		{
			return ModName + ": " + msg;
		}
	}
	public class ServerConfiguration
	{
		[HarmonyPatch(typeof(ZNet), "StopAll")]
		private static class ZNet_Shutdown_Patch
		{
			[HarmonyPrefix]
			private static void ZNet_StopAll_Prefix(ZNet __instance)
			{
				if (_instance != null)
				{
					Log.Debug("ZNet_StopAll_Patch_Prefix");
					_instance.ReceivedServerValues = false;
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class ZNet_OnNewConnection_Patch
		{
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				Log.Debug("ZNet OnNewConnection postfix");
				if (!__instance.IsServer())
				{
					try
					{
						peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)Instance.RPC_ClientConfigReceiver);
						Log.Debug("Player registered RPC_ClientConfigReceiver");
						return;
					}
					catch (Exception)
					{
						Log.Warning("Failed to register RPC");
						return;
					}
				}
				try
				{
					Instance.SendConfigToClient(peer);
				}
				catch (Exception)
				{
					Log.Warning("Error sending server configuration to client");
				}
			}
		}

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

			private object <>2__current;

			public ZPackage zpkg;

			private List<ZNetPeer>.Enumerator <>7__wrap1;

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

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

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

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

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						Log.Debug("Co_BroadcastConfig");
						List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers();
						<>7__wrap1 = connectedPeers.GetEnumerator();
						<>1__state = -3;
						break;
					}
					case 1:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap1.MoveNext())
					{
						ZNetPeer current = <>7__wrap1.Current;
						if (current != ZNet.instance.GetServerPeer())
						{
							current.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg });
							Log.Trace("Invoked ClientConfigReceiver on peer");
						}
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap1 = default(List<ZNetPeer>.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();
			}
		}

		public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>();

		private static ConfigFile LocalConfig;

		private static BaseUnityPlugin Mod;

		private static string ConfigFileName;

		private static ServerConfiguration _instance;

		private static Logging Log;

		public bool IsSetup;

		public bool ReceivedServerValues;

		public FileSystemWatcher ConfigWatcher;

		private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first.";

		public static ServerConfiguration Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new ServerConfiguration();
				}
				return _instance;
			}
		}

		private ServerConfiguration()
		{
		}

		public void Setup(ConfigFile config, BaseUnityPlugin modInstance)
		{
			LocalConfig = config;
			Log = Logging.GetLogger();
			Log.Trace("ServerConfiguration Setup");
			Mod = modInstance;
			ConfigFileName = Path.GetFileName(LocalConfig.ConfigFilePath);
			IsSetup = true;
		}

		public void CreateConfigWatcher()
		{
			ConfigWatcher = Utils.CreateFileWatcher(LocalConfig.ConfigFilePath, LoadConfig);
		}

		private void LoadConfig(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(LocalConfig.ConfigFilePath))
			{
				return;
			}
			try
			{
				Log.Debug($"Loading configuration {e.ChangeType}");
				LocalConfig.Reload();
			}
			catch
			{
				Log.Error("Error loading configuration file " + ConfigFileName);
			}
		}

		public static string GetPluginGuid()
		{
			return Mod.Info.Metadata.GUID;
		}

		public void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package)
		{
			if (!Instance.IsSetup)
			{
				Log.Error("ServerConfiguration not initialized. Setup first.");
				return;
			}
			Log.Debug("ClientConfigReceiver");
			string section;
			string name;
			while (package.GetPos() < package.Size())
			{
				section = package.ReadString();
				name = package.ReadString();
				string text = package.ReadString();
				Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage");
				DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section);
				if (delegatedConfigEntryBase != null)
				{
					Log.Trace("Found DCEB on client and setting to server value " + text);
					delegatedConfigEntryBase.ServerValue = text;
				}
				ConfigEntryBase val = LocalConfig[section, name];
				if (val != null)
				{
					Log.Trace("Found local CEB and setting underlying config value " + text);
					val.SetSerializedValue(text);
				}
			}
			ReceivedServerValues = true;
		}

		internal void WriteConfigEntries(ZPackage zpkg)
		{
			foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries)
			{
				Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage");
				zpkg.Write(serverDelegatedEntry.Section);
				zpkg.Write(serverDelegatedEntry.Name);
				zpkg.Write(serverDelegatedEntry.ServerValue);
			}
		}

		internal void SendConfigToClient(ZNetPeer peer)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if (!Instance.IsSetup)
			{
				Log.Error("ServerConfiguration not initialized. Setup first.");
				return;
			}
			Log.Debug("SendConfigToClient");
			ZPackage val = new ZPackage();
			WriteConfigEntries(val);
			peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val });
			Log.Trace("Invoked ClientConfigReceiver on peer");
		}

		public void SendConfigToAllClients(object o, SettingChangedEventArgs e)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if (!IsSetup)
			{
				Log.Error("ServerConfiguration not initialized. Setup first.");
			}
			else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0)
			{
				Log.Debug("SendConfigToAllClients");
				ZPackage zpkg = new ZPackage();
				WriteConfigEntries(zpkg);
				((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg));
			}
		}

		[IteratorStateMachine(typeof(<Co_BroadcastConfig>d__21))]
		private IEnumerator Co_BroadcastConfig(ZPackage zpkg)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Co_BroadcastConfig>d__21(0)
			{
				zpkg = zpkg
			};
		}
	}
	public class Utils
	{
		public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct
		{
			if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result))
			{
				return result;
			}
			return enumDefault;
		}

		public static int Guardrails(int value, int lbound, int ubound)
		{
			if (value < lbound)
			{
				return lbound;
			}
			if (value > ubound)
			{
				return ubound;
			}
			return value;
		}

		public static string Truncate(string value, int maxChars)
		{
			if (value == null)
			{
				return null;
			}
			if (value.Length <= maxChars)
			{
				return value;
			}
			return value.Substring(0, maxChars);
		}

		public static void GetCharactersInRangeXZ(Vector3 point, float radius, List<Character> characters)
		{
			//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)
			float num = radius * radius;
			foreach (Character s_character in Character.s_characters)
			{
				if (DistanceSqrXZ(((Component)s_character).transform.position, point) < num)
				{
					characters.Add(s_character);
				}
			}
		}

		public static float DistanceSqr(Vector3 v0, Vector3 v1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			float num = v1.x - v0.x;
			float num2 = v1.y - v0.y;
			float num3 = v1.z - v0.z;
			return num * num + num2 * num2 + num3 * num3;
		}

		public static float DistanceSqrXZ(Vector3 v0, Vector3 v1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			float num = v1.x - v0.x;
			float num2 = v1.z - v0.z;
			return num * num + num2 * num2;
		}

		public static float DistanceXZ(Vector3 v0, Vector3 v1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			float num = v1.x - v0.x;
			float num2 = v1.z - v0.z;
			return Mathf.Sqrt(num * num + num2 * num2);
		}

		public static float Guardrails(float value, float lbound, float ubound)
		{
			if (value < lbound)
			{
				return lbound;
			}
			if (value > ubound)
			{
				return ubound;
			}
			return value;
		}

		public static string UnClonifiedName(string name)
		{
			if (name == null)
			{
				return null;
			}
			int num = name.IndexOf("(Clone)");
			if (num < 1)
			{
				return name;
			}
			return name.Substring(0, num);
		}

		public static void SetTranslator(int id, string idText)
		{
			typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2]
			{
				"skill_" + id,
				idText
			});
		}

		public static string GetTranslated(int id)
		{
			Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id)));
			return Localization.instance.Localize("$skill_" + id);
		}

		public static string GetAssemblyPathedFile(string fileName)
		{
			return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName.Replace('\\', '/') + "/" + fileName;
		}

		public static Sprite GetPrefabIcon(string prefabName)
		{
			Sprite result = null;
			GameObject prefab = GetPrefab(prefabName);
			ItemDrop val = default(ItemDrop);
			if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val))
			{
				result = val.m_itemData.GetIcon();
			}
			return result;
		}

		public static Player GetPlayerByZDOID(ZDOID zid)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				ZDOID zDOID = ((Character)allPlayer).GetZDOID();
				if (((ZDOID)(ref zDOID)).Equals(zid))
				{
					return allPlayer;
				}
			}
			return null;
		}

		public static Character GetCharacterByZDOID(string cid)
		{
			//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)
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				ZDOID zDOID = allCharacter.GetZDOID();
				if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid))
				{
					return allCharacter;
				}
			}
			return null;
		}

		public static Character GetCharacterByZDOID(ZDOID cid)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				ZDOID zDOID = allCharacter.GetZDOID();
				if (((ZDOID)(ref zDOID)).Equals(cid))
				{
					return allCharacter;
				}
			}
			return null;
		}

		public static ZNetPeer GetPeerByRPC(ZRpc rpc)
		{
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer.m_rpc == rpc)
				{
					return peer;
				}
			}
			return null;
		}

		public static List<GameObject> GetGameObjectsOfType(Type t)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			List<GameObject> list = new List<GameObject>();
			Object[] array = Object.FindObjectsByType(t, (FindObjectsSortMode)0);
			foreach (Object val in array)
			{
				list.Add(((Component)val).gameObject);
			}
			return list;
		}

		public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0];
		}

		public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>();
			List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius);
			if (gameObjectsOfTypeInRange.Count > 0)
			{
				foreach (GameObject item in gameObjectsOfTypeInRange)
				{
					list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point)));
				}
				list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value));
				return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key);
			}
			return null;
		}

		public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return (from x in GetGameObjectsOfType(t)
				where Vector3.Distance(x.transform.position, point) < radius
				select x).ToList();
		}

		public static float GetPointDepth(Vector3 p)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p);
		}

		public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter)
		{
			List<string> list = new List<string>();
			string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				list.Add(text.Trim());
			}
			return list;
		}

		public static float GetSolidHeight(Vector3 p)
		{
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			int solidRayMask = ZoneSystem.instance.m_solidRayMask;
			float result = 0f;
			p.y += 1000f;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody))
			{
				result = ((RaycastHit)(ref val)).point.y;
			}
			return result;
		}

		public static Transform FindChild(Transform aParent, string aName)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in aParent)
			{
				Transform val = item;
				if (((Object)val).name == aName)
				{
					return val;
				}
				Transform val2 = FindChild(val, aName);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		public static Transform FindParent(Transform go)
		{
			while ((Object)(object)go.parent != (Object)null)
			{
				go = go.parent;
			}
			return go;
		}

		public static GameObject GetPrefab(int prefabHash)
		{
			return GetPrefabByHash(prefabHash);
		}

		public static GameObject GetPrefabByHash(int prefabHash)
		{
			GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash);
			Logging logger = Logging.GetLogger();
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found prefab in ObjectDB");
			}
			else
			{
				ZNetScene instance = ZNetScene.instance;
				val = ((instance != null) ? instance.GetPrefab(prefabHash) : null);
				if ((Object)(object)val != (Object)null)
				{
					logger.Debug("Found prefab in Scene");
				}
			}
			return val;
		}

		public static GameObject GetPrefab(string prefabName)
		{
			GameObject val = ObjectDB.instance.GetItemPrefab(prefabName);
			Logging logger = Logging.GetLogger();
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found " + prefabName + " in ObjectDB");
			}
			else
			{
				ZNetScene instance = ZNetScene.instance;
				val = ((instance != null) ? instance.GetPrefab(prefabName) : null);
				if ((Object)(object)val != (Object)null)
				{
					logger.Debug("Found " + prefabName + " in Scene");
				}
			}
			return val;
		}

		public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict)
		{
			if (dict == null)
			{
				return null;
			}
			IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp)
			{
				KeyValuePair<K, V> keyValuePair = kvp;
				string? obj = keyValuePair.Key?.ToString();
				string text = delimc;
				keyValuePair = kvp;
				return obj + text + keyValuePair.Value;
			});
			return string.Join(delimp, values);
		}

		public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict)
		{
			if (dict == null)
			{
				return;
			}
			dict.Clear();
			string[] separator = new string[1] { delimp };
			string[] separator2 = new string[1] { delimc };
			string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length == 2)
				{
					dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1]));
				}
			}
		}

		public static FileSystemWatcher CreateFileWatcher(string fullPath, FileSystemEventHandler handler)
		{
			string fileName = Path.GetFileName(fullPath);
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(fullPath.Substring(0, fullPath.Length - fileName.Length), fileName);
			fileSystemWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
			fileSystemWatcher.Changed += handler;
			fileSystemWatcher.Created += handler;
			fileSystemWatcher.IncludeSubdirectories = false;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			return fileSystemWatcher;
		}

		public static T TypedValue<T>(object a)
		{
			return (T)Convert.ChangeType(a, typeof(T));
		}

		public static float TimeAdjustedRamp(float maxValue, float duration, float elapsedTime, float pctFromStartRise, float pctFromEndFall)
		{
			float num = elapsedTime / duration;
			if (num <= pctFromStartRise)
			{
				return maxValue * (num / pctFromStartRise);
			}
			if (num >= 1f - pctFromEndFall)
			{
				return maxValue * ((1f - num) / pctFromEndFall);
			}
			return maxValue;
		}

		public static bool CopyComponentToGameObject(Component original, ref GameObject destination)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			Logging logger = Logging.GetLogger();
			Type type = ((object)original).GetType();
			logger.Debug($"Original Type is {type}");
			GameObject obj = destination;
			logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null));
			Component val = destination.GetComponent(type);
			if ((Object)(object)val == (Object)null)
			{
				val = destination.AddComponent(type);
			}
			if ((Object)(object)val == (Object)null)
			{
				logger.Debug("Destination component is null");
				return false;
			}
			Component val2 = (Component)Activator.CreateInstance(type);
			if ((Object)(object)val2 == (Object)null)
			{
				logger.Debug("Destination component is null");
				return false;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				logger.Debug("Boxed component is null");
				return false;
			}
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				fieldInfo.SetValue(val2, fieldInfo.GetValue(original));
			}
			val = val2;
			return true;
		}

		public static bool CopyObject(object original, object target)
		{
			Logging logger = Logging.GetLogger();
			Type type = original.GetType();
			Type type2 = target.GetType();
			if (type == null)
			{
				logger.Warning("Copy Object: Source object is null");
				Activator.CreateInstance(type);
				return false;
			}
			if (type2 == null)
			{
				logger.Warning("Copy Object: Destination object is null");
				return false;
			}
			if (type2 != type)
			{
				logger.Warning("Copy Object: Source and destination components are different types");
				return false;
			}
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				fieldInfo.SetValue(target, fieldInfo.GetValue(original));
			}
			return true;
		}
	}
}
namespace neobotics.ValheimMods
{
	internal class Cfg
	{
		public static KeyCode[] keyModifiers = (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 };

		public static KeyboardShortcut chestBindKeyDefault = new KeyboardShortcut((KeyCode)106, keyModifiers);

		public static DelegatedConfigEntry<Logging.LogLevels> debugLevel = null;

		public static DelegatedConfigEntry<KeyboardShortcut> chestBindKey = null;

		public static KeyboardShortcut chestOpenKeyDefault = new KeyboardShortcut((KeyCode)104, Array.Empty<KeyCode>());

		public static DelegatedConfigEntry<KeyboardShortcut> chestOpenKey = null;

		public static DelegatedConfigEntry<bool> useStrictCost = null;

		public static DelegatedConfigEntry<bool> teleportRestriction = null;

		public static DelegatedConfigEntry<int> bindCost = null;

		public static DelegatedConfigEntry<int> openCost = null;

		public static DelegatedConfigEntry<SeidrChest.ChestModes> chestMode = null;

		public static DelegatedConfigEntry<SeidrChest.CostModes> costMode = null;

		public static DelegatedConfigEntry<bool> invertEnderKey = null;

		public static void BepInExConfig(BaseUnityPlugin _instance)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(ChangeLogging);
			debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log. Default is 'Info'");
			SeidrChest.Log.LogLevel = debugLevel.Value;
			chestMode = new DelegatedConfigEntry<SeidrChest.ChestModes>(useServerDelegate: true);
			chestMode.ConfigEntry = _instance.Config.Bind<SeidrChest.ChestModes>("General", "ChestMode", SeidrChest.ChestModes.SeidrChest, "Seidr mode allows accessing the Seidr chest anyhwere. Ender mode links all personal chests to the same Seidr chest; you must open them to access the common toInventory.");
			costMode = new DelegatedConfigEntry<SeidrChest.CostModes>(useServerDelegate: true);
			costMode.ConfigEntry = _instance.Config.Bind<SeidrChest.CostModes>("Cost", "CostType", SeidrChest.CostModes.EitrThenStamina, "Set the type of energy used to bind and open Seidr chests. Can be exclusivley Eitr or Stamina, or Eitr first, followed by Stamina.");
			chestBindKey = new DelegatedConfigEntry<KeyboardShortcut>();
			chestBindKey.ConfigEntry = _instance.Config.Bind<KeyboardShortcut>("General", "BindSeidrChest", chestBindKeyDefault, "Press this key to seidr bind a Personal Chest to a Seidr Chest.");
			chestOpenKey = new DelegatedConfigEntry<KeyboardShortcut>();
			chestOpenKey.ConfigEntry = _instance.Config.Bind<KeyboardShortcut>("General", "OpenSeidrChest", chestOpenKeyDefault, "Press this key to open your Seidr Chest. In EnderChest mode, hold this key down when opening a Personal chest to access the actual chest contents.");
			useStrictCost = new DelegatedConfigEntry<bool>(useServerDelegate: true);
			useStrictCost.ConfigEntry = _instance.Config.Bind<bool>("Cost", "StrictCost", false, "Require cost to be met before binding or opening. If Eitr and/or Stamina is less than this cost (depending on CostType setting), chest cannot be bound or open.");
			invertEnderKey = new DelegatedConfigEntry<bool>();
			invertEnderKey.ConfigEntry = _instance.Config.Bind<bool>("General", "InvertEnderOpenKey", false, "Set True to invert Ender mode open action, i.e., open Personal Chest as default, open SeidrChest while holding the OpenSeidrChest key.");
			teleportRestriction = new DelegatedConfigEntry<bool>(useServerDelegate: true);
			teleportRestriction.ConfigEntry = _instance.Config.Bind<bool>("General", "RestrictNonTeleportable", false, "Set to true to prevent non-teleportable items in the Seidr chest.");
			bindCost = new DelegatedConfigEntry<int>(useServerDelegate: true);
			bindCost.ConfigEntry = _instance.Config.Bind<int>("Cost", "CostToBind", 50, new ConfigDescription("Sets the amount of eitr and/or stamina consumed to bind a Seidr chest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			openCost = new DelegatedConfigEntry<int>(useServerDelegate: true);
			openCost.ConfigEntry = _instance.Config.Bind<int>("Cost", "CostToOpen", 10, new ConfigDescription("Sets the amount of eitr and/or stamina consumed to use a Seidr chest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
		}

		public static void ChangeLogging(object s, EventArgs e)
		{
			SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			SeidrChest.Log.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
			SeidrChest.Log.LogLevel = debugLevel.Value;
		}
	}
	[BepInPlugin("neobotics.valheim_mod.seidrchest", "SeidrChest", "0.1.18")]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	public class SeidrChest : BaseUnityPlugin
	{
		public enum ChestModes
		{
			SeidrChest,
			EnderChest
		}

		public enum CostModes
		{
			EitrThenStamina,
			EitrOnly,
			StaminaOnly
		}

		[HarmonyPatch(typeof(Game), "Start")]
		private static class Game_Start_Patch
		{
			[HarmonyPostfix]
			private static void Game_Start_Patch_Postfix(Game __instance)
			{
				Log.Debug(" Game_Start_Patch_Postfix");
				ZRoutedRpc.instance.Register<string>("RequestSeidrZDO", (Action<long, string>)RPC_RequestSeidrZDO);
				ZRoutedRpc.instance.Register("CancelRequestZDO", (Action<long>)RPC_CancelRequestZDO);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		private static class InventoryGui_Hide_Patch
		{
			[HarmonyPostfix]
			private static void InventoryGui_Hide_Postfix(InventoryGui __instance)
			{
				if (originalAutocloseDistance >= 0f)
				{
					__instance.m_autoCloseDistance = originalAutocloseDistance;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "CloseContainer")]
		private static class InventoryGui_CloseContainer_Patch
		{
			[HarmonyPostfix]
			private static void InventoryGui_CloseContainer_Postfix(InventoryGui __instance)
			{
				Log.Debug("InventoryGui_CloseContainer_Patch_Postfix");
				if (originalAutocloseDistance >= 0f)
				{
					__instance.m_autoCloseDistance = originalAutocloseDistance;
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "FindSectorObjects")]
		public static class ZDOMan_FindSectorObjects1_Patch
		{
			private static void Prefix(ZDOMan __instance, Vector2i sector, int area, List<ZDO> sectorObjects)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				AddSectorObject(__instance, sector, area, sectorObjects);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class InventoryGui_Show_Patch
		{
			private static bool Prefix(InventoryGui __instance, ref Container container, out Container __state)
			{
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				__state = null;
				if (originalAutocloseDistance == -1f)
				{
					originalAutocloseDistance = __instance.m_autoCloseDistance;
				}
				if ((Object)(object)container != (Object)null)
				{
					if (Log.LogLevel >= Logging.LogLevels.Trace)
					{
						Log.Trace("Showing container name " + container.m_name);
					}
					if (container.m_name == "$piece_chestprivate" && Cfg.chestMode.Value == ChestModes.EnderChest && ((!Cfg.chestOpenKey.IsKeyDown() && !Cfg.invertEnderKey.Value) || (Cfg.chestOpenKey.IsKeyDown() && Cfg.invertEnderKey.Value)))
					{
						if (!SetupSeidrChest())
						{
							Log.Info("No Seidr chest is bound");
							return true;
						}
						Container val = default(Container);
						if ((Object)(object)voidChest != (Object)null && voidChest.TryGetComponent<Container>(ref val))
						{
							Log.Debug("Switching to Sedir chest");
							container = val;
						}
					}
					if ((Object)(object)voidChest != (Object)null && (Object)(object)voidChest.GetComponent<Container>() == (Object)(object)container)
					{
						Log.Debug("Showing Seidr chest");
						if (!HasSeidrCost(Player.m_localPlayer, Cfg.openCost.Value, binding: false))
						{
							return false;
						}
						ApplySeidrCost(Player.m_localPlayer, Cfg.openCost.Value);
						container.GetInventory().m_name = "Seiðr chest";
						if (Vector3.Distance(((Component)Player.m_localPlayer).transform.position, voidChest.transform.position) > 5f)
						{
							__instance.m_autoCloseDistance = float.MaxValue;
							Log.Debug("Reset autoclose distance");
						}
						else
						{
							__instance.m_autoCloseDistance = originalAutocloseDistance;
						}
					}
				}
				else
				{
					Log.Debug("Not a Container");
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		public static class Player_OnSpawned_Patch
		{
			public static void Postfix(Player __instance)
			{
				Log.Debug("Player OnSpawned");
				voidChest = null;
				voidZdo = null;
				if (!SetupSeidrChest() && !ZNet.instance.IsServer())
				{
					Log.Debug("No local ZDO. Requesting from server");
					RequestSeidrZDOFromServer(Player.m_localPlayer.GetPlayerName());
					((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_WaitForZDO());
				}
			}
		}

		[HarmonyPatch(typeof(Container), "CanBeRemoved")]
		public static class Container_CanBeRemoved_Patch
		{
			private static void Postfix(Container __instance, ref bool __result)
			{
				if (__result && (Object)(object)voidChest != (Object)null && (Object)(object)voidChest == (Object)(object)((Component)__instance).gameObject)
				{
					Log.Trace("Setting Seidr chest removal false");
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		public static class Container_GetHoverText_Patch
		{
			private static void Postfix(Container __instance, ref string __result)
			{
				if ((Object)(object)voidChest != (Object)null && Cfg.chestMode.Value == ChestModes.EnderChest && __instance.m_name == "$piece_chestprivate" && ((!Cfg.chestOpenKey.IsKeyDown() && !Cfg.invertEnderKey.Value) || (Cfg.chestOpenKey.IsKeyDown() && Cfg.invertEnderKey.Value)))
				{
					__result += " (Seiðr chest)";
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Update")]
		public static class Player_Update_Patch
		{
			private static void Prefix(Player __instance)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && OkToKey(__instance))
				{
					if (Cfg.chestBindKey.IsKeyPressed())
					{
						BindChest();
					}
					else if (Cfg.chestMode.Value == ChestModes.SeidrChest && Cfg.chestOpenKey.IsKeyPressed())
					{
						HandleChest();
					}
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		private static class Inventory_AddItem_ToSlot_Patch
		{
			private static bool Prefix(Inventory __instance, ItemData item, int amount, int x, int y, string ___m_name, out bool __result)
			{
				__result = true;
				if (Log.LogLevel >= Logging.LogLevels.Trace)
				{
					Log.Trace("AddItem_ToSlot " + item.m_shared.m_name + " to " + ___m_name);
				}
				if (!IsOkToMove(item, ___m_name))
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		private static class Inventory_AddItem_Patch
		{
			private static bool Prefix(Inventory __instance, ItemData item, string ___m_name, out bool __result)
			{
				__result = true;
				if (Log.LogLevel >= Logging.LogLevels.Trace)
				{
					Log.Trace("AddItem " + item.m_shared.m_name + " to " + ___m_name);
				}
				if (!IsOkToMove(item, ___m_name))
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		private static class Inventory_MoveItemToThis_Slot_Patch
		{
			private static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item, int amount, int x, int y, string ___m_name)
			{
				if (Log.LogLevel >= Logging.LogLevels.Trace)
				{
					Log.Trace("MoveItemToThis_Slot " + item.m_shared.m_name + " to " + ___m_name);
				}
				ItemData itemAt = __instance.GetItemAt(x, y);
				if (itemAt != null && !IsOkToMove(itemAt, fromInventory.GetName()))
				{
					return false;
				}
				if (!IsOkToMove(item, ___m_name))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData)
		})]
		private static class Inventory_MoveItemToThis_Patch
		{
			private static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item, string ___m_name)
			{
				if (Log.LogLevel >= Logging.LogLevels.Trace)
				{
					Log.Trace("MoveItemToThis " + item.m_shared.m_name + " to " + ___m_name);
				}
				if (!IsOkToMove(item, ___m_name))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
		private static class InventoryGrid_DropItem_Patch
		{
			private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, Inventory ___m_inventory, out bool __result)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				__result = true;
				string name = ___m_inventory.GetName();
				if (Log.LogLevel >= Logging.LogLevels.Trace)
				{
					Log.Trace("InventoryGrid_DropItem " + item.m_shared.m_name + " to " + name);
				}
				ItemData itemAt = ___m_inventory.GetItemAt(pos.x, pos.y);
				if (itemAt != null && !IsOkToMove(itemAt, fromInventory.GetName()))
				{
					return false;
				}
				if (!IsOkToMove(item, name))
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		private static class InventoryGui_UpdateContainer_Patch
		{
			private static void Prefix(InventoryGui __instance, Container ___m_currentContainer)
			{
				ZNetView val = default(ZNetView);
				if ((Object)(object)___m_currentContainer != (Object)null && !___m_currentContainer.IsOwner() && (Object)(object)voidChest != (Object)null && (Object)(object)((Component)___m_currentContainer).gameObject == (Object)(object)voidChest && ((Component)___m_currentContainer).gameObject.TryGetComponent<ZNetView>(ref val))
				{
					ZDO zDO = val.GetZDO();
					if (zDO != null)
					{
						zDO.SetOwner(((Character)Player.m_localPlayer).GetOwner());
					}
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "Awake")]
		private static class FejidStartup_Awake_Patch
		{
			private static void Postfix(FejdStartup __instance)
			{
				GetDetectionSet(new Dictionary<string, string> { { "yay.spikehimself.xstorage.harmony", "XStorage" } });
			}
		}

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

			private object <>2__current;

			private float <abortTime>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Log.Debug("Co_WaitForZDO");
					<abortTime>5__2 = Time.time + 20f;
					cancelRequest = false;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!SetupSeidrChest() && !cancelRequest && Time.time < <abortTime>5__2)
				{
					Log.Debug("Waiting for SeidrChest ZDO from server");
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				if (Time.time >= <abortTime>5__2)
				{
					Log.Warning("Didn't receive SeidrChest ZDO from server.");
				}
				if (cancelRequest)
				{
					cancelRequest = false;
					Log.Warning("Server didn't find SeidrChest.");
				}
				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();
			}
		}

		private static SeidrChest _modInstance;

		private static string Mod = "SeidrChest";

		private static string LcMod = Mod.ToLower();

		public static Logging Log;

		private const string convertedName = "Seiðr chest";

		private const string personalChestTag = "$piece_chestprivate";

		private Harmony harmony;

		private static float originalAutocloseDistance = -1f;

		private static GameObject voidChest = null;

		private static ZDO voidZdo = null;

		private static GameObject bindPrefab = null;

		private static bool cancelRequest = false;

		private const string CANTBIND = "You can't bind it";

		public const string SEIDRPREFIX = "SeidrChest_1847_";

		private const string XSTORAGESKIP = "XStorage_SkipMark";

		private const string SEIDERCHEST_TEMP = "SeidrChest_Temp";

		private static Dictionary<string, string> detectionSet = new Dictionary<string, string>();

		private static Dictionary<string, string> unpatchMods = new Dictionary<string, string>();

		public static SeidrChest GetInstance()
		{
			return _modInstance;
		}

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			_modInstance = this;
			Log = Logging.GetLogger(Logging.LogLevels.Info, Mod);
			harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			harmony.PatchAll(Assembly.GetExecutingAssembly());
			ConfigureMod();
			Log.Info("Awake");
		}

		private void ConfigureMod()
		{
			Log = Logging.GetLogger(Logging.LogLevels.Info, Mod);
			ServerConfiguration.Instance.Setup(((BaseUnityPlugin)this).Config, (BaseUnityPlugin)(object)this);
			Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance);
			ServerConfiguration.Instance.CreateConfigWatcher();
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}

		private static bool HasSeidrCost(Player aPlayer, float amount, bool binding = true)
		{
			bool flag = true;
			if (Cfg.useStrictCost.Value)
			{
				float eitr = aPlayer.GetEitr();
				float stamina = aPlayer.GetStamina();
				switch (Cfg.costMode.Value)
				{
				case CostModes.EitrOnly:
					if (eitr < amount)
					{
						flag = false;
					}
					break;
				case CostModes.StaminaOnly:
					if (stamina < amount)
					{
						flag = false;
					}
					break;
				default:
					if (eitr + stamina < amount)
					{
						flag = false;
					}
					break;
				}
				if (!flag)
				{
					Log.Info("Not enough energy to " + (binding ? "bind" : "use") + " the Seidr chest");
					((Character)Player.m_localPlayer).Message((MessageType)2, "Not enough energy", 0, (Sprite)null);
				}
			}
			return flag;
		}

		private static void ApplySeidrCost(Player aPlayer, float amount)
		{
			float eitr = aPlayer.GetEitr();
			aPlayer.GetStamina();
			if ((Cfg.costMode.Value == CostModes.EitrOnly || Cfg.costMode.Value == CostModes.EitrThenStamina) && eitr > 0f)
			{
				((Character)aPlayer).UseEitr(amount);
				amount -= eitr;
			}
			if ((Cfg.costMode.Value == CostModes.StaminaOnly || Cfg.costMode.Value == CostModes.EitrThenStamina) && amount > 0f)
			{
				((Character)aPlayer).UseStamina(amount);
			}
		}

		private static void RestoreToPersonalChest()
		{
			Log.Debug("RestoreToPersonalChest");
			Container val = default(Container);
			if ((Object)(object)voidChest != (Object)null && voidChest.TryGetComponent<Container>(ref val))
			{
				val.GetInventory().m_name = "$piece_chestprivate";
				val.m_name = "$piece_chestprivate";
			}
		}

		private static bool IsOkToMove(ItemData item, string name)
		{
			if (name == "Seiðr chest" && item?.m_shared != null && Cfg.teleportRestriction.Value && !item.m_shared.m_teleportable)
			{
				Log.Info("Can't store non-teleportable items in the Seidr chest");
				((Character)Player.m_localPlayer).Message((MessageType)1, "Can't store that in the chest", 0, (Sprite)null);
				return false;
			}
			return true;
		}

		private static void UnbindChest(bool message = true)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("UnbindChest");
			Container val = default(Container);
			if (!((Object)(object)voidChest != (Object)null) || !voidChest.TryGetComponent<Container>(ref val))
			{
				return;
			}
			if (message)
			{
				CreateAura(voidChest);
			}
			RestoreToPersonalChest();
			ZDO zDO = val.m_nview.GetZDO();
			if (zDO.IsValid())
			{
				zDO.Set(StringExtensionMethods.GetStableHashCode("XStorage_SkipMark"), false);
				if (ZDOHelper.Remove<string>(ZDOExtraData.s_strings, zDO.m_uid, StringExtensionMethods.GetStableHashCode("SeidrChest_1847_")))
				{
					Log.Debug($"Removed player reference from chest ZDO {zDO.m_uid}");
				}
			}
			voidChest = null;
			voidZdo = null;
			Log.Info("Seidr Chest is unbound");
			if (message)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "Seiðr chest is unbound", 0, (Sprite)null);
			}
		}

		private static bool HasNonTeleportableItems(Container container)
		{
			if (((container != null) ? container.GetInventory() : null) != null)
			{
				return container.GetInventory().GetAllItems().Find((ItemData x) => !x.m_shared.m_teleportable) != null;
			}
			return false;
		}

		private static void BindChest()
		{
			Player localPlayer = Player.m_localPlayer;
			Log.Debug("BindChest");
			GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
			GameObject val = ((hoverObject != null) ? ((Component)hoverObject.transform.root).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)val == (Object)(object)voidChest)
			{
				Log.Debug("Unbinding hovered Seidr chest");
				UnbindChest();
				return;
			}
			if (((Object)val).name != "piece_chest_private(Clone)")
			{
				Log.Info("Hovered object is not a personal chest");
				((Character)localPlayer).Message((MessageType)2, "You can't bind it", 0, (Sprite)null);
				return;
			}
			ZNetView val2 = default(ZNetView);
			if (!val.TryGetComponent<ZNetView>(ref val2))
			{
				Log.Warning("Hovering object has no view");
				return;
			}
			ZDO zDO = val2.GetZDO();
			Piece component = val.GetComponent<Piece>();
			Container container = default(Container);
			if (zDO == null || (Object)(object)component == (Object)null)
			{
				Log.Warning("Invalid hover object");
			}
			else if (!component.IsCreator())
			{
				Log.Info("You can only bind your own Personal chest");
				((Character)localPlayer).Message((MessageType)2, "You can't bind it", 0, (Sprite)null);
			}
			else if (Cfg.teleportRestriction.Value && val.TryGetComponent<Container>(ref container) && HasNonTeleportableItems(container))
			{
				Log.Info("You cannot bind a chest with items that can't be teleported");
				((Character)localPlayer).Message((MessageType)2, "You can't bind it", 0, (Sprite)null);
			}
			else if (HasSeidrCost(localPlayer, Cfg.bindCost.Value))
			{
				ApplySeidrCost(localPlayer, Cfg.bindCost.Value);
				if ((Object)(object)voidChest != (Object)null)
				{
					Log.Debug("Unbinding existing Seidr chest");
					UnbindChest(message: false);
				}
				voidChest = val;
				Log.Debug("Player selected own Personal chest");
				SaveSeidrChestZDO(zDO);
				Object.DontDestroyOnLoad((Object)(object)voidChest);
				CreateAura(voidChest);
				Container val3 = default(Container);
				if (voidChest.TryGetComponent<Container>(ref val3))
				{
					val3.m_name = "Seiðr chest";
					zDO.Set(StringExtensionMethods.GetStableHashCode("XStorage_SkipMark"), true);
				}
				Log.Info("Seidr Chest is bound");
				((Character)localPlayer).Message((MessageType)2, "Seiðr chest is bound", 0, (Sprite)null);
			}
		}

		private static void CreateAura(GameObject go)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bindPrefab == (Object)null)
			{
				bindPrefab = ZNetScene.instance.GetPrefab("fx_Immobilize");
			}
			if ((Object)(object)bindPrefab != (Object)null)
			{
				Object.Instantiate<GameObject>(bindPrefab, go.transform.position, Quaternion.identity);
			}
		}

		private static string GetChestWorldKey()
		{
			return "SeidrChest_1847_" + ZNet.m_world.m_name;
		}

		private static ZDO GetSeidrChestZDO(string playerName)
		{
			Log.Debug("GetSeidrChestZDO");
			int stableHashCode = StringExtensionMethods.GetStableHashCode("piece_chest_private");
			if (ZDOMan.instance.m_objectsByID != null)
			{
				foreach (ZDO value in ZDOMan.instance.m_objectsByID.Values)
				{
					if (value != null && value.m_prefab == stableHashCode && value.GetString("SeidrChest_1847_", "") == playerName)
					{
						return value;
					}
				}
			}
			Log.Debug("No Seidr chest ZDO found.");
			return null;
		}

		private static void RequestSeidrZDOFromServer(string playerName)
		{
			Log.Debug("RequestSeidrZDOFromServer");
			ZRoutedRpc.instance.InvokeRoutedRPC("RequestSeidrZDO", new object[1] { playerName });
		}

		private static void CancelRequestToServer(long peer)
		{
			Log.Debug("CancelRequestToServer");
			ZRoutedRpc.instance.InvokeRoutedRPC(peer, "CancelRequestZDO", Array.Empty<object>());
		}

		private static void RPC_RequestSeidrZDO(long id, string playerName)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (ZNet.instance.IsServer())
			{
				Log.Debug("RPC_RequestSeidrZDO");
				ZNetPeer peerByPlayerName = ZNet.instance.GetPeerByPlayerName(playerName);
				ZDO seidrChestZDO = GetSeidrChestZDO(playerName);
				if (seidrChestZDO != null)
				{
					Log.Debug($"Server sending Seidr chest ZDO with ZDOID {seidrChestZDO.m_uid} to {playerName}");
					seidrChestZDO.SetOwner(peerByPlayerName.m_uid);
					ZDOMan.instance.ForceSendZDO(peerByPlayerName.m_uid, seidrChestZDO.m_uid);
				}
				else
				{
					Log.Warning("Server can't find requested Seidr chest for " + playerName);
					CancelRequestToServer(id);
				}
			}
		}

		private static void RPC_CancelRequestZDO(long id)
		{
			if (!ZNet.instance.IsServer())
			{
				Log.Debug("RPC_CancelRequestZDO");
				cancelRequest = true;
			}
		}

		private static void SaveSeidrChestZDO(ZDO zdo)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("SaveSeidrChestZDO");
			zdo.Set("SeidrChest_1847_", Player.m_localPlayer.GetPlayerName());
			Log.Debug($"Saved player to Seidr chest ZDO {zdo.m_uid}");
		}

		private static bool SetupSeidrChest()
		{
			Log.Debug("SetupSeidrChest");
			if ((Object)(object)voidChest != (Object)null)
			{
				Log.Debug("Chest already exists");
				return true;
			}
			Log.Debug("Finding chest");
			ZDO seidrChestZDO = voidZdo;
			if (seidrChestZDO == null)
			{
				Log.Debug("No Seidr chest ZDO. Getting from local data.");
				seidrChestZDO = GetSeidrChestZDO(Player.m_localPlayer.GetPlayerName());
			}
			if (seidrChestZDO == null)
			{
				Log.Debug("No pre-existing chest");
				return false;
			}
			if (!ZNetScene.instance.HaveInstance(seidrChestZDO))
			{
				Log.Debug("No chest instance currently in scene... creating.");
				ZNetScene.instance.CreateObject(seidrChestZDO);
			}
			ZNetView val = ZNetScene.instance.FindInstance(seidrChestZDO);
			if ((Object)(object)val != (Object)null)
			{
				Log.Debug("Re-binding existing chest");
				voidChest = ((Component)val).gameObject;
				voidZdo = seidrChestZDO;
				Container val2 = default(Container);
				if (voidChest.TryGetComponent<Container>(ref val2))
				{
					val2.m_name = "Seiðr chest";
				}
				Object.DontDestroyOnLoad((Object)(object)voidChest);
				return true;
			}
			Log.Warning("Couldn't find or create existing chest instance");
			return false;
		}

		private static bool HandleChest()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			Log.Debug("HandleChest");
			if (!SetupSeidrChest())
			{
				Log.Info("No Seidr chest is bound");
				return false;
			}
			if (InventoryGui.instance.IsContainerOpen())
			{
				Container currentContainer = InventoryGui.instance.m_currentContainer;
				if ((Object)(object)currentContainer != (Object)null && (Object)(object)((Component)currentContainer).gameObject != (Object)(object)voidChest)
				{
					InventoryGui.instance.Hide();
				}
			}
			ZNetView val = default(ZNetView);
			if (voidChest.TryGetComponent<ZNetView>(ref val))
			{
				if (val.GetZDO() == null)
				{
					Log.Warning("Chest missing ZDO");
					return false;
				}
				Container val2 = default(Container);
				if (voidChest.TryGetComponent<Container>(ref val2))
				{
					if (val2.IsInUse())
					{
						Log.Debug("Closing chest");
						InventoryGui.instance.Hide();
						return true;
					}
					Log.Debug($"Seidr chest is {Vector3.Distance(voidChest.transform.position, ((Component)localPlayer).transform.position)} meters away");
					if (!HasSeidrCost(localPlayer, Cfg.openCost.Value, binding: false))
					{
						return false;
					}
					val2.m_name = "Seiðr chest";
					if (val2.Interact((Humanoid)(object)localPlayer, false, false))
					{
						Log.Debug("Interact successful");
						val2.m_inUse = false;
						val2.SetInUse(true);
						return true;
					}
					Log.Warning("Can't interact with chest");
					return false;
				}
				Log.Warning("Chest missing Container");
				return false;
			}
			Log.Warning("Chest missing ZNetView");
			return false;
		}

		private static bool OkToKey(Player player)
		{
			if (!Chat.instance.HasFocus() && !Console.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !GameCamera.InFreeFly() && !Minimap.IsOpen() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !((Character)player).InCutscene() && !((Character)player).InBed() && !((Character)player).IsTeleporting() && !((Character)player).IsDead())
			{
				return !((Character)player).InPlaceMode();
			}
			return false;
		}

		public static void GetDetectionSet(Dictionary<string, string> harmonyIds)
		{
			foreach (KeyValuePair<string, string> harmonyId in harmonyIds)
			{
				if (Harmony.HasAnyPatches(harmonyId.Key))
				{
					Log.Debug("Detected " + harmonyId.Value);
					if (!detectionSet.ContainsKey(harmonyId.Key))
					{
						detectionSet.Add(harmonyId.Key, harmonyId.Value);
					}
				}
			}
		}

		public static void AddExclusion(string key)
		{
			if (detectionSet.ContainsKey(key))
			{
				unpatchMods.Add(key, detectionSet[key]);
			}
		}

		public static void UnpatchMods()
		{
			foreach (KeyValuePair<string, string> unpatchMod in unpatchMods)
			{
				Log.Warning("Not compatible with " + unpatchMod.Value);
				Harmony.UnpatchID(unpatchMod.Key);
				detectionSet.Remove(unpatchMod.Key);
				Log.Warning("Disabled " + unpatchMod.Value);
			}
		}

		public static bool IsDetectedId(string key)
		{
			return detectionSet.ContainsKey(key);
		}

		private static void AddSectorObject(ZDOMan __instance, Vector2i sector, int area, List<ZDO> sectorObjects)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			ZNetView val = default(ZNetView);
			if (!((Object)(object)voidChest != (Object)null) || sectorObjects == null || !(ZoneSystem.GetZone(voidChest.transform.position) != sector) || !voidChest.TryGetComponent<ZNetView>(ref val))
			{
				return;
			}
			ZDO zDO = val.GetZDO();
			if (zDO != null && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				zDO.SetOwner(((Character)Player.m_localPlayer).GetOwner());
				if (!sectorObjects.Contains(zDO))
				{
					sectorObjects.Add(zDO);
				}
			}
		}

		[IteratorStateMachine(typeof(<Co_WaitForZDO>d__47))]
		private IEnumerator Co_WaitForZDO()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Co_WaitForZDO>d__47(0);
		}
	}
}