diff --git a/CCH.iml b/CCH.iml
index 740ca98..c9a6303 100644
--- a/CCH.iml
+++ b/CCH.iml
@@ -11,7 +11,7 @@
-
+
diff --git a/pom.xml b/pom.xml
index 884b90d..3508758 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,24 +7,25 @@
tech.xigam
CCH
- 1.4.3
+ 1.5.0
Complex Command Handler
A really useful and simple command handler for JDA.
https://github.com/KingRainbow44/Complex-Command-Handler/
-
-
-
-
-
+
+
+
+
+
+
17
@@ -127,7 +128,7 @@
net.dv8tion
JDA
- 5.0.0-alpha.5
+ 5.0.0-alpha.9
provided
diff --git a/src/main/java/tech/xigam/cch/ComplexCommandHandler.java b/src/main/java/tech/xigam/cch/ComplexCommandHandler.java
index 91ae55f..7d4c1ee 100644
--- a/src/main/java/tech/xigam/cch/ComplexCommandHandler.java
+++ b/src/main/java/tech/xigam/cch/ComplexCommandHandler.java
@@ -1,15 +1,16 @@
package tech.xigam.cch;
import net.dv8tion.jda.api.JDA;
-import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
+import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
@@ -43,9 +44,6 @@ public final class ComplexCommandHandler extends ListenerAdapter
public Consumer onArgumentError = interaction -> {};
- /**
- * This constructor should be called in {@link JDABuilder#addEventListeners}
- */
public ComplexCommandHandler(boolean usePrefix) {
this.usePrefix = usePrefix;
}
@@ -59,6 +57,7 @@ public ComplexCommandHandler registerCommand(BaseCommand command) {
}
public void setJda(JDA jda) {
+ jda.addEventListener(this);
this.jdaInstance = jda;
}
@@ -103,12 +102,6 @@ private void executeCommand(String command, Message message2, Member member, Tex
);
}
- /*
- * Completing commands.
- */
-
-
-
/*
* Handling interactive arguments.
*/
@@ -188,6 +181,22 @@ public void onCommandAutoCompleteInteraction(@NotNull CommandAutoCompleteInterac
command.prepareForCompletion(event, this);
}
+ @Override
+ public void onButtonInteraction(@NotNull ButtonInteractionEvent event) {
+ String rawReference = event.getComponentId();
+ if (!rawReference.startsWith("<"))
+ return;
+
+ var label = rawReference.split("<")[1].split(">")[0];
+ var command = commands.get(label);
+ command.prepareForCallback(label, event, this);
+ }
+
+ @Override
+ public void onMessageReactionAdd(@NotNull MessageReactionAddEvent event) {
+
+ }
+
/**
* Delete and create commands.
*/
diff --git a/src/main/java/tech/xigam/cch/command/BaseCommand.java b/src/main/java/tech/xigam/cch/command/BaseCommand.java
index b2e1880..4d365cb 100644
--- a/src/main/java/tech/xigam/cch/command/BaseCommand.java
+++ b/src/main/java/tech/xigam/cch/command/BaseCommand.java
@@ -1,15 +1,21 @@
package tech.xigam.cch.command;
+import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
+import net.dv8tion.jda.api.interactions.components.buttons.Button;
+import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import tech.xigam.cch.ComplexCommandHandler;
import tech.xigam.cch.utils.Interaction;
import java.util.List;
+import static tech.xigam.cch.utils.Validation.isUrl;
+
/**
* An interface used by {@link Command}, {@link SubCommand}, and {@link Alias}
*/
@@ -17,6 +23,7 @@ public interface BaseCommand {
/*
* General command information.
*/
+
String getLabel();
String getDescription();
@@ -24,6 +31,7 @@ public interface BaseCommand {
/*
* Back-end code.
*/
+
void execute(Interaction interaction);
void prepareForExecution(List arguments, Message message, Member sender, TextChannel channel, boolean skipArguments, ComplexCommandHandler handler);
@@ -31,4 +39,45 @@ public interface BaseCommand {
void prepareForExecution(SlashCommandInteractionEvent event, ComplexCommandHandler handler);
void prepareForCompletion(CommandAutoCompleteInteractionEvent event, ComplexCommandHandler handler);
+
+// void prepareForCallback(MessageReactionAddEvent event, ComplexCommandHandler handler);
+
+ void prepareForCallback(String cmdLabel, ButtonInteractionEvent event, ComplexCommandHandler handler);
+
+ /**
+ * Creates a button with proper handling for this command.
+ *
+ * @param style The button style.
+ * @param reference The reference to the button (or a URL).
+ * @param text The text to display on the button.
+ * @return The button.
+ */
+ default Button createButton(ButtonStyle style, String reference, String text) {
+ return Button.of(style, isUrl(reference) ? reference : "<" + this.getLabel().toLowerCase() + ">" + reference, text);
+ }
+
+ /**
+ * Creates a button with proper handling for this command.
+ *
+ * @param style The button style.
+ * @param reference The reference to the button (or a URL).
+ * @param emoji The emoji to show on the button.
+ * @return The button.
+ */
+ default Button createButton(ButtonStyle style, String reference, Emoji emoji) {
+ return Button.of(style, isUrl(reference) ? reference : "<" + this.getLabel().toLowerCase() + ">" + reference, emoji);
+ }
+
+ /**
+ * Creates a button with proper handling for this command.
+ *
+ * @param style The button style.
+ * @param reference The reference to the button (or a URL).
+ * @param text The text to show to the right of the emoji.
+ * @param emoji The emoji to show on the button.
+ * @return The button.
+ */
+ default Button createButton(ButtonStyle style, String reference, String text, Emoji emoji) {
+ return Button.of(style, isUrl(reference) ? reference : "<" + this.getLabel().toLowerCase() + ">" + reference, text, emoji);
+ }
}
diff --git a/src/main/java/tech/xigam/cch/command/Callable.java b/src/main/java/tech/xigam/cch/command/Callable.java
new file mode 100644
index 0000000..eced3c2
--- /dev/null
+++ b/src/main/java/tech/xigam/cch/command/Callable.java
@@ -0,0 +1,12 @@
+package tech.xigam.cch.command;
+
+import tech.xigam.cch.utils.Callback;
+
+/**
+ * Declares a class as callable, allowing:
+ * - buttons to work
+ * - forms to work
+ */
+public interface Callable {
+ void callback(Callback callback);
+}
diff --git a/src/main/java/tech/xigam/cch/command/Command.java b/src/main/java/tech/xigam/cch/command/Command.java
index 25aa3b7..6c18129 100644
--- a/src/main/java/tech/xigam/cch/command/Command.java
+++ b/src/main/java/tech/xigam/cch/command/Command.java
@@ -5,12 +5,10 @@
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import tech.xigam.cch.ComplexCommandHandler;
-import tech.xigam.cch.utils.Argument;
-import tech.xigam.cch.utils.Completion;
-import tech.xigam.cch.utils.Interaction;
-import tech.xigam.cch.utils.InteractiveArguments;
+import tech.xigam.cch.utils.*;
import java.util.ArrayList;
import java.util.HashMap;
@@ -130,6 +128,19 @@ public void prepareForCompletion(CommandAutoCompleteInteractionEvent event, Comp
((Completable) this).complete(new Completion(event));
}
+ @Override
+ public void prepareForCallback(String cmdLabel, ButtonInteractionEvent event, ComplexCommandHandler handler) {
+ if (subCommands.containsKey(cmdLabel)) {
+ var subCmd = this.getSubCommand(cmdLabel);
+ if (subCmd instanceof Callable)
+ ((Callable) subCmd).callback(new Callback(event));
+ return;
+ }
+
+ if (this instanceof Callable)
+ ((Callable) this).callback(new Callback(event));
+ }
+
public final Map getSubCommands() {
return subCommands;
}
diff --git a/src/main/java/tech/xigam/cch/defaults/DeployCommand.java b/src/main/java/tech/xigam/cch/defaults/DeployCommand.java
index 65c5a85..05ead0e 100644
--- a/src/main/java/tech/xigam/cch/defaults/DeployCommand.java
+++ b/src/main/java/tech/xigam/cch/defaults/DeployCommand.java
@@ -1,11 +1,13 @@
package tech.xigam.cch.defaults;
+import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import tech.xigam.cch.command.Arguments;
import tech.xigam.cch.command.Command;
import tech.xigam.cch.utils.Argument;
import tech.xigam.cch.utils.Interaction;
+import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
@@ -16,6 +18,11 @@ public DeployCommand() {
protected abstract boolean permissionCheck(Interaction interaction);
+ @Nullable
+ protected MessageEmbed embedify(String text) {
+ return null;
+ }
+
@Override
public void execute(Interaction interaction) {
if (!permissionCheck(interaction)) {
@@ -28,15 +35,22 @@ public void execute(Interaction interaction) {
if (!global && !interaction.isFromGuild()) {
global = true;
- interaction.sendMessage("You can't deploy slash commands to a DM, deploying globally instead.");
+ var embed = this.embedify("You can't deploy slash commands to a DM, deploying globally instead.");
+ if (embed == null)
+ interaction.reply("You can't deploy slash commands to a DM, deploying globally instead.");
+ else interaction.reply(embed);
}
if (delete) {
interaction.getCommandHandler().downsert(global ? null : interaction.getGuild());
- interaction.reply("Deleted all commands.");
+ var embed = this.embedify("Deleted all commands.");
+ if (embed == null) interaction.reply("Deleted all commands.");
+ else interaction.reply(embed);
} else {
interaction.getCommandHandler().deployAll(global ? null : interaction.getGuild());
- interaction.reply("Deployed all commands.");
+ var embed = this.embedify("Deployed all commands.");
+ if (embed == null) interaction.reply("Deployed all commands.");
+ else interaction.reply(embed);
}
}
diff --git a/src/main/java/tech/xigam/cch/utils/Callback.java b/src/main/java/tech/xigam/cch/utils/Callback.java
new file mode 100644
index 0000000..b8e0f27
--- /dev/null
+++ b/src/main/java/tech/xigam/cch/utils/Callback.java
@@ -0,0 +1,44 @@
+package tech.xigam.cch.utils;
+
+import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
+import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
+
+/**
+ * A callback for buttons and forms.
+ */
+public final class Callback {
+ private final boolean isSlash, inGuild;
+ private final String reference;
+
+ private GenericComponentInteractionCreateEvent interactionExecutor = null;
+
+ private boolean deferred = false;
+
+ public Callback(ButtonInteractionEvent event) {
+ this.isSlash = true;
+ this.inGuild = event.isFromGuild();
+ this.interactionExecutor = event;
+
+ var rawReference = event.getComponentId();
+ this.reference = rawReference.split(">")[1];
+ }
+
+ public String getReference() {
+ return this.reference;
+ }
+
+ // ---------- UTILITY METHODS ---------- \\
+
+ public Callback deferEdit() {
+ if (this.isSlash)
+ this.interactionExecutor.deferEdit().queue();
+ this.deferred = true;
+ return this;
+ }
+
+ // ---------- REPLY METHODS ---------- \\
+
+ public void reply(String message) {
+
+ }
+}
diff --git a/src/main/java/tech/xigam/cch/utils/Completion.java b/src/main/java/tech/xigam/cch/utils/Completion.java
index 192ca1a..5671ce8 100644
--- a/src/main/java/tech/xigam/cch/utils/Completion.java
+++ b/src/main/java/tech/xigam/cch/utils/Completion.java
@@ -56,6 +56,9 @@ public Completion addChoice(String mapping, Object value) {
}
public void reply() {
- this.completeEvent.replyChoices(this.choices).queue();
+ try {
+ this.completeEvent.replyChoices(this.choices).queue();
+ } catch (IllegalStateException ignored) {
+ }
}
}
diff --git a/src/main/java/tech/xigam/cch/utils/Interaction.java b/src/main/java/tech/xigam/cch/utils/Interaction.java
index b7b82db..2ebd6de 100644
--- a/src/main/java/tech/xigam/cch/utils/Interaction.java
+++ b/src/main/java/tech/xigam/cch/utils/Interaction.java
@@ -4,6 +4,7 @@
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.components.buttons.Button;
import tech.xigam.cch.ComplexCommandHandler;
import tech.xigam.cch.command.Arguments;
import tech.xigam.cch.command.BaseCommand;
@@ -13,13 +14,8 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
-public final class Interaction implements Cloneable {
- /*
- * Global data.
- * Set regardless of position.
- */
+public final class Interaction {
private final boolean isSlash, inGuild;
- private final BaseCommand command;
private final ComplexCommandHandler commandHandler;
private final Member member;
@@ -29,21 +25,19 @@ public final class Interaction implements Cloneable {
private SlashCommandInteractionEvent slashExecutor = null;
- /*
- * Information storage.
- */
private boolean ephemeral = false, sendToDMs = false;
private boolean deferred = false;
private final Map arguments = new HashMap<>();
private final List rawArguments = new ArrayList<>();
+ private final List