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); } }
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); }