Decompiled source of TeleportRay v1.0.1

TeleportRay.dll

Decompiled 20 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 TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("TeleportRay")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TeleportRay")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c92eb136-a7a9-4840-940d-7cacbb5e7dd8")]
[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 TeleportRay;

[BepInPlugin("azumi.teleportray", "TeleportRay", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigFile ConfigFile;

	internal static ConfigEntry<bool> TeleportRayEnabled;

	internal static ConfigEntry<bool> MarkerStatusUIEnabled;

	internal static ConfigEntry<string> RayColor;

	internal static ConfigEntry<float> PositionX;

	internal static ConfigEntry<float> PositionY;

	internal static ConfigEntry<Key> CurveTeleportKey;

	internal static ConfigEntry<Key> MarkerTeleportKey;

	internal static ConfigEntry<Key> MarkerTeleportBKey;

	internal static ConfigEntry<Key> StraightTeleportKey;

	internal static ConfigEntry<float> StraightTeleportDistance;

	internal static ConfigEntry<bool> AllowClients;

	internal static ConfigEntry<Key> ResetMarkerTeleportKey;

	internal static TeleportRayController Controller;

	private static GameObject runnerObject;

	private void Awake()
	{
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Expected O, but got Unknown
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigFile = ((BaseUnityPlugin)this).Config;
		Log.LogInfo((object)"TeleportRay loaded.");
		TeleportRayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TeleportRay Enabled", true, "Enable or disable the TeleportRay system.");
		AllowClients = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Allow Clients", true, "Allow connected clients to use TeleportRay. Host only; clients receive the host setting.");
		MarkerStatusUIEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Marker Teleport UI Enabled", true, "Show or hide the MARKER: A / B status text.");
		RayColor = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Ray Color", "#00F0FF", "Color of the ray, circles, and marker status text in HEX format, for example #00F0FF.");
		CurveTeleportKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Curve Teleport Key", (Key)34, "Press once to show the Curve Teleport ray. Press again to teleport.");
		StraightTeleportKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Straight Teleport Key", (Key)39, "Toggle a straight ray up to the configured distance.");
		MarkerTeleportKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Marker Teleport A Key", (Key)38, "Place or return to Marker Teleport A.");
		MarkerTeleportBKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Marker Teleport B Key", (Key)17, "Place or return to Marker Teleport B.");
		ResetMarkerTeleportKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Reset Marker Teleport Key", (Key)98, "Reset both teleport rays and Marker Teleport A/B destinations.");
		StraightTeleportDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Straight Teleport Distance", 100f, new ConfigDescription("Maximum Straight Teleport distance in meters (1–100 m).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
		PositionX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Position X", 340f, new ConfigDescription("Marker status text X position relative to the screen center. 0 is the horizontal center.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-366f, 373f), Array.Empty<object>()));
		PositionY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Position Y", 200f, new ConfigDescription("Marker status text Y position relative to the screen center. 0 is the vertical center.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-258f, 237f), Array.Empty<object>()));
		Controller = new TeleportRayController();
		AllowClients.SettingChanged += delegate
		{
			TeleportPermission.ForceRefresh();
		};
		TeleportRayEnabled.SettingChanged += delegate
		{
			if (!TeleportRayEnabled.Value)
			{
				Controller?.DisableSystem();
			}
		};
		RayColor.SettingChanged += delegate
		{
			Controller?.RefreshConfiguredColor();
			MarkerTeleportHud.RefreshColor();
		};
		MarkerStatusUIEnabled.SettingChanged += delegate
		{
			MarkerTeleportHud.Update();
		};
		PositionX.SettingChanged += delegate
		{
			MarkerTeleportHud.RefreshPosition();
		};
		PositionY.SettingChanged += delegate
		{
			MarkerTeleportHud.RefreshPosition();
		};
		SceneManager.sceneLoaded += OnSceneLoaded;
	}

	private static void OnSceneLoaded(Scene scene, LoadSceneMode _)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		Controller?.ResetForWorldTransition("scene changed");
		MarkerTeleportHud.Reset();
		if ((Object)(object)runnerObject == (Object)null)
		{
			runnerObject = new GameObject("TeleportRay_Runner");
			runnerObject.AddComponent<TeleportRayRunner>();
			Object.DontDestroyOnLoad((Object)(object)runnerObject);
		}
	}
}
public class TeleportRayRunner : MonoBehaviour
{
	private void Awake()
	{
	}

	private void Start()
	{
	}

	private void Update()
	{
		TeleportPermission.Tick();
		if (Plugin.TeleportRayEnabled == null || !Plugin.TeleportRayEnabled.Value)
		{
			Plugin.Controller?.DisableSystemSilently();
			MarkerTeleportHud.Update();
			return;
		}
		if (!TeleportPermission.Allowed)
		{
			Plugin.Controller?.DisableSystemSilently();
			MarkerTeleportHud.Update();
			return;
		}
		Keyboard current = Keyboard.current;
		if (current != null)
		{
			if (WasPressed(current, Plugin.CurveTeleportKey))
			{
				Plugin.Controller?.ToggleCurveTeleport();
			}
			if (WasPressed(current, Plugin.StraightTeleportKey))
			{
				Plugin.Controller?.ToggleStraightTeleport();
			}
			if (WasPressed(current, Plugin.MarkerTeleportBKey))
			{
				Plugin.Controller?.ToggleMarkerTeleport(markerB: true);
			}
			if (WasPressed(current, Plugin.MarkerTeleportKey))
			{
				Plugin.Controller?.ToggleMarkerTeleport(markerB: false);
			}
			if (WasPressed(current, Plugin.ResetMarkerTeleportKey))
			{
				Plugin.Controller?.ResetMarkerTeleport();
			}
		}
		Plugin.Controller?.Tick(Time.deltaTime);
		MarkerTeleportHud.Update();
	}

	private static bool WasPressed(Keyboard keyboard, ConfigEntry<Key> entry)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if (keyboard == null || entry == null || (int)entry.Value == 0)
		{
			return false;
		}
		ButtonControl val = (ButtonControl)(object)keyboard[entry.Value];
		return val != null && val.wasPressedThisFrame;
	}
}
internal static class MarkerTeleportHud
{
	private sealed class MarkerTeleportDragUI : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		private RectTransform rect;

		private Canvas canvas;

		internal void Initialize(RectTransform targetRect, Canvas targetCanvas)
		{
			rect = targetRect;
			canvas = targetCanvas;
		}

		public void OnPointerDown(PointerEventData eventData)
		{
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null) && !((Object)(object)canvas == (Object)null))
			{
				float num = ((canvas.scaleFactor > 0f) ? canvas.scaleFactor : 1f);
				RectTransform obj = rect;
				obj.anchoredPosition += eventData.delta / num;
			}
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rect != (Object)null)
			{
				SavePosition(rect.anchoredPosition);
			}
		}
	}

	private static GameObject counterObject;

	private static TextMeshProUGUI textObject;

	private static bool initialized;

	private static string lastColorHex = "";

	public static void Update()
	{
		if ((Object)(object)counterObject == (Object)null || (Object)(object)textObject == (Object)null)
		{
			counterObject = null;
			textObject = null;
			initialized = false;
		}
		if (Plugin.MarkerStatusUIEnabled == null || !Plugin.MarkerStatusUIEnabled.Value || Plugin.TeleportRayEnabled == null || !Plugin.TeleportRayEnabled.Value || !TeleportPermission.Allowed)
		{
			if ((Object)(object)counterObject != (Object)null)
			{
				counterObject.SetActive(false);
			}
			return;
		}
		if (!initialized)
		{
			Initialize();
		}
		if (!((Object)(object)counterObject == (Object)null) && !((Object)(object)textObject == (Object)null))
		{
			counterObject.SetActive(true);
			((TMP_Text)textObject).text = "MARKER: " + ((Plugin.Controller != null && Plugin.Controller.HasMarkerA) ? "A" : "--") + " / " + ((Plugin.Controller != null && Plugin.Controller.HasMarkerB) ? "B" : "--");
			RefreshColor();
		}
	}

	private static void Initialize()
	{
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Expected O, but got Unknown
		//IL_00dd: 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_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Expected O, but got Unknown
		//IL_018a: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		GameObject val2 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		TextMeshProUGUI componentInChildren = val2.GetComponentInChildren<TextMeshProUGUI>(true);
		if ((Object)(object)componentInChildren == (Object)null)
		{
			return;
		}
		Canvas componentInParent = val.GetComponentInParent<Canvas>();
		if (!((Object)(object)componentInParent == (Object)null))
		{
			if ((Object)(object)((Component)componentInParent).GetComponent<GraphicRaycaster>() == (Object)null)
			{
				((Component)componentInParent).gameObject.AddComponent<GraphicRaycaster>();
			}
			counterObject = new GameObject("TeleportRay_MarkerStatus", new Type[1] { typeof(RectTransform) });
			counterObject.transform.SetParent(val.transform, false);
			RectTransform component = counterObject.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(170f, 40f);
			textObject = counterObject.AddComponent<TextMeshProUGUI>();
			CopyStyle(componentInChildren, textObject);
			GameObject val3 = new GameObject("TeleportRay_MarkerStatus_DragArea", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(counterObject.transform, false);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			Image val4 = val3.AddComponent<Image>();
			((Graphic)val4).color = new Color(0f, 0f, 0f, 0f);
			((Graphic)val4).raycastTarget = true;
			MarkerTeleportDragUI markerTeleportDragUI = val3.AddComponent<MarkerTeleportDragUI>();
			markerTeleportDragUI.Initialize(component, componentInParent);
			RefreshPosition();
			RefreshColor();
			initialized = true;
		}
	}

	private static void CopyStyle(TextMeshProUGUI source, TextMeshProUGUI target)
	{
		//IL_002a: 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)
		((TMP_Text)target).font = ((TMP_Text)source).font;
		((TMP_Text)target).fontSharedMaterial = ((TMP_Text)source).fontSharedMaterial;
		((TMP_Text)target).spriteAsset = ((TMP_Text)source).spriteAsset;
		((TMP_Text)target).outlineColor = ((TMP_Text)source).outlineColor;
		((TMP_Text)target).outlineWidth = ((TMP_Text)source).outlineWidth;
		((TMP_Text)target).fontStyle = ((TMP_Text)source).fontStyle;
		((TMP_Text)target).fontSize = 20f;
		((TMP_Text)target).alignment = (TextAlignmentOptions)257;
		((TMP_Text)target).enableWordWrapping = false;
		((Graphic)target).raycastTarget = false;
		((TMP_Text)target).text = "MARKER: -- / --";
	}

	public static void RefreshPosition()
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)counterObject == (Object)null))
		{
			RectTransform component = counterObject.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				component.anchoredPosition = new Vector2(Plugin.PositionX?.Value ?? 380f, Plugin.PositionY?.Value ?? 250f);
			}
		}
	}

	private static void SavePosition(Vector2 position)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if (Plugin.PositionX != null)
		{
			Plugin.PositionX.Value = position.x;
		}
		if (Plugin.PositionY != null)
		{
			Plugin.PositionY.Value = position.y;
		}
		try
		{
			ConfigFile configFile = Plugin.ConfigFile;
			if (configFile != null)
			{
				configFile.Save();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("TeleportRay: Failed to save marker UI position: " + ex));
			}
		}
	}

	public static void RefreshColor()
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)textObject == (Object)null)
		{
			return;
		}
		string text = Plugin.RayColor?.Value ?? "#00F0FF";
		if (!(text == lastColorHex))
		{
			Color color = default(Color);
			if (!ColorUtility.TryParseHtmlString(text, ref color))
			{
				((Color)(ref color))..ctor(0f, 0.94f, 1f, 1f);
			}
			((Graphic)textObject).color = color;
			lastColorHex = text;
		}
	}

	public static void Reset()
	{
		if ((Object)(object)counterObject != (Object)null)
		{
			Object.Destroy((Object)(object)counterObject);
		}
		counterObject = null;
		textObject = null;
		initialized = false;
		lastColorHex = "";
	}
}
internal static class TeleportPermission
{
	private const string PermissionMessage = "azumi.teleportray.permission";

	private const string RequestMessage = "azumi.teleportray.teleport.request";

	private const string ResponseMessage = "azumi.teleportray.teleport.response";

	private static NetworkManager registered;

	private static bool handlersRegistered;

	private static bool wasListening;

	private static bool known;

	private static bool allowed;

	private static float nextQuery;

	private static float firstQueryTime;

	private static bool warnedNoResponse;

	private static uint nextId;

	private static uint pendingId;

	private static Vector3 pendingPosition;

	private static bool pendingInside;

	private static bool pendingElevator;

	private static bool pendingShip;

	private static float pendingUntil;

	private static bool pending;

	private static bool lastHostSetting;

	public static bool Allowed => (Object)(object)registered != (Object)null && registered.IsListening && (registered.IsServer || (known && allowed));

	public static void ForceRefresh()
	{
		if ((Object)(object)registered != (Object)null && registered.IsServer)
		{
			Broadcast();
		}
	}

	public static void Tick()
	{
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Expected O, but got Unknown
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Expected O, but got Unknown
		NetworkManager singleton = NetworkManager.Singleton;
		bool flag = (Object)(object)singleton != (Object)null && singleton.IsListening;
		if ((Object)(object)singleton != (Object)(object)registered || (!wasListening && flag))
		{
			if ((Object)(object)registered != (Object)null && handlersRegistered)
			{
				try
				{
					registered.CustomMessagingManager.UnregisterNamedMessageHandler("azumi.teleportray.permission");
					registered.CustomMessagingManager.UnregisterNamedMessageHandler("azumi.teleportray.teleport.request");
					registered.CustomMessagingManager.UnregisterNamedMessageHandler("azumi.teleportray.teleport.response");
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("Unregister permission handlers: " + ex));
					}
				}
			}
			registered = singleton;
			handlersRegistered = false;
			known = false;
			allowed = false;
			pending = false;
			nextQuery = 0f;
			firstQueryTime = Time.unscaledTime;
			warnedNoResponse = false;
		}
		wasListening = flag;
		if (!flag)
		{
			return;
		}
		if (!handlersRegistered)
		{
			try
			{
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				customMessagingManager.RegisterNamedMessageHandler("azumi.teleportray.permission", new HandleNamedMessageDelegate(ReceivePermission));
				customMessagingManager.RegisterNamedMessageHandler("azumi.teleportray.teleport.request", new HandleNamedMessageDelegate(ReceiveRequest));
				customMessagingManager.RegisterNamedMessageHandler("azumi.teleportray.teleport.response", new HandleNamedMessageDelegate(ReceiveResponse));
				handlersRegistered = true;
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("Permission registration: " + ex2));
				}
				return;
			}
		}
		if (singleton.IsServer)
		{
			bool value = Plugin.AllowClients.Value;
			if (value != lastHostSetting)
			{
				lastHostSetting = value;
				Broadcast();
			}
		}
		else if (!known && Time.unscaledTime >= nextQuery)
		{
			nextQuery = Time.unscaledTime + 2f;
			SendPermissionQuery();
		}
		if (!singleton.IsServer && !known && !warnedNoResponse && Time.unscaledTime - firstQueryTime > 7f)
		{
			warnedNoResponse = true;
			Notify("Host permission has not been received. TeleportRay remains disabled.");
		}
		if (pending && Time.unscaledTime > pendingUntil)
		{
			pending = false;
			Notify("Teleport request timed out. Host approval was not received.");
		}
	}

	private unsafe static void SendPermissionQuery()
	{
		//IL_0040: 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)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)registered == (Object)null || !registered.IsListening || registered.IsServer)
		{
			return;
		}
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1);
		try
		{
			byte b = 0;
			((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			registered.CustomMessagingManager.SendNamedMessage("azumi.teleportray.permission", 0uL, val, (NetworkDelivery)3);
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private unsafe static void SendPermission(ulong recipient, bool state)
	{
		//IL_003d: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)registered == (Object)null || !registered.IsListening)
		{
			return;
		}
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(1, (Allocator)2, -1);
		try
		{
			byte b = (byte)(state ? 1 : 0);
			((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			registered.CustomMessagingManager.SendNamedMessage("azumi.teleportray.permission", recipient, val, (NetworkDelivery)3);
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private static void Broadcast()
	{
		if ((Object)(object)registered == (Object)null || !registered.IsServer || !registered.IsListening)
		{
			return;
		}
		foreach (ulong connectedClientsId in registered.ConnectedClientsIds)
		{
			if (connectedClientsId != registered.LocalClientId)
			{
				SendPermission(connectedClientsId, Plugin.AllowClients.Value);
			}
		}
	}

	private static void ReceivePermission(ulong sender, FastBufferReader reader)
	{
		//IL_002d: 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)
		if ((Object)(object)registered == (Object)null || !registered.IsListening)
		{
			return;
		}
		byte b = default(byte);
		((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
		if (registered.IsServer)
		{
			if (registered.ConnectedClients.ContainsKey(sender))
			{
				SendPermission(sender, Plugin.AllowClients.Value);
			}
		}
		else if (sender == 0)
		{
			bool flag = b != 0;
			if (!known || flag != allowed)
			{
				Notify(flag ? "Host permission granted. TeleportRay is available." : "Host permission denied. TeleportRay is disabled.");
			}
			known = true;
			allowed = flag;
			if (!allowed)
			{
				pending = false;
				Plugin.Controller?.DisableSystemSilently();
			}
		}
	}

	public unsafe static void RequestTeleport(Vector3 target, bool inside, bool elevator, bool ship)
	{
		//IL_003a: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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)
		if (!Allowed || (Object)(object)registered == (Object)null)
		{
			Notify("TeleportRay: Host permission is required.");
			return;
		}
		if (registered.IsServer)
		{
			Apply(target, inside, elevator, ship);
			return;
		}
		if (pending)
		{
			Notify("Waiting for host approval.");
			return;
		}
		pending = true;
		pendingId = ++nextId;
		pendingPosition = target;
		pendingInside = inside;
		pendingElevator = elevator;
		pendingShip = ship;
		pendingUntil = Time.unscaledTime + 5f;
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(64, (Allocator)2, -1);
		try
		{
			((FastBufferWriter)(ref val)).WriteValueSafe<uint>(ref pendingId, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteValueSafe(ref target);
			registered.CustomMessagingManager.SendNamedMessage("azumi.teleportray.teleport.request", 0uL, val, (NetworkDelivery)3);
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private unsafe static void ReceiveRequest(ulong sender, FastBufferReader reader)
	{
		//IL_0039: 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_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_0194: 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_01b2: 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_00b0: 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_0150: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)registered == (Object)null || !registered.IsServer || !registered.IsListening)
		{
			return;
		}
		uint num = default(uint);
		((FastBufferReader)(ref reader)).ReadValueSafe<uint>(ref num, default(ForPrimitives));
		Vector3 val = default(Vector3);
		((FastBufferReader)(ref reader)).ReadValueSafe(ref val);
		bool flag = Plugin.AllowClients.Value && registered.ConnectedClients.ContainsKey(sender) && !float.IsNaN(val.x) && !float.IsNaN(val.y) && !float.IsNaN(val.z) && !float.IsInfinity(val.x) && !float.IsInfinity(val.y) && !float.IsInfinity(val.z);
		if (flag)
		{
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			PlayerControllerB val2 = null;
			if (array != null)
			{
				PlayerControllerB[] array2 = array;
				foreach (PlayerControllerB val3 in array2)
				{
					if ((Object)(object)val3 != (Object)null && val3.actualClientId == sender)
					{
						val2 = val3;
						break;
					}
				}
			}
			flag = (Object)(object)val2 != (Object)null && !val2.isPlayerDead && Vector3.Distance(((Component)val2).transform.position, val) <= 1005f;
		}
		FastBufferWriter val4 = default(FastBufferWriter);
		((FastBufferWriter)(ref val4))..ctor(16, (Allocator)2, -1);
		try
		{
			((FastBufferWriter)(ref val4)).WriteValueSafe<uint>(ref num, default(ForPrimitives));
			byte b = (byte)(flag ? 1 : 0);
			((FastBufferWriter)(ref val4)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			registered.CustomMessagingManager.SendNamedMessage("azumi.teleportray.teleport.response", sender, val4, (NetworkDelivery)3);
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val4))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private static void ReceiveResponse(ulong sender, FastBufferReader reader)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: 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_004a: 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)
		if ((Object)(object)registered == (Object)null || registered.IsServer || sender != 0)
		{
			return;
		}
		uint num = default(uint);
		((FastBufferReader)(ref reader)).ReadValueSafe<uint>(ref num, default(ForPrimitives));
		byte b = default(byte);
		((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
		if (pending && num == pendingId)
		{
			pending = false;
			if (b == 1 && Allowed)
			{
				Apply(pendingPosition, pendingInside, pendingElevator, pendingShip);
			}
			else
			{
				Notify("Host rejected the teleport request.");
			}
		}
	}

	private static void Apply(Vector3 target, bool inside, bool elevator, bool ship)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB val = StartOfRound.Instance?.localPlayerController;
		if (!((Object)(object)val == (Object)null) && !val.isPlayerDead)
		{
			val.TeleportPlayer(target, false, 0f, false, true);
			val.ResetPlayerBloodObjects(true);
			val.isInsideFactory = inside;
			val.isInElevator = elevator;
			val.isInHangarShipRoom = ship;
		}
	}

	private static void Notify(string message)
	{
		if ((Object)(object)HUDManager.Instance != (Object)null)
		{
			HUDManager.Instance.DisplayTip("TeleportRay", message, false, false, "LC_Tip1");
		}
	}
}
public class TeleportRayController
{
	private const float MaxDistance = 1000f;

	private const float GroundCastDistance = 100f;

	private const int CurveTeleportPoints = 100;

	private const float CurveWidth = 0.08f;

	private bool isActive;

	private bool straightMode;

	private bool hasMarkerB;

	private Vector3 markerBPosition;

	private bool markerBInside;

	private bool markerBElevator;

	private bool markerBShip;

	private bool hasDestination;

	private bool hasMarkerTeleportPosition;

	private Vector3 destination;

	private Vector3 markerTeleportPosition;

	private bool markerIsInsideFactory;

	private bool markerIsInElevator;

	private bool markerIsInHangarShipRoom;

	private bool worldStateInitialized;

	private int observedLevelId;

	private bool observedInShipPhase;

	private bool observedShipHasLanded;

	private StartOfRound observedRound;

	private GameObject root;

	private LineRenderer arcLine;

	private LineRenderer targetRing;

	private LineRenderer markerTeleportPositionRing;

	private LineRenderer markerBRing;

	private TextMeshPro markerALabel;

	private TextMeshPro markerBLabel;

	private Material material;

	private string lastColorHex = "";

	private Color currentColor = new Color(0f, 0.94f, 1f, 1f);

	private readonly int indicatorMask = LayerMask.GetMask(new string[3] { "Room", "Terrain", "Railing" });

	public bool HasMarkerTeleportPosition => hasMarkerTeleportPosition;

	public bool HasMarkerA => hasMarkerTeleportPosition;

	public bool HasMarkerB => hasMarkerB;

	public void ToggleCurveTeleport()
	{
		Toggle(straight: false);
	}

	public void ToggleStraightTeleport()
	{
		Toggle(straight: true);
	}

	private void Toggle(bool straight)
	{
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB localPlayer = GetLocalPlayer();
		if ((Object)(object)localPlayer == (Object)null || IsInputBlocked(localPlayer))
		{
			return;
		}
		if (!isActive || straightMode != straight)
		{
			straightMode = straight;
			isActive = true;
			EnsureVisuals();
			GameObject obj = root;
			if (obj != null)
			{
				obj.SetActive(true);
			}
			UpdateTarget(localPlayer);
			ShowNotification("TeleportRay", hasDestination ? ((straight ? "Straight Teleport" : "Curve Teleport") + " ray enabled.\nPress the key again to teleport.") : ((straight ? "Straight Teleport" : "Curve Teleport") + " ray enabled.\nNo valid destination is currently available."));
		}
		else
		{
			UpdateTarget(localPlayer);
			if (!hasDestination)
			{
				ShowNotification("TeleportRay", (straight ? "Straight Teleport" : "Curve Teleport") + ": No valid destination.");
				return;
			}
			Vector3 val = destination;
			TeleportPermission.RequestTeleport(val, localPlayer.isInsideFactory, localPlayer.isInElevator, localPlayer.isInHangarShipRoom);
			isActive = false;
			hasDestination = false;
			HideAimVisuals();
			ShowPositionNotification((straight ? "Straight Teleport" : "Curve Teleport") + " requested.", val);
		}
	}

	public void ToggleMarkerTeleport(bool markerB)
	{
		//IL_01a8: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: 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_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_019a: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB localPlayer = GetLocalPlayer();
		if ((Object)(object)localPlayer == (Object)null || IsInputBlocked(localPlayer))
		{
			return;
		}
		if (markerB)
		{
			if (!hasMarkerB)
			{
				markerBPosition = ((Component)localPlayer).transform.position;
				markerBInside = localPlayer.isInsideFactory;
				markerBElevator = localPlayer.isInElevator;
				markerBShip = localPlayer.isInHangarShipRoom;
				hasMarkerB = true;
				EnsureVisuals();
				GameObject obj = root;
				if (obj != null)
				{
					obj.SetActive(true);
				}
				DrawRing(markerBRing, markerBPosition);
				ShowPositionNotification("Marker Teleport B set.", markerBPosition);
			}
			else
			{
				TeleportPermission.RequestTeleport(markerBPosition, markerBInside, markerBElevator, markerBShip);
				hasMarkerB = false;
				LineRenderer obj2 = markerBRing;
				if (obj2 != null)
				{
					((Component)obj2).gameObject.SetActive(false);
				}
				if ((Object)(object)markerBLabel != (Object)null)
				{
					((Component)markerBLabel).gameObject.SetActive(false);
				}
			}
		}
		else if (!hasMarkerTeleportPosition)
		{
			markerTeleportPosition = ((Component)localPlayer).transform.position;
			markerIsInsideFactory = localPlayer.isInsideFactory;
			markerIsInElevator = localPlayer.isInElevator;
			markerIsInHangarShipRoom = localPlayer.isInHangarShipRoom;
			hasMarkerTeleportPosition = true;
			EnsureVisuals();
			GameObject obj3 = root;
			if (obj3 != null)
			{
				obj3.SetActive(true);
			}
			DrawMarkerTeleportRing();
			ShowPositionNotification("Marker Teleport set.", markerTeleportPosition);
		}
		else
		{
			Vector3 val = markerTeleportPosition;
			TeleportPermission.RequestTeleport(val, markerIsInsideFactory, markerIsInElevator, markerIsInHangarShipRoom);
			ClearMarkerTeleport();
			ShowPositionNotification("Teleport requested for Marker Teleport A.", val);
		}
	}

	public void ResetMarkerTeleport()
	{
		PlayerControllerB localPlayer = GetLocalPlayer();
		if ((Object)(object)localPlayer != (Object)null && IsInputBlocked(localPlayer))
		{
			return;
		}
		bool flag = isActive;
		bool flag2 = hasMarkerTeleportPosition || hasMarkerB;
		if (!flag && !flag2)
		{
			ShowNotification("TeleportRay", "No Curve/Straight Teleport or Marker Teleport is active.");
			return;
		}
		if (flag)
		{
			isActive = false;
			hasDestination = false;
			HideAimVisuals();
		}
		if (flag2)
		{
			ClearMarkerTeleport();
			hasMarkerB = false;
			LineRenderer obj = markerBRing;
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
			if ((Object)(object)markerBLabel != (Object)null)
			{
				((Component)markerBLabel).gameObject.SetActive(false);
			}
		}
		if (flag && flag2)
		{
			ShowNotification("TeleportRay", "Curve/Straight Teleport and Marker Teleport reset.");
		}
		else if (flag)
		{
			ShowNotification("TeleportRay", "Curve/Straight Teleport reset.");
		}
		else
		{
			ShowNotification("TeleportRay", "Marker Teleport reset.");
		}
	}

	public void DisableSystem()
	{
		ResetForWorldTransition("system disabled");
	}

	public void DisableSystemSilently()
	{
		if (isActive || hasMarkerTeleportPosition || hasMarkerB)
		{
			ResetForWorldTransition("permission unavailable");
		}
	}

	public void TickDisabled()
	{
		if ((Object)(object)root != (Object)null && root.activeSelf)
		{
			root.SetActive(false);
		}
	}

	public void ResetForWorldTransition(string reason)
	{
		bool flag = isActive || hasDestination || hasMarkerTeleportPosition || hasMarkerB;
		isActive = false;
		hasDestination = false;
		ClearMarkerTeleport();
		hasMarkerB = false;
		LineRenderer obj = markerBRing;
		if (obj != null)
		{
			((Component)obj).gameObject.SetActive(false);
		}
		if ((Object)(object)markerBLabel != (Object)null)
		{
			((Component)markerBLabel).gameObject.SetActive(false);
		}
		HideAimVisuals();
		if ((Object)(object)root != (Object)null)
		{
			root.SetActive(false);
		}
		if (flag)
		{
			Plugin.Log.LogInfo((object)("TeleportRay: Forced reset because " + reason + "."));
		}
	}

	private bool CheckForWorldTransition()
	{
		StartOfRound instance = StartOfRound.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			if (worldStateInitialized)
			{
				worldStateInitialized = false;
				observedRound = null;
				ResetForWorldTransition("game/round ended");
				return true;
			}
			return false;
		}
		int currentLevelID = instance.currentLevelID;
		bool inShipPhase = instance.inShipPhase;
		bool shipHasLanded = instance.shipHasLanded;
		if (!worldStateInitialized)
		{
			observedRound = instance;
			observedLevelId = currentLevelID;
			observedInShipPhase = inShipPhase;
			observedShipHasLanded = shipHasLanded;
			worldStateInitialized = true;
			return false;
		}
		if (!((Object)(object)observedRound != (Object)(object)instance) && observedLevelId == currentLevelID && observedInShipPhase == inShipPhase && observedShipHasLanded == shipHasLanded)
		{
			return false;
		}
		string reason = "world state changed (level " + observedLevelId + " -> " + currentLevelID + ", inShipPhase " + observedInShipPhase + " -> " + inShipPhase + ", shipHasLanded " + observedShipHasLanded + " -> " + shipHasLanded + ")";
		observedRound = instance;
		observedLevelId = currentLevelID;
		observedInShipPhase = inShipPhase;
		observedShipHasLanded = shipHasLanded;
		ResetForWorldTransition(reason);
		return true;
	}

	public void RefreshConfiguredColor()
	{
		ApplyConfiguredColor(force: true);
	}

	public void Tick(float _)
	{
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		ApplyConfiguredColor(force: false);
		if (CheckForWorldTransition())
		{
			return;
		}
		PlayerControllerB localPlayer = GetLocalPlayer();
		if ((Object)(object)localPlayer == (Object)null || localPlayer.isPlayerDead)
		{
			if (isActive || hasMarkerTeleportPosition || hasMarkerB)
			{
				ResetForWorldTransition(((Object)(object)localPlayer == (Object)null) ? "local player unavailable" : "local player died");
			}
			return;
		}
		if (hasMarkerB)
		{
			EnsureVisuals();
			GameObject obj = root;
			if (obj != null)
			{
				obj.SetActive(true);
			}
			DrawRing(markerBRing, markerBPosition);
		}
		if (hasMarkerTeleportPosition)
		{
			EnsureVisuals();
			GameObject obj2 = root;
			if (obj2 != null)
			{
				obj2.SetActive(true);
			}
			DrawMarkerTeleportRing();
		}
		if (isActive)
		{
			if (IsInputBlocked(localPlayer))
			{
				Clear();
			}
			else
			{
				UpdateTarget(localPlayer);
			}
		}
	}

	private static PlayerControllerB GetLocalPlayer()
	{
		if ((Object)(object)StartOfRound.Instance == (Object)null)
		{
			return null;
		}
		return StartOfRound.Instance.localPlayerController;
	}

	private static bool IsInputBlocked(PlayerControllerB player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return true;
		}
		if (player.inTerminalMenu || player.isTypingChat)
		{
			return true;
		}
		if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.chatTextField != (Object)null && HUDManager.Instance.chatTextField.isFocused)
		{
			return true;
		}
		return false;
	}

	private void UpdateTarget(PlayerControllerB player)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: 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_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_017f: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: 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_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: 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_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player.gameplayCamera == (Object)null)
		{
			HideVisuals();
			return;
		}
		Transform transform = ((Component)player.gameplayCamera).transform;
		Vector3 forward = transform.forward;
		float num = (straightMode ? Mathf.Clamp(Plugin.StraightTeleportDistance?.Value ?? 100f, 1f, 100f) : 1000f);
		bool flag;
		RaycastHit closestHit = default(RaycastHit);
		if (straightMode)
		{
			flag = TryGetStraightHit(player, transform.position, forward, num, out closestHit);
		}
		else
		{
			flag = Physics.Raycast(new Ray(transform.position, forward), ref closestHit, num, indicatorMask, (QueryTriggerInteraction)1);
			if (!flag)
			{
				flag = Physics.Raycast(new Ray(transform.position, forward), ref closestHit, num, -5, (QueryTriggerInteraction)1);
			}
		}
		if (!flag && !straightMode)
		{
			hasDestination = false;
			HideVisuals();
			return;
		}
		Vector3 val = (flag ? ((RaycastHit)(ref closestHit)).point : (transform.position + forward * num));
		if (!straightMode && ((RaycastHit)(ref closestHit)).normal.y <= 0f)
		{
			RaycastHit val2 = default(RaycastHit);
			bool flag2 = Physics.Raycast(new Ray(((RaycastHit)(ref closestHit)).point, Vector3.down), ref val2, 100f, indicatorMask, (QueryTriggerInteraction)1);
			if (!flag2)
			{
				flag2 = Physics.Raycast(new Ray(((RaycastHit)(ref closestHit)).point, Vector3.down), ref val2, 100f, -5, (QueryTriggerInteraction)1);
			}
			if (!flag2)
			{
				hasDestination = false;
				HideVisuals();
				return;
			}
			val = ((RaycastHit)(ref val2)).point;
		}
		if (val == Vector3.zero)
		{
			hasDestination = false;
			HideVisuals();
			return;
		}
		destination = val;
		hasDestination = true;
		EnsureVisuals();
		if ((Object)(object)root != (Object)null)
		{
			root.SetActive(true);
		}
		if (straightMode)
		{
			Vector3 rayStart = GetRayStart(transform);
			arcLine.positionCount = 2;
			arcLine.SetPosition(0, rayStart);
			arcLine.SetPosition(1, val);
		}
		else
		{
			DrawCurveTeleportRay(transform, val);
		}
		DrawTargetRing(val, (straightMode && !flag) ? forward : Vector3.zero);
		if ((Object)(object)arcLine != (Object)null)
		{
			((Component)arcLine).gameObject.SetActive(true);
		}
		if ((Object)(object)targetRing != (Object)null)
		{
			((Component)targetRing).gameObject.SetActive(true);
		}
	}

	private static bool TryGetStraightHit(PlayerControllerB player, Vector3 origin, Vector3 direction, float maxDistance, out RaycastHit closestHit)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: 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_0035: 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)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		closestHit = default(RaycastHit);
		RaycastHit[] array = Physics.RaycastAll(new Ray(origin, direction), maxDistance, -5, (QueryTriggerInteraction)1);
		float num = float.PositiveInfinity;
		bool result = false;
		Transform transform = ((Component)player).transform;
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val = array[i];
			Collider collider = ((RaycastHit)(ref val)).collider;
			if ((Object)(object)collider == (Object)null || ((RaycastHit)(ref val)).distance < 0.05f)
			{
				continue;
			}
			Transform transform2 = ((Component)collider).transform;
			if (!((Object)(object)transform2 != (Object)null) || (!((Object)(object)transform2 == (Object)(object)transform) && !transform2.IsChildOf(transform)))
			{
				PlayerControllerB componentInParent = ((Component)collider).GetComponentInParent<PlayerControllerB>();
				if (!((Object)(object)componentInParent == (Object)(object)player) && ((RaycastHit)(ref val)).distance < num)
				{
					num = ((RaycastHit)(ref val)).distance;
					closestHit = val;
					result = true;
				}
			}
		}
		return result;
	}

	private void DrawCurveTeleportRay(Transform origin, Vector3 target)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: 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)
		//IL_002a: 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_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)arcLine == (Object)null))
		{
			Vector3 forward = origin.forward;
			Vector3 rayStart = GetRayStart(origin);
			float control = rayStart.y + Mathf.Clamp(Mathf.Abs(forward.y * 20f), 0f, 10f);
			arcLine.positionCount = 100;
			arcLine.startWidth = 0.08f;
			arcLine.endWidth = 0.08f;
			for (int i = 0; i < 100; i++)
			{
				float num = (float)i / 100f;
				float num2 = SampleQuadraticBezier(rayStart.y, target.y, control, num);
				arcLine.SetPosition(i, new Vector3(Mathf.Lerp(rayStart.x, target.x, num), num2, Mathf.Lerp(rayStart.z, target.z, num)));
			}
		}
	}

	private static Vector3 GetRayStart(Transform origin)
	{
		//IL_0002: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		return origin.position + Quaternion.AngleAxis(90f, Vector3.up) * origin.forward;
	}

	private static float SampleQuadraticBezier(float start, float end, float control, float t)
	{
		float num = 1f - t;
		return num * num * start + 2f * num * t * control + t * t * end;
	}

	private void DrawTargetRing(Vector3 target, Vector3 airDirection)
	{
		//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_0036: 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_0074: 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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)targetRing == (Object)null))
		{
			targetRing.positionCount = 33;
			bool flag = ((Vector3)(ref airDirection)).sqrMagnitude > 0.001f;
			Quaternion val = (flag ? Quaternion.LookRotation(((Vector3)(ref airDirection)).normalized, Vector3.up) : Quaternion.identity);
			for (int i = 0; i < 33; i++)
			{
				float num = (float)i / 32f * (float)Math.PI * 2.1f;
				targetRing.SetPosition(i, target + (Vector3)(flag ? (val * new Vector3(Mathf.Cos(num) * 0.35f, Mathf.Sin(num) * 0.35f, 0f)) : new Vector3(Mathf.Cos(num) * 0.35f, 0.035f, Mathf.Sin(num) * 0.35f)));
			}
		}
	}

	private void EnsureVisuals()
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Expected O, but got Unknown
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Expected O, but got Unknown
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Expected O, but got Unknown
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		if ((Object)(object)root != (Object)null && (Object)(object)arcLine != (Object)null && (Object)(object)targetRing != (Object)null && (Object)(object)markerTeleportPositionRing != (Object)null && (Object)(object)markerBRing != (Object)null)
		{
			ApplyConfiguredColor(force: false);
			return;
		}
		root = new GameObject("TeleportRay_VisualRoot");
		Object.DontDestroyOnLoad((Object)(object)root);
		GameObject val = new GameObject("TeleportRay_Arc");
		val.transform.SetParent(root.transform);
		arcLine = val.AddComponent<LineRenderer>();
		SetupLineRenderer(arcLine, 0.08f);
		GameObject val2 = new GameObject("TeleportRay_Target");
		val2.transform.SetParent(root.transform);
		targetRing = val2.AddComponent<LineRenderer>();
		SetupLineRenderer(targetRing, 0.06f);
		GameObject val3 = new GameObject("TeleportRay_MarkerTeleport");
		val3.transform.SetParent(root.transform);
		markerTeleportPositionRing = val3.AddComponent<LineRenderer>();
		SetupLineRenderer(markerTeleportPositionRing, 0.06f);
		((Component)markerTeleportPositionRing).gameObject.SetActive(false);
		GameObject val4 = new GameObject("TeleportRay_MarkerB");
		val4.transform.SetParent(root.transform);
		markerBRing = val4.AddComponent<LineRenderer>();
		SetupLineRenderer(markerBRing, 0.06f);
		((Component)markerBRing).gameObject.SetActive(false);
		markerALabel = CreateMarkerLabel("A", "TeleportRay_MarkerA_Label");
		markerBLabel = CreateMarkerLabel("B", "TeleportRay_MarkerB_Label");
		ApplyConfiguredColor(force: true);
	}

	private TextMeshPro CreateMarkerLabel(string letter, string objectName)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(objectName);
		val.transform.SetParent(root.transform, false);
		TextMeshPro val2 = val.AddComponent<TextMeshPro>();
		((TMP_Text)val2).text = letter;
		((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val2).fontSize = 50f;
		((TMP_Text)val2).enableWordWrapping = false;
		((Graphic)val2).color = currentColor;
		GameObject val3 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter");
		if ((Object)(object)val3 != (Object)null)
		{
			TextMeshProUGUI componentInChildren = val3.GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((TMP_Text)componentInChildren).font != (Object)null)
			{
				((TMP_Text)val2).font = ((TMP_Text)componentInChildren).font;
			}
		}
		val2.transform.localScale = Vector3.one * 0.16f;
		val.SetActive(false);
		return val2;
	}

	private void UpdateMarkerLabel(TextMeshPro label, bool visible, Vector3 position)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)label == (Object)null))
		{
			((Component)label).gameObject.SetActive(visible);
			if (visible)
			{
				label.transform.position = position + Vector3.up * 0.065f;
				label.transform.rotation = Quaternion.Euler(90f, 0f, 0f);
				((Graphic)label).color = currentColor;
			}
		}
	}

	private void SetupLineRenderer(LineRenderer lr, float width)
	{
		//IL_009f: 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)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		if ((Object)(object)material == (Object)null)
		{
			Shader val = Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default");
			if ((Object)(object)val != (Object)null)
			{
				material = new Material(val)
				{
					name = "TeleportRay_LineMaterial",
					color = currentColor
				};
			}
			else
			{
				Plugin.Log.LogWarning((object)"TeleportRay: No compatible LineRenderer shader found.");
			}
		}
		if ((Object)(object)material != (Object)null)
		{
			((Renderer)lr).material = material;
		}
		lr.startColor = currentColor;
		lr.endColor = currentColor;
		lr.startWidth = width;
		lr.endWidth = width;
		lr.useWorldSpace = true;
		lr.positionCount = 2;
		((Renderer)lr).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)lr).receiveShadows = false;
	}

	private static void ShowPositionNotification(string message, Vector3 position)
	{
		ShowNotification("TeleportRay", message + "\nX: " + position.x.ToString("F1") + "  Y: " + position.y.ToString("F1") + "  Z: " + position.z.ToString("F1"));
	}

	private static void ShowNotification(string title, string message)
	{
		if ((Object)(object)HUDManager.Instance == (Object)null)
		{
			return;
		}
		try
		{
			HUDManager.Instance.DisplayTip(title, message, false, false, "LC_Tip1");
		}
		catch (Exception ex)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("TeleportRay: Failed to display notification: " + ex));
			}
		}
	}

	private void DrawRing(LineRenderer ring, Vector3 position)
	{
		//IL_0036: 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_0099: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)ring == (Object)null))
		{
			ring.positionCount = 33;
			for (int i = 0; i < 33; i++)
			{
				float num = (float)i / 32f * (float)Math.PI * 2.1f;
				ring.SetPosition(i, position + new Vector3(Mathf.Cos(num) * 0.35f, 0.035f, Mathf.Sin(num) * 0.35f));
			}
			((Component)ring).gameObject.SetActive(true);
			if ((Object)(object)ring == (Object)(object)markerBRing)
			{
				UpdateMarkerLabel(markerBLabel, visible: true, position);
			}
		}
	}

	private void DrawMarkerTeleportRing()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: 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 (hasMarkerTeleportPosition && !((Object)(object)markerTeleportPositionRing == (Object)null))
		{
			markerTeleportPositionRing.positionCount = 33;
			for (int i = 0; i < 33; i++)
			{
				float num = (float)i / 32f * (float)Math.PI * 2.1f;
				markerTeleportPositionRing.SetPosition(i, markerTeleportPosition + new Vector3(Mathf.Cos(num) * 0.35f, 0.035f, Mathf.Sin(num) * 0.35f));
			}
			((Component)markerTeleportPositionRing).gameObject.SetActive(true);
			UpdateMarkerLabel(markerALabel, visible: true, markerTeleportPosition);
		}
	}

	private void ApplyConfiguredColor(bool force)
	{
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		string text = Plugin.RayColor?.Value ?? "#00F0FF";
		if (!force && text == lastColorHex)
		{
			return;
		}
		Color val = default(Color);
		if (!ColorUtility.TryParseHtmlString(text, ref val))
		{
			((Color)(ref val))..ctor(0f, 0.94f, 1f, 1f);
			Plugin.Log.LogWarning((object)("TeleportRay: Invalid Ray Color '" + text + "'. Using #00F0FF."));
		}
		currentColor = val;
		lastColorHex = text;
		if ((Object)(object)material != (Object)null)
		{
			material.color = currentColor;
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", currentColor);
			}
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", currentColor);
			}
		}
		ApplyLineColor(arcLine);
		ApplyLineColor(targetRing);
		ApplyLineColor(markerTeleportPositionRing);
		ApplyLineColor(markerBRing);
		if ((Object)(object)markerALabel != (Object)null)
		{
			((Graphic)markerALabel).color = currentColor;
		}
		if ((Object)(object)markerBLabel != (Object)null)
		{
			((Graphic)markerBLabel).color = currentColor;
		}
	}

	private void ApplyLineColor(LineRenderer line)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)line == (Object)null))
		{
			line.startColor = currentColor;
			line.endColor = currentColor;
		}
	}

	private void ClearMarkerTeleport()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		hasMarkerTeleportPosition = false;
		markerTeleportPosition = Vector3.zero;
		markerIsInsideFactory = false;
		markerIsInElevator = false;
		markerIsInHangarShipRoom = false;
		LineRenderer obj = markerTeleportPositionRing;
		if (obj != null)
		{
			((Component)obj).gameObject.SetActive(false);
		}
		if ((Object)(object)markerALabel != (Object)null)
		{
			((Component)markerALabel).gameObject.SetActive(false);
		}
	}

	private void HideAimVisuals()
	{
		LineRenderer obj = arcLine;
		if (obj != null)
		{
			((Component)obj).gameObject.SetActive(false);
		}
		LineRenderer obj2 = targetRing;
		if (obj2 != null)
		{
			((Component)obj2).gameObject.SetActive(false);
		}
	}

	private void HideVisuals()
	{
		HideAimVisuals();
	}

	private void Clear()
	{
		isActive = false;
		hasDestination = false;
		HideAimVisuals();
	}
}