/// <summary>
 /// Adds a middleware delegate defined in-line to the application's request pipeline.
 /// </summary>
 /// <param name="app">The <see cref="IBotApplicationBuilder"/> instance.</param>
 /// <param name="middleware">A function that handles the request or calls the given next function.</param>
 /// <returns>The <see cref="IBotApplicationBuilder"/> instance.</returns>
 public static IBotApplicationBuilder Use(this IBotApplicationBuilder app, Func <MessageContext, Func <ValueTask>, ValueTask> middleware)
 {
     return(app.Use(next =>
     {
         return context =>
         {
             return middleware(context, () => next(context));
         };
     }));
 }
Exemplo n.º 2
0
        public static IBotApplicationBuilder UsePendingCommand(this IBotApplicationBuilder builder)
        {
            builder.Properties[BuilderPendingKey] = true;

            return(builder.Use(async(context, next) =>
            {
                if (int.TryParse(context.Request.Message, out var id))
                {
                    id -= 1;

                    var cacheClient = context.RequestServices.GetRequiredService <ICacheClient>();
                    var cache = await cacheClient.GetAsync <PendingCommand>(GetPendingCacheKey(context.User.Id));

                    if (cache.HasValue)
                    {
                        var pendingCommand = cache.Value;

                        if (pendingCommand.ChannelId == context.Request.ChannelId)
                        {
                            if (id < 0 || id >= pendingCommand.Values.Length)
                            {
                                context.Response.AddError("You gave an invalid number.");
                                return;
                            }

                            context.Request.Message = pendingCommand.Prefix + pendingCommand.CommandBegin + pendingCommand.Values[id] + pendingCommand.CommandEnd;

                            await next();

                            var response = context.Response.Actions
                                           .OfType <MessageActionResult>()
                                           .FirstOrDefault();

                            context.Response.DeleteMessage(pendingCommand.ChannelId, context.Request.MessageId);

                            if (response.Message != null)
                            {
                                response.Message.MessageId = pendingCommand.ErrorMessageId;
                            }
                            else
                            {
                                context.Response.DeleteMessage(pendingCommand.ChannelId, pendingCommand.ErrorMessageId);
                            }

                            return;
                        }
                    }
                }

                await next();
            }));
        }
Exemplo n.º 3
0
        public void ConfigureBot(IBotApplicationBuilder app)
        {
            app.UseIgnoreBots();
            app.Use((context, next) =>
            {
                if (context.Request.Message == "ping")
                {
                    context.Response.AddMessage("Pong");
                }

                return(next());
            });
        }
        public static IBotApplicationBuilder UsePrefix(this IBotApplicationBuilder builder)
        {
            var prefixProvider = builder.ApplicationServices.GetService <IPrefixProvider>();

            return(builder.Use(async(context, next) =>
            {
                if (context.Items.TryGetValue(SkipPrefixItemKey, out var skipPrefix) && Equals(skipPrefix, true))
                {
                    await next();
                    return;
                }

                var request = context.Request;
                var mention = context.Self?.Mention;

                string currentPrefix = null;

                if (mention != null && request.Message.StartsWith(mention))
                {
                    request.Message = request.Message.Substring(mention.Length).TrimStart();
                    currentPrefix = mention + " ";
                }
                else if (prefixProvider != null)
                {
                    await foreach (var prefix in prefixProvider.GetPrefixesAsync(context))
                    {
                        if (!request.Message.StartsWith(prefix))
                        {
                            continue;
                        }

                        request.Message = request.Message.Substring(prefix.Length).TrimStart();
                        currentPrefix = prefix;
                        break;
                    }
                }

                if (currentPrefix == null)
                {
                    return;
                }

                context.Items[PrefixItemKey] = currentPrefix;

                await next();
            }));
        }
Exemplo n.º 5
0
 public static IBotApplicationBuilder UseIgnoreBots(this IBotApplicationBuilder builder)
 {
     return(builder.Use((context, next) => context.User.IsBot ? default: next()));
 }
Exemplo n.º 6
0
        public static IBotApplicationBuilder UseCommands(this IBotApplicationBuilder builder)
        {
            var supportsPendingCommands = builder.Properties.TryGetValue(BuilderPendingKey, out var value) && Equals(value, true);

            return(builder.Use(async(context, next) =>
            {
                var commandManager = context.RequestServices.GetRequiredService <ICommandManager>();
                var argumentReader = context.Request.GetArgumentReader();
                var localizer = context.RequestServices.GetRequiredService <IStringLocalizer>();

                argumentReader.Reset();

                var commandName = await argumentReader.ReadStringAsync();
                var commands = commandManager.FindAll(commandName);
                var logger = context.RequestServices.GetRequiredService <ILogger <ICommandManager> >();
                var commandError = CommandError.None;

                if (commands.Count == 0)
                {
                    await next();
                    return;
                }

                var enabledModules = context.Request.GuildId.HasValue
                    ? await context.RequestServices.GetRequiredService <IModuleManager>().GetEnabledModulesAsync(context.Request.GuildId.Value)
                    : null;

                foreach (var command in commands)
                {
                    if (command.GuildOnly && !context.Request.GuildId.HasValue)
                    {
                        commandError = CommandError.GuildOnly;
                        continue;
                    }

                    if (command.Module != null && enabledModules != null && !enabledModules.Contains(command.Module))
                    {
                        commandError = CommandError.ModuleDisabled;
                        continue;
                    }

                    if (!await context.HasChannelPermission(command.Permission))
                    {
                        commandError = CommandError.ChannelNoPermission;
                        continue;
                    }

                    if (!await context.HasUserPermission(command.Permission))
                    {
                        commandError = CommandError.UserNoPermission;
                        continue;
                    }

                    try
                    {
                        await command.ExecuteAsync(context);
                        logger.LogTrace("User {Username} executed the command {CommandName}.", context.User.Username, commandName);
                        commandError = CommandError.None;
                        break;
                    }
                    catch (AmbiguousArgumentMatchException e)
                    {
                        var cacheClient = context.RequestServices.GetRequiredService <ICacheClient>();
                        var key = GetAmbiguousLocalizationKey(e.Type, supportsPendingCommands);
                        var items = e.Results.Take(5).ToArray();
                        var ids = items.Select(kv => kv.Key).ToArray();

                        var prefix = context.Items.TryGetValue("Prefix", out var prefixObj)
                            ? (string)prefixObj
                            : null;

                        var messageContent = localizer[key]
                                             .WithToken("Results", "\n```\n" + string.Join("\n", items.Select((kv, i) => $"{i + 1}: {kv.Value}")) + "\n```\n")
                                             .WithToken("Query", e.Query.Value);

                        commandError = CommandError.AmbiguousArgumentMatch;

                        var message = context.Response.AddError(messageContent);

                        if (supportsPendingCommands)
                        {
                            message.Then(async args =>
                            {
                                var pendingCommand = new PendingCommand(
                                    e.Query.CommandBegin,
                                    e.Query.CommandEnd,
                                    ids,
                                    context.Request.ChannelId,
                                    args.Message.Id,
                                    prefix
                                    );

                                await cacheClient.SetAsync(
                                    GetPendingCacheKey(context.User.Id),
                                    pendingCommand,
                                    TimeSpan.FromMinutes(1)
                                    );
                            });
                        }

                        break;
                    }
                    catch (MissingArgumentException)
                    {
                        commandError = CommandError.InvalidArguments;
                    }
                    catch (CommandNotAvailableException)
                    {
                        logger.LogTrace("User {Username} could not execute the command {CommandName}.", context.User.Username, commandName);
                        commandError = CommandError.Unavailable;
                    }
                }

                if (commandError != CommandError.None && localizer.TryGetString("Command.Error." + commandError, out var errorMessage))
                {
                    context.Response.AddError(errorMessage);
                }

                switch (commandError)
                {
                case CommandError.GuildOnly:
                    logger.LogDebug("User {Username} tried to execute the command {CommandName} but the command can only be executed in guild channels.", context.User.Username, commandName);
                    break;

                case CommandError.ChannelNoPermission:
                    logger.LogDebug("User {Username} tried to execute the command {CommandName} but the server owner disabled the permission in the channel.", context.User.Username, commandName);
                    break;

                case CommandError.UserNoPermission:
                    logger.LogDebug("User {Username} tried to execute the command {CommandName} but didn't have the required permissions to do so.", context.User.Username, commandName);
                    break;

                case CommandError.InvalidArguments:
                    logger.LogTrace("User {Username} tried to execute the command {CommandName} but didn't provide all the arguments.", context.User.Username, commandName);
                    break;
                }

                await next();
            }));
        }