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 DoorTeleporter v1.0.0
DoorTeleporter.dll
Decompiled 4 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [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("DoorTeleporter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DoorTeleporter")] [assembly: AssemblyTitle("DoorTeleporter")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DoorTeleporter { internal static class ManualPatches { internal static void Apply(Harmony harmony) { try { Prefix(typeof(Terminal), "OnSubmit", typeof(OnSubmitPatch), "Prefix"); Prefix(typeof(Terminal), "ParseWord", typeof(ParseWordPatch), "Prefix", new Type[2] { typeof(string), typeof(int) }); Prefix(typeof(Terminal), "ParsePlayerSentence", typeof(ParseSentencePatch), "Prefix"); Prefix(typeof(Terminal), "LoadNewNode", typeof(LoadNewNodePatch), "Prefix"); Postfix(typeof(Terminal), "Awake", typeof(TerminalLifecyclePatch), "AwakePostfix"); Postfix(typeof(Terminal), "Start", typeof(TerminalLifecyclePatch), "StartPostfix"); } catch (Exception arg) { Plugin.Log.LogError((object)$"ManualPatches.Apply failed: {arg}"); } void Postfix(Type type, string name, Type patchType, string method) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(type, name, (Type[])null, (Type[])null); Plugin.Log.LogInfo((object)("Resolve " + type.Name + "." + name + " => " + ((methodInfo == null) ? "NULL" : "ok"))); if (!(methodInfo == null)) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(patchType, method, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("Patched " + type.Name + "." + name + " postfix " + method)); } } void Prefix(Type type, string name, Type patchType, string method, Type[]? args = null) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown MethodInfo methodInfo = ((args == null) ? AccessTools.Method(type, name, (Type[])null, (Type[])null) : AccessTools.Method(type, name, args, (Type[])null)); Plugin.Log.LogInfo((object)("Resolve " + type.Name + "." + name + " => " + ((methodInfo == null) ? "NULL" : (methodInfo.IsPublic ? "public" : "nonpublic")))); if (!(methodInfo == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(patchType, method, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("Patched " + type.Name + "." + name + " prefix " + method)); } } } } internal static class TerminalInput { internal static string? LastSubmitted; private static readonly HashSet<string> Commands = new HashSet<string>(StringComparer.Ordinal) { "doorport", "dtp", "exitport", "fireexit", "randomexit", "door teleport", "door teleporter" }; internal static string Normalize(string? raw) { if (string.IsNullOrEmpty(raw)) { return ""; } return Regex.Replace(Regex.Replace(raw.ToLowerInvariant(), "[^a-z0-9\\s]", " "), "\\s+", " ").Trim(); } internal static string Extract(Terminal terminal) { try { string text = (((Object)(object)terminal.screenText != (Object)null) ? terminal.screenText.text : null); if (string.IsNullOrEmpty(text)) { return ""; } if (terminal.textAdded > 0 && text.Length >= terminal.textAdded) { return Normalize(text.Substring(text.Length - terminal.textAdded)); } int num = text.LastIndexOf('\n'); return Normalize(((num >= 0) ? text.Substring(num + 1) : text).Trim().TrimStart('>', ' ')); } catch { return ""; } } internal static bool IsDoorPortCommand(string input) { return Commands.Contains(input); } } internal static class OnSubmitPatch { public static bool Prefix(Terminal __instance) { try { string text = (TerminalInput.LastSubmitted = TerminalInput.Extract(__instance)); Plugin.Log.LogInfo((object)$"[OnSubmit] captured='{text}' enabled={Plugin.Enabled?.Value}"); if (Plugin.Enabled == null || !Plugin.Enabled.Value) { return true; } if (!TerminalInput.IsDoorPortCommand(text)) { return true; } string text2 = DoorPortActions.Run(text); Plugin.Log.LogInfo((object)("[OnSubmit] doorport handled '" + text + "'")); __instance.LoadNewNode(DoorPortActions.CreateDisplayNode(text2)); DoorPortActions.ReadyForNextCommand(__instance); return false; } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[OnSubmit] {arg}"); return true; } } } internal static class ParseWordPatch { public static bool Prefix(string playerWord, int specificityRequired, ref TerminalKeyword __result) { if (Plugin.Enabled == null || !Plugin.Enabled.Value) { return true; } try { string text = TerminalInput.Normalize(playerWord); Plugin.V($"[ParseWord] '{playerWord}' -> '{text}' spec={specificityRequired}"); if (!TerminalInput.IsDoorPortCommand(text)) { return true; } __result = DoorPortActions.GetKeyword(text); Plugin.Log.LogInfo((object)("[ParseWord] returning doorport keyword for '" + text + "'")); return false; } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[ParseWord] {arg}"); return true; } } } internal static class ParseSentencePatch { public static bool Prefix(Terminal __instance, ref TerminalNode __result) { if (Plugin.Enabled == null || !Plugin.Enabled.Value) { return true; } try { string text = TerminalInput.LastSubmitted; if (string.IsNullOrEmpty(text)) { text = TerminalInput.Extract(__instance); } Plugin.V("[ParseSentence] input='" + text + "'"); if (string.IsNullOrEmpty(text) || !TerminalInput.IsDoorPortCommand(text)) { return true; } string text2 = DoorPortActions.Run(text); __result = DoorPortActions.CreateDisplayNode(text2); TerminalInput.LastSubmitted = null; Plugin.Log.LogInfo((object)("[ParseSentence] handled '" + text + "'")); return false; } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[ParseSentence] {arg}"); return true; } } } internal static class LoadNewNodePatch { private static int _reentry; public static void Prefix(TerminalNode node) { if ((Object)(object)node == (Object)null || _reentry > 0) { return; } try { if (Plugin.Enabled == null || !Plugin.Enabled.Value) { return; } if (!DoorPortActions.TryGetCommandForNode(node, out string cmd)) { Plugin.V("[LoadNewNode] unrelated"); return; } Plugin.Log.LogInfo((object)("[LoadNewNode] doorport keyword node for '" + cmd + "' — running action")); _reentry++; try { string text = DoorPortActions.Run(cmd); string text2 = (text.EndsWith("\n") ? text : (text + "\n")); if (!text2.EndsWith("\n\n")) { text2 += "\n"; } node.displayText = text2; node.clearPreviousText = true; node.acceptAnything = false; node.overrideOptions = false; } finally { _reentry--; } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"[LoadNewNode] {arg}"); } } } internal static class TerminalLifecyclePatch { public static void AwakePostfix(Terminal __instance) { Plugin.Log.LogInfo((object)"[Terminal.Awake] postfix hit"); DoorPortActions.EnsureKeywordsRegistered(__instance); DoorPortActions.EnsureHelpText(__instance); } public static void StartPostfix(Terminal __instance) { Plugin.Log.LogInfo((object)"[Terminal.Start] postfix hit"); DoorPortActions.EnsureKeywordsRegistered(__instance); DoorPortActions.EnsureHelpText(__instance); } } internal static class DoorPortActions { private static readonly Dictionary<string, TerminalKeyword> Keywords = new Dictionary<string, TerminalKeyword>(); private static readonly Dictionary<TerminalNode, string> NodeCommands = new Dictionary<TerminalNode, string>(); private static bool _registered; private static bool _helpInjected; private const string HelpMarker = "[DoorTeleporter]"; private const string HelpFingerprint = ">DOORPORT"; private const string HelpBlock = ">DOORPORT\nTeleport yourself in front of a random main or fire exit.\nAlso: DTP / EXITPORT / FIREEXIT\n\n"; internal static TerminalNode CreateDisplayNode(string text) { TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>(); string text2 = text ?? ""; if (!text2.EndsWith("\n")) { text2 += "\n"; } if (!text2.EndsWith("\n\n")) { text2 += "\n"; } obj.displayText = text2; obj.clearPreviousText = true; obj.maxCharactersToType = 80; obj.acceptAnything = false; obj.overrideOptions = false; return obj; } internal static void ReadyForNextCommand(Terminal terminal) { try { if (!((Object)(object)terminal?.screenText == (Object)null)) { terminal.screenText.ActivateInputField(); ((Selectable)terminal.screenText).Select(); int num = ((terminal.screenText.text != null) ? terminal.screenText.text.Length : 0); terminal.screenText.caretPosition = num; terminal.screenText.selectionAnchorPosition = num; terminal.screenText.selectionFocusPosition = num; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ReadyForNextCommand] " + ex.Message)); } } internal static bool TryGetCommandForNode(TerminalNode node, out string cmd) { if (NodeCommands.TryGetValue(node, out cmd)) { return true; } string text = node.displayText ?? ""; if (text.StartsWith("Ship teleport command:", StringComparison.OrdinalIgnoreCase)) { cmd = TerminalInput.Normalize(text.Substring("Ship teleport command:".Length)); return TerminalInput.IsDoorPortCommand(cmd); } cmd = ""; return false; } internal static TerminalKeyword GetKeyword(string word) { string text = (word.Contains(" ") ? word.Split(' ')[0] : word); if (Keywords.TryGetValue(text, out TerminalKeyword value) && (Object)(object)value != (Object)null) { return value; } EnsureKeyword(text); return Keywords[text]; } private static void EnsureKeyword(string word) { if (!Keywords.ContainsKey(word)) { TerminalNode val = CreateDisplayNode("Ship teleport command: " + word + "\n"); NodeCommands[val] = word; TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>(); val2.word = word; val2.isVerb = false; val2.specialKeywordResult = val; Keywords[word] = val2; } } internal static void EnsureKeywordsRegistered(Terminal terminal) { try { if (terminal?.terminalNodes?.allKeywords == null) { Plugin.Log.LogInfo((object)"Keyword register skipped: allKeywords null"); return; } EnsureKeyword("doorport"); EnsureKeyword("dtp"); EnsureKeyword("exitport"); EnsureKeyword("fireexit"); EnsureKeyword("randomexit"); if (_registered) { Plugin.V("Keywords already registered"); return; } List<TerminalKeyword> list = new List<TerminalKeyword>(terminal.terminalNodes.allKeywords); foreach (KeyValuePair<string, TerminalKeyword> kv in Keywords) { if (!list.Exists((TerminalKeyword k) => (Object)(object)k != (Object)null && k.word == kv.Key)) { list.Add(kv.Value); } } terminal.terminalNodes.allKeywords = list.ToArray(); _registered = true; Plugin.Log.LogInfo((object)$"Registered doorport keywords (allKeywords={list.Count}, trackedNodes={NodeCommands.Count})"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("EnsureKeywordsRegistered failed: " + ex.Message)); } } internal static void EnsureHelpText(Terminal terminal) { try { if (terminal?.terminalNodes?.specialNodes == null) { return; } int num = 0; for (int i = 0; i < terminal.terminalNodes.specialNodes.Count; i++) { if (TryApplyHelpToNode(terminal.terminalNodes.specialNodes[i], $"specialNodes[{i}]")) { num++; } } TerminalKeyword[] allKeywords = terminal.terminalNodes.allKeywords; if (allKeywords != null) { TerminalKeyword[] array = allKeywords; foreach (TerminalKeyword val in array) { if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(val.word)) { string word = val.word; if ((string.Equals(word, "help", StringComparison.OrdinalIgnoreCase) || string.Equals(word, "other", StringComparison.OrdinalIgnoreCase) || string.Equals(word, "others", StringComparison.OrdinalIgnoreCase)) && TryApplyHelpToNode(val.specialKeywordResult, "keyword:" + word)) { num++; } } } } if (num > 0) { _helpInjected = true; } else if (!_helpInjected) { Plugin.Log.LogInfo((object)"[Help] no command-list page found yet"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Help] " + ex.Message)); } } private static bool IsCommandListPage(string page) { if (string.IsNullOrEmpty(page)) { return false; } bool num = page.IndexOf(">STORE", StringComparison.OrdinalIgnoreCase) >= 0; bool flag = page.IndexOf(">BESTIARY", StringComparison.OrdinalIgnoreCase) >= 0; bool flag2 = page.IndexOf(">STORAGE", StringComparison.OrdinalIgnoreCase) >= 0; bool flag3 = page.IndexOf(">OTHER", StringComparison.OrdinalIgnoreCase) >= 0; if (!num || !(flag || flag2 || flag3)) { return false; } return true; } private static bool TryApplyHelpToNode(TerminalNode? node, string label) { if ((Object)(object)node == (Object)null || string.IsNullOrEmpty(node.displayText)) { return false; } string text = StripLegacyHelpHeader(node.displayText); if (!IsCommandListPage(text)) { string text2 = StripDoorPortHelp(text); if (text2 != node.displayText) { node.displayText = text2; Plugin.Log.LogInfo((object)("[Help] stripped doorport docs from non-list " + label)); } return false; } if (text.IndexOf(">DOORPORT", StringComparison.OrdinalIgnoreCase) >= 0) { if (text != node.displayText) { node.displayText = text; } return false; } node.displayText = InjectHelp(text); Plugin.Log.LogInfo((object)("[Help] injected doorport docs into " + label)); return true; } private static string StripLegacyHelpHeader(string page) { if (string.IsNullOrEmpty(page) || page.IndexOf("[DoorTeleporter]", StringComparison.Ordinal) < 0) { return page; } return page.Replace("[DoorTeleporter]\n\n", "").Replace("[DoorTeleporter]\n", "").Replace("[DoorTeleporter]", ""); } private static string StripDoorPortHelp(string page) { if (string.IsNullOrEmpty(page) || page.IndexOf(">DOORPORT", StringComparison.OrdinalIgnoreCase) < 0) { return page; } if (page.Contains(">DOORPORT\nTeleport yourself in front of a random main or fire exit.\nAlso: DTP / EXITPORT / FIREEXIT\n\n")) { return page.Replace(">DOORPORT\nTeleport yourself in front of a random main or fire exit.\nAlso: DTP / EXITPORT / FIREEXIT\n\n", ""); } int num = page.IndexOf(">DOORPORT", StringComparison.OrdinalIgnoreCase); if (num < 0) { return page; } int num2 = page.IndexOf("\n\n", num); num2 = ((num2 >= 0) ? (num2 + 2) : page.Length); int num3 = num; if (num3 >= 2 && page[num3 - 2] == '\n' && page[num3 - 1] == '\n') { num3 -= 2; } else if (num3 >= 1 && page[num3 - 1] == '\n') { num3--; } return page.Substring(0, num3) + page.Substring(num2); } private static string InjectHelp(string page) { page = StripLegacyHelpHeader(page); int num = page.IndexOf(">OTHER", StringComparison.OrdinalIgnoreCase); if (num < 0) { num = page.IndexOf("OTHER", StringComparison.OrdinalIgnoreCase); } if (num >= 0) { int num2 = page.IndexOf("\n\n", num); if (num2 > num) { int num3 = num2 + 2; return page.Substring(0, num3) + ">DOORPORT\nTeleport yourself in front of a random main or fire exit.\nAlso: DTP / EXITPORT / FIREEXIT\n\n" + page.Substring(num3); } } if (!page.EndsWith("\n")) { page += "\n"; } if (!page.EndsWith("\n\n")) { page += "\n"; } return page + ">DOORPORT\nTeleport yourself in front of a random main or fire exit.\nAlso: DTP / EXITPORT / FIREEXIT\n\n"; } internal static string Run(string input) { if (input != null) { int length = input.Length; if (length <= 8) { if (length != 3) { if (length == 8) { switch (input[0]) { case 'd': break; case 'e': goto IL_0060; case 'f': goto IL_006f; default: goto IL_00c0; } if (input == "doorport") { goto IL_00b8; } } } else if (input == "dtp") { goto IL_00b8; } } else if (length != 10) { if (length != 13) { if (length == 15 && input == "door teleporter") { goto IL_00b8; } } else if (input == "door teleport") { goto IL_00b8; } } else if (input == "randomexit") { goto IL_00b8; } } goto IL_00c0; IL_00b8: return TeleportToRandomDoor(); IL_00c0: return "Unknown doorport command.\n"; IL_0060: if (input == "exitport") { goto IL_00b8; } goto IL_00c0; IL_006f: if (input == "fireexit") { goto IL_00b8; } goto IL_00c0; } private static string TeleportToRandomDoor() { //IL_01ce: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0234: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_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) PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return "Local player not available.\n"; } if (val.isPlayerDead) { return "Can't door-teleport while dead.\n"; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.inShipPhase) { return "No facility doors while in orbit.\n"; } bool flag = Plugin.IncludeMain == null || Plugin.IncludeMain.Value; bool flag2 = Plugin.IncludeFireExits == null || Plugin.IncludeFireExits.Value; if (!flag && !flag2) { return "Both main and fire exits are disabled in config.\n"; } EntranceTeleport[] array; try { array = Object.FindObjectsOfType<EntranceTeleport>(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[DoorPort] FindObjectsOfType: " + ex.Message)); return "Could not find facility doors.\n"; } if (array == null || array.Length == 0) { return "No facility doors found (land on a moon first).\n"; } List<EntranceTeleport> list = new List<EntranceTeleport>(); EntranceTeleport[] array2 = array; foreach (EntranceTeleport val2 in array2) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.entrancePoint == (Object)null || !val2.isEntranceToBuilding) { continue; } if (val2.entranceId == 0) { if (flag) { list.Add(val2); } } else if (flag2) { list.Add(val2); } } if (list.Count == 0) { return "No matching entrances (check IncludeMainEntrance / IncludeFireExits).\n"; } EntranceTeleport val3 = list[Random.Range(0, list.Count)]; Transform entrancePoint = val3.entrancePoint; float num = Plugin.StandBackMeters?.Value ?? 0.35f; Vector3 val4 = entrancePoint.position; try { Vector3 val5 = -entrancePoint.forward; val5.y = 0f; if (((Vector3)(ref val5)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val5)).Normalize(); val4 += val5 * Mathf.Max(0f, num); } } catch { } float y = entrancePoint.eulerAngles.y; try { Vector3 val6 = entrancePoint.position - val4; Quaternion val7 = Quaternion.LookRotation(((Vector3)(ref val6)).normalized, Vector3.up); y = ((Quaternion)(ref val7)).eulerAngles.y; } catch { } try { val.TeleportPlayer(val4, true, y, true, true); Plugin.Log.LogInfo((object)$"[DoorPort] Teleported to entranceId={val3.entranceId} pos={val4} candidates={list.Count}"); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[DoorPort] TeleportPlayer failed: " + ex2.Message)); return "Teleport failed.\n"; } string text = ((val3.entranceId == 0) ? "main entrance" : $"fire exit #{val3.entranceId}"); return "Teleported to " + text + ".\n"; } } [BepInPlugin("com.benhough.lethal.DoorTeleporter", "DoorTeleporter", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "com.benhough.lethal.DoorTeleporter"; public const string ModName = "DoorTeleporter"; public const string ModVersion = "1.0.0"; private readonly Harmony _harmony = new Harmony("com.benhough.lethal.DoorTeleporter"); internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<bool> Enabled { get; private set; } internal static ConfigEntry<bool> IncludeMain { get; private set; } internal static ConfigEntry<bool> IncludeFireExits { get; private set; } internal static ConfigEntry<float> StandBackMeters { get; private set; } internal static ConfigEntry<bool> Verbose { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable terminal commands: doorport / dtp / exitport / fireexit."); IncludeMain = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeMainEntrance", true, "Allow teleporting to the main facility entrance (entranceId 0)."); IncludeFireExits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeFireExits", true, "Allow teleporting to fire-exit entrances (entranceId > 0)."); StandBackMeters = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StandBackMeters", 0.35f, "Nudge slightly back from the entrance point so you stand in front of the door."); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", false, "Log terminal/door-teleport traces."); ManualPatches.Apply(_harmony); Log.LogInfo((object)"DoorTeleporter v1.0.0 loaded."); } internal static void V(string msg) { if (Verbose != null && Verbose.Value) { Log.LogInfo((object)msg); } } } internal static class PluginInfo { public const string PLUGIN_GUID = "com.benhough.lethal.DoorTeleporter"; public const string PLUGIN_NAME = "DoorTeleporter"; public const string PLUGIN_VERSION = "1.0.0"; } }