private async Task HandleCommandsAsync(DiscordClient sender, MessageCreateEventArgs e) { if (e.Author.IsBot) // bad bot { return; } if (!this.Config.EnableDms && e.Channel.IsPrivate) { return; } var mpos = -1; if (this.Config.EnableMentionPrefix) { mpos = e.Message.GetMentionPrefixLength(this.Client.CurrentUser); } if (this.Config.StringPrefixes?.Any() == true) { foreach (var pfix in this.Config.StringPrefixes) { if (mpos == -1 && !string.IsNullOrWhiteSpace(pfix)) { mpos = e.Message.GetStringPrefixLength(pfix, this.Config.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase); } } } if (mpos == -1 && this.Config.PrefixResolver != null) { mpos = await this.Config.PrefixResolver(e.Message).ConfigureAwait(false); } if (mpos == -1) { return; } ReadOnlyMemory <char> pfx = e.Message.Content.AsMemory().Slice(0, mpos); ReadOnlyMemory <char> cnt = e.Message.Content.AsMemory().Slice(mpos); var __ = 0; var fname = cnt.ExtractNextArgument(ref __); var cmd = this.FindCommand(cnt, out string args); var ctx = this.CreateContext(e.Message, pfx.ToString(), cmd, args); if (cmd == null) { await this._error.InvokeAsync(this, new CommandErrorEventArgs { Context = ctx, Exception = new CommandNotFoundException(fname) }).ConfigureAwait(false); return; } await this.Config.CommandExecutor.ExecuteAsync(ctx).ConfigureAwait(false); }
/// <summary> /// Finds a specified command by its qualified name, then separates arguments. /// </summary> /// <param name="commandString">Qualified name of the command, optionally with arguments.</param> /// <param name="rawArguments">Separated arguments.</param> /// <returns>Found command or null if none was found.</returns> public Command FindCommand(ReadOnlyMemory <char> commandString, out string rawArguments) { rawArguments = null; var ignoreCase = !this.Config.CaseSensitive; var pos = 0; var next = commandString.ExtractNextArgument(ref pos); if (next == null) { return(null); } if (!this.RegisteredCommands.TryGetValue(next, out var cmd)) { if (!ignoreCase) { return(null); } next = next.ToLowerInvariant(); var cmdKvp = this.RegisteredCommands.FirstOrDefault(x => x.Key.ToLowerInvariant() == next); if (cmdKvp.Value == null) { return(null); } cmd = cmdKvp.Value; } if (!(cmd is CommandGroup)) { rawArguments = commandString.Span.Slice(pos).Trim().ToString(); return(cmd); } while (cmd is CommandGroup) { var cm2 = cmd as CommandGroup; var oldPos = pos; next = commandString.ExtractNextArgument(ref pos); if (next == null) { break; } if (ignoreCase) { next = next.ToLowerInvariant(); cmd = cm2.Children.FirstOrDefault(x => x.Name.ToLowerInvariant() == next || x.Aliases?.Any(xx => xx.ToLowerInvariant() == next) == true); } else { cmd = cm2.Children.FirstOrDefault(x => x.Name == next || x.Aliases?.Contains(next) == true); } if (cmd == null) { cmd = cm2; pos = oldPos; break; } } rawArguments = commandString.Span.Slice(pos).Trim().ToString(); return(cmd); }