diff --git a/src/main/java/info/itsthesky/disky/core/JDAUtils.java b/src/main/java/info/itsthesky/disky/core/JDAUtils.java index adc9fb1c..86363dc5 100644 --- a/src/main/java/info/itsthesky/disky/core/JDAUtils.java +++ b/src/main/java/info/itsthesky/disky/core/JDAUtils.java @@ -104,27 +104,31 @@ public static Class getOptionClass(OptionType type) { } public static Object parseOptionValue(OptionMapping option) { - switch (option.getType()) { - case ROLE: - return option.getAsRole(); - case USER: - return option.getAsUser(); - case CHANNEL: - return option.getAsChannel().asGuildMessageChannel(); - case NUMBER: - return option.getAsDouble(); - case INTEGER: - return option.getAsInt(); - case STRING: - return option.getAsString(); - case ATTACHMENT: - return option.getAsAttachment(); - case BOOLEAN: - return option.getAsBoolean(); - case MENTIONABLE: - return option.getAsMentionable(); - default: - return new Object(); + try { + switch (option.getType()) { + case ROLE: + return option.getAsRole(); + case USER: + return option.getAsUser(); + case CHANNEL: + return option.getAsChannel().asGuildMessageChannel(); + case NUMBER: + return option.getAsDouble(); + case INTEGER: + return option.getAsInt(); + case STRING: + return option.getAsString(); + case ATTACHMENT: + return option.getAsAttachment(); + case BOOLEAN: + return option.getAsBoolean(); + case MENTIONABLE: + return option.getAsMentionable(); + default: + return null; + } + } catch (IllegalStateException ex) { + return null; } } } diff --git a/src/main/java/info/itsthesky/disky/elements/events/interactions/SlashCompletionEvent.java b/src/main/java/info/itsthesky/disky/elements/events/interactions/SlashCompletionEvent.java index 67a6f35d..274ba0c4 100644 --- a/src/main/java/info/itsthesky/disky/elements/events/interactions/SlashCompletionEvent.java +++ b/src/main/java/info/itsthesky/disky/elements/events/interactions/SlashCompletionEvent.java @@ -30,6 +30,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; + public class SlashCompletionEvent extends DiSkyEvent { static { diff --git a/src/main/java/info/itsthesky/disky/elements/structures/slash/ExprSlashArgument.java b/src/main/java/info/itsthesky/disky/elements/structures/slash/ExprSlashArgument.java index d48a3ddc..db707176 100644 --- a/src/main/java/info/itsthesky/disky/elements/structures/slash/ExprSlashArgument.java +++ b/src/main/java/info/itsthesky/disky/elements/structures/slash/ExprSlashArgument.java @@ -125,7 +125,6 @@ else if (j == 1) @Override public @NotNull Class getReturnType() { - System.out.println("class: " + arg.getTypeInfo().getC()); return arg.getTypeInfo().getC(); } diff --git a/src/main/java/info/itsthesky/disky/elements/structures/slash/SlashManager.java b/src/main/java/info/itsthesky/disky/elements/structures/slash/SlashManager.java index d154e67d..eb14a196 100644 --- a/src/main/java/info/itsthesky/disky/elements/structures/slash/SlashManager.java +++ b/src/main/java/info/itsthesky/disky/elements/structures/slash/SlashManager.java @@ -7,9 +7,12 @@ import info.itsthesky.disky.core.Bot; import info.itsthesky.disky.elements.effects.SendTyping; import info.itsthesky.disky.elements.events.interactions.SlashCommandReceiveEvent; +import info.itsthesky.disky.elements.events.interactions.SlashCompletionEvent; +import info.itsthesky.disky.elements.structures.slash.models.ParsedArgument; import info.itsthesky.disky.elements.structures.slash.models.ParsedCommand; import info.itsthesky.disky.elements.structures.slash.models.RegisteredCommand; import net.dv8tion.jda.api.events.guild.GuildReadyEvent; +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.session.ReadyEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; @@ -174,6 +177,8 @@ else if (value instanceof Number) optionData.addChoice(key, ((Number) value).doubleValue()); }); } + if (parsedArgument.isAutoCompletion()) + optionData.setAutoComplete(true); slashCommandData.addOptions(optionData); }); @@ -197,7 +202,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { return; } - registeredCommand.prepareArguments(event); + registeredCommand.prepareArguments(event.getOptions()); final Trigger trigger = registeredCommand.getTrigger(); final SlashCommandReceiveEvent.BukkitSlashCommandReceiveEvent bukkitEvent = new SlashCommandReceiveEvent.BukkitSlashCommandReceiveEvent(new SlashCommandReceiveEvent()); bukkitEvent.setJDAEvent(event); @@ -206,6 +211,35 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { } } + @Override + public void onCommandAutoCompleteInteraction(CommandAutoCompleteInteractionEvent event) { + if (event.isFromGuild()) { + final RegisteredCommand registeredCommand = findCommand(event.getName(), event.getGuild().getId()); + if (registeredCommand == null) { + DiSky.debug("Received command " + event.getName() + " but it's not registered on guild " + event.getGuild().getId() + " for bot " + event.getJDA().getSelfUser().getGlobalName()); + return; + } + final String focusedArgument = event.getFocusedOption().getName(); + final Trigger trigger = registeredCommand.getArguments() + .stream() + .filter(parsedArgument -> parsedArgument.getName().equals(focusedArgument)) + .findFirst() + .map(ParsedArgument::getOnCompletionRequest) + .orElse(null); + if (trigger == null) { + DiSky.debug("Received command " + event.getName() + " but no completion trigger for argument " + focusedArgument); + return; + } + + registeredCommand.prepareArguments(event.getOptions()); + final SlashCompletionEvent.BukkitSlashCompletionEvent bukkitEvent = + new SlashCompletionEvent.BukkitSlashCompletionEvent(new SlashCompletionEvent()); + bukkitEvent.setJDAEvent(event); + + trigger.execute(bukkitEvent); + } + } + @Override public void onReady(ReadyEvent event) { //todo: global commands diff --git a/src/main/java/info/itsthesky/disky/elements/structures/slash/StructSlashCommand.java b/src/main/java/info/itsthesky/disky/elements/structures/slash/StructSlashCommand.java index 9e6d086b..d219bbc3 100644 --- a/src/main/java/info/itsthesky/disky/elements/structures/slash/StructSlashCommand.java +++ b/src/main/java/info/itsthesky/disky/elements/structures/slash/StructSlashCommand.java @@ -16,6 +16,7 @@ import info.itsthesky.disky.core.SkriptUtils; import info.itsthesky.disky.elements.events.bots.ReadyEvent; import info.itsthesky.disky.elements.events.interactions.SlashCommandReceiveEvent; +import info.itsthesky.disky.elements.events.interactions.SlashCompletionEvent; import info.itsthesky.disky.elements.structures.slash.models.ParsedArgument; import info.itsthesky.disky.elements.structures.slash.models.ParsedCommand; import net.dv8tion.jda.api.Permission; @@ -312,11 +313,11 @@ private List parseArguments() { final SectionNode completionNode = container.getOptional("on completion request", SectionNode.class, true); if (completionNode != null) { final Trigger trigger = new Trigger(getParser().getCurrentScript(), "completion for argument " + argument.getName(), new SimpleEvent(), - SkriptUtils.loadCode(completionNode, SimpleDiSkyEvent.class)); + SkriptUtils.loadCode(completionNode, SlashCompletionEvent.BukkitSlashCompletionEvent.class)); argument.setOnCompletionRequest(trigger); } - if (argument.isAutoCompletion() && argument.isAutoCompletion()) { + if (argument.hasChoices() && argument.isAutoCompletion()) { Skript.error("You can't have both auto completion and choices for the same argument."); return null; } diff --git a/src/main/java/info/itsthesky/disky/elements/structures/slash/models/ParsedCommand.java b/src/main/java/info/itsthesky/disky/elements/structures/slash/models/ParsedCommand.java index b06f4b83..30f4a260 100644 --- a/src/main/java/info/itsthesky/disky/elements/structures/slash/models/ParsedCommand.java +++ b/src/main/java/info/itsthesky/disky/elements/structures/slash/models/ParsedCommand.java @@ -124,8 +124,7 @@ public boolean shouldUpdate(ParsedCommand command) { || !this.getGuilds().equals(command.getGuilds());*/ } - public void prepareArguments(SlashCommandInteractionEvent event) { - final List options = event.getOptions(); + public void prepareArguments(List options) { for (int i = 0; i < options.size(); i++) { final OptionMapping option = options.get(i); final ParsedArgument argument = arguments.get(i);