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 TerminalFormatter v0.3.6
TerminalFormatter.dll
Decompiled 4 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConsoleTables; using HarmonyLib; using LethalLevelLoader; using Microsoft.CodeAnalysis; using MrovLib; using MrovLib.ContentType; using MrovLib.Events; using TerminalFormatter.Compatibility; using TerminalFormatter.Nodes; using TerminalUtils; using TerminalUtils.Definitions; using TerminalUtils.InfoTypes.Moons; using TerminalUtils.Nodes; using UnityEngine; using UnityEngine.UI; using WeatherRegistry; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("LethalLevelLoader")] [assembly: IgnoresAccessChecksTo("LethalLevelLoader.Patcher")] [assembly: IgnoresAccessChecksTo("MrovLib")] [assembly: IgnoresAccessChecksTo("TerminalUtils")] [assembly: IgnoresAccessChecksTo("WeatherRegistry")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TerminalFormatter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A template for Lethal Company")] [assembly: AssemblyFileVersion("0.3.6.0")] [assembly: AssemblyInformationalVersion("0.3.6+5101cba445dfb0185b321635d9bc937ac3eb7a91")] [assembly: AssemblyProduct("TerminalFormatter")] [assembly: AssemblyTitle("TerminalFormatter")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TerminalFormatter { 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<bool> DetailedScanPage { get; private set; } public static ConfigEntry<int> DivideShopPage { get; private set; } public static ConfigEntry<bool> UseShortenedWeathers { get; private set; } public static ConfigEntry<bool> AlwaysDisplayHiddenMoons { get; private set; } public static ConfigEntry<bool> ShowNumberedPlanetNames { get; private set; } public static ConfigEntry<bool> ShowDecorations { get; private set; } public static ConfigEntry<bool> ShowGroupDividerLines { get; private set; } public static ConfigEntry<bool> ShowHelpText { 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"); DetailedScanPage = configFile.Bind<bool>("General", "Detailed Scan Page", true, "Enable detailed scan page"); UseShortenedWeathers = configFile.Bind<bool>("Moons", "Use Shortened Weathers", false, "Use shortened weathers in moons catalogue"); ShowNumberedPlanetNames = configFile.Bind<bool>("Moons", "Show Numbered Planet Names", false, "Show numbered planet names in terminal"); AlwaysDisplayHiddenMoons = configFile.Bind<bool>("Moons", "Always Display Hidden Moons", false, "Always display hidden moons in moons catalogue"); ShowDecorations = configFile.Bind<bool>("General", "Show Decorations", false, "Show decorations in terminal"); ShowGroupDividerLines = configFile.Bind<bool>("General", "Show Group Divider Lines", false, "Show group divider lines in terminal"); ShowHelpText = configFile.Bind<bool>("General", "Show Help Text", false, "Show help text in terminal"); DivideShopPage = configFile.Bind<int>("Store", "Divide shop page into groups", 5, "Number of items per shop section (set to 0 to disable)"); } } public class Header { public string CreateHeader(string text) { StringBuilder stringBuilder = new StringBuilder(); int length = text.Length; stringBuilder.Append(" ╔"); for (int i = 0; i < length + 2; i++) { stringBuilder.Append("═"); } stringBuilder.Append("╗\n"); stringBuilder.Append("╭─╢ "); stringBuilder.Append(text); stringBuilder.Append(" ╟&╮\n"); stringBuilder.Append("│ ╚"); for (int j = 0; j < length + 2; j++) { stringBuilder.Append("═"); } stringBuilder.Append("╝^│\n"); return stringBuilder.ToString(); } public string CreateHeaderWithoutLines(string text, int padLeft = 2) { StringBuilder stringBuilder = new StringBuilder(); int length = text.Length; for (int i = 0; i < padLeft; i++) { stringBuilder.Append(" "); } stringBuilder.Append("╔"); for (int j = 0; j < length + 2; j++) { stringBuilder.Append("═"); } stringBuilder.Append("╗\n"); for (int k = 0; k < padLeft; k++) { stringBuilder.Append(" "); } stringBuilder.Append("║ "); stringBuilder.Append(text); stringBuilder.Append(" ║\n"); for (int l = 0; l < padLeft; l++) { stringBuilder.Append(" "); } stringBuilder.Append("╚"); for (int m = 0; m < length + 2; m++) { stringBuilder.Append("═"); } stringBuilder.Append("╝\n"); return stringBuilder.ToString(); } internal string CreateNumberedHeader(string text, int padLeft = 2, Dictionary<int, string> replaceNumbers = null) { string text2 = CreateHeaderWithoutLines(text, padLeft); StringBuilder stringBuilder = new StringBuilder(); string[] array = text2.Split('\n'); for (int i = 0; i < array.Length; i++) { stringBuilder.Append(" "); stringBuilder.Append(array[i].Trim()); stringBuilder.Append(" " + ((replaceNumbers != null && replaceNumbers.ContainsKey(i)) ? replaceNumbers[i] : "")); stringBuilder.Append("\n"); } return stringBuilder.ToString(); } } 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("TerminalFormatter"); ((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; } } [BepInPlugin("TerminalFormatter", "TerminalFormatter", "0.3.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Event <>9__7_0; internal void <Awake>b__7_0() { new Moons(); new Route(); new RouteAfter(); new RouteLocked(); new Scan(); new Store(); new Buy(); new BuyAfter(); new CannotAfford(); new Bestiary(); new Storage(); Variables.ShipCache = null; } } internal static ManualLogSource logger; internal static Logger debugLogger = new Logger("Debug", (LoggingType)2); internal static Harmony harmony = new Harmony("TerminalFormatter"); internal static TerminalNode LockedNode; internal static DawnLibCompatibility DawnLibCompat; internal static LLLCompatibility LLLCompat; internal static WeatherRegistryCompatibility WeatherRegistryCompat; private void Awake() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown logger = ((BaseUnityPlugin)this).Logger; harmony.PatchAll(); ConfigManager.Init(((BaseUnityPlugin)this).Config); DawnLibCompat = new DawnLibCompatibility("com.github.teamxiaolan.dawnlib"); LLLCompat = new LLLCompatibility("imabatby.lethallevelloader"); WeatherRegistryCompat = new WeatherRegistryCompatibility("mrov.WeatherRegistry"); CustomEvent contentManagerReady = EventManager.ContentManagerReady; object obj = <>c.<>9__7_0; if (obj == null) { Event val = delegate { new Moons(); new Route(); new RouteAfter(); new RouteLocked(); new Scan(); new Store(); new Buy(); new BuyAfter(); new CannotAfford(); new Bestiary(); new Storage(); Variables.ShipCache = null; }; <>c.<>9__7_0 = val; obj = (object)val; } contentManagerReady.AddListener((Event)obj); LockedNode = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)LockedNode).name = "RouteLocked"; LockedNode.clearPreviousText = true; LockedNode.acceptAnything = true; LockedNode.displayText = "You cannot route to the selected moon. The route is locked."; LockedNode.terminalOptions = Array.Empty<CompatibleNoun>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin TerminalFormatter is loaded!"); } } internal class Settings { internal static List<TerminalFormatterNode> RegisteredNodes = new List<TerminalFormatterNode>(); public static readonly int terminalWidth = 48; public static bool firstUse = true; 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; } public class SharedMethods { public static string GetWeather(SelectableLevel level) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) string weather = SharedMethods.GetWeather(level); int num = Settings.planetWeatherWidth - 1; ((Logger)Plugin.debugLogger).LogDebug($"Length : {weather.Length}|{num}"); if (weather.Length >= num || ConfigManager.UseShortenedWeathers.Value) { if (((CompatibilityHandler)Plugin.WeatherRegistryCompat).IsModPresent) { return Plugin.WeatherRegistryCompat.GetShortenedWeather(level.currentWeather); } return Regex.Replace(weather, "\\s+", "").Substring(0, num); } return weather; } public static string GetNumberlessPlanetName(SelectableLevel level) { return SharedMethods.GetNumberlessPlanetName(level); } public static int GetPrice(int beforeDiscountPrice) { if (((CompatibilityHandler)Plugin.LGUCompat).IsModPresent) { return Plugin.LGUCompat.GetMoonPrice(beforeDiscountPrice); } return beforeDiscountPrice; } } public abstract class TerminalFormatterNode : TerminalNodeReplacement { public List<string> NodeNamesToMatch { get; internal set; } = new List<string>(); public TerminalFormatterNode(string name, List<string> nodeNames) : base(name, (TerminalNode)null, ConfigManager.configFile.Bind<bool>("Nodes", name, true, "Enable node " + name)) { NodeNamesToMatch = nodeNames; Settings.RegisteredNodes.Add(this); ((Logger)Plugin.debugLogger).LogInfo("Registered node " + name); } public TerminalFormatterNode(string name, TerminalNode terminalNode) : base(name, terminalNode, ConfigManager.configFile.Bind<bool>("Nodes", name, true, "Enable node " + name)) { Settings.RegisteredNodes.Add(this); ((Logger)Plugin.debugLogger).LogInfo("Registered node " + name); } } [HarmonyPatch(typeof(Terminal))] [HarmonyPatch(typeof(Terminal))] public class TerminalPatches { private static TerminalNode lastNode; [HarmonyPrefix] [HarmonyPatch(typeof(Terminal), "LoadNewNode")] [HarmonyPriority(500)] public static bool CheckIfLocked(Terminal __instance, TerminalNode node) { if ((Object)(object)node == (Object)null) { return true; } lastNode = node; if (!((CompatibilityHandler)Plugin.LLL).IsModPresent && !((CompatibilityHandler)Plugin.DawnLibCompat).IsModPresent) { return true; } if (!((Object)node).name.ToLower().Contains("route") && !node.buyRerouteToMoon.Equals(-2)) { return true; } if (((Object)node).name == "RouteLocked") { ((Logger)Plugin.debugLogger).LogDebug("Node is RouteLocked"); return true; } Route val = ((IEnumerable<Route>)ContentManager.Routes).FirstOrDefault((Func<Route, bool>)((Route x) => (Object)(object)x.Nodes.Node == (Object)(object)node)); if (val == null) { ((Logger)Plugin.debugLogger).LogDebug("Level is null"); return true; } if ((Object)(object)val.Level == (Object)null) { return true; } if (node.displayText.ToLower().Contains("route locked!") && ((CompatibilityHandler)Plugin.DawnLibCompat).IsModPresent) { if (Plugin.DawnLibCompat.GetLevelStatus(val.Level).locked) { ((Logger)Plugin.debugLogger).LogInfo("Node is locked by DawnLib!!"); __instance.LoadNewNode(Plugin.LockedNode); return false; } return true; } if (SharedMethods.IsMoonLockedLLL(val.Level)) { ((Logger)Plugin.debugLogger).LogInfo("Node is locked!!"); __instance.LoadNewNode(Plugin.LockedNode); return false; } return true; } [HarmonyPrefix] [HarmonyPatch("LoadNewNode")] [HarmonyPriority(0)] [HarmonyAfter(new string[] { "imabatby.lethallevelloader", "com.github.teamxiaolan.dawnlib" })] [HarmonyBefore(new string[] { "mrov.TerminalUtils" })] public static bool LoadNewTerminalFormatterNode(Terminal __instance, TerminalNode node) { __instance.modifyingText = true; ((Selectable)__instance.screenText).interactable = true; string text = null; Variables.CurrentNode = node; Variables.LastReplacedNode = null; List<TerminalFormatterNode> list = (from formatterNode in Settings.RegisteredNodes where formatterNode.NodeNamesToMatch.Count > 0 where formatterNode.NodeNamesToMatch.Any((string y) => ((Object)node).name.Contains(y)) select formatterNode).ToList(); if (list != null) { ((Logger)Plugin.debugLogger).LogDebug($"Possible nodes count: {list.Count}"); for (int num = 0; num < list.Count; num++) { TerminalFormatterNode terminalFormatterNode = list[num]; if (terminalFormatterNode == null) { continue; } ((Logger)Plugin.debugLogger).LogDebug("Checking if node " + ((TerminalNodeReplacement)terminalFormatterNode).Name + " is valid..."); if (!((TerminalNodeReplacement)terminalFormatterNode).IsNodeValid(node)) { ((Logger)Plugin.debugLogger).LogDebug("Node " + ((TerminalNodeReplacement)terminalFormatterNode).Name + " is not valid"); continue; } if (!((TerminalNodeReplacement)terminalFormatterNode).Enabled.Value) { ((Logger)Plugin.debugLogger).LogDebug("Node " + ((TerminalNodeReplacement)terminalFormatterNode).Name + " is not enabled"); continue; } ((Logger)Plugin.debugLogger).LogDebug("Using node " + ((TerminalNodeReplacement)terminalFormatterNode).Name); text = ((TerminalNodeReplacement)terminalFormatterNode).GetNodeText(node); break; } if (text != null) { 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(text); stringBuilder.AppendLine(); stringBuilder.Append("\n" + new string('-', Settings.dividerLength) + "\n"); ((Logger)Plugin.debugLogger).LogMessage("New display text:\n" + text); if (node.playSyncedClip != -1) { __instance.PlayTerminalAudioServerRpc(node.playSyncedClip); } else if ((Object)(object)node.playClip != (Object)null) { __instance.terminalAudio.PlayOneShot(node.playClip); } __instance.LoadTerminalImage(node); __instance.currentNode = node; __instance.screenText.text = stringBuilder.ToString(); __instance.currentText = stringBuilder.ToString(); __instance.textAdded = 0; Settings.firstUse = false; Variables.LastReplacedNode = node; NodeReplacementManager.ReplaceNode = false; return false; } return true; } return true; } } public class Variables { internal static TerminalNode CurrentNode; public static TerminalNode LastReplacedNode; private static GameObject _shipCache; public static Terminal Terminal => TerminalManager.Terminal; public static GameObject ShipCache { get { if ((Object)(object)_shipCache == (Object)null) { _shipCache = GameObject.Find("/Environment/HangarShip"); } return _shipCache; } set { _shipCache = value; } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "TerminalFormatter"; public const string PLUGIN_NAME = "TerminalFormatter"; public const string PLUGIN_VERSION = "0.3.6"; } } namespace TerminalFormatter.Patches { [HarmonyPatch(typeof(HangarShipDoor))] public static class HangarShipDoorStartPatch { [HarmonyPostfix] [HarmonyPatch("Start")] public static void PatchMethod() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ((Logger)Plugin.debugLogger).LogDebug("Applying HangarShipDoor Start Patch"); TerminalManager.PreviewInfoTypes.Add("NumberedName", (PreviewInfoType<SelectableLevel>)new PreviewNameNumbered()); } } public static class String { public static string Sanitized(this string currentString) { return new string(currentString.SkipToLetters().RemoveWhitespace().ToLowerInvariant() .AsSpan()); } public static string RemoveWhitespace(this string input) { return new string((from c in input.ToCharArray() where !char.IsWhiteSpace(c) select c).ToArray()); } public static string SkipToLetters(this string input) { return new string(input.SkipWhile((char c) => !char.IsLetter(c)).ToArray()); } public static string StripSpecialCharacters(this string input) { string text = string.Empty; for (int i = 0; i < input.Length; i++) { char c = input[i]; if (char.IsLetterOrDigit(c) || c.ToString() == " ") { text += c; } } return text; } } } namespace TerminalFormatter.Nodes { public class Bestiary : TerminalFormatterNode { public Bestiary() : base("Bestiary", new List<string>(1) { "0_Bestiary" }) { ((TerminalNodeReplacement)this).HelpText = " Welcome to the Bestiary! \n Use INFO after creature name to learn more."; } public override string GetNodeText(TerminalNode node) { string value = new Header().CreateHeaderWithoutLines("BESTIARY"); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(value); List<int> scannedCreatures = Variables.Terminal.scannedEnemyIDs; if (ConfigManager.ShowHelpText.Value) { stringBuilder.Append((((TerminalNodeReplacement)this).HelpText != null) ? ("\n" + ((TerminalNodeReplacement)this).HelpText + "\n\n") : ""); } else { stringBuilder.Append("\n"); } if (Variables.Terminal.scannedEnemyIDs == null || Variables.Terminal.scannedEnemyIDs.Count == 0) { stringBuilder.Append(" NO DATA COLLECTED"); stringBuilder.Append(" \n"); stringBuilder.Append(" Scan creatures to unlock their data."); return stringBuilder.ToString(); } List<Creature> list = ContentManager.Creatures.Where((Creature x) => scannedCreatures.Contains(x.InfoNode.creatureFileID)).ToList(); foreach (Creature item in list) { if (ConfigManager.ShowDecorations.Value) { stringBuilder.Append(" * "); } else { stringBuilder.Append(" "); } stringBuilder.Append(item.Name); stringBuilder.Append("\n"); } return stringBuilder.ToString(); } } public class Buy : TerminalFormatterNode { internal BuyableThing LastResolvedBuyable; public Buy() : base("Buy", new List<string>(5) { "buy", "BuyNode", "Buy", "Buy1", "Node1" }) { } public BuyableThing ResolveNodeIntoBuyable(TerminalNode node) { ((Logger)Plugin.debugLogger).LogDebug("Resolving node " + ((Object)node).name + " into Buyable"); return (from x in ContentManager.Buyables where x.Nodes != null && (Object)(object)x.Nodes.Node != (Object)null where (Object)(object)x.Nodes.Node == (Object)(object)node || ((Object)x.Nodes.Node).name == ((Object)node).name select x).FirstOrDefault(); } public override bool IsNodeValid(TerminalNode node) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) BuyableThing val = ResolveNodeIntoBuyable(node); if (val != null) { Plugin.logger.LogDebug((object)$"Resolved Item: {val.Name}({val.Type})"); } return val != null; } public override string GetNodeText(TerminalNode node) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Title", "Things" }); Terminal terminal = Variables.Terminal; BuyableThing val2 = (LastResolvedBuyable = ResolveNodeIntoBuyable(node)); string value = new Header().CreateHeaderWithoutLines("CONFIRM PURCHASE"); StringBuilder stringBuilder = new StringBuilder(); val.AddRow(new object[2] { "ITEM:", val2.Name }); bool flag = typeof(BuyableItem) == ((object)val2).GetType(); if (flag) { val.AddRow(new object[2] { "PRICE:", $"${val2.Price}" }); } if (node.buyItemIndex >= 0 && terminal.itemSalesPercentages[node.buyItemIndex] != 100) { val.AddRow(new object[2] { "DISCOUNT:", $"{100 - terminal.itemSalesPercentages[node.buyItemIndex]}%" }); } if (flag) { val.AddRow(new object[2] { "AMOUNT:", terminal.playerDefinedAmount.ToString() }); } val.AddRow(new object[2] { "", "" }); val.AddRow(new object[2] { "TOTAL: ", $"${terminal.totalCostOfItems} (${terminal.groupCredits - terminal.totalCostOfItems} after purchase)" }); stringBuilder.Append(value); stringBuilder.Append("\n\n"); stringBuilder.Append("Please CONFIRM or DENY the purchase:"); stringBuilder.Append("\n\n"); stringBuilder.Append(val.ToStringCustomDecoration(false, false, false)); return stringBuilder.ToString(); } } public class BuyAfter : TerminalFormatterNode { internal BuyableThing LastResolvedBuyable; public BuyAfter() : base("BuyAfter", new List<string>(9) { "Node2", "node2", "confirm", "2", "buy", "BuyNode", "Buy", "Buy1", "Node1" }) { } public BuyableThing ResolveNodeIntoBuyable(TerminalNode node) { ((Logger)Plugin.debugLogger).LogDebug("Resolving node " + ((Object)node).name + " into Buyable"); return (from x in ContentManager.Buyables where x.Nodes != null && (Object)(object)x.Nodes.NodeConfirm != (Object)null where (Object)(object)x.Nodes.NodeConfirm == (Object)(object)node || ((Object)x.Nodes.NodeConfirm).name == ((Object)node).name select x).FirstOrDefault(); } public override bool IsNodeValid(TerminalNode node) { BuyableThing val = ResolveNodeIntoBuyable(node); return val != null; } public override string GetNodeText(TerminalNode node) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Title", "Things" }); Terminal terminal = Variables.Terminal; BuyableThing val2 = (LastResolvedBuyable = ResolveNodeIntoBuyable(node)); string value = new Header().CreateHeaderWithoutLines("SUCCESS!"); StringBuilder stringBuilder = new StringBuilder(); val.AddRow(new object[2] { "ITEM:", val2.Name }); bool flag = typeof(BuyableItem) == ((object)val2).GetType(); int playerDefinedAmount = terminal.playerDefinedAmount; stringBuilder.Append(value); stringBuilder.Append("\n\n"); stringBuilder.Append("Thank you for your purchase!\n"); if (flag) { stringBuilder.Append(string.Format("Your {0} ({1} x {2}) {3} on {4} way!", (playerDefinedAmount == 1) ? "item" : "items", terminal.playerDefinedAmount, val2.Name, (playerDefinedAmount == 1) ? "is" : "are", (playerDefinedAmount == 1) ? "its" : "their")); } else { stringBuilder.Append("Your unlockable is now available!"); } return stringBuilder.ToString(); } } public class CannotAfford : TerminalFormatterNode { public CannotAfford() : base("CannotAfford", new List<string>(1) { "CannotAfford" }) { } public override bool IsNodeValid(TerminalNode node) { node.clearPreviousText = true; return true; } public override string GetNodeText(TerminalNode node) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Title", "Things" }); string value = new Header().CreateHeaderWithoutLines("COMPANY STORE"); StringBuilder stringBuilder = new StringBuilder(); val.AddRow(new object[2] { "YOUR CREDITS:", $"${Variables.Terminal.groupCredits}" }); val.AddRow(new object[2] { "TOTAL:", $"${Variables.Terminal.totalCostOfItems}" }); stringBuilder.Append(value); stringBuilder.Append("\n\n"); stringBuilder.Append("You cannot afford this purchase!"); stringBuilder.Append("\n\n"); stringBuilder.Append(val.ToStringCustomDecoration(false, false, false)); return stringBuilder.ToString(); } } public class Moons : TerminalFormatterNode { public Moons() : base("Moons", new List<string>(4) { "MoonsCatalogue", "preview", "sort", "filter" }) { ((TerminalNodeReplacement)this).HelpText = " Welcome to the exomoons catalogue! \n Use ROUTE to to set the autopilot route. \n Use INFO to learn about any moon."; } public override string GetNodeText(TerminalNode node) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown List<SelectableLevel> currentLevels = TerminalManager.GetCurrentLevels(); List<PreviewInfoType<SelectableLevel>> list = TerminalManager.CurrentPreviewInfoType; if (ConfigManager.ShowNumberedPlanetNames.Value) { list = list.Select((PreviewInfoType<SelectableLevel> infoType) => (((TerminalInfoType)infoType).Name == "Name") ? TerminalManager.PreviewInfoTypes["NumberedName"] : infoType).ToList(); } ConsoleTable val = new ConsoleTable(TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => "").ToArray()); StringBuilder stringBuilder = new StringBuilder(); string text = "MOONS CATALOGUE"; Dictionary<int, string> replaceNumbers = new Dictionary<int, string> { { 0, "PREVIEW: <size=70%>" + string.Join(", ", from info in TerminalManager.CurrentPreviewInfoType where !((TerminalInfoType)info).Name.Contains("Name") select ((TerminalInfoType)info).Name.ToUpper()) + "</size>" }, { 1, "SORT: " + ((TerminalInfoType)TerminalManager.CurrentSortInfoType).Name.ToUpper() }, { 2, "FILTER: " + ((TerminalInfoType)TerminalManager.CurrentFilterInfoType).Name.ToUpper() } }; string value = new Header().CreateNumberedHeader(text, 2, replaceNumbers); int num = 1; foreach (SelectableLevel level in currentLevels) { if (Defaults.IgnoreLevels.Contains(SharedMethods.GetNumberlessPlanetName(level))) { ((Logger)Plugin.debugLogger).LogInfo("Skipping hidden level " + ((Object)level).name + " because it's in the ignore list."); } else { if (LevelHelper.IsHidden(level) && !ConfigManager.AlwaysDisplayHiddenMoons.Value) { continue; } string[] array = list.Select((PreviewInfoType<SelectableLevel> info) => ((TerminalInfoType)info).Name.Contains("Name") ? ("* " + info.Value(level)) : info.Value(level)).ToArray(); object[] array2 = array; val.AddRow(array2); if (num % 3 == 0) { num = 1; if (ConfigManager.ShowGroupDividerLines.Value) { string[] array3 = new string[list.Count]; array3[0] = "".PadRight(Settings.planetNameWidth, '-'); array2 = array3; val.AddRow(array2); } else { array2 = list.Select((PreviewInfoType<SelectableLevel> _) => "").ToArray(); val.AddRow(array2); } } else { num++; } } } string value2 = val.ToStringCustomDecoration(false, false, false); stringBuilder.Append(value); if (ConfigManager.ShowHelpText.Value) { stringBuilder.Append((((TerminalNodeReplacement)this).HelpText != null) ? ("\n" + ((TerminalNodeReplacement)this).HelpText + "\n\n") : ""); } stringBuilder.Append($" The Company // Buying at {Mathf.RoundToInt(StartOfRound.Instance.companyBuyingRate * 100f)}% \n\n"); stringBuilder.Append(value2); string text2 = stringBuilder.ToString().TrimEnd(); ((Logger)Plugin.debugLogger).LogDebug("Final string:\n" + text2); return text2; } } public class Route : TerminalFormatterNode { public Route() : base("Route", new List<string>(2) { "route", "Route" }) { } public Route ResolveNodeIntoRoute(TerminalNode node) { return ((IEnumerable<Route>)ContentManager.Routes).FirstOrDefault((Func<Route, bool>)((Route x) => (Object)(object)x.Nodes.Node == (Object)(object)node)); } public override bool IsNodeValid(TerminalNode node) { Route val = ResolveNodeIntoRoute(node); if (val == null) { return false; } ((Logger)Plugin.debugLogger).LogDebug("Resolved Route: " + ((val != null) ? val.Name : null) + "(" + val?.Level?.PlanetName + ")"); if (LevelHelper.IsLocked(val.Level)) { return false; } return true; } public override string GetNodeText(TerminalNode node) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Title", "Things" }); Route val2 = ResolveNodeIntoRoute(node); string value = new Header().CreateHeaderWithoutLines("CONFIRM ROUTE"); StringBuilder stringBuilder = new StringBuilder(); SelectableLevel level = val2.Level; string weather = SharedMethods.GetWeather(level); int price = SharedMethods.GetPrice(node.itemCost); val.AddRow(new object[2] { "PLANET:", SharedMethods.GetNumberlessPlanetName(level) }); val.AddRow(new object[2] { "PRICE:", $"${price} (${Variables.Terminal.groupCredits - price} after routing)" }); val.AddRow(new object[2] { "WEATHER:", (weather == "") ? "Clear" : weather }); stringBuilder.Append(value); stringBuilder.Append("\n\n"); stringBuilder.Append("Please CONFIRM or DENY routing the autopilot:"); stringBuilder.Append("\n\n"); stringBuilder.Append(val.ToStringCustomDecoration(false, false, false)); return stringBuilder.ToString(); } } public class RouteAfter : TerminalFormatterNode { public RouteAfter() : base("RouteAfter", new List<string>(2) { "route", "Route" }) { } public Route ResolveNodeIntoRoute(TerminalNode node) { return ContentManager.Routes.Where((Route x) => (Object)(object)x.Nodes.NodeConfirm == (Object)(object)node).FirstOrDefault(); } public override bool IsNodeValid(TerminalNode node) { Route val = ResolveNodeIntoRoute(node); return val != null; } public override string GetNodeText(TerminalNode node) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Title", "Things" }); Route val2 = ResolveNodeIntoRoute(node); string value = new Header().CreateHeaderWithoutLines("SUCCESS!"); StringBuilder stringBuilder = new StringBuilder(); SelectableLevel level = val2.Level; string weather = SharedMethods.GetWeather(level); int price = SharedMethods.GetPrice(node.itemCost); val.AddRow(new object[2] { "PLANET:", SharedMethods.GetNumberlessPlanetName(level) }); val.AddRow(new object[2] { "WEATHER:", (weather == "") ? "Clear" : weather }); stringBuilder.Append(value); stringBuilder.Append("\n\n"); stringBuilder.Append("Thank you for your purchase!\n"); stringBuilder.Append("You're currently headed to:"); stringBuilder.Append("\n\n"); stringBuilder.Append(val.ToStringCustomDecoration(false, false, false)); return stringBuilder.ToString(); } } public class RouteLocked : TerminalFormatterNode { public RouteLocked() : base("RouteLocked", new List<string>(1) { "RouteLocked" }) { } public override bool IsNodeValid(TerminalNode node) { return true; } public override string GetNodeText(TerminalNode node) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[2] { "Title", "Things" }); string value = new Header().CreateHeaderWithoutLines("ROUTE LOCKED"); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(value); stringBuilder.Append("\n\n"); stringBuilder.Append("You cannot currently route to the selected moon."); stringBuilder.Append("\n\n"); stringBuilder.Append(val.ToStringCustomDecoration(false, false, false)); return stringBuilder.ToString(); } } public class Scan : TerminalFormatterNode { public Scan() : base("Scan", new List<string>(1) { "ScanInfo" }) { } public override bool IsNodeValid(TerminalNode node) { return true; } public override string GetNodeText(TerminalNode node) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown Scan val = (Scan)TerminalManager.NodeReplacements[TerminalManager.ScanPage]; bool value = ConfigManager.DetailedScanPage.Value; bool inShipPhase = StartOfRound.Instance.inShipPhase; bool flag = LevelHelper.CompanyMoons.Contains(StartOfRound.Instance.currentLevel); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("\n"); List<GrabbableObject> objects = val.GetObjects(); int count = objects.Count; int num = objects.Sum((GrabbableObject x) => x.scrapValue); string text = "SCANNER"; Dictionary<int, string> replaceNumbers = new Dictionary<int, string> { { 0, "SCANNING " + (inShipPhase ? "SHIP" : "MOON") }, { 1, "ITEMS: " + count }, { 2, "VALUE: $" + num } }; string value2 = new Header().CreateNumberedHeader(text, 2, replaceNumbers); stringBuilder.Append(value2); ConsoleTable val2 = new ConsoleTable(new string[3] { "Name", "Price", "Two-handed?" }); foreach (GrabbableObject item in objects) { val2.AddRow(new object[3] { item.itemProperties.itemName, $"${item.scrapValue}", item.itemProperties.twoHanded ? "●" : "○" }); } if (value) { stringBuilder.Append(val2.ToStringCustomDecoration(true, false, false)); } return stringBuilder.ToString(); } } public class Storage : TerminalFormatterNode { public Storage() : base("Storage", new List<string>(1) { "ItemsInStorage" }) { ((TerminalNodeReplacement)this).HelpText = " Welcome to the Storage! \n Type item's name to retrieve it. \n To store items, use [X] while moving the object."; } public override string GetNodeText(TerminalNode node) { string value = new Header().CreateHeaderWithoutLines("STORAGE"); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(value); if (ConfigManager.ShowHelpText.Value) { stringBuilder.Append((((TerminalNodeReplacement)this).HelpText != null) ? ("\n" + ((TerminalNodeReplacement)this).HelpText + "\n\n") : ""); } else { stringBuilder.Append("\n"); } List<UnlockableItem> list = StartOfRound.Instance.unlockablesList.unlockables.Where((UnlockableItem unlockable) => unlockable.inStorage).ToList(); if (list.Count == 0) { stringBuilder.Append("No items stored.\n"); return stringBuilder.ToString(); } foreach (UnlockableItem item in list) { if (ConfigManager.ShowDecorations.Value) { stringBuilder.Append(" * "); } else { stringBuilder.Append(" "); } stringBuilder.Append(item.unlockableName); stringBuilder.Append("\n"); } return stringBuilder.ToString(); } } public class Store : TerminalFormatterNode { public Store() : base("Store", new List<string>(1) { "0_StoreHub" }) { ((TerminalNodeReplacement)this).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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Expected O, but got Unknown ConsoleTable val = new ConsoleTable(new string[3] { "Name", "Price", "Owned" }); GameObject val2 = GameObject.Find("/Environment/HangarShip"); List<GrabbableObject> list = val2.GetComponentsInChildren<GrabbableObject>().ToList(); bool value = ConfigManager.ShowDecorations.Value; string text = "COMPANY STORE"; string value2 = new Header().CreateHeaderWithoutLines(text); StringBuilder stringBuilder = new StringBuilder().Append(value2); if (ConfigManager.ShowHelpText.Value) { stringBuilder.Append((((TerminalNodeReplacement)this).HelpText != null) ? ("\n" + ((TerminalNodeReplacement)this).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 val4) { //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 = val4.Type; switch (type - 1) { case 0: { BuyableUnlockable val7 = (BuyableUnlockable)val4; return !val7.IsUnlocked; } case 1: { BuyableDecoration val6 = (BuyableDecoration)val4; if (val6.InRotation) { return !((BuyableUnlockable)val6).IsUnlocked; } return false; } case 2: { BuyableSuit val5 = (BuyableSuit)val4; if (val5.InRotation) { return !val5.IsUnlocked; } return false; } default: return true; } }).ToList()); foreach (KeyValuePair<PurchaseType, List<BuyableThing>> item2 in dictionary) { if (item2.Value.Count == 0) { continue; } int num = 1; val.AddRow(new object[3] { "", "", "" }); val.AddRow(new object[3] { "[" + ((object)item2.Key/*cast due to .constrained prefix*/).ToString().ToUpperInvariant() + "S]", "", "" }); if (value) { val.AddRow(new object[3] { new string('-', Settings.dividerLength) ?? "", "", "" }); } for (int num2 = 0; num2 < item2.Value.Count; num2++) { BuyableThing val3 = item2.Value[num2]; string text2 = val3.Name; string text3 = $"${val3.Price}"; string text4 = ""; if (value) { text2 = "* " + text2; } if ((int)val3.Type == 0) { BuyableItem item = (BuyableItem)val3; if (((CompatibilityHandler)Plugin.DawnLibCompat).IsModPresent) { if (!Plugin.DawnCompatibility.IsItemInStore(item.Item)) { continue; } text2 = Plugin.DawnCompatibility.GetStoreItemNameOverride(item.Item); } if (item.Discount != 0) { string text5 = ((item.Discount != 0) ? string.Format(" {0}-{1}%{2}", value ? "(" : "", item.Discount, value ? ")" : "") : ""); text2 = ((text2.Length + text5.Length <= Settings.itemNameWidth) ? (text2.PadRight(Settings.itemNameWidth - text5.Length) + text5).PadRight(Settings.itemNameWidth) : (text2.Substring(0, Settings.itemNameWidth - 4 - text5.Length) + "... " + text5)); decimal d = Convert.ToDecimal(((BuyableThing)item).Price) * Convert.ToDecimal(item.DiscountPercentage); int num3 = (int)Math.Floor(d); text3 = $"${num3}"; } text4 = list.FindAll((GrabbableObject x) => x.itemProperties.itemName == item.Item.itemName).Count.ToString("D2"); } val.AddRow(new object[3] { text2.PadRight(Settings.itemNameWidth) ?? "", text3 ?? "", ((text4 == "" || text4 == "00") ? "" : ("×" + text4)) ?? "" }); if (ConfigManager.DivideShopPage.Value == 0 || num2 == item2.Value.Count - 1) { continue; } if (num % ConfigManager.DivideShopPage.Value == 0) { num = 1; if (ConfigManager.ShowGroupDividerLines.Value) { val.AddRow(new object[3] { "".PadRight(Settings.itemNameWidth, '-'), "".PadRight(5, '-'), "".PadRight(5, '-') }); } else { val.AddRow(new object[3] { "", "", "" }); } } else { num++; } } } string value3 = val.ToStringCustomDecoration(true, true, false).TrimEnd(); stringBuilder.Append(value3); return stringBuilder.ToString().TrimEnd(); } } } namespace TerminalFormatter.Compatibility { internal class DawnLibCompatibility : CompatibilityHandler { public DawnLibCompatibility(string guid, string version = null) : base(guid, version, false) { } public (bool locked, bool hidden) GetLevelStatus(SelectableLevel level) { return Plugin.DawnCompatibility.GetLevelStatus(level); } } internal class LLLCompatibility : CompatibilityHandler { public LLLCompatibility(string guid, string version = null) : base(guid, version, false) { } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public override void Init() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown if (((CompatibilityHandler)this).IsModPresent) { Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(Patches), "TerminalLoadNewNode_Postfix", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LLLCompatibility), "LLLLoadNodePatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (((CompatibilityHandler)Plugin.DawnLibCompat).IsModPresent) { Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(TerminalManager), "SwapRouteNodeToLockedNode", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LLLCompatibility), "SwapRouteNodeToLockedNode", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } public static bool LLLLoadNodePatch(Terminal __0, ref TerminalNode __1) { if ((Object)(object)__1 == (Object)(object)Variables.LastReplacedNode) { return false; } return true; } public static bool SwapRouteNodeToLockedNode() { return false; } } internal class WeatherRegistryCompatibility : CompatibilityHandler { public WeatherRegistryCompatibility(string guid, string version = null) : base(guid, version, false) { } public string GetShortenedWeather(LevelWeatherType weather) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return WeatherManager.GetWeather(weather).NameShort; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }