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 OpenLib v0.4.3
plugins/OpenLib.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using Dawn.Utils; using GameNetcodeStuff; using HarmonyLib; using InteractiveTerminalAPI.UI; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using ModelReplacement; using OpenBodyCams; using OpenBodyCams.API; using OpenLib.Common; using OpenLib.Compat; using OpenLib.ConfigManager; using OpenLib.CoreMethods; using OpenLib.Events; using OpenLib.InteractiveMenus; using OpenLib.Menus; using TMPro; using TerminalStuff; using TerminalStuff.EventSub; using TerminalStuff.SpecialStuff; using TwoRadarMaps; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering.HighDefinition; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("darmuhsTerminalStuff")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("darmuh")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.4.3")] [assembly: AssemblyInformationalVersion("0.4.3+d53fc94fd108f72cca6259e3e75920016687397c")] [assembly: AssemblyProduct("OpenLib")] [assembly: AssemblyTitle("OpenLib")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.3.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.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; } } [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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace OpenLib { public class Loggers { public enum LoggingLevel { WarningsPlus = 4, Message = 8, Info = 0x10, Debug = 0x20 } private static void Log(LogLevel bepLevel, object data) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) int value = (int)ConfigSetup.LogLevel.Value; int num = (int)bepLevel; if (num <= value) { Plugin.Log.Log(bepLevel, data); } } internal static void LogDebug(object data) { Log((LogLevel)32, data); } internal static void LogInfo(object data) { Log((LogLevel)16, data); } internal static void LogMessage(object data) { Log((LogLevel)8, data); } internal static void WARNING(object data) { Log((LogLevel)4, data); } internal static void ERROR(object data) { Log((LogLevel)2, data); } internal static void FATAL(object data) { Log((LogLevel)1, data); } } public class PageBuilder { public StringBuilder? Content { get; set; } public int PageNumber { get; set; } } public class PageSplitter { public static List<PageBuilder> SplitTextIntoPages(string inputText, int maxLinesPerPage, string nextPageBlurb) { string[] array = inputText.Split(new string[1] { Environment.NewLine }, StringSplitOptions.None); List<PageBuilder> list = new List<PageBuilder>(); int i = 0; int num = 1; while (i < array.Length) { PageBuilder pageBuilder = new PageBuilder { Content = new StringBuilder(), PageNumber = num }; for (; i < array.Length && string.IsNullOrWhiteSpace(array[i]); i++) { } for (int j = 0; j < maxLinesPerPage; j++) { if (i >= array.Length) { break; } pageBuilder.Content.AppendLine(array[i]); i++; } if (i < array.Length - 2) { pageBuilder.Content.AppendLine(nextPageBlurb ?? ""); } else { pageBuilder.Content.AppendLine("\r\n"); } list.Add(pageBuilder); num++; } return list; } } [HarmonyPatch(typeof(GameNetworkManager), "Start")] public class GameStartPatch { public static void Postfix() { EventManager.GameNetworkManagerStart.Invoke(); NetworkClassBase.RegisterNetworkPrefabs(); } } [HarmonyPatch(typeof(StartOfRound), "Awake")] public class StartRoundAwake { public static void Postfix() { EventManager.StartOfRoundAwake.Invoke(); NetworkClassBase.SpawnNetworkPrefab(); } } [HarmonyPatch(typeof(StartOfRound), "Start")] public class StartRoundPatch { public static void Postfix() { EventManager.StartOfRoundStart.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "StartGame")] public class LandingPatch { public static void Postfix() { EventManager.StartOfRoundStartGame.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "ResetShip")] public class ShipResetPatch { public static void Postfix() { EventManager.ShipReset.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "PassTimeToNextDay")] public class NextDayPatch { public static void Postfix() { EventManager.NextDayEvent.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")] public class OnShipLandedMiscPatch { public static void Postfix() { EventManager.OnShipLandedMiscPatch.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "ShipHasLeft")] public class ShipLeftPatch { public static void Postfix() { EventManager.ShipLeft.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "OnClientConnect")] public class OnClientConnectPatch { public static void Postfix() { EventManager.OnClientConnect.Invoke(); } } [HarmonyPatch(typeof(StartOfRound), "ChangeLevel")] public class RouteEvent { public static void Postfix() { EventManager.StartOfRoundChangeLevel.Invoke(); } } [HarmonyPatch(typeof(RoundManager), "SetBigDoorCodes")] public class SetBigDoorCodes { public static void Postfix() { EventManager.SetBigDoorCodes.Invoke(); } } [HarmonyPatch(typeof(RoundManager), "SpawnMapObjects")] public class SpawnMapObjects { public static void Postfix() { EventManager.SpawnMapObjects.Invoke(); } } [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] public class NewQuotaPatch { public static void Postfix() { EventManager.NewQuota.Invoke(); } } [HarmonyPatch(typeof(AutoParentToShip), "Awake")] public class AutoParentGameObjectPatch { public static void Postfix(AutoParentToShip __instance) { if (!((Object)(object)((Component)__instance).gameObject == (Object)null)) { EventManager.AutoParentEvent.Invoke(((Component)__instance).gameObject); } } } [HarmonyPatch(typeof(NetworkObject), "Spawn")] public class ObjectSpawnPatch { public static void Postfix(NetworkObject __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).gameObject == (Object)null)) { EventManager.NetworkObjectSpawn.Invoke(((Component)__instance).gameObject); } } } [HarmonyPatch(typeof(PlayerControllerB), "StartPerformingEmoteServerRpc")] public class EmotePatch { public static void Postfix() { EventManager.PlayerEmote.Invoke(); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] public class PlayerUpdatePatch { public static bool usePatch; public static bool inShip; public static bool spectate_inShip; public static bool isDead; public static void Postfix(PlayerControllerB __instance) { if (usePatch && !((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) && !((Object)(object)StartOfRound.Instance.localPlayerController != (Object)(object)__instance)) { if (__instance.isInHangarShipRoom != inShip) { inShip = __instance.isInHangarShipRoom; EventManager.PlayerIsInShip.Invoke(); } if (__instance.isPlayerDead != isDead) { isDead = __instance.isPlayerDead; EventManager.PlayerIsDead.Invoke(); } if (__instance.isPlayerDead && (Object)(object)__instance.spectatedPlayerScript != (Object)null && __instance.spectatedPlayerScript.isInHangarShipRoom != spectate_inShip) { spectate_inShip = __instance.spectatedPlayerScript.isInHangarShipRoom; EventManager.SpecatingPlayerIsInShip.Invoke(); } } } } public class SpectateNextPatch { [HarmonyPatch(typeof(PlayerControllerB), "SpectateNextPlayer")] public class PlayerSpawnPatch : MonoBehaviour { private static void Postfix() { EventManager.SpecateNextPlayer.Invoke(); } } } public class SpawnPatch { [HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")] public class PlayerSpawnPatch { private static void Postfix() { EventManager.PlayerSpawn.Invoke(); } } } [HarmonyPatch(typeof(ShipTeleporter), "Awake")] public class TeleporterInit { private static void Postfix(ShipTeleporter __instance) { EventManager.TeleporterAwake.Invoke(__instance); } } [HarmonyPatch(typeof(Terminal), "Awake")] public class AwakeTermPatch { private static void Postfix(Terminal __instance) { EventManager.TerminalAwake.Invoke(__instance); } } [HarmonyPatch(typeof(Terminal), "Start")] public class TerminalStartPatch { private static void Postfix() { EventManager.TerminalStart.Invoke(); } } [HarmonyPatch(typeof(Terminal), "OnDisable")] public class DisableTermPatch { private static void Postfix() { EventManager.TerminalDisable.Invoke(); } } [HarmonyPatch(typeof(Terminal), "QuitTerminal")] public class QuitTerminalPatch { private static void Postfix() { EventManager.TerminalQuit.Invoke(); } } [HarmonyPatch(typeof(Terminal), "LoadNewNode")] public class LoadNewNodePatch { private static void Postfix(TerminalNode node) { EventManager.TerminalLoadNewNode.Invoke(node); string text = (((Object)(object)node != (Object)null) ? ((Object)node).name : "Null Node"); Loggers.LogDebug("LoadNewNode - " + text); } } [HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")] public class AffordableNodePatch { private static void Postfix(TerminalNode node) { EventManager.TerminalLoadIfAffordable.Invoke(node); } } [HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")] public class Terminal_Begin_Patch { private static void Postfix() { EventManager.TerminalBeginUsing.Invoke(); } } [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] public class Terminal_ParsePlayerSentence_Patch { private static void Postfix(ref TerminalNode __result) { if (!((Object)(object)__result == (Object)null)) { TerminalNode val = EventManager.TerminalParseSent.NodeInvoke(ref __result); __result = val; } } } [HarmonyPatch(typeof(Terminal), "Update")] public class TerminalUpdatePatch { public static bool inUse; public static bool usePatch; public static int menuIndex; private static void Postfix(Terminal __instance) { if (usePatch && __instance.placeableObject.inUse != inUse) { inUse = __instance.placeableObject.inUse; EventManager.SetTerminalInUse.Invoke(); } } [HarmonyPrefix] private static bool Prefix(Terminal __instance) { if (!usePatch || !__instance.terminalInUse) { return true; } if (MenusContainer.AnyOpenLibMenuActive()) { __instance.scrollBarCanvasGroup.alpha = 0f; ((TMP_Text)__instance.topRightText).text = $"${__instance.groupCredits}"; if (__instance.placeableObject.inUse != inUse) { inUse = __instance.placeableObject.inUse; EventManager.SetTerminalInUse.Invoke(); } if (((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame) { EventManager.TerminalMenuKeyPressed.Invoke(); } return false; } if (((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame) { EventManager.TerminalKeyPressed.Invoke(); } return true; } } [BepInPlugin("darmuh.OpenLib", "OpenLib", "0.4.3")] public class Plugin : BaseUnityPlugin { public static Plugin instance = null; internal static ManualLogSource Log = null; public bool TerminalStuff; public bool LobbyCompat; public bool TerminalFormatter; public bool ITAPI; public bool LethalConfig; public bool OpenBodyCamsMod; public bool TwoRadarMapsMod; public bool ModelReplacement; public bool TooManyEmotes; public bool MirrorDecor; public static List<CommandManager> AllCommands = new List<CommandManager>(); public static List<TerminalKeyword> KeywordsAdded = new List<TerminalKeyword>(); public static List<TerminalNode> NodesAdded = new List<TerminalNode>(); public static List<CompatibleNoun> NounsAdded = new List<CompatibleNoun>(); public static List<TerminalAccessibleObject> AllTerminalCodes = new List<TerminalAccessibleObject>(); public Terminal Terminal; public static List<TerminalNode> ShopNodes = new List<TerminalNode>(); public const string Id = "darmuh.OpenLib"; public bool DawnLibPresent => Chainloader.PluginInfos.ContainsKey("com.github.teamxiaolan.dawnlib"); public static string Name => "OpenLib"; public static string Version => "0.4.3"; public static List<CommandManager> GetActiveCommands() { if (AllCommands.Count == 0) { return new List<CommandManager>(); } return AllCommands.FindAll((CommandManager x) => x.IsCreated); } private void Awake() { instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"OpenLib is loading with version 0.4.3!\nThis mod has been compiled for v80 of Lethal Company and may not work with earlier versions!"); ConfigSetup.defaultManaged = new List<ManagedConfig>(); CommandRegistry.InitListing(ref ConfigSetup.defaultListing); ConfigSetup.BindConfigSettings(); ((BaseUnityPlugin)this).Config.ConfigReloaded += OnConfigReloaded; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); EventUsage.Subscribers(); AllInteractiveMenus.AllMenus = new List<InteractiveMenu>(); string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "openlib.bundle"); if (File.Exists(text)) { AssetBundle val = AssetBundle.LoadFromFile(text); NetworkClassBase.Prefab = val.LoadAsset<GameObject>("Openlib Networker"); } else { Log.LogError((object)("Openlib Networker asset cannot be found! Expected path: " + text)); } Log.LogInfo((object)"OpenLib load complete!"); } internal void OnConfigReloaded(object sender, EventArgs e) { Log.LogInfo((object)"Config has been reloaded!"); ConfigSetup.ReadConfigAndAssignValues(((BaseUnityPlugin)instance).Config, ConfigSetup.defaultManaged); } } public class NodeInfo { [CompilerGenerated] private CommandManager <command>P; public string Name; public string InfoText; public Func<string> InfoAction; public TerminalNode terminalNode; public NodeInfo(CommandManager command) { <command>P = command; Name = <command>P.Name; InfoText = string.Empty; base..ctor(); } public void GetDefaultInfo(CommandManager command) { string text = "[ " + CommonStringStuff.GetKeywordsForMenuItem(command.KeywordList) + " ]\r\n"; text = ((command.IsEnabled == null) ? (text + "No further information on this command!\r\n\r\n") : (text + ((ConfigEntryBase)command.IsEnabled.ConfigItem).Description.Description + "\r\n\r\n")); InfoText = text; } public void CreateInfoNode() { if (!((Object)(object)CommonTerminal.InfoKeyword == (Object)null)) { TerminalKeyword info = CommonTerminal.InfoKeyword; terminalNode = BasicTerminal.CreateNewTerminalNode(); ((Object)terminalNode).name = "info_" + Name; terminalNode.displayText = InfoText; terminalNode.clearPreviousText = true; CollectionExtensions.Do<string>((IEnumerable<string>)<command>P.KeywordList, (Action<string>)delegate(string Keyword) { AddingThings.AddCompatibleNoun(ref info, Keyword, terminalNode); }); Loggers.LogDebug("info node created and assigned to command!"); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "OpenLib"; public const string PLUGIN_NAME = "OpenLib"; public const string PLUGIN_VERSION = "0.4.3"; } } namespace OpenLib.Menus { public class CommandsMenu { internal static CommandsMenuBase CommandMenu = null; internal static CommandMenuItem<CommandsMenuBase> MainMenuItem = null; internal static List<CommandMenuItem<CommandsMenuBase>> AllCommandMenuItems = new List<CommandMenuItem<CommandsMenuBase>>(); internal static void Init() { CommandMenu = new CommandsMenuBase("Commands Menu") { MainMenu = MainMenuItem, PageSize = 10, AdjustScrollInMenu = false }; MainMenuItem = CreateMainMenu(CommandMenu, "My Commands Menu", () => "=== My Commands Main Menu ===\n\n", () => "Created by darmuh"); } internal static void RuntimeSetup() { List<CommandManager> activeCommands = Plugin.GetActiveCommands(); UpdateMenuListing(CommandMenu, MainMenuItem, activeCommands); CreateAndSetControlsFooter(CommandMenu, AllCommandMenuItems); } public static void UpdateMenuListing(CommandsMenuBase menuBase, CommandMenuItem<CommandsMenuBase> mainMenuItem, List<CommandManager> CommandList, string defaultCategory = "Other") { if (mainMenuItem.NestedMenus.Count == 0) { MakeCommandMenuItems(menuBase, CommandList, defaultCategory, mainMenuItem); return; } List<CommandMenuItem<CommandsMenuBase>> list = mainMenuItem.NestedMenus.ConvertAll((MenuItem x) => x as CommandMenuItem<CommandsMenuBase>); foreach (CommandMenuItem<CommandsMenuBase> item in list) { item.isEnabled = CommandList.Contains(item.Command); CommandList.Remove(item.Command); UpdateMenuVisibility(item); } if (CommandList.Count > 0) { MakeCommandMenuItems(menuBase, CommandList, defaultCategory, mainMenuItem); } } private static void UpdateMenuVisibility(CommandMenuItem<CommandsMenuBase> item) { if (item.isEnabled) { if (item.Parent == null) { if (item.CachedParent == null) { Loggers.WARNING("Unable to update " + item.Name + "'s parent. CachedParent is null!"); } else { item.SetParentMenu(item.CachedParent); } } } else if (item.Parent != null) { item.CachedParent = item.Parent; item.SetParentMenu(null); } } internal static string EnterCommandMenu() { if (MainMenuItem == null) { return "This menu has not been created correctly"; } CommandMenu.EnterAtPage(MainMenuItem); return ""; } public static CommandMenuItem<CommandsMenuBase> CreateMainMenu(CommandsMenuBase menuBase, string menuName, Func<string> header = null, Func<string> footer = null) { if (header == null) { header = () => string.Empty; } if (footer == null) { footer = () => string.Empty; } CommandMenuItem<CommandsMenuBase> commandMenuItem = new CommandMenuItem<CommandsMenuBase>(menuBase, menuName) { Header = header, Footer = footer }; AllCommandMenuItems.Add(commandMenuItem); return commandMenuItem; } public static List<CommandMenuItem<CommandsMenuBase>> MakeCommandMenuItems(CommandsMenuBase menuBase, List<CommandManager> commands, string DefaultCategory, CommandMenuItem<CommandsMenuBase> MainMenu) { CommandsMenuBase menuBase2 = menuBase; List<CommandMenuItem<CommandsMenuBase>> commandMenuItems = new List<CommandMenuItem<CommandsMenuBase>>(); Dictionary<CommandManager, string> dictionary = new Dictionary<CommandManager, string>(); if (commands.Count < 1) { return commandMenuItems; } foreach (CommandManager command in commands) { if (string.IsNullOrEmpty(command.Category)) { dictionary.Add(command, DefaultCategory); } else { dictionary.Add(command, command.Category); } } foreach (KeyValuePair<CommandManager, string> category in dictionary) { MenuItem menuItem = MainMenu.NestedMenus.FirstOrDefault((MenuItem c) => Misc.CompareStringsInvariant(c.Name, category.Value)); CommandMenuItem<CommandsMenuBase> cat = menuItem as CommandMenuItem<CommandsMenuBase>; if (cat == null) { cat = new CommandMenuItem<CommandsMenuBase>(menuBase2, category.Value.ToUpperInvariant()); commandMenuItems.Add(cat); cat.SetParentMenu(MainMenu); cat.Header = () => CommandsMenuBase.ConvertHeader(menuBase2.CategoryHeader, cat.Name); } CreateCommandMenuItems(menuBase2, cat, category.Key, ref commandMenuItems); } foreach (CommandMenuItem<CommandsMenuBase> item in commandMenuItems) { if (item.Command == null && item.Parent == null) { item.SetParentMenu(MainMenu); } } AllCommandMenuItems.AddRange(commandMenuItems); return commandMenuItems; } public static void CreateAndSetControlsFooter(CommandsMenuBase menuBase, List<CommandMenuItem<CommandsMenuBase>> MenuItems) { SetMenuItemsFooter(MenuItems, menuBase.Controls); } public static void SetMenuItemsFooter(List<CommandMenuItem<CommandsMenuBase>> MenuItems, Func<string> footer) { foreach (CommandMenuItem<CommandsMenuBase> MenuItem in MenuItems) { MenuItem.Footer = footer; } } public static void CreateCommandMenuItems(CommandsMenuBase menuBase, CommandMenuItem<CommandsMenuBase> parent, CommandManager command, ref List<CommandMenuItem<CommandsMenuBase>> commandMenuItems) { CommandsMenuBase menuBase2 = menuBase; CommandMenuItem<CommandsMenuBase> parent2 = parent; CommandManager command2 = command; CommandMenuItem<CommandsMenuBase> CommandName = TryCreate(menuBase2, command2); commandMenuItems.Add(CommandName); CommandName.Header = () => CommandsMenuBase.ConvertHeader(menuBase2.CommandHeader, parent2.Name, CommandName.Name); CommandName.SetParentMenu(parent2); if (menuBase2.AddKeywordsMenu) { if (!TryGetChild(CommandName, command2.Name + " Keywords", out CommandMenuItem<CommandsMenuBase> item)) { item = new CommandMenuItem<CommandsMenuBase>(menuBase2, command2.Name + " Keywords"); commandMenuItems.Add(item); item.SetParentMenu(CommandName); } item.Header = () => CommandsMenuBase.ConvertHeader(menuBase2.KeywordsHeader, parent2.Name, CommandName.Name); foreach (string keyword in command2.KeywordList) { if (!TryGetChild(item, keyword, out CommandMenuItem<CommandsMenuBase> item2)) { item2 = new CommandMenuItem<CommandsMenuBase>(menuBase2, keyword); commandMenuItems.Add(item2); item2.SetParentMenu(item); item2.Header = () => CommandsMenuBase.ConvertHeader(menuBase2.KeywordsHeader, parent2.Name, CommandName.Name); } } } if (command2.IsEnabled != null && menuBase2.AddInfoMenu) { if (!TryGetChild(CommandName, command2.Name + " Information", out CommandMenuItem<CommandsMenuBase> item3)) { item3 = new CommandMenuItem<CommandsMenuBase>(menuBase2, command2.Name + " Information"); commandMenuItems.Add(item3); item3.SetParentMenu(CommandName); } item3.Header = () => CommandsMenuBase.ConvertHeader(menuBase2.InfoHeader, parent2.Name, CommandName.Name); if (!TryGetChild(item3, ((ConfigEntryBase)command2.IsEnabled.ConfigItem).Description.Description, out CommandMenuItem<CommandsMenuBase> item4)) { item4 = new CommandMenuItem<CommandsMenuBase>(menuBase2, ((ConfigEntryBase)command2.IsEnabled.ConfigItem).Description.Description); commandMenuItems.Add(item4); item4.SetParentMenu(item3); } item4.Header = () => CommandsMenuBase.ConvertHeader(menuBase2.InfoHeader, parent2.Name, CommandName.Name); } if ((!command2.AcceptAdditionalText || !menuBase2.AddRunCommand) && !TryGetChild(CommandName, "Run " + command2.Name, out CommandMenuItem<CommandsMenuBase> item5)) { item5 = new CommandMenuItem<CommandsMenuBase>(menuBase2, "Run " + command2.Name) { LoadPageOnSelect = false }; commandMenuItems.Add(item5); item5.SetParentMenu(CommandName); OpenLib.Events.Events.CustomEvent customEvent = new OpenLib.Events.Events.CustomEvent(); customEvent.AddListener(delegate { menuBase2.ExitPage = command2; menuBase2.ExitMenu(enableInput: true); }); item5.SelectionEvent = customEvent; } } public static CommandMenuItem<CommandsMenuBase> TryCreate(CommandsMenuBase menuBase, CommandManager command) { CommandManager command2 = command; CommandMenuItem<CommandsMenuBase> commandMenuItem = AllCommandMenuItems.FirstOrDefault((CommandMenuItem<CommandsMenuBase> c) => c.Command == command2); if (commandMenuItem != null) { return commandMenuItem; } return new CommandMenuItem<CommandsMenuBase>(menuBase, command2.Name) { Command = command2 }; } public static bool TryGetChild(CommandMenuItem<CommandsMenuBase> Parent, string expectedName, out CommandMenuItem<CommandsMenuBase> item) { CommandMenuItem<CommandsMenuBase> Parent2 = Parent; string expectedName2 = expectedName; item = AllCommandMenuItems.FirstOrDefault((CommandMenuItem<CommandsMenuBase> c) => c.Parent == Parent2 && c.Name == expectedName2); return item != null; } public static bool TryGetCategoryMenuItem(string categoryName, out CommandMenuItem<CommandsMenuBase> match) { string categoryName2 = categoryName; List<CommandMenuItem<CommandsMenuBase>> source = AllCommandMenuItems.FindAll((CommandMenuItem<CommandsMenuBase> x) => x.Parent == MainMenuItem && x.Command == null); match = source.FirstOrDefault((CommandMenuItem<CommandsMenuBase> x) => x.Name == categoryName2); return match != null; } public static void SetCategoryHeader(string categoryName, Func<string> header) { if (TryGetCategoryMenuItem(categoryName, out CommandMenuItem<CommandsMenuBase> match)) { match.Header = header; } } public static void SetCategoryFooter(string categoryName, Func<string> footer) { if (TryGetCategoryMenuItem(categoryName, out CommandMenuItem<CommandsMenuBase> match)) { match.Footer = footer; } } } public class CommandsMenuBase : BetterMenu<CommandsMenuBase> { public bool AddKeywordsMenu = true; public bool AddInfoMenu = true; public bool AddRunCommand = true; public string CommandHeader = "======== {commandName} ========\n\n"; public string KeywordsHeader = "======== {commandName} Keywords ========\n\n"; public string CategoryHeader = "======== {catName>>} COMMANDS ========\n\n"; public string InfoHeader = "====== {commandName} Information ======\n\n"; public const string CategoryName = "catName"; public const string CommandName = "commandName"; public const string ToUpper = ">>"; public const string ToLower = "<<"; public static readonly List<string> AcceptableVariables = new List<string>(4) { "catName", "commandName", ">>", "<<" }; public CommandManager ExitPage; public CommandsMenuBase(string name, Dictionary<Key, Action> MoreMenuActions = null) : base(name, MoreMenuActions) { ExitAction = CustomExitAction; OnEnter.AddListener(delegate { ExitPage = null; }); } public void CustomExitAction() { if (ExitPage != null) { if (LogicHandling.GetDisplayTextFromCommand(ref ExitPage.terminalNode)) { CommonTerminal.LoadNewNode(ExitPage.terminalNode); } else { CommonTerminal.LoadNewNode(CommonTerminal.HomePage); } } else { CommonTerminal.LoadNewNode(CommonTerminal.HomePage); } } public static string ConvertHeader(string query, string catName, string commandName = "") { if (string.IsNullOrEmpty(query)) { return query; } List<string> substrings = Misc.GetSubstrings('{', '}', query); if (substrings.Count == 0) { return query; } foreach (string item in substrings) { string text = item.Replace("{", "").Replace("}", ""); if (Misc.StringContainsInvariant(item, "catName")) { text = text.Replace("catName", catName); } if (Misc.StringContainsInvariant(item, "commandName")) { text = text.Replace("commandName", commandName); } if (Misc.StringContainsInvariant(item, ">>")) { text = text.Replace(">>", "").ToUpperInvariant(); } if (Misc.StringContainsInvariant(item, "<<")) { text = text.Replace("<<", "").ToLowerInvariant(); } query = query.Replace(item, text); } return query; } public string Controls() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append($"\r\n\r\nPage [{leftMenu}] < {CurrentPage}/{Mathf.CeilToInt((float)DisplayMenuItemsOfType.Count / (float)PageSize)} > [{rightMenu}]\r\n"); stringBuilder.Append($"Back: [{leaveMenu}] Select: [{selectMenu}]\r\n"); return stringBuilder.ToString(); } } public class CommandMenuItem<TMenu> : MenuItem<TMenu> where TMenu : BetterMenuBase { private string _name; private bool _showEmpty; private OpenLib.Events.Events.CustomEvent _selection; private List<MenuItem> _nested; public bool isEnabled; public CommandManager Command; public MenuItem CachedParent; public TMenu MenuBase; public override string Name { get { return _name; } set { _name = value; } } public override bool ShowIfEmptyNest { get { return _showEmpty; } set { _showEmpty = value; } } public override OpenLib.Events.Events.CustomEvent SelectionEvent { get { return _selection; } set { _selection = value; } } public override List<MenuItem> NestedMenus { get { return _nested; } set { _nested = value; } } public CommandMenuItem(TMenu betterMenu, string name) { _name = name; _showEmpty = true; _selection = new OpenLib.Events.Events.CustomEvent(); _nested = new List<MenuItem>(); isEnabled = true; MenuBase = betterMenu; base..ctor(betterMenu); } } [Obsolete("Doing away with this style of Menu...")] public class MenuBuild { public static bool isNextEnabled = false; public static int nextCount = 1; public static string currentCategory = ""; public static TerminalMenu currentMenu = null; public static List<TerminalMenu> allMenus = new List<TerminalMenu>(); public static List<TerminalMenuCategory> InitCategories(Dictionary<string, string> CategoryItems) { Loggers.LogDebug("InitCategories START"); List<TerminalMenuCategory> list = new List<TerminalMenuCategory>(); if (CategoryItems.Count < 1) { return list; } foreach (KeyValuePair<string, string> CategoryItem in CategoryItems) { TerminalMenuCategory item = new TerminalMenuCategory { CatName = CategoryItem.Key, CatDescription = CategoryItem.Value }; list.Add(item); } Loggers.LogDebug("InitCategories SUCCESS"); return list; } public static bool ShouldAddCategoryNameToMainMenu(List<TerminalMenuItem> menuItems, string categoryName) { foreach (TerminalMenuItem menuItem in menuItems) { if (menuItem.Category == categoryName) { return true; } } return false; } public static List<TerminalMenuItem> TerminalMenuItems(List<ManagedConfig> managedBools) { List<TerminalMenuItem> list = new List<TerminalMenuItem>(); managedBools.RemoveAll((ManagedConfig m) => m == null); foreach (ManagedConfig managedBool in managedBools) { if (managedBool.menuItem != null && managedBool.KeywordList != null && managedBool.KeywordList.Count > 0) { list.Add(managedBool.menuItem); } } Loggers.LogDebug("\n\n\n"); Loggers.LogDebug($"myMenuItems count: {list.Count}"); Loggers.LogDebug("\n\n\n"); return list; } public static TerminalMenu AssembleMainMenu(string menuName, string keyword, string mainMenuText, List<TerminalMenuCategory> categoryList, List<TerminalMenuItem> menuItems, bool addToOther = false, string menuDescription = "") { TerminalMenu terminalMenu = new TerminalMenu { MenuName = menuName, setKeyword = keyword, Categories = categoryList, MainMenuText = mainMenuText, menuItems = menuItems, currentCategory = "", nextCount = 1, isNextEnabled = false }; string displayText = AssembleMainMenuText(terminalMenu); if (addToOther) { AddingThings.AddBasicCommand(terminalMenu.MenuName + "_main", terminalMenu.setKeyword, displayText, isVerb: false, clearText: true, "other", menuDescription); } else { AddingThings.AddBasicCommand(terminalMenu.MenuName + "_main", terminalMenu.setKeyword, displayText, isVerb: false, clearText: true); } allMenus.Add(terminalMenu); return terminalMenu; } public static bool InMainMenu(TerminalNode terminalNode, TerminalMenu terminalMenu) { if (terminalMenu == null) { Loggers.ERROR("ERROR: OpenLib menu is NULL, most likely failed to create!"); return false; } if (((Object)terminalNode).name.Contains(terminalMenu.MenuName)) { terminalMenu.isActive = true; terminalMenu.nextCount = 1; terminalMenu.currentCategory = ""; Loggers.LogDebug("In main menu of " + terminalMenu.MenuName); return true; } if (terminalMenu.isNextEnabled && terminalMenu.terminalNodes.Contains(terminalNode)) { Loggers.LogDebug("Still in menus but not main, next is enabled"); return false; } terminalMenu.isActive = false; return false; } public static string AssembleMainMenuText(TerminalMenu terminalMenu) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(terminalMenu.MainMenuText + "\r\n\r\n"); if (terminalMenu.Categories.Count > 0) { foreach (TerminalMenuCategory category in terminalMenu.Categories) { stringBuilder.Append("[" + category.CatName.ToUpper() + "]\r\n" + category.CatDescription + "\r\n\r\n"); } } return stringBuilder.ToString(); } public static string AssembleMainMenuText(string MainMenuText, Dictionary<string, string> Categories) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(MainMenuText + "\r\n\r\n"); if (Categories.Count > 0) { foreach (KeyValuePair<string, string> Category in Categories) { stringBuilder.Append("[" + Category.Key.ToUpper() + "]\r\n" + Category.Value + "\r\n\r\n"); } } return stringBuilder.ToString(); } public static void CreateCategoryCommands(TerminalMenu terminalMenu, MainListing yourModListing) { List<Dictionary<string, List<string>>> list = new List<Dictionary<string, List<string>>>(); foreach (TerminalMenuCategory category in terminalMenu.Categories) { Loggers.LogDebug("checking category in terminalMenu.categories"); Dictionary<string, List<string>> item = MakeCategoryList(category, terminalMenu.menuItems); if (!list.Contains(item)) { list.Add(item); } TerminalNode item2 = AddingThings.CreateNode(terminalMenu, category.CatName ?? "", category.CatName.ToLower(), GetFirstInList, yourModListing); terminalMenu.terminalNodes.Add(item2); } terminalMenu.categoryLists = list; TerminalNode item3 = AddingThings.CreateNode(terminalMenu, "nextInMenu", "next", NextInList, yourModListing, isNextPageCommand: true); terminalMenu.terminalNodes.Add(item3); } public static void CreateCategoryFauxCommands(TerminalMenu terminalMenu, MainListing yourModListing) { CreateCategoryFauxCommands(terminalMenu, yourModListing, "more"); } public static void CreateCategoryFauxCommands(TerminalMenu terminalMenu, MainListing yourModListing, string mainWord) { List<Dictionary<string, List<string>>> list = new List<Dictionary<string, List<string>>>(); foreach (TerminalMenuCategory category in terminalMenu.Categories) { Loggers.LogDebug("checking category in terminalMenu.categories"); Dictionary<string, List<string>> item = MakeCategoryList(category, terminalMenu.menuItems); if (!list.Contains(item)) { list.Add(item); } FauxKeyword fauxWord = new FauxKeyword(mainWord, category.CatName, GetFirstInList) { AllowOtherFauxWords = true, requireExact = true }; AddingThings.AddToFauxListing(fauxWord, yourModListing); } terminalMenu.categoryLists = list; FauxKeyword fauxWord2 = new FauxKeyword(mainWord, "next", NextInList) { AllowOtherFauxWords = true }; AddingThings.AddToFauxListing(fauxWord2, yourModListing); } public static void UpdateCategories(TerminalMenu myMenu) { List<Dictionary<string, List<string>>> list = new List<Dictionary<string, List<string>>>(); foreach (TerminalMenuCategory category in myMenu.Categories) { Loggers.LogDebug("checking category in myMenu.categories"); Dictionary<string, List<string>> item = MakeCategoryList(category, myMenu.menuItems); if (!list.Contains(item)) { list.Add(item); } } myMenu.categoryLists = list; } public static List<string> GetCategoryList(string catName, out TerminalMenu menuName) { Loggers.LogDebug("2.1"); List<string> result = new List<string>(); foreach (TerminalMenu allMenu in allMenus) { Loggers.LogDebug("2.2"); if (!allMenu.isActive) { continue; } for (int i = 0; i < allMenu.Categories.Count; i++) { Loggers.LogDebug("2.3"); foreach (KeyValuePair<string, List<string>> item in allMenu.categoryLists[i]) { if (Misc.CompareStringsInvariant(item.Key, catName)) { Loggers.LogDebug("categorylist found!!!"); menuName = allMenu; return item.Value; } } } } Loggers.LogDebug("2.1 FAIL"); menuName = null; return result; } public static Dictionary<string, List<string>> MakeCategoryList(TerminalMenuCategory category, List<TerminalMenuItem> terminalMenuItems) { Loggers.LogDebug("MakeCategoryList START"); string catName = category.CatName; Loggers.LogDebug(catName); List<string> list = new List<string>(); Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); Loggers.LogDebug($"count: {terminalMenuItems.Count}"); foreach (TerminalMenuItem terminalMenuItem in terminalMenuItems) { Loggers.LogDebug("checking " + terminalMenuItem.ItemName); if (Misc.CompareStringsInvariant(terminalMenuItem.Category, catName)) { list.Add("> " + CommonStringStuff.GetKeywordsForMenuItem(terminalMenuItem.itemKeywords) + "\r\n" + terminalMenuItem.itemDescription + "\r\n"); Loggers.LogDebug(CommonStringStuff.GetKeywordsForMenuItem(terminalMenuItem.itemKeywords) + " added"); Loggers.LogDebug(terminalMenuItem.itemDescription + " added too!"); } } Loggers.LogDebug("setting catName list"); dictionary.Add(catName, list); Loggers.LogDebug("MakeCategoryList END"); return dictionary; } public static string NextInList() { if (!isNextEnabled) { return "Not currently in any menus...\r\n\r\n"; } Loggers.LogDebug("currentCategory = " + currentCategory); nextCount++; GetCategoryFromString(currentCategory); TerminalMenu menuName; List<string> categoryList = GetCategoryList(currentCategory, out menuName); if (menuName == null) { return "ERROR: Unable to get current category!\r\n\r\n"; } menuName.isActive = true; menuName.nextCount = nextCount; menuName.currentCategory = currentCategory; string nextPage = CommonStringStuff.GetNextPage(categoryList, currentCategory, 4, nextCount, out isNextEnabled); Loggers.LogDebug($"currentCategory:{currentCategory} nextCount: {nextCount} isNextEnabled: {isNextEnabled}"); menuName.isNextEnabled = isNextEnabled; return nextPage; } public static string GetFirstInList() { Loggers.LogDebug("1"); nextCount = 1; string text = Plugin.instance.Terminal.screenText.text; int textAdded = Plugin.instance.Terminal.textAdded; int length = text.Length; int num = length - textAdded; string input = text.Substring(num, length - num); currentCategory = GetCategoryFromString(input); Loggers.LogDebug("currentCategory detected as: [" + currentCategory + "]"); Loggers.LogDebug("2"); TerminalMenu menuName; List<string> categoryList = GetCategoryList(currentCategory, out menuName); menuName.isActive = true; menuName.nextCount = nextCount; menuName.currentCategory = currentCategory; Loggers.LogDebug("3"); string nextPage = CommonStringStuff.GetNextPage(categoryList, currentCategory, 4, 1, out isNextEnabled); menuName.isNextEnabled = isNextEnabled; Loggers.LogDebug("4"); return nextPage; } public static string GetCategoryFromString(string input) { string input2 = input; Loggers.LogDebug("Getting Category from string: [" + input2 + "]"); foreach (TerminalMenu allMenu in allMenus) { if (allMenu.categoryLists.Any((Dictionary<string, List<string>> c) => c.Any((KeyValuePair<string, List<string>> d) => Misc.CompareStringsInvariant(d.Key, input2)))) { Loggers.LogDebug("detected menu with categoryList containing string " + input2 + "!!"); allMenu.isActive = true; int index = allMenu.categoryLists.FindIndex((Dictionary<string, List<string>> c) => c.Any<KeyValuePair<string, List<string>>>((KeyValuePair<string, List<string>> d) => Misc.CompareStringsInvariant(d.Key, input2))); return allMenu.categoryLists[index].First<KeyValuePair<string, List<string>>>((KeyValuePair<string, List<string>> d) => Misc.CompareStringsInvariant(d.Key, input2)).Key; } Loggers.LogDebug("menu does not contain string " + input2); allMenu.isActive = false; } return "CategoryNameFailure"; } public static string GetCategoryFromNode(TerminalNode givenNode) { Loggers.LogDebug("1.1"); if ((Object)(object)givenNode == (Object)null) { Loggers.ERROR("GetCategoryFromNode: givenNode is null!!!!"); return ""; } foreach (TerminalMenu allMenu in allMenus) { if (!allMenu.terminalNodePerCategory.ContainsValue(givenNode)) { Loggers.LogDebug("menu does not contain node " + ((Object)givenNode).name); allMenu.isActive = false; continue; } foreach (KeyValuePair<string, TerminalNode> item in allMenu.terminalNodePerCategory) { if ((Object)(object)item.Value == (Object)(object)givenNode) { Loggers.LogDebug("FOUND NODE AND PAIR " + item.Key); allMenu.isActive = true; return item.Key; } } } Loggers.ERROR("GetCategoryFromNode FAILURE: COULD NOT FIND NODE???"); return ""; } public static TerminalMenuItem MakeMenuItem(ManagedConfig managedBool) { if (managedBool.categoryText != "") { return new TerminalMenuItem { itemKeywords = managedBool.KeywordList, itemDescription = managedBool.configDescription, ItemName = managedBool.ConfigItemName, Category = managedBool.categoryText }; } return null; } public static TerminalMenuItem MakeMenuItem(string categoryText, List<string> keywordList, string configDescription, string itemName) { if (categoryText != "") { return new TerminalMenuItem { itemKeywords = keywordList, itemDescription = configDescription, ItemName = itemName, Category = categoryText }; } Loggers.WARNING("Empty categoryText, Unable to create TerminalMenuItem! (null return)"); return null; } } [Obsolete("This style of menu will be deleted in next major update to library, once all mods are confirmed not using this")] public class TerminalMenu { public string MenuName = string.Empty; public string MainMenuText = string.Empty; public string setKeyword = string.Empty; public List<TerminalMenuCategory> Categories = new List<TerminalMenuCategory>(); public List<TerminalMenuItem> menuItems = new List<TerminalMenuItem>(); public Dictionary<string, TerminalNode> terminalNodePerCategory = new Dictionary<string, TerminalNode>(); public List<Dictionary<string, List<string>>> categoryLists = new List<Dictionary<string, List<string>>>(); public List<TerminalNode> terminalNodes = new List<TerminalNode>(); public string currentCategory { get; internal set; } = string.Empty; public bool isActive { get; internal set; } public bool isNextEnabled { get; internal set; } public int nextCount { get; internal set; } = 1; public void Delete() { MenuBuild.allMenus.Remove(this); menuItems.Clear(); categoryLists.Clear(); Categories.Clear(); terminalNodePerCategory.Clear(); terminalNodes.Clear(); } } public class TerminalMenuItem { public string ItemName = string.Empty; public string Category = string.Empty; public List<string> itemKeywords; public string itemDescription = string.Empty; public void Delete() { itemDescription = ""; Category = ""; ItemName = ""; if (itemKeywords.Count > 0) { itemKeywords.Clear(); } } } public class TerminalMenuCategory { public string CatName { get; set; } public string CatDescription { get; set; } } } namespace OpenLib.InteractiveMenus { public abstract class BetterMenuBase { public List<MenuItem> AllMenuItemsOfType = new List<MenuItem>(); public abstract string Name { get; set; } public abstract Type MenuType { get; } public abstract object BoxedValue { get; } public abstract bool InMenu { get; set; } public abstract OpenLib.Events.Events.CustomEvent InputEvent { get; set; } public abstract OpenLib.Events.Events.CustomEvent ExitTerminal { get; set; } public abstract MenuItem MainMenu { get; set; } public List<T> GetMenuItemsOfType<T>() where T : MenuItem { return AllMenuItemsOfType.OfType<T>().ToList(); } public override string ToString() { return Name; } } public class BetterMenu<T> : BetterMenuBase { [CompilerGenerated] private sealed class <DelayUpdateText>d__68 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public BetterMenu<T> <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayUpdateText>d__68(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown int num = <>1__state; BetterMenu<T> betterMenu = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; if (!betterMenu.AcceptAnything) { betterMenu.MenuNode.displayText = betterMenu.GetPageText(); } if (string.IsNullOrEmpty(betterMenu.MenuNode.displayText)) { betterMenu.ExitInTerminal(); } <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 2; return true; case 2: <>1__state = -1; CommonTerminal.LoadNewNode(betterMenu.MenuNode); <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 3; return true; case 3: <>1__state = -1; if (betterMenu.AdjustScrollInMenu) { betterMenu.ScrollAdjust(); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <MenuClose>d__78 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public BetterMenu<T> <>4__this; public bool enableInput; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MenuClose>d__78(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown int num = <>1__state; BetterMenu<T> betterMenu = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; betterMenu.OnExit.Invoke(); <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; betterMenu.InMenu = false; betterMenu.AcceptAnything = false; CollectionExtensions.Do<MenuItem>((IEnumerable<MenuItem>)betterMenu.AllMenuItemsOfType, (Action<MenuItem>)delegate(MenuItem x) { x.IsActive = false; }); CommonTerminal.ChangeCaretColor(CommonTerminal.CaretOriginal, saveOriginal: false); <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 2; return true; case 2: <>1__state = -1; if (betterMenu.ExitAction == null) { CommonTerminal.LoadNewNode(CommonTerminal.HomePage); } else { betterMenu.ExitAction(); } if (enableInput) { Plugin.instance.Terminal.screenText.ActivateInputField(); ((Selectable)Plugin.instance.Terminal.screenText).interactable = true; } betterMenu.OnExitComplete.Invoke(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <MenuStart>d__79 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public BetterMenu<T> <>4__this; public MenuItem Start; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MenuStart>d__79(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown int num = <>1__state; BetterMenu<T> betterMenu = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (betterMenu.InMenu) { return false; } if (Start == null) { Start = betterMenu.MainMenu; } Start.IsActive = true; betterMenu.AcceptAnything = false; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; betterMenu.InMenu = true; CommonTerminal.ChangeCaretColor(CommonTerminal.transparent, saveOriginal: true); betterMenu.ActiveSelection = 0; betterMenu.CurrentPage = 1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 2; return true; case 2: <>1__state = -1; Plugin.instance.Terminal.screenText.DeactivateInputField(false); ((Selectable)Plugin.instance.Terminal.screenText).interactable = false; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 3; return true; case 3: <>1__state = -1; Start.SelectionEvent?.Invoke(); if (Start.LoadPageOnSelect) { betterMenu.LoadPage.Invoke(); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private string _name = ""; private bool _inMenu; private MenuItem _mainMenu; private OpenLib.Events.Events.CustomEvent _inputEvent = new OpenLib.Events.Events.CustomEvent(); private OpenLib.Events.Events.CustomEvent _exitEvent = new OpenLib.Events.Events.CustomEvent(); public MenuItem CurrentMenuItem; public TerminalNode MenuNode; public Action ExitAction; public OpenLib.Events.Events.CustomEvent OnExit = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent OnExitComplete = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent OnEnter = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent OnLoad = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent LoadPage = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent UpMenuEvent = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent DownMenuEvent = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent LeftMenuEvent = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent RightMenuEvent = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEvent AcceptAnyKeyEvent = new OpenLib.Events.Events.CustomEvent(); public OpenLib.Events.Events.CustomEventRef<List<MenuItem>> MenuItemList = new OpenLib.Events.Events.CustomEventRef<List<MenuItem>>(); public Key upMenu = (Key)63; public Key downMenu = (Key)64; public Key leftMenu = (Key)61; public Key rightMenu = (Key)62; public Key selectMenu = (Key)2; public Key leaveMenu = (Key)65; public Dictionary<Key, Action> MainActions = new Dictionary<Key, Action>(); public Dictionary<Key, Action> OtherActions = new Dictionary<Key, Action>(); public bool IsMenuEnabled; public bool AcceptAnything; public bool AdjustScrollInMenu; private int _activeIndex; private int _endIndex; public int CurrentPage = 1; public int PageSize = 8; public List<MenuItem> DisplayMenuItemsOfType = new List<MenuItem>(); public override string Name { get { return _name; } set { _name = value; } } public override Type MenuType => typeof(T); public override object BoxedValue => this; public override bool InMenu { get { return _inMenu; } set { _inMenu = value; } } public override MenuItem MainMenu { get { return _mainMenu; } set { _mainMenu = value; } } public override OpenLib.Events.Events.CustomEvent InputEvent { get { return _inputEvent; } set { _inputEvent = value; } } public override OpenLib.Events.Events.CustomEvent ExitTerminal { get { return _exitEvent; } set { _exitEvent = value; } } public int ActiveSelection { get { return _activeIndex; } set { _activeIndex = value; } } public int EndIndex { get { return _endIndex; } set { _endIndex = value; } } public override string ToString() { return Name; } public BetterMenu(string name, Dictionary<Key, Action> MoreMenuActions = null) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!TerminalUpdatePatch.usePatch) { TerminalUpdatePatch.usePatch = true; } Name = name; LoadPage.AddListener(Load); InputEvent.AddListener(HandleInput); ExitTerminal.AddListener(ExitTerminalLeave); AcceptAnyKeyEvent.AddListener(DefaultAcceptAnything); UpdateMainActions(); if (MoreMenuActions != null) { OtherActions = MoreMenuActions; } MenusContainer.AllMenus.Add(this); } public void ReplaceEventAction(OpenLib.Events.Events.CustomEvent eventName, OpenLib.Events.Events.CustomEvent.Event newMethod) { if (eventName.Listeners > 0) { eventName.RemoveAllListeners(); } eventName.AddListener(newMethod); } public void AddToOtherActions(Key key, Action action) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (OtherActions.ContainsKey(key)) { OtherActions.Remove(key); } OtherActions.Add(key, action); } public void UpdateMainActions() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) MainActions.Clear(); MainActions.Add(upMenu, UpMenu); MainActions.Add(downMenu, DownMenu); MainActions.Add(leftMenu, LeftMenu); MainActions.Add(rightMenu, RightMenu); MainActions.Add(selectMenu, SelectInMenu); MainActions.Add(leaveMenu, ExitInTerminal); } internal void HandleInput() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!InMenu || (Object)(object)MenuNode == (Object)null) { return; } if (AcceptAnything && AcceptAnyKeyEvent.HasListeners) { AcceptAnyKeyEvent.Invoke(); return; } Key? main = MainActions.FirstOrDefault<KeyValuePair<Key, Action>>((KeyValuePair<Key, Action> x) => ((ButtonControl)Keyboard.current[x.Key]).isPressed).Key; if (main.HasValue) { MainActions.FirstOrDefault<KeyValuePair<Key, Action>>((KeyValuePair<Key, Action> x) => (Key?)x.Key == main).Value?.Invoke(); } if (OtherActions.Count == 0) { return; } Key? other = OtherActions.FirstOrDefault<KeyValuePair<Key, Action>>((KeyValuePair<Key, Action> x) => ((ButtonControl)Keyboard.current[x.Key]).isPressed).Key; if (other.HasValue) { OtherActions.FirstOrDefault<KeyValuePair<Key, Action>>((KeyValuePair<Key, Action> x) => (Key?)x.Key == other).Value?.Invoke(); } } public void Load() { MenuItem menuItem = AllMenuItemsOfType.FirstOrDefault((MenuItem x) => x.IsActive); if (menuItem == null) { Loggers.ERROR("Unable to load current page! Nothing is active!"); return; } if ((Object)(object)MenuNode == (Object)null) { Loggers.ERROR("NRE detected at MenuNode! This menu did not set it's terminal node correctly!"); return; } menuItem.OnPageLoad?.Invoke(); OnLoad.Invoke(); ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(DelayUpdateText()); } public void DefaultAcceptAnything() { AcceptAnything = false; MenuItem menuItem = AllMenuItemsOfType.FirstOrDefault((MenuItem x) => x.IsActive); if (menuItem.NestedMenus.Count == 0) { ExitInTerminal(); } else { LoadPage.Invoke(); } } [IteratorStateMachine(typeof(BetterMenu<>.<DelayUpdateText>d__68))] private IEnumerator DelayUpdateText() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayUpdateText>d__68(0) { <>4__this = this }; } private void ScrollAdjust() { float num = ((float)EndIndex - (float)ActiveSelection) / (float)EndIndex; if (num >= 1f) { ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(Plugin.instance.Terminal.forceScrollbarUp()); } else if (num == 0f) { ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(Plugin.instance.Terminal.forceScrollbarDown()); } else { Plugin.instance.Terminal.scrollBarVertical.value = num; } } public string GetPageText() { StringBuilder stringBuilder = new StringBuilder(); CurrentMenuItem = AllMenuItemsOfType.FirstOrDefault((MenuItem x) => x.IsActive); if (CurrentMenuItem == null) { Loggers.WARNING("Unable to get current menu page!!"); return ""; } stringBuilder.Append(CurrentMenuItem.Header() ?? ""); DisplayMenuItemsOfType = AllMenuItemsOfType.FindAll((MenuItem x) => CurrentMenuItem.NestedMenus.Contains(x)); DisplayMenuItemsOfType.RemoveAll((MenuItem x) => !x.ShowIfEmptyNest && x.NestedMenus.Count == 0); if (DisplayMenuItemsOfType.Count == 0) { stringBuilder.Append("\r\n\r\nThis menu listing is currently empty :(\r\n"); if (CurrentMenuItem != null) { stringBuilder.Append(CurrentMenuItem.Footer() ?? ""); } return stringBuilder.ToString(); } CurrentMenuItem.AdjustNestedMenuList.Invoke(ref DisplayMenuItemsOfType); CurrentPage = Misc.CycleIndex(CurrentPage, 1, Mathf.CeilToInt((float)DisplayMenuItemsOfType.Count / (float)PageSize)); int num = (CurrentPage - 1) * PageSize; int num3 = (EndIndex = Mathf.Min(num + PageSize, DisplayMenuItemsOfType.Count)); ActiveSelection = Misc.CycleIndex(ActiveSelection, num, num3 - 1); Loggers.LogDebug($"{Name} menu activeselection: {ActiveSelection}"); CollectionExtensions.DoIf<MenuItem>((IEnumerable<MenuItem>)DisplayMenuItemsOfType, (Func<MenuItem, bool>)((MenuItem x) => x.OnPageLoad != null), (Action<MenuItem>)delegate(MenuItem x) { x.OnPageLoad(); }); for (int i = num; i < num3; i++) { string text = string.Empty; if (ActiveSelection == i) { text = ">>> "; } text += DisplayMenuItemsOfType[i].Prefix; text += DisplayMenuItemsOfType[i].Name; text += DisplayMenuItemsOfType[i].Suffix; stringBuilder.Append(text + "\n"); } int num4 = num3 - num - PageSize; if (num4 < 0) { for (int j = num4; j < 0; j++) { stringBuilder.Append('\n'); } } if (CurrentMenuItem == null) { Loggers.WARNING("Unable to select current menu item!!"); } else { stringBuilder.Append(CurrentMenuItem.Footer() ?? ""); } return stringBuilder.ToString(); } public void SelectInMenu() { if (DisplayMenuItemsOfType.Count == 0) { return; } MenuItem menuItem = AllMenuItemsOfType.FirstOrDefault((MenuItem x) => x.IsActive); if (menuItem == null) { Loggers.WARNING("Unable to select current menu item!!"); return; } Loggers.LogDebug("Selecting Nested Menu Item!"); MenuItem menuItem2 = DisplayMenuItemsOfType[ActiveSelection]; menuItem2.SelectionEvent?.Invoke(); if (menuItem2.NestedMenus.Count > 0) { Loggers.LogDebug("Setting to nested menu item!"); CurrentPage = 1; ActiveSelection = 0; CollectionExtensions.Do<MenuItem>((IEnumerable<MenuItem>)AllMenuItemsOfType, (Action<MenuItem>)delegate(MenuItem x) { x.IsActive = false; }); menuItem2.IsActive = true; } if (menuItem2.LoadPageOnSelect) { LoadPage.Invoke(); } } public void AddMenuItem(MenuItem menuItem) { if (!AllMenuItemsOfType.Contains(menuItem)) { AllMenuItemsOfType.Add(menuItem); } } public void ExitInTerminal() { MenuItem menuItem = AllMenuItemsOfType.FirstOrDefault((MenuItem x) => x.IsActive); if (menuItem == null) { Loggers.WARNING("Unable to get current menu page!!"); } if (menuItem == null) { ExitMenu(enableInput: true); } else if (menuItem.Parent != null) { Loggers.LogDebug("Setting to ParentMenu!"); ActiveSelection = 0; CurrentPage = 1; menuItem.IsActive = false; menuItem.Parent.IsActive = true; LoadPage.Invoke(); } else { ExitMenu(enableInput: true); } } public void ExitTerminalLeave() { ExitMenu(enableInput: false); } public void ExitMenu(bool enableInput) { ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(MenuClose(enableInput)); } public void EnterAtPage(MenuItem menuItem) { OnEnter.Invoke(); ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(MenuStart(menuItem)); } public void EnterMenu() { OnEnter.Invoke(); ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(MenuStart()); } [IteratorStateMachine(typeof(BetterMenu<>.<MenuClose>d__78))] internal IEnumerator MenuClose(bool enableInput) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MenuClose>d__78(0) { <>4__this = this, enableInput = enableInput }; } [IteratorStateMachine(typeof(BetterMenu<>.<MenuStart>d__79))] internal IEnumerator MenuStart(MenuItem Start = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MenuStart>d__79(0) { <>4__this = this, Start = Start }; } public void UpMenu() { if (InMenu) { ActiveSelection--; UpMenuEvent.Invoke(); LoadPage.Invoke(); } } public void DownMenu() { if (InMenu) { ActiveSelection++; DownMenuEvent.Invoke(); LoadPage.Invoke(); } } public void LeftMenu() { if (InMenu) { CurrentPage--; LeftMenuEvent.Invoke(); LoadPage.Invoke(); } } public void RightMenu() { if (InMenu) { CurrentPage++; RightMenuEvent.Invoke(); LoadPage.Invoke(); } } } public abstract class MenuItem<TMenu> : MenuItem where TMenu : BetterMenuBase { public new TMenu BetterMenu => (TMenu)base.BetterMenu; protected MenuItem(TMenu betterMenu) : base(betterMenu) { } } public abstract class MenuItem { private string _prefix = string.Empty; private string _suffix = string.Empty; private bool _isActive; private bool _LoadOnSelect = true; private MenuItem _parent; private Func<string> _header = () => string.Empty; private Func<string> _footer = () => string.Empty; protected BetterMenuBase? BetterMenu { get; } public abstract string Name { get; set; } public abstract bool ShowIfEmptyNest { get; set; } public virtual string Prefix { get { return _prefix; } set { _prefix = value; } } public virtual string Suffix { get { return _suffix; } set { _suffix = value; } } public virtual bool IsActive { get { return _isActive; } set { _isActive = value; } } public virtual bool LoadPageOnSelect { get { return _LoadOnSelect; } set { _LoadOnSelect = value; } } public virtual Action OnPageLoad { get; set; } public abstract OpenLib.Events.Events.CustomEvent SelectionEvent { get; set; } public virtual OpenLib.Events.Events.CustomEventRef<List<MenuItem>> AdjustNestedMenuList { get; set; } = new OpenLib.Events.Events.CustomEventRef<List<MenuItem>>(); public abstract List<MenuItem> NestedMenus { get; set; } public virtual MenuItem Parent { get { return _parent; } set { _parent = value; } } public virtual Func<string> Header { get { return _header; } set { _header = value; } } public virtual Func<string> Footer { get { return _footer; } set { _footer = value; } } [Obsolete("Added for compatibility with older versions, please use the constructor with the bettermenubase")] protected MenuItem() { Loggers.LogInfo("MenuItem created from obsolete constructor! Please use constructor with BetterMenuBase!"); } protected MenuItem(BetterMenuBase betterMenu) { if (betterMenu == null) { Loggers.ERROR("Unable to assign menu item to NULL betterMenu!"); return; } BetterMenu = betterMenu; betterMenu.AllMenuItemsOfType.Add(this); } public override string ToString() { return Name; } public virtual void SetParentMenu(MenuItem parent) { Parent?.NestedMenus.RemoveAll((MenuItem m) => m == this); Parent = parent; if (parent != null && !parent.NestedMenus.Contains(this)) { parent.NestedMenus.Add(this); } } public virtual void AddNestedItem(MenuItem child) { if (child != null) { child.Parent = this; if (!NestedMenus.Contains(child)) { NestedMenus.Add(child); } } } public virtual void RemoveFromParent() { if (Parent != null) { Parent.NestedMenus.RemoveAll((MenuItem m) => m == this); Parent = null; } } public virtual void RemoveChild(MenuItem child) { if (child != null) { if (child.Parent != null) { child.Parent = null; } NestedMenus.Remove(child); } } } public class MenusContainer { public static List<BetterMenuBase> AllMenus = new List<BetterMenuBase>(); private static int _activeIndex = 0; public static int StaticIndex { get { return _activeIndex; } set { _activeIndex = value; } } public static bool TryGetMenu(string menuName, out BetterMenuBase item) { string menuName2 = menuName; item = AllMenus.FirstOrDefault((BetterMenuBase x) => x.Name == menuName2); if (item == null) { return false; } return true; } public static bool AnyMenuActive() { if (AllInteractiveMenus.AnyInteractiveMenuActive()) { return true; } bool flag = false; if (Plugin.instance.ITAPI) { flag = InteractiveTermAPI.ApplicationInUse(); } if (flag) { return true; } if (AllMenus.Count == 0) { return false; } if (AllMenus.Any((BetterMenuBase x) => x.InMenu)) { return true; } return false; } public static bool AnyBetterMenuActive() { if (AllMenus.Count == 0) { return false; } if (AllMenus.Any((BetterMenuBase x) => x.InMenu)) { return true; } return false; } public static bool AnyOpenLibMenuActive() { if (AllInteractiveMenus.AnyInteractiveMenuActive()) { return true; } if (AllMenus.Count == 0) { return false; } if (AllMenus.Any((BetterMenuBase x) => x.InMenu)) { return true; } return false; } } } namespace OpenLib.Examples { internal class Examples { public static void TestMyTAO() { TerminalCodeObject<PlayerControllerB> terminalCodeObject = new TerminalCodeObject<PlayerControllerB>(StartOfRound.Instance.localPlayerController, ((Component)StartOfRound.Instance.localPlayerController).gameObject, dynamicMapIcon: true); terminalCodeObject.OnCodeUsed.AddListener((UnityAction<TerminalAccessibleObject, PlayerControllerB>)TestCodeEvent); terminalCodeObject.OnCooldownComplete.AddListener((UnityAction<TerminalAccessibleObject, PlayerControllerB>)TestCoolDownEvent); terminalCodeObject.SetTimers(10f, 0f); } public static void TestCodeEvent(TerminalAccessibleObject Code, PlayerControllerB playerOfCode) { if ((Object)(object)Code == (Object)null) { Loggers.WARNING("Code is NULL!"); return; } Plugin.Log.LogDebug((object)$"{Code.objectCode} activated! Status: isPoweredOn - {Code.isPoweredOn}, Cooldown: {Code.inCooldown}, Cooldown Timer: {Code.currentCooldownTimer}"); playerOfCode.drunkness = 20f; } public static void TestCoolDownEvent(TerminalAccessibleObject Code, PlayerControllerB playerOfCode) { if ((Object)(object)Code == (Object)null) { Loggers.WARNING("Code is NULL!"); return; } Plugin.Log.LogDebug((object)$"{Code.objectCode} cooldown reached! Status: isPoweredOn - {Code.isPoweredOn}, Cooldown: {Code.inCooldown}, Cooldown Timer: {Code.currentCooldownTimer}"); playerOfCode.drunkness = 0f; } } } namespace OpenLib.Events { public static class EventManager { public static Events.CustomEvent TerminalDisable = new Events.CustomEvent(); public static Events.CustomEvent TerminalStart = new Events.CustomEvent(); public static Events.CustomEvent TerminalBeginUsing = new Events.CustomEvent(); public static Events.CustomEvent TerminalQuit = new Events.CustomEvent(); public static Events.CustomEvent<Terminal> TerminalAwake = new Events.CustomEvent<Terminal>(); public static Events.CustomEvent<TerminalNode> TerminalLoadIfAffordable = new Events.CustomEvent<TerminalNode>(); public static Events.TerminalNodeEvent TerminalParseSent = new Events.TerminalNodeEvent(); public static Events.CustomEvent<TerminalNode> TerminalLoadNewNode = new Events.CustomEvent<TerminalNode>(); public static Events.TerminalNodeEvent GetNewDisplayText = new Events.TerminalNodeEvent(); public static Events.CustomEvent StartOfRoundAwake = new Events.CustomEvent(); public static Events.CustomEvent StartOfRoundStart = new Events.CustomEvent(); public static Events.CustomEvent StartOfRoundStartGame = new Events.CustomEvent(); public static Events.CustomEvent StartOfRoundChangeLevel = new Events.CustomEvent(); public static Events.CustomEvent ShipReset = new Events.CustomEvent(); public static Events.CustomEvent SetBigDoorCodes = new Events.CustomEvent(); public static Events.CustomEvent SpawnMapObjects = new Events.CustomEvent(); public static Events.CustomEvent NextDayEvent = new Events.CustomEvent(); public static Events.CustomEvent OnShipLandedMiscPatch = new Events.CustomEvent(); public static Events.CustomEvent ShipLeft = new Events.CustomEvent(); public static Events.CustomEvent NewQuota = new Events.CustomEvent(); public static Events.CustomEvent PlayerSpawn = new Events.CustomEvent(); public static Events.CustomEvent PlayerEmote = new Events.CustomEvent(); public static Events.CustomEvent<ShipTeleporter> TeleporterAwake = new Events.CustomEvent<ShipTeleporter>(); public static Events.CustomEvent NormalTPFound = new Events.CustomEvent(); public static Events.CustomEvent InverseTPFound = new Events.CustomEvent(); public static Events.CustomEvent GameNetworkManagerStart = new Events.CustomEvent(); public static Events.CustomEvent OnClientConnect = new Events.CustomEvent(); public static Events.CustomEvent SpecateNextPlayer = new Events.CustomEvent(); public static Events.CustomEvent TerminalDelayStart = new Events.CustomEvent(); public static Events.CustomEvent SetTerminalInUse = new Events.CustomEvent(); public static Events.CustomEvent TerminalKeyPressed = new Events.CustomEvent(); public static Events.CustomEvent TerminalMenuKeyPressed = new Events.CustomEvent(); public static Events.CustomEvent PlayerIsInShip = new Events.CustomEvent(); public static Events.CustomEvent PlayerIsDead = new Events.CustomEvent(); public static Events.CustomEvent SpecatingPlayerIsInShip = new Events.CustomEvent(); public static Events.CustomEvent<GameObject> AutoParentEvent = new Events.CustomEvent<GameObject>(); public static Events.CustomEvent<GameObject> NetworkObjectSpawn = new Events.CustomEvent<GameObject>(); } public class Events { public class CustomEvent<T> { public delegate void ParameterEvent(T param); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event ParameterEvent OnParameterEvent; public void Invoke(T param) { this.OnParameterEvent?.Invoke(param); } public void AddListener(ParameterEvent listener) { OnParameterEvent += listener; Listeners++; } public void RemoveListener(ParameterEvent listener) { OnParameterEvent -= listener; Listeners--; } } public class CustomEventRef<T> { public delegate void ParameterEvent(ref T param); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event ParameterEvent OnParameterEvent; public void Invoke(ref T param) { this.OnParameterEvent?.Invoke(ref param); } public void AddListener(ParameterEvent listener) { OnParameterEvent += listener; Listeners++; } public void RemoveListener(ParameterEvent listener) { OnParameterEvent -= listener; Listeners--; } } public class TerminalNodeEvent { public delegate TerminalNode Event(ref TerminalNode original); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event Event OnEvent; public TerminalNode NodeInvoke(ref TerminalNode original) { return this.OnEvent?.Invoke(ref original); } public void AddListener(Event listener) { OnEvent += listener; Listeners++; } public void RemoveListener(Event listener) { OnEvent -= listener; Listeners--; } } public class TerminalKeywordEvent { public delegate TerminalKeyword Event(ref TerminalKeyword original); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event Event OnEvent; public TerminalKeyword WordInvoke(ref TerminalKeyword original) { return this.OnEvent?.Invoke(ref original); } public void AddListener(Event listener) { OnEvent += listener; Listeners++; } public void RemoveListener(Event listener) { OnEvent -= listener; Listeners--; } } public class CustomEvent { public delegate void Event(); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event Event OnEvent; public void Invoke() { if (HasListeners) { this.OnEvent?.Invoke(); } } public void AddListener(Event listener) { OnEvent += listener; Listeners++; } public void RemoveListener(Event listener) { OnEvent -= listener; Listeners--; } public void RemoveAllListeners() { if (Listeners != 0) { List<Delegate> list = this.OnEvent.GetInvocationList().ToList(); CollectionExtensions.Do<Delegate>((IEnumerable<Delegate>)list, (Action<Delegate>)delegate(Delegate x) { OnEvent -= (Event)x; }); Listeners = 0; } } } } public class EventUsage { public static List<ConfigFile> configsToReload = new List<ConfigFile>(); internal static void Subscribers() { EventManager.TerminalAwake.AddListener(OnTerminalAwake); EventManager.TerminalStart.AddListener(OnTerminalStart); EventManager.TerminalQuit.AddListener(OnTerminalQuit); EventManager.TerminalDisable.AddListener(OnTerminalDisable); EventManager.TerminalLoadNewNode.AddListener(OnLoadNewNode); EventManager.TerminalParseSent.AddListener(OnParseSent); EventManager.TerminalBeginUsing.AddListener(OnUsingTerminal); EventManager.GameNetworkManagerStart.AddListener(StartGame.OnGameStart); EventManager.TeleporterAwake.AddListener(Teleporter.CheckTeleporterTypeAndAssign); EventManager.TerminalMenuKeyPressed.AddListener(OnMenuKeyPress); } private static void OnTerminalAwake(Terminal instance) { Plugin.instance.Terminal = instance; Loggers.LogInfo("Setting Plugin.instance.Terminal"); CommandRegistry.GetCommandsToAdd(ConfigSetup.defaultManaged, ConfigSetup.defaultListing); CommandManager.AddAllCommandsToTerminal(); } private static void OnTerminalDisable() { if (Plugin.instance.OpenBodyCamsMod) { OpenBodyCamFuncs.ResidualCamsCheck(); } RemoveThings.OnTerminalDisable(); TerminalStart.delayStartEnum = false; ListManagement.ClearLists(); CollectionExtensions.Do<CommandManager>((IEnumerable<CommandManager>)Plugin.AllCommands, (Action<CommandManager>)delegate(CommandManager x) { x.TerminalDisabled(); }); foreach (ConfigFile item in configsToReload) { Loggers.LogDebug("reloading config from list"); item.Save(); item.Reload(); } configsToReload.Clear(); } private static void OnTerminalStart() { TerminalStart.TerminalStartGroupDelay(); } private static void OnTerminalQuit() { if (MenusContainer.AllMenus.Count != 0) { MenusContainer.AllMenus.FirstOrDefault((BetterMenuBase x) => x.InMenu)?.ExitTerminal.Invoke(); } } internal static void OnMenuKeyPress() { if (AllInteractiveMenus.AllMenus.Count != 0) { AllInteractiveMenus.AllMenus.FirstOrDefault((InteractiveMenu x) => x.inMenu && x.isMenuEnabled)?.HandleInput(); } if (MenusContainer.AllMenus.Count != 0) { MenusContainer.AllMenus.FirstOrDefault((BetterMenuBase x) => x.InMenu)?.InputEvent.Invoke(); } CommonTerminal.TrySyncNodeOnly(Plugin.instance.Terminal.currentNode); } public static void OnUsingTerminal() { Loggers.LogInfo("Start Using Terminal Postfix"); } private static bool ParseFailed(TerminalNode terminalNode, Terminal self) { if ((Object)(object)terminalNode == (Object)(object)self.terminalNodes.specialNodes[10]) { return true; } if ((Object)(object)terminalNode == (Object)(object)self.terminalNodes.specialNodes[11]) { return true; } if ((Object)(object)terminalNode == (Object)(object)self.terminalNodes.specialNodes[12]) { return true; } return false; } public static TerminalNode OnParseSent(ref TerminalNode node) { Loggers.LogDebug("parsing sentence"); if ((Object)(object)node == (Object)null) { Loggers.WARNING("node detected as NULL, returning..."); return node; } if (ParseFailed(node, Plugin.instance.Terminal)) { string text = Plugin.instance.Terminal.screenText.text; int textAdded = Plugin.instance.Terminal.textAdded; int length = text.Length; int num = length - textAdded; string text2 = text.Substring(num, length - num); if (text2.Length > 0) { if (LogicHandling.GetDisplayFromFaux(ConfigSetup.defaultListing.fauxKeywords, text2, ref node)) { Loggers.LogInfo("faux word detected on current node!"); } if (CommonTerminal.TryGetNodeFromList(text2, ConfigSetup.defaultListing.specialListString, out TerminalNode returnNode)) { node = returnNode; Loggers.LogDebug("node found matching specialListString in text - " + text2); } if (CommonTerminal.TryGetCommand(text2, out TerminalNode returnNode2)) { node = returnNode2; Loggers.LogDebug("node found matching CommandManager listing in text - " + text2); } } } if (LogicHandling.GetNewDisplayText(ConfigSetup.defaultListing, ref node)) { Loggers.LogInfo("node found: " + ((Object)node).name); } if (LogicHandling.GetDisplayTextFromCommand(ref node)) { Loggers.LogInfo("command found: " + ((Object)node).name); } return node; } public static void OnLoadNewNode(TerminalNode node) { if (!((Object)(object)node == (Object)null)) { Loggers.LogDebug(((Object)node).name + " has been loaded"); if (node.acceptAnything && node.terminalOptions.Length < 1) { node.acceptAnything = false; Loggers.LogDebug("fixing node property to avoid errors! (eg. LLL route locked)"); } } } } } namespace OpenLib.CoreMethods { public class AddingThings { private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray(); public static void AddKeywordToExistingNode(string keyWord, TerminalNode existingNode, bool addToList = true) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown List<TerminalKeyword> list = Plugin.instance.Terminal.terminalNodes.allKeywords.ToList(); List<CompatibleNoun> list2 = new List<CompatibleNoun>(); TerminalKeyword val = BasicTerminal.CreateNewTerminalKeyword(keyWord + "_keyword", keyWord.ToLower()); val.isVerb = false; val.specialKeywordResult = existingNode; if (existingNode.terminalOptions != null) { list2 = existingNode.terminalOptions.ToList(); Loggers.LogDebug(((Object)existingNode).name + " has existing terminalOptions"); } CompatibleNoun item = new CompatibleNoun(val, existingNode); list2.Add(item); existingNode.terminalOptions = list2.ToArray(); list.Add(val); if (addToList) { Plugin.KeywordsAdded.Add(val); } Loggers.LogDebug("Adding " + keyWord + " to existing node " + ((Object)existingNode).name); Plugin.instance.Terminal.terminalNodes.allKeywords = list.ToArray(); } public static TerminalKeyword AddKeywordToNode(string keyWord, TerminalNode existingNode, bool addToList = true) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown List<TerminalKeyword> list = Plugin.instance.Terminal.terminalNodes.allKeywords.ToList(); List<CompatibleNoun> list2 = new List<CompatibleNoun>(); TerminalKeyword val = BasicTerminal.CreateNewTerminalKeyword(keyWord + "_keyword", keyWord.ToLower()); val.isVerb = false; val.specialKeywordResult = existingNode; if (existingNode.terminalOptions != null) { list2 = existingNode.terminalOptions.ToList(); Loggers.LogDebug(((Object)existingNode).name + " has existing terminalOptions"); } CompatibleNoun item = new CompatibleNoun(val, existingNode); list2.Add(item); existingNode.terminalOptions = list2.ToArray(); list.Add(val); if (addToList) { Plugin.KeywordsAdded.Add(val); } Loggers.LogDebug("Adding " + keyWord + " to existing node " + ((Object)existingNode).name); Plugin.instance.Terminal.terminalNodes.allKeywords = list.ToArray(); return val; } public static void AddToHelpCommand(string textToAdd) { TerminalNode val = Plugin.instance.Terminal.terminalNodes.specialNodes[13]; if (val.displayText.Contains(textToAdd)) { Loggers.WARNING("Help command already contains this text: " + textToAdd); return; } int startIndex = val.displayText.LastIndexOf('['); val.displayText = val.displayText.Insert(startIndex, textToAdd + "\r\n\r\n"); } public static void AddToExistingNodeText(string textToAdd, ref TerminalNode existingNode) { if (existingNode.displayText.Contains(textToAdd)) { Plugin.Log.LogWarning((object)("Unable to add below text to " + ((Object)existingNode).name + ", it already has this text in it")); return; } Loggers.LogDebug($"oldtext length {existingNode.displayText.Length}"); Loggers.LogDebug(existingNode.displayText); string text = existingNode.displayText.TrimEnd(NewLineChars); text = text + "\n" + textToAdd + "\r\n\r\n"; existingNode.displayText = text; Loggers.LogDebug(((Object)existingNode).name + " text updated!!!"); } public static TerminalNode CreateDummyNode(string nodeName, bool clearPrevious, string displayText) { if (DynamicBools.UseMatchingNode(nodeName, out TerminalNode returnNode)) { returnNode.displayText = displayText; returnNode.clearPreviousText = clearPrevious; } else { returnNode = BasicTerminal.CreateNewTerminalNode(); ((Object)returnNode).name = nodeName; returnNode.displayText = displayText; returnNode.clearPreviousText = clearPrevious; } return returnNode; } public static void AddBasicCommand(string nodeName, string keyWord, string displayText, bool isVerb, bool clearText, string category = "", string keywordDescription = "") { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!LogicHandling.TryGetFromAllNodes("OtherCommands", out TerminalNode outNode) && Misc.CompareStringsInvariant(category, "other")) { Loggers.WARNING("Unable to add " + keyWord + " to " + category + "\n" + category + " TerminalNode could not be found!"); return; } List<TerminalKeyword> list = Plugin.instance.Terminal.terminalNodes.allKeywords.ToList(); if (!DynamicBools.IsCommandCreatedAlready(keyWord, displayText, list)) { CommonThings.CheckForAndDeleteKeyWord(keyWord.ToLower()); TerminalNode val = BasicTerminal.CreateNewTerminalNode(); ((Object)val).name = nodeName; val.displayText = displayText; val.clearPreviousText = clearText; TerminalKeyword val2 = BasicTerminal.CreateNewTerminalKeyword(nodeName + "_keyword", keyWord.ToLower()); ((Object)val2).name = nodeName + "_keyword"; val2.word = keyWord.ToLower(); val2.isVerb = isVerb; val2.specialKeywordResult = val; new CompatibleNoun(val2, val); list.Add(val2); Plugin.instance.Terminal.terminalNodes.allKeywords = list.ToArray(); if (!Plugin.NodesAdded.Contains(val)) { Plugin.NodesAdded.Add(val); } if (!Plugin.KeywordsAdded.Contains(val2)) { Plugin.KeywordsAdded.Add(val2); } if (Misc.CompareStringsInvariant(category, "other") && (Object)(object)outNode != (Object)null) { AddToExistingNodeText(keywordDescription ?? "", ref outNode); Loggers.LogDebug("adding node to other listing"); } } } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static TerminalNode AddNodeManual(string nodeName, string stringValue, Func<string> commandAction, bool clearText, int CommandType, MainListing yourModListing, int price = 0, Func<string> ConfirmAction = null, Func<string> DenyAction = null, string confirmText = "", string denyText = "", bool alwaysInStock = false, int maxStock = 1, string storeName = "", bool reuseFunc = false, string itemList = "") { TerminalNode val = null; List<string> list = new List<string>(); if (stringValue != null) { list = CommonStringStuff.GetKeywordsPerConfigItem(stringValue); } foreach (string item in list) { val = BaseCommandCreation(nodeName, item, commandAction, clearText, CommandType, yourModListing, price, ConfirmAction, DenyAction, confirmText, denyText, alwaysInStock, maxStock, storeName, reuseFunc, itemList); } if ((Object)(object)val == (Object)null) { Loggers.WARNING("Returning NULL terminal node @AddNodeManual!!!"); } return val; } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static TerminalNode AddNodeManual(string nodeName, ConfigEntry<string> stringValue, Func<string> commandAction, bool clearText, int CommandType, MainListing yourModListing, List<ManagedConfig> managedBools, string category = "", string description = "", int price = 0, Func<string> ConfirmAction = null, Func<string> DenyAction = null, string confirmText = "", string denyText = "", bool alwaysInStock = false, int maxStock = 1, string storeName = "", bool reuseFunc = false, string itemList = "") { TerminalNode val = null; List<string> list = new List<string>(); bool flag = true; if (stringValue != null) { flag = false; list = CommonStringStuff.GetKeywordsPerConfigItem(stringValue.Value); } foreach (string item in list) { val = BaseCommandCreation(nodeName, item, commandAction, clearText, CommandType, yourModListing, price, ConfirmAction, DenyAction, confirmText, denyText, alwaysInStock, maxStock, storeName, reuseFunc, itemList); } if ((Object)(object)val == (Object)null) { Loggers.WARNING("Returning NULL terminal node @AddNodeManual!!!"); } if (ManagedBoolGet.CanAddToManagedBoolList(managedBools, nodeName)) { TerminalMenuItem menuItem = new TerminalMenuItem { Category = category, itemDescription = description, ItemName = nodeName, itemKeywords = list }; ManagedConfig managedConfig = new ManagedConfig { TerminalNode = val, menuItem = menuItem, ConfigItemName = nodeName }; managedBools.Add(managedConfig); if (!flag) { ConfigSetup.AddManagedString(stringValue, ref managedBools, managedConfig); } } return val; } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static TerminalNode CreateNode(TerminalMenu terminalMenu, string nodeName, string keyWord, Func<string> commandAction, MainListing yourModListing, bool isNextPageCommand = false) { List<TerminalKeyword> list = Plugin.instance.Terminal.terminalNodes.allKeywords.ToList(); Loggers.LogDebug(nodeName ?? ""); Loggers.LogDebug(keyWord); bool clearPreviousText = true; CommonThings.CheckForAndDeleteKeyWord(keyWord.ToLower()); TerminalNode val = BasicTerminal.CreateNewTerminalNode(); ((Object)val).name = nodeName; val.displayText = nodeName; val.clearPreviousText = clearPreviousText; val.buyUnlockable = false; Loggers.LogDebug("node created"); TerminalKeyword val2 = BasicTerminal.CreateNewTerminalKeyword(nodeName + "_keyword", keyWord.ToLower()); val2.isVerb = false; val2.specialKeywordResult = val; Loggers.LogDebug("keyword created"); yourModListing.Listing.Add(val, commandAction); Loggers.LogDebug("func added to listing"); if (!isNextPageCommand) { terminalMenu.terminalNodePerCategory.Add(keyWord, val); Loggers.LogDebug("added terminalNode to menus nodelisting"); } list.Add(val2); Plugin.KeywordsAdded.Add(val2); Plugin.instance.Terminal.terminalNodes.allKeywords = list.ToArray(); Loggers.LogDebug("added to all keyword lists"); return val; } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static void InfoText(ManagedConfig managedBool, string keyWord, TerminalKeyword infoWord, MainListing yourModListing) { if (managedBool.InfoAction != null) { TerminalNode val = BasicTerminal.CreateNewTerminalNode(); ((Object)val).name = "info_" + keyWord; val.displayText = "infoAction should replace this"; yourModListing.Listing.Add(val, managedBool.InfoAction); val.clearPreviousText = true; AddCompatibleNoun(ref infoWord, keyWord, val); Loggers.LogDebug("info node created with infoAction!"); } else if (managedBool.InfoText.Length > 1) { TerminalNode val2 = BasicTerminal.CreateNewTerminalNode(); ((Object)val2).name = "info_" + keyWord; val2.displayText = managedBool.InfoText; val2.clearPreviousText = true; AddCompatibleNoun(ref infoWord, keyWord, val2); Loggers.LogDebug("info node created"); } } public static void AddToFauxListing(FauxKeyword fauxWord, MainListing yourListing) { if (fauxWord != null && fauxWord.Keyword != null && (Object)(object)fauxWord.MainPage != (Object)null) { yourListing.fauxKeywords.Add(fauxWord); } } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static TerminalNode CreateNode(ManagedConfig managedBool, string keyWord, MainListing yourModListing) { List<TerminalKeyword> list = Plugin.instance.Terminal.terminalNodes.allKeywords.ToList(); Func<string> mainAction = managedBool.MainAction; string text; if (managedBool.nodeName.Length < 2) { text = managedBool.ConfigItemName; Loggers.LogDebug("managedBool nodename is blank, using configitemname"); } else { text = managedBool.nodeName; Loggers.LogDebug("using nodeName: " + text); } bool clearText = managedBool.clearText; TerminalNode val = BaseCommandCreation(text, keyWord, mainAction, managedBool.clearText, managedBool.CommandType, yourModListing, managedBool.price, managedBool.ConfirmAction, managedBool.DenyAction, managedBool.confirmText, managedBool.denyText, managedBool.alwaysInStock, managedBool.maxStock, managedBool.storeName, managedBool.reuseFunc, managedBool.itemList); if ((Object)(object)val == (Object)null) { Loggers.WARNING("terminalNode is NULL at CreateNode!!!"); } return val; } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static void AddConfirm(string nodeName, ManagedConfig managedBool, Dictionary<TerminalNode, Func<string>> nodeListing, out CompatibleNoun confirm, out CompatibleNoun deny) { confirm = BasicTerminal.CreateCompatibleNoun(nodeName, "confirm", managedBool.confirmText, managedBool.price, managedBool.ConfirmAction, nodeListing); deny = BasicTerminal.CreateCompatibleNoun(nodeName, "deny", managedBool.denyText, managedBool.price, managedBool.DenyAction, nodeListing); } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static void AddConfirm(string nodeName, int price, Func<string> ConfirmAction, Func<string> DenyAction, string confirmText, string denyText, Dictionary<TerminalNode, Func<string>> nodeListing, out CompatibleNoun confirm, out CompatibleNoun deny) { confirm = BasicTerminal.CreateCompatibleNoun(nodeName, "confirm", confirmText, price, ConfirmAction, nodeListing); deny = BasicTerminal.CreateCompatibleNoun(nodeName, "deny", denyText, price, DenyAction, nodeListing); } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static void AddStoreCommand(string nodeName, ref TerminalKeyword keyword, ManagedConfig managedBool, MainListing mainListing, out CompatibleNoun confirm, out CompatibleNoun deny) { if ((Object)(object)managedBool.TerminalNode == (Object)null) { Loggers.ERROR("node is null when adding store command!!!"); confirm = null; deny = null; } else if (managedBool.ConfirmAction != null) { AddConfirm(nodeName, managedBool, mainListing.Listing, out confirm, out deny); StoreStuff(nodeName, managedBool.storeName, ref keyword, ref managedBool.TerminalNode, managedBool.price, managedBool.alwaysInStock, managedBool.maxStock, ref confirm, ref deny); } else { Loggers.ERROR("Shop nodes NEED confirmation, but confirmAction is null for " + nodeName + "!"); confirm = null; deny = null; } } [Obsolete("use CommandManager class, if equivalent method does not exist will exist in the future")] public static void AddStoreCommand(string nodeName, string storeName, ref TerminalKeyword keyword, ref TerminalNode node, int price, Func<string> ConfirmAction, Func<string> DenyAction, string confirmText, string denyText, MainListing mainListing, bool alwa