Decompiled source of AccessibleTerminal v1.0.0

AccessibleTerminal.dll

Decompiled 8 months 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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;

[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("AccessibleTerminal")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Execute just about any terminal command, without the use of a keyboard.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2d8ae576cddf9fd33db7d5bba1d29d90cb6e2012")]
[assembly: AssemblyProduct("AccessibleTerminal")]
[assembly: AssemblyTitle("AccessibleTerminal")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 AccessibleTerminal
{
	[BepInPlugin("pacoito.AccessibleTerminal", "AccessibleTerminal", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal const string GUID = "pacoito.AccessibleTerminal";

		internal const string PLUGIN_NAME = "AccessibleTerminal";

		internal const string VERSION = "1.0.0";

		internal static ManualLogSource StaticLogger;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			StaticLogger = ((BaseUnityPlugin)this).Logger;
			try
			{
				Harmony val = new Harmony("AccessibleTerminal");
				val.PatchAll(Assembly.GetExecutingAssembly());
				StaticLogger.LogInfo((object)"AccessibleTerminal loaded!");
			}
			catch (Exception arg)
			{
				StaticLogger.LogError((object)string.Format("Error while initializing {0}: {1}", "AccessibleTerminal", arg));
			}
		}
	}
	internal class TerminalGUI : MonoBehaviour
	{
		internal static TerminalGUI Instance;

		internal Terminal terminal;

		internal bool terminalReady = false;

		private int currentPage = 1;

		private int pages;

		private int col;

		private int row;

		private int limit;

		private float menuX;

		private float menuY;

		private float menuWidth;

		private float menuHeight;

		private float buttonX;

		private float buttonY;

		private float buttonWidth;

		private float buttonHeight;

		private float betweenSpaceX;

		private float betweenSpaceY;

		private GUIStyle boxStyle;

		private GUIStyle buttonStyle;

		private GUIStyle textFieldStyle;

		private bool stylesInitialized = false;

		private readonly Stack<string> undo = new Stack<string>();

		private List<string> buttonList = new List<string>();

		private bool buttonPressed = false;

		private int buttonCount = 0;

		private List<string> actions;

		private List<string> items;

		private List<string> moons;

		private List<string> enemies;

		private List<string> players;

		private List<string> decor;

		private List<string> upgrades;

		private List<string> numbers;

		private List<string> codes;

		private List<string> boosters;

		private List<string> logs;

		private readonly List<string> mainMenu = new List<string>(11)
		{
			"Actions", "Items", "Moons", "Enemies", "Players", "Decor", "Upgrades", "Story Logs", "Codes", "Boosters",
			"Numbers"
		};

		private bool isOnMainMenu = true;

		private readonly string[] unused = new string[3] { "confirm", "deny", "reset credits" };

		private void Awake()
		{
			if (!((Object)(object)Instance != (Object)null))
			{
				Instance = this;
				terminal = Object.FindObjectOfType<Terminal>();
			}
		}

		private void Start()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			col = 8;
			row = 2;
			limit = col * row;
			menuWidth = 1200f;
			menuHeight = 600f;
			Resolution currentResolution = Screen.currentResolution;
			menuX = ((float)((Resolution)(ref currentResolution)).width - menuWidth) * 0.5f;
			currentResolution = Screen.currentResolution;
			menuY = (float)((Resolution)(ref currentResolution)).height - menuHeight;
			betweenSpaceX = 4f;
			betweenSpaceY = 8f;
			buttonWidth = menuWidth / (float)col - betweenSpaceX;
			buttonHeight = menuHeight / (float)(row * 2);
			buttonX = menuX + betweenSpaceX * 0.5f;
			buttonY = menuY + menuHeight / menuWidth * 100f;
			List<TerminalKeyword> source = new List<TerminalKeyword>(terminal.terminalNodes.allKeywords);
			actions = source.Where((TerminalKeyword action) => (action.isVerb || Object.op_Implicit((Object)(object)action.specialKeywordResult)) && !unused.Contains(action.word)).Select(delegate(TerminalKeyword action)
			{
				string text = action.word.ToUpper()[0].ToString();
				string word = action.word;
				return text + word.Substring(1, word.Length - 1);
			}).ToList();
			actions.Add("Transmit");
			items = terminal.buyableItemsList.Select((Item item) => ((Object)item).name).ToList();
			moons = (from moon in terminal.moonsCatalogueList
				select moon.PlanetName.Trim() into name
				select Regex.Match(name, "(?!\\d*\\s).*").Value).ToList();
			enemies = (from enemy in terminal.enemyFiles
				select enemy.creatureName.Trim() into name
				select Regex.Match(name, "^.*([^s]$|(?=s$))").Value).ToList();
			players = StartOfRound.Instance.allPlayerScripts.Select((PlayerControllerB player) => player.playerUsername).ToList();
			List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables;
			decor = (from decor in unlockables
				where Object.op_Implicit((Object)(object)decor.shopSelectionNode) && !decor.alwaysInStock
				select decor.unlockableName).ToList();
			upgrades = (from upgrade in unlockables
				where upgrade.IsPlaceable && upgrade.alwaysInStock
				select upgrade.unlockableName).ToList();
			logs = terminal.logEntryFiles.Select((TerminalNode node) => node.creatureName).ToList();
			codes = (from code in source
				where code.accessTerminalObjects
				select code.word).ToList();
			string[] randomNames = StartOfRound.Instance.randomNames;
			List<string> list = new List<string>(randomNames.Length);
			string[] array = randomNames;
			foreach (string item2 in array)
			{
				list.Add(item2);
			}
			boosters = list;
			numbers = (from num in Enumerable.Range(0, 48)
				select num.ToString()).ToList();
		}

		private void OnGUI()
		{
			//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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			InitStyles();
			if ((Object)(object)terminal == (Object)null)
			{
				terminal = Object.FindObjectOfType<Terminal>();
			}
			if (buttonList.Count != buttonCount)
			{
				pages = Mathf.CeilToInt((float)buttonList.Count / (float)limit);
				buttonCount = buttonList.Count;
			}
			string text = $"Page {currentPage} of {pages}.";
			GUI.backgroundColor = Color32.op_Implicit(new Color32((byte)0, (byte)0, (byte)15, (byte)130));
			GUI.Box(new Rect(menuX, menuY, menuWidth, menuHeight), text, boxStyle);
			float x = buttonX;
			Resolution currentResolution = Screen.currentResolution;
			CreateButton(x, (float)((Resolution)(ref currentResolution)).height - menuHeight * 0.125f + 1f, menuWidth * 0.5f - betweenSpaceX, menuHeight * 0.125f, "Submit command", buttonStyle, delegate
			{
				if (IsActualConfirmationNode())
				{
					SetTerminalInput("CONFIRM");
				}
				if (GetTerminalInput().Length > 0)
				{
					terminal.OnSubmit();
				}
				undo.Clear();
			});
			float x2 = buttonX + menuWidth * 0.5f;
			currentResolution = Screen.currentResolution;
			CreateButton(x2, (float)((Resolution)(ref currentResolution)).height - menuHeight * 0.125f + 1f, menuWidth * 0.5f - betweenSpaceX, menuHeight * 0.125f, "Back / delete word", buttonStyle, delegate
			{
				if (!isOnMainMenu)
				{
					ToMainMenu();
				}
				else if (IsActualConfirmationNode())
				{
					SetTerminalInput("DENY");
					terminal.OnSubmit();
				}
				else if (undo.Count > 0)
				{
					SetTerminalInput(undo.Pop());
				}
				else
				{
					terminal.QuitTerminal();
				}
			});
			float x3 = buttonX;
			currentResolution = Screen.currentResolution;
			CreateButton(x3, (float)((Resolution)(ref currentResolution)).height - menuHeight * 0.25f - betweenSpaceY + 1f, menuWidth * 0.5f - betweenSpaceX, menuHeight * 0.125f, "◀ Previous Page", buttonStyle, delegate
			{
				if (currentPage > 1)
				{
					currentPage--;
				}
			});
			float x4 = buttonX + menuWidth * 0.5f;
			currentResolution = Screen.currentResolution;
			CreateButton(x4, (float)((Resolution)(ref currentResolution)).height - menuHeight * 0.25f - betweenSpaceY + 1f, menuWidth * 0.5f - betweenSpaceX, menuHeight * 0.125f, "Next Page ▶", buttonStyle, delegate
			{
				if (currentPage < pages)
				{
					currentPage++;
				}
			});
			CreateButton(buttonX - betweenSpaceX - menuHeight * 0.0625f, menuY, menuHeight * 0.0625f, menuHeight * 0.5f - betweenSpaceY * 0.25f, "▲", buttonStyle, delegate
			{
				Scrollbar scrollBarVertical2 = terminal.scrollBarVertical;
				scrollBarVertical2.value = Mathf.Clamp01(scrollBarVertical2.value + 0.5f);
			});
			CreateButton(buttonX - betweenSpaceX - menuHeight * 0.0625f, menuY + betweenSpaceY * 0.25f + menuHeight * 0.5f + 1f, menuHeight * 0.0625f, menuHeight * 0.5f - betweenSpaceY * 0.25f, "▼", buttonStyle, delegate
			{
				Scrollbar scrollBarVertical = terminal.scrollBarVertical;
				scrollBarVertical.value = Mathf.Clamp01(scrollBarVertical.value - 0.5f);
			});
			if (buttonList.Count == 0)
			{
				return;
			}
			int num = limit * (currentPage - 1);
			int num2 = num + ((currentPage == pages) ? ((buttonList.Count - 1) % limit) : (limit - 1));
			int i;
			for (i = num; i <= num2; i++)
			{
				if (buttonPressed)
				{
					break;
				}
				CreateButton(buttonX + (buttonWidth + betweenSpaceX) * (float)(i % limit % col), buttonY + (buttonHeight + betweenSpaceY) * (float)Mathf.FloorToInt((float)(i % limit / col)), buttonWidth, buttonHeight, buttonList[i], buttonStyle, delegate
				{
					if (isOnMainMenu)
					{
						switch (i)
						{
						case 0:
							ChangeMenu(actions);
							break;
						case 1:
							ChangeMenu(items);
							break;
						case 2:
							ChangeMenu(moons);
							break;
						case 3:
							ChangeMenu(enemies);
							break;
						case 4:
							ChangeMenu(players);
							break;
						case 5:
							ChangeMenu(decor);
							break;
						case 6:
							ChangeMenu(upgrades);
							break;
						case 7:
							ChangeMenu(logs);
							break;
						case 8:
							ChangeMenu(codes);
							break;
						case 9:
							ChangeMenu(boosters);
							break;
						case 10:
							ChangeMenu(numbers);
							break;
						}
					}
					else
					{
						string terminalInput = GetTerminalInput();
						string text2 = buttonList[i];
						if (terminalInput.Length > 0)
						{
							text2 = " " + text2;
							undo.Push(terminalInput);
						}
						else
						{
							undo.Push("");
						}
						SetTerminalInput(terminalInput + text2);
						ToMainMenu();
					}
				});
			}
			buttonPressed = false;
		}

		private void InitStyles()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			if (!stylesInitialized)
			{
				stylesInitialized = true;
				Color[] array = (Color[])(object)new Color[4];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = Color.white;
				}
				Texture2D val = new Texture2D(2, 2);
				val.SetPixels(array);
				val.Apply();
				boxStyle = new GUIStyle(GUI.skin.box);
				boxStyle.normal.textColor = Color32.op_Implicit(new Color32((byte)30, byte.MaxValue, (byte)0, byte.MaxValue));
				boxStyle.normal.background = val;
				((Object)boxStyle.normal.background).hideFlags = (HideFlags)61;
				boxStyle.fontSize = 12;
				boxStyle.fontStyle = (FontStyle)0;
				boxStyle.alignment = (TextAnchor)1;
				buttonStyle = new GUIStyle(GUI.skin.button);
				buttonStyle.normal.textColor = Color32.op_Implicit(new Color32((byte)20, (byte)142, (byte)0, byte.MaxValue));
				buttonStyle.normal.background = val;
				((Object)buttonStyle.normal.background).hideFlags = (HideFlags)61;
				buttonStyle.hover.textColor = Color32.op_Implicit(new Color32((byte)36, byte.MaxValue, (byte)0, byte.MaxValue));
				buttonStyle.hover.background = val;
				((Object)buttonStyle.hover.background).hideFlags = (HideFlags)61;
				buttonStyle.fontSize = 18;
				buttonStyle.fontStyle = (FontStyle)1;
				buttonStyle.wordWrap = true;
				textFieldStyle = new GUIStyle(GUI.skin.button);
				textFieldStyle.normal.textColor = Color32.op_Implicit(new Color32((byte)20, (byte)142, (byte)0, byte.MaxValue));
				textFieldStyle.normal.background = val;
				((Object)textFieldStyle.normal.background).hideFlags = (HideFlags)61;
				textFieldStyle.fontSize = 9;
				textFieldStyle.fontStyle = (FontStyle)1;
			}
		}

		private void CreateButton(float x, float y, float width, float height, string text, GUIStyle style, Action action)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (GUI.Button(new Rect(x, y, width, height), text, style))
			{
				action();
				buttonPressed = true;
			}
		}

		internal void RefreshPlayers()
		{
			players = StartOfRound.Instance.allPlayerScripts.Select((PlayerControllerB player) => player.playerUsername).ToList();
		}

		public void ToggleVisibility()
		{
			((Behaviour)this).enabled = !((Behaviour)this).enabled;
		}

		public void ChangeMenu(List<string> buttonList)
		{
			this.buttonList = buttonList;
			isOnMainMenu = false;
		}

		public void ToMainMenu()
		{
			buttonList = mainMenu;
			isOnMainMenu = true;
			currentPage = 1;
		}

		public string GetTerminalInput()
		{
			string currentText = terminal.currentText;
			int textAdded = terminal.textAdded;
			int length = currentText.Length;
			int num = length - textAdded;
			return currentText.Substring(num, length - num);
		}

		public void SetTerminalInput(string newText)
		{
			if (!terminalReady)
			{
				terminal.TextChanged("");
				terminal.textAdded = 0;
				undo.Clear();
				undo.Push("");
			}
			Terminal obj = terminal;
			string currentText = terminal.currentText;
			int textAdded = terminal.textAdded;
			obj.TextChanged(currentText.Substring(0, currentText.Length - textAdded) + newText);
			terminal.screenText.text = terminal.currentText;
			terminal.textAdded = newText.Length;
		}

		public bool IsActualConfirmationNode()
		{
			return terminal.currentText.Contains("Please CONFIRM or DENY.") && !terminal.currentText.Contains("Cancelled order.");
		}
	}
}
namespace AccessibleTerminal.Patches
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatches
	{
		[HarmonyPatch("OnClientConnect", new Type[] { typeof(ulong) })]
		[HarmonyPostfix]
		private static void OnPlayerJoin(ulong clientId)
		{
			TerminalGUI.Instance?.RefreshPlayers();
		}

		[HarmonyPatch("OnPlayerDC", new Type[]
		{
			typeof(int),
			typeof(ulong)
		})]
		[HarmonyPostfix]
		private static void OnPlayerLeave(int playerObjectNumber, ulong clientId)
		{
			TerminalGUI.Instance?.RefreshPlayers();
		}
	}
	[HarmonyPatch]
	internal static class TerminalPatches
	{
		private static CursorLockMode prevLock;

		private static bool wasVisible;

		[HarmonyPatch(typeof(Terminal), "Awake")]
		[HarmonyPostfix]
		private static void OnInitTerminal()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("TerminalGUI");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)61;
			TerminalGUI terminalGUI = val.AddComponent<TerminalGUI>();
			((Behaviour)terminalGUI).enabled = false;
		}

		[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
		[HarmonyPostfix]
		private static void OnOpenTerminal()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			TerminalGUI.Instance.ToMainMenu();
			TerminalGUI.Instance.ToggleVisibility();
			prevLock = Cursor.lockState;
			wasVisible = Cursor.visible;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			if ((Object)(object)StartOfRound.Instance.localPlayerController != (Object)null)
			{
				StartOfRound.Instance.localPlayerController.disableLookInput = true;
			}
		}

		[HarmonyPatch(typeof(Terminal), "QuitTerminal")]
		[HarmonyPrefix]
		private static void OnCloseTerminal()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			TerminalGUI.Instance.ToggleVisibility();
			Cursor.lockState = prevLock;
			Cursor.visible = wasVisible;
			if ((Object)(object)StartOfRound.Instance.localPlayerController != (Object)null)
			{
				StartOfRound.Instance.localPlayerController.disableLookInput = false;
			}
		}

		[HarmonyPatch(typeof(Terminal), "TextChanged", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		private static void OnTextChanged(string newText, bool ___modifyingText)
		{
			TerminalGUI.Instance.terminalReady = !___modifyingText;
		}

		[HarmonyPatch(typeof(KillLocalPlayer), "KillPlayer", new Type[] { typeof(PlayerControllerB) })]
		[HarmonyPostfix]
		private static void OnPlayerDeath(PlayerControllerB playerWhoTriggered)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)playerWhoTriggered == (Object)null) && ((NetworkBehaviour)playerWhoTriggered).IsLocalPlayer)
			{
				Cursor.lockState = prevLock;
				Cursor.visible = wasVisible;
				playerWhoTriggered.disableLookInput = false;
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPostfix]
		private static void OnDisconnect()
		{
			if ((Object)(object)TerminalGUI.Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)TerminalGUI.Instance).gameObject);
				TerminalGUI.Instance = null;
			}
		}
	}
}