Remove the need to register slash commands separately
All checks were successful
continuous-integration/drone/push Build is passing

We modified the slash command interface to allow getting command data, and created a generic implementation of it that automatically retrieves data from the command data. The interface should not be used now. Instead, extending the implementation is preferred as it provides a semi-working command already.
This commit is contained in:
Bea 2022-11-22 16:39:31 +01:00
parent ee263a1297
commit a7ac446b0b
12 changed files with 126 additions and 65 deletions

View File

@ -4,16 +4,22 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
public class AvatarCommand implements SlashCommand
public class AvatarCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "avatar";
public CommandData getSlashCommandData() {
return Commands.slash("avatar", "Get someone's profile picture.")
.addOption(OptionType.USER, "user", "User you want to grab the avatar of.")
.addOption(OptionType.INTEGER, "size", "The size of the returned image.",
false,
true);
}
@Override

View File

@ -2,22 +2,24 @@ package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
import wtf.beatrice.hidekobot.util.FormatUtil;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.List;
public class BotInfoCommand implements SlashCommand
public class BotInfoCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "botinfo";
public CommandData getSlashCommandData() {
return Commands.slash("botinfo", "Get info about the bot.");
}
@Override

View File

@ -1,5 +1,6 @@
package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageHistory;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
@ -8,22 +9,28 @@ import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
import java.util.ArrayList;
import java.util.List;
public class ClearCommand implements SlashCommand
public class ClearCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "clear";
public CommandData getSlashCommandData() {
return Commands.slash("clear", "Clear the current channel's chat.")
.addOption(OptionType.INTEGER, "amount", "The amount of messages to delete.")
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE));
}
@Override

View File

@ -5,21 +5,25 @@ import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
import wtf.beatrice.hidekobot.util.RandomUtil;
import java.util.List;
public class CoinFlipCommand implements SlashCommand
public class CoinFlipCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "coinflip";
public CommandData getSlashCommandData()
{
return Commands.slash("coinflip",
"Flip a coin and get head or tails.");
}
private final Button reflipButton = Button.primary("coinflip_reflip", "Flip again")

View File

@ -1,20 +1,23 @@
package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class DieCommand implements SlashCommand
public class DieCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "die";
public CommandData getSlashCommandData() {
return Commands.slash("die", "Stop the bot's process.")
.setDefaultPermissions(DefaultMemberPermissions.DISABLED);
}
@Override

View File

@ -2,16 +2,19 @@ package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
public class HelpCommand implements SlashCommand
public class HelpCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "help";
public CommandData getSlashCommandData()
{
return Commands.slash("help",
"Get general help on the bot.");
}
@Override

View File

@ -5,22 +5,26 @@ import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
public class InviteCommand implements SlashCommand
public class InviteCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "invite";
public CommandData getSlashCommandData()
{
return Commands.slash("invite", "Get an invite link for the bot.");
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{

View File

@ -1,14 +1,19 @@
package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
public class PingCommand implements SlashCommand
public class PingCommand extends SlashCommandImpl
{
@Override
public String getCommandName() {
return "ping";
public CommandData getSlashCommandData()
{
return Commands.slash("ping",
"Test if the bot is responsive.");
}
@Override

View File

@ -1,18 +1,28 @@
package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
public class SayCommand implements SlashCommand
public class SayCommand extends SlashCommandImpl
{
@Override
public CommandData getSlashCommandData()
{
@Override
public String getCommandName() {
return "say";
return Commands.slash("say", "Make the bot say something.")
.addOption(OptionType.STRING, "text",
"The message to send.",
true,
false)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE));
}
@Override

View File

@ -1,10 +1,12 @@
package wtf.beatrice.hidekobot.objects;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import org.jetbrains.annotations.NotNull;
public interface SlashCommand
{
/**
* Get the command's registered label, or how Discord sees and runs the registered command.
*
@ -12,6 +14,13 @@ public interface SlashCommand
*/
String getCommandName();
/**
* Get a JDA command data object that will then be used to tell the Discord API the specifics of this
* command.
*
* @return the command data object.
*/
CommandData getSlashCommandData();
/**
* Run the command logic by parsing the event and replying accordingly.
*

View File

@ -0,0 +1,24 @@
package wtf.beatrice.hidekobot.objects;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import org.jetbrains.annotations.NotNull;
public class SlashCommandImpl implements SlashCommand
{
@Override
public String getCommandName() {
return getSlashCommandData().getName();
}
@Override
public CommandData getSlashCommandData() {
return null;
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event) {
event.reply("Base command implementation").queue();
}
}

View File

@ -1,14 +1,12 @@
package wtf.beatrice.hidekobot.util;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.listeners.MessageCommandListener;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import java.util.ArrayList;
import java.util.List;
@ -18,28 +16,14 @@ public class SlashCommandUtil
private static final Logger logger = new Logger(MessageCommandListener.class);
static List<CommandData> allCommands = new ArrayList<>()
{{
add(Commands.slash("avatar", "Get someone's profile picture.")
.addOption(OptionType.USER, "user", "User you want to grab the avatar of.")
.addOption(OptionType.INTEGER, "size", "The size of the returned image.", false, true));
add(Commands.slash("botinfo", "Get info about the bot."));
add(Commands.slash("die", "Stop the bot's process.")
.setDefaultPermissions(DefaultMemberPermissions.DISABLED));
add(Commands.slash("clear", "Clear the current channel's chat.")
.addOption(OptionType.INTEGER, "amount", "The amount of messages to delete.")
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE)));
add(Commands.slash("coinflip", "Flip a coin and get head or tails."));
add(Commands.slash("help", "Get general help on the bot."));
add(Commands.slash("invite", "Get an invite link for the bot."));
add(Commands.slash("ping", "Test if the bot is responsive."));
add(Commands.slash("say", "Make the bot say something.")
.addOption(OptionType.STRING, "text", "The message to send.", true, false)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE)));
}};
public static void updateSlashCommands(boolean force)
{
// populate commands list from registered commands
List<CommandData> allCommands = new ArrayList<>();
for(SlashCommand cmd : Cache.getSlashCommandListener().getRegisteredCommands())
{ allCommands.add(cmd.getSlashCommandData()); }
JDA jdaInstance = HidekoBot.getAPI();
// get all the already registered commands