diff --git a/src/main/java/me/goudham/command/CommandLoader.java b/src/main/java/me/goudham/command/CommandLoader.java new file mode 100644 index 00000000..167ab80a --- /dev/null +++ b/src/main/java/me/goudham/command/CommandLoader.java @@ -0,0 +1,10 @@ +package me.goudham.command; + +import io.micronaut.inject.BeanDefinition; +import java.util.List; +import java.util.Map; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; + +public interface CommandLoader { + List loadIntoMapAndReturnCommands(Map> commandMap); +} diff --git a/src/main/java/me/goudham/command/SlashCommandLoader.java b/src/main/java/me/goudham/command/SlashCommandLoader.java new file mode 100644 index 00000000..2acaf698 --- /dev/null +++ b/src/main/java/me/goudham/command/SlashCommandLoader.java @@ -0,0 +1,183 @@ +package me.goudham.command; + +import io.micronaut.context.BeanContext; +import io.micronaut.core.annotation.AnnotationValue; +import io.micronaut.core.annotation.Introspected; +import io.micronaut.inject.BeanDefinition; +import io.micronaut.inject.qualifiers.Qualifiers; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import me.goudham.command.annotation.Choice; +import me.goudham.command.annotation.Command; +import me.goudham.command.annotation.Option; +import me.goudham.command.annotation.SubCommand; +import me.goudham.command.annotation.SubCommandGroup; +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.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; + +@Singleton +@Introspected +public class SlashCommandLoader implements CommandLoader { + private final BeanContext beanContext; + + @Inject + public SlashCommandLoader(BeanContext beanContext) { + this.beanContext = beanContext; + } + + @Override + public List loadIntoMapAndReturnCommands(Map> commandMap) { + Collection> beanDefinitions = beanContext.getBeanDefinitions(Qualifiers.byStereotype(Command.class)); + List commandDataList = new ArrayList<>(); + + for (BeanDefinition beanDefinition : beanDefinitions) { + AnnotationValue slashCommand = beanDefinition.getDeclaredAnnotation("me.goudham.command.annotation.Command"); + if (slashCommand != null) { + String name = slashCommand.stringValue("name").orElseThrow(); + String description = slashCommand.stringValue("description").orElseThrow(); + boolean isVisible = slashCommand.booleanValue("isVisible").orElseThrow(); + + CommandData commandData = new CommandData(name, description); + commandData.setDefaultEnabled(isVisible); + + List subcommandGroupDataList = loadSubCommandGroups(slashCommand); + List subcommandData = loadSubCommands(slashCommand); + List optionData = loadOptions(slashCommand); + + if (subcommandGroupDataList != null) commandData.addSubcommandGroups(subcommandGroupDataList); + if (subcommandData != null) commandData.addSubcommands(subcommandData); + if (optionData != null) commandData.addOptions(optionData); + + commandDataList.add(commandData); + commandMap.put(name, beanDefinition); + } else { + throw new RuntimeException(); + } + } + + return commandDataList; + } + + private List loadSubCommandGroups(AnnotationValue slashCommand) { + if (slashCommand.contains("subCommandGroups")) { + List subcommandGroupDataList = new ArrayList<>(); + List> subCommandGroupAnnotations = slashCommand.getAnnotations("subCommandGroups", SubCommandGroup.class); + for (AnnotationValue subCommandGroup : subCommandGroupAnnotations) { + String name = subCommandGroup.stringValue("name").orElseThrow(); + String description = subCommandGroup.stringValue("description").orElseThrow(); + + SubcommandGroupData subcommandGroupData = new SubcommandGroupData(name, description); + List subcommandData = loadSubCommands(subCommandGroup); + if (subcommandData != null) subcommandGroupData.addSubcommands(subcommandData); + + subcommandGroupDataList.add(subcommandGroupData); + } + + return subcommandGroupDataList; + } + + return null; + } + + private List loadSubCommands(AnnotationValue slashCommand) { + if (slashCommand.contains("subCommands")) { + List subcommandDataList = new ArrayList<>(); + List> subCommandAnnotations = slashCommand.getAnnotations("subCommands", SubCommand.class); + + for (AnnotationValue subCommand : subCommandAnnotations) { + String name = subCommand.stringValue("name").orElseThrow(); + String description = subCommand.stringValue("description").orElseThrow(); + + SubcommandData subCommandData = new SubcommandData(name, description); + List optionData = loadOptions(subCommand); + if (optionData != null) subCommandData.addOptions(optionData); + + + subcommandDataList.add(subCommandData); + } + + return subcommandDataList; + } + + return null; + } + + private List loadOptions(AnnotationValue slashCommand) { + if (slashCommand.contains("options")) { + List optionList = new ArrayList<>(); + List> optionAnnotations = slashCommand.getAnnotations("options", Option.class); + + for (AnnotationValue