Make slash commands interface and load them dynamically
continuous-integration/drone/push Build is passing Details

Slash commands are now loaded dynamically by implementing a SlashCommand interface and storing them in a loaded commands map.
This commit is contained in:
Bea 2022-11-22 14:32:22 +01:00
parent 7ae4790d5c
commit 882c695484
13 changed files with 133 additions and 26 deletions

View File

@ -6,6 +6,7 @@ import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.requests.GatewayIntent;
import sun.misc.Signal;
import wtf.beatrice.hidekobot.commands.slash.*;
import wtf.beatrice.hidekobot.datasource.ConfigurationSource;
import wtf.beatrice.hidekobot.datasource.DatabaseSource;
import wtf.beatrice.hidekobot.listeners.ButtonInteractionListener;
@ -97,9 +98,21 @@ public class HidekoBot
}
// register commands
SlashCommandListener slashCommandListener = new SlashCommandListener();
slashCommandListener.registerCommand(new AvatarCommand());
slashCommandListener.registerCommand(new BotInfoCommand());
slashCommandListener.registerCommand(new ClearCommand());
slashCommandListener.registerCommand(new CoinFlipCommand());
slashCommandListener.registerCommand(new DieCommand());
slashCommandListener.registerCommand(new HelpCommand());
slashCommandListener.registerCommand(new InviteCommand());
slashCommandListener.registerCommand(new PingCommand());
slashCommandListener.registerCommand(new SayCommand());
// register listeners
jda.addEventListener(new MessageListener());
jda.addEventListener(new SlashCommandListener());
jda.addEventListener(slashCommandListener);
jda.addEventListener(new SlashCommandCompleter());
jda.addEventListener(new ButtonInteractionListener());

View File

@ -6,10 +6,17 @@ import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEve
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand;
public class AvatarCommand
public class AvatarCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "avatar";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
// defer reply because this might take a moment

View File

@ -6,15 +6,22 @@ import net.dv8tion.jda.api.interactions.commands.Command;
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.util.FormatUtil;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.List;
public class BotInfoCommand
public class BotInfoCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "botinfo";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
// defer reply because this might take a moment

View File

@ -13,13 +13,21 @@ 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 java.util.ArrayList;
import java.util.List;
public class ClearCommand
public class ClearCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "clear";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{

View File

@ -9,16 +9,23 @@ 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.util.RandomUtil;
import java.util.List;
public class CoinFlipCommand
public class CoinFlipCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "coinflip";
}
private final Button reflipButton = Button.primary("coinflip_reflip", "Flip again")
.withEmoji(Emoji.fromFormatted("\uD83E\uDE99"));
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
// perform coin flip

View File

@ -4,13 +4,20 @@ import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEve
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class DieCommand
public class DieCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "die";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
if(Cache.getBotOwnerId() != event.getUser().getIdLong())

View File

@ -4,10 +4,17 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.objects.SlashCommand;
public class HelpCommand
public class HelpCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "help";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
// defer reply because replying might take a while

View File

@ -11,9 +11,17 @@ 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;
public class InviteCommand
public class InviteCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "invite";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
// defer reply because this might take a moment

View File

@ -2,9 +2,16 @@ package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.objects.SlashCommand;
public class PingCommand
public class PingCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "ping";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
event.reply("Pong!").queue();

View File

@ -4,10 +4,18 @@ 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.OptionMapping;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.objects.SlashCommand;
public class SayCommand
public class SayCommand implements SlashCommand
{
@Override
public String getCommandName() {
return "say";
}
@Override
public void runSlashCommand(@NotNull SlashCommandInteractionEvent event)
{
MessageChannel channel = event.getChannel();

View File

@ -10,6 +10,12 @@ import wtf.beatrice.hidekobot.util.Logger;
public class MessageListener extends ListenerAdapter
{
private final String commandRegex = "(?i)^(hideko|hde)\\b";
// (?i) -> case insensitive flag
// ^ -> start of string (not in middle of a sentence)
// \b -> the word has to end here
// .* -> there can be anything else after this word
private final Logger logger = new Logger(MessageListener.class);
@Override
@ -17,24 +23,31 @@ public class MessageListener extends ListenerAdapter
{
String eventMessage = event.getMessage().getContentDisplay();
if(!eventMessage.toLowerCase().matches(commandRegex + ".*"))
return;
MessageChannel channel = event.getChannel();
// generate args from the string
String argsString = eventMessage.replaceAll(commandRegex + "\\s*", "");
String[] args = argsString.split("\\s+");
event.getMessage().reply("Hi").queue();
if(eventMessage.equalsIgnoreCase("hideko"))
{
MessageChannel channel = event.getChannel();
channel.sendMessage("Hello there! ✨").queue();
return;
}
if(eventMessage.equalsIgnoreCase("ping"))
{
MessageChannel channel = event.getChannel();
channel.sendMessage("Pong!").queue();
return;
}
if(eventMessage.equalsIgnoreCase("hideko verbose"))
{
MessageChannel channel = event.getChannel();
boolean verbose = Cache.isVerbose();
String msg = verbose ? "off" : "on";

View File

@ -3,24 +3,28 @@ package wtf.beatrice.hidekobot.listeners;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.commands.slash.*;
import wtf.beatrice.hidekobot.objects.SlashCommand;
import java.util.HashMap;
public class SlashCommandListener extends ListenerAdapter
{
HashMap<String, SlashCommand> registeredCommands = new HashMap<>();
public void registerCommand(SlashCommand command)
{
registeredCommands.remove(command.getCommandName());
registeredCommands.put(command.getCommandName(), command);
}
@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event)
{
switch (event.getName().toLowerCase()) {
case "avatar" -> new AvatarCommand().runSlashCommand(event);
case "botinfo" -> new BotInfoCommand().runSlashCommand(event);
case "clear" -> new ClearCommand().runSlashCommand(event);
case "coinflip" -> new CoinFlipCommand().runSlashCommand(event);
case "die" -> new DieCommand().runSlashCommand(event);
case "help" -> new HelpCommand().runSlashCommand(event);
case "invite" -> new InviteCommand().runSlashCommand(event);
case "ping" -> new PingCommand().runSlashCommand(event);
case "say" -> new SayCommand().runSlashCommand(event);
}
String commandName = event.getName().toLowerCase();
SlashCommand command = registeredCommands.get(commandName);
if(command == null) return;
command.runSlashCommand(event);
}
}

View File

@ -0,0 +1,11 @@
package wtf.beatrice.hidekobot.objects;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.jetbrains.annotations.NotNull;
public interface SlashCommand
{
String getCommandName();
void runSlashCommand(@NotNull SlashCommandInteractionEvent event);
}