Decompiled source of OpenLib v0.1.8
OpenLib.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; 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 GameNetcodeStuff; using HarmonyLib; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using OpenLib.Common; using OpenLib.Compat; using OpenLib.ConfigManager; using OpenLib.CoreMethods; using OpenLib.Events; using OpenLib.Menus; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("OpenLib")] [assembly: AssemblyDescription("https://github.com/darmuh/OpenLib")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OpenLib")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e2700abc-7bc7-4bd0-b787-effe68445b6a")] [assembly: AssemblyFileVersion("0.1.8")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.8.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace OpenLib { [HarmonyPatch(typeof(StartOfRound), "Awake")] public class StartRoundAwake { public static void Postfix() { EventManager.StartOfRoundAwake.Invoke(); } } [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), "ChangeLevel")] public class RouteEvent { public static void Postfix() { EventManager.StartOfRoundChangeLevel.Invoke(); } } public class SpawnPatch { [HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")] public class PlayerSpawnPatch : MonoBehaviour { private static void Postfix() { EventManager.PlayerSpawn.Invoke(); } } } [HarmonyPatch(typeof(ShipTeleporter), "Awake")] public class TeleporterInit : ShipTeleporter { private static void Postfix(ShipTeleporter __instance) { EventManager.TeleporterAwake.Invoke(__instance); } } [HarmonyPatch(typeof(GameNetworkManager), "Start")] public class GameStartPatch { public static void Postfix() { EventManager.GameNetworkManagerStart.Invoke(); } } 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(Terminal), "Awake")] public class AwakeTermPatch : Terminal { private static void Postfix(Terminal __instance) { EventManager.TerminalAwake.Invoke(__instance); } } [HarmonyPatch(typeof(Terminal), "OnDisable")] public class DisableTermPatch : Terminal { private static void Postfix() { EventManager.TerminalDisable.Invoke(); } } [HarmonyPatch(typeof(Terminal), "QuitTerminal")] public class QuitTerminalPatch : Terminal { private static void Postfix() { EventManager.TerminalQuit.Invoke(); } } [HarmonyPatch(typeof(Terminal), "LoadNewNode")] public class LoadNewNodePatch : Terminal { private static void Postfix(TerminalNode node) { EventManager.TerminalLoadNewNode.Invoke(node); } } [HarmonyPatch(typeof(Terminal), "Start")] public class TerminalStartPatch : Terminal { private static void Postfix() { EventManager.TerminalStart.Invoke(); } } [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) { TerminalNode val = EventManager.TerminalParseSent.NodeInvoke(ref __result); __result = val; } } [HarmonyPatch(typeof(Terminal), "SetTerminalInUseClientRpc")] public class TerminalInUseRpcPatch { private static void Postfix() { EventManager.SetTerminalInUse.Invoke(); } } [HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")] public class AffordableNodePatch { private static void Postfix(TerminalNode node) { EventManager.TerminalLoadIfAffordable.Invoke(node); } } [BepInPlugin("darmuh.OpenLib", "OpenLib", "0.1.8")] public class Plugin : BaseUnityPlugin { public static class PluginInfo { public const string PLUGIN_GUID = "darmuh.OpenLib"; public const string PLUGIN_NAME = "OpenLib"; public const string PLUGIN_VERSION = "0.1.8"; } public static Plugin instance; internal static ManualLogSource Log; public bool LobbyCompat = false; public bool TerminalFormatter = false; public static List<TerminalKeyword> keywordsAdded = new List<TerminalKeyword>(); public static List<TerminalNode> nodesAdded = new List<TerminalNode>(); public Terminal Terminal; public static List<TerminalNode> ShopNodes = new List<TerminalNode>(); private void Awake() { instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"OpenLib is loading with version 0.1.8!"); ConfigSetup.defaultManaged = new List<ManagedConfig>(); ConfigSetup.defaultListing = new MainListing(); CommandRegistry.InitListing(ref ConfigSetup.defaultListing); ConfigSetup.BindConfigSettings(); ((BaseUnityPlugin)this).Config.ConfigReloaded += OnConfigReloaded; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); EventUsage.Subscribers(); 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); } internal static void MoreLogs(string message) { if (ConfigSetup.ExtensiveLogging.Value) { Log.LogInfo((object)message); } } internal static void Spam(string message) { if (ConfigSetup.DeveloperLogging.Value) { Log.LogDebug((object)message); } } internal static void ERROR(string message) { Log.LogError((object)message); } internal static void WARNING(string message) { Log.LogWarning((object)message); } } } namespace OpenLib.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("OpenLib.Properties.Resources", typeof(Resources).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal Resources() { } } } namespace OpenLib.Menus { public class MenuStuff { } public class TerminalMenu { public string MenuName; public string MainMenuText; public string setKeyword; public List<TerminalMenuCategory> Categories = new List<TerminalMenuCategory>(); public string currentCategory; public bool isActive; public bool isNextEnabled; public int nextCount = 1; public List<TerminalMenuItem> menuItems; 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 void Delete() { MenuBuild.allMenus.Remove(this); menuItems.Clear(); categoryLists.Clear(); Categories.Clear(); terminalNodePerCategory.Clear(); terminalNodes.Clear(); } } public class TerminalMenuItem { public string ItemName; public string Category; public List<string> itemKeywords; public string itemDescription; public void Delete() { itemDescription = ""; Category = ""; ItemName = ""; if (itemKeywords.Count > 0) { itemKeywords.Clear(); } } } public class TerminalMenuCategory { public string CatName; public string CatDescription; } public class MenuBuild { public static bool isNextEnabled = false; public static int nextCount = 1; public static string currentCategory = ""; public static TerminalMenu currentMenu; public static List<TerminalMenu> allMenus = new List<TerminalMenu>(); public static List<TerminalMenuCategory> InitCategories(Dictionary<string, string> CategoryItems) { Plugin.Spam("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); } Plugin.Spam("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>(); foreach (ManagedConfig managedBool in managedBools) { if (managedBool.menuItem != null) { list.Add(managedBool.menuItem); } } Plugin.Spam("\n\n\n"); Plugin.Spam($"myMenuItems count: {list.Count}"); Plugin.Spam("\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 (((Object)terminalNode).name.Contains(terminalMenu.MenuName)) { terminalMenu.isActive = true; terminalMenu.nextCount = 1; terminalMenu.currentCategory = ""; Plugin.Spam("In main menu of " + terminalMenu.MenuName); return true; } if (terminalMenu.isNextEnabled && terminalMenu.terminalNodes.Contains(terminalNode)) { Plugin.Spam("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) { Plugin.Spam("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 UpdateCategories(TerminalMenu myMenu) { List<Dictionary<string, List<string>>> list = new List<Dictionary<string, List<string>>>(); foreach (TerminalMenuCategory category in myMenu.Categories) { Plugin.Spam("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) { Plugin.Spam("2.1"); List<string> result = new List<string>(); foreach (TerminalMenu allMenu in allMenus) { Plugin.Spam("2.2"); if (!allMenu.isActive) { continue; } for (int i = 0; i < allMenu.Categories.Count; i++) { Plugin.Spam("2.3"); foreach (KeyValuePair<string, List<string>> item in allMenu.categoryLists[i]) { if (item.Key.ToLower() == catName.ToLower()) { Plugin.Spam("categorylist found!!!"); menuName = allMenu; return item.Value; } } } } Plugin.Spam("2.1 FAIL"); menuName = null; return result; } public static Dictionary<string, List<string>> MakeCategoryList(TerminalMenuCategory category, List<TerminalMenuItem> terminalMenuItems) { Plugin.Spam("MakeCategoryList START"); string catName = category.CatName; Plugin.Spam(catName); List<string> list = new List<string>(); Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); Plugin.Spam($"count: {terminalMenuItems.Count}"); foreach (TerminalMenuItem terminalMenuItem in terminalMenuItems) { Plugin.Spam("checking " + terminalMenuItem.ItemName); if (terminalMenuItem.Category.ToLower() == catName.ToLower()) { list.Add("> " + CommonStringStuff.GetKeywordsForMenuItem(terminalMenuItem.itemKeywords) + "\r\n" + terminalMenuItem.itemDescription + "\r\n"); Plugin.Spam(CommonStringStuff.GetKeywordsForMenuItem(terminalMenuItem.itemKeywords) + " added"); Plugin.Spam(terminalMenuItem.itemDescription + " added too!"); } } Plugin.Spam("setting catName list"); dictionary.Add(catName, list); Plugin.Spam("MakeCategoryList END"); return dictionary; } public static string NextInList() { if (!isNextEnabled) { return "Not currently in any menus...\r\n\r\n"; } Plugin.Spam("currentCategory = " + currentCategory); nextCount++; 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); Plugin.Spam($"currentCategory:{currentCategory} nextCount: {nextCount} isNextEnabled: {isNextEnabled}"); menuName.isNextEnabled = isNextEnabled; return nextPage; } public static string GetFirstInList() { Plugin.Spam("1"); nextCount = 1; currentCategory = GetCategoryFromNode(CommonTerminal.parseNode); Plugin.Spam("2"); TerminalMenu menuName; List<string> categoryList = GetCategoryList(currentCategory, out menuName); menuName.isActive = true; menuName.nextCount = nextCount; menuName.currentCategory = currentCategory; Plugin.Spam("3"); string nextPage = CommonStringStuff.GetNextPage(categoryList, currentCategory, 4, 1, out isNextEnabled); menuName.isNextEnabled = isNextEnabled; Plugin.Spam("4"); return nextPage; } public static string GetCategoryFromNode(TerminalNode givenNode) { Plugin.Spam("1.1"); if ((Object)(object)givenNode == (Object)null) { Plugin.ERROR("givenNode is null!!!!"); return ""; } foreach (TerminalMenu allMenu in allMenus) { if (!allMenu.terminalNodePerCategory.ContainsValue(givenNode)) { Plugin.Spam("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) { Plugin.Spam("FOUND NODE AND PAIR " + item.Key); allMenu.isActive = true; return item.Key; } } } Plugin.ERROR("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 }; } return null; } } } namespace OpenLib.Common { public class CommonEnums { public static bool quitTerminalEnum; public static IEnumerator TerminalQuitter(Terminal terminal) { if (!quitTerminalEnum) { quitTerminalEnum = true; yield return (object)new WaitForSeconds(0.5f); terminal.QuitTerminal(true); quitTerminalEnum = false; } } public static IEnumerator TerminalQuitter(Terminal terminal, bool syncTerminalInUse) { if (!quitTerminalEnum) { quitTerminalEnum = true; yield return (object)new WaitForSeconds(0.5f); terminal.QuitTerminal(syncTerminalInUse); quitTerminalEnum = false; } } } public class CommonTerminal { public static TerminalNode parseNode; public static void ToggleScreen(bool status) { ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(Plugin.instance.Terminal.waitUntilFrameEndToSetActive(status)); Plugin.Spam($"Screen set to {status}"); } public static TerminalNode GetNodeFromList(string query, Dictionary<string, TerminalNode> nodeListing) { foreach (KeyValuePair<string, TerminalNode> item in nodeListing) { if (item.Key == query) { return item.Value; } } return null; } public static void AddShopItemsToFurnitureList(List<TerminalNode> UnlockableNodes) { foreach (TerminalNode UnlockableNode in UnlockableNodes) { if (!Plugin.instance.Terminal.ShipDecorSelection.Contains(UnlockableNode)) { Plugin.instance.Terminal.ShipDecorSelection.Add(UnlockableNode); Plugin.Spam("adding " + UnlockableNode.creatureName + " to shipdecorselection"); } else { Plugin.Spam(UnlockableNode.creatureName + " already in shipdecorselection"); } } Plugin.Spam("nodes have been added"); } public static string ClearText() { string result = "\n"; Plugin.Spam("display text cleared for real this time!!!"); return result; } } public class Misc { public static PlayerControllerB GetPlayerFromName(string playerName) { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.playerUsername.ToLower() == playerName) { return val; } } return null; } public static PlayerControllerB GetPlayerUsingTerminal() { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!val.isPlayerDead && (Object)(object)val.currentTriggerInAnimationWith == (Object)(object)Plugin.instance.Terminal.terminalTrigger) { Plugin.MoreLogs("Player: " + val.playerUsername + " detected using terminal."); return val; } } return null; } public static int HostClientID() { PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.isHostPlayerObject) { Plugin.MoreLogs($"Player: {val.playerUsername} is the host, client ID: {val.playerClientId}."); return (int)val.playerClientId; } } return -1; } public static Color HexToColor(string hex) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); ColorUtility.TryParseHtmlString(hex, ref result); return result; } public static void LogColorBeforeChange(Color color, ConfigEntry<string> entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string text = ColorUtility.ToHtmlStringRGB(color); Plugin.Log.LogDebug((object)("Previous Color noted as [" + text + "] for configItem - " + ((ConfigEntryBase)entry).Definition.Key)); } } public class CommonStringStuff { public static string GetNextPage(List<string> categoryItems, string categoryTitle, int pageSize, int currentPage, out bool isNextEnabled) { currentPage = Mathf.Clamp(currentPage, 1, Mathf.CeilToInt((float)categoryItems.Count / (float)pageSize)); int num = (currentPage - 1) * pageSize; int num2 = Mathf.Min(num + pageSize, categoryItems.Count); int num3 = 0; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("============ All [" + categoryTitle.ToUpper() + "] Commands ============"); stringBuilder.Append("\r\n"); for (int i = num; i < num2; i++) { string text = categoryItems[i]; stringBuilder.Append(text + "\r\n"); num3++; } int num4 = pageSize - num3; for (int j = 0; j < num4; j++) { stringBuilder.Append("\r\n"); } stringBuilder.Append("\r\n"); stringBuilder.Append($"Page {currentPage}/{Mathf.CeilToInt((float)categoryItems.Count / (float)pageSize)}\r\n"); if (num2 < categoryItems.Count) { stringBuilder.Append("Type next to see the next page of [" + categoryTitle + "] commands!\r\n"); isNextEnabled = true; } else { isNextEnabled = false; } return stringBuilder.ToString(); } public static string[] GetWords() { string text = Plugin.instance.Terminal.screenText.text.Substring(Plugin.instance.Terminal.screenText.text.Length - Plugin.instance.Terminal.textAdded); return text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } public static string[] GetWordsAndKeyword(List<string> configItemWords, string[] words) { List<string> list = new List<string>(); bool flag = false; foreach (string text in words) { Plugin.MoreLogs("checking " + text); foreach (string configItemWord in configItemWords) { if (configItemWord.Contains(text)) { list.Add(configItemWord); flag = true; Plugin.MoreLogs("adding " + configItemWord + " to list"); break; } } if (!flag) { list.Add(text); Plugin.MoreLogs("adding non-keyword, word: " + text); } } return list.ToArray(); } public static List<string> GetKeywordsPerConfigItem(string configItem) { List<string> result = new List<string>(); if (configItem.Length > 0) { result = (from item in configItem.Split(new char[1] { ';' }) select item.TrimStart(Array.Empty<char>())).ToList(); } return result; } public static List<string> GetKeywordsPerConfigItem(string configItem, char separator) { List<string> result = new List<string>(); if (configItem.Length > 0) { result = (from item in configItem.Split(new char[1] { separator }) select item.TrimStart(Array.Empty<char>())).ToList(); } return result; } public static List<int> GetNumberListFromStringList(List<string> stringList) { List<int> list = new List<int>(); foreach (string @string in stringList) { if (int.TryParse(@string, out var result)) { list.Add(result); } else { Plugin.ERROR("Could not parse " + @string + " to integer"); } } return list; } public static List<string> GetItemList(string rawList) { List<string> result = new List<string>(); if (rawList.Length > 0) { result = (from item in rawList.Split(new char[1] { ',' }) select item.TrimStart(Array.Empty<char>())).ToList(); } return result; } public static List<string> GetListToLower(List<string> stringList) { List<string> list = new List<string>(); foreach (string @string in stringList) { list.Add(@string.ToLower()); } return list; } public static string GetKeywordsForMenuItem(List<string> itemKeywords) { StringBuilder stringBuilder = new StringBuilder(); foreach (string itemKeyword in itemKeywords) { stringBuilder.Append(itemKeyword + ", "); } string text = stringBuilder.ToString(); return text.Remove(text.Length - 2); } public static string GetCleanedScreenText(Terminal __instance) { string s = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded); return RemovePunctuation(s); } public static string RemovePunctuation(string s) { StringBuilder stringBuilder = new StringBuilder(); foreach (char c in s) { if (!char.IsPunctuation(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString().ToLower(); } } public class StartGame { internal static bool oneTimeOnly; internal static void CompatibilityCheck() { if (SoftCompatibility("BMX.LobbyCompatibility", ref Plugin.instance.LobbyCompat)) { Plugin.Spam("LobbyCompatibility detected, setting appropriate Lobby Compatibility Level depending on networking status"); BMX_LobbyCompat.SetCompat(isNetworked: false); } if (SoftCompatibility("TerminalFormatter", ref Plugin.instance.TerminalFormatter)) { Plugin.Spam("Terminal Formatter by mrov detected!"); } } internal static void OnGameStart() { CompatibilityCheck(); oneTimeOnly = false; } public static bool SoftCompatibility(string PluginGUID, ref bool isDetected) { if (Chainloader.PluginInfos.ContainsKey(PluginGUID)) { string name = Assembly.GetCallingAssembly().GetName().Name; isDetected = true; Plugin.Log.LogInfo((object)$"{PluginGUID} detected! Plugin: {name} has set compatibility bool - {isDetected}"); return isDetected; } return isDetected = false; } } public class Teleporter { public static ShipTeleporter NormalTP; public static ShipTeleporter InverseTP; public static void CheckTeleporterTypeAndAssign(ShipTeleporter instance) { if (instance.isInverseTeleporter) { ITPexists(instance); } else { TPexists(instance); } } public static void TPexists(ShipTeleporter instance) { NormalTP = instance; Plugin.MoreLogs("NormalTP instance detected and set."); EventManager.NormalTPFound.Invoke(); } public static void ITPexists(ShipTeleporter instance) { InverseTP = instance; Plugin.MoreLogs("InverseTP instance detected and set."); EventManager.InverseTPFound.Invoke(); } } public class TerminalStart { public static bool delayStartEnum; internal static void TerminalStartGroupDelay() { Plugin.Spam("Starting TerminalDelayStartEnumerator"); ((MonoBehaviour)Plugin.instance.Terminal).StartCoroutine(TerminalDelayStartEnumerator()); } internal static IEnumerator TerminalDelayStartEnumerator() { if (!delayStartEnum) { delayStartEnum = true; yield return (object)new WaitForSeconds(1f); Plugin.MoreLogs("1 Second delay methods starting."); EventManager.TerminalDelayStart.Invoke(); AddStoreItems(); delayStartEnum = false; } } public static void AddStoreItems() { if (!Plugin.instance.TerminalFormatter) { AddShopItemsToFurnitureList(); } } private static void AddShopItemsToFurnitureList() { foreach (TerminalNode shopNode in Plugin.ShopNodes) { if (!Plugin.instance.Terminal.ShipDecorSelection.Contains(shopNode)) { Plugin.instance.Terminal.ShipDecorSelection.Add(shopNode); Plugin.Spam("adding " + shopNode.creatureName + " to shipdecorselection"); } else { Plugin.Spam(shopNode.creatureName + " already in shipdecorselection"); } } Plugin.Spam("nodes have been added"); } } } 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 SetTerminalInUse = 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.CustomEvent<TerminalNode> GetNewDisplayText = new Events.CustomEvent<TerminalNode>(); 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 PlayerSpawn = 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 TerminalDelayStart = new Events.CustomEvent(); } 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 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() { this.OnEvent?.Invoke(); } public void AddListener(Event listener) { OnEvent += listener; Listeners++; } public void RemoveListener(Event listener) { OnEvent -= listener; Listeners--; } } } public class EventUsage { public static List<ConfigFile> configsToReload = new List<ConfigFile>(); public static void Subscribers() { EventManager.TerminalAwake.AddListener(OnTerminalAwake); EventManager.TerminalStart.AddListener(OnTerminalStart); 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); } public static void OnTerminalAwake(Terminal instance) { Plugin.instance.Terminal = instance; Plugin.MoreLogs("Setting Plugin.instance.Terminal"); CommandRegistry.GetCommandsToAdd(ConfigSetup.defaultManaged, ConfigSetup.defaultListing); } public static void OnTerminalDisable() { RemoveThings.OnTerminalDisable(); TerminalStart.delayStartEnum = false; ListManagement.ClearLists(); foreach (ConfigFile item in configsToReload) { Plugin.Spam("reloading config from list"); item.Save(); item.Reload(); } configsToReload.Clear(); } public static void OnTerminalStart() { TerminalStart.TerminalStartGroupDelay(); } public static void OnUsingTerminal() { Plugin.MoreLogs("Start Using Terminal Postfix"); } public static TerminalNode OnParseSent(ref TerminalNode node) { Plugin.Spam("parse event"); if ((Object)(object)node == (Object)null) { Plugin.ERROR("node detected as NULL"); return node; } string cleanedScreenText = CommonStringStuff.GetCleanedScreenText(Plugin.instance.Terminal); if (cleanedScreenText.Length > 0) { string[] array = cleanedScreenText.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (ConfigSetup.defaultListing.specialListString.ContainsKey(array[0])) { TerminalNode nodeFromList = CommonTerminal.GetNodeFromList(array[0], ConfigSetup.defaultListing.specialListString); node = nodeFromList; } } if (LogicHandling.GetNewDisplayText(ConfigSetup.defaultListing, ref node)) { Plugin.MoreLogs("node found: " + ((Object)node).name); } return node; } public static void OnLoadNewNode(TerminalNode node) { Plugin.Spam($"listing count: {ConfigSetup.defaultListing.Listing.Count}"); if ((Object)(object)node != (Object)null) { Plugin.Spam(((Object)node).name + " has been loaded"); } } } } 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; List<CompatibleNoun> list3 = new List<CompatibleNoun>(); TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val).name = keyWord + "_keyword"; val.word = keyWord.ToLower(); val.isVerb = false; val.specialKeywordResult = existingNode; if (existingNode.terminalOptions != null) { CompatibleNoun[] terminalOptions = existingNode.terminalOptions; List<CompatibleNoun> list4 = new List<CompatibleNoun>(terminalOptions.Length); list4.AddRange(terminalOptions); list3 = list4; Plugin.Spam(((Object)existingNode).name + " has existing terminalOptions"); } CompatibleNoun item = new CompatibleNoun { noun = val, result = existingNode }; list3.Add(item); existingNode.terminalOptions = list3.ToArray(); list2.Add(val); if (addToList) { Plugin.keywordsAdded.Add(val); } Plugin.Spam("Adding " + keyWord + " to existing node " + ((Object)existingNode).name); Plugin.instance.Terminal.terminalNodes.allKeywords = list2.ToArray(); } public static TerminalKeyword AddKeywordToNode(string keyWord, TerminalNode existingNode, bool addToList = true) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; List<CompatibleNoun> list3 = new List<CompatibleNoun>(); TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val).name = keyWord + "_keyword"; val.word = keyWord.ToLower(); val.isVerb = false; val.specialKeywordResult = existingNode; if (existingNode.terminalOptions != null) { CompatibleNoun[] terminalOptions = existingNode.terminalOptions; List<CompatibleNoun> list4 = new List<CompatibleNoun>(terminalOptions.Length); list4.AddRange(terminalOptions); list3 = list4; Plugin.Spam(((Object)existingNode).name + " has existing terminalOptions"); } CompatibleNoun item = new CompatibleNoun { noun = val, result = existingNode }; list3.Add(item); existingNode.terminalOptions = list3.ToArray(); list2.Add(val); if (addToList) { Plugin.keywordsAdded.Add(val); } Plugin.Spam("Adding " + keyWord + " to existing node " + ((Object)existingNode).name); Plugin.instance.Terminal.terminalNodes.allKeywords = list2.ToArray(); return val; } public static void AddToHelpCommand(string textToAdd) { TerminalNode val = Plugin.instance.Terminal.terminalNodes.specialNodes[13]; if (val.displayText.Contains(textToAdd)) { Plugin.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; } Plugin.Spam($"oldtext length {existingNode.displayText.Length}"); Plugin.Spam(existingNode.displayText); string text = existingNode.displayText.TrimEnd(NewLineChars); text = text + "\n" + textToAdd + "\r\n\r\n"; existingNode.displayText = text; Plugin.Spam(((Object)existingNode).name + " text updated!!!"); } public static TerminalNode CreateDummyNode(string nodeName, bool clearPrevious, string displayText) { if (DynamicBools.UseMatchingNode(nodeName, out var returnNode)) { returnNode.displayText = displayText; returnNode.clearPreviousText = clearPrevious; } else { returnNode = ScriptableObject.CreateInstance<TerminalNode>(); ((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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) TerminalNode existingNode = LogicHandling.GetFromAllNodes("OtherCommands"); TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; if (!DynamicBools.IsCommandCreatedAlready(keyWord, displayText, list2)) { CommonThings.CheckForAndDeleteKeyWord(keyWord.ToLower()); TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = nodeName; val.displayText = displayText; val.clearPreviousText = clearText; TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val2).name = nodeName + "_keyword"; val2.word = keyWord.ToLower(); val2.isVerb = isVerb; val2.specialKeywordResult = val; new CompatibleNoun { noun = val2, result = val }; list2.Add(val2); Plugin.instance.Terminal.terminalNodes.allKeywords = list2.ToArray(); if (!Plugin.nodesAdded.Contains(val)) { Plugin.nodesAdded.Add(val); } if (!Plugin.keywordsAdded.Contains(val2)) { Plugin.keywordsAdded.Add(val2); } if (category.ToLower() == "other") { AddToExistingNodeText(keywordDescription ?? "", ref existingNode); Plugin.Spam("adding node to other listing"); } } } 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 result = null; List<string> list = new List<string>(); if (stringValue != null) { list = CommonStringStuff.GetKeywordsPerConfigItem(stringValue); } foreach (string item in list) { TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list2 = new List<TerminalKeyword>(allKeywords.Length); list2.AddRange(allKeywords); List<TerminalKeyword> list3 = list2; if (DynamicBools.IsCommandCreatedAlready(yourModListing.Listing, item, commandAction, list3, out var _) && !reuseFunc) { continue; } CommonThings.CheckForAndDeleteKeyWord(item.ToLower()); if (DynamicBools.DoesNodeExist(yourModListing.Listing, commandAction, out var node) && !reuseFunc) { AddKeywordToExistingNode(item, node); Plugin.Spam("existing node found " + ((Object)node).name + ", reusing associated func and adding additional keyword " + item); continue; } TerminalNode node2 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)node2).name = nodeName; node2.displayText = nodeName; node2.clearPreviousText = clearText; node2.buyUnlockable = false; result = node2; TerminalKeyword keyword = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)keyword).name = nodeName + "_keyword"; keyword.word = item.ToLower(); keyword.isVerb = false; keyword.specialKeywordResult = node2; CompatibleNoun confirm = null; CompatibleNoun deny = null; switch (CommandType) { case 1: AddConfirm(nodeName, price, ConfirmAction, DenyAction, confirmText, denyText, yourModListing.Listing, out confirm, out deny); node2.acceptAnything = false; Plugin.Spam("command type 1 detected, adding basic confirmation"); break; case 2: AddStoreCommand(nodeName, storeName, ref keyword, ref node2, price, ConfirmAction, DenyAction, confirmText, denyText, yourModListing, alwaysInStock, maxStock, out confirm, out deny); Plugin.Spam("command type 2 detected, adding store logic"); node2.acceptAnything = false; yourModListing.shopNodes.Add(confirm.result); yourModListing.shopNodes.Add(node2); yourModListing.shopNodes.Add(deny.result); if (itemList.Length > 1) { confirm.result.buyUnlockable = false; yourModListing.storePacks.Add(node2, itemList); Plugin.Spam("storepack detected, adding itemlist"); } break; } if (confirm != null && deny != null) { list3.Add(confirm.noun); Plugin.keywordsAdded.Add(confirm.noun); list3.Add(deny.noun); Plugin.keywordsAdded.Add(deny.noun); node2.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny }; node2.overrideOptions = true; } else { Plugin.Spam("no confirmation logic added for " + item); } yourModListing.Listing.Add(node2, commandAction); list3.Add(keyword); if (!Plugin.nodesAdded.Contains(node2)) { Plugin.nodesAdded.Add(node2); } if (!Plugin.keywordsAdded.Contains(keyword)) { Plugin.keywordsAdded.Add(keyword); } Plugin.instance.Terminal.terminalNodes.allKeywords = list3.ToArray(); } return result; } 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) { TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list2 = new List<TerminalKeyword>(allKeywords.Length); list2.AddRange(allKeywords); List<TerminalKeyword> list3 = list2; if (DynamicBools.IsCommandCreatedAlready(yourModListing.Listing, item, commandAction, list3, out var _) && !reuseFunc) { continue; } CommonThings.CheckForAndDeleteKeyWord(item.ToLower()); if (DynamicBools.DoesNodeExist(yourModListing.Listing, commandAction, out var node) && !reuseFunc) { AddKeywordToExistingNode(item, node); Plugin.Spam("existing node found " + ((Object)node).name + ", reusing associated func and adding additional keyword " + item); continue; } TerminalNode node2 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)node2).name = nodeName; node2.displayText = nodeName; node2.clearPreviousText = clearText; node2.buyUnlockable = false; val = node2; TerminalKeyword keyword = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)keyword).name = nodeName + "_keyword"; keyword.word = item.ToLower(); keyword.isVerb = false; keyword.specialKeywordResult = node2; CompatibleNoun confirm = null; CompatibleNoun deny = null; switch (CommandType) { case 1: AddConfirm(nodeName, price, ConfirmAction, DenyAction, confirmText, denyText, yourModListing.Listing, out confirm, out deny); node2.acceptAnything = false; Plugin.Spam("command type 1 detected, adding basic confirmation"); break; case 2: AddStoreCommand(nodeName, storeName, ref keyword, ref node2, price, ConfirmAction, DenyAction, confirmText, denyText, yourModListing, alwaysInStock, maxStock, out confirm, out deny); Plugin.Spam("command type 2 detected, adding store logic"); node2.acceptAnything = false; yourModListing.shopNodes.Add(confirm.result); yourModListing.shopNodes.Add(node2); yourModListing.shopNodes.Add(deny.result); if (itemList.Length > 1) { confirm.result.buyUnlockable = false; yourModListing.storePacks.Add(node2, itemList); Plugin.Spam("storepack detected, adding itemlist"); } break; } if (confirm != null && deny != null) { list3.Add(confirm.noun); Plugin.keywordsAdded.Add(confirm.noun); list3.Add(deny.noun); Plugin.keywordsAdded.Add(deny.noun); node2.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny }; node2.overrideOptions = true; } else { Plugin.Spam("no confirmation logic added for " + item); } yourModListing.Listing.Add(node2, commandAction); list3.Add(keyword); if (!Plugin.nodesAdded.Contains(node2)) { Plugin.nodesAdded.Add(node2); } if (!Plugin.keywordsAdded.Contains(keyword)) { Plugin.keywordsAdded.Add(keyword); } Plugin.instance.Terminal.terminalNodes.allKeywords = list3.ToArray(); } 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; } public static TerminalNode CreateNode(TerminalMenu terminalMenu, string nodeName, string keyWord, Func<string> commandAction, MainListing yourModListing, bool isNextPageCommand = false) { TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; Plugin.Spam(nodeName ?? ""); Plugin.Spam(keyWord); bool clearPreviousText = true; CommonThings.CheckForAndDeleteKeyWord(keyWord.ToLower()); TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = nodeName; val.displayText = nodeName; val.clearPreviousText = clearPreviousText; val.buyUnlockable = false; Plugin.Spam("node created"); TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val2).name = nodeName + "_keyword"; val2.word = keyWord.ToLower(); val2.isVerb = false; val2.specialKeywordResult = val; Plugin.Spam("keyword created"); yourModListing.Listing.Add(val, commandAction); Plugin.Spam("func added to listing"); if (!isNextPageCommand) { terminalMenu.terminalNodePerCategory.Add(keyWord, val); Plugin.Spam("added terminalNode to menus nodelisting"); } list2.Add(val2); Plugin.keywordsAdded.Add(val2); Plugin.instance.Terminal.terminalNodes.allKeywords = list2.ToArray(); Plugin.Spam("added to all keyword lists"); return val; } public static TerminalNode CreateNode(ManagedConfig managedBool, string keyWord, MainListing yourModListing) { TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; Func<string> mainAction = managedBool.MainAction; string text; if (managedBool.nodeName.Length < 2) { text = managedBool.ConfigItemName; Plugin.Spam("managedBool nodename is blank, using configitemname"); } else { text = managedBool.nodeName; Plugin.Spam("using nodeName: " + text); } bool clearText = managedBool.clearText; if (DynamicBools.IsCommandCreatedAlready(yourModListing.Listing, keyWord, mainAction, list2, out var outKeyword) && !managedBool.reuseFunc) { return outKeyword.specialKeywordResult; } CommonThings.CheckForAndDeleteKeyWord(keyWord.ToLower()); if (DynamicBools.DoesNodeExist(yourModListing.Listing, mainAction, out var node) && !managedBool.reuseFunc) { AddKeywordToExistingNode(keyWord, node); Plugin.Spam("existing node found " + ((Object)node).name + ", re-using func and adding additional keyword " + keyWord); return node; } TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = text; val.displayText = text; val.clearPreviousText = clearText; val.buyUnlockable = false; managedBool.TerminalNode = val; TerminalKeyword keyword = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)keyword).name = text + "_keyword"; keyword.word = keyWord.ToLower(); keyword.isVerb = false; keyword.specialKeywordResult = val; CompatibleNoun confirm = null; CompatibleNoun deny = null; if (managedBool.CommandType == 1) { AddConfirm(text, managedBool, out confirm, out deny); if (managedBool.ConfirmAction != null) { yourModListing.Listing.Add(confirm.result, managedBool.ConfirmAction); Plugin.Spam("confirmResult FUNC added"); } if (managedBool.DenyAction != null) { yourModListing.Listing.Add(deny.result, managedBool.DenyAction); Plugin.Spam("denyResult FUNC added"); } val.acceptAnything = false; Plugin.Spam("command type 1 detected, adding basic confirmation"); } else if (managedBool.CommandType == 2) { AddStoreCommand(text, ref keyword, managedBool, yourModListing, out confirm, out deny); Plugin.Spam("command type 2 detected, adding store logic"); val.acceptAnything = false; yourModListing.shopNodes.Add(confirm.result); yourModListing.shopNodes.Add(val); yourModListing.shopNodes.Add(deny.result); if (managedBool.itemList.Length > 1) { confirm.result.buyUnlockable = false; yourModListing.storePacks.Add(val, managedBool.itemList); Plugin.Spam("storepack detected, adding itemlist"); } } if (confirm != null && deny != null) { list2.Add(confirm.noun); Plugin.keywordsAdded.Add(confirm.noun); list2.Add(deny.noun); Plugin.keywordsAdded.Add(deny.noun); val.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny }; val.overrideOptions = true; } else { Plugin.Spam("no confirmation logic added for " + keyWord); } yourModListing.Listing.Add(val, mainAction); list2.Add(keyword); if (!Plugin.nodesAdded.Contains(val)) { Plugin.nodesAdded.Add(val); } if (!Plugin.keywordsAdded.Contains(keyword)) { Plugin.keywordsAdded.Add(keyword); } Plugin.instance.Terminal.terminalNodes.allKeywords = list2.ToArray(); return val; } public static void AddConfirm(string nodeName, ManagedConfig managedBool, out CompatibleNoun confirm, out CompatibleNoun deny) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown confirm = new CompatibleNoun { noun = ScriptableObject.CreateInstance<TerminalKeyword>() }; confirm.noun.word = "confirm"; confirm.noun.isVerb = true; confirm.result = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)confirm.result).name = nodeName + "_confirm"; confirm.result.displayText = managedBool.confirmText; confirm.result.clearPreviousText = true; confirm.result.itemCost = managedBool.price; confirm.noun.specialKeywordResult = confirm.result; deny = new CompatibleNoun { noun = ScriptableObject.CreateInstance<TerminalKeyword>() }; deny.noun.word = "deny"; deny.noun.isVerb = true; deny.result = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)deny.result).name = nodeName + "_deny"; deny.result.displayText = managedBool.denyText; deny.result.clearPreviousText = true; deny.noun.specialKeywordResult = deny.result; } 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) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown confirm = new CompatibleNoun { noun = ScriptableObject.CreateInstance<TerminalKeyword>() }; confirm.noun.word = "confirm"; confirm.noun.isVerb = true; confirm.result = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)confirm.result).name = nodeName + "_confirm"; confirm.result.displayText = confirmText; confirm.result.clearPreviousText = true; confirm.result.itemCost = price; confirm.noun.specialKeywordResult = confirm.result; if (ConfirmAction != null) { nodeListing.Add(confirm.result, ConfirmAction); } deny = new CompatibleNoun { noun = ScriptableObject.CreateInstance<TerminalKeyword>() }; deny.noun.word = "deny"; deny.noun.isVerb = true; deny.result = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)deny.result).name = nodeName + "_deny"; deny.result.displayText = denyText; deny.result.clearPreviousText = true; deny.noun.specialKeywordResult = deny.result; if (DenyAction != null) { nodeListing.Add(deny.result, DenyAction); } } public static void AddStoreCommand(string nodeName, ref TerminalKeyword keyword, ManagedConfig managedBool, MainListing mainListing, out CompatibleNoun confirm, out CompatibleNoun deny) { TerminalNode terminalNode = managedBool.TerminalNode; if ((Object)(object)terminalNode == (Object)null) { Plugin.ERROR("Unable to retrieve managedBool TerminalNode"); confirm = null; deny = null; } else if (managedBool.ConfirmAction != null) { AddConfirm(nodeName, managedBool, out confirm, out deny); confirm.result.buyUnlockable = true; if (managedBool.ConfirmAction != null) { mainListing.Listing.Add(confirm.result, managedBool.ConfirmAction); Plugin.Spam("confirmResult FUNC added"); } if (managedBool.DenyAction != null) { mainListing.Listing.Add(deny.result, managedBool.DenyAction); Plugin.Spam("denyResult FUNC added"); } terminalNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny }; UnlockableItem item = AddUnlockable(managedBool); if (!StartOfRound.Instance.unlockablesList.unlockables.Contains(item)) { StartOfRound.Instance.unlockablesList.unlockables.Add(item); } int num = StartOfRound.Instance.unlockablesList.unlockables.IndexOf(item); Plugin.Spam($"new unlockable found at {num} out of count: {StartOfRound.Instance.unlockablesList.unlockables.Count}"); terminalNode.creatureName = managedBool.storeName; terminalNode.shipUnlockableID = num; terminalNode.itemCost = managedBool.price; terminalNode.overrideOptions = true; confirm.result.shipUnlockableID = num; confirm.result.buyUnlockable = true; confirm.result.itemCost = managedBool.price; if (DynamicBools.TryGetKeyword("buy", out var terminalKeyword)) { AddToBuyWord(ref terminalKeyword, ref keyword, item); } Plugin.ShopNodes.Add(terminalNode); Plugin.Spam("Store nodes created for " + managedBool.storeName); } else { Plugin.ERROR("Shop nodes NEED confirmation, but confirmAction is null for " + managedBool.storeName + "!"); confirm = null; deny = null; } } 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 alwaysInStock, int maxStock, out CompatibleNoun confirm, out CompatibleNoun deny) { if ((Object)(object)node == (Object)null) { Plugin.ERROR("node is null when adding store command!!!"); confirm = null; deny = null; } else if (ConfirmAction != null) { AddConfirm(nodeName, price, ConfirmAction, DenyAction, confirmText, denyText, mainListing.Listing, out confirm, out deny); node.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { confirm, deny }; UnlockableItem item = AddUnlockable(nodeName, node, alwaysInStock, maxStock); if (!StartOfRound.Instance.unlockablesList.unlockables.Contains(item)) { StartOfRound.Instance.unlockablesList.unlockables.Add(item); } int shipUnlockableID = StartOfRound.Instance.unlockablesList.unlockables.IndexOf(item); node.creatureName = storeName; node.shipUnlockableID = shipUnlockableID; confirm.result.shipUnlockableID = shipUnlockableID; confirm.result.buyUnlockable = false; confirm.result.itemCost = price; if (DynamicBools.TryGetKeyword("buy", out var terminalKeyword)) { AddToBuyWord(ref terminalKeyword, ref keyword, item); } Plugin.ShopNodes.Add(node); Plugin.Spam("Store nodes created for " + nodeName); } else { Plugin.ERROR("Shop nodes NEED confirmation, but confirmAction is null for " + nodeName + "!"); confirm = null; deny = null; } } public static UnlockableItem AddUnlockable(ManagedConfig managedBool) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown if (managedBool.UnlockableItem != null) { Plugin.Spam(managedBool.ConfigItemName + " already contained item: " + managedBool.UnlockableItem.unlockableName); return managedBool.UnlockableItem; } UnlockableItem val; if (DynamicBools.TryGetAndReturnUnlockable(managedBool.storeName, out var itemOut)) { Plugin.Spam("found matching item for " + managedBool.storeName); itemOut.unlockableType = 1; itemOut.shopSelectionNode = managedBool.TerminalNode; itemOut.alwaysInStock = managedBool.alwaysInStock; itemOut.IsPlaceable = false; itemOut.spawnPrefab = false; itemOut.maxNumber = managedBool.maxStock; val = itemOut; } else { Plugin.Spam("Creating unlockable item from managedBool: " + managedBool.ConfigItemName); val = new UnlockableItem { unlockableType = 1, alreadyUnlocked = false, hasBeenUnlockedByPlayer = false, unlockableName = managedBool.storeName, shopSelectionNode = managedBool.TerminalNode, alwaysInStock = managedBool.alwaysInStock, IsPlaceable = false, spawnPrefab = false, maxNumber = managedBool.maxStock }; } managedBool.UnlockableItem = val; return val; } public static UnlockableItem AddUnlockable(string storeName, TerminalNode node, bool alwaysInStock, int maxStock) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown if (DynamicBools.TryGetAndReturnUnlockable(storeName, out var itemOut)) { Plugin.Spam("found matching item for " + storeName); itemOut.unlockableType = 1; itemOut.shopSelectionNode = node; itemOut.alwaysInStock = alwaysInStock; itemOut.IsPlaceable = false; itemOut.spawnPrefab = false; itemOut.maxNumber = maxStock; return itemOut; } Plugin.Spam("Creating unlockable item manually for item: " + storeName); return new UnlockableItem { unlockableType = 1, unlockableName = storeName, shopSelectionNode = node, alwaysInStock = alwaysInStock, IsPlaceable = false, spawnPrefab = false, maxNumber = maxStock }; } public static void AddToBuyWord(ref TerminalKeyword buyKeyword, ref TerminalKeyword terminalKeyword, UnlockableItem item) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown terminalKeyword.defaultVerb = buyKeyword; Plugin.Spam("Added buy verb to " + buyKeyword.word); CompatibleNoun item2 = new CompatibleNoun { noun = terminalKeyword, result = item.shopSelectionNode }; CompatibleNoun[] compatibleNouns = buyKeyword.compatibleNouns; List<CompatibleNoun> list = new List<CompatibleNoun>(compatibleNouns.Length); list.AddRange(compatibleNouns); List<CompatibleNoun> list2 = list; list2.Add(item2); buyKeyword.compatibleNouns = list2.ToArray(); } public static void AddToKeyword(ref TerminalKeyword originalKeyword, ref TerminalKeyword newWord) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (!originalKeyword.isVerb) { Plugin.Log.LogWarning((object)"AddToKeyword called on non-verb"); return; } newWord.defaultVerb = originalKeyword; Plugin.Spam("Added verb " + originalKeyword.word + " to " + newWord.word); CompatibleNoun item = new CompatibleNoun { noun = newWord, result = newWord.specialKeywordResult }; CompatibleNoun[] compatibleNouns = originalKeyword.compatibleNouns; List<CompatibleNoun> list = new List<CompatibleNoun>(compatibleNouns.Length); list.AddRange(compatibleNouns); List<CompatibleNoun> list2 = list; list2.Add(item); originalKeyword.compatibleNouns = list2.ToArray(); } [Obsolete("This doesn't work at the moment")] public static void AddNounWordSimple(string originalVerb, string nodeName, string keyWord, string displayText, bool clearText) { //IL_0064: 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_0075: Expected O, but got Unknown if (originalVerb.Length < 1) { Plugin.WARNING("originalVerb text is invalid"); return; } if (!DynamicBools.TryGetKeyword(originalVerb, out var terminalKeyword)) { Plugin.WARNING("Unable to find word for " + originalVerb); return; } TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = nodeName; val.displayText = displayText; val.clearPreviousText = clearText; CompatibleNoun val2 = new CompatibleNoun { noun = ScriptableObject.CreateInstance<TerminalKeyword>() }; ((Object)val2.noun).name = nodeName + "_Noun"; val2.noun.word = keyWord.ToLower(); val2.noun.isVerb = false; val2.result = val; val2.noun.specialKeywordResult = val; if (!Plugin.nodesAdded.Contains(val)) { Plugin.nodesAdded.Add(val); } if (!Plugin.keywordsAdded.Contains(val2.noun)) { Plugin.keywordsAdded.Add(val2.noun); } AddToKeyword(ref terminalKeyword, ref val2.noun); } } public class CommonThings { public static void CheckForAndDeleteKeyWord(string keyWord) { Plugin.Spam("Checking for " + keyWord); TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; for (int num = list2.Count - 1; num >= 0; num--) { if (list2[num].word.Equals(keyWord)) { list2.RemoveAt(num); break; } } Plugin.instance.Terminal.terminalNodes.allKeywords = list2.ToArray(); Plugin.Spam("keyword list adjusted, removed " + keyWord); } } public class ListManagement { public static void ClearLists() { Plugin.ShopNodes.Clear(); } } public class MainListing { public List<TerminalNode> terminalNodes = new List<TerminalNode>(); public List<TerminalKeyword> terminalKeywords = new List<TerminalKeyword>(); public Dictionary<TerminalNode, Func<string>> Listing = new Dictionary<TerminalNode, Func<string>>(); public List<TerminalNode> shopNodes = new List<TerminalNode>(); public Dictionary<TerminalNode, int> specialListNum = new Dictionary<TerminalNode, int>(); public Dictionary<string, TerminalNode> specialListString = new Dictionary<string, TerminalNode>(); public Dictionary<int, string> ListNumToString = new Dictionary<int, string>(); public Dictionary<TerminalNode, string> storePacks = new Dictionary<TerminalNode, string>(); public void DeleteAll() { terminalKeywords.Clear(); terminalNodes.Clear(); Listing.Clear(); shopNodes.Clear(); specialListNum.Clear(); specialListString.Clear(); ListNumToString.Clear(); storePacks.Clear(); } } public class CommandRegistry { public static void InitListing(ref MainListing listingName) { if (listingName == null) { listingName = new MainListing(); } listingName.terminalNodes = new List<TerminalNode>(); listingName.terminalKeywords = new List<TerminalKeyword>(); listingName.Listing = new Dictionary<TerminalNode, Func<string>>(); listingName.shopNodes = new List<TerminalNode>(); listingName.specialListNum = new Dictionary<TerminalNode, int>(); listingName.specialListString = new Dictionary<string, TerminalNode>(); listingName.ListNumToString = new Dictionary<int, string>(); if (listingName == null) { Plugin.ERROR("InitListing still null"); } } public static void GetCommandsToAdd(List<ManagedConfig> managedBools, MainListing listingName) { Plugin.MoreLogs("GetCommandsToAdd"); if (managedBools == null || listingName == null) { Plugin.Spam("params are null"); return; } TerminalNode existingNode = LogicHandling.GetFromAllNodes("OtherCommands"); Plugin.Spam($"listing count: {listingName.Listing.Count}"); foreach (ManagedConfig managedBool in managedBools) { if (managedBool.BoolValue) { Plugin.Spam("configvalue is true"); TerminalMenuItem terminalMenuItem = MenuBuild.MakeMenuItem(managedBool); if (terminalMenuItem != null) { managedBool.menuItem = terminalMenuItem; } Plugin.MoreLogs(managedBool.ConfigItemName + " found in managed bools and is active"); if (managedBool.KeywordList != null) { AddCommandKeyword(managedBool, listingName); if (managedBool.categoryText.ToLower() == "other") { AddingThings.AddToExistingNodeText("\n" + managedBool.configDescription, ref existingNode); } } } else { Plugin.Spam("configvalue is false, deleting menuItem if not null"); managedBool.menuItem?.Delete(); } } } public static void AddCommandKeyword(ManagedConfig managedBool, MainListing listingName) { if (managedBool == null) { Plugin.ERROR("managedBool is null @AddCommandKeyword()"); return; } if (managedBool.KeywordList.Count == 0) { Plugin.Spam("KeywordList Count = 0 for " + managedBool.ConfigItemName); return; } Plugin.Spam("AddCommandKeyword starting:"); foreach (string keyword in managedBool.KeywordList) { Plugin.Spam("adding " + keyword); managedBool.TerminalNode = AddingThings.CreateNode(managedBool, keyword, listingName); if (managedBool.specialNum != -1 && !listingName.specialListNum.ContainsKey(managedBool.TerminalNode)) { listingName.specialListNum.Add(managedBool.TerminalNode, managedBool.specialNum); listingName.ListNumToString.Add(managedBool.specialNum, managedBool.specialString); Plugin.MoreLogs($"Added viewnode types to dictionaries, {managedBool.specialNum}"); } else if (managedBool.specialString.Length > 1) { listingName.specialListString.Add(keyword, managedBool.TerminalNode); Plugin.MoreLogs("mapping keyword" + keyword + " for " + managedBool.specialString + " node"); } } } } public class DynamicBools { public static bool UseMatchingNode(string nodeName, out TerminalNode returnNode) { TerminalNode[] array = Object.FindObjectsOfType<TerminalNode>(); TerminalNode[] array2 = array; foreach (TerminalNode val in array2) { if (((Object)val).name.ToLower().Equals(nodeName.ToLower())) { returnNode = val; Plugin.Spam("Existing terminalNode [" + nodeName + "] found, using it rather than making a new one for this command"); return true; } } returnNode = null; return false; } public static bool TryGetKeyword(string keyWord) { TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; foreach (TerminalKeyword item in list2) { if (item.word.ToLower().Equals(keyWord.ToLower())) { return true; } } return false; } public static bool TryGetKeyword(string keyWord, out TerminalKeyword terminalKeyword) { TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length); list.AddRange(allKeywords); List<TerminalKeyword> list2 = list; foreach (TerminalKeyword item in list2) { if (item.word.ToLower().Equals(keyWord.ToLower())) { Plugin.Spam("Keyword: [" + keyWord + "] found!"); terminalKeyword = item; return true; } } terminalKeyword = null; return false; } public static bool TryGetAndReturnUnlockable(string unlockableName, out UnlockableItem itemOut) { List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables; List<UnlockableItem> list = new List<UnlockableItem>(unlockables.Count); list.AddRange(unlockables); List<UnlockableItem> list2 = list; foreach (UnlockableItem item in list2) { if (item.unlockableName.Equals(unlockableName)) { itemOut = item; return true; } } itemOut = null; return false; } public static bool TryGetAndReturnItem(string unlockableName, out Item itemOut) { Item[] buyableItemsList = Plugin.instance.Terminal.buyableItemsList; List<Item> list = new List<Item>(buyableItemsList.Length); list.AddRange(buyableItemsList); List<Item> list2 = list; foreach (Item item in list2) { if (item.itemName.ToLower().Equals(unlockableName.ToLower())) { itemOut = item; return true; } } itemOut = null; return false; } public static bool IsCommandCreatedAlready(string keyWord, string displayText, List<TerminalKeyword> terminalKeywords) { foreach (TerminalKeyword terminalKeyword in terminalKeywords) { if (terminalKeyword.word.ToLower() == keyWord.ToLower() && terminalKeyword.specialKeywordResult.displayText == displayText) { Plugin.Spam("word: " + keyWord + " found with valid node: " + ((Object)terminalKeyword.specialKeywordResult).name); return true; } } return false; } public static bool IsCommandCreatedAlready(Dictionary<TerminalNode, Func<string>> MainCommandListing, string keyWord, Func<string> commandAction, List<TerminalKeyword> terminalKeywords) { if (MainCommandListing.Count == 0) { return false; } foreach (KeyValuePair<TerminalNode, Func<string>> item in MainCommandListing) { if (!(item.Value == commandAction)) { continue; } foreach (TerminalKeyword terminalKeyword in terminalKeywords) { if (terminalKeyword.word.ToLower() == keyWord.ToLower() && (Object)(object)terminalKeyword.specialKeywordResult == (Object)(object)item.Key) { Plugin.Spam("word: " + keyWord + " found with valid node: " + ((Object)terminalKeyword.specialKeywordResult).name); return true; } } } return false; } public static bool IsCommandCreatedAlready(Dictionary<TerminalNode, Func<string>> MainCommandListing, string keyWord, Func<string> commandAction, List<TerminalKeyword> terminalKeywords, out TerminalKeyword outKeyword) { outKeyword = null; if (MainCommandListing.Count == 0) { return false; } foreach (KeyValuePair<TerminalNode, Func<string>> item in MainCommandListing) { if (!(item.Value == commandAction)) { continue; } foreach (TerminalKeyword terminalKeyword in terminalKeywords) { if (terminalKeyword.word.ToLower() == keyWord.ToLower() && (Object)(object)terminalKeyword.specialKeywordResult == (Object)(object)item.Key) { Plugin.Spam("word: " + keyWord + " found with valid node: " + ((Object)terminalKeyword.specialKeywordResult).name); outKeyword = terminalKeyword; return true; } } } return false; } public static bool DoesNodeExist(Dictionary<TerminalNode, Func<string>> MainCommandListing, Func<string> commandAction, out TerminalNode node) { node = null; if (MainCommandListing.Count == 0) { return false; } foreach (KeyValuePair<TerminalNode, Func<string>> item in MainCommandListing) { if ((Object)(object)item.Key == (Object)null || !(item.Value == commandAction)) { continue; } node = item.Key; return true; } return false; } } public class RemoveThings { public static void OnTerminalDisable() { Plugin.Spam("OnTerminalDisable called"); DeleteAllNodes(ref Plugin.nodesAdded); DeleteAllKeywords(ref Plugin.keywordsAdded); ConfigSetup.defaultListing.DeleteAll(); } public static void DeleteNounWord(ref TerminalKeyword keyWord, string terminalKeyword) { CompatibleNoun[] compatibleNouns = keyWord.compatibleNouns; List<CompatibleNoun> list = new List<CompatibleNoun>(compatibleNouns.Length); list.AddRange(compatibleNouns); List<CompatibleNoun> list2 = list; List<CompatibleNoun> list3 = new List<CompatibleNoun>(); foreach (CompatibleNoun item in list2) { if (item.noun.word.ToLower() == terminalKeyword.ToLower()) { list3.Add(item); } } for (int num = list3.Count - 1; num >= 0; num--) { Plugin.Spam("Deleting noun: " + list3[num].noun.word + " from word: " + keyWord.word); Object.Destroy((Object)(object)list3[num].noun); } keyWord.compatibleNouns = list2.ToArray(); } public static void RemoveCompatibleNoun(ref TerminalKeyword mainWord, TerminalKeyword wordToRemove) { bool flag = false; if (mainWord.compatibleNouns == null) { return; } List<CompatibleNoun> list = new List<CompatibleNoun>(); CompatibleNoun[] compatibleNouns = mainWord.compatibleNouns; foreach (CompatibleNoun val in compatibleNouns) { if ((Object)(object)val.noun != (Object)(object)wordToRemove) { list.Add(val); continue; } flag = true; Plugin.Spam("Removing " + wordToRemove.word); } mainWord.compatibleNouns = list.ToArray(); Plugin.Spam($"DeleteCompatibleNoun of {wordToRemove.word} from {mainWord.word} complete, word removed: {flag}"); } public static void DeleteAllKeywords(ref List<TerminalKeyword> keywordList) { if (keywordList.Count == 0) { return; } List<TerminalKeyword> list = keywordList; TerminalKeyword[] allKeywords = Plugin.instance.Terminal.terminalNodes.allKeywords; List<TerminalKeyword> list2 = new List<TerminalKeyword>(allKeywords.Length); list2.AddRange(allKeywords); List<TerminalKeyword> list3 = list2; foreach (TerminalKeyword keyword in keywordList) { if (DynamicBools.TryGetKeyword("buy", out var terminalKeyword)) { DeleteNounWord(ref terminalKeyword, keyword.word); } for (int num = list3.Count - 1; num >= 0; num--) { if ((Object)(object)list3[num] == (Object)(object)keyword) { Plugin.Spam("Removing " + keyword.word + " from all keywords list"); list3.RemoveAt(num); break; } } } for (int num2 = list.Count - 1; num2 >= 0; num2--) { Plugin.Spam("Deleting keyword Object: " + list[num2].word); Object.Destroy((Object)(object)list[num2]); } keywordList.Clear(); Plugin.instance.Terminal.terminalNodes.allKeywords = list3.ToArray(); } public static void DeleteAllNodes(ref Dictionary<TerminalNode, int> nodeDictionary) { List<TerminalNode> list = new List<TerminalNode>(); foreach (KeyValuePair<TerminalNode, int> item in nodeDictionary) { list.Add(item.Key); } nodeDictionary.Clear(); for (int num = list.Count - 1; num >= 0; num--) { Plugin.Spam("Deleting node: " + ((Object)list[num]).name); Object.Destroy((Object)(object)list[num]); } } public static void DeleteAllNodes(ref Dictionary<TerminalNode, Func<string>> nodeDictionary) { if (nodeDictionary.Count == 0) { return; } List<TerminalNode> list = new List<TerminalNode>(); foreach (KeyValuePair<TerminalNode, Func<string>> item in nodeDictionary) { list.Add(item.Key); } nodeDictionary.Clear(); for (int num = list.Count - 1; num >= 0; num--) { Plugin.Spam("Deleting node: " + ((Object)list[num]).name); Object.Destroy((Object)(object)list[num]); } } public static void DeleteAllNodes(ref List<TerminalNode> nodeList) { if (nodeList.Count == 0) { return; } List<TerminalNode> list = new List<TerminalNode>(); foreach (TerminalNode node in nodeList) { list.Add(node); } nodeList.Clear(); for (int num = list.Count - 1; num >= 0; num--) { Plugin.Spam("Deleting node: " + ((Object)list[num]).name); Object.Destroy((Object)(object)list[num]); } } public static void DeleteMatchingNode(string nodeName) { List<TerminalNode> allNodes = LogicHandling.GetAllNodes(); for (int num = allNodes.Count - 1; num >= 0; num--) { if (((Object)allNodes[num]).name.Equals(nodeName)) { Object.Destroy((Object)(object)allNodes[num]); break; } } } public static bool TryGetAndDeleteUnlockableName(string unlockableName, out int indexPos) { List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables; List<UnlockableItem> list = new List<UnlockableItem>(unlockables.Count); list.AddRange(unlockables); List<UnlockableItem> list2 = list; for (int num = list2.Count - 1; num >= 0; num--) { if (list2[num].unlockableName.Equals(unlockableName)) { Plugin.Spam("Unlockable: [" + unlockableName + "] found! Removing unlockable and noting index position"); StartOfRound.Instance.unlockablesList.unlockables.Remove(list2[num]); indexPos = num; return true; } } indexPos = -1; return false; } } public class LogicHandling { public static bool GetNewDisplayText(MainListing providedListing, ref TerminalNode node) { if ((Object)(object)node == (Object)null || providedListing.Listing.Count == 0) { Plugin.Spam("node is null or listing is 0"); return false; } Dictionary<TerminalNode, Func<string>> listing = providedListing.Listing; if (listing.Count < 1) { return false; } Plugin.Spam("command dictionary is not null in provided listing"); EventManager.GetNewDisplayText.Invoke(node); if (listing.TryGetValue(node, out var value)) { CommonTerminal.parseNode = node; Plugin.Spam("Func<string> found for " + ((Object)node).name); node.displayText = value(); return true; } Plugin.MoreLogs("Not in special nodeListing dictionary"); return false; } public static bool GetNewDisplayText(List<MainListing> providedListing, ref TerminalNode node) { if ((Object)(object)node == (Object)null || providedListing.Count == 0) { Plugin.Spam("node is null or listings do not exist"); return false; } bool result = false; int num = 0; foreach (MainListing item in providedListing) { Dictionary<TerminalNode, Func<string>> listing = item.Listing; if (listing.Count >= 1) { num++; Plugin.Spam($"command dictionary in this listing is not null ({num})"); EventManager.GetNewDisplayText.Invoke(node); if (listing.TryGetValue(node, out var value)) { CommonTerminal.parseNode = node; Plugin.MoreLogs("Func<string> found for " + ((Object)node).name + " in one of provided listings"); node.displayText = value(); result = true; break; } Plugin.Spam("Not in special nodeListing dictionary"); } } Plugin.MoreLogs("provided listings do not contain this node"); return result; } public static Func<string> GetFuncFromNode(List<MainListing> providedListing, ref TerminalNode node) { if ((Object)(object)node == (Object)null || providedListing.Count == 0) { Plugin.Spam("node is null or listings do not exist"); return null; } int num = 0; foreach (MainListing item in providedListing) { Dictionary<TerminalNode, Func<string>> listing = item.Listing; if (listing.Count >= 1) { num++; Plugin.Spam($"command dictionary in this listing is not null ({num})"); if (listing.TryGetValue(node, out var value)) { Plugin.MoreLogs("Func<string> found for " + ((Object)node).name + " in one of provided listings"); return value; } Plugin.Spam("Not in this special nodeListing dictionary"); } } Plugin.MoreLogs("provided listings do not contain this node"); return null; } public static TerminalNode GetFromAllNodes(string nodeName) { List<TerminalNode> allNodes = GetAllNodes(); foreach (TerminalNode item in allNodes) { if ((Object)(object)item == (Object)null || !(((Object)item).name == nodeName)) { continue; } Plugin.Spam(nodeName + " found!"); return item; } Plugin.Spam(nodeName + " could not be found, result set to null."); return null; } public static List<TerminalNode> GetAllNodes() { TerminalNode[] array = Resources.FindObjectsOfTypeAll<TerminalNode>(); List<TerminalNode> list = new List<TerminalNode>(array.Length); list.AddRange(array); return list; } public static void SetTerminalInput(string terminalInput) { Plugin.instance.Terminal.TextChanged(Plugin.instance.Terminal.currentText.Substring(0, Plugin.instance.Terminal.currentText.Length - Plugin.instance.Terminal.textAdded) + terminalInput); Plugin.instance.Terminal.screenText.text = Plugin.instance.Terminal.currentText; Plugin.instance.Terminal.textAdded = terminalInput.Length; } } } namespace OpenLib.ConfigManager { public class ConfigMisc { public static bool CheckChangedConfigSetting(List<ManagedConfig> managedItems, ConfigEntryBase entryBase) { ConfigEntry<bool> val = default(ConfigEntry<bool>); ConfigEntry<string> val2 = default(ConfigEntry<string>); foreach (ManagedConfig managedItem in managedItems) { if (!(managedItem.configDescription == entryBase.Description.Description)) { continue; } if (entryBase.BoxedValue.GetType() == typeof(bool)) { if (entryBase.ConfigFile.TryGetEntry<bool>(entryBase.Definition, ref val)) { if (managedItem.BoolValue != val.Value) { managedItem.ConfigChange(val.Value); Plugin.Spam("Updating config item: " + ((ConfigEntryBase)val).Definition.Key + " in managedItems"); return true; } Plugin.Spam("item value matches config item: " + ((ConfigEntryBase)val).Definition.Key); } } else if (entryBase.BoxedValue.GetType() == typeof(string) && entryBase.ConfigFile.TryGetEntry<string>(entryBase.Definition, ref val2)) { if (managedItem.StringValue != val2.Value) { managedItem.ConfigChange(val2.Value); Plugin.Spam("Updating config item: " + ((ConfigEntryBase)val2).Definition.Key + " in managedItems"); List<string> keywordsPerConfigItem = CommonStringStuff.GetKeywordsPerConfigItem(val2.Value); managedItem.relatedConfigItem.KeywordList = keywordsPerConfigItem; return true; } Plugin.Spam("item value matches config item: " + ((ConfigEntryBase)val2).Definition.Key); } } Plugin.Spam("could not match changed config setting to any managed config items"); return false; } public static bool ShouldReloadConfigNow(ConfigEntry<string> entry) { if ((Object)(object)Plugin.instance.Terminal != (Object)null) { if (!EventUsage.configsToReload.Contains(((ConfigEntryBase)entry).ConfigFile)) { EventUsage.configsToReload.Add(((ConfigEntryBase)entry).ConfigFile); } return false; } return true; } } public class ManagedConfig { public string ConfigItemName; public bool RequiresNetworking; public int ConfigType = -1; public string StringValue; public int IntValue; public bool BoolValue = false; public List<string> KeywordList; public Func<string> MainAction; public int CommandType; public bool clearText; public bool alwaysInStock; public bool reuseFunc; public int maxStock; public int price; public int specialNum; public string nodeName; public string storeName; public string itemList; public string specialString; public string confirmText; public string denyText; public string categoryText; public string configDescription; public Func<string> ConfirmAction; public Func<string> DenyAction; public TerminalMenuItem menuItem; public TerminalNode TerminalNode; public UnlockableItem UnlockableItem; public ManagedConfig relatedConfigItem; public void ConfigChange(bool newValue) { if (newValue) { BoolValue = newValue; } else { BoolValue = newValue; } } public void ConfigChange(string newValue) { if (newValue != StringValue) { StringValue = newValue; Plugin.Spam("Updating string value for managed item " + ConfigItemName); } } public void SetManagedBoolValues(string configItemName, bool isEnabled, string descrip, bool isNetworked = false, string category = "", List<string> keywordList = null, Func<string> mainAction = null, int commandType = 0, bool clear = true, Func<string> confirmAction = null, Func<string> denyAction = null, string confirmTxt = "confirm", string denyTxt = "deny", string special = "", int specialInt = -1, string nodestring = "", string items = "", int value = 0, string storeString = "", bool inStock = true, int stockMax = 0, bool reuseFnc = false) { ConfigType = 0; BoolValue = isEnabled; MainAction = mainAction; KeywordList = keywordList; ConfigItemName = configItemName; RequiresNetworking = isNetworked; price = value; CommandType = commandType; clearText = clear; ConfirmAction = confirmAction; DenyAction = denyAction; confirmText = confirmTxt; denyText = denyTxt; specialNum = specialInt; specialString = special; itemList = items; storeName = storeString; alwaysInStock = inStock; maxStock = stockMax; nodeName = nodestring; categoryText = category; configDescription = descrip; reuseFunc = reuseFnc; } } public class ManagedBoolGet { public static bool TryGetItemByName(List<ManagedConfig> managedBools, string query, int configType, out ManagedConfig result) { if (managedBools.Count == 0) { Plugin.Spam("managedBools count = 0"); result = null; return false; } Plugin.Spam("TryGetItemByName: " + query); foreach (ManagedConfig managedBool in managedBools) { if (managedBool.ConfigItemName == query && managedBool.ConfigType == configType) { result = managedBool; Plugin.Spam($"{query} found with matching config type: {configType}, returning true"); return true; } } Plugin.Spam(query + " not found"); result = null; return false; } public static bool CanAddToManagedBoolList(List<ManagedConfig> managedBools, string nodeName) { foreach (ManagedConfig managedBool in managedBools) { if (managedBool.ConfigItemName == nodeName) { Plugin.Log.LogWarning((object)("Tried to add " + nodeName + " to managedBools list when it's already in it!")); return false; } } Plugin.Spam("node is not in managedbool list and can be added!"); return true; } public static bool TryGetItemByName(List<ManagedConfig> managedBools, string query) { foreach (ManagedConfig managedBool in managedBools) { if (managedBool.ConfigItemName == query) { return true; } } return false; } } public static class ConfigSetup { public static List<ManagedConfig> defaultManaged = new List<ManagedConfig>(); public static MainListing defaultListing; public static ConfigEntry<bool> ExtensiveLogging { get; internal set; } public static ConfigEntry<bool> DeveloperLogging { get; internal set; } public static void BindConfigSettings() { Plugin.Log.LogInfo((object)"Binding configuration settings"); ExtensiveLogging = MakeBool(((BaseUnityPlugin)Plugin.instance).Config, "Debug", "ExtensiveLogging", defaultValue: false, "Enable or Disable extensive logging for this mod."); DeveloperLogging = MakeBool(((BaseUnityPlugin)Plugin.instance).Config, "Debug", "DeveloperLogging", defaultValue: false, "Enable or Disable developer logging for this mod. (this will fill your log file FAST)"); } public static ManagedConfig AddManagedBool(ConfigEntry<bool> boolEntry, List<ManagedConfig> managedItems, bool isNetworked = false, string category = "", string configString = "", Func<string> mainAction = null, int commandType = 0, bool clearText = true, Func<string> confirmAction = null, Func<string> denyAction = null, string confirmText = "confirm", string denyText = "deny", string special = "", int specialNum = -1, string nodeName = "", string itemList = "", int price = 0, string storeName = "", bool alwaysInStock = true, int maxStock = 0, bool reuseFunc = false) { List<string> keywordsPerConfigItem = CommonStringStuff.GetKeywordsPerConfigItem(configString); if (ManagedBoolGet.TryGetItemByName(managedItems, ((ConfigEntryBase)boolEntry).Definition.Key, 0, out var result)) { result.SetManagedBoolValues(((ConfigEntryBase)boolEntry).Definition.Key, boolEntry.Value, ((ConfigEntryBase)boolEntry).Description.Description, isNetworked, category, keywordsPerConfigItem, mainAction, commandType, clearText, confirmAction, denyAction, confirmText, denyText, special, specialNum, nodeName, itemList, price, storeName, alwaysInStock, maxStock, reuseFunc); return result; } ManagedConfig managedConfig = new ManagedConfig(); managedConfig.SetManagedBoolValues(((ConfigEntryBase)boolEntry).Definition.Key, boolEntry.Value, ((ConfigEntryBase)boolEntry).Description.Description, isNetworked, category, keywordsPerConfigItem, mainAction, commandType, clearText, confirmAction, denyAction, confirmText, denyText, special, specialNum, nodeName, itemList, price, storeName, alwaysInStock, maxStock, reuseFunc); managedItems.Add(managedConfig); return managedConfig; } public static ManagedConfig AddManagedBool(ConfigEntry<bool> boolEntry, List<ManagedConfig> managedItems, bool isNetworked = false, string category = "", ConfigEntry<string> configString = null, Func<string> mainAction = null, int commandType = 0, bool clearText = true, Func<string> confirmAction = null, Func<string> denyAction = null, string confirmText = "confirm", string denyText = "deny", string special = "", int specialNum = -1, string nodeName = "", string itemList = "", int price = 0, string storeName = "", bool alwaysInStock = true, int maxStock = 0, bool reuseFunc = false) { List<string> keywordList = new List<string>(); bool flag = true; if (configString != null) { flag = false; keywordList = CommonStringStuff.GetKeywordsPerConfigItem(configString.Value); } if (ManagedBoolGet.TryGetItemByName(managedItems, ((ConfigEntryBase)boolEntry).Definition.Key, 0, out var result)) { result