Decompiled source of TeleportEverything v1.2.10

TeleportEverything.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TeleportEverything")]
[assembly: AssemblyConfiguration("Release")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TeleportEverything
{
	internal static class ConfigLogDump
	{
		internal static void Schedule(BaseUnityPlugin plugin, ManualLogSource log)
		{
			((MonoBehaviour)plugin).StartCoroutine(Run(plugin, log));
		}

		private static IEnumerator Run(BaseUnityPlugin plugin, ManualLogSource log)
		{
			yield return null;
			yield return null;
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				foreach (ConfigDefinition key in plugin.Config.Keys)
				{
					string text = key.Key.ToLowerInvariant();
					if (text.Contains("pass") || text.Contains("token") || text.Contains("secret"))
					{
						continue;
					}
					ConfigEntryBase val = plugin.Config[key];
					if (!object.Equals(val.BoxedValue, val.DefaultValue))
					{
						if (stringBuilder.Length > 0)
						{
							stringBuilder.Append("; ");
						}
						stringBuilder.Append(key.Section).Append('.').Append(key.Key)
							.Append('=')
							.Append(val.BoxedValue);
						if (stringBuilder.Length > 1500)
						{
							stringBuilder.Append("; ...");
							break;
						}
					}
				}
				log.LogInfo((object)("[TeleportEverything] config (changed from default): " + ((stringBuilder.Length == 0) ? "none" : stringBuilder.ToString())));
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[TeleportEverything] config dump failed: " + ex.Message));
			}
		}
	}
	[BepInPlugin("zenox.teleporteverything", "TeleportEverything", "1.2.10")]
	public class TeleportEverythingPlugin : BaseUnityPlugin
	{
		public enum AllyTransportMode
		{
			Disabled,
			FollowingOnly,
			AllTamedNearby,
			AllTamedExceptNamed,
			OnlyNamed
		}

		private readonly struct PendingAllyReattach
		{
			public readonly ZDOID Id;

			public readonly string Name;

			public readonly Vector3 PlacedAt;

			public readonly long OwnerBeforeClaim;

			public readonly long OwnerAfterClaim;

			public readonly float PlacedAtTime;

			public PendingAllyReattach(ZDOID id, string name, Vector3 placedAt, long ownerBeforeClaim, long ownerAfterClaim)
			{
				//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_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)
				Id = id;
				Name = name;
				PlacedAt = placedAt;
				OwnerBeforeClaim = ownerBeforeClaim;
				OwnerAfterClaim = ownerAfterClaim;
				PlacedAtTime = Time.realtimeSinceStartup;
			}
		}

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		private static class Player_UpdateTeleport_AllyReattach_Patch
		{
			private static void Postfix(Player __instance, bool ___m_teleporting)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: 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_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
				if (___m_teleporting || pendingAllyReattachIds.Count == 0 || !ModEnabled.Value)
				{
					return;
				}
				List<PendingAllyReattach> list = new List<PendingAllyReattach>();
				float y = default(float);
				foreach (PendingAllyReattach pendingAllyReattachId in pendingAllyReattachIds)
				{
					GameObject val = ZNetScene.instance.FindInstance(pendingAllyReattachId.Id);
					if ((Object)(object)val == (Object)null)
					{
						float num = Time.realtimeSinceStartup - pendingAllyReattachId.PlacedAtTime;
						if (num < AllyReattachGraceSeconds.Value)
						{
							list.Add(pendingAllyReattachId);
							continue;
						}
						TeleportEverythingPlugin instance = Instance;
						if (instance != null)
						{
							((BaseUnityPlugin)instance).Logger.LogWarning((object)($"[TeleportEverything AllyTransport] MOB DISAPPEARED: '{pendingAllyReattachId.Name}' (ZDOID {pendingAllyReattachId.Id}) was placed at {pendingAllyReattachId.PlacedAt} " + $"{num:0.00}s ago during ally transport, but could not be found near the player even after retrying for {AllyReattachGraceSeconds.Value:0.00}s. " + $"Ownership was {pendingAllyReattachId.OwnerBeforeClaim} -> {pendingAllyReattachId.OwnerAfterClaim} (mySessionId={ZDOMan.GetSessionID()}) at transport time. " + "Likely cause: the ZDO ownership claim for this creature didn't finish propagating before its old zone unloaded."));
						}
						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();
				pendingAllyReattachIds.AddRange(list);
			}
		}

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

			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_003a: 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_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)
				if (__result && ModEnabled.Value && AllyMode.Value != AllyTransportMode.Disabled)
				{
					TransportAllies((Vector3)(((??)activePortalPosition) ?? ((Component)__instance).transform.position), ((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_0041: 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 += LocalizeMessage("zenox_te_hover_allies", ("count", count.ToString()));
					}
				}
			}
		}

		public enum CartTransportMode
		{
			Disabled,
			Enabled,
			OnlyDungeons,
			PortalsOnly
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_CartExitClearance_Patch
		{
			private static void Prefix(Player __instance, ref Vector3 pos, Quaternion rot)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: 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_0049: 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_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_0096: 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)
				if (ModEnabled.Value && CartTransportAllowedNow() && !((Object)(object)FindAttachedCart(((Component)__instance).transform.position, (Character)(object)__instance) == (Object)null))
				{
					float num = (IsDungeonTeleport ? 7f : 3f);
					Vector3 val = pos + rot * Vector3.forward * num;
					TeleportEverythingPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Exit clearance: nudging destination {pos} -> {val} ({num}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_001d: 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_0024: Unknown result type (might be due to invalid IL or missing references)
				if (__result && ModEnabled.Value && CartTransportAllowedNow())
				{
					TransportAttachedCart(((Component)__instance).transform.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_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: 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_003d: 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_0105: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d6: 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));
				}
				LogFloorDiagnostic(((Component)__instance).transform.position, "final reattach");
				PlaceCartForAttach(val, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation, anchorToFloor: false);
				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}.");
				}
				TeleportEverythingPlugin instance4 = Instance;
				if (instance4 != null)
				{
					((BaseUnityPlugin)instance4).Logger.LogInfo((object)("[TeleportEverything CartTransport] Cart '" + ((Object)val).name + "' placed safely nearby, left detached (automatic reattach skipped on every arrival to avoid the joint-rotation-mismatch explosion - see comment above)."));
				}
				ShowTransportMessage((Character)(object)__instance, LocalizeMessage("zenox_te_msg_cart_arrived_detached"));
				if (pendingReattachWasDungeon)
				{
					StartDungeonArrivalFallWatch(((Component)__instance).transform.position);
				}
				pendingReattachWasDungeon = false;
				Rigidbody[] componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].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;
			}
		}

		internal static class Localizer
		{
			private static readonly Type LocalizationType;

			private static readonly PropertyInfo InstanceProperty;

			private static readonly MethodInfo LocalizeMethod;

			private static readonly MethodInfo AddWordMethod;

			private static readonly MethodInfo GetSelectedLanguageMethod;

			private static readonly MethodInfo LoadCsvMethod;

			private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

			private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

			private static readonly ConditionalWeakTable<object, string> localizationLanguage;

			private static readonly List<WeakReference<object>> localizationObjects;

			private static BaseUnityPlugin _plugin;

			private static readonly List<string> fileExtensions;

			private static object Instance => InstanceProperty.GetValue(null);

			private static BaseUnityPlugin plugin
			{
				get
				{
					//IL_009b: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a5: Expected O, but got Unknown
					if (_plugin == null)
					{
						IEnumerable<TypeInfo> source;
						try
						{
							source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
						}
						catch (ReflectionTypeLoadException ex)
						{
							source = from t in ex.Types
								where t != null
								select t.GetTypeInfo();
						}
						_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
					}
					return _plugin;
				}
			}

			internal static string LocalizeRaw(string text)
			{
				return (string)LocalizeMethod.Invoke(Instance, new object[1] { text });
			}

			private static void UpdatePlaceholderText(object localizationInstance, string key)
			{
				localizationLanguage.TryGetValue(localizationInstance, out var value);
				string text = loadedTexts[value][key];
				if (PlaceholderProcessors.TryGetValue(key, out var value2))
				{
					text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
				}
				AddWordMethod.Invoke(localizationInstance, new object[2] { key, text });
			}

			public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string> convertConfigValue = null) where T : notnull
			{
				if (convertConfigValue == null)
				{
					convertConfigValue = (T val) => val.ToString();
				}
				if (!PlaceholderProcessors.ContainsKey(key))
				{
					PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
				}
				config.SettingChanged += delegate
				{
					UpdatePlaceholder();
				};
				if (loadedTexts.ContainsKey((string)GetSelectedLanguageMethod.Invoke(Instance, null)))
				{
					UpdatePlaceholder();
				}
				void UpdatePlaceholder()
				{
					PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
					UpdatePlaceholderText(Instance, key);
				}
			}

			public static void Load()
			{
				object instance = Instance;
				LoadLocalization(instance, (string)GetSelectedLanguageMethod.Invoke(instance, null));
			}

			private static void LoadLocalization(object __instance, string language)
			{
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Expected O, but got Unknown
				//IL_0211: Unknown result type (might be due to invalid IL or missing references)
				//IL_021b: Expected O, but got Unknown
				if (!localizationLanguage.Remove(__instance))
				{
					localizationObjects.Add(new WeakReference<object>(__instance));
				}
				localizationLanguage.Add(__instance, language);
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
					where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
					select f)
				{
					string text = Path.GetFileNameWithoutExtension(item).Split('.')[1];
					if (dictionary.ContainsKey(text))
					{
						Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
					}
					else
					{
						dictionary[text] = item;
					}
				}
				byte[] array = LoadTranslationFromAssembly("English");
				if (array == null)
				{
					throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
				}
				Dictionary<string, string> dictionary2 = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
				if (dictionary2 == null)
				{
					throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
				}
				string text2 = null;
				if (language != "English")
				{
					if (dictionary.ContainsKey(language))
					{
						text2 = File.ReadAllText(dictionary[language]);
					}
					else
					{
						byte[] array2 = LoadTranslationFromAssembly(language);
						if (array2 != null)
						{
							text2 = Encoding.UTF8.GetString(array2);
						}
					}
				}
				if (text2 == null && dictionary.ContainsKey("English"))
				{
					text2 = File.ReadAllText(dictionary["English"]);
				}
				if (text2 != null)
				{
					foreach (KeyValuePair<string, string> item2 in ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
					{
						dictionary2[item2.Key] = item2.Value;
					}
				}
				loadedTexts[language] = dictionary2;
				foreach (KeyValuePair<string, string> item3 in dictionary2)
				{
					UpdatePlaceholderText(__instance, item3.Key);
				}
			}

			static Localizer()
			{
				//IL_00da: 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_0108: Expected O, but got Unknown
				LocalizationType = AccessTools.TypeByName("Localization");
				InstanceProperty = AccessTools.Property(LocalizationType, "instance");
				LocalizeMethod = AccessTools.Method(LocalizationType, "Localize", new Type[1] { typeof(string) }, (Type[])null);
				AddWordMethod = AccessTools.Method(LocalizationType, "AddWord", (Type[])null, (Type[])null);
				GetSelectedLanguageMethod = AccessTools.Method(LocalizationType, "GetSelectedLanguage", (Type[])null, (Type[])null);
				LoadCsvMethod = AccessTools.Method(LocalizationType, "LoadCSV", (Type[])null, (Type[])null);
				PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
				loadedTexts = new Dictionary<string, Dictionary<string, string>>();
				localizationLanguage = new ConditionalWeakTable<object, string>();
				localizationObjects = new List<WeakReference<object>>();
				fileExtensions = new List<string> { ".json", ".yml" };
				new Harmony("zenox.teleporteverything.localizationmanager").Patch((MethodBase)LoadCsvMethod, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}

			private static byte[] LoadTranslationFromAssembly(string language)
			{
				foreach (string fileExtension in fileExtensions)
				{
					byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
					if (array != null)
					{
						return array;
					}
				}
				return null;
			}

			public static byte[] ReadEmbeddedFileBytes(string resourceFileName, Assembly containingAssembly = null)
			{
				using MemoryStream memoryStream = new MemoryStream();
				if ((object)containingAssembly == null)
				{
					containingAssembly = Assembly.GetCallingAssembly();
				}
				string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
				if (text != null)
				{
					containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
				}
				return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
			}
		}

		[HarmonyPatch(typeof(Teleport), "Interact")]
		private static class Teleport_Interact_DungeonTracking_Patch
		{
			private static void Prefix(bool hold, Teleport __instance)
			{
				//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_0041: 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)
				if (!ModEnabled.Value || hold || !((Object)(object)__instance.m_targetPoint != (Object)null))
				{
					return;
				}
				IsDungeonTeleport = true;
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(TeleportGetTeleportPoint(__instance.m_targetPoint) + Vector3.up, Vector3.down, ref val, 1000f, SolidRayMask))
				{
					CurrentDungeonTypeName = ((Object)((Component)((RaycastHit)(ref val)).collider).transform.root).name;
					TeleportEverythingPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)("[TeleportEverything] Dungeon type detected: '" + CurrentDungeonTypeName + "' (raycast hit '" + ((Object)((RaycastHit)(ref val)).collider).name + "')."));
					}
				}
				else
				{
					CurrentDungeonTypeName = null;
					TeleportEverythingPlugin instance2 = Instance;
					if (instance2 != null)
					{
						((BaseUnityPlugin)instance2).Logger.LogInfo((object)"[TeleportEverything] Dungeon type detection: raycast found nothing at target point - CurrentDungeonTypeName stays null.");
					}
				}
			}

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

		[HarmonyPatch(typeof(Player), "UpdateTeleport")]
		private static class Player_UpdateTeleport_EnemyReattach_Patch
		{
			private static void Postfix(bool ___m_teleporting)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: 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_0070: 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_013f: 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_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Unknown result type (might be due to invalid IL or missing references)
				if (___m_teleporting || pendingEnemyReattachIds.Count == 0 || !ModEnabled.Value)
				{
					return;
				}
				float y = default(float);
				foreach (PendingAllyReattach pendingEnemyReattachId in pendingEnemyReattachIds)
				{
					GameObject val = ZNetScene.instance.FindInstance(pendingEnemyReattachId.Id);
					if ((Object)(object)val == (Object)null)
					{
						TeleportEverythingPlugin instance = Instance;
						if (instance != null)
						{
							((BaseUnityPlugin)instance).Logger.LogWarning((object)($"[TeleportEverything EnemyTransport] MOB DISAPPEARED: '{pendingEnemyReattachId.Name}' (ZDOID {pendingEnemyReattachId.Id}) was placed at {pendingEnemyReattachId.PlacedAt} " + $"{Time.realtimeSinceStartup - pendingEnemyReattachId.PlacedAtTime:0.00}s ago during enemy transport, but could not be found near the player after the teleport completed. " + $"Ownership was {pendingEnemyReattachId.OwnerBeforeClaim} -> {pendingEnemyReattachId.OwnerAfterClaim} (mySessionId={ZDOMan.GetSessionID()}) at transport time. " + "Likely cause: the ZDO ownership claim for this creature didn't finish propagating before its old zone unloaded (more likely with several enemies dragged in the same frame)."));
						}
						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 EnemyTransport] Final placement: '{((Object)val).name}' grounded at {position}.");
					}
				}
				pendingEnemyReattachIds.Clear();
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_EnemyTransport_Patch
		{
			private static void Postfix(Player __instance, Vector3 pos, Quaternion rot, bool __result)
			{
				//IL_0022: 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_0029: Unknown result type (might be due to invalid IL or missing references)
				if (__result && ModEnabled.Value && TakeEnemiesWithYou.Value)
				{
					TransportTargetingEnemies(((Component)__instance).transform.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_002e: 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(TeleportWorld), "Teleport")]
		private static class TeleportWorld_Teleport_PreventTeleportWhileChasedMessage_Patch
		{
			private static bool Prefix(Player player)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				if (!ModEnabled.Value || !PreventTeleportWhileChased.Value || (Object)(object)player == (Object)null)
				{
					return true;
				}
				if (GetTargetingEnemies(((Component)player).transform.position, (Character)(object)player).Count > 0)
				{
					((Character)player).Message((MessageType)2, LocalizeMessage("zenox_te_msg_vikings_dont_run"), 0, (Sprite)null, false);
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "IsTeleportable")]
		private static class Inventory_IsTeleportable_ItemTransport_Patch
		{
			private static void Postfix(Inventory __instance, ref bool __result)
			{
				if (!__result && Time.time - lastBlockedItemLogTime >= 2f)
				{
					lastBlockedItemLogTime = Time.time;
					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 blocked by cheat-tier item '" + allItem.m_shared.m_name + "'."));
							}
						}
						else if (!allItem.m_shared.m_teleportable)
						{
							TeleportEverythingPlugin instance2 = Instance;
							if (instance2 != null)
							{
								((BaseUnityPlugin)instance2).Logger.LogInfo((object)("[TeleportEverything ItemTransport] Teleport blocked by restricted item '" + allItem.m_shared.m_name + "'."));
							}
						}
					}
				}
				if (__result || !ModEnabled.Value || !TransportRestrictedItems.Value)
				{
					return;
				}
				if (!TransportCheatTierItems.Value)
				{
					foreach (ItemData allItem2 in __instance.GetAllItems())
					{
						if (allItem2.m_shared.m_toolTier < 1000)
						{
							continue;
						}
						if (Time.time - lastBlockedItemLogTime >= 2f)
						{
							lastBlockedItemLogTime = Time.time;
							TeleportEverythingPlugin instance3 = Instance;
							if (instance3 != null)
							{
								((BaseUnityPlugin)instance3).Logger.LogInfo((object)("[TeleportEverything ItemTransport] Teleport still blocked - inventory contains cheat-tier item '" + allItem2.m_shared.m_name + "' (TransportCheatTierItems is off)."));
							}
						}
						return;
					}
				}
				__result = true;
				if (Time.time - lastOverrideAppliedLogTime >= 2f)
				{
					lastOverrideAppliedLogTime = Time.time;
					TeleportEverythingPlugin instance4 = Instance;
					if (instance4 != null)
					{
						((BaseUnityPlugin)instance4).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 ConfigEntry<float> AllyReattachGraceSeconds;

		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<PendingAllyReattach> pendingAllyReattachIds = new List<PendingAllyReattach>();

		private static Vector3? activePortalPosition;

		private static bool activePortalAllowsAllItems;

		private static ZDOID? pendingReattachCartId;

		public static SyncedValue<CartTransportMode> TransportCartsMode;

		public static ConfigEntry<float> CartSearchRadius;

		public static SyncedValue<bool> TaxCartRestrictedItemsPortals;

		public static SyncedValue<bool> TaxCartRestrictedItemsDungeons;

		public static SyncedValue<bool> BlockCartsWithRestrictedItems;

		public static SyncedValue<bool> PreventCartAutoDetach;

		private const float CartExitExtraDistance = 3f;

		private const float CartDungeonExitExtraDistance = 7f;

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

		private static bool pendingReattachWasDungeon;

		private static bool trackingDungeonArrivalFall;

		private static float dungeonArrivalTrackStartTime;

		private static float dungeonArrivalStartY;

		private static float dungeonArrivalLastLoggedY;

		private static readonly int SolidRayMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });

		private static bool cartAwaitingGround;

		private static float cartAwaitingGroundStartTime;

		private static ZDOID cartAwaitingGroundId;

		private const float CartGroundWaitTimeoutSeconds = 15f;

		public const string PluginGUID = "zenox.teleporteverything";

		public const string PluginName = "TeleportEverything";

		public const string PluginVersion = "1.2.10";

		public static TeleportEverythingPlugin Instance;

		public static ConfigEntry<bool> ModEnabled;

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

		internal static bool IsDungeonTeleport;

		private static readonly Func<Teleport, Vector3> TeleportGetTeleportPoint = AccessTools.MethodDelegate<Func<Teleport, Vector3>>(AccessTools.Method(typeof(Teleport), "GetTeleportPoint", (Type[])null, (Type[])null), (object)null, true);

		internal static string CurrentDungeonTypeName;

		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>();

		private static readonly List<PendingAllyReattach> pendingEnemyReattachIds = new List<PendingAllyReattach>();

		public static SyncedValue<bool> TransportRestrictedItems;

		public static SyncedValue<bool> TransportCheatTierItems;

		public static SyncedValue<int> TransportFeePercent;

		public static SyncedString FeeExemptItems;

		private static HashSet<string> feeExemptSet;

		private static string feeExemptSetSource;

		private static float lastBlockedItemLogTime = -999f;

		private static float lastOverrideAppliedLogTime = -999f;

		private const float ItemLogThrottleSeconds = 2f;

		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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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>()));
			AllyReattachGraceSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Allies", "ReattachGraceSeconds", 2f, new ConfigDescription("Seconds to keep retrying to find a transported ally after the teleport completes, before giving up and logging it as lost. Higher = more tolerant of network lag, at the cost of a longer delay before the 'MOB DISAPPEARED' warning (if it really is lost) appears in the log.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), 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, ""));
		}

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

		private static bool IsFollowing(Character character, string localPlayerName)
		{
			string followedPlayerName = GetFollowedPlayerName(character);
			if (!string.IsNullOrEmpty(followedPlayerName))
			{
				return followedPlayerName == localPlayerName;
			}
			return false;
		}

		internal static List<Character> GetTransportableAllies(Vector3 pos, GameObject followTarget, bool verboseLog = false)
		{
			//IL_003c: 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;
			}
			Player component = followTarget.GetComponent<Player>();
			string text = ((component != null) ? component.GetPlayerName() : null) ?? "";
			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 component2 = ((Component)item).GetComponent<Tameable>();
				MonsterAI component3 = ((Component)item).GetComponent<MonsterAI>();
				if ((Object)(object)component2 == (Object)null || (Object)(object)component3 == (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 (!component2.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;
				}
				bool flag = IsFollowing(item, text);
				Tameable val = component2;
				bool flag2 = (Object)(object)val != (Object)null && val.m_commandable;
				if (value switch
				{
					AllyTransportMode.FollowingOnly => (!flag2 || flag) ? 1 : 0, 
					AllyTransportMode.AllTamedNearby => 1, 
					AllyTransportMode.AllTamedExceptNamed => (!IsNamed(item)) ? 1 : 0, 
					AllyTransportMode.OnlyNamed => IsNamed(item) ? 1 : 0, 
					_ => 0, 
				} == 0)
				{
					if (verboseLog)
					{
						string arg = ((value == AllyTransportMode.FollowingOnly) ? $" (ZDO follow='{flag}', expected player='{text}')" : "");
						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;
				}
				string followedPlayerName = GetFollowedPlayerName(item);
				if (!string.IsNullOrEmpty(followedPlayerName) && followedPlayerName != text)
				{
					if (verboseLog)
					{
						TeleportEverythingPlugin instance6 = Instance;
						if (instance6 != null)
						{
							((BaseUnityPlugin)instance6).Logger.LogInfo((object)("[TeleportEverything AllyTransport] '" + ((Object)item).name + "' skipped: currently following a different player ('" + followedPlayerName + "'), not in this player's custody."));
						}
					}
					continue;
				}
				if (verboseLog)
				{
					TeleportEverythingPlugin instance7 = Instance;
					if (instance7 != null)
					{
						((BaseUnityPlugin)instance7).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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: 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_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: 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, LocalizeMessage("zenox_te_msg_allies_teleported", ("count", transportableAllies.Count.ToString())));
			}
			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())
				{
					continue;
				}
				long owner = component.GetZDO().GetOwner();
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
					ZDOMan instance2 = ZDOMan.instance;
					if (instance2 != null)
					{
						instance2.ForceSendZDO(component.GetZDO().m_uid);
					}
				}
				long owner2 = component.GetZDO().GetOwner();
				TeleportEverythingPlugin instance3 = Instance;
				if (instance3 != null)
				{
					((BaseUnityPlugin)instance3).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] '{((Object)val).name}' (ZDOID {component.GetZDO().m_uid}) ownership: before={owner}, after={owner2}, mySessionId={ZDOMan.GetSessionID()}.");
				}
				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);
				}
				ZDOMan instance4 = ZDOMan.instance;
				if (instance4 != null)
				{
					instance4.ForceSendZDO(component.GetZDO().m_uid);
				}
				pendingAllyReattachIds.Add(new PendingAllyReattach(component.GetZDO().m_uid, ((Object)val).name, val3, owner, owner2));
				TeleportEverythingPlugin instance5 = Instance;
				if (instance5 != null)
				{
					((BaseUnityPlugin)instance5).Logger.LogInfo((object)$"[TeleportEverything AllyTransport] Teleported '{((Object)val).name}' to {val3} (pending final ground placement).");
				}
			}
		}

		private void BindCartTransportConfig()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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. PortalsOnly = the opposite - only through player-built portals, never dungeon rune stones."));
			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>()));
			TaxCartRestrictedItemsPortals = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Carts", "TaxCartRestrictedItemsPortals", true, "If true, the same TransportFeePercent (see [Items]) is also taken from portal-restricted items in the cart's own inventory when transported through a player-built portal."));
			TaxCartRestrictedItemsDungeons = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Carts", "TaxCartRestrictedItemsDungeons", true, "Same as TaxCartRestrictedItemsPortals, but for dungeon rune-stone cart transport specifically."));
			BlockCartsWithRestrictedItems = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Carts", "BlockCartsWithRestrictedItems", false, "If true, a cart containing any portal-restricted or cheat-tier item is left behind entirely instead of being transported (taxed or not) - lets you allow ordinary cart transport while still keeping restricted cargo out of carts specifically."));
			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 IsBlockedDungeonType()
		{
			if (IsDungeonTeleport && CurrentDungeonTypeName != null)
			{
				return CurrentDungeonTypeName.IndexOf("SunkenCrypt", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static bool CartTransportAllowedNow()
		{
			if (IsBlockedDungeonType())
			{
				return false;
			}
			return TransportCartsMode.Value switch
			{
				CartTransportMode.Enabled => true, 
				CartTransportMode.OnlyDungeons => IsDungeonTeleport, 
				CartTransportMode.PortalsOnly => !IsDungeonTeleport, 
				_ => false, 
			};
		}

		private static bool CartHasRestrictedItems(Inventory inventory)
		{
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (!allItem.m_shared.m_teleportable || allItem.m_shared.m_toolTier >= 1000)
				{
					return true;
				}
			}
			return false;
		}

		private static Vagon FindAttachedCart(Vector3 pos, Character player)
		{
			//IL_0000: 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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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 (BlockCartsWithRestrictedItems.Value && (Object)(object)val.m_container != (Object)null && CartHasRestrictedItems(val.m_container.GetInventory()))
			{
				TeleportEverythingPlugin instance3 = Instance;
				if (instance3 != null)
				{
					((BaseUnityPlugin)instance3).Logger.LogInfo((object)("[TeleportEverything CartTransport] Cart '" + ((Object)val).name + "' left behind - contains a portal-restricted or cheat-tier item and BlockCartsWithRestrictedItems is on."));
				}
				ShowTransportMessage((Character)(object)player, LocalizeMessage("zenox_te_msg_cart_left_behind"));
				return;
			}
			if ((IsDungeonTeleport ? TaxCartRestrictedItemsDungeons.Value : TaxCartRestrictedItemsPortals.Value) && (Object)(object)val.m_container != (Object)null)
			{
				ApplyItemTransportFee(val.m_container.GetInventory(), (Character)(object)player);
			}
			LogFloorDiagnostic(targetPos, "t=0 initial placement");
			PlaceCartForAttach(val, targetPos, targetRot, anchorToFloor: true);
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				zDO.SetPosition(((Component)val).transform.position);
			}
			TeleportEverythingPlugin instance4 = Instance;
			if (instance4 != null)
			{
				((BaseUnityPlugin)instance4).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>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].isKinematic = true;
			}
			TeleportEverythingPlugin instance5 = Instance;
			if (instance5 != null)
			{
				ManualLogSource logger = ((BaseUnityPlugin)instance5).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;
			pendingReattachWasDungeon = IsDungeonTeleport;
		}

		internal static void StartDungeonArrivalFallWatch(Vector3 playerPos)
		{
			//IL_0010: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			trackingDungeonArrivalFall = true;
			dungeonArrivalTrackStartTime = Time.time;
			dungeonArrivalStartY = playerPos.y;
			dungeonArrivalLastLoggedY = playerPos.y;
			TeleportEverythingPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Dungeon arrival fall watch started at Y={playerPos.y:F1}.");
			}
		}

		internal static void TickDungeonArrivalFallWatch()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (!trackingDungeonArrivalFall || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			float num = Time.time - dungeonArrivalTrackStartTime;
			float y = ((Component)Player.m_localPlayer).transform.position.y;
			if (Mathf.Abs(y - dungeonArrivalLastLoggedY) >= 5f)
			{
				dungeonArrivalLastLoggedY = y;
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Dungeon arrival fall watch: {num:F1}s after arrival, Y={y:F1} (started at Y={dungeonArrivalStartY:F1}, delta={y - dungeonArrivalStartY:F1}).");
				}
				LogFloorDiagnostic(((Component)Player.m_localPlayer).transform.position, $"fall watch @{num:F1}s");
			}
			if (num >= 10f)
			{
				trackingDungeonArrivalFall = false;
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Dungeon arrival fall watch ended after 10s. Final Y={y:F1} (started at Y={dungeonArrivalStartY:F1}, total delta={y - dungeonArrivalStartY:F1}).");
				}
			}
		}

		private static void LogFloorDiagnostic(Vector3 pos, string context)
		{
			//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_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)
			//IL_00ff: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(pos + Vector3.up, Vector3.down, ref val, 1000f, SolidRayMask))
			{
				string text = ((Object)((Component)((RaycastHit)(ref val)).collider).transform).name;
				Transform parent = ((Component)((RaycastHit)(ref val)).collider).transform.parent;
				int num = 0;
				while ((Object)(object)parent != (Object)null && num < 4)
				{
					text = ((Object)parent).name + "/" + text;
					parent = parent.parent;
					num++;
				}
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Floor diagnostic ({context}): raycast from {pos} hit '{text}' (layer={LayerMask.LayerToName(((Component)((RaycastHit)(ref val)).collider).gameObject.layer)}) at Y={((RaycastHit)(ref val)).point.y:F2}, {((RaycastHit)(ref val)).distance:F2}m away.");
				}
			}
			else
			{
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Floor diagnostic ({context}): raycast from {pos} hit NOTHING within 1000m straight down.");
				}
			}
		}

		private static void PlaceCartForAttach(Vagon cart, Vector3 referencePos, Quaternion referenceRot, bool anchorToFloor)
		{
			//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)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0033: 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_003d: 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_0044: 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_007f: 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_008b: 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_0052: 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_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_00c2: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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 - referenceRot * val;
			if (anchorToFloor)
			{
				float y = default(float);
				if (ZoneSystem.instance.FindFloor(val2, ref y))
				{
					val2.y = y;
				}
				else
				{
					val2.y = ZoneSystem.instance.GetSolidHeight(val2) + 0.5f;
				}
			}
			Vector3 val3 = val2 - ((Component)cart).transform.position;
			Rigidbody component = ((Component)cart).GetComponent<Rigidbody>();
			Rigidbody[] componentsInChildren = ((Component)cart).GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody val4 in componentsInChildren)
			{
				val4.isKinematic = true;
				Transform transform = ((Component)val4).transform;
				transform.position += val3;
				val4.linearVelocity = Vector3.zero;
				val4.angularVelocity = Vector3.zero;
				if ((Object)(object)val4 == (Object)(object)component)
				{
					((Component)val4).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 void StartCartGroundWait(Vagon cart)
		{
			//IL_002f: 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)
			ZNetView component = ((Component)cart).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				cartAwaitingGround = true;
				cartAwaitingGroundStartTime = Time.time;
				cartAwaitingGroundId = component.GetZDO().m_uid;
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)("[TeleportEverything CartTransport] Holding cart '" + ((Object)cart).name + "' kinematic until a real floor is confirmed beneath it."));
				}
			}
		}

		internal static void TickCartGroundWait()
		{
			//IL_002b: 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)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (!cartAwaitingGround || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			float num = Time.time - cartAwaitingGroundStartTime;
			Vagon val = FindCartByZdoid(((Component)Player.m_localPlayer).transform.position, cartAwaitingGroundId);
			float num2 = default(float);
			if ((Object)(object)val == (Object)null)
			{
				cartAwaitingGround = false;
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Ground wait ended after {num:F1}s - cart no longer found nearby.");
				}
			}
			else if (ZoneSystem.instance.FindFloor(((Component)val).transform.position, ref num2))
			{
				Vector3 position = ((Component)val).transform.position;
				position.y = num2;
				((Component)val).transform.position = position;
				Physics.SyncTransforms();
				ZNetView component = ((Component)val).GetComponent<ZNetView>();
				if (component != null)
				{
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						zDO.SetPosition(position);
					}
				}
				Rigidbody[] componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].isKinematic = false;
				}
				cartAwaitingGround = false;
				TeleportEverythingPlugin instance2 = Instance;
				if (instance2 != null)
				{
					((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[TeleportEverything CartTransport] Real floor confirmed after {num:F1}s at Y={num2:F1} - released cart to normal physics.");
				}
			}
			else if (num >= 15f)
			{
				Rigidbody[] componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].isKinematic = false;
				}
				cartAwaitingGround = false;
				TeleportEverythingPlugin instance3 = Instance;
				if (instance3 != null)
				{
					((BaseUnityPlugin)instance3).Logger.LogWarning((object)$"[TeleportEverything CartTransport] No floor found under cart '{((Object)val).name}' after {15f}s - releasing anyway as a safety net (may still fall - please report if this happens).");
				}
			}
		}

		private static Vagon FindCartByZdoid(Vector3 pos, ZDOID id)
		{
			//IL_0000: 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_0053: 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()
		{
			ConfigLogDump.Schedule((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger);
			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());
			Localizer.Load();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"TeleportEverything v1.2.10 loaded.");
		}

		internal static string LocalizeMessage(string key, params (string Placeholder, string Value)[] replacements)
		{
			string text = Localizer.LocalizeRaw("$" + key);
			for (int i = 0; i < replacements.Length; i++)
			{
				(string Placeholder, string Value) tuple = replacements[i];
				string item = tuple.Placeholder;
				string item2 = tuple.Value;
				text = text.Replace("{" + item + "}", item2);
			}
			return text;
		}

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

		private void Update()
		{
			TickDungeonArrivalFallWatch();
			TickCartGroundWait();
		}

		private void BindEnemyTransportConfig()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0010: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: 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, LocalizeMessage("zenox_te_msg_enemies_followed", ("count", targetingEnemies.Count.ToString())));
			}
			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())
				{
					continue;
				}
				long owner = component.GetZDO().GetOwner();
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
					ZDOMan instance2 = ZDOMan.instance;
					if (instance2 != null)
					{
						instance2.ForceSendZDO(component.GetZDO().m_uid);
					}
				}
				long owner2 = component.GetZDO().GetOwner();
				TeleportEverythingPlugin instance3 = Instance;
				if (instance3 != null)
				{
					((BaseUnityPlugin)instance3).Logger.LogInfo((object)$"[TeleportEverything EnemyTransport] '{((Object)item).name}' (ZDOID {component.GetZDO().m_uid}) ownership: before={owner}, after={owner2}, mySessionId={ZDOMan.GetSessionID()}.");
				}
				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;
					component2.isKinematic = true;
				}
				((Component)item).transform.position = val3;
				if ((Object)(object)component2 != (Object)null)
				{
					Physics.SyncTransforms();
				}
				ZDO zDO = component.GetZDO();
				if (zDO != null)
				{
					zDO.SetPosition(val3);
				}
				ZDOMan instance4 = ZDOMan.instance;
				if (instance4 != null)
				{
					instance4.ForceSendZDO(component.GetZDO().m_uid);
				}
				pendingEnemyReattachIds.Add(new PendingAllyReattach(component.GetZDO().m_uid, ((Object)item).name, val3, owner, owner2));
				TeleportEverythingPlugin instance5 = Instance;
				if (instance5 != null)
				{
					((BaseUnityPlugin)instance5).Logger.LogInfo((object)$"[TeleportEverything EnemyTransport] Dragged '{((Object)item).name}' to {val3} (pending final ground placement).");
				}
			}
		}

		private void BindItemTransportConfig()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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."));
			TransportCheatTierItems = new SyncedValue<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("Items", "TransportCheatTierItems", true, "If true, also bypasses vanilla's tool-tier 1000+ portal block (normally meant for debug/cheat items, but also seen on at least one legitimate endgame item). If false, any item with this flag still blocks the whole portal use, same as vanilla."));
			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(ItemData item)
		{
			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);
			}
			if (!feeExemptSet.Contains(item.m_shared.m_name))
			{
				if ((Object)(object)item.m_dropPrefab != (Object)null)
				{
					return feeExemptSet.Contains(((Object)item.m_dropPrefab).name);
				}
				return false;
			}
			return true;
		}

		internal static void ApplyItemTransportFee(Inventory inventory, Character owner = null)
		{
			if (TransportFeePercent.Value <= 0)
			{
				return;
			}
			if (activePortalPosition.HasValue && activePortalAllowsAllItems)
			{
				TeleportEverythingPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)"[TeleportEverything ItemTransport] No transport fee - this portal already allows all items in vanilla (m_allowAllItems).");
				}
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (ItemData item in inventory.GetAllItems().ToList())
			{
				if (item.m_shared.m_teleportable || IsFeeExempt(item))
				{
					continue;
				}
				int num3 = Mathf.CeilToInt((float)item.m_stack * ((float)TransportFeePercent.Value / 100f));
				if (num3 > 0)
				{
					inventory.RemoveItem(item, num3);
					num++;
					num2 += num3;
					TeleportEverythingPlugin instance2 = Instance;
					if (instance2 != null)
					{
						((BaseUnityPlugin)instance2).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, LocalizeMessage("zenox_te_msg_transport_toll", ("amount", num2.ToString()), ("percent", TransportFeePercent.Value.ToString()), ("stacks", num.ToString())));
			}
		}

		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)
			{
				value = (new HashSet<string>(from s in maskCsv.Split(',')
					select s.Trim() into s
					where s.Length > 0
					select s), maskCsv);
				maskCache[cacheKey] = value;
			}
			bool flag = value.Item1.Any((string entry) => characterName.Contains(entry));
			if (mode != MaskMode.Block)
			{
				return flag;
			}
			return !flag;
		}

		private void BindPortalConfig()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0027: 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)
			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
		{
			get
			{
				if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || !serverOverride.HasValue)
				{
					return config.Value;
				}
				return serverOverride.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
		{
			get
			{
				if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || serverOverride == null)
				{
					return config.Value;
				}
				return serverOverride;
			}
		}

		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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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."));
			}
		}
	}
}