Example #1
0
        public async Task <Suggestions> GetCompletionSuggestions(ParseResults <TSource> parse, int cursor)
        {
            var context = parse.Context;

            var nodeBeforeCursor = context.FindSuggestionContext(cursor);
            var parent           = nodeBeforeCursor.Parent;
            var start            = Math.Min(nodeBeforeCursor.StartPos, cursor);

            var fullInput               = parse.Reader.String;
            var truncatedInput          = fullInput.Substring(0, cursor);
            var truncatedInputLowerCase = truncatedInput.ToLowerInvariant();
            var futures = new Task <Suggestions> [parent.Children.Count()];
            var i       = 0;

            foreach (var node in parent.Children)
            {
                var future = Suggestions.Empty();
                try
                {
                    future = node.ListSuggestions(context.Build(truncatedInput), new SuggestionsBuilder(truncatedInput, truncatedInputLowerCase, start));
                }
                catch (CommandSyntaxException)
                {
                }

                futures[i++] = future;
            }

            await Task.WhenAll(futures);

            return(Suggestions.Merge(fullInput, futures.Select(s => s.Result).ToArray()));
        }
Example #2
0
/**
 * Gets suggestions for a parsed input string on what comes next.
 *
 * <p>As it is ultimately up to custom argument types to provide suggestions, it may be an asynchronous operation,
 * for example getting in-game data or player names etc. As such, this method returns a future and no guarantees
 * are made to when or how the future completes.</p>
 *
 * <p>The suggestions provided will be in the context of the end of the parsed input string, but may suggest
 * new or replacement strings for earlier in the input string. For example, if the end of the string was
 * {@code foobar} but an argument preferred it to be {@code minecraft:foobar}, it will suggest a replacement for that
 * whole segment of the input.</p>
 *
 * @param parse the result of a {@link #parse(StringReader, Object)}
 * @return a future that will eventually resolve into a {@link Suggestions} object
 */
        public Task <Suggestions> GetCompletionSuggestions(ParseResults <TSource> parse)
        {
            return(GetCompletionSuggestions(parse, parse.Reader.TotalLength));
        }
Example #3
0
        /**
         * Executes a given pre-parsed command.
         *
         * <p>If this command returns a value, then it successfully executed something. If the execution was a failure,
         * then an exception will be thrown.
         * Most exceptions will be of type {@link CommandSyntaxException}, but it is possible that a {@link RuntimeException}
         * may bubble up from the result of a command. The meaning behind the returned result is arbitrary, and will depend
         * entirely on what command was performed.</p>
         *
         * <p>If the command passes through a node that is {@link CommandNode#isFork()} then it will be 'forked'.
         * A forked command will not bubble up any {@link CommandSyntaxException}s, and the 'result' returned will turn into
         * 'amount of successful commands executes'.</p>
         *
         * <p>After each and any command is ran, a registered callback given to {@link #setConsumer(ResultConsumer)}
         * will be notified of the result and success of the command. You can use that method to gather more meaningful
         * results than this method will return, especially when a command forks.</p>
         *
         * @param parse the result of a successful {@link #parse(StringReader, Object)}
         * @return a numeric result from a "command" that was performed.
         * @throws CommandSyntaxException if the command failed to parse or execute
         * @throws RuntimeException if the command failed to execute and was not handled gracefully
         * @see #parse(String, Object)
         * @see #parse(StringReader, Object)
         * @see #execute(String, Object)
         * @see #execute(StringReader, Object)
         */
        ///<exception cref="CommandSyntaxException" />
        public int Execute(ParseResults <TSource> parse)
        {
            if (parse.Reader.CanRead())
            {
                if (parse.Exceptions.Count == 1)
                {
                    throw parse.Exceptions.Values.Single();
                }
                else if (parse.Context.Range.IsEmpty)
                {
                    throw CommandSyntaxException.BuiltInExceptions.DispatcherUnknownCommand().CreateWithContext(parse.Reader);
                }
                else
                {
                    throw CommandSyntaxException.BuiltInExceptions.DispatcherUnknownArgument().CreateWithContext(parse.Reader);
                }
            }

            var result          = 0;
            var successfulForks = 0;
            var forked          = false;
            var foundCommand    = false;
            var command         = parse.Reader.String;
            var original        = parse.Context.Build(command);
            var contexts        = new List <CommandContext <TSource> > {
                original
            };
            List <CommandContext <TSource> > next = null;

            while (contexts != null)
            {
                var size = contexts.Count;
                for (var i = 0; i < size; i++)
                {
                    var context = contexts[i];
                    var child   = context.Child;
                    if (child != null)
                    {
                        forked |= context.IsForked();
                        if (child.HasNodes())
                        {
                            foundCommand = true;
                            var modifier = context.RedirectModifier;
                            if (modifier == null)
                            {
                                if (next == null)
                                {
                                    next = new List <CommandContext <TSource> >(1);
                                }

                                next.Add(child.CopyFor(context.Source));
                            }
                            else
                            {
                                try
                                {
                                    var results = modifier(context);
                                    if (results.Count > 0)
                                    {
                                        if (next == null)
                                        {
                                            next = new List <CommandContext <TSource> >(results.Count());
                                        }

                                        foreach (var source in results)
                                        {
                                            next.Add(child.CopyFor(source));
                                        }
                                    }
                                }
                                catch (CommandSyntaxException)
                                {
                                    Consumer(context, false, 0);
                                    if (!forked)
                                    {
                                        throw;
                                    }
                                }
                            }
                        }
                    }
                    else if (context.Command != null)
                    {
                        foundCommand = true;
                        try
                        {
                            var value = context.Command(context);
                            result += value;
                            Consumer(context, true, value);
                            successfulForks++;
                        }
                        catch (CommandSyntaxException)
                        {
                            Consumer(context, false, 0);
                            if (!forked)
                            {
                                throw;
                            }
                        }
                    }
                }

                contexts = next;
                next     = null;
            }

            if (!foundCommand)
            {
                Consumer(original, false, 0);
                throw CommandSyntaxException.BuiltInExceptions.DispatcherUnknownCommand().CreateWithContext(parse.Reader);
            }

            return(forked ? successfulForks : result);
        }