diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandDefinition.java b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandDefinition.java new file mode 100644 index 0000000..a8c623d --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandDefinition.java @@ -0,0 +1,73 @@ +package net.tomatentum.marinara.interaction.commands; + +public record CommandDefinition(String applicationCommand, String applicationCommandDescription, String[] subCommandGroups, String subCommand, String subCommandDescription) { + + @Override + public final boolean equals(Object o) { + if (!(o instanceof CommandDefinition)) + return false; + CommandDefinition other = (CommandDefinition) o; + return other.applicationCommand.equals(this.applicationCommand) && + other.subCommandGroups.equals(this.subCommandGroups) && + other.subCommand.equals(this.subCommand); + } + + public static class Builder { + private String applicationCommandName; + private String applicationCommandDescription; + private String[] subCommandGroupNames; + private String subCommandName; + private String subCommandDescription; + + public Builder() { + this.subCommandGroupNames = new String[0]; + } + + public CommandDefinition build() { + if (applicationCommandName == null) + throw new IllegalArgumentException("applicationCommandName cant be null"); + + return new CommandDefinition(applicationCommandName, applicationCommandDescription, subCommandGroupNames, subCommandName, subCommandDescription); + } + + public void setApplicationCommandName(String applicationCommandName) { + this.applicationCommandName = applicationCommandName; + } + + public void setApplicationCommandDescription(String applicationCommandDescription) { + this.applicationCommandDescription = applicationCommandDescription; + } + + public void setSubCommandGroupNames(String[] subCommandGroupNames) { + this.subCommandGroupNames = subCommandGroupNames; + } + + public void setSubCommandName(String subCommandName) { + this.subCommandName = subCommandName; + } + + public void setSubCommandDescription(String subCommandDescription) { + this.subCommandDescription = subCommandDescription; + } + + public String getApplicationCommandName() { + return applicationCommandName; + } + + public String getApplicationCommandDescription() { + return applicationCommandDescription; + } + + public String[] getSubCommandGroupNames() { + return subCommandGroupNames; + } + + public String getSubCommandName() { + return subCommandName; + } + + public String getSubCommandDescription() { + return subCommandDescription; + } + } +} diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/CommandInteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/CommandInteractionMethod.java new file mode 100644 index 0000000..9746b66 --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/CommandInteractionMethod.java @@ -0,0 +1,83 @@ +package net.tomatentum.marinara.interaction.methods; + +import java.lang.reflect.Method; + +import net.tomatentum.marinara.interaction.InteractionType; +import net.tomatentum.marinara.interaction.commands.CommandDefinition; +import net.tomatentum.marinara.interaction.commands.annotation.ApplicationCommand; +import net.tomatentum.marinara.interaction.commands.annotation.CommandOption; +import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; +import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; +import net.tomatentum.marinara.util.ReflectionUtil; +import net.tomatentum.marinara.handler.InteractionHandler; +import net.tomatentum.marinara.wrapper.LibraryWrapper; + +public class CommandInteractionMethod extends InteractionMethod { + + private CommandOption[] options; + + private CommandDefinition commandDefinition; + + CommandInteractionMethod(Method method, InteractionHandler handler, LibraryWrapper wrapper) { + super(method, handler, wrapper); + parseMethod(); + } + + @Override + public Object getParameter(Object context, int index) { + return wrapper.convertCommandOption(context, options[index].type(), options[index].name()); + } + + @Override + public boolean canRun(Object context) { + CommandDefinition other = wrapper.getCommandDefinition(context); + return commandDefinition.equals(other); + } + + @Override + public InteractionType getType() { + return InteractionType.COMMAND; + } + + public CommandOption[] getOptions() { + return options; + } + + public CommandDefinition getCommandDefinition() { + return commandDefinition; + } + + private void parseMethod() { + ReflectionUtil.checkValidCommandMethod(method); + parseOptions(); + + ApplicationCommand cmd = ReflectionUtil.getAnnotation(method, ApplicationCommand.class); + CommandDefinition.Builder builder = new CommandDefinition.Builder(); + builder.setApplicationCommandName(cmd.name()); + builder.setApplicationCommandDescription(cmd.description()); + + if (ReflectionUtil.isAnnotationPresent(method, SubCommandGroup.class)) { + SubCommandGroup cmdGroup = ReflectionUtil.getAnnotation(method, SubCommandGroup.class); + builder.setSubCommandGroupNames(cmdGroup.name().split(" ")); + } + + if (ReflectionUtil.isAnnotationPresent(method, SubCommand.class)) { + SubCommand subCmd = ReflectionUtil.getAnnotation(method, SubCommand.class); + builder.setSubCommandName(subCmd.name()); + builder.setSubCommandDescription(subCmd.description()); + } + + this.commandDefinition = builder.build(); + } + + private CommandOption[] parseOptions() { + if (method.isAnnotationPresent(SubCommand.class)) { + SubCommand subCmd = method.getAnnotation(SubCommand.class); + return subCmd.options(); + }else { + ApplicationCommand subCmd = method.getAnnotation(ApplicationCommand.class); + return subCmd.options(); + } + } + +} diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java new file mode 100644 index 0000000..fdd9854 --- /dev/null +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java @@ -0,0 +1,65 @@ +package net.tomatentum.marinara.interaction.methods; + +import java.lang.reflect.Method; +import java.security.InvalidParameterException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import net.tomatentum.marinara.handler.InteractionHandler; +import net.tomatentum.marinara.interaction.InteractionType; +import net.tomatentum.marinara.interaction.commands.annotation.ApplicationCommand; +import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; +import net.tomatentum.marinara.wrapper.LibraryWrapper; + +public abstract class InteractionMethod { + + public static InteractionMethod create(Method method, InteractionHandler handler, LibraryWrapper wrapper) { + if (method.isAnnotationPresent(ApplicationCommand.class) || method.isAnnotationPresent(SubCommand.class)) + return new CommandInteractionMethod(method, handler, wrapper); + + return null; + } + + protected Method method; + protected InteractionHandler handler; + protected LibraryWrapper wrapper; + + protected InteractionMethod(Method method, InteractionHandler handler, LibraryWrapper wrapper) { + if (!Arrays.asList(handler.getClass().getMethods()).contains(method)) + throw new InvalidParameterException("Method does not apply to specified handler"); + this.method = method; + this.handler = handler; + this.wrapper = wrapper; + } + + public abstract Object getParameter(Object parameter, int index); + + public abstract boolean canRun(Object context); + + public abstract InteractionType getType(); + + public void run(Object context) { + int parameterCount = method.getParameterCount(); + List parameters = new ArrayList<>(); + + for (int i = 0; i < parameterCount; i++) { + if (i == 0) { + parameters.add(context); + continue; + } + parameters.add(getParameter(context, i-1)); + } + method.setAccessible(true); + try { + method.invoke(handler, parameters); + }catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + public Method getMethod() { + return method; + } + +} diff --git a/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java b/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java index 3a9825e..d4dcea2 100644 --- a/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java +++ b/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java @@ -4,7 +4,8 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -import net.tomatentum.marinara.command.option.OptionType; +import net.tomatentum.marinara.interaction.commands.CommandDefinition; +import net.tomatentum.marinara.interaction.commands.option.OptionType; import net.tomatentum.marinara.interaction.InteractionType; public abstract class LibraryWrapper { @@ -30,7 +31,6 @@ public abstract class LibraryWrapper { } public abstract InteractionType getInteractionType(Class clazz); - public abstract OptionType getOptionType(Class clazz); - public abstract LibraryConverter getConverter(); - -} + public abstract Object convertCommandOption(Object context, OptionType type, String optionName); + public abstract CommandDefinition getCommandDefinition(Object context); +} \ No newline at end of file