Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SpectateEnemiesFork v2.9.0
SpectateEnemy.dll
Decompiled 2 days agousing 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 SpectateEnemy.NetcodePatcher; 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.8.0.0")] [assembly: AssemblyInformationalVersion("2.8.0+f172922df5c949e445145afc53955d88abd8459f")] [assembly: AssemblyProduct("SpectateEnemy")] [assembly: AssemblyTitle("SpectateEnemy")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.8.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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.8.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_0135: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) if (windowID == 0) { scrollPos = GUI.BeginScrollView(new Rect(5f, 20f, 490f, 370f), scrollPos, new Rect(5f, 20f, 490f, 370f), false, true); 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.8.0"; } } 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() { if ((Object)(object)SpectateEnemies.Instance != (Object)null) { 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"; } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace SpectateEnemy.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }