Decompiled source of CinematicPath Toolkit v1.0.1

plugins/ChineseCanFly.CinematicPathToolkit.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ChineseCanFly.CinematicPathToolkit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+aed86014d19bf05a513bee91bba80cf530e90692")]
[assembly: AssemblyProduct("ChineseCanFly.CinematicPathToolkit")]
[assembly: AssemblyTitle("ChineseCanFly.CinematicPathToolkit")]
[assembly: AssemblyVersion("1.0.1.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 ChineseCanFly.CinematicPathToolkit
{
	[BepInPlugin("ChineseCanFly.CinematicPathToolkit", "CinematicPath Toolkit", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class TunerPlugin : BaseUnityPlugin
	{
		public const string Guid = "ChineseCanFly.CinematicPathToolkit";

		public const string CinematicPathGuid = "mrGMD.cinematicpath";

		internal static ManualLogSource Log;

		internal static TunerPlugin Instance;

		internal static ConfigEntry<KeyCode> Hotkey;

		internal static ConfigEntry<float> MinDuration;

		internal static ConfigEntry<float> MaxDuration;

		internal static ConfigEntry<bool> TakeOverMove;

		internal static ConfigEntry<bool> InvForward;

		internal static ConfigEntry<bool> InvStrafe;

		internal static ConfigEntry<bool> InvUp;

		internal static ConfigEntry<bool> InvMouseX;

		internal static ConfigEntry<bool> InvMouseY;

		internal static ConfigEntry<float> FlySpeed;

		internal static ConfigEntry<bool> SuppressKinematicWarnings;

		internal static FieldInfo IsFreeCamField;

		internal static FieldInfo IsEditModeField;

		internal static bool Open;

		internal static Type CpType;

		internal static Type CkType;

		internal static object Cp;

		internal static FieldInfo CheckpointsField;

		internal static FieldInfo ShowAllMenuField;

		internal static FieldInfo IsPlayingField;

		internal static MethodInfo RecalcMethod;

		internal static MethodInfo StartMethod;

		internal static MethodInfo StopMethod;

		internal static MethodInfo LengthMethod;

		internal static MethodInfo VisualsMethod;

		internal static FieldInfo PosField;

		internal static FieldInfo RotField;

		internal static FieldInfo MoveSpeedField;

		internal static FieldInfo RotSpeedField;

		private Rect _rect = new Rect(20f, 80f, 430f, 300f);

		private Vector2 _scroll;

		private readonly Dictionary<int, float> _dur = new Dictionary<int, float>();

		private int _lastCount = -1;

		private float _stopAt = -1f;

		private float _globalSpeed = 4f;

		private int _sel;

		private Vector3 _posCenter;

		private float _nextVisual;

		private bool _visualDirty;

		internal static bool Ready { get; private set; }

		private void Awake()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Expected O, but got Unknown
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Expected O, but got Unknown
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Expected O, but got Unknown
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Expected O, but got Unknown
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Toggle Hotkey", (KeyCode)287, "Open or close the tuner window. Close CinematicPath's own window first.");
			MinDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Min Duration", 0.3f, new ConfigDescription("Left end of the duration sliders (seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			MaxDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Max Duration", 30f, new ConfigDescription("Right end of the duration sliders (seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 120f), Array.Empty<object>()));
			string text = "Movement";
			TakeOverMove = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Take Over Movement", false, "Replace CinematicPath's freecam movement with this plugin's. Needed only if the controls feel wrong: it is the only way to flip axes. Default off = untouched.");
			InvForward = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Invert W/S", false, "Only used when Take Over Movement is on.");
			InvStrafe = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Invert A/D", false, "Only used when Take Over Movement is on.");
			InvUp = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Invert Space/Ctrl", false, "Only used when Take Over Movement is on (Space is up by default).");
			InvMouseX = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Invert Mouse X", false, "Only used when Take Over Movement is on.");
			InvMouseY = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Invert Mouse Y", false, "Only used when Take Over Movement is on.");
			FlySpeed = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Fly Speed", 8f, new ConfigDescription("Metres per second while flying (hold Left Shift for x2).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>()));
			SuppressKinematicWarnings = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "Silence Kinematic Velocity Warnings", true, "Unity logs 'Setting linear/angular velocity of a kinematic body is not supported' once per frame while the freecam rig makes the player kinematic. Setting velocity on a kinematic body does nothing anyway, so the try is dropped here to keep the log (and the per-frame native logging) quiet. Turn off to restore default behaviour.");
			try
			{
				CpType = AccessTools.TypeByName("CinematicPath");
				CkType = AccessTools.TypeByName("Checkpoint");
				if (CpType == null || CkType == null)
				{
					Log.LogWarning((object)"CinematicPath types not found - tuner idle.");
					return;
				}
				CheckpointsField = AccessTools.Field(CpType, "checkpoints");
				ShowAllMenuField = AccessTools.Field(CpType, "showAllMenu");
				IsPlayingField = AccessTools.Field(CpType, "isPlaying");
				IsFreeCamField = AccessTools.Field(CpType, "isFreeCam");
				IsEditModeField = AccessTools.Field(CpType, "isEditMode");
				RecalcMethod = AccessTools.Method(CpType, "RecalculateSegment", (Type[])null, (Type[])null);
				StartMethod = AccessTools.Method(CpType, "StartPlayback", new Type[1] { typeof(int) }, (Type[])null);
				StopMethod = AccessTools.Method(CpType, "StopPlayback", (Type[])null, (Type[])null);
				LengthMethod = AccessTools.Method(CpType, "CalculateBezierLength", (Type[])null, (Type[])null);
				VisualsMethod = AccessTools.Method(CpType, "UpdateVisuals", (Type[])null, (Type[])null);
				PosField = AccessTools.Field(CkType, "pos");
				RotField = AccessTools.Field(CkType, "rot");
				MoveSpeedField = AccessTools.Field(CkType, "moveSpeed");
				RotSpeedField = AccessTools.Field(CkType, "rotSpeed");
				if (CheckpointsField == null || RecalcMethod == null || StartMethod == null || StopMethod == null || LengthMethod == null || PosField == null || RotField == null)
				{
					Log.LogWarning((object)("CinematicPath members changed - tuner idle. Missing: " + ((CheckpointsField == null) ? "checkpoints " : "") + ((RecalcMethod == null) ? "RecalculateSegment " : "") + ((StartMethod == null) ? "StartPlayback " : "") + ((LengthMethod == null) ? "CalculateBezierLength " : "")));
					return;
				}
				Harmony val = new Harmony("ChineseCanFly.CinematicPathToolkit");
				val.Patch((MethodBase)AccessTools.Method(CpType, "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(TunerPlugin).GetMethod("SkipWhileOpen", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				MethodInfo methodInfo = AccessTools.Method(CpType, "HandleFreeCamInput", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(TunerPlugin).GetMethod("SkipTheirMovement", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				Ready = true;
				Log.LogInfo((object)"CinematicPath Toolkit v1.0.1 loaded (F6 = open).");
				if (SuppressKinematicWarnings.Value)
				{
					MethodInfo methodInfo2 = AccessTools.PropertySetter(typeof(Rigidbody), "linearVelocity") ?? AccessTools.Method(typeof(Rigidbody), "set_linearVelocity", (Type[])null, (Type[])null);
					MethodInfo methodInfo3 = AccessTools.PropertySetter(typeof(Rigidbody), "angularVelocity") ?? AccessTools.Method(typeof(Rigidbody), "set_angularVelocity", (Type[])null, (Type[])null);
					if (methodInfo2 != null)
					{
						val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(TunerPlugin).GetMethod("SkipForKinematic", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					if (methodInfo3 != null)
					{
						val.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(TunerPlugin).GetMethod("SkipForKinematic", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					Log.LogInfo((object)("kinematic velocity warnings: " + ((methodInfo2 != null && methodInfo3 != null) ? "suppressed" : "patch target missing")));
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Cinematic Tuner failed to initialise: " + ex));
			}
		}

		private static bool SkipForKinematic(Rigidbody __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				return !__instance.isKinematic;
			}
			return true;
		}

		private static bool SkipWhileOpen()
		{
			return !Open;
		}

		private static bool SkipTheirMovement()
		{
			return !TakeOverMove.Value;
		}

		private static bool InFreeCam()
		{
			try
			{
				return IsFreeCamField != null && Cp != null && (bool)IsFreeCamField.GetValue(Cp);
			}
			catch
			{
				return false;
			}
		}

		private static bool IsPlaying()
		{
			try
			{
				return IsPlayingField != null && Cp != null && (bool)IsPlayingField.GetValue(Cp);
			}
			catch
			{
				return false;
			}
		}

		private static bool TheirMenuOpen()
		{
			try
			{
				bool num = ShowAllMenuField != null && Cp != null && (bool)ShowAllMenuField.GetValue(Cp);
				bool flag = IsEditModeField != null && Cp != null && (bool)IsEditModeField.GetValue(Cp);
				return num || flag;
			}
			catch
			{
				return false;
			}
		}

		private void DoMovement()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if (!((Object)(object)main == (Object)null))
			{
				Transform transform = ((Component)main).transform;
				float num = Input.GetAxis("Mouse X") * 2f * (InvMouseX.Value ? (-1f) : 1f);
				float num2 = Input.GetAxis("Mouse Y") * 2f * (InvMouseY.Value ? (-1f) : 1f);
				Vector3 eulerAngles = transform.eulerAngles;
				eulerAngles.y += num;
				float num3 = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x);
				num3 = Mathf.Clamp(num3 - num2, -89f, 89f);
				eulerAngles.x = (num3 + 360f) % 360f;
				transform.eulerAngles = eulerAngles;
				float num4 = Input.GetAxis("Vertical") * (InvForward.Value ? (-1f) : 1f);
				float num5 = Input.GetAxis("Horizontal") * (InvStrafe.Value ? (-1f) : 1f);
				float num6 = 0f;
				if (Input.GetKey((KeyCode)32))
				{
					num6 += 1f;
				}
				if (Input.GetKey((KeyCode)306))
				{
					num6 -= 1f;
				}
				num6 *= (InvUp.Value ? (-1f) : 1f);
				Vector3 val = transform.forward * num4 + transform.right * num5 + Vector3.up * num6;
				if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
				{
					((Vector3)(ref val)).Normalize();
				}
				float num7 = FlySpeed.Value * (Input.GetKey((KeyCode)304) ? 2f : 1f);
				transform.position += val * num7 * Time.deltaTime;
			}
		}

		private void Update()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (!Ready)
			{
				return;
			}
			if (Input.GetKeyDown(Hotkey.Value))
			{
				Toggle();
			}
			if (Cp == null)
			{
				if (Chainloader.PluginInfos.TryGetValue("mrGMD.cinematicpath", out var value) && (Object)(object)value.Instance != (Object)null)
				{
					Cp = value.Instance;
				}
				return;
			}
			if (TakeOverMove.Value && !Open && InFreeCam() && !IsPlaying() && !TheirMenuOpen())
			{
				DoMovement();
			}
			if (Open)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				if (_stopAt > 0f && Time.time >= _stopAt)
				{
					Stop();
				}
				if (Input.GetKeyDown((KeyCode)27))
				{
					Toggle();
				}
			}
		}

		private void Toggle()
		{
			Open = !Open;
			if (Open)
			{
				try
				{
					ShowAllMenuField?.SetValue(Cp, false);
					IsEditModeField?.SetValue(Cp, false);
				}
				catch
				{
				}
				_stopAt = -1f;
				return;
			}
			try
			{
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
			catch
			{
			}
		}

		private IList Cps()
		{
			if (Cp == null)
			{
				return null;
			}
			return CheckpointsField.GetValue(Cp) as IList;
		}

		private float Length(object a, object b)
		{
			return (float)LengthMethod.Invoke(Cp, new object[3] { a, b, 20 });
		}

		private float Angle(object a, object b)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0024: 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_002c: 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_0032: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0080: 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)
			Quaternion val = (Quaternion)RotField.GetValue(a);
			Quaternion val2 = (Quaternion)RotField.GetValue(b);
			Vector3 eulerAngles = ((Quaternion)(ref val)).eulerAngles;
			Vector3 eulerAngles2 = ((Quaternion)(ref val2)).eulerAngles;
			float num = Mathf.Abs(Mathf.DeltaAngle(eulerAngles.y, eulerAngles2.y));
			float num2 = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x);
			float num3 = ((eulerAngles2.x > 180f) ? (eulerAngles2.x - 360f) : eulerAngles2.x);
			return Mathf.Max(num, Mathf.Abs(num3 - num2));
		}

		private float Duration(object segStart, float len, float ang)
		{
			float num = ((MoveSpeedField != null) ? ((float)MoveSpeedField.GetValue(segStart)) : 0f);
			float num2 = ((RotSpeedField != null) ? ((float)RotSpeedField.GetValue(segStart)) : 0f);
			float num3 = ((num > 0.01f) ? (len / num) : 0f);
			float num4 = ((num2 > 0.01f && ang > 0.01f) ? (ang / num2) : 0f);
			return Mathf.Max(num3, num4);
		}

		private void SetDuration(int index, float seconds)
		{
			IList list = Cps();
			if (list == null)
			{
				return;
			}
			try
			{
				RecalcMethod.Invoke(Cp, new object[4] { list, index, seconds, true });
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("set duration failed: " + ex.Message));
			}
		}

		private void Play(int index, float seconds)
		{
			IList list = Cps();
			if (list == null || list.Count < 2)
			{
				return;
			}
			try
			{
				Stop();
				StartMethod.Invoke(Cp, new object[1] { index });
				_stopAt = Time.time + Mathf.Max(0.3f, seconds) + 0.15f;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("play failed: " + ex.Message));
			}
		}

		private void Stop()
		{
			_stopAt = -1f;
			try
			{
				StopMethod?.Invoke(Cp, null);
			}
			catch
			{
			}
		}

		private Vector3 PosOf(object cp)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return (Vector3)PosField.GetValue(cp);
		}

		private void Dirty()
		{
			_visualDirty = true;
		}

		private void TickVisuals()
		{
			if (!_visualDirty || Time.time < _nextVisual)
			{
				return;
			}
			_visualDirty = false;
			_nextVisual = Time.time + 0.1f;
			try
			{
				VisualsMethod?.Invoke(Cp, new object[1]);
			}
			catch
			{
			}
		}

		private void OnGUI()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00ac: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!Ready || !Open || Cp == null)
			{
				return;
			}
			IList list = Cps();
			int num = list?.Count ?? 0;
			if (num != _lastCount)
			{
				_lastCount = num;
				_dur.Clear();
				_sel = Mathf.Clamp(_sel, 0, Mathf.Max(0, num - 1));
				if (num > 0)
				{
					_posCenter = PosOf(list[_sel]);
				}
			}
			_rect = GUILayout.Window(7311, _rect, new WindowFunction(DrawWindow), "Cinematic Tuner  (F6 关闭)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(500f) });
		}

		private void DrawWindow(int id)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_073a: Unknown result type (might be due to invalid IL or missing references)
			//IL_075f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0764: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: 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_022a: 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_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: 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_0196: 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_01b2: 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_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a15: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			IList list = Cps();
			int num = list?.Count ?? 0;
			int num2 = Mathf.Max(0, num - 1);
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			if (num > 0)
			{
				_sel = Mathf.Clamp(_sel, 0, num - 1);
				object obj = list[_sel];
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("点位", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) });
				if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }))
				{
					_sel = (_sel - 1 + num) % num;
					_posCenter = PosOf(list[_sel]);
				}
				GUILayout.Label($"#{_sel + 1} / {num}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(62f) });
				if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }))
				{
					_sel = (_sel + 1) % num;
					_posCenter = PosOf(list[_sel]);
				}
				if (GUILayout.Button("⊙ 记成当前相机", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(116f) }))
				{
					Camera main = Camera.main;
					if ((Object)(object)main != (Object)null)
					{
						PosField.SetValue(obj, ((Component)main).transform.position);
						RotField.SetValue(obj, ((Component)main).transform.rotation);
						_posCenter = ((Component)main).transform.position;
						Dirty();
					}
				}
				if (GUILayout.Button("← 飞到这个点", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
				{
					Camera main2 = Camera.main;
					if ((Object)(object)main2 != (Object)null)
					{
						((Component)main2).transform.position = PosOf(obj);
						((Component)main2).transform.rotation = (Quaternion)RotField.GetValue(obj);
					}
				}
				GUILayout.EndHorizontal();
				Vector3 val = PosOf(obj);
				Vector3 val2 = val - _posCenter;
				if (((Vector3)(ref val2)).sqrMagnitude > 900f)
				{
					_posCenter = val;
				}
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("X 前/后", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
				float num3 = GUILayout.HorizontalSlider(val.x, _posCenter.x - 25f, _posCenter.x + 25f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
				GUILayout.Label(val.x.ToString("0.0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Y 高/低", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
				float num4 = GUILayout.HorizontalSlider(val.y, _posCenter.y - 25f, _posCenter.y + 25f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
				GUILayout.Label(val.y.ToString("0.0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Z 左/右", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
				float num5 = GUILayout.HorizontalSlider(val.z, _posCenter.z - 25f, _posCenter.z + 25f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
				GUILayout.Label(val.z.ToString("0.0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				GUILayout.EndHorizontal();
				Quaternion val3 = (Quaternion)RotField.GetValue(obj);
				Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles;
				float num6 = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("朝向 左右", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
				float num7 = GUILayout.HorizontalSlider(eulerAngles.y, 0f, 360f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
				GUILayout.Label(eulerAngles.y.ToString("0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("朝向 上下", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
				float num8 = GUILayout.HorizontalSlider(num6, -89f, 89f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
				GUILayout.Label(num6.ToString("0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) });
				GUILayout.EndHorizontal();
				bool num9 = Mathf.Abs(num3 - val.x) > 0.001f || Mathf.Abs(num4 - val.y) > 0.001f || Mathf.Abs(num5 - val.z) > 0.001f;
				bool flag = Mathf.Abs(Mathf.DeltaAngle(num7, eulerAngles.y)) > 0.01f || Mathf.Abs(num8 - num6) > 0.01f;
				if (num9)
				{
					PosField.SetValue(obj, (object)new Vector3(num3, num4, num5));
					Dirty();
				}
				if (flag)
				{
					RotField.SetValue(obj, Quaternion.Euler(num8, num7, 0f));
					Dirty();
				}
				TickVisuals();
				GUILayout.Label("X/Y/Z 滑条窗口 = 当前值 ±25 米;想让窗口挪到别处,先把点飞过去再拉一下", Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("还没有检查点:先按 F10 进自由飞,左键记点", Array.Empty<GUILayoutOption>());
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("统一速度", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			_globalSpeed = GUILayout.HorizontalSlider(_globalSpeed, 0.5f, 12f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) });
			GUILayout.Label($"{_globalSpeed:0.0} 米/秒", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(85f) });
			if (GUILayout.Button("套到全部", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
			{
				for (int i = 0; i < num2; i++)
				{
					float num10 = Length(list[i], list[i + 1]);
					if (num10 > 0.05f)
					{
						SetDuration(i, num10 / _globalSpeed);
					}
				}
				_dur.Clear();
			}
			GUILayout.EndHorizontal();
			GUILayout.Label("段:拖动即时生效;关掉本窗口后按右键重开模组窗口,数字会刷新", Array.Empty<GUILayoutOption>());
			_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(Mathf.Max(40f, (float)num2 * 28f)) });
			for (int j = 0; j < num2; j++)
			{
				object obj2 = list[j];
				object b = list[j + 1];
				float num11 = Length(obj2, b);
				float num12 = Angle(obj2, b);
				float num13 = Duration(obj2, num11, num12);
				if (!_dur.ContainsKey(j))
				{
					_dur[j] = ((num13 > 0.05f) ? num13 : 3f);
				}
				else if (!GUI.changed && Mathf.Abs(_dur[j] - num13) > 0.02f)
				{
					_dur[j] = num13;
				}
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label($"#{j + 1}→#{j + 2}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) });
				GUILayout.Label($"{num11:0.0}m {num12:0}°", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(88f) });
				float num14 = GUILayout.HorizontalSlider(_dur[j], MinDuration.Value, MaxDuration.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
				if (Mathf.Abs(num14 - _dur[j]) > 0.001f)
				{
					_dur[j] = num14;
					SetDuration(j, num14);
				}
				float num15 = ((num14 > 0.01f) ? (num11 / num14) : 0f);
				GUILayout.Label($"{num14:0.00}s {num15:0.0}m/s", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(104f) });
				if (GUILayout.Button("▶", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }))
				{
					Play(j, num14);
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("全播", Array.Empty<GUILayoutOption>()))
			{
				IList list2 = Cps();
				if (list2 != null && list2.Count >= 2)
				{
					Play(0, 1f);
					_stopAt = -1f;
				}
			}
			if (GUILayout.Button("停止", Array.Empty<GUILayoutOption>()))
			{
				Stop();
			}
			if (GUILayout.Button("重新算全部时长", Array.Empty<GUILayoutOption>()))
			{
				_lastCount = -1;
				_dur.Clear();
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}
	}
}