Decompiled source of TerminalUtils v0.0.14

TerminalUtils.dll

Decompiled 2 days ago
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<TerminalCommandNode> Commands { get; set; } = new List<TerminalCommandNode>();

		public static Dictionary<string, TerminalCommandNode> CommandLookup
		{
			get
			{
				Dictionary<string, TerminalCommandNode> lookup = new Dictionary<string, TerminalCommandNode>();
				Commands.ForEach(delegate(TerminalCommandNode command)
				{
					lookup[((CommandNode)command).Name] = command;
				});
				return lookup;
			}
		}

		public static void Init()
		{
			Commands.Clear();
			CommandNode = TerminalNodeManager.CreateTerminalNode("TerminalUtilsCommandNode");
			CommandNode.acceptAnything = false;
			RedirectToMoonsNode = TerminalNodeManager.CreateTerminalNode("TerminalUtilsRedirectToMoonsNode");
			RedirectToMoonsNode.acceptAnything = false;
			RedirectToStoreNode = TerminalNodeManager.CreateTerminalNode("TerminalUtilsRedirectToStoreNode");
			RedirectToStoreNode.acceptAnything = false;
		}

		public static TerminalNode RunTerminalCommand(TerminalCommandNode command, string[] args)
		{
			string displayText = "";
			if (command == null)
			{
				CommandNode.displayText = $"Command '{command}' not found.";
				return CommandNode;
			}
			if (!command.ShouldRun())
			{
				CommandNode.displayText = "Command '" + ((CommandNode)command).Name + "' cannot run!";
				return CommandNode;
			}
			if (command.Subcommands.Count == 0 || args.Length < 1)
			{
				((Logger)Plugin.debugLogger).LogDebug("Running command '" + ((CommandNode)command).Name + "' with no subcommand");
				displayText = command.Execute(args);
			}
			else
			{
				((Logger)Plugin.debugLogger).LogInfo("Looking for subcommand '" + args[0] + "'; available: " + string.Join(", ", command.Subcommands.ConvertAll((TerminalCommandNode sc) => ((CommandNode)sc).Name)));
				try
				{
					TerminalCommandNode terminalCommandNode = command.Subcommands.Find((TerminalCommandNode sc) => ((CommandNode)sc).Name == args[0]);
					if (terminalCommandNode == null)
					{
						displayText = "Subcommand '" + args[0] + "' not found for command '" + ((CommandNode)command).Name + "'.";
					}
					displayText = terminalCommandNode.Execute(args);
				}
				catch (Exception arg)
				{
					((Logger)Plugin.debugLogger).LogError($"Error finding subcommand: {arg}");
				}
			}
			if ((Object)(object)command.RedirectToNode != (Object)null)
			{
				((Logger)Plugin.debugLogger).LogDebug("Redirecting to node '" + ((Object)command.RedirectToNode).name + "'");
				return command.RedirectToNode;
			}
			CommandNode.displayText = displayText;
			return CommandNode;
		}
	}
	public class ConfigManager
	{
		internal static ConfigFile configFile;

		public static ConfigManager Instance { get; private set; }

		public static ConfigEntry<LoggingType> LoggingLevels { get; private set; }

		public static ConfigEntry<int> LinesToScroll { get; private set; }

		public static ConfigEntry<bool> UseLegacyScrollBehavior { get; private set; }

		public static ConfigEntry<string> PreviewInfoType { get; private set; }

		public static ConfigEntry<string> FilterInfoType { get; private set; }

		public static ConfigEntry<string> SortInfoType { get; private set; }

		public static ConfigEntry<bool> DisplayLockedMoons { get; private set; }

		public static ConfigEntry<string> StoreSortInfoType { get; private set; }

		public static ConfigEntry<int> DivideStore { get; private set; }

		public static ConfigEntry<bool> DetailedScanPage { get; private set; }

		public static ConfigEntry<bool> DisplayAccuratePrices { get; private set; }

		public static void Init(ConfigFile config)
		{
			Instance = new ConfigManager(config);
		}

		private ConfigManager(ConfigFile config)
		{
			configFile = config;
			LoggingLevels = configFile.Bind<LoggingType>("Debug", "Logging Levels", (LoggingType)0, "Set the logging level for the mod");
			LinesToScroll = configFile.Bind<int>("General", "Lines to Scroll", 10, "Number of lines to scroll per mouse wheel tick");
			UseLegacyScrollBehavior = configFile.Bind<bool>("General", "Use Legacy Scroll Behavior", false, "Whether to use the legacy scroll behavior (from TerminalFormatter)");
			PreviewInfoType = configFile.Bind<string>("Preferences", "Preview Info Type", Defaults.defaultPreviewType, "Set the preview info type. Must be the name of an existing preview info type.");
			FilterInfoType = configFile.Bind<string>("Preferences", "Filter Info Type", Defaults.defaultFilterType, "Set the filter info type. Must be the name of an existing filter info type.");
			SortInfoType = configFile.Bind<string>("Preferences", "Sort Info Type", Defaults.defaultSortType, "Set the default sort info type. Must be the name of an existing sort info type.");
			StoreSortInfoType = configFile.Bind<string>("Preferences", "Store Sort Info Type", Defaults.defaultStoreSortType, "Set the default store sort info type. Must be the name of an existing store sort info type.");
			DisplayLockedMoons = configFile.Bind<bool>("Moons", "Display Locked Moons", true, "Whether to display locked moons in the moon catalogue.");
			DivideStore = configFile.Bind<int>("Store", "Divide Store page into groups", 5, "Set the number of items to divide the store into. 0 means no division.");
			DetailedScanPage = configFile.Bind<bool>("Scan", "Display Detailed Scan", true, "Enable detailed scan page");
			DisplayAccuratePrices = configFile.Bind<bool>("Scan", "Display Accurate Prices", false, "Enable accurate prices on scan page");
		}
	}
	public static class Defaults
	{
		public static readonly int terminalWidth = 48;

		internal static readonly int planetWeatherWidth = 18;

		internal static readonly int planetNameWidth = terminalWidth + 2 - planetWeatherWidth - 9;

		internal static readonly int itemNameWidth = terminalWidth - 9 - 10;

		internal static readonly int dividerLength = 17;

		internal static readonly string defaultPreviewType = "Name;Price;Weather";

		internal static readonly string defaultFilterType = "None";

		internal static readonly string defaultSortType = "None";

		internal static readonly string defaultStoreSortType = "Name";
	}
	public static class InfoTypeResolver
	{
		public static List<PreviewInfoType<SelectableLevel>> GetPreviewInfoType(string inputString)
		{
			if (string.IsNullOrEmpty(inputString))
			{
				return (from typeName in Defaults.defaultPreviewType.Split(";")
					select TerminalManager.PreviewInfoTypes[typeName]).ToList();
			}
			if (!inputString.ToLowerInvariant().Contains("Name".ToLowerInvariant()))
			{
				inputString = "Name;" + inputString;
				Plugin.logger.LogDebug((object)("Preview type did not contain 'Name', defaulting to 'Name;" + inputString + "'"));
			}
			string[] source = (from s in inputString.Split(';')
				where !string.IsNullOrWhiteSpace(s)
				select s.Trim()).ToArray();
			return (from typeName in source
				select TerminalManager.PreviewInfoTypes.FirstOrDefault((KeyValuePair<string, PreviewInfoType<SelectableLevel>> info) => info.Key.ToLowerInvariant() == typeName.ToLowerInvariant()) into info
				where info.Value != null
				select info.Value).ToList();
		}

		public static FilterInfoType<SelectableLevel> GetFilterInfoType(string inputString)
		{
			if (string.IsNullOrEmpty(inputString))
			{
				return TerminalManager.FilterInfoTypes["None"];
			}
			FilterInfoType<SelectableLevel> value = TerminalManager.FilterInfoTypes.FirstOrDefault((KeyValuePair<string, FilterInfoType<SelectableLevel>> info) => info.Key.ToLowerInvariant() == inputString.ToLowerInvariant()).Value;
			if (value == null)
			{
				Plugin.logger.LogWarning((object)("FilterInfoType '" + inputString + "' not found, defaulting to 'None'"));
				return TerminalManager.FilterInfoTypes["None"];
			}
			return value;
		}

		public static SortInfoType<SelectableLevel> GetSortInfoType(string inputString)
		{
			if (string.IsNullOrEmpty(inputString))
			{
				return TerminalManager.SortInfoTypes["None"];
			}
			SortInfoType<SelectableLevel> value = TerminalManager.SortInfoTypes.FirstOrDefault((KeyValuePair<string, SortInfoType<SelectableLevel>> info) => info.Key.ToLowerInvariant() == inputString.ToLowerInvariant()).Value;
			if (value == null)
			{
				Plugin.logger.LogWarning((object)("SortInfoType '" + inputString + "' not found, defaulting to 'None'"));
				return TerminalManager.SortInfoTypes["None"];
			}
			return value;
		}

		public static SortInfoType<BuyableThing> GetStoreSortInfoType(string inputString)
		{
			if (string.IsNullOrEmpty(inputString))
			{
				return TerminalManager.StoreSortInfoTypes["None"];
			}
			return TerminalManager.StoreSortInfoTypes.FirstOrDefault((KeyValuePair<string, SortInfoType<BuyableThing>> info) => info.Key.ToLowerInvariant() == inputString.ToLowerInvariant()).Value;
		}
	}
	public class Logger : Logger
	{
		public Logger(string SourceName, LoggingType defaultLoggingType = (LoggingType)1)
			: base(SourceName, defaultLoggingType)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			((Logger)this).ModName = SourceName;
			((Logger)this).LogSource = Logger.CreateLogSource("TerminalUtils");
			((Logger)this)._name = SourceName;
		}

		public override bool ShouldLog(LoggingType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return ConfigManager.LoggingLevels.Value >= type;
		}
	}
	public static class NodeReplacementManager
	{
		internal static List<TerminalNodeReplacement> RegisteredNodes = new List<TerminalNodeReplacement>();

		public static bool ReplaceNode = true;
	}
	[BepInPlugin("mrov.TerminalUtils", "TerminalUtils", "0.0.14")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource logger;

		internal static Logger debugLogger = new Logger("Debug", (LoggingType)2);

		internal static Harmony harmony = new Harmony("mrov.TerminalUtils");

		internal static LethalLevelLoaderCompatibility LLLCompatibility = new LethalLevelLoaderCompatibility("imabatby.lethallevelloader");

		internal static DawnLibCompatibility DawnCompatibility = new DawnLibCompatibility("com.github.teamxiaolan.dawnlib");

		internal static WeatherRegistryCompatibility WeatherRegistryCompatibility = new WeatherRegistryCompatibility("mrov.WeatherRegistry");

		internal static LethalMoonUnlocksCompatibility LMUCompatibility = new LethalMoonUnlocksCompatibility("com.xmods.lethalmoonunlocks");

		internal static LethalConstellationsCompatibility LCCompatibility = new LethalConstellationsCompatibility("com.github.darmuh.LethalConstellations");

		internal static LategameUpgradesCompatibility LGUCompat = new LategameUpgradesCompatibility("MoreShipUpgrades");

		internal static StoreRotationConfigCompatibility SRCCompat = new StoreRotationConfigCompatibility("pacoito.StoreRotationConfig");

		internal static LethalLibCompatibility LLCompat = new LethalLibCompatibility("Evaisa.LethalLib");

		internal static LunarConfigCompatibility LunarConfigCompat = new LunarConfigCompatibility("Crafty.LunarConfig");

		private void Awake()
		{
			logger = ((BaseUnityPlugin)this).Logger;
			harmony.PatchAll();
			ConfigManager.Init(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin mrov.TerminalUtils is loaded!");
		}
	}
	public static class StartupManager
	{
		public static void Init(Terminal _instance)
		{
			TerminalManager.Init(_instance);
			CommandManager.Init();
			PreviewCommand item = new PreviewCommand();
			CommandManager.Commands.Add(item);
			SortCommand item2 = new SortCommand();
			CommandManager.Commands.Add(item2);
			FilterCommand item3 = new FilterCommand();
			CommandManager.Commands.Add(item3);
			SimulateCommand item4 = new SimulateCommand();
			CommandManager.Commands.Add(item4);
			StoreSortCommand item5 = new StoreSortCommand();
			CommandManager.Commands.Add(item5);
		}
	}
	public static class TerminalManager
	{
		public static Dictionary<string, PreviewInfoType<SelectableLevel>> PreviewInfoTypes = new Dictionary<string, PreviewInfoType<SelectableLevel>>();

		public static Dictionary<string, FilterInfoType<SelectableLevel>> FilterInfoTypes = new Dictionary<string, FilterInfoType<SelectableLevel>>();

		public static Dictionary<string, SortInfoType<SelectableLevel>> SortInfoTypes = new Dictionary<string, SortInfoType<SelectableLevel>>();

		public static Dictionary<string, SortInfoType<BuyableThing>> StoreSortInfoTypes = new Dictionary<string, SortInfoType<BuyableThing>>();

		public static Dictionary<TerminalNode, TerminalNodeReplacement> NodeReplacements = new Dictionary<TerminalNode, TerminalNodeReplacement>();

		public static Terminal Terminal => ContentManager.Terminal;

		public static TerminalNode MoonsPage { get; private set; }

		public static TerminalNode StorePage { get; private set; }

		public static TerminalNode ScanPage { get; private set; }

		public static List<PreviewInfoType<SelectableLevel>> CurrentPreviewInfoType { get; set; }

		public static FilterInfoType<SelectableLevel> CurrentFilterInfoType { get; set; }

		public static SortInfoType<SelectableLevel> CurrentSortInfoType { get; set; }

		public static SortInfoType<BuyableThing> CurrentStoreSortInfoType { get; set; }

		internal static void Init(Terminal terminal)
		{
			MoonsPage = ContentManager.MoonsKeyword.specialKeywordResult;
			StorePage = ((IEnumerable<TerminalNode>)ContentManager.Nodes).FirstOrDefault((Func<TerminalNode, bool>)((TerminalNode node) => ((Object)node).name == "0_StoreHub"));
			ScanPage = ((IEnumerable<TerminalNode>)ContentManager.Nodes).FirstOrDefault((Func<TerminalNode, bool>)((TerminalNode node) => ((Object)node).name == "ScanInfo"));
			RegisterLocalInfoTypes();
			CurrentPreviewInfoType = InfoTypeResolver.GetPreviewInfoType(ConfigManager.PreviewInfoType.Value);
			CurrentFilterInfoType = InfoTypeResolver.GetFilterInfoType(ConfigManager.FilterInfoType.Value);
			CurrentSortInfoType = InfoTypeResolver.GetSortInfoType(ConfigManager.SortInfoType.Value);
			CurrentStoreSortInfoType = InfoTypeResolver.GetStoreSortInfoType(ConfigManager.StoreSortInfoType.Value);
			NodeReplacements = new Dictionary<TerminalNode, TerminalNodeReplacement>
			{
				{
					MoonsPage,
					new MoonCatalogue()
				},
				{
					StorePage,
					new StoreCatalogue()
				},
				{
					ScanPage,
					new Scan()
				}
			};
		}

		private static void RegisterLocalInfoTypes()
		{
			PreviewInfoTypes.Clear();
			SortInfoTypes.Clear();
			FilterInfoTypes.Clear();
			StoreSortInfoTypes.Clear();
			PreviewInfoTypes.Add("Name", new PreviewName());
			PreviewInfoTypes.Add("Price", new PreviewPrice());
			PreviewInfoTypes.Add("Weather", new PreviewWeather());
			PreviewInfoTypes.Add("Difficulty", new PreviewDifficulty());
			if (((CompatibilityHandler)Plugin.LCCompatibility).IsModPresent)
			{
				PreviewInfoTypes.Add("Constellation", new PreviewConstellation());
			}
			if (((CompatibilityHandler)Plugin.LMUCompatibility).IsModPresent)
			{
				PreviewInfoTypes.Add("LMU", new PreviewLMU());
			}
			SortInfoTypes.Add("None", new TerminalUtils.InfoTypes.Moons.SortNone());
			SortInfoTypes.Add("Name", new TerminalUtils.InfoTypes.Moons.SortName());
			SortInfoTypes.Add("Price", new TerminalUtils.InfoTypes.Moons.SortPrice());
			SortInfoTypes.Add("Difficulty", new SortDifficulty());
			if (((CompatibilityHandler)Plugin.LunarConfigCompat).IsModPresent)
			{
				SortInfoTypes.Add("Lunar", new SortLunar());
			}
			FilterInfoTypes.Add("None", new FilterNone());
			FilterInfoTypes.Add("Price", new FilterPrice());
			FilterInfoTypes.Add("Weather", new FilterWeather());
			StoreSortInfoTypes.Add("None", new TerminalUtils.InfoTypes.Store.SortNone());
			StoreSortInfoTypes.Add("Name", new TerminalUtils.InfoTypes.Store.SortName());
			StoreSortInfoTypes.Add("Price", new TerminalUtils.InfoTypes.Store.SortPrice());
		}

		public static List<SelectableLevel> GetCurrentLevels()
		{
			List<SelectableLevel> inputList = CurrentFilterInfoType.Filter(LevelHelper.Levels).ToList();
			return CurrentSortInfoType.Sort(inputList);
		}

		public static List<BuyableThing> GetCurrentStoreItems()
		{
			return CurrentStoreSortInfoType.Sort(ContentManager.Buyables.ToList());
		}
	}
	public class TerminalNodeManager
	{
		internal static TerminalNode lastResolvedNode;

		public static void Init()
		{
		}

		public static TerminalKeyword AddVerb(string name, string word)
		{
			TerminalKeyword val = ScriptableObject.CreateInstance<TerminalKeyword>();
			((Object)val).name = name;
			val.word = word;
			val.isVerb = true;
			ContentManager.AddTerminalKeywords(new List<TerminalKeyword>(1) { val });
			return val;
		}

		public static void AddTerminalContent(List<TerminalNode> terminalNodes = null, List<TerminalKeyword> terminalKeywords = null)
		{
			if (terminalNodes != null && terminalNodes.Count > 0)
			{
				ContentManager.AddTerminalNodes(terminalNodes);
			}
			if (terminalKeywords != null && terminalKeywords.Count > 0)
			{
				ContentManager.AddTerminalKeywords(terminalKeywords);
			}
		}

		public static TerminalNode CreateTerminalNode(string name, string terminalEvent = "")
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			((Object)val).name = name;
			val.terminalEvent = terminalEvent;
			val.displayText = "";
			val.clearPreviousText = true;
			val.acceptAnything = true;
			val.terminalOptions = Array.Empty<CompatibleNoun>();
			val.maxCharactersToType = 25;
			val.itemCost = 0;
			val.buyItemIndex = -1;
			val.buyVehicleIndex = -1;
			val.buyRerouteToMoon = -1;
			val.displayPlanetInfo = -1;
			val.shipUnlockableID = -1;
			val.creatureFileID = -1;
			val.storyLogFileID = -1;
			val.playSyncedClip = -1;
			return val;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "mrov.TerminalUtils";

		public const string PLUGIN_NAME = "TerminalUtils";

		public const string PLUGIN_VERSION = "0.0.14";
	}
}
namespace TerminalUtils.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed", new Type[] { typeof(CallbackContext) })]
	internal class TerminalScrollMousePatch
	{
		private static float scrollAmount = 1f / 3f;

		public static string CurrentText { get; internal set; } = "";

		private static void ScrollMouse_performed(Scrollbar scrollbar, float scrollDirection)
		{
			if ((Object)(object)scrollbar == (Object)null)
			{
				((Logger)Plugin.debugLogger).LogWarning("scrollbar is null - too bad!");
				return;
			}
			if (string.CompareOrdinal(TerminalManager.Terminal.currentText, CurrentText) != 0)
			{
				CurrentText = TerminalManager.Terminal.currentText;
				Regex regex = new Regex("(?>\\n{1,2}|)[A-Za-z0-9\\ \\'\\:\\.’“,”?!/%*$;\\-\\+\\[\\]\\(\\)]{1,50}", RegexOptions.Multiline | RegexOptions.Compiled);
				int num = regex.Matches(CurrentText.Trim()).Count + 3;
				int num2 = ((!ConfigManager.UseLegacyScrollBehavior.Value) ? num : (CurrentText.Count((char c) => c.Equals('\n')) + 1));
				int value = ConfigManager.LinesToScroll.Value;
				((Logger)Plugin.debugLogger).LogWarning($"ScrollMouse_performed: text has changed; textLength = {num2}; amountOfLinesInCurrentPage = {num}");
				float num3 = (float)value / (float)num;
				scrollAmount = num3;
			}
			scrollbar.value += scrollDirection * scrollAmount;
			((Logger)Plugin.debugLogger).LogMessage($"ScrollMouse_performed: scrollbar.value = {scrollbar.value}, scrollDirection = {scrollDirection}, scrollAmount = {scrollAmount}");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "terminalScrollVertical"), (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[5]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "terminalScrollVertical")),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(TerminalScrollMousePatch), "ScrollMouse_performed", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Ret, (object)null)
			}).InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class TerminalLoadNewNodePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("LoadNewNode")]
		[HarmonyAfter(new string[] { "imabatby.lethallevelloader", "com.github.teamxiaolan.dawnlib" })]
		public static bool PatchMethod(Terminal __instance, TerminalNode node)
		{
			if (!NodeReplacementManager.ReplaceNode)
			{
				return true;
			}
			if (TerminalManager.NodeReplacements.ContainsKey(node))
			{
				__instance.modifyingText = true;
				((Selectable)__instance.screenText).interactable = true;
				TerminalNodeReplacement terminalNodeReplacement = TerminalManager.NodeReplacements[node];
				if (!terminalNodeReplacement.Enabled.Value)
				{
					((Logger)Plugin.debugLogger).LogInfo("Node replacement " + terminalNodeReplacement.Name + " is disabled, skipping replacement");
					return true;
				}
				Plugin.logger.LogInfo((object)("Replacing node " + ((Object)__instance.currentNode).name + " with " + terminalNodeReplacement.Name));
				StringBuilder stringBuilder = new StringBuilder();
				if (Object.op_Implicit((Object)(object)__instance.displayingPersistentImage))
				{
					stringBuilder.Append("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
				}
				stringBuilder.Append("\n\n");
				stringBuilder.Append(terminalNodeReplacement.GetNodeText(node));
				stringBuilder.Append("\n" + new string('-', 17) + "\n");
				__instance.LoadTerminalImage(node);
				__instance.currentNode = node;
				__instance.screenText.text = stringBuilder.ToString();
				__instance.currentText = stringBuilder.ToString();
				__instance.textAdded = 0;
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch("LoadNewNode")]
		public static void PatchMethod()
		{
			NodeReplacementManager.ReplaceNode = true;
		}
	}
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	internal class TerminalParsePlayerSentencePatch
	{
		[HarmonyPrefix]
		[HarmonyBefore(new string[] { "mrov.WeatherRegistry" })]
		public static bool GameMethodPatch(Terminal __instance, ref TerminalNode __result)
		{
			string text = __instance.screenText.text;
			int textAdded = __instance.textAdded;
			string text2 = text.Substring(text.Length - textAdded);
			text2 = __instance.RemovePunctuation(text2);
			List<string> list = text2.Split(' ').ToList();
			if (list.Count >= 1 && CommandManager.CommandLookup.TryGetValue(list[0], out var value))
			{
				((Logger)Plugin.debugLogger).LogWarning("Command detected, passing to CommandManager");
				if (list.Count >= 2)
				{
					string[] args = list.Skip(1).ToArray();
					TerminalNode val = CommandManager.RunTerminalCommand(value, args);
					__result = val;
					return false;
				}
				return true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class TerminalStartPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Postfix(Terminal __instance)
		{
			StartupManager.Init(__instance);
			if (((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent)
			{
				Plugin.LLLCompatibility.RemoveMoonNodeEvent();
			}
		}
	}
}
namespace TerminalUtils.Nodes
{
	public class MoonCatalogue : TerminalNodeReplacement
	{
		public MoonCatalogue()
			: base("Moon Catalogue", TerminalManager.MoonsPage)
		{
			base.HelpText = " Welcome to the exomoons catalogue! \n Use ROUTE to set the autopilot. \n Use INFO to learn about a moon.";
		}

		public override string GetNodeText(TerminalNode node)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			List<SelectableLevel> currentLevels = TerminalManager.GetCurrentLevels();
			((Logger)Plugin.debugLogger).LogDebug("Current preview types: " + string.Join(", ", TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name)));
			StringBuilder stringBuilder = new StringBuilder();
			ConsoleTable val = new ConsoleTable(TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => "").ToArray());
			int num = 1;
			List<PreviewInfoType<SelectableLevel>> currentPreviewInfoType = TerminalManager.CurrentPreviewInfoType;
			((Logger)Plugin.debugLogger).LogDebug("Current preview types: " + string.Join(", ", currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name)));
			foreach (SelectableLevel level in currentLevels)
			{
				if (LevelHelper.IsHidden(level) || (LevelHelper.IsLocked(level) && !ConfigManager.DisplayLockedMoons.Value) || Defaults.VanillaHiddenMoons.Contains(StringResolver.GetNumberlessName(level)))
				{
					continue;
				}
				string[] array = currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => (info.Name == "Name") ? ("* " + info.Value(level)) : info.Value(level)).ToArray();
				object[] array2 = array;
				val.AddRow(array2);
				if (num % 3 == 0)
				{
					num = 1;
					array2 = currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> _) => "").ToArray();
					val.AddRow(array2);
				}
				else
				{
					num++;
				}
			}
			stringBuilder.AppendLine((base.HelpText != null) ? ("\n" + base.HelpText + "\n\n") : "");
			stringBuilder.Append($" The Company // Buying at {Mathf.RoundToInt(StartOfRound.Instance.companyBuyingRate * 100f)}% \n\n");
			stringBuilder.Append(val.ToStringCustomDecoration(false, false, false));
			stringBuilder.AppendLine();
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("PREVIEW: " + string.Join(", ", currentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name)) + "\nSORT: " + TerminalManager.CurrentSortInfoType.Name + "; FILTER: " + TerminalManager.CurrentFilterInfoType.Name);
			return stringBuilder.ToString().TrimEnd();
		}
	}
	public class Scan : TerminalNodeReplacement
	{
		public Scan()
			: base("Scan", TerminalManager.ScanPage)
		{
		}

		public bool GrabbablePredicate(GrabbableObject obj)
		{
			bool inShipPhase = StartOfRound.Instance.inShipPhase;
			if (LevelHelper.CompanyMoons.Contains(StartOfRound.Instance.currentLevel))
			{
				return true;
			}
			if (inShipPhase)
			{
				if (!obj.isInElevator)
				{
					return obj.isInShipRoom;
				}
				return true;
			}
			if (obj.isInShipRoom)
			{
				return !obj.isInElevator;
			}
			return true;
		}

		public List<GrabbableObject> GetObjects()
		{
			return (from x in Object.FindObjectsOfType<GrabbableObject>()
				where x.itemProperties.isScrap && (Object)(object)x.radarIcon != (Object)null && GrabbablePredicate(x)
				orderby x.scrapValue
				select x).ToList();
		}

		public override string GetNodeText(TerminalNode node)
		{
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			bool value = ConfigManager.DetailedScanPage.Value;
			bool flag = ConfigManager.DisplayAccuratePrices.Value;
			Random random = new Random(StartOfRound.Instance.randomMapSeed);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("\n");
			bool inShipPhase = StartOfRound.Instance.inShipPhase;
			bool flag2 = LevelHelper.CompanyMoons.Contains(StartOfRound.Instance.currentLevel);
			List<GrabbableObject> objects = GetObjects();
			int num = objects.Count;
			int num2 = objects.Sum((GrabbableObject x) => x.scrapValue);
			if (flag2)
			{
				stringBuilder.Append("Scanning all scrap:");
			}
			else
			{
				stringBuilder.Append("Scanning scrap " + (inShipPhase ? "in the ship" : "on the moon") + ":");
			}
			if (!flag && (inShipPhase || flag2))
			{
				flag = true;
			}
			if (!flag)
			{
				int num3 = 0;
				foreach (GrabbableObject item in objects)
				{
					num3 += Mathf.Clamp(random.Next(item.itemProperties.minValue, item.itemProperties.maxValue), item.scrapValue - 6 * num, item.scrapValue + 9 * num);
				}
				num2 = num3;
			}
			if (!value)
			{
				stringBuilder.Append(string.Format("\nFound {0} scrap item{1}, worth {2}${3}.", num, (num > 1) ? "s" : "", flag ? "" : "about ", num2));
			}
			else
			{
				stringBuilder.Append(string.Format("\nFound {0} scrap item{1}, worth {2}${3}.", num, (num > 1) ? "s" : "", flag ? "" : "about ", num2));
				stringBuilder.Append("\n\n");
				ConsoleTable val = new ConsoleTable(new string[2] { "Name", "Price" });
				foreach (GrabbableObject item2 in objects)
				{
					val.AddRow(new object[2]
					{
						item2.itemProperties.itemName.PadRight(Defaults.itemNameWidth),
						$"${(flag ? ((object)item2.scrapValue) : $"{item2.itemProperties.minValue}-${item2.itemProperties.maxValue}")}"
					});
					num++;
					num2 += item2.scrapValue;
				}
				stringBuilder.Append("\n");
				stringBuilder.Append(val.ToStringCustomDecoration(true, false, false));
			}
			return stringBuilder.ToString();
		}
	}
	public class StoreCatalogue : TerminalNodeReplacement
	{
		public StoreCatalogue()
			: base("Store Catalogue", TerminalManager.StorePage)
		{
			base.HelpText = " Welcome to the Company store. \n Use words BUY and INFO on any item. \n Order items in bulk by typing a number.";
		}

		public override string GetNodeText(TerminalNode node)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			ConsoleTable val = new ConsoleTable(new string[2] { "Name", "Price" });
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append((base.HelpText != null) ? ("\n" + base.HelpText + "\n") : "");
			PurchaseType[] array = new PurchaseType[5];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			PurchaseType[] desiredOrder = (PurchaseType[])(object)array;
			Dictionary<PurchaseType, List<BuyableThing>> dictionary = (from thing in TerminalManager.GetCurrentStoreItems()
				group thing by thing.Type).OrderBy(delegate(IGrouping<PurchaseType, BuyableThing> group)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				int num4 = Array.IndexOf(desiredOrder, group.Key);
				return (num4 != -1) ? num4 : int.MaxValue;
			}).ToDictionary((IGrouping<PurchaseType, BuyableThing> group) => group.Key, (IGrouping<PurchaseType, BuyableThing> group) => group.Where(delegate(BuyableThing item)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Expected I4, but got Unknown
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Expected O, but got Unknown
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Expected O, but got Unknown
				PurchaseType type = item.Type;
				switch (type - 1)
				{
				case 0:
				{
					BuyableUnlockable val6 = (BuyableUnlockable)item;
					return !val6.IsUnlocked;
				}
				case 1:
				{
					BuyableDecoration val5 = (BuyableDecoration)item;
					if (val5.InRotation)
					{
						return !((BuyableUnlockable)val5).IsUnlocked;
					}
					return false;
				}
				case 2:
				{
					BuyableSuit val4 = (BuyableSuit)item;
					if (val4.InRotation)
					{
						return !val4.IsUnlocked;
					}
					return false;
				}
				default:
					return true;
				}
			}).ToList());
			foreach (KeyValuePair<PurchaseType, List<BuyableThing>> item in dictionary)
			{
				if (item.Value.Count == 0)
				{
					continue;
				}
				int num = 1;
				val.AddRow(new object[2] { "", "" });
				val.AddRow(new object[2]
				{
					"[" + ((object)item.Key/*cast due to .constrained prefix*/).ToString().ToUpperInvariant() + "S]",
					""
				});
				for (int num2 = 0; num2 < item.Value.Count; num2++)
				{
					BuyableThing val2 = item.Value[num2];
					string text = val2.Name.PadRight(30);
					string text2 = $"${val2.Price}";
					if ((int)val2.Type == 0)
					{
						BuyableItem val3 = (BuyableItem)val2;
						if (val3.Discount != 0)
						{
							string arg = ((val3.Discount != 0) ? $"  (-{val3.Discount}%)" : "");
							decimal d = Convert.ToDecimal(((BuyableThing)val3).Price) * Convert.ToDecimal(val3.DiscountPercentage);
							int num3 = (int)Math.Floor(d);
							text2 = $"${num3}{arg}";
						}
						if (((CompatibilityHandler)Plugin.DawnCompatibility).IsModPresent)
						{
							if (!Plugin.DawnCompatibility.IsItemInStore(val3.Item))
							{
								continue;
							}
							text = Plugin.DawnCompatibility.GetStoreItemNameOverride(val3.Item);
						}
					}
					val.AddRow(new object[2]
					{
						"* " + text,
						text2 ?? ""
					});
					if (ConfigManager.DivideStore.Value != 0 && num2 != item.Value.Count - 1)
					{
						if (num % ConfigManager.DivideStore.Value == 0)
						{
							num = 1;
							val.AddRow(new object[2] { "", "" });
						}
						else
						{
							num++;
						}
					}
				}
			}
			string value = val.ToStringCustomDecoration(false, true, false).TrimEnd();
			stringBuilder.Append(value);
			return stringBuilder.ToString().TrimEnd();
		}
	}
}
namespace TerminalUtils.InfoTypes.Store
{
	public class SortName : SortInfoType<BuyableThing>
	{
		public SortName()
			: base("Name")
		{
		}

		public override List<BuyableThing> Sort(List<BuyableThing> inputList)
		{
			inputList.Sort((BuyableThing a, BuyableThing b) => a.Name.CompareTo(b.Name));
			return inputList;
		}
	}
	public class SortNone : SortInfoType<BuyableThing>
	{
		public SortNone()
			: base("None")
		{
		}

		public override List<BuyableThing> Sort(List<BuyableThing> inputList)
		{
			return inputList;
		}
	}
	public class SortPrice : SortInfoType<BuyableThing>
	{
		public SortPrice()
			: base("Price")
		{
		}

		public override List<BuyableThing> Sort(List<BuyableThing> inputList)
		{
			inputList.Sort((BuyableThing a, BuyableThing b) => a.Price.CompareTo(b.Price));
			return inputList;
		}
	}
}
namespace TerminalUtils.InfoTypes.Moons
{
	public class FilterNone : FilterInfoType<SelectableLevel>
	{
		public FilterNone()
			: base("None")
		{
		}

		public override List<SelectableLevel> Filter(List<SelectableLevel> inputList)
		{
			return inputList;
		}
	}
	public class FilterPrice : FilterInfoType<SelectableLevel>
	{
		public FilterPrice()
			: base("Price")
		{
		}

		public override List<SelectableLevel> Filter(List<SelectableLevel> inputList)
		{
			return inputList.Where((SelectableLevel lvl) => ContentManager.RouteDictionary.GetRoute(lvl).Price <= ContentManager.Terminal.groupCredits).ToList();
		}
	}
	public class FilterWeather : FilterInfoType<SelectableLevel>
	{
		public FilterWeather()
			: base("Weather")
		{
		}

		public override List<SelectableLevel> Filter(List<SelectableLevel> inputList)
		{
			return inputList.Where((SelectableLevel lvl) => ContentManager.RouteDictionary.GetRoute(lvl).Price >= ContentManager.Terminal.groupCredits).ToList();
		}
	}
	public class PreviewConstellation : PreviewInfoType<SelectableLevel>
	{
		public PreviewConstellation()
			: base("Constellation")
		{
		}

		public override string Value(SelectableLevel inputValue)
		{
			return Plugin.LCCompatibility.GetConstellationName(inputValue);
		}
	}
	public class PreviewDifficulty : PreviewInfoType<SelectableLevel>
	{
		public PreviewDifficulty()
			: base("Difficulty")
		{
			base.MaxLength = 5;
		}

		public override string Value(SelectableLevel inputValue)
		{
			return inputValue.riskLevel;
		}
	}
	public class PreviewLMU : PreviewInfoType<SelectableLevel>
	{
		public PreviewLMU()
			: base("LMU")
		{
		}

		public override string Value(SelectableLevel inputValue)
		{
			object obj = (Plugin.LMUCompatibility.MoonUnlockables.TryGetValue(inputValue, out obj) ? obj : null);
			LMUnlockable val = (LMUnlockable)((obj is LMUnlockable) ? obj : null);
			if (val == null)
			{
				return null;
			}
			return val.BuildTagString();
		}
	}
	public class PreviewName : PreviewInfoType<SelectableLevel>
	{
		public PreviewName()
			: base("Name")
		{
			base.MaxLength = LevelHelper.LongestPlanetName.Length;
		}

		public override string Value(SelectableLevel inputValue)
		{
			return StringResolver.GetNumberlessName(inputValue);
		}
	}
	public class PreviewNameNumbered : PreviewInfoType<SelectableLevel>
	{
		public PreviewNameNumbered()
			: base("NameNumbered")
		{
			base.MaxLength = LevelHelper.LongestPlanetName.Length + 4;
		}

		public override string Value(SelectableLevel inputValue)
		{
			string value = Regex.Match(inputValue.PlanetName, "^\\d+").Value;
			return value.PadLeft(3, '0') + " " + StringResolver.GetNumberlessName(inputValue);
		}
	}
	public class PreviewPrice : PreviewInfoType<SelectableLevel>
	{
		public PreviewPrice()
			: base("Price")
		{
		}

		public override string Value(SelectableLevel inputValue)
		{
			if (((CompatibilityHandler)Plugin.LGUCompat).IsModPresent)
			{
				return $"${Plugin.LGUCompat.GetMoonPrice(ContentManager.RouteDictionary.GetRoute(inputValue).Price)}";
			}
			return $"${ContentManager.RouteDictionary.GetRoute(inputValue).Price}";
		}
	}
	public class PreviewWeather : PreviewInfoType<SelectableLevel>
	{
		public PreviewWeather()
			: base("Weather")
		{
		}

		public override string Value(SelectableLevel inputValue)
		{
			string text = ((object)Unsafe.As<LevelWeatherType, LevelWeatherType>(ref inputValue.currentWeather)/*cast due to .constrained prefix*/).ToString();
			if (((CompatibilityHandler)Plugin.WeatherRegistryCompatibility).IsModPresent)
			{
				text = Plugin.WeatherRegistryCompatibility.GetWeather(inputValue);
			}
			if (!(text == "None"))
			{
				return text;
			}
			return "";
		}
	}
	public class SortDifficulty : SortInfoType<SelectableLevel>
	{
		private static readonly List<string> difficultyOrder = new List<string>(10) { "Safe", "F", "E", "D", "C", "B", "A", "S", "Unknown", "?" };

		public SortDifficulty()
			: base("Difficulty")
		{
		}

		public override List<SelectableLevel> Sort(List<SelectableLevel> inputList)
		{
			inputList.Sort(delegate(SelectableLevel a, SelectableLevel b)
			{
				string source = (string.IsNullOrWhiteSpace(a.riskLevel) ? "Unknown" : a.riskLevel.Trim());
				string source2 = (string.IsNullOrWhiteSpace(b.riskLevel) ? "Unknown" : b.riskLevel.Trim());
				int num = source.Count((char c) => c == '+');
				int num2 = source.Count((char c) => c == '-');
				int num3 = source2.Count((char c) => c == '+');
				int num4 = source2.Count((char c) => c == '-');
				string baseA = new string(source.Where((char c) => c != '+' && c != '-').ToArray()).Trim();
				string baseB = new string(source2.Where((char c) => c != '+' && c != '-').ToArray()).Trim();
				if (string.IsNullOrEmpty(baseA))
				{
					baseA = "Unknown";
				}
				if (string.IsNullOrEmpty(baseB))
				{
					baseB = "Unknown";
				}
				int num5 = difficultyOrder.FindIndex((string s) => string.Equals(s, baseA, StringComparison.OrdinalIgnoreCase));
				int num6 = difficultyOrder.FindIndex((string s) => string.Equals(s, baseB, StringComparison.OrdinalIgnoreCase));
				if (num5 == -1)
				{
					num5 = difficultyOrder.Count;
				}
				if (num6 == -1)
				{
					num6 = difficultyOrder.Count;
				}
				if (num5 != num6)
				{
					return num5.CompareTo(num6);
				}
				int num7 = num - num2;
				int value = num3 - num4;
				return num7.CompareTo(value);
			});
			return inputList;
		}
	}
	public class SortLunar : SortInfoType<SelectableLevel>
	{
		public SortLunar()
			: base("Lunar")
		{
		}

		public override List<SelectableLevel> Sort(List<SelectableLevel> inputList)
		{
			inputList.Sort((SelectableLevel a, SelectableLevel b) => Plugin.LunarConfigCompat.GetMoonIndex(b).CompareTo(Plugin.LunarConfigCompat.GetMoonIndex(a)));
			return inputList;
		}
	}
	public class SortName : SortInfoType<SelectableLevel>
	{
		public SortName()
			: base("Name")
		{
		}

		public override List<SelectableLevel> Sort(List<SelectableLevel> inputList)
		{
			inputList.Sort((SelectableLevel a, SelectableLevel b) => StringResolver.GetAlphanumericName(a).CompareTo(StringResolver.GetAlphanumericName(b)));
			return inputList;
		}
	}
	public class SortNone : SortInfoType<SelectableLevel>
	{
		public SortNone()
			: base("None")
		{
		}

		public override List<SelectableLevel> Sort(List<SelectableLevel> inputList)
		{
			return inputList;
		}
	}
	public class SortPrice : SortInfoType<SelectableLevel>
	{
		public SortPrice()
			: base("Price")
		{
		}

		public override List<SelectableLevel> Sort(List<SelectableLevel> inputList)
		{
			inputList.Sort((SelectableLevel a, SelectableLevel b) => ContentManager.RouteDictionary.GetRoute(a).Price.CompareTo(ContentManager.RouteDictionary.GetRoute(b).Price));
			return inputList;
		}
	}
}
namespace TerminalUtils.Enums
{
	public enum TerminalDisplayType
	{
		Preview,
		Sort,
		Filter
	}
}
namespace TerminalUtils.Definitions
{
	public abstract class ConfigHandler<T, CT> : ConfigHandler<T, CT>
	{
		public ConfigHandler(CT value)
		{
			((ConfigHandler<T, CT>)this).DefaultValue = value;
		}
	}
	public class FilterInfoType<T> : TerminalInfoType
	{
		public FilterInfoType(string Name)
		{
			base.Name = Name;
			base.Type = TerminalDisplayType.Filter;
		}

		public virtual List<T> Filter(List<T> inputList)
		{
			return inputList;
		}
	}
	public interface ITerminalInfoType
	{
		string Name { get; }

		TerminalDisplayType Type { get; }
	}
	public class TerminalInfoType : ITerminalInfoType
	{
		public string Name { get; set; }

		public TerminalDisplayType Type { get; set; }

		public override string ToString()
		{
			return $"{Name} ({Type})";
		}
	}
	public class PreviewGroup
	{
		public List<PreviewInfoType> PreviewInfoTypes { get; set; }
	}
	public class PreviewInfoType : TerminalInfoType
	{
		public int MaxLength { get; set; } = Defaults.terminalWidth;

		public PreviewInfoType(string Name)
		{
			base.Name = Name;
			base.Type = TerminalDisplayType.Preview;
		}
	}
	public abstract class PreviewInfoType<T> : PreviewInfoType
	{
		protected PreviewInfoType(string Name)
			: base(Name)
		{
		}

		public string ValueWithMaxLength(T inputValue)
		{
			string text = Value(inputValue);
			if (text.Length > base.MaxLength)
			{
				text = text.Substring(0, base.MaxLength - 3) + "...";
			}
			return text;
		}

		public virtual string Value(T inputValue)
		{
			return "";
		}

		public override string ToString()
		{
			return $"{base.Name} ({base.Type})";
		}
	}
	public class SortInfoType<T> : TerminalInfoType
	{
		public SortInfoType(string Name)
		{
			base.Name = Name;
			base.Type = TerminalDisplayType.Sort;
		}

		public virtual List<T> Sort(List<T> inputList)
		{
			return inputList;
		}
	}
	public abstract class TerminalCommandNode : CommandNode
	{
		public List<TerminalCommandNode> Subcommands { get; set; } = new List<TerminalCommandNode>();

		public bool HostOnly { get; set; }

		public int TerminalSound { get; set; } = -1;

		public TerminalNode RedirectToNode { get; set; }

		protected TerminalCommandNode(string Name)
			: base(Name)
		{
		}

		public virtual bool ShouldRun()
		{
			if (!HostOnly || ((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				return true;
			}
			return false;
		}

		public virtual string Execute(string[] args)
		{
			return "";
		}
	}
	public abstract class TerminalNodeReplacement
	{
		public string Name { get; set; }

		public string HelpText { get; set; }

		public TerminalNode NodeToMatch { get; set; }

		public ConfigEntry<bool> Enabled { get; set; }

		public virtual bool IsNodeValid(TerminalNode node)
		{
			return true;
		}

		public abstract string GetNodeText(TerminalNode node);

		public TerminalNodeReplacement(string name, TerminalNode NodeToMatch, ConfigEntry<bool> enabled = null)
		{
			Name = name;
			this.NodeToMatch = NodeToMatch;
			if (enabled != null)
			{
				Enabled = enabled;
			}
			else
			{
				Enabled = ConfigManager.configFile.Bind<bool>("Nodes", name, true, "Enable node " + name);
			}
			NodeReplacementManager.RegisteredNodes.Add(this);
			((Logger)Plugin.debugLogger).LogInfo("Registered node " + name);
		}
	}
}
namespace TerminalUtils.Compatibility
{
	public class DawnLibCompatibility : CompatibilityHandler
	{
		public DawnLibCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public override void Init()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (((CompatibilityHandler)this).IsModPresent)
			{
				Type type = AccessTools.TypeByName("Dawn.MoonRegistrationHandler");
				Plugin.harmony.Patch((MethodBase)AccessTools.Method(type, "DynamicMoonCatalogue", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(DawnLibCompatibility), "InsertMoonCatalogueSkip", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public object GetLevelDawnInfo(SelectableLevel level)
		{
			return SelectableLevelExtensions.GetDawnInfo(level);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public (bool locked, bool hidden) GetLevelStatus(SelectableLevel level)
		{
			if (!((CompatibilityHandler)this).IsModPresent)
			{
				return (locked: false, hidden: false);
			}
			TerminalPurchaseResult val = SelectableLevelExtensions.GetDawnInfo(level).DawnPurchaseInfo.PurchasePredicate.CanPurchase();
			HiddenPurchaseResult val2 = (HiddenPurchaseResult)(object)((val is HiddenPurchaseResult) ? val : null);
			if (val2 == null)
			{
				if (!(val is FailedPurchaseResult))
				{
					if (val is SuccessPurchaseResult)
					{
						return (locked: false, hidden: false);
					}
					return (locked: false, hidden: false);
				}
				return (locked: true, hidden: false);
			}
			return (locked: val2.IsFailure, hidden: true);
		}

		public static IEnumerable<CodeInstruction> InsertMoonCatalogueSkip(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.Start().Insert((CodeInstruction[])(object)new CodeInstruction[6]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldarg_1, (object)null),
				new CodeInstruction(OpCodes.Ldarg_2, (object)null),
				new CodeInstruction(OpCodes.Ldarg_3, (object)null),
				new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.Method(typeof(orig_TextPostProcess), "Invoke", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Ret, (object)null)
			});
			return val.InstructionEnumeration();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static Dictionary<string, int> GetDungeonRarities(SelectableLevel level)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			DawnMoonInfo dawnInfo = SelectableLevelExtensions.GetDawnInfo(level);
			List<DawnDungeonInfo> list = new List<DawnDungeonInfo>();
			List<float> list2 = new List<float>();
			SpawnWeightContext val = default(SpawnWeightContext);
			foreach (DawnDungeonInfo value2 in ((Registry<DawnDungeonInfo>)(object)LethalContent.Dungeons).Values)
			{
				((SpawnWeightContext)(ref val))..ctor(dawnInfo, (DawnDungeonInfo)null, (DawnWeatherEffectInfo)null);
				int valueOrDefault = ProviderTableSpawnWeightExtensions.GetFor<int?>(value2.Weights, ref val).GetValueOrDefault();
				if (valueOrDefault > 0)
				{
					list.Add(value2);
					list2.Add(valueOrDefault);
				}
			}
			((Logger)Plugin.debugLogger).LogDebug(string.Format("Found {0} possible dungeons for level {1}: {2}", list.Count, level.PlanetName, string.Join(", ", list.Select((DawnDungeonInfo d) => ((DawnBaseInfo<DawnDungeonInfo>)(object)d).Key))));
			for (int num = 0; num < list.Count; num++)
			{
				string key = StringExtensions.ReplaceNumbersWithWords(StringExtensions.ToCapitalized(StringExtensions.RemoveLeadingNumbers(((DawnBaseInfo<DawnDungeonInfo>)(object)list[num]).Key.Key))).Replace(" ", "_");
				int value = (int)list2[num];
				dictionary[key] = value;
			}
			return dictionary;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public string GetStoreItemNameOverride(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			DawnItemInfo dawnInfo = ItemExtensions.GetDawnInfo(item);
			DawnShopItemInfo shopInfo = dawnInfo.ShopInfo;
			if (shopInfo == null)
			{
				return item.itemName;
			}
			TerminalPurchaseResult val = shopInfo.DawnPurchaseInfo.PurchasePredicate.CanPurchase();
			FailedPurchaseResult val2 = (FailedPurchaseResult)(object)((val is FailedPurchaseResult) ? val : null);
			if (val2 != null)
			{
				if (val2.OverrideName != null)
				{
					((Logger)Plugin.debugLogger).LogCustom($"Overriding name of {((DawnBaseInfo<DawnItemInfo>)(object)dawnInfo).Key} with {val2.OverrideName}", (LogLevel)32, (LoggingType)1);
				}
				return val2.OverrideName ?? item.itemName;
			}
			return item.itemName;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public bool IsItemInStore(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			DawnItemInfo dawnInfo = ItemExtensions.GetDawnInfo(item);
			object obj;
			if (dawnInfo == null)
			{
				obj = null;
			}
			else
			{
				DawnShopItemInfo shopInfo = dawnInfo.ShopInfo;
				if (shopInfo == null)
				{
					obj = null;
				}
				else
				{
					DawnPurchaseInfo dawnPurchaseInfo = shopInfo.DawnPurchaseInfo;
					obj = ((dawnPurchaseInfo != null) ? dawnPurchaseInfo.PurchasePredicate : null);
				}
			}
			ITerminalPurchasePredicate val = (ITerminalPurchasePredicate)obj;
			if (val == null)
			{
				return false;
			}
			return !(val.CanPurchase() is HiddenPurchaseResult);
		}
	}
	internal class LategameUpgradesCompatibility : CompatibilityHandler
	{
		public LategameUpgradesCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		internal int GetMoonPrice(int price)
		{
			string text = "MoreShipUpgrades.UpgradeComponents.TierUpgrades.EfficientEngines";
			Type type = ((CompatibilityHandler)Plugin.LGUCompat).GetModAssembly.GetType(text ?? "");
			if (type == null)
			{
				((Logger)Plugin.debugLogger).LogWarning("Could not find " + text + " type");
				return price;
			}
			MethodInfo method = type.GetMethod("GetDiscountedMoonPrice", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				((Logger)Plugin.debugLogger).LogWarning("Could not find GetDiscountedMoonPrice method in EfficientEngines");
				return price;
			}
			return (int)method.Invoke(null, new object[1] { price });
		}
	}
	public class LethalConstellationsCompatibility : CompatibilityHandler
	{
		public Dictionary<SelectableLevel, string> Constellations { get; private set; } = new Dictionary<SelectableLevel, string>();

		public LethalConstellationsCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public override void Init()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (((CompatibilityHandler)this).IsModPresent)
			{
				EventManager.ContentManagerReady.AddListener(new Event(GetConstellations));
			}
		}

		public void GetConstellations()
		{
			if (!((CompatibilityHandler)this).IsModPresent || !((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent)
			{
				return;
			}
			Dictionary<SelectableLevel, string> constellationsDict = new Dictionary<SelectableLevel, string>();
			List<ClassMapper> constellationStuff = Collections.ConstellationStuff;
			foreach (ClassMapper item in constellationStuff)
			{
				string constellationName = item.consName;
				List<SelectableLevel> list = (from moonName in item.constelMoons
					select StringResolver.ResolveStringToLevels(moonName).FirstOrDefault() into level
					where (Object)(object)level != (Object)null
					select level).ToList();
				list.ForEach(delegate(SelectableLevel level)
				{
					constellationsDict[level] = constellationName;
				});
			}
			Constellations = constellationsDict;
		}

		public string GetConstellationName(SelectableLevel level)
		{
			if (!((CompatibilityHandler)this).IsModPresent)
			{
				return null;
			}
			Constellations.TryGetValue(level, out var value);
			return value;
		}
	}
	public class LethalLevelLoaderCompatibility : CompatibilityHandler
	{
		public LethalLevelLoaderCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public void RemoveMoonNodeEvent()
		{
			if (((CompatibilityHandler)this).IsModPresent)
			{
				TerminalManager.onLoadNewNodeRegisteredEventsDictionary.Clear();
			}
		}

		public static bool IsLevelLocked(SelectableLevel level)
		{
			return SharedMethods.IsMoonLockedLLL(level);
		}

		public static bool IsLevelHidden(SelectableLevel level)
		{
			return SharedMethods.IsMoonHiddenLLL(level);
		}

		public static List<ExtendedDungeonFlowWithRarity> GetExtendedDungeonFlowsWithRarity(ExtendedLevel extendedLevel)
		{
			List<ExtendedDungeonFlowWithRarity> list = new List<ExtendedDungeonFlowWithRarity>();
			CollectionExtensions.Do<ExtendedDungeonFlowWithRarity>((IEnumerable<ExtendedDungeonFlowWithRarity>)DungeonManager.GetValidExtendedDungeonFlows(extendedLevel, false), (Action<ExtendedDungeonFlowWithRarity>)list.Add);
			return list;
		}

		public static Dictionary<string, int> GetDungeonRarities(SelectableLevel level)
		{
			Dictionary<string, int> result = new Dictionary<string, int>();
			ExtendedLevel extendedLevel = default(ExtendedLevel);
			LevelManager.TryGetExtendedLevel(level, ref extendedLevel, (ContentType)2);
			CollectionExtensions.Do<ExtendedDungeonFlowWithRarity>((IEnumerable<ExtendedDungeonFlowWithRarity>)GetExtendedDungeonFlowsWithRarity(extendedLevel), (Action<ExtendedDungeonFlowWithRarity>)delegate(ExtendedDungeonFlowWithRarity flow)
			{
				result[((Object)flow.extendedDungeonFlow.DungeonFlow).name] = flow.rarity;
			});
			return result;
		}
	}
	internal class LethalLibCompatibility : CompatibilityHandler
	{
		public LethalLibCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public static bool IsLLItemDisabled(Item item)
		{
			return Items.shopItems.Find((ShopItem x) => (Object)(object)x.item == (Object)(object)item)?.wasRemoved ?? false;
		}

		public static bool IsLLUpgradeDisabled(UnlockableItem unlockable)
		{
			return Unlockables.registeredUnlockables.Find((RegisteredUnlockable x) => x.unlockable == unlockable)?.disabled ?? false;
		}
	}
	public class LethalMoonUnlocksCompatibility : CompatibilityHandler
	{
		public Dictionary<SelectableLevel, object> MoonUnlockables { get; private set; } = new Dictionary<SelectableLevel, object>();

		public LethalMoonUnlocksCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public override void Init()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (((CompatibilityHandler)this).IsModPresent)
			{
				EventManager.ContentManagerReady.AddListener(new Event(PopulateDictionary));
			}
		}

		public void PopulateDictionary()
		{
			if (!((CompatibilityHandler)this).IsModPresent)
			{
				return;
			}
			List<LMUnlockable> unlocks = UnlockManager.Instance.Unlocks;
			Dictionary<SelectableLevel, object> dictionary = new Dictionary<SelectableLevel, object>();
			foreach (LMUnlockable item in unlocks)
			{
				SelectableLevel selectableLevel = item.ExtendedLevel.SelectableLevel;
				if ((Object)(object)selectableLevel != (Object)null)
				{
					dictionary[selectableLevel] = item;
				}
			}
			MoonUnlockables = dictionary;
		}
	}
	public class LunarConfigCompatibility : CompatibilityHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Event <0>__ProcessNewOrder;
		}

		private static Dictionary<object, int> rawIndex = new Dictionary<object, int>();

		private static Dictionary<SelectableLevel, int> newIndex = new Dictionary<SelectableLevel, int>();

		public LunarConfigCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public override void Init()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			Plugin.logger.LogDebug((object)"Initializing LunarConfig compatibility...");
			Plugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(LunarCentral), "InitMoons", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LunarConfigCompatibility), "LunarConfig_GetOrderingAlgorithm", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null);
			CustomEvent contentManagerReady = EventManager.ContentManagerReady;
			object obj = <>O.<0>__ProcessNewOrder;
			if (obj == null)
			{
				Event val = ProcessNewOrder;
				<>O.<0>__ProcessNewOrder = val;
				obj = (object)val;
			}
			contentManagerReady.AddListener((Event)obj);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static IEnumerable<CodeInstruction> LunarConfig_GetOrderingAlgorithm(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			ConstructorInfo lunarCustomOrderCtor = AccessTools.Constructor(typeof(LunarConfigCustomMoonOrder), new Type[1] { typeof(Dictionary<DawnMoonInfo, int>) }, false);
			MethodInfo methodInfo = AccessTools.Method(typeof(LunarConfigCompatibility), "PassNewCatalogueIndex", (Type[])null, (Type[])null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ci.opcode == OpCodes.Newobj && object.Equals(ci.operand, lunarCustomOrderCtor)), (string)null)
			});
			if (val.IsValid)
			{
				((Logger)Plugin.debugLogger).LogDebug("Found the target instruction for LunarConfig_GetOrderingAlgorithm transpiler.");
				val.Insert((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)methodInfo)
				});
			}
			else
			{
				((Logger)Plugin.debugLogger).LogDebug("Failed to find the target instruction for LunarConfig_GetOrderingAlgorithm transpiler.");
			}
			return val.InstructionEnumeration();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static Dictionary<DawnMoonInfo, int> PassNewCatalogueIndex(Dictionary<DawnMoonInfo, int> newCatalogueIndex)
		{
			if (newCatalogueIndex == null)
			{
				return null;
			}
			newIndex.Clear();
			rawIndex.Clear();
			foreach (KeyValuePair<DawnMoonInfo, int> item in newCatalogueIndex)
			{
				rawIndex[item.Key] = item.Value;
			}
			return newCatalogueIndex;
		}

		private static void ProcessNewOrder()
		{
			if (rawIndex == null || rawIndex.Count == 0)
			{
				return;
			}
			List<SelectableLevel> levels = LevelHelper.Levels;
			foreach (SelectableLevel item in levels)
			{
				if (!((Object)(object)item == (Object)null))
				{
					DawnMoonInfo dawnInfo;
					try
					{
						dawnInfo = SelectableLevelExtensions.GetDawnInfo(item);
					}
					catch
					{
						continue;
					}
					if (dawnInfo != null)
					{
						newIndex[item] = (rawIndex.TryGetValue(dawnInfo, out var value) ? value : 0);
					}
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public int GetMoonIndex(SelectableLevel moon)
		{
			if (newIndex == null || !((Object)(object)moon != (Object)null) || !newIndex.TryGetValue(moon, out var value))
			{
				return 0;
			}
			return value;
		}
	}
	internal class StoreRotationConfigCompatibility : CompatibilityHandler
	{
		public StoreRotationConfigCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public override void Init()
		{
			if (((CompatibilityHandler)this).IsModPresent)
			{
				UnpatchTerminalScroll();
			}
		}

		public static int GetDiscountedPrice(BuyableThing buyable, out int discount)
		{
			return RotationSalesAPI.GetDiscountedPrice(buyable.Nodes.Node, ref discount);
		}

		public static void UnpatchTerminalScroll()
		{
			Plugin.harmony.Unpatch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "ScrollMouse_performed", (Type[])null, (Type[])null), (HarmonyPatchType)3, "pacoito.StoreRotationConfig");
		}
	}
	internal class WeatherRegistryCompatibility : CompatibilityHandler
	{
		public WeatherRegistryCompatibility(string guid, string version = null)
			: base(guid, version, false)
		{
		}

		public string GetWeather(SelectableLevel level)
		{
			return WeatherManager.GetCurrentWeatherName(level, false);
		}
	}
}
namespace TerminalUtils.Commands
{
	public class FilterCommand : TerminalCommandNode
	{
		public FilterCommand()
			: base("filter")
		{
			base.RedirectToNode = TerminalManager.MoonsPage;
		}

		public override string Execute(string[] args)
		{
			string filterTypeName = "none";
			Dictionary<string, FilterInfoType<SelectableLevel>> infoTypes = TerminalManager.FilterInfoTypes.Select((KeyValuePair<string, FilterInfoType<SelectableLevel>> kv) => kv.Value).ToDictionary((FilterInfoType<SelectableLevel> infoType) => infoType.Name.ToLowerInvariant(), (FilterInfoType<SelectableLevel> infoType) => infoType);
			((Logger)Plugin.debugLogger).LogDebug("Possible filter types: " + string.Join(", ", infoTypes.Keys));
			args.ToList().ForEach(delegate(string arg)
			{
				if (infoTypes.ContainsKey(arg))
				{
					filterTypeName = arg;
				}
			});
			TerminalManager.CurrentFilterInfoType = infoTypes[filterTypeName];
			ConfigManager.FilterInfoType.Value = infoTypes[filterTypeName].Name;
			return "";
		}
	}
	public class PreviewCommand : TerminalCommandNode
	{
		public PreviewCommand()
			: base("preview")
		{
			base.RedirectToNode = TerminalManager.MoonsPage;
		}

		public override string Execute(string[] args)
		{
			List<string> previewTypeNames = new List<string>(1) { "name" };
			Dictionary<string, PreviewInfoType<SelectableLevel>> infoTypes = TerminalManager.PreviewInfoTypes.Select((KeyValuePair<string, PreviewInfoType<SelectableLevel>> kv) => kv.Value).ToDictionary((PreviewInfoType<SelectableLevel> infoType) => infoType.Name.ToLowerInvariant(), (PreviewInfoType<SelectableLevel> infoType) => infoType);
			((Logger)Plugin.debugLogger).LogDebug("Possible preview types: " + string.Join(", ", infoTypes.Keys));
			args.ToList().ForEach(delegate(string arg)
			{
				infoTypes.Keys.Select((string key) => key.ToLowerInvariant()).ToList().ForEach(delegate(string key)
				{
					if (key.ToLowerInvariant().StartsWith(arg.ToLowerInvariant()))
					{
						Plugin.logger.LogDebug((object)("Preview type '" + arg + "' matched '" + key + "'"));
						arg = key;
					}
				});
				if (infoTypes.ContainsKey(arg))
				{
					previewTypeNames.Add(arg);
				}
			});
			TerminalManager.CurrentPreviewInfoType = previewTypeNames.Select((string name) => infoTypes[name]).ToList();
			ConfigManager.PreviewInfoType.Value = string.Join(";", TerminalManager.CurrentPreviewInfoType.Select((PreviewInfoType<SelectableLevel> info) => info.Name));
			return "";
		}
	}
	public class SimulateCommand : TerminalCommandNode
	{
		private static Dictionary<string, int> LLLResult = new Dictionary<string, int>();

		private static Dictionary<string, int> DawnResult = new Dictionary<string, int>();

		public SimulateCommand()
			: base("simulate")
		{
		}

		public override string Execute(string[] args)
		{
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			SelectableLevel val = StringResolver.ResolveStringToLevels(args[0]).FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				return "Level \"" + args[0] + "\" not found!";
			}
			Plugin.logger.LogInfo((object)("Simulating level: " + val.PlanetName));
			if (LevelHelper.CompanyMoons.Contains(val) || !val.spawnEnemiesAndScrap)
			{
				return val.PlanetName + " cannot generate interior!";
			}
			Dictionary<string, int> source = new Dictionary<string, int>();
			if (((CompatibilityHandler)Plugin.DawnCompatibility).IsModPresent)
			{
				source = DawnLibCompatibility.GetDungeonRarities(val);
			}
			else if (((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent)
			{
				source = LethalLevelLoaderCompatibility.GetDungeonRarities(val);
			}
			if (((CompatibilityHandler)Plugin.DawnCompatibility).IsModPresent)
			{
				DawnResult = DawnLibCompatibility.GetDungeonRarities(val);
			}
			if (((CompatibilityHandler)Plugin.LLLCompatibility).IsModPresent)
			{
				LLLResult = LethalLevelLoaderCompatibility.GetDungeonRarities(val);
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("Simulating dungeons on moon: " + LevelHelper.GetAlphanumericName(val) + " \n\n");
			ConsoleTable val2 = new ConsoleTable(new string[3] { "Interior", "Weight", "Chance" });
			val2.AddRow(new object[3] { "", "", "" });
			Dictionary<string, int> dictionary = source.OrderBy((KeyValuePair<string, int> o) => -o.Value).ToDictionary((KeyValuePair<string, int> k) => k.Key, (KeyValuePair<string, int> v) => v.Value);
			int num = dictionary.Values.Sum();
			((Logger)Plugin.debugLogger).LogDebug(string.Format("Total rarity pool for level {0}: {1}. Flows with rarity: {2}", val.PlanetName, num, string.Join("; ", dictionary.Select((KeyValuePair<string, int> kv) => $"{kv.Key} (rarity: {kv.Value})"))));
			foreach (var (text2, num3) in dictionary)
			{
				val2.AddRow(new object[3]
				{
					text2.PadRight(20),
					num3,
					(((float)num3 / (float)num * 100f).ToString("F2") + "%").PadLeft(4)
				});
			}
			val2.AddRow(new object[3] { "", "", "" });
			val2.AddRow(new object[3] { "", "", "" });
			val2.AddRow(new object[3]
			{
				"",
				num.ToString().PadRight(6),
				"100%".ToString().PadLeft(4)
			});
			stringBuilder.AppendLine(val2.ToStringCustomDecoration(true, false, false));
			return stringBuilder.ToString();
		}
	}
	public class SortCommand : TerminalCommandNode
	{
		public SortCommand()
			: base("sort")
		{
			base.RedirectToNode = TerminalManager.MoonsPage;
		}

		public override string Execute(string[] args)
		{
			string sortTypeName = "none";
			Dictionary<string, SortInfoType<SelectableLevel>> infoTypes = TerminalManager.SortInfoTypes.Select((KeyValuePair<string, SortInfoType<SelectableLevel>> kv) => kv.Value).ToDictionary((SortInfoType<SelectableLevel> infoType) => infoType.Name.ToLowerInvariant(), (SortInfoType<SelectableLevel> infoType) => infoType);
			((Logger)Plugin.debugLogger).LogDebug("Possible sort types: " + string.Join(", ", infoTypes.Keys));
			args.ToList().ForEach(delegate(string arg)
			{
				if (infoTypes.ContainsKey(arg))
				{
					sortTypeName = arg;
				}
			});
			TerminalManager.CurrentSortInfoType = infoTypes[sortTypeName];
			ConfigManager.SortInfoType.Value = infoTypes[sortTypeName].Name;
			return "";
		}
	}
	public class StoreSortCommand : TerminalCommandNode
	{
		public StoreSortCommand()
			: base("store")
		{
			base.RedirectToNode = TerminalManager.StorePage;
		}

		public override string Execute(string[] args)
		{
			string sortTypeName = "name";
			Dictionary<string, SortInfoType<BuyableThing>> infoTypes = TerminalManager.StoreSortInfoTypes.Select((KeyValuePair<string, SortInfoType<BuyableThing>> kv) => kv.Value).ToDictionary((SortInfoType<BuyableThing> infoType) => infoType.Name.ToLowerInvariant(), (SortInfoType<BuyableThing> infoType) => infoType);
			((Logger)Plugin.debugLogger).LogDebug("Possible store sort types: " + string.Join(", ", infoTypes.Keys));
			args.ToList().ForEach(delegate(string arg)
			{
				if (infoTypes.ContainsKey(arg))
				{
					sortTypeName = arg;
				}
			});
			TerminalManager.CurrentStoreSortInfoType = infoTypes[sortTypeName];
			ConfigManager.StoreSortInfoType.Value = infoTypes[sortTypeName].Name;
			return "";
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}