replace ExecutableCommandDefinition with InteractionIdentifiers
All checks were successful
github-mirror / push-github (push) Successful in 4s
Build / Gradle-Build (push) Successful in 42s
Test / Gradle-Test (push) Successful in 45s

This commit is contained in:
tueem 2025-03-03 12:38:48 +01:00
parent 76d7e9ef4f
commit 91b1df8d5b
Signed by: tueem
GPG Key ID: 65C8667EC17A88FB
17 changed files with 655 additions and 359 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ build
.vscode
lib/bin
wrapper/javacord/bin
wrapper/discord4j/bin

View File

@ -12,7 +12,7 @@ public class CommandConverter<A extends Object> {
return null;
}
public interface Spec<A extends Object, O extends Object, C extends Object> {
public static interface Spec<A extends Object, O extends Object, C extends Object> {
public A convertCommand(SlashCommandDefinition def);
public O convertSubCommand(SubCommand def, O[] options);

View File

@ -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;
}
}
}

View File

@ -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<ExecutableSlashCommandDefinition> 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<InteractionIdentifier> 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<SubCommandGroup> subCommandGroups = Arrays.stream(getExecutableDefinitons())
.filter((x) -> x.subCommandGroup() != null)
.map((x) -> x.subCommandGroup())
public SlashCommandIdentifier[] getSubCommandGroups() {
if (isRootCommand)
return null;
List<InteractionIdentifier> subCommandGroups = entries().stream()
.filter(x -> x.parent().parent() != null)
.map(x -> x.parent())
.toList();
HashMap<String, SubCommandGroup> 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<SubCommand> subCommands;
subCommands = Arrays.stream(getExecutableDefinitons())
.filter((x) -> x.subCommandGroup() == null && x.subCommand() != null)
.map((x) -> x.subCommand())
.toList();
HashMap<String, SubCommand> 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<SubCommand> subCommands;
subCommands = Arrays.stream(getExecutableDefinitons())
.filter((x) -> x.subCommandGroup().name().equals(groupName) && x.subCommand() != null)
.map((x) -> x.subCommand())
.toList();
HashMap<String, SubCommand> 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<InteractionIdentifier> 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<InteractionIdentifier> entries() {
return this.entries;
}
public RootCommandIdentifier rootIdentifier() {
return rootIdentifier;
}
public boolean isRootCommand() {

View File

@ -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<InteractionIdentifier> distinct(List<InteractionIdentifier> identifiers) {
HashMap<String, InteractionIdentifier> 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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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<ExecutableSlashCommandDefinition> consumer;
private boolean isAutoComplete;
private Consumer<SlashCommandIdentifier> consumer;
private Logger logger = LoggerUtil.getLogger(getClass());
public SlashCommandParser(Method method, Consumer<ExecutableSlashCommandDefinition> consumer) {
public SlashCommandParser(Method method, boolean isAutoComplete, Consumer<SlashCommandIdentifier> 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

View File

@ -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<InteractionMethod> 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<InteractionMethod> methods() {
return methods;
}
}

View File

@ -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<InteractionMethod> interactionMethods;
private Set<InteractionEntry> 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<InteractionEntry> 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<SlashCommandDefinition> defs = new ArrayList<>();
List<ExecutableSlashCommandDefinition> execDefs = interactionMethods.stream()
.filter((x) -> x.getClass().isAssignableFrom(SlashCommandInteractionMethod.class))
.map((x) -> ((SlashCommandInteractionMethod)x).getCommandDefinition())
List<SlashCommandIdentifier> slashIdentifiers = interactions.stream()
.filter((x) -> x.type().equals(InteractionType.COMMAND))
.map((x) -> (SlashCommandIdentifier)x.identifier())
.toList();
execDefs.forEach((def) -> {
slashIdentifiers.forEach((ident) -> {
Optional<SlashCommandDefinition> 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);
}
});
}

View File

@ -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();

View File

@ -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<Long, List<ApplicationCommandRequest>> 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<ApplicationCommandInteractionOption> 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<ApplicationCommandInteractionOption> 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<ApplicationCommandOptionData> 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<ApplicationCommandOptionData> 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<ApplicationCommandOptionData> 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<ApplicationCommandOptionChoiceData> convertChoices(SlashCommandOption option) {
List<ApplicationCommandOptionChoiceData> 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;

View File

@ -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<Long, Set<SlashCommandBuilder>> serverCommands = new HashMap<>();
Set<SlashCommandBuilder> 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<SlashCommandInteractionOption> 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<org.javacord.api.interaction.SlashCommandOption> 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<org.javacord.api.interaction.SlashCommandOption> 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<org.javacord.api.interaction.SlashCommandOption> 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<org.javacord.api.interaction.SlashCommandOptionChoice> convertChoices(SlashCommandOption option) {
List<org.javacord.api.interaction.SlashCommandOptionChoice> 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;