Skip to content

Commit

Permalink
Slash command support (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
Chew committed Jun 6, 2021
1 parent 232c870 commit 3a086dc
Show file tree
Hide file tree
Showing 7 changed files with 934 additions and 8 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ allprojects {
version = versionInfo.values().join('.')

ext {
jdaVersion = '4.2.1_255'
jdaVersion = '4.2.1_267'
slf4jVersion = '1.7.25'
okhttpVersion = '3.13.0'
findbugsVersion = '3.0.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,15 @@
public abstract class Command
{
/**
* The name of the command, allows the command to be called the format: {@code [prefix]<command name>}.
* The name of the command, allows the command to be called the formats: <br>
* Normal Command: {@code [prefix]<command name>}. <br>
* Slash Command: {@code /<command name>}
*/
protected String name = "null";

/**
* A small help String that summarizes the function of the command, used in the default help builder.
* A small help String that summarizes the function of the command, used in the default help builder,
* and shown in the client for Slash Commands.
*/
protected String help = "no help available";

Expand All @@ -85,6 +88,8 @@ public abstract class Command

/**
* An arguments format String for the command, used in the default help builder.
* Not supported for SlashCommands.
* @see SlashCommand#options
*/
protected String arguments = null;

Expand All @@ -102,7 +107,9 @@ public abstract class Command

/**
* {@code true} if the command may only be used by a User with an ID matching the
* Owners or any of the CoOwners.
* Owners or any of the CoOwners.<br>
* If enabled for a Slash Command, only owners (owner + up to 9 co-owners) will be added to the SlashCommand.
* All other permissions will be ignored.
* <br>Default {@code false}.
*/
protected boolean ownerCommand = false;
Expand All @@ -127,6 +134,7 @@ public abstract class Command
/**
* The aliases of the command, when calling a command these function identically to calling the
* {@link com.jagrosh.jdautilities.command.Command#name Command.name}.
* This options only works for normal commands, not slash commands.
*/
protected String[] aliases = new String[0];

Expand All @@ -152,7 +160,8 @@ public abstract class Command

/**
* {@code true} if this command should be hidden from the help.
* <br>Default {@code false}
* <br>Default {@code false}<br>
* <b>This has no effect for SlashCommands.</b>
*/
protected boolean hidden = false;

Expand Down Expand Up @@ -529,7 +538,7 @@ public boolean isOwnerCommand()
}

/**
* Checks whether or not this command should be hidden from the help
* Checks whether or not this command should be hidden from the help.
*
* @return {@code true} if the command should be hidden, otherwise {@code false}
*/
Expand Down Expand Up @@ -692,6 +701,7 @@ public String getFailureResponse()

/**
* Runs a test of the provided {@link java.util.function.Predicate}.
* Does not support SlashCommands.
*
* @param event
* The {@link com.jagrosh.jdautilities.command.CommandEvent CommandEvent}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,63 @@ public interface CommandClient
*/
void addCommand(Command command, int index);

/**
* Adds a single {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand} to this CommandClient's
* registered SlashCommand.
*
* <p>For CommandClient's containing 20 commands or less, command calls by users will have the bot iterate
* through the entire {@link java.util.ArrayList ArrayList} to find the command called. As expected, this
* can get fairly hefty if a bot has a lot of Commands registered to it.
*
* <p>To prevent delay a CommandClient that has more that 20 Commands registered to it will begin to use
* <b>indexed calls</b>.
* <br>Indexed calls use a {@link java.util.HashMap HashMap} which links their
* {@link com.jagrosh.jdautilities.command.SlashCommand#name name} to the index that which they
* are located at in the ArrayList they are stored.
*
* <p>This means that all insertion and removal of SlashCommands must reorganize the index maintained by the HashMap.
* <br>For this particular insertion, the SlashCommand provided is inserted at the end of the index, meaning it will
* become the "rightmost" Command in the ArrayList.
*
* @param command
* The Command to add
*
* @throws java.lang.IllegalArgumentException
* If the SlashCommand provided has a name or alias that has already been registered
*/
void addSlashCommand(SlashCommand command);

/**
* Adds a single {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand} to this CommandClient's
* registered Commands at the specified index.
*
* <p>For CommandClient's containing 20 commands or less, command calls by users will have the bot iterate
* through the entire {@link java.util.ArrayList ArrayList} to find the command called. As expected, this
* can get fairly hefty if a bot has a lot of Commands registered to it.
*
* <p>To prevent delay a CommandClient that has more that 20 Commands registered to it will begin to use
* <b>indexed calls</b>.
* <br>Indexed calls use a {@link java.util.HashMap HashMap} which links their
* {@link com.jagrosh.jdautilities.command.Command#name name} to the index that which they
* are located at in the ArrayList they are stored.
*
* <p>This means that all insertion and removal of Commands must reorganize the index maintained by the HashMap.
* <br>For this particular insertion, the Command provided is inserted at the index specified, meaning it will
* become the Command located at that index in the ArrayList. This will shift the Command previously located at
* that index as well as any located at greater indices, right one index ({@code size()+1}).
*
* @param command
* The Command to add
* @param index
* The index to add the Command at (must follow the specifications {@code 0<=index<=size()})
*
* @throws java.lang.ArrayIndexOutOfBoundsException
* If {@code index < 0} or {@code index > size()}
* @throws java.lang.IllegalArgumentException
* If the Command provided has a name or alias that has already been registered to an index
*/
void addSlashCommand(SlashCommand command, int index);

/**
* Removes a single {@link com.jagrosh.jdautilities.command.Command Command} from this CommandClient's
* registered Commands at the index linked to the provided name/alias.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public class CommandClientBuilder
private String carbonKey;
private String botsKey;
private final LinkedList<Command> commands = new LinkedList<>();
private final LinkedList<SlashCommand> slashCommands = new LinkedList<>();
private String forcedGuildId = null;
private boolean manualUpsert = false;
private CommandListener listener;
private boolean useHelp = true;
private boolean shutdownAutomatically = true;
Expand All @@ -75,7 +78,7 @@ public class CommandClientBuilder
public CommandClient build()
{
CommandClient client = new CommandClientImpl(ownerId, coOwnerIds, prefix, altprefix, prefixes, prefixFunction, commandPreProcessFunction, activity, status, serverInvite,
success, warning, error, carbonKey, botsKey, new ArrayList<>(commands), useHelp,
success, warning, error, carbonKey, botsKey, new ArrayList<>(commands), new ArrayList<>(slashCommands), forcedGuildId, manualUpsert, useHelp,
shutdownAutomatically, helpConsumer, helpWord, executor, linkedCacheSize, compiler, manager);
if(listener!=null)
client.setListener(listener);
Expand Down Expand Up @@ -346,6 +349,66 @@ public CommandClientBuilder addCommands(Command... commands)
return this;
}

/**
* Adds a {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand} and registers it to the
* {@link com.jagrosh.jdautilities.command.impl.CommandClientImpl CommandClientImpl} for this session.
*
* @param command
* The SlashCommand to add
*
* @return This builder
*/
public CommandClientBuilder addSlashCommand(SlashCommand command)
{
slashCommands.add(command);
return this;
}

/**
* Adds and registers multiple {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand}s to the
* {@link com.jagrosh.jdautilities.command.impl.CommandClientImpl CommandClientImpl} for this session.
* <br>This is the same as calling {@link com.jagrosh.jdautilities.command.CommandClientBuilder#addSlashCommand(SlashCommand)} multiple times.
*
* @param commands
* The Commands to add
*
* @return This builder
*/
public CommandClientBuilder addSlashCommands(SlashCommand... commands)
{
for(SlashCommand command: commands)
this.addSlashCommand(command);
return this;
}

/**
* Forces Guild Only for SlashCommands.
* This is the same as setting this.guildOnly = true and this.guildId = your value for every command.
* Setting this to null disables the feature, but it is off by default.
*
* @param guildId the guild ID.
* @return This Builder
*/
public CommandClientBuilder forceGuildOnly(String guildId)
{
this.forcedGuildId = guildId;
return this;
}

/**
* Whether or not to manually upsert slash commands.
* This is designed if you want to handle upserting, instead of doing it every boot.
* False by default.
*
* @param manualUpsert your option.
* @return This Builder
*/
public CommandClientBuilder setManualUpsert(boolean manualUpsert)
{
this.manualUpsert = manualUpsert;
return this;
}

/**
* Adds an annotated command module to the
* {@link com.jagrosh.jdautilities.command.impl.CommandClientImpl CommandClientImpl} for this session.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.jagrosh.jdautilities.command;

import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;

/**
Expand All @@ -35,6 +36,17 @@ public interface CommandListener
* The Command that was triggered
*/
default void onCommand(CommandEvent event, Command command) {}

/**
* Called when a {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand} is triggered
* by a {@link net.dv8tion.jda.api.events.interaction.SlashCommandEvent SlashCommandEvent}.
*
* @param event
* The SlashCommandEvent that triggered the Command
* @param command
* The SlashCommand that was triggered
*/
default void onSlashCommand(SlashCommandEvent event, SlashCommand command) {}

/**
* Called when a {@link com.jagrosh.jdautilities.command.Command Command} is triggered
Expand All @@ -51,6 +63,22 @@ default void onCommand(CommandEvent event, Command command) {}
* The Command that was triggered
*/
default void onCompletedCommand(CommandEvent event, Command command) {}

/**
* Called when a {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand} is triggered
* by a {@link net.dv8tion.jda.api.events.interaction.SlashCommandEvent SlashCommandEvent} after it's
* completed successfully.
*
* <p>Note that a <i>successfully</i> completed slash command is one that has not encountered
* an error or exception. Calls that do face errors should be handled by
* {@link CommandListener#onSlashCommandException(SlashCommandEvent, SlashCommand, Throwable) CommandListener#onSlashCommandException}
*
* @param event
* The SlashCommandEvent that triggered the Command
* @param command
* The SlashCommand that was triggered
*/
default void onCompletedSlashCommand(SlashCommandEvent event, SlashCommand command) {}

/**
* Called when a {@link com.jagrosh.jdautilities.command.Command Command} is triggered
Expand All @@ -63,6 +91,18 @@ default void onCompletedCommand(CommandEvent event, Command command) {}
* The Command that was triggered
*/
default void onTerminatedCommand(CommandEvent event, Command command) {}

/**
* Called when a {@link com.jagrosh.jdautilities.command.SlashCommand Command} is triggered
* by a {@link net.dv8tion.jda.api.events.interaction.SlashCommandEvent SlashCommandEvent} but is
* terminated before completion.
*
* @param event
* The SlashCommandEvent that triggered the Command
* @param command
* The SlashCommand that was triggered
*/
default void onTerminatedSlashCommand(SlashCommandEvent event, SlashCommand command) {}

/**
* Called when a {@link net.dv8tion.jda.api.events.message.MessageReceivedEvent MessageReceivedEvent}
Expand Down Expand Up @@ -117,4 +157,25 @@ default void onCommandException(CommandEvent event, Command command, Throwable t
// Default rethrow as a runtime exception.
throw throwable instanceof RuntimeException? (RuntimeException)throwable : new RuntimeException(throwable);
}

/**
* Called when a {@link com.jagrosh.jdautilities.command.SlashCommand SlashCommand}
* catches a {@link java.lang.Throwable Throwable} <b>during execution</b>.
*
* <p>This doesn't account for exceptions thrown during other pre-checks,
* and should not be treated as such!
*
* The {@link java.lang.NullPointerException NullPointerException} thrown will not be caught by this method!
*
* @param event
* The CommandEvent that triggered the Command
* @param command
* The Command that was triggered
* @param throwable
* The Throwable thrown during Command execution
*/
default void onSlashCommandException(SlashCommandEvent event, SlashCommand command, Throwable throwable) {
// Default rethrow as a runtime exception.
throw throwable instanceof RuntimeException? (RuntimeException)throwable : new RuntimeException(throwable);
}
}
Loading

0 comments on commit 3a086dc

Please sign in to comment.