Decompiled source of ShipTeleportTerminal v1.0.0

ShipTeleportTerminal.dll

Decompiled 3 hours ago
using 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 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("ShipTeleportTerminal")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShipTeleportTerminal")]
[assembly: AssemblyTitle("ShipTeleportTerminal")]
[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 ShipTeleportTerminal
{
	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)
		{
			"teleport", "tp", "beam", "teleporter", "ship teleport", "iteleport", "itp", "inverse", "inverse teleport", "inverse teleporter",
			"teleport inverse", "tp inverse"
		};

		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 IsTeleportCommand(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.IsTeleportCommand(text))
				{
					return true;
				}
				string text2 = TeleportActions.Run(text);
				Plugin.Log.LogInfo((object)("[OnSubmit] teleport handled '" + text + "'"));
				__instance.LoadNewNode(TeleportActions.CreateDisplayNode(text2));
				TeleportActions.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.IsTeleportCommand(text))
				{
					return true;
				}
				__result = TeleportActions.GetKeyword(text);
				Plugin.Log.LogInfo((object)("[ParseWord] returning teleport 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.IsTeleportCommand(text))
				{
					return true;
				}
				string text2 = TeleportActions.Run(text);
				__result = TeleportActions.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 (!TeleportActions.TryGetCommandForNode(node, out string cmd))
				{
					Plugin.V("[LoadNewNode] unrelated");
					return;
				}
				Plugin.Log.LogInfo((object)("[LoadNewNode] teleport keyword node for '" + cmd + "' — running action"));
				_reentry++;
				try
				{
					string text = TeleportActions.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");
			TeleportActions.EnsureKeywordsRegistered(__instance);
			TeleportActions.EnsureHelpText(__instance);
		}

		public static void StartPostfix(Terminal __instance)
		{
			Plugin.Log.LogInfo((object)"[Terminal.Start] postfix hit");
			TeleportActions.EnsureKeywordsRegistered(__instance);
			TeleportActions.EnsureHelpText(__instance);
		}
	}
	internal static class TeleportActions
	{
		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 = "[ShipTeleportTerminal]";

		private const string HelpFingerprint = ">TELEPORT";

		private const string HelpBlock = ">TELEPORT\nBeam the radar-targeted player (same as the teleporter button).\nAlso: TP / BEAM / ITELEPORT / ITP (inverse)\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.IsTeleportCommand(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("teleport");
				EnsureKeyword("tp");
				EnsureKeyword("beam");
				EnsureKeyword("teleporter");
				EnsureKeyword("iteleport");
				EnsureKeyword("itp");
				EnsureKeyword("inverse");
				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 teleport 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 = StripTeleportHelp(text);
				if (text2 != node.displayText)
				{
					node.displayText = text2;
					Plugin.Log.LogInfo((object)("[Help] stripped teleport docs from non-list " + label));
				}
				return false;
			}
			if (text.IndexOf(">TELEPORT", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				if (text != node.displayText)
				{
					node.displayText = text;
				}
				return false;
			}
			node.displayText = InjectHelp(text);
			Plugin.Log.LogInfo((object)("[Help] injected teleport docs into " + label));
			return true;
		}

		private static string StripLegacyHelpHeader(string page)
		{
			if (string.IsNullOrEmpty(page) || page.IndexOf("[ShipTeleportTerminal]", StringComparison.Ordinal) < 0)
			{
				return page;
			}
			return page.Replace("[ShipTeleportTerminal]\n\n", "").Replace("[ShipTeleportTerminal]\n", "").Replace("[ShipTeleportTerminal]", "");
		}

		private static string StripTeleportHelp(string page)
		{
			if (string.IsNullOrEmpty(page) || page.IndexOf(">TELEPORT", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return page;
			}
			if (page.Contains(">TELEPORT\nBeam the radar-targeted player (same as the teleporter button).\nAlso: TP / BEAM / ITELEPORT / ITP (inverse)\n\n"))
			{
				return page.Replace(">TELEPORT\nBeam the radar-targeted player (same as the teleporter button).\nAlso: TP / BEAM / ITELEPORT / ITP (inverse)\n\n", "");
			}
			int num = page.IndexOf(">TELEPORT", 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) + ">TELEPORT\nBeam the radar-targeted player (same as the teleporter button).\nAlso: TP / BEAM / ITELEPORT / ITP (inverse)\n\n" + page.Substring(num3);
				}
			}
			if (!page.EndsWith("\n"))
			{
				page += "\n";
			}
			if (!page.EndsWith("\n\n"))
			{
				page += "\n";
			}
			return page + ">TELEPORT\nBeam the radar-targeted player (same as the teleporter button).\nAlso: TP / BEAM / ITELEPORT / ITP (inverse)\n\n";
		}

		internal static string Run(string input)
		{
			switch (input)
			{
			case "teleporter":
			case "teleport":
			case "tp":
			case "beam":
			case "ship teleport":
				return Fire(inverse: false);
			case "tp inverse":
			case "inverse teleport":
			case "teleport inverse":
			case "iteleport":
			case "itp":
			case "inverse":
			case "inverse teleporter":
				return Fire(inverse: true);
			default:
				return "Unknown teleport command.\n";
			}
		}

		private static ShipTeleporter? ResolveTeleporter(bool inverse)
		{
			try
			{
				ShipTeleporter[] array = Object.FindObjectsOfType<ShipTeleporter>();
				if (array == null || array.Length == 0)
				{
					return null;
				}
				ShipTeleporter val = null;
				ShipTeleporter val2 = null;
				ShipTeleporter[] array2 = array;
				foreach (ShipTeleporter val3 in array2)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						if (val2 == null)
						{
							val2 = val3;
						}
						if (val3.isInverseTeleporter == inverse)
						{
							val = val3;
							break;
						}
					}
				}
				return val ?? (inverse ? null : val2);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Teleport] FindObjectsOfType: " + ex.Message));
				return null;
			}
		}

		private static string Fire(bool inverse)
		{
			if (inverse && Plugin.AllowInverse != null && !Plugin.AllowInverse.Value)
			{
				return "Inverse teleporter commands are disabled in config.\n";
			}
			ShipTeleporter val = ResolveTeleporter(inverse);
			if ((Object)(object)val == (Object)null)
			{
				if (!inverse)
				{
					return "Ship teleporter not found (is it unlocked/bought?).\n";
				}
				return "Inverse teleporter not found (is it unlocked/bought?).\n";
			}
			try
			{
				if (val.cooldownTime > 0f)
				{
					int num = Mathf.CeilToInt(val.cooldownTime);
					return string.Format("{0} cooling down ({1}s).\n", inverse ? "Inverse teleporter" : "Teleporter", num);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Teleport] cooldown read: " + ex.Message));
			}
			if (inverse)
			{
				try
				{
					if (!val.CanUseInverseTeleporter())
					{
						return "Inverse teleporter cannot be used right now.\n";
					}
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("[Teleport] CanUseInverseTeleporter: " + ex2.Message));
				}
			}
			try
			{
				val.PressTeleportButtonOnLocalClient();
				Plugin.Log.LogInfo((object)$"[Teleport] PressTeleportButtonOnLocalClient inverse={inverse} id={val.teleporterId}");
			}
			catch (Exception ex3)
			{
				Plugin.Log.LogWarning((object)("[Teleport] PressTeleportButtonOnLocalClient failed: " + ex3.Message + "; trying ServerRpc"));
				try
				{
					val.PressTeleportButtonServerRpc();
				}
				catch (Exception ex4)
				{
					Plugin.Log.LogWarning((object)("[Teleport] PressTeleportButtonServerRpc: " + ex4.Message));
					return "Teleporter button press failed.\n";
				}
			}
			if (!inverse)
			{
				return "Teleporter activated (radar target).\n";
			}
			return "Inverse teleporter activated.\n";
		}
	}
	[BepInPlugin("com.benhough.lethal.ShipTeleportTerminal", "ShipTeleportTerminal", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.benhough.lethal.ShipTeleportTerminal";

		public const string ModName = "ShipTeleportTerminal";

		public const string ModVersion = "1.0.0";

		private readonly Harmony _harmony = new Harmony("com.benhough.lethal.ShipTeleportTerminal");

		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> AllowInverse { 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: teleport / tp (and inverse variants).");
			AllowInverse = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowInverse", true, "Allow iteleport / itp / inverse for the inverse teleporter.");
			Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", false, "Log terminal/teleporter traces.");
			ManualPatches.Apply(_harmony);
			Log.LogInfo((object)string.Format("{0} v{1} loaded. Verbose={2}", "ShipTeleportTerminal", "1.0.0", Verbose.Value));
		}

		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.ShipTeleportTerminal";

		public const string PLUGIN_NAME = "ShipTeleportTerminal";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}