Decompiled source of ServersideQoL AutoPortalHub BETA v1.99.4

ServersideQoL.AutoPortalHub.dll

Decompiled 19 hours 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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArgusMagnus")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("ArgusMagnus")]
[assembly: AssemblyDescription("Connects your portals to a generated portal hub")]
[assembly: AssemblyFileVersion("1.99.4.0")]
[assembly: AssemblyInformationalVersion("1.99.4-beta+80c81ad250a0109e44b175db632e72dae9da8db5")]
[assembly: AssemblyProduct("ServersideQoL.AutoPortalHub")]
[assembly: AssemblyTitle("ServersideQoL.AutoPortalHub")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")]
[assembly: AssemblyVersion("1.99.4.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", "1.99.4")]
	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 = "1.99.4";

		public const string PluginInformationalVersion = "1.99.4-beta";

		internal const string DependencyDirectory = "C:\\repos\\Valheim.ServersideQoL\\Dependencies\\";

		private DateTimeOffset BuildTimestamp { get; } = new DateTimeOffset(639209323753533442L, 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()
		{
			bool flag = true;
			ServersideQoLPluginBase<AutoPortalHubPlugin, Config>.Logger.LogWarning((object)string.Format("You are running a pre-release version: {0} ({1})", "1.99.4-beta", BuildTimestamp.LocalDateTime));
		}
	}
	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)
			{
				return (object)this == other || (((ProcessorPrefabInfo)this).Equals((ProcessorPrefabInfo)(object)other) && EqualityComparer<TeleportWorld>.Default.Equals(TeleportWorld, other.TeleportWorld) && EqualityComparer<Sign>.Default.Equals(Sign, other.Sign));
			}

			[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 = 0f;

		private bool _updateHub;

		private int _lastHubWidth = 0;

		private Regex? _includeRegex;

		private Regex? _excludeRegex;

		private bool _autoTag;

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

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

		protected override void Initialize()
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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 val) => val.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 = GetPortalHubId(item),
						AllowAllItems = item.Fields<TeleportWorld>().GetBool((Func<Expression<Func<TeleportWorld, bool>>>)(() => (TeleportWorld x) => x.m_allowAllItems), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 50)
					});
					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 zdo = key;
					PortalState portalState = value;
					HashSet<int> hashSet3 = (portalState.AllowAllItems ? hashSet2 : hashSet);
					while (!hashSet3.Add(++num))
					{
					}
					int value2 = (portalState.HubId = num);
					SetPortalHubId(zdo, value2);
				}
			}
			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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			if (!_hubEnabled)
			{
				return (ProcessResult)2;
			}
			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", 89);
						ServersideQoLZDO? hubPortal = portalState.HubPortal;
						if (hubPortal != null)
						{
							vars = hubPortal.Vars;
							((ZDOVars)(ref vars)).SetTag(text, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 90);
						}
						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", 91);
						}
						_updateHub = true;
					}
				}
				return (ProcessResult)0;
			}
			if (prefabInfo.TeleportWorld == null)
			{
				return (ProcessResult)2;
			}
			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", 106);
						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", 107);
						}
						_updateHub = true;
					}
				}
				return (ProcessResult)0;
			}
			if (zdo.IsModCreator())
			{
				return (ProcessResult)2;
			}
			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", 131);
						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 = GetPortalHubId(zdo),
						AllowAllItems = zdo.Fields<TeleportWorld>().GetBool((Func<Expression<Func<TeleportWorld, bool>>>)(() => (TeleportWorld x) => x.m_allowAllItems), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 149)
					};
					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))
						{
						}
						ServersideQoLZDO zdo2 = zdo;
						int value2 = (state.HubId = num);
						SetPortalHubId(zdo2, value2);
					}
				}
				_updateHub = true;
			}
			return (ProcessResult)0;
		}

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

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

		private void UpdatePortalHub()
		{
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: 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();
				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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: 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", 335);
				ZDOVars vars = current.HubPortal.Vars;
				((ZDOVars)(ref vars)).SetTag(current.Tag, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 336);
				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", 350);
				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", 371)
							.Set((Func<Expression<Func<Fireplace, bool>>>)(() => (Fireplace x) => x.m_disableCoverCheck), true, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.AutoPortalHub\\PortalHubProcessor.cs", 372);
					}
				}
			}
			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);
				}
			}
		}

		private static int GetPortalHubId(ServersideQoLZDO zdo, int defaultValue = 0)
		{
			return zdo.ZDO.GetInt(__portalHubId, defaultValue);
		}

		private static void SetPortalHubId(ServersideQoLZDO zdo, int value)
		{
			zdo.ZDO.Set(__portalHubId, value, false);
		}
	}
}