2024-06-24 12:56:01 +00:00
|
|
|
package cc.fascinated.bat.service;
|
|
|
|
|
|
|
|
import cc.fascinated.bat.command.BatCommand;
|
|
|
|
import cc.fascinated.bat.command.BatSubCommand;
|
|
|
|
import cc.fascinated.bat.common.EmbedUtils;
|
2024-06-25 11:16:20 +00:00
|
|
|
import cc.fascinated.bat.features.scoresaber.command.numberone.NumberOneFeedCommand;
|
2024-06-25 09:40:17 +00:00
|
|
|
import cc.fascinated.bat.features.scoresaber.command.scoresaber.ScoreSaberCommand;
|
2024-06-25 10:14:12 +00:00
|
|
|
import cc.fascinated.bat.features.scoresaber.command.userfeed.UserFeedCommand;
|
2024-06-25 10:55:26 +00:00
|
|
|
import cc.fascinated.bat.model.BatGuild;
|
|
|
|
import cc.fascinated.bat.model.BatUser;
|
2024-06-24 12:56:01 +00:00
|
|
|
import lombok.NonNull;
|
|
|
|
import lombok.extern.log4j.Log4j2;
|
|
|
|
import net.dv8tion.jda.api.JDA;
|
|
|
|
import net.dv8tion.jda.api.entities.Guild;
|
|
|
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
|
|
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
|
import org.springframework.context.annotation.DependsOn;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Fascinated (fascinated7)
|
|
|
|
*/
|
|
|
|
@Service @Log4j2
|
|
|
|
@DependsOn("discordService")
|
|
|
|
public class CommandService extends ListenerAdapter {
|
|
|
|
/**
|
|
|
|
* The registered commands
|
|
|
|
*/
|
|
|
|
private final Map<String, BatCommand> commands = new HashMap<>();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The guild service to use
|
|
|
|
*/
|
|
|
|
private final GuildService guildService;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The user service to use
|
|
|
|
*/
|
|
|
|
private final UserService userService;
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
public CommandService(@NonNull GuildService guildService, @NonNull UserService userService, @NonNull ApplicationContext context) {
|
|
|
|
this.guildService = guildService;
|
|
|
|
this.userService = userService;
|
|
|
|
DiscordService.JDA.addEventListener(this);
|
|
|
|
|
|
|
|
// Guild commands
|
2024-06-25 10:19:51 +00:00
|
|
|
registerCommand(context.getBean(UserFeedCommand.class));
|
2024-06-25 11:16:20 +00:00
|
|
|
registerCommand(context.getBean(NumberOneFeedCommand.class));
|
2024-06-24 12:56:01 +00:00
|
|
|
|
|
|
|
// Global commands
|
2024-06-25 10:19:51 +00:00
|
|
|
registerCommand(context.getBean(ScoreSaberCommand.class));
|
2024-06-24 12:56:01 +00:00
|
|
|
|
|
|
|
registerSlashCommands(); // Register all slash commands
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Registers a command
|
|
|
|
*
|
|
|
|
* @param command The command to register
|
|
|
|
*/
|
|
|
|
public void registerCommand(@NonNull BatCommand command) {
|
|
|
|
commands.put(command.getName().toLowerCase(), command);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Registers all slash commands
|
|
|
|
*/
|
|
|
|
public void registerSlashCommands() {
|
|
|
|
log.info("Registering all slash commands");
|
|
|
|
JDA jda = DiscordService.JDA;
|
|
|
|
long before = System.currentTimeMillis();
|
|
|
|
|
|
|
|
// Unregister all commands that Discord has but we don't
|
|
|
|
jda.retrieveCommands().complete().forEach(command -> {
|
|
|
|
if (commands.containsKey(command.getName())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
jda.deleteCommandById(command.getId()).complete(); // Unregister the command on Discord
|
|
|
|
log.info("Unregistered unknown command \"{}\" from Discord", command.getName());
|
|
|
|
});
|
|
|
|
|
|
|
|
// Register all commands
|
2024-06-24 14:45:53 +00:00
|
|
|
jda.updateCommands().addCommands(commands.values().stream().map(BatCommand::getCommandData).toList()).complete();
|
2024-06-24 12:56:01 +00:00
|
|
|
log.info("Registered all slash commands in {}ms", System.currentTimeMillis() - before);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
|
|
|
|
Guild discordGuild = event.getGuild();
|
2024-06-25 10:14:12 +00:00
|
|
|
if (discordGuild == null || event.getUser().isBot() || event.getMember() == null) {
|
2024-06-24 12:56:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String commandName = event.getName();
|
|
|
|
BatCommand command = commands.get(commandName);
|
|
|
|
if (command == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BatGuild guild = guildService.getGuild(discordGuild.getId());
|
|
|
|
BatUser user = userService.getUser(event.getUser().getId());
|
|
|
|
try {
|
2024-06-25 10:14:12 +00:00
|
|
|
// No args provided, use the main command executor
|
2024-06-24 16:42:57 +00:00
|
|
|
if (event.getInteraction().getSubcommandName() == null) {
|
|
|
|
command.execute(guild, user, event.getChannel().asTextChannel(), event.getMember(), event.getInteraction());
|
2024-06-25 10:14:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subcommand provided, use the subcommand executor
|
|
|
|
for (Map.Entry<String, BatSubCommand> subCommand : command.getSubCommands().entrySet()) {
|
|
|
|
if (subCommand.getKey().equalsIgnoreCase(event.getInteraction().getSubcommandName())) {
|
|
|
|
subCommand.getValue().execute(guild, user, event.getChannel().asTextChannel(), event.getMember(), event.getInteraction());
|
|
|
|
break;
|
2024-06-24 12:56:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (Exception ex) {
|
|
|
|
log.error("An error occurred while executing command \"{}\"", commandName, ex);
|
|
|
|
event.replyEmbeds(EmbedUtils.buildErrorEmbed("An error occurred while executing the command\n\n" +
|
|
|
|
ex.getLocalizedMessage()).build()).queue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|