public CommandDispatcher(Spook cli) { _cli = cli; RegisterCommandHandler <string>((args, canConsumeAll) => { return(CommandToken.ReadString(args, canConsumeAll)); }); RegisterCommandHandler <string[]>((args, canConsumeAll) => { if (canConsumeAll) { var ret = CommandToken.ToString(args); args.Clear(); return(ret.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)); } else { return(CommandToken.ReadString(args, false).Split(',', ' ')); } }); RegisterCommandHandler <string, byte>(false, (str) => byte.Parse(str)); RegisterCommandHandler <string, bool>(false, (str) => str == "1" || str == "yes" || str == "y" || bool.Parse(str)); RegisterCommandHandler <string, ushort>(false, (str) => ushort.Parse(str)); RegisterCommandHandler <string, uint>(false, (str) => uint.Parse(str)); RegisterCommandHandler <string, JObject>((str) => JObject.Parse(str)); //RegisterCommandHandler<JObject, JArray>((obj) => (JArray)obj); RegisterCommand(this); }
public static string[] ToArguments(IEnumerable <CommandToken> tokens, bool removeEscape = true) { var list = new List <string>(); CommandToken lastToken = null; foreach (var token in tokens) { if (token is CommandStringToken str) { if (removeEscape && lastToken is CommandQuoteToken quote) { // Remove escape list.Add(str.Value.Replace("\\" + quote.Value, quote.Value)); } else { list.Add(str.Value); } } lastToken = token; } return(list.ToArray()); }
public static IEnumerable <CommandToken> Parse(string commandLine) { CommandToken lastToken = null; for (int index = 0, count = commandLine.Length; index < count;) { switch (commandLine[index]) { case ' ': { lastToken = CommandSpaceToken.Parse(commandLine, ref index); yield return(lastToken); break; } case '"': case '\'': { // "'" if (lastToken is CommandQuoteToken quote && quote.Value[0] != commandLine[index]) { goto default; } lastToken = CommandQuoteToken.Parse(commandLine, ref index); yield return(lastToken); break; } default: { lastToken = CommandStringToken.Parse(commandLine, ref index, lastToken is CommandQuoteToken quote ? quote : null); yield return(lastToken); break; } } } }
private bool TryProcessValue(Type parameterType, List <CommandToken> args, bool canConsumeAll, out object value) { if (args.Count > 0) { if (_handlers.TryGetValue(parameterType, out var handler)) { value = handler(args, canConsumeAll); return(true); } if (parameterType.IsEnum) { var arg = CommandToken.ReadString(args, canConsumeAll); value = Enum.Parse(parameterType, arg.Trim(), true); return(true); } } value = null; return(false); }
public bool OnCommand(string commandLine) { if (string.IsNullOrEmpty(commandLine)) { return(true); } string possibleHelp = null; var commandArgs = CommandToken.Parse(commandLine).ToArray(); var availableCommands = new List <(ConsoleCommandMethod Command, object[] Arguments)>(); foreach (var entries in _verbs.Values) { foreach (var command in entries) { if (command.IsThisCommand(commandArgs, out var consumedArgs)) { var arguments = new List <object>(); var args = commandArgs.Skip(consumedArgs).ToList(); CommandSpaceToken.Trim(args); try { var parameters = command.Method.GetParameters(); foreach (var arg in parameters) { // Parse argument if (TryProcessValue(arg.ParameterType, args, arg == parameters.Last(), out var value)) { arguments.Add(value); } else { if (arg.HasDefaultValue) { arguments.Add(arg.DefaultValue); } else { throw new ArgumentException(arg.Name); } } } availableCommands.Add((command, arguments.ToArray())); } catch { // Skip parse errors possibleHelp = command.Key; } } } } switch (availableCommands.Count) { case 0: { if (!string.IsNullOrEmpty(possibleHelp)) { OnHelpCommand(possibleHelp); return(true); } return(false); } case 1: { var(command, arguments) = availableCommands[0]; if (command.HelpCategory.Equals("NexusAPI")) { try { string[] args = arguments.Where(x => x != null) .Select(x => x.ToString()) .ToArray(); _cli.ExecuteAPI(command.Method.Name, args); } catch (Exception) { Spook.Logger.Message("invalid api command"); } return(true); } else { try { command.Method.Invoke(command.Instance, arguments); } catch (Exception e) { e = e.ExpandInnerExceptions(); Spook.Logger.Message(e.Message); } } return(true); } default: { // Show Ambiguous call throw new ArgumentException("Ambiguous calls for: " + string.Join(',', availableCommands.Select(u => u.Command.Key).Distinct())); } } }