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.entities.User;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping; 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 org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache; 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 @Override
public String getCommandName() { public CommandData getSlashCommandData() {
return "avatar"; 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 @Override

View File

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

View File

@ -1,5 +1,6 @@
package wtf.beatrice.hidekobot.commands.slash; 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.Message;
import net.dv8tion.jda.api.entities.MessageHistory; import net.dv8tion.jda.api.entities.MessageHistory;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; 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.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionHook; 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.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.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction; import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache; import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand; import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ClearCommand implements SlashCommand public class ClearCommand extends SlashCommandImpl
{ {
@Override @Override
public String getCommandName() { public CommandData getSlashCommandData() {
return "clear"; 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 @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.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; 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.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache; import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand; import wtf.beatrice.hidekobot.objects.SlashCommandImpl;
import wtf.beatrice.hidekobot.util.RandomUtil; import wtf.beatrice.hidekobot.util.RandomUtil;
import java.util.List; import java.util.List;
public class CoinFlipCommand implements SlashCommand public class CoinFlipCommand extends SlashCommandImpl
{ {
@Override @Override
public String getCommandName() { public CommandData getSlashCommandData()
return "coinflip"; {
return Commands.slash("coinflip",
"Flip a coin and get head or tails.");
} }
private final Button reflipButton = Button.primary("coinflip_reflip", "Flip again") private final Button reflipButton = Button.primary("coinflip_reflip", "Flip again")

View File

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

View File

@ -2,16 +2,19 @@ package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 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 org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache; 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 @Override
public String getCommandName() { public CommandData getSlashCommandData()
return "help"; {
return Commands.slash("help",
"Get general help on the bot.");
} }
@Override @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.channel.ChannelType;
import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 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.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction; import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache; import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot; 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 @Override
public String getCommandName() { public CommandData getSlashCommandData()
return "invite"; {
return Commands.slash("invite", "Get an invite link for the bot.");
} }
@Override @Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event) public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{ {

View File

@ -1,14 +1,19 @@
package wtf.beatrice.hidekobot.commands.slash; package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 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 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 @Override
public String getCommandName() { public CommandData getSlashCommandData()
return "ping"; {
return Commands.slash("ping",
"Test if the bot is responsive.");
} }
@Override @Override

View File

@ -1,18 +1,28 @@
package wtf.beatrice.hidekobot.commands.slash; 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.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 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.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 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()
{ {
return Commands.slash("say", "Make the bot say something.")
@Override .addOption(OptionType.STRING, "text",
public String getCommandName() { "The message to send.",
return "say"; true,
false)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE));
} }
@Override @Override

View File

@ -1,10 +1,12 @@
package wtf.beatrice.hidekobot.objects; package wtf.beatrice.hidekobot.objects;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public interface SlashCommand public interface SlashCommand
{ {
/** /**
* Get the command's registered label, or how Discord sees and runs the registered command. * Get the command's registered label, or how Discord sees and runs the registered command.
* *
@ -12,6 +14,13 @@ public interface SlashCommand
*/ */
String getCommandName(); 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. * 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; package wtf.beatrice.hidekobot.util;
import net.dv8tion.jda.api.JDA; 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.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.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands; import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot; import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.listeners.MessageCommandListener; import wtf.beatrice.hidekobot.listeners.MessageCommandListener;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -18,28 +16,14 @@ public class SlashCommandUtil
private static final Logger logger = new Logger(MessageCommandListener.class); 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) 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(); JDA jdaInstance = HidekoBot.getAPI();
// get all the already registered commands // get all the already registered commands