Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrated JDA's command-entities into SlashCommand & SlashCommand.Subcommand & made SmartQueue non-blocking #62

Merged
merged 15 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.0")
testImplementation("ch.qos.logback:logback-classic:1.4.4")

implementation("net.dv8tion:JDA:5.0.0-alpha.22")
implementation("com.github.DV8FromTheWorld:JDA:f181320b10")
compileOnly("com.google.code.findbugs:jsr305:3.0.2")
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/xyz/dynxsty/dih4jda/DIH4JDA.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
import xyz.dynxsty.dih4jda.config.DIH4JDAConfig;
import xyz.dynxsty.dih4jda.events.DIH4JDAEventListener;
import xyz.dynxsty.dih4jda.exceptions.DIH4JDAException;
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
import xyz.dynxsty.dih4jda.interactions.commands.ContextCommand;
import xyz.dynxsty.dih4jda.interactions.commands.RegistrationType;
import xyz.dynxsty.dih4jda.interactions.commands.SlashCommand;
import xyz.dynxsty.dih4jda.interactions.components.ButtonHandler;
import xyz.dynxsty.dih4jda.interactions.components.EntitySelectMenuHandler;
import xyz.dynxsty.dih4jda.interactions.components.ModalHandler;
import xyz.dynxsty.dih4jda.interactions.components.StringSelectMenuHandler;
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;

import javax.annotation.Nonnull;
import java.util.HashMap;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/xyz/dynxsty/dih4jda/DIH4JDABuilder.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package xyz.dynxsty.dih4jda;

import net.dv8tion.jda.api.JDA;
import org.jetbrains.annotations.Contract;
import xyz.dynxsty.dih4jda.config.DIH4JDAConfig;
import xyz.dynxsty.dih4jda.exceptions.CommandNotRegisteredException;
import xyz.dynxsty.dih4jda.exceptions.DIH4JDAException;
Expand Down
172 changes: 103 additions & 69 deletions src/main/java/xyz/dynxsty/dih4jda/InteractionHandler.java

Large diffs are not rendered by default.

35 changes: 10 additions & 25 deletions src/main/java/xyz/dynxsty/dih4jda/SmartQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
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;
Expand Down Expand Up @@ -52,13 +51,7 @@ protected SmartQueue(@Nonnull Set<SlashCommand> slashCommands, @Nonnull Set<Cont
* @return A {@link Pair} with the remaining {@link SlashCommandData} and {@link CommandData}.
* @since v1.5
*/
protected @Nonnull Pair<Set<SlashCommand>, Set<ContextCommand>> checkGlobal(@Nonnull JDA jda) {
List<Command> existing;
try {
existing = jda.retrieveCommands().complete();
} catch (ErrorResponseException e) {
return new Pair<>(Set.of(), Set.of());
}
protected @Nonnull Pair<Set<SlashCommand>, Set<ContextCommand>> checkGlobal(@Nonnull JDA jda, @Nonnull List<Command> existing) {
if (!existing.isEmpty()) {
return removeDuplicates(jda, existing, null);
}
Expand All @@ -72,15 +65,7 @@ protected SmartQueue(@Nonnull Set<SlashCommand> slashCommands, @Nonnull Set<Cont
* @return A {@link Pair} with the remaining {@link SlashCommandData} and {@link CommandData}.
* @since v1.5
*/
protected @Nonnull Pair<Set<SlashCommand>, Set<ContextCommand>> checkGuild(@Nonnull Guild guild) {
List<Command> existing;
try {
existing = guild.retrieveCommands().complete();
} catch (ErrorResponseException e) {
DIH4JDALogger.error("Could not retrieve Commands from Guild %s!" +
" Please make sure that the bot was invited with the application.commands scope!", guild.getName());
return new Pair<>(Set.of(), Set.of());
}
protected @Nonnull Pair<Set<SlashCommand>, Set<ContextCommand>> checkGuild(@Nonnull Guild guild, @Nonnull List<Command> existing) {
if (!existing.isEmpty()) {
return removeDuplicates(guild.getJDA(), existing, guild);
}
Expand All @@ -92,7 +77,7 @@ protected SmartQueue(@Nonnull Set<SlashCommand> slashCommands, @Nonnull Set<Cont
*
* @param jda The {@link JDA} instance.
* @param existing A List of all existing {@link Command}s.
* @param guild An optional guild parameter which is used with {@link SmartQueue#checkGuild(Guild)}.
* @param guild An optional guild parameter which is used with {@link SmartQueue#checkGuild(Guild, List)}.
* @return A {@link Pair} with the remaining {@link SlashCommandData} & {@link CommandData}.
* @since v1.5
*/
Expand All @@ -103,15 +88,15 @@ protected SmartQueue(@Nonnull Set<SlashCommand> slashCommands, @Nonnull Set<Cont
DIH4JDALogger.info(DIH4JDALogger.Type.SMART_QUEUE, prefix + "Found %s existing command(s)", existing.size());
// remove already-existing commands
commands.removeIf(cmd -> {
if (contextCommands.stream().anyMatch(data -> CommandUtils.isEqual(cmd, data.getCommandData(), global)) ||
slashCommands.stream().anyMatch(data -> CommandUtils.isEqual(cmd, data.getSlashCommandData(), global))) {
if (contextCommands.stream().anyMatch(data -> CommandUtils.equals(cmd, data.getCommandData(), global)) ||
slashCommands.stream().anyMatch(data -> CommandUtils.equals(cmd, data.getSlashCommandData(), global))) {
// check for command in blacklisted guilds
// this may be refactored soonTM, as its kinda clunky
if (!global) {
for (SlashCommand d : slashCommands) {
if (CommandUtils.isEqual(cmd, d.getSlashCommandData(), false)) {
if (CommandUtils.equals(cmd, d.getSlashCommandData(), false)) {
if (d.getRequiredGuilds().getFirst() == null) {
return false;
return true;
} else {
if (!Arrays.asList(d.getRequiredGuilds().getSecond()).contains(guild.getIdLong())) {
DIH4JDALogger.info("Deleting /%s in Guild: %s", cmd.getName(), guild.getName());
Expand All @@ -122,7 +107,7 @@ protected SmartQueue(@Nonnull Set<SlashCommand> slashCommands, @Nonnull Set<Cont
}
}
for (ContextCommand d : contextCommands) {
if (CommandUtils.isEqual(cmd, d.getCommandData(), false) &&
if (CommandUtils.equals(cmd, d.getCommandData(), false) &&
!Arrays.asList(d.getRequiredGuilds().getSecond()).contains(guild.getIdLong())) {
DIH4JDALogger.info("Deleting %s in Guild: %s", cmd.getName(), guild.getName());
cmd.delete().queue();
Expand All @@ -135,8 +120,8 @@ protected SmartQueue(@Nonnull Set<SlashCommand> slashCommands, @Nonnull Set<Cont
}
return false;
});
contextCommands.removeIf(data -> existing.stream().anyMatch(p -> CommandUtils.isEqual(p, data.getCommandData(), global)));
slashCommands.removeIf(data -> existing.stream().anyMatch(p -> CommandUtils.isEqual(p, data.getSlashCommandData(), global)));
contextCommands.removeIf(data -> existing.stream().anyMatch(p -> CommandUtils.equals(p, data.getCommandData(), global)));
slashCommands.removeIf(data -> existing.stream().anyMatch(p -> CommandUtils.equals(p, data.getSlashCommandData(), global)));
// remove unknown commands, if enabled
if (!commands.isEmpty()) {
for (Command command : commands) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package xyz.dynxsty.dih4jda.events;

import net.dv8tion.jda.api.interactions.Interaction;
import org.jetbrains.annotations.NotNull;
import xyz.dynxsty.dih4jda.DIH4JDA;
import xyz.dynxsty.dih4jda.DIH4JDALogger;

Expand Down Expand Up @@ -49,7 +48,7 @@ public I getInteraction() {
* @param event The {@link GenericDIH4JDAEvent} to fire.
* @since v1.5
*/
public static <I extends Interaction> void fire(@NotNull GenericDIH4JDAEvent<I> event) {
public static <I extends Interaction> void fire(@Nonnull GenericDIH4JDAEvent<I> event) {
if (event.getDIH4JDA().getEventListeners().isEmpty()) {
DIH4JDALogger.warn(DIH4JDALogger.Type.EVENT_FIRED, "%s was fired, but not handled (No listener registered)", event.getEventName());
if (event instanceof ThrowableDIH4JDAEvent && event.getDIH4JDA().getConfig().isDefaultPrintStacktrace()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package xyz.dynxsty.dih4jda.events;

import net.dv8tion.jda.api.interactions.Interaction;
import org.jetbrains.annotations.NotNull;
import xyz.dynxsty.dih4jda.DIH4JDA;

import javax.annotation.Nonnull;

/**
* Further abstraction of the {@link GenericDIH4JDAEvent} class, which features {@link Throwable}s.
*
Expand All @@ -13,7 +14,7 @@ public abstract class ThrowableDIH4JDAEvent<I extends Interaction> extends Gener

private final Throwable throwable;

protected ThrowableDIH4JDAEvent(@NotNull String eventName, @NotNull DIH4JDA dih4jda, I interaction, Throwable throwable) {
protected ThrowableDIH4JDAEvent(@Nonnull String eventName, @Nonnull DIH4JDA dih4jda, @Nonnull I interaction, @Nonnull Throwable throwable) {
super(eventName, dih4jda, interaction);
this.throwable = throwable;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package xyz.dynxsty.dih4jda.interactions.commands;

import javax.annotation.Nonnull;

/**
* Represents a command that can be executed.
* @param <E> the event to pass to the command.
Expand All @@ -13,10 +11,4 @@ public interface ExecutableCommand<E> {
* @param event the command that is getting passed.
*/
void execute(E event);
/**
* Gets the linked {@link SlashCommand}.
* @return the {@link SlashCommand} instance.
*/
@Nonnull
SlashCommand getSlashCommand();
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package xyz.dynxsty.dih4jda.interactions.commands;

import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
import xyz.dynxsty.dih4jda.InteractionHandler;

import javax.annotation.Nonnull;
import java.util.Map;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;

/**
* Represents a single Slash Command.
Expand All @@ -17,9 +21,10 @@ public abstract class SlashCommand extends AbstractCommand implements Executable

private SlashCommandData data = null;
private Subcommand[] subcommands = new Subcommand[]{};
private Map<SubcommandGroupData, Subcommand[]> subcommandGroups = Map.of();
private SubcommandGroup[] subcommandGroups = new SubcommandGroup[]{};

protected SlashCommand() {}
protected SlashCommand() {
}

public final SlashCommandData getSlashCommandData() {
return data;
Expand All @@ -45,12 +50,12 @@ public final Subcommand[] getSubcommands() {
*/
public final void addSubcommands(Subcommand... classes) {
for (Subcommand subcommand : classes) {
subcommand.mainCommandData = this;
subcommand.parent = this;
}
this.subcommands = classes;
}

public final Map<SubcommandGroupData, Subcommand[]> getSubcommandGroups() {
public final SubcommandGroup[] getSubcommandGroups() {
return subcommandGroups;
}

Expand All @@ -59,36 +64,40 @@ public final Map<SubcommandGroupData, Subcommand[]> getSubcommandGroups() {
*
* @param groups A map of the {@link SubcommandGroupData} and their corresponding {@link Subcommand}s.
*/
public final void addSubcommandGroups(Map<SubcommandGroupData, Subcommand[]> groups) {
public final void addSubcommandGroups(@Nonnull SubcommandGroup... groups) {
for (SubcommandGroup group : groups) {
for (Subcommand subcommand : group.getSubcommands()) {
subcommand.parent = this;
}
}
this.subcommandGroups = groups;
}

@Override
public void execute(SlashCommandInteractionEvent event) {}

@Nonnull
@Override
public SlashCommand getSlashCommand() {
return this;
/**
* Gets the corresponding {@link Command JDA entity} for this command.
* If the command was not cached or queued before (e.g. when using sharding), this may return null.
*
* @return The {@link Command} corresponding to this class.
*/
public @Nullable Command asCommand() {
if (data == null) return null;
return InteractionHandler.getRetrievedCommands().get(data.getName());
}

/**
* Model class which represents a single Subcommand.
*/
public abstract static class Subcommand implements ExecutableCommand<SlashCommandInteractionEvent> {
private SubcommandData data = null;
private SlashCommand mainCommandData = null;
private SlashCommand parent = null;

public final SubcommandData getSubcommandData() {
return data;
}

@Nonnull
@Override
public SlashCommand getSlashCommand() {
return mainCommandData;
}

/**
* Sets this subcommands' {@link SubcommandData}.
*
Expand All @@ -98,5 +107,74 @@ public SlashCommand getSlashCommand() {
public final void setSubcommandData(SubcommandData data) {
this.data = data;
}

/**
* Gets the {@link SlashCommand parent} for this subcommand.
*
* @return The corresponding {@link SlashCommand}.
*/
public SlashCommand getParent() {
jasonlessenich marked this conversation as resolved.
Show resolved Hide resolved
return parent;
}

/**
* Gets the corresponding {@link Command.Subcommand JDA-entity} for this subcommand.
* If the subcommand was not cached or queued before (e.g. when using sharding), this may return null.
*
* @return The {@link Command.Subcommand} corresponding to this class.
*/
public @Nullable Command.Subcommand asSubcommand() {
if (data == null) return null;
Command cmd = parent.asCommand();
if (cmd == null) return null;
List<Command.Subcommand> subcommands = new ArrayList<>(cmd.getSubcommands());
cmd.getSubcommandGroups().forEach(g -> subcommands.addAll(g.getSubcommands()));
return subcommands.stream()
.filter(c -> c.getName().equals(data.getName()))
.findFirst()
.orElse(null);
}
}

/**
* Model class which represents a single subcommand group.
* This simply holds the {@link SubcommandGroupData} and an array of all {@link Subcommand}s.
*/
public static class SubcommandGroup {
private final SubcommandGroupData data;
private final Subcommand[] subcommands;

private SubcommandGroup(SubcommandGroupData data, Subcommand... subcommands) {
this.data = data;
this.subcommands = subcommands;
}

/**
* Creates a new instance of the {@link SubcommandGroup} class.
*
* @param data The {@link SubcommandGroupData} to use.
* @param subcommands An array of {@link Subcommand}s. This should NOT be empty!
* @return The {@link SubcommandGroup}.
*/
@Nonnull
public static SubcommandGroup of(SubcommandGroupData data, Subcommand... subcommands) {
if (data == null) throw new IllegalArgumentException("SubcommandGroupData may not be null!");
if (subcommands == null || subcommands.length == 0) throw new IllegalArgumentException("Subcommands may not be empty!");
return new SubcommandGroup(data, subcommands);
}

/**
* @return The corresponding {@link SubcommandGroupData}.
*/
public SubcommandGroupData getData() {
return data;
}

/**
* @return An array of {@link Subcommand}s.
*/
public Subcommand[] getSubcommands() {
return subcommands;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.Command;
import org.jetbrains.annotations.Contract;

import javax.annotation.Nonnull;
import java.util.Arrays;
Expand Down
Loading