Beispiel #1
0
        /// <summary>
        /// Executes this command with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public virtual async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            var args = CommandsNextUtilities.BindArguments(ctx);

            try
            {
                var   ret = (Task)this.Callable.DynamicInvoke(args);
                await ret;
            }
            catch (Exception ex)
            {
                return(new CommandResult
                {
                    IsSuccessful = false,
                    Exception = ex,
                    Context = ctx
                });
            }

            return(new CommandResult
            {
                IsSuccessful = true,
                Context = ctx
            });
        }
Beispiel #2
0
        /// <summary>
        /// Executes this command with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public virtual async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            CommandResult res = default;

            try
            {
                var executed = false;
                foreach (var ovl in this.Overloads.OrderByDescending(x => x.Priority))
                {
                    ctx.Overload = ovl;
                    var args = await CommandsNextUtilities.BindArgumentsAsync(ctx, ctx.Config.IgnoreExtraArguments).ConfigureAwait(false);

                    if (!args.IsSuccessful)
                    {
                        continue;
                    }

                    ctx.RawArguments = args.Raw;

                    var mdl = ovl.InvocationTarget ?? this.Module?.GetInstance(ctx.Services);
                    if (mdl is BaseCommandModule bcmBefore)
                    {
                        await bcmBefore.BeforeExecutionAsync(ctx).ConfigureAwait(false);
                    }

                    args.Converted[0] = mdl;
                    var ret = (Task)ovl.Callable.DynamicInvoke(args.Converted);
                    await ret.ConfigureAwait(false);

                    executed = true;
                    res      = new CommandResult
                    {
                        IsSuccessful = true,
                        Context      = ctx
                    };

                    if (mdl is BaseCommandModule bcmAfter)
                    {
                        await bcmAfter.AfterExecutionAsync(ctx).ConfigureAwait(false);
                    }
                    break;
                }

                if (!executed)
                {
                    throw new ArgumentException("Could not find a suitable overload for the command.");
                }
            }
            catch (Exception ex)
            {
                res = new CommandResult
                {
                    IsSuccessful = false,
                    Exception    = ex,
                    Context      = ctx
                };
            }

            return(res);
        }
Beispiel #3
0
        /// <summary>
        /// Executes this command with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public virtual async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            try
            {
                var args = await CommandsNextUtilities.BindArguments(ctx, ctx.Config.IgnoreExtraArguments);

                ctx.RawArguments = args.Raw;
                var ret = (Task)this.Callable.DynamicInvoke(args.Converted);
                await ret.ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                return(new CommandResult
                {
                    IsSuccessful = false,
                    Exception = ex,
                    Context = ctx
                });
            }

            return(new CommandResult
            {
                IsSuccessful = true,
                Context = ctx
            });
        }
Beispiel #4
0
        /// <summary>
        /// Executes this command or its subcommand with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public override async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            var findpos = 0;
            var cn      = CommandsNextUtilities.ExtractNextArgument(ctx.RawArgumentString, ref findpos);

            if (cn != null)
            {
                var(comparison, comparer) = ctx.Config.CaseSensitive switch
                {
                    true => (StringComparison.InvariantCulture, StringComparer.InvariantCulture),
                    false => (StringComparison.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase)
                };
                var cmd = this.Children.FirstOrDefault(xc =>
                                                       xc.Name.Equals(cn, comparison) || (xc.Aliases != null && xc.Aliases.Contains(cn, comparer)));
                if (cmd != null)
                {
                    // pass the execution on
                    var xctx = new CommandContext
                    {
                        Client            = ctx.Client,
                        Message           = ctx.Message,
                        Command           = cmd,
                        Config            = ctx.Config,
                        RawArgumentString = ctx.RawArgumentString.Substring(findpos),
                        Prefix            = ctx.Prefix,
                        CommandsNext      = ctx.CommandsNext,
                        Services          = ctx.Services
                    };

                    var fchecks = await cmd.RunChecksAsync(xctx, false).ConfigureAwait(false);

                    return(fchecks.Any()
                        ? new CommandResult
                    {
                        IsSuccessful = false,
                        Exception = new ChecksFailedException(cmd, xctx, fchecks),
                        Context = xctx
                    }
                        : await cmd.ExecuteAsync(xctx).ConfigureAwait(false));
                }
            }

            return(!this.IsExecutableWithoutSubcommands
                ? new CommandResult
            {
                IsSuccessful = false,
                Exception = new InvalidOperationException("No matching subcommands were found, and this group is not executable."),
                Context = ctx
            }
                : await base.ExecuteAsync(ctx).ConfigureAwait(false));
        }
Beispiel #5
0
        public async Task HandleCommandsAsync(MessageCreateEventArgs e)
        {
            // Let the bot do its things
            await Task.Yield();

            if (e.Author.IsBot) // bad bot
            {
                return;
            }

            if (!this.Config.EnableDms && e.Channel.IsPrivate)
            {
                return;
            }

            if (this.Config.SelfBot && e.Author.Id != this.Client.CurrentUser.Id)
            {
                return;
            }

            var mpos = -1;

            if (this.Config.EnableMentionPrefix)
            {
                mpos = e.Message.GetMentionPrefixLength(this.Client.CurrentUser);
            }

            if (mpos == -1 && !string.IsNullOrWhiteSpace(this.Config.StringPrefix))
            {
                mpos = e.Message.GetStringPrefixLength(this.Config.StringPrefix);
            }

            if (mpos == -1 && this.Config.CustomPrefixPredicate != null)
            {
                mpos = await this.Config.CustomPrefixPredicate(e.Message);
            }

            if (mpos == -1)
            {
                return;
            }

            var cnt = e.Message.Content.Substring(mpos);
            var cms = CommandsNextUtilities.ExtractNextArgument(cnt, out var rrg);
            //var cmi = cnt.IndexOf(' ', mpos);
            //var cms = cmi != -1 ? cnt.Substring(mpos, cmi - mpos) : cnt.Substring(mpos);
            //var rrg = cmi != -1 ? cnt.Substring(cmi + 1) : "";
            //var arg = CommandsNextUtilities.SplitArguments(rrg);

            var cmd = this.TopLevelCommands.ContainsKey(cms) ? this.TopLevelCommands[cms] : null;

            if (cmd == null && !this.Config.CaseSensitive)
            {
                cmd = this.TopLevelCommands.FirstOrDefault(xkvp => xkvp.Key.ToLower() == cms.ToLower()).Value;
            }

            var ctx = new CommandContext
            {
                Client  = this.Client,
                Command = cmd,
                Message = e.Message,
                //RawArguments = new ReadOnlyCollection<string>(arg.ToList()),
                Config            = this.Config,
                RawArgumentString = rrg,
                CommandsNext      = this,
                Dependencies      = this.Config.Dependencies
            };

            if (cmd == null)
            {
                await this._error.InvokeAsync(new CommandErrorEventArgs { Context = ctx, Exception = new CommandNotFoundException("Specified command was not found.", cms) });

                return;
            }

            _ = Task.Run(async() =>
            {
                try
                {
                    var fchecks = new List <CheckBaseAttribute>();
                    if (cmd.ExecutionChecks != null && cmd.ExecutionChecks.Any())
                    {
                        foreach (var ec in cmd.ExecutionChecks)
                        {
                            if (!(await ec.CanExecute(ctx)))
                            {
                                fchecks.Add(ec);
                            }
                        }
                    }
                    if (fchecks.Any())
                    {
                        throw new ChecksFailedException("One or more pre-execution checks failed.", cmd, ctx, fchecks);
                    }

                    var res = await cmd.ExecuteAsync(ctx);

                    if (res.IsSuccessful)
                    {
                        await this._executed.InvokeAsync(new CommandExecutionEventArgs {
                            Context = res.Context
                        });
                    }
                    else
                    {
                        await this._error.InvokeAsync(new CommandErrorEventArgs {
                            Context = res.Context, Exception = res.Exception
                        });
                    }
                }
                catch (Exception ex)
                {
                    await this._error.InvokeAsync(new CommandErrorEventArgs {
                        Context = ctx, Exception = ex
                    });
                }
            });
        }
Beispiel #6
0
 /// <summary>
 /// Unregisters an argument converter for specified type.
 /// </summary>
 /// <typeparam name="T">Type for which to unregister the converter.</typeparam>
 public void UnregisterConverter <T>()
 => CommandsNextUtilities.UnregisterConverter <T>();
Beispiel #7
0
 /// <summary>
 /// Registers an argument converter for specified type.
 /// </summary>
 /// <typeparam name="T">Type for which to register the converter.</typeparam>
 /// <param name="converter">Converter to register.</param>
 public void RegisterConverter <T>(IArgumentConverter <T> converter)
 => CommandsNextUtilities.RegisterConverter(converter);
Beispiel #8
0
        public async Task HandleCommandsAsync(MessageCreateEventArgs e)
        {
            // Let the bot do its things
            await Task.Yield();

            if (e.Author.IsBot) // bad bot
            {
                return;
            }

            if (!this.Config.EnableDms && e.Channel.IsPrivate)
            {
                return;
            }

            if (this.Config.Selfbot && e.Author.Id != this.Client.CurrentUser.Id)
            {
                return;
            }

            var mpos = -1;

            if (this.Config.EnableMentionPrefix)
            {
                mpos = e.Message.GetMentionPrefixLength(this.Client.CurrentUser);
            }

            if (mpos == -1 && !string.IsNullOrWhiteSpace(this.Config.StringPrefix))
            {
                mpos = e.Message.GetStringPrefixLength(this.Config.StringPrefix);
            }

            if (mpos == -1 && this.Config.CustomPrefixPredicate != null)
            {
                mpos = await this.Config.CustomPrefixPredicate(e.Message).ConfigureAwait(false);
            }

            if (mpos == -1)
            {
                return;
            }

            var cnt = e.Message.Content.Substring(mpos);
            var cms = CommandsNextUtilities.ExtractNextArgument(cnt, out var rrg);

            var cmd = this.TopLevelCommands.ContainsKey(cms) ? this.TopLevelCommands[cms] : null;

            if (cmd == null && !this.Config.CaseSensitive)
            {
                cmd = this.TopLevelCommands.FirstOrDefault(xkvp => xkvp.Key.ToLowerInvariant() == cms.ToLowerInvariant()).Value;
            }

            var ctx = new CommandContext
            {
                Client  = this.Client,
                Command = cmd,
                Message = e.Message,
                //RawArguments = new ReadOnlyCollection<string>(arg.ToList()),
                Config            = this.Config,
                RawArgumentString = rrg,
                CommandsNext      = this
            };

            if (cmd == null)
            {
                await this._error.InvokeAsync(new CommandErrorEventArgs { Context = ctx, Exception = new CommandNotFoundException(cms) }).ConfigureAwait(false);

                return;
            }

            _ = Task.Run(async() =>
            {
                try
                {
                    var fchecks = await cmd.RunChecksAsync(ctx, false).ConfigureAwait(false);
                    if (fchecks.Any())
                    {
                        throw new ChecksFailedException(cmd, ctx, fchecks);
                    }

                    var res = await cmd.ExecuteAsync(ctx).ConfigureAwait(false);

                    if (res.IsSuccessful)
                    {
                        await this._executed.InvokeAsync(new CommandExecutionEventArgs {
                            Context = res.Context
                        }).ConfigureAwait(false);
                    }
                    else
                    {
                        await this._error.InvokeAsync(new CommandErrorEventArgs {
                            Context = res.Context, Exception = res.Exception
                        }).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    await this._error.InvokeAsync(new CommandErrorEventArgs {
                        Context = ctx, Exception = ex
                    }).ConfigureAwait(false);
                }
            });
        }
Beispiel #9
0
 /// <summary>
 /// Registers a user-friendly type name.
 /// </summary>
 /// <typeparam name="T">Type to register the name for.</typeparam>
 /// <param name="value">Name to register.</param>
 public void RegisterUserFriendlyTypeName <T>(string value)
 => CommandsNextUtilities.RegisterUserFriendlyTypeName <T>(value);
Beispiel #10
0
        /// <summary>
        /// Executes this command or its subcommand with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public override async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            var findpos = 0;
            var cn      = CommandsNextUtilities.ExtractNextArgument(ctx.RawArgumentString, ref findpos);

            if (cn != null)
            {
                Command cmd = null;
                if (ctx.Config.CaseSensitive)
                {
                    cmd = this.Children.FirstOrDefault(xc => xc.Name == cn || (xc.Aliases != null && xc.Aliases.Contains(cn)));
                }
                else
                {
                    cmd = this.Children.FirstOrDefault(xc => xc.Name.ToLowerInvariant() == cn.ToLowerInvariant() || (xc.Aliases != null && xc.Aliases.Select(xs => xs.ToLowerInvariant()).Contains(cn.ToLowerInvariant())));
                }

                if (cmd != null)
                {
                    // pass the execution on
                    var xctx = new CommandContext
                    {
                        Client            = ctx.Client,
                        Message           = ctx.Message,
                        Command           = cmd,
                        Config            = ctx.Config,
                        RawArgumentString = ctx.RawArgumentString.Substring(findpos),
                        Prefix            = ctx.Prefix,
                        CommandsNext      = ctx.CommandsNext,
                        Services          = ctx.Services
                    };

                    var fchecks = await cmd.RunChecksAsync(xctx, false).ConfigureAwait(false);

                    if (fchecks.Any())
                    {
                        return new CommandResult
                               {
                                   IsSuccessful = false,
                                   Exception    = new ChecksFailedException(cmd, xctx, fchecks),
                                   Context      = xctx
                               }
                    }
                    ;

                    return(await cmd.ExecuteAsync(xctx).ConfigureAwait(false));
                }
            }

            if (!this.IsExecutableWithoutSubcommands)
            {
                return new CommandResult
                       {
                           IsSuccessful = false,
                           Exception    = new InvalidOperationException("No matching subcommands were found, and this group is not executable."),
                           Context      = ctx
                       }
            }
            ;

            return(await base.ExecuteAsync(ctx).ConfigureAwait(false));
        }
    }
}
Beispiel #11
0
        /// <summary>
        /// Executes this command with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public virtual async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            CommandResult res = default;

            try
            {
                var executed = false;
                foreach (var ovl in this.Overloads.OrderByDescending(x => x.Priority))
                {
                    ctx.Overload = ovl;
                    var args = await CommandsNextUtilities.BindArguments(ctx, ctx.Config.IgnoreExtraArguments).ConfigureAwait(false);

                    if (!args.IsSuccessful)
                    {
                        continue;
                    }

                    ctx.RawArguments = args.Raw;

                    IServiceScope scope = null;
                    if (this.Module is TransientCommandModule)
                    {
                        scope = ctx.Services.CreateScope();
                        ctx.ServiceScopeContext = new CommandContext.ServiceContext(ctx.Services, scope);

                        ctx.Services = scope.ServiceProvider;
                    }

                    var mdl = this.Module.GetInstance(ctx.Services);
                    await mdl.BeforeExecutionAsync(ctx).ConfigureAwait(false);

                    args.Converted[0] = mdl;
                    var ret = (Task)ovl.Callable.DynamicInvoke(args.Converted);
                    await ret.ConfigureAwait(false);

                    executed = true;
                    res      = new CommandResult
                    {
                        IsSuccessful = true,
                        Context      = ctx
                    };

                    await mdl.AfterExecutionAsync(ctx).ConfigureAwait(false);

                    break;
                }

                if (!executed)
                {
                    throw new ArgumentException("Could not find a suitable overload for the command.");
                }
            }
            catch (Exception ex)
            {
                res = new CommandResult
                {
                    IsSuccessful = false,
                    Exception    = ex,
                    Context      = ctx
                };
            }

            return(res);
        }
Beispiel #12
0
        /// <summary>
        /// Executes this command or its subcommand with specified context.
        /// </summary>
        /// <param name="ctx">Context to execute the command in.</param>
        /// <returns>Command's execution results.</returns>
        public override async Task <CommandResult> ExecuteAsync(CommandContext ctx)
        {
            //var cn = ctx.RawArguments.FirstOrDefault();
            var cn = CommandsNextUtilities.ExtractNextArgument(ctx.RawArgumentString, out var x);

            if (x != null)
            {
                var xi = 0;
                for (; xi < x.Length; xi++)
                {
                    if (!char.IsWhiteSpace(x[xi]))
                    {
                        break;
                    }
                }
                if (xi > 0)
                {
                    x = x.Substring(xi);
                }
            }

            if (cn != null)
            {
                Command cmd = null;
                if (ctx.Config.CaseSensitive)
                {
                    cmd = this.Children.FirstOrDefault(xc => xc.Name == cn || (xc.Aliases != null && xc.Aliases.Contains(cn)));
                }
                else
                {
                    cmd = this.Children.FirstOrDefault(xc => xc.Name.ToLowerInvariant() == cn.ToLowerInvariant() || (xc.Aliases != null && xc.Aliases.Select(xs => xs.ToLowerInvariant()).Contains(cn.ToLowerInvariant())));
                }

                if (cmd != null)
                {
                    // pass the execution on
                    var xctx = new CommandContext
                    {
                        Client            = ctx.Client,
                        Message           = ctx.Message,
                        Command           = cmd,
                        Config            = ctx.Config,
                        RawArgumentString = x,
                        CommandsNext      = ctx.CommandsNext,
                        Dependencies      = ctx.Dependencies
                    };

                    var fchecks = await cmd.RunChecksAsync(xctx, false);

                    if (fchecks.Any())
                    {
                        return new CommandResult
                               {
                                   IsSuccessful = false,
                                   Exception    = new ChecksFailedException(cmd, xctx, fchecks),
                                   Context      = xctx
                               }
                    }
                    ;

                    return(await cmd.ExecuteAsync(xctx));
                }
            }

            if (this.Callable == null)
            {
                return new CommandResult
                       {
                           IsSuccessful = false,
                           Exception    = new InvalidOperationException("No matching subcommands were found, and this group is not executable."),
                           Context      = ctx
                       }
            }
            ;

            return(await base.ExecuteAsync(ctx));
        }
    }
}