示例#1
0
        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);
        }
示例#2
0
        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());
        }
示例#3
0
        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;
                }
                }
            }
        }
示例#4
0
        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);
        }
示例#5
0
        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()));
            }
            }
        }