package cc.fascinated.bat.command; import cc.fascinated.bat.features.Feature; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.model.BatUser; import lombok.AccessLevel; import lombok.Getter; import lombok.NonNull; import lombok.Setter; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.interactions.IntegrationType; import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction; import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; import net.dv8tion.jda.internal.interactions.CommandDataImpl; import java.util.*; /** * @author Braydon */ @Getter public abstract class BatCommand { /** * The info of this command. */ @NonNull private final InternalCommandInfo info; /** * The feature this command belongs to. */ @Setter private Feature feature; /** * The snowflake of this command, set when * this command is registered with Discord. */ @Setter private long snowflake; /** * The sub commands of this command, if any. */ private final Map subCommands = Collections.synchronizedMap(new HashMap<>()); /** * The internal data for this command. */ @Setter(AccessLevel.PRIVATE) private CommandDataImpl commandData; /** * The internal subcommand data for this command. */ @Setter(AccessLevel.PRIVATE) private SubcommandData subcommandData; public BatCommand() { if (!getClass().isAnnotationPresent(CommandInfo.class)) { throw new IllegalStateException("Missing @CommandInfo annotation in " + getClass().getSimpleName()); } info = new InternalCommandInfo(getClass().getAnnotation(CommandInfo.class)); List integrationTypes = new ArrayList<>(Collections.singletonList(IntegrationType.GUILD_INSTALL)); if (info.isUserInstall()) { integrationTypes.add(IntegrationType.USER_INSTALL); } commandData = new CommandDataImpl(info.getName(), info.getDescription()) .setContexts(InteractionContextType.ALL) .setIntegrationTypes(integrationTypes) .setGuildOnly(!getInfo().isUserInstall() && getInfo().isGuildOnly()); } /** * Fired when this command is executed. * * @param guild the guild the command was executed in, if any * @param user the user who executed the command * @param channel the channel the command was executed in * @param member the member who executed the command, null if not a guild * @param event the event that invoked this command */ public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) { } /** * Register the given sub commands. * * @param commands the commands to register */ protected final void addSubCommands(@NonNull BatCommand... commands) { for (BatCommand command : commands) { // Copy info from the parent command if (command.getInfo().getCategory() != info.getCategory()) { command.getInfo().setCategory(info.getCategory()); } if (command.getInfo().getPermissions().length == 0) { command.getInfo().setPermissions(info.getPermissions()); } if (command.getInfo().isGuildOnly() != info.isGuildOnly()) { command.getInfo().setGuildOnly(info.isGuildOnly()); } if (command.getInfo().isBotOwnerOnly() != info.isBotOwnerOnly()) { command.getInfo().setBotOwnerOnly(info.isBotOwnerOnly()); } command.setSubcommandData(new SubcommandData(command.getInfo().getName(), command.getInfo().getDescription())); for (OptionData option : command.getCommandData().getOptions()) { command.getSubcommandData().addOptions(option); } commandData.addSubcommands(command.getSubcommandData()); subCommands.put(command.getInfo().getName(), command); } } /** * Add the given options * to this command. * * @param options the options to add */ protected final void addOptions(OptionData... options) { commandData.addOptions(options); } }