using 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 Commands { get; set; } = new List(); public static Dictionary CommandLookup { get { Dictionary lookup = new Dictionary(); 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 LoggingLevels { get; private set; } public static ConfigEntry LinesToScroll { get; private set; } public static ConfigEntry UseLegacyScrollBehavior { get; private set; } public static ConfigEntry PreviewInfoType { get; private set; } public static ConfigEntry FilterInfoType { get; private set; } public static ConfigEntry SortInfoType { get; private set; } public static ConfigEntry DisplayLockedMoons { get; private set; } public static ConfigEntry StoreSortInfoType { get; private set; } public static ConfigEntry DivideStore { get; private set; } public static ConfigEntry DetailedScanPage { get; private set; } public static ConfigEntry DisplayAccuratePrices { get; private set; } public static void Init(ConfigFile config) { Instance = new ConfigManager(config); } private ConfigManager(ConfigFile config) { configFile = config; LoggingLevels = configFile.Bind("Debug", "Logging Levels", (LoggingType)0, "Set the logging level for the mod"); LinesToScroll = configFile.Bind("General", "Lines to Scroll", 10, "Number of lines to scroll per mouse wheel tick"); UseLegacyScrollBehavior = configFile.Bind("General", "Use Legacy Scroll Behavior", false, "Whether to use the legacy scroll behavior (from TerminalFormatter)"); PreviewInfoType = configFile.Bind("Preferences", "Preview Info Type", Defaults.defaultPreviewType, "Set the preview info type. Must be the name of an existing preview info type."); FilterInfoType = configFile.Bind("Preferences", "Filter Info Type", Defaults.defaultFilterType, "Set the filter info type. Must be the name of an existing filter info type."); SortInfoType = configFile.Bind("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("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("Moons", "Display Locked Moons", true, "Whether to display locked moons in the moon catalogue."); DivideStore = configFile.Bind("Store", "Divide Store page into groups", 5, "Set the number of items to divide the store into. 0 means no division."); DetailedScanPage = configFile.Bind("Scan", "Display Detailed Scan", true, "Enable detailed scan page"); DisplayAccuratePrices = configFile.Bind("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> 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> info) => info.Key.ToLowerInvariant() == typeName.ToLowerInvariant()) into info where info.Value != null select info.Value).ToList(); } public static FilterInfoType GetFilterInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return TerminalManager.FilterInfoTypes["None"]; } FilterInfoType value = TerminalManager.FilterInfoTypes.FirstOrDefault((KeyValuePair> 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 GetSortInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return TerminalManager.SortInfoTypes["None"]; } SortInfoType value = TerminalManager.SortInfoTypes.FirstOrDefault((KeyValuePair> 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 GetStoreSortInfoType(string inputString) { if (string.IsNullOrEmpty(inputString)) { return TerminalManager.StoreSortInfoTypes["None"]; } return TerminalManager.StoreSortInfoTypes.FirstOrDefault((KeyValuePair> 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 RegisteredNodes = new List(); 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> PreviewInfoTypes = new Dictionary>(); public static Dictionary> FilterInfoTypes = new Dictionary>(); public static Dictionary> SortInfoTypes = new Dictionary>(); public static Dictionary> StoreSortInfoTypes = new Dictionary>(); public static Dictionary NodeReplacements = new Dictionary(); 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> CurrentPreviewInfoType { get; set; } public static FilterInfoType CurrentFilterInfoType { get; set; } public static SortInfoType CurrentSortInfoType { get; set; } public static SortInfoType CurrentStoreSortInfoType { get; set; } internal static void Init(Terminal terminal) { MoonsPage = ContentManager.MoonsKeyword.specialKeywordResult; StorePage = ((IEnumerable)ContentManager.Nodes).FirstOrDefault((Func)((TerminalNode node) => ((Object)node).name == "0_StoreHub")); ScanPage = ((IEnumerable)ContentManager.Nodes).FirstOrDefault((Func)((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 { { 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 GetCurrentLevels() { List inputList = CurrentFilterInfoType.Filter(LevelHelper.Levels).ToList(); return CurrentSortInfoType.Sort(inputList); } public static List 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(); ((Object)val).name = name; val.word = word; val.isVerb = true; ContentManager.AddTerminalKeywords(new List(1) { val }); return val; } public static void AddTerminalContent(List terminalNodes = null, List 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(); ((Object)val).name = name; val.terminalEvent = terminalEvent; val.displayText = ""; val.clearPreviousText = true; val.acceptAnything = true; val.terminalOptions = Array.Empty(); 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 Transpiler(IEnumerable 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 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 currentLevels = TerminalManager.GetCurrentLevels(); ((Logger)Plugin.debugLogger).LogDebug("Current preview types: " + string.Join(", ", TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType info) => info.Name))); StringBuilder stringBuilder = new StringBuilder(); ConsoleTable val = new ConsoleTable(TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType info) => "").ToArray()); int num = 1; List> currentPreviewInfoType = TerminalManager.CurrentPreviewInfoType; ((Logger)Plugin.debugLogger).LogDebug("Current preview types: " + string.Join(", ", currentPreviewInfoType.Select((PreviewInfoType 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 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 _) => "").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 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 GetObjects() { return (from x in Object.FindObjectsOfType() 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 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> dictionary = (from thing in TerminalManager.GetCurrentStoreItems() group thing by thing.Type).OrderBy(delegate(IGrouping 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 group) => group.Key, (IGrouping 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> 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 { public SortName() : base("Name") { } public override List Sort(List inputList) { inputList.Sort((BuyableThing a, BuyableThing b) => a.Name.CompareTo(b.Name)); return inputList; } } public class SortNone : SortInfoType { public SortNone() : base("None") { } public override List Sort(List inputList) { return inputList; } } public class SortPrice : SortInfoType { public SortPrice() : base("Price") { } public override List Sort(List inputList) { inputList.Sort((BuyableThing a, BuyableThing b) => a.Price.CompareTo(b.Price)); return inputList; } } } namespace TerminalUtils.InfoTypes.Moons { public class FilterNone : FilterInfoType { public FilterNone() : base("None") { } public override List Filter(List inputList) { return inputList; } } public class FilterPrice : FilterInfoType { public FilterPrice() : base("Price") { } public override List Filter(List inputList) { return inputList.Where((SelectableLevel lvl) => ContentManager.RouteDictionary.GetRoute(lvl).Price <= ContentManager.Terminal.groupCredits).ToList(); } } public class FilterWeather : FilterInfoType { public FilterWeather() : base("Weather") { } public override List Filter(List inputList) { return inputList.Where((SelectableLevel lvl) => ContentManager.RouteDictionary.GetRoute(lvl).Price >= ContentManager.Terminal.groupCredits).ToList(); } } public class PreviewConstellation : PreviewInfoType { public PreviewConstellation() : base("Constellation") { } public override string Value(SelectableLevel inputValue) { return Plugin.LCCompatibility.GetConstellationName(inputValue); } } public class PreviewDifficulty : PreviewInfoType { public PreviewDifficulty() : base("Difficulty") { base.MaxLength = 5; } public override string Value(SelectableLevel inputValue) { return inputValue.riskLevel; } } public class PreviewLMU : PreviewInfoType { 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 { public PreviewName() : base("Name") { base.MaxLength = LevelHelper.LongestPlanetName.Length; } public override string Value(SelectableLevel inputValue) { return StringResolver.GetNumberlessName(inputValue); } } public class PreviewNameNumbered : PreviewInfoType { 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 { 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 { public PreviewWeather() : base("Weather") { } public override string Value(SelectableLevel inputValue) { string text = ((object)Unsafe.As(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 { private static readonly List difficultyOrder = new List(10) { "Safe", "F", "E", "D", "C", "B", "A", "S", "Unknown", "?" }; public SortDifficulty() : base("Difficulty") { } public override List Sort(List 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 { public SortLunar() : base("Lunar") { } public override List Sort(List inputList) { inputList.Sort((SelectableLevel a, SelectableLevel b) => Plugin.LunarConfigCompat.GetMoonIndex(b).CompareTo(Plugin.LunarConfigCompat.GetMoonIndex(a))); return inputList; } } public class SortName : SortInfoType { public SortName() : base("Name") { } public override List Sort(List inputList) { inputList.Sort((SelectableLevel a, SelectableLevel b) => StringResolver.GetAlphanumericName(a).CompareTo(StringResolver.GetAlphanumericName(b))); return inputList; } } public class SortNone : SortInfoType { public SortNone() : base("None") { } public override List Sort(List inputList) { return inputList; } } public class SortPrice : SortInfoType { public SortPrice() : base("Price") { } public override List Sort(List 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 : ConfigHandler { public ConfigHandler(CT value) { ((ConfigHandler)this).DefaultValue = value; } } public class FilterInfoType : TerminalInfoType { public FilterInfoType(string Name) { base.Name = Name; base.Type = TerminalDisplayType.Filter; } public virtual List Filter(List 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 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 : 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 : TerminalInfoType { public SortInfoType(string Name) { base.Name = Name; base.Type = TerminalDisplayType.Sort; } public virtual List Sort(List inputList) { return inputList; } } public abstract class TerminalCommandNode : CommandNode { public List Subcommands { get; set; } = new List(); 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 Enabled { get; set; } public virtual bool IsNodeValid(TerminalNode node) { return true; } public abstract string GetNodeText(TerminalNode node); public TerminalNodeReplacement(string name, TerminalNode NodeToMatch, ConfigEntry enabled = null) { Name = name; this.NodeToMatch = NodeToMatch; if (enabled != null) { Enabled = enabled; } else { Enabled = ConfigManager.configFile.Bind("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 InsertMoonCatalogueSkip(IEnumerable 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 GetDungeonRarities(SelectableLevel level) { Dictionary dictionary = new Dictionary(); DawnMoonInfo dawnInfo = SelectableLevelExtensions.GetDawnInfo(level); List list = new List(); List list2 = new List(); SpawnWeightContext val = default(SpawnWeightContext); foreach (DawnDungeonInfo value2 in ((Registry)(object)LethalContent.Dungeons).Values) { ((SpawnWeightContext)(ref val))..ctor(dawnInfo, (DawnDungeonInfo)null, (DawnWeatherEffectInfo)null); int valueOrDefault = ProviderTableSpawnWeightExtensions.GetFor(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)(object)d).Key)))); for (int num = 0; num < list.Count; num++) { string key = StringExtensions.ReplaceNumbersWithWords(StringExtensions.ToCapitalized(StringExtensions.RemoveLeadingNumbers(((DawnBaseInfo)(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)(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 Constellations { get; private set; } = new Dictionary(); 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 constellationsDict = new Dictionary(); List constellationStuff = Collections.ConstellationStuff; foreach (ClassMapper item in constellationStuff) { string constellationName = item.consName; List 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 GetExtendedDungeonFlowsWithRarity(ExtendedLevel extendedLevel) { List list = new List(); CollectionExtensions.Do((IEnumerable)DungeonManager.GetValidExtendedDungeonFlows(extendedLevel, false), (Action)list.Add); return list; } public static Dictionary GetDungeonRarities(SelectableLevel level) { Dictionary result = new Dictionary(); ExtendedLevel extendedLevel = default(ExtendedLevel); LevelManager.TryGetExtendedLevel(level, ref extendedLevel, (ContentType)2); CollectionExtensions.Do((IEnumerable)GetExtendedDungeonFlowsWithRarity(extendedLevel), (Action)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 MoonUnlockables { get; private set; } = new Dictionary(); 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 unlocks = UnlockManager.Instance.Unlocks; Dictionary dictionary = new Dictionary(); 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 rawIndex = new Dictionary(); private static Dictionary newIndex = new Dictionary(); 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 LunarConfig_GetOrderingAlgorithm(IEnumerable 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) }, false); MethodInfo methodInfo = AccessTools.Method(typeof(LunarConfigCompatibility), "PassNewCatalogueIndex", (Type[])null, (Type[])null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func)((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 PassNewCatalogueIndex(Dictionary newCatalogueIndex) { if (newCatalogueIndex == null) { return null; } newIndex.Clear(); rawIndex.Clear(); foreach (KeyValuePair item in newCatalogueIndex) { rawIndex[item.Key] = item.Value; } return newCatalogueIndex; } private static void ProcessNewOrder() { if (rawIndex == null || rawIndex.Count == 0) { return; } List 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> infoTypes = TerminalManager.FilterInfoTypes.Select((KeyValuePair> kv) => kv.Value).ToDictionary((FilterInfoType infoType) => infoType.Name.ToLowerInvariant(), (FilterInfoType 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 previewTypeNames = new List(1) { "name" }; Dictionary> infoTypes = TerminalManager.PreviewInfoTypes.Select((KeyValuePair> kv) => kv.Value).ToDictionary((PreviewInfoType infoType) => infoType.Name.ToLowerInvariant(), (PreviewInfoType 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 info) => info.Name)); return ""; } } public class SimulateCommand : TerminalCommandNode { private static Dictionary LLLResult = new Dictionary(); private static Dictionary DawnResult = new Dictionary(); 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 source = new Dictionary(); 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 dictionary = source.OrderBy((KeyValuePair o) => -o.Value).ToDictionary((KeyValuePair k) => k.Key, (KeyValuePair 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 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> infoTypes = TerminalManager.SortInfoTypes.Select((KeyValuePair> kv) => kv.Value).ToDictionary((SortInfoType infoType) => infoType.Name.ToLowerInvariant(), (SortInfoType 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> infoTypes = TerminalManager.StoreSortInfoTypes.Select((KeyValuePair> kv) => kv.Value).ToDictionary((SortInfoType infoType) => infoType.Name.ToLowerInvariant(), (SortInfoType 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) { } } }