Example #1
0
        public static async Task <ICommandResult> Help(DiscordMessageContext context, [DisplayName("page | command"), HelpText("Specifies page number or gets help for this specific command")] string command = null, [HelpText("Whether or not to show parameter descriptions")] Verbosity verbosity = Verbosity.Default)
        {
            const int pageSize      = 5;
            string    commandPrefix = CommandTools.GetCommandPrefix(context, context.Channel);

            var builder = new EmbedBuilder
            {
                Title = "Help",
                Color = new Color(33, 150, 243)
            };

            bool paginate = int.TryParse(command, out int page);

            if (paginate)
            {
                command = null;
            }
            else if (command == null)
            {
                page     = 1;
                paginate = true;
            }

            if (verbosity == Verbosity.Default)
            {
                verbosity = command != null ? Verbosity.Verbose : Verbosity.Standard;
            }

            var commands = command == null
                           ? commandMethods.Where(method => method.GetCustomAttribute <CommandScopeAttribute>()
                                                  ?.ChannelTypes.Contains(context.ChannelType)
                                                  ?? true)
                           .Where(method => method.GetCustomAttribute <PermissionsAttribute>()?.GetPermissionError(context) == null)
                           .ToList()
                           : GetCommands(command.StartsWith(commandPrefix)
                                                ? command.Substring(commandPrefix.Length)
                                                : command)
                           .ToList();

            if (commands.Count == 0 || commands[0] == null)
            {
                return(new ErrorResult($"The requested command {commandPrefix}{command} was not found"));
            }

            List <EmbedFieldBuilder> fields = new List <EmbedFieldBuilder>();

            foreach (MethodInfo method in commands)
            {
                var title = new StringBuilder();
                title.Append("`");
                title.Append(string.Join("|", method.GetCustomAttribute <CommandAttribute>().Names.Select(name => $"{commandPrefix}{name}")));
                title.Append(" ");
                title.Append(string.Join(" ", method.GetParameters()
                                         .Skip(1)
                                         .Select(param => param.IsOptional
                                                                     ? $"[{param.GetCustomAttribute<DisplayNameAttribute>()?.Name ?? param.Name}{(param.IsDefined(typeof(JoinRemainingParametersAttribute)) ? "..." : "")}{(param.DefaultValue == null ? "" : $" = {param.DefaultValue}")}]"
Example #2
0
        public static async Task <ICommandResult> Run(string commandMessage, ICommandContext context, string prefix, bool awaitResult)
        {
            var    args        = commandMessage.Trim().Substring(prefix.Length).Split(' ');
            string commandName = args[0];

            args = CommandTools.ParseArguments(string.Join(" ", args.Skip(1)));
            //MethodInfo command = GetCommand(commandName, args.Length);
            var commands = GetCommands(commandName);

            await DiscordBot.Log(context.LogMessage(commandName));

            List <object>  values       = null;
            ICommandResult error        = null;
            MethodInfo     commandToRun = null;

            foreach (var command in commands)
            {
                var parameters         = command.GetParameters();
                var requiredParameters = parameters.Where(param => !param.IsOptional).ToArray();

                Type contextType = context.GetType();
                if (!parameters[0].ParameterType.IsAssignableFrom(contextType))
                {
                    string message = $"That command is not valid in the context {context.GetType().Name}";
                    error = error ?? new ErrorResult(message, "Invalid Context");
                    continue;
                }

                if (args.Length < requiredParameters.Length - 1)
                {
                    string message = $"The syntax of the command was incorrect. The following parameters are required: `{string.Join("`, `", requiredParameters.Select(param => param.GetCustomAttribute<DisplayNameAttribute>()?.Name ?? param.Name).Skip(args.Length + 1))}`\nUse `{prefix}help {commandName}` for command info";
                    error = error ?? new ErrorResult(message, "Syntax Error");
                    continue;
                }

                if (context is DiscordMessageContext discordContext)
                {
                    if (!(command.GetCustomAttribute <CommandScopeAttribute>()?.ChannelTypes.Contains(discordContext.ChannelType) ?? true))
                    {
                        string message = $"The command `{prefix}{commandName}` is not valid in the scope {discordContext.ChannelType}";
                        error = error ?? new ErrorResult(message, "Scope Error");
                        continue;
                    }

                    string permissionError = command.GetCustomAttribute <PermissionsAttribute>()?.GetPermissionError(discordContext);
                    if (permissionError != null)
                    {
                        error = error ?? new ErrorResult(permissionError, "Permission Error");
                        continue;
                    }
                }

                values = new List <object>
                {
                    context
                };

                bool err = false;
                for (int i = 1; i < parameters.Length; i++)
                {
                    if (parameters[i].IsOptional && i > args.Length)
                    {
                        values.Add(Type.Missing);
                        continue;
                    }

                    if (i == parameters.Length - 1 && parameters[i].IsDefined(typeof(JoinRemainingParametersAttribute)))
                    {
                        if (parameters[i].ParameterType == typeof(string))
                        {
                            values.Add(string.Join(" ", args.Skip(i - 1)));
                        }
                        else if (parameters[i].ParameterType == typeof(string[]))
                        {
                            values.Add(args.Skip(i - 1).ToArray());
                        }
                        else
                        {
                            object converted = ConvertToType(parameters[i].ParameterType, string.Join(" ", args.Skip(i - 1)), context);
                            if (converted == null)
                            {
                                error = error ?? ThrowTypeError(context, string.Join(" ", args.Skip(i - 1)), parameters[i]);
                                err   = true;
                                break;
                            }
                            values.Add(converted);
                        }
                        break;
                    }

                    var result = ConvertToType(parameters[i].ParameterType, args[i - 1], context);
                    if (result == null)
                    {
                        error = error ?? ThrowTypeError(context, args[i - 1], parameters[i]);
                        err   = true;
                        break;
                    }

                    values.Add(result);
                }

                if (err)
                {
                    continue;
                }
                error        = null;
                commandToRun = command;
                break;
            }

            if (args.Length > 0 && context is DiscordMessageContext d && args[0] == "help" && commandName != "help")
            {
                var embed = new EmbedBuilder()
                            .WithDescription($"Did you mean `{prefix}help {commandName}`?")
                            .WithColor(new Color(0x2AC2E9))
                            .WithAuthor(author =>
                {
                    author
                    .WithName("Help")
                    .WithIconUrl("https://www.shareicon.net/data/128x128/2016/08/18/809295_info_512x512.png");
                });
                await d.Reply("", embed : embed.Build());
            }

            if (error != null)
            {
                await context.ReplyError(error.Message, ((ErrorResult)error).Title);

                return(error);
            }
            else
            {
                if (awaitResult)
                {
                    return(await RunCommand(context, commandToRun, values.ToArray()));
                }

#pragma warning disable 4014
                RunCommand(context, commandToRun, values.ToArray());
#pragma warning restore 4014
                return(new SuccessResult());
            }
        }