Decompiled source of ARIA Mod v1.0.1

lethalAI_Mod.dll

Decompiled 11 hours ago
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<InputAction> disabledActions = new List<InputAction>();

		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<Terminal>();
			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<EnemyAI>();
				foreach (EnemyAI val3 in array2)
				{
					if (!val3.isEnemyDead)
					{
						num2++;
					}
				}
				GrabbableObject[] array3 = Object.FindObjectsOfType<GrabbableObject>();
				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>();
				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<ShipTeleporter>();
				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<ARIAOverlay>();
			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<string> TerminalKeybind;

		private readonly Harmony harmony = new Harmony("com.yourname.lethalAI");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			TerminalKeybind = ((BaseUnityPlugin)this).Config.Bind<string>("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";
	}
}