Add Choices and Autocomplete #8
| @@ -0,0 +1,12 @@ | |||||||
|  | package net.tomatentum.marinara.interaction.annotation; | ||||||
|  |  | ||||||
|  | import java.lang.annotation.ElementType; | ||||||
|  | import java.lang.annotation.Retention; | ||||||
|  | import java.lang.annotation.RetentionPolicy; | ||||||
|  | import java.lang.annotation.Target; | ||||||
|  |  | ||||||
|  | @Target({ElementType.METHOD}) | ||||||
|  | @Retention(RetentionPolicy.RUNTIME) | ||||||
|  | public @interface AutoComplete { | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | package net.tomatentum.marinara.interaction.commands; | ||||||
|  |  | ||||||
|  | public interface ChoiceValueProvider<T> { | ||||||
|  |     T getChoiceValue(); | ||||||
|  | } | ||||||
| @@ -0,0 +1,78 @@ | |||||||
|  | package net.tomatentum.marinara.interaction.commands; | ||||||
|  |  | ||||||
|  | import java.lang.reflect.InvocationTargetException; | ||||||
|  | import java.lang.reflect.Method; | ||||||
|  | import java.lang.reflect.ParameterizedType; | ||||||
|  | import java.lang.reflect.Type; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
|  | import io.leangen.geantyref.AnnotationFormatException; | ||||||
|  | import io.leangen.geantyref.GenericTypeReflector; | ||||||
|  | import io.leangen.geantyref.TypeFactory; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; | ||||||
|  |  | ||||||
|  | public record EnumChoices(Class<? extends Enum<?>> enumClass, ChoiceType type, SlashCommandOptionChoice[] choices) { | ||||||
|  |  | ||||||
|  |     private static Method method; | ||||||
|  |  | ||||||
|  |     static { | ||||||
|  |         try { | ||||||
|  |             method = ChoiceValueProvider.class.getMethod("getChoiceValue"); | ||||||
|  |         } catch (NoSuchMethodException | SecurityException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static EnumChoices of(Class<? extends Enum<?>> enumClass) { | ||||||
|  |         if (!ChoiceValueProvider.class.isAssignableFrom(enumClass)) | ||||||
|  |             throw new IllegalArgumentException("Provided class needs to implement the ChoiceValueProvider interface."); | ||||||
|  |         ChoiceType type = parseChoiceType(enumClass); | ||||||
|  |         SlashCommandOptionChoice[] choices = parseChoices(enumClass, type); | ||||||
|  |         return new EnumChoices(enumClass, type, choices); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static ChoiceType parseChoiceType(Class<? extends Enum<?>> enumClass) { | ||||||
|  |         ParameterizedType type = (ParameterizedType) GenericTypeReflector.getExactSuperType(enumClass, ChoiceValueProvider.class); | ||||||
|  |         Type typeParam = type.getActualTypeArguments()[0]; | ||||||
|  |  | ||||||
|  |         if (!(typeParam instanceof Class<?>)) | ||||||
|  |             throw new IllegalArgumentException("ChoiceValueProvider need either a String or Number type parameter."); | ||||||
|  |  | ||||||
|  |         if (Long.class.isAssignableFrom((Class<?>) typeParam)) | ||||||
|  |             return ChoiceType.INTEGER; | ||||||
|  |         if (Double.class.isAssignableFrom((Class<?>) typeParam)) | ||||||
|  |             return ChoiceType.DOUBLE; | ||||||
|  |         if (String.class.isAssignableFrom((Class<?>) typeParam)) | ||||||
|  |             return ChoiceType.String; | ||||||
|  |         throw new IllegalArgumentException("ChoiceValueProvider need either a String, Number or Decimal type parameter."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static SlashCommandOptionChoice[] parseChoices(Class<? extends Enum<?>> enumClass, ChoiceType type) { | ||||||
|  |         Enum<? extends Enum<?>>[] constants = enumClass.getEnumConstants(); | ||||||
|  |         List<SlashCommandOptionChoice> choices = new ArrayList<>(); | ||||||
|  |         for (Enum<? extends Enum<?>> enumInstance : constants) { | ||||||
|  |             Object value; | ||||||
|  |             try { | ||||||
|  |                 value = method.invoke(enumInstance); | ||||||
|  |                 if (type.equals(ChoiceType.INTEGER)) | ||||||
|  |                     choices.add(TypeFactory.annotation(SlashCommandOptionChoice.class, Map.of("name", enumInstance.name(), "longValue", value))); | ||||||
|  |                 if (type.equals(ChoiceType.DOUBLE)) | ||||||
|  |                     choices.add(TypeFactory.annotation(SlashCommandOptionChoice.class, Map.of("name", enumInstance.name(), "doubleValue", value))); | ||||||
|  |                 if (type.equals(ChoiceType.String)) | ||||||
|  |                     choices.add(TypeFactory.annotation(SlashCommandOptionChoice.class, Map.of("name", enumInstance.name(), "stringValue", value))); | ||||||
|  |             } catch (IllegalAccessException | InvocationTargetException | AnnotationFormatException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return choices.toArray(new SlashCommandOptionChoice[0]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static enum ChoiceType { | ||||||
|  |         String, | ||||||
|  |         INTEGER, | ||||||
|  |         DOUBLE | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,8 +2,10 @@ package net.tomatentum.marinara.interaction.commands; | |||||||
|  |  | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption.PlaceHolderEnum; | ||||||
|  |  | ||||||
| public record ExecutableSlashCommandDefinition( | public record ExecutableSlashCommandDefinition( | ||||||
|     SlashCommand applicationCommand, |     SlashCommand applicationCommand, | ||||||
| @@ -11,6 +13,13 @@ public record ExecutableSlashCommandDefinition( | |||||||
|     SubCommandGroup subCommandGroup,  |     SubCommandGroup subCommandGroup,  | ||||||
|     SlashCommandOption[] options) { |     SlashCommandOption[] options) { | ||||||
|  |  | ||||||
|  |     public static SlashCommandOptionChoice[] getActualChoices(SlashCommandOption option) { | ||||||
|  |         SlashCommandOptionChoice[] choices = option.choices(); | ||||||
|  |         if (choices.length <= 0 && !option.choiceEnum().equals(PlaceHolderEnum.class)) | ||||||
|  |             choices = EnumChoices.of(option.choiceEnum()).choices(); | ||||||
|  |         return choices; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public final boolean equals(Object o) { |     public final boolean equals(Object o) { | ||||||
|         if (!(o instanceof ExecutableSlashCommandDefinition)) |         if (!(o instanceof ExecutableSlashCommandDefinition)) | ||||||
|   | |||||||
| @@ -14,4 +14,11 @@ public @interface SlashCommandOption { | |||||||
|     public String description() default ""; |     public String description() default ""; | ||||||
|     public SlashCommandOptionType type() default SlashCommandOptionType.STRING; |     public SlashCommandOptionType type() default SlashCommandOptionType.STRING; | ||||||
|     public boolean required() default false; |     public boolean required() default false; | ||||||
|  |     public boolean autocomplete() default false; | ||||||
|  |     public SlashCommandOptionChoice[] choices() default {}; | ||||||
|  |     public Class<? extends Enum<?>> choiceEnum() default PlaceHolderEnum.class; | ||||||
|  |  | ||||||
|  |     public static enum PlaceHolderEnum { | ||||||
|  |  | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | package net.tomatentum.marinara.interaction.commands.annotation; | ||||||
|  |  | ||||||
|  | public @interface SlashCommandOptionChoice { | ||||||
|  |     public String name(); | ||||||
|  |     public long longValue() default Long.MAX_VALUE; | ||||||
|  |     public double doubleValue() default Double.MAX_VALUE; | ||||||
|  |     public String stringValue() default ""; | ||||||
|  | } | ||||||
| @@ -1,16 +1,26 @@ | |||||||
| package net.tomatentum.marinara.interaction.commands.option; | package net.tomatentum.marinara.interaction.commands.option; | ||||||
|  |  | ||||||
| public enum SlashCommandOptionType { | public enum SlashCommandOptionType { | ||||||
|     ATTACHMENT, |     SUB_COMMAND(1), | ||||||
|     BOOLEAN, |     SUB_COMMAND_GROUP(2), | ||||||
|     CHANNEL, |     STRING(3), | ||||||
|     DECIMAL, |     INTEGER(4), | ||||||
|     LONG, |     BOOLEAN(5), | ||||||
|     MENTIONABLE, |     USER(6), | ||||||
|     ROLE, |     CHANNEL(7), | ||||||
|     STRING, |     ROLE(8), | ||||||
|     SUB_COMMAND, |     MENTIONABLE(9), | ||||||
|     SUB_COMMAND_GROUP, |     DOUBLE(10), | ||||||
|     UNKNOW, |     ATTACHMENT(11), | ||||||
|     USER |     UNKNOWN(-1); | ||||||
|  |  | ||||||
|  |     private final int value; | ||||||
|  |  | ||||||
|  |     private SlashCommandOptionType(int value) { | ||||||
|  |         this.value = value; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getValue() { | ||||||
|  |         return value; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,51 @@ | |||||||
|  | package net.tomatentum.marinara.interaction.methods; | ||||||
|  |  | ||||||
|  | import java.lang.reflect.Method; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.Marinara; | ||||||
|  | import net.tomatentum.marinara.interaction.InteractionHandler; | ||||||
|  | import net.tomatentum.marinara.interaction.InteractionType; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; | ||||||
|  | import net.tomatentum.marinara.parser.AnnotationParser; | ||||||
|  | import net.tomatentum.marinara.parser.SlashCommandParser; | ||||||
|  |  | ||||||
|  | public class AutoCompleteInteractionMethod extends InteractionMethod { | ||||||
|  |  | ||||||
|  |     private ExecutableSlashCommandDefinition commandDefinition; | ||||||
|  |  | ||||||
|  |     public AutoCompleteInteractionMethod(Method method,  | ||||||
|  |         InteractionHandler handler,  | ||||||
|  |         Marinara marinara | ||||||
|  |         ) { | ||||||
|  |         super(method, handler, marinara); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public AnnotationParser[] getParsers() { | ||||||
|  |         return new AnnotationParser[] {  | ||||||
|  |             new SlashCommandParser(method, (x) -> { this.commandDefinition = x; } )  | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Object getParameter(Object context, int index) { | ||||||
|  |         Class<?> type = getMethod().getParameterTypes()[index+1]; | ||||||
|  |         Object autocompleteOptionValue = marinara.getWrapper().getContextObjectProvider().getAutocompleteFocusedOption(context); | ||||||
|  |         if (autocompleteOptionValue != null) | ||||||
|  |             return autocompleteOptionValue; | ||||||
|  |  | ||||||
|  |         return marinara.getWrapper().getContextObjectProvider().getComponentContextObject(context, type); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean canRun(Object context) { | ||||||
|  |         ExecutableSlashCommandDefinition other = marinara.getWrapper().getCommandDefinition(context); | ||||||
|  |         return commandDefinition.equals(other); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionType getType() { | ||||||
|  |         return InteractionType.AUTOCOMPLETE; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -24,9 +24,9 @@ public class ButtonInteractionMethod extends InteractionMethod { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Object getParameter(Object parameter, int index) { |     public Object getParameter(Object context, int index) { | ||||||
|         Class<?> type = getMethod().getParameterTypes()[index+1]; |         Class<?> type = getMethod().getParameterTypes()[index+1]; | ||||||
|         return marinara.getWrapper().getComponentContextObject(parameter, type); |         return marinara.getWrapper().getContextObjectProvider().getComponentContextObject(context, type); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -38,4 +38,5 @@ public class ButtonInteractionMethod extends InteractionMethod { | |||||||
|     public InteractionType getType() { |     public InteractionType getType() { | ||||||
|         return InteractionType.BUTTON; |         return InteractionType.BUTTON; | ||||||
|     } |     } | ||||||
|  |      | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import net.tomatentum.marinara.Marinara; | |||||||
| import net.tomatentum.marinara.checks.AppliedCheck; | import net.tomatentum.marinara.checks.AppliedCheck; | ||||||
| import net.tomatentum.marinara.interaction.InteractionHandler; | import net.tomatentum.marinara.interaction.InteractionHandler; | ||||||
| import net.tomatentum.marinara.interaction.InteractionType; | import net.tomatentum.marinara.interaction.InteractionType; | ||||||
|  | import net.tomatentum.marinara.interaction.annotation.AutoComplete; | ||||||
| import net.tomatentum.marinara.interaction.annotation.Button; | import net.tomatentum.marinara.interaction.annotation.Button; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | ||||||
| @@ -24,6 +25,8 @@ import net.tomatentum.marinara.util.ReflectionUtil; | |||||||
| public abstract class InteractionMethod { | public abstract class InteractionMethod { | ||||||
|  |  | ||||||
|     public static InteractionMethod create(Method method, InteractionHandler handler, Marinara marinara) { |     public static InteractionMethod create(Method method, InteractionHandler handler, Marinara marinara) { | ||||||
|  |         if (method.isAnnotationPresent(AutoComplete.class)) | ||||||
|  |             return new AutoCompleteInteractionMethod(method, handler, marinara); | ||||||
|         if (method.isAnnotationPresent(SlashCommand.class) || method.isAnnotationPresent(SubCommand.class)) |         if (method.isAnnotationPresent(SlashCommand.class) || method.isAnnotationPresent(SubCommand.class)) | ||||||
|             return new SlashCommandInteractionMethod(method, handler, marinara); |             return new SlashCommandInteractionMethod(method, handler, marinara); | ||||||
|         if (method.isAnnotationPresent(Button.class)) |         if (method.isAnnotationPresent(Button.class)) | ||||||
| @@ -59,7 +62,7 @@ public abstract class InteractionMethod { | |||||||
|  |  | ||||||
|     public abstract AnnotationParser[] getParsers(); |     public abstract AnnotationParser[] getParsers(); | ||||||
|  |  | ||||||
|     public abstract Object getParameter(Object parameter, int index); |     public abstract Object getParameter(Object context, int index); | ||||||
|  |  | ||||||
|     public abstract boolean canRun(Object context); |     public abstract boolean canRun(Object context); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ public class SlashCommandInteractionMethod extends InteractionMethod { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Object getParameter(Object context, int index) { |     public Object getParameter(Object context, int index) { | ||||||
|         return marinara.getWrapper().convertCommandOption(context, commandDefinition.options()[index].type(), commandDefinition.options()[index].name()); |         return marinara.getWrapper().getContextObjectProvider().convertCommandOption(context, commandDefinition.options()[index].name()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | package net.tomatentum.marinara.wrapper; | ||||||
|  |  | ||||||
|  | public interface ContextObjectProvider { | ||||||
|  |  | ||||||
|  |     public Object convertCommandOption(Object context, String optionName); | ||||||
|  |  | ||||||
|  |     public Object getComponentContextObject(Object context, Class<?> type); | ||||||
|  |     public Object getInteractionContextObject(Object context, Class<?> type); | ||||||
|  |  | ||||||
|  |     public Object getAutocompleteFocusedOption(Object context); | ||||||
|  | } | ||||||
| @@ -6,7 +6,6 @@ import java.util.function.Consumer; | |||||||
|  |  | ||||||
| import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; | import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; | ||||||
| import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; | import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; | ||||||
| import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; |  | ||||||
| import net.tomatentum.marinara.interaction.InteractionType; | import net.tomatentum.marinara.interaction.InteractionType; | ||||||
|  |  | ||||||
| public abstract class LibraryWrapper { | public abstract class LibraryWrapper { | ||||||
| @@ -17,7 +16,6 @@ public abstract class LibraryWrapper { | |||||||
|         interactionSubscriber = new ArrayList<>(); |         interactionSubscriber = new ArrayList<>(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     public void handleInteraction(Object context) { |     public void handleInteraction(Object context) { | ||||||
|         interactionSubscriber.forEach((o) -> o.accept(context)); |         interactionSubscriber.forEach((o) -> o.accept(context)); | ||||||
|     } |     } | ||||||
| @@ -32,9 +30,10 @@ public abstract class LibraryWrapper { | |||||||
|     public abstract InteractionType getInteractionType(Class<?> clazz); |     public abstract InteractionType getInteractionType(Class<?> clazz); | ||||||
|  |  | ||||||
|     public abstract void registerSlashCommands(SlashCommandDefinition[] defs);  |     public abstract void registerSlashCommands(SlashCommandDefinition[] defs);  | ||||||
|     public abstract Object convertCommandOption(Object context, SlashCommandOptionType type, String optionName); |  | ||||||
|     public abstract ExecutableSlashCommandDefinition getCommandDefinition(Object context); |     public abstract ExecutableSlashCommandDefinition getCommandDefinition(Object context); | ||||||
|  |  | ||||||
|     public abstract String getButtonId(Object context); |     public abstract String getButtonId(Object context); | ||||||
|     public abstract Object getComponentContextObject(Object context, Class<?> type); |  | ||||||
|  |     public abstract ContextObjectProvider getContextObjectProvider(); | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -0,0 +1,110 @@ | |||||||
|  | package net.tomatentum.marinara.wrapper.javacord; | ||||||
|  |  | ||||||
|  | import org.javacord.api.interaction.AutocompleteInteraction; | ||||||
|  | import org.javacord.api.interaction.ButtonInteraction; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteraction; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteractionOption; | ||||||
|  | import org.javacord.api.interaction.SlashCommandOptionType; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.wrapper.ContextObjectProvider; | ||||||
|  |  | ||||||
|  | public class JavacordContextObjectProvider implements ContextObjectProvider { | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Object convertCommandOption(Object context, String optionName) { | ||||||
|  |         if (!(context instanceof SlashCommandInteraction)) | ||||||
|  |             return null; | ||||||
|  |         SlashCommandInteraction interaction = (SlashCommandInteraction) context; | ||||||
|  |         if (!interaction.getArguments().isEmpty()) | ||||||
|  |             return getOptionValue(interaction.getOptionByName(optionName).get()); | ||||||
|  |  | ||||||
|  |         SlashCommandInteractionOption subCommandOption = interaction.getOptions().getFirst(); | ||||||
|  |  | ||||||
|  |         if (!subCommandOption.getOptions().isEmpty()) | ||||||
|  |             subCommandOption = subCommandOption.getOptions().getFirst(); | ||||||
|  |  | ||||||
|  |         return getOptionValue(subCommandOption.getOptionByName(optionName).get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private Object getOptionValue(SlashCommandInteractionOption option) { | ||||||
|  |         SlashCommandOptionType type = getOptionType(option); | ||||||
|  |         switch (type) { | ||||||
|  |             case ATTACHMENT: | ||||||
|  |                 return option.getAttachmentValue().get(); | ||||||
|  |             case BOOLEAN: | ||||||
|  |                 return option.getBooleanValue().get(); | ||||||
|  |             case CHANNEL: | ||||||
|  |                 return option.getChannelValue().get(); | ||||||
|  |             case DECIMAL: | ||||||
|  |                 return option.getDecimalValue().get(); | ||||||
|  |             case LONG: | ||||||
|  |                 return option.getLongValue().get(); | ||||||
|  |             case MENTIONABLE: | ||||||
|  |                 return option.requestMentionableValue().get(); | ||||||
|  |             case ROLE: | ||||||
|  |                 return option.getRoleValue().get(); | ||||||
|  |             case STRING: | ||||||
|  |                 return option.getStringValue().get(); | ||||||
|  |             case USER: | ||||||
|  |                 return option.requestUserValue().get(); | ||||||
|  |             default: | ||||||
|  |                 return null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     private SlashCommandOptionType getOptionType(SlashCommandInteractionOption option) { | ||||||
|  |         if (option.getAttachmentValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.ATTACHMENT; | ||||||
|  |         if (option.getBooleanValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.BOOLEAN; | ||||||
|  |         if (option.getChannelValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.CHANNEL; | ||||||
|  |         if (option.getDecimalValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.DECIMAL; | ||||||
|  |         if (option.getLongValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.LONG; | ||||||
|  |         if (option.requestMentionableValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.MENTIONABLE; | ||||||
|  |         if (option.getRoleValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.ROLE; | ||||||
|  |         if (option.getStringValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.STRING; | ||||||
|  |         if (option.requestUserValue().isPresent()) | ||||||
|  |             return SlashCommandOptionType.USER; | ||||||
|  |  | ||||||
|  |         return SlashCommandOptionType.UNKNOWN; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Object getComponentContextObject(Object context, Class<?> type) { | ||||||
|  |         ButtonInteraction button = (ButtonInteraction) context; | ||||||
|  |         switch (type.getName()) { | ||||||
|  |             case "org.javacord.api.entity.message.Message": | ||||||
|  |                 return button.getMessage(); | ||||||
|  |             default: | ||||||
|  |                 return getInteractionContextObject(context, type); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Object getInteractionContextObject(Object context, Class<?> type) { | ||||||
|  |         ButtonInteraction button = (ButtonInteraction) context; | ||||||
|  |         switch (type.getName()) { | ||||||
|  |             case "org.javacord.api.entity.channel.TextChannel": | ||||||
|  |                 return button.getChannel().orElse(null); | ||||||
|  |             case "org.javacord.api.entity.server.Server": | ||||||
|  |                 return button.getServer().orElse(null); | ||||||
|  |             case "org.javacord.api.entity.user.User": | ||||||
|  |                 return button.getUser(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Object getAutocompleteFocusedOption(Object context) { | ||||||
|  |         AutocompleteInteraction interaction = (AutocompleteInteraction) context; | ||||||
|  |         return getOptionValue(interaction.getFocusedOption()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -11,10 +11,14 @@ import java.util.Set; | |||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import org.javacord.api.DiscordApi; | import org.javacord.api.DiscordApi; | ||||||
| import org.javacord.api.interaction.ApplicationCommandInteraction; | import org.javacord.api.interaction.ApplicationCommandInteraction; | ||||||
|  | import org.javacord.api.interaction.AutocompleteInteraction; | ||||||
| import org.javacord.api.interaction.ButtonInteraction; | import org.javacord.api.interaction.ButtonInteraction; | ||||||
| import org.javacord.api.interaction.SlashCommandBuilder; | import org.javacord.api.interaction.SlashCommandBuilder; | ||||||
| import org.javacord.api.interaction.SlashCommandInteraction; | import org.javacord.api.interaction.SlashCommandInteraction; | ||||||
| import org.javacord.api.interaction.SlashCommandInteractionOption; | import org.javacord.api.interaction.SlashCommandInteractionOption; | ||||||
|  | import org.javacord.api.interaction.SlashCommandOptionBuilder; | ||||||
|  | import org.javacord.api.interaction.SlashCommandOptionChoiceBuilder; | ||||||
|  | import org.javacord.api.interaction.SlashCommandOptionType; | ||||||
|  |  | ||||||
| import io.leangen.geantyref.AnnotationFormatException; | import io.leangen.geantyref.AnnotationFormatException; | ||||||
| import io.leangen.geantyref.TypeFactory; | import io.leangen.geantyref.TypeFactory; | ||||||
| @@ -23,31 +27,35 @@ import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefini | |||||||
| import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; | import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | ||||||
| import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | ||||||
| import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; | import net.tomatentum.marinara.wrapper.ContextObjectProvider; | ||||||
| import net.tomatentum.marinara.util.LoggerUtil; | import net.tomatentum.marinara.util.LoggerUtil; | ||||||
| import net.tomatentum.marinara.wrapper.LibraryWrapper; | import net.tomatentum.marinara.wrapper.LibraryWrapper; | ||||||
|  |  | ||||||
| public class JavacordWrapper extends LibraryWrapper { | public class JavacordWrapper extends LibraryWrapper { | ||||||
|  |  | ||||||
|     private DiscordApi api; |     private DiscordApi api; | ||||||
|  |     private JavacordContextObjectProvider contextObjectProvider; | ||||||
|      |      | ||||||
|     private Logger logger = LoggerUtil.getLogger(getClass()); |     private Logger logger = LoggerUtil.getLogger(getClass()); | ||||||
|  |  | ||||||
|     public JavacordWrapper(DiscordApi api) { |     public JavacordWrapper(DiscordApi api) { | ||||||
|         this.api = api; |         this.api = api; | ||||||
|  |         this.contextObjectProvider = new JavacordContextObjectProvider(); | ||||||
|         api.addInteractionCreateListener((e) -> handleInteraction(e.getInteraction())); |         api.addInteractionCreateListener((e) -> handleInteraction(e.getInteraction())); | ||||||
|         logger.info("Javacord wrapper loaded!"); |         logger.info("Javacord wrapper loaded!"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public InteractionType getInteractionType(Class<?> clazz) { |     public InteractionType getInteractionType(Class<?> clazz) { | ||||||
|  |         if (AutocompleteInteraction.class.isAssignableFrom(clazz)) | ||||||
|  |             return InteractionType.AUTOCOMPLETE; | ||||||
|         if (ApplicationCommandInteraction.class.isAssignableFrom(clazz)) |         if (ApplicationCommandInteraction.class.isAssignableFrom(clazz)) | ||||||
|             return InteractionType.COMMAND; |             return InteractionType.COMMAND; | ||||||
|         if (ButtonInteraction.class.isAssignableFrom(clazz)) |         if (ButtonInteraction.class.isAssignableFrom(clazz)) | ||||||
|             return InteractionType.BUTTON; |             return InteractionType.BUTTON; | ||||||
|  |  | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -72,22 +80,6 @@ public class JavacordWrapper extends LibraryWrapper { | |||||||
|         api.bulkOverwriteGlobalApplicationCommands(globalCommands); |         api.bulkOverwriteGlobalApplicationCommands(globalCommands); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Object convertCommandOption(Object context, SlashCommandOptionType type, String optionName) { |  | ||||||
|         if (!(context instanceof SlashCommandInteraction)) |  | ||||||
|             return null; |  | ||||||
|         SlashCommandInteraction interaction = (SlashCommandInteraction) context; |  | ||||||
|         if (!interaction.getArguments().isEmpty()) |  | ||||||
|             return getOptionValue(interaction.getOptionByName(optionName).get(), type); |  | ||||||
|  |  | ||||||
|         SlashCommandInteractionOption subCommandOption = interaction.getOptions().getFirst(); |  | ||||||
|  |  | ||||||
|         if (!subCommandOption.getOptions().isEmpty()) |  | ||||||
|             subCommandOption = subCommandOption.getOptions().getFirst(); |  | ||||||
|  |  | ||||||
|         return getOptionValue(subCommandOption.getOptionByName(optionName).get(), type); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public ExecutableSlashCommandDefinition getCommandDefinition(Object context) { |     public ExecutableSlashCommandDefinition getCommandDefinition(Object context) { | ||||||
|         if (!(context instanceof SlashCommandInteraction)) |         if (!(context instanceof SlashCommandInteraction)) | ||||||
| @@ -128,43 +120,53 @@ public class JavacordWrapper extends LibraryWrapper { | |||||||
|     private org.javacord.api.interaction.SlashCommandOption convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) { |     private org.javacord.api.interaction.SlashCommandOption convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) { | ||||||
|         SubCommand[] subCommands = def.getSubCommands(subGroup.name()); |         SubCommand[] subCommands = def.getSubCommands(subGroup.name()); | ||||||
|         org.javacord.api.interaction.SlashCommandOption[] convertedSubCommands = (org.javacord.api.interaction.SlashCommandOption[]) Arrays.stream(subCommands).map(this::convertSubCommandDef).toArray(); |         org.javacord.api.interaction.SlashCommandOption[] convertedSubCommands = (org.javacord.api.interaction.SlashCommandOption[]) Arrays.stream(subCommands).map(this::convertSubCommandDef).toArray(); | ||||||
|         return org.javacord.api.interaction.SlashCommandOption.createWithOptions(org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND_GROUP, subGroup.name(), subGroup.description(), Arrays.asList(convertedSubCommands)); |         return org.javacord.api.interaction.SlashCommandOption.createWithOptions( | ||||||
|  |             org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND_GROUP,  | ||||||
|  |             subGroup.name(),  | ||||||
|  |             subGroup.description(),  | ||||||
|  |             Arrays.asList(convertedSubCommands)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private org.javacord.api.interaction.SlashCommandOption convertSubCommandDef(SubCommand sub) { |     private org.javacord.api.interaction.SlashCommandOption convertSubCommandDef(SubCommand sub) { | ||||||
|         List<org.javacord.api.interaction.SlashCommandOption> convertedOptions = new ArrayList<>(); |         List<org.javacord.api.interaction.SlashCommandOption> convertedOptions = new ArrayList<>(); | ||||||
|         Arrays.stream(sub.options()).map(this::convertOptionDef).forEach(convertedOptions::add); |         Arrays.stream(sub.options()).map(this::convertOptionDef).forEach(convertedOptions::add); | ||||||
|         return org.javacord.api.interaction.SlashCommandOption.createWithOptions(org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND, sub.name(), sub.description(), convertedOptions); |         return org.javacord.api.interaction.SlashCommandOption.createWithOptions( | ||||||
|  |             org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND,  | ||||||
|  |             sub.name(),  | ||||||
|  |             sub.description(),  | ||||||
|  |             convertedOptions); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private org.javacord.api.interaction.SlashCommandOption convertOptionDef(SlashCommandOption option) { |     private org.javacord.api.interaction.SlashCommandOption convertOptionDef(SlashCommandOption option) { | ||||||
|         org.javacord.api.interaction.SlashCommandOptionType type = Enum.valueOf(org.javacord.api.interaction.SlashCommandOptionType.class, option.type().toString()); |         SlashCommandOptionType type = SlashCommandOptionType.fromValue(option.type().getValue()); | ||||||
|         return org.javacord.api.interaction.SlashCommandOption.create(type, option.name(), option.description(), option.required()); |         SlashCommandOptionBuilder builder = new SlashCommandOptionBuilder(); | ||||||
|  |         builder | ||||||
|  |             .setType(type) | ||||||
|  |             .setName(option.name()) | ||||||
|  |             .setDescription(option.description()) | ||||||
|  |             .setRequired(option.required()) | ||||||
|  |             .setAutocompletable(option.autocomplete()) | ||||||
|  |             .setChoices(convertChoices(option)); | ||||||
|  |          | ||||||
|  |         return builder.build(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private Object getOptionValue(SlashCommandInteractionOption option, SlashCommandOptionType type) { |     private List<org.javacord.api.interaction.SlashCommandOptionChoice> convertChoices(SlashCommandOption option) { | ||||||
|         switch (type) { |         List<org.javacord.api.interaction.SlashCommandOptionChoice> convertedChoices = new ArrayList<>(); | ||||||
|             case ATTACHMENT: |         for (SlashCommandOptionChoice choice : ExecutableSlashCommandDefinition.getActualChoices(option)) { | ||||||
|                 return option.getAttachmentValue().get(); |             SlashCommandOptionChoiceBuilder builder = new SlashCommandOptionChoiceBuilder(); | ||||||
|             case BOOLEAN: |             builder.setName(choice.name()); | ||||||
|                 return option.getBooleanValue().get(); |             if (choice.longValue() != Long.MAX_VALUE) | ||||||
|             case CHANNEL: |                 builder.setValue(choice.longValue()); | ||||||
|                 return option.getChannelValue().get(); |             /* | ||||||
|             case DECIMAL: |             not yet available | ||||||
|                 return option.getDecimalValue().get(); |             if (choice.doubleValue() != Double.MAX_VALUE) | ||||||
|             case LONG: |                 builder.setValue(choice.doubleValue()); | ||||||
|                 return option.getLongValue().get(); |             */ | ||||||
|             case MENTIONABLE: |             if (!choice.stringValue().isEmpty()) | ||||||
|                 return option.getMentionableValue().get(); |                 builder.setValue(choice.stringValue()); | ||||||
|             case ROLE: |  | ||||||
|                 return option.getRoleValue().get(); |  | ||||||
|             case STRING: |  | ||||||
|                 return option.getStringValue().get(); |  | ||||||
|             case USER: |  | ||||||
|                 return option.getUserValue().get(); |  | ||||||
|             default: |  | ||||||
|                 return null; |  | ||||||
|         } |         } | ||||||
|  |         return convertedChoices; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -174,20 +176,8 @@ public class JavacordWrapper extends LibraryWrapper { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Object getComponentContextObject(Object context, Class<?> type) { |     public ContextObjectProvider getContextObjectProvider() { | ||||||
|         ButtonInteraction button = (ButtonInteraction) context; |         return contextObjectProvider; | ||||||
|         switch (type.getName()) { |  | ||||||
|             case "org.javacord.api.entity.channel.TextChannel": |  | ||||||
|                 return button.getChannel().orElse(null); |  | ||||||
|             case "org.javacord.api.entity.message.Message": |  | ||||||
|                 return button.getMessage(); |  | ||||||
|             case "org.javacord.api.entity.server.Server": |  | ||||||
|                 return button.getServer().orElse(null); |  | ||||||
|             case "org.javacord.api.entity.user.User": |  | ||||||
|                 return button.getUser(); |  | ||||||
|     } |     } | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package net.tomatentum.marinara.test; | ||||||
|  |  | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertTrue; | ||||||
|  |  | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.Marinara; | ||||||
|  | import net.tomatentum.marinara.test.mocks.AutocompleteInteractionMock; | ||||||
|  | import net.tomatentum.marinara.test.mocks.DiscordApiMock; | ||||||
|  | import net.tomatentum.marinara.wrapper.LibraryWrapper; | ||||||
|  | import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; | ||||||
|  |  | ||||||
|  | public class AutoCompleteTest { | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void testAutocomplete() { | ||||||
|  |         LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this test. | ||||||
|  |         Marinara marinara = Marinara.load(wrapper); | ||||||
|  |         marinara.getRegistry().addInteractions(new TestAutocomplete()); | ||||||
|  |         wrapper.handleInteraction(new AutocompleteInteractionMock()); | ||||||
|  |         assertTrue(AutocompleteInteractionMock.didAutocompleteRun); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package net.tomatentum.marinara.test; | ||||||
|  |  | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  |  | ||||||
|  | import java.util.Collections; | ||||||
|  |  | ||||||
|  | import org.javacord.api.interaction.AutocompleteInteraction; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.interaction.InteractionHandler; | ||||||
|  | import net.tomatentum.marinara.interaction.annotation.AutoComplete; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||||
|  |  | ||||||
|  | public class TestAutocomplete implements InteractionHandler { | ||||||
|  |      | ||||||
|  |     @SlashCommand(name = "test") | ||||||
|  |     @AutoComplete | ||||||
|  |     public void autocomplete(AutocompleteInteraction context, String value) { | ||||||
|  |         System.out.println("Success!"); | ||||||
|  |         assertEquals(value, "test"); | ||||||
|  |         context.respondWithChoices(Collections.emptyList()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | package net.tomatentum.marinara.test; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.interaction.commands.ChoiceValueProvider; | ||||||
|  |  | ||||||
|  | public enum TestChoiceEnum implements ChoiceValueProvider<String> { | ||||||
|  |     TestValue("testValue"), | ||||||
|  |     FooBar("fooBar"), | ||||||
|  |     Spongebob("spongebob"); | ||||||
|  |  | ||||||
|  |     private String value; | ||||||
|  |  | ||||||
|  |     private TestChoiceEnum(String value) { | ||||||
|  |         this.value = value; | ||||||
|  |     } | ||||||
|  |     @Override | ||||||
|  |     public String getChoiceValue() { | ||||||
|  |         return value; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -20,7 +20,8 @@ public class TestCommand implements InteractionHandler { | |||||||
|             @SlashCommandOption( |             @SlashCommandOption( | ||||||
|                 name = "foo", |                 name = "foo", | ||||||
|                 description = "foo bar is very fooby", |                 description = "foo bar is very fooby", | ||||||
|                 type = SlashCommandOptionType.STRING |                 type = SlashCommandOptionType.STRING, | ||||||
|  |                 choiceEnum = TestChoiceEnum.class | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|         ) |         ) | ||||||
|   | |||||||
| @@ -0,0 +1,179 @@ | |||||||
|  | package net.tomatentum.marinara.test.mocks; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.EnumSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
|  |  | ||||||
|  | import org.javacord.api.DiscordApi; | ||||||
|  | import org.javacord.api.entity.channel.TextChannel; | ||||||
|  | import org.javacord.api.entity.message.component.HighLevelComponent; | ||||||
|  | import org.javacord.api.entity.permission.PermissionType; | ||||||
|  | import org.javacord.api.entity.server.Server; | ||||||
|  | import org.javacord.api.entity.user.User; | ||||||
|  | import org.javacord.api.interaction.AutocompleteInteraction; | ||||||
|  | import org.javacord.api.interaction.DiscordLocale; | ||||||
|  | import org.javacord.api.interaction.InteractionType; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteractionOption; | ||||||
|  | import org.javacord.api.interaction.SlashCommandOptionChoice; | ||||||
|  | import org.javacord.api.interaction.callback.InteractionFollowupMessageBuilder; | ||||||
|  | import org.javacord.api.interaction.callback.InteractionImmediateResponseBuilder; | ||||||
|  | import org.javacord.api.interaction.callback.InteractionOriginalResponseUpdater; | ||||||
|  |  | ||||||
|  | public class AutocompleteInteractionMock implements AutocompleteInteraction { | ||||||
|  |  | ||||||
|  |     public static boolean didAutocompleteRun = false; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getFullCommandName() { | ||||||
|  |         return "test"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public long getCommandId() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getCommandId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getCommandIdAsString() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getCommandIdAsString'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getCommandName() { | ||||||
|  |         return "test"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Long> getRegisteredCommandServerId() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getRegisteredCommandServerId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public long getApplicationId() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getApplicationId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionType getType() { | ||||||
|  |         return InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionImmediateResponseBuilder createImmediateResponder() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'createImmediateResponder'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<InteractionOriginalResponseUpdater> respondLater() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'respondLater'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<InteractionOriginalResponseUpdater> respondLater(boolean ephemeral) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'respondLater'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<Void> respondWithModal(String customId, String title, | ||||||
|  |             List<HighLevelComponent> components) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'respondWithModal'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionFollowupMessageBuilder createFollowupMessageBuilder() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'createFollowupMessageBuilder'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Server> getServer() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getServer'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<TextChannel> getChannel() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getChannel'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public User getUser() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getUser'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getToken() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getToken'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int getVersion() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getVersion'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public DiscordLocale getLocale() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getLocale'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<DiscordLocale> getServerLocale() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getServerLocale'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<EnumSet<PermissionType>> getBotPermissions() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getBotPermissions'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public DiscordApi getApi() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getApi'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public long getId() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<SlashCommandInteractionOption> getOptions() { | ||||||
|  |         return new ArrayList<>(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<SlashCommandInteractionOption> getArguments() { | ||||||
|  |         return new ArrayList<>(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<Void> respondWithChoices(List<SlashCommandOptionChoice> choices) { | ||||||
|  |         didAutocompleteRun = true; | ||||||
|  |         return CompletableFuture.completedFuture(null); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public SlashCommandInteractionOption getFocusedOption() { | ||||||
|  |         return new SlashCommandInteractionOptionMock(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -41,52 +41,52 @@ public class SlashCommandInteractionOptionMock implements SlashCommandInteractio | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<Long> getLongValue() { |     public Optional<Long> getLongValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getLongValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<Boolean> getBooleanValue() { |     public Optional<Boolean> getBooleanValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getBooleanValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<User> getUserValue() { |     public Optional<User> getUserValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getUserValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<CompletableFuture<User>> requestUserValue() { |     public Optional<CompletableFuture<User>> requestUserValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'requestUserValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<ServerChannel> getChannelValue() { |     public Optional<ServerChannel> getChannelValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getChannelValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<Attachment> getAttachmentValue() { |     public Optional<Attachment> getAttachmentValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getAttachmentValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<Role> getRoleValue() { |     public Optional<Role> getRoleValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getRoleValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<Mentionable> getMentionableValue() { |     public Optional<Mentionable> getMentionableValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getMentionableValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<Double> getDecimalValue() { |     public Optional<Double> getDecimalValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'getDecimalValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Optional<CompletableFuture<Mentionable>> requestMentionableValue() { |     public Optional<CompletableFuture<Mentionable>> requestMentionableValue() { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method 'requestMentionableValue'"); |         return Optional.empty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user