Decompiled source of TeleportEverything v1.1.3

TeleportEverything.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TeleportEverything")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TeleportEverything")]
[assembly: AssemblyTitle("TeleportEverything")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TeleportEverything
{
	[BepInPlugin("zenox.teleporteverything", "TeleportEverything", "1.1.2")]
	public class TeleportEverythingPlugin : BaseUnityPlugin
	{
		public enum AllyTransportMode
		{
			Disabled,
			FollowingOnly,
			AllTamedNearby,
			AllTamedExceptNamed,
			OnlyNamed
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		private static class Player_UpdateTeleport_AllyReattach_Patch
		{
			private static void Postfix(Player __instance, bool ___m_teleporting)
			{
				//IL_003c: 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_0048: 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_0093: 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_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: 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_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				if (___m_teleporting || pendingAllyReattachIds.Count == 0 || !ModEnabled.Value)
				{
					return;
				}
				float y = default(float);
				foreach (ZDOID pendingAllyReattachId in pendingAllyReattachIds)
				{
					GameObject val = ZNetScene.instance.FindInstance(pendingAllyReattachId);
					if ((Object)(object)val == (Object)null)
					{
						TeleportEverythingPlugin instance = Instance;
						if (instance != null)
						{
							((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] Final placement skipped - ally {pendingAllyReattachId} not found near the player's final position.");
						}
						continue;
					}
					Vector3 position = val.transform.position;
					if (ZoneSystem.instance.FindFloor(position, ref y))
					{
						position.y = y;
					}
					Rigidbody component = val.GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null)
					{
						component.position = position;
						component.linearVelocity = Vector3.zero;
						component.angularVelocity = Vector3.zero;
					}
					val.transform.position = position;
					if ((Object)(object)component != (Object)null)
					{
						Physics.SyncTransforms();
					}
					ZNetView component2 = val.GetComponent<ZNetView>();
					if (component2 != null)
					{
						ZDO zDO = component2.GetZDO();
						if (zDO != null)
						{
							zDO.SetPosition(position);
						}
					}
					if ((Object)(object)component != (Object)null)
					{
						component.isKinematic = false;
					}
					TeleportEverythingPlugin instance2 = Instance;
					if (instance2 != null)
					{
						((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] Final placement: '{((Object)val).name}' grounded at {position}.");
					}
				}
				pendingAllyReattachIds.Clear();
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
		private static class TeleportWorld_Teleport_TrackPosition_Patch
		{
			private static void Prefix(TeleportWorld __instance)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				activePortalPosition = ((Component)__instance).transform.position;
			}

			private static void Postfix()
			{
				activePortalPosition = null;
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_AllyTransport_Patch
		{
			private static void Postfix(Player __instance, Vector3 pos, Quaternion rot, bool __result)
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: 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)
				if (__result && ModEnabled.Value && AllyMode.Value != AllyTransportMode.Disabled)
				{
					Vector3 fromPos = (Vector3)(((??)activePortalPosition) ?? ((Component)__instance).transform.position);
					TransportAllies(fromPos, ((Component)__instance).gameObject, pos, rot, __instance);
				}
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "GetHoverText")]
		private static class TeleportWorld_GetHoverText_AllyCount_Patch
		{
			private static void Postfix(TeleportWorld __instance, ref string __result)
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				if (ModEnabled.Value && ShowAllyCountOnHover.Value && AllyMode.Value != AllyTransportMode.Disabled && !string.IsNullOrEmpty(__result) && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					int count = GetTransportableAllies(((Component)__instance).transform.position, ((Component)Player.m_localPlayer).gameObject).Count;
					if (count > 0)
					{
						__result += $"\n{count} companion(s) nearby would teleport with you";
					}
				}
			}
		}

		public enum CartTransportMode
		{
			Disabled,
			Enabled,
			OnlyDungeons
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_CartExitClearance_Patch
		{
			private static void Prefix(Player __instance, ref Vector3 pos, Quaternion rot)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//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_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: 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_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: 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)
				if (ModEnabled.Value && CartTransportAllowedNow() && !((Object)(object)FindAttachedCart(((Component)__instance).transform.position, (Character)(object)__instance) == (Object)null))
				{
					Vector3 val = pos + rot * Vector3.forward * 3f;
					TeleportEverythingPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Exit clearance: nudging destination {pos} -> {val} ({3f}m) for attached cart.");
					}
					pos = val;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_CartTransport_Patch
		{
			private static void Postfix(Player __instance, Vector3 pos, Quaternion rot, bool __result)
			{
				//IL_0027: 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_002d: 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_0030: Unknown result type (might be due to invalid IL or missing references)
				if (__result && ModEnabled.Value && CartTransportAllowedNow())
				{
					Vector3 position = ((Component)__instance).transform.position;
					TransportAttachedCart(position, __instance, pos, rot);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		private static class Player_UpdateTeleport_CartReattach_Patch
		{
			private static void Postfix(Player __instance, bool ___m_teleporting)
			{
				//IL_002e: 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_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_010a: 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_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0226: Unknown result type (might be due to invalid IL or missing references)
				//IL_022c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0231: Unknown result type (might be due to invalid IL or missing references)
				//IL_023c: Unknown result type (might be due to invalid IL or missing references)
				if (___m_teleporting || !pendingReattachCartId.HasValue || !ModEnabled.Value)
				{
					return;
				}
				ZDOID value = pendingReattachCartId.Value;
				pendingReattachCartId = null;
				Vagon val = FindCartByZdoid(((Component)__instance).transform.position, value);
				if ((Object)(object)val == (Object)null)
				{
					TeleportEverythingPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)"[TeleportEverything CartTransport] Reattach skipped - transported cart not found near the player's final position.");
					}
					return;
				}
				int instanceID = ((Object)val).GetInstanceID();
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					ManualLogSource logger = ((BaseUnityPlugin)instance2).Logger;
					object[] obj = new object[4] { instanceID, null, null, null };
					Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
					obj[1] = ((component != null) ? new bool?(component.isKinematic) : ((bool?)null));
					obj[2] = ((Component)val).transform.position;
					obj[3] = ((Component)__instance).transform.position;
					logger.LogInfo((object)string.Format("[TeleportEverything CartTransport] Re-attach: cart instanceID={0}, isKinematic={1}, position BEFORE re-place={2}, player position={3}.", obj));
				}
				PlaceCartForAttach(val, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation);
				ZNetView component2 = ((Component)val).GetComponent<ZNetView>();
				if (component2 != null)
				{
					ZDO zDO = component2.GetZDO();
					if (zDO != null)
					{
						zDO.SetPosition(((Component)val).transform.position);
					}
				}
				TeleportEverythingPlugin instance3 = Instance;
				if (instance3 != null)
				{
					((BaseUnityPlugin)instance3).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Re-attach: cart instanceID={((Object)val).GetInstanceID()} (same object: {((Object)val).GetInstanceID() == instanceID}), position AFTER re-place={((Component)val).transform.position}.");
				}
				if (VagonCanAttach(val, ((Component)__instance).gameObject))
				{
					VagonAttachTo(val, ((Component)__instance).gameObject);
					TeleportEverythingPlugin instance4 = Instance;
					if (instance4 != null)
					{
						((BaseUnityPlugin)instance4).Logger.LogInfo((object)("[TeleportEverything CartTransport] Re-attached cart '" + ((Object)val).name + "' to the player after arrival."));
					}
					ShowTransportMessage((Character)(object)__instance, "Cart re-attached");
				}
				else
				{
					float y = ((Component)val).transform.up.y;
					float num = (((Object)(object)val.m_attachPoint != (Object)null) ? Vector3.Distance(((Component)__instance).transform.position + val.m_attachOffset, val.m_attachPoint.position) : (-1f));
					TeleportEverythingPlugin instance5 = Instance;
					if (instance5 != null)
					{
						((BaseUnityPlugin)instance5).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Re-attach skipped - cart '{((Object)val).name}' failed CanAttach (transform.up.y={y:F2} [need >=0.1], distance={num:F2}m [need <{val.m_detachDistance:F1}m]).");
					}
				}
				Rigidbody[] componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>();
				foreach (Rigidbody val2 in componentsInChildren)
				{
					val2.isKinematic = false;
				}
			}
		}

		[HarmonyPatch(typeof(Vagon), "Update")]
		private static class Vagon_Update_PreventAutoDetach_Patch
		{
			private static void Prefix(Vagon __instance, out float __state)
			{
				__state = __instance.m_detachDistance;
				if (ModEnabled.Value && PreventCartAutoDetach.Value)
				{
					__instance.m_detachDistance = float.MaxValue;
				}
			}

			private static void Postfix(Vagon __instance, float __state)
			{
				__instance.m_detachDistance = __state;
			}
		}

		[HarmonyPatch(typeof(Teleport), "Interact")]
		private static class Teleport_Interact_DungeonTracking_Patch
		{
			private static void Prefix(bool hold, Teleport __instance)
			{
				if (ModEnabled.Value && !hold && (Object)(object)__instance.m_targetPoint != (Object)null)
				{
					IsDungeonTeleport = true;
				}
			}

			private static void Postfix()
			{
				if (ModEnabled.Value)
				{
					IsDungeonTeleport = false;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_EnemyTransport_Patch
		{
			private static void Postfix(Player __instance, Vector3 pos, Quaternion rot, bool __result)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: 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_0035: Unknown result type (might be due to invalid IL or missing references)
				if (__result && ModEnabled.Value && TakeEnemiesWithYou.Value)
				{
					Vector3 position = ((Component)__instance).transform.position;
					TransportTargetingEnemies(position, __instance, pos, rot);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "IsTeleportable")]
		private static class Humanoid_IsTeleportable_PreventTeleportWhileChased_Patch
		{
			private static void Postfix(Humanoid __instance, ref bool __result)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				if (!__result || !ModEnabled.Value || !PreventTeleportWhileChased.Value)
				{
					return;
				}
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null && GetTargetingEnemies(((Component)val).transform.position, (Character)(object)val).Count > 0)
				{
					__result = false;
					TeleportEverythingPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)"[TeleportEverything EnemyTransport] Teleport blocked - a hostile creature is actively targeting you nearby (PreventTeleportWhileChased).");
					}
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "IsTeleportable")]
		private static class Inventory_IsTeleportable_ItemTransport_Patch
		{
			private static void Postfix(Inventory __instance, ref bool __result)
			{
				if (__result || !ModEnabled.Value || !TransportRestrictedItems.Value)
				{
					return;
				}
				foreach (ItemData allItem in __instance.GetAllItems())
				{
					if (allItem.m_shared.m_toolTier >= 1000)
					{
						TeleportEverythingPlugin instance = Instance;
						if (instance != null)
						{
							((BaseUnityPlugin)instance).Logger.LogInfo((object)("[TeleportEverything ItemTransport] Teleport still blocked - inventory contains cheat-tier item '" + allItem.m_shared.m_name + "'."));
						}
						return;
					}
				}
				__result = true;
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogInfo((object)"[TeleportEverything ItemTransport] IsTeleportable override applied - restricted items no longer block this portal use.");
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_ItemTransportFee_Patch
		{
			private static void Postfix(Player __instance, bool __result)
			{
				if (__result && ModEnabled.Value && TransportRestrictedItems.Value && !IsDungeonTeleport)
				{
					ApplyItemTransportFee(((Humanoid)__instance).GetInventory(), (Character)(object)__instance);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class InventoryGrid_UpdateGui_ItemTransportIcon_Patch
		{
			private static void Postfix(List<InventoryElement> ___m_elements)
			{
				if (!ModEnabled.Value || !TransportRestrictedItems.Value)
				{
					return;
				}
				foreach (InventoryElement ___m_element in ___m_elements)
				{
					if ((Object)(object)___m_element.m_noteleport != (Object)null)
					{
						((Behaviour)___m_element.m_noteleport).enabled = false;
					}
				}
			}
		}

		public enum MaskMode
		{
			Disabled,
			Block,
			AllowOnly
		}

		public enum MessageMode
		{
			NoMessages,
			TopLeft,
			Centered
		}

		[HarmonyPatch(typeof(TeleportWorld), "Awake")]
		private static class TeleportWorld_Awake_Portal_Patch
		{
			private static void Postfix(TeleportWorld __instance)
			{
				if (ModEnabled.Value)
				{
					__instance.m_activationRange *= PortalActivationRangeMultiplier.Value;
				}
			}
		}

		[HarmonyPatch(typeof(EffectFade), "Awake")]
		private static class EffectFade_Awake_PortalSoundVolume_Patch
		{
			private static readonly FieldInfo BaseVolumeField = AccessTools.Field(typeof(EffectFade), "m_baseVolume");

			private static void Postfix(EffectFade __instance)
			{
				if (ModEnabled.Value && !((Object)(object)((Component)__instance).GetComponentInParent<TeleportWorld>() == (Object)null))
				{
					float num = (float)BaseVolumeField.GetValue(__instance);
					BaseVolumeField.SetValue(__instance, num * PortalSoundVolume.Value);
				}
			}
		}

		public static SyncedValue<AllyTransportMode> AllyMode;

		public static ConfigEntry<float> AllySearchRadius;

		public static SyncedValue<bool> TransportBoars;

		public static SyncedValue<bool> TransportLoxes;

		public static SyncedValue<bool> TransportWolves;

		public static ConfigEntry<bool> ShowAllyCountOnHover;

		public static SyncedValue<MaskMode> AllyMaskMode;

		public static SyncedString AllyTransportMask;

		private static readonly List<Character> allyCharacterBuffer = new List<Character>();

		private static readonly List<ZDOID> pendingAllyReattachIds = new List<ZDOID>();

		private static Vector3? activePortalPosition;

		private static readonly Action<Vagon, GameObject> VagonAttachTo = AccessTools.MethodDelegate<Action<Vagon, GameObject>>(AccessTools.Method(typeof(Vagon), "AttachTo", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Vagon, GameObject, bool> VagonCanAttach = AccessTools.MethodDelegate<Func<Vagon, GameObject, bool>>(AccessTools.Method(typeof(Vagon), "CanAttach", (Type[])null, (Type[])null), (object)null, true);

		private static ZDOID? pendingReattachCartId;

		public static SyncedValue<CartTransportMode> TransportCartsMode;

		public static ConfigEntry<float> CartSearchRadius;

		public static SyncedValue<bool> TaxCartRestrictedItems;

		public static SyncedValue<bool> PreventCartAutoDetach;

		private const float CartExitExtraDistance = 3f;

		private static readonly Collider[] cartColliderBuffer = (Collider[])(object)new Collider[512];

		public const string PluginGUID = "zenox.teleporteverything";

		public const string PluginName = "TeleportEverything";

		public const string PluginVersion = "1.1.2";

		public static TeleportEverythingPlugin Instance;

		public static ConfigEntry<bool> ModEnabled;

		private readonly Harmony harmony = new Harmony("zenox.teleporteverything");

		internal static bool IsDungeonTeleport;

		public static SyncedValue<bool> TakeEnemiesWithYou;

		public static ConfigEntry<float> EnemySearchRadius;

		public static SyncedValue<int> MaxEnemiesTransported;

		public static ConfigEntry<float> EnemySpawnOffset;

		public static ConfigEntry<float> EnemySpawnScatterRadius;

		public static SyncedValue<MaskMode> EnemiesMaskMode;

		public static SyncedString EnemiesTransportMask;

		public static SyncedValue<bool> PreventTeleportWhileChased;

		private static readonly List<Character> enemyCharacterBuffer = new List<Character>();

		public static SyncedValue<bool> TransportRestrictedItems;

		public static SyncedValue<int> TransportFeePercent;

		public static SyncedString FeeExemptItems;

		private static HashSet<string> feeExemptSet;

		private static string feeExemptSetSource;

		private static readonly Dictionary<string, (HashSet<string> set, string source)> maskCache = new Dictionary<string, (HashSet<string>, string)>();

		public static ConfigEntry<float> PortalActivationRangeMultiplier;

		public static ConfigEntry<float> PortalSoundVolume;

		public static ConfigEntry<MessageMode> TransportMessageMode;

		private void BindAllyTransportConfig()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			AllyMode = new SyncedValue<AllyTransportMode>(((BaseUnityPlugin)this).Config.Bind<AllyTransportMode>("Allies", "AllyMode", AllyTransportMode.FollowingOnly, "Which nearby tamed creatures teleport with you. FollowingOnly = only ones currently following you. AllTamedNearby = every tamed creature in range, following or not. AllTamedExceptNamed = every tamed creature except ones you've given a custom name. OnlyNamed = only ones you've given a custom name. Disabled = no ally transport."));
			AllySearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Allies", "SearchRadius", 10f, new ConfigDescription("Radius in meters to search for transportable allies around the teleport point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			TransportBoars = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Allies", "TransportBoars", true, "If false, tamed boars never teleport with you regardless of AllyMode."));
			TransportLoxes = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Allies", "TransportLoxes", true, "If false, tamed loxes never teleport with you regardless of AllyMode."));
			TransportWolves = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Allies", "TransportWolves", true, "If false, tamed wolves never teleport with you regardless of AllyMode."));
			ShowAllyCountOnHover = ((BaseUnityPlugin)this).Config.Bind<bool>("Allies", "ShowAllyCountOnHover", true, "If true, hovering a portal shows how many nearby allies would teleport with you.");
			AllyMaskMode = new SyncedValue<MaskMode>(((BaseUnityPlugin)this).Config.Bind<MaskMode>("Allies", "AllyMaskMode", MaskMode.Disabled, "Disabled = no extra filtering. Block = AllyTransportMask names are never transported. AllowOnly = ONLY AllyTransportMask names are transported."));
			AllyTransportMask = new SyncedString(((BaseUnityPlugin)this).Config.Bind<string>("Allies", "AllyTransportMask", "", "Comma-separated creature names (substring match, e.g. 'Wolf,Lox') used by AllyMaskMode."));
		}

		private static bool IsSpeciesAllowed(Character character)
		{
			string name = ((Object)character).name;
			if (name.Contains("Boar") && !TransportBoars.Value)
			{
				return false;
			}
			if (name.Contains("Lox") && !TransportLoxes.Value)
			{
				return false;
			}
			if (name.Contains("Wolf") && !TransportWolves.Value)
			{
				return false;
			}
			return PassesMask("Ally", name, AllyMaskMode.Value, AllyTransportMask.Value);
		}

		private static bool IsNamed(Character character)
		{
			ZNetView component = ((Component)character).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			return !string.IsNullOrEmpty(component.GetZDO().GetString(ZDOVars.s_tamedName, ""));
		}

		internal static List<Character> GetTransportableAllies(Vector3 pos, GameObject followTarget, bool verboseLog = false)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			List<Character> list = new List<Character>();
			AllyTransportMode value = AllyMode.Value;
			if (value == AllyTransportMode.Disabled)
			{
				return list;
			}
			allyCharacterBuffer.Clear();
			Character.GetCharactersInRange(pos, AllySearchRadius.Value, allyCharacterBuffer);
			if (verboseLog)
			{
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] Scan: {allyCharacterBuffer.Count} character(s) within {AllySearchRadius.Value}m of teleport-from position.");
				}
			}
			foreach (Character item in allyCharacterBuffer)
			{
				Tameable component = ((Component)item).GetComponent<Tameable>();
				MonsterAI component2 = ((Component)item).GetComponent<MonsterAI>();
				if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
				{
					if (verboseLog)
					{
						TeleportEverythingPlugin instance2 = Instance;
						if (instance2 != null)
						{
							((BaseUnityPlugin)instance2).Logger.LogInfo((object)("[TeleportEverything AllyTransport] '" + ((Object)item).name + "' skipped: no Tameable/MonsterAI component (not a tameable creature)."));
						}
					}
					continue;
				}
				if (!component.IsTamed())
				{
					if (verboseLog)
					{
						TeleportEverythingPlugin instance3 = Instance;
						if (instance3 != null)
						{
							((BaseUnityPlugin)instance3).Logger.LogInfo((object)("[TeleportEverything AllyTransport] '" + ((Object)item).name + "' skipped: not tamed."));
						}
					}
					continue;
				}
				if (!IsSpeciesAllowed(item))
				{
					if (verboseLog)
					{
						TeleportEverythingPlugin instance4 = Instance;
						if (instance4 != null)
						{
							((BaseUnityPlugin)instance4).Logger.LogInfo((object)("[TeleportEverything AllyTransport] '" + ((Object)item).name + "' skipped: species transport disabled in config."));
						}
					}
					continue;
				}
				GameObject followTarget2 = component2.GetFollowTarget();
				if (1 == 0)
				{
				}
				bool flag = value switch
				{
					AllyTransportMode.FollowingOnly => (Object)(object)followTarget2 == (Object)(object)followTarget, 
					AllyTransportMode.AllTamedNearby => true, 
					AllyTransportMode.AllTamedExceptNamed => !IsNamed(item), 
					AllyTransportMode.OnlyNamed => IsNamed(item), 
					_ => false, 
				};
				if (1 == 0)
				{
				}
				if (!flag)
				{
					if (verboseLog)
					{
						string arg = ((value == AllyTransportMode.FollowingOnly) ? (" (follow target='" + (((Object)(object)followTarget2 == (Object)null) ? "null" : ((Object)followTarget2).name) + "', expected='" + ((Object)followTarget).name + "')") : "");
						TeleportEverythingPlugin instance5 = Instance;
						if (instance5 != null)
						{
							((BaseUnityPlugin)instance5).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] '{((Object)item).name}' skipped: doesn't qualify for mode {value}{arg}.");
						}
					}
					continue;
				}
				if (verboseLog)
				{
					TeleportEverythingPlugin instance6 = Instance;
					if (instance6 != null)
					{
						((BaseUnityPlugin)instance6).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] '{((Object)item).name}' qualifies for transport (mode={value}).");
					}
				}
				list.Add(item);
			}
			return list;
		}

		internal static void TransportAllies(Vector3 fromPos, GameObject followTarget, Vector3 targetPos, Quaternion targetRot, Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			List<Character> transportableAllies = GetTransportableAllies(fromPos, followTarget, verboseLog: true);
			TeleportEverythingPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] Mode={AllyMode.Value}, {transportableAllies.Count} ally/allies found near teleport-from position.");
			}
			if (transportableAllies.Count > 0)
			{
				ShowTransportMessage((Character)(object)player, $"{transportableAllies.Count} companion(s) teleported with you");
			}
			for (int i = 0; i < transportableAllies.Count; i++)
			{
				Character val = transportableAllies[i];
				ZNetView component = ((Component)val).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid())
				{
					if (!component.IsOwner())
					{
						component.ClaimOwnership();
					}
					Vector3 val2 = new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)) * (1f + (float)i * 0.5f);
					Vector3 val3 = targetPos + val2;
					Rigidbody component2 = ((Component)val).GetComponent<Rigidbody>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.position = val3;
						component2.linearVelocity = Vector3.zero;
						component2.angularVelocity = Vector3.zero;
						component2.isKinematic = true;
					}
					((Component)val).transform.position = val3;
					((Component)val).transform.rotation = targetRot;
					if ((Object)(object)component2 != (Object)null)
					{
						Physics.SyncTransforms();
					}
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						zDO.SetPosition(val3);
					}
					pendingAllyReattachIds.Add(component.GetZDO().m_uid);
					TeleportEverythingPlugin instance2 = Instance;
					if (instance2 != null)
					{
						((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] Teleported '{((Object)val).name}' to {val3} (pending final ground placement).");
					}
				}
			}
		}

		private void BindCartTransportConfig()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			TransportCartsMode = new SyncedValue<CartTransportMode>(((BaseUnityPlugin)this).Config.Bind<CartTransportMode>("Carts", "TransportCartsMode", CartTransportMode.Enabled, "Disabled = never. Enabled = a cart attached to the player teleports through any portal/teleporter. OnlyDungeons = only through dungeon rune stones (the Teleport component in crypts etc.), not player-built portals."));
			CartSearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Carts", "SearchRadius", 10f, new ConfigDescription("Radius in meters to search for the player's attached cart around the teleport point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			TaxCartRestrictedItems = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Carts", "TaxCartRestrictedItems", true, "If true, the same TransportFeePercent (see [Items]) is also taken from portal-restricted items sitting in the cart's own inventory."));
			PreventCartAutoDetach = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Carts", "PreventCartAutoDetach", true, "If true, an attached cart only detaches when you do it yourself (or it tips over) - vanilla otherwise re-checks the attach distance every frame and silently detaches on its own whenever you drift more than a couple meters away while pulling it."));
		}

		private static bool CartTransportAllowedNow()
		{
			CartTransportMode value = TransportCartsMode.Value;
			if (1 == 0)
			{
			}
			bool result = value switch
			{
				CartTransportMode.Enabled => true, 
				CartTransportMode.OnlyDungeons => IsDungeonTeleport, 
				_ => false, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static Vagon FindAttachedCart(Vector3 pos, Character player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, CartSearchRadius.Value, cartColliderBuffer);
			TeleportEverythingPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Scan: {num} collider(s) within {CartSearchRadius.Value}m of teleport-from position.");
			}
			if (num >= cartColliderBuffer.Length)
			{
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogWarning((object)$"[TeleportEverything CartTransport] Collider buffer maxed out ({cartColliderBuffer.Length}) - results may be truncated, a cart could be missed. Consider lowering CartSearchRadius.");
				}
			}
			Vagon result = null;
			HashSet<Vagon> hashSet = new HashSet<Vagon>();
			for (int i = 0; i < num; i++)
			{
				Vagon componentInParent = ((Component)cartColliderBuffer[i]).GetComponentInParent<Vagon>();
				if (!((Object)(object)componentInParent == (Object)null) && hashSet.Add(componentInParent))
				{
					bool flag = componentInParent.IsAttached();
					bool flag2 = componentInParent.IsAttached(player);
					TeleportEverythingPlugin instance3 = Instance;
					if (instance3 != null)
					{
						((BaseUnityPlugin)instance3).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Found cart '{((Object)componentInParent).name}': IsAttached()={flag}, IsAttached(player)={flag2}.");
					}
					if (flag2)
					{
						result = componentInParent;
					}
				}
			}
			return result;
		}

		internal static void TransportAttachedCart(Vector3 fromPos, Player player, Vector3 targetPos, Quaternion targetRot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			Vagon val = FindAttachedCart(fromPos, (Character)(object)player);
			if ((Object)(object)val == (Object)null)
			{
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)"[TeleportEverything CartTransport] No attached cart found near teleport-from position.");
				}
				return;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogInfo((object)("[TeleportEverything CartTransport] Attached cart '" + ((Object)val).name + "' found but has no valid ZNetView - skipped."));
				}
				return;
			}
			if (!component.IsOwner())
			{
				component.ClaimOwnership();
			}
			if (TaxCartRestrictedItems.Value && (Object)(object)val.m_container != (Object)null)
			{
				ApplyItemTransportFee(val.m_container.GetInventory(), (Character)(object)player);
			}
			PlaceCartForAttach(val, targetPos, targetRot);
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				zDO.SetPosition(((Component)val).transform.position);
			}
			TeleportEverythingPlugin instance3 = Instance;
			if (instance3 != null)
			{
				((BaseUnityPlugin)instance3).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Teleported cart '{((Object)val).name}' (instanceID={((Object)val).GetInstanceID()}) to {((Component)val).transform.position}.");
			}
			Rigidbody[] componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody val2 in componentsInChildren)
			{
				val2.isKinematic = true;
			}
			TeleportEverythingPlugin instance4 = Instance;
			if (instance4 != null)
			{
				ManualLogSource logger = ((BaseUnityPlugin)instance4).Logger;
				Rigidbody component2 = ((Component)val).GetComponent<Rigidbody>();
				logger.LogInfo((object)$"[TeleportEverything CartTransport] Kinematic freeze applied: rootBody.isKinematic={((component2 != null) ? new bool?(component2.isKinematic) : ((bool?)null))}, pendingReattachCartId={component.GetZDO().m_uid}.");
			}
			pendingReattachCartId = component.GetZDO().m_uid;
		}

		private static void PlaceCartForAttach(Vagon cart, Vector3 referencePos, Quaternion referenceRot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0031: 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_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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0097: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Quaternion.Inverse(((Component)cart).transform.rotation) * (cart.m_attachPoint.position - ((Component)cart).transform.position);
			Vector3 val2 = referencePos + cart.m_attachOffset;
			Vector3 val3 = val2 - referenceRot * val;
			Vector3 val4 = val3 - ((Component)cart).transform.position;
			Rigidbody component = ((Component)cart).GetComponent<Rigidbody>();
			Rigidbody[] componentsInChildren = ((Component)cart).GetComponentsInChildren<Rigidbody>();
			Rigidbody[] array = componentsInChildren;
			foreach (Rigidbody val5 in array)
			{
				val5.isKinematic = true;
				Transform transform = ((Component)val5).transform;
				transform.position += val4;
				val5.linearVelocity = Vector3.zero;
				val5.angularVelocity = Vector3.zero;
				if ((Object)(object)val5 == (Object)(object)component)
				{
					((Component)val5).transform.rotation = referenceRot;
				}
			}
			((Component)cart).transform.rotation = referenceRot;
			Physics.SyncTransforms();
			TeleportEverythingPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] PlaceCartForAttach: cart.position -> {((Component)cart).transform.position}.");
			}
		}

		private static Vagon FindCartByZdoid(Vector3 pos, ZDOID id)
		{
			//IL_0001: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, CartSearchRadius.Value, cartColliderBuffer);
			for (int i = 0; i < num; i++)
			{
				Vagon componentInParent = ((Component)cartColliderBuffer[i]).GetComponentInParent<Vagon>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().m_uid == id)
					{
						return componentInParent;
					}
				}
			}
			return null;
		}

		private void Awake()
		{
			Instance = this;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable/disable the whole mod.");
			BindItemTransportConfig();
			BindPortalConfig();
			BindAllyTransportConfig();
			BindCartTransportConfig();
			BindEnemyTransportConfig();
			harmony.PatchAll(Assembly.GetExecutingAssembly());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"TeleportEverything v1.1.2 loaded.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void BindEnemyTransportConfig()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			TakeEnemiesWithYou = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "TakeEnemiesWithYou", false, "If true, nearby hostile creatures actively targeting you get pulled through the portal with you. Off by default - this is a deliberate risk, not a convenience."));
			EnemySearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies", "SearchRadius", 6f, new ConfigDescription("Radius in meters to search for hostile creatures currently targeting you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			MaxEnemiesTransported = new SyncedValue<int>(((BaseUnityPlugin)this).Config.Bind<int>("Enemies", "MaxEnemiesTransported", 3, new ConfigDescription("Safety cap on how many enemies can be dragged through a single teleport.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>())));
			EnemySpawnOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies", "SpawnOffset", 6f, new ConfigDescription("How far in front of the destination (in the direction you arrive facing) dragged enemies are placed, so they don't land on top of you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>()));
			EnemySpawnScatterRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Enemies", "SpawnScatterRadius", 3f, new ConfigDescription("Random scatter radius around the spawn offset point, so multiple enemies don't stack exactly on top of each other.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>()));
			EnemiesMaskMode = new SyncedValue<MaskMode>(((BaseUnityPlugin)this).Config.Bind<MaskMode>("Enemies", "EnemiesMaskMode", MaskMode.Disabled, "Disabled = no extra filtering. Block = EnemiesTransportMask names are never dragged along. AllowOnly = ONLY EnemiesTransportMask names can be dragged along."));
			EnemiesTransportMask = new SyncedString(((BaseUnityPlugin)this).Config.Bind<string>("Enemies", "EnemiesTransportMask", "", "Comma-separated creature names (substring match, e.g. 'Troll,Draugr') used by EnemiesMaskMode."));
			PreventTeleportWhileChased = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Enemies", "PreventTeleportWhileChased", false, "If true, you can't use a portal at all while a hostile creature is actively targeting you nearby (\"Vikings don't run\") - same search radius as TakeEnemiesWithYou. Off by default."));
		}

		internal static List<Character> GetTargetingEnemies(Vector3 pos, Character player)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			List<Character> list = new List<Character>();
			enemyCharacterBuffer.Clear();
			Character.GetCharactersInRange(pos, EnemySearchRadius.Value, enemyCharacterBuffer);
			foreach (Character item in enemyCharacterBuffer)
			{
				if ((Object)(object)item == (Object)(object)player || item.IsPlayer() || item.IsTamed())
				{
					continue;
				}
				BaseAI baseAI = item.GetBaseAI();
				if (!((Object)(object)baseAI == (Object)null) && baseAI.HaveTarget() && !((Object)(object)baseAI.GetTargetCreature() != (Object)(object)player) && PassesMask("Enemy", ((Object)item).name, EnemiesMaskMode.Value, EnemiesTransportMask.Value))
				{
					list.Add(item);
					if (list.Count >= MaxEnemiesTransported.Value)
					{
						break;
					}
				}
			}
			return list;
		}

		internal static void TransportTargetingEnemies(Vector3 fromPos, Player player, Vector3 targetPos, Quaternion targetRot)
		{
			//IL_001a: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			if (MaxEnemiesTransported.Value <= 0)
			{
				return;
			}
			List<Character> targetingEnemies = GetTargetingEnemies(fromPos, (Character)(object)player);
			TeleportEverythingPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything EnemyTransport] {targetingEnemies.Count} targeting enem(y/ies) found near teleport-from position (cap={MaxEnemiesTransported.Value}).");
			}
			if (targetingEnemies.Count > 0)
			{
				ShowTransportMessage((Character)(object)player, $"{targetingEnemies.Count} hostile creature(s) followed you through the portal!");
			}
			Vector3 val = targetPos + targetRot * Vector3.forward * EnemySpawnOffset.Value;
			foreach (Character item in targetingEnemies)
			{
				ZNetView component = ((Component)item).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid())
				{
					if (!component.IsOwner())
					{
						component.ClaimOwnership();
					}
					Vector2 val2 = Random.insideUnitCircle * EnemySpawnScatterRadius.Value;
					Vector3 val3 = val + new Vector3(val2.x, 0f, val2.y);
					Rigidbody component2 = ((Component)item).GetComponent<Rigidbody>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.position = val3;
						component2.linearVelocity = Vector3.zero;
						component2.angularVelocity = Vector3.zero;
					}
					((Component)item).transform.position = val3;
					if ((Object)(object)component2 != (Object)null)
					{
						Physics.SyncTransforms();
					}
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						zDO.SetPosition(val3);
					}
					TeleportEverythingPlugin instance2 = Instance;
					if (instance2 != null)
					{
						((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[TeleportEverything EnemyTransport] Dragged '{((Object)item).name}' to {val3}.");
					}
				}
			}
		}

		private void BindItemTransportConfig()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			TransportRestrictedItems = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Items", "TransportRestrictedItems", true, "If true, items that vanilla normally blocks from portal travel (ore, ingots, dragon eggs, ...) can be teleported."));
			TransportFeePercent = new SyncedValue<int>(((BaseUnityPlugin)this).Config.Bind<int>("Items", "TransportFeePercent", 0, new ConfigDescription("Percentage of each restricted item's stack removed as a toll when teleporting with it. 0 = free.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())));
			FeeExemptItems = new SyncedString(((BaseUnityPlugin)this).Config.Bind<string>("Items", "FeeExemptItems", "", "Comma-separated internal item names (e.g. DragonEgg) that never pay the transport fee, even if otherwise restricted. Leave empty for none."));
		}

		private static bool IsFeeExempt(string itemName)
		{
			if (feeExemptSet == null || feeExemptSetSource != FeeExemptItems.Value)
			{
				feeExemptSetSource = FeeExemptItems.Value;
				feeExemptSet = new HashSet<string>(from s in feeExemptSetSource.Split(',')
					select s.Trim() into s
					where s.Length > 0
					select s);
			}
			return feeExemptSet.Contains(itemName);
		}

		internal static void ApplyItemTransportFee(Inventory inventory, Character owner = null)
		{
			if (TransportFeePercent.Value <= 0)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (ItemData item in inventory.GetAllItems().ToList())
			{
				if (item.m_shared.m_teleportable || IsFeeExempt(item.m_shared.m_name))
				{
					continue;
				}
				int num3 = Mathf.CeilToInt((float)item.m_stack * ((float)TransportFeePercent.Value / 100f));
				if (num3 > 0)
				{
					inventory.RemoveItem(item, num3);
					num++;
					num2 += num3;
					TeleportEverythingPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything ItemTransport] Fee taken: {num3}x '{item.m_shared.m_name}' ({TransportFeePercent.Value}% toll).");
					}
				}
			}
			if (num > 0 && (Object)(object)owner != (Object)null)
			{
				ShowTransportMessage(owner, $"Transport toll: {num2} item(s) taken ({TransportFeePercent.Value}%) from {num} restricted stack(s)");
			}
		}

		internal static bool PassesMask(string cacheKey, string characterName, MaskMode mode, string maskCsv)
		{
			if (mode == MaskMode.Disabled)
			{
				return true;
			}
			if (!maskCache.TryGetValue(cacheKey, out (HashSet<string>, string) value) || value.Item2 != maskCsv)
			{
				HashSet<string> item = new HashSet<string>(from s in maskCsv.Split(',')
					select s.Trim() into s
					where s.Length > 0
					select s);
				value = (item, maskCsv);
				maskCache[cacheKey] = value;
			}
			bool flag = value.Item1.Any((string entry) => characterName.Contains(entry));
			return (mode == MaskMode.Block) ? (!flag) : flag;
		}

		private void BindPortalConfig()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			PortalActivationRangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Portal", "ActivationRangeMultiplier", 1f, new ConfigDescription("Multiplier on the portal's activation range (how close you need to be to use it). 1 = vanilla default.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			PortalSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Portal", "SoundVolume", 1f, new ConfigDescription("Volume multiplier for the portal's ambient sound effect. 1 = vanilla default, 0 = silent.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			TransportMessageMode = ((BaseUnityPlugin)this).Config.Bind<MessageMode>("Portal", "MessageMode", MessageMode.Centered, "How transport feature messages (items taxed, cart re-attached, etc.) are shown. NoMessages = none, TopLeft/Centered = vanilla message styles.");
		}

		internal static void ShowTransportMessage(Character player, string text)
		{
			//IL_002e: 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 (TransportMessageMode.Value != MessageMode.NoMessages && !((Object)(object)player == (Object)null))
			{
				MessageType val = (MessageType)((TransportMessageMode.Value != MessageMode.Centered) ? 1 : 2);
				player.Message(val, text, 0, (Sprite)null, false);
			}
		}
	}
	internal interface ISyncedValue
	{
		void WriteTo(ZPackage pkg);

		void ReadFrom(ZPackage pkg);

		void ClearOverride();
	}
	public sealed class SyncedValue<T> : ISyncedValue where T : struct
	{
		private readonly ConfigEntry<T> config;

		private T? serverOverride;

		public T Value => (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && serverOverride.HasValue) ? serverOverride.Value : config.Value;

		internal SyncedValue(ConfigEntry<T> config)
		{
			this.config = config;
			TeleportEverythingServerSync.Registered.Add(this);
		}

		void ISyncedValue.WriteTo(ZPackage pkg)
		{
			object obj = config.Value;
			if (obj is bool flag)
			{
				pkg.Write(flag);
			}
			else if (obj is float num)
			{
				pkg.Write(num);
			}
			else if (obj is int num2)
			{
				pkg.Write(num2);
			}
			else if (typeof(T).IsEnum)
			{
				pkg.Write(Convert.ToInt32(obj));
			}
		}

		void ISyncedValue.ReadFrom(ZPackage pkg)
		{
			if (typeof(T) == typeof(bool))
			{
				serverOverride = (T)(object)pkg.ReadBool();
			}
			else if (typeof(T) == typeof(float))
			{
				serverOverride = (T)(object)pkg.ReadSingle();
			}
			else if (typeof(T) == typeof(int))
			{
				serverOverride = (T)(object)pkg.ReadInt();
			}
			else if (typeof(T).IsEnum)
			{
				serverOverride = (T)Enum.ToObject(typeof(T), pkg.ReadInt());
			}
		}

		void ISyncedValue.ClearOverride()
		{
			serverOverride = null;
		}
	}
	public sealed class SyncedString : ISyncedValue
	{
		private readonly ConfigEntry<string> config;

		private string serverOverride;

		public string Value => (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && serverOverride != null) ? serverOverride : config.Value;

		internal SyncedString(ConfigEntry<string> config)
		{
			this.config = config;
			TeleportEverythingServerSync.Registered.Add(this);
		}

		void ISyncedValue.WriteTo(ZPackage pkg)
		{
			pkg.Write(config.Value ?? "");
		}

		void ISyncedValue.ReadFrom(ZPackage pkg)
		{
			serverOverride = pkg.ReadString();
		}

		void ISyncedValue.ClearOverride()
		{
			serverOverride = null;
		}
	}
	internal static class TeleportEverythingServerSync
	{
		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class ZNet_OnNewConnection_ConfigSync_Patch
		{
			private static void Postfix(ZNetPeer peer)
			{
				peer.m_rpc.Register<ZPackage>("TeleportEverything_ConfigSync", (Action<ZRpc, ZPackage>)delegate(ZRpc rpc, ZPackage pkg)
				{
					ApplyPackage(pkg);
				});
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private static class ZNet_RPC_PeerInfo_ConfigSync_Patch
		{
			private static void Postfix(ZNet __instance, ZRpc rpc)
			{
				if (__instance.IsServer())
				{
					rpc.Invoke("TeleportEverything_ConfigSync", new object[1] { BuildPackage() });
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnDestroy")]
		private static class ZNet_OnDestroy_ConfigSync_Patch
		{
			private static void Postfix()
			{
				foreach (ISyncedValue item in Registered)
				{
					item.ClearOverride();
				}
			}
		}

		private const string RpcName = "TeleportEverything_ConfigSync";

		private static readonly ManualLogSource Log = Logger.CreateLogSource("TeleportEverything.ServerSync");

		internal static readonly List<ISyncedValue> Registered = new List<ISyncedValue>();

		private static ZPackage BuildPackage()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(Registered.Count);
			foreach (ISyncedValue item in Registered)
			{
				item.WriteTo(val);
			}
			return val;
		}

		private static void ApplyPackage(ZPackage pkg)
		{
			try
			{
				int num = pkg.ReadInt();
				if (num != Registered.Count)
				{
					Log.LogWarning((object)$"Server sent {num} synced config value(s) but this client expects {Registered.Count} - mod version mismatch? Ignoring the server's config push, using local config instead.");
					return;
				}
				foreach (ISyncedValue item in Registered)
				{
					item.ReadFrom(pkg);
				}
				Log.LogInfo((object)$"Applied {Registered.Count} synced config value(s) received from the server.");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to apply server config sync (version mismatch?): " + ex.Message + ". Using local config instead."));
			}
		}
	}
}