Decompiled source of SpectateEnemies v2.4.1

SpectateEnemy.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[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("SpectateEnemy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("2.3.1.0")]
[assembly: AssemblyInformationalVersion("2.3.1+714e57b90c271eaae7485da5bf6e165162350071")]
[assembly: AssemblyProduct("SpectateEnemy")]
[assembly: AssemblyTitle("SpectateEnemy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.3.1.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SpectateEnemy
{
	internal class Inputs : LcInputActions
	{
		[InputAction("<Keyboard>/e", Name = "Swap between Players/Enemies")]
		public InputAction SwapKey { get; set; }

		[InputAction("<Keyboard>/insert", Name = "Open Config Menu")]
		public InputAction MenuKey { get; set; }

		[InputAction("<Mouse>/rightButton", Name = "Toggle Flashlight")]
		public InputAction FlashlightKey { get; set; }

		[InputAction("<Mouse>/scroll/down", Name = "Zoom Out")]
		public InputAction ZoomOutKey { get; set; }

		[InputAction("<Mouse>/scroll/up", Name = "Zoom In")]
		public InputAction ZoomInKey { get; set; }
	}
	[BepInPlugin("SpectateEnemy", "SpectateEnemy", "2.4.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public static MethodInfo raycastSpectate = null;

		public static MethodInfo displaySpectatorTip = null;

		public static Inputs Inputs = new Inputs();

		public static ConfigFile Configuration;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Configuration = ((BaseUnityPlugin)this).Config;
			harmony = new Harmony("SpectateEnemy");
			harmony.PatchAll();
			raycastSpectate = AccessTools.Method(typeof(PlayerControllerB), "RaycastSpectateCameraAroundPivot", (Type[])null, (Type[])null);
			displaySpectatorTip = AccessTools.Method(typeof(HUDManager), "DisplaySpectatorTip", (Type[])null, (Type[])null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SpectateEnemy loaded!");
		}
	}
	internal class Spectatable : MonoBehaviour
	{
		public SpectatableType type = SpectatableType.Enemy;

		public string enemyName = "Enemy";

		public string maskedName = string.Empty;

		public EnemyAI enemyInstance = null;
	}
	internal enum SpectatableType
	{
		Enemy,
		Turret,
		Landmine,
		Masked,
		GhostGirl
	}
	internal class SpectateEnemies : MonoBehaviour
	{
		public static SpectateEnemies Instance;

		private static readonly Dictionary<string, ConfigEntry<bool>> settings = new Dictionary<string, ConfigEntry<bool>>();

		private bool WindowOpen = false;

		private Rect window = new Rect(10f, 10f, 500f, 400f);

		private Vector2 scrollPos = Vector2.zero;

		public int SpectatedEnemyIndex = -1;

		public bool SpectatingEnemies = false;

		public Spectatable[] SpectatorList;

		public float ZoomLevel = 1f;

		public ConfigEntry<bool> HideControls;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			SetupKeybinds();
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			HideControls = Plugin.Configuration.Bind<bool>("Config", "Hide Controls", false, "Hides the controls toolip on the right hand side.");
		}

		private void SetupKeybinds()
		{
			Plugin.Inputs.SwapKey.performed += OnSwapKeyPressed;
			Plugin.Inputs.MenuKey.performed += OnMenuKeyPressed;
			Plugin.Inputs.FlashlightKey.performed += OnFlashlightKeyPressed;
			Plugin.Inputs.ZoomOutKey.performed += OnZoomOutPressed;
			Plugin.Inputs.ZoomInKey.performed += OnZoomInPressed;
		}

		private void OnSwapKeyPressed(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				if (((NetworkBehaviour)localPlayerController).IsOwner && localPlayerController.isPlayerDead && !StartOfRound.Instance.shipIsLeaving && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
				{
					ToggleSpectatingMode(localPlayerController);
				}
			}
		}

		private void OnMenuKeyPressed(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				if (((NetworkBehaviour)localPlayerController).IsOwner && localPlayerController.isPlayerDead && !StartOfRound.Instance.shipIsLeaving && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
				{
					Toggle();
				}
			}
		}

		private void OnFlashlightKeyPressed(CallbackContext context)
		{
			if (!((CallbackContext)(ref context)).performed || !((Object)(object)GameNetworkManager.Instance != (Object)null) || !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null))
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)HUDManager.Instance != (Object)null && ((NetworkBehaviour)localPlayerController).IsOwner && localPlayerController.isPlayerDead && !StartOfRound.Instance.shipIsLeaving && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject))
			{
				Light component = ((Component)HUDManager.Instance.playersManager.spectateCamera).GetComponent<Light>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = !((Behaviour)component).enabled;
				}
			}
		}

		private void OnZoomOutPressed(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && SpectatingEnemies)
			{
				ZoomLevel += 0.1f;
				if (ZoomLevel > 10f)
				{
					ZoomLevel = 10f;
				}
			}
		}

		private void OnZoomInPressed(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && SpectatingEnemies)
			{
				ZoomLevel -= 0.1f;
				if (ZoomLevel < 1f)
				{
					ZoomLevel = 1f;
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			if (!SpectatingEnemies)
			{
				return;
			}
			if (SpectatorList.Length == 0)
			{
				SpectatingEnemies = false;
				return;
			}
			Spectatable obj = SpectatorList.ElementAtOrDefault(SpectatedEnemyIndex);
			if ((Object)(object)obj == (Object)null)
			{
				GetNextValidSpectatable();
				return;
			}
			if ((obj.type == SpectatableType.Enemy || obj.type == SpectatableType.Masked || obj.type == SpectatableType.GhostGirl) && (Object)(object)obj.enemyInstance != (Object)null && obj.enemyInstance.isEnemyDead)
			{
				GetNextValidSpectatable();
				return;
			}
			Vector3? spectatePosition = GetSpectatePosition(obj);
			if (!spectatePosition.HasValue)
			{
				GetNextValidSpectatable();
				return;
			}
			if (obj.enemyName == "Enemy")
			{
				TryFixName(ref obj);
			}
			GameNetworkManager.Instance.localPlayerController.spectateCameraPivot.position = spectatePosition.Value;
			if (obj.type == SpectatableType.Masked && obj.maskedName != string.Empty)
			{
				((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = $"(Spectating: {obj.maskedName}) [{ZoomLevel:F1}x]";
			}
			else if (obj.type == SpectatableType.GhostGirl)
			{
				DressGirlAI component = ((Component)obj).gameObject.GetComponent<DressGirlAI>();
				((EnemyAI)component).EnableEnemyMesh(true, true);
				PlayerControllerB targetPlayer = ((EnemyAI)component).targetPlayer;
				if ((Object)(object)targetPlayer != (Object)null)
				{
					((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = $"(Spectating: {obj.maskedName}) [{ZoomLevel:F1}x]\n(Targeting: {targetPlayer.playerUsername})";
				}
				else
				{
					((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = $"(Spectating: {obj.maskedName}) [{ZoomLevel:F1}x]\n(No Target)";
				}
			}
			else
			{
				((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = $"(Spectating: {obj.enemyName}) [{ZoomLevel:F1}x]";
			}
			Plugin.raycastSpectate.Invoke(GameNetworkManager.Instance.localPlayerController, Array.Empty<object>());
			((Component)((Component)GameNetworkManager.Instance.localPlayerController.spectateCameraPivot).GetComponentInChildren<Camera>()).transform.localPosition = Vector3.back * (ZoomLevel + 0.5f);
		}

		private Vector3? GetSpectatePosition(Spectatable obj)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (obj.type == SpectatableType.Enemy || obj.type == SpectatableType.Masked || obj.type == SpectatableType.GhostGirl)
			{
				EnemyAI enemyInstance = obj.enemyInstance;
				if ((Object)(object)enemyInstance != (Object)null)
				{
					return ((Object)(object)enemyInstance.eye == (Object)null) ? ((Component)enemyInstance).transform.position : enemyInstance.eye.position;
				}
			}
			else if (obj.type == SpectatableType.Turret)
			{
				Turret component = ((Component)obj).GetComponent<Turret>();
				if ((Object)(object)component != (Object)null)
				{
					return ((Component)component.centerPoint).transform.position;
				}
			}
			else
			{
				if (obj.type == SpectatableType.Landmine)
				{
					return ((Component)obj).transform.position;
				}
				Debug.LogError((object)("[SpectateEnemy]: Error when spectating: no handler for SpectatableType " + obj.type));
			}
			return null;
		}

		private void TryFixName(ref Spectatable obj)
		{
			MaskedPlayerEnemy val = default(MaskedPlayerEnemy);
			EnemyAI val2 = default(EnemyAI);
			Turret val3 = default(Turret);
			Landmine val4 = default(Landmine);
			if (((Component)obj).gameObject.TryGetComponent<MaskedPlayerEnemy>(ref val))
			{
				if ((Object)(object)val.mimickingPlayer != (Object)null)
				{
					obj.enemyName = val.mimickingPlayer.playerUsername;
				}
				else
				{
					obj.enemyName = ((EnemyAI)val).enemyType.enemyName;
				}
			}
			else if (((Component)obj).gameObject.TryGetComponent<EnemyAI>(ref val2))
			{
				obj.enemyName = val2.enemyType.enemyName;
			}
			else if (((Component)obj).gameObject.TryGetComponent<Turret>(ref val3))
			{
				obj.enemyName = "Turret";
			}
			else if (((Component)obj).gameObject.TryGetComponent<Landmine>(ref val4))
			{
				obj.enemyName = "Landmine";
			}
		}

		public void ToggleSpectatingMode(PlayerControllerB __instance)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			SpectatingEnemies = !SpectatingEnemies;
			if (SpectatingEnemies)
			{
				SpectatorList = (from x in Object.FindObjectsByType<Spectatable>((FindObjectsSortMode)0)
					where GetSetting(SanitizeEnemyName(x.enemyName))
					select x).ToArray();
				if (SpectatorList.Length == 0)
				{
					SpectatingEnemies = false;
					Plugin.displaySpectatorTip.Invoke(HUDManager.Instance, new object[1] { "No enemies to spectate" });
					return;
				}
				if (SpectatedEnemyIndex == -1 || SpectatedEnemyIndex >= SpectatorList.Length)
				{
					if ((Object)(object)__instance.spectatedPlayerScript == (Object)null)
					{
						GetNextValidSpectatable();
					}
					else
					{
						float num = 999999f;
						int spectatedEnemyIndex = 0;
						for (int i = 0; i < SpectatorList.Length; i++)
						{
							Vector3 val = ((Component)SpectatorList[i]).transform.position - ((Component)__instance.spectatedPlayerScript).transform.position;
							float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
							if (sqrMagnitude < num * num)
							{
								num = sqrMagnitude;
								spectatedEnemyIndex = i;
							}
						}
						SpectatedEnemyIndex = spectatedEnemyIndex;
					}
				}
				__instance.spectatedPlayerScript = null;
			}
			else
			{
				__instance.spectatedPlayerScript = ((IEnumerable<PlayerControllerB>)__instance.playersManager.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => !x.isPlayerDead && x.isPlayerControlled));
				((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "(Spectating: " + __instance.spectatedPlayerScript.playerUsername + ")";
			}
		}

		public void PopulateSettings()
		{
			EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>();
			EnemyType[] array2 = array;
			foreach (EnemyType val in array2)
			{
				if (!(val.enemyName == "Red pill") && !(val.enemyName == "Lasso"))
				{
					string text = SanitizeEnemyName(val.enemyName);
					settings.TryAdd(text, Plugin.Configuration.Bind<bool>("Enemies", text, !val.isDaytimeEnemy, "Enables spectating " + text));
				}
			}
			settings.TryAdd("Landmine", Plugin.Configuration.Bind<bool>("Enemies", "Landmine", false, "Enables spectating Landmines"));
			settings.TryAdd("Turret", Plugin.Configuration.Bind<bool>("Enemies", "Turret", false, "Enables spectating Turrets"));
			Debug.LogWarning((object)"[SpectateEnemies]: Config loaded");
			AssertSettings();
		}

		public bool SpectateNextEnemy()
		{
			if (SpectatorList.Length == 0)
			{
				SpectatingEnemies = false;
				return true;
			}
			GetNextValidSpectatable();
			return false;
		}

		private string SanitizeEnemyName(string enemyName)
		{
			return enemyName.Replace("\\", "").Replace("\"", "").Replace("'", "")
				.Replace("[", "")
				.Replace("]", "");
		}

		private void GetNextValidSpectatable()
		{
			SpectatorList = (from x in Object.FindObjectsByType<Spectatable>((FindObjectsSortMode)0)
				where GetSetting(SanitizeEnemyName(x.enemyName))
				select x).ToArray();
			int num = 0;
			int num2 = SpectatedEnemyIndex;
			while (num < SpectatorList.Length)
			{
				num2++;
				if (num2 >= SpectatorList.Length)
				{
					num2 = 0;
				}
				Spectatable spectatable = SpectatorList.ElementAtOrDefault(num2);
				if ((Object)(object)spectatable != (Object)null)
				{
					if ((spectatable.type == SpectatableType.Enemy || spectatable.type == SpectatableType.Masked || spectatable.type == SpectatableType.GhostGirl) && (Object)(object)spectatable.enemyInstance != (Object)null && spectatable.enemyInstance.isEnemyDead)
					{
						num++;
						continue;
					}
					if (settings.ContainsKey(SanitizeEnemyName(spectatable.enemyName)))
					{
						SpectatedEnemyIndex = num2;
						return;
					}
				}
				num++;
			}
			SpectatingEnemies = false;
			Plugin.displaySpectatorTip.Invoke(HUDManager.Instance, new object[1] { "No enemies to spectate" });
		}

		private void AssertSettings()
		{
			foreach (KeyValuePair<string, ConfigEntry<bool>> setting in settings)
			{
				Debug.LogWarning((object)$"{setting.Key} : {setting.Value.Value}");
			}
		}

		public bool GetSetting(string name)
		{
			if (settings.ContainsKey(name))
			{
				return settings[name].Value;
			}
			return false;
		}

		public void Toggle()
		{
			WindowOpen = !WindowOpen;
		}

		public void Hide()
		{
			WindowOpen = false;
		}

		public bool IsMenuOpen()
		{
			return WindowOpen;
		}

		private void OnGUI()
		{
			//IL_000c: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0030: 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)
			if (WindowOpen)
			{
				GUI.color = Color.gray;
				window = GUI.Window(0, window, new WindowFunction(DrawGUI), "Spectator Settings");
			}
		}

		private void DrawGUI(int windowID)
		{
			//IL_0133: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (windowID == 0)
			{
				scrollPos = GUI.BeginScrollView(new Rect(5f, 20f, 490f, 400f), scrollPos, new Rect(5f, 20f, 490f, 400f));
				GUI.Label(new Rect(10f, 30f, 500f, 100f), "Tip: Checking the box next to an enemy name will enable spectating it.");
				int num = 0;
				int num2 = 0;
				foreach (string item in settings.Keys.ToList())
				{
					settings[item].Value = GUI.Toggle(new Rect((float)(10 + 150 * num), (float)(60 + 30 * num2), 150f, 20f), settings[item].Value, item);
					num++;
					if (num == 3)
					{
						num = 0;
						num2++;
					}
				}
				GUI.EndScrollView(true);
			}
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 10000f));
		}
	}
	public class SpectateEnemiesAPI
	{
		public static bool IsLoaded => (Object)(object)SpectateEnemies.Instance != (Object)null;

		public static bool IsSpectatingEnemies => SpectateEnemies.Instance.SpectatingEnemies;

		public static GameObject CurrentEnemySpectating()
		{
			if (IsSpectatingEnemies && SpectateEnemies.Instance.SpectatedEnemyIndex > -1)
			{
				return ((Component)SpectateEnemies.Instance.SpectatorList[SpectateEnemies.Instance.SpectatedEnemyIndex]).gameObject;
			}
			return null;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "SpectateEnemy";

		public const string PLUGIN_NAME = "SpectateEnemy";

		public const string PLUGIN_VERSION = "2.3.1";
	}
}
namespace SpectateEnemy.Patches
{
	[HarmonyPatch(typeof(DressGirlAI), "Start")]
	internal class DressGirlAI_Patches
	{
		private static void Postfix(DressGirlAI __instance)
		{
			Spectatable spectatable = ((Component)__instance).gameObject.GetComponent<Spectatable>();
			if ((Object)(object)spectatable == (Object)null)
			{
				spectatable = ((Component)__instance).gameObject.AddComponent<Spectatable>();
				spectatable.enemyName = ((EnemyAI)__instance).enemyType.enemyName;
				spectatable.enemyInstance = (EnemyAI)(object)__instance;
			}
			spectatable.type = SpectatableType.GhostGirl;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "Start")]
	internal class EnemyAI_Patches
	{
		private static void Postfix(EnemyAI __instance)
		{
			Spectatable spectatable = ((Component)__instance).gameObject.AddComponent<Spectatable>();
			spectatable.enemyName = __instance.enemyType.enemyName;
			spectatable.enemyInstance = __instance;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
	internal class GameNetworkManager_Disconnect
	{
		private static void Postfix()
		{
			SpectateEnemies.Instance.SpectatedEnemyIndex = -1;
			SpectateEnemies.Instance.SpectatingEnemies = false;
			SpectateEnemies.Instance.Hide();
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "OnApplicationQuit")]
	internal class GameNetworkManager_Quit
	{
		private static void Prefix()
		{
			if ((Object)(object)SpectateEnemies.Instance != (Object)null)
			{
				Plugin.Configuration.Save();
				Debug.LogWarning((object)"[SpectateEnemies]: Config saved");
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "Update")]
	internal class HUDManager_Patches
	{
		private static void Postfix(HUDManager __instance)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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)
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) || !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null))
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (!localPlayerController.isPlayerDead)
			{
				return;
			}
			if (StartOfRound.Instance.shipIsLeaving)
			{
				SpectateEnemies.Instance.Hide();
				Light component = ((Component)__instance.playersManager.spectateCamera).GetComponent<Light>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				return;
			}
			InputBinding val = Plugin.Inputs.SwapKey.bindings[0];
			string text = InputControlPath.ToHumanReadableString(((InputBinding)(ref val)).effectivePath, (HumanReadableStringOptions)2, (InputControl)null);
			val = Plugin.Inputs.MenuKey.bindings[0];
			string text2 = InputControlPath.ToHumanReadableString(((InputBinding)(ref val)).effectivePath, (HumanReadableStringOptions)2, (InputControl)null);
			val = Plugin.Inputs.FlashlightKey.bindings[0];
			string text3 = InputControlPath.ToHumanReadableString(((InputBinding)(ref val)).effectivePath, (HumanReadableStringOptions)2, (InputControl)null);
			val = Plugin.Inputs.ZoomOutKey.bindings[0];
			string text4 = InputControlPath.ToHumanReadableString(((InputBinding)(ref val)).effectivePath, (HumanReadableStringOptions)2, (InputControl)null);
			val = Plugin.Inputs.ZoomInKey.bindings[0];
			string text5 = InputControlPath.ToHumanReadableString(((InputBinding)(ref val)).effectivePath, (HumanReadableStringOptions)2, (InputControl)null);
			if (!SpectateEnemies.Instance.HideControls.Value)
			{
				if (SpectateEnemies.Instance.SpectatingEnemies)
				{
					TextMeshProUGUI holdButtonToEndGameEarlyText = __instance.holdButtonToEndGameEarlyText;
					((TMP_Text)holdButtonToEndGameEarlyText).text = ((TMP_Text)holdButtonToEndGameEarlyText).text + "\n\n\n\n\nSpectate Players: [" + text + "]\nFlashlight : [" + text3 + "]\nZoom Out : [" + text4 + "]\nZoom In : [" + text5 + "]\nConfig Menu : [" + text2 + "]";
				}
				else
				{
					TextMeshProUGUI holdButtonToEndGameEarlyText = __instance.holdButtonToEndGameEarlyText;
					((TMP_Text)holdButtonToEndGameEarlyText).text = ((TMP_Text)holdButtonToEndGameEarlyText).text + "\n\n\n\n\nSpectate Enemies: [" + text + "]\nFlashlight : [" + text3 + "]\nConfig Menu : [" + text2 + "]";
				}
			}
		}
	}
	[HarmonyPatch(typeof(Landmine), "Start")]
	internal class Landmine_Patches
	{
		private static void Postfix(Landmine __instance)
		{
			Spectatable spectatable = ((Component)__instance).gameObject.AddComponent<Spectatable>();
			spectatable.type = SpectatableType.Landmine;
			spectatable.enemyName = "Landmine";
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy), "Start")]
	internal class MaskedPlayerEnemy_Patches
	{
		private static void Postfix(MaskedPlayerEnemy __instance)
		{
			Spectatable spectatable = ((Component)__instance).gameObject.AddComponent<Spectatable>();
			spectatable.type = SpectatableType.Masked;
			spectatable.enemyName = ((EnemyAI)__instance).enemyType.enemyName;
			if ((Object)(object)__instance.mimickingPlayer != (Object)null)
			{
				spectatable.maskedName = __instance.mimickingPlayer.playerUsername;
			}
			spectatable.enemyInstance = (EnemyAI)(object)__instance;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ActivateItem_performed")]
	internal class PlayerControllerB_Use
	{
		private static bool Prefix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerDead && !StartOfRound.Instance.shipIsLeaving && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject))
			{
				if (SpectateEnemies.Instance.IsMenuOpen())
				{
					return false;
				}
				if (SpectateEnemies.Instance.SpectatingEnemies)
				{
					SpectateEnemies.Instance.SpectateNextEnemy();
				}
				return true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SpectateNextPlayer")]
	internal class PlayerControllerB_SpectateNext
	{
		private static bool Prefix()
		{
			return !SpectateEnemies.Instance.SpectatingEnemies;
		}
	}
	[HarmonyPatch(typeof(QuickMenuManager), "Start")]
	internal class QuickMenuManager_Patches
	{
		private static void Postfix()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)SpectateEnemies.Instance == (Object)null)
			{
				GameObject val = new GameObject("SpectateEnemiesObject");
				SpectateEnemies spectateEnemies = val.AddComponent<SpectateEnemies>();
				spectateEnemies.PopulateSettings();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
	internal class StartOfRound_Patches
	{
		private static void Postfix()
		{
			SpectateEnemies.Instance.SpectatedEnemyIndex = -1;
			SpectateEnemies.Instance.SpectatingEnemies = false;
			SpectateEnemies.Instance.Hide();
		}
	}
	[HarmonyPatch(typeof(Turret), "Start")]
	internal class Turret_Patches
	{
		private static void Postfix(Turret __instance)
		{
			Spectatable spectatable = ((Component)__instance).gameObject.AddComponent<Spectatable>();
			spectatable.type = SpectatableType.Turret;
			spectatable.enemyName = "Turret";
		}
	}
}