Decompiled source of ServersideQoL v0.1.1

Valheim.ServersideQoL.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[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 ExtensionMethods
	{
		public static void Update(this Inventory inventory, ZDO zdo)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			string @string = zdo.GetString(ZDOVars.s_items, "");
			if (string.IsNullOrEmpty(@string))
			{
				inventory.GetAllItems().Clear();
			}
			else
			{
				inventory.Load(new ZPackage(@string));
			}
		}
	}
	[BepInPlugin("argusmagnus.TestMod", "TestMod", "0.1.1")]
	public sealed class Main : BaseUnityPlugin
	{
		private record PrefabInfo(GameObject Prefab, IReadOnlyDictionary<Type, Component> Components)
		{
			public Sign? Sign { get; } = Get<Sign>(Components);


			public MapTable? MapTable { get; } = Get<MapTable>(Components);


			public Tameable? Tameable { get; } = Get<Tameable>(Components);


			public Fireplace? Fireplace { get; } = Get<Fireplace>(Components);


			public Container? Container { get; } = Get<Container>(Components);


			public Ship? Ship { get; } = Get<Ship>(Components);


			public ItemDrop? ItemDrop { get; } = Get<ItemDrop>(Components);


			public Piece? Piece { get; } = Get<Piece>(Components);


			public Smelter? Smelter { get; } = Get<Smelter>(Components);


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

		private record struct ItemKey(string Name, int Quality, int Variant)
		{
			public ItemKey(string Name, int Quality, int Variant)
			{
				this.Name = Name;
				this.Quality = Quality;
				this.Variant = Variant;
			}

			public static implicit operator ItemKey(ItemData data)
			{
				return new ItemKey(data);
			}

			public ItemKey(ItemData data)
				: this(data.m_shared.m_name, data.m_quality, data.m_variant)
			{
			}
		}

		private record struct SharedItemDataKey(string Name)
		{
			public static implicit operator SharedItemDataKey(SharedData data)
			{
				return new SharedItemDataKey(data.m_name);
			}
		}

		private record SectorInfo(List<ZNetPeer> Peers, List<ZDO> ZDOs)
		{
			public int InverseWeight { get; set; }
		}

		private record Pin(long OwnerId, string Tag, Vector3 Pos, PinType Type, bool IsChecked, string Author)
		{
			[CompilerGenerated]
			protected virtual bool PrintMembers(StringBuilder builder)
			{
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				RuntimeHelpers.EnsureSufficientExecutionStack();
				builder.Append("OwnerId = ");
				builder.Append(OwnerId.ToString());
				builder.Append(", Tag = ");
				builder.Append((object?)Tag);
				builder.Append(", Pos = ");
				Vector3 pos = Pos;
				builder.Append(((object)(Vector3)(ref pos)).ToString());
				builder.Append(", Type = ");
				PinType type = Type;
				builder.Append(((object)(PinType)(ref type)).ToString());
				builder.Append(", IsChecked = ");
				builder.Append(IsChecked.ToString());
				builder.Append(", Author = ");
				builder.Append((object?)Author);
				return true;
			}

			[CompilerGenerated]
			public void Deconstruct(out long OwnerId, out string Tag, out Vector3 Pos, out PinType Type, out bool IsChecked, out string Author)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected I4, but got Unknown
				OwnerId = this.OwnerId;
				Tag = this.Tag;
				Pos = this.Pos;
				Type = (PinType)(int)this.Type;
				IsChecked = this.IsChecked;
				Author = this.Author;
			}
		}

		private static class ZDOVarsEx
		{
			private static class _HasFields<T> where T : MonoBehaviour
			{
				public static int HasFields { get; } = StringExtensionMethods.GetStableHashCode("HasFields" + typeof(T).Name);

			}

			public static int HasFields { get; } = StringExtensionMethods.GetStableHashCode("HasFields");


			public static int TameableCommandable { get; } = StringExtensionMethods.GetStableHashCode("Tameable.m_commandable");


			public static int FireplaceInfiniteFuel { get; } = StringExtensionMethods.GetStableHashCode("Fireplace.m_infiniteFuel");


			public static int FireplaceCanTurnOff { get; } = StringExtensionMethods.GetStableHashCode("Fireplace.m_canTurnOff");


			public static int FireplaceCanRefill { get; } = StringExtensionMethods.GetStableHashCode("Fireplace.m_canRefill");


			public static int FireplaceFuelPerSec { get; } = StringExtensionMethods.GetStableHashCode("Fireplace.m_secPerFuel");


			public static int ContainerWidth { get; } = StringExtensionMethods.GetStableHashCode("Container.m_width");


			public static int ContainerHeight { get; } = StringExtensionMethods.GetStableHashCode("Container.m_height");


			public static int SmelterMaxFuel { get; } = StringExtensionMethods.GetStableHashCode("Smelter.m_maxFuel");


			public static int SmelterMaxOre { get; } = StringExtensionMethods.GetStableHashCode("Smelter.m_maxOre");


			public static int GetHasFields<T>() where T : MonoBehaviour
			{
				return _HasFields<T>.HasFields;
			}
		}

		[CompilerGenerated]
		private sealed class <<Start>g__CallExecute|33_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|33_0>d(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Expected O, but got Unknown
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (YieldInstruction)new WaitForSeconds(<>4__this._cfg.General.StartDelay.Value);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				<>4__this.Execute();
				<>2__current = (YieldInstruction)new WaitForSeconds(1f / <>4__this._cfg.General.Frequency.Value);
				<>1__state = 2;
				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();
			}
		}

		private const string PluginGuid = "argusmagnus.TestMod";

		private const string PluginName = "TestMod";

		private const string PluginVersion = "0.1.1";

		private readonly ModConfig _cfg;

		private readonly Regex _clockRegex = new Regex("(?:" + string.Join("|", ClockEmojis.Select(Regex.Escape)) + ")(?:\\s*\\d\\d\\:\\d\\d)?");

		private readonly IReadOnlyDictionary<int, PrefabInfo> _prefabInfo = new Dictionary<int, PrefabInfo>();

		private readonly ConcurrentHashSet<ZDOID> _ships = new ConcurrentHashSet<ZDOID>();

		private readonly ConcurrentDictionary<ZDOID, uint> _dataRevisions = new ConcurrentDictionary<ZDOID, uint>();

		private readonly ConcurrentDictionary<SharedItemDataKey, ConcurrentDictionary<ZDOID, Inventory>> _containersByItemName = new ConcurrentDictionary<SharedItemDataKey, ConcurrentDictionary<ZDOID, Inventory>>();

		private ulong _executeCounter;

		private uint _unfinishedProcessingInRow;

		private bool _resetPrefabInfo;

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

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

		private readonly List<Pin> _pins = new List<Pin>();

		private int _pinsHash;

		private Regex? _includePortalRegex;

		private Regex? _excludePortalRegex;

		private static int PluginGuidHash { get; } = StringExtensionMethods.GetStableHashCode("argusmagnus.TestMod");


		private static ManualLogSource Logger { get; } = Logger.CreateLogSource("TestMod");


		internal static IReadOnlyList<string> ClockEmojis { get; } = new <>z__ReadOnlyArray<string>(new string[24]
		{
			"\ud83d\udd5b", "\ud83d\udd67", "\ud83d\udd50", "\ud83d\udd5c", "\ud83d\udd51", "\ud83d\udd5d", "\ud83d\udd52", "\ud83d\udd5e", "\ud83d\udd53", "\ud83d\udd5f",
			"\ud83d\udd54", "\ud83d\udd60", "\ud83d\udd55", "\ud83d\udd61", "\ud83d\udd56", "\ud83d\udd62", "\ud83d\udd57", "\ud83d\udd63", "\ud83d\udd58", "\ud83d\udd64",
			"\ud83d\udd59", "\ud83d\udd65", "\ud83d\udd5a", "\ud83d\udd66"
		});


		public Main()
		{
			_cfg = new ModConfig(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				_resetPrefabInfo = true;
			};
		}

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

		private void Execute()
		{
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_0755: Unknown result type (might be due to invalid IL or missing references)
			//IL_075a: Unknown result type (might be due to invalid IL or missing references)
			//IL_075f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0761: Unknown result type (might be due to invalid IL or missing references)
			//IL_089f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Unknown result type (might be due to invalid IL or missing references)
			//IL_086b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_0698: Unknown result type (might be due to invalid IL or missing references)
			//IL_080a: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0916: Unknown result type (might be due to invalid IL or missing references)
			//IL_091b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0920: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0857: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a85: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_095e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0963: Unknown result type (might be due to invalid IL or missing references)
			//IL_096d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0974: Unknown result type (might be due to invalid IL or missing references)
			//IL_097e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0985: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aea: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_11af: Unknown result type (might be due to invalid IL or missing references)
			//IL_1236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e71: Unknown result type (might be due to invalid IL or missing references)
			//IL_1208: Unknown result type (might be due to invalid IL or missing references)
			//IL_1274: Unknown result type (might be due to invalid IL or missing references)
			//IL_100b: Unknown result type (might be due to invalid IL or missing references)
			//IL_1012: Expected O, but got Unknown
			//IL_0ecf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ed6: Expected O, but got Unknown
			//IL_132c: Unknown result type (might be due to invalid IL or missing references)
			//IL_12ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fae: Unknown result type (might be due to invalid IL or missing references)
			//IL_13a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_10c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_10d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_10df: Expected I4, but got Unknown
			//IL_1445: Unknown result type (might be due to invalid IL or missing references)
			//IL_144c: Expected O, but got Unknown
			//IL_1450: Unknown result type (might be due to invalid IL or missing references)
			//IL_145a: Expected O, but got Unknown
			//IL_1138: Unknown result type (might be due to invalid IL or missing references)
			//IL_1757: Unknown result type (might be due to invalid IL or missing references)
			//IL_175c: Unknown result type (might be due to invalid IL or missing references)
			//IL_176b: Unknown result type (might be due to invalid IL or missing references)
			//IL_179a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1785: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d39: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d3e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d4d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d7c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d67: Unknown result type (might be due to invalid IL or missing references)
			//IL_17c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_17ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_152a: Unknown result type (might be due to invalid IL or missing references)
			//IL_15ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_15f6: Expected O, but got Unknown
			//IL_1620: Unknown result type (might be due to invalid IL or missing references)
			//IL_1da5: Unknown result type (might be due to invalid IL or missing references)
			//IL_1dac: Unknown result type (might be due to invalid IL or missing references)
			//IL_22c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_22cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_22e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_232f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2316: Unknown result type (might be due to invalid IL or missing references)
			//IL_184b: Unknown result type (might be due to invalid IL or missing references)
			//IL_1850: Unknown result type (might be due to invalid IL or missing references)
			//IL_185a: Expected O, but got Unknown
			//IL_2370: Unknown result type (might be due to invalid IL or missing references)
			//IL_237b: Unknown result type (might be due to invalid IL or missing references)
			//IL_18a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_1955: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f48: Unknown result type (might be due to invalid IL or missing references)
			//IL_1adb: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ae2: Expected O, but got Unknown
			//IL_1b08: Unknown result type (might be due to invalid IL or missing references)
			//IL_2081: Unknown result type (might be due to invalid IL or missing references)
			//IL_2088: Expected O, but got Unknown
			//IL_20ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_25f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_1a0e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2834: Unknown result type (might be due to invalid IL or missing references)
			//IL_283d: Expected O, but got Unknown
			//IL_2879: Unknown result type (might be due to invalid IL or missing references)
			//IL_202d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2746: Unknown result type (might be due to invalid IL or missing references)
			if (ZNet.instance == null)
			{
				return;
			}
			if (!ZNet.instance.IsServer())
			{
				Logger.LogWarning((object)"Mod should only be installed on the host");
				throw new OperationCanceledException();
			}
			if (ZNetScene.instance == null || ZDOMan.instance == null)
			{
				return;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			if (_executeCounter++ == 0L || _resetPrefabInfo)
			{
				_resetPrefabInfo = false;
				IDictionary<int, PrefabInfo> dictionary = (IDictionary<int, PrefabInfo>)_prefabInfo;
				dictionary.Clear();
				_ships.Clear();
				string text = _cfg.MapTables.AutoUpdatePortalsInclude.Value.Trim();
				_includePortalRegex = (string.IsNullOrEmpty(text) ? null : new Regex(ConvertToRegexPattern(text)));
				text = _cfg.MapTables.AutoUpdatePortalsExclude.Value.Trim();
				_excludePortalRegex = (string.IsNullOrEmpty(text) ? null : new Regex(ConvertToRegexPattern(text)));
				List<HashSet<Type>> list = new List<HashSet<Type>>();
				foreach (PropertyInfo item9 in from x in _cfg.GetType().GetProperties()
					where x.PropertyType.IsClass
					select x)
				{
					object obj = null;
					IEnumerable<RequiredPrefabsAttribute> enumerable = null;
					PropertyInfo[] properties = item9.PropertyType.GetProperties();
					foreach (PropertyInfo propertyInfo in properties)
					{
						IEnumerable<RequiredPrefabsAttribute> customAttributes = propertyInfo.GetCustomAttributes<RequiredPrefabsAttribute>();
						if (propertyInfo.PropertyType != typeof(ConfigEntry<bool>))
						{
							if (customAttributes.Any())
							{
								throw new Exception("RequiredPrefabsAttribute only supported on classes and properties of type ConfigEntry");
							}
							continue;
						}
						if (obj == null)
						{
							obj = item9.GetValue(_cfg);
						}
						if (!((ConfigEntry<bool>)propertyInfo.GetValue(obj)).Value)
						{
							continue;
						}
						if (enumerable == null)
						{
							enumerable = item9.PropertyType.GetCustomAttributes<RequiredPrefabsAttribute>();
						}
						foreach (RequiredPrefabsAttribute item10 in customAttributes)
						{
							HashSet<Type> types = item10.Prefabs.ToHashSet();
							if (!list.Any((HashSet<Type> x) => x.SequenceEqual(types)))
							{
								list.Add(types);
							}
						}
					}
					foreach (RequiredPrefabsAttribute item11 in enumerable ?? Array.Empty<RequiredPrefabsAttribute>())
					{
						HashSet<Type> classTypes = item11.Prefabs.ToHashSet();
						if (classTypes != null && !list.Any((HashSet<Type> x) => x.SequenceEqual(classTypes)))
						{
							list.Add(classTypes);
						}
					}
				}
				if (list == null || list.Count <= 0)
				{
					return;
				}
				bool flag = false;
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					Dictionary<Type, Component> dictionary2 = null;
					foreach (HashSet<Type> item12 in list)
					{
						List<(Type, Component)> list2 = (from x in item12
							select (x, prefab.GetComponent(x)) into x
							where x.Component != null
							select x).ToList();
						if (list2.Count != item12.Count)
						{
							continue;
						}
						foreach (var (key, value) in list2)
						{
							if (dictionary2 == null)
							{
								dictionary2 = new Dictionary<Type, Component>();
							}
							if (!dictionary2.ContainsKey(key))
							{
								dictionary2.Add(key, value);
							}
						}
					}
					if (dictionary2 != null)
					{
						PrefabInfo prefabInfo = new PrefabInfo(prefab, dictionary2);
						dictionary.Add(StringExtensionMethods.GetStableHashCode(((Object)prefab).name), prefabInfo);
						flag = flag || prefabInfo.Ship != null;
					}
				}
				if (!flag)
				{
					return;
				}
				{
					PrefabInfo value18;
					foreach (ZDO item13 in ((IReadOnlyDictionary<ZDOID, ZDO>)typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(ZDOMan.instance)).Values.Where((ZDO x) => _prefabInfo.TryGetValue(x.GetPrefab(), out value18) && value18.Ship != null))
					{
						_ships.Add(item13.m_uid);
					}
					return;
				}
			}
			Inventory value3;
			if (_executeCounter % (ulong)(60f * _cfg.General.Frequency.Value) == 0)
			{
				foreach (ZDOID key3 in _dataRevisions.Keys)
				{
					if (ZDOMan.instance.GetZDO(key3) == null)
					{
						_dataRevisions.TryRemove(key3, out var _);
					}
				}
				foreach (ConcurrentDictionary<ZDOID, Inventory> value19 in _containersByItemName.Values)
				{
					foreach (ZDOID key4 in value19.Keys)
					{
						if (ZDOMan.instance.GetZDO(key4) == null)
						{
							value19.TryRemove(key4, out value3);
						}
					}
				}
			}
			List<ZNetPeer> peers = ZNet.instance.GetPeers();
			if (peers == null || peers.Count <= 0)
			{
				return;
			}
			ConcurrentDictionary<Vector2i, SectorInfo> playerSectorsOld = _playerSectorsOld;
			ConcurrentDictionary<Vector2i, SectorInfo> playerSectors = _playerSectors;
			_playerSectors = playerSectorsOld;
			_playerSectorsOld = playerSectors;
			_playerSectors.Clear();
			Vector2i key2 = default(Vector2i);
			foreach (ZNetPeer item14 in peers)
			{
				Vector2i zone = ZoneSystem.GetZone(item14.m_refPos);
				for (int j = zone.x - _cfg.General.ZonesAroundPlayers.Value; j <= zone.x + _cfg.General.ZonesAroundPlayers.Value; j++)
				{
					for (int k = zone.y - _cfg.General.ZonesAroundPlayers.Value; k <= zone.y + _cfg.General.ZonesAroundPlayers.Value; k++)
					{
						((Vector2i)(ref key2))..ctor(j, k);
						if (_playerSectorsOld.TryRemove(key2, out SectorInfo value4))
						{
							_playerSectors.TryAdd(key2, value4);
							value4.InverseWeight = 0;
							value4.Peers.Clear();
							value4.Peers.Add(item14);
						}
						else if (_playerSectors.TryGetValue(key2, out value4))
						{
							value4.InverseWeight = 0;
							value4.Peers.Add(item14);
						}
						else
						{
							value4 = new SectorInfo(new List<ZNetPeer>(1) { item14 }, new List<ZDO>());
							_playerSectors.TryAdd(key2, value4);
						}
					}
				}
			}
			if (_unfinishedProcessingInRow > 10)
			{
				foreach (ZNetPeer item15 in peers)
				{
					Vector2i zone2 = ZoneSystem.GetZone(item15.m_refPos);
					foreach (var item16 in _playerSectors.Select<KeyValuePair<Vector2i, SectorInfo>, (Vector2i, SectorInfo)>((KeyValuePair<Vector2i, SectorInfo> x) => (x.Key, x.Value)))
					{
						Vector2i item = item16.Item1;
						SectorInfo item2 = item16.Item2;
						int num = item.x - zone2.x;
						int num2 = item.y - zone2.y;
						item2.InverseWeight += num * num + num2 * num2;
					}
				}
			}
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			string timeText = null;
			List<Pin> list3 = null;
			byte[] array = null;
			_pins.Clear();
			int num6 = 0;
			IEnumerable<KeyValuePair<Vector2i, SectorInfo>> source = _playerSectors.AsEnumerable();
			if (_unfinishedProcessingInRow > 10)
			{
				source = source.OrderBy((KeyValuePair<Vector2i, SectorInfo> x) => x.Value.InverseWeight);
			}
			foreach (var (val, sectorInfo) in source.Select((KeyValuePair<Vector2i, SectorInfo> x) => (x.Key, x.Value)))
			{
				if (stopwatch.ElapsedMilliseconds > _cfg.General.MaxProcessingTime.Value)
				{
					break;
				}
				num3++;
				if ((object)sectorInfo != null)
				{
					List<ZDO> zDOs = sectorInfo.ZDOs;
					if (zDOs != null && zDOs.Count == 0)
					{
						ZDOMan.instance.FindSectorObjects(val, 1, 0, sectorInfo.ZDOs, (List<ZDO>)null);
					}
				}
				num5 += sectorInfo.ZDOs.Count;
				while ((object)sectorInfo != null)
				{
					List<ZDO> zDOs = sectorInfo.ZDOs;
					if (zDOs == null || zDOs.Count <= 0 || stopwatch.ElapsedMilliseconds >= _cfg.General.MaxProcessingTime.Value)
					{
						break;
					}
					num4++;
					ZDO val2 = sectorInfo.ZDOs[sectorInfo.ZDOs.Count - 1];
					sectorInfo.ZDOs.RemoveAt(sectorInfo.ZDOs.Count - 1);
					if (!val2.IsValid() || !_prefabInfo.TryGetValue(val2.GetPrefab(), out PrefabInfo value5))
					{
						continue;
					}
					if (!_cfg.Signs.TimeSigns.Value || value5.Sign != null)
					{
						string @string = val2.GetString(ZDOVars.s_text, "");
						string text2 = _clockRegex.Replace(@string, delegate
						{
							if (timeText == null)
							{
								float dayFraction = EnvMan.instance.GetDayFraction();
								int index = (int)Math.Floor((float)(ClockEmojis.Count * 2) * dayFraction) % ClockEmojis.Count;
								TimeSpan timeSpan = TimeSpan.FromDays(dayFraction);
								timeText = $"{ClockEmojis[index]} {timeSpan:hh\\:mm}";
							}
							return timeText;
						});
						if (@string != text2)
						{
							Logger.LogDebug((object)("Changing sign text from '" + @string + "' to '" + text2 + "'"));
							val2.Set(ZDOVars.s_text, text2);
						}
					}
					if (value5.MapTable != null && (_cfg.MapTables.AutoUpdatePortals.Value || _cfg.MapTables.AutoUpdateShips.Value))
					{
						List<Pin> pins = _pins;
						if (pins != null && pins.Count == 0)
						{
							IEnumerable<Pin> enumerable2 = Enumerable.Empty<Pin>();
							if (_cfg.MapTables.AutoUpdatePortals.Value)
							{
								enumerable2 = enumerable2.Concat(from x in ZDOMan.instance.GetPortals()
									select new Pin(PluginGuidHash, x.GetString(ZDOVars.s_tag, ""), x.GetPosition(), (PinType)6, IsChecked: false, "argusmagnus.TestMod"));
								if ((_includePortalRegex ?? _excludePortalRegex) != null)
								{
									enumerable2 = enumerable2.Where((Pin x) => (_includePortalRegex?.IsMatch(x.Tag) ?? true) && !(_excludePortalRegex?.IsMatch(x.Tag) ?? false));
								}
							}
							if (_cfg.MapTables.AutoUpdateShips.Value)
							{
								enumerable2 = enumerable2.Concat(from x in _ships.Select(delegate(ZDOID x)
									{
										//IL_0006: Unknown result type (might be due to invalid IL or missing references)
										//IL_0020: Unknown result type (might be due to invalid IL or missing references)
										ZDO zDO4 = ZDOMan.instance.GetZDO(x);
										if (zDO4 == null)
										{
											_ships.Remove(x);
										}
										return zDO4;
									})
									where x != null
									select new Pin(PluginGuidHash, (!_prefabInfo.TryGetValue(x.GetPrefab(), out PrefabInfo value17)) ? "" : (value17.Piece?.m_name ?? ""), x.GetPosition(), (PinType)10, IsChecked: false, "argusmagnus.TestMod"));
							}
							foreach (Pin item17 in enumerable2)
							{
								_pins.Add(item17);
								num6 = (num6, item17).GetHashCode();
							}
							int pinsHash = num6;
							int pinsHash2 = _pinsHash;
							_pinsHash = pinsHash;
							num6 = pinsHash2;
						}
						if (_pinsHash == num6 && _dataRevisions.TryGetValue(val2.m_uid, out var value6) && value6 == val2.DataRevision)
						{
							continue;
						}
						list3?.Clear();
						byte[] array2 = val2.GetByteArray(ZDOVars.s_data, (byte[])null);
						ZPackage val3;
						if (array2 != null)
						{
							array2 = Utils.Decompress(array2);
							val3 = new ZPackage(array2);
							int num7 = val3.ReadInt();
							if (num7 != 3)
							{
								Logger.LogWarning((object)$"MapTable data version {num7} is not supported");
								continue;
							}
							array2 = val3.ReadByteArray();
							if (array2.Length != Minimap.instance.m_textureSize * Minimap.instance.m_textureSize)
							{
								Logger.LogWarning((object)"Invalid explored map data length");
								array2 = null;
							}
							int num8 = val3.ReadInt();
							if (list3 == null)
							{
								list3 = new List<Pin>(num8);
							}
							if (list3.Capacity < num8)
							{
								list3.Capacity = num8;
							}
							foreach (int item18 in Enumerable.Range(0, num8))
							{
								Pin pin = new Pin(val3.ReadLong(), val3.ReadString(), val3.ReadVector3(), (PinType)val3.ReadInt(), val3.ReadBool(), val3.ReadString());
								if (pin.OwnerId != PluginGuidHash)
								{
									list3.Add(pin);
								}
							}
						}
						val3 = new ZPackage();
						val3.Write(3);
						val3.Write(array2 ?? array ?? (array = new byte[Minimap.instance.m_textureSize * Minimap.instance.m_textureSize]));
						val3.Write(_pins.Count + (list3?.Count ?? 0));
						foreach (Pin item19 in _pins.Concat(list3?.AsEnumerable() ?? Array.Empty<Pin>()))
						{
							val3.Write(item19.OwnerId);
							val3.Write(item19.Tag);
							val3.Write(item19.Pos);
							val3.Write((int)item19.Type);
							val3.Write(item19.IsChecked);
							val3.Write(item19.Author);
						}
						val2.Set(ZDOVars.s_data, Utils.Compress(val3.GetArray()));
						_dataRevisions[val2.m_uid] = val2.DataRevision;
						ShowMessage(sectorInfo.Peers, (MessageType)1, "$msg_mapsaved");
						continue;
					}
					if (value5.Tameable != null && _cfg.Tames.MakeCommandable.Value && !value5.Tameable.m_commandable && val2.GetBool(ZDOVars.s_tamed, false))
					{
						if (_dataRevisions.TryGetValue(val2.m_uid, out var value7) && value7 == val2.DataRevision)
						{
							continue;
						}
						val2.Set(ZDOVarsEx.HasFields, true);
						val2.Set(ZDOVarsEx.GetHasFields<Tameable>(), true);
						val2.Set(ZDOVarsEx.TameableCommandable, true);
						_dataRevisions[val2.m_uid] = val2.DataRevision;
					}
					if (value5.Ship != null)
					{
						_ships.Add(val2.m_uid);
					}
					if (value5.Fireplace != null && _cfg.Fireplaces.MakeToggleable.Value)
					{
						if (_dataRevisions.TryGetValue(val2.m_uid, out var value8) && value8 == val2.DataRevision)
						{
							continue;
						}
						val2.Set(ZDOVarsEx.HasFields, true);
						val2.Set(ZDOVarsEx.GetHasFields<Fireplace>(), true);
						val2.Set(ZDOVarsEx.FireplaceFuelPerSec, 0f);
						val2.Set(ZDOVarsEx.FireplaceCanTurnOff, true);
						val2.Set(ZDOVarsEx.FireplaceCanRefill, false);
						_dataRevisions[val2.m_uid] = val2.DataRevision;
					}
					if ((object)value5 != null && value5.Container != null && value5.Piece != null)
					{
						if ((_dataRevisions.TryGetValue(val2.m_uid, out var value9) && val2.DataRevision == value9) || val2.GetLong(ZDOVars.s_creator, 0L) == 0 || val2.GetBool(ZDOVars.s_inUse, false) || !CheckMinDistance(peers, val2))
						{
							continue;
						}
						_dataRevisions[val2.m_uid] = val2.DataRevision;
						string string2 = val2.GetString(ZDOVars.s_items, "");
						if (string.IsNullOrEmpty(string2))
						{
							continue;
						}
						int num9 = value5.Container.m_width;
						int num10 = value5.Container.m_height;
						if (val2.GetBool(ZDOVarsEx.GetHasFields<Container>(), false))
						{
							num9 = val2.GetInt(ZDOVarsEx.ContainerWidth, num9);
							num10 = val2.GetInt(ZDOVarsEx.ContainerHeight, num10);
						}
						Inventory val4 = new Inventory(value5.Container.m_name, value5.Container.m_bkg, num9, num10);
						val4.Load(new ZPackage(string2));
						bool flag2 = false;
						int num11 = 0;
						int num12 = 0;
						foreach (ItemData item20 in from x in val4.GetAllItems()
							orderby (!x.IsEquipable()) ? 1 : 0, x.m_shared.m_name, x.m_stack descending
							select x)
						{
							ConcurrentDictionary<ZDOID, Inventory> orAdd = _containersByItemName.GetOrAdd(item20.m_shared, (SharedItemDataKey _) => new ConcurrentDictionary<ZDOID, Inventory>());
							orAdd[val2.m_uid] = val4;
							if (_cfg.Containers.AutoSort.Value)
							{
								if (item20.m_gridPos.x != num11 || item20.m_gridPos.y != num12)
								{
									item20.m_gridPos.x = num11;
									item20.m_gridPos.y = num12;
									flag2 = true;
								}
								if (++num11 >= num9)
								{
									num11 = 0;
									num12++;
								}
							}
						}
						if (!flag2)
						{
							continue;
						}
						ZPackage val5 = new ZPackage();
						val4.Save(val5);
						string2 = val5.GetBase64();
						val2.Set(ZDOVars.s_items, string2);
						_dataRevisions[val2.m_uid] = val2.DataRevision;
						ShowMessage(sectorInfo.Peers, (MessageType)1, value5.Piece.m_name + " sorted");
					}
					ConcurrentDictionary<ZDOID, Inventory> value12;
					if (value5.ItemDrop != null && _cfg.Containers.AutoPickup.Value)
					{
						if ((value5.Piece != null && val2.GetBool(ZDOVars.s_piece, false)) || !CheckMinDistance(peers, val2, _cfg.Containers.AutoPickupMinPlayerDistance.Value))
						{
							continue;
						}
						SharedData shared = ZNetScene.instance.GetPrefab(val2.GetPrefab()).GetComponent<ItemDrop>().m_itemData.m_shared;
						if (!_containersByItemName.TryGetValue(shared, out ConcurrentDictionary<ZDOID, Inventory> value10))
						{
							continue;
						}
						HashSet<Vector2i> hashSet = null;
						ItemData val6 = null;
						foreach (var item21 in value10.Select((KeyValuePair<ZDOID, Inventory> x) => (x.Key, x.Value)))
						{
							ZDOID item3 = item21.Item1;
							Inventory item4 = item21.Item2;
							ZDO zDO = ZDOMan.instance.GetZDO(item3);
							if (zDO == null)
							{
								value10.TryRemove(item3, out value3);
							}
							else
							{
								if (!_dataRevisions.TryGetValue(item3, out var value11) || zDO.DataRevision != value11 || Utils.DistanceSqr(val2.GetPosition(), zDO.GetPosition()) > _cfg.Containers.AutoPickupRange.Value * _cfg.Containers.AutoPickupRange.Value || zDO.GetBool(ZDOVars.s_inUse, false) || !CheckMinDistance(peers, zDO))
								{
									continue;
								}
								item4.Update(zDO);
								if (val6 == null)
								{
									val6 = new ItemData
									{
										m_shared = shared
									};
									PrivateAccessor.LoadFromZDO(val6, val2);
								}
								int num13 = val6.m_stack;
								if (hashSet == null)
								{
									hashSet = new HashSet<Vector2i>();
								}
								hashSet.Clear();
								ItemData val7 = null;
								foreach (ItemData allItem in item4.GetAllItems())
								{
									hashSet.Add(allItem.m_gridPos);
									if (new ItemKey(val6) != allItem)
									{
										continue;
									}
									if (val7 == null)
									{
										val7 = allItem;
									}
									int num14 = allItem.m_shared.m_maxStackSize - allItem.m_stack;
									if (num14 > 0)
									{
										int num15 = Math.Min(num13, num14);
										allItem.m_stack += num15;
										num13 -= num15;
										if (num13 == 0)
										{
											break;
										}
									}
								}
								if (val7 == null)
								{
									value10.TryRemove(item3, out value3);
									if (value10 != null && value10.Count == 0)
									{
										_containersByItemName.TryRemove(val6.m_shared, out value12);
									}
									continue;
								}
								if (item4.GetAllItems() != item4.GetAllItems())
								{
									throw new Exception("Algorithm assumption violated");
								}
								int num16 = item4.GetEmptySlots();
								while (num13 > 0 && num16 > 0)
								{
									int num17 = Math.Min(num13, val6.m_shared.m_maxStackSize);
									ItemData val8 = val7.Clone();
									val8.m_stack = num17;
									val8.m_gridPos.x = -1;
									for (int l = 0; l < item4.GetWidth(); l++)
									{
										if (val8.m_gridPos.x >= 0)
										{
											break;
										}
										for (int m = 0; m < item4.GetHeight(); m++)
										{
											if (hashSet.Add(new Vector2i(l, m)))
											{
												ref int x2 = ref val8.m_gridPos.x;
												ref int y = ref val8.m_gridPos.y;
												int pinsHash = l;
												int num18 = m;
												x2 = pinsHash;
												y = num18;
												break;
											}
										}
									}
									item4.GetAllItems().Add(val8);
									num13 -= num17;
									num16--;
								}
								if (num13 != val6.m_stack)
								{
									ZPackage val9 = new ZPackage();
									item4.Save(val9);
									zDO.Set(ZDOVars.s_items, val9.GetBase64());
									_dataRevisions[zDO.m_uid] = zDO.DataRevision;
									val6.m_stack = num13;
									val2.SetOwner(ZDOMan.GetSessionID());
									ItemDrop.SaveToZDO(val6, val2);
									ShowMessage(sectorInfo.Peers, (MessageType)1, "Dropped " + val6.m_shared.m_name + " moved to " + _prefabInfo[zDO.GetPrefab()].Piece.m_name);
								}
								if (val6.m_stack == 0)
								{
									break;
								}
							}
						}
						int? num19 = val6?.m_stack;
						if (num19.HasValue && num19.GetValueOrDefault() == 0)
						{
							val2.SetOwner(ZDOMan.GetSessionID());
							ZDOMan.instance.DestroyZDO(val2);
						}
					}
					if (!_cfg.Smelters.FeedFromContainers.Value || value5.Smelter == null || !CheckMinDistance(peers, val2))
					{
						continue;
					}
					bool @bool = val2.GetBool(ZDOVarsEx.GetHasFields<Smelter>(), false);
					int num20 = value5.Smelter.m_maxFuel;
					if (@bool)
					{
						num20 = val2.GetInt(ZDOVarsEx.SmelterMaxFuel, num20);
					}
					float @float = val2.GetFloat(ZDOVars.s_fuel, 0f);
					int num21 = (int)((float)num20 - @float);
					if (num21 > num20 / 2)
					{
						ItemData fuelItem = value5.Smelter.m_fuelItem.m_itemData;
						int num22 = 0;
						if (_containersByItemName.TryGetValue(fuelItem.m_shared, out ConcurrentDictionary<ZDOID, Inventory> value13))
						{
							List<ItemData> list4 = null;
							foreach (var item22 in value13.Select((KeyValuePair<ZDOID, Inventory> x) => (x.Key, x.Value)))
							{
								ZDOID item5 = item22.Item1;
								Inventory item6 = item22.Item2;
								ZDO zDO2 = ZDOMan.instance.GetZDO(item5);
								if (zDO2 == null)
								{
									value13.TryRemove(item5, out value3);
								}
								else
								{
									if (!_dataRevisions.TryGetValue(item5, out var value14) || zDO2.DataRevision != value14 || Utils.DistanceXZ(val2.GetPosition(), zDO2.GetPosition()) > 4f || zDO2.GetBool(ZDOVars.s_inUse, false) || !CheckMinDistance(peers, zDO2))
									{
										continue;
									}
									item6.Update(zDO2);
									list4?.Clear();
									float num23 = 0f;
									int num24 = _cfg.Smelters.FeedFromContainersLeaveAtLeastFuel.Value;
									foreach (ItemData item23 in from x in item6.GetAllItems()
										where new ItemKey(x) == fuelItem
										orderby x.m_stack
										select x)
									{
										int num25 = Math.Min(num21, item23.m_stack);
										int num26 = Math.Min(num25, num24);
										num24 -= num26;
										num25 -= num26;
										if (num25 != 0)
										{
											num23 += (float)num25;
											item23.m_stack -= num25;
											if (item23.m_stack == 0)
											{
												(list4 ?? (list4 = new List<ItemData>())).Add(item23);
											}
											num21 -= num25;
											if (num21 == 0)
											{
												break;
											}
										}
									}
									if (num23 == 0f)
									{
										value13.TryRemove(item5, out value3);
										if (value13 != null && value13.Count == 0)
										{
											_containersByItemName.TryRemove(fuelItem.m_shared, out value12);
										}
										continue;
									}
									if (list4 != null && list4.Count > 0)
									{
										if (item6.GetAllItems() != item6.GetAllItems())
										{
											throw new Exception("Algorithm assumption violated");
										}
										foreach (ItemData item24 in list4)
										{
											item6.GetAllItems().Remove(item24);
										}
										List<ItemData> allItems = item6.GetAllItems();
										if (allItems != null && allItems.Count == 0)
										{
											value13.TryRemove(item5, out value3);
											if (value13 != null && value13.Count == 0)
											{
												_containersByItemName.TryRemove(fuelItem.m_shared, out value12);
											}
										}
									}
									val2.Set(ZDOVars.s_fuel, @float + num23);
									ZPackage val10 = new ZPackage();
									item6.Save(val10);
									zDO2.Set(ZDOVars.s_items, val10.GetBase64());
									_dataRevisions[zDO2.m_uid] = zDO2.DataRevision;
									num22 += (int)num23;
									if (num21 == 0)
									{
										break;
									}
								}
							}
						}
						if (num22 != 0)
						{
							ShowMessage(peers, (MessageType)1, $"{value5.Piece?.m_name ?? value5.Smelter.m_name} $msg_added {num22} {fuelItem.m_shared.m_name}");
						}
					}
					int num27 = value5.Smelter.m_maxOre;
					if (@bool)
					{
						num27 = val2.GetInt(ZDOVarsEx.SmelterMaxOre, num27);
					}
					int @int = val2.GetInt(ZDOVars.s_queued, 0);
					int num28 = num27 - val2.GetInt(ZDOVars.s_queued, 0);
					if (num28 <= num27 / 2)
					{
						continue;
					}
					foreach (ItemConversion item25 in value5.Smelter.m_conversion)
					{
						ItemData oreItem = item25.m_from.m_itemData;
						int num29 = 0;
						if (_containersByItemName.TryGetValue(oreItem.m_shared, out ConcurrentDictionary<ZDOID, Inventory> value15))
						{
							List<ItemData> list5 = null;
							foreach (var item26 in value15.Select((KeyValuePair<ZDOID, Inventory> x) => (x.Key, x.Value)))
							{
								ZDOID item7 = item26.Item1;
								Inventory item8 = item26.Item2;
								ZDO zDO3 = ZDOMan.instance.GetZDO(item7);
								if (zDO3 == null)
								{
									value15.TryRemove(item7, out value3);
								}
								else
								{
									if (!_dataRevisions.TryGetValue(item7, out var value16) || zDO3.DataRevision != value16 || Utils.DistanceXZ(val2.GetPosition(), zDO3.GetPosition()) > 4f || zDO3.GetBool(ZDOVars.s_inUse, false) || !CheckMinDistance(peers, zDO3))
									{
										continue;
									}
									item8.Update(zDO3);
									list5?.Clear();
									int num30 = 0;
									int num31 = _cfg.Smelters.FeedFromContainersLeaveAtLeastOre.Value;
									foreach (ItemData item27 in from x in item8.GetAllItems()
										where new ItemKey(x) == oreItem
										orderby x.m_stack
										select x)
									{
										int num32 = Math.Min(num28, item27.m_stack);
										int num33 = Math.Min(num32, num31);
										num31 -= num33;
										num32 -= num33;
										if (num32 != 0)
										{
											num30 += num32;
											item27.m_stack -= num32;
											if (item27.m_stack == 0)
											{
												(list5 ?? (list5 = new List<ItemData>())).Add(item27);
											}
											num28 -= num32;
											if (num28 == 0)
											{
												break;
											}
										}
									}
									if (num30 == 0)
									{
										value15.TryRemove(item7, out value3);
										if (value15 != null && value15.Count == 0)
										{
											_containersByItemName.TryRemove(oreItem.m_shared, out value12);
										}
										continue;
									}
									if (list5 != null && list5.Count > 0)
									{
										if (item8.GetAllItems() != item8.GetAllItems())
										{
											throw new Exception("Algorithm assumption violated");
										}
										foreach (ItemData item28 in list5)
										{
											item8.GetAllItems().Remove(item28);
										}
										List<ItemData> allItems = item8.GetAllItems();
										if (allItems != null && allItems.Count == 0)
										{
											value15.TryRemove(item7, out value3);
											if (value15 != null && value15.Count == 0)
											{
												_containersByItemName.TryRemove(oreItem.m_shared, out value12);
											}
										}
									}
									val2.SetOwner(ZDOMan.GetSessionID());
									for (int n = 0; n < num30; n++)
									{
										val2.Set($"item{@int + n}", ((Object)((Component)item25.m_from).gameObject).name);
									}
									val2.Set(ZDOVars.s_queued, @int + num30, false);
									ZPackage val11 = new ZPackage();
									item8.Save(val11);
									zDO3.Set(ZDOVars.s_items, val11.GetBase64());
									_dataRevisions[zDO3.m_uid] = zDO3.DataRevision;
									num29 += num30;
									if (num28 == 0)
									{
										break;
									}
								}
							}
						}
						if (num29 != 0)
						{
							ShowMessage(peers, (MessageType)1, $"{value5.Piece?.m_name ?? value5.Smelter.m_name} $msg_added {num29} {oreItem.m_shared.m_name}");
						}
					}
				}
			}
			Logger.Log((LogLevel)((stopwatch.ElapsedMilliseconds > _cfg.General.MaxProcessingTime.Value) ? 16 : 32), (object)string.Format("{0} took {1} ms to process {2} of {3} ZDOs in {4} of {5} zones", "Execute", stopwatch.ElapsedMilliseconds, num4, num5, num3, _playerSectors.Count));
			if (num3 < _playerSectors.Count || num4 < num5)
			{
				_unfinishedProcessingInRow++;
			}
			else
			{
				_unfinishedProcessingInRow = 0u;
			}
		}

		private static void Log(LogLevel logLevel, string text = "", [CallerLineNumber] int lineNo = 0)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Logger.Log(logLevel, (object)(string.IsNullOrEmpty(text) ? $"Line: {lineNo}" : $"Line: {lineNo}: {text}"));
		}

		private static void ShowMessage(IEnumerable<ZNetPeer> peers, MessageType type, string message)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected I4, but got Unknown
			foreach (ZNetPeer peer in peers)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "ShowMessage", new object[2]
				{
					(int)type,
					message
				});
			}
		}

		private bool CheckMinDistance(IEnumerable<ZNetPeer> peers, ZDO zdo)
		{
			return CheckMinDistance(peers, zdo, _cfg.General.MinPlayerDistance.Value);
		}

		private bool CheckMinDistance(IEnumerable<ZNetPeer> peers, ZDO zdo, float minDistance)
		{
			ZDO zdo2 = zdo;
			return peers.Min((ZNetPeer x) => Utils.DistanceSqr(x.m_refPos, zdo2.GetPosition())) >= minDistance * minDistance;
		}

		private static string ConvertToRegexPattern(string searchPattern)
		{
			searchPattern = Regex.Escape(searchPattern);
			searchPattern = searchPattern.Replace("\\*", ".*").Replace("\\?", ".?");
			return "(?i)^" + searchPattern + "$";
		}
	}
	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<float> StartDelay { get; } = cfg.Bind<float>(section, "StartDelay", 0f, "Time (in seconds) before the mod starts processing the world");


			public ConfigEntry<float> Frequency { get; } = cfg.Bind<float>(section, "Frequency", 2f, "How many times per second the mod processes the world");


			public ConfigEntry<int> MaxProcessingTime { get; } = cfg.Bind<int>(section, "MaxProcessingTime", 50, "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 GeneralConfig(ConfigFile cfg, string section)
			{
			}
		}

		[RequiredPrefabs<Sign>]
		public sealed class SignsConfig
		{
			public ConfigEntry<bool> TimeSigns { get; } = cfg.Bind<bool>(section, "TimeSigns", true, string.Concat("True to update sign texts which contain time emojis (any of ", string.Concat(Main.ClockEmojis), ") with the in-game time"));


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

		[RequiredPrefabs<MapTable>]
		public sealed class MapTableConfig
		{
			public ConfigEntry<bool> AutoUpdatePortals { get; } = cfg.Bind<bool>(section, "AutoUpdatePortals", true, "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");


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


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

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


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

		[RequiredPrefabs<Fireplace>]
		public sealed class FireplacesConfig
		{
			public ConfigEntry<bool> MakeToggleable { get; } = cfg.Bind<bool>(section, "MakeToggleable", true, "True to make all fireplaces (including torches, braziers, etc.) toggleable");


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

		[RequiredPrefabs<Container, Piece>]
		public sealed class ContainersConfig
		{
			public ConfigEntry<bool> AutoSort { get; } = cfg.Bind<bool>(section, "AutoSort", true, "True to auto sort container inventories");


			[RequiredPrefabs<ItemDrop>]
			[RequiredPrefabs<Piece>]
			public ConfigEntry<bool> AutoPickup { get; } = cfg.Bind<bool>(section, "AutoPickup", true, "True to automatically put dropped items into containers if they already contain said item");


			public ConfigEntry<float> AutoPickupRange { get; } = cfg.Bind<float>(section, "AutoPickupRange", 64f, "Required proximity of a container to a dropped item to be considered as auto pickup target");


			public ConfigEntry<float> AutoPickupMinPlayerDistance { get; } = cfg.Bind<float>(section, "AutoPickupMinPlayerDistance", 8f, "Min distance all player must have to a dropped item for it to be picked up");


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

		[RequiredPrefabs<Smelter>]
		public sealed class SmeltersConfig
		{
			[RequiredPrefabs<Container, Piece>]
			public ConfigEntry<bool> FeedFromContainers { get; } = cfg.Bind<bool>(section, "FeedFromContainers", true, "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 GeneralConfig General { get; } = new GeneralConfig(cfg, "1. General");


		public SignsConfig Signs { get; } = new SignsConfig(cfg, "2. Signs");


		public MapTableConfig MapTables { get; } = new MapTableConfig(cfg, "3. Map Tables");


		public TamesConfig Tames { get; } = new TamesConfig(cfg, "4. Tames");


		public FireplacesConfig Fireplaces { get; } = new FireplacesConfig(cfg, "5. Fireplaces");


		public ContainersConfig Containers { get; } = new ContainersConfig(cfg, "6. Containers");


		public SmeltersConfig Smelters { get; } = new SmeltersConfig(cfg, "7. Smelters");


		public ModConfig(ConfigFile cfg)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = true)]
	internal abstract class RequiredPrefabsAttribute : Attribute
	{
		public Type[] Prefabs { get; }

		protected RequiredPrefabsAttribute(params Type[] prefabs)
		{
			Prefabs = prefabs;
			base..ctor();
		}
	}
	internal sealed class RequiredPrefabsAttribute<T> : RequiredPrefabsAttribute where T : Component
	{
		public RequiredPrefabsAttribute()
			: base(typeof(T))
		{
		}
	}
	internal sealed class RequiredPrefabsAttribute<T1, T2> : RequiredPrefabsAttribute where T1 : Component where T2 : Component
	{
		public RequiredPrefabsAttribute()
			: base(typeof(T1), typeof(T2))
		{
		}
	}
	internal static class PrivateAccessor
	{
		private static readonly Action<ItemData, ZDO> __loadFromZDO;

		public static void LoadFromZDO(ItemData itemData, ZDO zdo)
		{
			__loadFromZDO(itemData, zdo);
		}

		static PrivateAccessor()
		{
			MethodInfo? method = typeof(ItemDrop).GetMethod("LoadFromZDO", BindingFlags.Static | BindingFlags.NonPublic);
			ParameterExpression parameterExpression = Expression.Parameter(typeof(ItemData));
			ParameterExpression parameterExpression2 = Expression.Parameter(typeof(ZDO));
			__loadFromZDO = Expression.Lambda<Action<ItemData, ZDO>>(Expression.Call(method, parameterExpression, parameterExpression2), new ParameterExpression[2] { parameterExpression, parameterExpression2 }).Compile();
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

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

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

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

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}