예제 #1
0
        private static void ProcessFullMatch(Context ctx, string message, CommandMatch match)
        {
            //Insert the context into the match
            match.extractedParams[0] = ctx;

            //Catch any failed preconditions
            try
            {
                //Catch exceptions thrown by the target and rethrow them
                try
                {
                    //Invoke the command
                    match.cmd.Invoke(match.module, match.extractedParams);
                }
                catch (TargetInvocationException ex)
                {
                    //Rethrow the actual exception
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                }
            }
            catch (PreconditionException ex)
            {
                //Send error
                Bot.GetBotInstance().SendErrorMessage(ctx.message.Channel, "Error:", ex.Message);
            }
        }
예제 #2
0
        public static List <CommandMatch> ProcessCommand(CommandModuleBase module, string inputString)
        {
            //Prepare a list to hold our candidates
            var candidates = new List <CommandMatch>();

            //Go through each command in the module
            module.Commands.ForEach(cmd =>
            {
                //Grab the signature to match
                var signature = CommandManager.GetCommandSignature(cmd);

                //Prepare our iterators
                var inputIterator     = new StringIterator(inputString);
                var signatureIterator = new StringIterator(signature);

                //Prepare candidate
                var paramInfo = cmd.GetParameters();
                var candidate = new CommandMatch
                {
                    module          = module,
                    cmd             = cmd,
                    inputMatch      = 0,
                    signatureMatch  = 0,
                    signatureLength = signature.Length,
                    extractedParams = new object[paramInfo.Length],
                    count           = 1
                };

                //Iterate through the strings
                while (true)
                {
                    //Check for valid iterators
                    if (!inputIterator.Current().HasValue || !signatureIterator.Current().HasValue)
                    {
                        break;
                    }

                    //Get the next characters
                    var ch1 = inputIterator.Current().Value;
                    var ch2 = signatureIterator.Current().Value;

                    //Check if we hit a whitespace character in the signature
                    if (char.IsWhiteSpace(ch2))
                    {
                        //Check that the input string has at least one whitespace
                        if (char.IsWhiteSpace(ch1))
                        {
                            //Skip the whitespace
                            inputIterator.SkipWhitespace();
                            signatureIterator.SkipWhitespace();

                            //Continue without advancing iterators
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }

                    //Check if we reached a parameter
                    if ((ch2 == '{') && (signatureIterator.Peek() == '}'))
                    {
                        //Skip any whitespace before our parameter
                        inputIterator.SkipWhitespace();

                        //Try to match the input against our expected parameter
                        if (CheckMatch(paramInfo[candidate.count], inputIterator, signatureIterator, out object result))
                        {
                            //Store the result
                            candidate.extractedParams[candidate.count++] = result;

                            //Skip over the brackets in the signature
                            signatureIterator.Skip();
                            signatureIterator.Skip();

                            //Check if the signature is not explicitly requiring a whitespace
                            var tmp = signatureIterator.Current();
                            if (tmp.HasValue && !char.IsWhiteSpace(tmp.Value))
                            {
                                //Allow optional whitespace which we skip
                                inputIterator.SkipWhitespace();
                            }

                            //Continue without advancing iterators
                            continue;
                        }
                        break;
                    }

                    //Normal case-insensitive string comparison
                    if (char.ToLowerInvariant(ch1) != char.ToLowerInvariant(ch2))
                    {
                        break;
                    }

                    //Advance our iterators
                    inputIterator.Next();
                    signatureIterator.Next();
                }

                //Update how much we matched of the input and signature
                candidate.inputMatch     = inputIterator.Index;
                candidate.signatureMatch = signatureIterator.Index;

                //Push candidate into list
                candidates.Add(candidate);
            });

            //Return the candidates
            return(candidates);
        }