From de3da2e5c175b74980f78ae1d9349593d425775f Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Wed, 24 Apr 2024 17:54:26 +0200
Subject: [PATCH 01/38] remove obsolete methods in PermissionsProvider
---
pom.xml | 11 ++++++++
.../permissions/PermissionsProvider.java | 26 -------------------
2 files changed, 11 insertions(+), 26 deletions(-)
diff --git a/pom.xml b/pom.xml
index a3f933bec..ffa45b1b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -106,5 +106,16 @@
annotations
24.0.1
+
+
+ ch.qos.logback
+ logback-classic
+ 1.4.12
+
+
+ ch.qos.logback
+ logback-core
+ 1.4.12
+
diff --git a/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java b/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java
index 5dfd8d9c3..54cd209b1 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/permissions/PermissionsProvider.java
@@ -2,14 +2,10 @@
import com.github.kaktushose.jda.commands.annotations.interactions.Permissions;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.jetbrains.annotations.NotNull;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Interface for performing permission checks.
*
@@ -40,26 +36,4 @@ public interface PermissionsProvider {
*/
boolean hasPermission(@NotNull Member member, @NotNull Context context);
- /**
- * Gets a {@link List} of user ids that map to the given permission string.
- *
- * @param guild the corresponding guild
- * @param permission the corresponding string
- * @return a {@link List} of user ids
- */
- default List getUsersWithPermission(Guild guild, String permission) {
- return new ArrayList<>();
- }
-
- /**
- * Gets a {@link List} of role ids that map to the given permission string.
- *
- * @param guild the corresponding guild
- * @param permission the corresponding string
- * @return a {@link List} of role ids
- */
- default List getRolesWithPermission(Guild guild, String permission) {
- return new ArrayList<>();
- }
-
}
From da36e41af0bacdc2cddfbd9aca78c30b5e9d0df5 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Mon, 29 Apr 2024 14:10:02 +0200
Subject: [PATCH 02/38] fix modal defaultValue not being set
---
.../kaktushose/jda/commands/reflect/TextInputDefinition.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java
index 66471b880..386024e7f 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/TextInputDefinition.java
@@ -88,7 +88,7 @@ public net.dv8tion.jda.api.interactions.components.text.TextInput toTextInput()
if (!placeholder.isBlank()) {
textInput.setPlaceholder(placeholder);
}
- if (!placeholder.isBlank()) {
+ if (!defaultValue.isBlank()) {
textInput.setValue(defaultValue);
}
From 649440b3e890ce30e79be5795ec577c524e08929 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Fri, 10 May 2024 13:39:54 +0200
Subject: [PATCH 03/38] add option to link runtimeId for message builder
components
---
.../kaktushose/jda/commands/JDACommands.java | 59 +++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
index f973e600d..09f9a3860 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
@@ -230,6 +230,36 @@ public Button getButton(String button) {
return buttonDefinition.toButton().withId(buttonDefinition.createCustomId(runtime.getRuntimeId()));
}
+ /**
+ * Gets a JDA {@link Button} to use it for message builders based on the jda-commands id and links it an
+ * existing
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}.
+ *
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a button defined by a
+ * {@code onButton(ComponentEvent event)} method inside an {@code ExampleButton} class would be
+ * {@code ExampleButton.onButton}.
+ *
+ *
+ * @param button the id of the button
+ * @param runtimeId the id of the
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}
+ * @return a JDA {@link Button}
+ */
+ public Button getButton(String button, String runtimeId) {
+ if (!button.matches("[a-zA-Z]+\\.[a-zA-Z]+")) {
+ throw new IllegalArgumentException("Unknown Button");
+ }
+
+ String sanitizedId = button.replaceAll("\\.", "");
+ ButtonDefinition buttonDefinition = interactionRegistry.getButtons().stream()
+ .filter(it -> it.getDefinitionId().equals(sanitizedId))
+ .findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Button"));
+
+ return buttonDefinition.toButton().withId(buttonDefinition.createCustomId(runtimeId));
+ }
+
/**
* Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id.
*
@@ -256,6 +286,35 @@ public SelectMenu getSelectMenu(String selectMenu) {
return selectMenuDefinition.toSelectMenu(runtime.getRuntimeId(), true);
}
+ /**
+ * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id and links it an
+ * existing
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}.
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
+ * {@code ExampleMenu.onSelectMenu}.
+ *
+ *
+ * @param selectMenu the id of the selectMenu
+ * @param runtimeId the id of the
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}
+ * @return a JDA {@link SelectMenu}
+ */
+ public SelectMenu getSelectMenu(String selectMenu, String runtimeId) {
+ if (!selectMenu.matches("[a-zA-Z]+\\.[a-zA-Z]+")) {
+ throw new IllegalArgumentException("Unknown Select Menu");
+ }
+
+ String sanitizedId = selectMenu.replaceAll("\\.", "");
+ GenericSelectMenuDefinition> selectMenuDefinition = interactionRegistry.getSelectMenus().stream()
+ .filter(it -> it.getDefinitionId().equals(sanitizedId))
+ .findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Select Menu"));
+
+ return selectMenuDefinition.toSelectMenu(runtimeId, true);
+ }
+
/**
* Gets the {@link ImplementationRegistry}.
*
From 18635417f1a62fe575b70048d2d874a1beaf8492 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Sun, 2 Jun 2024 14:49:46 +0200
Subject: [PATCH 04/38] improve builder components methods
---
.../kaktushose/jda/commands/JDACommands.java | 45 ++++++++++++++--
.../interactions/GenericEvent.java | 54 +++++++++++++++++++
2 files changed, 96 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
index 09f9a3860..d6bd23ec7 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
@@ -242,9 +242,9 @@ public Button getButton(String button) {
* {@code ExampleButton.onButton}.
*
*
- * @param button the id of the button
- * @param runtimeId the id of the
- * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}
+ * @param button the id of the button
+ * @param runtimeId the id of the
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}
* @return a JDA {@link Button}
*/
public Button getButton(String button, String runtimeId) {
@@ -286,6 +286,23 @@ public SelectMenu getSelectMenu(String selectMenu) {
return selectMenuDefinition.toSelectMenu(runtime.getRuntimeId(), true);
}
+ /**
+ * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id.
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
+ * {@code ExampleMenu.onSelectMenu}.
+ *
+ *
+ * @param selectMenu the id of the selectMenu
+ * @param clazz the subtype of {@link SelectMenu}
+ * @return a JDA {@link SelectMenu}
+ */
+ public T getSelectMenu(String selectMenu, Class clazz) {
+ return (T) getSelectMenu(selectMenu);
+ }
+
/**
* Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id and links it an
* existing
@@ -315,6 +332,28 @@ public SelectMenu getSelectMenu(String selectMenu, String runtimeId) {
return selectMenuDefinition.toSelectMenu(runtimeId, true);
}
+ /**
+ * Gets a JDA {@link SelectMenu} subtype to use it for message builders based on the jda-commands id and links it an
+ * existing
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}.
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
+ * {@code ExampleMenu.onSelectMenu}.
+ *
+ *
+ * @param selectMenu the id of the selectMenu
+ * @param runtimeId the id of the
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime
+ * InteractionRuntime}
+ * @param clazz the subtype of {@link SelectMenu}
+ * @return a JDA {@link SelectMenu}
+ */
+ public T getSelectMenu(String selectMenu, String runtimeId, Class clazz) {
+ return (T) getSelectMenu(selectMenu, runtimeId);
+ }
+
/**
* Gets the {@link ImplementationRegistry}.
*
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java
index 7a81dd311..8c732a70b 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java
@@ -3,6 +3,8 @@
import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition;
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
+import net.dv8tion.jda.api.interactions.components.buttons.Button;
+import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
/**
* Extension of JDAs {@link GenericInteractionCreateEvent} class. This is the base class for the different event classes.
@@ -56,4 +58,56 @@ public Context getContext() {
public JDACommands getJdaCommands() {
return context.getJdaCommands();
}
+
+ /**
+ * Gets a JDA {@link Button} to use it for message builders based on the jda-commands id. The returned button will
+ * be linked to the runtime of this event.
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a button defined by a
+ * {@code onButton(ComponentEvent event)} method inside an {@code ExampleButton} class would be
+ * {@code ExampleButton.onButton}.
+ *
+ *
+ * @param button the id of the button
+ * @return a JDA {@link Button}
+ */
+ public Button getButton(String button) {
+ return getJdaCommands().getButton(button, context.getRuntime().getRuntimeId());
+ }
+
+ /**
+ * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id. The returned
+ * SelectMenu will be linked to the runtime of this event.
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
+ * {@code ExampleMenu.onSelectMenu}.
+ *
+ *
+ * @param menu the id of the selectMenu
+ * @return a JDA {@link SelectMenu}
+ */
+ public SelectMenu getSelectMenu(String menu) {
+ return getJdaCommands().getSelectMenu(menu, context.getRuntime().getRuntimeId());
+ }
+
+ /**
+ * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id. The returned
+ * SelectMenu will be linked to the runtime of this event.
+ *
+ *
+ * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
+ * {@code ExampleMenu.onSelectMenu}.
+ *
+ *
+ * @param menu the id of the selectMenu
+ * @param clazz the subtype of {@link SelectMenu}
+ * @return a JDA {@link SelectMenu}
+ */
+ public S getSelectMenu(String menu, Class clazz) {
+ return getJdaCommands().getSelectMenu(menu, getContext().getRuntime().getRuntimeId(), clazz);
+ }
}
From 04ff5c267d14b77582772071697eb6cb495dd897 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Thu, 4 Jul 2024 10:52:57 +0200
Subject: [PATCH 05/38] properly escape string replacements
---
.../jda/commands/data/EmbedDTO.java | 29 ++++++++++---------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/data/EmbedDTO.java b/src/main/java/com/github/kaktushose/jda/commands/data/EmbedDTO.java
index 7c394019a..f4b561366 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/data/EmbedDTO.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/data/EmbedDTO.java
@@ -10,6 +10,7 @@
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Map;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
@@ -279,56 +280,56 @@ public EmbedDTO injectValues(Map values) {
*/
public EmbedDTO injectValue(String name, Object object) {
if (title != null) {
- title = title.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ title = title.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (description != null) {
- description = description.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ description = description.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (url != null) {
- url = url.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ url = url.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (color != null) {
- color = color.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ color = color.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (timestamp != null) {
- timestamp = timestamp.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ timestamp = timestamp.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (footer != null) {
if (footer.iconUrl != null) {
- footer.iconUrl = footer.iconUrl.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ footer.iconUrl = footer.iconUrl.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (footer.text != null) {
- footer.text = footer.text.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ footer.text = footer.text.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
}
if (thumbnail != null) {
if (thumbnail.url != null) {
- thumbnail.url = thumbnail.url.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ thumbnail.url = thumbnail.url.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
}
if (image != null) {
if (image.url != null) {
- image.url = image.url.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ image.url = image.url.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
}
if (author != null) {
if (author.iconUrl != null) {
- author.iconUrl = author.iconUrl.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ author.iconUrl = author.iconUrl.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (author.name != null) {
- author.name = author.name.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ author.name = author.name.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (author.url != null) {
- author.url = author.url.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ author.url = author.url.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
}
if (fields != null) {
for (Field field : fields) {
if (field.name != null) {
- field.name = field.name.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ field.name = field.name.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
if (field.value != null) {
- field.value = field.value.replaceAll(String.format(Pattern.quote("{%s}"), name), String.valueOf(object));
+ field.value = field.value.replaceAll(String.format(Pattern.quote("{%s}"), Matcher.quoteReplacement(name)), String.valueOf(object));
}
}
}
From 5bc8482d6438b536e6ded174d8599f7b4027e7af Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Sun, 4 Aug 2024 17:35:49 +0200
Subject: [PATCH 06/38] bump jda version and fix reply bug [#137]
---
pom.xml | 2 +-
.../jda/commands/dispatching/reply/Replyable.java | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index ffa45b1b0..ac3c0ae15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -66,7 +66,7 @@
net.dv8tion
JDA
- 5.0.0-beta.22
+ 5.0.2
club.minnced
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java
index 2808b1842..e844403c6 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java
@@ -97,7 +97,7 @@ default void reply(@NotNull EmbedDTO embedDTO) {
* @see JDA RestAction Documentation
*/
default void reply(@NotNull String message, @Nullable Consumer success) {
- reply(message);
+ getReplyContext().getBuilder().setContent(message);
setSuccessCallback(success);
reply();
}
@@ -111,7 +111,7 @@ default void reply(@NotNull String message, @Nullable Consumer success)
* @see JDA RestAction Documentation
*/
default void reply(@NotNull MessageCreateData message, @Nullable Consumer success) {
- reply(message);
+ getReplyContext().getBuilder().applyData(message);
setSuccessCallback(success);
reply();
}
@@ -125,7 +125,7 @@ default void reply(@NotNull MessageCreateData message, @Nullable ConsumerJDA RestAction Documentation
*/
default void reply(@NotNull EmbedBuilder builder, @Nullable Consumer success) {
- reply(builder);
+ getReplyContext().getBuilder().setEmbeds(builder.build());
setSuccessCallback(success);
reply();
}
@@ -139,7 +139,7 @@ default void reply(@NotNull EmbedBuilder builder, @Nullable Consumer su
* @see JDA RestAction Documentation
*/
default void reply(@NotNull EmbedDTO embedDTO, @Nullable Consumer success) {
- reply(embedDTO);
+ getReplyContext().getBuilder().setEmbeds(embedDTO.toMessageEmbed());
setSuccessCallback(success);
reply();
}
From 90bf1148b57760950a81ccf1743d050c68925776 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Sun, 4 Aug 2024 17:42:02 +0200
Subject: [PATCH 07/38] fix unit tests
---
src/test/java/adapting/mock/GuildMock.java | 2 +-
src/test/java/adapting/mock/JDAMock.java | 26 +++++++++++++++++++++
src/test/java/adapting/mock/MemberMock.java | 6 -----
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/src/test/java/adapting/mock/GuildMock.java b/src/test/java/adapting/mock/GuildMock.java
index 4701b0110..6e6340ea2 100644
--- a/src/test/java/adapting/mock/GuildMock.java
+++ b/src/test/java/adapting/mock/GuildMock.java
@@ -128,7 +128,7 @@ public AuditableRestAction ban(@NotNull UserSnowflake user, int deletionTi
@NotNull
@Override
- public AuditableRestAction ban(@NotNull Collection collection, @Nullable Duration duration) {
+ public AuditableRestAction ban(@NotNull Collection extends UserSnowflake> users, @Nullable Duration deletionTime) {
return null;
}
diff --git a/src/test/java/adapting/mock/JDAMock.java b/src/test/java/adapting/mock/JDAMock.java
index d209a5542..5e840d744 100644
--- a/src/test/java/adapting/mock/JDAMock.java
+++ b/src/test/java/adapting/mock/JDAMock.java
@@ -9,6 +9,7 @@
import net.dv8tion.jda.api.entities.sticker.StickerPack;
import net.dv8tion.jda.api.entities.sticker.StickerSnowflake;
import net.dv8tion.jda.api.entities.sticker.StickerUnion;
+import net.dv8tion.jda.api.events.GenericEvent;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.hooks.IEventManager;
import net.dv8tion.jda.api.interactions.commands.Command;
@@ -23,6 +24,7 @@
import net.dv8tion.jda.api.requests.restaction.*;
import net.dv8tion.jda.api.requests.restaction.pagination.EntitlementPaginationAction;
import net.dv8tion.jda.api.sharding.ShardManager;
+import net.dv8tion.jda.api.utils.Once;
import net.dv8tion.jda.api.utils.cache.CacheFlag;
import net.dv8tion.jda.api.utils.cache.CacheView;
import net.dv8tion.jda.api.utils.cache.ChannelCacheView;
@@ -162,6 +164,12 @@ public List getRegisteredListeners() {
return null;
}
+ @NotNull
+ @Override
+ public Once.Builder listenOnce(@NotNull Class eventType) {
+ return null;
+ }
+
@NotNull
@Override
public RestAction> retrieveCommands() {
@@ -452,6 +460,24 @@ public EntitlementPaginationAction retrieveEntitlements() {
return null;
}
+ @NotNull
+ @Override
+ public RestAction retrieveEntitlementById(long entitlementId) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public TestEntitlementCreateAction createTestEntitlement(long skuId, long ownerId, @NotNull TestEntitlementCreateAction.OwnerType ownerType) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public RestAction deleteTestEntitlement(long entitlementId) {
+ return null;
+ }
+
@NotNull
@Override
public JDA setRequiredScopes(@NotNull Collection collection) {
diff --git a/src/test/java/adapting/mock/MemberMock.java b/src/test/java/adapting/mock/MemberMock.java
index ad5ca995a..9b7563280 100644
--- a/src/test/java/adapting/mock/MemberMock.java
+++ b/src/test/java/adapting/mock/MemberMock.java
@@ -255,12 +255,6 @@ public AuditableRestAction kick() {
return Member.super.kick();
}
- @NotNull
- @Override
- public AuditableRestAction kick(@Nullable String reason) {
- return Member.super.kick(reason);
- }
-
@NotNull
@Override
public AuditableRestAction mute(boolean mute) {
From d1e7cb62293fff0ba56214875eea12ae8bec5f4b Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Wed, 7 Aug 2024 18:11:20 +0200
Subject: [PATCH 08/38] update JsonErrorMessageFactory to use new
executionFailed embed format
---
src/examples/embeds.json | 8 +++++++-
.../jda/commands/embeds/JsonErrorMessageFactory.java | 11 ++++++++++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/src/examples/embeds.json b/src/examples/embeds.json
index 25d070914..11da18637 100644
--- a/src/examples/embeds.json
+++ b/src/examples/embeds.json
@@ -42,7 +42,13 @@
},
"executionFailed": {
"title": "Command Execution Failed",
- "description": "```exception```",
+ "description": "The command execution has unexpectedly failed. Please report the following error to the bot devs.",
+ "fields": [
+ {
+ "name": "Error Message",
+ "value": "{error}"
+ }
+ ],
"color": "#ff0000"
},
"unknownInteraction": {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java b/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java
index 3cb381d9b..be7186167 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java
@@ -10,6 +10,7 @@
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import org.jetbrains.annotations.NotNull;
+import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -118,8 +119,16 @@ public MessageCreateData getCommandExecutionFailedMessage(@NotNull Context conte
if (!embedCache.containsEmbed("executionFailed")) {
return super.getCommandExecutionFailedMessage(context, exception);
}
+ String error = String.format("```The user \"%s\" attempted to execute an \"%s\" interaction at %s, " +
+ "but a \"%s\" occurred. " +
+ "Please refer to the logs for further information.```",
+ context.getEvent().getUser().toString(),
+ context.getEvent().getInteraction().getType(),
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()),
+ exception.getClass().getName()
+ );
return embedCache.getEmbed("executionFailed")
- .injectValue("exception", exception.toString())
+ .injectValue("error", error)
.toMessageCreateData();
}
From 37ee8b06ecb5dd441c7615a6f47042fe67b62828 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Mon, 25 Nov 2024 14:22:29 +0100
Subject: [PATCH 09/38] fix guild commands not registering
---
.../kaktushose/jda/commands/JDACommands.java | 3 +-
.../jda/commands/SlashCommandUpdater.java | 99 ++++++++-----------
2 files changed, 44 insertions(+), 58 deletions(-)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
index d6bd23ec7..27d18b48b 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
@@ -80,8 +80,7 @@ private JDACommands(Object jda, Class> clazz, LocalizationFunction function, D
interactionRegistry.index(clazz, packages);
updater = new SlashCommandUpdater(this);
- updater.updateGlobalCommands();
- jdaContext.performTask(it -> it.addEventListener(dispatcherSupervisor));
+ updater.updateAllCommands();
isActive = true;
log.info("Finished loading!");
diff --git a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
index 89b0c1a32..ccbe5ea52 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
@@ -7,12 +7,9 @@
import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition;
import com.github.kaktushose.jda.commands.scope.GuildScopeProvider;
import net.dv8tion.jda.api.entities.Guild;
-import net.dv8tion.jda.api.events.guild.GuildReadyEvent;
-import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
-import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,13 +23,12 @@
* @see CommandTree
* @since 2.3.0
*/
-public class SlashCommandUpdater extends ListenerAdapter {
+public class SlashCommandUpdater {
private static final Logger log = LoggerFactory.getLogger(SlashCommandUpdater.class);
private final JDAContext jdaContext;
private final GuildScopeProvider guildScopeProvider;
private final InteractionRegistry interactionRegistry;
- private Map> guildMapping;
/**
* Constructs a new SlashCommandUpdater.
@@ -43,47 +39,6 @@ public SlashCommandUpdater(JDACommands jdaCommands) {
this.jdaContext = jdaCommands.getJDAContext();
guildScopeProvider = jdaCommands.getImplementationRegistry().getGuildScopeProvider();
interactionRegistry = jdaCommands.getInteractionRegistry();
- guildMapping = getGuildMapping();
- }
-
- private Map> getGuildMapping() {
- Set guildCommands = interactionRegistry.getCommands()
- .stream()
- .filter(it -> it.getCommandScope() == SlashCommand.CommandScope.GUILD)
- .collect(Collectors.toSet());
-
- CommandTree tree = new CommandTree(
- guildCommands.stream()
- .filter(it -> it.getCommandType() == Command.Type.SLASH)
- .map(it -> (SlashCommandDefinition) it)
- .collect(Collectors.toSet())
- );
- log.debug("Generated slash command tree:\n" + tree);
-
- Set result = new HashSet<>();
- result.addAll(tree.getCommands());
- result.addAll(guildCommands.stream().
- filter(it -> (it.getCommandType() == Command.Type.USER || it.getCommandType() == Command.Type.MESSAGE))
- .map(GenericCommandDefinition::toCommandData)
- .collect(Collectors.toSet())
- );
- log.debug("Registering commands: " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
-
- Map> guildMapping = new HashMap<>();
- for (CommandData command : result) {
- // create a copy so that a user doesn't modify the command data used for registration
- Set guildIds = guildScopeProvider.getGuildsForCommand(CommandData.fromData(command.toData()));
- if (guildIds.isEmpty()) {
- log.debug("No guilds provided for command {}", command.getName());
- } else {
- log.debug("Using guilds {} for command {}", guildIds, command.getName());
- }
- guildIds.forEach(id -> {
- guildMapping.putIfAbsent(id, new HashSet<>());
- guildMapping.get(id).add(command);
- });
- }
- return guildMapping;
}
/**
@@ -100,12 +55,12 @@ public void updateAllCommands() {
*/
public void updateGuildCommands() {
log.debug("Updating guild commands...");
- guildMapping = getGuildMapping();
+ Map> guildMapping = getGuildMapping();
for (Guild guild : jdaContext.getGuildCache()) {
Set commands = guildMapping.getOrDefault(guild.getIdLong(), Collections.emptySet());
guild.updateCommands().addCommands(commands).queue();
+ log.debug(String.format("Registered guild command(s) %s for %s", commands.stream().map(CommandData::getName).collect(Collectors.toSet()), guild));
}
- log.debug("Done!");
}
/**
@@ -125,7 +80,7 @@ public void updateGlobalCommands() {
.map(it -> (SlashCommandDefinition) it)
.collect(Collectors.toSet())
);
- log.debug("Generated slash command tree:\n" + tree);
+ log.debug("Generated slash command tree with CommandScope.GLOBAL:\n" + tree);
Set result = new HashSet<>();
result.addAll(tree.getCommands());
@@ -134,16 +89,48 @@ public void updateGlobalCommands() {
.map(GenericCommandDefinition::toCommandData)
.collect(Collectors.toSet())
);
- log.debug("Registering commands: " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
+ log.debug("Registered global command(s): " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
jdaContext.performTask(jda -> jda.updateCommands().addCommands(result).queue());
- log.debug("Done!");
}
- @Override
- public void onGuildReady(@NotNull GuildReadyEvent event) {
- Guild guild = event.getGuild();
- Set commands = guildMapping.getOrDefault(guild.getIdLong(), Collections.emptySet());
- guild.updateCommands().addCommands(commands).queue();
+ private Map> getGuildMapping() {
+ Set guildCommands = interactionRegistry.getCommands()
+ .stream()
+ .filter(it -> it.getCommandScope() == SlashCommand.CommandScope.GUILD)
+ .collect(Collectors.toSet());
+
+ CommandTree tree = new CommandTree(
+ guildCommands.stream()
+ .filter(it -> it.getCommandType() == Command.Type.SLASH)
+ .map(it -> (SlashCommandDefinition) it)
+ .collect(Collectors.toSet())
+ );
+ log.debug("Generated slash command tree with CommandScope.GUILD:\n" + tree);
+
+ Set result = new HashSet<>();
+ result.addAll(tree.getCommands());
+ result.addAll(guildCommands.stream().
+ filter(it -> (it.getCommandType() == Command.Type.USER || it.getCommandType() == Command.Type.MESSAGE))
+ .map(GenericCommandDefinition::toCommandData)
+ .collect(Collectors.toSet())
+ );
+ log.debug("Interactions eligible for registration: " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
+
+ Map> guildMapping = new HashMap<>();
+ for (CommandData command : result) {
+ // create a copy so that a user doesn't modify the command data used for registration
+ Set guildIds = guildScopeProvider.getGuildsForCommand(CommandData.fromData(command.toData()));
+ if (guildIds.isEmpty()) {
+ log.debug("No guilds provided for command \"{}\"", command.getName());
+ } else {
+ log.debug("Using guild(s) {} for command \"{}\"", guildIds, command.getName());
+ }
+ guildIds.forEach(id -> {
+ guildMapping.putIfAbsent(id, new HashSet<>());
+ guildMapping.get(id).add(command);
+ });
+ }
+ return guildMapping;
}
}
From aa52965bb229ebc5fd0fd1d200ee0b9308982b9a Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Mon, 25 Nov 2024 14:22:29 +0100
Subject: [PATCH 10/38] fix guild commands not registering
---
.../kaktushose/jda/commands/JDACommands.java | 2 +-
.../jda/commands/SlashCommandUpdater.java | 99 ++++++++-----------
2 files changed, 44 insertions(+), 57 deletions(-)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
index d6bd23ec7..e1165047e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
@@ -80,7 +80,7 @@ private JDACommands(Object jda, Class> clazz, LocalizationFunction function, D
interactionRegistry.index(clazz, packages);
updater = new SlashCommandUpdater(this);
- updater.updateGlobalCommands();
+ updater.updateAllCommands();
jdaContext.performTask(it -> it.addEventListener(dispatcherSupervisor));
isActive = true;
diff --git a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
index 89b0c1a32..ccbe5ea52 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
@@ -7,12 +7,9 @@
import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition;
import com.github.kaktushose.jda.commands.scope.GuildScopeProvider;
import net.dv8tion.jda.api.entities.Guild;
-import net.dv8tion.jda.api.events.guild.GuildReadyEvent;
-import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
-import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,13 +23,12 @@
* @see CommandTree
* @since 2.3.0
*/
-public class SlashCommandUpdater extends ListenerAdapter {
+public class SlashCommandUpdater {
private static final Logger log = LoggerFactory.getLogger(SlashCommandUpdater.class);
private final JDAContext jdaContext;
private final GuildScopeProvider guildScopeProvider;
private final InteractionRegistry interactionRegistry;
- private Map> guildMapping;
/**
* Constructs a new SlashCommandUpdater.
@@ -43,47 +39,6 @@ public SlashCommandUpdater(JDACommands jdaCommands) {
this.jdaContext = jdaCommands.getJDAContext();
guildScopeProvider = jdaCommands.getImplementationRegistry().getGuildScopeProvider();
interactionRegistry = jdaCommands.getInteractionRegistry();
- guildMapping = getGuildMapping();
- }
-
- private Map> getGuildMapping() {
- Set guildCommands = interactionRegistry.getCommands()
- .stream()
- .filter(it -> it.getCommandScope() == SlashCommand.CommandScope.GUILD)
- .collect(Collectors.toSet());
-
- CommandTree tree = new CommandTree(
- guildCommands.stream()
- .filter(it -> it.getCommandType() == Command.Type.SLASH)
- .map(it -> (SlashCommandDefinition) it)
- .collect(Collectors.toSet())
- );
- log.debug("Generated slash command tree:\n" + tree);
-
- Set result = new HashSet<>();
- result.addAll(tree.getCommands());
- result.addAll(guildCommands.stream().
- filter(it -> (it.getCommandType() == Command.Type.USER || it.getCommandType() == Command.Type.MESSAGE))
- .map(GenericCommandDefinition::toCommandData)
- .collect(Collectors.toSet())
- );
- log.debug("Registering commands: " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
-
- Map> guildMapping = new HashMap<>();
- for (CommandData command : result) {
- // create a copy so that a user doesn't modify the command data used for registration
- Set guildIds = guildScopeProvider.getGuildsForCommand(CommandData.fromData(command.toData()));
- if (guildIds.isEmpty()) {
- log.debug("No guilds provided for command {}", command.getName());
- } else {
- log.debug("Using guilds {} for command {}", guildIds, command.getName());
- }
- guildIds.forEach(id -> {
- guildMapping.putIfAbsent(id, new HashSet<>());
- guildMapping.get(id).add(command);
- });
- }
- return guildMapping;
}
/**
@@ -100,12 +55,12 @@ public void updateAllCommands() {
*/
public void updateGuildCommands() {
log.debug("Updating guild commands...");
- guildMapping = getGuildMapping();
+ Map> guildMapping = getGuildMapping();
for (Guild guild : jdaContext.getGuildCache()) {
Set commands = guildMapping.getOrDefault(guild.getIdLong(), Collections.emptySet());
guild.updateCommands().addCommands(commands).queue();
+ log.debug(String.format("Registered guild command(s) %s for %s", commands.stream().map(CommandData::getName).collect(Collectors.toSet()), guild));
}
- log.debug("Done!");
}
/**
@@ -125,7 +80,7 @@ public void updateGlobalCommands() {
.map(it -> (SlashCommandDefinition) it)
.collect(Collectors.toSet())
);
- log.debug("Generated slash command tree:\n" + tree);
+ log.debug("Generated slash command tree with CommandScope.GLOBAL:\n" + tree);
Set result = new HashSet<>();
result.addAll(tree.getCommands());
@@ -134,16 +89,48 @@ public void updateGlobalCommands() {
.map(GenericCommandDefinition::toCommandData)
.collect(Collectors.toSet())
);
- log.debug("Registering commands: " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
+ log.debug("Registered global command(s): " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
jdaContext.performTask(jda -> jda.updateCommands().addCommands(result).queue());
- log.debug("Done!");
}
- @Override
- public void onGuildReady(@NotNull GuildReadyEvent event) {
- Guild guild = event.getGuild();
- Set commands = guildMapping.getOrDefault(guild.getIdLong(), Collections.emptySet());
- guild.updateCommands().addCommands(commands).queue();
+ private Map> getGuildMapping() {
+ Set guildCommands = interactionRegistry.getCommands()
+ .stream()
+ .filter(it -> it.getCommandScope() == SlashCommand.CommandScope.GUILD)
+ .collect(Collectors.toSet());
+
+ CommandTree tree = new CommandTree(
+ guildCommands.stream()
+ .filter(it -> it.getCommandType() == Command.Type.SLASH)
+ .map(it -> (SlashCommandDefinition) it)
+ .collect(Collectors.toSet())
+ );
+ log.debug("Generated slash command tree with CommandScope.GUILD:\n" + tree);
+
+ Set result = new HashSet<>();
+ result.addAll(tree.getCommands());
+ result.addAll(guildCommands.stream().
+ filter(it -> (it.getCommandType() == Command.Type.USER || it.getCommandType() == Command.Type.MESSAGE))
+ .map(GenericCommandDefinition::toCommandData)
+ .collect(Collectors.toSet())
+ );
+ log.debug("Interactions eligible for registration: " + result.stream().map(CommandData::getName).collect(Collectors.toSet()));
+
+ Map> guildMapping = new HashMap<>();
+ for (CommandData command : result) {
+ // create a copy so that a user doesn't modify the command data used for registration
+ Set guildIds = guildScopeProvider.getGuildsForCommand(CommandData.fromData(command.toData()));
+ if (guildIds.isEmpty()) {
+ log.debug("No guilds provided for command \"{}\"", command.getName());
+ } else {
+ log.debug("Using guild(s) {} for command \"{}\"", guildIds, command.getName());
+ }
+ guildIds.forEach(id -> {
+ guildMapping.putIfAbsent(id, new HashSet<>());
+ guildMapping.get(id).add(command);
+ });
+ }
+ return guildMapping;
}
}
From fce1488337f6b585edd90aaf351187f3bb1214a1 Mon Sep 17 00:00:00 2001
From: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
Date: Fri, 29 Nov 2024 20:17:02 +0100
Subject: [PATCH 11/38] improve documentation
---
.../jda/commands/reflect/InteractionRegistry.java | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java
index 2c66e5cd3..5d41a5f4a 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java
@@ -129,7 +129,8 @@ public Set getInteractionControllers() {
}
/**
- * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}.
+ * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}, this includes both
+ * {@link SlashCommandDefinition} and {@link ContextCommandDefinition}.
*
* @return a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}
*/
@@ -138,9 +139,9 @@ public Set getCommands() {
}
/**
- * Gets a possibly-empty list of all {@link SlashCommandDefinition CommandDefinitions}.
+ * Gets a possibly-empty list of all {@link SlashCommandDefinition SlashCommandDefinitions}.
*
- * @return a possibly-empty list of all {@link SlashCommandDefinition CommandDefinitions}
+ * @return a possibly-empty list of all {@link SlashCommandDefinition SlashCommandDefinitions}
*/
public Set getSlashCommands() {
return commands.stream().filter(it -> (it.getCommandType() == Command.Type.SLASH))
@@ -149,9 +150,9 @@ public Set getSlashCommands() {
}
/**
- * Gets a possibly-empty list of all {@link ContextCommandDefinition CommandDefinitions}.
+ * Gets a possibly-empty list of all {@link ContextCommandDefinition ContextCommandDefinitions}.
*
- * @return a possibly-empty list of all {@link ContextCommandDefinition CommandDefinitions}
+ * @return a possibly-empty list of all {@link ContextCommandDefinition ContextCommandDefinitions}
*/
public Set getContextCommands() {
return commands.stream().filter(it ->
From c1ab4dfe5b8c8d06baf120c44bf0f35d4602b728 Mon Sep 17 00:00:00 2001
From: Nick Hensel <47005420+Goldmensch@users.noreply.github.com>
Date: Wed, 4 Dec 2024 21:27:16 +0100
Subject: [PATCH 12/38] Bump to java 23 and refactoring (#140)
* Refactor part of reflect package and JDACommands.java
* fix compile errors and unit tests
* fix incorrect java version in ci
* bump jacoco version
* remove isActive functionality
* fix auto complete dispatching
* move parameter validation to helper methods
* Make AutoCompleteDefinition and SlashCommandDefinition immutable
* Refactor tree
* fix unit tests
* make getComponent methods accessible again
* fix CommandTree printing
* remove unnecessary generic type from GenericEvent
* fix unit tests
* unify functional interfaces
* refactor reply
* change Helpers class and fix unit tests
* formatting
* formatting
---------
Co-authored-by: Kaktushose <42280757+Kaktushose@users.noreply.github.com>
---
.envrc | 1 +
.github/workflows/ci.yml | 10 +-
flake.lock | 58 ++++
flake.nix | 37 +++
pom.xml | 6 +-
.../kaktushose/jda/commands/Helpers.java | 91 ++++++
.../kaktushose/jda/commands/JDACommands.java | 246 ++++------------
.../kaktushose/jda/commands/JDAContext.java | 87 ++----
.../jda/commands/SlashCommandUpdater.java | 12 +-
.../interactions/ContextCommand.java | 7 -
.../annotations/interactions/Interaction.java | 9 +-
.../interactions/SlashCommand.java | 7 -
.../jda/commands/data/CommandTree.java | 10 +-
.../jda/commands/data/EmbedCache.java | 5 +-
.../jda/commands/data/TreeNode.java | 13 +-
.../dependency/DependencyInjector.java | 2 +-
.../dispatching/DispatcherSupervisor.java | 30 +-
.../dispatching/RuntimeSupervisor.java | 2 +-
.../dispatching/adapter/TypeAdapter.java | 21 +-
.../adapter/TypeAdapterRegistry.java | 16 +-
.../adapter/impl/AudioChannelAdapter.java | 26 +-
.../adapter/impl/BooleanAdapter.java | 2 +-
.../dispatching/adapter/impl/ByteAdapter.java | 2 +-
.../adapter/impl/CharacterAdapter.java | 2 +-
.../adapter/impl/DoubleAdapter.java | 2 +-
.../adapter/impl/FloatAdapter.java | 2 +-
.../adapter/impl/GuildChannelAdapter.java | 20 +-
.../impl/GuildMessageChannelAdapter.java | 26 +-
.../adapter/impl/IntegerAdapter.java | 2 +-
.../dispatching/adapter/impl/LongAdapter.java | 2 +-
.../adapter/impl/MemberAdapter.java | 5 +-
.../adapter/impl/NewsChannelAdapter.java | 18 +-
.../dispatching/adapter/impl/RoleAdapter.java | 5 +-
.../adapter/impl/ShortAdapter.java | 2 +-
.../adapter/impl/StageChannelAdapter.java | 18 +-
.../adapter/impl/TextChannelAdapter.java | 18 +-
.../adapter/impl/ThreadChannelAdapter.java | 18 +-
.../dispatching/adapter/impl/UserAdapter.java | 5 +-
.../adapter/impl/VoiceChannelAdapter.java | 18 +-
.../dispatching/interactions/Context.java | 54 +---
.../interactions/GenericDispatcher.java | 51 ++--
.../interactions/GenericEvent.java | 75 ++---
.../autocomplete/AutoCompleteDispatcher.java | 20 +-
.../autocomplete/AutoCompleteEvent.java | 8 +-
.../commands/CommandDispatcher.java | 30 +-
.../interactions/commands/CommandEvent.java | 8 +-
.../commands/SlashCommandContext.java | 10 +-
.../components/ComponentDispatcher.java | 21 +-
.../components/ComponentEvent.java | 8 +-
.../interactions/modals/ModalDispatcher.java | 17 +-
.../interactions/modals/ModalEvent.java | 8 +-
.../dispatching/middleware/Middleware.java | 7 +-
.../middleware/MiddlewareRegistry.java | 13 +-
.../middleware/impl/ConstraintMiddleware.java | 8 +-
.../middleware/impl/CooldownMiddleware.java | 4 +-
.../impl/PermissionsMiddleware.java | 2 +-
.../dispatching/reply/ModalReplyable.java | 2 +-
.../commands/dispatching/reply/Replyable.java | 24 +-
.../dispatching/reply/components/Buttons.java | 55 +---
.../reply/components/Component.java | 2 +-
.../reply/components/SelectMenus.java | 18 +-
.../dispatching/validation/Validator.java | 3 +-
.../validation/impl/MaximumValidator.java | 2 +-
.../validation/impl/MinimumValidator.java | 2 +-
.../impl/NotPermissionValidator.java | 2 +-
.../validation/impl/NotRoleValidator.java | 4 +-
.../validation/impl/NotUserValidator.java | 4 +-
.../validation/impl/PermissionValidator.java | 2 +-
.../validation/impl/RoleValidator.java | 4 +-
.../validation/impl/UserValidator.java | 4 +-
.../embeds/DefaultErrorMessageFactory.java | 6 +-
.../embeds/JsonErrorMessageFactory.java | 10 +-
.../reflect/ConstraintDefinition.java | 54 +---
.../commands/reflect/CooldownDefinition.java | 69 +----
.../InteractionControllerDefinition.java | 269 ++++++------------
.../commands/reflect/InteractionRegistry.java | 114 +++-----
.../commands/reflect/MethodBuildContext.java | 22 ++
.../commands/reflect/ParameterDefinition.java | 236 ++++-----------
.../commands/reflect/TextInputDefinition.java | 101 +------
.../interactions/AutoCompleteDefinition.java | 48 +---
.../EphemeralInteractionDefinition.java | 5 +-
.../GenericInteractionDefinition.java | 2 +-
.../reflect/interactions/ModalDefinition.java | 27 +-
.../commands/ContextCommandDefinition.java | 50 ++--
.../commands/GenericCommandDefinition.java | 26 +-
.../commands/SlashCommandDefinition.java | 133 ++++-----
.../components/ButtonDefinition.java | 66 ++---
.../GenericComponentDefinition.java | 3 +-
.../menus/EntitySelectMenuDefinition.java | 82 +++---
.../menus/GenericSelectMenuDefinition.java | 2 +-
.../menus/SelectOptionDefinition.java | 81 +-----
.../menus/StringSelectMenuDefinition.java | 74 ++---
.../scope/DefaultGuildScopeProvider.java | 3 +-
.../commands/scope/GuildScopeProvider.java | 6 +-
src/main/java/module-info.java | 9 +
src/test/java/adapting/CustomTypeAdapter.java | 2 +-
.../adapting/TypeAdapterRegistryTest.java | 42 ++-
src/test/java/adapting/TypeAdapterTest.java | 147 +++++-----
src/test/java/adapting/mock/GuildMock.java | 10 +-
.../java/adapting/mock/JDACommandsMock.java | 28 +-
.../CommandDefinitionTestController.java | 5 -
.../commands/SlashCommandDefinitionTest.java | 76 ++---
.../InteractionControllerDefinitionTest.java | 41 ++-
.../parameters/ParameterDefinitionTest.java | 16 +-
104 files changed, 1233 insertions(+), 1967 deletions(-)
create mode 100644 .envrc
create mode 100644 flake.lock
create mode 100644 flake.nix
create mode 100644 src/main/java/com/github/kaktushose/jda/commands/Helpers.java
create mode 100644 src/main/java/com/github/kaktushose/jda/commands/reflect/MethodBuildContext.java
create mode 100644 src/main/java/module-info.java
diff --git a/.envrc b/.envrc
new file mode 100644
index 000000000..8392d159f
--- /dev/null
+++ b/.envrc
@@ -0,0 +1 @@
+use flake
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b7b48e9a6..516aef305 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,7 +2,7 @@ name: Java CI
on:
push:
- branches: [ main, development, release/* ]
+ branches: [ main, development, release/*, feature/*, bump-to-java-23 ]
pull_request:
branches: [ main, development, release/* ]
@@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - name: Set up JDK 11
- uses: actions/setup-java@v1
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
with:
- java-version: 11
+ distribution: 'temurin'
+ java-version: '23'
- name: Build with Maven
run: mvn -B package --file pom.xml
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 000000000..413c1f80b
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,58 @@
+{
+ "nodes": {
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1730504689,
+ "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "506278e768c2a08bec68eb62932193e341f55c90",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1733064805,
+ "narHash": "sha256-7NbtSLfZO0q7MXPl5hzA0sbVJt6pWxxtGWbaVUDDmjs=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "31d66ae40417bb13765b0ad75dd200400e98de84",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "lastModified": 1730504152,
+ "narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=",
+ "type": "tarball",
+ "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 000000000..7ecec0e01
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,37 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ };
+
+ outputs = {
+ self,
+ flake-parts,
+ ...
+ } @ inputs:
+ flake-parts.lib.mkFlake {inherit inputs;} {
+ systems = ["x86_64-linux"];
+
+ perSystem = {
+ config,
+ lib,
+ pkgs,
+ system,
+ ...
+ }: let
+ javaVersion = 23;
+
+ jdk = pkgs."temurin-bin-${toString javaVersion}";
+ gradle = pkgs.gradle.override {
+ javaToolchains = [
+ jdk
+ ];
+ };
+ in {
+ devShells.default = pkgs.mkShell {
+ name = "Jack";
+ packages = with pkgs; [git jdk gradle maven];
+ };
+ };
+ };
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ac3c0ae15..891c26d86 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,8 +19,8 @@
maven-compiler-plugin
3.10.1
- 11
- 11
+ 23
+ 23
-parameters
@@ -43,7 +43,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.8
+ 0.8.12
diff --git a/src/main/java/com/github/kaktushose/jda/commands/Helpers.java b/src/main/java/com/github/kaktushose/jda/commands/Helpers.java
new file mode 100644
index 000000000..e78e8649f
--- /dev/null
+++ b/src/main/java/com/github/kaktushose/jda/commands/Helpers.java
@@ -0,0 +1,91 @@
+package com.github.kaktushose.jda.commands;
+
+import com.github.kaktushose.jda.commands.annotations.interactions.Permissions;
+import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
+import com.github.kaktushose.jda.commands.reflect.MethodBuildContext;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+public final class Helpers {
+
+ private static final Logger log = LoggerFactory.getLogger(Helpers.class);
+
+ /**
+ * Sanitizes a String containing a raw mention. This will remove all markdown characters namely < @ # & ! >
+ * For instance: {@code <@!393843637437464588>} gets sanitized to {@code 393843637437464588}
+ *
+ * @param mention the raw String to sanitize
+ * @return the sanitized String
+ */
+ public static String sanitizeMention(@NotNull String mention) {
+ if (mention.matches("<[@#][&!]?([0-9]{4,})>")) {
+ return mention.replaceAll("<[@#][&!]?", "").replace(">", "");
+ }
+ return mention;
+ }
+
+ public static Optional resolveGuildChannel(Context context, String raw) {
+ GuildChannel guildChannel;
+ raw = sanitizeMention(raw);
+
+ Guild guild = context.getEvent().getGuild();
+ if (raw.matches("\\d+")) {
+ guildChannel = guild.getGuildChannelById(raw);
+ } else {
+ String finalRaw = raw;
+ guildChannel = guild.getChannels().stream().filter(it -> it.getName().equalsIgnoreCase(finalRaw))
+ .findFirst().orElse(null);
+ }
+ return Optional.ofNullable(guildChannel);
+ }
+
+ public static Set permissions(MethodBuildContext context) {
+ Permissions permission = context.method().getAnnotation(Permissions.class);
+
+ if (permission != null) {
+ HashSet mergedPermissions = new HashSet<>(context.permissions());
+ mergedPermissions.addAll(Set.of(permission.value()));
+ return Collections.unmodifiableSet(mergedPermissions);
+ }
+ return context.permissions();
+ }
+
+ public static boolean ephemeral(MethodBuildContext context, boolean localEphemeral) {
+ return context.interaction().ephemeral() || localEphemeral;
+ }
+
+ public static boolean isIncorrectParameterType(Method method, int index, Class> type) {
+ if (!type.isAssignableFrom(method.getParameters()[index].getType())) {
+ log.error("An error has occurred! Skipping Interaction {}.{}:",
+ method.getDeclaringClass().getSimpleName(),
+ method.getName(),
+ new IllegalArgumentException(String.format("%d. parameter must be of type %s", index + 1, type.getSimpleName())));
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isIncorrectParameterAmount(Method method, int amount) {
+ if (method.getParameters().length != amount) {
+ log.error("An error has occurred! Skipping Interaction {}.{}:",
+ method.getDeclaringClass().getSimpleName(),
+ method.getName(),
+ new IllegalArgumentException(String.format(
+ "Invalid amount of parameters!. Expected: %d Actual: %d",
+ amount,
+ method.getParameters().length
+ )));
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
index e1165047e..33864f8e1 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/JDACommands.java
@@ -21,70 +21,57 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
- * Represents an active instance of this framework and provides access to all underlying classes.
- *
- * @since 1.0.0
- */
-public class JDACommands {
+public record JDACommands(
+ JDAContext jdaContext,
+ DispatcherSupervisor dispatcherSupervisor,
+ MiddlewareRegistry middlewareRegistry,
+ TypeAdapterRegistry adapterRegistry,
+ ValidatorRegistry validatorRegistry,
+ DependencyInjector dependencyInjector,
+ InteractionRegistry interactionRegistry,
+ SlashCommandUpdater updater,
+ RuntimeSupervisor runtimeSupervisor
+) {
private static final Logger log = LoggerFactory.getLogger(JDACommands.class);
- private static boolean isActive;
- private final JDAContext jdaContext;
- private final ImplementationRegistry implementationRegistry;
- private final DispatcherSupervisor dispatcherSupervisor;
- private final MiddlewareRegistry middlewareRegistry;
- private final TypeAdapterRegistry adapterRegistry;
- private final ValidatorRegistry validatorRegistry;
- private final DependencyInjector dependencyInjector;
- private final InteractionRegistry interactionRegistry;
- private final SlashCommandUpdater updater;
- private final RuntimeSupervisor runtimeSupervisor;
-
- // this is needed for unit testing
- protected JDACommands() {
- jdaContext = null;
- implementationRegistry = null;
- runtimeSupervisor = null;
- middlewareRegistry = null;
- adapterRegistry = null;
- validatorRegistry = null;
- dependencyInjector = null;
- dispatcherSupervisor = null;
- interactionRegistry = null;
- updater = null;
- }
- private JDACommands(Object jda, Class> clazz, LocalizationFunction function, DependencyInjector injector, String... packages) {
+ private static JDACommands startInternal(Object jda, Class> clazz, LocalizationFunction function, DependencyInjector dependencyInjector, String... packages) {
log.info("Starting JDA-Commands...");
- if (isActive) {
- throw new IllegalStateException("An instance of the command framework is already running!");
- }
-
- jdaContext = new JDAContext(jda);
- dependencyInjector = injector;
+ var jdaContext = new JDAContext(jda);
dependencyInjector.index(clazz, packages);
- middlewareRegistry = new MiddlewareRegistry();
- adapterRegistry = new TypeAdapterRegistry();
- validatorRegistry = new ValidatorRegistry();
- implementationRegistry = new ImplementationRegistry(dependencyInjector, middlewareRegistry, adapterRegistry, validatorRegistry);
- interactionRegistry = new InteractionRegistry(validatorRegistry, dependencyInjector, function);
+ var middlewareRegistry = new MiddlewareRegistry();
+ var adapterRegistry = new TypeAdapterRegistry();
+ var validatorRegistry = new ValidatorRegistry();
+ var implementationRegistry = new ImplementationRegistry(dependencyInjector, middlewareRegistry, adapterRegistry, validatorRegistry);
+ var interactionRegistry = new InteractionRegistry(validatorRegistry, dependencyInjector, function);
- runtimeSupervisor = new RuntimeSupervisor(dependencyInjector);
- dispatcherSupervisor = new DispatcherSupervisor(this);
+ var runtimeSupervisor = new RuntimeSupervisor(dependencyInjector);
+ var dispatcherSupervisor = new DispatcherSupervisor(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor);
implementationRegistry.index(clazz, packages);
interactionRegistry.index(clazz, packages);
- updater = new SlashCommandUpdater(this);
+ var updater = new SlashCommandUpdater(jdaContext, implementationRegistry.getGuildScopeProvider(), interactionRegistry);
updater.updateAllCommands();
+
jdaContext.performTask(it -> it.addEventListener(dispatcherSupervisor));
- isActive = true;
log.info("Finished loading!");
+
+ return new JDACommands(
+ jdaContext,
+ dispatcherSupervisor,
+ middlewareRegistry,
+ adapterRegistry,
+ validatorRegistry,
+ dependencyInjector,
+ interactionRegistry,
+ updater,
+ runtimeSupervisor
+ );
}
/**
@@ -96,7 +83,7 @@ private JDACommands(Object jda, Class> clazz, LocalizationFunction function, D
* @return a new JDACommands instance
*/
public static JDACommands start(@NotNull JDA jda, @NotNull Class> clazz, @NotNull String... packages) {
- return new JDACommands(jda, clazz, ResourceBundleLocalizationFunction.empty().build(), new DefaultDependencyInjector(), packages);
+ return startInternal(jda, clazz, ResourceBundleLocalizationFunction.empty().build(), new DefaultDependencyInjector(), packages);
}
/**
@@ -108,7 +95,7 @@ public static JDACommands start(@NotNull JDA jda, @NotNull Class> clazz, @NotN
* @return a new JDACommands instance
*/
public static JDACommands start(@NotNull ShardManager shardManager, @NotNull Class> clazz, @NotNull String... packages) {
- return new JDACommands(shardManager, clazz, ResourceBundleLocalizationFunction.empty().build(), new DefaultDependencyInjector(), packages);
+ return startInternal(shardManager, clazz, ResourceBundleLocalizationFunction.empty().build(), new DefaultDependencyInjector(), packages);
}
/**
@@ -121,7 +108,7 @@ public static JDACommands start(@NotNull ShardManager shardManager, @NotNull Cla
* @return a new JDACommands instance
*/
public static JDACommands start(@NotNull JDA jda, @NotNull Class> clazz, LocalizationFunction function, @NotNull String... packages) {
- return new JDACommands(jda, clazz, function, new DefaultDependencyInjector(), packages);
+ return startInternal(jda, clazz, function, new DefaultDependencyInjector(), packages);
}
/**
@@ -134,7 +121,7 @@ public static JDACommands start(@NotNull JDA jda, @NotNull Class> clazz, Local
* @return a new JDACommands instance
*/
public static JDACommands start(@NotNull ShardManager shardManager, @NotNull Class> clazz, LocalizationFunction function, @NotNull String... packages) {
- return new JDACommands(shardManager, clazz, function, new DefaultDependencyInjector(), packages);
+ return startInternal(shardManager, clazz, function, new DefaultDependencyInjector(), packages);
}
/**
@@ -148,7 +135,7 @@ public static JDACommands start(@NotNull ShardManager shardManager, @NotNull Cla
* @return a new JDACommands instance
*/
public static JDACommands start(@NotNull JDA jda, @NotNull Class> clazz, LocalizationFunction function, DependencyInjector injector, @NotNull String... packages) {
- return new JDACommands(jda, clazz, function, injector, packages);
+ return startInternal(jda, clazz, function, injector, packages);
}
/**
@@ -162,16 +149,7 @@ public static JDACommands start(@NotNull JDA jda, @NotNull Class> clazz, Local
* @return a new JDACommands instance
*/
public static JDACommands start(@NotNull ShardManager shardManager, @NotNull Class> clazz, LocalizationFunction function, DependencyInjector injector, @NotNull String... packages) {
- return new JDACommands(shardManager, clazz, function, injector, packages);
- }
-
- /**
- * Whether this JDACommands instance is active.
- *
- * @return {@code true} if the JDACommands instance is active
- */
- public static boolean isActive() {
- return isActive;
+ return startInternal(shardManager, clazz, function, injector, packages);
}
/**
@@ -180,28 +158,15 @@ public static boolean isActive() {
*/
public void shutdown() {
jdaContext.performTask(jda -> jda.removeEventListener(dispatcherSupervisor));
- isActive = false;
- }
-
- /**
- * Gets the {@link DispatcherSupervisor}.
- *
- * @return the {@link DispatcherSupervisor}
- */
- public DispatcherSupervisor getDispatcherSupervisor() {
- return dispatcherSupervisor;
}
/**
* Updates all slash commands that are registered with
* {@link com.github.kaktushose.jda.commands.annotations.interactions.SlashCommand.CommandScope#GUILD
* CommandScope#Guild}
- *
- * @return this instance
*/
- public JDACommands updateGuildCommands() {
+ public void updateGuildCommands() {
updater.updateGuildCommands();
- return this;
}
/**
@@ -272,7 +237,8 @@ public Button getButton(String button, String runtimeId) {
* @param selectMenu the id of the selectMenu
* @return a JDA {@link SelectMenu}
*/
- public SelectMenu getSelectMenu(String selectMenu) {
+ @SuppressWarnings("unchecked")
+ public T getSelectMenu(String selectMenu) {
if (!selectMenu.matches("[a-zA-Z]+\\.[a-zA-Z]+")) {
throw new IllegalArgumentException("Unknown Select Menu");
}
@@ -283,43 +249,28 @@ public SelectMenu getSelectMenu(String selectMenu) {
.findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Select Menu"));
RuntimeSupervisor.InteractionRuntime runtime = runtimeSupervisor.newRuntime(selectMenuDefinition);
- return selectMenuDefinition.toSelectMenu(runtime.getRuntimeId(), true);
+ return (T) selectMenuDefinition.toSelectMenu(runtime.getRuntimeId(), true);
}
/**
- * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id.
- *
- *
- * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
- * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
- * {@code ExampleMenu.onSelectMenu}.
- *
- *
- * @param selectMenu the id of the selectMenu
- * @param clazz the subtype of {@link SelectMenu}
- * @return a JDA {@link SelectMenu}
- */
- public T getSelectMenu(String selectMenu, Class clazz) {
- return (T) getSelectMenu(selectMenu);
- }
-
- /**
- * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id and links it an
+ * Gets a JDA {@link SelectMenu} subtype to use it for message builders based on the jda-commands id and links it an
* existing
* {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}.
*
*
- * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * The id is made up of the simple class name and the method name. E.g. the id of a select menu defined by a
* {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
* {@code ExampleMenu.onSelectMenu}.
*
*
* @param selectMenu the id of the selectMenu
* @param runtimeId the id of the
- * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}
+ * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime
+ * InteractionRuntime}
* @return a JDA {@link SelectMenu}
*/
- public SelectMenu getSelectMenu(String selectMenu, String runtimeId) {
+ @SuppressWarnings("unchecked")
+ public T getSelectMenu(String selectMenu, String runtimeId) {
if (!selectMenu.matches("[a-zA-Z]+\\.[a-zA-Z]+")) {
throw new IllegalArgumentException("Unknown Select Menu");
}
@@ -329,101 +280,6 @@ public SelectMenu getSelectMenu(String selectMenu, String runtimeId) {
.filter(it -> it.getDefinitionId().equals(sanitizedId))
.findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Select Menu"));
- return selectMenuDefinition.toSelectMenu(runtimeId, true);
- }
-
- /**
- * Gets a JDA {@link SelectMenu} subtype to use it for message builders based on the jda-commands id and links it an
- * existing
- * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime InteractionRuntime}.
- *
- *
- * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
- * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
- * {@code ExampleMenu.onSelectMenu}.
- *
- *
- * @param selectMenu the id of the selectMenu
- * @param runtimeId the id of the
- * {@link com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime
- * InteractionRuntime}
- * @param clazz the subtype of {@link SelectMenu}
- * @return a JDA {@link SelectMenu}
- */
- public T getSelectMenu(String selectMenu, String runtimeId, Class clazz) {
- return (T) getSelectMenu(selectMenu, runtimeId);
- }
-
- /**
- * Gets the {@link ImplementationRegistry}.
- *
- * @return the {@link ImplementationRegistry}
- */
- public ImplementationRegistry getImplementationRegistry() {
- return implementationRegistry;
- }
-
-
- /**
- * Gets the {@link RuntimeSupervisor}
- *
- * @return the {@link RuntimeSupervisor}
- */
- public RuntimeSupervisor getRuntimeSupervisor() {
- return runtimeSupervisor;
- }
-
- /**
- * Gets the {@link TypeAdapterRegistry}.
- *
- * @return the {@link TypeAdapterRegistry}
- */
- public TypeAdapterRegistry getAdapterRegistry() {
- return adapterRegistry;
- }
-
- /**
- * Gets the {@link ValidatorRegistry}.
- *
- * @return the {@link ValidatorRegistry}
- */
- public ValidatorRegistry getValidatorRegistry() {
- return validatorRegistry;
- }
-
- /**
- * Gets the {@link InteractionRegistry}.
- *
- * @return the {@link InteractionRegistry}
- */
- public InteractionRegistry getInteractionRegistry() {
- return interactionRegistry;
- }
-
- /**
- * Gets the {@link JDAContext}.
- *
- * @return the JDAContext.
- */
- public JDAContext getJDAContext() {
- return jdaContext;
- }
-
- /**
- * Gets the {@link MiddlewareRegistry}.
- *
- * @return the {@link MiddlewareRegistry}
- */
- public MiddlewareRegistry getMiddlewareRegistry() {
- return middlewareRegistry;
- }
-
- /**
- * Gets the {@link DependencyInjector}.
- *
- * @return the {@link DependencyInjector}
- */
- public DependencyInjector getDependencyInjector() {
- return dependencyInjector;
+ return (T) selectMenuDefinition.toSelectMenu(runtimeId, true);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/JDAContext.java b/src/main/java/com/github/kaktushose/jda/commands/JDAContext.java
index e1a8aa0a8..612ccf373 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/JDAContext.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/JDAContext.java
@@ -4,6 +4,7 @@
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.sharding.ShardManager;
import net.dv8tion.jda.api.utils.cache.SnowflakeCacheView;
+import org.jetbrains.annotations.ApiStatus;
import java.util.List;
import java.util.function.Consumer;
@@ -14,17 +15,18 @@
*
* @since 2.3.0
*/
-public class JDAContext {
+@ApiStatus.Internal
+public final class JDAContext {
- private final Object jda;
+ private final Object context;
/**
* Constructs a new JDAContext.
*
- * @param jda the {@link JDA} or {@link ShardManager} object
+ * @param context the {@link JDA} or {@link ShardManager} object
*/
- public JDAContext(Object jda) {
- this.jda = jda;
+ public JDAContext(Object context) {
+ this.context = context;
}
/**
@@ -33,35 +35,14 @@ public JDAContext(Object jda) {
* @param consumer the operation to perform
*/
public void performTask(Consumer consumer) {
- if (jda instanceof ShardManager) {
- ((ShardManager) jda).getShardCache().forEach(consumer);
- } else if (jda instanceof JDA) {
- consumer.accept((JDA) jda);
- } else {
- throw new IllegalArgumentException(String.format("Cannot cast %s", jda.getClass().getSimpleName()));
+ switch (context) {
+ case ShardManager shardManager -> shardManager.getShardCache().forEach(consumer);
+ case JDA jda -> consumer.accept(jda);
+ default ->
+ throw new IllegalArgumentException(String.format("Cannot cast %s", context.getClass().getSimpleName()));
}
}
- /**
- * Gets the JDA instance as an Object. This can either be {@link JDA} or a {@link ShardManager}.
- * Use {@link #isShardManager()} to distinguish.
- *
- * @return the JDA instance.
- */
- public Object getJDAObject() {
- return jda;
- }
-
- /**
- * Whether the JDA instance is a {@link ShardManager}.
- *
- * @return {@code true} if the JDA instance is a {@link ShardManager}
- * @deprecated
- */
- public boolean isShardManager() {
- return jda instanceof ShardManager;
- }
-
/**
* An unmodifiable List of all {@link Guild Guilds} that the logged account is connected to.
* If this account is not connected to any {@link Guild Guilds}, this will return an empty list.
@@ -72,13 +53,12 @@ public boolean isShardManager() {
* @return Possibly-empty list of all the {@link Guild Guilds} that this account is connected to.
*/
public List getGuilds() {
- if (jda instanceof ShardManager) {
- return ((ShardManager) jda).getGuilds();
- } else if (jda instanceof JDA) {
- return ((JDA) jda).getGuilds();
- } else {
- throw new IllegalArgumentException(String.format("Cannot cast %s", jda.getClass().getSimpleName()));
- }
+ return switch (context) {
+ case ShardManager shardManager -> shardManager.getGuilds();
+ case JDA jda -> jda.getGuilds();
+ default ->
+ throw new IllegalArgumentException(String.format("Cannot cast %s", context.getClass().getSimpleName()));
+ };
}
/**
@@ -87,30 +67,11 @@ public List getGuilds() {
* @return {@link SnowflakeCacheView}
*/
public SnowflakeCacheView getGuildCache() {
- if (jda instanceof ShardManager) {
- return ((ShardManager) jda).getGuildCache();
- } else if (jda instanceof JDA) {
- return ((JDA) jda).getGuildCache();
- } else {
- throw new IllegalArgumentException(String.format("Cannot cast %s", jda.getClass().getSimpleName()));
- }
- }
-
- /**
- * Gets the JDA instance as {@link JDA}.
- *
- * @return the JDA instance as {@link JDA}
- */
- public JDA getAsJDA() {
- return (JDA) jda;
- }
-
- /**
- * Gets the JDA instance as {@link ShardManager}.
- *
- * @return the JDA instance as {@link ShardManager}
- */
- public ShardManager getAsShardManager() {
- return (ShardManager) jda;
+ return switch (context) {
+ case ShardManager shardManager -> shardManager.getGuildCache();
+ case JDA jda -> jda.getGuildCache();
+ default ->
+ throw new IllegalArgumentException(String.format("Cannot cast %s", context.getClass().getSimpleName()));
+ };
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
index ccbe5ea52..b3be2c4b2 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/SlashCommandUpdater.java
@@ -32,13 +32,11 @@ public class SlashCommandUpdater {
/**
* Constructs a new SlashCommandUpdater.
- *
- * @param jdaCommands the corresponding {@link JDACommands} instance
*/
- public SlashCommandUpdater(JDACommands jdaCommands) {
- this.jdaContext = jdaCommands.getJDAContext();
- guildScopeProvider = jdaCommands.getImplementationRegistry().getGuildScopeProvider();
- interactionRegistry = jdaCommands.getInteractionRegistry();
+ public SlashCommandUpdater(JDAContext jdaContext, GuildScopeProvider guildScopeProvider, InteractionRegistry interactionRegistry) {
+ this.jdaContext = jdaContext;
+ this.guildScopeProvider = guildScopeProvider;
+ this.interactionRegistry = interactionRegistry;
}
/**
@@ -120,7 +118,7 @@ private Map> getGuildMapping() {
Map> guildMapping = new HashMap<>();
for (CommandData command : result) {
// create a copy so that a user doesn't modify the command data used for registration
- Set guildIds = guildScopeProvider.getGuildsForCommand(CommandData.fromData(command.toData()));
+ Set guildIds = guildScopeProvider.apply(CommandData.fromData(command.toData()));
if (guildIds.isEmpty()) {
log.debug("No guilds provided for command \"{}\"", command.getName());
} else {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java
index f99449093..5dbf518d9 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/ContextCommand.java
@@ -41,13 +41,6 @@
*/
boolean isGuildOnly() default false;
- /**
- * Returns whether this command is active and thus can be executed or not.
- *
- * @return {@code true} if this command is active
- */
- boolean isActive() default true;
-
/**
* Returns whether this command can only be executed in NSFW channels.
*
diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Interaction.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Interaction.java
index a732ce9a9..608b708b7 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Interaction.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/Interaction.java
@@ -7,7 +7,7 @@
/**
* Classes annotated with Interaction will be scanned at startup and are eligible for defining interactions such as
- * slash commands, buttons, modals or context menus.
+ * slash commands, buttonContainers, modals or context menus.
*
* @since 4.0.0
*/
@@ -22,13 +22,6 @@
*/
String value() default "";
- /**
- * Returns whether this interaction is active and thus can be executed or not
- *
- * @return {@code true} if this interaction is active
- */
- boolean isActive() default true;
-
/**
* Returns whether this interaction should send ephemeral replies by default.
*
diff --git a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SlashCommand.java b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SlashCommand.java
index f82920fb1..8a5792b05 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SlashCommand.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/annotations/interactions/SlashCommand.java
@@ -52,13 +52,6 @@
*/
String desc() default "N/A";
- /**
- * Returns whether this command is active and thus can be executed or not.
- *
- * @return {@code true} if this command is active
- */
- boolean isActive() default true;
-
/**
* Returns whether this command can only be executed in NSFW channels.
*
diff --git a/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java b/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java
index d97eaebec..e82ed4a24 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/data/CommandTree.java
@@ -14,22 +14,22 @@
* @see Discord Subcommands and Subcommand Groups Documentation
* @since 2.3.0
*/
-public class CommandTree {
-
- private final TreeNode root;
+public record CommandTree(
+ TreeNode root
+) {
/**
* Constructs an empty CommandTree.
*/
public CommandTree() {
- root = new TreeNode();
+ this(new TreeNode());
}
/**
* Constructs a new CommandTree.
*/
public CommandTree(Collection commands) {
- root = new TreeNode();
+ this(new TreeNode());
addAll(commands);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/data/EmbedCache.java b/src/main/java/com/github/kaktushose/jda/commands/data/EmbedCache.java
index b833daf7f..34c769c34 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/data/EmbedCache.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/data/EmbedCache.java
@@ -27,7 +27,7 @@ public class EmbedCache {
private static final Gson gson = new Gson();
private final File file;
private final InputStream stream;
- private Map embedMap;
+ private final Map embedMap;
/**
* Constructs a new EmbedCache object.
@@ -93,7 +93,8 @@ public void loadEmbeds() {
JsonReader jsonReader = new JsonReader(reader);
Type type = new TypeToken>() {
}.getType();
- embedMap = gson.fromJson(jsonReader, type);
+ embedMap.clear();
+ embedMap.putAll(gson.fromJson(jsonReader, type));
} catch (FileNotFoundException | JsonIOException | JsonSyntaxException e) {
log.error("An error has occurred while loading the file!", e);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java b/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java
index b37acc9f0..7fa68c38b 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/data/TreeNode.java
@@ -21,12 +21,13 @@
* @see CommandTree
* @since 2.3.0
*/
-public class TreeNode implements Iterable {
+public record TreeNode(
+ String name,
+ SlashCommandDefinition command,
+ List children
+) implements Iterable {
private static final Logger log = LoggerFactory.getLogger(SlashCommandUpdater.class);
- private final String name;
- private final SlashCommandDefinition command;
- private final List children;
/**
* Constructs an empty TreeNode. Should only be used for root nodes.
@@ -42,9 +43,7 @@ public TreeNode() {
* @param command the {@link SlashCommandDefinition}
*/
public TreeNode(@NotNull String name, @Nullable SlashCommandDefinition command) {
- this.name = name;
- this.command = command;
- children = new ArrayList<>();
+ this(name, command, new ArrayList<>());
}
/**
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dependency/DependencyInjector.java b/src/main/java/com/github/kaktushose/jda/commands/dependency/DependencyInjector.java
index 57d5b7e1c..937db317e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dependency/DependencyInjector.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dependency/DependencyInjector.java
@@ -47,5 +47,5 @@ public interface DependencyInjector {
* Injects all registered dependencies with the corresponding value. If no value is present {@code null} gets injected.
*/
void inject(Object instance);
-
}
+
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java
index 34dcd9b90..1eba503bc 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/DispatcherSupervisor.java
@@ -1,6 +1,6 @@
package com.github.kaktushose.jda.commands.dispatching;
-import com.github.kaktushose.jda.commands.JDACommands;
+import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher;
import com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete.AutoCompleteDispatcher;
@@ -8,6 +8,9 @@
import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext;
import com.github.kaktushose.jda.commands.dispatching.interactions.components.ComponentDispatcher;
import com.github.kaktushose.jda.commands.dispatching.interactions.modals.ModalDispatcher;
+import com.github.kaktushose.jda.commands.dispatching.middleware.MiddlewareRegistry;
+import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
@@ -33,18 +36,20 @@ public class DispatcherSupervisor extends ListenerAdapter {
private static final Logger log = LoggerFactory.getLogger(DispatcherSupervisor.class);
private final Map, GenericDispatcher> dispatchers;
- private final JDACommands jdaCommands;
+ private final InteractionRegistry interactionRegistry;
+ private final ImplementationRegistry implementationRegistry;
/**
* Constructs a new DispatcherSupervisor.
*/
- public DispatcherSupervisor(JDACommands jdaCommands) {
- this.jdaCommands = jdaCommands;
+ public DispatcherSupervisor(MiddlewareRegistry middlewareRegistry, ImplementationRegistry implementationRegistry, InteractionRegistry interactionRegistry, TypeAdapterRegistry adapterRegistry, RuntimeSupervisor runtimeSupervisor) {
dispatchers = new HashMap<>();
- register(GenericCommandInteractionEvent.class, new CommandDispatcher(jdaCommands));
- register(CommandAutoCompleteInteractionEvent.class, new AutoCompleteDispatcher(jdaCommands));
- register(GenericComponentInteractionCreateEvent.class, new ComponentDispatcher(jdaCommands));
- register(ModalInteractionEvent.class, new ModalDispatcher(jdaCommands));
+ register(GenericCommandInteractionEvent.class, new CommandDispatcher(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor));
+ register(CommandAutoCompleteInteractionEvent.class, new AutoCompleteDispatcher(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor));
+ register(GenericComponentInteractionCreateEvent.class, new ComponentDispatcher(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor));
+ register(ModalInteractionEvent.class, new ModalDispatcher(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor));
+ this.interactionRegistry = interactionRegistry;
+ this.implementationRegistry = implementationRegistry;
}
/**
@@ -79,12 +84,9 @@ public void onGenericInteractionCreate(@NotNull GenericInteractionCreateEvent ev
return;
}
- Context context;
- if (SlashCommandInteractionEvent.class.isAssignableFrom(clazz)) {
- context = new SlashCommandContext((SlashCommandInteractionEvent) event, jdaCommands);
- } else {
- context = new Context(event, jdaCommands);
- }
+ Context context = SlashCommandInteractionEvent.class.isAssignableFrom(clazz)
+ ? new SlashCommandContext((SlashCommandInteractionEvent) event, interactionRegistry, implementationRegistry)
+ : new Context(event, interactionRegistry, implementationRegistry);
GenericDispatcher dispatcher = dispatchers.get(key.get());
log.debug("Calling {}", dispatcher.getClass().getName());
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java
index b33539874..1de864ce0 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/RuntimeSupervisor.java
@@ -174,7 +174,7 @@ private Optional getRuntime(String interactionId) {
/**
* A runtime used for executing interactions. This class holds the instance of the class annotated with
- * {@link Interaction Interaction} where commands, buttons, etc. live in. This runtime can only be used once per
+ * {@link Interaction Interaction} where commands, buttonContainers, etc. live in. This runtime can only be used once per
* command execution.
*
* @since 4.0.0
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java
index 09db79b82..bb6ece764 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapter.java
@@ -4,15 +4,17 @@
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
+import java.util.function.BiFunction;
/**
* Generic top level interface for type adapting.
*
- * @see com.github.kaktushose.jda.commands.annotations.Implementation
* @param the type the adapter parses
+ * @see com.github.kaktushose.jda.commands.annotations.Implementation
* @since 2.0.0
*/
-public interface TypeAdapter {
+@FunctionalInterface
+public interface TypeAdapter extends BiFunction> {
/**
* Attempts to parse a String to the given type.
@@ -21,19 +23,6 @@ public interface TypeAdapter {
* @param context the {@link Context}
* @return the parsed type or an empty Optional if the parsing fails
*/
- Optional parse(@NotNull String raw, @NotNull Context context);
+ Optional apply(@NotNull String raw, @NotNull Context context);
- /**
- * Sanitizes a String containing a raw mention. This will remove all markdown characters namely < @ # & ! >
- * For instance: {@code <@!393843637437464588>} gets sanitized to {@code 393843637437464588}
- *
- * @param mention the raw String to sanitize
- * @return the sanitized String
- */
- default String sanitizeMention(@NotNull String mention) {
- if (mention.matches("<[@#][&!]?([0-9]{4,})>")) {
- return mention.replaceAll("<[@#][&!]?", "").replace(">", "");
- }
- return mention;
- }
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java
index db0ddddd0..78c7b0c29 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/TypeAdapterRegistry.java
@@ -1,7 +1,6 @@
package com.github.kaktushose.jda.commands.dispatching.adapter;
import com.github.kaktushose.jda.commands.dispatching.adapter.impl.*;
-import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent;
import com.github.kaktushose.jda.commands.dispatching.interactions.commands.SlashCommandContext;
import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory;
import com.github.kaktushose.jda.commands.reflect.ParameterDefinition;
@@ -138,12 +137,11 @@ public void adapt(@NotNull SlashCommandContext context) {
ErrorMessageFactory messageFactory = context.getImplementationRegistry().getErrorMessageFactory();
log.debug("Type adapting arguments...");
- arguments.add(new CommandEvent(context));
for (int i = 0; i < command.getActualParameters().size(); i++) {
ParameterDefinition parameter = command.getActualParameters().get(i);
// if parameter is array don't parse
- if (String[].class.isAssignableFrom(parameter.getType())) {
+ if (String[].class.isAssignableFrom(parameter.type())) {
log.debug("First parameter is String array. Not adapting arguments");
arguments.add(input);
break;
@@ -162,24 +160,24 @@ public void adapt(@NotNull SlashCommandContext context) {
// if the default value is an empty String (thus not present) add a null value to the argument list
// else try to type adapt the default value
- if (parameter.getDefaultValue() == null) {
- arguments.add(DEFAULT_MAPPINGS.getOrDefault(parameter.getType(), null));
+ if (parameter.defaultValue() == null) {
+ arguments.add(DEFAULT_MAPPINGS.getOrDefault(parameter.type(), null));
continue;
} else {
- raw = parameter.getDefaultValue();
+ raw = parameter.defaultValue();
}
} else {
raw = input[i];
}
- log.debug("Trying to adapt input \"{}\" to type {}", raw, parameter.getType().getName());
+ log.debug("Trying to adapt input \"{}\" to type {}", raw, parameter.type().getName());
- Optional> adapter = get(parameter.getType());
+ Optional> adapter = get(parameter.type());
if (adapter.isEmpty()) {
throw new IllegalArgumentException("No type adapter found!");
}
- Optional> parsed = adapter.get().parse(raw, context);
+ Optional> parsed = adapter.get().apply(raw, context);
if (parsed.isEmpty()) {
log.debug("Type adapting failed!");
context.setCancelled(messageFactory.getTypeAdaptingFailedMessage(context));
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java
index 126ae0630..761277506 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/AudioChannelAdapter.java
@@ -1,11 +1,10 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel;
-import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
@@ -25,29 +24,14 @@ public class AudioChannelAdapter implements TypeAdapter {
* @return the parsed {@link AudioChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- GuildChannel guildChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- guildChannel = guild.getGuildChannelById(raw);
- } else {
- String finalRaw = raw;
- guildChannel = guild.getChannels().stream().filter(it -> it.getName().equalsIgnoreCase(finalRaw))
- .findFirst().orElse(null);
- }
- if (guildChannel == null) {
- return Optional.empty();
- }
- if (!guildChannel.getType().isAudio()) {
- return Optional.empty();
- }
- return Optional.of((AudioChannel) guildChannel);
+ return Helpers.resolveGuildChannel(context, raw)
+ .filter(it -> it.getType().isAudio())
+ .map(AudioChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java
index a9a24ac15..f34be3cd1 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/BooleanAdapter.java
@@ -22,7 +22,7 @@ public class BooleanAdapter implements TypeAdapter {
* @return the parsed boolean or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
if ("true".equalsIgnoreCase(raw) || "1".equals(raw)) {
return Optional.of(true);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java
index 303c726af..6cff244ad 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ByteAdapter.java
@@ -21,7 +21,7 @@ public class ByteAdapter implements TypeAdapter {
* @return the parsed Byte or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
try {
return Optional.of(Byte.valueOf(raw));
} catch (NumberFormatException ignored) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java
index 3bf6f1a92..295379dd6 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/CharacterAdapter.java
@@ -21,7 +21,7 @@ public class CharacterAdapter implements TypeAdapter {
* @return the parsed Char or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
if (raw.length() == 1) {
return Optional.of(raw.charAt(0));
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java
index daf8ba35e..891ba7202 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/DoubleAdapter.java
@@ -21,7 +21,7 @@ public class DoubleAdapter implements TypeAdapter {
* @return the parsed Double or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
try {
return Optional.of(Double.valueOf(raw));
} catch (NumberFormatException ignored) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java
index 46917917d..5fd3b5c2e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/FloatAdapter.java
@@ -21,7 +21,7 @@ public class FloatAdapter implements TypeAdapter {
* @return the parsed Float or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
try {
return Optional.of(Float.valueOf(raw));
} catch (NumberFormatException ignored) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java
index b4e881646..aaa78ed8f 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildChannelAdapter.java
@@ -1,8 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import org.jetbrains.annotations.NotNull;
@@ -24,26 +24,12 @@ public class GuildChannelAdapter implements TypeAdapter {
* @return the parsed {@link GuildChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- GuildChannel guildChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- guildChannel = guild.getGuildChannelById(raw);
- } else {
- String finalRaw = raw;
- guildChannel = guild.getChannels().stream().filter(it -> it.getName().equalsIgnoreCase(finalRaw))
- .findFirst().orElse(null);
- }
- if (guildChannel == null) {
- return Optional.empty();
- }
- return Optional.of(guildChannel);
+ return Helpers.resolveGuildChannel(context, raw);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java
index 9935563fd..917285bdd 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/GuildMessageChannelAdapter.java
@@ -1,10 +1,9 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
-import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import org.jetbrains.annotations.NotNull;
@@ -25,29 +24,14 @@ public class GuildMessageChannelAdapter implements TypeAdapter parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- GuildChannel guildChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- guildChannel = guild.getGuildChannelById(raw);
- } else {
- String finalRaw = raw;
- guildChannel = guild.getChannels().stream().filter(it -> it.getName().equalsIgnoreCase(finalRaw))
- .findFirst().orElse(null);
- }
- if (guildChannel == null) {
- return Optional.empty();
- }
- if (!guildChannel.getType().isMessage()) {
- return Optional.empty();
- }
- return Optional.of((GuildMessageChannel) guildChannel);
+ return Helpers.resolveGuildChannel(context, raw)
+ .filter(it -> it.getType().isMessage())
+ .map(GuildMessageChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java
index 31cb6d39f..af18275a0 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/IntegerAdapter.java
@@ -21,7 +21,7 @@ public class IntegerAdapter implements TypeAdapter {
* @return the parsed Integer or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
try {
return Optional.of((int) Double.parseDouble(raw));
} catch (NumberFormatException ignored) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java
index 54f585e46..7b753cf47 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/LongAdapter.java
@@ -21,7 +21,7 @@ public class LongAdapter implements TypeAdapter {
* @return the parsed Long or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
try {
return Optional.of((long) Double.parseDouble(raw));
} catch (NumberFormatException ignored) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java
index e50fa771a..e7faf5e64 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/MemberAdapter.java
@@ -1,5 +1,6 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import net.dv8tion.jda.api.entities.Guild;
@@ -24,13 +25,13 @@ public class MemberAdapter implements TypeAdapter {
* @return the parsed {@link Member} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
if (context.getEvent().getGuild() == null) {
return Optional.empty();
}
Member member;
- raw = sanitizeMention(raw);
+ raw = Helpers.sanitizeMention(raw);
Guild guild = context.getEvent().getGuild();
if (raw.matches("\\d+")) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java
index 924b020e8..778e7f94a 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/NewsChannelAdapter.java
@@ -1,8 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel;
import org.jetbrains.annotations.NotNull;
@@ -24,24 +24,12 @@ public class NewsChannelAdapter implements TypeAdapter {
* @return the parsed {@link NewsChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- NewsChannel newsChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- newsChannel = guild.getNewsChannelById(raw);
- } else {
- newsChannel = guild.getNewsChannelsByName(raw, true).stream().findFirst().orElse(null);
- }
- if (newsChannel == null) {
- return Optional.empty();
- }
- return Optional.of(newsChannel);
+ return Helpers.resolveGuildChannel(context, raw).filter(NewsChannel.class::isInstance).map(NewsChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java
index 43af60261..7f0de03da 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/RoleAdapter.java
@@ -1,5 +1,6 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import net.dv8tion.jda.api.entities.Guild;
@@ -23,13 +24,13 @@ public class RoleAdapter implements TypeAdapter {
* @return the parsed {@link Role} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
if (context.getEvent().getGuild() == null) {
return Optional.empty();
}
Role role;
- raw = sanitizeMention(raw);
+ raw = Helpers.sanitizeMention(raw);
Guild guild = context.getEvent().getGuild();
if (raw.matches("\\d+")) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java
index 03d4396b1..8a4d4fe34 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ShortAdapter.java
@@ -21,7 +21,7 @@ public class ShortAdapter implements TypeAdapter {
* @return the parsed Short or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
try {
return Optional.of(Short.valueOf(raw));
} catch (NumberFormatException ignored) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java
index 54e0fcb36..4e57998cd 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/StageChannelAdapter.java
@@ -1,8 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.concrete.StageChannel;
import org.jetbrains.annotations.NotNull;
@@ -24,24 +24,12 @@ public class StageChannelAdapter implements TypeAdapter {
* @return the parsed {@link StageChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- StageChannel stageChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- stageChannel = guild.getStageChannelById(raw);
- } else {
- stageChannel = guild.getStageChannelsByName(raw, true).stream().findFirst().orElse(null);
- }
- if (stageChannel == null) {
- return Optional.empty();
- }
- return Optional.of(stageChannel);
+ return Helpers.resolveGuildChannel(context, raw).filter(StageChannel.class::isInstance).map(StageChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java
index 02618557f..38dd0a4a0 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/TextChannelAdapter.java
@@ -1,8 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import org.jetbrains.annotations.NotNull;
@@ -23,23 +23,11 @@ public class TextChannelAdapter implements TypeAdapter {
* @return the parsed {@link TextChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
if (context.getEvent().getGuild() == null) {
return Optional.empty();
}
- TextChannel textChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- textChannel = guild.getTextChannelById(raw);
- } else {
- textChannel = guild.getTextChannelsByName(raw, true).stream().findFirst().orElse(null);
- }
- if (textChannel == null) {
- return Optional.empty();
- }
- return Optional.of(textChannel);
+ return Helpers.resolveGuildChannel(context, raw).filter(TextChannel.class::isInstance).map(TextChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java
index 259575634..7a797d9c1 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/ThreadChannelAdapter.java
@@ -1,8 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
import org.jetbrains.annotations.NotNull;
@@ -24,24 +24,12 @@ public class ThreadChannelAdapter implements TypeAdapter {
* @return the parsed {@link ThreadChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- ThreadChannel threadChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- threadChannel = guild.getThreadChannelById(raw);
- } else {
- threadChannel = guild.getThreadChannelsByName(raw, true).stream().findFirst().orElse(null);
- }
- if (threadChannel == null) {
- return Optional.empty();
- }
- return Optional.of(threadChannel);
+ return Helpers.resolveGuildChannel(context, raw).filter(ThreadChannel.class::isInstance).map(ThreadChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java
index 75a07cde4..314f8cb59 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/UserAdapter.java
@@ -1,5 +1,6 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import net.dv8tion.jda.api.JDA;
@@ -24,9 +25,9 @@ public class UserAdapter implements TypeAdapter {
* @return the parsed {@link User} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
User user;
- raw = sanitizeMention(raw);
+ raw = Helpers.sanitizeMention(raw);
JDA jda = context.getEvent().getJDA();
if (raw.matches("\\d+")) {
try {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java
index be4f910e1..6a804e3a2 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/adapter/impl/VoiceChannelAdapter.java
@@ -1,8 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.adapter.impl;
+import com.github.kaktushose.jda.commands.Helpers;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapter;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel;
import org.jetbrains.annotations.NotNull;
@@ -24,24 +24,12 @@ public class VoiceChannelAdapter implements TypeAdapter {
* @return the parsed {@link VoiceChannel} or an empty Optional if the parsing fails
*/
@Override
- public Optional parse(@NotNull String raw, @NotNull Context context) {
+ public Optional apply(@NotNull String raw, @NotNull Context context) {
Channel channel = context.getEvent().getChannel();
if (channel == null) {
return Optional.empty();
}
- VoiceChannel voiceChannel;
- raw = sanitizeMention(raw);
-
- Guild guild = context.getEvent().getGuild();
- if (raw.matches("\\d+")) {
- voiceChannel = guild.getVoiceChannelById(raw);
- } else {
- voiceChannel = guild.getVoiceChannelsByName(raw, true).stream().findFirst().orElse(null);
- }
- if (voiceChannel == null) {
- return Optional.empty();
- }
- return Optional.of(voiceChannel);
+ return Helpers.resolveGuildChannel(context, raw).filter(VoiceChannel.class::isInstance).map(VoiceChannel.class::cast);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java
index 77bb2f12a..1959eac86 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/Context.java
@@ -1,9 +1,9 @@
package com.github.kaktushose.jda.commands.dispatching.interactions;
-import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.dispatching.KeyValueStore;
import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor.InteractionRuntime;
import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
@@ -24,22 +24,22 @@ public class Context {
protected final GenericInteractionCreateEvent event;
protected MessageCreateData errorMessage;
protected ImplementationRegistry registry;
- protected JDACommands jdaCommands;
protected boolean cancelled;
protected boolean ephemeral;
protected InteractionRuntime runtime;
protected GenericInteractionDefinition interactionDefinition;
+ protected final InteractionRegistry interactionRegistry;
+ protected final ImplementationRegistry implementationRegistry;
/**
* Constructs a new GenericContext.
*
- * @param jdaCommands the corresponding {@link JDACommands} instance
- * @param event the corresponding {@link GenericInteractionCreateEvent}
+ * @param event the corresponding {@link GenericInteractionCreateEvent}
*/
- public Context(GenericInteractionCreateEvent event, JDACommands jdaCommands) {
+ public Context(GenericInteractionCreateEvent event, InteractionRegistry interactionRegistry, ImplementationRegistry implementationRegistry) {
this.event = event;
- this.jdaCommands = jdaCommands;
- this.registry = jdaCommands.getImplementationRegistry();
+ this.interactionRegistry = interactionRegistry;
+ this.implementationRegistry = implementationRegistry;
}
public GenericInteractionCreateEvent getEvent() {
@@ -56,16 +56,6 @@ public MessageCreateData getErrorMessage() {
return errorMessage;
}
- /**
- * Gets the corresponding {@link ImplementationRegistry} instance.
- *
- * @return the corresponding {@link ImplementationRegistry} instance
- */
- @NotNull
- public ImplementationRegistry getImplementationRegistry() {
- return registry;
- }
-
/**
* Set the {@link ImplementationRegistry} instance.
*
@@ -78,28 +68,6 @@ public Context setImplementationRegistry(@NotNull ImplementationRegistry registr
return this;
}
- /**
- * Gets the corresponding {@link JDACommands} instance.
- *
- * @return the corresponding {@link JDACommands} instance
- */
- @NotNull
- public JDACommands getJdaCommands() {
- return jdaCommands;
- }
-
- /**
- * Set the {@link JDACommands} instance.
- *
- * @param jdaCommands the {@link JDACommands} instance
- * @return the current Context instance
- */
- @NotNull
- public Context setJdaCommands(@NotNull JDACommands jdaCommands) {
- this.jdaCommands = jdaCommands;
- return this;
- }
-
/**
* Whether the context should be cancelled.
*
@@ -210,4 +178,12 @@ public Context setKeyValueStore(KeyValueStore keyValueStore) {
runtime.setKeyValueStore(keyValueStore);
return this;
}
+
+ public ImplementationRegistry getImplementationRegistry() {
+ return implementationRegistry;
+ }
+
+ public InteractionRegistry getInteractionRegistry() {
+ return interactionRegistry;
+ }
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java
index c20a3a844..26c05690d 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericDispatcher.java
@@ -1,6 +1,5 @@
package com.github.kaktushose.jda.commands.dispatching.interactions;
-import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor;
import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry;
import com.github.kaktushose.jda.commands.dispatching.middleware.Middleware;
@@ -20,7 +19,6 @@ public abstract class GenericDispatcher {
private final static Logger log = LoggerFactory.getLogger(GenericDispatcher.class);
- protected final JDACommands jdaCommands;
protected final MiddlewareRegistry middlewareRegistry;
protected final ImplementationRegistry implementationRegistry;
protected final InteractionRegistry interactionRegistry;
@@ -29,51 +27,42 @@ public abstract class GenericDispatcher {
/**
* Constructs a new GenericDispatcher.
- *
- * @param jdaCommands the corresponding {@link JDACommands} instance.
*/
- public GenericDispatcher(JDACommands jdaCommands) {
- this.jdaCommands = jdaCommands;
- middlewareRegistry = jdaCommands.getMiddlewareRegistry();
- implementationRegistry = jdaCommands.getImplementationRegistry();
- interactionRegistry = jdaCommands.getInteractionRegistry();
- adapterRegistry = jdaCommands.getAdapterRegistry();
- runtimeSupervisor = jdaCommands.getRuntimeSupervisor();
+ public GenericDispatcher(MiddlewareRegistry middlewareRegistry,
+ ImplementationRegistry implementationRegistry,
+ InteractionRegistry interactionRegistry,
+ TypeAdapterRegistry adapterRegistry,
+ RuntimeSupervisor runtimeSupervisor) {
+ this.middlewareRegistry = middlewareRegistry;
+ this.implementationRegistry = implementationRegistry;
+ this.interactionRegistry = interactionRegistry;
+ this.adapterRegistry = adapterRegistry;
+ this.runtimeSupervisor = runtimeSupervisor;
}
protected void executeMiddlewares(Context context) {
log.debug("Executing middlewares...");
for (Middleware middleware : middlewareRegistry.getMiddlewares(Priority.PERMISSIONS)) {
- log.debug("Executing middleware {}", middleware.getClass().getSimpleName());
- middleware.execute(context);
- if (context.isCancelled()) {
- return;
- }
+ if (executeMiddleware(context, middleware)) return;
}
for (Middleware middleware : middlewareRegistry.getMiddlewares(Priority.HIGH)) {
- log.debug("Executing middleware {}", middleware.getClass().getSimpleName());
- middleware.execute(context);
- if (context.isCancelled()) {
- return;
- }
+ if (executeMiddleware(context, middleware)) return;
}
for (Middleware middleware : middlewareRegistry.getMiddlewares(Priority.NORMAL)) {
- log.debug("Executing middleware {}", middleware.getClass().getSimpleName());
- middleware.execute(context);
- if (context.isCancelled()) {
- return;
- }
+ if (executeMiddleware(context, middleware)) return;
}
for (Middleware middleware : middlewareRegistry.getMiddlewares(Priority.LOW)) {
- log.debug("Executing middleware {}", middleware.getClass().getSimpleName());
- middleware.execute(context);
- if (context.isCancelled()) {
- return;
- }
+ if (executeMiddleware(context, middleware)) return;
}
}
+ private boolean executeMiddleware(Context context, Middleware middleware) {
+ log.debug("Executing middleware {}", middleware.getClass().getSimpleName());
+ middleware.accept(context);
+ return context.isCancelled();
+ }
+
/**
* Dispatches a {@link Context}.
*
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java
index 8c732a70b..40236932e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/GenericEvent.java
@@ -1,7 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.interactions;
-import com.github.kaktushose.jda.commands.JDACommands;
-import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
+import com.github.kaktushose.jda.commands.reflect.interactions.components.ButtonDefinition;
+import com.github.kaktushose.jda.commands.reflect.interactions.components.menus.GenericSelectMenuDefinition;
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
@@ -15,30 +16,20 @@
* @see com.github.kaktushose.jda.commands.dispatching.interactions.modals.ModalEvent ModalEvent
* @since 4.0.0
*/
-public abstract class GenericEvent extends GenericInteractionCreateEvent {
+public abstract class GenericEvent extends GenericInteractionCreateEvent {
protected final Context context;
- private final T definition;
+ private final InteractionRegistry interactionRegistry;
/**
* Constructs a new GenericEvent.
*
* @param context the underlying {@link Context}
*/
- @SuppressWarnings("unchecked")
- protected GenericEvent(Context context) {
+ protected GenericEvent(Context context, InteractionRegistry interactionRegistry) {
super(context.getEvent().getJDA(), context.getEvent().getResponseNumber(), context.getEvent().getInteraction());
- definition = (T) context.getInteractionDefinition();
this.context = context;
- }
-
- /**
- * Get the interaction object which describes the component that is executed.
- *
- * @return the underlying interaction object
- */
- public T getInteractionDefinition() {
- return definition;
+ this.interactionRegistry = interactionRegistry;
}
/**
@@ -50,15 +41,6 @@ public Context getContext() {
return context;
}
- /**
- * Get the {@link JDACommands} object.
- *
- * @return the {@link JDACommands} object
- */
- public JDACommands getJdaCommands() {
- return context.getJdaCommands();
- }
-
/**
* Gets a JDA {@link Button} to use it for message builders based on the jda-commands id. The returned button will
* be linked to the runtime of this event.
@@ -73,7 +55,16 @@ public JDACommands getJdaCommands() {
* @return a JDA {@link Button}
*/
public Button getButton(String button) {
- return getJdaCommands().getButton(button, context.getRuntime().getRuntimeId());
+ if (!button.matches("[a-zA-Z]+\\.[a-zA-Z]+")) {
+ throw new IllegalArgumentException("Unknown Button");
+ }
+
+ String sanitizedId = button.replaceAll("\\.", "");
+ ButtonDefinition buttonDefinition = interactionRegistry.getButtons().stream()
+ .filter(it -> it.getDefinitionId().equals(sanitizedId))
+ .findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Button"));
+
+ return buttonDefinition.toButton().withId(buttonDefinition.createCustomId(context.getRuntime().getRuntimeId()));
}
/**
@@ -81,7 +72,7 @@ public Button getButton(String button) {
* SelectMenu will be linked to the runtime of this event.
*
*
- * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
+ * The id is made up of the simple class name and the method name. E.g. the id of a select menu defined by a
* {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
* {@code ExampleMenu.onSelectMenu}.
*
@@ -89,25 +80,17 @@ public Button getButton(String button) {
* @param menu the id of the selectMenu
* @return a JDA {@link SelectMenu}
*/
- public SelectMenu getSelectMenu(String menu) {
- return getJdaCommands().getSelectMenu(menu, context.getRuntime().getRuntimeId());
- }
+ @SuppressWarnings("unchecked")
+ public T getSelectMenu(String menu) {
+ if (!menu.matches("[a-zA-Z]+\\.[a-zA-Z]+")) {
+ throw new IllegalArgumentException("Unknown Select Menu");
+ }
- /**
- * Gets a JDA {@link SelectMenu} to use it for message builders based on the jda-commands id. The returned
- * SelectMenu will be linked to the runtime of this event.
- *
- *
- * The id is made up of the simple class name and the method name. E.g. the id of a a select menu defined by a
- * {@code onSelectMenu(ComponentEvent event)} method inside an {@code ExampleMenu} class would be
- * {@code ExampleMenu.onSelectMenu}.
- *
- *
- * @param menu the id of the selectMenu
- * @param clazz the subtype of {@link SelectMenu}
- * @return a JDA {@link SelectMenu}
- */
- public S getSelectMenu(String menu, Class clazz) {
- return getJdaCommands().getSelectMenu(menu, getContext().getRuntime().getRuntimeId(), clazz);
+ String sanitizedId = menu.replaceAll("\\.", "");
+ GenericSelectMenuDefinition> selectMenuDefinition = interactionRegistry.getSelectMenus().stream()
+ .filter(it -> it.getDefinitionId().equals(sanitizedId))
+ .findFirst().orElseThrow(() -> new IllegalArgumentException("Unknown Select Menu"));
+
+ return (T) selectMenuDefinition.toSelectMenu(context.getRuntime().getRuntimeId(), true);
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java
index 9f78764aa..34ef20298 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteDispatcher.java
@@ -1,9 +1,13 @@
package com.github.kaktushose.jda.commands.dispatching.interactions.autocomplete;
-import com.github.kaktushose.jda.commands.JDACommands;
+import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor;
+import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher;
+import com.github.kaktushose.jda.commands.dispatching.middleware.MiddlewareRegistry;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
+import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import org.slf4j.Logger;
@@ -23,17 +27,21 @@ public class AutoCompleteDispatcher extends GenericDispatcher {
/**
* Constructs a new AutoCompleteDispatcher.
*
- * @param jdaCommands the corresponding {@link JDACommands} instance.
+ * @param middlewareRegistry
+ * @param implementationRegistry
+ * @param interactionRegistry
+ * @param adapterRegistry
+ * @param runtimeSupervisor
*/
- public AutoCompleteDispatcher(JDACommands jdaCommands) {
- super(jdaCommands);
+ public AutoCompleteDispatcher(MiddlewareRegistry middlewareRegistry, ImplementationRegistry implementationRegistry, InteractionRegistry interactionRegistry, TypeAdapterRegistry adapterRegistry, RuntimeSupervisor runtimeSupervisor) {
+ super(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor);
}
@Override
public void onEvent(Context context) {
CommandAutoCompleteInteractionEvent event = (CommandAutoCompleteInteractionEvent) context.getEvent();
Optional optionalAutoComplete = interactionRegistry.getAutoCompletes().stream()
- .filter(it -> it.getCommandNames().contains(event.getFullCommandName()))
+ .filter(it -> it.getCommandNames().stream().anyMatch(name -> event.getFullCommandName().startsWith(name)))
.findFirst();
if (optionalAutoComplete.isEmpty()) {
@@ -53,7 +61,7 @@ public void onEvent(Context context) {
log.debug("Input matches auto complete: {}", autoComplete.getDefinitionId());
log.info("Executing auto complete {} for user {}", autoComplete.getMethod().getName(), event.getMember());
try {
- autoComplete.getMethod().invoke(runtimeSupervisor.newRuntime(autoComplete).getInstance(), new AutoCompleteEvent(context));
+ autoComplete.getMethod().invoke(runtimeSupervisor.newRuntime(autoComplete).getInstance(), new AutoCompleteEvent(context, interactionRegistry));
} catch (Exception exception) {
throw new IllegalStateException("Auto complete execution failed!", exception);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java
index b4584161e..425738cdb 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/autocomplete/AutoCompleteEvent.java
@@ -2,7 +2,7 @@
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent;
-import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.CommandAutoCompleteInteraction;
@@ -21,12 +21,12 @@
* @see GenericEvent
* @since 4.0.0
*/
-public class AutoCompleteEvent extends GenericEvent {
+public class AutoCompleteEvent extends GenericEvent {
private final CommandAutoCompleteInteractionEvent event;
- protected AutoCompleteEvent(Context context) {
- super(context);
+ protected AutoCompleteEvent(Context context, InteractionRegistry interactionRegistry) {
+ super(context, interactionRegistry);
event = (CommandAutoCompleteInteractionEvent) context.getEvent();
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java
index 62f9288fa..8df5ef346 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandDispatcher.java
@@ -1,11 +1,14 @@
package com.github.kaktushose.jda.commands.dispatching.interactions.commands;
-import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor;
+import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher;
+import com.github.kaktushose.jda.commands.dispatching.middleware.MiddlewareRegistry;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory;
+import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition;
import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent;
@@ -31,12 +34,16 @@ public class CommandDispatcher extends GenericDispatcher {
private static final Logger log = LoggerFactory.getLogger(CommandDispatcher.class);
/**
- * Constructs a new GenericDispatcher.
+ * Constructs a new CommandDispatcher.
*
- * @param jdaCommands the corresponding {@link JDACommands} instance.
+ * @param middlewareRegistry
+ * @param implementationRegistry
+ * @param interactionRegistry
+ * @param adapterRegistry
+ * @param runtimeSupervisor
*/
- public CommandDispatcher(JDACommands jdaCommands) {
- super(jdaCommands);
+ public CommandDispatcher(MiddlewareRegistry middlewareRegistry, ImplementationRegistry implementationRegistry, InteractionRegistry interactionRegistry, TypeAdapterRegistry adapterRegistry, RuntimeSupervisor runtimeSupervisor) {
+ super(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor);
}
@Override
@@ -68,10 +75,10 @@ public void onEvent(Context context) {
Map options = slashContext.getOptionsAsMap();
List parameters = new ArrayList<>();
slashCommand.getActualParameters().forEach(param -> {
- if (!options.containsKey(param.getName())) {
+ if (!options.containsKey(param.name())) {
return;
}
- parameters.add(options.get(param.getName()).getAsString());
+ parameters.add(options.get(param.name()).getAsString());
});
slashContext.setInput(parameters.toArray(new String[]{}));
@@ -81,11 +88,12 @@ public void onEvent(Context context) {
}
arguments = slashContext.getArguments();
+ arguments.addFirst(new CommandEvent(context, interactionRegistry));
} else {
- arguments = new ArrayList<>() {{
- add(new CommandEvent(context));
- add(((GenericContextInteractionEvent>) event).getTarget());
- }};
+ arguments = List.of(
+ new CommandEvent(context, interactionRegistry),
+ ((GenericContextInteractionEvent>) event).getTarget()
+ );
}
executeMiddlewares(context);
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java
index 85d5b71f6..80537979a 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/CommandEvent.java
@@ -4,7 +4,7 @@
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent;
import com.github.kaktushose.jda.commands.dispatching.reply.ModalReplyable;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
-import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import org.jetbrains.annotations.NotNull;
/**
@@ -15,7 +15,7 @@
* @see GenericEvent
* @since 4.0.0
*/
-public class CommandEvent extends GenericEvent implements ModalReplyable {
+public class CommandEvent extends GenericEvent implements ModalReplyable {
private final ReplyContext replyContext;
@@ -24,8 +24,8 @@ public class CommandEvent extends GenericEvent impleme
*
* @param context the underlying {@link Context}
*/
- public CommandEvent(@NotNull Context context) {
- super(context);
+ public CommandEvent(@NotNull Context context, InteractionRegistry interactionRegistry) {
+ super(context, interactionRegistry);
replyContext = new ReplyContext(context);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java
index f0fee96e1..68bfa9c87 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/commands/SlashCommandContext.java
@@ -1,7 +1,8 @@
package com.github.kaktushose.jda.commands.dispatching.interactions.commands;
-import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
+import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
@@ -27,11 +28,10 @@ public class SlashCommandContext extends Context {
/**
* Constructs a new CommandContext.
*
- * @param event the corresponding {@link SlashCommandInteractionEvent}
- * @param jdaCommands the corresponding {@link JDACommands} instance
+ * @param event the corresponding {@link SlashCommandInteractionEvent}
*/
- public SlashCommandContext(SlashCommandInteractionEvent event, JDACommands jdaCommands) {
- super(event, jdaCommands);
+ public SlashCommandContext(SlashCommandInteractionEvent event, InteractionRegistry interactionRegistry, ImplementationRegistry implementationRegistry) {
+ super(event, interactionRegistry, implementationRegistry);
setOptions(event.getOptions());
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java
index ebb26ab1e..c6f14199f 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentDispatcher.java
@@ -1,11 +1,14 @@
package com.github.kaktushose.jda.commands.dispatching.interactions.components;
-import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor;
+import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher;
+import com.github.kaktushose.jda.commands.dispatching.middleware.MiddlewareRegistry;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory;
+import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.CustomId;
import com.github.kaktushose.jda.commands.reflect.interactions.EphemeralInteractionDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.components.ButtonDefinition;
@@ -34,10 +37,14 @@ public class ComponentDispatcher extends GenericDispatcher {
/**
* Constructs a new ComponentDispatcher.
*
- * @param jdaCommands the corresponding {@link JDACommands} instance.
+ * @param middlewareRegistry
+ * @param implementationRegistry
+ * @param interactionRegistry
+ * @param adapterRegistry
+ * @param runtimeSupervisor
*/
- public ComponentDispatcher(JDACommands jdaCommands) {
- super(jdaCommands);
+ public ComponentDispatcher(MiddlewareRegistry middlewareRegistry, ImplementationRegistry implementationRegistry, InteractionRegistry interactionRegistry, TypeAdapterRegistry adapterRegistry, RuntimeSupervisor runtimeSupervisor) {
+ super(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor);
}
@Override
@@ -90,11 +97,11 @@ public void onEvent(Context context) {
try {
Class> clazz = component.getClass();
if (EntitySelectMenuDefinition.class.isAssignableFrom(clazz)) {
- component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context), ((EntitySelectInteractionEvent) event).getMentions());
+ component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context, interactionRegistry), ((EntitySelectInteractionEvent) event).getMentions());
} else if (StringSelectMenuDefinition.class.isAssignableFrom(clazz)) {
- component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context), ((StringSelectInteractionEvent) event).getValues());
+ component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context, interactionRegistry), ((StringSelectInteractionEvent) event).getValues());
} else if (ButtonDefinition.class.isAssignableFrom(clazz)) {
- component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context));
+ component.getMethod().invoke(runtime.getInstance(), new ComponentEvent(context, interactionRegistry));
} else {
throw new IllegalStateException("Unknown component type! Please report this error the the devs of jda-commands.");
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java
index 854dfca6d..3b742398e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/components/ComponentEvent.java
@@ -4,7 +4,7 @@
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent;
import com.github.kaktushose.jda.commands.dispatching.reply.ModalReplyable;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
-import com.github.kaktushose.jda.commands.reflect.interactions.components.GenericComponentDefinition;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import org.jetbrains.annotations.NotNull;
@@ -18,7 +18,7 @@
* @see GenericEvent
* @since 4.0.0
*/
-public class ComponentEvent extends GenericEvent implements ModalReplyable {
+public class ComponentEvent extends GenericEvent implements ModalReplyable {
private final ReplyContext replyContext;
@@ -27,8 +27,8 @@ public class ComponentEvent extends GenericEvent imp
*
* @param context the underlying {@link Context}
*/
- public ComponentEvent(@NotNull Context context) {
- super(context);
+ public ComponentEvent(@NotNull Context context, InteractionRegistry interactionRegistry) {
+ super(context, interactionRegistry);
replyContext = new ReplyContext(context);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java
index 6a89a32d8..533159f74 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalDispatcher.java
@@ -1,11 +1,14 @@
package com.github.kaktushose.jda.commands.dispatching.interactions.modals;
-import com.github.kaktushose.jda.commands.JDACommands;
import com.github.kaktushose.jda.commands.dispatching.RuntimeSupervisor;
+import com.github.kaktushose.jda.commands.dispatching.adapter.TypeAdapterRegistry;
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericDispatcher;
+import com.github.kaktushose.jda.commands.dispatching.middleware.MiddlewareRegistry;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
import com.github.kaktushose.jda.commands.embeds.ErrorMessageFactory;
+import com.github.kaktushose.jda.commands.reflect.ImplementationRegistry;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.CustomId;
import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
@@ -31,10 +34,14 @@ public class ModalDispatcher extends GenericDispatcher {
/**
* Constructs a new ModalDispatcher.
*
- * @param jdaCommands the corresponding {@link JDACommands} instance.
+ * @param middlewareRegistry
+ * @param implementationRegistry
+ * @param interactionRegistry
+ * @param adapterRegistry
+ * @param runtimeSupervisor
*/
- public ModalDispatcher(JDACommands jdaCommands) {
- super(jdaCommands);
+ public ModalDispatcher(MiddlewareRegistry middlewareRegistry, ImplementationRegistry implementationRegistry, InteractionRegistry interactionRegistry, TypeAdapterRegistry adapterRegistry, RuntimeSupervisor runtimeSupervisor) {
+ super(middlewareRegistry, implementationRegistry, interactionRegistry, adapterRegistry, runtimeSupervisor);
}
@Override
@@ -83,7 +90,7 @@ public void onEvent(Context context) {
try {
context.setRuntime(runtime);
List arguments = new ArrayList<>();
- arguments.add(new ModalEvent(context));
+ arguments.add(new ModalEvent(context, interactionRegistry));
arguments.addAll(event.getValues().stream().map(ModalMapping::getAsString).collect(Collectors.toList()));
modal.getMethod().invoke(runtime.getInstance(), arguments.toArray());
} catch (Exception exception) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java
index b16a100d6..077007b3d 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/interactions/modals/ModalEvent.java
@@ -4,7 +4,7 @@
import com.github.kaktushose.jda.commands.dispatching.interactions.GenericEvent;
import com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext;
import com.github.kaktushose.jda.commands.dispatching.reply.Replyable;
-import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition;
+import com.github.kaktushose.jda.commands.reflect.InteractionRegistry;
import org.jetbrains.annotations.NotNull;
/**
@@ -15,12 +15,12 @@
* @see GenericEvent
* @since 4.0.0
*/
-public class ModalEvent extends GenericEvent implements Replyable {
+public class ModalEvent extends GenericEvent implements Replyable {
private final ReplyContext replyContext;
- protected ModalEvent(Context context) {
- super(context);
+ protected ModalEvent(Context context, InteractionRegistry interactionRegistry) {
+ super(context, interactionRegistry);
replyContext = new ReplyContext(context);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/Middleware.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/Middleware.java
index 7e58022db..3660b336b 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/Middleware.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/Middleware.java
@@ -3,6 +3,8 @@
import com.github.kaktushose.jda.commands.dispatching.interactions.Context;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
+import java.util.function.Consumer;
+
/**
* Middlewares run just before an interaction event gets dispatched. They are used to perform additional checks or add
* more info the {@link Context}. Either register them at the {@link MiddlewareRegistry} or use the
@@ -13,7 +15,8 @@
* @see MiddlewareRegistry
* @since 4.0.0
*/
-public interface Middleware {
+@FunctionalInterface
+public interface Middleware extends Consumer {
/**
* Executes this middleware with the given {@link Context}. Use {@link Context#setCancelled(MessageCreateData)}
@@ -21,6 +24,6 @@ public interface Middleware {
*
* @param context the {@link Context} of the current interaction event
*/
- void execute(Context context);
+ void accept(Context context);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/MiddlewareRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/MiddlewareRegistry.java
index bcc3c7288..0cf968558 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/MiddlewareRegistry.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/MiddlewareRegistry.java
@@ -22,7 +22,6 @@ public class MiddlewareRegistry {
/**
* Constructs a new MiddlewareRegistry.
- *
*/
public MiddlewareRegistry() {
middlewares = new HashMap<>();
@@ -37,8 +36,8 @@ public MiddlewareRegistry() {
/**
* Register {@link Middleware Middleware(s)} with the given {@link Priority}.
*
- * @param priority the {@link Priority} to register the {@link Middleware Middleware(s)} with
- * @param first the first {@link Middleware} to register
+ * @param priority the {@link Priority} to register the {@link Middleware Middleware(s)} with
+ * @param first the first {@link Middleware} to register
* @param middlewares additional {@link Middleware Middlewares} to register
* @return this instance for fluent interface
*/
@@ -50,7 +49,7 @@ public MiddlewareRegistry register(Priority priority, Middleware first, Middlewa
/**
* Register {@link Middleware Middleware(s)} with the given {@link Priority}.
*
- * @param priority the {@link Priority} to register the {@link Middleware Middleware(s)} with
+ * @param priority the {@link Priority} to register the {@link Middleware Middleware(s)} with
* @param middlewares the {@link Middleware Middleware(s)} to register
* @return this instance for fluent interface
*/
@@ -63,8 +62,8 @@ public MiddlewareRegistry register(Priority priority, Collection mid
/**
* Unregister {@link Middleware Middleware(s)} with the given {@link Priority}.
*
- * @param priority the {@link Priority} to unregister the {@link Middleware Middleware(s)} with
- * @param first the first {@link Middleware} to unregister
+ * @param priority the {@link Priority} to unregister the {@link Middleware Middleware(s)} with
+ * @param first the first {@link Middleware} to unregister
* @param middlewares additional {@link Middleware Middlewares} to unregister
* @return this instance for fluent interface
*/
@@ -76,7 +75,7 @@ public MiddlewareRegistry unregister(Priority priority, Middleware first, Middle
/**
* Unregister {@link Middleware Middleware(s)} with the given {@link Priority}.
*
- * @param priority the {@link Priority} to unregister the {@link Middleware Middleware(s)} with
+ * @param priority the {@link Priority} to unregister the {@link Middleware Middleware(s)} with
* @param middlewares the {@link Middleware Middleware(s)} to unregister
* @return this instance for fluent interface
*/
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/ConstraintMiddleware.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/ConstraintMiddleware.java
index 16e260cd6..c58799f31 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/ConstraintMiddleware.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/ConstraintMiddleware.java
@@ -32,7 +32,7 @@ public class ConstraintMiddleware implements Middleware {
* @param ctx the {@link Context} to filter
*/
@Override
- public void execute(@NotNull Context ctx) {
+ public void accept(@NotNull Context ctx) {
if (!SlashCommandInteractionEvent.class.isAssignableFrom(ctx.getEvent().getClass())) {
return;
}
@@ -44,10 +44,10 @@ public void execute(@NotNull Context ctx) {
for (int i = 1; i < arguments.size(); i++) {
Object argument = arguments.get(i);
ParameterDefinition parameter = parameters.get(i);
- for (ConstraintDefinition constraint : parameter.getConstraints()) {
- log.debug("Found constraint {} for parameter {}", constraint, parameter.getType().getName());
+ for (ConstraintDefinition constraint : parameter.constraints()) {
+ log.debug("Found constraint {} for parameter {}", constraint, parameter.type().getName());
- boolean validated = constraint.getValidator().validate(argument, constraint.getAnnotation(), context);
+ boolean validated = constraint.validator().apply(argument, constraint.annotation(), context);
if (!validated) {
context.setCancelled(
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/CooldownMiddleware.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/CooldownMiddleware.java
index ef3542910..638b4aa1a 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/CooldownMiddleware.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/CooldownMiddleware.java
@@ -38,7 +38,7 @@ public CooldownMiddleware() {
* @param context the {@link Context} to filter
*/
@Override
- public void execute(@NotNull Context context) {
+ public void accept(@NotNull Context context) {
if (!SlashCommandInteractionEvent.class.isAssignableFrom(context.getEvent().getClass())) {
return;
}
@@ -68,7 +68,7 @@ public void execute(@NotNull Context context) {
CooldownDefinition cooldown = command.getCooldown();
long startTime = System.currentTimeMillis();
- long duration = cooldown.getTimeUnit().toMillis(cooldown.getDelay());
+ long duration = cooldown.timeUnit().toMillis(cooldown.delay());
activeCooldowns.get(id).add(new CooldownEntry(command, startTime, duration));
log.debug("Added new cooldown entry for this user");
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/PermissionsMiddleware.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/PermissionsMiddleware.java
index d82f73702..13209a6ef 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/PermissionsMiddleware.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/middleware/impl/PermissionsMiddleware.java
@@ -34,7 +34,7 @@ public class PermissionsMiddleware implements Middleware {
* @param context the {@link Context} to filter
*/
@Override
- public void execute(@NotNull Context context) {
+ public void accept(@NotNull Context context) {
log.debug("Checking permissions...");
PermissionsProvider provider = context.getImplementationRegistry().getPermissionsProvider();
GenericInteractionCreateEvent event = context.getEvent();
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java
index 06b5f0f42..c49e6f403 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/ModalReplyable.java
@@ -29,7 +29,7 @@ default void replyModal(String modal) {
);
}
- ModalDefinition modalDefinition = context.getJdaCommands().getInteractionRegistry().getModals().stream()
+ ModalDefinition modalDefinition = context.getInteractionRegistry().getModals().stream()
.filter(it -> it.getDefinitionId().equals(String.format("%s%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), modal)))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unknown Modal"));
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java
index e844403c6..1faa089bd 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/Replyable.java
@@ -146,7 +146,7 @@ default void reply(@NotNull EmbedDTO embedDTO, @Nullable Consumer succe
/**
* Adds an {@link ActionRow} to the reply and adds the passed {@link Component Components} to it.
- * For buttons, they must be defined in the same
+ * For buttonContainers, they must be defined in the same
* {@link com.github.kaktushose.jda.commands.annotations.interactions.Interaction Interaction} as the referring
* {@link SlashCommand Command}.
*
@@ -159,15 +159,15 @@ default Replyable with(@NotNull Component... components) {
for (Component component : components) {
if (component instanceof Buttons) {
Buttons buttons = (Buttons) component;
- buttons.getButtonContainer().forEach(container -> {
- String id = String.format("%s%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), container.getName());
- context.getJdaCommands().getInteractionRegistry().getButtons()
+ buttons.buttonContainers().forEach(container -> {
+ String id = String.format("%s%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), container.name());
+ context.getInteractionRegistry().getButtons()
.stream()
.filter(it -> it.getDefinitionId().equals(id))
.findFirst()
.map(it -> {
- Button jdaButton = it.toButton().withDisabled(!container.isEnabled());
- //only assign ids to non-link buttons
+ Button jdaButton = it.toButton().withDisabled(!container.enabled());
+ //only assign ids to non-link buttonContainers
if (jdaButton.getUrl() == null) {
jdaButton = jdaButton.withId(it.createCustomId(context.getRuntime().getRuntimeId()));
}
@@ -177,9 +177,9 @@ default Replyable with(@NotNull Component... components) {
}
if (component instanceof SelectMenus) {
SelectMenus menus = (SelectMenus) component;
- menus.getSelectMenuContainer().forEach(container -> {
+ menus.selectMenuContainers().forEach(container -> {
String id = String.format("%s%s", context.getInteractionDefinition().getMethod().getDeclaringClass().getSimpleName(), container.getName());
- context.getJdaCommands().getInteractionRegistry().getSelectMenus()
+ context.getInteractionRegistry().getSelectMenus()
.stream()
.filter(it -> it.getDefinitionId().equals(id))
.findFirst().map(it -> it.toSelectMenu(context.getRuntime().getRuntimeId(), container.isEnabled()))
@@ -212,12 +212,12 @@ default KeyValueStore kv() {
/**
* Adds an {@link ActionRow} to the reply and adds the passed {@link Component Components} to it.
- * The buttons must be defined in the same
+ * The buttonContainers must be defined in the same
* {@link com.github.kaktushose.jda.commands.annotations.interactions.Interaction Interaction} as the referring
- * {@link SlashCommand Command}. This will enable all buttons. To add
- * disabled buttons, use {@link #with(Component...)}.
+ * {@link SlashCommand Command}. This will enable all buttonContainers. To add
+ * disabled buttonContainers, use {@link #with(Component...)}.
*
- * @param buttons the id of the buttons to add
+ * @param buttons the id of the buttonContainers to add
* @return the current instance for fluent interface
*/
default Replyable withButtons(@NotNull String... buttons) {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Buttons.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Buttons.java
index d5e89e8ff..ddc8e0be0 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Buttons.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Buttons.java
@@ -4,28 +4,27 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
- * {@link Component} implementation for buttons. This class can be used to add
+ * {@link Component} implementation for buttonContainers. This class can be used to add
* {@link com.github.kaktushose.jda.commands.annotations.interactions.Button Buttons} to messages while defining their
* state (enabled or disabled).
*
* @see Replyable#with(Component...)
* @since 2.3.0
*/
-public class Buttons implements Component {
+public record Buttons(Collection buttonContainers) implements Component {
- private final Collection buttons;
-
- private Buttons(Collection buttons) {
- this.buttons = buttons;
+ public Buttons(Collection buttonContainers) {
+ this.buttonContainers = Collections.unmodifiableCollection(buttonContainers);
}
/**
- * Add the buttons with the given ids to the reply message as enabled.
+ * Add the buttonContainers with the given ids to the reply message as enabled.
*
- * @param buttons the id of the buttons to add
+ * @param buttons the id of the buttonContainers to add
* @return instance of this class used inside the
* {@link com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext}
*/
@@ -34,9 +33,9 @@ public static Buttons enabled(String... buttons) {
}
/**
- * Add the buttons with the given ids to the reply message as disabled.
+ * Add the buttonContainers with the given ids to the reply message as disabled.
*
- * @param buttons the id of the buttons to add
+ * @param buttons the id of the buttonContainers to add
* @return instance of this class used inside the
* {@link com.github.kaktushose.jda.commands.dispatching.reply.ReplyContext}
*/
@@ -52,43 +51,9 @@ private static Buttons build(boolean enabled, String... buttons) {
return new Buttons(result);
}
- /**
- * Gets the {@link ButtonContainer}.
- *
- * @return the {@link ButtonContainer}
- */
- public Collection getButtonContainer() {
- return buttons;
- }
-
/**
* Contains information about a single {@link com.github.kaktushose.jda.commands.annotations.interactions.Button Button}.
*/
- public static class ButtonContainer {
- private final String name;
- private final boolean enabled;
-
- private ButtonContainer(String name, boolean enabled) {
- this.name = name;
- this.enabled = enabled;
- }
-
- /**
- * Gets the button id.
- *
- * @return the button id
- */
- public String getName() {
- return name;
- }
-
- /**
- * Whether the button is enabled or not.
- *
- * @return {@code true} if the button is enabled
- */
- public boolean isEnabled() {
- return enabled;
- }
+ public record ButtonContainer(String name, boolean enabled) {
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Component.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Component.java
index 21b2fc5a9..3e8ec4c33 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Component.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/Component.java
@@ -10,5 +10,5 @@
* @see SelectMenus
* @since 2.3.0
*/
-public interface Component {
+public sealed interface Component permits Buttons, SelectMenus {
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/SelectMenus.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/SelectMenus.java
index 29db541ff..1ffac30c4 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/SelectMenus.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/reply/components/SelectMenus.java
@@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -15,12 +16,10 @@
* @see Replyable#with(Component...)
* @since 2.3.0
*/
-public class SelectMenus implements Component {
+public record SelectMenus(Collection selectMenuContainers) implements Component {
- private final Collection selectMenus;
-
- private SelectMenus(Collection selectMenus) {
- this.selectMenus = selectMenus;
+ public SelectMenus(Collection selectMenuContainers) {
+ this.selectMenuContainers = Collections.unmodifiableCollection(selectMenuContainers);
}
/**
@@ -53,15 +52,6 @@ private static SelectMenus build(boolean enabled, String... menus) {
return new SelectMenus(result);
}
- /**
- * Gets the {@link SelectMenuContainer}.
- *
- * @return the {@link SelectMenuContainer}
- */
- public Collection getSelectMenuContainer() {
- return selectMenus;
- }
-
/**
* Contains information about a single select menu (either StringSelectMenu or EntitySelectMenu).
*/
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java
index 365bebb46..7734c2a5f 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/Validator.java
@@ -10,6 +10,7 @@
* @see com.github.kaktushose.jda.commands.annotations.constraints.Constraint Constraint
* @since 2.0.0
*/
+@FunctionalInterface
public interface Validator {
/**
@@ -20,6 +21,6 @@ public interface Validator {
* @param context the corresponding {@link Context}
* @return {@code true} if the argument passes the constraints
*/
- boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context);
+ boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context);
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java
index cbd98f296..6e7902469 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MaximumValidator.java
@@ -22,7 +22,7 @@ public class MaximumValidator implements Validator {
* @return {@code true} if the argument is a number whose value is lower or equal to the specified maximum
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
Max max = (Max) annotation;
return ((Number) argument).longValue() <= max.value();
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java
index 4aebc7d20..2f7982bb3 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/MinimumValidator.java
@@ -23,7 +23,7 @@ public class MinimumValidator implements Validator {
* @return {@code true} if the argument is a number whose value is greater or equal to the specified minimum
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
Min min = (Min) annotation;
return ((Number) argument).longValue() >= min.value();
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java
index 027c47532..541b0236e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotPermissionValidator.java
@@ -29,7 +29,7 @@ public class NotPermissionValidator implements Validator {
* permission
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
Set permissions = new HashSet<>();
NotPerm perm = (NotPerm) annotation;
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java
index 155ba5ff4..635f57d8a 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotRoleValidator.java
@@ -27,10 +27,10 @@ public class NotRoleValidator implements Validator {
* @return {@code true} if the argument is a user or member that doesn't have the specified guild role
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
NotRole roleAnnotation = (NotRole) annotation;
- Optional optional = new RoleAdapter().parse(roleAnnotation.value(), context);
+ Optional optional = new RoleAdapter().apply(roleAnnotation.value(), context);
Member member = (Member) argument;
return optional.filter(role -> member.getRoles().contains(role)).isEmpty();
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java
index 4f6119cfc..8f10a0af9 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/NotUserValidator.java
@@ -26,10 +26,10 @@ public class NotUserValidator implements Validator {
* @return {@code true} if the argument isn't the specified user or member
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
Member member = (Member) argument;
NotUser user = (NotUser) annotation;
- Optional optional = new MemberAdapter().parse(user.value(), context);
+ Optional optional = new MemberAdapter().apply(user.value(), context);
return optional.filter(member::equals).isEmpty();
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java
index a3d24e8fe..b2bdef7ac 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/PermissionValidator.java
@@ -29,7 +29,7 @@ public class PermissionValidator implements Validator {
* permission
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
Set permissions = new HashSet<>();
Perm perm = (Perm) annotation;
try {
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java
index de7134e92..517bdac63 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/RoleValidator.java
@@ -27,11 +27,11 @@ public class RoleValidator implements Validator {
* @return {@code true} if the argument is a user or member that has the specified guild role
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
com.github.kaktushose.jda.commands.annotations.constraints.Role roleAnnotation =
(com.github.kaktushose.jda.commands.annotations.constraints.Role) annotation;
- Optional optional = new RoleAdapter().parse(roleAnnotation.value(), context);
+ Optional optional = new RoleAdapter().apply(roleAnnotation.value(), context);
Member member = (Member) argument;
return optional.filter(role -> member.getRoles().contains(role)).isPresent();
diff --git a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java
index 1d026e2ad..2df8a190e 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/dispatching/validation/impl/UserValidator.java
@@ -26,10 +26,10 @@ public class UserValidator implements Validator {
* @return {@code true} if the argument is the specified user or member
*/
@Override
- public boolean validate(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
+ public boolean apply(@NotNull Object argument, @NotNull Object annotation, @NotNull Context context) {
Member member = (Member) argument;
User user = (User) annotation;
- Optional optional = new MemberAdapter().parse(user.value(), context);
+ Optional optional = new MemberAdapter().apply(user.value(), context);
return optional.filter(member::equals).isPresent();
}
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java b/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java
index bf2962fa5..feed5a152 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/embeds/DefaultErrorMessageFactory.java
@@ -33,10 +33,10 @@ public MessageCreateData getTypeAdaptingFailedMessage(@NotNull SlashCommandConte
List arguments = Arrays.asList(context.getInput());
command.getParameters().forEach(parameter -> {
- if (CommandEvent.class.isAssignableFrom(parameter.getType())) {
+ if (CommandEvent.class.isAssignableFrom(parameter.type())) {
return;
}
- String typeName = parameter.getType().getTypeName();
+ String typeName = parameter.type().getTypeName();
if (typeName.contains(".")) {
typeName = typeName.substring(typeName.lastIndexOf(".") + 1);
}
@@ -81,7 +81,7 @@ public MessageCreateData getConstraintFailedMessage(@NotNull Context context, @N
return new MessageCreateBuilder().setEmbeds(new EmbedBuilder()
.setColor(Color.ORANGE)
.setTitle("Parameter Error")
- .setDescription(String.format("```%s```", constraint.getMessage()))
+ .setDescription(String.format("```%s```", constraint.message()))
.build()
).build();
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java b/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java
index be7186167..94964f3d9 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/embeds/JsonErrorMessageFactory.java
@@ -41,10 +41,10 @@ public MessageCreateData getTypeAdaptingFailedMessage(@NotNull SlashCommandConte
List arguments = Arrays.asList(context.getInput());
command.getParameters().forEach(parameter -> {
- if (CommandEvent.class.isAssignableFrom(parameter.getType())) {
+ if (CommandEvent.class.isAssignableFrom(parameter.type())) {
return;
}
- String typeName = parameter.getType().getTypeName();
+ String typeName = parameter.type().getTypeName();
if (typeName.contains(".")) {
typeName = typeName.substring(typeName.lastIndexOf(".") + 1);
}
@@ -86,7 +86,7 @@ public MessageCreateData getConstraintFailedMessage(@NotNull Context context, @N
return super.getConstraintFailedMessage(context, constraint);
}
return embedCache.getEmbed("constraintFailed")
- .injectValue("message", constraint.getMessage())
+ .injectValue("message", constraint.message())
.toMessageCreateData();
}
@@ -120,8 +120,8 @@ public MessageCreateData getCommandExecutionFailedMessage(@NotNull Context conte
return super.getCommandExecutionFailedMessage(context, exception);
}
String error = String.format("```The user \"%s\" attempted to execute an \"%s\" interaction at %s, " +
- "but a \"%s\" occurred. " +
- "Please refer to the logs for further information.```",
+ "but a \"%s\" occurred. " +
+ "Please refer to the logs for further information.```",
context.getEvent().getUser().toString(),
context.getEvent().getInteraction().getType(),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()),
diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/ConstraintDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/ConstraintDefinition.java
index 002f52ede..91c63ed48 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/reflect/ConstraintDefinition.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/ConstraintDefinition.java
@@ -1,7 +1,6 @@
package com.github.kaktushose.jda.commands.reflect;
import com.github.kaktushose.jda.commands.dispatching.validation.Validator;
-import org.jetbrains.annotations.NotNull;
/**
* Representation of parameter constraint.
@@ -10,56 +9,5 @@
* @see Validator
* @since 2.0.0
*/
-public class ConstraintDefinition {
-
- private final Validator validator;
- private final String message;
- private final Object annotation;
-
- /**
- * Constructs a new ConstraintDefinition.
- *
- * @param validator the {@link Validator} to use
- * @param message the message to display if the constraint fails
- * @param annotation an instance of the annotation declaring the constraint
- */
- public ConstraintDefinition(@NotNull Validator validator, @NotNull String message, @NotNull Object annotation) {
- this.validator = validator;
- this.message = message;
- this.annotation = annotation;
- }
-
- /**
- * Gets the {@link Validator}.
- *
- * @return the {@link Validator}
- */
- public Validator getValidator() {
- return validator;
- }
-
- /**
- * Gets the message to display if the constraint fails.
- *
- * @return the message to display if the constraint fails
- */
- public String getMessage() {
- return message;
- }
-
- /**
- * Gets an instance of the annotation declaring the constraint.
- *
- * @return an instance of the annotation declaring the constraint
- */
- public Object getAnnotation() {
- return annotation;
- }
-
- @Override
- public String toString() {
- return "{" +
- "validator=" + validator.getClass().getName() +
- ", message='" + message + "'}";
- }
+public record ConstraintDefinition(Validator validator, String message, Object annotation) {
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/CooldownDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/CooldownDefinition.java
index b5049b85a..646a5ea3d 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/reflect/CooldownDefinition.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/CooldownDefinition.java
@@ -12,16 +12,10 @@
* @see Cooldown
* @since 2.0.0
*/
-public class CooldownDefinition {
-
- private long delay;
- private TimeUnit timeUnit;
-
- private CooldownDefinition(long delay, TimeUnit timeUnit) {
- this.delay = delay;
- this.timeUnit = timeUnit;
- }
-
+public record CooldownDefinition(
+ long delay,
+ TimeUnit timeUnit
+) {
/**
* Builds a new CooldownDefinition.
*
@@ -35,59 +29,4 @@ public static CooldownDefinition build(@Nullable Cooldown cooldown) {
}
return new CooldownDefinition(cooldown.value(), cooldown.timeUnit());
}
-
- /**
- * Sets the corresponding {@link Cooldown} annotation.
- *
- * @param cooldown the new {@link Cooldown} annotation to use
- */
- public void set(@Nullable CooldownDefinition cooldown) {
- if (cooldown == null) {
- delay = 0;
- return;
- }
- delay = cooldown.delay;
- timeUnit = cooldown.timeUnit;
- }
-
- /**
- * Gets the cooldown delay.
- *
- * @return the cooldown delay
- */
- public long getDelay() {
- return delay;
- }
-
- /**
- * Sets the cooldown delay
- *
- * @param delay the new delay
- */
- public void setDelay(long delay) {
- this.delay = delay;
- }
-
- /**
- * Gets the {@link TimeUnit} of the cooldown.
- *
- * @return the {@link TimeUnit} of the cooldown
- */
- public TimeUnit getTimeUnit() {
- return timeUnit;
- }
-
- /**
- * Sets the {@link TimeUnit} of the cooldown.
- *
- * @param timeUnit the new {@link TimeUnit}
- */
- public void setTimeUnit(TimeUnit timeUnit) {
- this.timeUnit = timeUnit;
- }
-
- @Override
- public String toString() {
- return "{" + "delay=" + delay + ", timeUnit=" + timeUnit + '}';
- }
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java
index d43d0abc7..9f04d4f6b 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionControllerDefinition.java
@@ -5,17 +5,14 @@
import com.github.kaktushose.jda.commands.dependency.DependencyInjector;
import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition;
+import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.ContextCommandDefinition;
-import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.components.ButtonDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.components.menus.EntitySelectMenuDefinition;
-import com.github.kaktushose.jda.commands.reflect.interactions.components.menus.GenericSelectMenuDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.components.menus.StringSelectMenuDefinition;
-import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction;
-import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,33 +21,17 @@
import java.lang.reflect.Method;
import java.util.Optional;
import java.util.*;
-import java.util.stream.Collectors;
/**
* Representation of an interaction controller.
*
* @since 2.0.0
*/
-public class InteractionControllerDefinition {
+public record InteractionControllerDefinition(
+ Set definitions
+) {
private static final Logger log = LoggerFactory.getLogger(InteractionControllerDefinition.class);
- private final List commands;
- private final List buttons;
- private final List> selectMenus;
- private final List autoCompletes;
- private final List modals;
-
- private InteractionControllerDefinition(List commands,
- List buttons,
- List> selectMenus,
- List autoCompletes,
- List modals) {
- this.commands = commands;
- this.buttons = buttons;
- this.selectMenus = selectMenus;
- this.autoCompletes = autoCompletes;
- this.modals = modals;
- }
/**
* Builds a new ControllerDefinition.
@@ -61,197 +42,111 @@ private InteractionControllerDefinition(List commands,
* @param localizationFunction the {@link LocalizationFunction} to use
* @return an {@link Optional} holding the ControllerDefinition
*/
- public static Optional build(@NotNull Class> interactionClass,
- @NotNull ValidatorRegistry validatorRegistry,
- @NotNull DependencyInjector dependencyInjector,
- @NotNull LocalizationFunction localizationFunction) {
+ public static InteractionControllerDefinition build(@NotNull Class> interactionClass,
+ @NotNull ValidatorRegistry validatorRegistry,
+ @NotNull DependencyInjector dependencyInjector,
+ @NotNull LocalizationFunction localizationFunction) {
Interaction interaction = interactionClass.getAnnotation(Interaction.class);
- if (!interaction.isActive()) {
- log.warn("Interaction class {} is set inactive. Skipping the controller and its commands", interactionClass.getName());
- return Optional.empty();
- }
-
- List fields = new ArrayList<>();
- for (Field field : interactionClass.getDeclaredFields()) {
- if (!field.isAnnotationPresent(Inject.class)) {
- continue;
- }
- fields.add(field);
- }
+ List fields = Arrays.stream(interactionClass.getDeclaredFields())
+ .filter(field -> field.isAnnotationPresent(Inject.class))
+ .toList();
dependencyInjector.registerDependencies(interactionClass, fields);
- final Set permissions = new HashSet<>();
- // index controller level permissions
- if (interactionClass.isAnnotationPresent(Permissions.class)) {
- Permissions permission = interactionClass.getAnnotation(Permissions.class);
- permissions.addAll(Arrays.stream(permission.value()).collect(Collectors.toSet()));
- }
+ Permissions permission = interactionClass.getAnnotation(Permissions.class);
+ final Set permissions = permission != null
+ ? Set.of(permission.value())
+ : Set.of();
// get controller level cooldown and use it if no command level cooldown is present
- CooldownDefinition cooldown = null;
- if (interactionClass.isAnnotationPresent(Cooldown.class)) {
- cooldown = CooldownDefinition.build(interactionClass.getAnnotation(Cooldown.class));
- }
+ Cooldown cooldownAnn = interactionClass.getAnnotation(Cooldown.class);
+ CooldownDefinition cooldown = cooldownAnn != null
+ ? CooldownDefinition.build(cooldownAnn)
+ : null;
+
+
+ Collection autoCompleteDefinitions = autoCompleteDefinitions(interactionClass);
// index interactions
- List commands = new ArrayList<>();
- List buttons = new ArrayList<>();
- List> selectMenus = new ArrayList<>();
- List autoCompletes = new ArrayList<>();
- List modals = new ArrayList<>();
- for (Method method : interactionClass.getDeclaredMethods()) {
+ Set interactionDefinitions = interactionDefinitions(
+ interactionClass,
+ validatorRegistry,
+ localizationFunction,
+ interaction,
+ permissions,
+ cooldown,
+ autoCompleteDefinitions
+ );
+
+ // validate auto completes
+ List commandDefinitions = interactionDefinitions.stream()
+ .filter(SlashCommandDefinition.class::isInstance)
+ .map(SlashCommandDefinition.class::cast)
+ .toList();
+
+ autoCompleteDefinitions.stream()
+ .map(AutoCompleteDefinition::getCommandNames)
+ .flatMap(Collection::stream)
+ .filter(name -> commandDefinitions.stream().noneMatch(command -> command.getName().startsWith(name)))
+ .forEach(s -> log.warn("No Command found for auto complete {}", s));
+
+ return new InteractionControllerDefinition(interactionDefinitions);
+ }
+ private static Collection autoCompleteDefinitions(Class> interactionClass) {
+ return Arrays.stream(interactionClass.getDeclaredMethods())
+ .filter(method -> method.isAnnotationPresent(AutoComplete.class))
+ .map(AutoCompleteDefinition::build)
+ .flatMap(Optional::stream)
+ .toList();
+ }
+
+ private static Set interactionDefinitions(Class> clazz,
+ ValidatorRegistry validatorRegistry,
+ LocalizationFunction localizationFunction,
+ Interaction interaction,
+ Set permissions,
+ CooldownDefinition cooldown,
+ Collection autocompletes) {
+ Set definitions = new HashSet<>(autocompletes);
+ for (Method method : clazz.getDeclaredMethods()) {
+ final MethodBuildContext context = new MethodBuildContext(
+ validatorRegistry,
+ localizationFunction,
+ interaction,
+ permissions,
+ cooldown,
+ method,
+ autocompletes
+ );
+
+ Optional extends GenericInteractionDefinition> definition = Optional.empty();
// index commands
if (method.isAnnotationPresent(SlashCommand.class)) {
- Optional optional = SlashCommandDefinition.build(method, validatorRegistry, localizationFunction);
- if (optional.isEmpty()) {
- continue;
- }
- SlashCommandDefinition commandDefinition = optional.get();
- commandDefinition.getPermissions().addAll(permissions);
- if (commandDefinition.getCooldown().getDelay() == 0) {
- commandDefinition.getCooldown().set(cooldown);
- }
- if (interaction.ephemeral()) {
- commandDefinition.setEphemeral(true);
- }
- commands.add(commandDefinition);
+ definition = SlashCommandDefinition.build(context);
}
if (method.isAnnotationPresent(ContextCommand.class)) {
- Optional optional = ContextCommandDefinition.build(method, localizationFunction);
- if (optional.isEmpty()) {
- continue;
- }
- ContextCommandDefinition commandDefinition = optional.get();
- commandDefinition.getPermissions().addAll(permissions);
- if (interaction.ephemeral()) {
- commandDefinition.setEphemeral(true);
- }
- commands.add(commandDefinition);
+ definition = ContextCommandDefinition.build(context);
}
// index components
if (method.isAnnotationPresent(Button.class)) {
- ButtonDefinition.build(method).ifPresent(button -> {
- if (interaction.ephemeral()) {
- button.setEphemeral(true);
- }
- button.getPermissions().addAll(permissions);
- buttons.add(button);
- });
+ definition = ButtonDefinition.build(context);
}
if (method.isAnnotationPresent(EntitySelectMenu.class)) {
- EntitySelectMenuDefinition.build(method).ifPresent(menu -> {
- if (interaction.ephemeral()) {
- menu.setEphemeral(true);
- }
- menu.getPermissions().addAll(permissions);
- selectMenus.add(menu);
- });
+ definition = EntitySelectMenuDefinition.build(context);
}
if (method.isAnnotationPresent(StringSelectMenu.class)) {
- StringSelectMenuDefinition.build(method).ifPresent(menu -> {
- if (interaction.ephemeral()) {
- menu.setEphemeral(true);
- }
- menu.getPermissions().addAll(permissions);
- selectMenus.add(menu);
- });
+ definition = StringSelectMenuDefinition.build(context);
}
//index modals
if (method.isAnnotationPresent(Modal.class)) {
- ModalDefinition.build(method).ifPresent(modal -> {
- if (interaction.ephemeral()) {
- modal.setEphemeral(true);
- }
- modal.getPermissions().addAll(permissions);
- modals.add(modal);
- });
+ definition = ModalDefinition.build(method);
}
- }
-
- //loop again and index auto complete
- for (Method method : interactionClass.getDeclaredMethods()) {
- if (method.isAnnotationPresent(AutoComplete.class)) {
- AutoCompleteDefinition.build(
- method,
- autoCompletes.stream().flatMap(it -> it.getCommandNames().stream()).collect(Collectors.toList())
- ).ifPresent(autoComplete -> {
- autoCompletes.add(autoComplete);
- Set commandNames = new HashSet<>();
- autoComplete.getCommandNames().forEach(name -> commands.stream()
- .filter(it -> it.getCommandType() == Command.Type.SLASH)
- .filter(command -> command.getName().startsWith(name))
- .forEach(command -> {
- ((SlashCommandDefinition) command).setAutoComplete(true);
- commandNames.add(command.getName());
- })
- );
- autoComplete.setCommandNames(commandNames);
- });
- }
+ definition.ifPresent(definitions::add);
}
-
- return Optional.of(new InteractionControllerDefinition(commands, buttons, selectMenus, autoCompletes, modals));
+ return definitions;
}
-
- /**
- * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}.
- *
- * @return a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}
- */
- public List getCommands() {
- return commands;
- }
-
- /**
- * Gets a possibly-empty list of all buttons.
- *
- * @return a possibly-empty list of all buttons
- */
- public List getButtons() {
- return buttons;
- }
-
- /**
- * Gets a possibly-empty list of all select menus.
- *
- * @return a possibly-empty list of all select menus
- */
- public List> getSelectMenus() {
- return selectMenus;
- }
-
- /**
- * Gets a possibly-empty list of all {@link AutoCompleteDefinition AutoCompleteDefinitions}.
- *
- * @return a possibly-empty list of all {@link AutoCompleteDefinition AutoCompleteDefinitions}
- */
- public Collection getAutoCompletes() {
- return autoCompletes;
- }
-
- /**
- * Gets a possibly-empty list of all {@link ModalDefinition ModalDefinitions}.
- *
- * @return a possibly-empty list of all {@link ModalDefinition ModalDefinitions}
- */
- public List getModals() {
- return modals;
- }
-
- @Override
- public String toString() {
- return "ControllerDefinition{" +
- "commands=" + commands +
- ", buttons=" + buttons +
- ", selectMenus=" + selectMenus +
- ", autoCompletes=" + autoCompletes +
- ", modals=" + modals +
- '}';
- }
-
}
diff --git a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java
index 5d41a5f4a..b50f04e7c 100644
--- a/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java
+++ b/src/main/java/com/github/kaktushose/jda/commands/reflect/InteractionRegistry.java
@@ -4,13 +4,12 @@
import com.github.kaktushose.jda.commands.dependency.DependencyInjector;
import com.github.kaktushose.jda.commands.dispatching.validation.ValidatorRegistry;
import com.github.kaktushose.jda.commands.reflect.interactions.AutoCompleteDefinition;
+import com.github.kaktushose.jda.commands.reflect.interactions.GenericInteractionDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.ModalDefinition;
-import com.github.kaktushose.jda.commands.reflect.interactions.commands.ContextCommandDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.GenericCommandDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.commands.SlashCommandDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.components.ButtonDefinition;
import com.github.kaktushose.jda.commands.reflect.interactions.components.menus.GenericSelectMenuDefinition;
-import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction;
import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
import org.jetbrains.annotations.NotNull;
@@ -22,29 +21,22 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
+import java.util.Collection;
import java.util.HashSet;
-import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* Central registry for all {@link SlashCommandDefinition CommandDefinitions}.
*
* @since 2.0.0
*/
-public class InteractionRegistry {
+public final class InteractionRegistry {
private final static Logger log = LoggerFactory.getLogger(InteractionRegistry.class);
private final ValidatorRegistry validatorRegistry;
private final DependencyInjector dependencyInjector;
private final LocalizationFunction localizationFunction;
- private final Set controllers;
- private final Set commands;
- private final Set buttons;
- private final Set> selectMenus;
- private final Set autoCompletes;
- private final Set modals;
+ private final Set definitions = new HashSet<>();
/**
* Constructs a new CommandRegistry.
@@ -59,12 +51,6 @@ public InteractionRegistry(@NotNull ValidatorRegistry validatorRegistry,
this.validatorRegistry = validatorRegistry;
this.dependencyInjector = dependencyInjector;
this.localizationFunction = localizationFunction;
- controllers = new HashSet<>();
- commands = new HashSet<>();
- buttons = new HashSet<>();
- selectMenus = new HashSet<>();
- autoCompletes = new HashSet<>();
- modals = new HashSet<>();
}
/**
@@ -92,82 +78,56 @@ public void index(@NotNull Class> clazz, @NotNull String... packages) {
for (Class> aClass : controllerSet) {
log.debug("Found interaction controller {}", aClass.getName());
- Optional optional = InteractionControllerDefinition.build(
+ InteractionControllerDefinition controller = InteractionControllerDefinition.build(
aClass,
validatorRegistry,
dependencyInjector,
localizationFunction
);
- if (optional.isEmpty()) {
- log.warn("Unable to index the interaction controller!");
- continue;
- }
-
- InteractionControllerDefinition controller = optional.get();
- controllers.add(controller);
- commands.addAll(controller.getCommands());
- buttons.addAll(controller.getButtons());
- selectMenus.addAll(controller.getSelectMenus());
- autoCompletes.addAll(controller.getAutoCompletes());
- modals.addAll(controller.getModals());
+ definitions.addAll(controller.definitions());
log.debug("Registered interaction controller {}", controller);
}
log.debug("Successfully registered {} interaction controller(s) with a total of {} interaction(s)!",
- controllers.size(),
- commands.size() + buttons.size());
+ controllerSet.size(),
+ definitions.size());
}
/**
- * Gets a possibly-empty list of all {@link InteractionControllerDefinition ControllerDefinitions}.
- *
- * @return a possibly-empty list of all {@link InteractionControllerDefinition ControllerDefinitions}
- */
- public Set getInteractionControllers() {
- return Collections.unmodifiableSet(controllers);
- }
-
- /**
- * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}, this includes both
- * {@link SlashCommandDefinition} and {@link ContextCommandDefinition}.
+ * Gets a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}.
*
* @return a possibly-empty list of all {@link GenericCommandDefinition CommandDefinitions}
*/
- public Set getCommands() {
- return Collections.unmodifiableSet(commands);
- }
-
- /**
- * Gets a possibly-empty list of all {@link SlashCommandDefinition SlashCommandDefinitions}.
- *
- * @return a possibly-empty list of all {@link SlashCommandDefinition SlashCommandDefinitions}
- */
- public Set getSlashCommands() {
- return commands.stream().filter(it -> (it.getCommandType() == Command.Type.SLASH))
- .map(it -> (SlashCommandDefinition) it)
- .collect(Collectors.toUnmodifiableSet());
+ public Collection getCommands() {
+ return definitions.stream()
+ .filter(GenericCommandDefinition.class::isInstance)
+ .map(GenericCommandDefinition.class::cast)
+ .toList();
}
/**
- * Gets a possibly-empty list of all {@link ContextCommandDefinition ContextCommandDefinitions}.
+ * Gets a possibly-empty list of all buttonContainers.
*
- * @return a possibly-empty list of all {@link ContextCommandDefinition ContextCommandDefinitions}
+ * @return a possibly-empty list of all buttonContainers
*/
- public Set