Decompiled source of PortalPreload v1.0.0

PortalPreload.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PortalPreload")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("PortalPreload")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
namespace PortalPreload
{
	[HarmonyPatch]
	internal static class FasterTeleporting
	{
		private static bool _destinationPreloaded = false;

		private static Vector3 _teleportDestination = Vector3.zero;

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		[HarmonyPostfix]
		private static void TeleportTo_Postfix(Player __instance, Vector3 pos, bool __result)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (__result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && PortalPreloadPlugin.EnableFasterTeleport.Value.IsOn())
			{
				_teleportDestination = pos;
				Vector2i zone = ZoneSystem.GetZone(pos);
				_destinationPreloaded = PortalPreloadPlugin.ProtectedZones.Contains(zone) || PortalPreloadPlugin.HasDestinationNear(pos);
				if (_destinationPreloaded)
				{
					__instance.m_teleportTimer = 2.1f;
					PortalPreloadPlugin.PortalPreloadLogger.LogDebug((object)$"Destination {zone} is preloaded - fast teleport enabled");
				}
			}
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		[HarmonyPrefix]
		private static bool UpdateTeleport_Prefix(Player __instance, float dt)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (!PortalPreloadPlugin.EnableFasterTeleport.Value.IsOn())
			{
				return true;
			}
			if (!__instance.m_teleporting)
			{
				return true;
			}
			if (!_destinationPreloaded)
			{
				return true;
			}
			__instance.m_teleportCooldown = 0f;
			__instance.m_teleportTimer += dt;
			if (__instance.m_teleportTimer <= 0.5f)
			{
				return false;
			}
			Vector3 val = __instance.m_teleportTargetRot * Vector3.forward;
			((Component)__instance).transform.position = __instance.m_teleportTargetPos;
			((Component)__instance).transform.rotation = __instance.m_teleportTargetRot;
			((Character)__instance).m_body.linearVelocity = Vector3.zero;
			((Character)__instance).m_maxAirAltitude = ((Component)__instance).transform.position.y;
			((Character)__instance).SetLookDir(val, 0f);
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return true;
			}
			bool num = ZoneSystem.instance.IsZoneLoaded(__instance.m_teleportTargetPos);
			float y = default(float);
			bool flag = ZoneSystem.instance.FindFloor(__instance.m_teleportTargetPos, ref y);
			if (num && (flag || __instance.m_teleportTimer > 3f))
			{
				if (flag)
				{
					Transform transform = ((Component)__instance).transform;
					Vector3 position = ((Component)__instance).transform.position;
					position.y = y;
					transform.position = position;
				}
				float teleportTimer = __instance.m_teleportTimer;
				__instance.m_teleportTimer = 0f;
				__instance.m_teleporting = false;
				((Character)__instance).ResetCloth();
				_destinationPreloaded = false;
				PortalPreloadPlugin.PortalPreloadLogger.LogDebug((object)$"Fast teleport completed in {teleportTimer:F2}s (floor found: {flag})");
				return false;
			}
			if (__instance.m_teleportTimer > 5f)
			{
				_destinationPreloaded = false;
				PortalPreloadPlugin.PortalPreloadLogger.LogDebug((object)"Fast teleport timeout - falling back to vanilla");
				return true;
			}
			return false;
		}

		[HarmonyPatch(typeof(ZNetScene), "IsAreaReady")]
		[HarmonyPostfix]
		private static void IsAreaReady_Postfix(Vector3 point, ref bool __result)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!__result && _destinationPreloaded && Vector3.Distance(point, _teleportDestination) < 10f)
			{
				__result = true;
			}
		}

		internal static void Reset()
		{
			//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)
			_destinationPreloaded = false;
			_teleportDestination = Vector3.zero;
		}
	}
	[BepInPlugin("Azumatt.PortalPreload", "PortalPreload", "1.0.0")]
	public class PortalPreloadPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		internal struct PortalTypeInfo
		{
			public readonly string PrefabName;

			public readonly bool ModelFacesForward;

			public PortalTypeInfo(string prefabName, bool modelFacesForward)
			{
				PrefabName = prefabName;
				ModelFacesForward = modelFacesForward;
			}
		}

		internal struct DestinationEntry
		{
			public Vector3 Position;

			public Vector2i Zone;

			public int ZoneRadius;
		}

		internal struct DeferredDestinationCleanup
		{
			public Vector3 DestinationPos;

			public ZDOID TrackedRemoteID;
		}

		[HarmonyPatch(typeof(TeleportWorld), "RPC_SetTag")]
		public static class TeleportWorld_RPC_SetTag_Patch
		{
			[CompilerGenerated]
			private sealed class <DelayedPreload>d__1 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public TeleportWorld portal;

				private int <i>5__2;

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

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

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

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

				private bool MoveNext()
				{
					//IL_0093: Unknown result type (might be due to invalid IL or missing references)
					//IL_0098: Unknown result type (might be due to invalid IL or missing references)
					//IL_009a: Unknown result type (might be due to invalid IL or missing references)
					//IL_009c: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
					//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
					//IL_00de: Unknown result type (might be due to invalid IL or missing references)
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<i>5__2 = 0;
						break;
					case 1:
					{
						<>1__state = -1;
						int num = <i>5__2 + 1;
						<i>5__2 = num;
						break;
					}
					}
					if (<i>5__2 < 100)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					if (portal.HaveTarget() && portal.TargetFound())
					{
						ZNetView nview = portal.m_nview;
						if ((Object)(object)nview == (Object)null)
						{
							return false;
						}
						ZDO zDO = nview.GetZDO();
						if (zDO == null)
						{
							return false;
						}
						ZDOID connectionZDOID = zDO.GetConnectionZDOID((ConnectionType)1);
						if (connectionZDOID != ZDOID.None)
						{
							ZDO zDO2 = ZDOMan.instance.GetZDO(connectionZDOID);
							if (zDO2 != null)
							{
								Vector3 position = zDO2.GetPosition();
								PortalPreloadLogger.LogInfo((object)$"RPC_SetTag patch: remote portal at {position} found. Preloading...");
								PreloadPortalDestination(position);
							}
						}
					}
					return false;
				}

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

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

			private static void Postfix(TeleportWorld __instance)
			{
				((MonoBehaviour)__instance).StartCoroutine(DelayedPreload(__instance));
			}

			[IteratorStateMachine(typeof(<DelayedPreload>d__1))]
			private static IEnumerator DelayedPreload(TeleportWorld portal)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <DelayedPreload>d__1(0)
				{
					portal = portal
				};
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "Awake")]
		public static class TeleportWorld_Awake_Patch
		{
			private static void Postfix(TeleportWorld __instance)
			{
				if (!Player.IsPlacementGhost(((Component)__instance).gameObject))
				{
					if ((Object)(object)((Component)__instance).GetComponent<PortalPreview>() == (Object)null)
					{
						((Component)__instance).gameObject.AddComponent<PortalPreview>();
						PortalPreloadLogger.LogInfo((object)"Added PortalPreview component to TeleportWorld.");
					}
					if ((Object)(object)__instance.m_proximityRoot != (Object)null && (Object)(object)((Component)__instance.m_proximityRoot).GetComponent<PortalProximityTrigger>() == (Object)null)
					{
						((Component)__instance.m_proximityRoot).gameObject.AddComponent<PortalProximityTrigger>();
						PortalPreloadLogger.LogInfo((object)"Added PortalProximityTrigger to m_proximityRoot.");
					}
				}
			}
		}

		[HarmonyPatch(typeof(Game), "Start")]
		private static class RegisterRPCGameStartPatch
		{
			private static void Postfix(Game __instance)
			{
				ZRoutedRpc.instance.Register<ZPackage>("RPC_SetPlayerNearby", (Action<long, ZPackage>)RPC_SetPlayerNearby);
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "OnDestroy")]
		private static class ZNetSceneOnDestroyCleanupPatch
		{
			private static void Postfix()
			{
				ClearAllDestinations();
				ProtectedZones.Clear();
				IsPlayerTeleporting = false;
				PortalPreview.ClearAllStaticState();
				FasterTeleporting.Reset();
				PortalPreloadLogger.LogDebug((object)"World unloading - cleared all static state");
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class PlayerTeleportToPatch
		{
			private static void Postfix(Player __instance, bool __result)
			{
				if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					IsPlayerTeleporting = true;
					PortalPreloadLogger.LogDebug((object)"Player started teleporting - protecting zones");
				}
			}
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		private static class PlayerUpdateTeleportPatch
		{
			[CompilerGenerated]
			private sealed class <DelayedZoneCleanup>d__1 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public Vector3 landingPos;

				public Vector2i landingZone;

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

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

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

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

				private bool MoveNext()
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0027: Expected O, but got Unknown
					//IL_0038: Unknown result type (might be due to invalid IL or missing references)
					//IL_005c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0061: Unknown result type (might be due to invalid IL or missing references)
					//IL_0066: Unknown result type (might be due to invalid IL or missing references)
					//IL_0092: Unknown result type (might be due to invalid IL or missing references)
					//IL_0098: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c3: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitForSeconds(5f);
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						RemoveDestination(landingPos);
						if ((Object)(object)Player.m_localPlayer != (Object)null)
						{
							Vector2i zone = ZoneSystem.GetZone(((Component)Player.m_localPlayer).transform.position);
							Vector2i val = default(Vector2i);
							for (int i = -2; i <= 2; i++)
							{
								for (int j = -2; j <= 2; j++)
								{
									((Vector2i)(ref val))..ctor(landingZone.x + i, landingZone.y + j);
									if (Mathf.Abs(zone.x - val.x) > 3 || Mathf.Abs(zone.y - val.y) > 3)
									{
										ProtectedZones.Remove(val);
									}
								}
							}
						}
						PortalPreloadLogger.LogDebug((object)"Cleaned up post-teleport zone protection");
						return false;
					}
				}

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

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

			private static void Postfix(Player __instance)
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !IsPlayerTeleporting || ((Character)__instance).IsTeleporting())
				{
					return;
				}
				IsPlayerTeleporting = false;
				PortalPreloadLogger.LogDebug((object)"Player finished teleporting - processing deferred cleanups");
				ProcessDeferredCleanups();
				Vector3 position = ((Component)__instance).transform.position;
				Vector2i zone = ZoneSystem.GetZone(position);
				for (int i = -2; i <= 2; i++)
				{
					for (int j = -2; j <= 2; j++)
					{
						ProtectedZones.Add(new Vector2i(zone.x + i, zone.y + j));
					}
				}
				AddDestination(position, 3);
				((MonoBehaviour)__instance).StartCoroutine(DelayedZoneCleanup(position, zone));
			}

			[IteratorStateMachine(typeof(<DelayedZoneCleanup>d__1))]
			private static IEnumerator DelayedZoneCleanup(Vector3 landingPos, Vector2i landingZone)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <DelayedZoneCleanup>d__1(0)
				{
					landingPos = landingPos,
					landingZone = landingZone
				};
			}
		}

		internal const string ModName = "PortalPreload";

		internal const string ModVersion = "1.0.0";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.PortalPreload";

		private static string ConfigFileName = "Azumatt.PortalPreload.cfg";

		private static string ConfigFileFullPath;

		public static readonly ManualLogSource PortalPreloadLogger;

		private readonly Harmony _harmony = new Harmony("Azumatt.PortalPreload");

		private static readonly ConfigSync ConfigSync;

		private static ConfigEntry<Toggle> _enablePreloading;

		internal static ConfigEntry<Toggle> EnableFasterTeleport;

		internal static readonly int PlayerNearbyCountKey;

		internal static readonly List<PortalTypeInfo> SupportedPortals;

		private static HashSet<int> _portalPrefabHashes;

		private static Dictionary<int, PortalTypeInfo> _portalConfigByHash;

		internal static HashSet<Vector2i> ProtectedZones;

		internal const float ObjectLoadRadius = 40f;

		internal const float CloseDistance = 5f;

		internal const float MediumDistance = 10f;

		internal const float FarDistance = 15f;

		internal static bool IsPlayerTeleporting;

		internal static DestinationEntry[] CachedDestinations;

		private static readonly Dictionary<Vector3, int> _destRadii;

		private static readonly Dictionary<Vector3, int> _destRefCounts;

		internal static readonly List<DeferredDestinationCleanup> DeferredCleanups;

		internal static HashSet<int> PortalPrefabHashes
		{
			get
			{
				if (_portalPrefabHashes == null)
				{
					RebuildPortalLookups();
				}
				return _portalPrefabHashes;
			}
		}

		internal static bool HasDestinations => CachedDestinations.Length != 0;

		internal static bool TryGetPortalConfig(int prefabHash, out PortalTypeInfo config)
		{
			if (_portalConfigByHash == null)
			{
				RebuildPortalLookups();
			}
			return _portalConfigByHash.TryGetValue(prefabHash, out config);
		}

		internal static void RebuildPortalLookups()
		{
			_portalPrefabHashes = new HashSet<int>();
			_portalConfigByHash = new Dictionary<int, PortalTypeInfo>();
			foreach (PortalTypeInfo supportedPortal in SupportedPortals)
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(supportedPortal.PrefabName);
				_portalPrefabHashes.Add(stableHashCode);
				_portalConfigByHash[stableHashCode] = supportedPortal;
			}
		}

		internal static int GetZoneRadiusForDistance(float distance)
		{
			if (distance <= 5f)
			{
				return 3;
			}
			if (distance <= 10f)
			{
				return 2;
			}
			return 1;
		}

		internal static void AddDestination(Vector3 pos, int zoneRadius)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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)
			if (_destRefCounts.TryGetValue(pos, out var value))
			{
				_destRefCounts[pos] = value + 1;
				if (zoneRadius > _destRadii[pos])
				{
					_destRadii[pos] = zoneRadius;
				}
			}
			else
			{
				_destRefCounts[pos] = 1;
				_destRadii[pos] = zoneRadius;
			}
			RebuildCachedDestinations();
		}

		internal static void UpdateDestinationRadius(Vector3 pos, int zoneRadius)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (_destRadii.ContainsKey(pos) && _destRadii[pos] != zoneRadius)
			{
				_destRadii[pos] = zoneRadius;
				RebuildCachedDestinations();
			}
		}

		internal static void RemoveDestination(Vector3 pos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (_destRefCounts.TryGetValue(pos, out var value))
			{
				if (value <= 1)
				{
					_destRefCounts.Remove(pos);
					_destRadii.Remove(pos);
				}
				else
				{
					_destRefCounts[pos] = value - 1;
				}
				RebuildCachedDestinations();
			}
		}

		internal static bool HasDestinationNear(Vector3 pos, float tolerance = 10f)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			float num = tolerance * tolerance;
			DestinationEntry[] cachedDestinations = CachedDestinations;
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				Vector3 val = cachedDestinations[i].Position - pos;
				if (((Vector3)(ref val)).sqrMagnitude < num)
				{
					return true;
				}
			}
			return false;
		}

		private static void RebuildCachedDestinations()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (_destRadii.Count == 0)
			{
				CachedDestinations = Array.Empty<DestinationEntry>();
				return;
			}
			DestinationEntry[] array = new DestinationEntry[_destRadii.Count];
			int num = 0;
			foreach (KeyValuePair<Vector3, int> destRadius in _destRadii)
			{
				array[num++] = new DestinationEntry
				{
					Position = destRadius.Key,
					Zone = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.GetZone(destRadius.Key) : Vector2i.zero),
					ZoneRadius = destRadius.Value
				};
			}
			CachedDestinations = array;
		}

		internal static void ClearAllDestinations()
		{
			_destRadii.Clear();
			_destRefCounts.Clear();
			DeferredCleanups.Clear();
			CachedDestinations = Array.Empty<DestinationEntry>();
		}

		internal static void ProcessDeferredCleanups()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (DeferredCleanups.Count == 0)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			foreach (DeferredDestinationCleanup deferredCleanup in DeferredCleanups)
			{
				RemoveDestination(deferredCleanup.DestinationPos);
				if (deferredCleanup.TrackedRemoteID != ZDOID.None && (Object)(object)localPlayer != (Object)null && ZDOMan.instance != null)
				{
					ZDO zDO = ZDOMan.instance.GetZDO(deferredCleanup.TrackedRemoteID);
					if (zDO != null)
					{
						SetPlayerNearby(zDO, deferredCleanup.TrackedRemoteID, localPlayer, entering: false);
					}
				}
			}
			DeferredCleanups.Clear();
		}

		public void Awake()
		{
			_enablePreloading = ((BaseUnityPlugin)this).Config.Bind<Toggle>("General", "EnablePreloading", Toggle.On, "If on, the mod preloads portal destinations.");
			EnableFasterTeleport = ((BaseUnityPlugin)this).Config.Bind<Toggle>("General", "EnableFasterTeleport", Toggle.On, "If on, the teleportation is faster.");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			((MonoBehaviour)this).InvokeRepeating("UpdateForceActive", 5f, 2f);
		}

		private async Task UpdateForceActive()
		{
			try
			{
				if (ZDOMan.instance == null || (Object)(object)ZoneSystem.instance == (Object)null || ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated() && !ZNet.instance.IsServer()))
				{
					return;
				}
				HashSet<int> hashes = PortalPrefabHashes;
				List<ZDO> obj = await ZoneSystem.instance.GetWorldObjectsAsync((ZDO zdo) => hashes.Contains(zdo.GetPrefab()));
				ProtectedZones.Clear();
				foreach (ZDO item in obj)
				{
					if (item != null && item.IsValid() && item.GetInt(PlayerNearbyCountKey, 0) > 0)
					{
						ProtectedZones.Add(ZoneSystem.GetZone(item.GetPosition()));
					}
				}
			}
			catch (Exception ex)
			{
				PortalPreloadLogger.LogError((object)("Failed to update force active: " + ex.Message));
			}
		}

		public static void SetPlayerNearby(ZDO remoteZDO, ZDOID remoteID, Player player, bool entering = true)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (remoteZDO != null && remoteZDO.IsValid() && ZDOMan.instance != null)
			{
				int num = (entering ? 1 : (-1));
				if (remoteZDO.IsOwner())
				{
					ModifyPlayerNearbyCount(remoteZDO, num);
				}
				else if (!remoteZDO.HasOwner())
				{
					remoteZDO.SetOwner(ZDOMan.GetSessionID());
					ModifyPlayerNearbyCount(remoteZDO, num);
				}
				else if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsDedicated() && ZNet.instance.IsServer())
				{
					remoteZDO.SetOwner(ZDOMan.GetSessionID());
					ModifyPlayerNearbyCount(remoteZDO, num);
				}
				else if (ZRoutedRpc.instance != null)
				{
					ZPackage val = new ZPackage();
					val.Write(remoteID);
					val.Write(num);
					ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "RPC_SetPlayerNearby", new object[1] { val });
				}
			}
		}

		private static void ModifyPlayerNearbyCount(ZDO zdo, int delta)
		{
			int @int = zdo.GetInt(PlayerNearbyCountKey, 0);
			int num = Mathf.Max(0, @int + delta);
			zdo.Set(PlayerNearbyCountKey, num, false);
		}

		public static void RPC_SetPlayerNearby(long sender, ZPackage pkg)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (ZDOMan.instance == null)
			{
				return;
			}
			ZDOID val = pkg.ReadZDOID();
			int delta = pkg.ReadInt();
			ZDO zDO = ZDOMan.instance.GetZDO(val);
			if (zDO == null || !zDO.IsValid())
			{
				return;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				if (!zDO.IsOwner())
				{
					zDO.SetOwner(ZDOMan.GetSessionID());
				}
				ModifyPlayerNearbyCount(zDO, delta);
			}
			else if (zDO.IsOwner())
			{
				ModifyPlayerNearbyCount(zDO, delta);
			}
		}

		public static void PreloadPortalDestination(Vector3 destinationPos)
		{
			//IL_0026: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (_enablePreloading.Value == Toggle.Off)
			{
				PortalPreloadLogger.LogDebug((object)"Preloading disabled by config.");
				return;
			}
			PortalPreloadLogger.LogInfo((object)$"Preloading destination at {destinationPos}");
			Vector2i zone = ZoneSystem.GetZone(destinationPos);
			int num = 5;
			Vector2i item = default(Vector2i);
			for (int i = -num; i <= num; i++)
			{
				for (int j = -num; j <= num; j++)
				{
					((Vector2i)(ref item))..ctor(zone.x + i, zone.y + j);
					ProtectedZones.Add(item);
				}
			}
		}

		static PortalPreloadPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			PortalPreloadLogger = Logger.CreateLogSource("PortalPreload");
			ConfigSync = new ConfigSync("Azumatt.PortalPreload")
			{
				DisplayName = "PortalPreload",
				CurrentVersion = "1.0.0",
				MinimumRequiredVersion = "1.0.0"
			};
			_enablePreloading = null;
			EnableFasterTeleport = null;
			PlayerNearbyCountKey = StringExtensionMethods.GetStableHashCode("playerNearbyCount");
			SupportedPortals = new List<PortalTypeInfo>
			{
				new PortalTypeInfo("portal_wood", modelFacesForward: false),
				new PortalTypeInfo("portal_stone", modelFacesForward: true)
			};
			_portalPrefabHashes = null;
			_portalConfigByHash = null;
			ProtectedZones = new HashSet<Vector2i>();
			IsPlayerTeleporting = false;
			CachedDestinations = Array.Empty<DestinationEntry>();
			_destRadii = new Dictionary<Vector3, int>();
			_destRefCounts = new Dictionary<Vector3, int>();
			DeferredCleanups = new List<DeferredDestinationCleanup>();
		}
	}
	public static class ToggleExtensions
	{
		[SpecialName]
		public sealed class <G>$F0761429328CE66EDE8B39DE93B80CE2
		{
			[SpecialName]
			public static class <M>$76059A2A9DE173D12B656BE2E483953E
			{
			}

			[ExtensionMarker("<M>$76059A2A9DE173D12B656BE2E483953E")]
			public bool IsOn()
			{
				throw null;
			}

			[ExtensionMarker("<M>$76059A2A9DE173D12B656BE2E483953E")]
			public bool IsOff()
			{
				throw null;
			}
		}

		public static bool IsOn(this PortalPreloadPlugin.Toggle toggle)
		{
			return toggle == PortalPreloadPlugin.Toggle.On;
		}

		public static bool IsOff(this PortalPreloadPlugin.Toggle toggle)
		{
			return toggle == PortalPreloadPlugin.Toggle.Off;
		}
	}
	public class PortalPreview : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <RegisterWhenReady>d__31 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public PortalPreview <>4__this;

			private int <attempts>5__2;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				PortalPreview portalPreview = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<attempts>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)portalPreview.portal != (Object)null && (Object)(object)portalPreview.portal.m_nview != (Object)null && portalPreview.portal.m_nview.GetZDO() == null)
				{
					if (++<attempts>5__2 > 600)
					{
						PortalPreloadPlugin.PortalPreloadLogger.LogWarning((object)"Timed out waiting for ZDO on PortalPreview");
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)portalPreview.portal != (Object)null && (Object)(object)portalPreview.portal.m_nview != (Object)null && portalPreview.portal.m_nview.GetZDO() != null)
				{
					RegisterPortal(portalPreview.portal);
					if (PortalPreloadPlugin.TryGetPortalConfig(portalPreview.portal.m_nview.GetZDO().GetPrefab(), out var config))
					{
						portalPreview._modelFacesForward = config.ModelFacesForward;
					}
				}
				portalPreview._registerCoroutine = null;
				return false;
			}

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

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

		private static readonly Dictionary<ZDOID, TeleportWorld> _portalRegistry = new Dictionary<ZDOID, TeleportWorld>();

		private static readonly HashSet<PortalPreview> _activePreviewsInRange = new HashSet<PortalPreview>();

		private static PortalPreview _closestPreview = null;

		private static float _closestDistance = float.MaxValue;

		private static readonly List<PortalPreview> _toRemove = new List<PortalPreview>();

		public int textureSize = 512;

		public float maxPreviewDistance = 12f;

		public string previewPlaneName = "PortalPreviewPlane";

		public Vector3 previewPlanePosition = new Vector3(0f, 1.31f, 0.01f);

		public Vector3 previewPlaneScale = new Vector3(2.85f, 2.85f, 2.85f);

		public float raycastWidth = 0.35f;

		public float nearClipPlaneMin = 0.1f;

		public float nearClipPlaneMax = 0.5f;

		public float minWaterDistance = 0.3f;

		private LayerMask blockCameraMask;

		private TeleportWorld portal;

		private Camera previewCam;

		private RenderTexture rt;

		private MeshRenderer planeRend;

		private TeleportWorld _cachedRemoteTW;

		private Renderer[] _cachedRemoteRenderers;

		private bool _hasRenderedLiveFrame;

		private bool _modelFacesForward;

		private int _framesInRange;

		private Coroutine _registerCoroutine;

		public static void RegisterPortal(TeleportWorld tw)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			object obj;
			if (tw == null)
			{
				obj = null;
			}
			else
			{
				ZNetView nview = tw.m_nview;
				obj = ((nview != null) ? nview.GetZDO() : null);
			}
			if (obj != null)
			{
				_portalRegistry[tw.m_nview.GetZDO().m_uid] = tw;
			}
		}

		public static void UnregisterPortal(TeleportWorld tw)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			object obj;
			if (tw == null)
			{
				obj = null;
			}
			else
			{
				ZNetView nview = tw.m_nview;
				obj = ((nview != null) ? nview.GetZDO() : null);
			}
			if (obj != null)
			{
				_portalRegistry.Remove(tw.m_nview.GetZDO().m_uid);
			}
		}

		public static TeleportWorld GetPortalByZDOID(ZDOID id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			_portalRegistry.TryGetValue(id, out TeleportWorld value);
			if ((Object)(object)value == (Object)null)
			{
				_portalRegistry.Remove(id);
				return null;
			}
			return value;
		}

		public static void ClearAllStaticState()
		{
			_portalRegistry.Clear();
			_activePreviewsInRange.Clear();
			_closestPreview = null;
			_closestDistance = float.MaxValue;
		}

		private void Awake()
		{
			portal = ((Component)this).GetComponent<TeleportWorld>();
			if ((Object)(object)portal == (Object)null)
			{
				Debug.LogError((object)"PortalPreview needs TeleportWorld");
			}
		}

		private void OnEnable()
		{
			_registerCoroutine = ((MonoBehaviour)this).StartCoroutine(RegisterWhenReady());
		}

		[IteratorStateMachine(typeof(<RegisterWhenReady>d__31))]
		private IEnumerator RegisterWhenReady()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RegisterWhenReady>d__31(0)
			{
				<>4__this = this
			};
		}

		private void OnDisable()
		{
			if (_registerCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_registerCoroutine);
				_registerCoroutine = null;
			}
			RemoveFromActiveRange();
		}

		private void Start()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			blockCameraMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "piece_nonsolid" }));
			rt = new RenderTexture(textureSize, textureSize, 24, (RenderTextureFormat)0);
			rt.antiAliasing = 2;
			((Texture)rt).filterMode = (FilterMode)1;
			GameObject val = new GameObject("PortalCam_" + ((Object)this).name);
			previewCam = val.AddComponent<Camera>();
			previewCam.CopyFrom(Camera.main);
			previewCam.targetTexture = rt;
			previewCam.cullingMask = -1;
			previewCam.useOcclusionCulling = false;
			previewCam.clearFlags = (CameraClearFlags)1;
			((Behaviour)previewCam).enabled = false;
			previewCam.depthTextureMode = (DepthTextureMode)1;
			Transform val2 = (Object.op_Implicit((Object)(object)portal.m_model) ? ((Component)portal.m_model).transform : ((Component)this).transform);
			GameObject val3 = new GameObject(previewPlaneName);
			val3.transform.SetParent(val2, false);
			val3.transform.localPosition = previewPlanePosition;
			val3.transform.localRotation = Quaternion.identity;
			val3.transform.localScale = previewPlaneScale;
			MeshFilter obj = val3.AddComponent<MeshFilter>();
			planeRend = val3.AddComponent<MeshRenderer>();
			obj.mesh = CreateCircleMesh(32, 0.5f);
			Material val4 = new Material(Shader.Find("Sprites/Default"));
			val4.mainTexture = (Texture)(object)rt;
			((Renderer)planeRend).material = val4;
			((Renderer)planeRend).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)planeRend).receiveShadows = false;
		}

		private Mesh CreateCircleMesh(int segments, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh();
			Vector3[] array = (Vector3[])(object)new Vector3[segments + 1];
			Vector2[] array2 = (Vector2[])(object)new Vector2[segments + 1];
			int[] array3 = new int[segments * 3];
			array[0] = Vector3.zero;
			array2[0] = new Vector2(0.5f, 0.5f);
			float num = (float)Math.PI * 2f / (float)segments;
			for (int i = 0; i < segments; i++)
			{
				float num2 = (float)i * num;
				float num3 = Mathf.Cos(num2) * radius;
				float num4 = Mathf.Sin(num2) * radius;
				array[i + 1] = new Vector3(num3, num4, 0f);
				array2[i + 1] = new Vector2(num3 / (2f * radius) + 0.5f, num4 / (2f * radius) + 0.5f);
			}
			for (int j = 0; j < segments; j++)
			{
				array3[j * 3] = 0;
				array3[j * 3 + 1] = j + 1;
				array3[j * 3 + 2] = ((j == segments - 1) ? 1 : (j + 2));
			}
			val.vertices = array;
			val.uv = array2;
			val.triangles = array3;
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}

		private void LateUpdate()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: 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_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_02b5: 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_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_02c7: 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_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			if (!portal.HaveTarget() || !portal.TargetFound())
			{
				RemoveFromActiveRange();
				if ((Object)(object)planeRend != (Object)null)
				{
					((Renderer)planeRend).enabled = false;
				}
				_hasRenderedLiveFrame = false;
				return;
			}
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			Vector3 val = (((Object)(object)((Character)localPlayer).m_eye != (Object)null) ? ((Character)localPlayer).m_eye.position : (((Component)localPlayer).transform.position + Vector3.up * 1.6f));
			float num = Vector3.Distance(val, ((Component)this).transform.position);
			if (num > maxPreviewDistance)
			{
				RemoveFromActiveRange();
				if ((Object)(object)planeRend != (Object)null)
				{
					((Renderer)planeRend).enabled = false;
				}
				return;
			}
			Transform val2 = (Object.op_Implicit((Object)(object)portal.m_model) ? ((Component)portal.m_model).transform : ((Component)this).transform);
			Vector3 val3 = val - val2.position;
			float num2 = Vector3.Dot(val2.forward, val3);
			if (_modelFacesForward ? (num2 < 0f) : (num2 > 0f))
			{
				RemoveFromActiveRange();
				if ((Object)(object)planeRend != (Object)null)
				{
					((Renderer)planeRend).enabled = false;
				}
				return;
			}
			AddToActiveRange(num);
			if ((Object)(object)_closestPreview != (Object)(object)this)
			{
				if ((Object)(object)planeRend != (Object)null)
				{
					((Renderer)planeRend).enabled = _hasRenderedLiveFrame;
				}
				return;
			}
			ZDOID connectionZDOID = portal.m_nview.GetZDO().GetConnectionZDOID((ConnectionType)1);
			if (connectionZDOID == ZDOID.None)
			{
				return;
			}
			ZDO zDO = ZDOMan.instance.GetZDO(connectionZDOID);
			if (zDO == null)
			{
				return;
			}
			TeleportWorld portalByZDOID = GetPortalByZDOID(zDO.m_uid);
			if ((Object)(object)portalByZDOID == (Object)null)
			{
				if ((Object)(object)planeRend != (Object)null)
				{
					((Renderer)planeRend).enabled = _hasRenderedLiveFrame;
				}
				return;
			}
			if ((Object)(object)planeRend != (Object)null)
			{
				((Renderer)planeRend).enabled = true;
			}
			_framesInRange++;
			Transform val4 = (((Object)(object)portal.m_model != (Object)null) ? ((Component)portal.m_model).transform : ((Component)this).transform);
			Transform obj = (((Object)(object)portalByZDOID.m_model != (Object)null) ? ((Component)portalByZDOID.m_model).transform : ((Component)portalByZDOID).transform);
			Matrix4x4 worldToLocalMatrix = val4.worldToLocalMatrix;
			Matrix4x4 localToWorldMatrix = obj.localToWorldMatrix;
			Matrix4x4 val5 = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 180f, 0f), Vector3.one);
			Matrix4x4 val6 = localToWorldMatrix * val5 * worldToLocalMatrix;
			Vector3 val7 = ((Matrix4x4)(ref val6)).MultiplyPoint3x4(val);
			Vector3 val8 = ((Matrix4x4)(ref val6)).MultiplyVector(((Object)(object)((Character)localPlayer).m_eye != (Object)null) ? ((Character)localPlayer).m_eye.forward : ((Component)main).transform.forward);
			Vector3 val9 = ((Matrix4x4)(ref val6)).MultiplyVector(Vector3.up);
			float num3 = (((Object)(object)GameCamera.instance != (Object)null) ? GameCamera.instance.m_distance : 4f);
			Vector3 val10 = -val8 * num3;
			Vector3 targetCamPos = val7 + val10;
			targetCamPos = ApplyCameraCollision(val7, targetCamPos, val8);
			float liquidLevel = Floating.GetLiquidLevel(targetCamPos, 1f, (LiquidType)10);
			if (targetCamPos.y < liquidLevel + minWaterDistance)
			{
				targetCamPos.y = liquidLevel + minWaterDistance;
			}
			((Component)previewCam).transform.position = targetCamPos;
			((Component)previewCam).transform.rotation = Quaternion.LookRotation(val8, val9);
			float nearClipPlane = nearClipPlaneMax;
			Vector3 val11 = val7 - targetCamPos;
			Vector3 normalized = ((Vector3)(ref val11)).normalized;
			if (Physics.CheckSphere(targetCamPos - normalized * nearClipPlaneMax, nearClipPlaneMax, LayerMask.op_Implicit(blockCameraMask)))
			{
				nearClipPlane = nearClipPlaneMin;
			}
			previewCam.fieldOfView = main.fieldOfView;
			previewCam.nearClipPlane = nearClipPlane;
			previewCam.farClipPlane = main.farClipPlane;
			if ((Object)(object)_cachedRemoteTW != (Object)(object)portalByZDOID || ((Object)(object)_cachedRemoteTW != (Object)null && _cachedRemoteRenderers == null))
			{
				_cachedRemoteTW = portalByZDOID;
				_cachedRemoteRenderers = ((Component)portalByZDOID).GetComponentsInChildren<Renderer>();
			}
			if (_cachedRemoteRenderers != null)
			{
				for (int i = 0; i < _cachedRemoteRenderers.Length; i++)
				{
					if ((Object)(object)_cachedRemoteRenderers[i] != (Object)null)
					{
						_cachedRemoteRenderers[i].enabled = false;
					}
				}
			}
			previewCam.Render();
			_hasRenderedLiveFrame = true;
			if (_cachedRemoteRenderers == null)
			{
				return;
			}
			for (int j = 0; j < _cachedRemoteRenderers.Length; j++)
			{
				if ((Object)(object)_cachedRemoteRenderers[j] != (Object)null)
				{
					_cachedRemoteRenderers[j].enabled = true;
				}
			}
		}

		private Vector3 ApplyCameraCollision(Vector3 eyePos, Vector3 targetCamPos, Vector3 forward)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = targetCamPos - eyePos;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float num = Vector3.Distance(eyePos, targetCamPos);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.SphereCast(eyePos, raycastWidth, normalized, ref val2, num, LayerMask.op_Implicit(blockCameraMask)))
			{
				float num2 = Mathf.Max(((RaycastHit)(ref val2)).distance - nearClipPlaneMin, 0.1f);
				return eyePos + normalized * num2;
			}
			if (Physics.Raycast(eyePos, normalized, ref val2, num, LayerMask.op_Implicit(blockCameraMask)))
			{
				float num3 = Mathf.Max(((RaycastHit)(ref val2)).distance - nearClipPlaneMin, 0.1f);
				Vector3 val3 = eyePos + normalized * num3;
				if (Vector3.Distance(eyePos, val3) < Vector3.Distance(eyePos, targetCamPos))
				{
					return val3;
				}
			}
			return targetCamPos;
		}

		private void AddToActiveRange(float distance)
		{
			_activePreviewsInRange.Add(this);
			if (_activePreviewsInRange.Count == 1)
			{
				_closestPreview = this;
				_closestDistance = distance;
			}
			else if (distance < _closestDistance)
			{
				_closestPreview = this;
				_closestDistance = distance;
			}
			else if ((Object)(object)_closestPreview == (Object)(object)this && distance > _closestDistance)
			{
				RecalculateClosest();
			}
		}

		private void RemoveFromActiveRange()
		{
			_framesInRange = 0;
			if (_activePreviewsInRange.Remove(this) && (Object)(object)_closestPreview == (Object)(object)this)
			{
				RecalculateClosest();
			}
		}

		private static void RecalculateClosest()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			_closestPreview = null;
			_closestDistance = float.MaxValue;
			_toRemove.Clear();
			foreach (PortalPreview item in _activePreviewsInRange)
			{
				if ((Object)(object)item == (Object)null)
				{
					_toRemove.Add(item);
				}
			}
			for (int i = 0; i < _toRemove.Count; i++)
			{
				_activePreviewsInRange.Remove(_toRemove[i]);
			}
			_toRemove.Clear();
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			Vector3 val = (((Object)(object)((Character)localPlayer).m_eye != (Object)null) ? ((Character)localPlayer).m_eye.position : (((Component)localPlayer).transform.position + Vector3.up * 1.6f));
			foreach (PortalPreview item2 in _activePreviewsInRange)
			{
				float num = Vector3.Distance(val, ((Component)item2).transform.position);
				if (num < _closestDistance)
				{
					_closestDistance = num;
					_closestPreview = item2;
				}
			}
		}

		private void OnDestroy()
		{
			UnregisterPortal(portal);
			RemoveFromActiveRange();
			if ((Object)(object)rt != (Object)null)
			{
				rt.Release();
				Object.Destroy((Object)(object)rt);
				rt = null;
			}
			if ((Object)(object)previewCam != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)previewCam).gameObject);
				previewCam = null;
			}
			if ((Object)(object)planeRend != (Object)null && (Object)(object)((Renderer)planeRend).material != (Object)null)
			{
				Object.Destroy((Object)(object)((Renderer)planeRend).material);
			}
			_cachedRemoteTW = null;
			_cachedRemoteRenderers = null;
		}
	}
	public class PortalProximityTrigger : MonoBehaviour
	{
		public float triggerRadius = 15f;

		private TeleportWorld portal;

		private ZDOID _trackedRemoteID = ZDOID.None;

		private bool _isPlayerInside;

		private Vector3 _destinationPos = Vector3.zero;

		private int _currentZoneRadius;

		private int _stayFrameCounter;

		private int _rampFrames;

		private const int RAMP_INTERVAL = 20;

		private void Awake()
		{
			portal = ((Component)this).GetComponentInParent<TeleportWorld>();
			if ((Object)(object)portal == (Object)null)
			{
				Debug.LogError((object)"PortalProximityTrigger: No TeleportWorld found in parent.");
				return;
			}
			SphereCollider val = ((Component)this).GetComponent<SphereCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)this).gameObject.AddComponent<SphereCollider>();
			}
			((Collider)val).isTrigger = true;
			val.radius = triggerRadius;
			((Component)this).gameObject.layer = LayerMask.NameToLayer("character_trigger");
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			if (_isPlayerInside || !IsLocalPlayer(other))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)portal == (Object)null || (Object)(object)portal.m_nview == (Object)null)
			{
				return;
			}
			ZDO zDO = portal.m_nview.GetZDO();
			if (zDO == null)
			{
				return;
			}
			ZDOID connectionZDOID = zDO.GetConnectionZDOID((ConnectionType)1);
			if (!(connectionZDOID == ZDOID.None) && ZDOMan.instance != null)
			{
				ZDO zDO2 = ZDOMan.instance.GetZDO(connectionZDOID);
				if (zDO2 != null)
				{
					Vector3 val = (_destinationPos = zDO2.GetPosition());
					int zoneRadiusForDistance = PortalPreloadPlugin.GetZoneRadiusForDistance(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)portal).transform.position));
					_rampFrames = 0;
					_currentZoneRadius = Mathf.Min(zoneRadiusForDistance, 1);
					PortalPreloadPlugin.AddDestination(val, _currentZoneRadius);
					_trackedRemoteID = connectionZDOID;
					_isPlayerInside = true;
					PortalPreloadPlugin.SetPlayerNearby(zDO2, connectionZDOID, localPlayer);
					PortalPreloadPlugin.PortalPreloadLogger.LogInfo((object)$"Player near portal – loading destination at {val} (ramping up)");
				}
			}
		}

		private void OnTriggerStay(Collider other)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!_isPlayerInside || _destinationPos == Vector3.zero)
			{
				return;
			}
			_rampFrames++;
			if (++_stayFrameCounter % 10 == 0 && IsLocalPlayer(other))
			{
				int zoneRadiusForDistance = PortalPreloadPlugin.GetZoneRadiusForDistance(Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)portal).transform.position));
				int num = 1 + _rampFrames / 20;
				int num2 = Mathf.Min(zoneRadiusForDistance, num);
				if (num2 != _currentZoneRadius)
				{
					_currentZoneRadius = num2;
					PortalPreloadPlugin.UpdateDestinationRadius(_destinationPos, _currentZoneRadius);
				}
			}
		}

		private void OnTriggerExit(Collider other)
		{
			if (_isPlayerInside && IsLocalPlayer(other))
			{
				CleanupDestination(Player.m_localPlayer);
				PortalPreloadPlugin.PortalPreloadLogger.LogInfo((object)"Player left portal area – destination will unload naturally");
			}
		}

		private void OnDisable()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (_isPlayerInside)
			{
				if (PortalPreloadPlugin.IsPlayerTeleporting)
				{
					PortalPreloadPlugin.DeferredCleanups.Add(new PortalPreloadPlugin.DeferredDestinationCleanup
					{
						DestinationPos = _destinationPos,
						TrackedRemoteID = _trackedRemoteID
					});
					_isPlayerInside = false;
					_destinationPos = Vector3.zero;
					_trackedRemoteID = ZDOID.None;
					_currentZoneRadius = 0;
					_rampFrames = 0;
				}
				else
				{
					CleanupDestination(Player.m_localPlayer);
				}
			}
		}

		private void CleanupDestination(Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (_destinationPos != Vector3.zero)
			{
				PortalPreloadPlugin.RemoveDestination(_destinationPos);
			}
			if (_trackedRemoteID != ZDOID.None && (Object)(object)player != (Object)null && ZDOMan.instance != null)
			{
				ZDO zDO = ZDOMan.instance.GetZDO(_trackedRemoteID);
				if (zDO != null)
				{
					PortalPreloadPlugin.SetPlayerNearby(zDO, _trackedRemoteID, player, entering: false);
				}
			}
			_isPlayerInside = false;
			_destinationPos = Vector3.zero;
			_trackedRemoteID = ZDOID.None;
			_currentZoneRadius = 0;
			_rampFrames = 0;
		}

		private static bool IsLocalPlayer(Collider other)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			if ((Object)(object)other.attachedRigidbody != (Object)null)
			{
				return (Object)(object)((Component)other.attachedRigidbody).gameObject == (Object)(object)((Component)localPlayer).gameObject;
			}
			return false;
		}
	}
	[PublicAPI]
	public static class MaterialReplacer
	{
		public enum ShaderType
		{
			Distortion,
			PieceShader,
			VegetationShader,
			RockShader,
			RugShader,
			GrassShader,
			CustomCreature,
			UseUnityShader
		}

		private static readonly Dictionary<GameObject, bool> ObjectToSwap;

		private static readonly Dictionary<string, Material> OriginalMaterials;

		private static readonly Dictionary<GameObject, ShaderType> ObjectsForShaderReplace;

		private static readonly HashSet<Shader> CachedShaders;

		private static bool hasRun;

		static MaterialReplacer()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			CachedShaders = new HashSet<Shader>();
			hasRun = false;
			OriginalMaterials = new Dictionary<string, Material>();
			ObjectToSwap = new Dictionary<GameObject, bool>();
			ObjectsForShaderReplace = new Dictionary<GameObject, ShaderType>();
			new Harmony("org.bepinex.helpers.PieceManager").Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaterialReplacer), "ReplaceAllMaterialsWithOriginal", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void RegisterGameObjectForShaderSwap(GameObject go, ShaderType type)
		{
			if (!ObjectsForShaderReplace.ContainsKey(go))
			{
				ObjectsForShaderReplace.Add(go, type);
			}
		}

		public static void RegisterGameObjectForMatSwap(GameObject go, bool isJotunnMock = false)
		{
			if (!ObjectToSwap.ContainsKey(go))
			{
				ObjectToSwap.Add(go, isJotunnMock);
			}
		}

		internal static void GetAllMaterials()
		{
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			foreach (Material val in array)
			{
				OriginalMaterials[((Object)val).name] = val;
			}
		}

		[HarmonyPriority(700)]
		private static void ReplaceAllMaterialsWithOriginal()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType == 4 || hasRun)
			{
				return;
			}
			if (OriginalMaterials.Count == 0)
			{
				GetAllMaterials();
			}
			foreach (KeyValuePair<GameObject, bool> item in ObjectToSwap)
			{
				GameObject key = item.Key;
				bool value = item.Value;
				ProcessGameObjectMaterials(key, value);
			}
			AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>();
			foreach (AssetBundle val in array)
			{
				IEnumerable<Shader> enumerable3;
				try
				{
					IEnumerable<Shader> enumerable2;
					if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val))
					{
						IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>();
						enumerable2 = enumerable;
					}
					else
					{
						enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>)
							where (Object)(object)shader != (Object)null
							select shader;
					}
					enumerable3 = enumerable2;
				}
				catch (Exception)
				{
					continue;
				}
				if (enumerable3 == null)
				{
					continue;
				}
				foreach (Shader item2 in enumerable3)
				{
					CachedShaders.Add(item2);
				}
			}
			foreach (KeyValuePair<GameObject, ShaderType> item3 in ObjectsForShaderReplace)
			{
				GameObject key2 = item3.Key;
				ShaderType value2 = item3.Value;
				ProcessGameObjectShaders(key2, value2);
			}
			hasRun = true;
		}

		internal static void ProcessGameObjectMaterials(GameObject go, bool isJotunnMock)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer obj in componentsInChildren)
			{
				Material[] sharedMaterials = obj.sharedMaterials.Select((Material material) => ReplaceMaterial(material, isJotunnMock)).ToArray();
				obj.sharedMaterials = sharedMaterials;
			}
		}

		private static Material ReplaceMaterial(Material originalMaterial, bool isJotunnMock)
		{
			string text = (isJotunnMock ? "JVLmock_" : "_REPLACE_");
			if (!((Object)originalMaterial).name.StartsWith(text, StringComparison.Ordinal))
			{
				return originalMaterial;
			}
			string text2 = ((Object)originalMaterial).name.Replace(" (Instance)", "").Replace(text, "");
			if (OriginalMaterials.TryGetValue(text2, out Material value))
			{
				return value;
			}
			Debug.LogWarning((object)("No suitable material found to replace: " + text2));
			return originalMaterial;
		}

		public static void ProcessGameObjectShaders(GameObject go, ShaderType shaderType)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] sharedMaterials = componentsInChildren[i].sharedMaterials;
				foreach (Material val in sharedMaterials)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.shader = GetShaderForType(val.shader, shaderType, ((Object)val.shader).name);
					}
				}
			}
		}

		private static Shader GetShaderForType(Shader orig, ShaderType shaderType, string originalShaderName)
		{
			return (Shader)(shaderType switch
			{
				ShaderType.Distortion => FindShaderWithName(orig, "Custom/Distortion"), 
				ShaderType.PieceShader => FindShaderWithName(orig, "Custom/Piece"), 
				ShaderType.VegetationShader => FindShaderWithName(orig, "Custom/Vegetation"), 
				ShaderType.RockShader => FindShaderWithName(orig, "Custom/StaticRock"), 
				ShaderType.RugShader => FindShaderWithName(orig, "Custom/Rug"), 
				ShaderType.GrassShader => FindShaderWithName(orig, "Custom/Grass"), 
				ShaderType.CustomCreature => FindShaderWithName(orig, "Custom/Creature"), 
				ShaderType.UseUnityShader => FindShaderWithName(orig, ((Object)(object)FindShaderWithName(orig, originalShaderName) != (Object)null) ? originalShaderName : "ToonDeferredShading2017"), 
				_ => FindShaderWithName(orig, "Standard"), 
			});
		}

		public static Shader FindShaderWithName(Shader origShader, string name)
		{
			foreach (Shader cachedShader in CachedShaders)
			{
				if (((Object)cachedShader).name == name)
				{
					return cachedShader;
				}
			}
			return origShader;
		}
	}
	[HarmonyPatch]
	public class ForceActivePatches
	{
		private static readonly HashSet<Vector2i> _cachedSectorSet = new HashSet<Vector2i>();

		private static readonly List<ZDO> _zdosToCreate = new List<ZDO>();

		private static int _frameCounter = 0;

		[HarmonyPatch(typeof(ZNetScene), "InActiveArea", new Type[]
		{
			typeof(Vector2i),
			typeof(Vector2i)
		})]
		[HarmonyPostfix]
		private static void InActiveArea(ZNetScene __instance, Vector2i zone, Vector2i refCenterZone, ref bool __result)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (__result)
			{
				return;
			}
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0)
			{
				return;
			}
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				int zoneRadius = reference.ZoneRadius;
				if (zone.x >= reference.Zone.x - zoneRadius && zone.x <= reference.Zone.x + zoneRadius && zone.y >= reference.Zone.y - zoneRadius && zone.y <= reference.Zone.y + zoneRadius)
				{
					__result = true;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "OutsideActiveArea", new Type[]
		{
			typeof(Vector3),
			typeof(Vector3)
		})]
		[HarmonyPostfix]
		private static void OutsideActiveArea(Vector3 point, ref bool __result)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!__result)
			{
				return;
			}
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0)
			{
				return;
			}
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				float num = (float)reference.ZoneRadius * 64f + 32f;
				if (Vector3.Distance(point, reference.Position) <= num)
				{
					__result = false;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "FindSectorObjects")]
		[HarmonyPostfix]
		private static void FindSectorObjects(ZDOMan __instance, Vector2i sector, int area, List<ZDO> sectorObjects)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0)
			{
				return;
			}
			_cachedSectorSet.Clear();
			_cachedSectorSet.Add(sector);
			for (int i = 1; i <= area; i++)
			{
				for (int j = sector.x - i; j <= sector.x + i; j++)
				{
					_cachedSectorSet.Add(new Vector2i(j, sector.y - i));
					_cachedSectorSet.Add(new Vector2i(j, sector.y + i));
				}
				for (int k = sector.y - i + 1; k <= sector.y + i - 1; k++)
				{
					_cachedSectorSet.Add(new Vector2i(sector.x - i, k));
					_cachedSectorSet.Add(new Vector2i(sector.x + i, k));
				}
			}
			Vector2i val = default(Vector2i);
			for (int l = 0; l < cachedDestinations.Length; l++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[l];
				for (int m = -reference.ZoneRadius; m <= reference.ZoneRadius; m++)
				{
					for (int n = -reference.ZoneRadius; n <= reference.ZoneRadius; n++)
					{
						((Vector2i)(ref val))..ctor(reference.Zone.x + n, reference.Zone.y + m);
						if (!_cachedSectorSet.Contains(val))
						{
							_cachedSectorSet.Add(val);
							__instance.FindObjects(val, sectorObjects);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "FindDistantObjects")]
		[HarmonyPrefix]
		private static bool FindDistantObjects(Vector2i sector)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0)
			{
				return true;
			}
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				int zoneRadius = reference.ZoneRadius;
				if (sector.x >= reference.Zone.x - zoneRadius && sector.x <= reference.Zone.x + zoneRadius && sector.y >= reference.Zone.y - zoneRadius && sector.y <= reference.Zone.y + zoneRadius)
				{
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(ZoneSystem), "CreateLocalZones")]
		[HarmonyPostfix]
		private static void CreateLocalZones(ZoneSystem __instance, ref bool __result)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0 || __result)
			{
				return;
			}
			Vector2i val = default(Vector2i);
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				if (__instance.PokeLocalZone(reference.Zone))
				{
					__result = true;
					break;
				}
				for (int j = reference.Zone.y - reference.ZoneRadius; j <= reference.Zone.y + reference.ZoneRadius; j++)
				{
					for (int k = reference.Zone.x - reference.ZoneRadius; k <= reference.Zone.x + reference.ZoneRadius; k++)
					{
						((Vector2i)(ref val))..ctor(k, j);
						if (!(val == reference.Zone) && __instance.PokeLocalZone(val))
						{
							__result = true;
							return;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "IsActiveAreaLoaded")]
		[HarmonyPostfix]
		private static void IsActiveAreaLoaded(ZoneSystem __instance, ref bool __result)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0 || !__result)
			{
				return;
			}
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				for (int j = -reference.ZoneRadius; j <= reference.ZoneRadius; j++)
				{
					for (int k = -reference.ZoneRadius; k <= reference.ZoneRadius; k++)
					{
						if (!__instance.m_zones.ContainsKey(new Vector2i(reference.Zone.x + k, reference.Zone.y + j)))
						{
							__result = false;
							return;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "IsAreaReady")]
		[HarmonyPostfix]
		private static void IsAreaReady(Vector3 point, ref bool __result)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (__result)
			{
				return;
			}
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0)
			{
				return;
			}
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				float num = (float)reference.ZoneRadius * 64f;
				if (Vector3.Distance(point, reference.Position) <= num && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.IsZoneLoaded(point))
				{
					__result = true;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "CreateDestroyObjects")]
		[HarmonyPostfix]
		private static void CreateDestroyObjects_ForceCreateNearDestinations(ZNetScene __instance)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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)
			PortalPreloadPlugin.DestinationEntry[] cachedDestinations = PortalPreloadPlugin.CachedDestinations;
			if (cachedDestinations.Length == 0 || ZDOMan.instance == null)
			{
				return;
			}
			_frameCounter++;
			if (_frameCounter % 5 != 0)
			{
				return;
			}
			float num = 1600f;
			int num2 = 0;
			Vector2i val = default(Vector2i);
			for (int i = 0; i < cachedDestinations.Length; i++)
			{
				ref PortalPreloadPlugin.DestinationEntry reference = ref cachedDestinations[i];
				for (int j = -reference.ZoneRadius; j <= reference.ZoneRadius; j++)
				{
					if (num2 >= 15)
					{
						break;
					}
					for (int k = -reference.ZoneRadius; k <= reference.ZoneRadius; k++)
					{
						if (num2 >= 15)
						{
							break;
						}
						((Vector2i)(ref val))..ctor(reference.Zone.x + k, reference.Zone.y + j);
						_zdosToCreate.Clear();
						ZDOMan.instance.FindObjects(val, _zdosToCreate);
						for (int l = 0; l < _zdosToCreate.Count; l++)
						{
							if (num2 >= 15)
							{
								break;
							}
							ZDO val2 = _zdosToCreate[l];
							if (__instance.m_instances.ContainsKey(val2) || !val2.IsValid() || (int)val2.Type > 2)
							{
								continue;
							}
							Vector3 val3 = val2.GetPosition() - reference.Position;
							if (!(((Vector3)(ref val3)).sqrMagnitude > num))
							{
								try
								{
									__instance.CreateObject(val2);
									num2++;
								}
								catch
								{
								}
							}
						}
					}
				}
			}
		}
	}
	public static class ZoneSystemExtension
	{
		[SpecialName]
		public sealed class <G>$C4EAF3E49419DCB8F1AA1FAC028204B4
		{
			[SpecialName]
			public static class <M>$FF334B291A5568FFD90BBDD3AE876A53
			{
			}

			[ExtensionMarker("<M>$FF334B291A5568FFD90BBDD3AE876A53")]
			public void SetGlobalKey(string key, object value)
			{
				throw null;
			}

			[ExtensionMarker("<M>$FF334B291A5568FFD90BBDD3AE876A53")]
			public string GetGlobalKeyValue(string key)
			{
				throw null;
			}

			[ExtensionMarker("<M>$FF334B291A5568FFD90BBDD3AE876A53")]
			public string GetOrAddGlobalKey(string key, string defaultValue)
			{
				throw null;
			}

			[ExtensionMarker("<M>$FF334B291A5568FFD90BBDD3AE876A53")]
			public (Vector2i, LocationInstance)[] GetGeneratedLocationsByName(string key)
			{
				throw null;
			}

			[ExtensionMarker("<M>$FF334B291A5568FFD90BBDD3AE876A53")]
			public Task<List<ZDO>> GetWorldObjectsAsync(params Func<ZDO, bool>[] customFilters)
			{
				throw null;
			}

			[ExtensionMarker("<M>$FF334B291A5568FFD90BBDD3AE876A53")]
			public Task<List<ZDO>> GetWorldObjectsAsync(string prefabName, params Func<ZDO, bool>[] customFilters)
			{
				throw null;
			}
		}

		internal static List<Vector3> tempPoints = new List<Vector3>();

		internal static bool creatingValidPlacesForLocation;

		internal static string creatingPlacesFor = "";

		public static void SetGlobalKey(this ZoneSystem zoneSystem, string key, object value)
		{
			zoneSystem.SetGlobalKey($"{key} {value}");
		}

		public static string GetGlobalKeyValue(this ZoneSystem zoneSystem, string key)
		{
			string result = default(string);
			zoneSystem.GetGlobalKey(key, ref result);
			return result;
		}

		public static string GetOrAddGlobalKey(this ZoneSystem zoneSystem, string key, string defaultValue)
		{
			string result = default(string);
			if (zoneSystem.GetGlobalKey(key, ref result))
			{
				return result;
			}
			zoneSystem.SetGlobalKey(key, defaultValue);
			return defaultValue;
		}

		public static (Vector2i, LocationInstance)[] GetGeneratedLocationsByName(this ZoneSystem zoneSystem, string key)
		{
			string key2 = key;
			return (from x in ZoneSystem.instance.m_locationInstances
				where x.Value.m_location.m_prefabName == key2
				select (x.Key, x.Value)).ToArray();
		}

		public static Task<List<ZDO>> GetWorldObjectsAsync(this ZoneSystem zoneSystem, params Func<ZDO, bool>[] customFilters)
		{
			Func<ZDO, bool>[] customFilters2 = customFilters;
			List<ZDO> zdos = new List<ZDO>(ZDOMan.instance.m_objectsByID.Values);
			return Task.Run(delegate
			{
				if (customFilters2 != null && customFilters2.Length != 0)
				{
					zdos = zdos.Where(delegate(ZDO x)
					{
						ZDO x2 = x;
						return customFilters2.All((Func<ZDO, bool> filter) => filter?.Invoke(x2) ?? true);
					}).ToList();
				}
				return zdos;
			});
		}

		public static async Task<List<ZDO>> GetWorldObjectsAsync(this ZoneSystem zoneSystem, string prefabName, params Func<ZDO, bool>[] customFilters)
		{
			int prefabHash = StringExtensionMethods.GetStableHashCode(prefabName);
			Func<ZDO, bool> func = (ZDO zdo) => zdo.GetPrefab() == prefabHash;
			return await zoneSystem.GetWorldObjectsAsync(customFilters.Concat<Func<ZDO, bool>>(new Func<ZDO, bool>[1] { func }).ToArray());
		}
	}
}
namespace ServerSync
{
	[PublicAPI]
	internal abstract class OwnConfigEntryBase
	{
		public object? LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	internal class SyncedConfigEntry<T> : OwnConfigEntryBase
	{
		public readonly ConfigEntry<T> SourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

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

		public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
		{
			SourceConfig = sourceConfig;
			base..ctor();
		}

		public void AssignLocalValue(T value)
		{
			if (LocalBaseValue == null)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal abstract class CustomSyncedValueBase
	{
		public object? LocalBaseValue;

		public readonly string Identifier;

		public readonly Type Type;

		private object? boxedValue;

		protected bool localIsOwner;

		public readonly int Priority;

		public object? BoxedValue
		{
			get
			{
				return boxedValue;
			}
			set
			{
				boxedValue = value;
				this.ValueChanged?.Invoke();
			}
		}

		public event Action? ValueChanged;

		protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
		{
			Priority = priority;
			Identifier = identifier;
			Type = type;
			configSync.AddCustomValue(this);
			localIsOwner = configSync.IsSourceOfTruth;
			configSync.SourceOfTruthChanged += delegate(bool truth)
			{
				localIsOwner = truth;
			};
		}
	}
	[PublicAPI]
	internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase
	{
		public T Value
		{
			get
			{
				return (T)base.BoxedValue;
			}
			set
			{
				base.BoxedValue = value;
			}
		}

		public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
			: base(configSync, identifier, typeof(T), priority)
		{
			Value = value;
		}

		public void AssignLocalValue(T value)
		{
			if (localIsOwner)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ReadOnly = false;
	}
	[PublicAPI]
	internal class ConfigSync
	{
		[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
		private static class SnatchCurrentlyHandlingRPC
		{
			public static ZRpc? currentRpc;

			[HarmonyPrefix]
			private static void Prefix(ZRpc __instance)
			{
				currentRpc = __instance;
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		internal static class RegisterRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				foreach (ConfigSync configSync2 in configSyncs)
				{
					ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
					if (isServer)
					{
						configSync2.InitialSyncDone = true;
						Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
					}
				}
				if (isServer)
				{
					((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
				}
				static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
				{
					ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
					{
						new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = isAdmin
						}
					});
					ConfigSync configSync = configSyncs.First();
					if (configSync != null)
					{
						((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
					}
				}
				static IEnumerator WatchAdminListChanges()
				{
					MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
					SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					List<string> CurrentList = new List<string>(adminList.GetList());
					while (true)
					{
						yield return (object)new WaitForSeconds(30f);
						if (!adminList.GetList().SequenceEqual(CurrentList))
						{
							CurrentList = new List<string>(adminList.GetList());
							List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
							{
								string hostName = p.m_rpc.GetSocket().GetHostName();
								return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName }));
							}).ToList();
							List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
							SendAdmin(nonAdminPeer, isAdmin: false);
							SendAdmin(adminPeer, isAdmin: true);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class RegisterClientRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					return;
				}
				foreach (ConfigSync configSync in configSyncs)
				{
					peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
				}
			}
		}

		private class ParsedConfigs
		{
			public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();

			public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ResetConfigsOnShutdown
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ProcessingServerUpdate = true;
				foreach (ConfigSync configSync in configSyncs)
				{
					configSync.resetConfigsFromServer();
					configSync.IsSourceOfTruth = true;
					configSync.InitialSyncDone = false;
				}
				ProcessingServerUpdate = false;
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private class SendConfigsAfterLogin
		{
			private class BufferingSocket : ZPlayFabSocket, ISocket
			{
				public volatile bool finished = false;

				public volatile int versionMatchQueued = -1;

				public readonly List<ZPackage> Package = new List<ZPackage>();

				public readonly ISocket Original;

				public BufferingSocket(ISocket original)
				{
					Original = original;
					((ZPlayFabSocket)this)..ctor();
				}

				public bool IsConnected()
				{
					return Original.IsConnected();
				}

				public ZPackage Recv()
				{
					return Original.Recv();
				}

				public int GetSendQueueSize()
				{
					return Original.GetSendQueueSize();
				}

				public int GetCurrentSendRate()
				{
					return Original.GetCurrentSendRate();
				}

				public bool IsHost()
				{
					return Original.IsHost();
				}

				public void Dispose()
				{
					Original.Dispose();
				}

				public bool GotNewData()
				{
					return Original.GotNewData();
				}

				public void Close()
				{
					Original.Close();
				}

				public string GetEndPointString()
				{
					return Original.GetEndPointString();
				}

				public void GetAndResetStats(out int totalSent, out int totalRecv)
				{
					Original.GetAndResetStats(ref totalSent, ref totalRecv);
				}

				public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
				{
					Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
				}

				public ISocket Accept()
				{
					return Original.Accept();
				}

				public int GetHostPort()
				{
					return Original.GetHostPort();
				}

				public bool Flush()
				{
					return Original.Flush();
				}

				public string GetHostName()
				{
					return Original.GetHostName();
				}

				public void VersionMatch()
				{
					if (finished)
					{
						Original.VersionMatch();
					}
					else
					{
						versionMatchQueued = Package.Count;
					}
				}

				public void Send(ZPackage pkg)
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Expected O, but got Unknown
					int pos = pkg.GetPos();
					pkg.SetPos(0);
					int num = pkg.ReadInt();
					if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
					{
						ZPackage val = new ZPackage(pkg.GetArray());
						val.SetPos(pos);
						Package.Add(val);
					}
					else
					{
						pkg.SetPos(pos);
						Original.Send(pkg);
					}
				}
			}

			[HarmonyPriority(800)]
			[HarmonyPrefix]
			private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
			{