Decompiled source of Stoker v0.0.2

plugins/Stoker.Plugin.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using SimpleInjector;
using Stoker.Base;
using Stoker.Base.Commands;
using Stoker.Base.Impl;
using Stoker.Base.Interfaces;
using Stoker.Plugin.Console;
using TrainworksReloaded.Core;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Stoker.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.2.0")]
[assembly: AssemblyInformationalVersion("0.0.2+53a1e5af4f5f61e8f6bb0f8f45d17a946caa46fa")]
[assembly: AssemblyProduct("Stoker.Plugin")]
[assembly: AssemblyTitle("Stoker.Plugin")]
[assembly: AssemblyVersion("0.0.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Stoker.Plugin
{
	[BepInPlugin("Stoker.Plugin", "Stoker.Plugin", "0.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger = new ManualLogSource("Stoker.Plugin");

		public void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin Stoker.Plugin is loaded!");
			RootCommandExecutor rootCommandExecutor = new RootCommandExecutor();
			rootCommandExecutor.TryAddCommand(HelpCommandFactory.Create(rootCommandExecutor));
			rootCommandExecutor.TryAddCommand(CardCommandFactory.Create());
			rootCommandExecutor.TryAddCommand(EchoCommandFactory.Create());
			rootCommandExecutor.TryAddCommand(GoldCommandFactory.Create());
			rootCommandExecutor.TryAddCommand(RelicCommandFactory.Create());
			rootCommandExecutor.TryAddCommand(HandCommandFactory.Create());
			rootCommandExecutor.TryAddCommand(PyreCommandFactory.Create());
			Railend.ConfigurePreAction((Action<Container>)delegate(Container c)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				c.RegisterInstance<RootCommandExecutor>(rootCommandExecutor);
				c.RegisterInstance<ConsoleLogger>(new ConsoleLogger(Logger));
			});
			if (((BaseUnityPlugin)this).Config.Bind<bool>("Console", "Enabled", true, "Enable the console").Value)
			{
				CreateConsole(rootCommandExecutor);
			}
		}

		private void CreateConsole(RootCommandExecutor rootCommandExecutor)
		{
			//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)
			//IL_001b: Expected O, but got Unknown
			GameObject val = new GameObject("StokerConsole");
			val.AddComponent<StokerConsole>().CommandExecutor = (ICommandExecutor?)(object)rootCommandExecutor;
			Object.DontDestroyOnLoad((Object)val);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Stoker.Plugin";

		public const string PLUGIN_NAME = "Stoker.Plugin";

		public const string PLUGIN_VERSION = "0.0.2";
	}
}
namespace Stoker.Plugin.Console
{
	public class LogListener : ILogListener, IDisposable
	{
		private readonly StokerConsole console;

		public LogListener(StokerConsole console)
		{
			this.console = console;
		}

		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			StokerConsole stokerConsole = console;
			string message = $"{eventArgs.Data}";
			LogLevel level = eventArgs.Level;
			LogType logType = (((int)level == 2) ? LogType.Error : (((int)level == 4) ? LogType.Warning : (((int)level != 16) ? LogType.Info : LogType.Info)));
			stokerConsole.AddLog(message, logType);
		}

		public void Dispose()
		{
		}
	}
	public enum LogType
	{
		Info,
		Warning,
		Error
	}
	public class StokerConsole : MonoBehaviour
	{
		private bool isVisible;

		private string inputText = "";

		private Vector2 scrollPosition;

		private readonly List<(string, LogType)> logHistory = new List<(string, LogType)>();

		private readonly List<string> commandHistory = new List<string>();

		private int historyIndex = -1;

		private const int MAX_LOG_LINES = 1000;

		private const float CONSOLE_HEIGHT = 0.5f;

		private const float CONSOLE_WIDTH = 0.98f;

		private readonly StringBuilder currentLine = new StringBuilder();

		private int completionIndex;

		private List<string> completions = new List<string>();

		private string tabCompletionText = "";

		private string lastInputText = "";

		private Rect consoleRect;

		private Rect logRect;

		private Rect inputRect;

		private Rect scrollViewRect;

		private Rect tabCompletionRect;

		private float width;

		private Vector2 lastScreenSize;

		public ICommandExecutor? CommandExecutor { get; set; }

		private void Awake()
		{
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			StartReadingOutput();
			UpdateRects();
		}

		private void UpdateRects()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Screen.height * 0.5f;
			width = (float)Screen.width * 0.98f;
			float num2 = ((float)Screen.width - width) / 2f;
			float num3 = (float)Screen.height * 0.01f;
			consoleRect = new Rect(num2, num3, width, num);
			logRect = new Rect(5f + ((Rect)(ref consoleRect)).x, 5f + ((Rect)(ref consoleRect)).y, ((Rect)(ref consoleRect)).width - 10f, ((Rect)(ref consoleRect)).height - 30f);
			inputRect = new Rect(5f + ((Rect)(ref consoleRect)).x, ((Rect)(ref consoleRect)).height - 25f + ((Rect)(ref consoleRect)).y, ((Rect)(ref consoleRect)).width - 10f, 20f);
			tabCompletionRect = new Rect(8f + ((Rect)(ref consoleRect)).x, ((Rect)(ref inputRect)).y, ((Rect)(ref inputRect)).width, ((Rect)(ref inputRect)).height);
		}

		private void OnDestroy()
		{
		}

		private void StartReadingOutput()
		{
			LogListener item = new LogListener(this);
			Logger.Listeners.Add((ILogListener)(object)item);
		}

		private void Update()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)96))
			{
				isVisible = !isVisible;
			}
			if ((float)Screen.width != lastScreenSize.x || (float)Screen.height != lastScreenSize.y)
			{
				UpdateRects();
				lastScreenSize = new Vector2((float)Screen.width, (float)Screen.height);
			}
		}

		private void OnGUI()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected I4, but got Unknown
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			if (!isVisible)
			{
				return;
			}
			Event current = Event.current;
			if ((int)current.type == 4 && GUI.GetNameOfFocusedControl() == "ConsoleInput")
			{
				KeyCode keyCode = current.keyCode;
				if ((int)keyCode != 9)
				{
					if ((int)keyCode != 13)
					{
						switch (keyCode - 273)
						{
						case 0:
							NavigateHistory(1);
							break;
						case 1:
							NavigateHistory(-1);
							break;
						case 2:
							if (current.shift && !string.IsNullOrEmpty(tabCompletionText))
							{
								inputText = tabCompletionText;
								current.Use();
							}
							break;
						}
					}
					else if (!string.IsNullOrWhiteSpace(inputText))
					{
						commandHistory.Add(inputText);
						historyIndex = -1;
						ProcessCommand(inputText);
						inputText = "";
						tabCompletionText = "";
						completions.Clear();
					}
				}
				else if (completions.Count > 0)
				{
					if (current.shift)
					{
						completionIndex--;
						if (completionIndex < 0)
						{
							completionIndex = completions.Count - 1;
						}
					}
					else
					{
						completionIndex++;
						if (completionIndex >= completions.Count)
						{
							completionIndex = 0;
						}
					}
					int num = inputText.LastIndexOf(" ");
					string text = ((num > -1) ? inputText.Substring(0, num + 1) : (inputText + " "));
					tabCompletionText = text + completions[completionIndex];
					current.Use();
				}
			}
			GUI.SetNextControlName("ConsoleBackground");
			GUI.Box(consoleRect, "");
			GUI.SetNextControlName("ConsoleLogArea");
			GUI.Box(logRect, "");
			GUI.SetNextControlName("ConsoleScrollView");
			scrollViewRect = new Rect(0f, 0f, width - 25f, (float)(logHistory.Count * 20));
			scrollPosition = GUI.BeginScrollView(logRect, scrollPosition, scrollViewRect);
			for (int i = 0; i < logHistory.Count; i++)
			{
				(string, LogType) tuple = logHistory[i];
				string item = tuple.Item1;
				GUI.color = (Color)(tuple.Item2 switch
				{
					LogType.Info => Color.white, 
					LogType.Warning => Color.yellow, 
					LogType.Error => Color.red, 
					_ => Color.white, 
				});
				GUI.Label(new Rect(5f, (float)(i * 20), ((Rect)(ref logRect)).width - 10f, 20f), item);
			}
			GUI.color = Color.white;
			GUI.EndScrollView();
			if (!string.IsNullOrEmpty(tabCompletionText))
			{
				GUI.SetNextControlName("ConsoleTabCompletion");
				GUI.color = new Color(1f, 0.8f, 0.8f, 0.8f);
				GUI.Label(tabCompletionRect, tabCompletionText);
				GUI.color = Color.white;
			}
			GUI.SetNextControlName("ConsoleInput");
			string text2 = GUI.TextField(inputRect, inputText);
			if (!(text2 != lastInputText))
			{
				return;
			}
			inputText = text2;
			lastInputText = text2;
			if (!string.IsNullOrEmpty(inputText))
			{
				ICommandExecutor? commandExecutor = CommandExecutor;
				string[] source = ((commandExecutor != null) ? commandExecutor.GetCompletions(inputText) : null) ?? Array.Empty<string>();
				completions = source.ToList();
				completionIndex = 0;
				if (completions.Count <= 0)
				{
					return;
				}
				int num2 = inputText.LastIndexOf(" ");
				string text3 = ((num2 > -1) ? inputText.Substring(0, num2 + 1) : (inputText + " "));
				bool flag = false;
				foreach (string completion in completions)
				{
					if (completion.StartsWith(text3))
					{
						tabCompletionText = completion;
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					tabCompletionText = text3 + completions[0];
				}
			}
			else
			{
				tabCompletionText = "";
				completions.Clear();
			}
		}

		private void NavigateHistory(int direction)
		{
			if (commandHistory.Count != 0)
			{
				historyIndex = Mathf.Clamp(historyIndex + direction, -1, commandHistory.Count - 1);
				inputText = ((historyIndex == -1) ? "" : commandHistory[commandHistory.Count - 1 - historyIndex]);
			}
		}

		private void ProcessCommand(string command)
		{
			ICommandExecutor? commandExecutor = CommandExecutor;
			if (commandExecutor != null)
			{
				commandExecutor.ExecuteAsync(command);
			}
		}

		public void AddLog(string message, LogType logType)
		{
			string[] array = message.Split(new string[2] { "\n", "\r\n" }, StringSplitOptions.None);
			foreach (string item in array)
			{
				logHistory.Add((item, logType));
			}
			if (logHistory.Count > 1000)
			{
				logHistory.RemoveRange(0, logHistory.Count - 1000);
			}
			scrollPosition.y = float.MaxValue;
		}
	}
}

plugins/Stoker.Base.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ShinyShoe.Loading;
using ShinyShoe.Logging;
using Stoker.Base.Builder;
using Stoker.Base.Data;
using Stoker.Base.Extension;
using Stoker.Base.Impl;
using Stoker.Base.Interfaces;
using TrainworksReloaded.Core;
using TrainworksReloaded.Core.Enum;
using TrainworksReloaded.Core.Interfaces;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Stoker.Base")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.2.0")]
[assembly: AssemblyInformationalVersion("0.0.2+53a1e5af4f5f61e8f6bb0f8f45d17a946caa46fa")]
[assembly: AssemblyProduct("Stoker.Base")]
[assembly: AssemblyTitle("Stoker.Base")]
[assembly: AssemblyVersion("0.0.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Stoker.Base
{
	public class ConsoleLogger : ILogProvider
	{
		private readonly ManualLogSource logger;

		public ConsoleLogger(ManualLogSource logger)
		{
			this.logger = logger;
			base..ctor();
		}

		public void CloseLog()
		{
		}

		public void Debug(string log, LogOptions options)
		{
			logger.LogDebug((object)log);
		}

		public void Debug(string log)
		{
			logger.LogDebug((object)log);
		}

		public void Error(string log, LogOptions options)
		{
			logger.LogError((object)log);
		}

		public void Error(string log)
		{
			logger.LogError((object)log);
		}

		public void Info(string log, LogOptions options)
		{
			logger.LogInfo((object)log);
		}

		public void Info(string log)
		{
			logger.LogInfo((object)log);
		}

		public void Log(string message)
		{
			logger.LogInfo((object)message);
		}

		public void Verbose(string log, LogOptions options)
		{
			logger.LogDebug((object)log);
		}

		public void Verbose(string log)
		{
			logger.LogDebug((object)log);
		}

		public void Warning(string log, LogOptions options)
		{
			logger.LogWarning((object)log);
		}

		public void Warning(string log)
		{
			logger.LogWarning((object)log);
		}
	}
}
namespace Stoker.Base.Interfaces
{
	public interface IArgument
	{
		string Name { get; }

		string Description { get; }

		string DefaultValue { get; }

		IEnumerable<string> Suggestions { get; }

		Type Type { get; }

		object? Parse(string value);
	}
	public interface IArgument<T> : IArgument
	{
		new T? Parse(string value);
	}
	public interface ICommand
	{
		string Name { get; }

		string Description { get; }

		IEnumerable<IArgument> Arguments { get; }

		IEnumerable<ICommandOption> Options { get; }

		IEnumerable<ICommand> SubCommands { get; }

		Func<HandlerArgs, Task>? Handler { get; }

		void AddArgument(IArgument argument);

		void AddOption(ICommandOption option);

		void AddSubCommand(ICommand subCommand);

		void SetHandler(Func<HandlerArgs, Task> handler);

		Task ExecuteAsync(string[] args);

		Task ExecuteAsync(HandlerArgs args);

		string[] GetCompletions(string[] args);
	}
	public interface ICommandExecutor
	{
		Task ExecuteAsync(string fullCommand);

		Task ExecuteAsync(string commandName, string[] args);

		bool ContainsCommand(string commandName);

		bool TryAddCommand(ICommand command);

		string[] GetCompletions(string fullCommand);

		string[] GetCompletions(string commandName, string[] args);
	}
	public interface ICommandOption
	{
		string Name { get; }

		string Description { get; }

		bool IsRequired { get; }

		string DefaultValue { get; }

		IEnumerable<string> Suggestions { get; }

		IEnumerable<string> Aliases { get; }

		Type Type { get; }

		object? Parse(string value);
	}
	public interface ICommandOption<T> : ICommandOption
	{
		new T? Parse(string value);
	}
}
namespace Stoker.Base.Impl
{
	public class Argument<T> : IArgument<T>, IArgument
	{
		public string Name { get; set; } = "";


		public string Description { get; set; } = "";


		public string DefaultValue { get; set; } = "";


		public Func<string, T?>? Parser { get; set; }

		public Func<IEnumerable<string>>? SuggestionsProvider { get; set; }

		public IEnumerable<string> Suggestions => SuggestionsProvider?.Invoke() ?? Array.Empty<string>();

		public Type Type => typeof(T);

		public T? Parse(string value)
		{
			if (Parser == null)
			{
				return default(T);
			}
			return Parser(value);
		}

		object? IArgument.Parse(string value)
		{
			return Parse(value);
		}
	}
	public class Command : ICommand
	{
		public string Name { get; set; } = "";


		public string Description { get; set; } = "";


		public List<IArgument> Arguments { get; set; } = new List<IArgument>();


		public List<ICommandOption> Options { get; set; } = new List<ICommandOption>();


		public List<ICommand> SubCommands { get; set; } = new List<ICommand>();


		public Func<HandlerArgs, Task>? Handler { get; set; }

		IEnumerable<IArgument> ICommand.Arguments => Arguments;

		IEnumerable<ICommandOption> ICommand.Options => Options;

		IEnumerable<ICommand> ICommand.SubCommands => SubCommands;

		public void AddArgument(IArgument argument)
		{
			Arguments.Add(argument);
		}

		public void AddOption(ICommandOption option)
		{
			Options.Add(option);
		}

		public void AddSubCommand(ICommand subCommand)
		{
			SubCommands.Add(subCommand);
		}

		private HandlerArgs ParseArgs(string[] args)
		{
			HandlerArgs handlerArgs = new HandlerArgs();
			int num = 0;
			HashSet<string> processedOptions = new HashSet<string>();
			foreach (ICommandOption option in Options)
			{
				if (!string.IsNullOrEmpty(option.DefaultValue))
				{
					handlerArgs.Options.Add(option.Name, option.Parse(option.DefaultValue));
				}
			}
			foreach (IArgument argument2 in Arguments)
			{
				if (!string.IsNullOrEmpty(argument2.DefaultValue))
				{
					handlerArgs.Arguments.Add(argument2.Name, argument2.Parse(argument2.DefaultValue));
				}
			}
			for (int i = 0; i < args.Length; i++)
			{
				string currentArg = args[i];
				if (currentArg.StartsWith("--") || currentArg.StartsWith("-"))
				{
					string optionName = currentArg.TrimStart('-');
					ICommandOption commandOption = Options.FirstOrDefault((ICommandOption o) => o.Name.Equals(optionName, StringComparison.OrdinalIgnoreCase)) ?? throw new Exception("Unknown option: " + optionName);
					object obj = null;
					if (i + 1 < args.Length && !args[i + 1].StartsWith("-"))
					{
						string value = args[++i];
						obj = commandOption.Parse(value);
					}
					else
					{
						obj = commandOption.Parse(commandOption.DefaultValue);
					}
					if (handlerArgs.Options.ContainsKey(optionName))
					{
						handlerArgs.Options[optionName] = obj;
					}
					else
					{
						handlerArgs.Options.Add(optionName, obj);
					}
					processedOptions.Add(optionName);
					continue;
				}
				if (SubCommands.FirstOrDefault((ICommand sc) => sc.Name.Equals(currentArg, StringComparison.OrdinalIgnoreCase)) != null)
				{
					handlerArgs.SubCommand = currentArg;
					handlerArgs.UnparsedArgs = args.Skip(i + 1).ToArray();
					break;
				}
				if (num < Arguments.Count)
				{
					IArgument argument = Arguments[num];
					if (handlerArgs.Arguments.ContainsKey(argument.Name))
					{
						handlerArgs.Arguments[argument.Name] = argument.Parse(currentArg);
					}
					else
					{
						handlerArgs.Arguments.Add(argument.Name, argument.Parse(currentArg));
					}
					num++;
					continue;
				}
				throw new Exception("One too many arguments: " + currentArg);
			}
			List<string> list = (from o in Options
				where o.IsRequired && !processedOptions.Contains(o.Name)
				select o.Name).ToList();
			if (list.Any())
			{
				throw new Exception("Missing required options: " + string.Join(", ", list));
			}
			return handlerArgs;
		}

		public Task ExecuteAsync(string[] args)
		{
			HandlerArgs args2 = ParseArgs(args);
			return ExecuteAsyncInternal(args2);
		}

		public Task ExecuteAsync(HandlerArgs args)
		{
			HandlerArgs args2 = ParseArgs(args.UnparsedArgs);
			return ExecuteAsyncInternal(args2);
		}

		private Task ExecuteAsyncInternal(HandlerArgs args)
		{
			HandlerArgs args2 = args;
			if (args2.SubCommand != null)
			{
				ICommand command = SubCommands.FirstOrDefault((ICommand sc) => sc.Name.Equals(args2.SubCommand, StringComparison.OrdinalIgnoreCase));
				if (command != null)
				{
					return command.ExecuteAsync(args2);
				}
			}
			if (Handler == null)
			{
				throw new Exception("No handler set for command");
			}
			return Handler(args2);
		}

		public void SetHandler(Func<HandlerArgs, Task> handler)
		{
			Handler = handler;
		}

		public string[] GetCompletions(string[] args)
		{
			string[] args2 = args;
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string lastArg = ((args2.Length != 0) ? args2[^1] : "");
			bool flag = lastArg.StartsWith("-");
			if (args2.Length == 0 && SubCommands.Count > 0)
			{
				hashSet.UnionWith(SubCommands.Select((ICommand sc) => sc.Name));
				return hashSet.ToArray();
			}
			ICommand command = SubCommands.FirstOrDefault((ICommand sc) => sc.Name.Equals(args2[0], StringComparison.OrdinalIgnoreCase));
			if (command != null)
			{
				return command.GetCompletions(args2.Skip(1).ToArray());
			}
			hashSet.UnionWith(from sc in SubCommands
				where sc.Name.StartsWith(args2[0], StringComparison.OrdinalIgnoreCase)
				select sc.Name);
			int num = 0;
			HashSet<string> usedOptions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			for (int i = 0; i < args2.Length; i++)
			{
				string text = args2[i];
				if (!text.StartsWith("-"))
				{
					continue;
				}
				string name = text.TrimStart('-');
				ICommandOption commandOption = Options.FirstOrDefault((ICommandOption o) => o.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
				usedOptions.Add(name);
				if (commandOption == null)
				{
					continue;
				}
				if (commandOption.Type == typeof(bool))
				{
					num++;
					continue;
				}
				num++;
				if (i + 1 < args2.Length && !args2[i + 1].StartsWith("-"))
				{
					num++;
					i++;
				}
			}
			int num2 = args2.Length - num;
			if (!flag && num2 < Arguments.Count)
			{
				IArgument argument = Arguments[num2];
				hashSet.UnionWith(argument.Suggestions);
			}
			int num3 = num2 - 1;
			if (!flag && num3 >= 0 && num3 < Arguments.Count)
			{
				IArgument argument2 = Arguments[num3];
				hashSet.UnionWith(argument2.Suggestions.Where((string s) => s != lastArg && s.StartsWith(lastArg, StringComparison.OrdinalIgnoreCase)));
			}
			if (flag)
			{
				if (lastArg.StartsWith("-"))
				{
					string optionName2 = args2[^1].TrimStart('-');
					ICommandOption commandOption2 = Options.FirstOrDefault((ICommandOption o) => o.Name.Equals(optionName2, StringComparison.OrdinalIgnoreCase));
					if (commandOption2 != null)
					{
						hashSet.UnionWith(commandOption2.Suggestions);
					}
					else
					{
						hashSet.UnionWith(from o in Options
							where !usedOptions.Contains(o.Name)
							select "--" + o.Name into c
							where c.StartsWith(lastArg, StringComparison.OrdinalIgnoreCase)
							select c);
					}
				}
				else if (args2.Length >= 2 && args2[^2].StartsWith("--"))
				{
					string optionName = args2[^2].TrimStart('-');
					ICommandOption commandOption3 = Options.FirstOrDefault((ICommandOption o) => o.Name.Equals(optionName, StringComparison.OrdinalIgnoreCase));
					if (commandOption3 != null)
					{
						hashSet.UnionWith(commandOption3.Suggestions);
					}
				}
			}
			if (num2 >= Arguments.Count)
			{
				hashSet.UnionWith(from o in Options
					where !usedOptions.Contains(o.Name)
					select "--" + o.Name);
			}
			if (hashSet.Count == 0 && !string.IsNullOrEmpty(lastArg))
			{
				hashSet.UnionWith(from sc in SubCommands
					where sc.Name.Contains(lastArg, StringComparison.OrdinalIgnoreCase)
					select sc.Name);
				hashSet.UnionWith(from o in Options
					where o.Name.Contains(lastArg, StringComparison.OrdinalIgnoreCase)
					select "--" + o.Name);
			}
			return hashSet.ToArray();
		}
	}
	public class CommandOption<T> : ICommandOption<T>, ICommandOption
	{
		public string Name { get; set; } = "";


		public string Description { get; set; } = "";


		public bool IsRequired { get; set; }

		public string DefaultValue { get; set; } = "";


		public IEnumerable<string> Aliases { get; set; } = Array.Empty<string>();


		public IEnumerable<string> Suggestions => SuggestionsProvider?.Invoke() ?? Array.Empty<string>();

		public Func<string, T?>? Parser { get; set; }

		public Func<IEnumerable<string>>? SuggestionsProvider { get; set; }

		public Type Type => typeof(T);

		public T? Parse(string value)
		{
			if (Parser == null)
			{
				return default(T);
			}
			return Parser(value);
		}

		object? ICommandOption.Parse(string value)
		{
			return Parse(value);
		}
	}
	public class OptionBuilder<T>
	{
		private readonly CommandOption<T> _option;

		public OptionBuilder(string name)
		{
			_option = new CommandOption<T>
			{
				Name = name
			};
		}

		public OptionBuilder<T> WithDescription(string description)
		{
			_option.Description = description;
			return this;
		}

		public OptionBuilder<T> WithDefaultValue(string defaultValue)
		{
			_option.DefaultValue = defaultValue;
			return this;
		}

		public OptionBuilder<T> WithAliases(params string[] aliases)
		{
			_option.Aliases = aliases;
			return this;
		}

		public OptionBuilder<T> WithParser(Func<string, T> parser)
		{
			_option.Parser = parser;
			return this;
		}

		public OptionBuilder<T> IsRequired()
		{
			_option.IsRequired = true;
			return this;
		}

		public ICommandOption Build()
		{
			return _option;
		}
	}
	public class RootCommandExecutor : ICommandExecutor
	{
		[CompilerGenerated]
		private sealed class <SplitArgs>d__12 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private string <>2__current;

			private int <>l__initialThreadId;

			private string commandLine;

			public string <>3__commandLine;

			private StringBuilder <result>5__2;

			private bool <quoted>5__3;

			private bool <escaped>5__4;

			private bool <allowcaret>5__5;

			private int <i>5__6;

			string IEnumerator<string>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SplitArgs>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<result>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				bool flag;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<result>5__2 = new StringBuilder();
					<quoted>5__3 = false;
					<escaped>5__4 = false;
					flag = false;
					<allowcaret>5__5 = false;
					<i>5__6 = 0;
					goto IL_01e2;
				case 1:
					<>1__state = -1;
					goto IL_01b3;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_01e2:
					if (<i>5__6 < commandLine.Length)
					{
						char c = commandLine[<i>5__6];
						if (c == '^' && !<quoted>5__3)
						{
							if (<allowcaret>5__5)
							{
								<result>5__2.Append(c);
								flag = true;
								<escaped>5__4 = false;
								<allowcaret>5__5 = false;
							}
							else if (<i>5__6 + 1 < commandLine.Length && commandLine[<i>5__6 + 1] == '^')
							{
								<allowcaret>5__5 = true;
							}
							else if (<i>5__6 + 1 == commandLine.Length)
							{
								<result>5__2.Append(c);
								flag = true;
								<escaped>5__4 = false;
							}
						}
						else if (<escaped>5__4)
						{
							<result>5__2.Append(c);
							flag = true;
							<escaped>5__4 = false;
						}
						else if (c == '"')
						{
							<quoted>5__3 = !<quoted>5__3;
							flag = true;
						}
						else if (c == '\\' && <i>5__6 + 1 < commandLine.Length && commandLine[<i>5__6 + 1] == '"')
						{
							<escaped>5__4 = true;
						}
						else
						{
							if (c == ' ' && !<quoted>5__3)
							{
								if (flag)
								{
									<>2__current = <result>5__2.ToString();
									<>1__state = 1;
									return true;
								}
								goto IL_01b3;
							}
							<result>5__2.Append(c);
							flag = true;
						}
						goto IL_01d2;
					}
					if (flag)
					{
						<>2__current = <result>5__2.ToString();
						<>1__state = 2;
						return true;
					}
					break;
					IL_01d2:
					<i>5__6++;
					goto IL_01e2;
					IL_01b3:
					<result>5__2.Clear();
					flag = false;
					goto IL_01d2;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<string> IEnumerable<string>.GetEnumerator()
			{
				<SplitArgs>d__12 <SplitArgs>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<SplitArgs>d__ = this;
				}
				else
				{
					<SplitArgs>d__ = new <SplitArgs>d__12(0);
				}
				<SplitArgs>d__.commandLine = <>3__commandLine;
				return <SplitArgs>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<string>)this).GetEnumerator();
			}
		}

		public List<ICommand> Commands { get; set; } = new List<ICommand>();


		private Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public bool TryAddCommand(ICommand command)
		{
			if (ContainsCommand(command.Name))
			{
				return false;
			}
			Commands.Add(command);
			return true;
		}

		public bool ContainsCommand(string commandName)
		{
			string commandName2 = commandName;
			return Commands.Any((ICommand c) => c.Name == commandName2);
		}

		public Task ExecuteAsync(string fullCommand)
		{
			string[] array = SplitArgs(fullCommand).ToArray();
			if (array.Length < 1)
			{
				return Task.CompletedTask;
			}
			string commandName = array[0];
			return ExecuteAsync(commandName, array.Skip(1).ToArray());
		}

		public Task ExecuteAsync(string commandName, string[] args)
		{
			string commandName2 = commandName;
			ICommand command = Commands.FirstOrDefault((ICommand c) => c.Name == commandName2);
			if (command == null)
			{
				LoggerLazy.Value.Error("Command '" + commandName2 + "' not found");
				return Task.CompletedTask;
			}
			LoggerLazy.Value.Log("> " + commandName2 + " " + string.Join(" ", args));
			try
			{
				return command.ExecuteAsync(args);
			}
			catch (Exception ex)
			{
				LoggerLazy.Value.Error(ex.Message);
				return Task.CompletedTask;
			}
		}

		[IteratorStateMachine(typeof(<SplitArgs>d__12))]
		private static IEnumerable<string> SplitArgs(string commandLine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SplitArgs>d__12(-2)
			{
				<>3__commandLine = commandLine
			};
		}

		public string[] GetCompletions(string commandName, string[] args)
		{
			string commandName2 = commandName;
			ICommand command = Commands.FirstOrDefault((ICommand c) => c.Name == commandName2);
			if (command == null)
			{
				return Array.Empty<string>();
			}
			return command.GetCompletions(args);
		}

		public string[] GetCompletions(string fullCommand)
		{
			string[] array = SplitArgs(fullCommand).ToArray();
			if (array.Length < 1)
			{
				return Array.Empty<string>();
			}
			string commandName = array[0];
			return GetCompletions(commandName, array.Skip(1).ToArray());
		}
	}
}
namespace Stoker.Base.Extension
{
	public static class BuilderExtensions
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static CommandBuilder AddHelpOptions(this CommandBuilder builder)
		{
			return builder.WithOption<bool>("help").WithDescription("Show help information").WithAliases("h")
				.WithDefaultValue("")
				.WithParser((string value) => value != null)
				.Parent();
		}

		public static CommandBuilder UseHelpMiddleware(this CommandBuilder builder)
		{
			CommandBuilder builder2 = builder;
			builder2.AddHelpOptions().UseHandlerMiddleware(delegate(Func<HandlerArgs, Task>? handler)
			{
				Func<HandlerArgs, Task> handler2 = handler;
				return (handler2 == null) ? ((Func<HandlerArgs, Task>)delegate(HandlerArgs args)
				{
					bool flag2 = default(bool);
					int num2;
					if (args.Options.ContainsKey("help"))
					{
						object obj2 = args.Options["help"];
						if (obj2 is bool)
						{
							flag2 = (bool)obj2;
							num2 = 1;
						}
						else
						{
							num2 = 0;
						}
					}
					else
					{
						num2 = 0;
					}
					if (((uint)num2 & (flag2 ? 1u : 0u)) != 0)
					{
						LoggerLazy.Value.Log(builder2.GetCommandHelpString());
					}
					return Task.CompletedTask;
				}) : ((Func<HandlerArgs, Task>)async delegate(HandlerArgs args)
				{
					bool flag = default(bool);
					int num;
					if (args.Options.ContainsKey("help"))
					{
						object obj = args.Options["help"];
						if (obj is bool)
						{
							flag = (bool)obj;
							num = 1;
						}
						else
						{
							num = 0;
						}
					}
					else
					{
						num = 0;
					}
					if (((uint)num & (flag ? 1u : 0u)) != 0)
					{
						LoggerLazy.Value.Log(builder2.GetCommandHelpString());
					}
					else
					{
						await handler2(args);
					}
				});
			});
			return builder2;
		}
	}
	public static class CommandExtension
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static void AddHelpOptions(this ICommand command)
		{
			ICommand command2 = command;
			CommandOption<bool> option = new CommandOption<bool>
			{
				Name = "help",
				Description = "Show help information",
				Aliases = new <>z__ReadOnlySingleElementList<string>("h"),
				DefaultValue = "",
				Parser = (string value) => value != null
			};
			command2.AddOption(option);
			if (command2.Handler == null)
			{
				command2.SetHandler(delegate(HandlerArgs args)
				{
					bool flag2 = default(bool);
					int num2;
					if (args.Options.ContainsKey("help"))
					{
						object obj2 = args.Options["help"];
						if (obj2 is bool)
						{
							flag2 = (bool)obj2;
							num2 = 1;
						}
						else
						{
							num2 = 0;
						}
					}
					else
					{
						num2 = 0;
					}
					if (((uint)num2 & (flag2 ? 1u : 0u)) != 0)
					{
						LoggerLazy.Value.Log(command2.GetCommandHelpString());
					}
					return Task.CompletedTask;
				});
				return;
			}
			command2.SetHandler(async delegate(HandlerArgs args)
			{
				bool flag = default(bool);
				int num;
				if (args.Options.ContainsKey("help"))
				{
					object obj = args.Options["help"];
					if (obj is bool)
					{
						flag = (bool)obj;
						num = 1;
					}
					else
					{
						num = 0;
					}
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) != 0)
				{
					LoggerLazy.Value.Log(command2.GetCommandHelpString());
				}
				else
				{
					await command2.ExecuteAsync(args);
				}
			});
		}

		public static string GetCommandUsage(this ICommand command)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(command.Name);
			if (command.Options.Count() < 3)
			{
				stringBuilder.Append(" [");
				bool flag = true;
				foreach (ICommandOption option in command.Options)
				{
					if (flag)
					{
						flag = false;
					}
					else
					{
						stringBuilder.Append(" ");
					}
					if (string.IsNullOrEmpty(option.DefaultValue))
					{
						stringBuilder.Append("--" + option.Name);
						continue;
					}
					stringBuilder.Append("--" + option.Name + "=<" + option.DefaultValue + ">");
				}
				stringBuilder.Append("]");
			}
			else if (command.Options.Count() != 0)
			{
				stringBuilder.Append(" [options]");
			}
			if (command.Arguments.Count() == 0 && command.Options.Count() == 0)
			{
				stringBuilder.Append(" ...");
			}
			foreach (IArgument argument in command.Arguments)
			{
				stringBuilder.Append(" <" + argument.Name + ">");
			}
			return stringBuilder.ToString();
		}

		public static string GetCommandHelpString(this ICommand command)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(command.Name + ".");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine(command.Description);
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Usage:");
			if (command.SubCommands.Any())
			{
				foreach (ICommand subCommand in command.SubCommands)
				{
					stringBuilder.AppendLine("  " + command.Name + " " + subCommand.GetCommandUsage());
				}
			}
			stringBuilder.AppendLine("  " + command.GetCommandUsage());
			if (command.Arguments.Any())
			{
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("Arguments:");
				foreach (IArgument argument in command.Arguments)
				{
					if (string.IsNullOrEmpty(argument.DefaultValue))
					{
						stringBuilder.AppendLine($"  {argument.Name,-30} {argument.Description}");
					}
					else
					{
						stringBuilder.AppendLine($"  {argument.Name,-30} {argument.Description}  [default: {argument.DefaultValue}]");
					}
				}
			}
			if (command.Options.Any())
			{
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("Options:");
				foreach (ICommandOption option in command.Options)
				{
					List<string> list = option.Aliases.Select((string a) => "-" + a).ToList();
					list.Add("--" + option.Name);
					string arg = string.Join(", ", list);
					if (string.IsNullOrEmpty(option.DefaultValue))
					{
						stringBuilder.AppendLine($"  {arg,-30} {option.Description}");
					}
					else
					{
						stringBuilder.AppendLine($"  {arg,-30} {option.Description}  [default: {option.DefaultValue}]");
					}
				}
			}
			return stringBuilder.ToString();
		}
	}
}
namespace Stoker.Base.Data
{
	public class HandlerArgs
	{
		public Dictionary<string, object?> Arguments { get; set; } = new Dictionary<string, object>();


		public Dictionary<string, object?> Options { get; set; } = new Dictionary<string, object>();


		public string[] UnparsedArgs { get; set; } = Array.Empty<string>();


		public string? SubCommand { get; set; }
	}
}
namespace Stoker.Base.Commands
{
	public class CardCommandFactory
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static ICommand Create()
		{
			return new CommandBuilder("card").WithDescription("Manage cards").WithSubCommand("add").WithDescription("Add a card to the deck")
				.WithArgument<string>("name")
				.WithDescription("The name of the card to add")
				.WithSuggestions(() => (from c in Railend.GetContainer().GetInstance<IRegister<CardData>>().GetAllIdentifiers((RegisterIdentifierType)0)
					select c.ToString()).ToArray())
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments3 = args.Arguments;
					if (!arguments3.ContainsKey("name"))
					{
						throw new Exception("Missing <name> argument");
					}
					if (!(arguments3["name"] is string text3))
					{
						throw new Exception("Invalid <name> argument");
					}
					if (string.IsNullOrEmpty(text3))
					{
						throw new Exception("Empty <name> argument");
					}
					LoggerLazy.Value.Log("Adding card: " + text3);
					CheatManager.Command_AddCard(text3);
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("add-random")
				.WithDescription("Add an amount of random cards to the deck")
				.WithArgument<int>("amount")
				.WithDescription("The amount of cards to add")
				.WithDefaultValue("1")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					//IL_016f: Unknown result type (might be due to invalid IL or missing references)
					//IL_017a: Expected O, but got Unknown
					Dictionary<string, object?> arguments2 = args.Arguments;
					if (!arguments2.ContainsKey("amount"))
					{
						throw new Exception("Missing <amount> argument");
					}
					if (!(arguments2["amount"] is int num3))
					{
						throw new Exception("Invalid <amount> argument");
					}
					LoggerLazy.Value.Log($"Adding {num3} random cards to the deck");
					IRegister<CardData> instance = Railend.GetContainer().GetInstance<IRegister<CardData>>();
					List<string> allIdentifiers2 = instance.GetAllIdentifiers((RegisterIdentifierType)0);
					Random random = new Random();
					SaveManager saveManager = default(SaveManager);
					ref SaveManager reference = ref saveManager;
					object? value = AccessTools.Field(typeof(CheatManager), "saveManager").GetValue(null);
					reference = (SaveManager)(((value is SaveManager) ? value : null) ?? throw new Exception("SaveManager not found"));
					int num4 = 0;
					int num5 = 0;
					CardData cardDataObj = default(CardData);
					bool? flag = default(bool?);
					while (num4 < num3 && num5 < 1000)
					{
						num5++;
						int index = random.Next(allIdentifiers2.Count);
						string text2 = allIdentifiers2[index];
						instance.TryLookupIdentifier(text2, (RegisterIdentifierType)0, ref cardDataObj, ref flag);
						if ((Object)(object)cardDataObj == (Object)null)
						{
							throw new Exception("CardData not found");
						}
						if (!cardDataObj.IsUnitAbility())
						{
							AccessTools.PropertySetter(typeof(CheatManager), "IsBusy").Invoke(null, new object[1] { true });
							LoadingScreen.AddTask((LoadingTask)new LoadAdditionalCards(cardDataObj, true, (DisplayStyle)1, (Action)delegate
							{
								CardState val = saveManager.AddCardToDeck(cardDataObj, (CardStateModifiers)null, true, 0, false, true, true, true);
								saveManager.DrawSpecificCard(val);
								AccessTools.PropertySetter(typeof(CheatManager), "IsBusy").Invoke(null, new object[1] { false });
								LoggerLazy.Value.Log("Adding <b>" + cardDataObj.Cheat_GetNameEnglish() + "</b> to hand.");
							}), true);
							num4++;
						}
					}
					if (num5 >= 1000)
					{
						throw new Exception("Failed to add all cards after random attempts.");
					}
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("remove")
				.WithDescription("Remove a card from the deck")
				.WithArgument<string>("name")
				.WithDescription("The name of the card to remove")
				.WithSuggestions(() => (from c in Railend.GetContainer().GetInstance<IRegister<CardData>>().GetAllIdentifiers((RegisterIdentifierType)0)
					select c.ToString()).ToArray())
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments = args.Arguments;
					if (!arguments.ContainsKey("name"))
					{
						throw new Exception("Missing <name> argument");
					}
					if (!(arguments["name"] is string text))
					{
						throw new Exception("Invalid <name> argument");
					}
					if (string.IsNullOrEmpty(text))
					{
						throw new Exception("Empty <name> argument");
					}
					LoggerLazy.Value.Log("Removing card: " + text);
					AccessTools.Method(typeof(CheatManager), "Command_RemoveCard", (Type[])null, (Type[])null).Invoke(null, new object[1] { text });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("list")
				.WithDescription("List all cards in the deck")
				.WithOption<int>("page")
				.WithDescription("The page number to list")
				.WithDefaultValue("1")
				.WithAliases("p")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.WithOption<int>("page-size")
				.WithDescription("The number of cards to list per page")
				.WithDefaultValue("10")
				.WithAliases("ps")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> options = args.Options;
					if (!options.ContainsKey("page"))
					{
						throw new Exception("Missing --page option");
					}
					if (!options.ContainsKey("page-size"))
					{
						throw new Exception("Missing --page-size option");
					}
					if (!(options["page"] is int num))
					{
						throw new Exception("Invalid --page option");
					}
					if (!(options["page-size"] is int num2))
					{
						throw new Exception("Invalid --page-size option");
					}
					List<string> allIdentifiers = Railend.GetContainer().GetInstance<IRegister<CardData>>().GetAllIdentifiers((RegisterIdentifierType)0);
					int count = (num - 1) * num2;
					IEnumerable<string> enumerable = allIdentifiers.Skip(count).Take(num2);
					LoggerLazy.Value.Log("Cards:");
					foreach (string item in enumerable)
					{
						LoggerLazy.Value.Log("  " + item);
					}
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.UseHelpMiddleware()
				.Build();
		}
	}
	public class EchoCommandFactory
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static ICommand Create()
		{
			return new CommandBuilder("echo").WithDescription("Echo a message").WithArgument<string>("message").WithDescription("The message to echo")
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					if (!args.Arguments.ContainsKey("message"))
					{
						throw new Exception("Missing <message> argument");
					}
					object obj = args.Arguments["message"];
					if (obj == null)
					{
						return Task.CompletedTask;
					}
					LoggerLazy.Value.Log(obj.ToString());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Build();
		}
	}
	public class GoldCommandFactory
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static ICommand Create()
		{
			return new CommandBuilder("gold").WithDescription("Manage gold").WithArgument<string>("amount").WithDescription("The amount of gold to add")
				.WithParser((string xs) => xs)
				.WithDefaultValue("100")
				.WithSuggestions(() => new string[3] { "100", "+100", "-100" }.ToArray())
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments = args.Arguments;
					if (!arguments.ContainsKey("amount"))
					{
						throw new Exception("Missing <amount> argument");
					}
					if (!(arguments["amount"] is string text))
					{
						throw new Exception("Invalid <amount> argument");
					}
					if (string.IsNullOrEmpty(text))
					{
						throw new Exception("Empty <amount> argument");
					}
					LoggerLazy.Value.Log("Adding " + text + " gold to the player");
					AccessTools.Method(typeof(CheatManager), "Command_AdjustGold", (Type[])null, (Type[])null).Invoke(null, new object[1] { text });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Build();
		}
	}
	public static class HandCommandFactory
	{
		public static ICommand Create()
		{
			return new CommandBuilder("hand").WithDescription("Manage the hand").WithSubCommand("draw").WithDescription("Draw cards")
				.WithArgument<int>("amount")
				.WithDescription("The amount of cards to draw")
				.WithSuggestions(() => new string[3] { "1", "2", "3" }.ToArray())
				.WithDefaultValue("1")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments2 = args.Arguments;
					if (!arguments2.ContainsKey("amount"))
					{
						throw new Exception("Missing <amount> argument");
					}
					if (!(arguments2["amount"] is int num2))
					{
						throw new Exception("Invalid <amount> argument");
					}
					if (num2 <= 0)
					{
						throw new Exception("Invalid <amount> argument. Must be greater than 0");
					}
					AccessTools.Method(typeof(CheatManager), "Command_DrawCards", (Type[])null, (Type[])null).Invoke(null, new object[1] { num2.ToString() });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("discard")
				.WithDescription("Discard a card")
				.WithArgument<int>("index")
				.WithDescription("The index of the card to discard")
				.WithSuggestions(() => new string[4] { "0", "1", "2", "3" }.ToArray())
				.WithDefaultValue("0")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments = args.Arguments;
					if (!arguments.ContainsKey("index"))
					{
						throw new Exception("Missing <index> argument");
					}
					if (!(arguments["index"] is int num))
					{
						throw new Exception("Invalid <index> argument");
					}
					AccessTools.Method(typeof(CheatManager), "Command_Discard", (Type[])null, (Type[])null).Invoke(null, new object[1] { num.ToString() });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("discard-all")
				.WithDescription("Discard all cards")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_DiscardAll", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.UseHelpMiddleware()
				.Build();
		}
	}
	public class HelpCommandFactory
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static ICommand Create(RootCommandExecutor rootCommand)
		{
			RootCommandExecutor rootCommand2 = rootCommand;
			return new CommandBuilder("help").WithDescription("Display help information").SetHandler(delegate
			{
				LoggerLazy.Value.Log("Available commands:");
				foreach (ICommand item in rootCommand2.Commands.OrderBy((ICommand c) => c.Name).ToList())
				{
					LoggerLazy.Value.Log($"  {item.Name,-12} - {item.Description}");
				}
				return Task.CompletedTask;
			}).UseHelpMiddleware()
				.Build();
		}
	}
	public static class PyreCommandFactory
	{
		public static ICommand Create()
		{
			return new CommandBuilder("pyre").WithDescription("Do things to the Pyre").WithSubCommand("health").WithDescription("Adjust the Pyre's health")
				.WithArgument<string>("amount")
				.WithDescription("The amount to adjust the Pyre's health")
				.WithSuggestions(() => new string[3] { "+50", "-50", "50" }.ToArray())
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments2 = args.Arguments;
					if (!arguments2.ContainsKey("health"))
					{
						throw new Exception("Missing <health> argument");
					}
					if (!(arguments2["health"] is string text2))
					{
						throw new Exception("Invalid <health> argument");
					}
					AccessTools.Method(typeof(CheatManager), "Command_AdjustTowerHP", (Type[])null, (Type[])null).Invoke(null, new object[1] { text2 });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("max-health")
				.WithDescription("Set the Pyre's max health")
				.WithArgument<string>("amount")
				.WithDescription("The amount to set the Pyre's max health")
				.WithSuggestions(() => new string[3] { "50", "100", "200" }.ToArray())
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments = args.Arguments;
					if (!arguments.ContainsKey("amount"))
					{
						throw new Exception("Missing <amount> argument");
					}
					if (!(arguments["amount"] is string text))
					{
						throw new Exception("Invalid <amount> argument");
					}
					AccessTools.Method(typeof(CheatManager), "Command_AdjustTowerMaxHP", (Type[])null, (Type[])null).Invoke(null, new object[1] { text });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.UseHelpMiddleware()
				.Build();
		}
	}
	public class RelicCommandFactory
	{
		private static Lazy<ConsoleLogger> LoggerLazy { get; set; } = new Lazy<ConsoleLogger>(() => Railend.GetContainer().GetInstance<ConsoleLogger>());


		public static ICommand Create()
		{
			return new CommandBuilder("relic").WithDescription("Manage relics").WithSubCommand("add").WithDescription("Add a relic to the deck")
				.WithArgument<string>("name")
				.WithDescription("The name of the relic to add")
				.WithSuggestions(() => (from c in Railend.GetContainer().GetInstance<IRegister<RelicData>>().GetAllIdentifiers((RegisterIdentifierType)0)
					select c.ToString()).ToArray())
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments2 = args.Arguments;
					if (!arguments2.ContainsKey("name"))
					{
						throw new Exception("Missing <name> argument");
					}
					if (!(arguments2["name"] is string text2))
					{
						throw new Exception("Invalid <name> argument");
					}
					if (string.IsNullOrEmpty(text2))
					{
						throw new Exception("Empty <name> argument");
					}
					LoggerLazy.Value.Log("Adding relic: " + text2);
					AccessTools.Method(typeof(CheatManager), "Command_AddArtifact", (Type[])null, (Type[])null).Invoke(null, new object[1] { text2 });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("remove")
				.WithDescription("Remove a relic from the deck")
				.WithArgument<string>("name")
				.WithDescription("The name of the relic to remove")
				.WithSuggestions(() => (from c in Railend.GetContainer().GetInstance<IRegister<RelicData>>().GetAllIdentifiers((RegisterIdentifierType)0)
					select c.ToString()).ToArray())
				.WithParser((string xs) => xs)
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> arguments = args.Arguments;
					if (!arguments.ContainsKey("name"))
					{
						throw new Exception("Missing <name> argument");
					}
					if (!(arguments["name"] is string text))
					{
						throw new Exception("Invalid <name> argument");
					}
					if (string.IsNullOrEmpty(text))
					{
						throw new Exception("Empty <name> argument");
					}
					LoggerLazy.Value.Log("Removing relic: " + text);
					AccessTools.Method(typeof(CheatManager), "Command_RemoveArtifact", (Type[])null, (Type[])null).Invoke(null, new object[1] { text });
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("list")
				.WithDescription("List all relics in the deck")
				.WithOption<int>("page")
				.WithDescription("The page number to list")
				.WithDefaultValue("1")
				.WithAliases("p")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.WithOption<int>("page-size")
				.WithDescription("The number of relics to list per page")
				.WithDefaultValue("10")
				.WithAliases("ps")
				.WithParser((string xs) => int.Parse(xs))
				.Parent()
				.SetHandler(delegate(HandlerArgs args)
				{
					Dictionary<string, object?> options = args.Options;
					if (!options.ContainsKey("page"))
					{
						throw new Exception("Missing --page option");
					}
					if (!options.ContainsKey("page-size"))
					{
						throw new Exception("Missing --page-size option");
					}
					if (!(options["page"] is int num))
					{
						throw new Exception("Invalid --page option");
					}
					if (!(options["page-size"] is int num2))
					{
						throw new Exception("Invalid --page-size option");
					}
					List<string> allIdentifiers = Railend.GetContainer().GetInstance<IRegister<RelicData>>().GetAllIdentifiers((RegisterIdentifierType)0);
					int count = (num - 1) * num2;
					IEnumerable<string> enumerable = allIdentifiers.Skip(count).Take(num2);
					LoggerLazy.Value.Log("Relics:");
					foreach (string item in enumerable)
					{
						LoggerLazy.Value.Log("  " + item);
					}
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.UseHelpMiddleware()
				.Build();
		}
	}
	public static class ToggleCommandFactory
	{
		public static ICommand Create()
		{
			return new CommandBuilder("toggle").WithDescription("Toggle a feature").WithSubCommand("god-pyre").WithDescription("Make the Pyre invincible")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_GodPyre", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("god-enemy")
				.WithDescription("Make enemies invincible")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_GodEnemies", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("god-monster")
				.WithDescription("Make monsters invincible")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_GodMonsters", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("god-ember")
				.WithDescription("Give Unlimited Ember")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_GodEmber", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("timing-display")
				.WithDescription("Toggle Timing Window")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_ToggleTimingDisplay", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.WithSubCommand("unit-display")
				.WithDescription("Toggle Unit Display")
				.SetHandler(delegate
				{
					AccessTools.Method(typeof(CheatManager), "Command_ToggleUnitInfoDisplay", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>());
					return Task.CompletedTask;
				})
				.UseHelpMiddleware()
				.Parent()
				.UseHelpMiddleware()
				.Build();
		}
	}
}
namespace Stoker.Base.Builder
{
	public class ArgumentBuilder<T>
	{
		private readonly CommandBuilder parentBuilder;

		private readonly Argument<T> _argument;

		public ArgumentBuilder(CommandBuilder parentBuilder, string name)
		{
			_argument = new Argument<T>
			{
				Name = name
			};
			this.parentBuilder = parentBuilder;
		}

		public ArgumentBuilder(CommandBuilder parentBuilder, Argument<T> argument)
		{
			_argument = argument;
			this.parentBuilder = parentBuilder;
		}

		public ArgumentBuilder<T> WithDescription(string description)
		{
			_argument.Description = description;
			return this;
		}

		public ArgumentBuilder<T> WithDefaultValue(string defaultValue)
		{
			_argument.DefaultValue = defaultValue;
			return this;
		}

		public ArgumentBuilder<T> WithParser(Func<string, T> parser)
		{
			_argument.Parser = parser;
			return this;
		}

		public ArgumentBuilder<T> WithSuggestions(Func<string[]> suggestionsProvider)
		{
			_argument.SuggestionsProvider = suggestionsProvider;
			return this;
		}

		public CommandBuilder Parent()
		{
			return parentBuilder;
		}

		public IArgument Build()
		{
			return _argument;
		}
	}
	public class CommandBuilder
	{
		protected readonly Command _command;

		public CommandBuilder(string name)
		{
			_command = new Command
			{
				Name = name
			};
		}

		public CommandBuilder(Command command)
		{
			_command = command;
		}

		public CommandBuilder WithDescription(string description)
		{
			_command.Description = description;
			return this;
		}

		public ArgumentBuilder<T> WithArgument<T>(string name)
		{
			Argument<T> argument = new Argument<T>
			{
				Name = name
			};
			_command.AddArgument(argument);
			return new ArgumentBuilder<T>(this, argument);
		}

		public OptionBuilder<T> WithOption<T>(string name)
		{
			CommandOption<T> option = new CommandOption<T>
			{
				Name = name
			};
			_command.AddOption(option);
			return new OptionBuilder<T>(this, option);
		}

		public SubCommandBuilder WithSubCommand(string name)
		{
			Command command = new Command
			{
				Name = name
			};
			_command.AddSubCommand(command);
			return new SubCommandBuilder(this, command);
		}

		public CommandBuilder SetHandler(Func<HandlerArgs, Task> handler)
		{
			_command.SetHandler(handler);
			return this;
		}

		public CommandBuilder UseHandlerMiddleware(Func<Func<HandlerArgs, Task>?, Func<HandlerArgs, Task>> middleware)
		{
			Func<HandlerArgs, Task> handler = _command.Handler;
			_command.SetHandler(middleware(handler));
			return this;
		}

		public string GetCommandHelpString()
		{
			return _command.GetCommandHelpString();
		}

		public string GetCommandUsageString()
		{
			return _command.GetCommandUsage();
		}

		public ICommand Build()
		{
			return _command;
		}

		public virtual CommandBuilder Parent()
		{
			return this;
		}
	}
	public class OptionBuilder<T>
	{
		private readonly CommandBuilder parentBuilder;

		private readonly CommandOption<T> _option;

		public OptionBuilder(CommandBuilder parentBuilder, string name)
		{
			_option = new CommandOption<T>
			{
				Name = name
			};
			this.parentBuilder = parentBuilder;
		}

		public OptionBuilder(CommandBuilder parentBuilder, CommandOption<T> option)
		{
			_option = option;
			this.parentBuilder = parentBuilder;
		}

		public OptionBuilder<T> WithDescription(string description)
		{
			_option.Description = description;
			return this;
		}

		public OptionBuilder<T> WithDefaultValue(string defaultValue)
		{
			_option.DefaultValue = defaultValue;
			return this;
		}

		public OptionBuilder<T> WithAliases(params string[] aliases)
		{
			_option.Aliases = aliases;
			return this;
		}

		public OptionBuilder<T> WithParser(Func<string, T> parser)
		{
			_option.Parser = parser;
			return this;
		}

		public OptionBuilder<T> IsRequired()
		{
			_option.IsRequired = true;
			return this;
		}

		public CommandBuilder Parent()
		{
			return parentBuilder;
		}

		public ICommandOption Build()
		{
			return _option;
		}
	}
	public class SubCommandBuilder : CommandBuilder
	{
		private readonly CommandBuilder parentBuilder;

		public SubCommandBuilder(CommandBuilder parentBuilder, Command command)
			: base(command)
		{
			this.parentBuilder = parentBuilder;
		}

		public SubCommandBuilder(CommandBuilder parentBuilder, string name)
			: base(name)
		{
			this.parentBuilder = parentBuilder;
		}

		public override CommandBuilder Parent()
		{
			return parentBuilder;
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}