Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TeleportEverything v1.2.10
TeleportEverything.dll
Decompiled a month agousing 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.")); } } } }