using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [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("lethalAI_Mod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("An AI system that activates when the first player dies.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("lethalAI_Mod")] [assembly: AssemblyTitle("lethalAI_Mod")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace lethalAI_Mod { public class ARIAOverlay : MonoBehaviour { public static bool isOpen = false; public static string outputText = "═══════════════════════════════════════\n ARIA - Artificial Rescue Intelligence\n Version 1.0.0 | The Company™\n═══════════════════════════════════════\n\n [OK] Neural systems initialized\n [OK] Ship mainframe connected\n [OK] Door control systems online\n [OK] Radar subsystems online\n [OK] Transmission array online\n\n WARNING: Activated due to employee fatality.\n Survival assistance mode engaged.\n\n Type 'help' for available commands.\n────────────────────────────────────────\n"; public static string inputText = ""; private static bool stylesInitialized = false; private static GUIStyle terminalStyle; private static GUIStyle inputStyle; private static GUIStyle backgroundStyle; private static GUIStyle mapLabelStyle; private static int currentRadarTarget = 0; private static Vector2 scrollPosition = Vector2.zero; private static bool shouldScrollToBottom = false; private static List disabledActions = new List(); private static void AppendOutput(string text) { outputText += text; if (outputText.Length > 3000) { outputText = outputText.Substring(outputText.Length - 3000); } shouldScrollToBottom = true; } public static void PlaySound(string type) { AudioSource val = HUDManager.Instance?.UIAudio; if (!((Object)(object)val == (Object)null)) { val.PlayOneShot(HUDManager.Instance.globalNotificationSFX); } } private void Update() { if (isOpen) { Camera val = StartOfRound.Instance?.mapScreen?.cam; if ((Object)(object)val != (Object)null) { val.Render(); } { foreach (InputAction item in InputSystem.ListEnabledActions()) { if (item.name.Contains("Spectate") || item.name.Contains("Swap")) { item.Disable(); if (!disabledActions.Contains(item)) { disabledActions.Add(item); } } } return; } } if (disabledActions.Count <= 0) { return; } foreach (InputAction disabledAction in disabledActions) { disabledAction.Enable(); } disabledActions.Clear(); } private void OnGUI() { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00db: 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_0108: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Invalid comparison between Unknown and I4 //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Invalid comparison between Unknown and I4 //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Invalid comparison between Unknown and I4 //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Invalid comparison between Unknown and I4 if (!isOpen) { return; } if (!stylesInitialized) { terminalStyle = new GUIStyle(); terminalStyle.normal.textColor = new Color(0f, 1f, 0.7f); terminalStyle.fontSize = 16; terminalStyle.wordWrap = true; inputStyle = new GUIStyle(GUI.skin.textField); inputStyle.normal.textColor = Color.white; inputStyle.fontSize = 16; inputStyle.normal.background = Texture2D.grayTexture; mapLabelStyle = new GUIStyle(); mapLabelStyle.normal.textColor = new Color(0f, 1f, 0.7f); mapLabelStyle.fontSize = 14; mapLabelStyle.alignment = (TextAnchor)4; Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, new Color(0f, 0.05f, 0.1f, 0.95f)); val.Apply(); backgroundStyle = new GUIStyle(); backgroundStyle.normal.background = val; stylesInitialized = true; } float num = (float)Screen.width * 0.45f; float num2 = (float)Screen.height * 0.7f; float num3 = (float)Screen.width * 0.03f; float num4 = (float)Screen.height * 0.15f; float num5 = (float)Screen.height * 0.45f; float num6 = (float)Screen.width * 0.53f; float num7 = (float)Screen.height * 0.15f; GUI.Box(new Rect(num3, num4, num, num2), "", backgroundStyle); GUI.Label(new Rect(num3 + 10f, num4 + 10f, num - 20f, 30f), "[ ARIA - SHIP AI SYSTEM ]", terminalStyle); GUI.Label(new Rect(num3 + 10f, num4 + 35f, num - 20f, 20f), "Commands: help | " + Plugin.TerminalKeybind.Value + " to close", terminalStyle); float num8 = num2 - 110f; float num9 = num - 30f; GUIStyle val2 = new GUIStyle(terminalStyle); val2.wordWrap = true; float num10 = val2.CalcHeight(new GUIContent(outputText), num9 - 20f); num10 = Mathf.Max(num10, num8); if (shouldScrollToBottom) { scrollPosition = new Vector2(0f, num10); shouldScrollToBottom = false; } scrollPosition = GUI.BeginScrollView(new Rect(num3 + 5f, num4 + 60f, num - 10f, num8), scrollPosition, new Rect(0f, 0f, num9, num10), false, false); GUI.Label(new Rect(5f, 0f, num9 - 20f, num10), outputText, terminalStyle); GUI.EndScrollView(); GUI.Label(new Rect(num3 + 10f, num4 + num2 - 40f, 20f, 30f), ">", terminalStyle); GUI.SetNextControlName("ARIAInput"); inputText = GUI.TextField(new Rect(num3 + 30f, num4 + num2 - 40f, num - 50f, 30f), inputText, inputStyle); GUI.FocusControl("ARIAInput"); if (Keyboard.current != null && ((ButtonControl)Keyboard.current.enterKey).wasPressedThisFrame && inputText.Trim() != "") { SubmitCommand(inputText.Trim().ToLower()); inputText = ""; } GUI.Box(new Rect(num6, num7, num5, num5), "", backgroundStyle); StartOfRound instance = StartOfRound.Instance; object obj; if (instance == null) { obj = null; } else { ManualCameraRenderer mapScreen = instance.mapScreen; if (mapScreen == null) { obj = null; } else { Camera cam = mapScreen.cam; obj = ((cam != null) ? cam.targetTexture : null); } } RenderTexture val3 = (RenderTexture)obj; if ((Object)(object)val3 != (Object)null) { GUI.DrawTexture(new Rect(num6 + 4f, num7 + 30f, num5 - 8f, num5 - 34f), (Texture)(object)val3, (ScaleMode)2); } else { GUI.Label(new Rect(num6, num7 + num5 / 2f - 10f, num5, 20f), "[ NO SIGNAL ]", mapLabelStyle); } string text = "Unknown"; if ((Object)(object)StartOfRound.Instance?.mapScreen != (Object)null) { PlayerControllerB targetedPlayer = StartOfRound.Instance.mapScreen.targetedPlayer; if ((Object)(object)targetedPlayer != (Object)null) { text = targetedPlayer.playerUsername; } } GUI.Label(new Rect(num6, num7 + 5f, num5, 20f), "[ TRACKING: " + text + " ]", mapLabelStyle); if (Event.current.isKey && (int)Event.current.type == 4 && (int)Event.current.keyCode != 286 && (int)Event.current.keyCode != 13 && (int)Event.current.keyCode > 0) { Event.current.Use(); } } private void SubmitCommand(string command) { AppendOutput("\n> " + command + "\n"); if (command == "help") { AppendOutput("\n ── AVAILABLE COMMANDS ──\n switch - Switch radar camera to next player\n scan - Scan for enemies and scrap\n open [door id] - Open a door\n close [door id] - Close a door\n teleport - Teleport a crew member to ship\n transmit [message] - Broadcast a message to all crew\n────────────────────────────────────────\n"); return; } Terminal val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { PlaySound("error"); AppendOutput("ERROR: Ship terminal not found.\n"); } else if (command == "switch") { ManualCameraRenderer val2 = StartOfRound.Instance?.mapScreen; PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (!((Object)(object)val2 != (Object)null) || array == null) { return; } int num = currentRadarTarget; do { currentRadarTarget++; if (currentRadarTarget >= array.Length) { currentRadarTarget = 0; } } while (!array[currentRadarTarget].isPlayerControlled && currentRadarTarget != num); val2.SwitchRadarTargetAndSync(currentRadarTarget); AppendOutput("Radar switched to: " + array[currentRadarTarget].playerUsername + "\n"); } else if (command == "scan") { int num2 = 0; int num3 = 0; EnemyAI[] array2 = Object.FindObjectsOfType(); foreach (EnemyAI val3 in array2) { if (!val3.isEnemyDead) { num2++; } } GrabbableObject[] array3 = Object.FindObjectsOfType(); foreach (GrabbableObject val4 in array3) { if (!val4.isHeld && !val4.isPocketed) { num3++; } } AppendOutput($"SCAN RESULTS:\n Hostile entities detected: {num2}\n Scrap items detected: {num3}\n"); } else if (command.StartsWith("open ") || command.StartsWith("close ")) { bool flag = command.StartsWith("open"); string text = command.Split(' ')[1]; TerminalAccessibleObject[] array4 = Object.FindObjectsOfType(); TerminalAccessibleObject[] array5 = array4; foreach (TerminalAccessibleObject val5 in array5) { if (val5.objectCode == text) { val5.SetDoorLocalClient(flag); AppendOutput((flag ? "Opening" : "Closing") + " door " + text + "...\n"); PlaySound("success"); return; } } PlaySound("error"); AppendOutput("No door found with code " + text + ".\n"); } else if (command == "teleport") { ShipTeleporter val6 = Object.FindObjectOfType(); if ((Object)(object)val6 == (Object)null) { PlaySound("error"); AppendOutput("ERROR: No teleporter found. Must be purchased first.\n"); } else { val6.PressTeleportButtonServerRpc(); PlaySound("success"); AppendOutput("Teleporting crew member to ship...\n"); } } else if (command.StartsWith("transmit ")) { string text2 = command.Substring(9); HUDManager.Instance.AddTextToChatOnServer("[ARIA]: " + text2, -1); PlaySound("success"); AppendOutput("Broadcast: " + text2 + "\n"); } else { PlaySound("error"); AppendOutput("Unknown command. Type 'help' for a list of commands.\n"); } } } [HarmonyPatch(typeof(HUDManager), "Awake")] public class HUDAwakePatch { private static void Postfix(HUDManager __instance) { ((Component)__instance).gameObject.AddComponent(); Plugin.Log.LogInfo((object)"ARIAOverlay attached to HUDManager!"); } } [HarmonyPatch(typeof(HUDManager), "Update")] public class HUDPatch { private static void Postfix(HUDManager __instance) { if (!Plugin.IsTerminalKeyPressed()) { return; } PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && val.isPlayerDead) { ARIAOverlay.isOpen = !ARIAOverlay.isOpen; if (ARIAOverlay.isOpen) { ARIAOverlay.PlaySound("open"); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } else { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } } } } [HarmonyPatch(typeof(StartOfRound), "ResetShip")] public class ResetPatch { private static void Postfix() { PlayerDeathPatch.AIActivated = false; PlayerDeathPatch.AIPlayer = null; ARIAOverlay.isOpen = false; ARIAOverlay.outputText = "═══════════════════════════════════════\n ARIA - Artificial Rescue Intelligence\n Version 1.0.0 | The Company™\n═══════════════════════════════════════\n\n [OK] Neural systems initialized\n [OK] Ship mainframe connected\n [OK] Door control systems online\n [OK] Radar subsystems online\n [OK] Transmission array online\n\n WARNING: Activated due to employee fatality.\n Survival assistance mode engaged.\n\n Type 'help' for available commands.\n────────────────────────────────────────\n"; Plugin.Log.LogInfo((object)"ARIA reset for new round."); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] public class BlockInputPatch { private static void Prefix(PlayerControllerB __instance) { if (ARIAOverlay.isOpen) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance != (Object)(object)val)) { __instance.disableLookInput = true; __instance.disableMoveInput = true; } } } private static void Postfix(PlayerControllerB __instance) { if (ARIAOverlay.isOpen) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance != (Object)(object)val)) { __instance.disableLookInput = false; __instance.disableMoveInput = false; } } } } [HarmonyPatch(typeof(PlayerControllerB), "SpectateNextPlayer")] public class BlockSpectateInputPatch { private static bool Prefix() { if (ARIAOverlay.isOpen) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB), "SpectateEnemies")] public class BlockSpectateEnemiesPatch { private static bool Prefix() { if (ARIAOverlay.isOpen) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB), "SpectateEnemies_performed")] public class BlockSpectateEnemiesPerformedPatch { private static bool Prefix() { if (ARIAOverlay.isOpen) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB), "SpectateNextPlayer_performed")] public class BlockSpectateNextPlayerPerformedPatch { private static bool Prefix() { if (ARIAOverlay.isOpen) { return false; } return true; } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] public class PlayerDeathPatch { public static bool AIActivated; public static PlayerControllerB AIPlayer; private static void Postfix(PlayerControllerB __instance) { if (!AIActivated) { AIActivated = true; AIPlayer = __instance; Plugin.Log.LogInfo((object)("Player " + __instance.playerUsername + " died first. ARIA activating!")); } } } [BepInPlugin("com.yourname.lethalAI", "Lethal AI Mod", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry TerminalKeybind; private readonly Harmony harmony = new Harmony("com.yourname.lethalAI"); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; TerminalKeybind = ((BaseUnityPlugin)this).Config.Bind("Keybinds", "TerminalKey", "F5", "Key to open/close the ARIA terminal while dead. Valid keys: F1-F12, Tab, Insert, Home, PageUp, PageDown"); Log.LogInfo((object)("Lethal AI Mod loaded! Terminal key: " + TerminalKeybind.Value)); harmony.PatchAll(); } public static bool IsTerminalKeyPressed() { if (Keyboard.current == null) { return false; } return TerminalKeybind.Value.ToUpper() switch { "F1" => ((ButtonControl)Keyboard.current.f1Key).wasPressedThisFrame, "F2" => ((ButtonControl)Keyboard.current.f2Key).wasPressedThisFrame, "F3" => ((ButtonControl)Keyboard.current.f3Key).wasPressedThisFrame, "F4" => ((ButtonControl)Keyboard.current.f4Key).wasPressedThisFrame, "F5" => ((ButtonControl)Keyboard.current.f5Key).wasPressedThisFrame, "F6" => ((ButtonControl)Keyboard.current.f6Key).wasPressedThisFrame, "F7" => ((ButtonControl)Keyboard.current.f7Key).wasPressedThisFrame, "F8" => ((ButtonControl)Keyboard.current.f8Key).wasPressedThisFrame, "F9" => ((ButtonControl)Keyboard.current.f9Key).wasPressedThisFrame, "F10" => ((ButtonControl)Keyboard.current.f10Key).wasPressedThisFrame, "F11" => ((ButtonControl)Keyboard.current.f11Key).wasPressedThisFrame, "F12" => ((ButtonControl)Keyboard.current.f12Key).wasPressedThisFrame, "TAB" => ((ButtonControl)Keyboard.current.tabKey).wasPressedThisFrame, "INSERT" => ((ButtonControl)Keyboard.current.insertKey).wasPressedThisFrame, "HOME" => ((ButtonControl)Keyboard.current.homeKey).wasPressedThisFrame, "PAGEUP" => ((ButtonControl)Keyboard.current.pageUpKey).wasPressedThisFrame, "PAGEDOWN" => ((ButtonControl)Keyboard.current.pageDownKey).wasPressedThisFrame, _ => ((ButtonControl)Keyboard.current.f5Key).wasPressedThisFrame, }; } } public static class PluginInfo { public const string PLUGIN_GUID = "lethalAI_Mod"; public const string PLUGIN_NAME = "lethalAI_Mod"; public const string PLUGIN_VERSION = "1.0.0"; } }