Decompiled source of ServersideQoL AutoPortalHub v2.0.0

ServersideQoL.AutoPortalHub.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
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 Microsoft.CodeAnalysis;
using ServersideQoL.Processors;
using ServersideQoL.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArgusMagnus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("ArgusMagnus")]
[assembly: AssemblyDescription("Connects your portals to a generated portal hub")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+cdafe98fecdc9c33d99ba13f064e37dcaca41712")]
[assembly: AssemblyProduct("ServersideQoL.AutoPortalHub")]
[assembly: AssemblyTitle("ServersideQoL.AutoPortalHub")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")]
[assembly: AssemblyVersion("2.0.0.0")]
[module: RefSafetyRules(11)]
[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();
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Count;

	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.Count;

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

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

	bool ICollection<T>.IsReadOnly => true;

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

	public <>z__ReadOnlyList(List<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 _items.Contains(item);
	}

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

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

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

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

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServersideQoL.AutoPortalHub
{
	[BepInPlugin("ArgusMagnus.ServersideQoL.AutoPortalHub", "ServersideQoL.AutoPortalHub", "2.0.0")]
	public sealed class AutoPortalHubPlugin : ServersideQoLPluginBase<AutoPortalHubPlugin, Config>
	{
		public const string Author = "ArgusMagnus";

		public const string PluginName = "ServersideQoL.AutoPortalHub";

		public const string PluginGuid = "ArgusMagnus.ServersideQoL.AutoPortalHub";

		public const string PluginVersion = "2.0.0";

		public const string PluginInformationalVersion = "2.0.0";

		private DateTimeOffset BuildTimestamp { get; } = new DateTimeOffset(639245732097572676L, default(TimeSpan));

		protected override Config CreateConfigSingleton(ConfigFile configFile, Logger logger)
		{
			return new Config(configFile, logger);
		}

		protected override void RegisterProcessors(IProcessorCollection processors)
		{
			processors.Add<PortalHubProcessor>();
		}

		private void Awake()
		{
		}
	}
	public sealed class Config : ConfigBase<Config>
	{
		private const string Section = "AutoPortalHub";

		public override ConfigEntry<bool> Enabled { get; } = ConfigBase<Config>.BindEx<bool>(cfg, "AutoPortalHub", true, "Enables/disables the entire mod.\r\nTrue to automatically generate a portal hub.\r\nPlaced portals which don't have a paired portal in the world will be connected to the portal hub.", (AcceptableValueBase)null, (Deprecated<Config>)null, "Enabled");

		public ConfigEntry<string> Exclude { get; } = ConfigBase<Config>.BindEx<string>(cfg, "AutoPortalHub", "", "Portals with a tag that matches this filter are not connected to the portal hub", (AcceptableValueBase)null, (Deprecated<Config>)null, "Exclude");

		public ConfigEntry<string> Include { get; } = ConfigBase<Config>.BindEx<string>(cfg, "AutoPortalHub", "*", "Only portals with a tag that matches this filter are connected to the portal hub", (AcceptableValueBase)null, (Deprecated<Config>)null, "Include");

		public ConfigEntry<bool> AutoNameNewPortals { get; } = ConfigBase<Config>.BindEx<bool>(cfg, "AutoPortalHub", false, "True to automatically name new portals", (AcceptableValueBase)null, (Deprecated<Config>)null, "AutoNameNewPortals");

		public ConfigEntry<string> AutoNameNewPortalsFormat { get; } = ConfigBase<Config>.BindEx<string>(cfg, "AutoPortalHub", "{0} {1:D2}", "Format string for auto-naming portals, the first argument is the biome name, the second is an automatically incremented integer", (AcceptableValueBase)new AcceptableFormatString(new object[2] { "Test", 0 }), (Deprecated<Config>)null, "AutoNameNewPortalsFormat");

		public Config(ConfigFile cfg, Logger logger)
			: base(cfg, logger)
		{
		}//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Expected O, but got Unknown

	}
	[Processor("84c672f5-9701-4aa0-a27e-1c79a341dd4d")]
	[DependsOn<PlayerRegistryProcessor>]
	public sealed class PortalHubProcessor : Processor<PortalHubProcessor.PrefabInfo>
	{
		public sealed record PrefabInfo(TeleportWorld? TeleportWorld, Sign? Sign) : ProcessorPrefabInfo()
		{
			[CompilerGenerated]
			public override string ToString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("PrefabInfo");
				stringBuilder.Append(" { ");
				if (((ProcessorPrefabInfo)this).PrintMembers(stringBuilder))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append('}');
				return stringBuilder.ToString();
			}

			[CompilerGenerated]
			protected override bool PrintMembers(StringBuilder builder)
			{
				if (((ProcessorPrefabInfo)this).PrintMembers(builder))
				{
					builder.Append(", ");
				}
				builder.Append("TeleportWorld = ");
				builder.Append(TeleportWorld);
				builder.Append(", Sign = ");
				builder.Append(Sign);
				return true;
			}

			[CompilerGenerated]
			public override int GetHashCode()
			{
				return (((ProcessorPrefabInfo)this).GetHashCode() * -1521134295 + EqualityComparer<TeleportWorld>.Default.GetHashCode(TeleportWorld)) * -1521134295 + EqualityComparer<Sign>.Default.GetHashCode(Sign);
			}

			[CompilerGenerated]
			public sealed override bool Equals(ProcessorPrefabInfo? other)
			{
				return ((object)this).Equals((object?)other);
			}

			[CompilerGenerated]
			public bool Equals(PrefabInfo? other)
			{
				if ((object)this != other)
				{
					if (((ProcessorPrefabInfo)this).Equals((ProcessorPrefabInfo)(object)other) && EqualityComparer<TeleportWorld>.Default.Equals(TeleportWorld, other.TeleportWorld))
					{
						return EqualityComparer<Sign>.Default.Equals(Sign, other.Sign);
					}
					return false;
				}
				return true;
			}

			[CompilerGenerated]
			private PrefabInfo(PrefabInfo original)
				: base((ProcessorPrefabInfo)(object)original)
			{
				TeleportWorld = original.TeleportWorld;
				Sign = original.Sign;
			}
		}

		private sealed class PortalState
		{
			public required string Tag { get; set; }

			public required int HubId { get; set; }

			public required bool AllowAllItems { get; init; }

			public ServersideQoLZDO? HubPortal { get; set; }

			public ServersideQoLZDO? HubSign { get; set; }
		}

		private readonly Dictionary<ServersideQoLZDO, PortalState> _knownPortals = new Dictionary<ServersideQoLZDO, PortalState>();

		private readonly IReadOnlyList<int> _torchPrefabs = new <>z__ReadOnlyArray<int>(new int[3]
		{
			Prefabs.StandingIronTorch,
			Prefabs.StandingIronTorchBlue,
			Prefabs.StandingIronTorchGreen
		});

		private bool _hubEnabled;

		private float _hubRadius;

		private bool _updateHub;

		private int _lastHubWidth;

		private Regex? _includeRegex;

		private Regex? _excludeRegex;

		private bool _autoTag;

		private readonly Vector3 _offset = ((Func<Vector3>)delegate
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(10820f, 0f, 0f);
			while (!Character.InInterior(val))
			{
				val.y += 1000f;
			}
			return val;
		})();

		private static readonly ServerVar<int> __portalHubIdVar = ServersideQoLPluginBase<AutoPortalHubPlugin, Config>.RegisterServerVar<int>("PortalHubId");

		protected override void Initialize()
		{
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			bool flag = _hubEnabled != ((ConfigBase<Config>)(object)ConfigBase<Config>.Instance).Enabled.Value;
			_hubEnabled = ((ConfigBase<Config>)(object)ConfigBase<Config>.Instance).Enabled.Value;
			_autoTag = _hubEnabled && ConfigBase<Config>.Instance.AutoNameNewPortals.Value;
			_knownPortals.Clear();
			if (_hubEnabled)
			{
				string text = ConfigBase<Config>.Instance.Include.Value.Trim();
				_includeRegex = (string.IsNullOrEmpty(text.Trim(new char[1] { '*' })) ? null : new Regex(Processor.ConvertToRegexPattern(text)));
				text = ConfigBase<Config>.Instance.Exclude.Value.Trim();
				_excludeRegex = (string.IsNullOrEmpty(text) ? null : new Regex(Processor.ConvertToRegexPattern(text)));
				foreach (ServersideQoLZDO item in ZDOMan.instance.GetPortals().Values.SelectMany((List<ZDO> x) => x.Select((ZDO val2) => val2.ServersideQoLZDO)))
				{
					string text2 = null;
					if (item.IsModCreator())
					{
						continue;
					}
					ZDOVars vars = item.Vars;
					if (!CheckFilter(text2 = ((ZDOVars)(ref vars)).GetTag("")))
					{
						continue;
					}
					_knownPortals.Add(item, new PortalState
					{
						Tag = text2,
						HubId = __portalHubIdVar.Get(item, 0),
						AllowAllItems = item.Fields<TeleportWorld>().GetBool((Func<Expression<Func<TeleportWorld, bool>>>)(() => (TeleportWorld x) => x.m_allowAllItems), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 54)
					});
					item.Destroyed += OnKnownPortalDestroyed;
				}
				HashSet<int> hashSet = (from x in _knownPortals.Values
					where !x.AllowAllItems
					select x.HubId).ToHashSet();
				HashSet<int> hashSet2 = (from x in _knownPortals.Values
					where x.AllowAllItems
					select x.HubId).ToHashSet();
				int num = 0;
				foreach (KeyValuePair<ServersideQoLZDO, PortalState> item2 in from x in _knownPortals
					where x.Value.HubId == 0
					orderby x.Value.Tag
					select x)
				{
					item2.Deconstruct(out var key, out var value);
					ServersideQoLZDO val = key;
					PortalState portalState = value;
					HashSet<int> hashSet3 = (portalState.AllowAllItems ? hashSet2 : hashSet);
					while (!hashSet3.Add(++num))
					{
					}
					ServerVar<int> _portalHubIdVar = __portalHubIdVar;
					int num2 = (portalState.HubId = num);
					_portalHubIdVar.Set(val, num2);
				}
			}
			if (flag || !_hubEnabled)
			{
				UpdatePortalHub();
			}
		}

		protected override void PreProcess(PeersEnumerable peers)
		{
			if (_updateHub && !((IEnumerable<Peer>)peers).Any((Peer x) => Utils.DistanceXZ(x.RefPos, _offset) < _hubRadius))
			{
				_updateHub = false;
				UpdatePortalHub();
			}
		}

		protected unsafe override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			if (_hubEnabled)
			{
				ServersideQoLZDO key;
				ZDOVars vars;
				PortalState value;
				if (prefabInfo.Sign != null && ((Processor)this).PlacedObjects.Contains(zdo))
				{
					_knownPortals.FirstOrDefault<KeyValuePair<ServersideQoLZDO, PortalState>>((KeyValuePair<ServersideQoLZDO, PortalState> x) => x.Value.HubSign == zdo).Deconstruct(out key, out value);
					ServersideQoLZDO val = key;
					PortalState portalState = value;
					if (portalState != null)
					{
						vars = zdo.Vars;
						string text = StringExtensionMethods.RemoveRichTextTags(((ZDOVars)(ref vars)).GetText(""));
						if (text != null && portalState.Tag != text)
						{
							portalState.Tag = text;
							vars = val.Vars;
							((ZDOVars)(ref vars)).SetTag(text, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 93);
							ServersideQoLZDO? hubPortal = portalState.HubPortal;
							if (hubPortal != null)
							{
								vars = hubPortal.Vars;
								((ZDOVars)(ref vars)).SetTag(text, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 94);
							}
							ServersideQoLZDO? hubSign = portalState.HubSign;
							if (hubSign != null)
							{
								vars = hubSign.Vars;
								((ZDOVars)(ref vars)).SetText("<color=white>" + text, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 95);
							}
							_updateHub = true;
						}
					}
					return (ProcessResult)0;
				}
				if (prefabInfo.TeleportWorld != null)
				{
					if (((Processor)this).PlacedObjects.Contains(zdo))
					{
						_knownPortals.FirstOrDefault<KeyValuePair<ServersideQoLZDO, PortalState>>((KeyValuePair<ServersideQoLZDO, PortalState> x) => x.Value.HubPortal == zdo).Deconstruct(out key, out value);
						ServersideQoLZDO val2 = key;
						PortalState portalState2 = value;
						if (portalState2 != null)
						{
							vars = zdo.Vars;
							string tag = ((ZDOVars)(ref vars)).GetTag("");
							if (tag != null && portalState2.Tag != tag)
							{
								portalState2.Tag = tag;
								vars = val2.Vars;
								((ZDOVars)(ref vars)).SetTag(tag, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 110);
								ServersideQoLZDO? hubSign2 = portalState2.HubSign;
								if (hubSign2 != null)
								{
									vars = hubSign2.Vars;
									((ZDOVars)(ref vars)).SetText("<color=white>" + tag, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 111);
								}
								_updateHub = true;
							}
						}
						return (ProcessResult)0;
					}
					if (!zdo.IsModCreator())
					{
						vars = zdo.Vars;
						string text2 = ((ZDOVars)(ref vars)).GetTag("");
						_knownPortals.TryGetValue(zdo, out PortalState state);
						if (_autoTag && state == null && string.IsNullOrEmpty(text2))
						{
							Biome biome = Processor.GetBiome(zdo.ZDO.GetPosition());
							string arg = Localization.instance.Localize("$biome_" + ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant());
							HashSet<string> hashSet = ZDOMan.instance.GetPortals().Values.SelectMany((List<ZDO> x) => x).Select(delegate(ZDO x)
							{
								//IL_0006: Unknown result type (might be due to invalid IL or missing references)
								//IL_000b: Unknown result type (might be due to invalid IL or missing references)
								ZDOVars vars2 = x.ServersideQoLZDO.Vars;
								return ((ZDOVars)(ref vars2)).GetTag("");
							}).ToHashSet();
							foreach (int item in Enumerable.Range(1, 1000))
							{
								string text3 = string.Format(ConfigBase<Config>.Instance.AutoNameNewPortalsFormat.Value, arg, item);
								if (!hashSet.Contains(text3))
								{
									vars = zdo.Vars;
									((ZDOVars)(ref vars)).SetTag(text2 = text3, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 135);
									break;
								}
							}
						}
						if (!CheckFilter(text2))
						{
							if (_knownPortals.Remove(zdo))
							{
								_updateHub = true;
							}
							zdo.Destroyed -= OnKnownPortalDestroyed;
						}
						else if (state?.Tag != text2)
						{
							if (state != null)
							{
								state.Tag = text2;
							}
							else
							{
								Dictionary<ServersideQoLZDO, PortalState> knownPortals = _knownPortals;
								ServersideQoLZDO key2 = zdo;
								PortalState obj = new PortalState
								{
									Tag = text2,
									HubId = __portalHubIdVar.Get(zdo, 0),
									AllowAllItems = zdo.Fields<TeleportWorld>().GetBool((Func<Expression<Func<TeleportWorld, bool>>>)(() => (TeleportWorld x) => x.m_allowAllItems), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 153)
								};
								value = obj;
								state = obj;
								knownPortals.Add(key2, value);
								zdo.Destroyed += OnKnownPortalDestroyed;
								if (state.HubId == 0)
								{
									HashSet<int> hashSet2 = (from x in _knownPortals.Values
										where x.AllowAllItems == state.AllowAllItems
										select x.HubId).ToHashSet();
									int num = 0;
									while (!hashSet2.Add(++num))
									{
									}
									ServerVar<int> _portalHubIdVar = __portalHubIdVar;
									ServersideQoLZDO obj2 = zdo;
									int num2 = (state.HubId = num);
									_portalHubIdVar.Set(obj2, num2);
								}
							}
							_updateHub = true;
						}
						return (ProcessResult)0;
					}
					return (ProcessResult)2;
				}
				return (ProcessResult)2;
			}
			return (ProcessResult)2;
		}

		private void OnKnownPortalDestroyed(ServersideQoLZDO zdo)
		{
			if (_knownPortals.Remove(zdo) && _hubEnabled)
			{
				_updateHub = true;
			}
		}

		private bool CheckFilter(string tag)
		{
			if ((_includeRegex ?? _excludeRegex) == null)
			{
				return true;
			}
			if (_includeRegex?.IsMatch(tag) ?? true)
			{
				return !(_excludeRegex?.IsMatch(tag) ?? false);
			}
			return false;
		}

		private void UpdatePortalHub()
		{
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			IReadOnlyList<PortalState> readOnlyList = Array.Empty<PortalState>();
			if (_hubEnabled && _knownPortals.Count > 0)
			{
				List<PortalState> list = new List<PortalState>();
				list.AddRange(from x in _knownPortals.Values
					group x by x.Tag into x
					where x.Count() % 2 != 0
					select x.First() into x
					orderby x.Tag
					select x);
				readOnlyList = new <>z__ReadOnlyList<PortalState>(list);
			}
			if (readOnlyList.Count == 0)
			{
				foreach (ServersideQoLZDO placedObject in ((Processor)this).PlacedObjects)
				{
					placedObject.Destroy();
				}
				((Processor)this).PlacedObjects.Clear();
				_lastHubWidth = 0;
				return;
			}
			int width = Math.Max(3, (int)Math.Ceiling((float)readOnlyList.Count / 4f + 1f));
			_hubRadius = (float)(width + 1) * 4f * Mathf.Sqrt(2f);
			bool flag = width == _lastHubWidth;
			_lastHubWidth = width;
			if (flag)
			{
				List<ServersideQoLZDO> list2 = ((Processor)this).PlacedObjects.Where((ServersideQoLZDO x) => x.ZDO.GetPrefab() != Prefabs.GraustenFloor4x4 && x.ZDO.GetPrefab() != Prefabs.GraustenWall4x2 && x.ZDO.GetPrefab() != Prefabs.DvergerGuardstone).ToList();
				foreach (ServersideQoLZDO item in list2)
				{
					item.Destroy();
					((Processor)this).PlacedObjects.Remove(item);
				}
			}
			else
			{
				foreach (ServersideQoLZDO placedObject2 in ((Processor)this).PlacedObjects)
				{
					placedObject2.Destroy();
				}
				((Processor)this).PlacedObjects.Clear();
				for (int num = 0; num < width; num++)
				{
					float num2 = ((float)num - (float)width / 2f) * 4f;
					for (int num3 = 0; num3 < width; num3++)
					{
						float num4 = ((float)num3 - (float)width / 2f) * 4f;
						Vector3 offset = _offset;
						offset.x += num2;
						offset.z += num4;
						((Processor)this).PlacePiece(offset, Prefabs.GraustenFloor4x4, 0f, (CreatorMarkers)0);
						offset.y += 4.5f;
						((Processor)this).PlacePiece(offset, Prefabs.GraustenFloor4x4, 0f, (CreatorMarkers)0);
						offset.y -= 4.5f;
					}
				}
			}
			IEnumerator<PortalState> enumerator4 = readOnlyList.GetEnumerator();
			for (int num5 = 0; num5 < width; num5++)
			{
				PlacePortalAndWalls(0, num5, width, flag, enumerator4, (int _, int k) => k < width - 1);
			}
			for (int num6 = 0; num6 < width; num6++)
			{
				PlacePortalAndWalls(num6, width - 1, width, flag, enumerator4, (int i, int _) => i < width - 1);
			}
			for (int num7 = width - 1; num7 >= 0; num7--)
			{
				PlacePortalAndWalls(width - 1, num7, width, flag, enumerator4, (int _, int k) => k > 0);
			}
			for (int num8 = width - 1; num8 >= 0; num8--)
			{
				PlacePortalAndWalls(num8, 0, width, flag, enumerator4, (int i, int _) => i > 0);
			}
			if (!enumerator4.MoveNext())
			{
				return;
			}
			throw new Exception("Algorithm failed to place all portals");
		}

		private IReadOnlyList<int> GetTorches(int hubId)
		{
			if (hubId == 0)
			{
				return Array.Empty<int>();
			}
			List<int> list = new List<int>(1) { 0 };
			for (int i = 0; i < hubId; i++)
			{
				list[0]++;
				for (int j = 0; j < list.Count; j++)
				{
					if (list[j] >= 3)
					{
						list[j] = 0;
						if (j == list.Count - 1)
						{
							list.Add(1);
						}
						else
						{
							list[j + 1]++;
						}
					}
				}
			}
			for (int k = 0; k < list.Count; k++)
			{
				list[k] = _torchPrefabs[list[k]];
			}
			return list;
		}

		private void PlacePortalAndWalls(int i, int k, int width, bool dontUpdateFloorAndWalls, IEnumerator<PortalState> statesEnumerator, Func<int, int, bool> placePortal)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_055b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			float num = ((float)i - (float)width / 2f) * 4f;
			float num2 = ((float)k - (float)width / 2f) * 4f;
			Vector3 offset = _offset;
			offset.x += num;
			offset.z += num2;
			bool flag = i == 0 || i == width - 1;
			bool flag2 = k == 0 || k == width - 1;
			if (!flag && !flag2)
			{
				throw new Exception("Unexpected values");
			}
			float num3 = 0f;
			if (flag && flag2)
			{
				num3 = ((k == 0 && i == 0) ? 45f : ((k == 0 && i != 0) ? 315f : ((k == 0 || i != 0) ? 225f : 135f)));
			}
			else if (flag)
			{
				num3 = ((i != 0) ? (num3 + 270f) : (num3 + 90f));
			}
			else if (flag2 && k != 0)
			{
				num3 += 180f;
			}
			if (!flag)
			{
				offset.z += ((k == 0) ? (-1.5f) : 1.5f);
			}
			else if (!flag2)
			{
				offset.x += ((i == 0) ? (-1.5f) : 1.5f);
			}
			if (placePortal(i, k) && statesEnumerator.MoveNext())
			{
				PortalState current = statesEnumerator.Current;
				float num4 = (current.AllowAllItems ? (-0.25f) : 0f);
				offset.y += num4;
				current.HubPortal = ((Processor)this).PlacePiece(offset, current.AllowAllItems ? Prefabs.Portal : Prefabs.PortalWood, num3, (CreatorMarkers)0);
				offset.y -= num4;
				current.HubPortal.Fields<TeleportWorld>().Set((Func<Expression<Func<TeleportWorld, bool>>>)(() => (TeleportWorld x) => x.m_allowAllItems), true, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 340);
				ZDOVars vars = current.HubPortal.Vars;
				((ZDOVars)(ref vars)).SetTag(current.Tag, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 341);
				if (flag && flag2)
				{
					offset.z += ((k == 0) ? (-0.25f) : 0.25f) * Mathf.Sqrt(2f);
					offset.x += ((i == 0) ? (-0.25f) : 0.25f) * Mathf.Sqrt(2f);
				}
				else if (!flag)
				{
					offset.z += ((k == 0) ? (-0.25f) : 0.25f);
				}
				else if (!flag2)
				{
					offset.x += ((i == 0) ? (-0.25f) : 0.25f);
				}
				offset.y += 2f;
				current.HubSign = ((Processor)this).PlacePiece(offset, Prefabs.Sign, num3, (CreatorMarkers)0);
				vars = current.HubSign.Vars;
				((ZDOVars)(ref vars)).SetText("<color=white>" + current.Tag, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 355);
				IReadOnlyList<int> torches = GetTorches(current.HubId);
				if (torches != null && torches.Count > 0)
				{
					offset.y -= 1.5f;
					Vector3 val = offset;
					float num5 = ((flag && flag2) ? (0.25f / Mathf.Sqrt(2f)) : 0.25f);
					for (int num6 = 0; num6 < torches.Count; num6++)
					{
						offset = val;
						float num7 = ((float)num6 - (float)(torches.Count - 1) / 2f) * num5;
						if (flag && flag2)
						{
							offset.x += ((k == 0) ? num7 : (0f - num7));
							offset.z += ((i == 0) ? (0f - num7) : num7);
						}
						else if (!flag)
						{
							offset.x += ((k == 0) ? num7 : (0f - num7));
						}
						else if (!flag2)
						{
							offset.z += ((i == 0) ? (0f - num7) : num7);
						}
						((Processor)this).PlacePiece(offset, torches[num6], num3, (CreatorMarkers)0).Fields<Fireplace>().Set((Func<Expression<Func<Fireplace, bool>>>)(() => (Fireplace x) => x.m_infiniteFuel), true, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 376)
							.Set((Func<Expression<Func<Fireplace, bool>>>)(() => (Fireplace x) => x.m_disableCoverCheck), true, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 377);
					}
				}
			}
			if (!dontUpdateFloorAndWalls)
			{
				if (flag)
				{
					offset = _offset;
					offset.x += num;
					offset.z += num2;
					offset.y += 0.25f;
					num3 = ((i == 0) ? 90 : 270);
					offset.x += ((i == 0) ? (-2f) : 2f);
					((Processor)this).PlacePiece(offset, Prefabs.GraustenWall4x2, num3, (CreatorMarkers)0);
					offset.y += 2f;
					((Processor)this).PlacePiece(offset, Prefabs.GraustenWall4x2, num3, (CreatorMarkers)0);
				}
				if (flag2)
				{
					offset = _offset;
					offset.x += num;
					offset.z += num2;
					offset.y += 0.25f;
					num3 = ((k != 0) ? 180 : 0);
					offset.z += ((k == 0) ? (-2f) : 2f);
					((Processor)this).PlacePiece(offset, Prefabs.GraustenWall4x2, num3, (CreatorMarkers)0);
					offset.y += 2f;
					((Processor)this).PlacePiece(offset, Prefabs.GraustenWall4x2, num3, (CreatorMarkers)0);
				}
			}
		}
	}
}