Merge remote-tracking branch 'origin/dev' into wrapper/d4j
This commit is contained in:
@@ -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.SlashCommandOption;
|
||||
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice;
|
||||
import net.tomatentum.marinara.interaction.commands.annotation.SubCommand;
|
||||
import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup;
|
||||
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption.PlaceHolderEnum;
|
||||
|
||||
public record ExecutableSlashCommandDefinition(
|
||||
SlashCommand applicationCommand,
|
||||
@@ -11,6 +13,13 @@ public record ExecutableSlashCommandDefinition(
|
||||
SubCommandGroup subCommandGroup,
|
||||
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
|
||||
public final boolean equals(Object o) {
|
||||
if (!(o instanceof ExecutableSlashCommandDefinition))
|
||||
|
@@ -14,4 +14,11 @@ public @interface SlashCommandOption {
|
||||
public String description() default "";
|
||||
public SlashCommandOptionType type() default SlashCommandOptionType.STRING;
|
||||
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;
|
||||
|
||||
public enum SlashCommandOptionType {
|
||||
ATTACHMENT,
|
||||
BOOLEAN,
|
||||
CHANNEL,
|
||||
DECIMAL,
|
||||
LONG,
|
||||
MENTIONABLE,
|
||||
ROLE,
|
||||
STRING,
|
||||
SUB_COMMAND,
|
||||
SUB_COMMAND_GROUP,
|
||||
UNKNOW,
|
||||
USER
|
||||
SUB_COMMAND(1),
|
||||
SUB_COMMAND_GROUP(2),
|
||||
STRING(3),
|
||||
INTEGER(4),
|
||||
BOOLEAN(5),
|
||||
USER(6),
|
||||
CHANNEL(7),
|
||||
ROLE(8),
|
||||
MENTIONABLE(9),
|
||||
DOUBLE(10),
|
||||
ATTACHMENT(11),
|
||||
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
|
||||
public Object getParameter(Object parameter, int index) {
|
||||
public Object getParameter(Object context, int index) {
|
||||
Class<?> type = getMethod().getParameterTypes()[index+1];
|
||||
return marinara.getWrapper().getComponentContextObject(parameter, type);
|
||||
return marinara.getWrapper().getContextObjectProvider().getComponentContextObject(context, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,4 +38,5 @@ public class ButtonInteractionMethod extends InteractionMethod {
|
||||
public InteractionType getType() {
|
||||
return InteractionType.BUTTON;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ import net.tomatentum.marinara.Marinara;
|
||||
import net.tomatentum.marinara.checks.AppliedCheck;
|
||||
import net.tomatentum.marinara.interaction.InteractionHandler;
|
||||
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.commands.annotation.SlashCommand;
|
||||
import net.tomatentum.marinara.interaction.commands.annotation.SubCommand;
|
||||
@@ -24,6 +25,8 @@ import net.tomatentum.marinara.util.ReflectionUtil;
|
||||
public abstract class InteractionMethod {
|
||||
|
||||
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))
|
||||
return new SlashCommandInteractionMethod(method, handler, marinara);
|
||||
if (method.isAnnotationPresent(Button.class))
|
||||
@@ -59,7 +62,7 @@ public abstract class InteractionMethod {
|
||||
|
||||
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);
|
||||
|
||||
|
@@ -26,7 +26,7 @@ public class SlashCommandInteractionMethod extends InteractionMethod {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@@ -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.ExecutableSlashCommandDefinition;
|
||||
import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType;
|
||||
import net.tomatentum.marinara.interaction.InteractionType;
|
||||
|
||||
public abstract class LibraryWrapper {
|
||||
@@ -17,7 +16,6 @@ public abstract class LibraryWrapper {
|
||||
interactionSubscriber = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
public void handleInteraction(Object context) {
|
||||
interactionSubscriber.forEach((o) -> o.accept(context));
|
||||
}
|
||||
@@ -32,9 +30,10 @@ public abstract class LibraryWrapper {
|
||||
public abstract InteractionType getInteractionType(Object context);
|
||||
|
||||
public abstract void registerSlashCommands(SlashCommandDefinition[] defs);
|
||||
public abstract Object convertCommandOption(Object context, SlashCommandOptionType type, String optionName);
|
||||
public abstract ExecutableSlashCommandDefinition getCommandDefinition(Object context);
|
||||
|
||||
public abstract String getButtonId(Object context);
|
||||
public abstract Object getComponentContextObject(Object context, Class<?> type);
|
||||
|
||||
public abstract ContextObjectProvider getContextObjectProvider();
|
||||
|
||||
}
|
Reference in New Issue
Block a user