Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TerminalUtils v0.0.14
TerminalUtils.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConsoleTables; using Dawn; using Dawn.Utils; using GameNetcodeStuff; using HarmonyLib; using LethalConstellations.PluginCore; using LethalLevelLoader; using LethalLib.Modules; using LethalMoonUnlocks; using LunarConfig.Objects.Config; using Microsoft.CodeAnalysis; using MrovLib; using MrovLib.ContentType; using MrovLib.Definitions; using MrovLib.Events; using On; using StoreRotationConfig.Api; using TerminalUtils.Commands; using TerminalUtils.Compatibility; using TerminalUtils.Definitions; using TerminalUtils.Enums; using TerminalUtils.InfoTypes.Moons; using TerminalUtils.InfoTypes.Store; using TerminalUtils.Nodes; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; using WeatherRegistry; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib.compatibility")] [assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib")] [assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib.dusk")] [assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib.interfaces")] [assembly: IgnoresAccessChecksTo("Crafty.LunarConfig")] [assembly: IgnoresAccessChecksTo("LethalConstellations")] [assembly: IgnoresAccessChecksTo("LethalLevelLoader")] [assembly: IgnoresAccessChecksTo("LethalLevelLoader.Patcher")] [assembly: IgnoresAccessChecksTo("LethalMoonUnlocks")] [assembly: IgnoresAccessChecksTo("MrovLib")] [assembly: IgnoresAccessChecksTo("WeatherRegistry")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TerminalUtils")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A template for Lethal Company")] [assembly: AssemblyFileVersion("0.0.14.0")] [assembly: AssemblyInformationalVersion("0.0.14+8ba015c5e86c5c646b60ee84920a2ea84ac94879")] [assembly: AssemblyProduct("TerminalUtils")] [assembly: AssemblyTitle("TerminalUtils")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TerminalUtils { public static class CommandManager { public static TerminalNode CommandNode; internal static TerminalNode RedirectToMoonsNode; internal static TerminalNode RedirectToStoreNode; public static List<TerminalCommandNode> Commands { get; set; } = new List<TerminalCommandNode>(); public static Dictionary<string, TerminalCommandNode> CommandLookup { get { Dictionary<string, TerminalCommandNode> lookup = new Dictionary<string, TerminalCommandNode>(); Commands.ForEach(delegate(TerminalCommandNode command) { lookup[((CommandNode)command).Name] = command; }); return lookup; } } public static void Init() { Commands.Clear(); CommandNode = TerminalNodeManager.CreateTerminalNode("TerminalUtilsCommandNode"); CommandNode.acceptAnything = false; RedirectToMoonsNode = TerminalNodeManager.CreateTerminalNode("TerminalUtilsRedirectToMoonsNode"); RedirectToMoonsNode.acceptAnything = false; RedirectToStoreNode = TerminalNodeManager.CreateTerminalNode("TerminalUtilsRedirectToStoreNode"); RedirectToStoreNode.acceptAnything = false; } public static TerminalNode RunTerminalCommand(TerminalCommandNode command, string[] args) { string displayText = ""; if (command == null) { CommandNode.displayText = $"Command '{command}' not found."; return CommandNode; } if (!command.ShouldRun()) { CommandNode.displayText = "Command '" + ((CommandNode)command).Name + "' cannot run!"; return CommandNode; } if (command.Subcommands.Count == 0 || args.Length < 1) { ((Logger)Plugin.debugLogger).LogDebug("Running command '" + ((CommandNode)command).Name + "' with no subcommand"); displayText = command.Execute(args); } else { ((Logger)Plugin.debugLogger).LogInfo("Looking for subcommand '" + args[0] + "'; available: " + string.Join(", ", command.Subcommands.ConvertAll((TerminalCommandNode sc) => ((CommandNode)sc).Name))); try { TerminalCommandNode terminalCommandNode = command.Subcommands.Find((TerminalCommandNode sc) => ((CommandNode)sc).Name == args[0]); if (terminalCommandNode == null) { displayText = "Subcommand '" + args[0] + "' not found for command '" + ((CommandNode)command).Name + "'."; } displayText = terminalCommandNode.Execute(args); } catch (Exception arg) { ((Logger)Plugin.debugLogger).LogError($"Error finding subcommand: {arg}"); } } if ((Object)(object)command.RedirectToNode != (Object)null) { ((Logger)Plugin.debugLogger).LogDebug("Redirecting to node '" + ((Object)command.RedirectToNode).name + "'"); return command.RedirectToNode; } CommandNode.displayText = displayText; return CommandNode; } } public class ConfigManager { internal static ConfigFile configFile; public static ConfigManager Instance { get; private set; } public static ConfigEntry<LoggingType> LoggingLevels { get; private set; } public static ConfigEntry<int> LinesToScroll { get; private set; } public static ConfigEntry<bool> UseLegacyScrollBehavior { get; private set; } public static ConfigEntry<string> PreviewInfoType { get; private set; } public static ConfigEntry<string> FilterInfoType { get; private set; } public static ConfigEntry<string> SortInfoType { get; private set; } public static ConfigEntry<bool> DisplayLockedMoons { get; private set; } public static ConfigEntry<string> StoreSortInfoType { get; private set; } public static ConfigEntry<int> DivideStore { get; private set; } public static ConfigEntry<bool> DetailedScanPage { get; private set; } public static ConfigEntry<bool> DisplayAccuratePrices { get; private set; } public static void Init(ConfigFile config) { Instance = new ConfigManager(config); } private ConfigManager(ConfigFile config) { configFile = config; LoggingLevels = configFile.Bind<LoggingType>("Debug", "Logging Levels", (LoggingType)0, "Set the logging level for the mod"); LinesToScroll = configFile.Bind<int>("General", "Lines to Scroll", 10, "Number of lines to scroll per mouse wheel tick"); UseLegacyScrollBehavior = configFile.Bind<bool>("General", "Use Legacy Scroll Behavior", false, "Whether to use the legacy scroll behavior (from TerminalFormatter)"); PreviewInfoType = configFile.Bind<string>("Preferences", "Preview Info Type", Defaults.defaultPreviewType, "Set the preview info type. Must be the name of an existing preview info type."); FilterInfoType = configFile.Bind<string>("Preferences", "Filter Info Type", Defaults.defaultFilterType, "Set the filter info type. Must be the name of an existing filter info type."); SortInfoType = configFile.Bind<string>("Preferences", "Sort Info Type", Defaults.defaultSortType, "Set the default sort info type. Must be the name of an existing sort info type."); StoreSortInfoType = configFile.Bind<string>("Preferences", "Store Sort Info Type", Defaults.defaultStoreSortType, "Set the default store sort info type. Must be the name of an existing store sort info type."); DisplayLockedMoons = configFile.Bind<bool>("Moons", "Display Locked Moons", true, "Whether to display locked moons in the moon catalogue."); DivideStore = configFile.Bind<int>("Store", "Divide Store page into groups", 5, "Set the number of items to divide the store into. 0 means no division."); DetailedScanPage = configFile.Bind<bool>("Scan", "Display Detailed Scan", true, "Enable detailed scan page"); DisplayAccuratePrices = configFile.Bind<bool>("Scan", "Display Accurate Prices", false, "Enable accurate prices on scan page"); } } public static class Defaults { public static readonly int terminalWidth = 48; internal static readonly int planetWeatherWidth = 18; internal static readonly int planetNameWidth = terminalWidth + 2 - planetWeatherWidth - 9; internal static readonly int itemNameWidth = terminalWidth - 9 - 10; internal static readonly int dividerLength = 17; internal static readonly string defaultPreviewType = "Name;Price;Weather"; internal static readonly string defaultFilterType = "None"; internal static readonly string defaultSortType = "None"; internal static readonly string defaultStoreSortType = "Name"; } public static class InfoTypeResolver { public static List<PreviewInfoType<SelectableLevel>> GetPreviewInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return (from typeName in Defaults.defaultPreviewType.Split(";") select TerminalManager.PreviewInfoTypes[typeName]).ToList(); } if (!inputString.ToLowerInvariant().Contains("Name".ToLowerInvariant())) { inputString = "Name;" + inputString; Plugin.logger.LogDebug((object)("Preview type did not contain 'Name', defaulting to 'Name;" + inputString + "'")); } string[] source = (from s in inputString.Split(';') where !string.IsNullOrWhiteSpace(s) select s.Trim()).ToArray(); return (from typeName in source select TerminalManager.PreviewInfoTypes.FirstOrDefault((KeyValuePair<string, PreviewInfoType<SelectableLevel>> info) => info.Key.ToLowerInvariant() == typeName.ToLowerInvariant()) into info where info.Value != null select info.Value).ToList(); } public static FilterInfoType<SelectableLevel> GetFilterInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return TerminalManager.FilterInfoTypes["None"]; } FilterInfoType<SelectableLevel> value = TerminalManager.FilterInfoTypes.FirstOrDefault((KeyValuePair<string, FilterInfoType<SelectableLevel>> info) => info.Key.ToLowerInvariant() == inputString.ToLowerInvariant()).Value; if (value == null) { Plugin.logger.LogWarning((object)("FilterInfoType '" + inputString + "' not found, defaulting to 'None'")); return TerminalManager.FilterInfoTypes["None"]; } return value; } public static SortInfoType<SelectableLevel> GetSortInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return TerminalManager.SortInfoTypes["None"]; } SortInfoType<SelectableLevel> value = TerminalManager.SortInfoTypes.FirstOrDefault((KeyValuePair<string, SortInfoType<SelectableLevel>> info) => info.Key.ToLowerInvariant() == inputString.ToLowerInvariant()).Value; if (value == null) { Plugin.logger.LogWarning((object)("SortInfoType '" + inputString + "' not found, defaulting to 'None'")); return TerminalManager.SortInfoTypes["None"]; } return value; } public static SortInfoType<BuyableThing> GetStoreSortInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return TerminalManager.StoreSortInfoTypes["None"]; } return TerminalManager.StoreSortInfoTypes.FirstOrDefault((KeyValuePair<string, SortInfoType<BuyableThing>> info) => info.Key.ToLowerInvariant() == inputString.ToLowerInvariant()).Value; } } public class Logger : Logger { public Logger(string SourceName, LoggingType defaultLoggingType = (LoggingType)1) : base(SourceName, defaultLoggingType) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ((Logger)this).ModName = SourceName; ((Logger)this).LogSource = Logger.CreateLogSource("TerminalUtils"); ((Logger)this)._name = SourceName; } public override bool ShouldLog(LoggingType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return ConfigManager.LoggingLevels.Value >= type; } } public static class NodeReplacementManager { internal static List<TerminalNodeReplacement> RegisteredNodes = new List<TerminalNodeReplacement>(); public static bool ReplaceNode = true; } [BepInPlugin("mrov.TerminalUtils", "TerminalUtils", "0.0.14")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource logger; internal static Logger debugLogger = new Logger("Debug", (LoggingType)2); internal static Harmony harmony = new Harmony("mrov.TerminalUtils"); internal static LethalLevelLoaderCompatibility LLLCompatibility = new LethalLevelLoaderCompatibility("imabatby.lethallevelloader"); internal static DawnLibCompatibility DawnCompatibility = new DawnLibCompatibility("com.github.teamxiaolan.dawnlib"); internal static WeatherRegistryCompatibility WeatherRegistryCompatibility = new WeatherRegistryCompatibility("mrov.WeatherRegistry"); internal static LethalMoonUnlocksCompatibility LMUCompatibility = new LethalMoonUnlocksCompatibility("com.xmods.lethalmoonunlocks"); internal static LethalConstellationsCompatibility LCCompatibility = new LethalConstellationsCompatibility("com.github.darmuh.LethalConstellations"); internal static LategameUpgradesCompatibility LGUCompat = new LategameUpgradesCompatibility("MoreShipUpgrades"); internal static StoreRotationConfigCompatibility SRCCompat = new StoreRotationConfigCompatibility("pacoito.StoreRotationConfig"); internal static LethalLibCompatibility LLCompat = new LethalLibCompatibility("Evaisa.LethalLib"); internal static LunarConfigCompatibility LunarConfigCompat = new LunarConfigCompatibility("Crafty.LunarConfig"); private void Awake() { logger = ((BaseUnityPlugin)this).Logger; harmony.PatchAll(); ConfigManager.Init(((BaseUnityPlugin)this).Config); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin mrov.TerminalUtils is loaded!"); } } public static class StartupManager { public static void Init(Terminal _instance) { TerminalManager.Init(_instance); CommandManager.Init(); PreviewCommand item = new PreviewCommand(); CommandManager.Commands.Add(item); SortCommand item2 = new SortCommand(); CommandManager.Commands.Add(item2); FilterCommand item3 = new FilterCommand(); CommandManager.Commands.Add(item3); SimulateCommand item4 = new SimulateCommand(); CommandManager.Commands.Add(item4); StoreSortCommand item5 = new StoreSortCommand(); CommandManager.Commands.Add(item5); } } public static class TerminalManager { public static Dictionary<string, PreviewInfoType<SelectableLevel>> PreviewInfoTypes = new Dictionary<string, PreviewInfoType<SelectableLevel>>(); public static Dictionary<string, FilterInfoType<SelectableLevel>> FilterInfoTypes = new Dictionary<string, FilterInfoType<SelectableLevel>>(); public static Dictionary<string, SortInfoType<SelectableLevel>> SortInfoTypes = new Dictionary<string, SortInfoType<SelectableLevel>>(); public static Dictionary<string, SortInfoType<BuyableThing>> StoreSortInfoTypes = new Dictionary<string, SortInfoType<BuyableThing>>(); public static Dictionary<TerminalNode, TerminalNodeReplacement> NodeReplacements = new Dictionary<TerminalNode, TerminalNodeReplacement>(); public static Terminal Terminal => ContentManager.Terminal; public static TerminalNode MoonsPage { get; private set; } public static TerminalNode StorePage { get; private set; } public static TerminalNode ScanPage { get; private set; } public static List<PreviewInfoType<SelectableLevel>> CurrentPreviewInfoType { get; set; } public static FilterInfoType<SelectableLevel> CurrentFilterInfoType { get; set; } public static SortInfoType<SelectableLevel> CurrentSortInfoType { get; set; } public static SortInfoType<BuyableThing> CurrentStoreSortInfoType { get; set; } internal static void Init(Terminal terminal) { MoonsPage = ContentManager.MoonsKeyword.specialKeywordResult; StorePage = ((IEnumerable<TerminalNode>)ContentManager.Nodes).FirstOrDefault((Func<TerminalNode, bool>)((TerminalNode node) => ((Object)node).name == "0_StoreHub")); ScanPage = ((IEnumerable<TerminalNode>)ContentManager.Nodes).FirstOrDefault((Func<TerminalNode, bool>)((TerminalNode node) => ((Object)node).name == "ScanInfo")); RegisterLocalInfoTypes(); CurrentPreviewInfoType = InfoTypeResolver.GetPreviewInfoType(ConfigManager.PreviewInfoType.Value); CurrentFilterInfoType = InfoTypeResolver.GetFilterInfoType(ConfigManager.FilterInfoType.Value); CurrentSortInfoType = InfoTypeResolver.GetSortInfoType(ConfigManager.SortInfoType.Value); CurrentStoreSortInfoType = InfoTypeResolver.GetStoreSortInfoType(ConfigManager.StoreSortInfoType.Value); NodeReplacements = new Dictionary<TerminalNode, TerminalNodeReplacement> { { MoonsPage, new MoonCatalogue() }, { StorePage, new StoreCatalogue() }, { ScanPage, new Scan() } }; } private static void RegisterLocalInfoTypes() { PreviewInfoTypes.Clear(); SortInfoTypes.Clear(); FilterInfoTypes.Clear(); StoreSortInfoTypes.Clear(); PreviewInfoTypes.Add("Name", new PreviewName()); PreviewInfoTypes.Add("Price", new PreviewPrice()); PreviewInfoTypes.Add("Weather", new PreviewWeather()); PreviewInfoTypes.Add("Difficulty", new PreviewDifficulty()); if (((CompatibilityHandler)Plugin.LCCompatibility).IsModPresent) { PreviewInfoTypes.Add("Constellation", new PreviewConstellation()); } if (((CompatibilityHandler)Plugin.LMUCompatibility).IsModPresent) { PreviewInfoTypes.Add("LMU", new PreviewLMU()); } SortInfoTypes.Add("None", new TerminalUtils.InfoTypes.Moons.SortNone()); SortInfoTypes.Add("Name", new TerminalUtils.InfoTypes.Moons.SortName()); SortInfoTypes.Add("Price", new TerminalUtils.InfoTypes.Moons.SortPrice()); SortInfoTypes.Add("Difficulty", new SortDifficulty()); if (((CompatibilityHandler)Plugin.LunarConfigCompat).IsModPresent) { SortInfoTypes.Add("Lunar", new SortLunar()); } FilterInfoTypes.Add("None", new FilterNone()); FilterInfoTypes.Add("Price", new FilterPrice()); FilterInfoTypes.Add("Weather", new FilterWeather()); StoreSortInfoTypes.Add("None", new TerminalUtils.InfoTypes.Store.SortNone()); StoreSortInfoTypes.Add("Name", new TerminalUtils.InfoTypes.Store.SortName()); StoreSortInfoTypes.Add("Price", new TerminalUtils.InfoTypes.Store.SortPrice()); } public static List<SelectableLevel> GetCurrentLevels() { List<SelectableLevel> inputList = CurrentFilterInfoType.Filter(LevelHelper.Levels).ToList(); return CurrentSortInfoType.Sort(inputList); } public static List<BuyableThing> GetCurrentStoreItems() { return CurrentStoreSortInfoType.Sort(ContentManager.Buyables.ToList()); } } public class TerminalNodeManager { internal static TerminalNode lastResolvedNode; public static void Init() { } public static TerminalKeyword AddVerb(string name, string word) { TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val).name = name; val.word = word; val.isVerb = true; ContentManager.AddTerminalKeywords(new List<TerminalKeyword>(1) { val }); return val; } public static void AddTerminalContent(List<TerminalNode> terminalNodes = null, List<TerminalKeyword> terminalKeywords = null) { if (terminalNodes != null && terminalNodes.Count > 0) { ContentManager.AddTerminalNodes(terminalNodes); } if (terminalKeywords != null && terminalKeywords.Count > 0) { ContentManager.AddTerminalKeywords(terminalKeywords); } } public static TerminalNode CreateTerminalNode(string name, string terminalEvent = "") { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = name; val.terminalEvent = terminalEvent; val.displayText = ""; val.clearPreviousText = true; val.acceptAnything = true; val.terminalOptions = Array.Empty<CompatibleNoun>(); val.maxCharactersToType = 25; val.itemCost = 0; val.buyItemIndex = -1; val.buyVehicleIndex = -1; val.buyRerouteToMoon = -1; val.displayPlanetInfo = -1; val.shipUnlockableID = -1; val.creatureFileID = -1; val.storyLogFileID = -1; val.playSyncedClip = -1; return val; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "mrov.TerminalUtils"; public const string PLUGIN_NAME = "TerminalUtils"; public const string PLUGIN_VERSION = "0.0.14"; } } namespace TerminalUtils.Patches { [HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed", new Type[] { typeof(CallbackContext) })] internal class TerminalScrollMousePatch { private static float scrollAmount = 1f / 3f; public static string CurrentText { get; internal set; } = ""; private static void ScrollMouse_performed(Scrollbar scrollbar, float scrollDirection) { if ((Object)(object)scrollbar == (Object)null) { ((Logger)Plugin.debugLogger).LogWarning("scrollbar is null - too bad!"); return; } if (string.CompareOrdinal(TerminalManager.Terminal.currentText, CurrentText) != 0) { CurrentText = TerminalManager.Terminal.currentText; Regex regex = new Regex("(?>\\n{1,2}|)[A-Za-z0-9\\ \\'\\:\\.’“,”?!/%*$;\\-\\+\\[\\]\\(\\)]{1,50}", RegexOptions.Multiline | RegexOptions.Compiled); int num = regex.Matches(CurrentText.Trim()).Count + 3; int num2 = ((!ConfigManager.UseLegacyScrollBehavior.Value) ? num : (CurrentText.Count((char c) => c.Equals('\n')) + 1)); int value = ConfigManager.LinesToScroll.Value; ((Logger)Plugin.debugLogger).LogWarning($"ScrollMouse_performed: text has changed; textLength = {num2}; amountOfLinesInCurrentPage = {num}"); float num3 = (float)value / (float)num; scrollAmount = num3; } scrollbar.value += scrollDirection * scrollAmount; ((Logger)Plugin.debugLogger).LogMessage($"ScrollMouse_performed: scrollbar.value = {scrollbar.value}, scrollDirection = {scrollDirection}, scrollAmount = {scrollAmount}"); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "terminalScrollVertical"), (string)null) }).Insert((CodeInstruction[])(object)new CodeInstruction[5] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "terminalScrollVertical")), new CodeInstruction(OpCodes.Ldloc_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(TerminalScrollMousePatch), "ScrollMouse_performed", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Ret, (object)null) }).InstructionEnumeration(); } } [HarmonyPatch(typeof(Terminal))] public static class TerminalLoadNewNodePatch { [HarmonyPrefix] [HarmonyPatch("LoadNewNode")] [HarmonyAfter(new string[] { "imabatby.lethallevelloader", "com.github.teamxiaolan.dawnlib" })] public static bool PatchMethod(Terminal __instance, TerminalNode node) { if (!NodeReplacementManager.ReplaceNode) { return true; } if (TerminalManager.NodeReplacements.ContainsKey(node)) { __instance.modifyingText = true; ((Selectable)__instance.screenText).interactable = true; TerminalNodeReplacement terminalNodeReplacement = TerminalManager.NodeReplacements[node]; if (!terminalNodeReplacement.Enabled.Value) { ((Logger)Plugin.debugLogger).LogInfo("Node replacement " + terminalNodeReplacement.Name + " is disabled, skipping replacement"); return true; } Plugin.logger.LogInfo((object)("Replacing node " + ((Object)__instance.currentNode).name + " with " + terminalNodeReplacement.Name)); StringBuilder stringBuilder = new StringBuilder(); if (Object.op_Implicit((Object)(object)__instance.displayingPersistentImage)) { stringBuilder.Append("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); } stringBuilder.Append("\n\n"); stringBuilder.Append(terminalNodeReplacement.GetNodeText(node)); stringBuilder.Append("\n" + new string('-', 17) + "\n"); __instance.LoadTerminalImage(node); __instance.currentNode = node; __instance.screenText.text = stringBuilder.ToString(); __instance.currentText = stringBuilder.ToString(); __instance.textAdded = 0; return false; } return true; } [HarmonyPostfix] [HarmonyPatch("LoadNewNode")] public static void PatchMethod() { NodeReplacementManager.ReplaceNode = true; } } [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] internal class TerminalParsePlayerSentencePatch { [HarmonyPrefix] [HarmonyBefore(new string[] { "mrov.WeatherRegistry" })] public static bool GameMethodPatch(Terminal __instance, ref TerminalNode __result) { string text = __instance.screenText.text; int textAdded = __instance.textAdded; string text2 = text.Substring(text.Length - textAdded); text2 = __instance.RemovePunctuation(text2); List<string> list = text2.Split(' ').ToList(); if (list.Count >= 1 && CommandManager.CommandLookup.TryGetValue(list[0], out var value)) { ((Logger)Plugin.debugLogger).LogWarning("Command detected, passing to CommandManager"); if (list.Count >= 2) { string[] args = list.Skip(1).ToArray(); TerminalNode val = CommandManager.RunTerminalCommand(value, args); __result = val; return false; } return true; } return true; } } [HarmonyPatch(typeof(Terminal))] public static class TerminalStartPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void Postfix(Terminal __instance) { StartupManager.Init(__instance); if (((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent) { Plugin.LLLCompatibility.RemoveMoonNodeEvent(); } } } } namespace TerminalUtils.Nodes { public class MoonCatalogue : TerminalNodeReplacement { public MoonCatalogue() : base("Moon Catalogue", TerminalManager.MoonsPage) { base.HelpText = " Welcome to the exomoons catalogue! \n Use ROUTE to set the autopilot. \n Use INFO to learn about a moon."; } public override string GetNodeText(TerminalNode node) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown List<SelectableLevel> currentLevels = TerminalManager.GetCurrentLevels(); ((Logger)Plugin.debugLogger).LogDebug("Current preview types: " + string.Join(", ", TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name))); StringBuilder stringBuilder = new StringBuilder(); ConsoleTable val = new ConsoleTable(TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => "").ToArray()); int num = 1; List<PreviewInfoType<SelectableLevel>> currentPreviewInfoType = TerminalManager.CurrentPreviewInfoType; ((Logger)Plugin.debugLogger).LogDebug("Current preview types: " + string.Join(", ", currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name))); foreach (SelectableLevel level in currentLevels) { if (LevelHelper.IsHidden(level) || (LevelHelper.IsLocked(level) && !ConfigManager.DisplayLockedMoons.Value) || Defaults.VanillaHiddenMoons.Contains(StringResolver.GetNumberlessName(level))) { continue; } string[] array = currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => (info.Name == "Name") ? ("* " + info.Value(level)) : info.Value(level)).ToArray(); object[] array2 = array; val.AddRow(array2); if (num % 3 == 0) { num = 1; array2 = currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> _) => "").ToArray(); val.AddRow(array2); } else { num++; } } stringBuilder.AppendLine((base.HelpText != null) ? ("\n" + base.HelpText + "\n\n") : ""); stringBuilder.Append($" The Company // Buying at {Mathf.RoundToInt(StartOfRound.Instance.companyBuyingRate * 100f)}% \n\n"); stringBuilder.Append(val.ToStringCustomDecoration(false, false, false)); stringBuilder.AppendLine(); stringBuilder.AppendLine(); stringBuilder.AppendLine("PREVIEW: " + string.Join(", ", currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name)) + "\nSORT: " + TerminalManager.CurrentSortInfoType.Name + "; FILTER: " + TerminalManager.CurrentFilterInfoType.Name); return stringBuilder.ToString().TrimEnd(); } } public class Scan : TerminalNodeReplacement { public Scan() : base("Scan", TerminalManager.ScanPage) { } public bool GrabbablePredicate(GrabbableObject obj) { bool inShipPhase = StartOfRound.Instance.inShipPhase; if (LevelHelper.CompanyMoons.Contains(StartOfRound.Instance.currentLevel)) { return true; } if (inShipPhase) { if (!obj.isInElevator) { return obj.isInShipRoom; } return true; } if (obj.isInShipRoom) { return !obj.isInElevator; } return true; } public List<GrabbableObject> GetObjects() { return (from x in Object.FindObjectsOfType<GrabbableObject>() where x.itemProperties.isScrap && (Object)(object)x.radarIcon != (Object)null && GrabbablePredicate(x) orderby x.scrapValue select x).ToList(); } public override string GetNodeText(TerminalNode node) { //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown bool value = ConfigManager.DetailedScanPage.Value; bool flag = ConfigManager.DisplayAccuratePrices.Value; Random random = new Random(StartOfRound.Instance.randomMapSeed); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("\n"); bool inShipPhase = StartOfRound.Instance.inShipPhase; bool flag2 = LevelHelper.CompanyMoons.Contains(StartOfRound.Instance.currentLevel); List<GrabbableObject> objects = GetObjects(); int num = objects.Count; int num2 = objects.Sum((GrabbableObject x) => x.scrapValue); if (flag2) { stringBuilder.Append("Scanning all scrap:"); } else { stringBuilder.Append("Scanning scrap " + (inShipPhase ? "in the ship" : "on the moon") + ":"); } if (!flag && (inShipPhase || flag2)) { flag = true; } if (!flag) { int num3 = 0; foreach (GrabbableObject item in objects) { num3 += Mathf.Clamp(random.Next(item.itemProperties.minValue, item.itemProperties.maxValue), item.scrapValue - 6 * num, item.scrapValue + 9 * num); } num2 = num3; } if (!value) { stringBuilder.Append(string.Format("\nFound {0} scrap item{1}, worth {2}${3}.", num, (num > 1) ? "s" : "", flag ? "" : "about ", num2)); } else { stringBuilder.Append(string.Format("\nFound {0} scrap item{1}, worth {2}${3}.", num, (num > 1) ? "s" : "", flag ? "" : "about ", num2)); stringBuilder.Append("\n\n"); ConsoleTable val = new ConsoleTable(new string[2] { "Name", "Price" }); foreach (GrabbableObject item2 in objects) { val.AddRow(new object[2] { item2.itemProperties.itemName.PadRight(Defaults.itemNameWidth), $"${(flag ? ((object)item2.scrapValue) : $"{item2.itemProperties.minValue}-${item2.itemProperties.maxValue}")}" }); num++; num2 += item2.scrapValue; } stringBuilder.Append("\n"); stringBuilder.Append(val.ToStringCustomDecoration(true, false, false)); } return stringBuilder.ToString(); } } public class StoreCatalogue : TerminalNodeReplacement { public StoreCatalogue() : base("Store Catalogue", TerminalManager.StorePage) { base.HelpText = " Welcome to the Company store. \n Use words BUY and INFO on any item. \n Order items in bulk by typing a number."; } public override string GetNodeText(TerminalNode node) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Name", "Price" }); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append((base.HelpText != null) ? ("\n" + base.HelpText + "\n") : ""); PurchaseType[] array = new PurchaseType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); PurchaseType[] desiredOrder = (PurchaseType[])(object)array; Dictionary<PurchaseType, List<BuyableThing>> dictionary = (from thing in TerminalManager.GetCurrentStoreItems() group thing by thing.Type).OrderBy(delegate(IGrouping<PurchaseType, BuyableThing> group) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) int num4 = Array.IndexOf(desiredOrder, group.Key); return (num4 != -1) ? num4 : int.MaxValue; }).ToDictionary((IGrouping<PurchaseType, BuyableThing> group) => group.Key, (IGrouping<PurchaseType, BuyableThing> group) => group.Where(delegate(BuyableThing item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected I4, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown PurchaseType type = item.Type; switch (type - 1) { case 0: { BuyableUnlockable val6 = (BuyableUnlockable)item; return !val6.IsUnlocked; } case 1: { BuyableDecoration val5 = (BuyableDecoration)item; if (val5.InRotation) { return !((BuyableUnlockable)val5).IsUnlocked; } return false; } case 2: { BuyableSuit val4 = (BuyableSuit)item; if (val4.InRotation) { return !val4.IsUnlocked; } return false; } default: return true; } }).ToList()); foreach (KeyValuePair<PurchaseType, List<BuyableThing>> item in dictionary) { if (item.Value.Count == 0) { continue; } int num = 1; val.AddRow(new object[2] { "", "" }); val.AddRow(new object[2] { "[" + ((object)item.Key/*cast due to .constrained prefix*/).ToString().ToUpperInvariant() + "S]", "" }); for (int num2 = 0; num2 < item.Value.Count; num2++) { BuyableThing val2 = item.Value[num2]; string text = val2.Name.PadRight(30); string text2 = $"${val2.Price}"; if ((int)val2.Type == 0) { BuyableItem val3 = (BuyableItem)val2; if (val3.Discount != 0) { string arg = ((val3.Discount != 0) ? $" (-{val3.Discount}%)" : ""); decimal d = Convert.ToDecimal(((BuyableThing)val3).Price) * Convert.ToDecimal(val3.DiscountPercentage); int num3 = (int)Math.Floor(d); text2 = $"${num3}{arg}"; } if (((CompatibilityHandler)Plugin.DawnCompatibility).IsModPresent) { if (!Plugin.DawnCompatibility.IsItemInStore(val3.Item)) { continue; } text = Plugin.DawnCompatibility.GetStoreItemNameOverride(val3.Item); } } val.AddRow(new object[2] { "* " + text, text2 ?? "" }); if (ConfigManager.DivideStore.Value != 0 && num2 != item.Value.Count - 1) { if (num % ConfigManager.DivideStore.Value == 0) { num = 1; val.AddRow(new object[2] { "", "" }); } else { num++; } } } } string value = val.ToStringCustomDecoration(false, true, false).TrimEnd(); stringBuilder.Append(value); return stringBuilder.ToString().TrimEnd(); } } } namespace TerminalUtils.InfoTypes.Store { public class SortName : SortInfoType<BuyableThing> { public SortName() : base("Name") { } public override List<BuyableThing> Sort(List<BuyableThing> inputList) { inputList.Sort((BuyableThing a, BuyableThing b) => a.Name.CompareTo(b.Name)); return inputList; } } public class SortNone : SortInfoType<BuyableThing> { public SortNone() : base("None") { } public override List<BuyableThing> Sort(List<BuyableThing> inputList) { return inputList; } } public class SortPrice : SortInfoType<BuyableThing> { public SortPrice() : base("Price") { } public override List<BuyableThing> Sort(List<BuyableThing> inputList) { inputList.Sort((BuyableThing a, BuyableThing b) => a.Price.CompareTo(b.Price)); return inputList; } } } namespace TerminalUtils.InfoTypes.Moons { public class FilterNone : FilterInfoType<SelectableLevel> { public FilterNone() : base("None") { } public override List<SelectableLevel> Filter(List<SelectableLevel> inputList) { return inputList; } } public class FilterPrice : FilterInfoType<SelectableLevel> { public FilterPrice() : base("Price") { } public override List<SelectableLevel> Filter(List<SelectableLevel> inputList) { return inputList.Where((SelectableLevel lvl) => ContentManager.RouteDictionary.GetRoute(lvl).Price <= ContentManager.Terminal.groupCredits).ToList(); } } public class FilterWeather : FilterInfoType<SelectableLevel> { public FilterWeather() : base("Weather") { } public override List<SelectableLevel> Filter(List<SelectableLevel> inputList) { return inputList.Where((SelectableLevel lvl) => ContentManager.RouteDictionary.GetRoute(lvl).Price >= ContentManager.Terminal.groupCredits).ToList(); } } public class PreviewConstellation : PreviewInfoType<SelectableLevel> { public PreviewConstellation() : base("Constellation") { } public override string Value(SelectableLevel inputValue) { return Plugin.LCCompatibility.GetConstellationName(inputValue); } } public class PreviewDifficulty : PreviewInfoType<SelectableLevel> { public PreviewDifficulty() : base("Difficulty") { base.MaxLength = 5; } public override string Value(SelectableLevel inputValue) { return inputValue.riskLevel; } } public class PreviewLMU : PreviewInfoType<SelectableLevel> { public PreviewLMU() : base("LMU") { } public override string Value(SelectableLevel inputValue) { object obj = (Plugin.LMUCompatibility.MoonUnlockables.TryGetValue(inputValue, out obj) ? obj : null); LMUnlockable val = (LMUnlockable)((obj is LMUnlockable) ? obj : null); if (val == null) { return null; } return val.BuildTagString(); } } public class PreviewName : PreviewInfoType<SelectableLevel> { public PreviewName() : base("Name") { base.MaxLength = LevelHelper.LongestPlanetName.Length; } public override string Value(SelectableLevel inputValue) { return StringResolver.GetNumberlessName(inputValue); } } public class PreviewNameNumbered : PreviewInfoType<SelectableLevel> { public PreviewNameNumbered() : base("NameNumbered") { base.MaxLength = LevelHelper.LongestPlanetName.Length + 4; } public override string Value(SelectableLevel inputValue) { string value = Regex.Match(inputValue.PlanetName, "^\\d+").Value; return value.PadLeft(3, '0') + " " + StringResolver.GetNumberlessName(inputValue); } } public class PreviewPrice : PreviewInfoType<SelectableLevel> { public PreviewPrice() : base("Price") { } public override string Value(SelectableLevel inputValue) { if (((CompatibilityHandler)Plugin.LGUCompat).IsModPresent) { return $"${Plugin.LGUCompat.GetMoonPrice(ContentManager.RouteDictionary.GetRoute(inputValue).Price)}"; } return $"${ContentManager.RouteDictionary.GetRoute(inputValue).Price}"; } } public class PreviewWeather : PreviewInfoType<SelectableLevel> { public PreviewWeather() : base("Weather") { } public override string Value(SelectableLevel inputValue) { string text = ((object)Unsafe.As<LevelWeatherType, LevelWeatherType>(ref inputValue.currentWeather)/*cast due to .constrained prefix*/).ToString(); if (((CompatibilityHandler)Plugin.WeatherRegistryCompatibility).IsModPresent) { text = Plugin.WeatherRegistryCompatibility.GetWeather(inputValue); } if (!(text == "None")) { return text; } return ""; } } public class SortDifficulty : SortInfoType<SelectableLevel> { private static readonly List<string> difficultyOrder = new List<string>(10) { "Safe", "F", "E", "D", "C", "B", "A", "S", "Unknown", "?" }; public SortDifficulty() : base("Difficulty") { } public override List<SelectableLevel> Sort(List<SelectableLevel> inputList) { inputList.Sort(delegate(SelectableLevel a, SelectableLevel b) { string source = (string.IsNullOrWhiteSpace(a.riskLevel) ? "Unknown" : a.riskLevel.Trim()); string source2 = (string.IsNullOrWhiteSpace(b.riskLevel) ? "Unknown" : b.riskLevel.Trim()); int num = source.Count((char c) => c == '+'); int num2 = source.Count((char c) => c == '-'); int num3 = source2.Count((char c) => c == '+'); int num4 = source2.Count((char c) => c == '-'); string baseA = new string(source.Where((char c) => c != '+' && c != '-').ToArray()).Trim(); string baseB = new string(source2.Where((char c) => c != '+' && c != '-').ToArray()).Trim(); if (string.IsNullOrEmpty(baseA)) { baseA = "Unknown"; } if (string.IsNullOrEmpty(baseB)) { baseB = "Unknown"; } int num5 = difficultyOrder.FindIndex((string s) => string.Equals(s, baseA, StringComparison.OrdinalIgnoreCase)); int num6 = difficultyOrder.FindIndex((string s) => string.Equals(s, baseB, StringComparison.OrdinalIgnoreCase)); if (num5 == -1) { num5 = difficultyOrder.Count; } if (num6 == -1) { num6 = difficultyOrder.Count; } if (num5 != num6) { return num5.CompareTo(num6); } int num7 = num - num2; int value = num3 - num4; return num7.CompareTo(value); }); return inputList; } } public class SortLunar : SortInfoType<SelectableLevel> { public SortLunar() : base("Lunar") { } public override List<SelectableLevel> Sort(List<SelectableLevel> inputList) { inputList.Sort((SelectableLevel a, SelectableLevel b) => Plugin.LunarConfigCompat.GetMoonIndex(b).CompareTo(Plugin.LunarConfigCompat.GetMoonIndex(a))); return inputList; } } public class SortName : SortInfoType<SelectableLevel> { public SortName() : base("Name") { } public override List<SelectableLevel> Sort(List<SelectableLevel> inputList) { inputList.Sort((SelectableLevel a, SelectableLevel b) => StringResolver.GetAlphanumericName(a).CompareTo(StringResolver.GetAlphanumericName(b))); return inputList; } } public class SortNone : SortInfoType<SelectableLevel> { public SortNone() : base("None") { } public override List<SelectableLevel> Sort(List<SelectableLevel> inputList) { return inputList; } } public class SortPrice : SortInfoType<SelectableLevel> { public SortPrice() : base("Price") { } public override List<SelectableLevel> Sort(List<SelectableLevel> inputList) { inputList.Sort((SelectableLevel a, SelectableLevel b) => ContentManager.RouteDictionary.GetRoute(a).Price.CompareTo(ContentManager.RouteDictionary.GetRoute(b).Price)); return inputList; } } } namespace TerminalUtils.Enums { public enum TerminalDisplayType { Preview, Sort, Filter } } namespace TerminalUtils.Definitions { public abstract class ConfigHandler<T, CT> : ConfigHandler<T, CT> { public ConfigHandler(CT value) { ((ConfigHandler<T, CT>)this).DefaultValue = value; } } public class FilterInfoType<T> : TerminalInfoType { public FilterInfoType(string Name) { base.Name = Name; base.Type = TerminalDisplayType.Filter; } public virtual List<T> Filter(List<T> inputList) { return inputList; } } public interface ITerminalInfoType { string Name { get; } TerminalDisplayType Type { get; } } public class TerminalInfoType : ITerminalInfoType { public string Name { get; set; } public TerminalDisplayType Type { get; set; } public override string ToString() { return $"{Name} ({Type})"; } } public class PreviewGroup { public List<PreviewInfoType> PreviewInfoTypes { get; set; } } public class PreviewInfoType : TerminalInfoType { public int MaxLength { get; set; } = Defaults.terminalWidth; public PreviewInfoType(string Name) { base.Name = Name; base.Type = TerminalDisplayType.Preview; } } public abstract class PreviewInfoType<T> : PreviewInfoType { protected PreviewInfoType(string Name) : base(Name) { } public string ValueWithMaxLength(T inputValue) { string text = Value(inputValue); if (text.Length > base.MaxLength) { text = text.Substring(0, base.MaxLength - 3) + "..."; } return text; } public virtual string Value(T inputValue) { return ""; } public override string ToString() { return $"{base.Name} ({base.Type})"; } } public class SortInfoType<T> : TerminalInfoType { public SortInfoType(string Name) { base.Name = Name; base.Type = TerminalDisplayType.Sort; } public virtual List<T> Sort(List<T> inputList) { return inputList; } } public abstract class TerminalCommandNode : CommandNode { public List<TerminalCommandNode> Subcommands { get; set; } = new List<TerminalCommandNode>(); public bool HostOnly { get; set; } public int TerminalSound { get; set; } = -1; public TerminalNode RedirectToNode { get; set; } protected TerminalCommandNode(string Name) : base(Name) { } public virtual bool ShouldRun() { if (!HostOnly || ((NetworkBehaviour)StartOfRound.Instance).IsHost) { return true; } return false; } public virtual string Execute(string[] args) { return ""; } } public abstract class TerminalNodeReplacement { public string Name { get; set; } public string HelpText { get; set; } public TerminalNode NodeToMatch { get; set; } public ConfigEntry<bool> Enabled { get; set; } public virtual bool IsNodeValid(TerminalNode node) { return true; } public abstract string GetNodeText(TerminalNode node); public TerminalNodeReplacement(string name, TerminalNode NodeToMatch, ConfigEntry<bool> enabled = null) { Name = name; this.NodeToMatch = NodeToMatch; if (enabled != null) { Enabled = enabled; } else { Enabled = ConfigManager.configFile.Bind<bool>("Nodes", name, true, "Enable node " + name); } NodeReplacementManager.RegisteredNodes.Add(this); ((Logger)Plugin.debugLogger).LogInfo("Registered node " + name); } } } namespace TerminalUtils.Compatibility { public class DawnLibCompatibility : CompatibilityHandler { public DawnLibCompatibility(string guid, string version = null) : base(guid, version, false) { } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public override void Init() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown if (((CompatibilityHandler)this).IsModPresent) { Type type = AccessTools.TypeByName("Dawn.MoonRegistrationHandler"); Plugin.harmony.Patch((MethodBase)AccessTools.Method(type, "DynamicMoonCatalogue", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(DawnLibCompatibility), "InsertMoonCatalogueSkip", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public object GetLevelDawnInfo(SelectableLevel level) { return SelectableLevelExtensions.GetDawnInfo(level); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public (bool locked, bool hidden) GetLevelStatus(SelectableLevel level) { if (!((CompatibilityHandler)this).IsModPresent) { return (locked: false, hidden: false); } TerminalPurchaseResult val = SelectableLevelExtensions.GetDawnInfo(level).DawnPurchaseInfo.PurchasePredicate.CanPurchase(); HiddenPurchaseResult val2 = (HiddenPurchaseResult)(object)((val is HiddenPurchaseResult) ? val : null); if (val2 == null) { if (!(val is FailedPurchaseResult)) { if (val is SuccessPurchaseResult) { return (locked: false, hidden: false); } return (locked: false, hidden: false); } return (locked: true, hidden: false); } return (locked: val2.IsFailure, hidden: true); } public static IEnumerable<CodeInstruction> InsertMoonCatalogueSkip(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.Start().Insert((CodeInstruction[])(object)new CodeInstruction[6] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Ldarg_2, (object)null), new CodeInstruction(OpCodes.Ldarg_3, (object)null), new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.Method(typeof(orig_TextPostProcess), "Invoke", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Ret, (object)null) }); return val.InstructionEnumeration(); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static Dictionary<string, int> GetDungeonRarities(SelectableLevel level) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); DawnMoonInfo dawnInfo = SelectableLevelExtensions.GetDawnInfo(level); List<DawnDungeonInfo> list = new List<DawnDungeonInfo>(); List<float> list2 = new List<float>(); SpawnWeightContext val = default(SpawnWeightContext); foreach (DawnDungeonInfo value2 in ((Registry<DawnDungeonInfo>)(object)LethalContent.Dungeons).Values) { ((SpawnWeightContext)(ref val))..ctor(dawnInfo, (DawnDungeonInfo)null, (DawnWeatherEffectInfo)null); int valueOrDefault = ProviderTableSpawnWeightExtensions.GetFor<int?>(value2.Weights, ref val).GetValueOrDefault(); if (valueOrDefault > 0) { list.Add(value2); list2.Add(valueOrDefault); } } ((Logger)Plugin.debugLogger).LogDebug(string.Format("Found {0} possible dungeons for level {1}: {2}", list.Count, level.PlanetName, string.Join(", ", list.Select((DawnDungeonInfo d) => ((DawnBaseInfo<DawnDungeonInfo>)(object)d).Key)))); for (int num = 0; num < list.Count; num++) { string key = StringExtensions.ReplaceNumbersWithWords(StringExtensions.ToCapitalized(StringExtensions.RemoveLeadingNumbers(((DawnBaseInfo<DawnDungeonInfo>)(object)list[num]).Key.Key))).Replace(" ", "_"); int value = (int)list2[num]; dictionary[key] = value; } return dictionary; } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public string GetStoreItemNameOverride(Item item) { if ((Object)(object)item == (Object)null) { return null; } DawnItemInfo dawnInfo = ItemExtensions.GetDawnInfo(item); DawnShopItemInfo shopInfo = dawnInfo.ShopInfo; if (shopInfo == null) { return item.itemName; } TerminalPurchaseResult val = shopInfo.DawnPurchaseInfo.PurchasePredicate.CanPurchase(); FailedPurchaseResult val2 = (FailedPurchaseResult)(object)((val is FailedPurchaseResult) ? val : null); if (val2 != null) { if (val2.OverrideName != null) { ((Logger)Plugin.debugLogger).LogCustom($"Overriding name of {((DawnBaseInfo<DawnItemInfo>)(object)dawnInfo).Key} with {val2.OverrideName}", (LogLevel)32, (LoggingType)1); } return val2.OverrideName ?? item.itemName; } return item.itemName; } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public bool IsItemInStore(Item item) { if ((Object)(object)item == (Object)null) { return false; } DawnItemInfo dawnInfo = ItemExtensions.GetDawnInfo(item); object obj; if (dawnInfo == null) { obj = null; } else { DawnShopItemInfo shopInfo = dawnInfo.ShopInfo; if (shopInfo == null) { obj = null; } else { DawnPurchaseInfo dawnPurchaseInfo = shopInfo.DawnPurchaseInfo; obj = ((dawnPurchaseInfo != null) ? dawnPurchaseInfo.PurchasePredicate : null); } } ITerminalPurchasePredicate val = (ITerminalPurchasePredicate)obj; if (val == null) { return false; } return !(val.CanPurchase() is HiddenPurchaseResult); } } internal class LategameUpgradesCompatibility : CompatibilityHandler { public LategameUpgradesCompatibility(string guid, string version = null) : base(guid, version, false) { } internal int GetMoonPrice(int price) { string text = "MoreShipUpgrades.UpgradeComponents.TierUpgrades.EfficientEngines"; Type type = ((CompatibilityHandler)Plugin.LGUCompat).GetModAssembly.GetType(text ?? ""); if (type == null) { ((Logger)Plugin.debugLogger).LogWarning("Could not find " + text + " type"); return price; } MethodInfo method = type.GetMethod("GetDiscountedMoonPrice", BindingFlags.Static | BindingFlags.Public); if (method == null) { ((Logger)Plugin.debugLogger).LogWarning("Could not find GetDiscountedMoonPrice method in EfficientEngines"); return price; } return (int)method.Invoke(null, new object[1] { price }); } } public class LethalConstellationsCompatibility : CompatibilityHandler { public Dictionary<SelectableLevel, string> Constellations { get; private set; } = new Dictionary<SelectableLevel, string>(); public LethalConstellationsCompatibility(string guid, string version = null) : base(guid, version, false) { } public override void Init() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (((CompatibilityHandler)this).IsModPresent) { EventManager.ContentManagerReady.AddListener(new Event(GetConstellations)); } } public void GetConstellations() { if (!((CompatibilityHandler)this).IsModPresent || !((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent) { return; } Dictionary<SelectableLevel, string> constellationsDict = new Dictionary<SelectableLevel, string>(); List<ClassMapper> constellationStuff = Collections.ConstellationStuff; foreach (ClassMapper item in constellationStuff) { string constellationName = item.consName; List<SelectableLevel> list = (from moonName in item.constelMoons select StringResolver.ResolveStringToLevels(moonName).FirstOrDefault() into level where (Object)(object)level != (Object)null select level).ToList(); list.ForEach(delegate(SelectableLevel level) { constellationsDict[level] = constellationName; }); } Constellations = constellationsDict; } public string GetConstellationName(SelectableLevel level) { if (!((CompatibilityHandler)this).IsModPresent) { return null; } Constellations.TryGetValue(level, out var value); return value; } } public class LethalLevelLoaderCompatibility : CompatibilityHandler { public LethalLevelLoaderCompatibility(string guid, string version = null) : base(guid, version, false) { } public void RemoveMoonNodeEvent() { if (((CompatibilityHandler)this).IsModPresent) { TerminalManager.onLoadNewNodeRegisteredEventsDictionary.Clear(); } } public static bool IsLevelLocked(SelectableLevel level) { return SharedMethods.IsMoonLockedLLL(level); } public static bool IsLevelHidden(SelectableLevel level) { return SharedMethods.IsMoonHiddenLLL(level); } public static List<ExtendedDungeonFlowWithRarity> GetExtendedDungeonFlowsWithRarity(ExtendedLevel extendedLevel) { List<ExtendedDungeonFlowWithRarity> list = new List<ExtendedDungeonFlowWithRarity>(); CollectionExtensions.Do<ExtendedDungeonFlowWithRarity>((IEnumerable<ExtendedDungeonFlowWithRarity>)DungeonManager.GetValidExtendedDungeonFlows(extendedLevel, false), (Action<ExtendedDungeonFlowWithRarity>)list.Add); return list; } public static Dictionary<string, int> GetDungeonRarities(SelectableLevel level) { Dictionary<string, int> result = new Dictionary<string, int>(); ExtendedLevel extendedLevel = default(ExtendedLevel); LevelManager.TryGetExtendedLevel(level, ref extendedLevel, (ContentType)2); CollectionExtensions.Do<ExtendedDungeonFlowWithRarity>((IEnumerable<ExtendedDungeonFlowWithRarity>)GetExtendedDungeonFlowsWithRarity(extendedLevel), (Action<ExtendedDungeonFlowWithRarity>)delegate(ExtendedDungeonFlowWithRarity flow) { result[((Object)flow.extendedDungeonFlow.DungeonFlow).name] = flow.rarity; }); return result; } } internal class LethalLibCompatibility : CompatibilityHandler { public LethalLibCompatibility(string guid, string version = null) : base(guid, version, false) { } public static bool IsLLItemDisabled(Item item) { return Items.shopItems.Find((ShopItem x) => (Object)(object)x.item == (Object)(object)item)?.wasRemoved ?? false; } public static bool IsLLUpgradeDisabled(UnlockableItem unlockable) { return Unlockables.registeredUnlockables.Find((RegisteredUnlockable x) => x.unlockable == unlockable)?.disabled ?? false; } } public class LethalMoonUnlocksCompatibility : CompatibilityHandler { public Dictionary<SelectableLevel, object> MoonUnlockables { get; private set; } = new Dictionary<SelectableLevel, object>(); public LethalMoonUnlocksCompatibility(string guid, string version = null) : base(guid, version, false) { } public override void Init() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (((CompatibilityHandler)this).IsModPresent) { EventManager.ContentManagerReady.AddListener(new Event(PopulateDictionary)); } } public void PopulateDictionary() { if (!((CompatibilityHandler)this).IsModPresent) { return; } List<LMUnlockable> unlocks = UnlockManager.Instance.Unlocks; Dictionary<SelectableLevel, object> dictionary = new Dictionary<SelectableLevel, object>(); foreach (LMUnlockable item in unlocks) { SelectableLevel selectableLevel = item.ExtendedLevel.SelectableLevel; if ((Object)(object)selectableLevel != (Object)null) { dictionary[selectableLevel] = item; } } MoonUnlockables = dictionary; } } public class LunarConfigCompatibility : CompatibilityHandler { [CompilerGenerated] private static class <>O { public static Event <0>__ProcessNewOrder; } private static Dictionary<object, int> rawIndex = new Dictionary<object, int>(); private static Dictionary<SelectableLevel, int> newIndex = new Dictionary<SelectableLevel, int>(); public LunarConfigCompatibility(string guid, string version = null) : base(guid, version, false) { } public override void Init() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //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_006f: Expected O, but got Unknown Plugin.logger.LogDebug((object)"Initializing LunarConfig compatibility..."); Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(LunarCentral), "InitMoons", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LunarConfigCompatibility), "LunarConfig_GetOrderingAlgorithm", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); CustomEvent contentManagerReady = EventManager.ContentManagerReady; object obj = <>O.<0>__ProcessNewOrder; if (obj == null) { Event val = ProcessNewOrder; <>O.<0>__ProcessNewOrder = val; obj = (object)val; } contentManagerReady.AddListener((Event)obj); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static IEnumerable<CodeInstruction> LunarConfig_GetOrderingAlgorithm(IEnumerable<CodeInstruction> instructions) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); ConstructorInfo lunarCustomOrderCtor = AccessTools.Constructor(typeof(LunarConfigCustomMoonOrder), new Type[1] { typeof(Dictionary<DawnMoonInfo, int>) }, false); MethodInfo methodInfo = AccessTools.Method(typeof(LunarConfigCompatibility), "PassNewCatalogueIndex", (Type[])null, (Type[])null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ci.opcode == OpCodes.Newobj && object.Equals(ci.operand, lunarCustomOrderCtor)), (string)null) }); if (val.IsValid) { ((Logger)Plugin.debugLogger).LogDebug("Found the target instruction for LunarConfig_GetOrderingAlgorithm transpiler."); val.Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)methodInfo) }); } else { ((Logger)Plugin.debugLogger).LogDebug("Failed to find the target instruction for LunarConfig_GetOrderingAlgorithm transpiler."); } return val.InstructionEnumeration(); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static Dictionary<DawnMoonInfo, int> PassNewCatalogueIndex(Dictionary<DawnMoonInfo, int> newCatalogueIndex) { if (newCatalogueIndex == null) { return null; } newIndex.Clear(); rawIndex.Clear(); foreach (KeyValuePair<DawnMoonInfo, int> item in newCatalogueIndex) { rawIndex[item.Key] = item.Value; } return newCatalogueIndex; } private static void ProcessNewOrder() { if (rawIndex == null || rawIndex.Count == 0) { return; } List<SelectableLevel> levels = LevelHelper.Levels; foreach (SelectableLevel item in levels) { if (!((Object)(object)item == (Object)null)) { DawnMoonInfo dawnInfo; try { dawnInfo = SelectableLevelExtensions.GetDawnInfo(item); } catch { continue; } if (dawnInfo != null) { newIndex[item] = (rawIndex.TryGetValue(dawnInfo, out var value) ? value : 0); } } } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public int GetMoonIndex(SelectableLevel moon) { if (newIndex == null || !((Object)(object)moon != (Object)null) || !newIndex.TryGetValue(moon, out var value)) { return 0; } return value; } } internal class StoreRotationConfigCompatibility : CompatibilityHandler { public StoreRotationConfigCompatibility(string guid, string version = null) : base(guid, version, false) { } public override void Init() { if (((CompatibilityHandler)this).IsModPresent) { UnpatchTerminalScroll(); } } public static int GetDiscountedPrice(BuyableThing buyable, out int discount) { return RotationSalesAPI.GetDiscountedPrice(buyable.Nodes.Node, ref discount); } public static void UnpatchTerminalScroll() { Plugin.harmony.Unpatch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "ScrollMouse_performed", (Type[])null, (Type[])null), (HarmonyPatchType)3, "pacoito.StoreRotationConfig"); } } internal class WeatherRegistryCompatibility : CompatibilityHandler { public WeatherRegistryCompatibility(string guid, string version = null) : base(guid, version, false) { } public string GetWeather(SelectableLevel level) { return WeatherManager.GetCurrentWeatherName(level, false); } } } namespace TerminalUtils.Commands { public class FilterCommand : TerminalCommandNode { public FilterCommand() : base("filter") { base.RedirectToNode = TerminalManager.MoonsPage; } public override string Execute(string[] args) { string filterTypeName = "none"; Dictionary<string, FilterInfoType<SelectableLevel>> infoTypes = TerminalManager.FilterInfoTypes.Select((KeyValuePair<string, FilterInfoType<SelectableLevel>> kv) => kv.Value).ToDictionary((FilterInfoType<SelectableLevel> infoType) => infoType.Name.ToLowerInvariant(), (FilterInfoType<SelectableLevel> infoType) => infoType); ((Logger)Plugin.debugLogger).LogDebug("Possible filter types: " + string.Join(", ", infoTypes.Keys)); args.ToList().ForEach(delegate(string arg) { if (infoTypes.ContainsKey(arg)) { filterTypeName = arg; } }); TerminalManager.CurrentFilterInfoType = infoTypes[filterTypeName]; ConfigManager.FilterInfoType.Value = infoTypes[filterTypeName].Name; return ""; } } public class PreviewCommand : TerminalCommandNode { public PreviewCommand() : base("preview") { base.RedirectToNode = TerminalManager.MoonsPage; } public override string Execute(string[] args) { List<string> previewTypeNames = new List<string>(1) { "name" }; Dictionary<string, PreviewInfoType<SelectableLevel>> infoTypes = TerminalManager.PreviewInfoTypes.Select((KeyValuePair<string, PreviewInfoType<SelectableLevel>> kv) => kv.Value).ToDictionary((PreviewInfoType<SelectableLevel> infoType) => infoType.Name.ToLowerInvariant(), (PreviewInfoType<SelectableLevel> infoType) => infoType); ((Logger)Plugin.debugLogger).LogDebug("Possible preview types: " + string.Join(", ", infoTypes.Keys)); args.ToList().ForEach(delegate(string arg) { infoTypes.Keys.Select((string key) => key.ToLowerInvariant()).ToList().ForEach(delegate(string key) { if (key.ToLowerInvariant().StartsWith(arg.ToLowerInvariant())) { Plugin.logger.LogDebug((object)("Preview type '" + arg + "' matched '" + key + "'")); arg = key; } }); if (infoTypes.ContainsKey(arg)) { previewTypeNames.Add(arg); } }); TerminalManager.CurrentPreviewInfoType = previewTypeNames.Select((string name) => infoTypes[name]).ToList(); ConfigManager.PreviewInfoType.Value = string.Join(";", TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name)); return ""; } } public class SimulateCommand : TerminalCommandNode { private static Dictionary<string, int> LLLResult = new Dictionary<string, int>(); private static Dictionary<string, int> DawnResult = new Dictionary<string, int>(); public SimulateCommand() : base("simulate") { } public override string Execute(string[] args) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown SelectableLevel val = StringResolver.ResolveStringToLevels(args[0]).FirstOrDefault(); if ((Object)(object)val == (Object)null) { return "Level \"" + args[0] + "\" not found!"; } Plugin.logger.LogInfo((object)("Simulating level: " + val.PlanetName)); if (LevelHelper.CompanyMoons.Contains(val) || !val.spawnEnemiesAndScrap) { return val.PlanetName + " cannot generate interior!"; } Dictionary<string, int> source = new Dictionary<string, int>(); if (((CompatibilityHandler)Plugin.DawnCompatibility).IsModPresent) { source = DawnLibCompatibility.GetDungeonRarities(val); } else if (((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent) { source = LethalLevelLoaderCompatibility.GetDungeonRarities(val); } if (((CompatibilityHandler)Plugin.DawnCompatibility).IsModPresent) { DawnResult = DawnLibCompatibility.GetDungeonRarities(val); } if (((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent) { LLLResult = LethalLevelLoaderCompatibility.GetDungeonRarities(val); } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Simulating dungeons on moon: " + LevelHelper.GetAlphanumericName(val) + " \n\n"); ConsoleTable val2 = new ConsoleTable(new string[3] { "Interior", "Weight", "Chance" }); val2.AddRow(new object[3] { "", "", "" }); Dictionary<string, int> dictionary = source.OrderBy((KeyValuePair<string, int> o) => -o.Value).ToDictionary((KeyValuePair<string, int> k) => k.Key, (KeyValuePair<string, int> v) => v.Value); int num = dictionary.Values.Sum(); ((Logger)Plugin.debugLogger).LogDebug(string.Format("Total rarity pool for level {0}: {1}. Flows with rarity: {2}", val.PlanetName, num, string.Join("; ", dictionary.Select((KeyValuePair<string, int> kv) => $"{kv.Key} (rarity: {kv.Value})")))); foreach (var (text2, num3) in dictionary) { val2.AddRow(new object[3] { text2.PadRight(20), num3, (((float)num3 / (float)num * 100f).ToString("F2") + "%").PadLeft(4) }); } val2.AddRow(new object[3] { "", "", "" }); val2.AddRow(new object[3] { "", "", "" }); val2.AddRow(new object[3] { "", num.ToString().PadRight(6), "100%".ToString().PadLeft(4) }); stringBuilder.AppendLine(val2.ToStringCustomDecoration(true, false, false)); return stringBuilder.ToString(); } } public class SortCommand : TerminalCommandNode { public SortCommand() : base("sort") { base.RedirectToNode = TerminalManager.MoonsPage; } public override string Execute(string[] args) { string sortTypeName = "none"; Dictionary<string, SortInfoType<SelectableLevel>> infoTypes = TerminalManager.SortInfoTypes.Select((KeyValuePair<string, SortInfoType<SelectableLevel>> kv) => kv.Value).ToDictionary((SortInfoType<SelectableLevel> infoType) => infoType.Name.ToLowerInvariant(), (SortInfoType<SelectableLevel> infoType) => infoType); ((Logger)Plugin.debugLogger).LogDebug("Possible sort types: " + string.Join(", ", infoTypes.Keys)); args.ToList().ForEach(delegate(string arg) { if (infoTypes.ContainsKey(arg)) { sortTypeName = arg; } }); TerminalManager.CurrentSortInfoType = infoTypes[sortTypeName]; ConfigManager.SortInfoType.Value = infoTypes[sortTypeName].Name; return ""; } } public class StoreSortCommand : TerminalCommandNode { public StoreSortCommand() : base("store") { base.RedirectToNode = TerminalManager.StorePage; } public override string Execute(string[] args) { string sortTypeName = "name"; Dictionary<string, SortInfoType<BuyableThing>> infoTypes = TerminalManager.StoreSortInfoTypes.Select((KeyValuePair<string, SortInfoType<BuyableThing>> kv) => kv.Value).ToDictionary((SortInfoType<BuyableThing> infoType) => infoType.Name.ToLowerInvariant(), (SortInfoType<BuyableThing> infoType) => infoType); ((Logger)Plugin.debugLogger).LogDebug("Possible store sort types: " + string.Join(", ", infoTypes.Keys)); args.ToList().ForEach(delegate(string arg) { if (infoTypes.ContainsKey(arg)) { sortTypeName = arg; } }); TerminalManager.CurrentStoreSortInfoType = infoTypes[sortTypeName]; ConfigManager.StoreSortInfoType.Value = infoTypes[sortTypeName].Name; return ""; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }