diff --git a/README.md b/README.md index 450c9b94..ef33f61f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ -[![JDA-Version](https://img.shields.io/badge/JDA%20Version-5.0.0--beta.15-important)](https://github.com/DV8FromTheWorld/JDA#download) -[![Generic badge](https://img.shields.io/badge/Download-4.0.0--alpha.4-green.svg)](https://github.com/Kaktushose/jda-commands/releases/latest) +[![JDA-Version](https://img.shields.io/badge/JDA%20Version-5.0.0--beta.17-important)](https://github.com/DV8FromTheWorld/JDA#download) +[![Generic badge](https://img.shields.io/badge/Download-4.0.0--alpha.5-green.svg)](https://github.com/Kaktushose/jda-commands/releases/latest) [![Java CI](https://github.com/Kaktushose/jda-commands/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/Kaktushose/jda-commands/actions/workflows/ci.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/f2b4367f6d0f42d89b7e51331f3ce299)](https://app.codacy.com/gh/Kaktushose/jda-commands/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/f2b4367f6d0f42d89b7e51331f3ce299)](https://app.codacy.com/gh/Kaktushose/jda-commands/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage) [![license-shield](https://img.shields.io/badge/License-Apache%202.0-lightgrey.svg)]() -[![migration-shield](https://img.shields.io/badge/Wiki-Migrating%20to%20V4-green.svg)](https://github.com/Kaktushose/jda-commands/wiki/Migration) # JDA-Commands @@ -16,7 +15,7 @@ any boilerplate code, so you can focus solely on the business logic of your bot | jda-commands | JDA | Text Commands | Interactions | Stable | |-----------------------------------------------------------------------------|-|--|---|---| -| [4.0.0-alpha.4](https://github.com/Kaktushose/jda-commands/releases/latest) |5|❌|✅|❌| +| [4.0.0-alpha.5](https://github.com/Kaktushose/jda-commands/releases/latest) |5|❌|✅|❌| | [3.0.0](https://github.com/Kaktushose/jda-commands/releases/tag/v3.0.0) |5|✅|❌|✅| | [2.2.0](https://github.com/Kaktushose/jda-commands/releases/tag/v.2.0.0) |4|✅|❌|✅| diff --git a/pom.xml b/pom.xml index e7bcf30a..161303b7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.kaktushose jda-commands - 4.0.0-alpha.4 + 4.0.0-alpha.5 UTF-8 @@ -66,7 +66,7 @@ net.dv8tion JDA - 5.0.0-beta.15 + 5.0.0-beta.17 club.minnced diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java index 64fd02b3..f9cc21ee 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java +++ b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java @@ -2,7 +2,7 @@ import com.github.kaktushose.jda.commands.dependency.DependencyInjector; import com.github.kaktushose.jda.commands.dispatching.DispatcherSupervisor; -import com.github.kaktushose.jda.commands.dispatching.ParserSupervisor; +import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry; import com.github.kaktushose.jda.commands.dispatching.filter.FilterRegistry; import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; @@ -30,19 +30,19 @@ public class JDACommands { private final JDAContext jdaContext; private final ImplementationRegistry implementationRegistry; private final DispatcherSupervisor dispatcherSupervisor; - private final ParserSupervisor parserSupervisor; private final FilterRegistry filterRegistry; private final TypeAdapterRegistry adapterRegistry; private final ValidatorRegistry validatorRegistry; private final DependencyInjector dependencyInjector; private final InteractionRegistry interactionRegistry; private final SlashCommandUpdater updater; + private final RuntimeSupervisor runtimeSupervisor; // this is needed for unit testing protected JDACommands() { jdaContext = null; implementationRegistry = null; - parserSupervisor = null; + runtimeSupervisor = null; filterRegistry = null; adapterRegistry = null; validatorRegistry = null; @@ -74,16 +74,16 @@ private JDACommands(Object jda, Class clazz, LocalizationFunction function, S ); interactionRegistry = new InteractionRegistry(validatorRegistry, dependencyInjector, function); + runtimeSupervisor = new RuntimeSupervisor(dependencyInjector); dispatcherSupervisor = new DispatcherSupervisor(this); - parserSupervisor = new ParserSupervisor(dispatcherSupervisor); implementationRegistry.index(clazz, packages); interactionRegistry.index(clazz, packages); - updater = new SlashCommandUpdater(this, interactionRegistry.getCommands()); + updater = new SlashCommandUpdater(this); updater.updateAllCommands(); - jdaContext.performTask(it -> it.addEventListener(parserSupervisor)); + jdaContext.performTask(it -> it.addEventListener(dispatcherSupervisor)); isActive = true; log.info("Finished loading!"); @@ -153,7 +153,7 @@ public static boolean isActive() { * This will not unregister any slash commands. */ public void shutdown() { - jdaContext.performTask(jda -> jda.removeEventListener(parserSupervisor)); + jdaContext.performTask(jda -> jda.removeEventListener(dispatcherSupervisor)); isActive = false; } @@ -178,13 +178,14 @@ public ImplementationRegistry getImplementationRegistry() { return implementationRegistry; } + /** - * Gets the {@link ParserSupervisor}. + * Gets the {@link RuntimeSupervisor} * - * @return the {@link ParserSupervisor} + * @return the {@link RuntimeSupervisor} */ - public ParserSupervisor getParserSupervisor() { - return parserSupervisor; + public RuntimeSupervisor getRuntimeSupervisor() { + return runtimeSupervisor; } /** diff --git a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java index 84823184..d55e5110 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java +++ b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java @@ -2,9 +2,12 @@ import com.github.kaktushose.jda.commands.annotations.interactions.SlashCommand; import com.github.kaktushose.jda.commands.data.CommandTree; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.InteractionRegistry; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import com.github.kaktushose.jda.commands.scope.GuildScopeProvider; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; import org.slf4j.Logger; @@ -15,7 +18,7 @@ /** * Class that sends the {@link SlashCommandData} to Discord. Uses a {@link CommandTree} to properly transpile all - * {@link CommandDefinition CommandDefinitions} to {@link SlashCommandData}. + * {@link SlashCommandDefinition CommandDefinitions} to {@link SlashCommandData}. * * @author Kaktushose * @version 4.0.0 @@ -26,18 +29,18 @@ public class SlashCommandUpdater { private static final Logger log = LoggerFactory.getLogger(SlashCommandUpdater.class); private final JDAContext jdaContext; - private final Collection commands; private final GuildScopeProvider guildScopeProvider; + private final InteractionRegistry interactionRegistry; /** * Constructs a new SlashCommandUpdater. * * @param jdaCommands the corresponding {@link JDACommands} instance */ - public SlashCommandUpdater(JDACommands jdaCommands, Collection commands) { + public SlashCommandUpdater(JDACommands jdaCommands) { this.jdaContext = jdaCommands.getJdaContext(); - this.commands = commands; guildScopeProvider = jdaCommands.getImplementationRegistry().getGuildScopeProvider(); + interactionRegistry = jdaCommands.getInteractionRegistry(); } /** @@ -53,19 +56,34 @@ public void updateAllCommands() { * Sends the guild scope {@link SlashCommandData} to Discord. */ public void updateGuildCommands() { - log.debug("Updating guild slash commands..."); - Set globalCommands = commands.stream() + log.debug("Updating guild commands..."); + + Set guildCommands = interactionRegistry.getCommands() + .stream() .filter(it -> it.getCommandScope() == SlashCommand.CommandScope.GUILD) .collect(Collectors.toSet()); - CommandTree tree = new CommandTree(globalCommands); - log.debug("Generated command tree:\n" + tree); - Collection labels = tree.getNames(); - log.debug("Using commands: " + labels); - Map> guildMapping = new HashMap<>(); - for (SlashCommandData command : tree.getCommands()) { + CommandTree tree = new CommandTree( + guildCommands.stream() + .filter(it -> it.getCommandType() == Command.Type.SLASH) + .map(it -> (SlashCommandDefinition) it) + .collect(Collectors.toSet()) + ); + log.debug("Generated slash command tree:\n" + tree); + + Set result = new HashSet<>(); + result.addAll(tree.getCommands()); + result.addAll(guildCommands.stream(). + filter(it -> (it.getCommandType() == Command.Type.USER || it.getCommandType() == Command.Type.MESSAGE)) + .map(GenericCommandDefinition::toCommandData) + .collect(Collectors.toSet()) + ); + log.debug("Registering commands: " + result.stream().map(CommandData::getName).collect(Collectors.toSet())); + + Map> guildMapping = new HashMap<>(); + for (CommandData command : result) { // create a copy so that a user doesn't modify the command data used for registration - Set guildIds = guildScopeProvider.getGuildsForCommand(SlashCommandData.fromData(command.toData())); + Set guildIds = guildScopeProvider.getGuildsForCommand(CommandData.fromData(command.toData())); if (guildIds.isEmpty()) { log.debug("No guilds provided for command {}", command.getName()); } else { @@ -88,17 +106,31 @@ public void updateGuildCommands() { * Sends the global scope {@link SlashCommandData} to Discord. */ public void updateGlobalCommands() { - log.debug("Updating global slash commands..."); - Set globalCommands = commands.stream() + log.debug("Updating global commands..."); + + Set globalCommands = interactionRegistry.getCommands() + .stream() .filter(it -> it.getCommandScope() == SlashCommand.CommandScope.GLOBAL) .collect(Collectors.toSet()); - CommandTree tree = new CommandTree(globalCommands); - log.debug("Generated command tree:\n" + tree); - Collection labels = tree.getNames(); - log.debug("Using commands: " + labels); - jdaContext.performTask(jda -> jda.updateCommands().addCommands(tree.getCommands()).queue()); - log.debug("Done!"); - } + CommandTree tree = new CommandTree( + globalCommands.stream() + .filter(it -> it.getCommandType() == Command.Type.SLASH) + .map(it -> (SlashCommandDefinition) it) + .collect(Collectors.toSet()) + ); + log.debug("Generated slash command tree:\n" + tree); + + Set result = new HashSet<>(); + result.addAll(tree.getCommands()); + result.addAll(globalCommands.stream(). + filter(it -> (it.getCommandType() == Command.Type.USER || it.getCommandType() == Command.Type.MESSAGE)) + .map(GenericCommandDefinition::toCommandData) + .collect(Collectors.toSet()) + ); + log.debug("Registering commands: " + result.stream().map(CommandData::getName).collect(Collectors.toSet())); + jdaContext.performTask(jda -> jda.updateCommands().addCommands(result).queue()); + log.debug("Done!"); + } } diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Button.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Button.java index bd6e5cff..1ba53de1 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Button.java +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Button.java @@ -1,6 +1,6 @@ package com.github.kaktushose.jda.commands.annotations.interactions; -import com.github.kaktushose.jda.commands.dispatching.interactions.buttons.ButtonEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; @@ -16,7 +16,7 @@ * {@link Interaction}. * Furthermore, the method signature has to meet the following conditions: *
    - *
  • First parameter must be of type {@link ButtonEvent ButtonEvent}
  • + *
  • First parameter must be of type {@link ComponentEvent ButtonEvent}
  • *
* * @author Kaktushose diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java new file mode 100644 index 00000000..e8e9c3c2 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java @@ -0,0 +1,94 @@ +package com.github.kaktushose.jda.commands.annotations.interactions; + +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.interactions.commands.Command; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods annotated with ContextMenu will be registered as a context menu command. + * + *

Therefore the method must be declared inside a class that is annotated with + * {@link com.github.kaktushose.jda.commands.annotations.interactions.Interaction}. + * Furthermore, the method signature has to meet the following conditions: + *

    + *
  • First parameter must be of type {@link CommandEvent}
  • + *
+ * + * @author Kaktushose + * @version 4.0.0 + * @see com.github.kaktushose.jda.commands.annotations.interactions.Interaction Interaction + * @since 4.0.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ContextCommand { + + /** + * Returns the name of the command. + * + * @return the name of the command + */ + String value() default ""; + + /** + * Returns whether this command is only usable in a guild. + * This only has an effect if this command is registered globally. + * + * @return {@code true} if this command is only usable in a guild + */ + boolean isGuildOnly() default false; + + /** + * Returns whether this command is active and thus can be executed or not. + * + * @return {@code true} if this command is active + */ + boolean isActive() default true; + + /** + * Returns whether this command can only be executed in NSFW channels. + * + * @return {@code true} if this command can only be executed in NSFW channels + */ + boolean isNSFW() default false; + + /** + * Returns whether this command should send ephemeral replies by default. Note that {@link Interaction#ephemeral()} + * set to {@code true} will override this value. + * + * @return {@code true} if this command should send ephemeral replies + */ + boolean ephemeral() default false; + + /** + * Returns an array of {@link net.dv8tion.jda.api.Permission Permissions} this command + * should be enabled for by default. Note that guild admins can modify this at any time. + * + * @return a set of permissions this command will be enabled for by default + * @see Permissions Permission + * @see net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions DefaultMemberPermissions.ENABLED + * @see net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions DefaultMemberPermissions.DISABLED + */ + Permission[] enabledFor() default Permission.UNKNOWN; + + /** + * Returns whether this command should be registered as a global or as a guild command. + * + * @return whether this command should be registered as a global or as a guild command + * @see SlashCommand.CommandScope + */ + SlashCommand.CommandScope scope() default SlashCommand.CommandScope.GLOBAL; + + /** + * Gets the type of this command. + * + * @return the type of the command + */ + Command.Type type(); + +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/EntitySelectMenu.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/EntitySelectMenu.java index dd34fac2..6c82bad2 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/EntitySelectMenu.java +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/EntitySelectMenu.java @@ -1,6 +1,6 @@ package com.github.kaktushose.jda.commands.annotations.interactions; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu.SelectTarget; @@ -17,7 +17,7 @@ * Furthermore, the method signature has to meet the following conditions: *
    *
  • First parameter must be of type - * {@link SelectMenuEvent SelectMenuEvent}
  • + * {@link ComponentEvent SelectMenuEvent} *
* * @author Kaktushose diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Modal.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Modal.java new file mode 100644 index 00000000..869eba5c --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Modal.java @@ -0,0 +1,38 @@ +package com.github.kaktushose.jda.commands.annotations.interactions; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods annotated with Modal will be registered as a modal at startup. + * + *

Therefore the method must be declared inside a class that is annotated with + * {@link Interaction}. + * + * @author Kaktushose + * @version 4.0.0 + * @see Interaction + * @see TextInput + * @since 4.0.0 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Modal { + + /** + * Gets the title of this modal. + * + * @return the title of the modal + */ + String value(); + + /** + * Whether this Modal should send ephemeral replies by default. + * + * @return {@code true} if to send ephemeral replies + */ + boolean ephemeral() default false; + +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SelectOption.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SelectOption.java index 9182a820..413c9feb 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SelectOption.java +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SelectOption.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.annotations.interactions; import com.github.kaktushose.jda.commands.annotations.internal.SelectOptionContainer; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import net.dv8tion.jda.api.entities.emoji.Emoji; import java.lang.annotation.*; @@ -15,7 +15,7 @@ * Furthermore, the method signature has to meet the following conditions: *

    *
  • First parameter must be of type - * {@link SelectMenuEvent SelectMenuEvent}
  • + * {@link ComponentEvent SelectMenuEvent} * {@link StringSelectMenu} annotation must be present *
* diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/StringSelectMenu.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/StringSelectMenu.java index ad7f379c..0ff681b2 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/StringSelectMenu.java +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/StringSelectMenu.java @@ -1,6 +1,6 @@ package com.github.kaktushose.jda.commands.annotations.interactions; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -15,7 +15,7 @@ * Furthermore, the method signature has to meet the following conditions: *
    *
  • First parameter must be of type - * {@link SelectMenuEvent SelectMenuEvent}
  • + * {@link ComponentEvent SelectMenuEvent} *
* * @author Kaktushose diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/TextInput.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/TextInput.java new file mode 100644 index 00000000..5b0d8877 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/TextInput.java @@ -0,0 +1,74 @@ +package com.github.kaktushose.jda.commands.annotations.interactions; + +import net.dv8tion.jda.api.interactions.components.text.TextInputStyle; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to add TextInputs to {@link Modal Modals}. + * + * @author Kaktushose + * @version 4.0.0 + * @since 4.0.0 + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface TextInput { + + /** + * The label shown above this text input box + * + * @return Label for the input + */ + String label() default ""; + + /** + * The placeholder of this TextInput + *
This is the short hint that describes the expected value of the TextInput field. + * + * @return Placeholder + */ + String value() default ""; + + /** + * The default value of this TextInput. + *
This sets a pre-populated text for this TextInput field + * + * @return default value + */ + String defaultValue() default ""; + + /** + * The minimum length. This is -1 if none has been set. + * + * @return Minimum length or -1 + */ + int minValue() default -1; + + /** + * The maximum length. This is -1 if none has been set. + * + * @return Maximum length or -1 + */ + int maxValue() default -1; + + /** + * The {@link TextInputStyle TextInputStyle}. The default value is {@link TextInputStyle#PARAGRAPH}. + * + * @return The TextInputStyle + */ + TextInputStyle style() default TextInputStyle.PARAGRAPH; + + /** + * Whether this TextInput is required. + *
If this is True, the user must populate this TextInput field before they can submit the Modal. + * + * @return True if this TextInput is required + * @see net.dv8tion.jda.api.interactions.components.text.TextInput#isRequired() + */ + boolean required() default true; + +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java b/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java index 4b8d979d..aaff70ab 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java +++ b/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java @@ -1,6 +1,6 @@ package com.github.kaktushose.jda.commands.data; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; import java.util.Collection; @@ -30,29 +30,29 @@ public CommandTree() { /** * Constructs a new CommandTree. */ - public CommandTree(Collection commands) { + public CommandTree(Collection commands) { root = new TreeNode(); addAll(commands); } /** - * Adds a {@link CommandDefinition} to the {@link CommandTree}. The label of the {@link CommandDefinition} will be + * Adds a {@link SlashCommandDefinition} to the {@link CommandTree}. The label of the {@link SlashCommandDefinition} will be * sanitized to match the regex {@code ^[\w-]+$}. Furthermore, if the label consists of more than three spaces any * additional space will be replaced with {@code _} due to Discords limitations on SubcommandGroups. * - * @param command the {@link CommandDefinition} to add + * @param command the {@link SlashCommandDefinition} to add */ - public void add(CommandDefinition command) { + public void add(SlashCommandDefinition command) { root.addChild(resolveLabel(command.getName()), command); } /** - * Adds all {@link CommandDefinition CommandDefinitions} of the {@link Collection} to the {@link CommandTree}. + * Adds all {@link SlashCommandDefinition CommandDefinitions} of the {@link Collection} to the {@link CommandTree}. * - * @param commands a {@link Collection} of {@link CommandDefinition CommandDefinitions} to add - * @see #add(CommandDefinition) + * @param commands a {@link Collection} of {@link SlashCommandDefinition CommandDefinitions} to add + * @see #add(SlashCommandDefinition) */ - public void addAll(Collection commands) { + public void addAll(Collection commands) { commands.forEach(this::add); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java b/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java index 97b3572d..a0324f4d 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java +++ b/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.data; import com.github.kaktushose.jda.commands.SlashCommandUpdater; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; @@ -24,7 +24,7 @@ public class TreeNode implements Iterable { private static final Logger log = LoggerFactory.getLogger(SlashCommandUpdater.class); private final String name; - private final CommandDefinition command; + private final SlashCommandDefinition command; private final List children; /** @@ -38,9 +38,9 @@ public TreeNode() { * Constructs a new TreeNode. * * @param name the name of the command - * @param command the {@link CommandDefinition} + * @param command the {@link SlashCommandDefinition} */ - public TreeNode(@NotNull String name, @Nullable CommandDefinition command) { + public TreeNode(@NotNull String name, @Nullable SlashCommandDefinition command) { this.name = name; this.command = command; children = new ArrayList<>(); @@ -57,9 +57,9 @@ public TreeNode(@NotNull String name, @Nullable CommandDefinition command) { *

This guarantees to create a {@link CommandTree} that respects Subcommands and SubcommandGroups. * * @param labels an Array of all labels, can be empty - * @param command the {@link CommandDefinition} to add + * @param command the {@link SlashCommandDefinition} to add */ - public void addChild(@NotNull String[] labels, @NotNull CommandDefinition command) { + public void addChild(@NotNull String[] labels, @NotNull SlashCommandDefinition command) { if (labels.length < 1) { return; } @@ -89,9 +89,9 @@ public Optional getChild(String name) { } /** - * Gets the label of the {@link CommandDefinition} of this {@link TreeNode}. + * Gets the label of the {@link SlashCommandDefinition} of this {@link TreeNode}. * - * @return the label of the {@link CommandDefinition} + * @return the label of the {@link SlashCommandDefinition} */ public String getName() { return name; @@ -116,12 +116,12 @@ public boolean hasChildren() { } /** - * Gets the {@link CommandDefinition} of this {@link TreeNode}. Returns an empty {@link Optional} if one or more - * children exist or if the {@link CommandDefinition} is {@code null}. + * Gets the {@link SlashCommandDefinition} of this {@link TreeNode}. Returns an empty {@link Optional} if one or more + * children exist or if the {@link SlashCommandDefinition} is {@code null}. * * @return an {@link Optional} holding the result */ - public Optional getCommand() { + public Optional getCommand() { if (children.size() > 0) { return Optional.empty(); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java index 3568e169..c2c63b25 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java @@ -1,39 +1,41 @@ package com.github.kaktushose.jda.commands.dispatching; import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; -import com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete.AutoCompleteContext; import com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete.AutoCompleteDispatcher; -import com.github.kaktushose.jda.commands.dispatching.interactions.buttons.ButtonContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.buttons.ButtonDispatcher; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandDispatcher; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuDispatcher; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentDispatcher; +import com.github.kaktushose.jda.commands.dispatching.interactions.modals.ModalDispatcher; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; +import java.util.Optional; /** - * Registry for {@link GenericDispatcher Dispatchers}. Delegates incoming {@link GenericContext} to the respective + * Registry for {@link GenericDispatcher Dispatchers}. Delegates incoming {@link Context} to the respective * {@link GenericDispatcher}. * * @author Kaktushose * @version 4.0.0 * @since 4.0.0 */ -public class DispatcherSupervisor { +public class DispatcherSupervisor extends ListenerAdapter { private static final Logger log = LoggerFactory.getLogger(DispatcherSupervisor.class); - private final Map>, - GenericDispatcher>> dispatchers; + private final Map, GenericDispatcher> dispatchers; private final JDACommands jdaCommands; - private final RuntimeSupervisor runtimeSupervisor; /** * Constructs a new DispatcherSupervisor. @@ -41,53 +43,53 @@ public class DispatcherSupervisor { public DispatcherSupervisor(JDACommands jdaCommands) { this.jdaCommands = jdaCommands; dispatchers = new HashMap<>(); - runtimeSupervisor = new RuntimeSupervisor(jdaCommands.getDependencyInjector()); - register(CommandContext.class, new CommandDispatcher(this, runtimeSupervisor)); - register(ButtonContext.class, new ButtonDispatcher(this, runtimeSupervisor)); - register(SelectMenuContext.class, new SelectMenuDispatcher(this, runtimeSupervisor)); - register(AutoCompleteContext.class, new AutoCompleteDispatcher(this, runtimeSupervisor)); + register(GenericCommandInteractionEvent.class, new CommandDispatcher(jdaCommands)); + register(CommandAutoCompleteInteractionEvent.class, new AutoCompleteDispatcher(jdaCommands)); + register(GenericComponentInteractionCreateEvent.class, new ComponentDispatcher(jdaCommands)); + register(ModalInteractionEvent.class, new ModalDispatcher(jdaCommands)); } /** * Registers a new {@link GenericDispatcher}. * - * @param context a subtype of {@link GenericContext} + * @param event a subtype of {@link GenericInteractionCreateEvent} * @param dispatcher the {@link GenericDispatcher} implementation for the event */ - public void register(@NotNull Class> context, - @NotNull GenericDispatcher> dispatcher) { - dispatchers.put(context, dispatcher); - log.debug("Registered dispatcher {} for event {}", dispatcher.getClass().getName(), context.getSimpleName()); + public void register(@NotNull Class event, @NotNull GenericDispatcher dispatcher) { + dispatchers.put(event, dispatcher); + log.debug("Registered dispatcher {} for event {}", dispatcher.getClass().getName(), event.getSimpleName()); } /** * Unregisters a {@link GenericDispatcher} * - * @param context the {@link GenericContext} to unregister any {@link GenericDispatcher} for + * @param event the {@link GenericInteractionCreateEvent} to unregister any {@link GenericDispatcher} for */ - public void unregister(@NotNull Class> context) { - dispatchers.remove(context); - log.debug("Unregistered dispatcher binding for event {}", context.getSimpleName()); + public void unregister(@NotNull Class event) { + dispatchers.remove(event); + log.debug("Unregistered dispatcher binding for event {}", event.getSimpleName()); } - /** - * Dispatches a {@link GenericContext} to its respective {@link GenericDispatcher}, e.g. - * CommandContext -> CommandDispatcher. Prints a warning if no {@link GenericDispatcher} was registered. - * - * @param context the {@link GenericContext} to dispatch - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public void onGenericEvent(@NotNull GenericContext context) { - Class clazz = context.getClass(); - if (!dispatchers.containsKey(clazz)) { - log.warn("No dispatcher found for {}", clazz.getSimpleName()); + @Override + public void onGenericInteractionCreate(@NotNull GenericInteractionCreateEvent event) { + Class clazz = event.getClass(); + Optional> key = dispatchers.keySet().stream() + .filter(it -> it.isAssignableFrom(clazz)) + .findFirst(); + if (key.isEmpty()) { + log.debug("No dispatcher found for {}", clazz.getSimpleName()); return; } - log.debug("Received {}", clazz.getSimpleName()); - GenericDispatcher dispatcher = dispatchers.get(clazz); - log.debug("Calling {}", dispatcher.getClass().getName()); + Context context; + if (SlashCommandInteractionEvent.class.isAssignableFrom(clazz)) { + context = new SlashCommandContext((SlashCommandInteractionEvent) event, jdaCommands); + } else { + context = new Context(event, jdaCommands); + } + GenericDispatcher dispatcher = dispatchers.get(key.get()); + log.debug("Calling {}", dispatcher.getClass().getName()); try { dispatcher.onEvent(context); } catch (Exception e) { @@ -95,13 +97,4 @@ public void onGenericEvent(@NotNull GenericContext, GenericParser> listeners; - - /** - * Constructs a new ParserSupervisor. - * - * @param dispatcher the calling {@link DispatcherSupervisor} - */ - public ParserSupervisor(@NotNull DispatcherSupervisor dispatcher) { - listeners = new HashMap<>(); - this.dispatcher = dispatcher; - register(SlashCommandInteractionEvent.class, new CommandParser()); - register(ButtonInteractionEvent.class, new ButtonParser()); - register(EntitySelectInteractionEvent.class, new SelectMenuParser()); - register(StringSelectInteractionEvent.class, new SelectMenuParser()); - register(CommandAutoCompleteInteractionEvent.class, new AutoCompleteParser()); - } - - /** - * Registers a new {@link GenericParser} for the given subtype of {@link GenericEvent}. - * - * @param listener the subtype of {@link GenericEvent} - * @param parser the {@link GenericParser} to register - */ - public void register(@NotNull Class listener, @NotNull GenericParser parser) { - listeners.put(listener, parser); - log.debug("Registered parser {} for event {}", parser.getClass().getName(), listener.getSimpleName()); - } - - /** - * Unregisters the {@link GenericParser} for the given subtype of {@link GenericEvent}. - * - * @param listener the subtype of {@link GenericEvent} - */ - public void unregister(@NotNull Class listener) { - listeners.remove(listener); - log.debug("Unregistered parser binding for event {}", listener.getSimpleName()); - } - - /** - * Distributes {@link GenericEvent GenericEvents} to the corresponding parser. If the parsing didn't fail, will call - * {@link DispatcherSupervisor#onGenericEvent(GenericContext)} - * - * @param event the {@link GenericEvent GenericEvents} to distribute - */ - @Override - public void onGenericEvent(@NotNull GenericEvent event) { - if (!listeners.containsKey(event.getClass())) { - return; - } - log.debug("Received {}", event.getClass().getSimpleName()); - GenericParser parser = listeners.get(event.getClass()); - log.debug("Calling {}", parser.getClass().getName()); - - GenericContext context = parser.parseInternal(event, dispatcher.getJdaCommands()); - - if (context.isCancelled()) { - if (context.getErrorMessage() != null) { - // TODO send message - } - return; - } - dispatcher.onGenericEvent(context); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java index 55fd0bf2..368efb31 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java @@ -1,7 +1,8 @@ package com.github.kaktushose.jda.commands.dispatching; import com.github.kaktushose.jda.commands.dependency.DependencyInjector; -import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteraction; +import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent; @@ -45,14 +46,14 @@ public RuntimeSupervisor(DependencyInjector injector) { * Creates a new {@link InteractionRuntime}. * * @param event the {@link GenericCommandInteractionEvent} to create the {@link InteractionRuntime} for - * @param interaction the {@link GenericInteraction} to create the {@link InteractionRuntime} from + * @param interaction the {@link GenericInteractionDefinition} to create the {@link InteractionRuntime} from * @return a new {@link InteractionRuntime} with a TTL of 15 minutes * @throws InvocationTargetException if the underlying constructor throws an exception * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class * @throws IllegalAccessException if this Constructor object is enforcing Java language access control and * the underlying constructor is inaccessible */ - public InteractionRuntime newRuntime(GenericCommandInteractionEvent event, GenericInteraction interaction) + public InteractionRuntime newRuntime(GenericCommandInteractionEvent event, GenericInteractionDefinition interaction) throws InvocationTargetException, InstantiationException, IllegalAccessException { Object instance = interaction.newInstance(); @@ -68,18 +69,18 @@ public InteractionRuntime newRuntime(GenericCommandInteractionEvent event, Gener } /** - * Gets an instance of the given {@link GenericInteraction}. If no instance exists yet, creates, stores and then + * Gets an instance of the given {@link GenericInteractionDefinition}. If no instance exists yet, creates, stores and then * returns the instance. * * @param event the {@link CommandAutoCompleteInteractionEvent} to get the instance for - * @param interaction the {@link GenericInteraction} to create or get an instance from - * @return an instance of the provided {@link GenericInteraction} + * @param interaction the {@link GenericInteractionDefinition} to create or get an instance from + * @return an instance of the provided {@link GenericInteractionDefinition} * @throws InvocationTargetException if the underlying constructor throws an exception * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class * @throws IllegalAccessException if this Constructor object is enforcing Java language access control and * the underlying constructor is inaccessible */ - public Object getOrCreateInstance(CommandAutoCompleteInteractionEvent event, GenericInteraction interaction) + public Object getOrCreateInstance(CommandAutoCompleteInteractionEvent event, GenericInteractionDefinition interaction) throws InvocationTargetException, InstantiationException, IllegalAccessException { String name = event.getFullCommandName(); if (staticInstances.containsKey(name)) { @@ -94,7 +95,7 @@ public Object getOrCreateInstance(CommandAutoCompleteInteractionEvent event, Gen /** * Gets an {@link Optional} holding the {@link InteractionRuntime}. Returns an empty {@link Optional} if no * {@link InteractionRuntime} has been created yet by calling - * {@link #newRuntime(GenericCommandInteractionEvent, GenericInteraction)}, if the underlying component wasn't + * {@link #newRuntime(GenericCommandInteractionEvent, GenericInteractionDefinition)}, if the underlying component wasn't * created by jda-commands or if the {@link InteractionRuntime} expired. * * @param event the {@link GenericComponentInteractionCreateEvent} to get the {@link InteractionRuntime} for @@ -108,6 +109,23 @@ public Optional getRuntime(GenericComponentInteractionCreate return Optional.ofNullable(runtimes.get(split[2])); } + /** + * Gets an {@link Optional} holding the {@link InteractionRuntime}. Returns an empty {@link Optional} if no + * {@link InteractionRuntime} has been created yet by calling + * {@link #newRuntime(GenericCommandInteractionEvent, GenericInteractionDefinition)}, if the underlying component wasn't + * created by jda-commands or if the {@link InteractionRuntime} expired. + * + * @param event the {@link ModalInteractionEvent} to get the {@link InteractionRuntime} for + * @return an {@link Optional} holding the {@link InteractionRuntime} + */ + public Optional getRuntime(ModalInteractionEvent event) { + String[] split = event.getModalId().split("\\."); + if (split.length != 3) { + return Optional.empty(); + } + return Optional.ofNullable(runtimes.get(split[2])); + } + /** * A runtime used for executing interactions. This class holds the instance of the class annotated with * {@link com.github.kaktushose.jda.commands.annotations.interactions.Interaction Interaction} where commands, diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java index 499505be..453ea1b9 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java @@ -1,6 +1,6 @@ package com.github.kaktushose.jda.commands.dispatching.adapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,10 +19,10 @@ public interface TypeAdapter { * Attempts to parse a String to the given type. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed type or an empty Optional if the parsing fails */ - Optional parse(@NotNull String raw, @NotNull GenericContext context); + Optional parse(@NotNull String raw, @NotNull Context context); /** * Sanitizes a String containing a raw mention. This will remove all markdown characters namely < @ # & ! > diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java index 3f251c95..67eb68a2 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java @@ -1,11 +1,11 @@ package com.github.kaktushose.jda.commands.dispatching.adapter; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.*; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory; import com.github.kaktushose.jda.commands.reflect.ParameterDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.User; @@ -31,7 +31,7 @@ public class TypeAdapterRegistry { private static final Logger log = LoggerFactory.getLogger(TypeAdapterRegistry.class); - private static final Map, Object> DEFAULT_MAPPINGS = new HashMap, Object>() { + private static final Map, Object> DEFAULT_MAPPINGS = new HashMap<>() { { put(byte.class, (byte) 0); put(short.class, (short) 0); @@ -128,19 +128,19 @@ public Optional> get(@Nullable Class type) { } /** - * Takes a {@link CommandContext} and attempts to type adapt the command input to the type specified by the - * {@link CommandDefinition}. Cancels the {@link CommandContext} if the type adapting fails. + * Takes a {@link SlashCommandContext} and attempts to type adapt the command input to the type specified by the + * {@link SlashCommandDefinition}. Cancels the {@link SlashCommandContext} if the type adapting fails. * - * @param context the {@link CommandContext} to type adapt + * @param context the {@link SlashCommandContext} to type adapt */ - public void adapt(@NotNull CommandContext context) { - CommandDefinition command = Objects.requireNonNull(context.getCommand()); + public void adapt(@NotNull SlashCommandContext context) { + SlashCommandDefinition command = Objects.requireNonNull(context.getCommand()); List arguments = new ArrayList<>(); String[] input = context.getInput(); ErrorMessageFactory messageFactory = context.getImplementationRegistry().getErrorMessageFactory(); log.debug("Type adapting arguments..."); - arguments.add(new CommandEvent(command, context)); + arguments.add(new CommandEvent(context)); for (int i = 0; i < command.getActualParameters().size(); i++) { ParameterDefinition parameter = command.getActualParameters().get(i); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java index 913116fd..02952a49 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel; @@ -23,11 +23,11 @@ public class AudioChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link AudioChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link AudioChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java index d9259afc..02586324 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -20,11 +20,11 @@ public class BooleanAdapter implements TypeAdapter { * Parsing is case-insensitive. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed boolean or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { if ("true".equalsIgnoreCase(raw) || "1".equals(raw)) { return Optional.of(true); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java index 8b375d70..e510e7a8 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class ByteAdapter implements TypeAdapter { * Attempts to parse a String to a Byte. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Byte or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { try { return Optional.of(Byte.valueOf(raw)); } catch (NumberFormatException ignored) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java index 03ebd4a6..00e896e1 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class CharacterAdapter implements TypeAdapter { * Casts a String to a Char if and only if {@code raw.length == 1}. Else, returns an empty Optional. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Char or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { if (raw.length() == 1) { return Optional.of(raw.charAt(0)); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java index d19f0f03..9f27df25 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class DoubleAdapter implements TypeAdapter { * Attempts to parse a String to a Double. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Double or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { try { return Optional.of(Double.valueOf(raw)); } catch (NumberFormatException ignored) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java index 0cd3dbc6..3c219349 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class FloatAdapter implements TypeAdapter { * Attempts to parse a String to a Float. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Float or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { try { return Optional.of(Float.valueOf(raw)); } catch (NumberFormatException ignored) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java index 80830127..a4d37174 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; @@ -22,11 +22,11 @@ public class GuildChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link GuildChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link GuildChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java index c3adb3bb..2be2e4b1 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; @@ -23,11 +23,11 @@ public class GuildMessageChannelAdapter implements TypeAdapter parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java index 1a43d325..3b42e865 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class IntegerAdapter implements TypeAdapter { * Attempts to parse a String to an Integer. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Integer or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { try { return Optional.of((int) Double.parseDouble(raw)); } catch (NumberFormatException ignored) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java index d62667b2..5900ce92 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class LongAdapter implements TypeAdapter { * Attempts to parse a String to a Long. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Long or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { try { return Optional.of((long) Double.parseDouble(raw)); } catch (NumberFormatException ignored) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java index 803cc661..a0501b80 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.exceptions.ErrorResponseException; @@ -22,11 +22,11 @@ public class MemberAdapter implements TypeAdapter { * Attempts to parse a String to a {@link Member}. Accepts both the member id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link Member} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { if (context.getEvent().getGuild() == null) { return Optional.empty(); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java index 0f4b0ace..ac7cca37 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel; @@ -22,11 +22,11 @@ public class NewsChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link NewsChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link NewsChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java index cbed4480..b2662ee8 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Role; import org.jetbrains.annotations.NotNull; @@ -21,11 +21,11 @@ public class RoleAdapter implements TypeAdapter { * Attempts to parse a String to a {@link Role}. Accepts both the role id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link Role} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { if (context.getEvent().getGuild() == null) { return Optional.empty(); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java index 44c8c890..6c885fe8 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -19,11 +19,11 @@ public class ShortAdapter implements TypeAdapter { * Attempts to parse a String to a Short. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed Short or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { try { return Optional.of(Short.valueOf(raw)); } catch (NumberFormatException ignored) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java index a5b19e1e..aad0f8b1 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.concrete.StageChannel; @@ -22,11 +22,11 @@ public class StageChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link StageChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link StageChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java index 5d959f41..609d9f6f 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import org.jetbrains.annotations.NotNull; @@ -21,11 +21,11 @@ public class TextChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link TextChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link TextChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { if (context.getEvent().getGuild() == null) { return Optional.empty(); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java index 75c40a5b..cf5d474e 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; @@ -22,11 +22,11 @@ public class ThreadChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link ThreadChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link ThreadChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java index 6efafd12..6d4d482d 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.exceptions.ErrorResponseException; @@ -22,11 +22,11 @@ public class UserAdapter implements TypeAdapter { * Attempts to parse a String to a {@link User}. Accepts both the user id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link User} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { User user; raw = sanitizeMention(raw); JDA jda = context.getEvent().getJDA(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java index bc6d127a..1b0c05be 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.adapter.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; @@ -22,11 +22,11 @@ public class VoiceChannelAdapter implements TypeAdapter { * Attempts to parse a String to a {@link VoiceChannel}. Accepts both the channel id and name. * * @param raw the String to parse - * @param context the {@link GenericContext} + * @param context the {@link Context} * @return the parsed {@link VoiceChannel} or an empty Optional if the parsing fails */ @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { Channel channel = context.getEvent().getChannel(); if (channel == null) { return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/Filter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/Filter.java index 4efd0a51..31bee223 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/Filter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/Filter.java @@ -1,11 +1,11 @@ package com.github.kaktushose.jda.commands.dispatching.filter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; /** - * Generic top level interface for the filter chain. A filter performs filtering tasks on a {@link GenericContext} - * before execution. A filter might modify the {@link GenericContext} or even cancel the whole event. + * Generic top level interface for the filter chain. A filter performs filtering tasks on a {@link Context} + * before execution. A filter might modify the {@link Context} or even cancel the whole event. * * @author Kaktushose * @version 2.0.0 @@ -14,11 +14,11 @@ public interface Filter { /** - * Performs the filtering on a {@link GenericContext} object. Use {@link GenericContext#setCancelled(boolean)} to - * indicate that the {@link GenericContext} didn't pass the filter. + * Performs the filtering on a {@link Context} object. Use {@link Context#setCancelled(boolean)} to + * indicate that the {@link Context} didn't pass the filter. * - * @param context the {@link GenericContext} to filter + * @param context the {@link Context} to filter */ - void apply(@NotNull GenericContext context); + void apply(@NotNull Context context); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/FilterRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/FilterRegistry.java index 8f5f0b39..9ecbb35d 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/FilterRegistry.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/FilterRegistry.java @@ -2,7 +2,7 @@ import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry; import com.github.kaktushose.jda.commands.dispatching.filter.impl.*; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -113,13 +113,13 @@ public enum FilterPosition { /** * Filter will be executed before command routing. The command will not be present in the - * {@link CommandContext}. + * {@link SlashCommandContext}. */ BEFORE_ROUTING, /** * Filter will be executed before type adapting. The command will be present in the - * {@link CommandContext} but not the type adapted input. + * {@link SlashCommandContext} but not the type adapted input. */ BEFORE_ADAPTING, diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/ConstraintFilter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/ConstraintFilter.java index 0416cc84..22859584 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/ConstraintFilter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/ConstraintFilter.java @@ -1,11 +1,11 @@ package com.github.kaktushose.jda.commands.dispatching.filter.impl; import com.github.kaktushose.jda.commands.dispatching.filter.Filter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.reflect.ConstraintDefinition; import com.github.kaktushose.jda.commands.reflect.ParameterDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +15,7 @@ /** * A {@link Filter} implementation that will check the parameter constraints a - * {@link CommandDefinition} might have. + * {@link SlashCommandDefinition} might have. * * @author Kaktushose * @version 2.0.0 @@ -27,14 +27,14 @@ public class ConstraintFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(ConstraintFilter.class); /** - * Checks if all parameters fulfill their constraints. Will cancel the {@link GenericContext} if a parameter + * Checks if all parameters fulfill their constraints. Will cancel the {@link Context} if a parameter * constraint fails. * - * @param ctx the {@link GenericContext} to filter + * @param ctx the {@link Context} to filter */ @Override - public void apply(@NotNull GenericContext ctx) { - CommandContext context = (CommandContext) ctx; + public void apply(@NotNull Context ctx) { + SlashCommandContext context = (SlashCommandContext) ctx; List arguments = context.getArguments(); List parameters = Objects.requireNonNull(context.getCommand()).getParameters(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/CooldownFilter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/CooldownFilter.java index 247158fe..f0abb955 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/CooldownFilter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/CooldownFilter.java @@ -2,10 +2,10 @@ import com.github.kaktushose.jda.commands.annotations.interactions.Cooldown; import com.github.kaktushose.jda.commands.dispatching.filter.Filter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.reflect.CooldownDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +15,7 @@ /** * A {@link Filter} implementation that contains the business logic behind command cooldowns. * If the command isn't annotated with {@link Cooldown Cooldown} or more - * formally if the {@link CommandDefinition} doesn't hold a {@link CooldownDefinition} or the delay of the + * formally if the {@link SlashCommandDefinition} doesn't hold a {@link CooldownDefinition} or the delay of the * {@link CooldownDefinition} amounts to {@code 0} this filter has no effect. * * @author Kaktushose @@ -33,14 +33,14 @@ public CooldownFilter() { } /** - * Checks if an active cooldown for the given {@link CommandDefinition} exists and will eventually cancel the + * Checks if an active cooldown for the given {@link SlashCommandDefinition} exists and will eventually cancel the * context. * - * @param context the {@link GenericContext} to filter + * @param context the {@link Context} to filter */ @Override - public void apply(@NotNull GenericContext context) { - CommandDefinition command = ((CommandContext) context).getCommand(); + public void apply(@NotNull Context context) { + SlashCommandDefinition command = ((SlashCommandContext) context).getCommand(); if (!command.hasCooldown()) { return; @@ -73,17 +73,17 @@ public void apply(@NotNull GenericContext context) { } private static class CooldownEntry { - private final CommandDefinition command; + private final SlashCommandDefinition command; private final long startTime; private final long duration; - public CooldownEntry(CommandDefinition command, long startTime, long duration) { + public CooldownEntry(SlashCommandDefinition command, long startTime, long duration) { this.command = command; this.startTime = startTime; this.duration = duration; } - public CommandDefinition getCommand() { + public SlashCommandDefinition getCommand() { return command; } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/DirectMessageFilter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/DirectMessageFilter.java index d520be07..4cf81f58 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/DirectMessageFilter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/DirectMessageFilter.java @@ -2,9 +2,9 @@ import com.github.kaktushose.jda.commands.annotations.interactions.SlashCommand; import com.github.kaktushose.jda.commands.dispatching.filter.Filter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.ChannelType; import org.jetbrains.annotations.NotNull; @@ -13,7 +13,7 @@ /** * A {@link Filter} implementation that checks if a - * {@link CommandDefinition} is available for execution in direct messages. + * {@link SlashCommandDefinition} is available for execution in direct messages. * * @author Kaktushose * @version 2.0.0 @@ -25,14 +25,14 @@ public class DirectMessageFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(DirectMessageFilter.class); /** - * Checks if a {@link CommandDefinition} is available for execution in - * direct messages and if not cancels the {@link GenericContext}, + * Checks if a {@link SlashCommandDefinition} is available for execution in + * direct messages and if not cancels the {@link Context}, * - * @param context the {@link GenericContext} to filter + * @param context the {@link Context} to filter */ @Override - public void apply(@NotNull GenericContext context) { - CommandContext commandContext = (CommandContext) context; + public void apply(@NotNull Context context) { + SlashCommandContext commandContext = (SlashCommandContext) context; Channel channel = context.getEvent().getChannel(); if (channel == null) { return; diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/PermissionsFilter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/PermissionsFilter.java index 80f59c3a..5a1489b8 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/PermissionsFilter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/PermissionsFilter.java @@ -2,8 +2,8 @@ import com.github.kaktushose.jda.commands.annotations.interactions.Permissions; import com.github.kaktushose.jda.commands.dispatching.filter.Filter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.permissions.PermissionsProvider; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; @@ -16,9 +16,9 @@ * A {@link Filter} implementation that will check permissions. * The default implementation can only handle discord permissions. However, the {@link PermissionsProvider} can be * used for own implementations. - * This filter will first check against {@link PermissionsProvider#hasPermission(User, GenericContext)} with a + * This filter will first check against {@link PermissionsProvider#hasPermission(User, Context)} with a * {@link User} object. This can be used for global permissions. Afterwards - * {@link PermissionsProvider#hasPermission(Member, GenericContext)} will be called. Since the {@link Member} is + * {@link PermissionsProvider#hasPermission(Member, Context)} will be called. Since the {@link Member} is * available this might be used for guild related permissions. * * @author Kaktushose @@ -34,10 +34,10 @@ public class PermissionsFilter implements Filter { /** * Checks if the {@link User} and respectively the {@link Member} has the permission to execute the command. * - * @param context the {@link GenericContext} to filter + * @param context the {@link Context} to filter */ @Override - public void apply(@NotNull GenericContext context) { + public void apply(@NotNull Context context) { log.debug("Checking permissions..."); PermissionsProvider provider = context.getImplementationRegistry().getPermissionsProvider(); @@ -51,7 +51,7 @@ public void apply(@NotNull GenericContext context) { } if (!hasPerms) { context.setCancelled(true).setErrorMessage( - context.getImplementationRegistry().getErrorMessageFactory().getInsufficientPermissionsMessage((CommandContext) context) + context.getImplementationRegistry().getErrorMessageFactory().getInsufficientPermissionsMessage((SlashCommandContext) context) ); log.debug("Insufficient permissions!"); return; diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/UserMuteFilter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/UserMuteFilter.java index b53aa880..d4e01ab9 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/UserMuteFilter.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/filter/impl/UserMuteFilter.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.filter.impl; import com.github.kaktushose.jda.commands.dispatching.filter.Filter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.permissions.PermissionsProvider; import net.dv8tion.jda.api.entities.User; import org.jetbrains.annotations.NotNull; @@ -17,7 +17,7 @@ * * @author Kaktushose * @version 2.0.0 - * @see PermissionsProvider#isMuted(User, GenericContext) + * @see PermissionsProvider#isMuted(User, Context) * @since 2.0.0 */ public class UserMuteFilter implements Filter { @@ -25,12 +25,12 @@ public class UserMuteFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(UserMuteFilter.class); /** - * Checks if a {@link User} is muted and will cancel the {@link GenericContext} if he is. + * Checks if a {@link User} is muted and will cancel the {@link Context} if he is. * - * @param context the {@link GenericContext} to filter + * @param context the {@link Context} to filter */ @Override - public void apply(@NotNull GenericContext context) { + public void apply(@NotNull Context context) { log.debug("Checking mutes..."); PermissionsProvider provider = context.getImplementationRegistry().getPermissionsProvider(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java similarity index 78% rename from src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericContext.java rename to src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java index f612a8b3..c47d642f 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericContext.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java @@ -4,7 +4,7 @@ import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime; import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry; -import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteraction; +import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.utils.messages.MessageCreateData; @@ -22,16 +22,16 @@ * @see GenericEvent * @since 2.0.0 */ -public class GenericContext { +public class Context { - protected final T event; + protected final GenericInteractionCreateEvent event; protected MessageCreateData errorMessage; protected ImplementationRegistry registry; protected JDACommands jdaCommands; protected boolean cancelled; protected boolean ephemeral; protected InteractionRuntime runtime; - protected GenericInteraction interaction; + protected GenericInteractionDefinition interactionDefinition; /** * Constructs a new GenericContext. @@ -39,13 +39,13 @@ public class GenericContext { * @param jdaCommands the corresponding {@link JDACommands} instance * @param event the corresponding {@link GenericInteractionCreateEvent} */ - public GenericContext(T event, JDACommands jdaCommands) { + public Context(GenericInteractionCreateEvent event, JDACommands jdaCommands) { this.event = event; this.jdaCommands = jdaCommands; this.registry = jdaCommands.getImplementationRegistry(); } - public T getEvent() { + public GenericInteractionCreateEvent getEvent() { return event; } @@ -66,7 +66,7 @@ public MessageCreateData getErrorMessage() { * @return the current CommandContext instance */ @NotNull - public GenericContext setErrorMessage(@NotNull MessageCreateData message) { + public Context setErrorMessage(@NotNull MessageCreateData message) { this.errorMessage = message; return this; } @@ -88,7 +88,7 @@ public ImplementationRegistry getImplementationRegistry() { * @return the current CommandContext instance */ @NotNull - public GenericContext setImplementationRegistry(@NotNull ImplementationRegistry registry) { + public Context setImplementationRegistry(@NotNull ImplementationRegistry registry) { this.registry = registry; return this; } @@ -110,7 +110,7 @@ public JDACommands getJdaCommands() { * @return the current CommandContext instance */ @NotNull - public GenericContext setJdaCommands(@NotNull JDACommands jdaCommands) { + public Context setJdaCommands(@NotNull JDACommands jdaCommands) { this.jdaCommands = jdaCommands; return this; } @@ -131,7 +131,7 @@ public boolean isCancelled() { * @return the current CommandContext instance */ @NotNull - public GenericContext setCancelled(final boolean cancelled) { + public Context setCancelled(final boolean cancelled) { this.cancelled = cancelled; return this; } @@ -140,7 +140,7 @@ public boolean isEphemeral() { return ephemeral; } - public GenericContext setEphemeral(boolean ephemeral) { + public Context setEphemeral(boolean ephemeral) { this.ephemeral = ephemeral; return this; } @@ -159,17 +159,17 @@ public InteractionRuntime getRuntime() { * * @return the current CommandContext instance */ - public GenericContext setRuntime(InteractionRuntime runtime) { + public Context setRuntime(InteractionRuntime runtime) { this.runtime = runtime; return this; } - public GenericInteraction getInteraction() { - return interaction; + public GenericInteractionDefinition getInteractionDefinition() { + return interactionDefinition; } - public GenericContext setInteraction(GenericInteraction interaction) { - this.interaction = interaction; + public Context setInteractionDefinition(GenericInteractionDefinition interactionDefinition) { + this.interactionDefinition = interactionDefinition; return this; } } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java index 157b233a..7cc87650 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java @@ -1,48 +1,47 @@ package com.github.kaktushose.jda.commands.dispatching.interactions; import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.DispatcherSupervisor; +import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry; import com.github.kaktushose.jda.commands.dispatching.filter.FilterRegistry; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandDispatcher; import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry; import com.github.kaktushose.jda.commands.reflect.InteractionRegistry; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; /** * Abstract base class for event dispatchers. * - * @param the subclass of {@link GenericContext} to dispatch * @author Kaktushose * @version 4.0.0 - * @see CommandDispatcher CommandDispatcher * @since 4.0.0 */ -public abstract class GenericDispatcher> { +public abstract class GenericDispatcher { + protected final JDACommands jdaCommands; protected final FilterRegistry filterRegistry; protected final ImplementationRegistry implementationRegistry; protected final InteractionRegistry interactionRegistry; protected final TypeAdapterRegistry adapterRegistry; + protected final RuntimeSupervisor runtimeSupervisor; /** * Constructs a new GenericDispatcher. * - * @param supervisor the {@link DispatcherSupervisor} which supervises this dispatcher. + * @param jdaCommands the corresponding {@link JDACommands} instance. */ - public GenericDispatcher(DispatcherSupervisor supervisor) { - JDACommands jdaCommands = supervisor.getJdaCommands(); + public GenericDispatcher(JDACommands jdaCommands) { + this.jdaCommands = jdaCommands; filterRegistry = jdaCommands.getFilterRegistry(); implementationRegistry = jdaCommands.getImplementationRegistry(); interactionRegistry = jdaCommands.getInteractionRegistry(); adapterRegistry = jdaCommands.getAdapterRegistry(); + runtimeSupervisor = jdaCommands.getRuntimeSupervisor(); } /** - * Dispatches a {@link GenericContext}. + * Dispatches a {@link Context}. * - * @param context the {@link GenericContext} to dispatch. + * @param context the {@link Context} to dispatch. */ - public abstract void onEvent(T context); + public abstract void onEvent(Context context); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java index 5828c48c..eebf50de 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java @@ -1,330 +1,61 @@ package com.github.kaktushose.jda.commands.dispatching.interactions; -import com.github.kaktushose.jda.commands.dispatching.interactions.buttons.ButtonEvent; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.*; -import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel; -import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; -import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; -import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; -import net.dv8tion.jda.api.events.Event; +import com.github.kaktushose.jda.commands.JDACommands; +import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; /** - * Extension of JDAs {@link Event} class that combines all common fields of all interaction events. This is the base - * class for the different event classes. + * Extension of JDAs {@link GenericInteractionCreateEvent} class. This is the base class for the different event classes. * * @author Kaktushose * @version 4.0.0 - * @see CommandEvent CommandEvent - * @see ButtonEvent ButtonEvent + * @see com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent CommandEvent + * @see com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent ComponentEvent + * @see com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete.AutoCompleteEvent AutoCompleteEvent + * @see com.github.kaktushose.jda.commands.dispatching.interactions.modals.ModalEvent ModalEvent * @since 4.0.0 */ -public class GenericEvent extends Event { - - private final Guild guild; - private final User user; - private final Member member; - private final MessageChannel channel; - private final ChannelType channelType; - private final Message message; - private final Map values; - - - protected GenericEvent(JDA api, long responseNumber, Guild guild, User user, Member member, - MessageChannel channel, ChannelType channelType, Message message) { - super(api, responseNumber); - this.guild = guild; - this.user = user; - this.member = member; - this.channel = channel; - this.channelType = channelType; - this.message = message; - this.values = new ConcurrentHashMap<>(); - } - - protected GenericEvent(GenericEvent event) { - this(event.getJDA(), event.getResponseNumber(), event.getGuild(), event.getUser(), event.getMember(), - event.getChannel(), event.getChannelType(), event.getMessage()); - } - - /** - * Constructs a new {@link GenericEvent} from a {@link SlashCommandInteractionEvent}. - * - * @param event the {@link SlashCommandInteractionEvent} to construct from - * @return a {@link GenericEvent} - */ - @NotNull - public static GenericEvent fromEvent(@NotNull GenericInteractionCreateEvent event) { - return new GenericEvent(event.getJDA(), event.getResponseNumber(), event.getGuild(), - event.getUser(), event.getMember(), event.getMessageChannel(), event.getChannelType(), null); - } - - /** - * The {@link Guild} the Message was received in. - *
If this Message was not received in a {@link TextChannel TextChannel}, - * this will throw an {@link java.lang.IllegalStateException}. - * - * @return The Guild the Message was received in - * @throws IllegalStateException If this was not sent in a {@link TextChannel} - * @see #isFromGuild() - * @see #isFromType(ChannelType) - * @see #getChannelType() - */ - @NotNull - public Guild getGuild() { - if (!isFromGuild()) { - throw new IllegalStateException("This message event did not happen in a guild"); - } - return guild; - } - - /** - * Whether this message was sent in a {@link Guild Guild}. - *
If this is {@code false} then {@link #getGuild()} will throw an {@link IllegalStateException}. - * - * @return {@code true}, if {@link #getChannelType()}.{@link ChannelType#isGuild() isGuild()} is true - */ - public boolean isFromGuild() { - return channelType.isGuild(); - } - - /** - * The Author of the Message received as {@link User} object. - *
This will be never-null but might be a fake user if Message was sent via Webhook (Guild only). - * See {@link Webhook#getDefaultUser()}. - * - * @return The Author of the Message - * @see Message#isWebhookMessage() - */ - @NotNull - public User getUser() { - return user; - } - - /** - * The Author of the Message received as {@link User} object. - *
This will be never-null but might be a fake user if Message was sent via Webhook (Guild only). - * See {@link Webhook#getDefaultUser()}. - * - * @return The Author of the Message - * @see Message#isWebhookMessage() - */ - @NotNull - public User getAuthor() { - return user; - } - - /** - * The Author of the Message received as {@link Member} object. - *
This will be {@code null} in case of Message being received in - * a {@link PrivateChannel PrivateChannel} - * or {@link Message#isWebhookMessage() isWebhookMessage()} returning {@code true}. - * - * @return The Author of the Message as null-able Member object - * @see Message#isWebhookMessage() - */ - @Nullable - public Member getMember() { - return member; - } - - /** - * The received {@link Message} object. - *
This will be {@code null} if this instance was not created from a {@link MessageReceivedEvent}. - * - * @return The received {@link Message} object - */ - @Nullable - public Message getMessage() { - return message; - } - - /** - * The {@link MessageChannel} for this Message. - * - * @return The MessageChannel - */ - @NotNull - public MessageChannel getChannel() { - return channel; - } - - /** - * The {@link NewsChannel} the Message was received in. - *
If this Message was not received in a {@link NewsChannel}, this will throw an {@link IllegalStateException}. - * - * @return The NewsChannel the Message was received in - * @throws IllegalStateException If this was not sent in a {@link NewsChannel} - * @see #isFromGuild() - * @see #isFromType(ChannelType) - * @see #getChannelType() - */ - public NewsChannel getNewsChannel() { - if (channel instanceof NewsChannel) { - return (NewsChannel) channel; - } else { - throw new IllegalStateException("Cannot convert channel of type " + channelType + " to NewsChannel"); - } - } - - /** - * The {@link TextChannel} the Message was received in. - *
If this Message was not received in a {@link TextChannel}, this will throw an {@link IllegalStateException}. - * - * @return The TextChannel the Message was received in - * @throws IllegalStateException If this was not sent in a {@link TextChannel} - * @see #isFromGuild() - * @see #isFromType(ChannelType) - * @see #getChannelType() - */ - @NotNull - public TextChannel getTextChannel() { - if (channel instanceof TextChannel) { - return (TextChannel) channel; - } else { - throw new IllegalStateException("Cannot convert channel of type " + channelType + " to TextChannel"); - } - } +public abstract class GenericEvent extends GenericInteractionCreateEvent { - /** - * The {@link ThreadChannel} the Message was received in. - *
If this Message was not received in a {@link ThreadChannel}, this will throw an {@link IllegalStateException}. - * - * @return The ThreadChannel the Message was received in - * @throws IllegalStateException If this was not sent in a {@link ThreadChannel} - * @see #isFromGuild() - * @see #isFromType(ChannelType) - * @see #getChannelType() - */ - public ThreadChannel getThreadChannel() { - if (channel instanceof ThreadChannel) { - return (ThreadChannel) channel; - } else { - throw new IllegalStateException("Cannot convert channel of type " + channelType + " to ThreadChannel"); - } - } - - /** - * The {@link GuildChannel} the Message was received in. - *
If this Message was not received in a {@link GuildChannel}, this will throw an {@link IllegalStateException}. - * - * @return The GuildChannel the Message was received in - * @throws IllegalStateException If this was not sent in a {@link GuildChannel} - * @see #isFromGuild() - * @see #isFromType(ChannelType) - * @see #getChannelType() - */ - public GuildChannel getGuildChannel() { - if (channel instanceof GuildChannel) { - return (GuildChannel) channel; - } else { - throw new IllegalStateException("Cannot convert channel of type " + channelType + " to GuildChannel"); - } - } - - /** - * The {@link PrivateChannel} the Message was received in. - *
If this Message was not received in a {@link PrivateChannel}, this will throw an {@link IllegalStateException}. - * - * @return The PrivateChannel the Message was received in - * @throws IllegalStateException If this was not sent in a {@link PrivateChannel} - * @see #isFromGuild() - * @see #isFromType(ChannelType) - * @see #getChannelType() - */ - public PrivateChannel getPrivateChannel() { - if (channel instanceof PrivateChannel) { - return (PrivateChannel) channel; - } else { - throw new IllegalStateException("Cannot convert channel of type " + channelType + " to PrivateChannel"); - } - } - - /** - * The {@link ChannelType} for this message. - * - * @return The ChannelType - */ - @NotNull - public ChannelType getChannelType() { - return channelType; - } - - /** - * Indicates whether the message is from the specified {@link ChannelType}. - * - * @param type The ChannelType - * @return {@code true}, if the message is from the specified channel type - */ - public boolean isFromType(ChannelType type) { - return type == channelType; - } - - /** - * Gets a value. - * - * @param key the key - * @param clazz the class of the value - * @param the type of the value - * @return an {@link Optional} holding the value - */ - public Optional get(String key, @NotNull Class clazz) { - return Optional.ofNullable(values.get(key)).filter(it -> it.getClass().isAssignableFrom(clazz)).map(clazz::cast); - } + private final T definition; + protected final Context context; /** - * Associates the specified value with the specified key. + * Constructs a new GenericEvent. * - * @param key the key - * @param value the value - * @return this instance for fluent interface + * @param context the underlying {@link Context} */ - public GenericEvent put(String key, Object value) { - values.put(key, value); - return this; + @SuppressWarnings("unchecked") + protected GenericEvent(Context context) { + super(context.getEvent().getJDA(), context.getEvent().getResponseNumber(), context.getEvent().getInteraction()); + definition = (T) context.getInteractionDefinition(); + this.context = context; } /** - * Whether this StateSection has a value mapped to the key. + * Get the interaction object which describes the component that is executed. * - * @param key the key - * @return {@code true} if this StateSection has a value mapped to the key + * @return the underlying interaction object */ - public boolean contains(String key) { - return values.containsKey(key); + public T getInteractionDefinition() { + return definition; } /** - * Removes the value mapping for a key. + * Get the {@link Context} object. * - * @param key key whose mapping is to be removed - * @return this instance for fluent interface + * @return the registered {@link Context} object */ - public GenericEvent remove(String key) { - values.remove(key); - return this; + public Context getContext() { + return context; } /** - * Removes all the value mappings. + * Get the {@link JDACommands} object. * - * @return this instance for fluent interface + * @return the {@link JDACommands} object */ - public GenericEvent clear() { - values.clear(); - return this; + public JDACommands getJdaCommands() { + return context.getJdaCommands(); } } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericParser.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericParser.java deleted file mode 100644 index 734193b0..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericParser.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandDispatcher; -import net.dv8tion.jda.api.events.GenericEvent; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; -import org.jetbrains.annotations.NotNull; - -/** - * Abstract toplevel class for defining event parsers. - * - * @param a subtype of {@link GenericEvent} the parser can parse - * @author Kaktushose - * @version 2.0.0 - * @since 2.0.0 - */ -public abstract class GenericParser { - - public GenericContext parseInternal(GenericEvent event, JDACommands jdaCommands) { - return parse((T) event, jdaCommands); - } - - /** - * Takes a subtype of {@link GenericEvent}, parses and transpiles it into a {@link GenericContext}. - * - * @param event the subtype of {@link GenericEvent} - * @param dispatcher the calling {@link CommandDispatcher} - * @return a new {@link GenericContext} - */ - @NotNull - public abstract GenericContext parse(@NotNull T event, @NotNull JDACommands jdaCommands); - -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteContext.java deleted file mode 100644 index a70da90f..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteContext.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; - -public class AutoCompleteContext extends GenericContext { - - /** - * Constructs a new AutoCompleteContext. - * - * @param event the corresponding {@link CommandAutoCompleteInteractionEvent} - * @param jdaCommands the corresponding {@link JDACommands} instance - */ - public AutoCompleteContext(CommandAutoCompleteInteractionEvent event, JDACommands jdaCommands) { - super(event, jdaCommands); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java index 28270542..ff0cd44f 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete; -import com.github.kaktushose.jda.commands.dispatching.DispatcherSupervisor; -import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; +import com.github.kaktushose.jda.commands.JDACommands; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition; import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; @@ -11,32 +11,28 @@ import java.util.Optional; /** - * Dispatches auto complete by taking a {@link AutoCompleteContext} and passing it through the execution chain. + * Dispatches auto complete by taking a {@link Context} and passing it through the execution chain. * * @author Kaktushose * @version 4.0.0 * @since 4.0.0 */ -public class AutoCompleteDispatcher extends GenericDispatcher { +public class AutoCompleteDispatcher extends GenericDispatcher { private static final Logger log = LoggerFactory.getLogger(AutoCompleteDispatcher.class); - private final RuntimeSupervisor runtimeSupervisor; /** * Constructs a new AutoCompleteDispatcher. * - * @param supervisor the {@link DispatcherSupervisor} which supervises this dispatcher. - * @param runtimeSupervisor the corresponding {@link RuntimeSupervisor} + * @param jdaCommands the corresponding {@link JDACommands} instance. */ - public AutoCompleteDispatcher(DispatcherSupervisor supervisor, RuntimeSupervisor runtimeSupervisor) { - super(supervisor); - this.runtimeSupervisor = runtimeSupervisor; + public AutoCompleteDispatcher(JDACommands jdaCommands) { + super(jdaCommands); } @Override - public void onEvent(AutoCompleteContext context) { - log.debug("Acknowledging event"); - CommandAutoCompleteInteractionEvent event = context.getEvent(); + public void onEvent(Context context) { + CommandAutoCompleteInteractionEvent event = (CommandAutoCompleteInteractionEvent) context.getEvent(); Optional optionalAutoComplete = interactionRegistry.getAutoCompletes().stream() .filter(it -> it.getCommandNames().contains(event.getFullCommandName())) .findFirst(); @@ -47,6 +43,8 @@ public void onEvent(AutoCompleteContext context) { } AutoCompleteDefinition autoComplete = optionalAutoComplete.get(); + log.debug("Input matches auto complete: {}", autoComplete.getId()); + log.info("Executing auto complete {} for user {}", autoComplete.getMethod().getName(), event.getMember()); try { autoComplete.getMethod().invoke(runtimeSupervisor.getOrCreateInstance(event, autoComplete), new AutoCompleteEvent(context)); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java index d16420df..bcbfaead 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java @@ -1,6 +1,8 @@ package com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; +import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition; import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.CommandAutoCompleteInteraction; @@ -21,13 +23,13 @@ * @see GenericEvent * @since 4.0.0 */ -public class AutoCompleteEvent extends GenericEvent { +public class AutoCompleteEvent extends GenericEvent { private final CommandAutoCompleteInteractionEvent event; - protected AutoCompleteEvent(AutoCompleteContext context) { - super(GenericEvent.fromEvent(context.getEvent())); - event = context.getEvent(); + protected AutoCompleteEvent(Context context) { + super(context); + event = (CommandAutoCompleteInteractionEvent) context.getEvent(); } /** @@ -260,7 +262,7 @@ public String getValue() { * @return The option type expected from this auto-complete response */ @Nonnull - public OptionType getType() { + public OptionType getOptionType() { return event.getFocusedOption().getType(); } } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteParser.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteParser.java deleted file mode 100644 index 0a3a2a2c..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteParser.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericParser; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; -import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; -import org.jetbrains.annotations.NotNull; - -public class AutoCompleteParser extends GenericParser { - - @Override - public @NotNull GenericContext parse(@NotNull CommandAutoCompleteInteractionEvent event, @NotNull JDACommands jdaCommands) { - return new AutoCompleteContext(event, jdaCommands); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonContext.java deleted file mode 100644 index 305ac870..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonContext.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.buttons; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; - -/** - * Implementation of {@link GenericContext} for {@link ButtonInteractionEvent}. - * - * @author Kaktushose - * @version 4.0.0 - * @since 4.0.0 - */ -public class ButtonContext extends GenericContext { - - private ButtonDefinition button; - - /** - * Constructs a new ButtonContext. - * - * @param event the corresponding {@link ButtonInteractionEvent} - * @param jdaCommands the corresponding {@link JDACommands} instance - */ - public ButtonContext(ButtonInteractionEvent event, JDACommands jdaCommands) { - super(event, jdaCommands); - } - - /** - * Gets the {@link ButtonDefinition}. - * - * @return the {@link ButtonDefinition} - */ - public ButtonDefinition getButton() { - return button; - } - - /** - * Set the {@link ButtonDefinition}. - * - * @param button the {@link ButtonDefinition} - * @return the current CommandContext instance - */ - public ButtonContext setButton(ButtonDefinition button) { - this.button = button; - setInteraction(button); - return this; - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonDispatcher.java deleted file mode 100644 index beb74f66..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonDispatcher.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.buttons; - -import com.github.kaktushose.jda.commands.dispatching.DispatcherSupervisor; -import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; -import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; -import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; -import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory; -import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.InvocationTargetException; -import java.util.Optional; - -/** - * Dispatches buttons by taking a {@link ButtonContext} and passing it through the execution chain. - * - * @author Kaktushose - * @version 4.0.0 - * @since 4.0.0 - */ -public class ButtonDispatcher extends GenericDispatcher { - - private static final Logger log = LoggerFactory.getLogger(ButtonDispatcher.class); - private final RuntimeSupervisor runtimeSupervisor; - - /** - * Constructs a new ButtonDispatcher. - * - * @param supervisor the {@link DispatcherSupervisor} which supervises this dispatcher. - * @param runtimeSupervisor the corresponding {@link RuntimeSupervisor} - */ - public ButtonDispatcher(DispatcherSupervisor supervisor, RuntimeSupervisor runtimeSupervisor) { - super(supervisor); - this.runtimeSupervisor = runtimeSupervisor; - } - - /** - * Dispatches a {@link ButtonContext}. - * - * @param context the {@link ButtonContext} to dispatch. - */ - @Override - public void onEvent(ButtonContext context) { - log.debug("Acknowledging event"); - ButtonInteractionEvent event = context.getEvent(); - event.deferEdit().queue(); - - ErrorMessageFactory messageFactory = implementationRegistry.getErrorMessageFactory(); - - Optional optionalRuntime = runtimeSupervisor.getRuntime(event); - if (optionalRuntime.isEmpty()) { - event.getHook().editOriginalComponents().queue(); - event.getHook().sendMessage(messageFactory.getUnknownInteractionMessage(context)).setEphemeral(true).queue(); - return; - } - InteractionRuntime runtime = optionalRuntime.get(); - log.debug("Found corresponding runtime with id \"{}\"", runtime); - - String[] splitId = event.getButton().getId().split("\\."); - String buttonId = String.format("%s.%s", splitId[0], splitId[1]); - Optional optionalButton = interactionRegistry.getButtons().stream() - .filter(it -> it.getId().equals(buttonId)) - .findFirst(); - if (optionalButton.isEmpty()) { - IllegalStateException exception = new IllegalStateException( - "No button found! Please report this error the the devs of jda-commands." - ); - context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, exception)); - checkCancelled(context); - throw exception; - } - - ButtonDefinition button = optionalButton.get(); - context.setButton(button).setEphemeral(button.isEphemeral()); - log.debug("Input matches button: {}", button); - - log.info("Executing button {} for user {}", button.getMethod().getName(), event.getMember()); - try { - context.setRuntime(runtime); - button.getMethod().invoke(runtime.getInstance(), new ButtonEvent(button, context)); - } catch (Exception exception) { - log.error("Button execution failed!", exception); - // this unwraps the underlying error in case of an exception inside the command class - Throwable throwable = exception instanceof InvocationTargetException ? exception.getCause() : exception; - context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, throwable)); - checkCancelled(context); - } - } - - @SuppressWarnings("ConstantConditions") - private boolean checkCancelled(ButtonContext context) { - if (context.isCancelled()) { - ReplyContext replyContext = new ReplyContext(context); - replyContext.getBuilder().applyData(context.getErrorMessage()); - replyContext.queue(); - return true; - } - return false; - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonEvent.java deleted file mode 100644 index 26e7be06..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonEvent.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.buttons; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; -import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; -import com.github.kaktushose.jda.commands.dispatching.reply.Replyable; -import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; -import net.dv8tion.jda.api.utils.messages.MessageCreateData; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -/** - * This class is a subclass of {@link GenericEvent}. - * It provides additional features for sending messages or editing the original message and also grants - * access to the {@link ButtonDefinition} object which describes the button interaction that is executed. - * - * @author Kaktushose - * @version 2.3.0 - * @see GenericEvent - * @see Replyable - * @since 1.0.0 - */ -public class ButtonEvent extends GenericEvent implements Replyable { - - private final ButtonDefinition button; - private final ButtonContext context; - private final ReplyContext replyContext; - - /** - * Constructs a ButtonEvent. - * - * @param button the underlying {@link ButtonDefinition} object - * @param context the {@link ButtonContext} - */ - public ButtonEvent(@NotNull ButtonDefinition button, @NotNull ButtonContext context) { - super(GenericEvent.fromEvent(context.getEvent())); - this.button = button; - this.context = context; - replyContext = new ReplyContext(context); - } - - /** - * Get the {@link ButtonDefinition} object which describes the button that is executed. - * - * @return the underlying {@link ButtonDefinition} object - */ - public ButtonDefinition getButtonDefinition() { - return button; - } - - /** - * Get the {@link JDACommands} object. - * - * @return the {@link JDACommands} object - */ - public JDACommands getJdaCommands() { - return context.getJdaCommands(); - } - - /** - * Get the {@link ButtonContext} object. - * - * @return the registered {@link ButtonContext} object - */ - @Override - public ButtonContext getContext() { - return context; - } - - @Override - public @NotNull ReplyContext getReplyContext() { - return replyContext; - } - - @Override - public void reply() { - Optional optional = context.getRuntime().getLatestReply(); - if (optional.isPresent()) { - MessageCreateData cached = optional.get(); - if (replyContext.isKeepComponents() && replyContext.getBuilder().getComponents().isEmpty()) { - replyContext.getBuilder().setComponents(cached.getComponents()); - } - - } - replyContext.queue(); - context.getRuntime().setLatestReply(replyContext.toMessageCreateData()); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonParser.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonParser.java deleted file mode 100644 index f8a0c64c..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/buttons/ButtonParser.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.buttons; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericParser; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import org.jetbrains.annotations.NotNull; - -/** - * An implementation of {@link GenericParser} that can parse {@link ButtonInteractionEvent}. - * - * @author Kaktushose - * @version 4.0.0 - * @since 4.0.0 - */ -public class ButtonParser extends GenericParser { - - /** - * Takes a {@link ButtonInteractionEvent}, parses and transpiles it into a {@link ButtonContext}. - * - * @param event the {@link SlashCommandInteractionEvent} to parse - * @param jdaCommands the {@link JDACommands} instance - * @return a new {@link ButtonContext} - */ - @Override - public @NotNull GenericContext parse(@NotNull ButtonInteractionEvent event, @NotNull JDACommands jdaCommands) { - return new ButtonContext(event, jdaCommands); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java index 094cbd48..821d0575 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java @@ -1,14 +1,17 @@ package com.github.kaktushose.jda.commands.dispatching.interactions.commands; -import com.github.kaktushose.jda.commands.dispatching.DispatcherSupervisor; +import com.github.kaktushose.jda.commands.JDACommands; import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; -import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime; -import com.github.kaktushose.jda.commands.dispatching.filter.Filter; -import com.github.kaktushose.jda.commands.dispatching.filter.FilterRegistry.FilterPosition; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.ContextCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; +import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.GenericContextInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.OptionMapping; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,101 +23,80 @@ import java.util.Optional; /** - * Dispatches commands by taking a {@link CommandContext} and passing it through the execution chain. + * Dispatches command events. * * @author Kaktushose * @version 4.0.0 - * @since 2.0.0 + * @since 4.0.0 */ -public class CommandDispatcher extends GenericDispatcher { +public class CommandDispatcher extends GenericDispatcher { private static final Logger log = LoggerFactory.getLogger(CommandDispatcher.class); - private final RuntimeSupervisor runtimeSupervisor; /** - * Constructs a new ButtonDispatcher. + * Constructs a new GenericDispatcher. * - * @param supervisor the {@link DispatcherSupervisor} which supervises this dispatcher. - * @param runtimeSupervisor the corresponding {@link RuntimeSupervisor} + * @param jdaCommands the corresponding {@link JDACommands} instance. */ - public CommandDispatcher(DispatcherSupervisor supervisor, RuntimeSupervisor runtimeSupervisor) { - super(supervisor); - this.runtimeSupervisor = runtimeSupervisor; + public CommandDispatcher(JDACommands jdaCommands) { + super(jdaCommands); } - /** - * Dispatches a {@link CommandContext}. This will route the command, apply all filters and parse the arguments. - * Finally, the command will be executed. - * - * @param context the {@link CommandContext} to dispatch. - */ - public void onEvent(CommandContext context) { + @Override + public void onEvent(Context context) { + GenericCommandInteractionEvent event = (GenericCommandInteractionEvent) context.getEvent(); ErrorMessageFactory messageFactory = implementationRegistry.getErrorMessageFactory(); - log.debug("Applying filters in phase BEFORE_ROUTING..."); - for (Filter filter : filterRegistry.getAll(FilterPosition.BEFORE_ROUTING)) { - filter.apply(context); - if (checkCancelled(context)) { - return; - } - } - - Optional optional = interactionRegistry.getCommands().stream() - .filter(it -> it.getName().equals(context.getEvent().getFullCommandName())) + Optional optional = interactionRegistry.getCommands().stream() + .filter(it -> it.getName().equals(event.getFullCommandName())) .findFirst(); + if (optional.isEmpty()) { - IllegalStateException exception = new IllegalStateException( - "No slash command found! Please report this error the the devs of jda-commands." - ); + IllegalStateException exception = new IllegalStateException("No command found! Please report this error the the devs of jda-commands."); context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, exception)); checkCancelled(context); throw exception; } - CommandDefinition command = optional.get(); - context.setCommand(command).setEphemeral(command.isEphemeral()); - log.debug("Input matches command: {}", command); - - log.debug("Acknowledging event"); - context.getEvent().deferReply(context.isEphemeral()).queue(); - - List parameters = new ArrayList<>(); - Map options = context.getOptionsAsMap(); - command.getActualParameters().forEach(param -> { - if (!options.containsKey(param.getName())) { + GenericCommandDefinition command = optional.get(); + context.setInteractionDefinition(command).setEphemeral(command.isEphemeral()); + log.debug("Input matches command: {}", command.getId()); + + List arguments; + if (command.getCommandType() == Command.Type.SLASH) { + SlashCommandDefinition slashCommand = (SlashCommandDefinition) command; + SlashCommandContext slashContext = (SlashCommandContext) context; + slashContext.setCommand(slashCommand); + + Map options = slashContext.getOptionsAsMap(); + List parameters = new ArrayList<>(); + slashCommand.getActualParameters().forEach(param -> { + if (!options.containsKey(param.getName())) { + return; + } + parameters.add(options.get(param.getName()).getAsString()); + }); + slashContext.setInput(parameters.toArray(new String[]{})); + + adapterRegistry.adapt(slashContext); + if (checkCancelled(slashContext)) { return; } - parameters.add(options.get(param.getName()).getAsString()); - }); - context.setInput(parameters.toArray(new String[]{})); - - log.debug("Applying filters in phase BEFORE_ADAPTING..."); - for (Filter filter : filterRegistry.getAll(FilterPosition.BEFORE_ADAPTING)) { - filter.apply(context); - if (checkCancelled(context)) { - return; - } - } - adapterRegistry.adapt(context); - if (checkCancelled(context)) { - return; - } - - log.debug("Applying filters in phase BEFORE_EXECUTION..."); - for (Filter filter : filterRegistry.getAll(FilterPosition.BEFORE_EXECUTION)) { - filter.apply(context); - if (checkCancelled(context)) { - return; - } + arguments = slashContext.getArguments(); + } else { + arguments = new ArrayList<>() {{ + add(new CommandEvent(context)); + add(((GenericContextInteractionEvent) event).getTarget()); + }}; } log.info("Executing command {} for user {}", command.getMethod().getName(), context.getEvent().getMember()); try { - InteractionRuntime runtime = runtimeSupervisor.newRuntime(context.getEvent(), command); + RuntimeSupervisor.InteractionRuntime runtime = runtimeSupervisor.newRuntime(event, command); context.setRuntime(runtime); - log.debug("Invoking method with following arguments: {}", context.getArguments()); - command.getMethod().invoke(runtime.getInstance(), context.getArguments().toArray()); + log.debug("Invoking method with following arguments: {}", arguments); + command.getMethod().invoke(runtime.getInstance(), arguments.toArray()); } catch (Exception exception) { log.error("Command execution failed!", exception); // this unwraps the underlying error in case of an exception inside the command class @@ -125,7 +107,7 @@ public void onEvent(CommandContext context) { } @SuppressWarnings("ConstantConditions") - private boolean checkCancelled(CommandContext context) { + private boolean checkCancelled(Context context) { if (context.isCancelled()) { ReplyContext replyContext = new ReplyContext(context); replyContext.getBuilder().applyData(context.getErrorMessage()); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java index 7ac6a2db..0104ebed 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java @@ -1,72 +1,38 @@ package com.github.kaktushose.jda.commands.dispatching.interactions.commands; -import com.github.kaktushose.jda.commands.JDACommands; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; +import com.github.kaktushose.jda.commands.dispatching.reply.ModalReplyable; import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; -import com.github.kaktushose.jda.commands.dispatching.reply.Replyable; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition; import org.jetbrains.annotations.NotNull; /** * This class is a subclass of {@link GenericEvent}. - * It provides some additional features for sending messages and also grants - * access to the {@link CommandDefinition} object which describes the command that is executed. + * It provides additional features for replying to a + * {@link net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent GenericCommandInteractionEvent}. * * @author Kaktushose * @version 4.0.0 * @see GenericEvent - * @see Replyable - * @since 1.0.0 + * @since 4.0.0 */ -public class CommandEvent extends GenericEvent implements Replyable { +public class CommandEvent extends GenericEvent implements ModalReplyable { - private final CommandDefinition command; - private final CommandContext context; private final ReplyContext replyContext; /** - * Constructs a CommandEvent. + * Constructs a new CommandEvent. * - * @param command the underlying {@link CommandDefinition} object - * @param context the {@link CommandContext} + * @param context the underlying {@link Context} */ - public CommandEvent(@NotNull CommandDefinition command, @NotNull CommandContext context) { - super(GenericEvent.fromEvent(context.getEvent())); - this.command = command; - this.context = context; + public CommandEvent(@NotNull Context context) { + super(context); replyContext = new ReplyContext(context); } - /** - * Get the {@link CommandDefinition} object which describes the command that is executed. - * - * @return the underlying {@link CommandDefinition} object - */ - public CommandDefinition getCommandDefinition() { - return command; - } - - /** - * Get the {@link JDACommands} object. - * - * @return the {@link JDACommands} object - */ - public JDACommands getJdaCommands() { - return context.getJdaCommands(); - } - - /** - * Get the {@link CommandContext} object. - * - * @return the registered {@link CommandContext} object - */ - @Override - public CommandContext getContext() { - return context; - } - @Override - public ReplyContext getReplyContext() { + public @NotNull ReplyContext getReplyContext() { return replyContext; } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandParser.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandParser.java deleted file mode 100644 index 771f90c7..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandParser.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.commands; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericParser; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import org.jetbrains.annotations.NotNull; - -/** - * An implementation of {@link GenericParser} that can parse {@link SlashCommandInteractionEvent}. - * - * @author Kaktushose - * @version 2.3.0 - * @since 2.3.0 - */ -public class CommandParser extends GenericParser { - - /** - * Takes a {@link SlashCommandInteractionEvent}, parses and transpiles it into a {@link CommandContext}. - * - * @param event the {@link SlashCommandInteractionEvent} to parse - * @param jdaCommands the {@link JDACommands} instance - * @return a new {@link CommandContext} - */ - @Override - @NotNull - public GenericContext parse(@NotNull SlashCommandInteractionEvent event, @NotNull JDACommands jdaCommands) { - return new CommandContext(event, jdaCommands).setOptions(event.getOptions()); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java similarity index 72% rename from src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandContext.java rename to src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java index 6f69ad16..c574a84c 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandContext.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java @@ -1,8 +1,8 @@ package com.github.kaktushose.jda.commands.dispatching.interactions.commands; import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.commands.OptionMapping; @@ -14,17 +14,17 @@ import java.util.Map; /** - * Implementation of {@link GenericContext} for {@link SlashCommandInteractionEvent}. + * Implementation of {@link Context} for {@link SlashCommandInteractionEvent}. * * @author Kaktushose * @version 4.0.0 * @since 4.0.0 */ -public class CommandContext extends GenericContext { +public class SlashCommandContext extends Context { private String[] input; private List options; - private CommandDefinition command; + private SlashCommandDefinition command; private List arguments; /** @@ -33,8 +33,14 @@ public class CommandContext extends GenericContext * @param event the corresponding {@link GenericInteractionCreateEvent} * @param jdaCommands the corresponding {@link JDACommands} instance */ - public CommandContext(SlashCommandInteractionEvent event, JDACommands jdaCommands) { + public SlashCommandContext(SlashCommandInteractionEvent event, JDACommands jdaCommands) { super(event, jdaCommands); + setOptions(event.getOptions()); + } + + @Override + public SlashCommandInteractionEvent getEvent() { + return (SlashCommandInteractionEvent) super.getEvent(); } /** @@ -57,7 +63,7 @@ public String[] getInput() { * @return the current CommandContext instance */ @NotNull - public CommandContext setInput(@NotNull String[] input) { + public SlashCommandContext setInput(@NotNull String[] input) { this.input = input; return this; } @@ -93,31 +99,31 @@ public Map getOptionsAsMap() { * @return the current CommandContext instance */ @NotNull - public CommandContext setOptions(@NotNull List options) { + public SlashCommandContext setOptions(@NotNull List options) { this.options = options; return this; } /** - * Gets the {@link CommandDefinition}. This will return null until the command got routed. + * Gets the {@link SlashCommandDefinition}. This will return null until the command got routed. * - * @return the {@link CommandDefinition} + * @return the {@link SlashCommandDefinition} */ @Nullable - public CommandDefinition getCommand() { + public SlashCommandDefinition getCommand() { return command; } /** - * Set the {@link CommandDefinition}. + * Set the {@link SlashCommandDefinition}. * - * @param command the {@link CommandDefinition} + * @param command the {@link SlashCommandDefinition} * @return the current CommandContext instance */ @NotNull - public CommandContext setCommand(@Nullable CommandDefinition command) { + public SlashCommandContext setCommand(@Nullable SlashCommandDefinition command) { this.command = command; - setInteraction(command); + setInteractionDefinition(command); return this; } @@ -138,7 +144,7 @@ public List getArguments() { * @return the current CommandContext instance */ @NotNull - public CommandContext setArguments(@NotNull List arguments) { + public SlashCommandContext setArguments(@NotNull List arguments) { this.arguments = arguments; return this; } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java new file mode 100644 index 00000000..f235fc74 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java @@ -0,0 +1,120 @@ +package com.github.kaktushose.jda.commands.dispatching.interactions.components; + +import com.github.kaktushose.jda.commands.JDACommands; +import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; +import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; +import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory; +import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.EphemeralInteractionDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.menus.EntitySelectMenuDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.menus.StringSelectMenuDefinition; +import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent; +import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent; +import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * Dispatches component events. + * + * @author Kaktushose + * @version 4.0.0 + * @since 4.0.0 + */ +public class ComponentDispatcher extends GenericDispatcher { + + private static final Logger log = LoggerFactory.getLogger(ComponentDispatcher.class); + + /** + * Constructs a new ComponentDispatcher. + * + * @param jdaCommands the corresponding {@link JDACommands} instance. + */ + public ComponentDispatcher(JDACommands jdaCommands) { + super(jdaCommands); + } + + @Override + public void onEvent(Context context) { + ErrorMessageFactory messageFactory = implementationRegistry.getErrorMessageFactory(); + GenericComponentInteractionCreateEvent event = (GenericComponentInteractionCreateEvent) context.getEvent(); + + Optional optionalRuntime = runtimeSupervisor.getRuntime(event); + if (optionalRuntime.isEmpty()) { + event.getHook().editOriginalComponents().queue(); + event.getHook().sendMessage(messageFactory.getUnknownInteractionMessage(context)).setEphemeral(true).queue(); + return; + } + RuntimeSupervisor.InteractionRuntime runtime = optionalRuntime.get(); + log.debug("Found corresponding runtime with id \"{}\"", runtime.getInstanceId()); + + String[] splitId = event.getComponentId().split("\\."); + String componentId = String.format("%s.%s", splitId[0], splitId[1]); + + List components = new ArrayList<>(); + components.addAll(interactionRegistry.getButtons()); + components.addAll(interactionRegistry.getSelectMenus()); + + Optional optionalComponent = components.stream().filter(it -> it.getId().equals(componentId)).findFirst(); + if (optionalComponent.isEmpty()) { + IllegalStateException exception = new IllegalStateException( + "No select menu found! Please report this error the the devs of jda-commands." + ); + context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, exception)); + checkCancelled(context); + throw exception; + } + + EphemeralInteractionDefinition component = optionalComponent.get(); + context.setInteractionDefinition(component).setEphemeral(component.isEphemeral()); + log.debug("Input matches component: {}", component.getId()); + + log.info("Executing select component {} for user {}", component.getMethod().getName(), event.getMember()); + context.setRuntime(runtime); + try { + Class clazz = component.getClass(); + if (EntitySelectMenuDefinition.class.isAssignableFrom(clazz)) { + component.getMethod().invoke( + runtime.getInstance(), + new ComponentEvent(context), + ((EntitySelectInteractionEvent) event).getMentions() + ); + } else if (StringSelectMenuDefinition.class.isAssignableFrom(clazz)) { + component.getMethod().invoke( + runtime.getInstance(), + new ComponentEvent(context), + ((StringSelectInteractionEvent) event).getValues() + ); + } else if (ButtonDefinition.class.isAssignableFrom(clazz)) { + component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context)); + } else { + throw new IllegalStateException("Unknown component type! Please report this error the the devs of jda-commands."); + } + } catch (Exception exception) { + log.error("Select menu execution failed!", exception); + // this unwraps the underlying error in case of an exception inside the command class + Throwable throwable = exception instanceof InvocationTargetException ? exception.getCause() : exception; + + context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, throwable)); + checkCancelled(context); + } + } + + @SuppressWarnings("ConstantConditions") + private boolean checkCancelled(Context context) { + if (context.isCancelled()) { + ReplyContext replyContext = new ReplyContext(context); + replyContext.getBuilder().applyData(context.getErrorMessage()); + replyContext.queue(); + return true; + } + return false; + } +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java new file mode 100644 index 00000000..f678a93c --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java @@ -0,0 +1,54 @@ +package com.github.kaktushose.jda.commands.dispatching.interactions.components; + +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; +import com.github.kaktushose.jda.commands.dispatching.reply.ModalReplyable; +import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; +import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +/** + * This class is a subclass of {@link GenericEvent}. + * It provides additional features for replying to a + * {@link net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent GenericComponentInteractionCreateEvent}. + * + * @author Kaktushose + * @version 4.0.0 + * @see GenericEvent + * @since 4.0.0 + */ +public class ComponentEvent extends GenericEvent implements ModalReplyable { + + private final ReplyContext replyContext; + + /** + * Constructs a ComponentEvent. + * + * @param context the underlying {@link Context} + */ + public ComponentEvent(@NotNull Context context) { + super(context); + replyContext = new ReplyContext(context); + } + + public ReplyContext getReplyContext() { + return replyContext; + } + + @Override + public void reply() { + Optional optional = context.getRuntime().getLatestReply(); + if (optional.isPresent()) { + MessageCreateData cached = optional.get(); + if (replyContext.isKeepComponents() && replyContext.getBuilder().getComponents().isEmpty()) { + replyContext.getBuilder().setComponents(cached.getComponents()); + } + + } + replyContext.queue(); + context.getRuntime().setLatestReply(replyContext.toMessageCreateData()); + } +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuContext.java deleted file mode 100644 index 0bd02302..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuContext.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.menus; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.EntitySelectMenuDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.GenericSelectMenuDefinition; -import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent; -import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; - -/** - * Implementation of {@link GenericContext} for {@link GenericSelectMenuInteractionEvent}. - * - * @author Kaktushose - * @version 4.0.0 - * @since 4.0.0 - */ -public class SelectMenuContext extends GenericContext> { - - private GenericSelectMenuDefinition selectMenu; - - /** - * Constructs a new SelectMenuContext. - * - * @param event the corresponding {@link GenericSelectMenuInteractionEvent} - * @param jdaCommands the corresponding {@link JDACommands} instance - */ - public SelectMenuContext(GenericSelectMenuInteractionEvent event, JDACommands jdaCommands) { - super(event, jdaCommands); - } - - /** - * Gets the {@link EntitySelectMenuDefinition}. - * - * @return the {@link EntitySelectMenuDefinition} - */ - public GenericSelectMenuDefinition getSelectMenu() { - return selectMenu; - } - - /** - * Set the {@link EntitySelectMenuDefinition}. - * - * @param selectMenu the {@link EntitySelectMenuDefinition} - * @return the current CommandContext instance - */ - public SelectMenuContext setSelectMenu(GenericSelectMenuDefinition selectMenu) { - this.selectMenu = selectMenu; - setInteraction(selectMenu); - return this; - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuDispatcher.java deleted file mode 100644 index 4df9976a..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuDispatcher.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.menus; - -import com.github.kaktushose.jda.commands.dispatching.DispatcherSupervisor; -import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; -import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; -import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.EntitySelectMenuDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.GenericSelectMenuDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.StringSelectMenuDefinition; -import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent; -import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.InvocationTargetException; -import java.util.Optional; - -public class SelectMenuDispatcher extends GenericDispatcher { - - private static final Logger log = LoggerFactory.getLogger(SelectMenuDispatcher.class); - private final RuntimeSupervisor runtimeSupervisor; - - /** - * Constructs a new ButtonDispatcher. - * - * @param supervisor the {@link DispatcherSupervisor} which supervises this dispatcher. - * @param runtimeSupervisor the corresponding {@link RuntimeSupervisor} - */ - public SelectMenuDispatcher(DispatcherSupervisor supervisor, RuntimeSupervisor runtimeSupervisor) { - super(supervisor); - this.runtimeSupervisor = runtimeSupervisor; - } - - /** - * Dispatches a {@link SelectMenuContext}. - * - * @param context the {@link SelectMenuContext} to dispatch. - */ - @Override - public void onEvent(SelectMenuContext context) { - log.debug("Acknowledging event"); - GenericSelectMenuInteractionEvent event = context.getEvent(); - event.deferEdit().queue(); - - ErrorMessageFactory messageFactory = implementationRegistry.getErrorMessageFactory(); - - Optional optionalRuntime = runtimeSupervisor.getRuntime(event); - if (optionalRuntime.isEmpty()) { - event.getHook().editOriginalComponents().queue(); - event.getHook().sendMessage(messageFactory.getUnknownInteractionMessage(context)).setEphemeral(true).queue(); - return; - } - RuntimeSupervisor.InteractionRuntime runtime = optionalRuntime.get(); - log.debug("Found corresponding runtime with id \"{}\"", runtime); - - String[] splitId = event.getComponentId().split("\\."); - String menuId = String.format("%s.%s", splitId[0], splitId[1]); - Optional> optionalMenu = interactionRegistry.getSelectMenus().stream() - .filter(it -> it.getId().equals(menuId)) - .findFirst(); - if (optionalMenu.isEmpty()) { - IllegalStateException exception = new IllegalStateException( - "No select menu found! Please report this error the the devs of jda-commands." - ); - context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, exception)); - checkCancelled(context); - throw exception; - } - - GenericSelectMenuDefinition menu = optionalMenu.get(); - context.setSelectMenu(menu).setEphemeral(menu.isEphemeral()); - log.debug("Input matches select menu: {}", menu); - - log.info("Executing select menu {} for user {}", menu.getMethod().getName(), event.getMember()); - try { - context.setRuntime(runtime); - - if (EntitySelectMenuDefinition.class.isAssignableFrom(menu.getClass())) { - EntitySelectInteractionEvent entityEvent = (EntitySelectInteractionEvent) event; - menu.getMethod().invoke(runtime.getInstance(), new SelectMenuEvent(menu, context), entityEvent.getMentions()); - } else if (StringSelectMenuDefinition.class.isAssignableFrom(menu.getClass())) { - menu.getMethod().invoke(runtime.getInstance(), new SelectMenuEvent(menu, context), event.getValues()); - } else { - throw new IllegalStateException("Unknown select menu type! Please report this error the the devs of jda-commands."); - } - - } catch (Exception exception) { - log.error("Select menu execution failed!", exception); - // this unwraps the underlying error in case of an exception inside the command class - Throwable throwable = exception instanceof InvocationTargetException ? exception.getCause() : exception; - context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, throwable)); - checkCancelled(context); - } - } - - @SuppressWarnings("ConstantConditions") - private boolean checkCancelled(SelectMenuContext context) { - if (context.isCancelled()) { - ReplyContext replyContext = new ReplyContext(context); - replyContext.getBuilder().applyData(context.getErrorMessage()); - replyContext.queue(); - return true; - } - return false; - } - -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuEvent.java deleted file mode 100644 index 5785feb4..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuEvent.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.menus; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; -import com.github.kaktushose.jda.commands.dispatching.interactions.buttons.ButtonContext; -import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; -import com.github.kaktushose.jda.commands.dispatching.reply.Replyable; -import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.EntitySelectMenuDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.menus.GenericSelectMenuDefinition; -import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; -import net.dv8tion.jda.api.utils.messages.MessageCreateData; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -/** - * This class is a subclass of {@link GenericEvent}. - * It provides additional features for sending messages or editing the original message and also grants - * access to the {@link EntitySelectMenuDefinition} object which describes the select menu interaction that is executed. - * - * @author Kaktushose - * @version 4.0.0 - * @see GenericEvent - * @see Replyable - * @since 4.0.0 - */ -public class SelectMenuEvent extends GenericEvent implements Replyable { - - private final GenericSelectMenuDefinition selectMenu; - private final SelectMenuContext context; - private final ReplyContext replyContext; - - /** - * Constructs a ButtonEvent. - * - * @param selectMenu the underlying {@link ButtonDefinition} object - * @param context the {@link ButtonContext} - */ - public SelectMenuEvent(@NotNull GenericSelectMenuDefinition selectMenu, @NotNull SelectMenuContext context) { - super(GenericEvent.fromEvent(context.getEvent())); - this.selectMenu = selectMenu; - this.context = context; - replyContext = new ReplyContext(context); - } - - /** - * Get the {@link EntitySelectMenuDefinition} object which describes the button that is executed. - * - * @return the underlying {@link EntitySelectMenuDefinition} object - */ - public GenericSelectMenuDefinition getSelectMenu() { - return selectMenu; - } - - /** - * Get the {@link SelectMenuContext} object. - * - * @return the registered {@link SelectMenuContext} object - */ - @Override - public SelectMenuContext getContext() { - return context; - } - - /** - * Get the {@link JDACommands} object. - * - * @return the {@link JDACommands} object - */ - public JDACommands getJdaCommands() { - return context.getJdaCommands(); - } - - public ReplyContext getReplyContext() { - return replyContext; - } - - @Override - public void reply() { - Optional optional = context.getRuntime().getLatestReply(); - if (optional.isPresent()) { - MessageCreateData cached = optional.get(); - if (replyContext.isKeepComponents() && replyContext.getBuilder().getComponents().isEmpty()) { - replyContext.getBuilder().setComponents(cached.getComponents()); - } - - } - replyContext.queue(); - context.getRuntime().setLatestReply(replyContext.toMessageCreateData()); - } - -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuParser.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuParser.java deleted file mode 100644 index 196dd37c..00000000 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/menus/SelectMenuParser.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.github.kaktushose.jda.commands.dispatching.interactions.menus; - -import com.github.kaktushose.jda.commands.JDACommands; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericParser; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; -import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; -import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent; -import org.jetbrains.annotations.NotNull; - -/** - * An implementation of {@link GenericParser} that can parse {@link ButtonInteractionEvent}. - * - * @author Kaktushose - * @version 4.0.0 - * @since 4.0.0 - */ -public class SelectMenuParser extends GenericParser> { - - /** - * Takes a {@link GenericSelectMenuInteractionEvent}, parses and transpiles it into a {@link SelectMenuContext}. - * - * @param event the {@link GenericSelectMenuInteractionEvent} to parse - * @param jdaCommands the {@link JDACommands} instance - * @return a new {@link SelectMenuContext} - */ - @Override - public @NotNull GenericContext parse(@NotNull GenericSelectMenuInteractionEvent event, @NotNull JDACommands jdaCommands) { - return new SelectMenuContext(event, jdaCommands); - } -} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java new file mode 100644 index 00000000..035752e4 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java @@ -0,0 +1,91 @@ +package com.github.kaktushose.jda.commands.dispatching.interactions.modals; + +import com.github.kaktushose.jda.commands.JDACommands; +import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher; +import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; +import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory; +import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import net.dv8tion.jda.api.interactions.modals.ModalMapping; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class ModalDispatcher extends GenericDispatcher { + + private static final Logger log = LoggerFactory.getLogger(ModalDispatcher.class); + + /** + * Constructs a new ButtonDispatcher. + * + * @param jdaCommands the corresponding {@link JDACommands} instance. + */ + public ModalDispatcher(JDACommands jdaCommands) { + super(jdaCommands); + } + + @Override + public void onEvent(Context context) { + ModalInteractionEvent event = (ModalInteractionEvent) context.getEvent(); + ErrorMessageFactory messageFactory = implementationRegistry.getErrorMessageFactory(); + + Optional optionalRuntime = runtimeSupervisor.getRuntime(event); + if (optionalRuntime.isEmpty()) { + event.getHook().sendMessage(messageFactory.getUnknownInteractionMessage(context)).setEphemeral(true).queue(); + return; + } + RuntimeSupervisor.InteractionRuntime runtime = optionalRuntime.get(); + log.debug("Found corresponding runtime with id \"{}\"", runtime.getInstanceId()); + + String[] splitId = event.getModalId().split("\\."); + String modalId = String.format("%s.%s", splitId[0], splitId[1]); + Optional optionalModal = interactionRegistry.getModals().stream() + .filter(it -> it.getId().equals(modalId)) + .findFirst(); + + if (optionalModal.isEmpty()) { + IllegalStateException exception = new IllegalStateException( + "No Modal found! Please report this error the the devs of jda-commands." + ); + context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, exception)); + checkCancelled(context); + throw exception; + } + + ModalDefinition modal = optionalModal.get(); + context.setInteractionDefinition(modal).setEphemeral(modal.isEphemeral()); + log.debug("Input matches Modal: {}", modal.getId()); + log.info("Executing Modal {} for user {}", modal.getMethod().getName(), event.getMember()); + try { + context.setRuntime(runtime); + List arguments = new ArrayList<>(); + arguments.add(new ModalEvent(context)); + arguments.addAll(event.getValues().stream().map(ModalMapping::getAsString).collect(Collectors.toSet())); + modal.getMethod().invoke(runtime.getInstance(), arguments.toArray()); + } catch (Exception exception) { + log.error("Modal execution failed!", exception); + // this unwraps the underlying error in case of an exception inside the command class + Throwable throwable = exception instanceof InvocationTargetException ? exception.getCause() : exception; + context.setCancelled(true).setErrorMessage(messageFactory.getCommandExecutionFailedMessage(context, throwable)); + checkCancelled(context); + } + } + + @SuppressWarnings("ConstantConditions") + private boolean checkCancelled(Context context) { + if (context.isCancelled()) { + ReplyContext replyContext = new ReplyContext(context); + replyContext.getBuilder().applyData(context.getErrorMessage()); + replyContext.setEditReply(false).queue(); + return true; + } + return false; + } +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java new file mode 100644 index 00000000..e6d53cf3 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java @@ -0,0 +1,38 @@ +package com.github.kaktushose.jda.commands.dispatching.interactions.modals; + +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; +import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext; +import com.github.kaktushose.jda.commands.dispatching.reply.Replyable; +import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition; +import org.jetbrains.annotations.NotNull; + +/** + * This class is a subclass of {@link GenericEvent}. + * It provides additional features for replying to a + * {@link net.dv8tion.jda.api.events.interaction.ModalInteractionEvent ModalInteractionEvent}. + * + * @author Kaktushose + * @version 4.0.0 + * @see GenericEvent + * @since 4.0.0 + */ +public class ModalEvent extends GenericEvent implements Replyable { + + private final ReplyContext replyContext; + + protected ModalEvent(Context context) { + super(context); + replyContext = new ReplyContext(context); + } + + @Override + public @NotNull ReplyContext getReplyContext() { + return replyContext; + } + + @Override + public void reply() { + replyContext.queue(); + } +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java new file mode 100644 index 00000000..df6a1582 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java @@ -0,0 +1,42 @@ +package com.github.kaktushose.jda.commands.dispatching.reply; + +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition; +import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; +import net.dv8tion.jda.api.interactions.callbacks.IModalCallback; + +/** + * Generic interface holding reply methods for modal replies. + * + * @author Kaktushose + * @version 4.0.0 + * @since 4.0.0 + */ +public interface ModalReplyable extends Replyable { + + /** + * Replies to this Interaction with a Modal. This will open a popup on the target user's Discord client. + * + * @param modal the id of the modal to reply with + */ + default void replyModal(String modal) { + IModalCallback callback; + Context context = getContext(); + GenericInteractionCreateEvent event = context.getEvent(); + if (event instanceof IModalCallback) { + callback = (IModalCallback) event; + } else { + throw new IllegalArgumentException( + String.format("Cannot reply to '%s'! Please report this error to the jda-commands devs!", event.getClass().getName()) + ); + } + + String id = String.format("%s.%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), modal); + + ModalDefinition modalDefinition = context.getJdaCommands().getInteractionRegistry().getModals().stream() + .filter(it -> it.getId().equals(id)).findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Modal")); + + callback.replyModal(modalDefinition.toModal(modalDefinition.getRuntimeId(context))).queue(); + } + +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ReplyContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ReplyContext.java index 5bbdb9bc..166e976b 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ReplyContext.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ReplyContext.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.reply; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; @@ -36,9 +36,9 @@ public class ReplyContext { /** * Constructs a new ReplyContext. * - * @param context the corresponding {@link CommandContext} + * @param context the corresponding {@link SlashCommandContext} */ - public ReplyContext(GenericContext context) { + public ReplyContext(Context context) { event = context.getEvent(); builder = new MessageCreateBuilder(); success = (message) -> { @@ -210,10 +210,9 @@ public void queue() { String.format("Cannot reply to '%s'! Please report this error to the jda-commands devs!", event.getClass().getName()) ); } - // The ReplyContext is also used for error messages and some appear even before acknowledging took place - // In this case the event gets acknowledged with ephemeral set to false + if (!event.isAcknowledged()) { - callback.deferReply(false).queue(); + callback.deferReply(ephemeralReply).queue(); } callback.getHook().setEphemeral(ephemeralReply); if (editReply) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java index 13c58fdc..073c9e1c 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java @@ -2,14 +2,13 @@ import com.github.kaktushose.jda.commands.annotations.interactions.SlashCommand; import com.github.kaktushose.jda.commands.data.EmbedDTO; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent; import com.github.kaktushose.jda.commands.dispatching.reply.components.Buttons; import com.github.kaktushose.jda.commands.dispatching.reply.components.Component; import com.github.kaktushose.jda.commands.dispatching.reply.components.SelectMenus; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.ItemComponent; import net.dv8tion.jda.api.interactions.components.buttons.Button; @@ -157,12 +156,12 @@ default void reply(@NotNull EmbedDTO embedDTO, @Nullable Consumer succe */ default Replyable with(@NotNull Component... components) { List items = new ArrayList<>(); - GenericContext context = getContext(); + Context context = getContext(); for (Component component : components) { if (component instanceof Buttons) { Buttons buttons = (Buttons) component; buttons.getButtons().forEach(button -> { - String id = String.format("%s.%s", context.getInteraction().getMethod().getDeclaringClass().getSimpleName(), button.getId()); + String id = String.format("%s.%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), button.getId()); context.getJdaCommands().getInteractionRegistry().getButtons() .stream() .filter(it -> it.getId().equals(id)) @@ -180,7 +179,7 @@ default Replyable with(@NotNull Component... components) { if (component instanceof SelectMenus) { SelectMenus menus = (SelectMenus) component; menus.getSelectMenus().forEach(menu -> { - String id = String.format("%s.%s", context.getInteraction().getMethod().getDeclaringClass().getSimpleName(), menu.getId()); + String id = String.format("%s.%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), menu.getId()); context.getJdaCommands().getInteractionRegistry().getSelectMenus() .stream() .filter(it -> it.getId().equals(id)) @@ -196,7 +195,7 @@ default Replyable with(@NotNull Component... components) { return this; } - GenericContext getContext(); + Context getContext(); /** * Adds an {@link ActionRow} to the reply and adds the passed {@link Component Components} to it. @@ -245,7 +244,7 @@ default Replyable setEphemeral(boolean ephemeral) { * @param success the callback consumer * @return the current instance for fluent interface */ - private Replyable setSuccessCallback(Consumer success) { + default Replyable setSuccessCallback(Consumer success) { getReplyContext().setSuccessCallback(success); return this; } @@ -256,7 +255,7 @@ private Replyable setSuccessCallback(Consumer success) { * @param failure the callback consumer * @return the current instance for fluent interface */ - private Replyable setFailureCallback(Consumer failure) { + default Replyable setFailureCallback(Consumer failure) { getReplyContext().setFailureCallback(failure); return this; } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java index 4e8bde41..48b60c37 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java @@ -1,6 +1,6 @@ package com.github.kaktushose.jda.commands.dispatching.validation; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import org.jetbrains.annotations.NotNull; /** @@ -18,9 +18,9 @@ public interface Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument passes the constraints */ - boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context); + boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java index 427d22e0..f719acb3 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.validation.impl; import com.github.kaktushose.jda.commands.annotations.constraints.Max; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import org.jetbrains.annotations.NotNull; @@ -20,11 +20,11 @@ public class MaximumValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is a number whose value is lower or equal to the specified maximum */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { Max max = (Max) annotation; return ((Number) argument).longValue() <= max.value(); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java index b8524b63..55ba17d9 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.validation.impl; import com.github.kaktushose.jda.commands.annotations.constraints.Min; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import org.jetbrains.annotations.NotNull; @@ -21,11 +21,11 @@ public class MinimumValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is a number whose value is greater or equal to the specified minimum */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { Min min = (Min) annotation; return ((Number) argument).longValue() >= min.value(); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java index 3b30cddf..516cb845 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.validation.impl; import com.github.kaktushose.jda.commands.annotations.constraints.NotPerm; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; @@ -26,12 +26,12 @@ public class NotPermissionValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is a user or member that doesn't have the specified discord * permission */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { Set permissions = new HashSet<>(); NotPerm perm = (NotPerm) annotation; diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java index 78bc945d..6ee5e13a 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java @@ -2,7 +2,7 @@ import com.github.kaktushose.jda.commands.annotations.constraints.NotRole; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.RoleAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; @@ -25,11 +25,11 @@ public class NotRoleValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is a user or member that doesn't have the specified guild role */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { NotRole roleAnnotation = (NotRole) annotation; Optional optional = new RoleAdapter().parse(roleAnnotation.value(), context); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java index dcb81e0d..90ebc058 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java @@ -2,7 +2,7 @@ import com.github.kaktushose.jda.commands.annotations.constraints.NotUser; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.MemberAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import net.dv8tion.jda.api.entities.Member; import org.jetbrains.annotations.NotNull; @@ -24,11 +24,11 @@ public class NotUserValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument isn't the specified user or member */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { Member member = (Member) argument; NotUser user = (NotUser) annotation; Optional optional = new MemberAdapter().parse(user.value(), context); diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java index 953cc6a9..6acf5a75 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.validation.impl; import com.github.kaktushose.jda.commands.annotations.constraints.Perm; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; @@ -26,12 +26,12 @@ public class PermissionValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is a user or member that has the specified discord * permission */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { Set permissions = new HashSet<>(); Perm perm = (Perm) annotation; try { diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java index 591fc1ee..61014024 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.dispatching.validation.impl; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.RoleAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; @@ -25,11 +25,11 @@ public class RoleValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is a user or member that has the specified guild role */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { com.github.kaktushose.jda.commands.annotations.constraints.Role roleAnnotation = (com.github.kaktushose.jda.commands.annotations.constraints.Role) annotation; diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java index 4b002af8..e7369b74 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java +++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java @@ -2,7 +2,7 @@ import com.github.kaktushose.jda.commands.annotations.constraints.User; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.MemberAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.validation.Validator; import net.dv8tion.jda.api.entities.Member; import org.jetbrains.annotations.NotNull; @@ -24,11 +24,11 @@ public class UserValidator implements Validator { * * @param argument the argument to validate * @param annotation the corresponding annotation - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the argument is the specified user or member */ @Override - public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull GenericContext context) { + public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) { Member member = (Member) argument; User user = (User) annotation; Optional optional = new MemberAdapter().parse(user.value(), context); diff --git a/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java b/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java index 09e9a618..588d612e 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java +++ b/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java @@ -1,10 +1,10 @@ package com.github.kaktushose.jda.commands.embeds; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.reflect.ConstraintDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; @@ -31,9 +31,9 @@ public class DefaultErrorMessageFactory implements ErrorMessageFactory { protected static final String PREFIX = Matcher.quoteReplacement("/"); @Override - public MessageCreateData getTypeAdaptingFailedMessage(@NotNull CommandContext context) { + public MessageCreateData getTypeAdaptingFailedMessage(@NotNull SlashCommandContext context) { StringBuilder sbExpected = new StringBuilder(); - CommandDefinition command = context.getCommand(); + SlashCommandDefinition command = context.getCommand(); List arguments = Arrays.asList(context.getInput()); command.getParameters().forEach(parameter -> { @@ -64,9 +64,9 @@ public MessageCreateData getTypeAdaptingFailedMessage(@NotNull CommandContext co } @Override - public MessageCreateData getInsufficientPermissionsMessage(@NotNull CommandContext context) { + public MessageCreateData getInsufficientPermissionsMessage(@NotNull SlashCommandContext context) { StringBuilder sbPermissions = new StringBuilder(); - CommandDefinition command = context.getCommand(); + SlashCommandDefinition command = context.getCommand(); command.getPermissions().forEach(permission -> sbPermissions.append(permission).append(", ")); String permissions = sbPermissions.toString().isEmpty() ? "N/A" : sbPermissions.substring(0, sbPermissions.length() - 2); MessageEmbed embed = new EmbedBuilder() @@ -82,7 +82,7 @@ public MessageCreateData getInsufficientPermissionsMessage(@NotNull CommandConte } @Override - public MessageCreateData getGuildMutedMessage(@NotNull GenericContext context) { + public MessageCreateData getGuildMutedMessage(@NotNull Context context) { return new MessageCreateBuilder().setEmbeds(new EmbedBuilder() .setColor(Color.RED) .setTitle("Insufficient Permissions") @@ -92,7 +92,7 @@ public MessageCreateData getGuildMutedMessage(@NotNull GenericContext context } @Override - public MessageCreateData getChannelMutedMessage(@NotNull GenericContext context) { + public MessageCreateData getChannelMutedMessage(@NotNull Context context) { return new MessageCreateBuilder().setEmbeds(new EmbedBuilder() .setColor(Color.RED) .setTitle("Insufficient Permissions") @@ -102,7 +102,7 @@ public MessageCreateData getChannelMutedMessage(@NotNull GenericContext conte } @Override - public MessageCreateData getUserMutedMessage(@NotNull GenericContext context) { + public MessageCreateData getUserMutedMessage(@NotNull Context context) { return new MessageCreateBuilder().setEmbeds(new EmbedBuilder() .setColor(Color.RED) .setTitle("Insufficient Permissions") @@ -112,7 +112,7 @@ public MessageCreateData getUserMutedMessage(@NotNull GenericContext context) } @Override - public MessageCreateData getConstraintFailedMessage(@NotNull GenericContext context, @NotNull ConstraintDefinition constraint) { + public MessageCreateData getConstraintFailedMessage(@NotNull Context context, @NotNull ConstraintDefinition constraint) { return new MessageCreateBuilder().setEmbeds(new EmbedBuilder() .setColor(Color.ORANGE) .setTitle("Parameter Error") @@ -122,7 +122,7 @@ public MessageCreateData getConstraintFailedMessage(@NotNull GenericContext c } @Override - public MessageCreateData getCooldownMessage(@NotNull GenericContext context, long ms) { + public MessageCreateData getCooldownMessage(@NotNull Context context, long ms) { long secs = TimeUnit.MILLISECONDS.toSeconds(ms); long seconds = secs % 60; long minutes = (secs / 60) % 60; @@ -153,7 +153,7 @@ public MessageCreateData getCooldownMessage(@NotNull GenericContext context, } @Override - public MessageCreateData getWrongChannelTypeMessage(@NotNull GenericContext context) { + public MessageCreateData getWrongChannelTypeMessage(@NotNull Context context) { return new MessageCreateBuilder().setEmbeds(new EmbedBuilder() .setColor(Color.RED) .setTitle("Wrong Channel Type") @@ -163,7 +163,7 @@ public MessageCreateData getWrongChannelTypeMessage(@NotNull GenericContext c } @Override - public MessageCreateData getCommandExecutionFailedMessage(@NotNull GenericContext context, @NotNull Throwable exception) { + public MessageCreateData getCommandExecutionFailedMessage(@NotNull Context context, @NotNull Throwable exception) { String error; error = String.format("```The user \"%s\" attempted to execute an \"%s\" interaction at %s, " + @@ -185,7 +185,7 @@ public MessageCreateData getCommandExecutionFailedMessage(@NotNull GenericContex } @Override - public MessageCreateData getUnknownInteractionMessage(@NotNull GenericContext context) { + public MessageCreateData getUnknownInteractionMessage(@NotNull Context context) { return new MessageCreateBuilder().setEmbeds(new EmbedBuilder() .setColor(Color.RED) .setTitle("Unknown Interaction") diff --git a/src/main/java/com/github/kaktushose/jda/commands/embeds/ErrorMessageFactory.java b/src/main/java/com/github/kaktushose/jda/commands/embeds/ErrorMessageFactory.java index 5bd556c4..94612677 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/embeds/ErrorMessageFactory.java +++ b/src/main/java/com/github/kaktushose/jda/commands/embeds/ErrorMessageFactory.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.embeds; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.reflect.ConstraintDefinition; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.utils.messages.MessageCreateData; @@ -20,83 +20,83 @@ public interface ErrorMessageFactory { /** * Gets a {@link MessageCreateData} to send when type adapting of the user input failed. * - * @param context the corresponding {@link CommandContext} + * @param context the corresponding {@link SlashCommandContext} * @return a {@link MessageCreateData} to send when type adapting failed */ - MessageCreateData getTypeAdaptingFailedMessage(@NotNull CommandContext context); + MessageCreateData getTypeAdaptingFailedMessage(@NotNull SlashCommandContext context); /** * Gets a {@link MessageCreateData} to send when a user is missing permissions. * - * @param context the corresponding {@link CommandContext} + * @param context the corresponding {@link SlashCommandContext} * @return a {@link MessageCreateData} to send when a user is missing permissions */ - MessageCreateData getInsufficientPermissionsMessage(@NotNull CommandContext context); + MessageCreateData getInsufficientPermissionsMessage(@NotNull SlashCommandContext context); /** * Gets a {@link MessageCreateData} to send when a {@link net.dv8tion.jda.api.entities.Guild Guild} is muted. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return a {@link MessageCreateData} to send when a {@link net.dv8tion.jda.api.entities.Guild Guild} is muted */ - MessageCreateData getGuildMutedMessage(@NotNull GenericContext context); + MessageCreateData getGuildMutedMessage(@NotNull Context context); /** * Gets a {@link MessageCreateData} to send when a {@link net.dv8tion.jda.api.entities.channel.concrete.TextChannel TextChannel} is muted. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return a {@link MessageCreateData} to send when a {@link net.dv8tion.jda.api.entities.channel.concrete.TextChannel TextChannel} is muted */ - MessageCreateData getChannelMutedMessage(@NotNull GenericContext context); + MessageCreateData getChannelMutedMessage(@NotNull Context context); /** * Gets a {@link MessageCreateData} to send when a {@link net.dv8tion.jda.api.entities.User User} is muted. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return a {@link MessageCreateData} to send when a {@link net.dv8tion.jda.api.entities.User User} is muted */ - MessageCreateData getUserMutedMessage(@NotNull GenericContext context); + MessageCreateData getUserMutedMessage(@NotNull Context context); /** * Gets a {@link MessageCreateData} to send when a parameter constraint fails. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @param constraint the corresponding {@link ConstraintDefinition} that failed * @return a {@link MessageCreateData} to send when a parameter constraint fails */ - MessageCreateData getConstraintFailedMessage(@NotNull GenericContext context, @NotNull ConstraintDefinition constraint); + MessageCreateData getConstraintFailedMessage(@NotNull Context context, @NotNull ConstraintDefinition constraint); /** * Gets a {@link Message} to send when a command still has a cooldown. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return a {@link MessageCreateData} to send when a command still has a cooldown */ - MessageCreateData getCooldownMessage(@NotNull GenericContext context, long ms); + MessageCreateData getCooldownMessage(@NotNull Context context, long ms); /** * Gets a {@link MessageCreateData} to send when the channel type isn't suitable for the command. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return a {@link MessageCreateData} to send when the channel type isn't suitable for the command */ - MessageCreateData getWrongChannelTypeMessage(@NotNull GenericContext context); + MessageCreateData getWrongChannelTypeMessage(@NotNull Context context); /** * Gets a {@link MessageCreateData} to send when the command execution failed. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @param exception the Exception that made the command execution fail * @return a {@link MessageCreateData} to send when the command execution failed */ - MessageCreateData getCommandExecutionFailedMessage(@NotNull GenericContext context, @NotNull Throwable exception); + MessageCreateData getCommandExecutionFailedMessage(@NotNull Context context, @NotNull Throwable exception); /** * Gets a {@link MessageCreateData} to send when an incoming interaction already timed out. * - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return a {@link MessageCreateData} to send when an incoming interaction already timed out */ - MessageCreateData getUnknownInteractionMessage(@NotNull GenericContext context); + MessageCreateData getUnknownInteractionMessage(@NotNull Context context); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java b/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java index 07b5de8f..c9123dba 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java +++ b/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java @@ -1,11 +1,11 @@ package com.github.kaktushose.jda.commands.embeds; import com.github.kaktushose.jda.commands.data.EmbedCache; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.reflect.ConstraintDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.utils.messages.MessageCreateData; import org.jetbrains.annotations.NotNull; @@ -31,13 +31,13 @@ public JsonErrorMessageFactory(EmbedCache embedCache) { } @Override - public MessageCreateData getTypeAdaptingFailedMessage(@NotNull CommandContext context) { + public MessageCreateData getTypeAdaptingFailedMessage(@NotNull SlashCommandContext context) { if (!embedCache.containsEmbed("typeAdaptingFailed")) { return super.getTypeAdaptingFailedMessage(context); } StringBuilder sbExpected = new StringBuilder(); - CommandDefinition command = context.getCommand(); + SlashCommandDefinition command = context.getCommand(); List arguments = Arrays.asList(context.getInput()); command.getParameters().forEach(parameter -> { @@ -64,12 +64,12 @@ public MessageCreateData getTypeAdaptingFailedMessage(@NotNull CommandContext co } @Override - public MessageCreateData getInsufficientPermissionsMessage(@NotNull CommandContext context) { + public MessageCreateData getInsufficientPermissionsMessage(@NotNull SlashCommandContext context) { if (!embedCache.containsEmbed("insufficientPermissions")) { return super.getInsufficientPermissionsMessage(context); } - CommandDefinition command = context.getCommand(); + SlashCommandDefinition command = context.getCommand(); StringBuilder sbPermissions = new StringBuilder(); command.getPermissions().forEach(permission -> sbPermissions.append(permission).append(", ")); String permissions = sbPermissions.toString().isEmpty() ? "N/A" : sbPermissions.substring(0, sbPermissions.length() - 2); @@ -82,7 +82,7 @@ public MessageCreateData getInsufficientPermissionsMessage(@NotNull CommandConte } @Override - public MessageCreateData getGuildMutedMessage(@NotNull GenericContext context) { + public MessageCreateData getGuildMutedMessage(@NotNull Context context) { if (!embedCache.containsEmbed("guildMuted")) { return super.getGuildMutedMessage(context); } @@ -90,7 +90,7 @@ public MessageCreateData getGuildMutedMessage(@NotNull GenericContext context } @Override - public MessageCreateData getChannelMutedMessage(@NotNull GenericContext context) { + public MessageCreateData getChannelMutedMessage(@NotNull Context context) { if (!embedCache.containsEmbed("channelMuted")) { return super.getChannelMutedMessage(context); } @@ -98,7 +98,7 @@ public MessageCreateData getChannelMutedMessage(@NotNull GenericContext conte } @Override - public MessageCreateData getUserMutedMessage(@NotNull GenericContext context) { + public MessageCreateData getUserMutedMessage(@NotNull Context context) { if (!embedCache.containsEmbed("userMuted")) { return super.getUserMutedMessage(context); } @@ -106,7 +106,7 @@ public MessageCreateData getUserMutedMessage(@NotNull GenericContext context) } @Override - public MessageCreateData getConstraintFailedMessage(@NotNull GenericContext context, @NotNull ConstraintDefinition constraint) { + public MessageCreateData getConstraintFailedMessage(@NotNull Context context, @NotNull ConstraintDefinition constraint) { if (!embedCache.containsEmbed("constraintFailed")) { return super.getConstraintFailedMessage(context, constraint); } @@ -116,7 +116,7 @@ public MessageCreateData getConstraintFailedMessage(@NotNull GenericContext c } @Override - public MessageCreateData getCooldownMessage(@NotNull GenericContext context, long ms) { + public MessageCreateData getCooldownMessage(@NotNull Context context, long ms) { if (!embedCache.containsEmbed("cooldown")) { return super.getCooldownMessage(context, ms); } @@ -132,7 +132,7 @@ public MessageCreateData getCooldownMessage(@NotNull GenericContext context, } @Override - public MessageCreateData getWrongChannelTypeMessage(@NotNull GenericContext context) { + public MessageCreateData getWrongChannelTypeMessage(@NotNull Context context) { if (!embedCache.containsEmbed("wrongChannel")) { return super.getWrongChannelTypeMessage(context); } @@ -140,7 +140,7 @@ public MessageCreateData getWrongChannelTypeMessage(@NotNull GenericContext c } @Override - public MessageCreateData getCommandExecutionFailedMessage(@NotNull GenericContext context, @NotNull Throwable exception) { + public MessageCreateData getCommandExecutionFailedMessage(@NotNull Context context, @NotNull Throwable exception) { if (!embedCache.containsEmbed("executionFailed")) { return super.getCommandExecutionFailedMessage(context, exception); } @@ -150,7 +150,7 @@ public MessageCreateData getCommandExecutionFailedMessage(@NotNull GenericContex } @Override - public MessageCreateData getUnknownInteractionMessage(@NotNull GenericContext context) { + public MessageCreateData getUnknownInteractionMessage(@NotNull Context context) { if (!embedCache.containsEmbed("unknownInteraction")) { return super.getUnknownInteractionMessage(context); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/permissions/DefaultPermissionsProvider.java b/src/main/java/com/github/kaktushose/jda/commands/permissions/DefaultPermissionsProvider.java index cdb46ddb..1aad2d34 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/permissions/DefaultPermissionsProvider.java +++ b/src/main/java/com/github/kaktushose/jda/commands/permissions/DefaultPermissionsProvider.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.permissions; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; @@ -14,10 +14,10 @@ /** * Default implementation of {@link PermissionsProvider} with the following behaviour: *
    - *
  • {@link PermissionsProvider#isMuted(User, GenericContext)} will always return {@code false}
  • - *
  • {@link PermissionsProvider#hasPermission(User, GenericContext)} will always return {@code true}
  • + *
  • {@link PermissionsProvider#isMuted(User, Context)} will always return {@code false}
  • + *
  • {@link PermissionsProvider#hasPermission(User, Context)} will always return {@code true}
  • *
  • - * {@link PermissionsProvider#hasPermission(Member, GenericContext)} will check against the default Discord permissions. More + * {@link PermissionsProvider#hasPermission(Member, Context)} will check against the default Discord permissions. More * formally, this method will work with any permission provided by {@link Permission#values()}, ignoring the * case. Any other permission String will be ignored. *
  • @@ -33,19 +33,19 @@ public class DefaultPermissionsProvider implements PermissionsProvider { private static final Logger log = LoggerFactory.getLogger(DefaultPermissionsProvider.class); @Override - public boolean isMuted(@NotNull User user, @NotNull GenericContext context) { + public boolean isMuted(@NotNull User user, @NotNull Context context) { return false; } @Override - public boolean hasPermission(@NotNull User user, @NotNull GenericContext context) { + public boolean hasPermission(@NotNull User user, @NotNull Context context) { return true; } @Override - public boolean hasPermission(@NotNull Member member, @NotNull GenericContext ctx) { + public boolean hasPermission(@NotNull Member member, @NotNull Context ctx) { // TODO temporary fix until permissions for other events were figured out - CommandContext context = (CommandContext) ctx; + SlashCommandContext context = (SlashCommandContext) ctx; for (String s : context.getCommand().getPermissions()) { // not a discord perm, continue if (Arrays.stream(Permission.values()).noneMatch(p -> p.name().equalsIgnoreCase(s))) { diff --git a/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java b/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java index 60efca03..77859bb7 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java +++ b/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java @@ -1,7 +1,7 @@ package com.github.kaktushose.jda.commands.permissions; import com.github.kaktushose.jda.commands.annotations.interactions.Permissions; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; @@ -22,35 +22,35 @@ public interface PermissionsProvider { /** - * Checks if a {@link User} is muted. Useful for ban lists, where the {@link GenericContext} should be cancelled even before + * Checks if a {@link User} is muted. Useful for ban lists, where the {@link Context} should be cancelled even before * routing, permission checks, etc. * * @param user the {@link User} to perform the check against - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the user is muted * @see com.github.kaktushose.jda.commands.dispatching.filter.impl.UserMuteFilter UserMuteFilter */ - boolean isMuted(@NotNull User user, @NotNull GenericContext context); + boolean isMuted(@NotNull User user, @NotNull Context context); /** - * Checks if a {@link User} has permissions. Compared to {@link #hasPermission(Member, GenericContext)} this method will be + * Checks if a {@link User} has permissions. Compared to {@link #hasPermission(Member, Context)} this method will be * called if the command gets executed in a non-guild context, where no member object is available. * * @param user the {@link User} to perform the check against - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the user has the permission to execute the command - * @see #hasPermission(Member, GenericContext) + * @see #hasPermission(Member, Context) */ - boolean hasPermission(@NotNull User user, @NotNull GenericContext context); + boolean hasPermission(@NotNull User user, @NotNull Context context); /** * Checks if a {@link Member} has permissions. * * @param member the {@link Member} to perform the check against - * @param context the corresponding {@link GenericContext} + * @param context the corresponding {@link Context} * @return {@code true} if the user has the permission to execute the command */ - boolean hasPermission(@NotNull Member member, @NotNull GenericContext context); + boolean hasPermission(@NotNull Member member, @NotNull Context context); /** * Gets a {@link List} of user ids that map to the given permission string. diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/ControllerDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java similarity index 52% rename from src/main/java/com/github/kaktushose/jda/commands/reflect/ControllerDefinition.java rename to src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java index 502e98f1..9a7b0f0d 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/ControllerDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java @@ -6,10 +6,14 @@ import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition; import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.ContextCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import com.github.kaktushose.jda.commands.reflect.interactions.menus.EntitySelectMenuDefinition; import com.github.kaktushose.jda.commands.reflect.interactions.menus.GenericSelectMenuDefinition; import com.github.kaktushose.jda.commands.reflect.interactions.menus.StringSelectMenuDefinition; +import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; import org.jetbrains.annotations.NotNull; @@ -23,99 +27,113 @@ import java.util.stream.Collectors; /** - * Representation of a interaction controller. + * Representation of an interaction controller. * * @author Kaktushose * @version 4.0.0 * @since 2.0.0 */ -public class ControllerDefinition { +public class InteractionControllerDefinition { - private static final Logger log = LoggerFactory.getLogger(ControllerDefinition.class); - private final List commands; + private static final Logger log = LoggerFactory.getLogger(InteractionControllerDefinition.class); + private final List commands; private final List buttons; private final List> selectMenus; private final List autoCompletes; + private final List modals; - private ControllerDefinition(List commands, - List buttons, - List> selectMenus, - List autoCompletes) { + private InteractionControllerDefinition(List commands, + List buttons, + List> selectMenus, + List autoCompletes, + List modals) { this.commands = commands; this.buttons = buttons; this.selectMenus = selectMenus; this.autoCompletes = autoCompletes; + this.modals = modals; } /** * Builds a new ControllerDefinition. * - * @param controllerClass the {@link Class} of the controller + * @param interactionClass the {@link Class} of the controller * @param validatorRegistry the corresponding {@link ValidatorRegistry} * @param dependencyInjector the corresponding {@link DependencyInjector} * @param localizationFunction the {@link LocalizationFunction} to use * @return an {@link Optional} holding the ControllerDefinition */ - public static Optional build(@NotNull Class controllerClass, - @NotNull ValidatorRegistry validatorRegistry, - @NotNull DependencyInjector dependencyInjector, - @NotNull LocalizationFunction localizationFunction) { - Interaction interaction = controllerClass.getAnnotation(Interaction.class); + public static Optional build(@NotNull Class interactionClass, + @NotNull ValidatorRegistry validatorRegistry, + @NotNull DependencyInjector dependencyInjector, + @NotNull LocalizationFunction localizationFunction) { + Interaction interaction = interactionClass.getAnnotation(Interaction.class); if (!interaction.isActive()) { - log.warn("Interaction class {} is set inactive. Skipping the controller and its commands", controllerClass.getName()); + log.warn("Interaction class {} is set inactive. Skipping the controller and its commands", interactionClass.getName()); return Optional.empty(); } List fields = new ArrayList<>(); - for (Field field : controllerClass.getDeclaredFields()) { + for (Field field : interactionClass.getDeclaredFields()) { if (!field.isAnnotationPresent(Inject.class)) { continue; } fields.add(field); } - dependencyInjector.registerDependencies(controllerClass, fields); + dependencyInjector.registerDependencies(interactionClass, fields); Set permissions = new HashSet<>(); // index controller level permissions - if (controllerClass.isAnnotationPresent(Permissions.class)) { - Permissions permission = controllerClass.getAnnotation(Permissions.class); + if (interactionClass.isAnnotationPresent(Permissions.class)) { + Permissions permission = interactionClass.getAnnotation(Permissions.class); permissions = Arrays.stream(permission.value()).collect(Collectors.toSet()); } // get controller level cooldown and use it if no command level cooldown is present CooldownDefinition cooldown = null; - if (controllerClass.isAnnotationPresent(Cooldown.class)) { - cooldown = CooldownDefinition.build(controllerClass.getAnnotation(Cooldown.class)); + if (interactionClass.isAnnotationPresent(Cooldown.class)) { + cooldown = CooldownDefinition.build(interactionClass.getAnnotation(Cooldown.class)); } // index interactions - List commands = new ArrayList<>(); + List commands = new ArrayList<>(); List buttons = new ArrayList<>(); List> selectMenus = new ArrayList<>(); List autoCompletes = new ArrayList<>(); - for (Method method : controllerClass.getDeclaredMethods()) { + List modals = new ArrayList<>(); + for (Method method : interactionClass.getDeclaredMethods()) { + // index commands if (method.isAnnotationPresent(SlashCommand.class)) { - Optional optional = CommandDefinition.build(method, validatorRegistry, localizationFunction); + Optional optional = SlashCommandDefinition.build(method, validatorRegistry, localizationFunction); if (optional.isEmpty()) { continue; } - CommandDefinition commandDefinition = optional.get(); - - // add controller level permissions + SlashCommandDefinition commandDefinition = optional.get(); commandDefinition.getPermissions().addAll(permissions); if (commandDefinition.getCooldown().getDelay() == 0) { commandDefinition.getCooldown().set(cooldown); } - if (interaction.ephemeral()) { commandDefinition.setEphemeral(true); } - + commands.add(commandDefinition); + } + if (method.isAnnotationPresent(ContextCommand.class)) { + Optional optional = ContextCommandDefinition.build(method, localizationFunction); + if (optional.isEmpty()) { + continue; + } + ContextCommandDefinition commandDefinition = optional.get(); + commandDefinition.getPermissions().addAll(permissions); + if (interaction.ephemeral()) { + commandDefinition.setEphemeral(true); + } commands.add(commandDefinition); } + // index components if (method.isAnnotationPresent(Button.class)) { ButtonDefinition.build(method).ifPresent(button -> { if (interaction.ephemeral()) { @@ -124,7 +142,6 @@ public static Optional build(@NotNull Class controllerC buttons.add(button); }); } - if (method.isAnnotationPresent(EntitySelectMenu.class)) { EntitySelectMenuDefinition.build(method).ifPresent(menu -> { if (interaction.ephemeral()) { @@ -142,6 +159,19 @@ public static Optional build(@NotNull Class controllerC }); } + //index modals + if (method.isAnnotationPresent(Modal.class)) { + ModalDefinition.build(method).ifPresent(modal -> { + if (interaction.ephemeral()) { + modal.setEphemeral(true); + } + modals.add(modal); + }); + } + } + + //loop again and index auto complete + for (Method method : interactionClass.getDeclaredMethods()) { if (method.isAnnotationPresent(AutoComplete.class)) { AutoCompleteDefinition.build( method, @@ -149,23 +179,29 @@ public static Optional build(@NotNull Class controllerC ).ifPresent(autoComplete -> { autoCompletes.add(autoComplete); - autoComplete.getCommandNames().forEach(name -> - commands.stream().filter(it -> it.getName().equals(name)) - .findFirst().ifPresent(it -> it.setAutoComplete(true)) + Set commandNames = new HashSet<>(); + autoComplete.getCommandNames().forEach(name -> commands.stream() + .filter(it -> it.getCommandType() == Command.Type.SLASH) + .filter(command -> command.getName().startsWith(name)) + .forEach(command -> { + ((SlashCommandDefinition) command).setAutoComplete(true); + commandNames.add(command.getName()); + }) ); + autoComplete.setCommandNames(commandNames); }); } } - return Optional.of(new ControllerDefinition(commands, buttons, selectMenus, autoCompletes)); + return Optional.of(new InteractionControllerDefinition(commands, buttons, selectMenus, autoCompletes, modals)); } /** - * Gets a possibly-empty list of all commands. + * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}. * - * @return a possibly-empty list of all commands + * @return a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions} */ - public List getCommands() { + public List getCommands() { return commands; } @@ -187,10 +223,24 @@ public List> getSelectMenus() return selectMenus; } + /** + * Gets a possibly-empty list of all {@link AutoCompleteDefinition AutoCompleteDefinitions}. + * + * @return a possibly-empty list of all {@link AutoCompleteDefinition AutoCompleteDefinitions} + */ public Collection getAutoCompletes() { return autoCompletes; } + /** + * Gets a possibly-empty list of all {@link ModalDefinition ModalDefinitions}. + * + * @return a possibly-empty list of all {@link ModalDefinition ModalDefinitions} + */ + public List getModals() { + return modals; + } + @Override public String toString() { return "ControllerDefinition{" + @@ -198,8 +248,8 @@ public String toString() { ", buttons=" + buttons + ", selectMenus=" + selectMenus + ", autoCompletes=" + autoCompletes + + ", modals=" + modals + '}'; } - } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java index de8ff8ee..786fd12f 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java @@ -5,8 +5,12 @@ import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition; import com.github.kaktushose.jda.commands.reflect.interactions.ButtonDefinition; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.ContextCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import com.github.kaktushose.jda.commands.reflect.interactions.menus.GenericSelectMenuDefinition; +import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; import org.jetbrains.annotations.NotNull; @@ -22,9 +26,10 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; /** - * Central registry for all {@link CommandDefinition CommandDefinitions}. + * Central registry for all {@link SlashCommandDefinition CommandDefinitions}. * * @author Kaktushose * @version 2.0.0 @@ -36,11 +41,12 @@ public class InteractionRegistry { private final ValidatorRegistry validatorRegistry; private final DependencyInjector dependencyInjector; private final LocalizationFunction localizationFunction; - private final Set controllers; - private final Set commands; + private final Set controllers; + private final Set commands; private final Set buttons; private final Set> selectMenus; private final Set autoCompletes; + private final Set modals; /** * Constructs a new CommandRegistry. @@ -60,6 +66,7 @@ public InteractionRegistry(@NotNull ValidatorRegistry validatorRegistry, buttons = new HashSet<>(); selectMenus = new HashSet<>(); autoCompletes = new HashSet<>(); + modals = new HashSet<>(); } /** @@ -85,9 +92,9 @@ public void index(@NotNull Class clazz, @NotNull String... packages) { Set> controllerSet = reflections.getTypesAnnotatedWith(Interaction.class); for (Class aClass : controllerSet) { - log.debug("Found controller {}", aClass.getName()); + log.debug("Found interaction controller {}", aClass.getName()); - Optional optional = ControllerDefinition.build( + Optional optional = InteractionControllerDefinition.build( aClass, validatorRegistry, dependencyInjector, @@ -95,43 +102,66 @@ public void index(@NotNull Class clazz, @NotNull String... packages) { ); if (optional.isEmpty()) { - log.warn("Unable to index the controller!"); + log.warn("Unable to index the interaction controller!"); continue; } - ControllerDefinition controller = optional.get(); + InteractionControllerDefinition controller = optional.get(); controllers.add(controller); commands.addAll(controller.getCommands()); buttons.addAll(controller.getButtons()); selectMenus.addAll(controller.getSelectMenus()); autoCompletes.addAll(controller.getAutoCompletes()); - - log.debug("Registered controller {}", controller); + modals.addAll(controller.getModals()); + log.debug("Registered interaction controller {}", controller); } - log.debug("Successfully registered {} controller(s) with a total of {} interaction(s)!", + log.debug("Successfully registered {} interaction controller(s) with a total of {} interaction(s)!", controllers.size(), commands.size() + buttons.size()); } /** - * Gets a possibly-empty list of all {@link ControllerDefinition ControllerDefinitions}. + * Gets a possibly-empty list of all {@link InteractionControllerDefinition ControllerDefinitions}. * - * @return a possibly-empty list of all {@link ControllerDefinition ControllerDefinitions} + * @return a possibly-empty list of all {@link InteractionControllerDefinition ControllerDefinitions} */ - public Set getControllers() { + public Set getInteractionControllers() { return Collections.unmodifiableSet(controllers); } /** - * Gets a possibly-empty list of all {@link CommandDefinition CommandDefinitions}. + * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}. * - * @return a possibly-empty list of all {@link CommandDefinition CommandDefinitions} + * @return a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions} */ - public Set getCommands() { + public Set getCommands() { return Collections.unmodifiableSet(commands); } + /** + * Gets a possibly-empty list of all {@link SlashCommandDefinition CommandDefinitions}. + * + * @return a possibly-empty list of all {@link SlashCommandDefinition CommandDefinitions} + */ + public Set getSlashCommands() { + return commands.stream().filter(it -> (it.getCommandType() == Command.Type.SLASH)) + .map(it -> (SlashCommandDefinition) it) + .collect(Collectors.toUnmodifiableSet()); + } + + /** + * Gets a possibly-empty list of all {@link ContextCommandDefinition CommandDefinitions}. + * + * @return a possibly-empty list of all {@link ContextCommandDefinition CommandDefinitions} + */ + public Set getContextCommands() { + return commands.stream().filter(it -> + (it.getCommandType() == Command.Type.USER) || it.getCommandType() == Command.Type.MESSAGE) + .map(it -> (ContextCommandDefinition) it) + .collect(Collectors.toUnmodifiableSet()); + } + /** * Gets a possibly-empty list of all {@link ButtonDefinition ButtonDefinitions}. * @@ -151,12 +181,15 @@ public Set getAutoCompletes() { } /** - * Gets a possibly-empty list of all {@link ButtonDefinition ButtonDefinitions}. + * Gets a possibly-empty list of all {@link ModalDefinition ModalDefinitions}. * - * @return a possibly-empty list of all {@link ButtonDefinition ButtonDefinitions} + * @return a possibly-empty list of all {@link ModalDefinition ModalDefinitions} */ public Set> getSelectMenus() { return Collections.unmodifiableSet(selectMenus); } + public Set getModals() { + return Collections.unmodifiableSet(modals); + } } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java new file mode 100644 index 00000000..bd203d47 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java @@ -0,0 +1,153 @@ +package com.github.kaktushose.jda.commands.reflect; + +import com.github.kaktushose.jda.commands.annotations.interactions.TextInput; +import net.dv8tion.jda.api.interactions.components.text.TextInput.Builder; +import net.dv8tion.jda.api.interactions.components.text.TextInputStyle; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Parameter; +import java.util.Optional; + +/** + * Representation of a {@link TextInput} of a + * {@link com.github.kaktushose.jda.commands.annotations.interactions.Modal Modal}. + * + * @author Kaktushose + * @version 4.0.0 + * @see TextInput + * @see com.github.kaktushose.jda.commands.annotations.interactions.Modal Modal + * @since 4.0.0 + */ +public class TextInputDefinition { + + private final String label; + private final String placeholder; + private final String defaultValue; + private final int minValue; + private final int maxValue; + private final TextInputStyle style; + private final boolean required; + + private TextInputDefinition(String label, + String placeholder, + String defaultValue, + int minValue, + int maxValue, + TextInputStyle style, + boolean required) { + this.label = label; + this.placeholder = placeholder; + this.defaultValue = defaultValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.style = style; + this.required = required; + } + + /** + * Builds a new TextInputDefinition. + * + * @param parameter the {@link Parameter} of the text input + * @return an {@link Optional} holding the TextInputDefinition + */ + public static Optional build(@NotNull Parameter parameter) { + if (!parameter.isAnnotationPresent(TextInput.class)) { + return Optional.empty(); + } + + // TODO for now we only allow Strings, maybe add type adapting in the future + if (!String.class.isAssignableFrom(parameter.getType())) { + return Optional.empty(); + } + + TextInput textInput = parameter.getAnnotation(TextInput.class); + + return Optional.of(new TextInputDefinition( + textInput.label().isEmpty() ? parameter.getName() : textInput.label(), + textInput.value(), + textInput.defaultValue(), + textInput.minValue(), + textInput.maxValue(), + textInput.style(), + textInput.required() + )); + } + + /** + * Transforms this TextInputDefinition to a {@link net.dv8tion.jda.api.interactions.components.text.TextInput TextInput}. + * + * @return the transformed {@link net.dv8tion.jda.api.interactions.components.text.TextInput TextInput} + */ + public net.dv8tion.jda.api.interactions.components.text.TextInput toTextInput() { + Builder textInput = net.dv8tion.jda.api.interactions.components.text.TextInput.create(label, label, style).setRequired(required); + + if (minValue != -1) { + textInput.setMinLength(minValue); + } + if (maxValue != -1) { + textInput.setMaxLength(maxValue); + } + if (!placeholder.isBlank()) { + textInput.setPlaceholder(placeholder); + } + if (!placeholder.isBlank()) { + textInput.setValue(defaultValue); + } + + return textInput.build(); + } + + /** + * Gets the label of the TextInput. + * + * @return the label of the TextInput + */ + public String getLabel() { + return label; + } + + /** + * Gets the placeholder of the TextInput. + * + * @return the placeholder of the TextInput + */ + public String getPlaceholder() { + return placeholder; + } + + /** + * Gets the minimum value of the TextInput. + * + * @return the minimum value of the TextInput + */ + public int getMinValue() { + return minValue; + } + + /** + * Gets the maximum value of the TextInput. + * + * @return the maximum value of the TextInput + */ + public int getMaxValue() { + return maxValue; + } + + /** + * Gets the {@link TextInputStyle} of the TextInput. + * + * @return the {@link TextInputStyle} of the TextInput + */ + public TextInputStyle getStyle() { + return style; + } + + /** + * Whether this TextInput is required. + * + * @return {@code true} if this TextInput is required + */ + public boolean isRequired() { + return required; + } +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/AutoCompleteDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/AutoCompleteDefinition.java index e1256a05..10368af9 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/AutoCompleteDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/AutoCompleteDefinition.java @@ -18,9 +18,9 @@ * @see AutoComplete * @since 4.0.0 */ -public class AutoCompleteDefinition extends GenericInteraction { +public class AutoCompleteDefinition extends GenericInteractionDefinition { - private final Set commands; + private Set commands; protected AutoCompleteDefinition(Method method, Set commands) { super(method); @@ -69,6 +69,15 @@ public static Optional build(@NotNull Method method, Lis return Optional.of(new AutoCompleteDefinition(method, values)); } + /** + * Set the command names this AutoComplete can handle + * + * @param commands a set of command names + */ + public void setCommandNames(Set commands) { + this.commands = commands; + } + /** * Gets a set of names of all the commands this AutoComplete can handle * diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ButtonDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ButtonDefinition.java index c3574bb0..0d61303e 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ButtonDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ButtonDefinition.java @@ -2,11 +2,10 @@ import com.github.kaktushose.jda.commands.annotations.interactions.Button; import com.github.kaktushose.jda.commands.annotations.interactions.Interaction; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.buttons.ButtonEvent; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import net.dv8tion.jda.api.entities.emoji.Emoji; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; import org.jetbrains.annotations.NotNull; @@ -21,7 +20,7 @@ * @see Button * @since 2.3.0 */ -public class ButtonDefinition extends EphemeralInteraction { +public class ButtonDefinition extends EphemeralInteractionDefinition { private final String label; private final Emoji emoji; @@ -60,11 +59,11 @@ public static Optional build(@NotNull Method method) { return Optional.empty(); } - if (!ButtonEvent.class.isAssignableFrom(method.getParameters()[0].getType())) { + if (!ComponentEvent.class.isAssignableFrom(method.getParameters()[0].getType())) { log.error("An error has occurred! Skipping Button {}.{}:", method.getDeclaringClass().getSimpleName(), method.getName(), - new IllegalArgumentException(String.format("First parameter must be of type %s!", ButtonEvent.class.getSimpleName()))); + new IllegalArgumentException(String.format("First parameter must be of type %s!", ComponentEvent.class.getSimpleName()))); return Optional.empty(); } @@ -148,11 +147,11 @@ public ButtonStyle getStyle() { * Gets the runtime id. The runtime id is composed of the static interaction id and the * snowflake id of the interaction event that created the runtime. * - * @param context the {@link CommandContext} this button will be attached to + * @param context the {@link SlashCommandContext} this button will be attached to * @return the runtime id */ @NotNull - public String getRuntimeId(GenericContext context) { + public String getRuntimeId(Context context) { return String.format("%s.%s", getId(), context.getRuntime().getInstanceId()); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/EphemeralInteraction.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/EphemeralInteractionDefinition.java similarity index 53% rename from src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/EphemeralInteraction.java rename to src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/EphemeralInteractionDefinition.java index f558dc68..d1ade2a0 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/EphemeralInteraction.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/EphemeralInteractionDefinition.java @@ -9,19 +9,29 @@ * @version 4.0.0 * @since 4.0.0 */ -public abstract class EphemeralInteraction extends GenericInteraction { +public abstract class EphemeralInteractionDefinition extends GenericInteractionDefinition { protected boolean ephemeral; - protected EphemeralInteraction(Method method, boolean ephemeral) { + protected EphemeralInteractionDefinition(Method method, boolean ephemeral) { super(method); this.ephemeral = ephemeral; } + /** + * Gets whether replies should be ephemeral. + * + * @return {@code true} if replies should be ephemeral + */ public boolean isEphemeral() { return ephemeral; } + /** + * Sets whether replies should be ephemeral. + * + * @param ephemeral {@code true} if replies should be ephemeral + */ public void setEphemeral(boolean ephemeral) { this.ephemeral = ephemeral; } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/GenericInteraction.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/GenericInteractionDefinition.java similarity index 92% rename from src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/GenericInteraction.java rename to src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/GenericInteractionDefinition.java index d6137cea..3a9ec84d 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/GenericInteraction.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/GenericInteractionDefinition.java @@ -14,14 +14,14 @@ * @version 4.0.0 * @since 4.0.0 */ -public abstract class GenericInteraction { +public abstract class GenericInteractionDefinition { - protected static final Logger log = LoggerFactory.getLogger(GenericInteraction.class); + protected static final Logger log = LoggerFactory.getLogger(GenericInteractionDefinition.class); protected final String id; protected final Method method; - protected GenericInteraction(Method method) { + protected GenericInteractionDefinition(Method method) { this.id = String.format("%s.%s", method.getDeclaringClass().getSimpleName(), method.getName()); this.method = method; } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ModalDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ModalDefinition.java new file mode 100644 index 00000000..45f33f1a --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/ModalDefinition.java @@ -0,0 +1,128 @@ +package com.github.kaktushose.jda.commands.reflect.interactions; + +import com.github.kaktushose.jda.commands.annotations.interactions.Interaction; +import com.github.kaktushose.jda.commands.annotations.interactions.Modal; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.modals.ModalEvent; +import com.github.kaktushose.jda.commands.reflect.TextInputDefinition; +import net.dv8tion.jda.api.interactions.modals.Modal.Builder; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * Representation of a Modal. + * + * @author Kaktushose + * @version 4.0.0 + * @see Modal + * @since 4.0.0 + */ +public class ModalDefinition extends EphemeralInteractionDefinition { + + private final String title; + private final List textInputs; + + protected ModalDefinition(Method method, boolean ephemeral, String title, List textInputs) { + super(method, ephemeral); + this.title = title; + this.textInputs = textInputs; + } + + /** + * Builds a new ModalDefinition. + * + * @param method the {@link Method} of the Modal + * @return an {@link Optional} holding the ModalDefinition + */ + public static Optional build(@NotNull Method method) { + if (!method.isAnnotationPresent(Modal.class) || !method.getDeclaringClass().isAnnotationPresent(Interaction.class)) { + return Optional.empty(); + } + + // Modals support up to 5 TextInputs + if (method.getParameters().length < 1 || method.getParameters().length > 6) { + log.error("An error has occurred! Skipping Modal {}.{}:", + method.getDeclaringClass().getSimpleName(), + method.getName(), + new IllegalArgumentException("Invalid amount of parameters!")); + return Optional.empty(); + } + + if (!ModalEvent.class.isAssignableFrom(method.getParameters()[0].getType())) { + log.error("An error has occurred! Skipping Modal {}.{}:", + method.getDeclaringClass().getSimpleName(), + method.getName(), + new IllegalArgumentException(String.format("First parameter must be of type %s!", ModalEvent.class.getSimpleName()))); + return Optional.empty(); + } + + List textInputs = new ArrayList<>(); + for (int i = 1; i < method.getParameters().length; i++) { + Parameter parameter = method.getParameters()[i]; + TextInputDefinition.build(parameter).ifPresent(textInputs::add); + } + + if (textInputs.isEmpty()) { + log.error("An error has occurred! Skipping Modal {}.{}:", + method.getDeclaringClass().getSimpleName(), + method.getName(), + new IllegalArgumentException("Modals need at least one valid TextInput")); + return Optional.empty(); + } + + Modal modal = method.getAnnotation(Modal.class); + + return Optional.of(new ModalDefinition(method, modal.ephemeral(), modal.value(), textInputs)); + } + + /** + * Transforms this ModalDefinition to a {@link net.dv8tion.jda.api.interactions.modals.Modal Modal}. + * + * @param id the id to use, see {@link #getRuntimeId(Context)} + * @return the transformed {@link net.dv8tion.jda.api.interactions.modals.Modal Modal} + */ + public net.dv8tion.jda.api.interactions.modals.Modal toModal(String id) { + Builder modal = net.dv8tion.jda.api.interactions.modals.Modal.create(id, title); + + textInputs.forEach(textInput -> modal.addActionRow(textInput.toTextInput())); + + return modal.build(); + } + + /** + * Gets the title of the modal. + * + * @return the title of the modal + */ + public String getTitle() { + return title; + } + + /** + * Gets all text inputs this modal uses + * + * @return a list of {@link TextInputDefinition TextInputDefinitions} + */ + public List getTextInputs() { + return textInputs; + } + + /** + * Gets the runtime id. The runtime id is composed of the static interaction id and the + * snowflake id of the interaction event that created the runtime. + * + * @param context the {@link SlashCommandContext} this button will be attached to + * @return the runtime id + */ + @NotNull + public String getRuntimeId(Context context) { + return String.format("%s.%s", getId(), context.getRuntime().getInstanceId()); + } + +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/ContextCommandDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/ContextCommandDefinition.java new file mode 100644 index 00000000..bb1e96f5 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/ContextCommandDefinition.java @@ -0,0 +1,108 @@ +package com.github.kaktushose.jda.commands.reflect.interactions.commands; + +import com.github.kaktushose.jda.commands.annotations.interactions.ContextCommand; +import com.github.kaktushose.jda.commands.annotations.interactions.Interaction; +import com.github.kaktushose.jda.commands.annotations.interactions.Permissions; +import com.github.kaktushose.jda.commands.annotations.interactions.SlashCommand; +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.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.build.Commands; +import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Representation of a ContextMenu command. + * + * @author Kaktushose + * @version 4.0.0 + * @see ContextCommand + * @since 4.0.0 + */ +public class ContextCommandDefinition extends GenericCommandDefinition { + + public ContextCommandDefinition(Method method, + boolean ephemeral, + String name, + Set permissions, + boolean isGuildOnly, + boolean isNSFW, + Command.Type commandType, + Set enabledPermissions, + SlashCommand.CommandScope scope, + LocalizationFunction localizationFunction) { + super(method, ephemeral, name, permissions, isGuildOnly, isNSFW, commandType, enabledPermissions, scope, localizationFunction); + } + + public static Optional build(@NotNull Method method, @NotNull LocalizationFunction localizationFunction) { + if (!method.isAnnotationPresent(ContextCommand.class) || !method.getDeclaringClass().isAnnotationPresent(Interaction.class)) { + return Optional.empty(); + } + + ContextCommand command = method.getAnnotation(ContextCommand.class); + + if (!command.isActive()) { + log.debug("Command {} is set inactive. Skipping this command!", method.getName()); + return Optional.empty(); + } + + Set permissions = new HashSet<>(); + if (method.isAnnotationPresent(Permissions.class)) { + Permissions permission = method.getAnnotation(Permissions.class); + permissions = new HashSet<>(Arrays.asList(permission.value())); + } + + Set enabledFor = Arrays.stream(command.enabledFor()).collect(Collectors.toSet()); + if (enabledFor.size() == 1 && enabledFor.contains(net.dv8tion.jda.api.Permission.UNKNOWN)) { + enabledFor.clear(); + } + + return Optional.of(new ContextCommandDefinition( + method, + command.ephemeral(), + command.value(), + permissions, + command.isGuildOnly(), + command.isNSFW(), + command.type(), + enabledFor, + command.scope(), + localizationFunction + )); + } + + @Override + public CommandData toCommandData() { + CommandData command = Commands.context(commandType, name); + command.setGuildOnly(isGuildOnly) + .setNSFW(isNSFW) + .setDefaultPermissions(DefaultMemberPermissions.enabledFor(enabledPermissions)) + .setLocalizationFunction(localizationFunction); + return command; + } + + @Override + public String toString() { + return "ContextCommandDefinition{" + + "id='" + id + '\'' + + ", method=" + method + + ", name='" + name + '\'' + + ", permissions=" + permissions + + ", isGuildOnly=" + isGuildOnly + + ", isNSFW=" + isNSFW + + ", commandType=" + commandType + + ", enabledPermissions=" + enabledPermissions + + ", scope=" + scope + + ", localizationFunction=" + localizationFunction + + ", ephemeral=" + ephemeral + + '}'; + } +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/GenericCommandDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/GenericCommandDefinition.java new file mode 100644 index 00000000..74424629 --- /dev/null +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/GenericCommandDefinition.java @@ -0,0 +1,146 @@ +package com.github.kaktushose.jda.commands.reflect.interactions.commands; + +import com.github.kaktushose.jda.commands.annotations.interactions.SlashCommand; +import com.github.kaktushose.jda.commands.reflect.interactions.EphemeralInteractionDefinition; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.interactions.commands.Command; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; +import java.util.Set; + +/** + * Generic base class of different command types. + * + * @author Kaktushose + * @version 4.0.0 + * @see SlashCommandDefinition + * @see ContextCommandDefinition + * @since 4.0.0 + */ +public abstract class GenericCommandDefinition extends EphemeralInteractionDefinition implements Comparable { + + protected final String name; + protected final Set permissions; + protected final boolean isGuildOnly; + protected final boolean isNSFW; + protected final Command.Type commandType; + protected final Set enabledPermissions; + protected final SlashCommand.CommandScope scope; + protected final LocalizationFunction localizationFunction; + + protected GenericCommandDefinition(Method method, + boolean ephemeral, + String name, + Set permissions, + boolean isGuildOnly, + boolean isNSFW, + Command.Type commandType, + Set enabledPermissions, + SlashCommand.CommandScope scope, + LocalizationFunction localizationFunction) { + super(method, ephemeral); + this.name = name; + this.permissions = permissions; + this.isGuildOnly = isGuildOnly; + this.isNSFW = isNSFW; + this.commandType = commandType; + this.enabledPermissions = enabledPermissions; + this.scope = scope; + this.localizationFunction = localizationFunction; + } + + /** + * Transforms this command definition to {@link CommandData}. + * + * @return the {@link CommandData} + */ + public abstract CommandData toCommandData(); + + /** + * Gets the command name. + * + * @return the command name + */ + public String getName() { + return name; + } + + /** + * Gets a set of permission Strings. + * + * @return set of permission Strings + */ + public Set getPermissions() { + return permissions; + } + + /** + * Whether this command can be executed inside direct messages. + * + * @return {@code true} if this command can be executed inside direct messages + */ + public boolean isGuildOnly() { + return isGuildOnly; + } + + /** + * Whether this command can only be executed in NSFW channels. + * + * @return {@code true} if this command can only be executed in NSFW channels + */ + public boolean isNSFW() { + return isNSFW; + } + + /** + * Gets a set of Discord permission Strings this command will be enabled for by default. + * + * @return a set of Discord permission Strings this command will be enabled for by default + */ + public Set getEnabledPermissions() { + return enabledPermissions; + } + + public Command.Type getCommandType() { + return commandType; + } + + public LocalizationFunction getLocalizationFunction() { + return localizationFunction; + } + + /** + * Gets the {@link SlashCommand.CommandScope CommandScope} of this command. + * + * @return the {@link SlashCommand.CommandScope CommandScope} of this command + */ + public SlashCommand.CommandScope getCommandScope() { + return scope; + } + + @Override + public String toString() { + return "GenericCommandDefinition{" + + "id='" + id + '\'' + + ", method=" + method + + ", name='" + name + '\'' + + ", permissions=" + permissions + + ", isGuildOnly=" + isGuildOnly + + ", isNSFW=" + isNSFW + + ", commandType=" + commandType + + ", enabledPermissions=" + enabledPermissions + + ", scope=" + scope + + ", localizationFunction=" + localizationFunction + + ", ephemeral=" + ephemeral + + '}'; + } + + @Override + public int compareTo(@NotNull GenericCommandDefinition command) { + return name.compareTo(command.name); + } + +} diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/CommandDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/SlashCommandDefinition.java similarity index 73% rename from src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/CommandDefinition.java rename to src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/SlashCommandDefinition.java index bf2a43a0..6628d217 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/CommandDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/commands/SlashCommandDefinition.java @@ -1,4 +1,4 @@ -package com.github.kaktushose.jda.commands.reflect.interactions; +package com.github.kaktushose.jda.commands.reflect.interactions.commands; import com.github.kaktushose.jda.commands.annotations.interactions.Cooldown; import com.github.kaktushose.jda.commands.annotations.interactions.Interaction; @@ -8,6 +8,8 @@ import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; import com.github.kaktushose.jda.commands.reflect.CooldownDefinition; import com.github.kaktushose.jda.commands.reflect.ParameterDefinition; +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.build.Commands; import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; @@ -28,46 +30,34 @@ * @see SlashCommand * @since 2.0.0 */ -public class CommandDefinition extends EphemeralInteraction implements Comparable { +public class SlashCommandDefinition extends GenericCommandDefinition { - private final String name; private final String description; private final List parameters; - private final Set permissions; - private final Set enabledPermissions; private final CooldownDefinition cooldown; - private final boolean isGuildOnly; - private final boolean isNSFW; - private final SlashCommand.CommandScope scope; - private final LocalizationFunction localizationFunction; private boolean isAutoComplete; - protected CommandDefinition(Method method, - boolean ephemeral, - String name, - String description, - List parameters, - Set permissions, - Set enabledPermissions, - CooldownDefinition cooldown, - boolean isGuildOnly, - boolean isNSFW, - SlashCommand.CommandScope scope, LocalizationFunction localizationFunction) { - super(method, ephemeral); - this.name = name; + public SlashCommandDefinition(Method method, + boolean ephemeral, + String name, + Set permissions, + boolean isGuildOnly, + boolean isNSFW, + Command.Type commandType, + Set enabledPermissions, + SlashCommand.CommandScope scope, + LocalizationFunction localizationFunction, + String description, + List parameters, + CooldownDefinition cooldown, + boolean isAutoComplete) { + super(method, ephemeral, name, permissions, isGuildOnly, isNSFW, commandType, enabledPermissions, scope, localizationFunction); this.description = description; this.parameters = parameters; - this.permissions = permissions; - this.enabledPermissions = enabledPermissions; this.cooldown = cooldown; - this.isGuildOnly = isGuildOnly; - this.isNSFW = isNSFW; - this.scope = scope; - this.localizationFunction = localizationFunction; - isAutoComplete = false; + this.isAutoComplete = isAutoComplete; } - /** * Builds a new CommandDefinition. * @@ -76,9 +66,9 @@ protected CommandDefinition(Method method, * @param localizationFunction the {@link LocalizationFunction} to use * @return an {@link Optional} holding the CommandDefinition */ - public static Optional build(@NotNull Method method, - @NotNull ValidatorRegistry validatorRegistry, - @NotNull LocalizationFunction localizationFunction) { + public static Optional build(@NotNull Method method, + @NotNull ValidatorRegistry validatorRegistry, + @NotNull LocalizationFunction localizationFunction) { if (!method.isAnnotationPresent(SlashCommand.class) || !method.getDeclaringClass().isAnnotationPresent(Interaction.class)) { return Optional.empty(); @@ -147,19 +137,22 @@ public static Optional build(@NotNull Method method, enabledFor.clear(); } - return Optional.of(new CommandDefinition( + return Optional.of(new SlashCommandDefinition( method, command.ephemeral(), label, - command.desc(), - parameters, permissions, - enabledFor, - CooldownDefinition.build(method.getAnnotation(Cooldown.class)), command.isGuildOnly(), command.isNSFW(), + Command.Type.SLASH, + enabledFor, command.scope(), - localizationFunction)); + localizationFunction, + command.desc(), + parameters, + CooldownDefinition.build(method.getAnnotation(Cooldown.class)), + false + )); } private static void logError(String message, Method commandMethod) { @@ -174,6 +167,7 @@ private static void logError(String message, Method commandMethod) { * * @return the transformed {@link SlashCommandData} */ + @Override public SlashCommandData toCommandData() { SlashCommandData command = Commands.slash( name, @@ -213,15 +207,6 @@ public SubcommandData toSubCommandData(String label) { return command; } - /** - * Gets the command name. - * - * @return the command name - */ - public String getName() { - return name; - } - /** * Returns the slash command description. * @@ -251,24 +236,6 @@ public List getActualParameters() { return parameters.subList(parameters.isEmpty() ? 0 : 1, parameters.size()); } - /** - * Gets a set of permission Strings. - * - * @return set of permission Strings - */ - public Set getPermissions() { - return permissions; - } - - /** - * Gets a set of Discord permission Strings this command will be enabled for by default. - * - * @return a set of Discord permission Strings this command will be enabled for by default - */ - public Set getEnabledPermissions() { - return enabledPermissions; - } - /** * Gets the {@link CooldownDefinition}. This is never null, even if the command has no cooldown. * @@ -287,24 +254,6 @@ public boolean hasCooldown() { return getCooldown().getDelay() > 0; } - /** - * Whether this command can be executed inside direct messages. - * - * @return {@code true} if this command can be executed inside direct messages - */ - public boolean isGuildOnly() { - return isGuildOnly; - } - - /** - * Whether this command can only be executed in NSFW channels. - * - * @return {@code true} if this command can only be executed in NSFW channels - */ - public boolean isNSFW() { - return isNSFW; - } - /** * Gets the {@link SlashCommand.CommandScope CommandScope} of this command. * @@ -329,46 +278,29 @@ public boolean isAutoComplete() { * @param autoComplete whether this can command support auto complete * @return this instance for fluent interface */ - public CommandDefinition setAutoComplete(boolean autoComplete) { + public SlashCommandDefinition setAutoComplete(boolean autoComplete) { this.isAutoComplete = autoComplete; return this; } - public LocalizationFunction getLocalizationFunction() { - return localizationFunction; - } - - /** - * Gets the {@link Method} of the command. - * - * @return the {@link Method} of the command - */ - public Method getMethod() { - return method; - } - @Override public String toString() { - return "CommandDefinition{" + - "name='" + name + '\'' + + return "SlashCommandDefinition{" + + "id='" + id + '\'' + + ", method=" + method + + ", name='" + name + '\'' + ", description='" + description + '\'' + ", parameters=" + parameters + - ", permissions=" + permissions + - ", enabledPermissions=" + enabledPermissions + ", cooldown=" + cooldown + + ", isAutoComplete=" + isAutoComplete + + ", permissions=" + permissions + ", isGuildOnly=" + isGuildOnly + ", isNSFW=" + isNSFW + + ", commandType=" + commandType + + ", enabledPermissions=" + enabledPermissions + ", scope=" + scope + ", localizationFunction=" + localizationFunction + - ", isAutoComplete=" + isAutoComplete + ", ephemeral=" + ephemeral + - ", id='" + id + '\'' + - ", method=" + method + '}'; } - - @Override - public int compareTo(@NotNull CommandDefinition command) { - return name.compareTo(command.name); - } } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/EntitySelectMenuDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/EntitySelectMenuDefinition.java index 65230601..84b1d1f0 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/EntitySelectMenuDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/EntitySelectMenuDefinition.java @@ -2,7 +2,7 @@ import com.github.kaktushose.jda.commands.annotations.interactions.EntitySelectMenu; import com.github.kaktushose.jda.commands.annotations.interactions.Interaction; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu.DefaultValue; import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu.SelectTarget; @@ -61,13 +61,13 @@ public static Optional build(@NotNull Method method) return Optional.empty(); } - if (!SelectMenuEvent.class.isAssignableFrom(method.getParameters()[0].getType()) && + if (!ComponentEvent.class.isAssignableFrom(method.getParameters()[0].getType()) && !List.class.isAssignableFrom(method.getParameters()[1].getType())) { log.error("An error has occurred! Skipping Button {}.{}:", method.getDeclaringClass().getSimpleName(), method.getName(), new IllegalArgumentException(String.format("First parameter must be of type %s, second parameter of type %s!", - SelectMenuEvent.class.getSimpleName(), + ComponentEvent.class.getSimpleName(), List.class.getSimpleName() ))); return Optional.empty(); diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/GenericSelectMenuDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/GenericSelectMenuDefinition.java index d98954fe..53d2d997 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/GenericSelectMenuDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/GenericSelectMenuDefinition.java @@ -1,9 +1,8 @@ package com.github.kaktushose.jda.commands.reflect.interactions.menus; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; -import com.github.kaktushose.jda.commands.reflect.interactions.EphemeralInteraction; -import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; +import com.github.kaktushose.jda.commands.reflect.interactions.EphemeralInteractionDefinition; import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; import org.jetbrains.annotations.NotNull; @@ -18,7 +17,7 @@ * @see StringSelectMenuDefinition * @since 4.0.0 */ -public abstract class GenericSelectMenuDefinition extends EphemeralInteraction { +public abstract class GenericSelectMenuDefinition extends EphemeralInteractionDefinition { protected final String placeholder; protected final int minValue; @@ -71,11 +70,11 @@ public int getMaxValue() { * Gets the runtime id. The runtime id is composed of the static interaction id and the * snowflake id of the interaction event that created the runtime. * - * @param context the {@link CommandContext} this button will be attached to + * @param context the {@link SlashCommandContext} this button will be attached to * @return the runtime id */ @NotNull - public String getRuntimeId(GenericContext context) { + public String getRuntimeId(Context context) { return String.format("%s.%s", getId(), context.getRuntime().getInstanceId()); } diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/StringSelectMenuDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/StringSelectMenuDefinition.java index fcd92ee3..a9fce59d 100644 --- a/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/StringSelectMenuDefinition.java +++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/interactions/menus/StringSelectMenuDefinition.java @@ -3,7 +3,7 @@ import com.github.kaktushose.jda.commands.annotations.interactions.Interaction; import com.github.kaktushose.jda.commands.annotations.interactions.SelectOption; import com.github.kaktushose.jda.commands.annotations.interactions.StringSelectMenu; -import com.github.kaktushose.jda.commands.dispatching.interactions.menus.SelectMenuEvent; +import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentEvent; import org.jetbrains.annotations.NotNull; import java.lang.reflect.Method; @@ -54,13 +54,13 @@ public static Optional build(@NotNull Method method) return Optional.empty(); } - if (!SelectMenuEvent.class.isAssignableFrom(method.getParameters()[0].getType()) && + if (!ComponentEvent.class.isAssignableFrom(method.getParameters()[0].getType()) && !List.class.isAssignableFrom(method.getParameters()[1].getType())) { log.error("An error has occurred! Skipping Button {}.{}:", method.getDeclaringClass().getSimpleName(), method.getName(), new IllegalArgumentException(String.format("First parameter must be of type %s, second parameter of type %s!", - SelectMenuEvent.class.getSimpleName(), + ComponentEvent.class.getSimpleName(), List.class.getSimpleName() ))); return Optional.empty(); diff --git a/src/test/java/adapting/CustomTypeAdapter.java b/src/test/java/adapting/CustomTypeAdapter.java index 1a1c24b7..8bee3ee1 100644 --- a/src/test/java/adapting/CustomTypeAdapter.java +++ b/src/test/java/adapting/CustomTypeAdapter.java @@ -1,6 +1,6 @@ package adapting; -import com.github.kaktushose.jda.commands.dispatching.interactions.GenericContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.Context; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter; import org.jetbrains.annotations.NotNull; @@ -9,7 +9,7 @@ public class CustomTypeAdapter implements TypeAdapter { @Override - public Optional parse(@NotNull String raw, @NotNull GenericContext context) { + public Optional parse(@NotNull String raw, @NotNull Context context) { return Optional.of(new CustomType()); } } diff --git a/src/test/java/adapting/TypeAdapterRegistryTest.java b/src/test/java/adapting/TypeAdapterRegistryTest.java index d6fdec19..de210f66 100644 --- a/src/test/java/adapting/TypeAdapterRegistryTest.java +++ b/src/test/java/adapting/TypeAdapterRegistryTest.java @@ -5,10 +5,10 @@ import adapting.mock.TypeAdapterRegistryTestController; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.IntegerAdapter; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.interactions.commands.localization.ResourceBundleLocalizationFunction; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -69,7 +69,7 @@ public void unregister_withExistingType_ShouldRemove() { @Test public void adapt_withStringArray_ShouldNotAdapt() throws NoSuchMethodException { - CommandContext context = buildContext(buildCommand("stringArray", CommandEvent.class, String[].class), "a", "b", "c"); + SlashCommandContext context = buildContext(buildCommand("stringArray", CommandEvent.class, String[].class), "a", "b", "c"); registry.adapt(context); @@ -78,14 +78,14 @@ public void adapt_withStringArray_ShouldNotAdapt() throws NoSuchMethodException @Test public void adapt_withLessInputThanParameters_ShouldThrow() throws NoSuchMethodException { - CommandContext context = buildContext(buildCommand("inputLength", CommandEvent.class, int.class)); + SlashCommandContext context = buildContext(buildCommand("inputLength", CommandEvent.class, int.class)); assertThrows(IllegalStateException.class, () -> registry.adapt(context)); } @Test public void adapt_withMoreInputThanParameters_ShouldNotCancel() throws NoSuchMethodException { - CommandContext context = buildContext(buildCommand("inputLength", CommandEvent.class, int.class), "1", "2"); + SlashCommandContext context = buildContext(buildCommand("inputLength", CommandEvent.class, int.class), "1", "2"); registry.adapt(context); @@ -94,7 +94,7 @@ public void adapt_withMoreInputThanParameters_ShouldNotCancel() throws NoSuchMet @Test public void adapt_withOptionalWithDefaultNull_ShouldAddNull() throws NoSuchMethodException { - CommandContext context = buildContext(buildCommand("optionalNull", CommandEvent.class, int.class)); + SlashCommandContext context = buildContext(buildCommand("optionalNull", CommandEvent.class, int.class)); registry.adapt(context); @@ -103,7 +103,7 @@ public void adapt_withOptionalWithDefaultNull_ShouldAddNull() throws NoSuchMetho @Test public void adapt_withOptionalWithDefault_ShouldAddDefault() throws NoSuchMethodException { - CommandContext context = buildContext(buildCommand("optionalDefault", CommandEvent.class, String.class)); + SlashCommandContext context = buildContext(buildCommand("optionalDefault", CommandEvent.class, String.class)); registry.adapt(context); @@ -113,7 +113,7 @@ public void adapt_withOptionalWithDefault_ShouldAddDefault() throws NoSuchMethod @Test public void adapt_withMissingTypeAdapter_ShouldThrowIllegalArgumentException() throws NoSuchMethodException { adapter.register(CustomType.class, new CustomTypeAdapter()); - CommandContext context = buildContext(buildCommand("noAdapter", CommandEvent.class, CustomType.class), "string"); + SlashCommandContext context = buildContext(buildCommand("noAdapter", CommandEvent.class, CustomType.class), "string"); adapter.unregister(CustomType.class); assertThrows(IllegalArgumentException.class, () -> registry.adapt(context)); @@ -121,21 +121,21 @@ public void adapt_withMissingTypeAdapter_ShouldThrowIllegalArgumentException() t @Test public void adapt_withWrongArgument_ShouldCancel() throws NoSuchMethodException { - CommandContext context = buildContext(buildCommand("wrongArgument", CommandEvent.class, int.class), "string"); + SlashCommandContext context = buildContext(buildCommand("wrongArgument", CommandEvent.class, int.class), "string"); registry.adapt(context); assertTrue(context.isCancelled()); } - private CommandDefinition buildCommand(String name, Class... parameterTypes) throws NoSuchMethodException { + private SlashCommandDefinition buildCommand(String name, Class... parameterTypes) throws NoSuchMethodException { Method method = controller.getMethod(name, parameterTypes); - CommandDefinition command = CommandDefinition.build(method, validator, ResourceBundleLocalizationFunction.empty().build()).orElse(null); + SlashCommandDefinition command = SlashCommandDefinition.build(method, validator, ResourceBundleLocalizationFunction.empty().build()).orElse(null); assertNotNull(command); return command; } - private CommandContext buildContext(CommandDefinition command, String... input) { - CommandContext context = new CommandContext( + private SlashCommandContext buildContext(SlashCommandDefinition command, String... input) { + SlashCommandContext context = new SlashCommandContext( new SlashCommandInteractionEventMock(), new JDACommandsMock()); context.setInput(input); diff --git a/src/test/java/adapting/TypeAdapterTest.java b/src/test/java/adapting/TypeAdapterTest.java index 1658be05..0a07b06b 100644 --- a/src/test/java/adapting/TypeAdapterTest.java +++ b/src/test/java/adapting/TypeAdapterTest.java @@ -5,7 +5,7 @@ import adapting.mock.JDAMock; import adapting.mock.SlashCommandInteractionEventMock; import com.github.kaktushose.jda.commands.dispatching.adapter.impl.*; -import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandContext; +import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -13,11 +13,11 @@ public class TypeAdapterTest { - private static CommandContext context; + private static SlashCommandContext context; @BeforeAll public static void setup() { - context = new CommandContext(new SlashCommandInteractionEventMock(), new JDACommandsMock()); + context = new SlashCommandContext(new SlashCommandInteractionEventMock(), new JDACommandsMock()); } @Test diff --git a/src/test/java/adapting/mock/SlashCommandInteractionEventMock.java b/src/test/java/adapting/mock/SlashCommandInteractionEventMock.java index a1d20e1c..b0a4474b 100644 --- a/src/test/java/adapting/mock/SlashCommandInteractionEventMock.java +++ b/src/test/java/adapting/mock/SlashCommandInteractionEventMock.java @@ -6,9 +6,13 @@ import net.dv8tion.jda.api.entities.channel.ChannelType; 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 org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + public class SlashCommandInteractionEventMock extends SlashCommandInteractionEvent { @@ -16,6 +20,12 @@ public SlashCommandInteractionEventMock() { super(new JDAMock(), 0, new SlashCommandInteractionMock()); } + @NotNull + @Override + public List getOptions() { + return new ArrayList<>(); + } + @Nullable @Override public Guild getGuild() { diff --git a/src/test/java/adapting/mock/SlashCommandInteractionMock.java b/src/test/java/adapting/mock/SlashCommandInteractionMock.java index 25d8864d..b2899959 100644 --- a/src/test/java/adapting/mock/SlashCommandInteractionMock.java +++ b/src/test/java/adapting/mock/SlashCommandInteractionMock.java @@ -57,6 +57,11 @@ public MessageChannelUnion getChannel() { return null; } + @Override + public long getChannelIdLong() { + return 0; + } + @Override public DiscordLocale getUserLocale() { return null; diff --git a/src/test/java/commands/CommandDefinitionTest.java b/src/test/java/commands/SlashCommandDefinitionTest.java similarity index 78% rename from src/test/java/commands/CommandDefinitionTest.java rename to src/test/java/commands/SlashCommandDefinitionTest.java index 919dfb1d..447ed073 100644 --- a/src/test/java/commands/CommandDefinitionTest.java +++ b/src/test/java/commands/SlashCommandDefinitionTest.java @@ -3,7 +3,7 @@ import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry; import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; import net.dv8tion.jda.api.interactions.commands.localization.ResourceBundleLocalizationFunction; import org.junit.jupiter.api.BeforeAll; @@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.*; -public class CommandDefinitionTest { +public class SlashCommandDefinitionTest { private static final LocalizationFunction LOCALIZATION_FUNCTION = ResourceBundleLocalizationFunction.empty().build(); @@ -38,34 +38,34 @@ public static void setup() { public void method_withoutAnnotation_ShouldReturnEmpty() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("noAnnotation"); - assertEquals(Optional.empty(), CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); + assertEquals(Optional.empty(), SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); } @Test public void method_withoutArgs_ShouldReturnEmpty() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("noArgs"); - assertEquals(Optional.empty(), CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); + assertEquals(Optional.empty(), SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); } @Test public void method_withoutCommandEvent_ShouldReturnEmpty() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("noCommandEvent", int.class); - assertEquals(Optional.empty(), CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); + assertEquals(Optional.empty(), SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); } @Test public void method_withWrongCommandEvent_ShouldReturnEmpty() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("wrongCommandEvent", int.class, CommandEvent.class); - assertEquals(Optional.empty(), CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); + assertEquals(Optional.empty(), SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); } @Test public void method_withCommandEvent_ShouldWork() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Method method = controller.getDeclaredMethod("commandEvent", CommandEvent.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -79,7 +79,7 @@ public void method_withCommandEvent_ShouldWork() throws NoSuchMethodException, I public void method_withUnsupportedType_ShouldWork() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Method method = controller.getDeclaredMethod("unsupported", CommandEvent.class, UnsupportedType.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -93,7 +93,7 @@ public void method_withUnsupportedType_ShouldWork() throws NoSuchMethodException @Test public void method_withStringArray_ShouldWork() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Method method = controller.getDeclaredMethod("arrayArgument", CommandEvent.class, String[].class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -108,14 +108,14 @@ public void method_withStringArray_ShouldWork() throws NoSuchMethodException, In public void method_withArgumentsAfterArray_ShouldReturnEmpty() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("argsAfterArray", CommandEvent.class, String[].class, int.class); - assertEquals(Optional.empty(), CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); + assertEquals(Optional.empty(), SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); } @Test public void method_withArgumentsAfterOptional_ShouldWork() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("argsAfterOptional", CommandEvent.class, String.class, int.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -130,7 +130,7 @@ public void method_withArgumentsAfterOptional_ShouldWork() throws NoSuchMethodEx @Test public void method_withOptionalAfterOptional_ShouldWork() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Method method = controller.getDeclaredMethod("optionalAfterOptional", CommandEvent.class, String.class, int.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -146,13 +146,13 @@ public void method_withOptionalAfterOptional_ShouldWork() throws NoSuchMethodExc public void command_isInactive_ShouldReturnEmpty() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("inactive"); - assertEquals(Optional.empty(), CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); + assertEquals(Optional.empty(), SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION)); } @Test public void cooldown_zeroTimeUnits_ShouldNotBeSet() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("zeroCooldown", CommandEvent.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -162,7 +162,7 @@ public void cooldown_zeroTimeUnits_ShouldNotBeSet() throws NoSuchMethodException @Test public void cooldown_tenMilliseconds_ShouldWork() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("cooldown", CommandEvent.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); @@ -174,7 +174,7 @@ public void cooldown_tenMilliseconds_ShouldWork() throws NoSuchMethodException { @Test public void permission_oneString_ShouldWork() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("permission", CommandEvent.class); - CommandDefinition definition = CommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); + SlashCommandDefinition definition = SlashCommandDefinition.build(method, validator, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(definition); diff --git a/src/test/java/controller/ControllerDefinitionTest.java b/src/test/java/controller/InteractionControllerDefinitionTest.java similarity index 69% rename from src/test/java/controller/ControllerDefinitionTest.java rename to src/test/java/controller/InteractionControllerDefinitionTest.java index 8368f3b2..a32f527a 100644 --- a/src/test/java/controller/ControllerDefinitionTest.java +++ b/src/test/java/controller/InteractionControllerDefinitionTest.java @@ -4,9 +4,10 @@ import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent; import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry; import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry; -import com.github.kaktushose.jda.commands.reflect.interactions.CommandDefinition; -import com.github.kaktushose.jda.commands.reflect.ControllerDefinition; +import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition; +import com.github.kaktushose.jda.commands.reflect.InteractionControllerDefinition; import commands.UnsupportedType; +import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; import net.dv8tion.jda.api.interactions.commands.localization.ResourceBundleLocalizationFunction; import org.junit.jupiter.api.BeforeAll; @@ -17,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.*; -public class ControllerDefinitionTest { +public class InteractionControllerDefinitionTest { private static final LocalizationFunction LOCALIZATION_FUNCTION = ResourceBundleLocalizationFunction.empty().build(); private static Class controller; @@ -42,9 +43,13 @@ public static void setup() { public void command_NoValues_ShouldAdoptControllerValues() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("adopt", CommandEvent.class); - ControllerDefinition controllerDefinition = ControllerDefinition.build(controller, validators, dependencyInjector, LOCALIZATION_FUNCTION).orElse(null); + InteractionControllerDefinition controllerDefinition = InteractionControllerDefinition.build(controller, validators, dependencyInjector, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(controllerDefinition); - CommandDefinition definition = controllerDefinition.getCommands().stream().filter(c -> c.getMethod().equals(method)).findFirst().orElse(null); + SlashCommandDefinition definition = controllerDefinition.getCommands().stream() + .filter(it -> it.getCommandType() == Command.Type.SLASH) + .map(it -> (SlashCommandDefinition) it) + .filter(c -> c.getMethod().equals(method)) + .findFirst().orElse(null); assertNotNull(definition); @@ -62,9 +67,13 @@ public void command_NoValues_ShouldAdoptControllerValues() throws NoSuchMethodEx public void command_OwnValues_ShouldCombineOrOverride() throws NoSuchMethodException { Method method = controller.getDeclaredMethod("combine", CommandEvent.class); - ControllerDefinition controllerDefinition = ControllerDefinition.build(controller, validators, dependencyInjector, LOCALIZATION_FUNCTION).orElse(null); + InteractionControllerDefinition controllerDefinition = InteractionControllerDefinition.build(controller, validators, dependencyInjector, LOCALIZATION_FUNCTION).orElse(null); assertNotNull(controllerDefinition); - CommandDefinition definition = controllerDefinition.getCommands().stream().filter(c -> c.getMethod().equals(method)).findFirst().orElse(null); + SlashCommandDefinition definition = controllerDefinition.getCommands().stream() + .filter(it -> it.getCommandType() == Command.Type.SLASH) + .map(it -> (SlashCommandDefinition) it) + .filter(c -> c.getMethod().equals(method)) + .findFirst().orElse(null); assertNotNull(definition); assertEquals("super sub", definition.getName()); diff --git a/src/test/resources/data/guilds.json b/src/test/resources/data/guilds.json deleted file mode 100644 index accf8a30..00000000 --- a/src/test/resources/data/guilds.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "0": { - "guildId": 0, - "prefix": "?", - "ignoreCase": false, - "ignoreBots": false, - "parseQuotes": false, - "helpLabels": [ - "foo" - ], - "mutedChannels": [ - 1 - ], - "isMutedGuild": true - } -} \ No newline at end of file