diff --git a/.gitignore b/.gitignore
index d11a53b..1dffc61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ build
.vscode
lib/bin
wrapper/javacord/bin
+wrapper/discord4j/bin
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandConverter.java b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandConverter.java
index fcbfb85..cd90895 100644
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandConverter.java
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/CommandConverter.java
@@ -12,7 +12,7 @@ public class CommandConverter {
return null;
}
- public interface Spec {
+ public static interface Spec {
public A convertCommand(SlashCommandDefinition def);
public O convertSubCommand(SubCommand def, O[] options);
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/ExecutableSlashCommandDefinition.java b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/ExecutableSlashCommandDefinition.java
deleted file mode 100644
index 480d363..0000000
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/ExecutableSlashCommandDefinition.java
+++ /dev/null
@@ -1,95 +0,0 @@
-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;
-import net.tomatentum.marinara.interaction.commands.choice.EnumChoices;
-
-public record ExecutableSlashCommandDefinition(
- SlashCommand applicationCommand,
- SubCommand subCommand,
- 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))
- return false;
- ExecutableSlashCommandDefinition other = (ExecutableSlashCommandDefinition) o;
- boolean equals = false;
-
- if (this.applicationCommand() != null && other.applicationCommand() != null)
- equals = this.applicationCommand().name().equals(other.applicationCommand().name());
-
- if (this.subCommandGroup() != null && other.subCommandGroup() != null)
- equals = this.subCommandGroup().name().equals(other.subCommandGroup().name());
-
- if (this.subCommand() != null && other.subCommand() != null)
- equals = this.subCommand().name().equals(other.subCommand().name());
-
- return equals;
- }
-
- @Override
- public final String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append(applicationCommand.name());
- if (subCommandGroup != null && subCommandGroup.name() != null)
- builder.append("::").append(subCommandGroup.name());
- if (subCommand != null && subCommand.name() != null)
- builder.append("::").append(subCommand.name());
- return builder.toString();
- }
-
- public boolean isRootCommand() {
- return subCommand == null;
- }
-
- public static class Builder {
- private SlashCommand applicationCommand;
- private SubCommand subCommand;
- private SubCommandGroup subCommandGroup;
-
- public ExecutableSlashCommandDefinition build() {
- if (applicationCommand == null)
- throw new IllegalArgumentException("applicationCommandName cant be null");
-
- return new ExecutableSlashCommandDefinition(applicationCommand, subCommand, subCommandGroup, subCommand != null ? subCommand.options() : applicationCommand.options());
- }
-
- public void setApplicationCommand(SlashCommand applicationCommand) {
- this.applicationCommand = applicationCommand;
- }
-
- public void setSubCommand(SubCommand subCommand) {
- this.subCommand = subCommand;
- }
-
- public void setSubCommandGroup(SubCommandGroup subCommandGroup) {
- this.subCommandGroup = subCommandGroup;
- }
-
- public SlashCommand getApplicationCommand() {
- return applicationCommand;
- }
-
- public SubCommand getSubCommand() {
- return subCommand;
- }
-
- public SubCommandGroup getSubCommandGroup() {
- return subCommandGroup;
- }
-
- }
-}
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/SlashCommandDefinition.java b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/SlashCommandDefinition.java
index 376f7a2..1fb073d 100644
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/SlashCommandDefinition.java
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/SlashCommandDefinition.java
@@ -1,100 +1,106 @@
package net.tomatentum.marinara.interaction.commands;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
-import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
-import net.tomatentum.marinara.interaction.commands.annotation.SubCommand;
-import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup;
+import org.apache.logging.log4j.Logger;
+
+import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
+import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption.PlaceHolderEnum;
+import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice;
+import net.tomatentum.marinara.interaction.commands.choice.EnumChoices;
+import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
+import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier;
+import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
+import net.tomatentum.marinara.util.LoggerUtil;
public class SlashCommandDefinition {
- private List executableDefinitons;
- private SlashCommand slashCommand;
- private boolean isRootCommand;
- public SlashCommandDefinition(SlashCommand applicationCommand) {
- this.executableDefinitons = new ArrayList<>();
- this.slashCommand = applicationCommand;
+ 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;
}
- public SlashCommandDefinition addExecutableCommand(ExecutableSlashCommandDefinition def) {
- if (def.applicationCommand() != null) {
- if (slashCommand == null)
- this.slashCommand = def.applicationCommand();
- if (!this.slashCommand.name().equals(def.applicationCommand().name()))
- throw new IllegalArgumentException(def + ": has a non matching Application Command description. Please edit it to equal all other descriptions or remove it to use other definitions descriptions");
- }
+ private Set entries;
+ private RootCommandIdentifier rootIdentifier;
+ private boolean isRootCommand;
- if (executableDefinitons.isEmpty())
- this.isRootCommand = def.isRootCommand();
+ private Logger logger = LoggerUtil.getLogger(getClass());
- if ((isRootCommand && !def.isRootCommand()) || (!isRootCommand && def.isRootCommand())) {
- throw new IllegalArgumentException(def + ": cannot have subcommands and rootcommand definitions together");
+ public SlashCommandDefinition(RootCommandIdentifier rootIdentifier) {
+ this.entries = new HashSet<>();
+ this.rootIdentifier = rootIdentifier;
+ this.isRootCommand = false;
+ }
+
+ public SlashCommandDefinition addIdentifier(InteractionIdentifier identifier) {
+ RootCommandIdentifier rootIdentifier = (RootCommandIdentifier) identifier.rootNode();
+
+ if (!this.rootIdentifier.equals(rootIdentifier))
+ throw new IllegalArgumentException("Root Node did not match.");
+
+ if (this.rootIdentifier.description() == null)
+ this.rootIdentifier = rootIdentifier;
+
+ if (!isRootCommand)
+ this.isRootCommand = identifier.parent() == null ? true : false;
+
+ if ((isRootCommand && identifier.parent() != null) || (!isRootCommand && identifier.parent() == null)) {
+ throw new IllegalArgumentException(identifier.toString() + ": cannot have subcommands and rootcommand definitions together");
}
- executableDefinitons.add(def);
+ entries.add(identifier);
+ this.logger.debug("Added identifer {} to command {}", identifier, rootIdentifier);
return this;
}
- public SubCommandGroup[] getSubCommandGroups() {
- List subCommandGroups = Arrays.stream(getExecutableDefinitons())
- .filter((x) -> x.subCommandGroup() != null)
- .map((x) -> x.subCommandGroup())
+ public SlashCommandIdentifier[] getSubCommandGroups() {
+ if (isRootCommand)
+ return null;
+
+ List subCommandGroups = entries().stream()
+ .filter(x -> x.parent().parent() != null)
+ .map(x -> x.parent())
.toList();
- HashMap subCommandGroupMap = new HashMap<>();
- subCommandGroups.forEach((x) -> {
- SubCommandGroup current = subCommandGroupMap.get(x.name());
- if (current == null || (current.description().isBlank() && !x.description().isBlank()))
- subCommandGroupMap.put(x.name(), x);
- });
-
- return subCommandGroupMap.values().toArray(SubCommandGroup[]::new);
+ return InteractionIdentifier.distinct(subCommandGroups).toArray(SlashCommandIdentifier[]::new);
}
- public SubCommand[] getSubCommands() {
- List subCommands;
- subCommands = Arrays.stream(getExecutableDefinitons())
- .filter((x) -> x.subCommandGroup() == null && x.subCommand() != null)
- .map((x) -> x.subCommand())
- .toList();
-
-
- HashMap subCommandMap = new HashMap<>();
- subCommands.forEach((x) -> {
- SubCommand current = subCommandMap.get(x.name());
- if (current == null || (current.description().isBlank() && !x.description().isBlank()))
- subCommandMap.put(x.name(), x);
- });
-
- return subCommandMap.values().toArray(SubCommand[]::new);
+ public SlashCommandIdentifier[] getSubCommands() {
+ if (isRootCommand)
+ return null;
+ return InteractionIdentifier.distinct(entries.stream().toList()).toArray(SlashCommandIdentifier[]::new);
}
- public SubCommand[] getSubCommands(String groupName) {
- List subCommands;
- subCommands = Arrays.stream(getExecutableDefinitons())
- .filter((x) -> x.subCommandGroup().name().equals(groupName) && x.subCommand() != null)
- .map((x) -> x.subCommand())
- .toList();
-
- HashMap subCommandMap = new HashMap<>();
- subCommands.forEach((x) -> {
- SubCommand current = subCommandMap.get(x.name());
- if (current == null || (current.description().isBlank() && !x.description().isBlank()))
- subCommandMap.put(x.name(), x);
- });
+ public SlashCommandIdentifier[] getSubCommands(String groupName) {
+ if (isRootCommand)
+ return null;
- return subCommandMap.values().toArray(SubCommand[]::new);
+ List subCommands = entries().stream()
+ .filter(x -> x.parent().parent() != null && x.parent().name().equals(groupName))
+ .map(x -> x.parent().parent())
+ .toList();
+
+ return InteractionIdentifier.distinct(subCommands).toArray(SlashCommandIdentifier[]::new);
}
- public SlashCommand getSlashCommand() {
- return slashCommand;
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SlashCommandDefinition))
+ return false;
+ SlashCommandDefinition other = (SlashCommandDefinition) obj;
+ return this.rootIdentifier().equals(other.rootIdentifier());
}
- public ExecutableSlashCommandDefinition[] getExecutableDefinitons() {
- return executableDefinitons.toArray(new ExecutableSlashCommandDefinition[0]);
+ public Set entries() {
+ return this.entries;
+ }
+
+ public RootCommandIdentifier rootIdentifier() {
+ return rootIdentifier;
}
public boolean isRootCommand() {
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/ident/InteractionIdentifier.java b/lib/src/main/java/net/tomatentum/marinara/interaction/ident/InteractionIdentifier.java
new file mode 100644
index 0000000..14a6bfd
--- /dev/null
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/ident/InteractionIdentifier.java
@@ -0,0 +1,158 @@
+package net.tomatentum.marinara.interaction.ident;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+
+import net.tomatentum.marinara.interaction.InteractionType;
+
+public class InteractionIdentifier {
+
+ public static InteractionIdentifier.Builder builder() {
+ return new InteractionIdentifier.Builder();
+ }
+
+ public static RootCommandIdentifier.Builder rootBuilder() {
+ return new RootCommandIdentifier.Builder();
+ }
+
+ public static SlashCommandIdentifier.Builder slashBuilder() {
+ return new SlashCommandIdentifier.Builder();
+ }
+
+ public static InteractionIdentifier createHierarchy(InteractionType type, String... names) {
+ InteractionIdentifier last = null;
+ for (String string : names) {
+ last = builder().name(string).type(type).parent(last).build();
+ }
+ return last;
+ }
+
+ public static void tryAddDescriptions(InteractionIdentifier receiver, InteractionIdentifier provider) {
+ if (receiver == null || provider == null)
+ return;
+
+ if (receiver.description().isBlank())
+ receiver.description = provider.description();
+ tryAddDescriptions(receiver.parent(), provider.parent());
+ }
+
+ /*
+ * TODO: Might not be the best solution. Propagating to future
+ * returns only one Identifier per name and takes the first present description
+ */
+ public static Collection distinct(List identifiers) {
+ HashMap distinctIdentifiers = new HashMap<>();
+ identifiers.forEach((x) -> {
+ InteractionIdentifier current = distinctIdentifiers.get(x.name());
+ if (current == null || (current.description().isBlank() && !x.description().isBlank()))
+ distinctIdentifiers.put(x.name(), x);
+ });
+ return distinctIdentifiers.values();
+ }
+
+ private InteractionIdentifier parent;
+ private String name;
+ private String description;
+ private InteractionType type;
+
+ InteractionIdentifier(InteractionIdentifier parent, String name, String description, InteractionType type) {
+ this.parent = parent;
+ this.name = name;
+ this.description = description;
+ this.type = type;
+ }
+
+ public InteractionIdentifier rootNode() { return rootNode(this); }
+
+ private InteractionIdentifier rootNode(InteractionIdentifier identifier) {
+ if (identifier.parent() == null)
+ return identifier;
+ return rootNode(identifier.parent());
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public String description() {
+ return description;
+ }
+
+ public InteractionIdentifier parent() {
+ return parent;
+ }
+
+ public InteractionType type() {
+ return type;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof InteractionIdentifier))
+ return false;
+ InteractionIdentifier ident = (InteractionIdentifier) obj;
+ if (!type().equals(ident.type()))
+ return false;
+ if (!name().equals(ident.name()))
+ return false;
+ return Objects.equals(ident, obj);
+ }
+
+ @Override
+ public String toString() {
+ if (parent() == null)
+ return name();
+ return "{}.{}".formatted(name(), parent().toString());
+ }
+
+ public static class Builder {
+ private InteractionIdentifier parent;
+ private String name;
+ private String description;
+ private InteractionType type;
+
+ public InteractionIdentifier parent() {
+ return parent;
+ }
+
+ public Builder parent(InteractionIdentifier parent) {
+ this.parent = parent;
+ return this;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String description() {
+ return description;
+ }
+
+ public Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public InteractionType type() {
+ return type;
+ }
+
+ public Builder type(InteractionType type) {
+ this.type = type;
+ return this;
+ }
+
+ public InteractionIdentifier build() {
+ return new InteractionIdentifier(parent, name, description, type);
+ }
+
+ }
+
+}
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/ident/RootCommandIdentifier.java b/lib/src/main/java/net/tomatentum/marinara/interaction/ident/RootCommandIdentifier.java
new file mode 100644
index 0000000..d32a6a7
--- /dev/null
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/ident/RootCommandIdentifier.java
@@ -0,0 +1,93 @@
+package net.tomatentum.marinara.interaction.ident;
+
+import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
+
+public class RootCommandIdentifier extends SlashCommandIdentifier {
+
+ private long[] serverIds;
+
+ public RootCommandIdentifier(
+ InteractionIdentifier parent,
+ String name,
+ String description,
+ SlashCommandOption[] options,
+ boolean isAutocomplete,
+ long[] serverIds) {
+ super(parent, name, description, options, isAutocomplete);
+ this.serverIds = serverIds;
+ }
+
+ public long[] serverIds() {
+ return serverIds;
+ }
+
+ public static class Builder {
+ private InteractionIdentifier parent;
+ private String name;
+ private String description;
+ private SlashCommandOption[] options;
+ private boolean isAutocomplete = false;
+ private long[] serverIds;
+
+
+ public InteractionIdentifier parent() {
+ return parent;
+ }
+
+ public Builder parent(InteractionIdentifier parent) {
+ this.parent = parent;
+ return this;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String description() {
+ return this.description;
+ }
+
+ public Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public SlashCommandOption[] options() {
+ return this.options;
+ }
+
+ public Builder options(SlashCommandOption[] options) {
+ this.options = options;
+ return this;
+ }
+
+ public boolean autocomplete() {
+ return this.isAutocomplete;
+ }
+
+ public Builder autocomplete(boolean isAutocomplete) {
+ this.isAutocomplete = isAutocomplete;
+ return this;
+ }
+
+ public long[] serverIds() {
+ return this.serverIds;
+ }
+
+ public Builder serverIds(long[] serverIds) {
+ this.serverIds = serverIds;
+ return this;
+ }
+
+ public SlashCommandIdentifier build() {
+ return new RootCommandIdentifier(parent, name, description, options, isAutocomplete, serverIds);
+ }
+
+ }
+
+}
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/ident/SlashCommandIdentifier.java b/lib/src/main/java/net/tomatentum/marinara/interaction/ident/SlashCommandIdentifier.java
new file mode 100644
index 0000000..8ecad75
--- /dev/null
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/ident/SlashCommandIdentifier.java
@@ -0,0 +1,83 @@
+package net.tomatentum.marinara.interaction.ident;
+
+import net.tomatentum.marinara.interaction.InteractionType;
+import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
+
+public class SlashCommandIdentifier extends InteractionIdentifier {
+
+ private SlashCommandOption[] options;
+
+ protected SlashCommandIdentifier(
+ InteractionIdentifier parent,
+ String name,
+ String description,
+ SlashCommandOption[] options,
+ boolean isAutocomplete
+ ) {
+ super(parent, name, description, isAutocomplete ? InteractionType.AUTOCOMPLETE : InteractionType.COMMAND);
+ this.options = options;
+ }
+
+ public SlashCommandOption[] options() {
+ return this.options;
+ }
+
+ public static class Builder {
+ private InteractionIdentifier parent;
+ private String name;
+ private String description;
+ private SlashCommandOption[] options;
+ private boolean isAutocomplete = false;
+
+ public InteractionIdentifier parent() {
+ return parent;
+ }
+
+ public Builder parent(InteractionIdentifier parent) {
+ this.parent = parent;
+ return this;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String description() {
+ return this.description;
+ }
+
+ public Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public SlashCommandOption[] options() {
+ return this.options;
+ }
+
+ public Builder options(SlashCommandOption[] options) {
+ this.options = options;
+ return this;
+ }
+
+ public boolean autocomplete() {
+ return this.isAutocomplete;
+ }
+
+ public Builder autocomplete(boolean isAutocomplete) {
+ this.isAutocomplete = isAutocomplete;
+ return this;
+ }
+
+ public SlashCommandIdentifier build() {
+ return new SlashCommandIdentifier(parent, name, description, options, isAutocomplete);
+ }
+
+ }
+
+}
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/AutoCompleteInteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/AutoCompleteInteractionMethod.java
index ffed507..fc08e4d 100644
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/AutoCompleteInteractionMethod.java
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/AutoCompleteInteractionMethod.java
@@ -4,14 +4,13 @@ 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.interaction.ident.InteractionIdentifier;
import net.tomatentum.marinara.parser.AnnotationParser;
import net.tomatentum.marinara.parser.SlashCommandParser;
public class AutoCompleteInteractionMethod extends InteractionMethod {
- private ExecutableSlashCommandDefinition commandDefinition;
+ private InteractionIdentifier interactionIdentifier;
public AutoCompleteInteractionMethod(Method method,
InteractionHandler handler,
@@ -21,15 +20,15 @@ public class AutoCompleteInteractionMethod extends InteractionMethod {
}
@Override
- public AnnotationParser[] getParsers() {
+ public AnnotationParser[] parsers() {
return new AnnotationParser[] {
- new SlashCommandParser(method, (x) -> { this.commandDefinition = x; } )
+ new SlashCommandParser(method, true, (x) -> { this.interactionIdentifier = x; } )
};
}
@Override
public Object getParameter(Object context, int index) {
- Class> type = getMethod().getParameterTypes()[index+1];
+ Class> type = method().getParameterTypes()[index+1];
Object autocompleteOptionValue = marinara.getWrapper().getContextObjectProvider().getAutocompleteFocusedOption(context);
if (autocompleteOptionValue != null)
return autocompleteOptionValue;
@@ -38,14 +37,8 @@ public class AutoCompleteInteractionMethod extends InteractionMethod {
}
@Override
- public boolean canRun(Object context) {
- ExecutableSlashCommandDefinition other = marinara.getWrapper().getCommandDefinition(context);
- return commandDefinition.equals(other);
- }
-
- @Override
- public InteractionType getType() {
- return InteractionType.AUTOCOMPLETE;
+ public InteractionIdentifier identifier() {
+ return interactionIdentifier;
}
}
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java
index fe039ac..ec011a4 100644
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/ButtonInteractionMethod.java
@@ -5,6 +5,7 @@ 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.ident.InteractionIdentifier;
import net.tomatentum.marinara.parser.AnnotationParser;
import net.tomatentum.marinara.parser.ButtonParser;
@@ -17,7 +18,7 @@ public class ButtonInteractionMethod extends InteractionMethod {
}
@Override
- public AnnotationParser[] getParsers() {
+ public AnnotationParser[] parsers() {
return new AnnotationParser[] {
new ButtonParser(method, (x) -> { this.customId = x; } )
};
@@ -25,18 +26,17 @@ public class ButtonInteractionMethod extends InteractionMethod {
@Override
public Object getParameter(Object context, int index) {
- Class> type = getMethod().getParameterTypes()[index+1];
+ Class> type = method().getParameterTypes()[index+1];
return marinara.getWrapper().getContextObjectProvider().getComponentContextObject(context, type);
}
@Override
- public boolean canRun(Object context) {
- return marinara.getWrapper().getButtonId(context).equals(customId);
+ public InteractionIdentifier identifier() {
+ return InteractionIdentifier.builder()
+ .name(customId)
+ .description("Button")
+ .type(InteractionType.BUTTON)
+ .build();
}
- @Override
- public InteractionType getType() {
- return InteractionType.BUTTON;
- }
-
}
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
index ddc3618..09d7c61 100644
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java
@@ -12,11 +12,11 @@ import org.apache.logging.log4j.Logger;
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;
+import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
import net.tomatentum.marinara.parser.AnnotationParser;
import net.tomatentum.marinara.parser.InteractionCheckParser;
import net.tomatentum.marinara.util.LoggerUtil;
@@ -42,7 +42,8 @@ public abstract class InteractionMethod {
private Logger logger = LoggerUtil.getLogger(getClass());
- protected InteractionMethod(Method method,
+ protected InteractionMethod(
+ Method method,
InteractionHandler handler,
Marinara marinara
) {
@@ -52,7 +53,7 @@ public abstract class InteractionMethod {
this.method = method;
this.handler = handler;
this.marinara = marinara;
- this.parsers = new ArrayList<>(Arrays.asList(getParsers()));
+ this.parsers = new ArrayList<>(Arrays.asList(parsers()));
this.appliedChecks = new ArrayList<>();
parsers.add(new InteractionCheckParser(method, appliedChecks::add, marinara.getCheckRegistry()));
@@ -60,14 +61,6 @@ public abstract class InteractionMethod {
parsers.stream().forEach(AnnotationParser::parse);
}
- public abstract AnnotationParser[] getParsers();
-
- public abstract Object getParameter(Object context, int index);
-
- public abstract boolean canRun(Object context);
-
- public abstract InteractionType getType();
-
public void run(Object context) {
if (this.appliedChecks.stream().filter(x -> !x.pre(context)).count() > 0)
return;
@@ -82,7 +75,13 @@ public abstract class InteractionMethod {
this.appliedChecks.forEach(x -> x.post(context));
}
- public Method getMethod() {
+ public abstract AnnotationParser[] parsers();
+
+ public abstract Object getParameter(Object context, int index);
+
+ public abstract InteractionIdentifier identifier();
+
+ public Method method() {
return method;
}
diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java
index 2f5faf4..d89d709 100644
--- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java
+++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/SlashCommandInteractionMethod.java
@@ -4,48 +4,34 @@ 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.interaction.ident.InteractionIdentifier;
+import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.parser.AnnotationParser;
import net.tomatentum.marinara.parser.SlashCommandParser;
public class SlashCommandInteractionMethod extends InteractionMethod {
- private ExecutableSlashCommandDefinition commandDefinition;
+ private SlashCommandIdentifier interactionIdentifier;
SlashCommandInteractionMethod(Method method, InteractionHandler handler, Marinara marinara) {
super(method, handler, marinara);
}
@Override
- public AnnotationParser[] getParsers() {
+ public AnnotationParser[] parsers() {
return new AnnotationParser[] {
- new SlashCommandParser(method, (x) -> { this.commandDefinition = x; } )
+ new SlashCommandParser(method, false, (x) -> { this.interactionIdentifier = x; } )
};
}
@Override
public Object getParameter(Object context, int index) {
- return marinara.getWrapper().getContextObjectProvider().convertCommandOption(context, commandDefinition.options()[index].name());
+ return marinara.getWrapper().getContextObjectProvider().convertCommandOption(context, interactionIdentifier.options()[index].name());
}
@Override
- public boolean canRun(Object context) {
- ExecutableSlashCommandDefinition other = marinara.getWrapper().getCommandDefinition(context);
- return commandDefinition.equals(other);
- }
-
- @Override
- public InteractionType getType() {
- return InteractionType.COMMAND;
- }
-
- public ExecutableSlashCommandDefinition getCommandDefinition() {
- return commandDefinition;
- }
-
- public void setCommandDefinition(ExecutableSlashCommandDefinition commandDefinition) {
- this.commandDefinition = commandDefinition;
+ public InteractionIdentifier identifier() {
+ return interactionIdentifier;
}
}
diff --git a/lib/src/main/java/net/tomatentum/marinara/parser/SlashCommandParser.java b/lib/src/main/java/net/tomatentum/marinara/parser/SlashCommandParser.java
index cf2a244..0cd7072 100644
--- a/lib/src/main/java/net/tomatentum/marinara/parser/SlashCommandParser.java
+++ b/lib/src/main/java/net/tomatentum/marinara/parser/SlashCommandParser.java
@@ -5,22 +5,26 @@ import java.util.function.Consumer;
import org.apache.logging.log4j.Logger;
-import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition;
+import net.tomatentum.marinara.interaction.InteractionType;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
import net.tomatentum.marinara.interaction.commands.annotation.SubCommand;
import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup;
+import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
+import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.util.ReflectionUtil;
public class SlashCommandParser implements AnnotationParser {
private Method method;
- private Consumer consumer;
+ private boolean isAutoComplete;
+ private Consumer consumer;
private Logger logger = LoggerUtil.getLogger(getClass());
- public SlashCommandParser(Method method, Consumer consumer) {
+ public SlashCommandParser(Method method, boolean isAutoComplete, Consumer consumer) {
this.method = method;
+ this.isAutoComplete = isAutoComplete;
this.consumer = consumer;
}
@@ -29,23 +33,36 @@ public class SlashCommandParser implements AnnotationParser {
this.checkValidCommandMethod(method);
SlashCommand cmd = ReflectionUtil.getAnnotation(method, SlashCommand.class);
- ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder();
- builder.setApplicationCommand(cmd);
+ InteractionIdentifier lastIdentifier = InteractionIdentifier.rootBuilder()
+ .name(cmd.name())
+ .description(cmd.description())
+ .options(cmd.options())
+ .autocomplete(isAutoComplete)
+ .serverIds(cmd.serverIds())
+ .build();
if (ReflectionUtil.isAnnotationPresent(method, SubCommandGroup.class)) {
SubCommandGroup cmdGroup = ReflectionUtil.getAnnotation(method, SubCommandGroup.class);
- builder.setSubCommandGroup(cmdGroup);
+ lastIdentifier = InteractionIdentifier.builder()
+ .name(cmdGroup.name())
+ .description(cmdGroup.description())
+ .type(isAutoComplete ? InteractionType.AUTOCOMPLETE : InteractionType.COMMAND)
+ .parent(lastIdentifier)
+ .build();
}
if (ReflectionUtil.isAnnotationPresent(method, SubCommand.class)) {
SubCommand subCmd = ReflectionUtil.getAnnotation(method, SubCommand.class);
- builder.setSubCommand(subCmd);
+ lastIdentifier = InteractionIdentifier.slashBuilder()
+ .name(subCmd.name())
+ .description(subCmd.description())
+ .options(subCmd.options())
+ .autocomplete(isAutoComplete)
+ .build();
}
- ExecutableSlashCommandDefinition def = builder.build();
-
- logger.trace("Parsed using SlashCommandParser for method {} with the result:\n{}", ReflectionUtil.getFullMethodName(method), def.toString());
- consumer.accept(builder.build());
+ logger.trace("Parsed using SlashCommandParser for method {} with the result:\n{}", ReflectionUtil.getFullMethodName(method), lastIdentifier.toString());
+ consumer.accept((SlashCommandIdentifier) lastIdentifier);
}
@Override
diff --git a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionEntry.java b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionEntry.java
new file mode 100644
index 0000000..6e2735b
--- /dev/null
+++ b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionEntry.java
@@ -0,0 +1,65 @@
+package net.tomatentum.marinara.registry;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import net.tomatentum.marinara.interaction.InteractionType;
+import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
+import net.tomatentum.marinara.interaction.methods.InteractionMethod;
+import net.tomatentum.marinara.util.LoggerUtil;
+
+public class InteractionEntry {
+ private InteractionIdentifier identifier;
+ private Set methods;
+
+ private Logger logger = LoggerUtil.getLogger(getClass());
+
+ public InteractionEntry(InteractionIdentifier identifier) {
+ this.identifier = identifier;
+ this.methods = new HashSet<>();
+ }
+
+ public InteractionEntry addMethod(InteractionMethod method) {
+ if (!method.identifier().equals(this.identifier))
+ throw new IllegalArgumentException("Method's identifier did not match the entry's identifier");
+
+ this.methods.add(method);
+ InteractionIdentifier.tryAddDescriptions(identifier, method.identifier());
+ return this;
+ }
+
+ public void runAll(Object context) {
+ this.methods.stream().forEach(x -> {
+ logger.debug("Running Method {} from {} with context {}", x.toString(), this.toString(), context.toString());
+ x.run(context);
+ });
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof InteractionEntry))
+ return false;
+ InteractionEntry other = (InteractionEntry) obj;
+ return other.identifier().equals(identifier());
+ }
+
+ @Override
+ public String toString() {
+ return "InteractionEntry(%s)".formatted(identifier().toString());
+ }
+
+ public InteractionType type() {
+ return identifier().type();
+ }
+
+ public InteractionIdentifier identifier() {
+ return identifier;
+ }
+
+ public Set methods() {
+ return methods;
+ }
+
+}
diff --git a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java
index 27a2152..59d01b7 100644
--- a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java
+++ b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java
@@ -2,8 +2,10 @@ package net.tomatentum.marinara.registry;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
import org.apache.logging.log4j.Logger;
@@ -11,28 +13,36 @@ import net.tomatentum.marinara.Marinara;
import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.InteractionType;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
-import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition;
-import net.tomatentum.marinara.interaction.methods.SlashCommandInteractionMethod;
+import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier;
+import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.util.LoggerUtil;
+import net.tomatentum.marinara.wrapper.LibraryWrapper;
import net.tomatentum.marinara.interaction.methods.InteractionMethod;
public class InteractionRegistry {
private Logger logger = LoggerUtil.getLogger(getClass());
- private List interactionMethods;
+ private Set interactions;
private Marinara marinara;
public InteractionRegistry(Marinara marinara) {
- this.interactionMethods = new ArrayList<>();
+ this.interactions = new HashSet<>();
this.marinara = marinara;
marinara.getWrapper().subscribeInteractions(this::handle);
}
+ /*
+ * TODO: Maybe relocate InteractionEntry checking to another class with description merging.
+ */
public void addInteractions(InteractionHandler interactionHandler) {
for (Method method : interactionHandler.getClass().getMethods()) {
InteractionMethod iMethod = InteractionMethod.create(method, interactionHandler, marinara);
if (iMethod != null) {
- this.interactionMethods.add(iMethod);
- logger.debug("Added {} method from {}", iMethod.getMethod().getName(), interactionHandler.getClass().getSimpleName());
+ Optional entry = this.interactions.stream().filter(iMethod::equals).findFirst();
+ if (entry.isEmpty()) {
+ interactions.add(new InteractionEntry(iMethod.identifier()).addMethod(iMethod));
+ }else
+ entry.get().addMethod(iMethod);
+ logger.debug("Added {} method from {}", iMethod.method().getName(), interactionHandler.getClass().getSimpleName());
}
}
logger.info("Added all Interactions from {}", interactionHandler.getClass().getSimpleName());
@@ -40,25 +50,22 @@ public class InteractionRegistry {
public void registerCommands() {
List defs = new ArrayList<>();
- List execDefs = interactionMethods.stream()
- .filter((x) -> x.getClass().isAssignableFrom(SlashCommandInteractionMethod.class))
- .map((x) -> ((SlashCommandInteractionMethod)x).getCommandDefinition())
+ List slashIdentifiers = interactions.stream()
+ .filter((x) -> x.type().equals(InteractionType.COMMAND))
+ .map((x) -> (SlashCommandIdentifier)x.identifier())
.toList();
- execDefs.forEach((def) -> {
+ slashIdentifiers.forEach((ident) -> {
Optional appDef = defs.stream()
- .filter((x) -> x.getSlashCommand().equals(def.applicationCommand()))
+ .filter((x) -> x.rootIdentifier().equals(ident.rootNode()))
.findFirst();
- if (appDef.isPresent())
- appDef.get().addExecutableCommand(def);
- else
- defs.add(new SlashCommandDefinition(def.applicationCommand()).addExecutableCommand(def));
- logger.debug("Added Executable Command {}{}{} for registration",
- def.applicationCommand().name(),
- def.subCommandGroup() == null ? "" : "." + def.subCommandGroup().name(),
- def.subCommand() == null ? "" : "." + def.subCommand().name()
- );
+ if (appDef.isPresent())
+ appDef.get().addIdentifier(ident);
+ else
+ defs.add(
+ new SlashCommandDefinition((RootCommandIdentifier) ident.rootNode())
+ .addIdentifier(ident));
});
marinara.getWrapper().registerSlashCommands(defs.toArray(SlashCommandDefinition[]::new));
@@ -66,12 +73,12 @@ public class InteractionRegistry {
}
public void handle(Object context) {
- InteractionType type = marinara.getWrapper().getInteractionType(context);
logger.debug("Received {} interaction ", context);
- interactionMethods.forEach((m) -> {
- if (m.getType().equals(type) && m.canRun(context)) {
- logger.info("Running {} interaction using {}\ncontext: {}", type, m.getMethod().toString(), context.toString());
- m.run(context);
+ LibraryWrapper wrapper = marinara.getWrapper();
+ interactions.forEach((e) -> {
+ if (wrapper.getInteractionIdentifier(context).equals(e.identifier())) {
+ logger.info("Running {} interaction using {}\ncontext: {}", e.type(), e.toString(), context.toString());
+ e.runAll(context);
}
});
}
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 7bf932a..0a4ede7 100644
--- a/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java
+++ b/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java
@@ -5,8 +5,7 @@ import java.util.List;
import java.util.function.Consumer;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
-import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition;
-import net.tomatentum.marinara.interaction.InteractionType;
+import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
public abstract class LibraryWrapper {
@@ -27,12 +26,8 @@ public abstract class LibraryWrapper {
interactionSubscriber.remove(consumer);
}
- public abstract InteractionType getInteractionType(Object context);
-
public abstract void registerSlashCommands(SlashCommandDefinition[] defs);
- public abstract ExecutableSlashCommandDefinition getCommandDefinition(Object context);
-
- public abstract String getButtonId(Object context);
+ public abstract InteractionIdentifier getInteractionIdentifier(Object context);
public abstract ContextObjectProvider getContextObjectProvider();
diff --git a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java
index b5f7f73..7c046b3 100644
--- a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java
+++ b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java
@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.function.Function;
import org.apache.logging.log4j.Logger;
@@ -20,16 +19,13 @@ import discord4j.discordjson.json.ApplicationCommandOptionChoiceData;
import discord4j.discordjson.json.ApplicationCommandOptionData;
import discord4j.discordjson.json.ApplicationCommandRequest;
-import io.leangen.geantyref.AnnotationFormatException;
-import io.leangen.geantyref.TypeFactory;
import net.tomatentum.marinara.interaction.InteractionType;
-import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
-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.ident.InteractionIdentifier;
+import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier;
+import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.wrapper.ContextObjectProvider;
import net.tomatentum.marinara.wrapper.LibraryWrapper;
@@ -63,18 +59,6 @@ public class Discord4JWrapper extends LibraryWrapper {
logger.info("Discord4J wrapper loaded!");
}
- @Override
- public InteractionType getInteractionType(Object context) {
- if (ChatInputAutoCompleteEvent.class.isAssignableFrom(context.getClass()))
- return InteractionType.AUTOCOMPLETE;
- if (ChatInputInteractionEvent.class.isAssignableFrom(context.getClass()))
- return InteractionType.COMMAND;
- if (ButtonInteractionEvent.class.isAssignableFrom(context.getClass()))
- return InteractionType.BUTTON;
-
- return null;
- }
-
@Override
public void registerSlashCommands(SlashCommandDefinition[] defs) {
HashMap> serverCommands = new HashMap<>();
@@ -83,8 +67,8 @@ public class Discord4JWrapper extends LibraryWrapper {
for (SlashCommandDefinition slashCommandDefinition : defs) {
ApplicationCommandRequest request = convertSlashCommand(slashCommandDefinition);
- if (slashCommandDefinition.getSlashCommand().serverIds().length > 0) {
- for (long serverId : slashCommandDefinition.getSlashCommand().serverIds()) {
+ if (slashCommandDefinition.rootIdentifier().serverIds().length > 0) {
+ for (long serverId : slashCommandDefinition.rootIdentifier().serverIds()) {
serverCommands.putIfAbsent(serverId, new ArrayList<>());
serverCommands.get(serverId).add(request);
}
@@ -99,9 +83,16 @@ public class Discord4JWrapper extends LibraryWrapper {
}
@Override
- public ExecutableSlashCommandDefinition getCommandDefinition(Object context) {
+ public InteractionIdentifier getInteractionIdentifier(Object context) {
+
+ if (context instanceof ButtonInteractionEvent) {
+ ButtonInteractionEvent interaction = (ButtonInteractionEvent) context;
+ return InteractionIdentifier.builder().name(interaction.getCustomId()).type(InteractionType.BUTTON).build();
+ }
+
List options;
String commandName;
+ boolean isAutocomplete = false;
if (context instanceof ChatInputInteractionEvent) {
ChatInputInteractionEvent interaction = (ChatInputInteractionEvent) context;
@@ -111,30 +102,35 @@ public class Discord4JWrapper extends LibraryWrapper {
ChatInputAutoCompleteEvent interaction = (ChatInputAutoCompleteEvent) context;
options = SUB_FILTER.apply(interaction.getOptions());
commandName = interaction.getCommandName();
+ isAutocomplete = true;
}else
return null;
- ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder();
+ InteractionIdentifier last = InteractionIdentifier.slashBuilder().name(commandName).autocomplete(isAutocomplete).build();
- try {
- builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", commandName)));
- if (!options.isEmpty()) {
- if (!ARG_FILTER.apply(options.getFirst().getOptions()).isEmpty()) {
- builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName())));
- builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", SUB_FILTER.apply(options.getFirst().getOptions()).getFirst().getName())));
- }else
- builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", options.getFirst().getName())));
- }
- } catch (AnnotationFormatException e) {
- logger.fatal(e);
+ if (!options.isEmpty()) {
+ List sub_options = SUB_FILTER.apply(options.getFirst().getOptions());
+ if (!sub_options.isEmpty()) {
+ last = InteractionIdentifier.builder()
+ .name(options.getFirst().getName())
+ .type(isAutocomplete ? InteractionType.AUTOCOMPLETE : InteractionType.COMMAND)
+ .parent(last).build();
+ last = InteractionIdentifier.slashBuilder()
+ .name(sub_options.getFirst().getName())
+ .autocomplete(isAutocomplete)
+ .parent(last).build();
+ }else
+ last = InteractionIdentifier.slashBuilder()
+ .name(options.getFirst().getName())
+ .autocomplete(isAutocomplete)
+ .parent(last).build();
}
-
- return builder.build();
+ return last;
}
private ApplicationCommandRequest convertSlashCommand(SlashCommandDefinition def) {
List options = new ArrayList<>();
- SlashCommand cmd = def.getSlashCommand();
+ RootCommandIdentifier cmd = def.rootIdentifier();
if (!def.isRootCommand()) {
Arrays.stream(def.getSubCommands(null)).map(this::convertSubCommandDef).forEach(options::add);
Arrays.stream(def.getSubCommandGroups()).map((x) -> convertSubCommandGroupDef(def, x)).forEach(options::add);
@@ -149,8 +145,8 @@ public class Discord4JWrapper extends LibraryWrapper {
.build();
}
- private ApplicationCommandOptionData convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) {
- SubCommand[] subCommands = def.getSubCommands(subGroup.name());
+ private ApplicationCommandOptionData convertSubCommandGroupDef(SlashCommandDefinition def, SlashCommandIdentifier subGroup) {
+ SlashCommandIdentifier[] subCommands = def.getSubCommands(subGroup.name());
List convertedSubCommands = Arrays.stream(subCommands).map(this::convertSubCommandDef).toList();
return ApplicationCommandOptionData.builder()
.type(Type.SUB_COMMAND_GROUP.getValue())
@@ -160,7 +156,7 @@ public class Discord4JWrapper extends LibraryWrapper {
.build();
}
- private ApplicationCommandOptionData convertSubCommandDef(SubCommand sub) {
+ private ApplicationCommandOptionData convertSubCommandDef(SlashCommandIdentifier sub) {
List convertedOptions = Arrays.stream(sub.options()).map(this::convertOptionDef).toList();
return ApplicationCommandOptionData.builder()
.type(Type.SUB_COMMAND_GROUP.getValue())
@@ -184,7 +180,7 @@ public class Discord4JWrapper extends LibraryWrapper {
private List convertChoices(SlashCommandOption option) {
List convertedChoices = new ArrayList<>();
- for (SlashCommandOptionChoice choice : ExecutableSlashCommandDefinition.getActualChoices(option)) {
+ for (SlashCommandOptionChoice choice : SlashCommandDefinition.getActualChoices(option)) {
var builder = ApplicationCommandOptionChoiceData.builder();
builder.name(choice.name());
if (choice.longValue() != Long.MAX_VALUE)
@@ -198,12 +194,6 @@ public class Discord4JWrapper extends LibraryWrapper {
return convertedChoices;
}
- @Override
- public String getButtonId(Object context) {
- ButtonInteractionEvent button = (ButtonInteractionEvent) context;
- return button.getCustomId();
- }
-
@Override
public ContextObjectProvider getContextObjectProvider() {
return this.contextObjectProvider;
diff --git a/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java b/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java
index 38d0d55..6c1932d 100644
--- a/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java
+++ b/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java
@@ -5,12 +5,10 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import org.javacord.api.DiscordApi;
-import org.javacord.api.interaction.ApplicationCommandInteraction;
import org.javacord.api.interaction.AutocompleteInteraction;
import org.javacord.api.interaction.ButtonInteraction;
import org.javacord.api.interaction.SlashCommandBuilder;
@@ -20,16 +18,13 @@ 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.TypeFactory;
import net.tomatentum.marinara.interaction.InteractionType;
-import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
-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.ident.InteractionIdentifier;
+import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier;
+import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.wrapper.ContextObjectProvider;
import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.wrapper.LibraryWrapper;
@@ -51,25 +46,14 @@ public class JavacordWrapper extends LibraryWrapper {
logger.info("Javacord wrapper loaded!");
}
- @Override
- public InteractionType getInteractionType(Object context) {
- if (AutocompleteInteraction.class.isAssignableFrom(context.getClass()))
- return InteractionType.AUTOCOMPLETE;
- if (ApplicationCommandInteraction.class.isAssignableFrom(context.getClass()))
- return InteractionType.COMMAND;
- if (ButtonInteraction.class.isAssignableFrom(context.getClass()))
- return InteractionType.BUTTON;
- return null;
- }
-
@Override
public void registerSlashCommands(SlashCommandDefinition[] defs) {
HashMap> serverCommands = new HashMap<>();
Set globalCommands = new HashSet<>();
for (SlashCommandDefinition slashCommandDefinition : defs) {
SlashCommandBuilder builder = convertSlashCommand(slashCommandDefinition);
- if (slashCommandDefinition.getSlashCommand().serverIds().length > 0) {
- for (long serverId : slashCommandDefinition.getSlashCommand().serverIds()) {
+ if (slashCommandDefinition.rootIdentifier().serverIds().length > 0) {
+ for (long serverId : slashCommandDefinition.rootIdentifier().serverIds()) {
serverCommands.putIfAbsent(serverId, new HashSet<>());
serverCommands.get(serverId).add(builder);
}
@@ -84,32 +68,52 @@ public class JavacordWrapper extends LibraryWrapper {
}
@Override
- public ExecutableSlashCommandDefinition getCommandDefinition(Object context) {
+ public InteractionIdentifier getInteractionIdentifier(Object context) {
+ if (context instanceof ButtonInteraction) {
+ ButtonInteraction button = (ButtonInteraction) context;
+ return InteractionIdentifier.builder().name(button.getCustomId()).type(InteractionType.BUTTON).build();
+ }
+
if (!(context instanceof SlashCommandInteraction))
return null;
+ boolean isAutocomplete = false;
+
+ if (context instanceof AutocompleteInteraction)
+ isAutocomplete = true;
+
SlashCommandInteraction interaction = (SlashCommandInteraction) context;
- ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder();
+ InteractionIdentifier lastIdentifier = InteractionIdentifier.rootBuilder()
+ .name(interaction.getCommandName())
+ .autocomplete(isAutocomplete)
+ .build();
List options = interaction.getOptions();
- try {
- builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", interaction.getCommandName())));
- if (!options.isEmpty()) {
- if (!options.getFirst().getArguments().isEmpty()) {
- builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName())));
- builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", options.getFirst().getOptions().getFirst().getName())));
- }else
- builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", options.getFirst().getName())));
- }
- } catch (AnnotationFormatException e) {
- logger.fatal(e);
+ if (!options.isEmpty()) {
+ if (!options.getFirst().getArguments().isEmpty()) {
+ lastIdentifier = InteractionIdentifier.builder()
+ .name(options.getFirst().getName())
+ .type(isAutocomplete ? InteractionType.AUTOCOMPLETE : InteractionType.COMMAND)
+ .parent(lastIdentifier)
+ .build();
+ lastIdentifier = InteractionIdentifier.slashBuilder()
+ .name(options.getFirst().getOptions().getFirst().getName())
+ .autocomplete(isAutocomplete)
+ .parent(lastIdentifier)
+ .build();
+ }else
+ lastIdentifier = InteractionIdentifier.slashBuilder()
+ .name(options.getFirst().getName())
+ .autocomplete(isAutocomplete)
+ .parent(lastIdentifier)
+ .build();
}
- return builder.build();
+ return lastIdentifier;
}
private SlashCommandBuilder convertSlashCommand(SlashCommandDefinition def) {
List options = new ArrayList<>();
- SlashCommand cmd = def.getSlashCommand();
+ RootCommandIdentifier cmd = def.rootIdentifier();
if (!def.isRootCommand()) {
Arrays.stream(def.getSubCommands(null)).map(this::convertSubCommandDef).forEach(options::add);
Arrays.stream(def.getSubCommandGroups()).map((x) -> convertSubCommandGroupDef(def, x)).forEach(options::add);
@@ -120,8 +124,8 @@ public class JavacordWrapper extends LibraryWrapper {
return org.javacord.api.interaction.SlashCommand.with(cmd.name(), cmd.description(), options);
}
- private org.javacord.api.interaction.SlashCommandOption convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) {
- SubCommand[] subCommands = def.getSubCommands(subGroup.name());
+ private org.javacord.api.interaction.SlashCommandOption convertSubCommandGroupDef(SlashCommandDefinition def, SlashCommandIdentifier subGroup) {
+ SlashCommandIdentifier[] subCommands = def.getSubCommands(subGroup.name());
List convertedSubCommands = Arrays.stream(subCommands).map(this::convertSubCommandDef).toList();
return org.javacord.api.interaction.SlashCommandOption.createWithOptions(
org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND_GROUP,
@@ -130,7 +134,7 @@ public class JavacordWrapper extends LibraryWrapper {
convertedSubCommands);
}
- private org.javacord.api.interaction.SlashCommandOption convertSubCommandDef(SubCommand sub) {
+ private org.javacord.api.interaction.SlashCommandOption convertSubCommandDef(SlashCommandIdentifier sub) {
List convertedOptions = Arrays.stream(sub.options()).map(this::convertOptionDef).toList();
return org.javacord.api.interaction.SlashCommandOption.createWithOptions(
org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND,
@@ -155,7 +159,7 @@ public class JavacordWrapper extends LibraryWrapper {
private List convertChoices(SlashCommandOption option) {
List convertedChoices = new ArrayList<>();
- for (SlashCommandOptionChoice choice : ExecutableSlashCommandDefinition.getActualChoices(option)) {
+ for (SlashCommandOptionChoice choice : SlashCommandDefinition.getActualChoices(option)) {
SlashCommandOptionChoiceBuilder builder = new SlashCommandOptionChoiceBuilder();
builder.setName(choice.name());
if (choice.longValue() != Long.MAX_VALUE)
@@ -172,12 +176,6 @@ public class JavacordWrapper extends LibraryWrapper {
return convertedChoices;
}
- @Override
- public String getButtonId(Object context) {
- ButtonInteraction button = (ButtonInteraction) context;
- return button.getCustomId();
- }
-
@Override
public ContextObjectProvider getContextObjectProvider() {
return contextObjectProvider;