|
| 1 | +/* |
| 2 | + * MMDBot - https://github.com/MinecraftModDevelopment/MMDBot |
| 3 | + * Copyright (C) 2016-2021 <MMD - MinecraftModDevelopment> |
| 4 | + * |
| 5 | + * This library is free software; you can redistribute it and/or |
| 6 | + * modify it under the terms of the GNU Lesser General Public |
| 7 | + * License as published by the Free Software Foundation; either |
| 8 | + * version 2.1 of the License, or (at your option) any later version. |
| 9 | + * |
| 10 | + * This library is distributed in the hope that it will be useful, |
| 11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | + * Lesser General Public License for more details. |
| 14 | + * |
| 15 | + * You should have received a copy of the GNU Lesser General Public |
| 16 | + * License along with this library; if not, write to the Free Software |
| 17 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
| 18 | + * USA |
| 19 | + * https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html |
| 20 | + */ |
| 21 | +package com.mcmoddev.mmdbot.modules.commands.bot.info; |
| 22 | + |
| 23 | +import com.jagrosh.jdautilities.command.Command; |
| 24 | +import com.jagrosh.jdautilities.command.CommandEvent; |
| 25 | +import com.mcmoddev.mmdbot.MMDBot; |
| 26 | +import com.mcmoddev.mmdbot.core.References; |
| 27 | +import com.mcmoddev.mmdbot.modules.commands.CommandModule; |
| 28 | +import net.dv8tion.jda.api.EmbedBuilder; |
| 29 | +import net.dv8tion.jda.api.entities.Emoji; |
| 30 | +import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; |
| 31 | +import net.dv8tion.jda.api.hooks.ListenerAdapter; |
| 32 | +import net.dv8tion.jda.api.interactions.components.Button; |
| 33 | +import net.dv8tion.jda.api.interactions.components.Component; |
| 34 | +import net.dv8tion.jda.api.requests.restaction.MessageAction; |
| 35 | +import org.jetbrains.annotations.NotNull; |
| 36 | + |
| 37 | +import java.time.Instant; |
| 38 | +import java.util.ArrayList; |
| 39 | +import java.util.List; |
| 40 | + |
| 41 | +/** |
| 42 | + * This command doesn't use the normal syntax. |
| 43 | + * Instead, it provides a single Consumer<CommandEvent> that the CommandClient can use. |
| 44 | + * |
| 45 | + * This should not be turned into a normal Command. |
| 46 | + * |
| 47 | + * @author Curle |
| 48 | + */ |
| 49 | +public class CmdHelp { |
| 50 | + |
| 51 | + private static final int COMMANDS_PER_PAGE = 25; |
| 52 | + |
| 53 | + /** |
| 54 | + * Prepare the potential scrolling buttons for a help command, |
| 55 | + * and send the message with the proper embeds. |
| 56 | + * |
| 57 | + * See {@link #getHelpStartingAt(int)} for the implementation. |
| 58 | + * @param e |
| 59 | + */ |
| 60 | + public static void execute(CommandEvent e) { |
| 61 | + MessageAction reply = e.getChannel().sendMessageEmbeds(getHelpStartingAt(0).build()); |
| 62 | + Component[] buttons = createScrollButtons(0); |
| 63 | + if (buttons.length > 0) |
| 64 | + reply.setActionRow(buttons); |
| 65 | + |
| 66 | + reply.queue(); |
| 67 | + } |
| 68 | + |
| 69 | + /** |
| 70 | + * Create the row of Component interaction buttons. |
| 71 | + * <p> |
| 72 | + * Currently, this just creates a left and right arrow. |
| 73 | + * Left arrow scrolls back a page. Right arrow scrolls forward a page. |
| 74 | + * |
| 75 | + * @param start The quote number at the start of the current page. |
| 76 | + * @return A row of buttons to go back and forth by one page in a quote list. |
| 77 | + */ |
| 78 | + private static Component[] createScrollButtons(int start) { |
| 79 | + List<Component> components = new ArrayList<>(); |
| 80 | + if (start != 0) { |
| 81 | + components.add(Button.secondary(ButtonListener.BUTTON_ID_PREFIX + "-" + start + "-prev", |
| 82 | + Emoji.fromUnicode("◀️"))); |
| 83 | + } |
| 84 | + if (start + COMMANDS_PER_PAGE < CommandModule.getCommandClient().getCommands().size() + CommandModule.getCommandClient().getSlashCommands().size()) { |
| 85 | + components.add(Button.primary(ButtonListener.BUTTON_ID_PREFIX + "-" + start + "-next", |
| 86 | + Emoji.fromUnicode("▶️"))); |
| 87 | + } |
| 88 | + return components.toArray(new Component[0]); |
| 89 | + } |
| 90 | + |
| 91 | + /** |
| 92 | + * Given a starting index, build an embed that we can display for users |
| 93 | + * to summarise all available commands. |
| 94 | + * Intended to be used with pagination in the case of servers with LOTS of commands. |
| 95 | + */ |
| 96 | + private static EmbedBuilder getHelpStartingAt(int index) { |
| 97 | + EmbedBuilder embed = new EmbedBuilder(); |
| 98 | + embed.setAuthor(References.NAME, References.ISSUE_TRACKER, MMDBot.getInstance().getSelfUser().getAvatarUrl()); |
| 99 | + embed.setDescription("All registered commands:"); |
| 100 | + |
| 101 | + List<Command> commandList = CommandModule.getCommandClient().getCommands(); |
| 102 | + commandList.addAll(CommandModule.getCommandClient().getSlashCommands()); |
| 103 | + |
| 104 | + // Embeds have a 25 field limit. We need to make sure we don't exceed that. |
| 105 | + if(commandList.size() < 25) { |
| 106 | + for (Command c : commandList) |
| 107 | + embed.addField(c.getName(), c.getHelp(), true); |
| 108 | + } else { |
| 109 | + // Make sure we only go up to the limit. |
| 110 | + for (int i = index; i < index + 25; i++) |
| 111 | + if (i < commandList.size()) |
| 112 | + embed.addField(commandList.get(i).getName(), commandList.get(i).getHelp(), true); |
| 113 | + } |
| 114 | + |
| 115 | + embed.setFooter(References.NAME).setTimestamp(Instant.now()); |
| 116 | + |
| 117 | + return embed; |
| 118 | + } |
| 119 | + |
| 120 | + public static class ButtonListener extends ListenerAdapter { |
| 121 | + private static final String BUTTON_ID_PREFIX = "help"; |
| 122 | + |
| 123 | + @Override |
| 124 | + public void onButtonClick(@NotNull final ButtonClickEvent event) { |
| 125 | + var button = event.getButton(); |
| 126 | + if (button == null || button.getId() == null) { |
| 127 | + return; |
| 128 | + } |
| 129 | + |
| 130 | + String[] idParts = button.getId().split("-"); |
| 131 | + if (idParts.length != 3) { |
| 132 | + return; |
| 133 | + } |
| 134 | + |
| 135 | + if (!idParts[0].equals(BUTTON_ID_PREFIX)) { |
| 136 | + return; |
| 137 | + } |
| 138 | + |
| 139 | + int current = Integer.parseInt(idParts[1]); |
| 140 | + |
| 141 | + if (idParts[2].equals("next")) { |
| 142 | + event |
| 143 | + .editMessageEmbeds(getHelpStartingAt(current + COMMANDS_PER_PAGE).build()) |
| 144 | + .setActionRow(createScrollButtons(current + COMMANDS_PER_PAGE)) |
| 145 | + .queue(); |
| 146 | + } else { |
| 147 | + if (idParts[2].equals("prev")) { |
| 148 | + event |
| 149 | + .editMessageEmbeds(getHelpStartingAt(current - COMMANDS_PER_PAGE).build()) |
| 150 | + .setActionRow(createScrollButtons(current - COMMANDS_PER_PAGE)) |
| 151 | + .queue(); |
| 152 | + } |
| 153 | + } |
| 154 | + } |
| 155 | + } |
| 156 | + } |
| 157 | + |
0 commit comments