Decompiled source of ServersideQoL v0.2.13

Valheim.ServersideQoL.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Valheim.ServersideQoL.Processors;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Valheim.ServersideQoL")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.13.0")]
[assembly: AssemblyInformationalVersion("0.2.13+dd2f7a3e5d90ab7229c4f1667cc74aab9317228b")]
[assembly: AssemblyProduct("Valheim.ServersideQoL")]
[assembly: AssemblyTitle("Valheim.ServersideQoL")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	internal static class IsExternalInit
	{
	}
}
namespace Valheim.ServersideQoL
{
	internal sealed class ConcurrentHashSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyCollection<T> where T : notnull
	{
		private readonly ConcurrentDictionary<T, object?> _dict = new ConcurrentDictionary<T, object>();

		public int Count => _dict.Count;

		bool ICollection<T>.IsReadOnly => false;

		public bool Add(T value)
		{
			return _dict.TryAdd(value, null);
		}

		public bool Remove(T value)
		{
			object value2;
			return _dict.TryRemove(value, out value2);
		}

		void ICollection<T>.Add(T item)
		{
			if (!Add(item))
			{
				throw new InvalidOperationException();
			}
		}

		public void Clear()
		{
			_dict.Clear();
		}

		public bool Contains(T item)
		{
			return _dict.ContainsKey(item);
		}

		void ICollection<T>.CopyTo(T[] array, int arrayIndex)
		{
			throw new NotImplementedException();
		}

		IEnumerator<T> IEnumerable<T>.GetEnumerator()
		{
			return _dict.Keys.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _dict.Keys.GetEnumerator();
		}
	}
	internal static class EnumUtils
	{
		private static class Generic<T> where T : unmanaged, Enum
		{
			public static bool IsBitSet { get; } = OfType(typeof(T)).IsBitSet;


			public static Func<T, ulong> EnumToUInt64 { get; }

			public static Func<ulong, T> UInt64ToEnum { get; }

			public static Func<T, long> EnumToInt64 { get; }

			public static Func<long, T> Int64ToEnum { get; }

			static Generic()
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(T));
				EnumToUInt64 = Expression.Lambda<Func<T, ulong>>(Expression.ConvertChecked(parameterExpression, typeof(ulong)), new ParameterExpression[1] { parameterExpression }).Compile();
				ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ulong));
				UInt64ToEnum = Expression.Lambda<Func<ulong, T>>(Expression.ConvertChecked(parameterExpression2, typeof(T)), new ParameterExpression[1] { parameterExpression2 }).Compile();
				ParameterExpression parameterExpression3 = Expression.Parameter(typeof(T));
				EnumToInt64 = Expression.Lambda<Func<T, long>>(Expression.ConvertChecked(parameterExpression3, typeof(long)), new ParameterExpression[1] { parameterExpression3 }).Compile();
				ParameterExpression parameterExpression4 = Expression.Parameter(typeof(long));
				Int64ToEnum = Expression.Lambda<Func<long, T>>(Expression.ConvertChecked(parameterExpression4, typeof(T)), new ParameterExpression[1] { parameterExpression4 }).Compile();
			}
		}

		public sealed class ObjectEnumUtils
		{
			public bool IsBitSet { get; } = enumType.GetCustomAttribute<FlagsAttribute>() != null;


			public Func<object, ulong> EnumToUInt64 { get; }

			public Func<ulong, object> UInt64ToEnum { get; }

			public Func<object, long> EnumToInt64 { get; }

			public Func<long, object> Int64ToEnum { get; }

			public ObjectEnumUtils(Type enumType)
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(object));
				EnumToUInt64 = Expression.Lambda<Func<object, ulong>>(Expression.ConvertChecked(Expression.Convert(parameterExpression, enumType), typeof(ulong)), new ParameterExpression[1] { parameterExpression }).Compile();
				ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ulong));
				UInt64ToEnum = Expression.Lambda<Func<ulong, object>>(Expression.Convert(Expression.ConvertChecked(parameterExpression2, enumType), typeof(object)), new ParameterExpression[1] { parameterExpression2 }).Compile();
				ParameterExpression parameterExpression3 = Expression.Parameter(typeof(object));
				EnumToInt64 = Expression.Lambda<Func<object, long>>(Expression.ConvertChecked(Expression.Convert(parameterExpression3, enumType), typeof(long)), new ParameterExpression[1] { parameterExpression3 }).Compile();
				ParameterExpression parameterExpression4 = Expression.Parameter(typeof(long));
				Int64ToEnum = Expression.Lambda<Func<long, object>>(Expression.Convert(Expression.ConvertChecked(parameterExpression4, enumType), typeof(object)), new ParameterExpression[1] { parameterExpression4 }).Compile();
				base..ctor();
			}
		}

		private static readonly ConcurrentDictionary<Type, ObjectEnumUtils> __isBitSet = new ConcurrentDictionary<Type, ObjectEnumUtils>();

		public static ObjectEnumUtils OfType(Type type)
		{
			return __isBitSet.GetOrAdd(type, (Type t) => new ObjectEnumUtils(t));
		}

		public static bool IsBitSet<T>() where T : unmanaged, Enum
		{
			return Generic<T>.IsBitSet;
		}

		public static ulong ToUInt64<T>(this T value) where T : unmanaged, Enum
		{
			return Generic<T>.EnumToUInt64(value);
		}

		public static T ToEnum<T>(ulong value) where T : unmanaged, Enum
		{
			return Generic<T>.UInt64ToEnum(value);
		}

		public static long ToInt64<T>(this T value) where T : unmanaged, Enum
		{
			return Generic<T>.EnumToInt64(value);
		}

		public static T ToEnum<T>(long value) where T : unmanaged, Enum
		{
			return Generic<T>.Int64ToEnum(value);
		}
	}
	internal interface IZDOInventory
	{
		Inventory Inventory { get; }

		IList<ItemData> Items { get; }

		void Save();
	}
	internal sealed class ExtendedZDO : ZDO
	{
		public readonly struct ZDOVars_
		{
			private readonly ExtendedZDO _zdo;

			public ZDOVars_(ExtendedZDO zdo)
			{
				_zdo = zdo;
			}

			public int GetState(int defaultValue = 0)
			{
				return ((ZDO)_zdo).GetInt(ZDOVars.s_state, defaultValue);
			}

			public void SetState(int value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_state, value, false);
			}

			public long GetCreator(long defaultValue = 0L)
			{
				return ((ZDO)_zdo).GetLong(ZDOVars.s_creator, defaultValue);
			}

			public void SetCreator(long value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_creator, value);
			}

			public bool GetInUse(bool defaultValue = false)
			{
				return ((ZDO)_zdo).GetBool(ZDOVars.s_inUse, defaultValue);
			}

			public void SetInUse(bool value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_inUse, value);
			}

			public float GetFuel(float defaultValue = 0f)
			{
				return ((ZDO)_zdo).GetFloat(ZDOVars.s_fuel, defaultValue);
			}

			public void SetFuel(float value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_fuel, value);
			}

			public bool GetPiece(bool defaultValue = false)
			{
				return ((ZDO)_zdo).GetBool(ZDOVars.s_piece, defaultValue);
			}

			public void SetPiece(bool value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_piece, value);
			}

			public string GetItems(string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(ZDOVars.s_items, defaultValue);
			}

			public void SetItems(string value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_items, value);
			}

			public string GetTag(string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(ZDOVars.s_tag, defaultValue);
			}

			public void SetTag(string value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_tag, value);
			}

			public byte[]? GetData(byte[]? defaultValue = null)
			{
				return ((ZDO)_zdo).GetByteArray(ZDOVars.s_data, defaultValue);
			}

			public void SetData(byte[]? value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_data, value);
			}

			public float GetStamina(float defaultValue = 0f)
			{
				return ((ZDO)_zdo).GetFloat(ZDOVars.s_stamina, defaultValue);
			}

			public void SetStamina(float value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_stamina, value);
			}

			public long GetPlayerID(long defaultValue = 0L)
			{
				return ((ZDO)_zdo).GetLong(ZDOVars.s_playerID, defaultValue);
			}

			public void SetPlayerID(long value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_playerID, value);
			}

			public string GetPlayerName(string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(ZDOVars.s_playerName, defaultValue);
			}

			public void SetPlayerName(string value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_playerName, value);
			}

			public string GetFollow(string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(ZDOVars.s_follow, defaultValue);
			}

			public void SetFollow(string value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_follow, value);
			}

			public int GetRightItem(int defaultValue = 0)
			{
				return ((ZDO)_zdo).GetInt(ZDOVars.s_rightItem, defaultValue);
			}

			public void SetRightItem(int value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_rightItem, value, false);
			}

			public string GetText(string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(ZDOVars.s_text, defaultValue);
			}

			public void SetText(string value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_text, value);
			}

			public string GetItem(int idx, string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(FormattableString.Invariant($"item{idx}"), defaultValue);
			}

			public void SetItem(int idx, string value)
			{
				((ZDO)_zdo).Set(FormattableString.Invariant($"item{idx}"), value);
			}

			public int GetQueued(int defaultValue = 0)
			{
				return ((ZDO)_zdo).GetInt(ZDOVars.s_queued, defaultValue);
			}

			public void SetQueued(int value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_queued, value, false);
			}

			public bool GetTamed(bool defaultValue = false)
			{
				return ((ZDO)_zdo).GetBool(ZDOVars.s_tamed, defaultValue);
			}

			public void SetTamed(bool value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_tamed, value);
			}

			public float GetTameTimeLeft(float defaultValue = 0f)
			{
				return ((ZDO)_zdo).GetFloat(ZDOVars.s_tameTimeLeft, defaultValue);
			}

			public void SetTameTimeLeft(float value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_tameTimeLeft, value);
			}

			public int GetAmmo(int defaultValue = 0)
			{
				return ((ZDO)_zdo).GetInt(ZDOVars.s_ammo, defaultValue);
			}

			public void SetAmmo(int value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_ammo, value, false);
			}

			public string GetAmmoType(string defaultValue = "")
			{
				return ((ZDO)_zdo).GetString(ZDOVars.s_ammoType, defaultValue);
			}

			public void SetAmmoType(string value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_ammoType, value);
			}

			public float GetGrowStart(float defaultValue = 0f)
			{
				return ((ZDO)_zdo).GetFloat(ZDOVars.s_growStart, defaultValue);
			}

			public void SetGrowStart(float value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_growStart, value);
			}

			public DateTime GetSpawnTime(DateTime defaultValue = default(DateTime))
			{
				return new DateTime(((ZDO)_zdo).GetLong(ZDOVars.s_spawnTime, defaultValue.Ticks));
			}

			public void SetSpawnTime(DateTime value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_spawnTime, value.Ticks);
			}

			public float GetHealth(float defaultValue = 0f)
			{
				return ((ZDO)_zdo).GetFloat(ZDOVars.s_health, defaultValue);
			}

			public void SetHealth(float value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_health, value);
			}

			public int GetPermitted(int defaultValue = 0)
			{
				return ((ZDO)_zdo).GetInt(ZDOVars.s_permitted, defaultValue);
			}

			public void SetPermitted(int value)
			{
				((ZDO)_zdo).Set(ZDOVars.s_permitted, value, false);
			}
		}

		private sealed class AdditionalData_
		{
			private static ConcurrentDictionary<int, IReadOnlyList<Processor>> _processors = new ConcurrentDictionary<int, IReadOnlyList<Processor>>();

			public IReadOnlyList<Processor> Processors { get; private set; } = Processor.DefaultProcessors;


			public PrefabInfo PrefabInfo { get; }

			public ConcurrentDictionary<Type, object>? ComponentFieldAccessors { get; set; }

			public Dictionary<Processor, uint>? ProcessorDataRevisions { get; set; }

			public ZDOInventory? Inventory { get; set; }

			public bool? HasFields { get; set; }

			public static AdditionalData_ Dummy { get; } = new AdditionalData_(Valheim.ServersideQoL.PrefabInfo.Dummy);


			public AdditionalData_(PrefabInfo prefabInfo)
			{
				PrefabInfo = prefabInfo;
				base..ctor();
			}

			public void Ungregister(IEnumerable<Processor> processors)
			{
				IEnumerable<Processor> processors2 = processors;
				int num = 0;
				foreach (Processor processor in Processors)
				{
					if (!processors2.Any((Processor x) => x == processor))
					{
						num = (num, processor.GetType()).GetHashCode();
					}
				}
				Processors = _processors.GetOrAdd(num, (int _) => Processors.Where((Processor x) => !processors2.Any((Processor y) => x == y)).ToList());
				foreach (Processor item in processors2)
				{
					ProcessorDataRevisions?.Remove(item);
				}
			}

			public void ReregisterAll()
			{
				Processors = Processor.DefaultProcessors;
			}
		}

		public sealed class ComponentFieldAccessor<TComponent>
		{
			private readonly ExtendedZDO _zdo;

			private readonly TComponent _component;

			private bool? _hasComponentFields;

			private static readonly int __hasComponentFieldsHash = StringExtensionMethods.GetStableHashCode(FormattableString.Invariant(FormattableStringFactory.Create("{0}{1}", "HasFields", typeof(TComponent).Name)));

			private bool HasFields
			{
				get
				{
					if (_zdo.HasFields)
					{
						bool valueOrDefault = _hasComponentFields.GetValueOrDefault();
						if (!_hasComponentFields.HasValue)
						{
							valueOrDefault = ((ZDO)_zdo).GetBool(__hasComponentFieldsHash, false);
							_hasComponentFields = valueOrDefault;
							return valueOrDefault;
						}
						return valueOrDefault;
					}
					return false;
				}
			}

			public ComponentFieldAccessor(ExtendedZDO zdo, TComponent component)
			{
				_zdo = zdo;
				_component = component;
				base..ctor();
			}

			private void SetHasFields(bool value)
			{
				if (value && !_zdo.HasFields)
				{
					_zdo.SetHasFields();
				}
				if (_hasComponentFields != value)
				{
					ExtendedZDO zdo = _zdo;
					int _hasComponentFieldsHash = __hasComponentFieldsHash;
					bool? flag = (_hasComponentFields = value);
					((ZDO)zdo).Set(_hasComponentFieldsHash, flag.Value);
				}
			}

			private static int GetHash<T>(Expression<Func<TComponent, T>> fieldExpression, out FieldInfo field)
			{
				MemberExpression memberExpression = (MemberExpression)fieldExpression.Body;
				field = (FieldInfo)memberExpression.Member;
				return StringExtensionMethods.GetStableHashCode(FormattableString.Invariant($"{typeof(TComponent).Name}.{field.Name}"));
			}

			private T Get<T>(Expression<Func<TComponent, T>> fieldExpression, Func<ZDO, int, T?, T> getter)
			{
				MemberExpression memberExpression = (MemberExpression)fieldExpression.Body;
				FieldInfo fieldInfo = (FieldInfo)memberExpression.Member;
				if (!HasFields)
				{
					return (T)fieldInfo.GetValue(_component);
				}
				int stableHashCode = StringExtensionMethods.GetStableHashCode(FormattableString.Invariant($"{typeof(TComponent).Name}.{fieldInfo.Name}"));
				return getter((ZDO)(object)_zdo, stableHashCode, (T)fieldInfo.GetValue(_component));
			}

			public bool GetBool(Expression<Func<TComponent, bool>> fieldExpression)
			{
				return Get(fieldExpression, (ZDO zdo, int hash, bool defaultValue) => zdo.GetBool(hash, defaultValue));
			}

			public float GetFloat(Expression<Func<TComponent, float>> fieldExpression)
			{
				return Get(fieldExpression, (ZDO zdo, int hash, float defaultValue) => zdo.GetFloat(hash, defaultValue));
			}

			public int GetInt(Expression<Func<TComponent, int>> fieldExpression)
			{
				return Get(fieldExpression, (ZDO zdo, int hash, int defaultValue) => zdo.GetInt(hash, defaultValue));
			}

			public string GetString(Expression<Func<TComponent, string>> fieldExpression)
			{
				return Get(fieldExpression, (ZDO zdo, int hash, string? defaultValue) => zdo.GetString(hash, defaultValue));
			}

			private ComponentFieldAccessor<TComponent> SetCore<T>(Expression<Func<TComponent, T>> fieldExpression, T value, Action<ZDO, int>? remover, Action<ZDO, int, T> setter) where T : notnull
			{
				FieldInfo field;
				int hash = GetHash(fieldExpression, out field);
				if (remover != null)
				{
					ref T reference = ref value;
					T val = default(T);
					if (val == null)
					{
						val = reference;
						reference = ref val;
					}
					if (reference.Equals(field.GetValue(_component)))
					{
						remover((ZDO)(object)_zdo, hash);
						goto IL_0071;
					}
				}
				if (!HasFields)
				{
					SetHasFields(value: true);
				}
				setter((ZDO)(object)_zdo, hash, value);
				goto IL_0071;
				IL_0071:
				return this;
			}

			public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, bool>> fieldExpression, bool value)
			{
				return SetCore(fieldExpression, value, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveInt(hash);
				}, delegate(ZDO zdo, int hash, bool value)
				{
					zdo.Set(hash, value);
				});
			}

			public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, float>> fieldExpression, float value)
			{
				return SetCore(fieldExpression, value, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveFloat(hash);
				}, delegate(ZDO zdo, int hash, float value)
				{
					zdo.Set(hash, value);
				});
			}

			public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, int>> fieldExpression, int value)
			{
				return SetCore(fieldExpression, value, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveInt(hash);
				}, delegate(ZDO zdo, int hash, int value)
				{
					zdo.Set(hash, value, false);
				});
			}

			public ComponentFieldAccessor<TComponent> Set(Expression<Func<TComponent, string>> fieldExpression, string value)
			{
				return SetCore(fieldExpression, value, null, delegate(ZDO zdo, int hash, string value)
				{
					zdo.Set(hash, value);
				});
			}

			private bool SetIfChangedCore<T>(Expression<Func<TComponent, T>> fieldExpression, T value, Action<ZDO, int>? remover, Action<ZDO, int, T> setter, Func<ZDO, int, T?, T> getter) where T : notnull
			{
				FieldInfo field;
				int hash = GetHash(fieldExpression, out field);
				T val = (T)field.GetValue(_component);
				ref T reference = ref value;
				T val2 = default(T);
				if (val2 == null)
				{
					val2 = reference;
					reference = ref val2;
				}
				if (reference.Equals(getter((ZDO)(object)_zdo, hash, val)))
				{
					return false;
				}
				if (remover != null && value.Equals(val))
				{
					remover((ZDO)(object)_zdo, hash);
				}
				else
				{
					if (!HasFields)
					{
						SetHasFields(value: true);
					}
					setter((ZDO)(object)_zdo, hash, value);
				}
				return true;
			}

			public bool SetIfChanged(Expression<Func<TComponent, bool>> fieldExpression, bool value)
			{
				return SetIfChangedCore(fieldExpression, value, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveInt(hash);
				}, delegate(ZDO zdo, int hash, bool value)
				{
					zdo.Set(hash, value);
				}, (ZDO zdo, int hash, bool defaultValue) => zdo.GetBool(hash, defaultValue));
			}

			public bool SetIfChanged(Expression<Func<TComponent, float>> fieldExpression, float value)
			{
				return SetIfChangedCore(fieldExpression, value, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveFloat(hash);
				}, delegate(ZDO zdo, int hash, float value)
				{
					zdo.Set(hash, value);
				}, (ZDO zdo, int hash, float defaultValue) => zdo.GetFloat(hash, defaultValue));
			}

			public bool SetIfChanged(Expression<Func<TComponent, int>> fieldExpression, int value)
			{
				return SetIfChangedCore(fieldExpression, value, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveInt(hash);
				}, delegate(ZDO zdo, int hash, int value)
				{
					zdo.Set(hash, value, false);
				}, (ZDO zdo, int hash, int defaultValue) => zdo.GetInt(hash, defaultValue));
			}

			public bool SetIfChanged(Expression<Func<TComponent, string>> fieldExpression, string value)
			{
				return SetIfChangedCore(fieldExpression, value, null, delegate(ZDO zdo, int hash, string value)
				{
					zdo.Set(hash, value);
				}, (ZDO zdo, int hash, string? defaultValue) => zdo.GetString(hash, defaultValue));
			}

			private ComponentFieldAccessor<TComponent> ResetCore<T>(Expression<Func<TComponent, T>> fieldExpression, Action<ZDO, int> remover)
			{
				FieldInfo field;
				int hash = GetHash(fieldExpression, out field);
				remover((ZDO)(object)_zdo, hash);
				return this;
			}

			public ComponentFieldAccessor<TComponent> Reset(Expression<Func<TComponent, bool>> fieldExpression)
			{
				return ResetCore(fieldExpression, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveInt(hash);
				});
			}

			public ComponentFieldAccessor<TComponent> Reset(Expression<Func<TComponent, float>> fieldExpression)
			{
				return ResetCore(fieldExpression, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveFloat(hash);
				});
			}

			public ComponentFieldAccessor<TComponent> Reset(Expression<Func<TComponent, int>> fieldExpression)
			{
				return ResetCore(fieldExpression, delegate(ZDO zdo, int hash)
				{
					zdo.RemoveInt(hash);
				});
			}

			private bool ResetIfChangedCore<T>(Expression<Func<TComponent, T>> fieldExpression, Func<ZDO, int, bool> remover)
			{
				FieldInfo field;
				int hash = GetHash(fieldExpression, out field);
				return remover((ZDO)(object)_zdo, hash);
			}

			public bool ResetIfChanged(Expression<Func<TComponent, bool>> fieldExpression)
			{
				return ResetIfChangedCore(fieldExpression, (ZDO zdo, int hash) => zdo.RemoveInt(hash));
			}

			public bool ResetIfChanged(Expression<Func<TComponent, float>> fieldExpression)
			{
				return ResetIfChangedCore(fieldExpression, (ZDO zdo, int hash) => zdo.RemoveFloat(hash));
			}

			public bool ResetIfChanged(Expression<Func<TComponent, int>> fieldExpression)
			{
				return ResetIfChangedCore(fieldExpression, (ZDO zdo, int hash) => zdo.RemoveInt(hash));
			}
		}

		private sealed class ZDOInventory : IZDOInventory
		{
			private IList<ItemData>? _items;

			private uint _dataRevision;

			private string? _lastData;

			public Inventory Inventory { get; private set; }

			public ExtendedZDO ZDO { get; private set; }

			public IList<ItemData> Items
			{
				get
				{
					if (_items == null)
					{
						_items = Inventory.GetAllItems();
					}
					else if (_items != Inventory.GetAllItems())
					{
						throw new Exception("Assumption violated");
					}
					return _items;
				}
			}

			public ZDOInventory(ExtendedZDO zdo)
			{
				ZDO = zdo;
				_dataRevision = uint.MaxValue;
				base..ctor();
			}

			public ZDOInventory Update()
			{
				//IL_0135: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: Expected O, but got Unknown
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Expected O, but got Unknown
				if (_dataRevision == ((ZDO)ZDO).DataRevision)
				{
					return this;
				}
				string items = ZDO.Vars.GetItems();
				if (_lastData == items)
				{
					return this;
				}
				ComponentFieldAccessor<Container> componentFieldAccessor = ZDO.Fields<Container>(getUnknownComponent: false);
				int @int = componentFieldAccessor.GetInt((Expression<Func<Container, int>>)((Container x) => x.m_width));
				int int2 = componentFieldAccessor.GetInt((Expression<Func<Container, int>>)((Container x) => x.m_height));
				if (Inventory == null || Inventory.GetWidth() != @int || Inventory.GetHeight() != int2)
				{
					Inventory = new Inventory(ZDO.PrefabInfo.Container.Value.Container.m_name, ZDO.PrefabInfo.Container.Value.Container.m_bkg, @int, int2);
				}
				if (string.IsNullOrEmpty(items))
				{
					Items.Clear();
				}
				else
				{
					Inventory.Load(new ZPackage(items));
				}
				_dataRevision = ((ZDO)ZDO).DataRevision;
				_lastData = items;
				return this;
			}

			public void UpdateZDO(ExtendedZDO zdo)
			{
				ZDO = zdo;
				_items = null;
				_dataRevision = 0u;
				_lastData = null;
				Update();
			}

			public void Save()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				ZPackage val = new ZPackage();
				Inventory.Save(val);
				uint dataRevision = ((ZDO)ZDO).DataRevision;
				string @base = val.GetBase64();
				ZDO.Vars.SetItems(@base);
				if (dataRevision != ((ZDO)ZDO).DataRevision)
				{
					(Container, Piece, PieceTable, PrefabInfo.Optional<ZSyncTransform>)? container = ZDO.PrefabInfo.Container;
					if (container.HasValue)
					{
						PrefabInfo.Optional<ZSyncTransform> item = container.GetValueOrDefault().Item4;
						if (item.Value != null)
						{
							ExtendedZDO zDO = ZDO;
							((ZDO)zDO).DataRevision = ((ZDO)zDO).DataRevision + 120;
						}
					}
				}
				_dataRevision = ((ZDO)ZDO).DataRevision;
				_lastData = @base;
			}
		}

		private ZDOID _lastId = ZDOID.None;

		private AdditionalData_? _addData;

		private static readonly int __hasFieldsHash = StringExtensionMethods.GetStableHashCode("HasFields");

		private AdditionalData_ AddData
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				if (_lastId != base.m_uid || _addData == null)
				{
					_lastId = base.m_uid;
					PrefabInfo prefabInfo = SharedProcessorState.GetPrefabInfo(((ZDO)this).GetPrefab());
					if (prefabInfo != null)
					{
						_addData = new AdditionalData_(prefabInfo);
					}
					else
					{
						_addData = AdditionalData_.Dummy;
					}
				}
				return _addData;
			}
		}

		public PrefabInfo PrefabInfo => AddData.PrefabInfo;

		public IZDOInventory Inventory
		{
			get
			{
				AdditionalData_ addData = AddData;
				ZDOInventory zDOInventory = addData.Inventory;
				if (zDOInventory == null)
				{
					if (!PrefabInfo.Container.HasValue)
					{
						throw new InvalidOperationException();
					}
					ZDOInventory zDOInventory3 = (addData.Inventory = new ZDOInventory(this));
					zDOInventory = zDOInventory3;
				}
				return zDOInventory.Update();
			}
		}

		public bool HasFields
		{
			get
			{
				AdditionalData_ addData = AddData;
				bool? hasFields = addData.HasFields;
				bool valueOrDefault = hasFields.GetValueOrDefault();
				if (!hasFields.HasValue)
				{
					valueOrDefault = ((ZDO)this).GetBool(__hasFieldsHash, false);
					bool? hasFields2 = valueOrDefault;
					addData.HasFields = hasFields2;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}

		public ZDOVars_ Vars => new ZDOVars_(this);

		public IReadOnlyList<Processor> Processors => AddData.Processors;

		private void SetHasFields()
		{
			if ((!AddData.HasFields) ?? true)
			{
				((ZDO)this).Set(__hasFieldsHash, true);
				AddData.HasFields = true;
			}
		}

		public void UnregisterProcessors(IEnumerable<Processor> processors)
		{
			AddData.Ungregister(processors);
		}

		public void ReregisterAllProcessors()
		{
			_addData?.ReregisterAll();
		}

		public void UpdateProcessorDataRevision(Processor processor)
		{
			AdditionalData_ addData = AddData;
			(addData.ProcessorDataRevisions ?? (addData.ProcessorDataRevisions = new Dictionary<Processor, uint>()))[processor] = ((ZDO)this).DataRevision;
		}

		public bool CheckProcessorDataRevisionChanged(Processor processor)
		{
			if (AddData.ProcessorDataRevisions == null || !AddData.ProcessorDataRevisions.TryGetValue(processor, out var value) || value != ((ZDO)this).DataRevision)
			{
				return true;
			}
			return false;
		}

		public void Destroy()
		{
			ClaimOwnershipInternal();
			ZDOMan.instance.DestroyZDO((ZDO)(object)this);
			_addData = null;
		}

		public ExtendedZDO Recreate()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			int prefab = ((ZDO)this).GetPrefab();
			Vector3 position = ((ZDO)this).GetPosition();
			long owner = ((ZDO)this).GetOwner();
			ZPackage val = new ZPackage();
			((ZDO)this).Serialize(val);
			Destroy();
			ExtendedZDO extendedZDO = (ExtendedZDO)(object)ZDOMan.instance.CreateNewZDO(position, prefab);
			((ZDO)extendedZDO).Deserialize(new ZPackage(val.GetArray()));
			((ZDO)extendedZDO).SetOwnerInternal(owner);
			return extendedZDO;
		}

		public void ClaimOwnership()
		{
			((ZDO)this).SetOwner(ZDOMan.GetSessionID());
		}

		public void ClaimOwnershipInternal()
		{
			((ZDO)this).SetOwnerInternal(ZDOMan.GetSessionID());
		}

		public ComponentFieldAccessor<TComponent> Fields<TComponent>(bool getUnknownComponent = false) where TComponent : MonoBehaviour
		{
			AdditionalData_ addData = AddData;
			return (ComponentFieldAccessor<TComponent>)(addData.ComponentFieldAccessors ?? (addData.ComponentFieldAccessors = new ConcurrentDictionary<Type, object>())).GetOrAdd(typeof(TComponent), delegate(Type key)
			{
				if (!PrefabInfo.Components.TryGetValue(key, out MonoBehaviour value) && getUnknownComponent)
				{
					value = (MonoBehaviour)(object)PrefabInfo.Prefab.GetComponentInChildren<TComponent>();
				}
				if (value == null)
				{
					throw new KeyNotFoundException();
				}
				return new ComponentFieldAccessor<TComponent>(this, (TComponent)(object)value);
			});
		}
	}
	internal static class ExtensionMethods
	{
		public static ExtendedZDO? GetExtendedZDO(this ZDOMan instance, ZDOID id)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return (ExtendedZDO)(object)instance.GetZDO(id);
		}
	}
	[BepInPlugin("argusmagnus.ServersideQoL", "ServersideQoL", "0.2.13")]
	public sealed class Main : BaseUnityPlugin
	{
		private record SectorInfo(List<ZNetPeer> Peers, List<ZDO> ZDOs)
		{
			public int InverseWeight { get; set; }
		}

		private sealed class MyTerminal : Terminal
		{
			private sealed class MyConsoleEventArgs : ConsoleEventArgs
			{
				public MyConsoleEventArgs(string command, params string[] args)
					: base("", (Terminal)null)
				{
					int num = 0;
					string[] array = new string[1 + args.Length];
					array[num] = command;
					num++;
					foreach (string text in args)
					{
						array[num] = text;
						num++;
					}
					base.Args = array;
				}
			}

			protected override Terminal m_terminalInstance
			{
				get
				{
					throw new NotImplementedException();
				}
			}

			public static void ExecuteCommand(string command, params string[] args)
			{
				ConsoleCommand command2 = Terminal.commands[command];
				ConsoleEvent action = command2.GetAction();
				if (action != null)
				{
					action.Invoke((ConsoleEventArgs)(object)new MyConsoleEventArgs(command, args));
					return;
				}
				ConsoleEventFailable actionFailable = command2.GetActionFailable();
				if (actionFailable != null)
				{
					object obj = actionFailable.Invoke((ConsoleEventArgs)(object)new MyConsoleEventArgs(command, args));
					if (obj is bool && (bool)obj)
					{
						return;
					}
					throw new Exception(obj.ToString());
				}
				throw new ArgumentException("command");
			}
		}

		[CompilerGenerated]
		private sealed class <<Start>g__CallExecute|34_0>d : IEnumerator<YieldInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private YieldInstruction <>2__current;

			public Main <>4__this;

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

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

			[DebuggerHidden]
			public <<Start>g__CallExecute|34_0>d(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected O, but got Unknown
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Expected O, but got Unknown
				int num = <>1__state;
				Main main = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_004f;
				case 1:
					<>1__state = -1;
					goto IL_004f;
				case 2:
					<>1__state = -1;
					goto IL_0094;
				case 3:
					{
						<>1__state = -1;
						try
						{
							main.Execute();
						}
						catch (OperationCanceledException)
						{
							return false;
						}
						catch (Exception ex2)
						{
							main.Logger.LogError((object)ex2);
							return false;
						}
						break;
					}
					IL_004f:
					if (ZNet.instance == null)
					{
						<>2__current = (YieldInstruction)new WaitForSeconds(0.2f);
						<>1__state = 1;
						return true;
					}
					if (!ZNet.instance.IsServer())
					{
						main.Logger.LogWarning((object)"Mod should only be installed on the host");
						return false;
					}
					goto IL_0094;
					IL_0094:
					if (ZDOMan.instance == null || ZNetScene.instance == null)
					{
						<>2__current = (YieldInstruction)new WaitForSeconds(0.2f);
						<>1__state = 2;
						return true;
					}
					if (!main.Initialize())
					{
						return false;
					}
					break;
				}
				<>2__current = (YieldInstruction)new WaitForSeconds(1f / main.Config.General.Frequency.Value);
				<>1__state = 3;
				return true;
			}

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

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

		internal const string PluginName = "ServersideQoL";

		internal const string PluginGuid = "argusmagnus.ServersideQoL";

		private ModConfig? _config;

		private readonly Stopwatch _watch = new Stopwatch();

		private ulong _executeCounter;

		private uint _unfinishedProcessingInRow;

		private ConcurrentDictionary<Vector2i, SectorInfo> _playerSectors = new ConcurrentDictionary<Vector2i, SectorInfo>();

		private ConcurrentDictionary<Vector2i, SectorInfo> _playerSectorsOld = new ConcurrentDictionary<Vector2i, SectorInfo>();

		private readonly HashSet<ZDOID> _ignore = new HashSet<ZDOID>();

		private readonly List<Processor> _unregister = new List<Processor>();

		private bool _configChanged = true;

		private readonly GameVersion ExpectedGameVersion = GameVersion.ParseGameVersion("0.220.5");

		private const uint ExpectedNetworkVersion = 34u;

		private const uint ExpectedItemDataVersion = 106u;

		private const uint ExpectedWorldVersion = 35u;

		internal const string DummyConfigSection = "Z - Dummy";

		private const string PluginVersion = "0.2.13";

		internal const string PluginInformationalVersion = "0.2.13";

		internal static int PluginGuidHash { get; } = StringExtensionMethods.GetStableHashCode("argusmagnus.ServersideQoL");


		internal static Main Instance { get; private set; } = null;


		private static Harmony HarmonyInstance { get; } = new Harmony("argusmagnus.ServersideQoL");


		internal ManualLogSource Logger { get; } = Logger.CreateLogSource("ServersideQoL");


		internal ModConfig Config => _config ?? (_config = new ModConfig(((BaseUnityPlugin)this).Config));

		public Main()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
		}

		private void Awake()
		{
			HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine((IEnumerator)CallExecute());
			[IteratorStateMachine(typeof(<<Start>g__CallExecute|34_0>d))]
			IEnumerator<YieldInstruction> CallExecute()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <<Start>g__CallExecute|34_0>d(0)
				{
					<>4__this = this
				};
			}
		}

		private bool Initialize()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!Config.General.Enabled.Value)
			{
				return false;
			}
			bool flag = false;
			bool flag2 = false;
			if (RuntimeInformation.Instance.GameVersion != ExpectedGameVersion)
			{
				Logger.LogWarning((object)FormattableString.Invariant($"Unsupported game version: {RuntimeInformation.Instance.GameVersion}, expected: {ExpectedGameVersion}"));
				flag = true;
				flag2 |= !Config.General.IgnoreGameVersionCheck.Value;
			}
			if (RuntimeInformation.Instance.NetworkVersion != 34)
			{
				Logger.LogWarning((object)FormattableString.Invariant($"Unsupported network version: {RuntimeInformation.Instance.NetworkVersion}, expected: {34u}"));
				flag = true;
				flag2 |= !Config.General.IgnoreNetworkVersionCheck.Value;
			}
			if ((long)RuntimeInformation.Instance.ItemDataVersion != 106)
			{
				Logger.LogWarning((object)FormattableString.Invariant($"Unsupported item data version: {RuntimeInformation.Instance.ItemDataVersion}, expected: {106u}"));
				flag = true;
				flag2 |= !Config.General.IgnoreItemDataVersionCheck.Value;
			}
			if ((long)RuntimeInformation.Instance.WorldVersion != 35)
			{
				Logger.LogWarning((object)FormattableString.Invariant($"Unsupported world version: {RuntimeInformation.Instance.WorldVersion}, expected: {35u}"));
				flag = true;
				flag2 |= !Config.General.IgnoreWorldVersionCheck.Value;
			}
			if (flag)
			{
				if (flag2)
				{
					Logger.LogError((object)"Version checks failed. Mod execution is stopped");
					return false;
				}
				Logger.LogError((object)"Version checks failed, but you chose to ignore the checks (config). Continuing...");
			}
			return true;
		}

		private void Execute()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0829: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b5c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0949: Unknown result type (might be due to invalid IL or missing references)
			_executeCounter++;
			if (_configChanged)
			{
				_configChanged = false;
				if (Config.WorldModifiers.SetPresetFromConfig.Value)
				{
					try
					{
						MyTerminal.ExecuteCommand("setworldpreset", FormattableString.Invariant($"{Config.WorldModifiers.Preset.Value}"));
					}
					catch (Exception ex)
					{
						Logger.LogError((object)ex);
					}
				}
				if (Config.WorldModifiers.SetModifiersFromConfig.Value)
				{
					foreach (var (val, val2) in Config.WorldModifiers.Modifiers.Select<KeyValuePair<WorldModifiers, ConfigEntry<WorldModifierOption>>, (WorldModifiers, WorldModifierOption)>((KeyValuePair<WorldModifiers, ConfigEntry<WorldModifierOption>> x) => (x.Key, x.Value.Value)))
					{
						try
						{
							MyTerminal.ExecuteCommand("setworldmodifier", FormattableString.Invariant($"{val}"), FormattableString.Invariant($"{val2}"));
						}
						catch (Exception ex2)
						{
							Logger.LogError((object)ex2);
						}
					}
				}
				if (Config.GlobalsKeys.SetGlobalKeysFromConfig.Value)
				{
					foreach (var item5 in Config.GlobalsKeys.KeyConfigs.Select<KeyValuePair<GlobalKeys, ConfigEntryBase>, (GlobalKeys, ConfigEntryBase)>((KeyValuePair<GlobalKeys, ConfigEntryBase> x) => (x.Key, x.Value)))
					{
						GlobalKeys item = item5.Item1;
						ConfigEntryBase item2 = item5.Item2;
						object boxedValue = item2.BoxedValue;
						if (boxedValue is bool)
						{
							if ((bool)boxedValue)
							{
								ZoneSystem.instance.SetGlobalKey(item);
							}
							else
							{
								ZoneSystem.instance.RemoveGlobalKey(item);
							}
							continue;
						}
						float num;
						try
						{
							num = (float)Convert.ChangeType(item2.BoxedValue, typeof(float));
						}
						catch (Exception ex3)
						{
							Logger.LogError((object)ex3);
							continue;
						}
						ZoneSystem.instance.SetGlobalKey(item, num);
					}
				}
				foreach (Processor defaultProcessor in Processor.DefaultProcessors)
				{
					defaultProcessor.Initialize();
				}
				if (_executeCounter == 1)
				{
					((BaseUnityPlugin)this).Config.Bind<string>("Z - Dummy", "Dummy", "", FormattableString.Invariant($"Dummy entry which does nothing, it's abused to include runtime information in the config file:{Environment.NewLine}{RuntimeInformation.Instance}"));
					((BaseUnityPlugin)this).Config.SettingChanged += delegate
					{
						_configChanged = true;
					};
					return;
				}
				Logger.LogInfo((object)"Configuration changed");
				{
					foreach (ExtendedZDO value3 in ZDOMan.instance.GetObjectsByID().Values)
					{
						value3.ReregisterAllProcessors();
					}
					return;
				}
			}
			List<ZNetPeer> peers = ZNet.instance.GetPeers();
			if (peers == null || peers.Count <= 0)
			{
				return;
			}
			_watch.Restart();
			if (_executeCounter % (ulong)(60f * Config.General.Frequency.Value) == 0L)
			{
				foreach (var (key, concurrentHashSet) in SharedProcessorState.FollowingTamesByPlayerName.Select<KeyValuePair<string, ConcurrentHashSet<ZDOID>>, (string, ConcurrentHashSet<ZDOID>)>((KeyValuePair<string, ConcurrentHashSet<ZDOID>> x) => (x.Key, x.Value)))
				{
					foreach (ZDOID item6 in (IEnumerable<ZDOID>)concurrentHashSet)
					{
						ZDO zDO = ZDOMan.instance.GetZDO(item6);
						if (zDO == null || !zDO.IsValid())
						{
							concurrentHashSet.Remove(item6);
						}
					}
					if (concurrentHashSet != null && concurrentHashSet.Count == 0)
					{
						SharedProcessorState.FollowingTamesByPlayerName.TryRemove(key, out ConcurrentHashSet<ZDOID> _);
					}
				}
			}
			ConcurrentDictionary<Vector2i, SectorInfo> playerSectorsOld = _playerSectorsOld;
			ConcurrentDictionary<Vector2i, SectorInfo> playerSectors = _playerSectors;
			_playerSectors = playerSectorsOld;
			_playerSectorsOld = playerSectors;
			_playerSectors.Clear();
			Vector2i key2 = default(Vector2i);
			foreach (ZNetPeer item7 in peers)
			{
				Vector2i zone = ZoneSystem.GetZone(item7.m_refPos);
				for (int i = zone.x - Config.General.ZonesAroundPlayers.Value; i <= zone.x + Config.General.ZonesAroundPlayers.Value; i++)
				{
					for (int j = zone.y - Config.General.ZonesAroundPlayers.Value; j <= zone.y + Config.General.ZonesAroundPlayers.Value; j++)
					{
						((Vector2i)(ref key2))..ctor(i, j);
						if (_playerSectorsOld.TryRemove(key2, out SectorInfo value2))
						{
							_playerSectors.TryAdd(key2, value2);
							value2.InverseWeight = 0;
							value2.Peers.Clear();
							value2.Peers.Add(item7);
						}
						else if (_playerSectors.TryGetValue(key2, out value2))
						{
							value2.InverseWeight = 0;
							value2.Peers.Add(item7);
						}
						else
						{
							value2 = new SectorInfo(new List<ZNetPeer>(1) { item7 }, new List<ZDO>());
							_playerSectors.TryAdd(key2, value2);
						}
					}
				}
			}
			if (_unfinishedProcessingInRow > 10)
			{
				foreach (ZNetPeer item8 in peers)
				{
					Vector2i zone2 = ZoneSystem.GetZone(item8.m_refPos);
					foreach (var item9 in _playerSectors.Select<KeyValuePair<Vector2i, SectorInfo>, (Vector2i, SectorInfo)>((KeyValuePair<Vector2i, SectorInfo> x) => (x.Key, x.Value)))
					{
						Vector2i item3 = item9.Item1;
						SectorInfo item4 = item9.Item2;
						int num2 = item3.x - zone2.x;
						int num3 = item3.y - zone2.y;
						item4.InverseWeight += num2 * num2 + num3 * num3;
					}
				}
			}
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			IEnumerable<KeyValuePair<Vector2i, SectorInfo>> source = _playerSectors.AsEnumerable();
			if (_unfinishedProcessingInRow > 10)
			{
				source = source.OrderBy((KeyValuePair<Vector2i, SectorInfo> x) => x.Value.InverseWeight);
			}
			foreach (Processor defaultProcessor2 in Processor.DefaultProcessors)
			{
				defaultProcessor2.PreProcess();
			}
			foreach (var (val3, sectorInfo) in source.Select((KeyValuePair<Vector2i, SectorInfo> x) => (x.Key, x.Value)))
			{
				if (_watch.ElapsedMilliseconds > Config.General.MaxProcessingTime.Value)
				{
					break;
				}
				num4++;
				if ((object)sectorInfo != null)
				{
					List<ZDO> zDOs = sectorInfo.ZDOs;
					if (zDOs != null && zDOs.Count == 0)
					{
						ZDOMan.instance.FindSectorObjects(val3, 1, 0, sectorInfo.ZDOs, (List<ZDO>)null);
					}
				}
				num6 += sectorInfo.ZDOs.Count;
				while ((object)sectorInfo != null)
				{
					List<ZDO> zDOs = sectorInfo.ZDOs;
					if (zDOs == null || zDOs.Count <= 0 || _watch.ElapsedMilliseconds >= Config.General.MaxProcessingTime.Value)
					{
						break;
					}
					num5++;
					ExtendedZDO extendedZDO2 = (ExtendedZDO)(object)sectorInfo.ZDOs[sectorInfo.ZDOs.Count - 1];
					sectorInfo.ZDOs.RemoveAt(sectorInfo.ZDOs.Count - 1);
					if (!((ZDO)extendedZDO2).IsValid() || extendedZDO2.PrefabInfo == PrefabInfo.Dummy || _ignore.Contains(((ZDO)extendedZDO2).m_uid))
					{
						continue;
					}
					if (extendedZDO2.Processors.Count > 1)
					{
						Processor claimedExclusiveBy = null;
						foreach (Processor processor in extendedZDO2.Processors)
						{
							if (processor.ClaimExclusive(extendedZDO2))
							{
								if (claimedExclusiveBy == null)
								{
									claimedExclusiveBy = processor;
								}
								else if (Config.General.DiagnosticLogs.Value)
								{
									Logger.LogError((object)FormattableString.Invariant($"ZDO {((ZDO)extendedZDO2).m_uid} claimed exclusive by {processor.GetType().Name} while already claimed by {claimedExclusiveBy.GetType().Name}"));
								}
							}
						}
						if (claimedExclusiveBy != null)
						{
							extendedZDO2.UnregisterProcessors(extendedZDO2.Processors.Where((Processor x) => x != claimedExclusiveBy));
						}
					}
					bool flag = false;
					bool flag2 = false;
					_unregister.Clear();
					foreach (Processor processor2 in extendedZDO2.Processors)
					{
						processor2.Process(extendedZDO2, sectorInfo.Peers);
						if (processor2.UnregisterZdoProcessor)
						{
							_unregister.Add(processor2);
						}
						if (flag = processor2.DestroyZdo)
						{
							extendedZDO2.Destroy();
							break;
						}
						flag2 = flag2 || processor2.RecreateZdo;
					}
					if (!flag && flag2)
					{
						extendedZDO2.Recreate();
					}
					else if (_unregister.Count > 0)
					{
						extendedZDO2.UnregisterProcessors(_unregister);
					}
				}
			}
			if (num4 < _playerSectors.Count || num5 < num6)
			{
				_unfinishedProcessingInRow++;
			}
			else
			{
				_unfinishedProcessingInRow = 0u;
			}
			_watch.Stop();
			if (Config.General.DiagnosticLogs.Value)
			{
				LogLevel val4 = (LogLevel)((_watch.ElapsedMilliseconds > Config.General.MaxProcessingTime.Value) ? 16 : 32);
				Logger.Log(val4, (object)FormattableString.Invariant(FormattableStringFactory.Create("{0} took {1} ms to process {2} of {3} ZDOs in {4} of {5} zones. Uncomplete runs in row: {6}", "Execute", _watch.ElapsedMilliseconds, num5, num6, num4, _playerSectors.Count, _unfinishedProcessingInRow)));
				Logger.Log(val4, (object)FormattableString.Invariant(FormattableStringFactory.Create("Processing Time: {0}", string.Join(", ", from x in Processor.DefaultProcessors
					where x.ProcessingTime.Ticks > 0
					orderby x.ProcessingTime.Ticks descending
					select FormattableString.Invariant($"{x.GetType().Name}: {x.ProcessingTime.TotalMilliseconds}ms")))));
			}
		}
	}
	internal sealed class ModConfig
	{
		public sealed class GeneralConfig
		{
			public ConfigEntry<bool> Enabled { get; } = cfg.Bind<bool>(section, "Enabled", true, "Enables/disables the entire mode");


			public ConfigEntry<bool> InWorldConfigRoom { get; } = cfg.Bind<bool>(section, "InWorldConfigRoom", false, "True to generate an in-world room which admins can enter to configure this mod by editing signs. A portal is placed at the start location");


			public ConfigEntry<bool> DiagnosticLogs { get; } = cfg.Bind<bool>(section, "DiagnosticLogs", false, "Enables/disables diagnostic logs");


			public ConfigEntry<float> Frequency { get; } = cfg.Bind<float>(section, "Frequency", 5f, new ConfigDescription("How many times per second the mod processes the world", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public ConfigEntry<int> MaxProcessingTime { get; } = cfg.Bind<int>(section, "MaxProcessingTime", 20, "Max processing time (in ms) per update");


			public ConfigEntry<int> ZonesAroundPlayers { get; } = cfg.Bind<int>(section, "ZonesAroundPlayers", 1, "Zones to process around each player");


			public ConfigEntry<float> MinPlayerDistance { get; } = cfg.Bind<float>(section, "MinPlayerDistance", 4f, "Min distance all players must have to a ZDO for it to be modified");


			public ConfigEntry<bool> IgnoreGameVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreGameVersionCheck", true, "True to ignore the game version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption");


			public ConfigEntry<bool> IgnoreNetworkVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreNetworkVersionCheck", false, "True to ignore the network version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption");


			public ConfigEntry<bool> IgnoreItemDataVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreItemDataVersionCheck", false, "True to ignore the item data version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption");


			public ConfigEntry<bool> IgnoreWorldVersionCheck { get; } = cfg.Bind<bool>(section, "IgnoreWorldVersionCheck", false, "True to ignore the world version check. Turning this off may lead to the mod being run in an untested version and may lead to data loss/world corruption");


			public GeneralConfig(ConfigFile cfg, string section)
			{
			}//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown

		}

		public sealed class SignsConfig
		{
			public ConfigEntry<bool> TimeSigns { get; } = cfg.Bind<bool>(section, "TimeSigns", false, FormattableString.Invariant($"True to update sign texts which contain time emojis (any of {string.Concat(SignProcessor.ClockEmojis)}) with the in-game time"));


			public SignsConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class MapTableConfig
		{
			public ConfigEntry<bool> AutoUpdatePortals { get; } = cfg.Bind<bool>(section, "AutoUpdatePortals", false, "True to update map tables with portal pins");


			public ConfigEntry<string> AutoUpdatePortalsExclude { get; } = cfg.Bind<string>(section, "AutoUpdatePortalsExclude", "", "Portals with a tag that matches this filter are not added to map tables");


			public ConfigEntry<string> AutoUpdatePortalsInclude { get; } = cfg.Bind<string>(section, "AutoUpdatePortalsInclude", "*", "Only portals with a tag that matches this filter are added to map tables");


			public ConfigEntry<bool> AutoUpdateShips { get; } = cfg.Bind<bool>(section, "AutoUpdateShips", false, "True to update map tables with ship pins");


			public MapTableConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class TamesConfig
		{
			public ConfigEntry<bool> MakeCommandable { get; } = cfg.Bind<bool>(section, "MakeCommandable", false, "True to make all tames commandable (like wolves)");


			public ConfigEntry<bool> ShowTamingProgress { get; } = cfg.Bind<bool>(section, "ShowTamingProgress", false, "True to show taming progress to nearby players");


			public ConfigEntry<bool> ShowGrowingProgress { get; } = cfg.Bind<bool>(section, "ShowGrowingProgress", false, "True to show growing progress to nearby players");


			public ConfigEntry<bool> AlwaysFed { get; } = cfg.Bind<bool>(section, "AlwaysFed", false, "True to make tames always fed (not hungry)");


			public ConfigEntry<bool> TeleportFollow { get; } = cfg.Bind<bool>(section, "TeleportFollow", false, "True to teleport following tames to the players location if the player gets too far away from them");


			public TamesConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class FireplacesConfig
		{
			public enum IgnoreRainOptions
			{
				Never,
				Always,
				InsideShield
			}

			public ConfigEntry<bool> MakeToggleable { get; } = cfg.Bind<bool>(section, "MakeToggleable", false, "True to make all fireplaces (including torches, braziers, etc.) toggleable");


			public ConfigEntry<bool> InfiniteFuel { get; } = cfg.Bind<bool>(section, "InfiniteFuel", false, "True to make all fireplaces have infinite fuel");


			public ConfigEntry<IgnoreRainOptions> IgnoreRain { get; } = cfg.Bind<IgnoreRainOptions>(section, "IgnoreRain", IgnoreRainOptions.Never, new ConfigDescription("Options to make all fireplaces ignore rain", (AcceptableValueBase)(object)new AcceptableEnum<IgnoreRainOptions>(), Array.Empty<object>()));


			public FireplacesConfig(ConfigFile cfg, string section)
			{
			}//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown

		}

		public sealed class ContainersConfig
		{
			public ConfigEntry<bool> AutoSort { get; }

			public ConfigEntry<bool> AutoPickup { get; }

			public ConfigEntry<float> AutoPickupRange { get; }

			public ConfigEntry<float> AutoPickupMinPlayerDistance { get; }

			public IReadOnlyDictionary<int, ConfigEntry<string>> ContainerSizes { get; }

			public ContainersConfig(ConfigFile cfg, string section)
			{
				ConfigFile cfg2 = cfg;
				string section2 = section;
				AutoSort = cfg2.Bind<bool>(section2, "AutoSort", false, "True to auto sort container inventories");
				AutoPickup = cfg2.Bind<bool>(section2, "AutoPickup", false, "True to automatically put dropped items into containers if they already contain said item");
				AutoPickupRange = cfg2.Bind<float>(section2, "AutoPickupRange", 64f, "Required proximity of a container to a dropped item to be considered as auto pickup target");
				AutoPickupMinPlayerDistance = cfg2.Bind<float>(section2, "AutoPickupMinPlayerDistance", 8f, "Min distance all player must have to a dropped item for it to be picked up");
				ContainerSizes = (from x in ZNetScene.instance.m_prefabs
					where SharedProcessorState.PieceTablesByPiece.ContainsKey(((Object)x).name)
					select (((Object)x).name, x.GetComponent<Container>() ?? x.GetComponentInChildren<Container>(), x.GetComponent<Piece>()) into x
					where x.Container != null && x.Piece != null
					select x).ToDictionary<(string, Container, Piece), int, ConfigEntry<string>>(((string Name, Container Container, Piece Piece) x) => StringExtensionMethods.GetStableHashCode(x.Name), ((string Name, Container Container, Piece Piece) x) => cfg2.Bind<string>(section2, FormattableString.Invariant($"InventorySize_{x.Name}"), FormattableString.Invariant($"{x.Container.m_width}x{x.Container.m_height}"), FormattableString.Invariant($"Inventory size for '{Localization.instance.Localize(x.Piece.m_name)}'")));
				base..ctor();
			}
		}

		public sealed class SmeltersConfig
		{
			public ConfigEntry<bool> FeedFromContainers { get; } = cfg.Bind<bool>(section, "FeedFromContainers", false, "True to automatically feed smelters from nearby containers");


			public ConfigEntry<float> FeedFromContainersRange { get; } = cfg.Bind<float>(section, "FeedFromContainersRange", 4f, "Required proxmity of a container to a smelter to be used as feeding source");


			public ConfigEntry<int> FeedFromContainersLeaveAtLeastFuel { get; } = cfg.Bind<int>(section, "FeedFromContainersLeaveAtLeastFuel", 1, "Minimum amout of fuel to leave in a container");


			public ConfigEntry<int> FeedFromContainersLeaveAtLeastOre { get; } = cfg.Bind<int>(section, "FeedFromContainersLeaveAtLeastOre", 1, "Minimum amout of ore to leave in a container");


			public SmeltersConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class WindmillsConfig
		{
			public ConfigEntry<bool> IgnoreWind { get; } = cfg.Bind<bool>(section, "IgnoreWind", false, "True to make windmills ignore wind (Cover still decreases operating efficiency though)");


			public WindmillsConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class CartsConfig
		{
			public ConfigEntry<float> ContentMassMultiplier { get; } = cfg.Bind<float>(section, "ContentMassMultiplier", 1f, new ConfigDescription("Multiplier for a carts content weight. E.g. set to 0 to ignore a cart's content weight", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public CartsConfig(ConfigFile cfg, string section)
			{
			}//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown

		}

		public sealed class DoorsConfig
		{
			public ConfigEntry<float> AutoCloseMinPlayerDistance { get; } = cfg.Bind<float>(section, "AutoCloseMinPlayerDistance", float.NaN, FormattableString.Invariant($"Min distance all players must have to the door before it is closed. {float.NaN} to disable this feature"));


			public DoorsConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class PlayersConfig
		{
			public ConfigEntry<bool> InfiniteBuildingStamina { get; } = cfg.Bind<bool>(section, "InfiniteBuildingStamina", false, FormattableString.Invariant(FormattableStringFactory.Create("True to give players infinite stamina when building. If you want infinite stamina in general, set the global key '{0}' to 0", "StaminaRate")));


			public ConfigEntry<bool> InfiniteFarmingStamina { get; } = cfg.Bind<bool>(section, "InfiniteFarmingStamina", false, FormattableString.Invariant(FormattableStringFactory.Create("True to give players infinite stamina when farming. If you want infinite stamina in general, set the global key '{0}' to 0", "StaminaRate")));


			public PlayersConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class TurretsConfig
		{
			public ConfigEntry<bool> DontTargetPlayers { get; } = cfg.Bind<bool>(section, "DontTargetPlayers", false, "True to stop ballistas from targeting players");


			public ConfigEntry<bool> DontTargetTames { get; } = cfg.Bind<bool>(section, "DontTargetTames", false, "True to stop ballistas from targeting tames");


			public ConfigEntry<bool> LoadFromContainers { get; } = cfg.Bind<bool>(section, "LoadFromContainers", false, "True to automatically load ballistas from containers");


			public ConfigEntry<float> LoadFromContainersRange { get; } = cfg.Bind<float>(section, "LoadFromContainersRange", 4f, "Required proxmity of a container to a ballista to be used as ammo source");


			public TurretsConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class WearNTearConfig
		{
			[Flags]
			public enum DisableSupportRequirementsOptions
			{
				None = 0,
				PlayerBuilt = 1,
				World = 2
			}

			public ConfigEntry<bool> DisableRainDamage { get; } = cfg.Bind<bool>(section, "DisableRainDamage", false, "True to prevent rain from damaging build pieces");


			public ConfigEntry<DisableSupportRequirementsOptions> DisableSupportRequirements { get; } = cfg.Bind<DisableSupportRequirementsOptions>(section, "DisableSupportRequirements", DisableSupportRequirementsOptions.None, new ConfigDescription("Ignore support requirements on build pieces", (AcceptableValueBase)(object)new AcceptableEnum<DisableSupportRequirementsOptions>(), Array.Empty<object>()));


			public WearNTearConfig(ConfigFile cfg, string section)
			{
			}//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown

		}

		public sealed class PortalHubConfig
		{
			public ConfigEntry<bool> Enable { get; } = cfg.Bind<bool>(section, "Enable", false, "True to automatically generate a portal hub");


			public ConfigEntry<string> Exclude { get; } = cfg.Bind<string>(section, "Exclude", "", "Portals with a tag that matches this filter are not added to the portal hub");


			public ConfigEntry<string> Include { get; } = cfg.Bind<string>(section, "Include", "*", "Only portals with a tag that matches this filter are added to the portal hub");


			public PortalHubConfig(ConfigFile cfg, string section)
			{
			}
		}

		public sealed class WorldModifiersConfig
		{
			public ConfigEntry<bool> SetPresetFromConfig { get; } = cfg.Bind<bool>(section, "SetPresetFromConfig", false, FormattableString.Invariant(FormattableStringFactory.Create("True to set the world preset according to the '{0}' config entry", "Preset")));


			public ConfigEntry<WorldPresets> Preset { get; } = GetPreset(cfg, section);


			public ConfigEntry<bool> SetModifiersFromConfig { get; } = cfg.Bind<bool>(section, "SetModifiersFromConfig", false, "True to set world modifiers according to the following configuration entries");


			public IReadOnlyDictionary<WorldModifiers, ConfigEntry<WorldModifierOption>> Modifiers { get; } = GetModifiers(cfg, section);


			public WorldModifiersConfig(ConfigFile cfg, string section)
			{
			}

			private static ConfigEntry<WorldPresets> GetPreset(ConfigFile cfg, string section)
			{
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Expected O, but got Unknown
				IReadOnlyList<KeyButton> source = PrivateAccessor.GetServerOptionsGUIPresets();
				return cfg.Bind<WorldPresets>(section, "Preset", (WorldPresets)0, new ConfigDescription(FormattableString.Invariant(FormattableStringFactory.Create("World preset. Enable '{0}' for this to have an effect", "SetPresetFromConfig")), (AcceptableValueBase)(object)new AcceptableEnum<WorldPresets>(source.Select((KeyButton x) => x.m_preset)), Array.Empty<object>()));
			}

			private static IReadOnlyDictionary<WorldModifiers, ConfigEntry<WorldModifierOption>> GetModifiers(ConfigFile cfg, string section)
			{
				ConfigFile cfg2 = cfg;
				string section2 = section;
				return (from keySlider in PrivateAccessor.GetServerOptionsGUIModifiers().OfType<KeySlider>()
					select (keySlider.m_modifier, cfg2.Bind<WorldModifierOption>(section2, FormattableString.Invariant($"{keySlider.m_modifier}"), (WorldModifierOption)0, new ConfigDescription(FormattableString.Invariant(FormattableStringFactory.Create("World modifier '{0}'. Enable '{1}' for this to have an effect", keySlider.m_modifier, "SetModifiersFromConfig")), (AcceptableValueBase)(object)new AcceptableEnum<WorldModifierOption>(keySlider.m_settings.Select((SliderSetting x) => x.m_modifierValue)), Array.Empty<object>())))).ToDictionary<(WorldModifiers, ConfigEntry<WorldModifierOption>), WorldModifiers, ConfigEntry<WorldModifierOption>>(((WorldModifiers Key, ConfigEntry<WorldModifierOption> Cfg) x) => x.Key, ((WorldModifiers Key, ConfigEntry<WorldModifierOption> Cfg) x) => x.Cfg);
			}
		}

		public sealed class GlobalsKeysConfig
		{
			public ConfigEntry<bool> SetGlobalKeysFromConfig { get; } = cfg.Bind<bool>(section, "SetGlobalKeysFromConfig", false, "True to set global keys according to the following configuration entries");


			public IReadOnlyDictionary<GlobalKeys, ConfigEntryBase> KeyConfigs { get; } = ((GlobalKeyConfigFinder)(tmp ?? (tmp = new GlobalKeyConfigFinder()))).Get<GlobalKeys>((GlobalKeys?)(GlobalKeys)30, cfg, section, FormattableString.Invariant(FormattableStringFactory.Create("Sets the value for the '{{0}}' global key. Enable '{0}' for this to have an effect", "SetGlobalKeysFromConfig")));


			public ConfigEntry<bool> NoPortalsPreventsContruction { get; } = cfg.Bind<bool>(section, "NoPortalsPreventsContruction", true, FormattableString.Invariant($"True to change the effect of the '{(object)(GlobalKeys)26}' global key, to prevent the construction of new portals but leave existing portals functional"));


			public GlobalsKeysConfig(ConfigFile cfg, string section, object? tmp = null)
			{
			}
		}

		private sealed class GlobalKeyConfigFinder
		{
			private sealed record FieldInfoEx(FieldInfo Field, object? OriginalValueObject, double OriginalValue);

			private readonly List<FieldInfoEx> fields = (from x in typeof(Game).GetFields(BindingFlags.Static | BindingFlags.Public)
				select new FieldInfoEx(x, x.GetValue(null), TryGetAsDouble(x)) into x
				where !double.IsNaN(x.OriginalValue)
				select x).ToList();

			private readonly List<(double TestValue, double Value)> _testResults = new List<(double, double)>();

			private readonly IEnumerable<double> _testValues;

			private readonly Dictionary<string, string> _keyTestValues;

			private MethodInfo? _bindDefinition;

			public IReadOnlyDictionary<TKey, ConfigEntryBase> Get<TKey>(TKey? maxEclusive, ConfigFile cfg, string section, string descriptionFormat) where TKey : unmanaged, Enum
			{
				//IL_038b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0392: Expected O, but got Unknown
				//IL_0400: Unknown result type (might be due to invalid IL or missing references)
				//IL_0407: Expected O, but got Unknown
				//IL_0375: Unknown result type (might be due to invalid IL or missing references)
				//IL_037c: Expected O, but got Unknown
				Dictionary<TKey, ConfigEntryBase> dictionary = new Dictionary<TKey, ConfigEntryBase>();
				foreach (TKey value3 in Enum.GetValues(typeof(TKey)))
				{
					if (maxEclusive.HasValue && value3.ToInt64() >= maxEclusive.Value.ToInt64())
					{
						continue;
					}
					string text = value3.ToString();
					string key = text.ToLower();
					FieldInfo fieldInfo = null;
					object value = null;
					double num = double.NaN;
					_testResults.Clear();
					foreach (double testValue in _testValues)
					{
						_keyTestValues.Clear();
						_keyTestValues.Add(key, FormattableString.Invariant($"{testValue}"));
						try
						{
							Game.UpdateWorldRates(new HashSet<string>(), _keyTestValues);
						}
						catch (NullReferenceException)
						{
						}
						double num2 = double.NaN;
						if ((object)fieldInfo == null)
						{
							int index;
							(fieldInfo, value, num, num2, index) = fields.Select((FieldInfoEx x, int i) => (x.Field, x.OriginalValueObject, x.OriginalValue, TryGetAsDouble(x.Field), i)).FirstOrDefault<(FieldInfo, object, double, double, int)>(((FieldInfo Field, object OriginalValueObject, double OriginalValue, double Value, int i) x) => x.OriginalValue != x.Value);
							if ((object)fieldInfo != null)
							{
								fields.RemoveAt(index);
							}
						}
						else
						{
							num2 = TryGetAsDouble(fieldInfo);
							if (num2 == num)
							{
								num2 = double.NaN;
							}
						}
						if (!double.IsNaN(num2))
						{
							_testResults.Add((testValue, num2));
						}
					}
					List<(double, double)> testResults = _testResults;
					if (testResults != null && testResults.Count > 0 && (object)fieldInfo != null)
					{
						double min = _testResults.Min(((double TestValue, double Value) x) => x.Value);
						double max = _testResults.Max(((double TestValue, double Value) x) => x.Value);
						IEnumerable<(double, double)> source = _testResults.Where(((double TestValue, double Value) x) => x.Value != 0.0 && x.Value > min && x.Value < max);
						double num3 = (source.Any() ? source.Average<(double, double)>(((double TestValue, double Value) x) => x.TestValue / x.Value) : 1.0);
						min *= num3;
						max *= num3;
						num *= num3;
						AcceptableValueBase val2 = null;
						if (min > -3.4028234663852886E+38 && max < 3.4028234663852886E+38 && min < max)
						{
							val2 = (AcceptableValueBase)Activator.CreateInstance(typeof(AcceptableValueRange<>).MakeGenericType(fieldInfo.FieldType), Convert.ChangeType(min, fieldInfo.FieldType), Convert.ChangeType(max, fieldInfo.FieldType));
						}
						ConfigDescription val3 = new ConfigDescription(string.Format(descriptionFormat, text), val2, Array.Empty<object>());
						if ((object)_bindDefinition == null)
						{
							_bindDefinition = new Func<string, string, bool, ConfigDescription, ConfigEntry<bool>>(cfg.Bind<bool>).Method.GetGenericMethodDefinition();
						}
						ConfigEntryBase value2 = (ConfigEntryBase)_bindDefinition.MakeGenericMethod(fieldInfo.FieldType).Invoke(cfg, new object[4]
						{
							section,
							text,
							Convert.ChangeType(num, fieldInfo.FieldType),
							val3
						});
						dictionary.Add(value3, value2);
					}
					else
					{
						dictionary.Add(value3, (ConfigEntryBase)(object)cfg.Bind<bool>(section, text, false, string.Format(descriptionFormat, text)));
					}
					fieldInfo?.SetValue(null, value);
				}
				return dictionary;
			}

			private static double TryGetAsDouble(FieldInfo field)
			{
				object value = field.GetValue(null);
				try
				{
					return (double)Convert.ChangeType(value, typeof(double));
				}
				catch
				{
					return double.NaN;
				}
			}

			public GlobalKeyConfigFinder()
			{
				List<double> list = new List<double>();
				list.Add(-3.4028234663852886E+38);
				list.Add(-2147483648.0);
				list.AddRange(Enumerable.Range(-100, 100).Select((Func<int, double>)((int x) => x)));
				list.Add(2147483647.0);
				list.Add(3.4028234663852886E+38);
				_testValues = new <>z__ReadOnlyList<double>(list);
				_keyTestValues = new Dictionary<string, string>();
				base..ctor();
			}
		}

		public sealed class TradersConfig
		{
			public IReadOnlyDictionary<Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)>> AlwaysUnlock { get; } = GetAlwaysUnlock(cfg, section);


			public TradersConfig(ConfigFile cfg, string section)
			{
			}

			private static IReadOnlyDictionary<Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)>> GetAlwaysUnlock(ConfigFile cfg, string section)
			{
				ConfigFile cfg2 = cfg;
				string section2 = section;
				if (!ZNet.instance.IsServer() || !ZNet.instance.IsDedicated())
				{
					return new Dictionary<Trader, IReadOnlyList<(string, ConfigEntry<bool>)>>();
				}
				return (from x in (from x in ZNetScene.instance.m_prefabs
						select x.GetComponent<Trader>() into x
						where x != null
						select x).Select((Func<Trader, (Trader, IReadOnlyList<(string, ConfigEntry<bool>)>)>)((Trader trader) => (trader, (from x in trader.m_items
						where !string.IsNullOrEmpty(x.m_requiredGlobalKey)
						select x into item
						select (item.m_requiredGlobalKey, cfg2.Bind<bool>(section2, FormattableString.Invariant(FormattableStringFactory.Create("{0}{1}{2}", "AlwaysUnlock", ((Object)trader).name, ((Object)item.m_prefab).name)), false, FormattableString.Invariant($"Remove the progression requirements for buying {Localization.instance.Localize(item.m_prefab.m_itemData.m_shared.m_name)} from {Localization.instance.Localize(trader.m_name)}")))).ToList())))
					where x.Entries.Any()
					select x).ToDictionary<(Trader, IReadOnlyList<(string, ConfigEntry<bool>)>), Trader, IReadOnlyList<(string, ConfigEntry<bool>)>>(((Trader Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)> Entries) x) => x.Trader, ((Trader Trader, IReadOnlyList<(string GlobalKey, ConfigEntry<bool> ConfigEntry)> Entries) x) => x.Entries);
			}
		}

		public sealed class PlantsConfig
		{
			public ConfigEntry<float> GrowTimeMultiplier { get; } = cfg.Bind<float>(section, "GrowTimeMultiplier", 1f, new ConfigDescription("Multiply plant grow time by this factor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public ConfigEntry<float> SpaceRequirementMultiplier { get; } = cfg.Bind<float>(section, "SpaceRequirementMultiplier", 1f, new ConfigDescription("Multiply plant grow time by this factor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public ConfigEntry<bool> DontDestroyIfCantGrow { get; } = cfg.Bind<bool>(section, "DontDestroyIfCantGrow", false, "True to keep plants which can't grow alive");


			public PlantsConfig(ConfigFile cfg, string section)
			{
			}//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown

		}

		public sealed class SummonsConfig
		{
			public ConfigEntry<float> UnsummonDistanceMultiplier { get; } = cfg.Bind<float>(section, "UnsummonDistanceMultiplier", 1f, new ConfigDescription("Multiply unsummon distance by this factor. 0 to disable distance-based unsummoning", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public ConfigEntry<float> UnsummonLogoutTimeMultiplier { get; } = cfg.Bind<float>(section, "UnsummonLogoutTimeMultiplier", 1f, new ConfigDescription("Multiply the time after which summons are unsummoned when the player logs out. 0 to disable logout-based unsummoning", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public SummonsConfig(ConfigFile cfg, string section)
			{
			}//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown

		}

		public sealed class TrapsConfig
		{
			public ConfigEntry<bool> DisableTriggeredByPlayers { get; } = cfg.Bind<bool>(section, "DisableTriggeredByPlayers", false, "True to stop traps from being triggered by players");


			public ConfigEntry<bool> DisableFriendlyFire { get; } = cfg.Bind<bool>(section, "DisableFriendlyFire", false, "True to stop traps from damaging players and tames");


			public ConfigEntry<float> SelfDamageMultiplier { get; } = cfg.Bind<float>(section, "SelfDamageMultiplier", 1f, new ConfigDescription("Multiply the damage the trap takes when it is triggered by this factor. 0 to make the trap take no damage", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.PositiveInfinity), Array.Empty<object>()));


			public TrapsConfig(ConfigFile cfg, string section)
			{
			}//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown

		}

		internal sealed class AcceptableEnum<T> : AcceptableValueBase where T : unmanaged, Enum
		{
			private readonly T _default;

			public IReadOnlyList<T> AcceptableValues { get; }

			public AcceptableEnum()
				: this((IEnumerable<T>)(T[])Enum.GetValues(typeof(T)))
			{
			}

			public AcceptableEnum(IEnumerable<T> values)
				: base(typeof(T))
			{
				if (EnumUtils.IsBitSet<T>())
				{
					List<T> list = new List<T>();
					list.AddRange(values.Where((T x) => !x.Equals(default(T))));
					AcceptableValues = new <>z__ReadOnlyList<T>(list);
					_default = default(T);
					return;
				}
				object obj = values as IReadOnlyList<T>;
				if (obj == null)
				{
					List<T> list2 = new List<T>();
					list2.AddRange(values);
					obj = new <>z__ReadOnlyList<T>(list2);
				}
				AcceptableValues = (IReadOnlyList<T>)obj;
				_default = AcceptableValues.FirstOrDefault();
			}

			public override object Clamp(object value)
			{
				if (value is T)
				{
					T e = (T)value;
					if (EnumUtils.IsBitSet<T>())
					{
						ulong val = e.ToUInt64();
						ulong num = 0uL;
						foreach (ulong item in from x in AcceptableValues
							select x.ToUInt64() into x
							where (val & x) == x
							select x)
						{
							num |= item;
						}
						return EnumUtils.ToEnum<T>(num);
					}
					if (!AcceptableValues.Any((T x) => x.Equals(e)))
					{
						return _default;
					}
					return e;
				}
				return _default;
			}

			public override bool IsValid(object value)
			{
				return object.Equals(value, ((AcceptableValueBase)this).Clamp(value));
			}

			public override string ToDescriptionString()
			{
				if (EnumUtils.IsBitSet<T>())
				{
					return FormattableString.Invariant(FormattableStringFactory.Create("# Acceptable values: {0} or combination of {1}", _default, string.Join(", ", AcceptableValues.Where((T x) => !x.Equals(_default)))));
				}
				return FormattableString.Invariant(FormattableStringFactory.Create("# Acceptable values: {0}", string.Join(", ", AcceptableValues)));
			}
		}

		public ConfigFile ConfigFile { get; }

		public GeneralConfig General { get; }

		public SignsConfig Signs { get; }

		public MapTableConfig MapTables { get; }

		public TamesConfig Tames { get; }

		public SummonsConfig Summons { get; }

		public FireplacesConfig Fireplaces { get; }

		public ContainersConfig Containers { get; }

		public SmeltersConfig Smelters { get; }

		public WindmillsConfig Windmills { get; }

		public CartsConfig Carts { get; }

		public DoorsConfig Doors { get; }

		public PlayersConfig Players { get; }

		public TurretsConfig Turrets { get; }

		public WearNTearConfig WearNTear { get; }

		public TradersConfig Traders { get; }

		public PlantsConfig Plants { get; }

		public TrapsConfig Traps { get; }

		public PortalHubConfig PortalHub { get; }

		public WorldModifiersConfig WorldModifiers { get; }

		public GlobalsKeysConfig GlobalsKeys { get; }

		public ModConfig(ConfigFile cfg)
		{
			ConfigFile = cfg;
			General = new GeneralConfig(cfg, "A - General");
			Signs = new SignsConfig(cfg, "B - Signs");
			MapTables = new MapTableConfig(cfg, "B - Map Tables");
			Tames = new TamesConfig(cfg, "B - Tames");
			Summons = new SummonsConfig(cfg, "B - Summons");
			Fireplaces = new FireplacesConfig(cfg, "B - Fireplaces");
			Containers = new ContainersConfig(cfg, "B - Containers");
			Smelters = new SmeltersConfig(cfg, "B - Smelters");
			Windmills = new WindmillsConfig(cfg, "B - Windmills");
			Carts = new CartsConfig(cfg, "B - Carts");
			Doors = new DoorsConfig(cfg, "B - Doors");
			Players = new PlayersConfig(cfg, "B - Players");
			Turrets = new TurretsConfig(cfg, "B - Turrets");
			WearNTear = new WearNTearConfig(cfg, "B - Build Pieces");
			Traders = new TradersConfig(cfg, "B - Traders");
			Plants = new PlantsConfig(cfg, "B - Plants");
			Traps = new TrapsConfig(cfg, "B - Traps");
			PortalHub = new PortalHubConfig(cfg, "B - Portal Hub");
			WorldModifiers = new WorldModifiersConfig(cfg, "C - World Modifiers");
			GlobalsKeys = new GlobalsKeysConfig(cfg, "D - Global Keys");
			base..ctor();
		}
	}
	internal sealed class PrefabInfo
	{
		public record struct Optional<T>(T? Value) where T : MonoBehaviour
		{
			public static implicit operator T(in Optional<T> value)
			{
				return value.Value ?? throw new ArgumentNullException();
			}
		}

		public GameObject Prefab { get; }

		public string PrefabName
		{
			get
			{
				GameObject prefab = Prefab;
				return ((prefab != null) ? ((Object)prefab).name : null) ?? "";
			}
		}

		public IReadOnlyDictionary<Type, MonoBehaviour> Components { get; }

		public Sign? Sign { get; }

		public MapTable? MapTable { get; }

		public Tameable? Tameable { get; }

		public Fireplace? Fireplace { get; }

		public (Container Container, Piece Piece, PieceTable PieceTable, Optional<ZSyncTransform> ZSyncTransform)? Container { get; }

		public (Ship Ship, Piece Piece)? Ship { get; }

		public (ItemDrop ItemDrop, Optional<Piece> Piece)? ItemDrop { get; }

		public Smelter? Smelter { get; }

		public ShieldGenerator? ShieldGenerator { get; }

		public Windmill? Windmill { get; }

		public Vagon? Vagon { get; }

		public Player? Player { get; }

		public TeleportWorld? TeleportWorld { get; }

		public Door? Door { get; }

		public (Turret Turret, Piece Piece, PieceTable PieceTable)? Turret { get; }

		public (WearNTear WearNTear, Optional<Piece> Piece, Optional<PieceTable> PieceTable)? WearNTear { get; }

		public Trader? Trader { get; }

		public Plant? Plant { get; }

		public EggGrow? EggGrow { get; }

		public Growup? Growup { get; }

		public (Aoe Aoe, Piece Piece, PieceTable PieceTable, Optional<Trap> Trap)? Trap { get; }

		public static PrefabInfo Dummy { get; } = new PrefabInfo(null, new Dictionary<Type, MonoBehaviour>(0));


		public PrefabInfo(GameObject prefab, IReadOnlyDictionary<Type, MonoBehaviour> components)
		{
			Prefab = prefab;
			Components = components;
			Sign = Get<Sign>(components);
			MapTable = Get<MapTable>(components);
			Tameable = Get<Tameable>(components);
			Fireplace = Get<Fireplace>(components);
			(Container, Optional<Piece>, Optional<PieceTable>, Optional<ZSyncTransform>)? tuple = Get<Container, Piece, PieceTable, ZSyncTransform>(components);
			(Container, Piece, PieceTable, Optional<ZSyncTransform>)? obj;
			if (!tuple.HasValue)
			{
				obj = null;
			}
			else
			{
				(Container, Optional<Piece>, Optional<PieceTable>, Optional<ZSyncTransform>) valueOrDefault = tuple.GetValueOrDefault();
				obj = (valueOrDefault.Item1, valueOrDefault.Item2, valueOrDefault.Item3, valueOrDefault.Item4);
			}
			Container = obj;
			(Ship, Optional<Piece>)? tuple2 = Get<Ship, Piece>(components);
			(Ship, Piece)? obj2;
			if (!tuple2.HasValue)
			{
				obj2 = null;
			}
			else
			{
				(Ship, Optional<Piece>) valueOrDefault2 = tuple2.GetValueOrDefault();
				obj2 = (valueOrDefault2.Item1, valueOrDefault2.Item2);
			}
			Ship = obj2;
			ItemDrop = Get<ItemDrop, Piece>(components);
			Smelter = Get<Smelter>(components);
			ShieldGenerator = Get<ShieldGenerator>(components);
			Windmill = Get<Windmill>(components);
			Vagon = Get<Vagon>(components);
			Player = Get<Player>(components);
			TeleportWorld = Get<TeleportWorld>(components);
			Door = Get<Door>(components);
			(Turret, Optional<Piece>, Optional<PieceTable>)? tuple3 = Get<Turret, Piece, PieceTable>(components);
			(Turret, Piece, PieceTable)? obj3;
			if (!tuple3.HasValue)
			{
				obj3 = null;
			}
			else
			{
				(Turret, Optional<Piece>, Optional<PieceTable>) valueOrDefault3 = tuple3.GetValueOrDefault();
				obj3 = (valueOrDefault3.Item1, valueOrDefault3.Item2, valueOrDefault3.Item3);
			}
			Turret = obj3;
			WearNTear = Get<WearNTear, Piece, PieceTable>(components);
			Trader = Get<Trader>(components);
			Plant = Get<Plant>(components);
			EggGrow = Get<EggGrow>(components);
			Growup = Get<Growup>(components);
			(Aoe, Optional<Piece>, Optional<PieceTable>, Optional<Trap>)? tuple4 = Get<Aoe, Piece, PieceTable, Trap>(components);
			(Aoe, Piece, PieceTable, Optional<Trap>)? obj4;
			if (!tuple4.HasValue)
			{
				obj4 = null;
			}
			else
			{
				(Aoe, Optional<Piece>, Optional<PieceTable>, Optional<Trap>) valueOrDefault4 = tuple4.GetValueOrDefault();
				obj4 = (valueOrDefault4.Item1, valueOrDefault4.Item2, valueOrDefault4.Item3, valueOrDefault4.Item4);
			}
			Trap = obj4;
			base..ctor();
		}

		private static T? Get<T>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T : MonoBehaviour
		{
			if (!prefabs.TryGetValue(typeof(T), out MonoBehaviour value))
			{
				return default(T);
			}
			return (T)(object)value;
		}

		private static (T1 F1, Optional<T2> F2)? Get<T1, T2>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T1 : MonoBehaviour where T2 : MonoBehaviour
		{
			if (!prefabs.TryGetValue(typeof(T1), out MonoBehaviour value))
			{
				return null;
			}
			MonoBehaviour value2;
			return ((T1)(object)value, new Optional<T2>(prefabs.TryGetValue(typeof(T2), out value2) ? ((T2)(object)value2) : default(T2)));
		}

		private static (T1 F1, Optional<T2> F2, Optional<T3> F3)? Get<T1, T2, T3>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T1 : MonoBehaviour where T2 : MonoBehaviour where T3 : MonoBehaviour
		{
			if (!prefabs.TryGetValue(typeof(T1), out MonoBehaviour value))
			{
				return null;
			}
			MonoBehaviour value2;
			MonoBehaviour value3;
			return ((T1)(object)value, new Optional<T2>(prefabs.TryGetValue(typeof(T2), out value2) ? ((T2)(object)value2) : default(T2)), new Optional<T3>(prefabs.TryGetValue(typeof(T3), out value3) ? ((T3)(object)value3) : default(T3)));
		}

		private static (T1 F1, Optional<T2> F2, Optional<T3> F3, Optional<T4> F4)? Get<T1, T2, T3, T4>(IReadOnlyDictionary<Type, MonoBehaviour> prefabs) where T1 : MonoBehaviour where T2 : MonoBehaviour where T3 : MonoBehaviour where T4 : MonoBehaviour
		{
			if (!prefabs.TryGetValue(typeof(T1), out MonoBehaviour value))
			{
				return null;
			}
			MonoBehaviour value2;
			MonoBehaviour value3;
			MonoBehaviour value4;
			return ((T1)(object)value, new Optional<T2>(prefabs.TryGetValue(typeof(T2), out value2) ? ((T2)(object)value2) : default(T2)), new Optional<T3>(prefabs.TryGetValue(typeof(T3), out value3) ? ((T3)(object)value3) : default(T3)), new Optional<T4>(prefabs.TryGetValue(typeof(T4), out value4) ? ((T4)(object)value4) : default(T4)));
		}
	}
	internal static class PrivateAccessor
	{
		private static Action<ItemData, ZDO>? __loadFromZDO;

		private static Func<ConsoleCommand, ConsoleEvent?>? __getCommandAction;

		private static Func<ConsoleCommand, ConsoleEventFailable?>? __getCommandActionFailable;

		private static Func<IReadOnlyList<KeyButton>>? __getServerOptionsGUIPresets;

		private static Func<IReadOnlyList<KeyUI>>? __getServerOptionsGUIModifiers;

		private static Func<ZDOMan, IReadOnlyDictionary<ZDOID, ZDO>>? __getZDOManObjectsByID;

		private static Func<Localization, IReadOnlyDictionary<string, string>>? __getLocalizationStrings;

		private static Action<ZDOMan>? __convertPortals;

		public static Action<ItemData, ZDO> LoadFromZDO
		{
			get
			{
				Action<ItemData, ZDO>? action = __loadFromZDO;
				if (action == null)
				{
					MethodInfo? method = typeof(ItemDrop).GetMethod("LoadFromZDO", BindingFlags.Static | BindingFlags.NonPublic);
					ParameterExpression parameterExpression = Expression.Parameter(typeof(ItemData));
					ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ZDO));
					action = (__loadFromZDO = Expression.Lambda<Action<ItemData, ZDO>>(Expression.Call(method, parameterExpression, parameterExpression2), new ParameterExpression[2] { parameterExpression, parameterExpression2 }).Compile());
				}
				return action;
			}
		}

		public static Func<IReadOnlyList<KeyButton>> GetServerOptionsGUIPresets => __getServerOptionsGUIPresets ?? (__getServerOptionsGUIPresets = Expression.Lambda<Func<IReadOnlyList<KeyButton>>>(Expression.Field(null, typeof(ServerOptionsGUI).GetField("m_presets", BindingFlags.Static | BindingFlags.NonPublic)), Array.Empty<ParameterExpression>()).Compile());

		public static Func<IReadOnlyList<KeyUI>> GetServerOptionsGUIModifiers => __getServerOptionsGUIModifiers ?? (__getServerOptionsGUIModifiers = Expression.Lambda<Func<IReadOnlyList<KeyUI>>>(Expression.Field(null, typeof(ServerOptionsGUI).GetField("m_modifiers", BindingFlags.Static | BindingFlags.NonPublic)), Array.Empty<ParameterExpression>()).Compile());

		public static ConsoleEvent? GetAction(this ConsoleCommand command)
		{
			Func<ConsoleCommand, ConsoleEvent?>? func = __getCommandAction;
			if (func == null)
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(ConsoleCommand));
				func = (__getCommandAction = Expression.Lambda<Func<ConsoleCommand, ConsoleEvent>>(Expression.Field(parameterExpression, typeof(ConsoleCommand).GetField("action", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile());
			}
			return func(command);
		}

		public static ConsoleEventFailable? GetActionFailable(this ConsoleCommand command)
		{
			Func<ConsoleCommand, ConsoleEventFailable?>? func = __getCommandActionFailable;
			if (func == null)
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(ConsoleCommand));
				func = (__getCommandActionFailable = Expression.Lambda<Func<ConsoleCommand, ConsoleEventFailable>>(Expression.Field(parameterExpression, typeof(ConsoleCommand).GetField("actionFailable", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile());
			}
			return func(command);
		}

		public static IReadOnlyDictionary<ZDOID, ZDO> GetObjectsByID(this ZDOMan instance)
		{
			Func<ZDOMan, IReadOnlyDictionary<ZDOID, ZDO>>? func = __getZDOManObjectsByID;
			if (func == null)
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(ZDOMan));
				func = (__getZDOManObjectsByID = Expression.Lambda<Func<ZDOMan, IReadOnlyDictionary<ZDOID, ZDO>>>(Expression.Field(parameterExpression, typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile());
			}
			return func(instance);
		}

		public static IReadOnlyDictionary<string, string> GetStrings(this Localization instance)
		{
			Func<Localization, IReadOnlyDictionary<string, string>>? func = __getLocalizationStrings;
			if (func == null)
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(Localization));
				func = (__getLocalizationStrings = Expression.Lambda<Func<Localization, IReadOnlyDictionary<string, string>>>(Expression.Field(parameterExpression, typeof(Localization).GetField("m_translations", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile());
			}
			return func(instance);
		}

		public static void ConvertPortals(this ZDOMan instance)
		{
			Action<ZDOMan>? action = __convertPortals;
			if (action == null)
			{
				ParameterExpression parameterExpression = Expression.Parameter(typeof(ZDOMan));
				action = (__convertPortals = Expression.Lambda<Action<ZDOMan>>(Expression.Call(parameterExpression, typeof(ZDOMan).GetMethod("ConvertPortals", BindingFlags.Instance | BindingFlags.NonPublic)), new ParameterExpression[1] { parameterExpression }).Compile());
			}
			action(instance);
		}
	}
	internal sealed record RuntimeInformation(string ModVersion, GameVersion GameVersion, uint NetworkVersion, int ItemDataVersion, int WorldVersion, string LoadedMods)
	{
		private sealed record Mod(string GUID, string Name, string? Version);

		public static RuntimeInformation Instance { get; } = Initialize();


		private static RuntimeInformation Initialize()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			Type type = typeof(Game).Assembly.GetType("Version", throwOnError: true);
			object obj = type.GetProperty("CurrentVersion")?.GetValue(null);
			GameVersion gameVersion = ((!(obj is GameVersion)) ? default(GameVersion) : ((GameVersion)obj));
			obj = type.GetField("m_networkVersion")?.GetValue(null);
			uint networkVersion = ((obj is uint) ? ((uint)obj) : 0u);
			obj = type.GetField("m_itemDataVersion")?.GetValue(null);
			int itemDataVersion = ((obj is int) ? ((int)obj) : 0);
			obj = type.GetField("m_worldVersion")?.GetValue(null);
			int worldVersion = ((obj is int) ? ((int)obj) : 0);
			IEnumerable<Mod> values = from x in Chainloader.PluginInfos.Values
				where x.Instance != Main.Instance
				select new Mod(x.Metadata.GUID, x.Metadata.Name, FormattableString.Invariant($"{x.Metadata.Version}"));
			string loadedMods = FormattableString.Invariant(FormattableStringFactory.Create("{{ {0} }}", string.Join(", ", values)));
			return new RuntimeInformation("0.2.13", gameVersion, networkVersion, itemDataVersion, worldVersion, loadedMods);
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("ModVersion = ");
			builder.Append((object?)ModVersion);
			builder.Append(", GameVersion = ");
			GameVersion gameVersion = GameVersion;
			builder.Append(((object)(GameVersion)(ref gameVersion)).ToString());
			builder.Append(", NetworkVersion = ");
			builder.Append(NetworkVersion.ToString());
			builder.Append(", ItemDataVersion = ");
			builder.Append(ItemDataVersion.ToString());
			builder.Append(", WorldVersion = ");
			builder.Append(WorldVersion.ToString());
			builder.Append(", LoadedMods = ");
			builder.Append((object?)LoadedMods);
			return true;
		}

		[CompilerGenerated]
		private RuntimeInformation(RuntimeInformation original)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			ModVersion = original.ModVersion;
			GameVersion = original.GameVersion;
			NetworkVersion = original.NetworkVersion;
			ItemDataVersion = original.ItemDataVersion;
			WorldVersion = original.WorldVersion;
			LoadedMods = original.LoadedMods;
		}
	}
}
namespace Valheim.ServersideQoL.Processors
{
	internal sealed class ContainerProcessor : Processor
	{
		private readonly Dictionary<ItemKey, int> _stackPerItem = new Dictionary<ItemKey, int>();

		public ContainerProcessor(ManualLogSource logger, ModConfig cfg)
			: base(logger, cfg)
		{
		}

		protected override bool ProcessCore(ExtendedZDO zdo, IEnumerable<ZNetPeer> peers)
		{
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			if (!zdo.PrefabInfo.Container.HasValue || zdo.Vars.GetCreator(0L) == 0L)
			{
				base.UnregisterZdoProcessor = true;
				return false;
			}
			ExtendedZDO.ComponentFieldAccessor<Container> componentFieldAccessor = zdo.Fields<Container>(getUnknownComponent: false);
			IZDOInventory inventory = zdo.Inventory;
			int width = inventory.Inventory.GetWidth();
			int height = inventory.Inventory.GetHeight();
			int result;
			int result2;
			int num2;
			int num3;
			int num4;
			if (base.Config.Containers.ContainerSizes.TryGetValue(((ZDO)zdo).GetPrefab(), out ConfigEntry<string> value))
			{
				string[] array = value.Value.Split(new char[1] { 'x' }, 2);
				if (array != null && array.Length == 2 && int.TryParse(array[0], out result) && int.TryParse(array[1], out result2))
				{
					int num = width;
					num2 = height;
					num3 = result;
					num4 = result2;
					if (num != num3 || num2 != num4)
					{
						IZDOInventory inventory2 = zdo.Inventory;
						if (inventory2 != null)
						{
							IList<ItemData> items = inventory2.Items;
							if (items != null && items.Count == 0)
							{
								componentFieldAccessor.Set((Expression<Func<Container, int>>)((Container x) => x.m_width), width = result);
								componentFieldAccessor.Set((Expression<Func<Container, int>>)((Container x) => x.m_height), height = result2);
								base.RecreateZdo = true;
								return false;
							}
						}
						goto IL_01d2;
					}
				}
			}
			result = width;
			result2 = height;
			goto IL_01d2;
			IL_0368:
			bool flag = false;
			ItemData val = null;
			_stackPerItem.Clear();
			foreach (ItemData item in from x in inventory.Items
				orderby (!x.IsEquipable()) ? 1 : 0, x.m_shared.m_name, x.m_stack descending
				select x)
			{
				if ((int)zdo.PrefabInfo.Container.Value.Container.m_privacy != 0)
				{
					ConcurrentHashSet<ExtendedZDO> orAdd = SharedProcessorState.ContainersByItemName.GetOrAdd(item.m_shared, (SharedItemDataKey _) => new ConcurrentHashSet<ExtendedZDO>());
					orAdd.Add(zdo);
				}
				if (!base.Config.Containers.AutoSort.Value && !base.RecreateZdo)
				{
					continue;
				}
				if (val != null && new ItemKey(item) == val)
				{
					int num5 = Math.Min(item.m_stack, val.m_shared.m_maxStackSize - val.m_stack);
					ItemData obj = val;
					obj.m_stack += num5;
					item.m_stack -= num5;
					flag = true;
				}
				if (item.m_stack != 0)
				{
					if (!_stackPerItem.TryGetValue(item, out var value2))
					{
						value2 = 0;
					}
					_stackPerItem[item] = value2 + 1;