Decompiled source of RopeObserver v0.4.1

plugins/RopeObserver.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 RopeObserver
{
	internal static class L
	{
		private static ConfigEntry<bool> _useEnglish;

		public static bool English
		{
			get
			{
				if (_useEnglish != null)
				{
					return _useEnglish.Value;
				}
				return true;
			}
		}

		public static void Bind(ConfigEntry<bool> useEnglish)
		{
			_useEnglish = useEnglish;
		}

		public static string T(string chinese, string english)
		{
			if (!English)
			{
				return chinese;
			}
			return english;
		}
	}
	internal static class ModConfig
	{
		public static ConfigFile Config;

		public static ConfigEntry<bool> Enable;

		public static ConfigEntry<float> MinLengthMeters;

		public static ConfigEntry<float> KeepAfterPlaceSeconds;

		public static ConfigEntry<bool> UseEnglish;

		public static ConfigEntry<bool> DebugLog;

		public static ConfigEntry<float> WindowX;

		public static ConfigEntry<float> WindowY;

		public static ConfigEntry<float> WindowWidth;

		public static ConfigEntry<bool> ShowLabel;

		public static ConfigEntry<string> LabelText;

		public static ConfigEntry<KeyCode> DragModifierKey;

		public static ConfigEntry<float> CameraDistance;

		public static ConfigEntry<float> Elevation;

		public static ConfigEntry<float> HorizontalOffset;

		public static ConfigEntry<float> Fov;

		public static ConfigEntry<int> FocusPart;

		public static ConfigEntry<KeyCode> FarKey;

		public static ConfigEntry<KeyCode> NearKey;

		public static ConfigEntry<KeyCode> LeftKey;

		public static ConfigEntry<KeyCode> RightKey;

		public static ConfigEntry<KeyCode> VerticalModifierKey;

		public static ConfigEntry<float> MoveSpeed;

		public static ConfigEntry<float> ElevationSpeed;

		public static void Init(ConfigFile config)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Expected O, but got Unknown
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Expected O, but got Unknown
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Expected O, but got Unknown
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Expected O, but got Unknown
			Config = config;
			Enable = config.Bind<bool>("General / 通用", "Enable / 启用", true, "Whether to enable the rope picture-in-picture preview. / 是否启用RopeObserver。");
			MinLengthMeters = config.Bind<float>("General / 通用", "Min length (m) / 显示阈值(米)", 1f, new ConfigDescription("Show the window only when the unspooled rope is longer than this. / 放出的绳子长于该值才显示小窗。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>()));
			KeepAfterPlaceSeconds = config.Bind<float>("General / 通用", "Keep after placing (s) / 放置后保留(秒)", 1.5f, new ConfigDescription("After the rope is placed, keep the window visible for this many seconds (0 = hide at once). / 放置绳索后窗口继续显示多少秒,0 表示立即隐藏。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			UseEnglish = config.Bind<bool>("General / 通用", "UI language: English / 界面语言:英文", true, "Use English for the window label and log messages. / 小窗标签与日志使用英文。");
			L.Bind(UseEnglish);
			DebugLog = config.Bind<bool>("General / 通用", "Debug log / 调试日志", false, "Log exceptions for troubleshooting. / 排查问题时打开,输出异常日志。");
			WindowX = config.Bind<float>("Window / 窗口", "Window X / 窗口 X", -1f, "Window left edge in pixels. Negative = auto (bottom-left). Dragging in game updates this. / 小窗左边距(像素),负值表示自动(左下角)。游戏中拖动会自动更新。");
			WindowY = config.Bind<float>("Window / 窗口", "Window Y / 窗口 Y", -1f, "Window top edge in pixels. Negative = auto (bottom-left). Dragging in game updates this. / 小窗上边距(像素),负值表示自动(左下角)。游戏中拖动会自动更新。");
			WindowWidth = config.Bind<float>("Window / 窗口", "Window width (px) / 窗口宽度(像素)", 640f, new ConfigDescription("Window width in pixels; height follows 16:9. / 小窗宽度(像素),高度按 16:9 自动计算。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(96f, 1280f), Array.Empty<object>()));
			ShowLabel = config.Bind<bool>("Window / 窗口", "Show label / 显示标签", false, "Show the small label at the top-left of the window. / 是否显示小窗左上角的标签。");
			LabelText = config.Bind<string>("Window / 窗口", "Label text / 标签文字", "", "Label text. Empty = follow UI language (\"Rope Preview\" / \"绳索预览\"). / 标签文字,留空则跟随界面语言。");
			DragModifierKey = config.Bind<KeyCode>("Window / 窗口", "Drag modifier key / 拖动修饰键", (KeyCode)307, "Hold this key and drag with the left mouse button to move the window. / 按住该键并用鼠标左键拖动即可移动小窗(默认右 Alt)。");
			CameraDistance = config.Bind<float>("Camera / 相机", "Camera distance (m) / 相机距离(米)", 10f, new ConfigDescription("Distance from the focus point; larger shows a wider view. / 相机到聚焦点的距离,越大视野越广。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 100f), Array.Empty<object>()));
			Elevation = config.Bind<float>("Camera / 相机", "Elevation (deg) / 俯仰角(度)", 20f, new ConfigDescription("Camera elevation angle. / 相机抬高角度,越大越从高处俯视。游戏中可用垂直修饰键+上/下实时增减。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-30f, 89f), Array.Empty<object>()));
			HorizontalOffset = config.Bind<float>("Camera / 相机", "Horizontal offset (m) / 水平偏移(米)", 0f, new ConfigDescription("Left/right offset in meters; positive is right. / 相机水平左右偏移(米),正为右、负为左。游戏中可用左右键实时增减。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-50f, 50f), Array.Empty<object>()));
			Fov = config.Bind<float>("Camera / 相机", "Field of view / 视野角度", 85f, new ConfigDescription("Window camera field of view in degrees. / 小窗相机视野角(度),越大越广角。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 110f), Array.Empty<object>()));
			FocusPart = config.Bind<int>("Camera / 相机", "Focus point / 视角关注点", 0, new ConfigDescription("Where the camera focuses: 0 lowest point, 1 middle, 2 highest. / 相机聚焦在绳子的哪个位置:0 绳最低点,1 绳中段,2 绳最高处。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
			FarKey = config.Bind<KeyCode>("CameraControls / 相机操控", "Far key / 拉远键", (KeyCode)274, "Hold to move the window camera farther. / 游戏中按住:小窗相机拉远(默认 ↓)。");
			NearKey = config.Bind<KeyCode>("CameraControls / 相机操控", "Near key / 拉近键", (KeyCode)273, "Hold to move the window camera closer. / 游戏中按住:小窗相机拉近(默认 ↑)。");
			LeftKey = config.Bind<KeyCode>("CameraControls / 相机操控", "Left key / 左移键", (KeyCode)276, "Hold to move the window camera left. / 游戏中按住:小窗相机左移(默认 ←)。");
			RightKey = config.Bind<KeyCode>("CameraControls / 相机操控", "Right key / 右移键", (KeyCode)275, "Hold to move the window camera right. / 游戏中按住:小窗相机右移(默认 →)。");
			VerticalModifierKey = config.Bind<KeyCode>("CameraControls / 相机操控", "Vertical modifier key / 垂直修饰键", (KeyCode)305, "Hold this modifier to make Up/Down change elevation. / 按住该修饰键时,上下键改为升降相机(右Ctrl+↑ 升高,右Ctrl+↓ 降低)。");
			MoveSpeed = config.Bind<float>("CameraControls / 相机操控", "Move speed (m/s) / 移动速度(米/秒)", 5f, new ConfigDescription("Speed of the arrow keys pushing the camera. / 上下左右键推动相机的速度。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 40f), Array.Empty<object>()));
			ElevationSpeed = config.Bind<float>("CameraControls / 相机操控", "Elevation speed (deg/s) / 升降速度(度/秒)", 25f, new ConfigDescription("Speed of elevation change with the modifier + Up/Down. / 垂直修饰键+上下键改变俯仰角的速度。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 120f), Array.Empty<object>()));
		}
	}
	[BepInPlugin("RopeObserver", "RopeObserver", "0.4.1")]
	[BepInProcess("PEAK.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private GameObject _host;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			PluginInfo.Init(((BaseUnityPlugin)this).Logger);
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			_host = new GameObject("RopeObserver_Host");
			((Object)_host).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)_host);
			_host.AddComponent<RopeObserverManager>();
			PluginInfo.Log("已加载 v0.4.1:手持绳索卷轴放绳超过 " + ModConfig.MinLengthMeters.Value + " 米时显示小窗。");
		}

		private void OnDestroy()
		{
			if ((Object)(object)_host != (Object)null)
			{
				Object.Destroy((Object)(object)_host);
				_host = null;
			}
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "RopeObserver";

		public const string Name = "RopeObserver";

		public const string Version = "0.4.1";

		private static ManualLogSource _logger;

		public static void Init(ManualLogSource logger)
		{
			_logger = logger;
		}

		public static void Log(string message)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogInfo((object)("[RopeObserver] " + message));
			}
		}

		public static void Warn(string message)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogWarning((object)("[RopeObserver] " + message));
			}
		}
	}
	internal sealed class RopeObserverManager : MonoBehaviour
	{
		private RopeObserverWindow _window;

		private bool _tuningHeld;

		private bool _tuningDirty;

		private Rope _tracked;

		private Rope _graceRope;

		private Rope _armedRope;

		private float _graceUntil;

		private void Awake()
		{
			_window = new RopeObserverWindow(((Component)this).transform);
		}

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception ex)
			{
				if (ModConfig.DebugLog.Value)
				{
					PluginInfo.Warn(ex.ToString());
				}
			}
		}

		private void Tick()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			RopeView view;
			if (!ModConfig.Enable.Value)
			{
				ResetState();
				_window.SetVisible(visible: false);
			}
			else if (RopeSpoolWatcher.TryGetLocalRope(out view))
			{
				if ((Object)(object)_tracked != (Object)null && (Object)(object)_tracked != (Object)(object)view.Rope && (int)_tracked.attachmenState == 2)
				{
					ArmGrace(_tracked);
				}
				_tracked = view.Rope;
				if (view.LengthMeters >= ModConfig.MinLengthMeters.Value)
				{
					_graceUntil = 0f;
					Show(view);
				}
				else if (!TryShowGrace())
				{
					_window.SetVisible(visible: false);
				}
			}
			else
			{
				if ((Object)(object)_tracked != (Object)null && (int)_tracked.attachmenState == 2)
				{
					ArmGrace(_tracked);
				}
				if (!TryShowGrace())
				{
					ResetState();
					_window.SetVisible(visible: false);
				}
			}
		}

		private void ArmGrace(Rope rope)
		{
			float num = Mathf.Max(0f, ModConfig.KeepAfterPlaceSeconds.Value);
			if (!(num <= 0f) && !((Object)(object)rope == (Object)null) && !((Object)(object)rope == (Object)(object)_armedRope))
			{
				_graceRope = rope;
				_armedRope = rope;
				_graceUntil = Time.time + num;
			}
		}

		private bool TryShowGrace()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (_graceUntil <= 0f || Time.time >= _graceUntil)
			{
				return false;
			}
			if ((Object)(object)_graceRope == (Object)null)
			{
				return false;
			}
			if (!RopeSpoolWatcher.TryGetRopeView(_graceRope, GetPlayerPos(), out var view))
			{
				return false;
			}
			Show(view);
			return true;
		}

		private void Show(RopeView view)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			HandleCameraKeys();
			Vector3 focus = RopeSpoolWatcher.PickFocus(view, ModConfig.FocusPart.Value);
			_window.UpdateTransform(focus, view.PlayerPos);
			_window.SetVisible(visible: true);
		}

		private void ResetState()
		{
			_tracked = null;
			_graceRope = null;
			_armedRope = null;
			_graceUntil = 0f;
		}

		private static Vector3 GetPlayerPos()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.localPlayer;
			Character val = ((localPlayer != null) ? localPlayer.character : null);
			if (!((Object)(object)val != (Object)null))
			{
				return Vector3.zero;
			}
			return val.Center;
		}

		private void HandleCameraKeys()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0034: 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)
			bool flag = IsHeld(ModConfig.VerticalModifierKey.Value);
			bool num = IsHeld(ModConfig.FarKey.Value);
			bool flag2 = IsHeld(ModConfig.NearKey.Value);
			bool flag3 = IsHeld(ModConfig.LeftKey.Value);
			bool flag4 = IsHeld(ModConfig.RightKey.Value);
			float num2 = ModConfig.MoveSpeed.Value * Time.unscaledDeltaTime;
			float num3 = ModConfig.ElevationSpeed.Value * Time.unscaledDeltaTime;
			bool flag5 = false;
			if (num)
			{
				if (flag)
				{
					ModConfig.Elevation.Value = Mathf.Clamp(ModConfig.Elevation.Value + num3, -30f, 89f);
				}
				else
				{
					ModConfig.CameraDistance.Value = Mathf.Clamp(ModConfig.CameraDistance.Value + num2, 0.5f, 100f);
				}
				flag5 = true;
			}
			if (flag2)
			{
				if (flag)
				{
					ModConfig.Elevation.Value = Mathf.Clamp(ModConfig.Elevation.Value - num3, -30f, 89f);
				}
				else
				{
					ModConfig.CameraDistance.Value = Mathf.Clamp(ModConfig.CameraDistance.Value - num2, 0.5f, 100f);
				}
				flag5 = true;
			}
			if (flag3)
			{
				ModConfig.HorizontalOffset.Value = Mathf.Clamp(ModConfig.HorizontalOffset.Value - num2, -50f, 50f);
				flag5 = true;
			}
			if (flag4)
			{
				ModConfig.HorizontalOffset.Value = Mathf.Clamp(ModConfig.HorizontalOffset.Value + num2, -50f, 50f);
				flag5 = true;
			}
			if (flag5)
			{
				_tuningHeld = true;
				_tuningDirty = true;
			}
			else
			{
				if (!_tuningHeld)
				{
					return;
				}
				_tuningHeld = false;
				if (_tuningDirty)
				{
					ConfigFile config = ModConfig.Config;
					if (config != null)
					{
						config.Save();
					}
					_tuningDirty = false;
				}
			}
		}

		private static bool IsHeld(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key != 0)
			{
				return Input.GetKey(key);
			}
			return false;
		}

		private void OnGUI()
		{
			try
			{
				_window?.Draw();
			}
			catch (Exception ex)
			{
				if (ModConfig.DebugLog.Value)
				{
					PluginInfo.Warn(ex.ToString());
				}
			}
		}

		private void OnDestroy()
		{
			_window?.Release();
			_window = null;
		}
	}
	internal sealed class RopeObserverWindow
	{
		private const float DrawMargin = 12f;

		private readonly Transform _parent;

		private GameObject _camObj;

		private Camera _cam;

		private RenderTexture _rt;

		private int _rtWidth;

		private int _rtHeight;

		private bool _visible;

		private bool _dragging;

		private Vector2 _dragOffset;

		private static Type _urpCameraDataType;

		private static bool _urpTypeResolved;

		private static GUIStyle _labelStyle;

		public RopeObserverWindow(Transform parent)
		{
			_parent = parent;
		}

		public void UpdateTransform(Vector3 focus, Vector3 playerPos)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_003c: 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_0092: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_006a: 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_0070: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			EnsureRig();
			EnsureRenderTexture();
			if (!((Object)(object)_camObj == (Object)null) && !((Object)(object)_cam == (Object)null))
			{
				Vector3 up = Vector3.up;
				Vector3 val = Vector3.ProjectOnPlane(playerPos - focus, up);
				if (((Vector3)(ref val)).sqrMagnitude < 0.04f)
				{
					Camera main = Camera.main;
					val = (((Object)(object)main != (Object)null) ? Vector3.ProjectOnPlane(((Component)main).transform.forward, up) : Vector3.forward);
				}
				if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
				{
					val = Vector3.forward;
				}
				((Vector3)(ref val)).Normalize();
				Vector3 val2 = Vector3.Cross(up, val);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				float num = Mathf.Clamp(ModConfig.Elevation.Value, -30f, 89f) * ((float)Math.PI / 180f);
				Vector3 val3 = -val * Mathf.Cos(num) + up * Mathf.Sin(num);
				((Vector3)(ref val3)).Normalize();
				float num2 = Mathf.Clamp(ModConfig.CameraDistance.Value, 0.5f, 100f);
				float value = ModConfig.HorizontalOffset.Value;
				Vector3 val4 = focus + val3 * num2 + normalized * value;
				Vector3 val5 = focus - val4;
				if (((Vector3)(ref val5)).sqrMagnitude < 1E-06f)
				{
					val5 = -val3;
				}
				((Vector3)(ref val5)).Normalize();
				Vector3 val6 = ((Mathf.Abs(Vector3.Dot(val5, up)) > 0.999f) ? val : up);
				_camObj.transform.position = val4;
				_camObj.transform.rotation = Quaternion.LookRotation(val5, val6);
				_cam.fieldOfView = Mathf.Clamp(ModConfig.Fov.Value, 20f, 110f);
			}
		}

		public void SetVisible(bool visible)
		{
			_visible = visible;
			if ((Object)(object)_cam != (Object)null)
			{
				((Behaviour)_cam).enabled = visible;
			}
		}

		private void EnsureRig()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (!((Object)(object)_camObj != (Object)null))
			{
				_camObj = new GameObject("RopeObserver_Camera");
				_camObj.transform.SetParent(_parent, false);
				((Object)_camObj).hideFlags = (HideFlags)61;
				_cam = _camObj.AddComponent<Camera>();
				((Behaviour)_cam).enabled = false;
				_cam.depth = -50f;
				_cam.clearFlags = (CameraClearFlags)1;
				_cam.nearClipPlane = 0.03f;
				_cam.farClipPlane = 1500f;
				_cam.allowHDR = false;
				_cam.allowMSAA = false;
				_cam.stereoTargetEye = (StereoTargetEyeMask)0;
				int num = LayerMask.NameToLayer("UI");
				if (num >= 0)
				{
					Camera cam = _cam;
					cam.cullingMask &= ~(1 << num);
				}
				EnsureUrpCameraData();
			}
		}

		private void EnsureUrpCameraData()
		{
			if (!_urpTypeResolved || !(_urpCameraDataType == null))
			{
				if (_urpCameraDataType == null)
				{
					_urpTypeResolved = true;
					_urpCameraDataType = ResolveUrpCameraType();
				}
				if (_urpCameraDataType != null && (Object)(object)((Component)_cam).GetComponent(_urpCameraDataType) == (Object)null)
				{
					((Component)_cam).gameObject.AddComponent(_urpCameraDataType);
				}
			}
		}

		private static Type ResolveUrpCameraType()
		{
			Type type = Type.GetType("UnityEngine.Rendering.Universal.UniversalAdditionalCameraData, Unity.RenderPipelines.Universal.Runtime");
			if (type != null)
			{
				return type;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				type = assemblies[i].GetType("UnityEngine.Rendering.Universal.UniversalAdditionalCameraData");
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private void EnsureRenderTexture()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			int num = Mathf.Clamp(Mathf.RoundToInt(ModConfig.WindowWidth.Value), 96, 1280);
			int num2 = Mathf.Clamp(Mathf.RoundToInt((float)num * 9f / 16f), 54, 720);
			if (!((Object)(object)_rt != (Object)null) || num != _rtWidth || num2 != _rtHeight)
			{
				ReleaseRenderTexture();
				_rtWidth = num;
				_rtHeight = num2;
				_rt = new RenderTexture(num, num2, 24, (RenderTextureFormat)7);
				((Object)_rt).hideFlags = (HideFlags)61;
				_rt.Create();
				if ((Object)(object)_cam != (Object)null)
				{
					_cam.targetTexture = _rt;
				}
			}
		}

		private void ReleaseRenderTexture()
		{
			if ((Object)(object)_cam != (Object)null)
			{
				_cam.targetTexture = null;
			}
			if ((Object)(object)_rt != (Object)null)
			{
				_rt.Release();
				Object.Destroy((Object)(object)_rt);
				_rt = null;
			}
		}

		public void Draw()
		{
			//IL_0055: 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_005c: 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_00b4: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			if (_visible && !((Object)(object)_rt == (Object)null))
			{
				EnsureLabelStyle();
				float num = Mathf.Clamp(ModConfig.WindowWidth.Value, 96f, Mathf.Max(96f, (float)Screen.width - 16f));
				float h = num * 9f / 16f;
				Rect val = WindowRect(num, h);
				HandleDrag(val);
				GUI.color = new Color(0f, 0f, 0f, 0.85f);
				GUI.DrawTexture(new Rect(((Rect)(ref val)).x - 2f, ((Rect)(ref val)).y - 2f, ((Rect)(ref val)).width + 4f, ((Rect)(ref val)).height + 4f), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = Color.white;
				GUI.DrawTexture(val, (Texture)(object)_rt, (ScaleMode)0, false);
				if (ModConfig.ShowLabel.Value)
				{
					string text = (string.IsNullOrEmpty(ModConfig.LabelText.Value) ? L.T("绳索预览", "Rope Preview") : ModConfig.LabelText.Value);
					DrawLabel(val, text);
				}
			}
		}

		private static Rect WindowRect(float w, float h)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			float num = ModConfig.WindowX.Value;
			float num2 = ModConfig.WindowY.Value;
			if (num < 0f)
			{
				num = 12f;
			}
			if (num2 < 0f)
			{
				num2 = (float)Screen.height - h - 12f;
			}
			num = Mathf.Clamp(num, 0f, Mathf.Max(0f, (float)Screen.width - w));
			num2 = Mathf.Clamp(num2, 0f, Mathf.Max(0f, (float)Screen.height - h));
			return new Rect(num, num2, w, h);
		}

		private void HandleDrag(Rect rect)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Invalid comparison between Unknown and I4
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Event current = Event.current;
			if (current == null)
			{
				return;
			}
			if (!_dragging)
			{
				if ((int)current.type == 0 && current.button == 0 && ((Rect)(ref rect)).Contains(current.mousePosition) && IsDragModifierHeld())
				{
					_dragging = true;
					_dragOffset = current.mousePosition - new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y);
					current.Use();
				}
			}
			else if ((int)current.type == 3 && current.button == 0)
			{
				Vector2 val = current.mousePosition - _dragOffset;
				ModConfig.WindowX.Value = val.x;
				ModConfig.WindowY.Value = val.y;
				current.Use();
			}
			else if ((int)current.type == 1 && current.button == 0)
			{
				_dragging = false;
				ConfigFile config = ModConfig.Config;
				if (config != null)
				{
					config.Save();
				}
				current.Use();
			}
		}

		private static bool IsDragModifierHeld()
		{
			//IL_0005: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = ModConfig.DragModifierKey.Value;
			if ((int)value != 0)
			{
				return Input.GetKey(value);
			}
			return false;
		}

		private static void DrawLabel(Rect windowRect, string text)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0069: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(text))
			{
				GUIContent val = new GUIContent(text);
				Vector2 val2 = _labelStyle.CalcSize(val);
				Rect val3 = default(Rect);
				((Rect)(ref val3))..ctor(((Rect)(ref windowRect)).x + 4f, ((Rect)(ref windowRect)).y + 4f, val2.x + 10f, val2.y + 4f);
				GUI.color = new Color(0f, 0f, 0f, 0.7f);
				GUI.DrawTexture(val3, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = Color.white;
				GUI.Label(new Rect(((Rect)(ref val3)).x + 5f, ((Rect)(ref val3)).y + 2f, val2.x, val2.y), val, _labelStyle);
			}
		}

		private static void EnsureLabelStyle()
		{
			//IL_0012: 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_0024: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (_labelStyle == null)
			{
				_labelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13
				};
				_labelStyle.normal.textColor = Color.white;
				_labelStyle.font = CreateChineseFont();
			}
		}

		private static Font CreateChineseFont()
		{
			try
			{
				Font val = Font.CreateDynamicFontFromOSFont(new string[6] { "Microsoft YaHei", "微软雅黑", "SimHei", "黑体", "Noto Sans CJK SC", "Arial" }, 13);
				if ((Object)(object)val != (Object)null)
				{
					((Object)val).hideFlags = (HideFlags)61;
				}
				return val;
			}
			catch
			{
				return null;
			}
		}

		public void Release()
		{
			ReleaseRenderTexture();
			if ((Object)(object)_camObj != (Object)null)
			{
				Object.Destroy((Object)(object)_camObj);
				_camObj = null;
				_cam = null;
			}
		}
	}
	internal sealed class RopeView
	{
		public RopeSpool Spool;

		public Rope Rope;

		public float LengthMeters;

		public List<Transform> Segments;

		public Vector3 StartPos;

		public Vector3 EndPos;

		public Vector3 PlayerPos;
	}
	internal static class RopeSpoolWatcher
	{
		public static bool TryGetLocalRope(out RopeView view)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Invalid comparison between Unknown and I4
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			view = null;
			Player localPlayer = Player.localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Character character = localPlayer.character;
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			CharacterData data = character.data;
			Item val = ((data != null) ? data.currentItem : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if ((int)val.itemState != 1)
			{
				return false;
			}
			RopeSpool componentInChildren = ((Component)val).GetComponentInChildren<RopeSpool>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return false;
			}
			Rope rope = componentInChildren.rope;
			if ((Object)(object)rope == (Object)null)
			{
				return false;
			}
			if ((int)rope.attachmenState != 1)
			{
				return false;
			}
			if (!TryGetRopeView(rope, character.Center, out view))
			{
				return false;
			}
			view.Spool = componentInChildren;
			return true;
		}

		public static bool TryGetRopeView(Rope rope, Vector3 playerPos, out RopeView view)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			view = null;
			if ((Object)(object)rope == (Object)null)
			{
				return false;
			}
			List<Transform> ropeSegments = rope.GetRopeSegments();
			if (ropeSegments == null || ropeSegments.Count == 0)
			{
				return false;
			}
			if (!TryPickExtreme(ropeSegments, lowest: true, out var pos))
			{
				return false;
			}
			if (!TryPickExtreme(ropeSegments, lowest: false, out var pos2))
			{
				return false;
			}
			view = new RopeView
			{
				Rope = rope,
				LengthMeters = rope.GetLengthInMeters(),
				Segments = ropeSegments,
				StartPos = pos2,
				EndPos = pos,
				PlayerPos = playerPos
			};
			return true;
		}

		public static Vector3 PickFocus(RopeView view, int part)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			List<Transform> segments = view.Segments;
			if (segments == null || segments.Count == 0)
			{
				return view.EndPos;
			}
			if (part == 0 && TryPickExtreme(segments, lowest: true, out var pos))
			{
				return pos;
			}
			if (part == 2 && TryPickExtreme(segments, lowest: false, out var pos2))
			{
				return pos2;
			}
			if (TryPick(segments, segments.Count / 2, out var pos3))
			{
				return pos3;
			}
			return view.EndPos;
		}

		private static bool TryPickExtreme(List<Transform> segments, bool lowest, out Vector3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			pos = Vector3.zero;
			bool flag = false;
			float num = 0f;
			for (int i = 0; i < segments.Count; i++)
			{
				Transform val = segments[i];
				if (!((Object)(object)val == (Object)null))
				{
					float y = val.position.y;
					if (!flag || (lowest ? (y < num) : (y > num)))
					{
						num = y;
						pos = val.position;
						flag = true;
					}
				}
			}
			return flag;
		}

		private static bool TryPick(List<Transform> segments, int index, out Vector3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			pos = Vector3.zero;
			for (int i = 0; i < segments.Count; i++)
			{
				int num = index - i;
				if (num >= 0 && num < segments.Count && (Object)(object)segments[num] != (Object)null)
				{
					pos = segments[num].position;
					return true;
				}
				int num2 = index + i;
				if (num2 >= 0 && num2 < segments.Count && (Object)(object)segments[num2] != (Object)null)
				{
					pos = segments[num2].position;
					return true;
				}
			}
			return false;
		}
	}
}