Decompiled source of Aliens Speedrun Paths v1.0.1

plugins/AliensSpeedrunPaths.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Fields;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Alienpxgaming")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Copyright © 2026 Alienpxgaming. All rights reserved.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("Alien's Speedrun Paths")]
[assembly: AssemblyTitle("AliensSpeedrunPaths")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
[BepInPlugin("alien.runrecorder", "Run Path Recorder Compare Speed Kills", "9.3.0")]
public class Plugin : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <AutoStartAfterSceneLoad>d__67 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public Plugin <>4__this;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <AutoStartAfterSceneLoad>d__67(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if (!<>4__this.isRecording && (Object)(object)<>4__this.GetPlayerTransform() != (Object)null)
				{
					<>4__this.StartRecording();
					<>4__this.SetStatus("AUTO RECORDING STARTED");
				}
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private PluginConfigurator pluginConfig;

	private EnumField<BindKey> recordKeyField;

	private EnumField<BindKey> loadKeyField;

	private EnumField<BindKey> autoStartKeyField;

	private EnumField<BindKey> toggleGhostKeyField;

	private EnumField<BindKey> clearKeyField;

	private EnumField<BindKey> toggleTimeKeyField;

	private EnumField<BindKey> menuKeyField;

	private BoolField autoStartField;

	private BoolField showActionTimesField;

	private FloatField highHorizontalSpeedThresholdField;

	private FloatField horizontalSpeedDropThresholdField;

	private FloatField verticalSpeedThresholdField;

	private FloatField routeDifferenceThresholdField;

	private bool isRecording = false;

	private bool ghostVisible = true;

	private bool menuOpen = false;

	private float recordTimer = 0f;

	private float recordInterval = 0.08f;

	private float checkpointScanTimer = 0f;

	private float checkpointScanInterval = 0.3f;

	private float checkpointDetectDistance = 5f;

	private float enemyScanTimer = 0f;

	private float enemyScanInterval = 0.25f;

	private float speedEventTimer = 0f;

	private float speedEventInterval = 0.45f;

	private float lastSampledHorizontalSpeed = 0f;

	private bool hasLastSpeedSample = false;

	private float fallbackRecordStartTime;

	private float hoverScreenRadius = 95f;

	private float hoverMaxWorldDistance = 200f;

	private float clusterDistance = 3f;

	private float routeDifferenceSampleStep = 0.5f;

	private float routeDifferenceCooldown = 2f;

	private List<RunPoint> currentPoints = new List<RunPoint>();

	private List<ActionPoint> currentActions = new List<ActionPoint>();

	private List<CheckpointPoint> currentCheckpoints = new List<CheckpointPoint>();

	private List<KillPoint> currentKills = new List<KillPoint>();

	private List<SpeedMarkerPoint> currentSpeedMarkers = new List<SpeedMarkerPoint>();

	private List<RunPoint> loadedAPoints = new List<RunPoint>();

	private List<RunPoint> loadedBPoints = new List<RunPoint>();

	private bool loadedA = false;

	private bool loadedB = false;

	private HashSet<string> touchedCheckpointIds = new HashSet<string>();

	private Dictionary<int, EnemyTrack> trackedEnemies = new Dictionary<int, EnemyTrack>();

	private readonly List<GameObject> ghostObjects = new List<GameObject>();

	private readonly List<HoverMarker> hoverMarkers = new List<HoverMarker>();

	private string saveFolder;

	private string latestRunPath;

	private string defaultRunColorHex = "#00FFFF";

	private string activeColorFilter = "";

	private ColorOption[] palette = new ColorOption[8]
	{
		new ColorOption("Cyan", "#00FFFF"),
		new ColorOption("Pink", "#FF40FF"),
		new ColorOption("Yellow", "#FFFF00"),
		new ColorOption("Green", "#40FF40"),
		new ColorOption("Red", "#FF4040"),
		new ColorOption("Blue", "#4080FF"),
		new ColorOption("Orange", "#FF9900"),
		new ColorOption("White", "#FFFFFF")
	};

	private string screenStatus = "";

	private float screenStatusTimer = 0f;

	private GUIStyle keybindStyle;

	private GUIStyle statusStyle;

	private GUIStyle menuStyle;

	private GUIStyle buttonStyle;

	private GUIStyle smallStyle;

	private GUIStyle selectedStyle;

	private Vector2 menuScroll = Vector2.zero;

	private List<RunFileEntry> runFiles = new List<RunFileEntry>();

	private Dictionary<string, string> renameInputs = new Dictionary<string, string>();

	private void Awake()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Run Path Recorder Compare Speed Kills loaded.");
		CreatePluginConfiguratorMenu();
		saveFolder = Path.Combine(Paths.PluginPath, "AlienRuns");
		if (!Directory.Exists(saveFolder))
		{
			Directory.CreateDirectory(saveFolder);
		}
		latestRunPath = Path.Combine(saveFolder, "latest_run.txt");
		SceneManager.activeSceneChanged += OnSceneChanged;
		RefreshRunFiles();
		SetStatus("RUN RECORDER LOADED");
	}

	private void CreatePluginConfiguratorMenu()
	{
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Expected O, but got Unknown
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Expected O, but got Unknown
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Expected O, but got Unknown
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Expected O, but got Unknown
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: 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
		pluginConfig = PluginConfigurator.Create("Run Path Recorder", "alien.runrecorder");
		recordKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Start/Stop Recording Key", "key_start_stop_recording", BindKey.Semicolon);
		loadKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Load Latest Run to A Key", "key_load_latest_run_to_a", BindKey.Quote);
		autoStartKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Toggle Auto Start Key", "key_toggle_auto_start", BindKey.LeftBracket);
		toggleGhostKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Show/Hide Loaded Runs Key", "key_show_hide_loaded_runs", BindKey.Comma);
		clearKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Clear Loaded Runs Key", "key_clear_loaded_runs", BindKey.Period);
		toggleTimeKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Toggle Dot Time Key", "key_toggle_dot_time", BindKey.Backslash);
		menuKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Open/Close Run Menu Key", "key_open_close_menu", BindKey.RightBracket);
		autoStartField = new BoolField(pluginConfig.rootPanel, "Auto-start recording on level entry", "auto_start_recording", false);
		showActionTimesField = new BoolField(pluginConfig.rootPanel, "Show dot run time text", "show_dot_time_text", true);
		highHorizontalSpeedThresholdField = new FloatField(pluginConfig.rootPanel, "High horizontal speed threshold", "high_horizontal_speed_threshold", 35f);
		horizontalSpeedDropThresholdField = new FloatField(pluginConfig.rootPanel, "Speed drop threshold", "horizontal_speed_drop_threshold", 18f);
		verticalSpeedThresholdField = new FloatField(pluginConfig.rootPanel, "Vertical speed threshold", "vertical_speed_threshold", 12f);
		routeDifferenceThresholdField = new FloatField(pluginConfig.rootPanel, "Route difference marker distance", "route_difference_threshold", 8f);
		highHorizontalSpeedThresholdField.minimumValue = 0f;
		highHorizontalSpeedThresholdField.maximumValue = 200f;
		horizontalSpeedDropThresholdField.minimumValue = 0f;
		horizontalSpeedDropThresholdField.maximumValue = 200f;
		verticalSpeedThresholdField.minimumValue = 0f;
		verticalSpeedThresholdField.maximumValue = 200f;
		routeDifferenceThresholdField.minimumValue = 0f;
		routeDifferenceThresholdField.maximumValue = 100f;
	}

	private void OnDestroy()
	{
		SceneManager.activeSceneChanged -= OnSceneChanged;
	}

	private void OnSceneChanged(Scene oldScene, Scene newScene)
	{
		if (isRecording)
		{
			StopRecordingAndSave("LEVEL FINISHED / CHANGED - AUTO SAVED", levelFinished: true);
		}
		if (autoStartField.value)
		{
			((MonoBehaviour)this).StartCoroutine(AutoStartAfterSceneLoad());
		}
	}

	[IteratorStateMachine(typeof(<AutoStartAfterSceneLoad>d__67))]
	private IEnumerator AutoStartAfterSceneLoad()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <AutoStartAfterSceneLoad>d__67(0)
		{
			<>4__this = this
		};
	}

	private void Update()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown(GetKey(recordKeyField, (KeyCode)59)))
		{
			ToggleRecording();
		}
		if (Input.GetKeyDown(GetKey(loadKeyField, (KeyCode)39)))
		{
			LoadLatestRunIntoSlot("A");
		}
		if (Input.GetKeyDown(GetKey(autoStartKeyField, (KeyCode)91)))
		{
			autoStartField.value = !autoStartField.value;
			SetStatus(autoStartField.value ? "AUTO START RECORDING: ON" : "AUTO START RECORDING: OFF");
		}
		if (Input.GetKeyDown(GetKey(toggleGhostKeyField, (KeyCode)44)))
		{
			ToggleGhostVisibility();
		}
		if (Input.GetKeyDown(GetKey(clearKeyField, (KeyCode)46)))
		{
			ClearGhost();
			loadedA = false;
			loadedB = false;
			SetStatus("GHOST CLEARED");
		}
		if (Input.GetKeyDown(GetKey(toggleTimeKeyField, (KeyCode)92)))
		{
			showActionTimesField.value = !showActionTimesField.value;
			SetStatus(showActionTimesField.value ? "DOT TIME TEXT: ON" : "DOT TIME TEXT: OFF");
		}
		if (Input.GetKeyDown(GetKey(menuKeyField, (KeyCode)93)))
		{
			menuOpen = !menuOpen;
			RefreshRunFiles();
			SetStatus(menuOpen ? "RUN MENU OPENED" : "RUN MENU CLOSED");
		}
		if (isRecording)
		{
			RecordMovementTick();
			RecordActions();
			ScanCheckpoints();
			TrackEnemyKills();
			RecordSpeedEvents();
		}
		if (screenStatusTimer > 0f)
		{
			screenStatusTimer -= Time.deltaTime;
		}
		UpdateDotLookHover();
		FaceHoverTextsToCamera();
	}

	private void OnGUI()
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: 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)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		EnsureStyles();
		string text = (isRecording ? "RECORDING: ON" : "RECORDING: OFF");
		string text2 = (autoStartField.value ? "AUTO START: ON" : "AUTO START: OFF");
		string text3 = (ghostVisible ? "LOADED RUNS: SHOWN" : "LOADED RUNS: HIDDEN");
		string text4 = (showActionTimesField.value ? "DOT TIME: ON" : "DOT TIME: OFF");
		string text5 = text + "\n" + text2 + "\n" + text3 + "\n" + text4 + "\n" + KeyText(GetKey(recordKeyField, (KeyCode)59)) + "  Start/Stop Recording\n" + KeyText(GetKey(loadKeyField, (KeyCode)39)) + "  Load Latest Run to A\n" + KeyText(GetKey(autoStartKeyField, (KeyCode)91)) + "  Toggle Auto Start\n" + KeyText(GetKey(toggleGhostKeyField, (KeyCode)44)) + "  Show/Hide Loaded Runs\n" + KeyText(GetKey(clearKeyField, (KeyCode)46)) + "  Clear Loaded Runs\n" + KeyText(GetKey(toggleTimeKeyField, (KeyCode)92)) + "  Toggle Dot Time\n" + KeyText(GetKey(menuKeyField, (KeyCode)93)) + "  Open/Close Run Menu";
		GUI.Label(new Rect(15f, (float)(Screen.height - 275), 620f, 275f), text5, keybindStyle);
		if (screenStatusTimer > 0f && !string.IsNullOrEmpty(screenStatus))
		{
			GUI.Label(new Rect(15f, (float)(Screen.height - 320), 1300f, 40f), screenStatus, statusStyle);
		}
		if (menuOpen)
		{
			DrawRunMenu();
		}
	}

	private KeyCode GetKey(EnumField<BindKey> field, KeyCode fallback)
	{
		//IL_0014: 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_001a: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		if (field == null)
		{
			return fallback;
		}
		return BindKeyToKeyCode(field.value, fallback);
	}

	private KeyCode BindKeyToKeyCode(BindKey bindKey, KeyCode fallback)
	{
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: 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_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: 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_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: 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_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: 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_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_0329: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Unknown result type (might be due to invalid IL or missing references)
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		return (KeyCode)(bindKey switch
		{
			BindKey.None => 0, 
			BindKey.Semicolon => 59, 
			BindKey.Quote => 39, 
			BindKey.LeftBracket => 91, 
			BindKey.RightBracket => 93, 
			BindKey.Backslash => 92, 
			BindKey.Comma => 44, 
			BindKey.Period => 46, 
			BindKey.Slash => 47, 
			BindKey.Minus => 45, 
			BindKey.Equals => 61, 
			BindKey.F1 => 282, 
			BindKey.F2 => 283, 
			BindKey.F3 => 284, 
			BindKey.F4 => 285, 
			BindKey.F5 => 286, 
			BindKey.F6 => 287, 
			BindKey.F7 => 288, 
			BindKey.F8 => 289, 
			BindKey.F9 => 290, 
			BindKey.F10 => 291, 
			BindKey.F11 => 292, 
			BindKey.F12 => 293, 
			BindKey.Alpha0 => 48, 
			BindKey.Alpha1 => 49, 
			BindKey.Alpha2 => 50, 
			BindKey.Alpha3 => 51, 
			BindKey.Alpha4 => 52, 
			BindKey.Alpha5 => 53, 
			BindKey.Alpha6 => 54, 
			BindKey.Alpha7 => 55, 
			BindKey.Alpha8 => 56, 
			BindKey.Alpha9 => 57, 
			BindKey.A => 97, 
			BindKey.B => 98, 
			BindKey.C => 99, 
			BindKey.D => 100, 
			BindKey.E => 101, 
			BindKey.F => 102, 
			BindKey.G => 103, 
			BindKey.H => 104, 
			BindKey.I => 105, 
			BindKey.J => 106, 
			BindKey.K => 107, 
			BindKey.L => 108, 
			BindKey.M => 109, 
			BindKey.N => 110, 
			BindKey.O => 111, 
			BindKey.P => 112, 
			BindKey.Q => 113, 
			BindKey.R => 114, 
			BindKey.S => 115, 
			BindKey.T => 116, 
			BindKey.U => 117, 
			BindKey.V => 118, 
			BindKey.W => 119, 
			BindKey.X => 120, 
			BindKey.Y => 121, 
			BindKey.Z => 122, 
			BindKey.Insert => 277, 
			BindKey.Delete => 127, 
			BindKey.Home => 278, 
			BindKey.End => 279, 
			BindKey.PageUp => 280, 
			BindKey.PageDown => 281, 
			BindKey.Keypad0 => 256, 
			BindKey.Keypad1 => 257, 
			BindKey.Keypad2 => 258, 
			BindKey.Keypad3 => 259, 
			BindKey.Keypad4 => 260, 
			BindKey.Keypad5 => 261, 
			BindKey.Keypad6 => 262, 
			BindKey.Keypad7 => 263, 
			BindKey.Keypad8 => 264, 
			BindKey.Keypad9 => 265, 
			_ => fallback, 
		});
	}

	private string KeyText(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0004: Invalid comparison between Unknown and I4
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Invalid comparison between Unknown and I4
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Invalid comparison between Unknown and I4
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Invalid comparison between Unknown and I4
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Invalid comparison between Unknown and I4
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Invalid comparison between Unknown and I4
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Invalid comparison between Unknown and I4
		if ((int)key == 59)
		{
			return ";";
		}
		if ((int)key == 39)
		{
			return "'";
		}
		if ((int)key == 91)
		{
			return "[";
		}
		if ((int)key == 93)
		{
			return "]";
		}
		if ((int)key == 92)
		{
			return "\\";
		}
		if ((int)key == 44)
		{
			return ",";
		}
		if ((int)key == 46)
		{
			return ".";
		}
		if ((int)key == 32)
		{
			return "Space";
		}
		return ((object)(KeyCode)(ref key)).ToString();
	}

	private void EnsureStyles()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Expected O, but got Unknown
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Expected O, but got Unknown
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Expected O, but got Unknown
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Expected O, but got Unknown
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		if (keybindStyle == null)
		{
			keybindStyle = new GUIStyle(GUI.skin.label);
			keybindStyle.fontSize = 18;
			keybindStyle.normal.textColor = Color.white;
		}
		if (statusStyle == null)
		{
			statusStyle = new GUIStyle(GUI.skin.label);
			statusStyle.fontSize = 24;
			statusStyle.normal.textColor = Color.yellow;
		}
		if (menuStyle == null)
		{
			menuStyle = new GUIStyle(GUI.skin.box);
			menuStyle.fontSize = 18;
			menuStyle.normal.textColor = Color.white;
		}
		if (buttonStyle == null)
		{
			buttonStyle = new GUIStyle(GUI.skin.button);
			buttonStyle.fontSize = 15;
		}
		if (smallStyle == null)
		{
			smallStyle = new GUIStyle(GUI.skin.label);
			smallStyle.fontSize = 14;
			smallStyle.normal.textColor = Color.white;
		}
		if (selectedStyle == null)
		{
			selectedStyle = new GUIStyle(GUI.skin.label);
			selectedStyle.fontSize = 18;
			selectedStyle.normal.textColor = Color.white;
			selectedStyle.alignment = (TextAnchor)4;
		}
	}

	private void DrawRunMenu()
	{
		//IL_0026: 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_008e: 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_0121: 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_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_033a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0402: Unknown result type (might be due to invalid IL or missing references)
		//IL_0441: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0546: Unknown result type (might be due to invalid IL or missing references)
		//IL_0593: Unknown result type (might be due to invalid IL or missing references)
		//IL_0689: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0636: Unknown result type (might be due to invalid IL or missing references)
		//IL_0713: Unknown result type (might be due to invalid IL or missing references)
		float num = 1030f;
		float num2 = 640f;
		float num3 = (float)Screen.width - num - 25f;
		float num4 = 30f;
		GUI.Box(new Rect(num3, num4, num, num2), "Saved Runs - Speed / Kills / Compare", menuStyle);
		if (GUI.Button(new Rect(num3 + 20f, num4 + 35f, 110f, 32f), "Refresh", buttonStyle))
		{
			RefreshRunFiles();
		}
		GUI.Label(new Rect(num3 + 145f, num4 + 40f, 130f, 24f), "Filter:", smallStyle);
		float num5 = num3 + 200f;
		if (GUI.Button(new Rect(num5, num4 + 35f, 55f, 32f), "All", buttonStyle))
		{
			activeColorFilter = "";
			RefreshRunFiles();
		}
		num5 += 65f;
		for (int i = 0; i < palette.Length; i++)
		{
			ColorOption colorOption = palette[i];
			if (DrawColorButton(new Rect(num5, num4 + 35f, 45f, 32f), colorOption.hex))
			{
				if (activeColorFilter == colorOption.hex)
				{
					activeColorFilter = "";
				}
				else
				{
					activeColorFilter = colorOption.hex;
				}
				RefreshRunFiles();
			}
			if (activeColorFilter == colorOption.hex)
			{
				GUI.Label(new Rect(num5 + 12f, num4 + 65f, 25f, 18f), "▲", selectedStyle);
			}
			num5 += 52f;
		}
		string text = (string.IsNullOrEmpty(activeColorFilter) ? "Showing: All" : ("Showing: " + GetColorName(activeColorFilter)));
		GUI.Label(new Rect(num5 + 10f, num4 + 40f, 260f, 24f), text, smallStyle);
		GUI.Label(new Rect(num3 + 20f, num4 + 82f, 950f, 24f), "Keybinds/settings are in Settings > PLUGIN CONFIG > Run Path Recorder.", smallStyle);
		menuScroll = GUI.BeginScrollView(new Rect(num3 + 20f, num4 + 115f, num - 40f, num2 - 135f), menuScroll, new Rect(0f, 0f, num - 70f, Mathf.Max(500f, (float)runFiles.Count * 150f)));
		float num6 = 0f;
		if (runFiles.Count == 0)
		{
			GUI.Label(new Rect(0f, 0f, 600f, 30f), "No runs found for this filter.", smallStyle);
		}
		Rect rect = default(Rect);
		for (int j = 0; j < runFiles.Count; j++)
		{
			RunFileEntry runFileEntry = runFiles[j];
			GUI.Box(new Rect(0f, num6, num - 80f, 140f), "");
			GUI.Label(new Rect(10f, num6 + 8f, 410f, 22f), runFileEntry.displayName, smallStyle);
			GUI.Label(new Rect(10f, num6 + 32f, 410f, 22f), "Saved: " + runFileEntry.savedTime, smallStyle);
			GUI.Label(new Rect(10f, num6 + 56f, 410f, 22f), "Status: " + runFileEntry.finishStatus, smallStyle);
			GUI.Label(new Rect(10f, num6 + 80f, 410f, 22f), "Color: " + GetColorName(runFileEntry.colorHex), smallStyle);
			GUI.Label(new Rect(10f, num6 + 104f, 410f, 22f), runFileEntry.fileName, smallStyle);
			if (!renameInputs.ContainsKey(runFileEntry.path))
			{
				renameInputs[runFileEntry.path] = runFileEntry.displayName;
			}
			renameInputs[runFileEntry.path] = GUI.TextField(new Rect(430f, num6 + 10f, 180f, 30f), renameInputs[runFileEntry.path]);
			if (GUI.Button(new Rect(620f, num6 + 10f, 90f, 30f), "Rename", buttonStyle))
			{
				RenameRun(runFileEntry.path, renameInputs[runFileEntry.path]);
				RefreshRunFiles();
			}
			GUI.Label(new Rect(430f, num6 + 50f, 70f, 24f), "Color:", smallStyle);
			float num7 = 500f;
			for (int k = 0; k < palette.Length; k++)
			{
				ColorOption colorOption2 = palette[k];
				((Rect)(ref rect))..ctor(num7, num6 + 47f, 48f, 34f);
				if (DrawColorButton(rect, colorOption2.hex))
				{
					ChangeRunColor(runFileEntry.path, colorOption2.hex);
					runFileEntry.colorHex = colorOption2.hex;
					runFiles[j].colorHex = colorOption2.hex;
					SetStatus("RUN COLOR SET TO " + GetColorName(colorOption2.hex));
				}
				if (runFileEntry.colorHex == colorOption2.hex)
				{
					GUI.Label(new Rect(num7 + 15f, num6 + 80f, 25f, 18f), "▲", selectedStyle);
				}
				num7 += 55f;
			}
			if (GUI.Button(new Rect(430f, num6 + 100f, 95f, 30f), "Load A", buttonStyle))
			{
				LoadRunFile(runFileEntry.path, "A");
			}
			if (GUI.Button(new Rect(535f, num6 + 100f, 95f, 30f), "Load B", buttonStyle))
			{
				LoadRunFile(runFileEntry.path, "B");
			}
			if (GUI.Button(new Rect(640f, num6 + 100f, 130f, 30f), "Set Latest", buttonStyle))
			{
				CopyToLatest(runFileEntry.path);
				SetStatus("SET AS LATEST RUN");
			}
			num6 += 150f;
		}
		GUI.EndScrollView();
	}

	private bool DrawColorButton(Rect rect, string hex)
	{
		//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_001c: 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_002f: 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_001b: Unknown result type (might be due to invalid IL or missing references)
		Color backgroundColor = GUI.backgroundColor;
		Color white = default(Color);
		if (!ColorUtility.TryParseHtmlString(hex, ref white))
		{
			white = Color.white;
		}
		GUI.backgroundColor = white;
		bool result = GUI.Button(rect, "");
		GUI.backgroundColor = backgroundColor;
		return result;
	}

	private string GetColorName(string hex)
	{
		for (int i = 0; i < palette.Length; i++)
		{
			if (palette[i].hex == hex)
			{
				return palette[i].name;
			}
		}
		return hex;
	}

	private Material MakeMaterial(string hex)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: 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)
		Shader val = Shader.Find("Sprites/Default");
		Material val2 = new Material(val);
		Color cyan = default(Color);
		if (!ColorUtility.TryParseHtmlString(hex, ref cyan))
		{
			cyan = Color.cyan;
		}
		val2.color = cyan;
		return val2;
	}

	private Material MakeMaterialColor(Color color)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		Shader val = Shader.Find("Sprites/Default");
		Material val2 = new Material(val);
		val2.color = color;
		return val2;
	}

	private Color HexToColor(string hex)
	{
		//IL_0016: 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_0010: 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_001a: Unknown result type (might be due to invalid IL or missing references)
		Color result = default(Color);
		if (!ColorUtility.TryParseHtmlString(hex, ref result))
		{
			return Color.cyan;
		}
		return result;
	}

	private void UpdateDotLookHover()
	{
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: 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)
		//IL_00e6: 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_010b: 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_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: 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)
		if (!ghostVisible)
		{
			HideAllHoverTexts();
			return;
		}
		Camera main = Camera.main;
		if ((Object)(object)main == (Object)null)
		{
			return;
		}
		HideAllHoverTexts();
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f);
		HoverMarker hoverMarker = null;
		float num = 999999f;
		Vector2 val3 = default(Vector2);
		foreach (HoverMarker hoverMarker2 in hoverMarkers)
		{
			if (hoverMarker2 == null || (Object)(object)hoverMarker2.dotObject == (Object)null || (Object)(object)hoverMarker2.textObject == (Object)null || !hoverMarker2.dotObject.activeInHierarchy)
			{
				continue;
			}
			Vector3 position = hoverMarker2.dotObject.transform.position;
			float num2 = Vector3.Distance(((Component)main).transform.position, position);
			if (num2 > hoverMaxWorldDistance)
			{
				continue;
			}
			Vector3 val2 = main.WorldToScreenPoint(position);
			if (!(val2.z <= 0f))
			{
				((Vector2)(ref val3))..ctor(val2.x, val2.y);
				float num3 = Vector2.Distance(val, val3);
				if (num3 <= hoverScreenRadius && num3 < num)
				{
					hoverMarker = hoverMarker2;
					num = num3;
				}
			}
		}
		if (hoverMarker != null)
		{
			hoverMarker.textMesh.text = BuildHoverText(hoverMarker);
			hoverMarker.textObject.SetActive(true);
		}
	}

	private void HideAllHoverTexts()
	{
		foreach (HoverMarker hoverMarker in hoverMarkers)
		{
			if (hoverMarker != null && (Object)(object)hoverMarker.textObject != (Object)null)
			{
				hoverMarker.textObject.SetActive(false);
			}
		}
	}

	private string BuildHoverText(HoverMarker marker)
	{
		if (showActionTimesField.value)
		{
			return marker.label + "\nRun Time: " + marker.timeText;
		}
		return marker.label;
	}

	private void FaceHoverTextsToCamera()
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		Camera main = Camera.main;
		if ((Object)(object)main == (Object)null)
		{
			return;
		}
		foreach (HoverMarker hoverMarker in hoverMarkers)
		{
			if (hoverMarker != null && !((Object)(object)hoverMarker.textObject == (Object)null) && hoverMarker.textObject.activeSelf)
			{
				hoverMarker.textObject.transform.rotation = Quaternion.LookRotation(hoverMarker.textObject.transform.position - ((Component)main).transform.position);
			}
		}
	}

	private void SetStatus(string message)
	{
		screenStatus = message;
		screenStatusTimer = 5f;
		((BaseUnityPlugin)this).Logger.LogInfo((object)message);
	}

	private void ToggleRecording()
	{
		if (!isRecording)
		{
			StartRecording();
		}
		else
		{
			StopRecordingAndSave("RECORDING SAVED", levelFinished: false);
		}
	}

	private void StartRecording()
	{
		Transform playerTransform = GetPlayerTransform();
		if ((Object)(object)playerTransform == (Object)null)
		{
			SetStatus("CANNOT START: NO PLAYER/CAMERA");
			return;
		}
		currentPoints = new List<RunPoint>();
		currentActions = new List<ActionPoint>();
		currentCheckpoints = new List<CheckpointPoint>();
		currentKills = new List<KillPoint>();
		currentSpeedMarkers = new List<SpeedMarkerPoint>();
		touchedCheckpointIds = new HashSet<string>();
		trackedEnemies = new Dictionary<int, EnemyTrack>();
		fallbackRecordStartTime = Time.time;
		recordTimer = 0f;
		checkpointScanTimer = 0f;
		enemyScanTimer = 0f;
		speedEventTimer = 0f;
		lastSampledHorizontalSpeed = 0f;
		hasLastSpeedSample = false;
		isRecording = true;
		RecordMovementPointNow();
		TrackEnemyKills();
		SetStatus("RECORDING STARTED");
	}

	private void StopRecordingAndSave(string statusMessage, bool levelFinished)
	{
		isRecording = false;
		RecordMovementPointNow();
		string text = SaveRunTXT(levelFinished);
		SetStatus(statusMessage + " | " + currentPoints.Count + " POINTS / " + currentActions.Count + " ACTIONS / " + currentKills.Count + " KILLS / " + currentSpeedMarkers.Count + " SPEED DOTS");
		if (!string.IsNullOrEmpty(text))
		{
			CopyToLatest(text);
		}
		RefreshRunFiles();
	}

	private Transform GetPlayerTransform()
	{
		Camera main = Camera.main;
		if ((Object)(object)main != (Object)null)
		{
			return ((Component)main).transform;
		}
		GameObject val = GameObject.Find("Player");
		if ((Object)(object)val != (Object)null)
		{
			return val.transform;
		}
		return null;
	}

	private float GetRunTimerSeconds()
	{
		if (TryFindUltrakillTimer(out var timer))
		{
			return timer;
		}
		return Time.time - fallbackRecordStartTime;
	}

	private bool TryFindUltrakillTimer(out float timer)
	{
		timer = 0f;
		GameObject[] array = Object.FindObjectsOfType<GameObject>();
		GameObject[] array2 = array;
		foreach (GameObject val in array2)
		{
			if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
			{
				continue;
			}
			string text = ((Object)val).name.ToLower();
			if (!text.Contains("timer") && !text.Contains("time") && !text.Contains("rank") && !text.Contains("stats") && !text.Contains("hud"))
			{
				continue;
			}
			Component[] components = val.GetComponents<Component>();
			Component[] array3 = components;
			foreach (Component val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null) && TryReadTimerFromComponent(val2, out timer))
				{
					return true;
				}
			}
		}
		return false;
	}

	private bool TryReadTimerFromComponent(Component component, out float timer)
	{
		timer = 0f;
		Type type = ((object)component).GetType();
		string text = type.Name.ToLower();
		if (!text.Contains("timer") && !text.Contains("time") && !text.Contains("rank") && !text.Contains("stats") && !text.Contains("hud"))
		{
			return false;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
		FieldInfo[] fields = type.GetFields(bindingAttr);
		FieldInfo[] array = fields;
		foreach (FieldInfo fieldInfo in array)
		{
			string text2 = fieldInfo.Name.ToLower();
			switch (text2)
			{
			default:
				if (!text2.Contains("leveltime") && !text2.Contains("currenttime") && !text2.Contains("seconds") && !text2.Contains("timer"))
				{
					continue;
				}
				break;
			case "time":
			case "timer":
			case "currenttime":
			case "leveltime":
			case "seconds":
				break;
			}
			object value;
			try
			{
				value = fieldInfo.GetValue(component);
			}
			catch
			{
				continue;
			}
			if (TryConvertToFloat(value, out timer) && timer >= 0f && timer < 99999f)
			{
				return true;
			}
		}
		PropertyInfo[] properties = type.GetProperties(bindingAttr);
		PropertyInfo[] array2 = properties;
		foreach (PropertyInfo propertyInfo in array2)
		{
			if (!propertyInfo.CanRead)
			{
				continue;
			}
			string text3 = propertyInfo.Name.ToLower();
			switch (text3)
			{
			default:
				if (!text3.Contains("leveltime") && !text3.Contains("currenttime") && !text3.Contains("seconds") && !text3.Contains("timer"))
				{
					continue;
				}
				break;
			case "time":
			case "timer":
			case "currenttime":
			case "leveltime":
			case "seconds":
				break;
			}
			object value2;
			try
			{
				value2 = propertyInfo.GetValue(component, null);
			}
			catch
			{
				continue;
			}
			if (!TryConvertToFloat(value2, out timer) || !(timer >= 0f) || !(timer < 99999f))
			{
				continue;
			}
			return true;
		}
		return false;
	}

	private bool TryConvertToFloat(object value, out float result)
	{
		if (value is float num)
		{
			result = num;
			return true;
		}
		if (value is int num2)
		{
			result = num2;
			return true;
		}
		if (value is double num3)
		{
			result = (float)num3;
			return true;
		}
		result = 0f;
		return false;
	}

	private void RecordMovementTick()
	{
		recordTimer += Time.deltaTime;
		if (!(recordTimer < recordInterval))
		{
			recordTimer = 0f;
			RecordMovementPointNow();
		}
	}

	private void RecordMovementPointNow()
	{
		//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_002f: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		Transform playerTransform = GetPlayerTransform();
		if (!((Object)(object)playerTransform == (Object)null))
		{
			Vector3 position = playerTransform.position;
			RunPoint runPoint = new RunPoint();
			runPoint.time = GetRunTimerSeconds();
			runPoint.x = position.x;
			runPoint.y = position.y;
			runPoint.z = position.z;
			currentPoints.Add(runPoint);
		}
	}

	private void RecordSpeedEvents()
	{
		//IL_00df: 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)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		speedEventTimer += Time.deltaTime;
		if (speedEventTimer < speedEventInterval)
		{
			return;
		}
		speedEventTimer = 0f;
		if (currentPoints == null || currentPoints.Count < 2)
		{
			return;
		}
		RunPoint runPoint = currentPoints[currentPoints.Count - 1];
		int index = Mathf.Max(0, currentPoints.Count - 8);
		RunPoint runPoint2 = currentPoints[index];
		float num = Mathf.Max(0.01f, runPoint.time - runPoint2.time);
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(runPoint2.x, runPoint2.y, runPoint2.z);
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(runPoint.x, runPoint.y, runPoint.z);
		Vector3 val3 = val2 - val;
		Vector2 val4 = default(Vector2);
		((Vector2)(ref val4))..ctor(val3.x, val3.z);
		float num2 = ((Vector2)(ref val4)).magnitude / num;
		float num3 = val3.y / num;
		string text = "";
		if (num2 >= highHorizontalSpeedThresholdField.value)
		{
			text = "HIGH SPEED";
		}
		if (hasLastSpeedSample)
		{
			float num4 = lastSampledHorizontalSpeed - num2;
			if (num4 >= horizontalSpeedDropThresholdField.value)
			{
				if (text.Length > 0)
				{
					text += " + ";
				}
				text += "SPEED DROP";
			}
		}
		if (Mathf.Abs(num3) >= verticalSpeedThresholdField.value)
		{
			if (text.Length > 0)
			{
				text += " + ";
			}
			text += ((num3 > 0f) ? "VERT UP" : "VERT DOWN");
		}
		lastSampledHorizontalSpeed = num2;
		hasLastSpeedSample = true;
		if (text.Length != 0)
		{
			SpeedMarkerPoint speedMarkerPoint = new SpeedMarkerPoint();
			speedMarkerPoint.time = runPoint.time;
			speedMarkerPoint.x = runPoint.x;
			speedMarkerPoint.y = runPoint.y;
			speedMarkerPoint.z = runPoint.z;
			speedMarkerPoint.horizontalSpeed = num2;
			speedMarkerPoint.verticalSpeed = num3;
			speedMarkerPoint.label = text;
			currentSpeedMarkers.Add(speedMarkerPoint);
		}
	}

	private void RecordActions()
	{
		Camera main = Camera.main;
		if (!((Object)(object)main == (Object)null))
		{
			string currentWeaponName = GetCurrentWeaponName();
			if (Input.GetMouseButtonDown(0))
			{
				RecordActionMarker(main, currentWeaponName + " PRIMARY");
			}
			if (Input.GetMouseButtonDown(1))
			{
				RecordActionMarker(main, currentWeaponName + " ALT");
			}
			if (Input.GetMouseButtonDown(2))
			{
				RecordActionMarker(main, currentWeaponName + " MIDDLE");
			}
			if (Input.GetKeyDown((KeyCode)114))
			{
				RecordActionMarker(main, currentWeaponName + " R");
			}
			if (Input.GetKeyDown((KeyCode)102))
			{
				RecordActionMarker(main, "PUNCH / MELEE");
			}
		}
	}

	private void RecordActionMarker(Camera cam, string label)
	{
		//IL_0007: 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_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_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_0050: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = ((Component)cam).transform.position;
		Vector3 forward = ((Component)cam).transform.forward;
		ActionPoint actionPoint = new ActionPoint();
		actionPoint.time = GetRunTimerSeconds();
		actionPoint.x = position.x;
		actionPoint.y = position.y;
		actionPoint.z = position.z;
		actionPoint.dx = forward.x;
		actionPoint.dy = forward.y;
		actionPoint.dz = forward.z;
		actionPoint.label = label;
		currentActions.Add(actionPoint);
	}

	private void ScanCheckpoints()
	{
		//IL_004f: 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_00fa: 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_0144: 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_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		checkpointScanTimer += Time.deltaTime;
		if (checkpointScanTimer < checkpointScanInterval)
		{
			return;
		}
		checkpointScanTimer = 0f;
		Transform playerTransform = GetPlayerTransform();
		if ((Object)(object)playerTransform == (Object)null)
		{
			return;
		}
		Vector3 position = playerTransform.position;
		GameObject[] array = Object.FindObjectsOfType<GameObject>();
		GameObject[] array2 = array;
		foreach (GameObject val in array2)
		{
			if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
			{
				continue;
			}
			string text = ((Object)val).name.ToLower();
			string text2 = "";
			try
			{
				text2 = val.tag.ToLower();
			}
			catch
			{
			}
			if (!text.Contains("checkpoint") && !text.Contains("check point") && !text2.Contains("checkpoint"))
			{
				continue;
			}
			float num = Vector3.Distance(position, val.transform.position);
			if (!(num > checkpointDetectDistance))
			{
				string item = ((Object)val).name + "_" + Mathf.RoundToInt(val.transform.position.x) + "_" + Mathf.RoundToInt(val.transform.position.y) + "_" + Mathf.RoundToInt(val.transform.position.z);
				if (!touchedCheckpointIds.Contains(item))
				{
					touchedCheckpointIds.Add(item);
					CheckpointPoint checkpointPoint = new CheckpointPoint();
					checkpointPoint.time = GetRunTimerSeconds();
					checkpointPoint.x = val.transform.position.x;
					checkpointPoint.y = val.transform.position.y;
					checkpointPoint.z = val.transform.position.z;
					checkpointPoint.label = "CHECKPOINT";
					currentCheckpoints.Add(checkpointPoint);
					SetStatus("CHECKPOINT RECORDED");
				}
			}
		}
	}

	private void TrackEnemyKills()
	{
		//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_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		enemyScanTimer += Time.deltaTime;
		if (enemyScanTimer < enemyScanInterval)
		{
			return;
		}
		enemyScanTimer = 0f;
		HashSet<int> hashSet = new HashSet<int>();
		GameObject[] array = (GameObject[])(object)new GameObject[0];
		try
		{
			array = GameObject.FindGameObjectsWithTag("Enemy");
		}
		catch
		{
			return;
		}
		GameObject[] array2 = array;
		foreach (GameObject val in array2)
		{
			if (!((Object)(object)val == (Object)null) && val.activeInHierarchy)
			{
				int instanceID = ((Object)val).GetInstanceID();
				hashSet.Add(instanceID);
				if (!trackedEnemies.ContainsKey(instanceID))
				{
					EnemyTrack enemyTrack = new EnemyTrack();
					enemyTrack.id = instanceID;
					enemyTrack.name = ((Object)val).name.Replace("(Clone)", "").Trim();
					enemyTrack.lastPosition = val.transform.position;
					enemyTrack.lastSeenTime = GetRunTimerSeconds();
					trackedEnemies[instanceID] = enemyTrack;
				}
				else
				{
					EnemyTrack enemyTrack2 = trackedEnemies[instanceID];
					enemyTrack2.lastPosition = val.transform.position;
					enemyTrack2.lastSeenTime = GetRunTimerSeconds();
					trackedEnemies[instanceID] = enemyTrack2;
				}
			}
		}
		List<int> list = new List<int>();
		foreach (KeyValuePair<int, EnemyTrack> trackedEnemy in trackedEnemies)
		{
			int key = trackedEnemy.Key;
			if (!hashSet.Contains(key))
			{
				list.Add(key);
			}
		}
		foreach (int item in list)
		{
			EnemyTrack enemyTrack3 = trackedEnemies[item];
			trackedEnemies.Remove(item);
			KillPoint killPoint = new KillPoint();
			killPoint.time = GetRunTimerSeconds();
			killPoint.x = enemyTrack3.lastPosition.x;
			killPoint.y = enemyTrack3.lastPosition.y;
			killPoint.z = enemyTrack3.lastPosition.z;
			killPoint.label = "KILL: " + enemyTrack3.name;
			currentKills.Add(killPoint);
		}
	}

	private string GetCurrentWeaponName()
	{
		GameObject[] array = Object.FindObjectsOfType<GameObject>();
		GameObject[] array2 = array;
		foreach (GameObject val in array2)
		{
			if (!((Object)(object)val == (Object)null) && val.activeInHierarchy)
			{
				string text = ((Object)val).name.ToLower();
				if (text.Contains("revolver") || text.Contains("shotgun") || text.Contains("nailgun") || text.Contains("railcannon") || text.Contains("rocket") || text.Contains("sawblade"))
				{
					return ((Object)val).name.Replace("(Clone)", "").Trim();
				}
			}
		}
		return "WEAPON";
	}

	private string SaveRunTXT(bool levelFinished)
	{
		string text = "Run_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
		string text2 = Path.Combine(saveFolder, text + ".txt");
		WriteRunFile(text2, text, levelFinished, defaultRunColorHex, currentPoints, currentActions, currentCheckpoints, currentKills, currentSpeedMarkers);
		return text2;
	}

	private void WriteRunFile(string path, string displayName, bool levelFinished, string colorHex, List<RunPoint> points, List<ActionPoint> actions, List<CheckpointPoint> checkpoints, List<KillPoint> kills, List<SpeedMarkerPoint> speedMarkers)
	{
		//IL_0050: 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)
		using StreamWriter streamWriter = new StreamWriter(path, append: false);
		streamWriter.WriteLine("RUNRECORDER_V11_PLUGINCONFIGURATOR");
		streamWriter.WriteLine("NAME|" + displayName.Replace("|", "/"));
		streamWriter.WriteLine("COLOR|" + colorHex);
		Scene activeScene = SceneManager.GetActiveScene();
		streamWriter.WriteLine("SCENE|" + ((Scene)(ref activeScene)).name);
		streamWriter.WriteLine("SAVED|" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
		streamWriter.WriteLine("FINISHED|" + (levelFinished ? "YES" : "NO"));
		streamWriter.WriteLine("POINTS|" + points.Count);
		foreach (RunPoint point in points)
		{
			streamWriter.WriteLine("P|" + F(point.time) + "|" + F(point.x) + "|" + F(point.y) + "|" + F(point.z));
		}
		streamWriter.WriteLine("ACTIONS|" + actions.Count);
		foreach (ActionPoint action in actions)
		{
			streamWriter.WriteLine("A|" + F(action.time) + "|" + F(action.x) + "|" + F(action.y) + "|" + F(action.z) + "|" + F(action.dx) + "|" + F(action.dy) + "|" + F(action.dz) + "|" + action.label.Replace("|", "/"));
		}
		streamWriter.WriteLine("CHECKPOINTS|" + checkpoints.Count);
		foreach (CheckpointPoint checkpoint in checkpoints)
		{
			streamWriter.WriteLine("C|" + F(checkpoint.time) + "|" + F(checkpoint.x) + "|" + F(checkpoint.y) + "|" + F(checkpoint.z) + "|" + checkpoint.label.Replace("|", "/"));
		}
		streamWriter.WriteLine("KILLS|" + kills.Count);
		foreach (KillPoint kill in kills)
		{
			streamWriter.WriteLine("K|" + F(kill.time) + "|" + F(kill.x) + "|" + F(kill.y) + "|" + F(kill.z) + "|" + kill.label.Replace("|", "/"));
		}
		streamWriter.WriteLine("SPEEDMARKERS|" + speedMarkers.Count);
		foreach (SpeedMarkerPoint speedMarker in speedMarkers)
		{
			streamWriter.WriteLine("S|" + F(speedMarker.time) + "|" + F(speedMarker.x) + "|" + F(speedMarker.y) + "|" + F(speedMarker.z) + "|" + F(speedMarker.horizontalSpeed) + "|" + F(speedMarker.verticalSpeed) + "|" + speedMarker.label.Replace("|", "/"));
		}
	}

	private void CopyToLatest(string path)
	{
		if (File.Exists(path))
		{
			File.Copy(path, latestRunPath, overwrite: true);
		}
	}

	private void LoadLatestRunIntoSlot(string slot)
	{
		if (!File.Exists(latestRunPath))
		{
			SetStatus("NO latest_run.txt FOUND");
		}
		else
		{
			LoadRunFile(latestRunPath, slot);
		}
	}

	private void LoadRunFile(string path, string slot)
	{
		if (!File.Exists(path))
		{
			SetStatus("RUN FILE NOT FOUND");
			return;
		}
		ReadRunFile(path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string displayName, out string _, out string colorHex, out bool _);
		DrawRun(points, actions, checkpoints, kills, speedMarkers, slot, displayName, colorHex);
	}

	private void ReadRunFile(string path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string displayName, out string savedTime, out string colorHex, out bool levelFinished)
	{
		points = new List<RunPoint>();
		actions = new List<ActionPoint>();
		checkpoints = new List<CheckpointPoint>();
		kills = new List<KillPoint>();
		speedMarkers = new List<SpeedMarkerPoint>();
		displayName = Path.GetFileNameWithoutExtension(path);
		savedTime = File.GetLastWriteTime(path).ToString("yyyy-MM-dd HH:mm:ss");
		colorHex = defaultRunColorHex;
		levelFinished = false;
		string[] array = File.ReadAllLines(path);
		string[] array2 = array;
		foreach (string text in array2)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				continue;
			}
			string[] array3 = text.Split('|');
			if (array3.Length != 0)
			{
				if (array3[0] == "NAME" && array3.Length >= 2)
				{
					displayName = array3[1];
				}
				if (array3[0] == "COLOR" && array3.Length >= 2)
				{
					colorHex = array3[1];
				}
				if (array3[0] == "SAVED" && array3.Length >= 2)
				{
					savedTime = array3[1];
				}
				if (array3[0] == "FINISHED" && array3.Length >= 2)
				{
					levelFinished = array3[1] == "YES";
				}
				if (array3[0] == "P" && array3.Length >= 5)
				{
					RunPoint runPoint = new RunPoint();
					runPoint.time = Parse(array3[1]);
					runPoint.x = Parse(array3[2]);
					runPoint.y = Parse(array3[3]);
					runPoint.z = Parse(array3[4]);
					points.Add(runPoint);
				}
				if (array3[0] == "A" && array3.Length >= 9)
				{
					ActionPoint actionPoint = new ActionPoint();
					actionPoint.time = Parse(array3[1]);
					actionPoint.x = Parse(array3[2]);
					actionPoint.y = Parse(array3[3]);
					actionPoint.z = Parse(array3[4]);
					actionPoint.dx = Parse(array3[5]);
					actionPoint.dy = Parse(array3[6]);
					actionPoint.dz = Parse(array3[7]);
					actionPoint.label = array3[8];
					actions.Add(actionPoint);
				}
				if (array3[0] == "C" && array3.Length >= 6)
				{
					CheckpointPoint checkpointPoint = new CheckpointPoint();
					checkpointPoint.time = Parse(array3[1]);
					checkpointPoint.x = Parse(array3[2]);
					checkpointPoint.y = Parse(array3[3]);
					checkpointPoint.z = Parse(array3[4]);
					checkpointPoint.label = array3[5];
					checkpoints.Add(checkpointPoint);
				}
				if (array3[0] == "K" && array3.Length >= 6)
				{
					KillPoint killPoint = new KillPoint();
					killPoint.time = Parse(array3[1]);
					killPoint.x = Parse(array3[2]);
					killPoint.y = Parse(array3[3]);
					killPoint.z = Parse(array3[4]);
					killPoint.label = array3[5];
					kills.Add(killPoint);
				}
				if (array3[0] == "S" && array3.Length >= 8)
				{
					SpeedMarkerPoint speedMarkerPoint = new SpeedMarkerPoint();
					speedMarkerPoint.time = Parse(array3[1]);
					speedMarkerPoint.x = Parse(array3[2]);
					speedMarkerPoint.y = Parse(array3[3]);
					speedMarkerPoint.z = Parse(array3[4]);
					speedMarkerPoint.horizontalSpeed = Parse(array3[5]);
					speedMarkerPoint.verticalSpeed = Parse(array3[6]);
					speedMarkerPoint.label = array3[7];
					speedMarkers.Add(speedMarkerPoint);
				}
			}
		}
	}

	private void DrawRun(List<RunPoint> points, List<ActionPoint> actions, List<CheckpointPoint> checkpoints, List<KillPoint> kills, List<SpeedMarkerPoint> speedMarkers, string slot, string displayName, string colorHex)
	{
		//IL_0022: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		ClearGhostSlot(slot);
		ClearGhostSlot("DIFF");
		Material runMat = MakeMaterial(colorHex);
		Color baseColor = HexToColor(colorHex);
		SetStatus("LOADED " + slot + ": " + points.Count + " POINTS / " + actions.Count + " ACTIONS / " + kills.Count + " KILLS / " + speedMarkers.Count + " SPEED DOTS");
		DrawSpeedMovementPath(points, baseColor, slot);
		DrawClusteredActionDots(actions, runMat, slot, displayName);
		DrawCheckpointDots(checkpoints, runMat, slot, displayName);
		DrawKillDots(kills, runMat, slot, displayName);
		DrawSpeedMarkerDots(speedMarkers, slot);
		if (slot == "A")
		{
			loadedAPoints = points;
			loadedA = true;
		}
		if (slot == "B")
		{
			loadedBPoints = points;
			loadedB = true;
		}
		if (loadedA && loadedB)
		{
			DrawRouteDifferenceMarkers();
		}
		ghostVisible = true;
		SetGhostVisibility(visible: true);
	}

	private void DrawSpeedMovementPath(List<RunPoint> points, Color baseColor, string slot)
	{
		//IL_008b: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Expected O, but got Unknown
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		if (points == null || points.Count < 2)
		{
			SetStatus("NO PATH POINTS RECORDED");
			return;
		}
		Vector3 val = default(Vector3);
		Vector3 val2 = default(Vector3);
		for (int i = 0; i < points.Count - 1; i++)
		{
			RunPoint runPoint = points[i];
			RunPoint runPoint2 = points[i + 1];
			((Vector3)(ref val))..ctor(runPoint.x, runPoint.y, runPoint.z);
			((Vector3)(ref val2))..ctor(runPoint2.x, runPoint2.y, runPoint2.z);
			float num = Mathf.Max(0.01f, runPoint2.time - runPoint.time);
			float num2 = Vector3.Distance(val, val2) / num;
			float num3 = Mathf.InverseLerp(5f, 60f, num2);
			Color val3 = baseColor * 0.35f;
			val3.a = 1f;
			Color color = Color.Lerp(val3, baseColor, num3);
			float num4 = Mathf.Lerp(0.08f, 0.34f, num3);
			GameObject val4 = new GameObject("Alien Speed Path Segment " + slot);
			val4.AddComponent<GhostSlot>().slot = slot;
			ghostObjects.Add(val4);
			LineRenderer val5 = val4.AddComponent<LineRenderer>();
			val5.positionCount = 2;
			val5.startWidth = num4;
			val5.endWidth = num4;
			((Renderer)val5).material = MakeMaterialColor(color);
			val5.useWorldSpace = true;
			val5.SetPosition(0, val);
			val5.SetPosition(1, val2);
		}
	}

	private void DrawClusteredActionDots(List<ActionPoint> actions, Material runMat, string slot, string runName)
	{
		//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_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_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: 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_0057: 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_0063: 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)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		if (actions == null)
		{
			return;
		}
		List<ActionCluster> list = BuildActionClusters(actions);
		foreach (ActionCluster item in list)
		{
			Vector3 val = item.AveragePosition();
			Vector3 val2 = item.AverageDirection();
			if (val2 == Vector3.zero)
			{
				val2 = Vector3.forward;
			}
			Vector3 val3 = val + val2 * 5f;
			GameObject val4 = new GameObject("Alien Action Direction Line " + slot);
			val4.AddComponent<GhostSlot>().slot = slot;
			ghostObjects.Add(val4);
			LineRenderer val5 = val4.AddComponent<LineRenderer>();
			val5.positionCount = 2;
			val5.startWidth = 0.06f;
			val5.endWidth = 0.02f;
			((Renderer)val5).material = runMat;
			val5.useWorldSpace = true;
			val5.SetPosition(0, val);
			val5.SetPosition(1, val3);
			CreateHoverDot(val, Vector3.one * 0.8f, runMat, slot, "[" + slot + "] " + BuildClusterLabel(item), BuildClusterTimeText(item), 1.25f);
		}
	}

	private void DrawCheckpointDots(List<CheckpointPoint> checkpoints, Material runMat, string slot, string runName)
	{
		//IL_0033: 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_0042: 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_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references)
		if (checkpoints == null)
		{
			return;
		}
		foreach (CheckpointPoint checkpoint in checkpoints)
		{
			Vector3 pos = new Vector3(checkpoint.x, checkpoint.y, checkpoint.z) + Vector3.up * 0.5f;
			CreateHoverDot(pos, Vector3.one * 1f, runMat, slot, "[" + slot + "] CHECKPOINT", FormatTime(checkpoint.time), 1.35f);
		}
	}

	private void DrawKillDots(List<KillPoint> kills, Material runMat, string slot, string runName)
	{
		//IL_000f: 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_0044: 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)
		//IL_0058: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		if (kills == null)
		{
			return;
		}
		Material mat = MakeMaterialColor(Color.red);
		foreach (KillPoint kill in kills)
		{
			Vector3 pos = new Vector3(kill.x, kill.y, kill.z) + Vector3.up * 1.2f;
			CreateHoverDot(pos, Vector3.one * 1.1f, mat, slot, "[" + slot + "] " + kill.label, FormatTime(kill.time), 1.45f);
		}
	}

	private void DrawSpeedMarkerDots(List<SpeedMarkerPoint> speedMarkers, string slot)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: 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_0060: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		if (speedMarkers == null)
		{
			return;
		}
		Material mat = MakeMaterialColor(new Color(1f, 0.9f, 0.1f));
		foreach (SpeedMarkerPoint speedMarker in speedMarkers)
		{
			Vector3 pos = new Vector3(speedMarker.x, speedMarker.y, speedMarker.z) + Vector3.up * 0.35f;
			string label = "[" + slot + "] " + speedMarker.label + "\nH Speed: " + speedMarker.horizontalSpeed.ToString("0.0", CultureInfo.InvariantCulture) + "\nV Speed: " + speedMarker.verticalSpeed.ToString("0.0", CultureInfo.InvariantCulture);
			CreateHoverDot(pos, Vector3.one * 0.9f, mat, slot, label, FormatTime(speedMarker.time), 1.45f);
		}
	}

	private void DrawRouteDifferenceMarkers()
	{
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: 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_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: 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_0178: Expected O, but got Unknown
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		ClearGhostSlot("DIFF");
		if (loadedAPoints == null || loadedBPoints == null || loadedAPoints.Count < 2 || loadedBPoints.Count < 2)
		{
			return;
		}
		float num = Mathf.Max(loadedAPoints[0].time, loadedBPoints[0].time);
		float num2 = Mathf.Min(loadedAPoints[loadedAPoints.Count - 1].time, loadedBPoints[loadedBPoints.Count - 1].time);
		if (num2 <= num)
		{
			return;
		}
		float num3 = -999f;
		Material val = MakeMaterialColor(Color.white);
		for (float num4 = num; num4 <= num2; num4 += routeDifferenceSampleStep)
		{
			if (TryGetPositionAtTime(loadedAPoints, num4, out var position) && TryGetPositionAtTime(loadedBPoints, num4, out var position2))
			{
				float num5 = Vector3.Distance(position, position2);
				if (!(num5 < routeDifferenceThresholdField.value) && !(num4 - num3 < routeDifferenceCooldown))
				{
					num3 = num4;
					Vector3 val2 = (position + position2) * 0.5f;
					GameObject val3 = new GameObject("Alien Route Difference Line");
					val3.AddComponent<GhostSlot>().slot = "DIFF";
					ghostObjects.Add(val3);
					LineRenderer val4 = val3.AddComponent<LineRenderer>();
					val4.positionCount = 2;
					val4.startWidth = 0.12f;
					val4.endWidth = 0.12f;
					((Renderer)val4).material = val;
					val4.useWorldSpace = true;
					val4.SetPosition(0, position);
					val4.SetPosition(1, position2);
					CreateHoverDot(val2 + Vector3.up * 0.5f, Vector3.one * 1f, val, "DIFF", "ROUTE DIFFERENCE\nDistance: " + num5.ToString("0.0", CultureInfo.InvariantCulture) + "m", FormatTime(num4), 1.3f);
				}
			}
		}
	}

	private bool TryGetPositionAtTime(List<RunPoint> points, float time, out Vector3 position)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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_0137: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		if (points == null || points.Count == 0)
		{
			return false;
		}
		if (time <= points[0].time)
		{
			position = new Vector3(points[0].x, points[0].y, points[0].z);
			return true;
		}
		Vector3 val = default(Vector3);
		Vector3 val2 = default(Vector3);
		for (int i = 0; i < points.Count - 1; i++)
		{
			RunPoint runPoint = points[i];
			RunPoint runPoint2 = points[i + 1];
			if (time >= runPoint.time && time <= runPoint2.time)
			{
				float num = runPoint2.time - runPoint.time;
				if (num <= 0.0001f)
				{
					num = 0.0001f;
				}
				float num2 = Mathf.Clamp01((time - runPoint.time) / num);
				((Vector3)(ref val))..ctor(runPoint.x, runPoint.y, runPoint.z);
				((Vector3)(ref val2))..ctor(runPoint2.x, runPoint2.y, runPoint2.z);
				position = Vector3.Lerp(val, val2, num2);
				return true;
			}
		}
		RunPoint runPoint3 = points[points.Count - 1];
		position = new Vector3(runPoint3.x, runPoint3.y, runPoint3.z);
		return true;
	}

	private void CreateHoverDot(Vector3 pos, Vector3 scale, Material mat, string slot, string label, string timeText, float textHeight)
	{
		//IL_002e: 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_008d: 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_0099: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
		((Object)val).name = "Alien Hover Dot " + slot;
		val.AddComponent<GhostSlot>().slot = slot;
		val.transform.position = pos;
		val.transform.localScale = scale;
		Renderer component = val.GetComponent<Renderer>();
		if ((Object)(object)component != (Object)null)
		{
			component.material = mat;
		}
		Collider component2 = val.GetComponent<Collider>();
		if ((Object)(object)component2 != (Object)null)
		{
			Object.Destroy((Object)(object)component2);
		}
		ghostObjects.Add(val);
		GameObject val2 = CreateWorldText(val.transform.position + Vector3.up * textHeight, "", mat.color, 0.55f, slot);
		val2.SetActive(false);
		ghostObjects.Add(val2);
		HoverMarker hoverMarker = new HoverMarker();
		hoverMarker.slot = slot;
		hoverMarker.dotObject = val;
		hoverMarker.textObject = val2;
		hoverMarker.textMesh = val2.GetComponent<TextMesh>();
		hoverMarker.label = label;
		hoverMarker.timeText = timeText;
		hoverMarkers.Add(hoverMarker);
	}

	private GameObject CreateWorldText(Vector3 position, string textValue, Color color, float size, string slot)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Alien Dot Hover Text " + slot);
		val.AddComponent<GhostSlot>().slot = slot;
		val.transform.position = position;
		TextMesh val2 = val.AddComponent<TextMesh>();
		val2.text = textValue;
		val2.characterSize = size;
		val2.fontSize = 90;
		val2.anchor = (TextAnchor)4;
		val2.alignment = (TextAlignment)1;
		val2.color = color;
		return val;
	}

	private List<ActionCluster> BuildActionClusters(List<ActionPoint> actions)
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: 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_0071: Unknown result type (might be due to invalid IL or missing references)
		List<ActionCluster> list = new List<ActionCluster>();
		Vector3 val = default(Vector3);
		foreach (ActionPoint action in actions)
		{
			((Vector3)(ref val))..ctor(action.x, action.y, action.z);
			bool flag = false;
			foreach (ActionCluster item in list)
			{
				if (item.label == action.label)
				{
					Vector3 val2 = item.AveragePosition();
					if (Vector3.Distance(val, val2) <= clusterDistance)
					{
						item.actions.Add(action);
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				ActionCluster actionCluster = new ActionCluster();
				actionCluster.label = action.label;
				actionCluster.actions = new List<ActionPoint>();
				actionCluster.actions.Add(action);
				list.Add(actionCluster);
			}
		}
		return list;
	}

	private string BuildClusterLabel(ActionCluster cluster)
	{
		string text = cluster.label;
		if (cluster.actions.Count > 1)
		{
			text = text + " x" + cluster.actions.Count;
		}
		return text;
	}

	private string BuildClusterTimeText(ActionCluster cluster)
	{
		string text = "";
		for (int i = 0; i < cluster.actions.Count; i++)
		{
			if (i > 0)
			{
				text += ", ";
			}
			text += FormatTime(cluster.actions[i].time);
		}
		return text;
	}

	private string FormatTime(float seconds)
	{
		if (seconds < 0f)
		{
			seconds = 0f;
		}
		int num = Mathf.FloorToInt(seconds / 60f);
		float num2 = seconds - (float)num * 60f;
		return num.ToString("00") + ":" + num2.ToString("00.000", CultureInfo.InvariantCulture);
	}

	private void ToggleGhostVisibility()
	{
		ghostVisible = !ghostVisible;
		SetGhostVisibility(ghostVisible);
		if (!ghostVisible)
		{
			HideAllHoverTexts();
		}
		if (ghostVisible)
		{
			SetStatus("GHOST SHOWN");
		}
		else
		{
			SetStatus("GHOST HIDDEN");
		}
	}

	private void SetGhostVisibility(bool visible)
	{
		foreach (GameObject ghostObject in ghostObjects)
		{
			if ((Object)(object)ghostObject != (Object)null)
			{
				ghostObject.SetActive(visible);
			}
		}
	}

	private void ClearGhost()
	{
		foreach (GameObject ghostObject in ghostObjects)
		{
			if ((Object)(object)ghostObject != (Object)null)
			{
				Object.Destroy((Object)(object)ghostObject);
			}
		}
		ghostObjects.Clear();
		hoverMarkers.Clear();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Cleared all ghost visuals.");
	}

	private void ClearGhostSlot(string slot)
	{
		List<GameObject> list = new List<GameObject>();
		foreach (GameObject ghostObject in ghostObjects)
		{
			if (!((Object)(object)ghostObject == (Object)null))
			{
				GhostSlot component = ghostObject.GetComponent<GhostSlot>();
				if ((Object)(object)component != (Object)null && component.slot == slot)
				{
					list.Add(ghostObject);
				}
			}
		}
		foreach (GameObject item in list)
		{
			ghostObjects.Remove(item);
			if ((Object)(object)item != (Object)null)
			{
				Object.Destroy((Object)(object)item);
			}
		}
		List<HoverMarker> list2 = new List<HoverMarker>();
		foreach (HoverMarker hoverMarker in hoverMarkers)
		{
			if (hoverMarker != null && hoverMarker.slot == slot)
			{
				list2.Add(hoverMarker);
			}
		}
		foreach (HoverMarker item2 in list2)
		{
			hoverMarkers.Remove(item2);
		}
	}

	private void RefreshRunFiles()
	{
		runFiles.Clear();
		if (!Directory.Exists(saveFolder))
		{
			return;
		}
		string[] files = Directory.GetFiles(saveFolder, "*.txt");
		string[] array = files;
		foreach (string text in array)
		{
			if (Path.GetFileName(text).ToLower() == "latest_run.txt")
			{
				continue;
			}
			try
			{
				ReadRunFile(text, out List<RunPoint> _, out List<ActionPoint> _, out List<CheckpointPoint> _, out List<KillPoint> _, out List<SpeedMarkerPoint> _, out string displayName, out string savedTime, out string colorHex, out bool levelFinished);
				if (string.IsNullOrEmpty(activeColorFilter) || !(colorHex != activeColorFilter))
				{
					RunFileEntry runFileEntry = new RunFileEntry();
					runFileEntry.path = text;
					runFileEntry.fileName = Path.GetFileName(text);
					runFileEntry.displayName = displayName;
					runFileEntry.savedTime = savedTime;
					runFileEntry.colorHex = colorHex;
					runFileEntry.finishStatus = (levelFinished ? "LEVEL FINISHED" : "MANUAL / INTERRUPTED");
					runFileEntry.writeTime = File.GetLastWriteTime(text);
					runFiles.Add(runFileEntry);
					if (!renameInputs.ContainsKey(text))
					{
						renameInputs[text] = displayName;
					}
				}
			}
			catch
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to read run file: " + text));
			}
		}
		runFiles.Sort((RunFileEntry a, RunFileEntry b) => b.writeTime.CompareTo(a.writeTime));
	}

	private void ChangeRunColor(string path, string newColorHex)
	{
		if (!File.Exists(path))
		{
			SetStatus("COLOR CHANGE FAILED: FILE NOT FOUND");
			return;
		}
		ReadRunFile(path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string displayName, out string _, out string _, out bool levelFinished);
		WriteRunFile(path, displayName, levelFinished, newColorHex, points, actions, checkpoints, kills, speedMarkers);
	}

	private void RenameRun(string path, string newName)
	{
		if (!File.Exists(path))
		{
			SetStatus("RENAME FAILED: FILE NOT FOUND");
			return;
		}
		if (string.IsNullOrWhiteSpace(newName))
		{
			SetStatus("RENAME FAILED: EMPTY NAME");
			return;
		}
		ReadRunFile(path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string _, out string _, out string colorHex, out bool levelFinished);
		string text = MakeSafeFileName(newName);
		string directoryName = Path.GetDirectoryName(path);
		string text2 = Path.Combine(directoryName, text + ".txt");
		int num = 1;
		while (File.Exists(text2) && text2 != path)
		{
			text2 = Path.Combine(directoryName, text + "_" + num + ".txt");
			num++;
		}
		WriteRunFile(text2, newName, levelFinished, colorHex, points, actions, checkpoints, kills, speedMarkers);
		if (text2 != path)
		{
			File.Delete(path);
		}
		SetStatus("RENAMED RUN");
	}

	private string MakeSafeFileName(string name)
	{
		char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
		foreach (char c in invalidFileNameChars)
		{
			name = name.Replace(c.ToString(), "");
		}
		name = name.Trim();
		if (string.IsNullOrEmpty(name))
		{
			name = "Renamed_Run";
		}
		return name;
	}

	private string F(float value)
	{
		return value.ToString(CultureInfo.InvariantCulture);
	}

	private float Parse(string value)
	{
		return float.Parse(value, CultureInfo.InvariantCulture);
	}
}
public enum BindKey
{
	None,
	Semicolon,
	Quote,
	LeftBracket,
	RightBracket,
	Backslash,
	Comma,
	Period,
	Slash,
	Minus,
	Equals,
	F1,
	F2,
	F3,
	F4,
	F5,
	F6,
	F7,
	F8,
	F9,
	F10,
	F11,
	F12,
	Alpha0,
	Alpha1,
	Alpha2,
	Alpha3,
	Alpha4,
	Alpha5,
	Alpha6,
	Alpha7,
	Alpha8,
	Alpha9,
	A,
	B,
	C,
	D,
	E,
	F,
	G,
	H,
	I,
	J,
	K,
	L,
	M,
	N,
	O,
	P,
	Q,
	R,
	S,
	T,
	U,
	V,
	W,
	X,
	Y,
	Z,
	Insert,
	Delete,
	Home,
	End,
	PageUp,
	PageDown,
	Keypad0,
	Keypad1,
	Keypad2,
	Keypad3,
	Keypad4,
	Keypad5,
	Keypad6,
	Keypad7,
	Keypad8,
	Keypad9
}
public class ColorOption
{
	public string name;

	public string hex;

	public ColorOption(string name, string hex)
	{
		this.name = name;
		this.hex = hex;
	}
}
public class GhostSlot : MonoBehaviour
{
	public string slot;
}
public class RunPoint
{
	public float time;

	public float x;

	public float y;

	public float z;
}
public class ActionPoint
{
	public float time;

	public float x;

	public float y;

	public float z;

	public float dx;

	public float dy;

	public float dz;

	public string label;
}
public class CheckpointPoint
{
	public float time;

	public float x;

	public float y;

	public float z;

	public string label;
}
public class KillPoint
{
	public float time;

	public float x;

	public float y;

	public float z;

	public string label;
}
public class SpeedMarkerPoint
{
	public float time;

	public float x;

	public float y;

	public float z;

	public float horizontalSpeed;

	public float verticalSpeed;

	public string label;
}
public class EnemyTrack
{
	public int id;

	public string name;

	public Vector3 lastPosition;

	public float lastSeenTime;
}
public class ActionCluster
{
	public string label;

	public List<ActionPoint> actions;

	public Vector3 AveragePosition()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: 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_0094: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_007f: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		if (actions == null || actions.Count == 0)
		{
			return Vector3.zero;
		}
		Vector3 val = Vector3.zero;
		foreach (ActionPoint action in actions)
		{
			val += new Vector3(action.x, action.y, action.z);
		}
		return val / (float)actions.Count;
	}

	public Vector3 AverageDirection()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: 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_0089: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_0081: 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 (actions == null || actions.Count == 0)
		{
			return Vector3.forward;
		}
		Vector3 val = Vector3.zero;
		foreach (ActionPoint action in actions)
		{
			val += new Vector3(action.dx, action.dy, action.dz);
		}
		return ((Vector3)(ref val)).normalized;
	}
}
public class HoverMarker
{
	public string slot;

	public GameObject dotObject;

	public GameObject textObject;

	public TextMesh textMesh;

	public string label;

	public string timeText;
}
public class RunFileEntry
{
	public string path;

	public string fileName;

	public string displayName;

	public string savedTime;

	public string colorHex;

	public string finishStatus;

	public DateTime writeTime;
}
namespace MyFirstUltrakillMod
{
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.alienpxgaming.speedrunpaths";

		public const string PLUGIN_NAME = "Alien's Speedrun Paths";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}