Exemplo n.º 1
0
        public async Task DefaultHelpAsync(CommandContext ctx, [Description("Optional command to provide help for.")] params string[] command)
        {
            // We have to use reflection because TopLevelCommands is marked private and we're not forking DSharpPlus
            PropertyInfo TopLevelCommandsProp   = typeof(CommandsNextExtension).GetProperty("TopLevelCommands", BindingFlags.NonPublic | BindingFlags.Instance);
            MethodInfo   TopLevelCommandsGetter = TopLevelCommandsProp.GetGetMethod(nonPublic: true);
            var          toplevel = ((Dictionary <string, Command>)TopLevelCommandsGetter.Invoke(ctx.CommandsNext, null)).Values.Distinct();

            // We instance our help formatter directly because we don't have access to the help formatting factory
            var helpbuilder = new HelpFormatter(ctx);

            if (command != null && command.Any())
            {
                Command cmd       = null;
                var     search_in = toplevel;
                foreach (var c in command)
                {
                    if (search_in == null)
                    {
                        cmd = null;
                        break;
                    }

                    // We don't have access to config so f**k it, case insensitive help
                    //if (ctx.Config.CaseSensitive)
                    //    cmd = search_in.FirstOrDefault(xc => xc.Name == c || (xc.Aliases != null && xc.Aliases.Contains(c)));
                    //else
                    cmd = search_in.FirstOrDefault(xc => xc.Name.ToLowerInvariant() == c.ToLowerInvariant() || (xc.Aliases != null && xc.Aliases.Select(xs => xs.ToLowerInvariant()).Contains(c.ToLowerInvariant())));

                    if (cmd == null)
                    {
                        break;
                    }

                    var cfl = await cmd.RunChecksAsync(ctx, true).ConfigureAwait(false);

                    if (cfl.Any())
                    {
                        throw new ChecksFailedException(cmd, ctx, cfl);
                    }

                    if (cmd is CommandGroup)
                    {
                        search_in = (cmd as CommandGroup).Children;
                    }
                    else
                    {
                        search_in = null;
                    }
                }

                if (cmd == null)
                {
                    throw new CommandNotFoundException(string.Join(" ", command));
                }

                helpbuilder.WithCommand(cmd);

                if (cmd is CommandGroup gx)
                {
                    var sxs = gx.Children.Where(xc => !xc.IsHidden);
                    var scs = new List <Command>();
                    foreach (var sc in sxs)
                    {
                        if (sc.ExecutionChecks == null || !sc.ExecutionChecks.Any())
                        {
                            scs.Add(sc);
                            continue;
                        }

                        var cfl = await sc.RunChecksAsync(ctx, true).ConfigureAwait(false);

                        if (!cfl.Any())
                        {
                            scs.Add(sc);
                        }
                    }

                    if (scs.Any())
                    {
                        helpbuilder.WithSubcommands(scs.OrderBy(xc => xc.Name));
                    }
                }
            }
            else
            {
                var sxs = toplevel.Where(xc => !xc.IsHidden);
                var scs = new List <Command>();
                foreach (var sc in sxs)
                {
                    if (sc.ExecutionChecks == null || !sc.ExecutionChecks.Any())
                    {
                        scs.Add(sc);
                        continue;
                    }

                    var cfl = await sc.RunChecksAsync(ctx, true).ConfigureAwait(false);

                    if (!cfl.Any())
                    {
                        scs.Add(sc);
                    }
                }

                if (scs.Any())
                {
                    helpbuilder.WithSubcommands(scs.OrderBy(xc => xc.Name));
                }
            }

            var hmsg = helpbuilder.Build();

            // The main reason for this change, allowing help to be DM'd and the original command deleted.
            DiscordHelpers.DeleteNonPrivateMessage(ctx);
            await DiscordHelpers.RespondAsDM(ctx, hmsg.Embed).ConfigureAwait(false);
        }