Decompiled source of WarpBack v1.0.0

WarpBack.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("WarpBack")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WarpBack")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a2cbf801-c072-46d1-86f2-e780de2bc74d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace WarpBack;

[BepInPlugin("azumi.warpback", "WarpBack", "1.0.0")]
public class WarpBackPlugin : BaseUnityPlugin
{
	internal static WarpBackPlugin Instance;

	internal static ManualLogSource Log;

	private Harmony harmony;

	internal static ConfigEntry<Key> InitialPositionWarpKey;

	internal static ConfigEntry<Key> SavePositionKey;

	internal static ConfigEntry<Key> LoadPositionWarpKey;

	internal static ConfigEntry<Key> TeleporterKey;

	private static Vector3 savedPosition;

	private static Quaternion savedRotation;

	private static bool hasSavedPosition;

	private static float lastWarpPressTime;

	private static float lastSavePositionPressTime;

	private static float lastWarpBackPressTime;

	private static float lastTeleporterPressTime;

	private const float InputCooldown = 0.2f;

	private void Awake()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("azumi.warpback");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"WarpBack loaded.");
		InitialPositionWarpKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Initial Position Warp Key", (Key)97, "Key used to warp to initial ship position.");
		SavePositionKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Save Position Key", (Key)98, "Key used to save the current player position.");
		LoadPositionWarpKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Load Position Warp Key", (Key)99, "Key used to warp to the saved position, or the initial ship position if no saved position exists.");
		TeleporterKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Remote Teleporter Key", (Key)100, "Key used to remotely press the ship teleporter button.");
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Initial Position Warp Key: {InitialPositionWarpKey.Value}");
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Save Position Key: {SavePositionKey.Value}");
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Load Position Warp Key: {LoadPositionWarpKey.Value}");
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Remote Teleporter Key: {TeleporterKey.Value}");
	}

	internal static void CheckInput()
	{
		if (Keyboard.current != null)
		{
			CheckWarpInput();
			CheckSavePositionInput();
			CheckWarpBackInput();
			CheckTeleporterInput();
		}
	}

	private static void CheckWarpInput()
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		Key value = InitialPositionWarpKey.Value;
		if ((int)value != 0)
		{
			ButtonControl val = (ButtonControl)(object)Keyboard.current[value];
			if (val != null && val.wasPressedThisFrame && !(Time.time - lastWarpPressTime < 0.2f))
			{
				lastWarpPressTime = Time.time;
				Log.LogInfo((object)$"Initial position warp key pressed: {value}");
				TryWarpLocalPlayer();
			}
		}
	}

	private static void CheckSavePositionInput()
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		Key value = SavePositionKey.Value;
		if ((int)value != 0)
		{
			ButtonControl val = (ButtonControl)(object)Keyboard.current[value];
			if (val != null && val.wasPressedThisFrame && !(Time.time - lastSavePositionPressTime < 0.2f))
			{
				lastSavePositionPressTime = Time.time;
				Log.LogInfo((object)$"Save position key pressed: {value}");
				TrySavePosition();
			}
		}
	}

	private static void CheckWarpBackInput()
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		Key value = LoadPositionWarpKey.Value;
		if ((int)value != 0)
		{
			ButtonControl val = (ButtonControl)(object)Keyboard.current[value];
			if (val != null && val.wasPressedThisFrame && !(Time.time - lastWarpBackPressTime < 0.2f))
			{
				lastWarpBackPressTime = Time.time;
				Log.LogInfo((object)$"Load position warp key pressed: {value}");
				TryWarpBack();
			}
		}
	}

	private static void CheckTeleporterInput()
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		Key value = TeleporterKey.Value;
		if ((int)value != 0)
		{
			ButtonControl val = (ButtonControl)(object)Keyboard.current[value];
			if (val != null && val.wasPressedThisFrame && !(Time.time - lastTeleporterPressTime < 0.2f))
			{
				lastTeleporterPressTime = Time.time;
				Log.LogInfo((object)$"Remote teleporter key pressed: {value}");
				TryRemoteTeleporter();
			}
		}
	}

	public static void TrySavePosition()
	{
		//IL_0093: 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_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_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)StartOfRound.Instance == (Object)null)
		{
			ShowNotification("WarpBack", "Unable to access the current game state.");
			return;
		}
		PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
		if ((Object)(object)val == (Object)null)
		{
			ShowNotification("WarpBack", "Unable to find the local player.");
		}
		else if (CanUseWarpFunctions(val))
		{
			if (val.isPlayerDead)
			{
				ShowNotification("WarpBack", "You cannot save your position while dead.");
				return;
			}
			savedPosition = ((Component)val).transform.position;
			savedRotation = ((Component)val).transform.rotation;
			hasSavedPosition = true;
			Log.LogInfo((object)($"Saved position: {savedPosition} / " + $"rotation: {((Quaternion)(ref savedRotation)).eulerAngles}"));
			ShowNotification("WarpBack", "Position saved successfully.\n" + $"X: {savedPosition.x:F1}  " + $"Y: {savedPosition.y:F1}  " + $"Z: {savedPosition.z:F1}");
		}
	}

	public static void TryWarpBack()
	{
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)StartOfRound.Instance == (Object)null)
		{
			ShowNotification("WarpBack", "Unable to access the current game state.");
			return;
		}
		PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
		if ((Object)(object)val == (Object)null)
		{
			ShowNotification("WarpBack", "Unable to find the local player.");
		}
		else
		{
			if (!CanUseWarpFunctions(val))
			{
				return;
			}
			if (val.isPlayerDead)
			{
				ShowNotification("WarpBack", "You cannot warp while dead.");
				return;
			}
			Vector3 position;
			if (hasSavedPosition)
			{
				position = savedPosition;
				Log.LogInfo((object)("LoadPositionWarp: Saved position found. " + $"Warping player {val.playerClientId} " + $"to saved position {position}"));
			}
			else
			{
				Transform shipSpawnPoint = GetShipSpawnPoint();
				if ((Object)(object)shipSpawnPoint == (Object)null)
				{
					Log.LogWarning((object)"LoadPositionWarp: No saved position and ship spawn point was not found.");
					ShowNotification("WarpBack", "No saved position and the initial ship position could not be found.");
					return;
				}
				position = shipSpawnPoint.position;
				Log.LogInfo((object)("LoadPositionWarp: No saved position. " + $"Warping player {val.playerClientId} " + $"to initial ship position {position}"));
			}
			val.TeleportPlayer(position, false, 0f, false, true);
			val.ResetPlayerBloodObjects(true);
			val.isInElevator = true;
			val.isInHangarShipRoom = true;
			val.isInsideFactory = false;
			ShowNotification("WarpBack", hasSavedPosition ? ("Warped to the saved position.\n" + $"X: {position.x:F1}  " + $"Y: {position.y:F1}  " + $"Z: {position.z:F1}") : ("No saved position.\nWarped to the initial ship position.\n" + $"X: {position.x:F1}  " + $"Y: {position.y:F1}  " + $"Z: {position.z:F1}"));
		}
	}

	public static void TryRemoteTeleporter()
	{
		if ((Object)(object)StartOfRound.Instance == (Object)null)
		{
			ShowNotification("WarpBack", "Unable to access the current game state.");
			return;
		}
		PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
		if ((Object)(object)val == (Object)null)
		{
			ShowNotification("WarpBack", "Unable to find the local player.");
		}
		else
		{
			if (!CanUseWarpFunctions(val))
			{
				return;
			}
			if (val.isPlayerDead)
			{
				ShowNotification("WarpBack", "You cannot use the teleporter while dead.");
				return;
			}
			ShipTeleporter[] array = Object.FindObjectsOfType<ShipTeleporter>();
			if (array == null || array.Length == 0)
			{
				Log.LogInfo((object)"Remote teleporter blocked: no ShipTeleporter found.");
				ShowNotification("WarpBack", "No teleporter was found.");
				return;
			}
			ShipTeleporter val2 = null;
			for (int i = 0; i < array.Length; i++)
			{
				if (!((Object)(object)array[i] == (Object)null) && !array[i].isInverseTeleporter)
				{
					val2 = array[i];
					break;
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Log.LogInfo((object)"Remote teleporter blocked: normal teleporter not found.");
				ShowNotification("WarpBack", "No normal teleporter is available.");
				return;
			}
			if ((Object)(object)val2.buttonTrigger != (Object)null && !val2.buttonTrigger.interactable)
			{
				Log.LogInfo((object)("Remote teleporter blocked: teleporter is on cooldown. " + $"Teleporter ID: {val2.teleporterId}"));
				ShowNotification("WarpBack", "The teleporter is currently on cooldown.");
				return;
			}
			if ((Object)(object)StartOfRound.Instance.mapScreen == (Object)null)
			{
				Log.LogWarning((object)"Remote teleporter blocked: map screen not found.");
				ShowNotification("WarpBack", "Unable to access the ship monitor.");
				return;
			}
			if (StartOfRound.Instance.allPlayerScripts == null || StartOfRound.Instance.allPlayerScripts.Length == 0)
			{
				Log.LogWarning((object)"Remote teleporter blocked: player list not found.");
				ShowNotification("WarpBack", "Unable to access the player list.");
				return;
			}
			int num = -1;
			for (int j = 0; j < StartOfRound.Instance.allPlayerScripts.Length; j++)
			{
				if ((Object)(object)StartOfRound.Instance.allPlayerScripts[j] == (Object)(object)val)
				{
					num = j;
					break;
				}
			}
			if (num < 0)
			{
				Log.LogWarning((object)"Remote teleporter blocked: local player was not found.");
				ShowNotification("WarpBack", "Unable to select the local player.");
				return;
			}
			Log.LogInfo((object)("WarpBack: Switching radar target to local player. " + $"Index: {num}, " + $"Player ID: {val.playerClientId}"));
			StartOfRound.Instance.mapScreen.SwitchRadarTargetAndSync(num);
			Log.LogInfo((object)("WarpBack: Activating normal teleporter. " + $"Player ID: {val.playerClientId}, " + $"Teleporter ID: {val2.teleporterId}"));
			val2.PressTeleportButtonOnLocalClient();
			Log.LogInfo((object)("WarpBack: PressTeleportButtonOnLocalClient() called. " + $"Player ID: {val.playerClientId}, " + $"Teleporter ID: {val2.teleporterId}"));
			ShowNotification("WarpBack", "Teleporter request sent.");
		}
	}

	public static void TryWarpLocalPlayer()
	{
		//IL_0227: 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_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)StartOfRound.Instance == (Object)null)
		{
			Log.LogWarning((object)"Initial position warp blocked: StartOfRound instance not found.");
			ShowNotification("WarpBack", "Unable to access the current game state.");
			return;
		}
		PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
		if ((Object)(object)val == (Object)null)
		{
			Log.LogWarning((object)"Initial position warp blocked: local player not found.");
			ShowNotification("WarpBack", "Unable to find the local player.");
			return;
		}
		if (!StartOfRound.Instance.inShipPhase)
		{
			Log.LogInfo((object)"Initial position warp blocked: not in orbit.");
			ShowNotification("WarpBack", "This function can only be used while in orbit.");
			return;
		}
		if (val.inTerminalMenu)
		{
			Log.LogInfo((object)"Initial position warp blocked: terminal menu open.");
			ShowNotification("WarpBack", "Please close the terminal before using this function.");
			return;
		}
		if (val.isTypingChat)
		{
			Log.LogInfo((object)"Initial position warp blocked: player is typing chat.");
			ShowNotification("WarpBack", "This function cannot be used while typing in chat.");
			return;
		}
		Terminal val2 = Object.FindObjectOfType<Terminal>();
		if ((Object)(object)val2 != (Object)null && val2.terminalInUse)
		{
			Log.LogInfo((object)"Initial position warp blocked: terminal is in use.");
			ShowNotification("WarpBack", "This function cannot be used while the terminal is in use.");
			return;
		}
		if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.chatTextField != (Object)null && HUDManager.Instance.chatTextField.isFocused)
		{
			Log.LogInfo((object)"Initial position warp blocked: chat field focused.");
			ShowNotification("WarpBack", "This function cannot be used while typing in chat.");
			return;
		}
		if (val.isPlayerDead)
		{
			Log.LogInfo((object)"Initial position warp blocked: player is dead.");
			ShowNotification("WarpBack", "You cannot warp while dead.");
			return;
		}
		Transform shipSpawnPoint = GetShipSpawnPoint();
		if ((Object)(object)shipSpawnPoint == (Object)null)
		{
			Log.LogWarning((object)"Initial position warp blocked: failed to find ship spawn point.");
			ShowNotification("WarpBack", "The initial ship position could not be found.");
			return;
		}
		Vector3 position = shipSpawnPoint.position;
		val.TeleportPlayer(position, false, 0f, false, true);
		val.isInElevator = true;
		val.isInHangarShipRoom = true;
		val.isInsideFactory = false;
		val.ResetPlayerBloodObjects(true);
		Log.LogInfo((object)("InitialPositionWarp: Warped player " + $"{val.playerClientId} " + $"to initial ship position {position}"));
		ShowNotification("WarpBack", "Warped to the initial ship position.\n" + $"X: {position.x:F1}  " + $"Y: {position.y:F1}  " + $"Z: {position.z:F1}");
	}

	private static bool CanUseWarpFunctions(PlayerControllerB localPlayer)
	{
		if (!StartOfRound.Instance.inShipPhase)
		{
			Log.LogInfo((object)"WarpBack function blocked: not in orbit.");
			ShowNotification("WarpBack", "This function can only be used while in orbit.");
			return false;
		}
		if (localPlayer.inTerminalMenu)
		{
			Log.LogInfo((object)"Warp function blocked: terminal menu open.");
			ShowNotification("WarpBack", "Please close the terminal before using this function.");
			return false;
		}
		if (localPlayer.isTypingChat)
		{
			Log.LogInfo((object)"Warp function blocked: player is typing chat.");
			ShowNotification("WarpBack", "This function cannot be used while typing in chat.");
			return false;
		}
		Terminal val = Object.FindObjectOfType<Terminal>();
		if ((Object)(object)val != (Object)null && val.terminalInUse)
		{
			Log.LogInfo((object)"Warp function blocked: terminal is in use.");
			ShowNotification("WarpBack", "This function cannot be used while the terminal is in use.");
			return false;
		}
		if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.chatTextField != (Object)null && HUDManager.Instance.chatTextField.isFocused)
		{
			Log.LogInfo((object)"Warp function blocked: chat field focused.");
			return false;
		}
		return true;
	}

	private static void ShowNotification(string title, string message)
	{
		Log.LogInfo((object)("Notification: " + title + " - " + message));
		if ((Object)(object)HUDManager.Instance == (Object)null)
		{
			return;
		}
		try
		{
			HUDManager.Instance.DisplayTip(title, message, false, false, "LC_Tip1");
		}
		catch (Exception arg)
		{
			Log.LogWarning((object)$"Failed to display notification: {arg}");
		}
	}

	private static Transform GetShipSpawnPoint()
	{
		if ((Object)(object)StartOfRound.Instance == (Object)null)
		{
			return null;
		}
		if (StartOfRound.Instance.playerSpawnPositions == null)
		{
			return null;
		}
		if (StartOfRound.Instance.playerSpawnPositions.Length == 0)
		{
			return null;
		}
		return StartOfRound.Instance.playerSpawnPositions[0];
	}
}
[HarmonyPatch(typeof(HUDManager))]
internal static class HUDManagerPatch
{
	[HarmonyPatch("Update")]
	[HarmonyPostfix]
	private static void UpdatePatch()
	{
		WarpBackPlugin.CheckInput();
	}
}