Compare commits

..

No commits in common. "47b4796695e6c6234d35ad7b8652298dc4e4e12c" and "66a2d8b2a9b733114497a767aae3c7c3e7ad10a1" have entirely different histories.

95 changed files with 560 additions and 603 deletions

22
pom.xml

@ -107,13 +107,11 @@
<groupId>io.mongock</groupId>
<artifactId>mongock-springboot-v3</artifactId>
<version>5.2.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.mongock</groupId>
<artifactId>mongodb-springdata-v4-driver</artifactId>
<version>5.2.4</version>
<scope>compile</scope>
</dependency>
<!-- Redis for caching -->
@ -140,41 +138,49 @@
<version>1.18.32</version>
<scope>provided</scope>
</dependency>
<!-- Dependencies -->
<!-- <dependency>-->
<!-- <groupId>net.dv8tion</groupId>-->
<!-- <artifactId>JDA</artifactId>-->
<!-- <version>5.0.0-beta.24</version>-->
<!-- </dependency>-->
<dependency>
<groupId>io.github.freya022</groupId>
<artifactId>JDA</artifactId>
<version>2ed819ad15</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.jodah</groupId>
<artifactId>expiringmap</artifactId>
<version>0.5.11</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>se.michaelthelin.spotify</groupId>
<artifactId>spotify-web-api-java</artifactId>
<version>8.4.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>uk.co.conoregan</groupId>
<artifactId>themoviedbapi</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -20,7 +20,7 @@ import java.nio.file.StandardCopyOption;
import java.util.Objects;
@EnableScheduling
@SpringBootApplication
@SpringBootApplication(scanBasePackages = "cc.fascinated.bat")
@EnableMongock
@Log4j2(topic = "Bat")
public class BatApplication {

@ -1,123 +1,103 @@
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.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
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.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Braydon
* @author Fascinated (fascinated7)
*/
@Getter
public abstract class BatCommand {
@Setter
public abstract class BatCommand implements BatCommandExecutor {
/**
* The info of this command.
* The information about the command
*/
@NonNull private final InternalCommandInfo info;
private final CommandInfo commandInfo;
/**
* The feature this command belongs to.
* The command data for the slash command
*/
@Setter private Feature feature;
private final CommandDataImpl commandData;
/**
* The snowflake of this command, set when
* this command is registered with Discord.
* The sub commands of the command
*/
@Setter private long snowflake;
private final Map<String, BatSubCommand> subCommands = new HashMap<>();
/**
* The sub commands of this command, if any.
* The category of the command
*/
private final Map<String, BatCommand> subCommands = Collections.synchronizedMap(new HashMap<>());
private Category category;
/**
* The internal data for this command.
* The feature that the command belongs to
*/
@Setter(AccessLevel.PRIVATE) private CommandDataImpl commandData;
private Feature feature;
/**
* The internal subcommand data for this command.
* Whether the command can only be used by the bot owner
*/
@Setter(AccessLevel.PRIVATE) private SubcommandData subcommandData;
private boolean botOwnerOnly;
/**
* The command snowflake from Discord
*/
private long commandSnowflake;
public BatCommand() {
if (!getClass().isAnnotationPresent(CommandInfo.class)) {
throw new IllegalStateException("Missing @CommandInfo annotation in " + getClass().getSimpleName());
}
info = new InternalCommandInfo(getClass().getAnnotation(CommandInfo.class));
this.commandInfo = getClass().getAnnotation(CommandInfo.class);
this.category = this.commandInfo.category();
this.botOwnerOnly = this.commandInfo.botOwnerOnly();
List<IntegrationType> integrationTypes = new ArrayList<>(Collections.singletonList(IntegrationType.GUILD_INSTALL));
if (info.isUserInstall()) {
integrationTypes.add(IntegrationType.USER_INSTALL);
}
commandData = new CommandDataImpl(info.getName(), info.getDescription())
List<IntegrationType> integrationTypes = this.commandInfo.userInstall() ? List.of(IntegrationType.GUILD_INSTALL, IntegrationType.USER_INSTALL) :
List.of(IntegrationType.GUILD_INSTALL);
this.commandData = new CommandDataImpl(this.commandInfo.name(), this.commandInfo.description())
.setGuildOnly(this.commandInfo.guildOnly())
.setContexts(InteractionContextType.ALL)
.setIntegrationTypes(integrationTypes)
.setGuildOnly(info.isGuildOnly());
.setIntegrationTypes(integrationTypes);
}
/**
* Fired when this command is executed.
* Adds a sub command to the command
*
* @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
* @param subCommand The sub 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);
}
public void addSubCommand(@NonNull BatSubCommand subCommand) {
this.subCommands.put(subCommand.getCommandInfo().name().toLowerCase(), subCommand);
this.commandData.addSubcommands(subCommand.getCommandData());
}
/**
* Add the given options
* to this command.
* Adds an option to the sub command
*
* @param options the options to add
* @param optionType the type of the option
* @param name the name of the option
* @param description the description of the option
* @param required whether the option is required
*/
protected final void addOptions(OptionData... options) {
commandData.addOptions(options);
protected void addOption(OptionType optionType, String name, String description, boolean required) {
this.commandData.addOption(optionType, name, description, required);
}
}
/**
* Gets all the options for the command
*
* @param interaction The slash command interaction
* @return The option strings
*/
public List<String> getOptions(SlashCommandInteraction interaction) {
return interaction.getOptions().stream().map(OptionMapping::getName).toList();
}
}

@ -0,0 +1,31 @@
package cc.fascinated.bat.command;
import cc.fascinated.bat.model.BatGuild;
import cc.fascinated.bat.model.BatUser;
import lombok.NonNull;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
/**
* @author Fascinated (fascinated7)
*/
public interface BatCommandExecutor {
/**
* Executes the command using a slash command event.
*
* @param guild the bat guild the command was executed in (null if the command was executed in a DM)
* @param user the bat user that executed the command
* @param channel the channel the command was executed in
* @param member the member that executed the command
* @param event the slash command event
*/
default void execute(
BatGuild guild,
@NonNull BatUser user,
@NonNull MessageChannel channel,
Member member,
@NonNull SlashCommandInteraction event
) {
}
}

@ -0,0 +1,45 @@
package cc.fascinated.bat.command;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
/**
* @author Fascinated (fascinated7)
*/
@Getter
@Setter
public class BatSubCommand implements BatCommandExecutor {
/**
* The information about the sub command
*/
private final CommandInfo commandInfo;
/**
* The command data for the slash command
*/
private final SubcommandData commandData;
/**
* The commands snowflake from Discord
*/
private long commandSnowflake;
public BatSubCommand() {
this.commandInfo = getClass().getAnnotation(CommandInfo.class);
this.commandData = new SubcommandData(this.commandInfo.name(), this.commandInfo.description());
}
/**
* Adds an option to the sub command
*
* @param optionType the type of the option
* @param name the name of the option
* @param description the description of the option
* @param required whether the option is required
*/
public void addOption(OptionType optionType, String name, String description, boolean required) {
this.commandData.addOption(optionType, name, description, required);
}
}

@ -2,35 +2,43 @@ package cc.fascinated.bat.command;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import java.util.Arrays;
import java.util.List;
/**
* @author Fascinated (fascinated7)
*/
@AllArgsConstructor
@Getter
public enum Category {
GENERAL(Emoji.fromUnicode("U+2699"), "General"),
FUN(Emoji.fromFormatted("U+1F973"), "Fun"),
SERVER(Emoji.fromFormatted("U+1F5A5"), "Server"),
MODERATION(Emoji.fromFormatted("U+1F6E0"), "Moderation"),
UTILITY(Emoji.fromFormatted("U+1F6E0"), "Utility"),
MUSIC(Emoji.fromFormatted("U+1F3B5"), "Music"),
MOVIES_TV(Emoji.fromFormatted("U+1F3A5"), "Movies & TV"),
MESSAGES(Emoji.fromFormatted("U+1F4A3"), "Messages"),
LOGS(Emoji.fromFormatted("U+1F4D1"), "Logs"),
BEAT_SABER(Emoji.fromFormatted("U+1FA84"), "Beat Saber");
GENERAL(Emoji.fromUnicode("U+2699"), "General", false),
FUN(Emoji.fromFormatted("U+1F973"), "Fun", false),
SERVER(Emoji.fromFormatted("U+1F5A5"), "Server", false),
MODERATION(Emoji.fromFormatted("U+1F6E0"), "Moderation", false),
UTILITY(Emoji.fromFormatted("U+1F6E0"), "Utility", false),
MUSIC(Emoji.fromFormatted("U+1F3B5"), "Music", false),
MOVIES_TV(Emoji.fromFormatted("U+1F3A5"), "Movies & TV", false),
MESSAGES(Emoji.fromFormatted("U+1F4A3"), "Messages", false),
LOGS(Emoji.fromFormatted("U+1F4D1"), "Logs", false),
BEAT_SABER(Emoji.fromFormatted("U+1FA84"), "Beat Saber", false),
BOT_ADMIN(null, null, true);
/**
* The emoji for the category
*/
@NonNull private final Emoji emoji;
private final Emoji emoji;
/**
* The name of the category
*/
@NonNull private final String name;
private final String name;
/**
* If the category is hidden
*/
private final boolean hidden;
/**
* Gets a category by its name
@ -46,4 +54,13 @@ public enum Category {
}
return null;
}
/**
* Gets all the visible categories
*
* @return the visible categories
*/
public static List<Category> getCategories() {
return Arrays.stream(Category.values()).filter(category -> !category.isHidden()).toList();
}
}

@ -8,9 +8,6 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotated at the top of a class to define
* the default values for a {@link BatCommand}.
*
* @author Fascinated (fascinated7)
*/
@Retention(RetentionPolicy.RUNTIME)

@ -1,60 +0,0 @@
package cc.fascinated.bat.command;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import net.dv8tion.jda.api.Permission;
/**
* The internal command info of a {@link BatCommand}.
*
* @author Braydon
*/
@Setter(AccessLevel.PROTECTED) @Getter
public class InternalCommandInfo {
/**
* The name of the command.
*/
@NonNull private final String name;
/**
* The description of the command.
*/
@NonNull private final String description;
/**
* The category of the command.
*/
@NonNull private Category category;
/**
* The permissions required to run this command, if any.
*/
private Permission[] permissions;
/**
* Whether this command can only be ran within a guild.
*/
private boolean guildOnly;
/**
* Whether this command can be user installed.
*/
private final boolean userInstall;
/**
* Whether the command can only be ran by the bot owner.
*/
private boolean botOwnerOnly;
protected InternalCommandInfo(@NonNull CommandInfo annotation) {
name = annotation.name();
description = annotation.description();
category = annotation.category();
permissions = annotation.requiredPermissions();
guildOnly = annotation.guildOnly();
userInstall = annotation.userInstall();
botOwnerOnly = annotation.botOwnerOnly();
}
}

@ -37,10 +37,11 @@ public abstract class Feature {
* @param command The command to register
*/
public void registerCommand(@NonNull CommandService commandService, @NonNull BatCommand command) {
command.setFeature(this);
for (BatCommand subCommand : command.getSubCommands().values()) {
subCommand.setFeature(this);
// If the command using the default category then set the category to the feature's category
if (command.getCategory() == Category.GENERAL) {
command.setCategory(this.category);
}
command.setFeature(this);
commandService.registerCommand(command);
}
}

@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -22,18 +21,9 @@ import org.springframework.stereotype.Component;
@CommandInfo(name = "afk", description = "Sets your AFK status")
public class AfkCommand extends BatCommand {
public AfkCommand() {
super.addOptions(new OptionData(OptionType.STRING, "reason", "The reason for being AFK", false));
super.addOption(OptionType.STRING, "reason", "The reason for being AFK", false);
}
/**
* 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
*/
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
AfkProfile profile = guild.getProfile(AfkProfile.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.autorole.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.RoleUtils;
@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,10 +22,10 @@ import org.springframework.stereotype.Component;
*/
@Component("autoroles:add.sub")
@CommandInfo(name = "add", description = "Adds a role to the auto roles list")
public class AddSubCommand extends BatCommand {
public class AddSubCommand extends BatSubCommand {
@Autowired
public AddSubCommand() {
super.addOptions(new OptionData(OptionType.ROLE, "role", "The role to add", true));
super.addOption(OptionType.ROLE, "role", "The role to add", true);
}
@Override

@ -14,11 +14,9 @@ import org.springframework.stereotype.Component;
@CommandInfo(name = "autorole", description = "Set up the automatic role system for members on join", requiredPermissions = Permission.MANAGE_SERVER)
public class AutoRoleCommand extends BatCommand {
public AutoRoleCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(ListSubCommand.class),
context.getBean(AddSubCommand.class),
context.getBean(RemoveSubCommand.class),
context.getBean(ClearSubCommand.class)
);
super.addSubCommand(context.getBean(ListSubCommand.class));
super.addSubCommand(context.getBean(AddSubCommand.class));
super.addSubCommand(context.getBean(RemoveSubCommand.class));
super.addSubCommand(context.getBean(ClearSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.autorole.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("autoroles:clear.sub")
@CommandInfo(name = "clear", description = "Clears all auto roles")
public class ClearSubCommand extends BatCommand {
public class ClearSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.autorole.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component("autoroles:list.sub")
@CommandInfo(name = "list", description = "Lists all auto roles")
public class ListSubCommand extends BatCommand {
public class ListSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.autorole.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -22,10 +21,10 @@ import org.springframework.stereotype.Component;
*/
@Component("autoroles:remove.sub")
@CommandInfo(name = "remove", description = "Removes a role from the auto roles list")
public class RemoveSubCommand extends BatCommand {
public class RemoveSubCommand extends BatSubCommand {
@Autowired
public RemoveSubCommand() {
super.addOptions(new OptionData(OptionType.ROLE, "role", "The role to remove", true));
super.addOption(OptionType.ROLE, "role", "The role to remove", true);
}
@Override

@ -1,6 +1,7 @@
package cc.fascinated.bat.features.base.commands.botadmin.premium;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.Category;
import cc.fascinated.bat.command.CommandInfo;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
@ -11,13 +12,11 @@ import org.springframework.stereotype.Component;
* @author Fascinated (fascinated7)
*/
@Component
@CommandInfo(name = "premiumadmin", description = "Set a guild as premium", botOwnerOnly = true)
@CommandInfo(name = "premiumadmin", description = "Set a guild as premium", botOwnerOnly = true, category = Category.BOT_ADMIN)
public class PremiumAdminCommand extends BatCommand {
@Autowired
public PremiumAdminCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(SetSubCommand.class),
context.getBean(RemoveSubCommand.class)
);
super.addSubCommand(context.getBean(SetSubCommand.class));
super.addSubCommand(context.getBean(RemoveSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.botadmin.premium;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.model.BatGuild;
import cc.fascinated.bat.model.BatUser;
@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -21,13 +20,13 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "remove", description = "Remove premium from a guild")
public class RemoveSubCommand extends BatCommand {
public class RemoveSubCommand extends BatSubCommand {
private final GuildService guildService;
@Autowired
public RemoveSubCommand(GuildService guildService) {
this.guildService = guildService;
super.addOptions(new OptionData(OptionType.STRING, "guild", "The guild id to set as premium", true));
super.addOption(OptionType.STRING, "guild", "The guild id to set as premium", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.botadmin.premium;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.model.BatGuild;
import cc.fascinated.bat.model.BatUser;
@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -21,16 +20,14 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "set", description = "Adds premium to a guild")
public class SetSubCommand extends BatCommand {
public class SetSubCommand extends BatSubCommand {
private final GuildService guildService;
@Autowired
public SetSubCommand(@NonNull GuildService guildService) {
this.guildService = guildService;
super.addOptions(
new OptionData(OptionType.STRING, "guild", "The guild id to set as premium", true),
new OptionData(OptionType.BOOLEAN, "infinite", "Whether the premium length should be infinite", true)
);
super.addOption(OptionType.STRING, "guild", "The guild id to set as premium", true);
super.addOption(OptionType.BOOLEAN, "infinite", "Whether the premium length should be infinite", true);
}
@Override

@ -15,7 +15,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -25,7 +24,7 @@ import org.springframework.stereotype.Component;
@CommandInfo(name = "lookupuser", description = "Lookup a user", userInstall = true)
public class LookupUserCommand extends BatCommand {
public LookupUserCommand() {
super.addOptions(new OptionData(OptionType.STRING, "id", "The id of the user", true));
super.addOption(OptionType.STRING, "id", "The id of the user", true);
}
@Override

@ -11,7 +11,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -44,7 +43,7 @@ public class EightBallCommand extends BatCommand {
};
public EightBallCommand() {
super.addOptions(new OptionData(OptionType.STRING, "question", "The question you want to ask the 8ball", true));
super.addOption(OptionType.STRING, "question", "The question you want to ask the 8ball", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.fun.image;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.WebRequest;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "cat", description = "Get a random cat image")
public class CatSubCommand extends BatCommand {
public class CatSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
CatImageToken[] responseEntity = WebRequest.getAsEntity("https://api.thecatapi.com/v1/images/search", CatImageToken[].class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.fun.image;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.WebRequest;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "dog", description = "Get a random dog image")
public class DogSubCommand extends BatCommand {
public class DogSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
RandomImage responseEntity = WebRequest.getAsEntity("https://dog.ceo/api/breeds/image/random", RandomImage.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.fun.image;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.WebRequest;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "duck", description = "Get a random duck image")
public class DuckSubCommand extends BatCommand {
public class DuckSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
RandomDuck responseEntity = WebRequest.getAsEntity("https://random-d.uk/api/v2/random", RandomDuck.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.fun.image;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.WebRequest;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "fox", description = "Get a random fox image")
public class FoxSubCommand extends BatCommand {
public class FoxSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
RandomFoxToken responseEntity = WebRequest.getAsEntity("https://randomfox.ca/floof/", RandomFoxToken.class);

@ -16,11 +16,9 @@ import org.springframework.stereotype.Component;
public class ImageCommand extends BatCommand {
@Autowired
public ImageCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(CatSubCommand.class),
context.getBean(DogSubCommand.class),
context.getBean(FoxSubCommand.class),
context.getBean(DuckSubCommand.class)
);
super.addSubCommand(context.getBean(CatSubCommand.class));
super.addSubCommand(context.getBean(DogSubCommand.class));
super.addSubCommand(context.getBean(FoxSubCommand.class));
super.addSubCommand(context.getBean(DuckSubCommand.class));
}
}

@ -2,6 +2,7 @@ package cc.fascinated.bat.features.base.commands.general;
import cc.fascinated.bat.Consts;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.Category;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
@ -16,6 +17,7 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
@ -27,6 +29,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Fascinated (fascinated7)
@ -59,45 +62,44 @@ public class HelpCommand extends BatCommand implements EventListener {
event.reply("Invalid category selected.").queue();
return;
}
event.reply("hello this doesnt work yet").queue();
// StringBuilder commands = new StringBuilder();
// List<BatCommand> categoryCommands = commandService.getCommandsByCategory(category, true);
// if (categoryCommands.isEmpty()) {
// commands = new StringBuilder("No commands available in this category.");
// } else {
// for (BatCommand command : categoryCommands) {
// if (!command.getSubCommands().isEmpty()) {
// for (Map.Entry<String, BatSubCommand> entry : command.getSubCommands().entrySet()) {
// BatSubCommand subCommand = entry.getValue();
// SubcommandData commandData = subCommand.getCommandData();
// commands.append("</%s %s:%s> - %s\n".formatted(
// command.getCommandInfo().name(),
// commandData.getName(),
// subCommand.getCommandSnowflake(),
// commandData.getDescription()
// ));
// }
// continue;
// }
// commands.append("</%s:%s> - %s\n".formatted(
// command.getCommandInfo().name(),
// command.getCommandSnowflake(),
// command.getCommandInfo().description()
// ));
// }
// }
//
// int subCommands = categoryCommands.stream().mapToInt(command -> command.getSubCommands().size()).sum();
// event.editMessageEmbeds(EmbedUtils.genericEmbed()
// .setAuthor("%s Category".formatted(category.getName()))
// .setDescription("%s command%s (with %s sub-command%s)\n\n**Commands:**\n%s".formatted(
// categoryCommands.size(),
// categoryCommands.size() == 1 ? "" : "s",
// subCommands,
// subCommands == 1 ? "" : "s",
// commands.toString()
// )).build()).queue();
StringBuilder commands = new StringBuilder();
List<BatCommand> categoryCommands = commandService.getCommandsByCategory(category, true);
if (categoryCommands.isEmpty()) {
commands = new StringBuilder("No commands available in this category.");
} else {
for (BatCommand command : categoryCommands) {
if (!command.getSubCommands().isEmpty()) {
for (Map.Entry<String, BatSubCommand> entry : command.getSubCommands().entrySet()) {
BatSubCommand subCommand = entry.getValue();
SubcommandData commandData = subCommand.getCommandData();
commands.append("</%s %s:%s> - %s\n".formatted(
command.getCommandInfo().name(),
commandData.getName(),
subCommand.getCommandSnowflake(),
commandData.getDescription()
));
}
continue;
}
commands.append("</%s:%s> - %s\n".formatted(
command.getCommandInfo().name(),
command.getCommandSnowflake(),
command.getCommandInfo().description()
));
}
}
int subCommands = categoryCommands.stream().mapToInt(command -> command.getSubCommands().size()).sum();
event.editMessageEmbeds(EmbedUtils.genericEmbed()
.setAuthor("%s Category".formatted(category.getName()))
.setDescription("%s command%s (with %s sub-command%s)\n\n**Commands:**\n%s".formatted(
categoryCommands.size(),
categoryCommands.size() == 1 ? "" : "s",
subCommands,
subCommands == 1 ? "" : "s",
commands.toString()
)).build()).queue();
}
/**
@ -107,8 +109,8 @@ public class HelpCommand extends BatCommand implements EventListener {
*/
private MessageEmbed createHomeEmbed() {
StringBuilder categories = new StringBuilder();
for (Category category : Category.values()) {
long commandCount = commandService.getCommandsByCategory(category).size();
for (Category category : Category.getCategories()) {
long commandCount = commandService.getCommandsByCategory(category, true).size();
categories.append("➜ %s - **%s Command%s**\n".formatted(
category.getName(),
commandCount,
@ -138,9 +140,9 @@ public class HelpCommand extends BatCommand implements EventListener {
private LayoutComponent[] createHomeActions() {
List<SelectOption> options = new ArrayList<>();
options.add(SelectOption.of("Home", "home").withEmoji(Emoji.fromUnicode("U+1F3E0")));
for (Category category : Category.values()) {
options.add(SelectOption.of(category.getName(), category.getName()).withEmoji(category.getEmoji()));
}
options.addAll(Category.getCategories().stream().map(category ->
SelectOption.of(category.getName(), category.getName()).withEmoji(category.getEmoji()))
.toList());
return new LayoutComponent[]{
ActionRow.of(

@ -15,9 +15,7 @@ import org.springframework.stereotype.Component;
public class AvatarCommand extends BatCommand {
@Autowired
public AvatarCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(GuildSubCommand.class),
context.getBean(UserSubCommand.class)
);
super.addSubCommand(context.getBean(GuildSubCommand.class));
super.addSubCommand(context.getBean(UserSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.general.avatar;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("avatar:guild.sub")
@CommandInfo(name = "guild", description = "View the avatar of the guild")
public class GuildSubCommand extends BatCommand {
public class GuildSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
ImageProxy icon = guild.getDiscordGuild().getIcon();

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.general.avatar;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -20,9 +19,9 @@ import org.springframework.stereotype.Component;
*/
@Component("avatar:user.sub")
@CommandInfo(name = "user", description = "View the avatar of a user", guildOnly = false)
public class UserSubCommand extends BatCommand {
public class UserSubCommand extends BatSubCommand {
public UserSubCommand() {
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the avatar of", true));
super.addOption(OptionType.USER, "user", "The user to view the avatar of", true);
}
@Override

@ -15,9 +15,7 @@ import org.springframework.stereotype.Component;
public class BannerCommand extends BatCommand {
@Autowired
public BannerCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(GuildSubCommand.class),
context.getBean(UserSubCommand.class)
);
super.addSubCommand(context.getBean(GuildSubCommand.class));
super.addSubCommand(context.getBean(UserSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.general.banner;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("banner:guild.sub")
@CommandInfo(name = "guild", description = "View the banner of the guild")
public class GuildSubCommand extends BatCommand {
public class GuildSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
ImageProxy banner = guild.getDiscordGuild().getBanner();

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.general.banner;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.utils.ImageProxy;
import org.springframework.stereotype.Component;
@ -21,9 +20,9 @@ import org.springframework.stereotype.Component;
*/
@Component("banner:user.sub")
@CommandInfo(name = "user", description = "View the banner of a user", guildOnly = false)
public class UserSubCommand extends BatCommand {
public class UserSubCommand extends BatSubCommand {
public UserSubCommand() {
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the banner of", true));
super.addOption(OptionType.USER, "user", "The user to view the banner of", true);
}
@Override

@ -16,10 +16,8 @@ import org.springframework.stereotype.Component;
public class ChannelCommand extends BatCommand {
@Autowired
public ChannelCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(ViewTopicSubCommand.class),
context.getBean(SetTopicSubCommand.class),
context.getBean(RemoveTopicSubCommand.class)
);
super.addSubCommand(context.getBean(ViewTopicSubCommand.class));
super.addSubCommand(context.getBean(SetTopicSubCommand.class));
super.addSubCommand(context.getBean(RemoveTopicSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.server.channel;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -21,9 +20,9 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "removetopic", description = "Remove the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL)
public class RemoveTopicSubCommand extends BatCommand {
public class RemoveTopicSubCommand extends BatSubCommand {
public RemoveTopicSubCommand() {
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel to remove the topic of", false));
super.addOption(OptionType.CHANNEL, "channel", "The channel to remove the topic of", false);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.server.channel;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -13,27 +13,22 @@ import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
* @author Nick (okNick)
*/
@Component
@CommandInfo(name = "settopic", description = "Set the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL)
public class SetTopicSubCommand extends BatCommand {
public class SetTopicSubCommand extends BatSubCommand {
public SetTopicSubCommand() {
super.addOptions(
new OptionData(OptionType.STRING, "topic", "The topic to set", true),
new OptionData(OptionType.CHANNEL, "channel", "The channel to set the topic of", false)
);
super.addOption(OptionType.STRING, "topic", "The topic to set", true);
super.addOption(OptionType.CHANNEL, "channel", "The channel to set the topic of", false);
}
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
Channel target = event.getOption("channel") == null ? channel : Objects.requireNonNull(event.getOption("channel")).getAsChannel();
Channel target = event.getOption("channel") == null ? channel : event.getOption("channel").getAsChannel();
if (!(target instanceof TextChannel textChannel)) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
@ -42,7 +37,7 @@ public class SetTopicSubCommand extends BatCommand {
return;
}
String topic = Objects.requireNonNull(event.getOption("topic")).getAsString();
String topic = event.getOption("topic").getAsString();
if (topic.length() > 1024) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("The topic must be 1024 characters or less!")

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.server.channel;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -12,7 +12,6 @@ import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -20,9 +19,9 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "viewtopic", description = "View the topic of a channel")
public class ViewTopicSubCommand extends BatCommand {
public class ViewTopicSubCommand extends BatSubCommand {
public ViewTopicSubCommand() {
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel to view the topic of", false));
super.addOption(OptionType.CHANNEL, "channel", "The channel to view the topic of", false);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.server.feature;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.Feature;
@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,10 +22,10 @@ import org.springframework.stereotype.Component;
*/
@Component("feature:disable.sub")
@CommandInfo(name = "disable", description = "Disables a feature")
public class DisableSubCommand extends BatCommand {
public class DisableSubCommand extends BatSubCommand {
@Autowired
public DisableSubCommand() {
super.addOptions(new OptionData(OptionType.STRING, "feature", "The feature to disable", true));
super.addOption(OptionType.STRING, "feature", "The feature to disable", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.server.feature;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.Feature;
@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,10 +22,10 @@ import org.springframework.stereotype.Component;
*/
@Component("feature:enable.sub")
@CommandInfo(name = "enable", description = "Enables a feature")
public class EnableSubCommand extends BatCommand {
public class EnableSubCommand extends BatSubCommand {
@Autowired
public EnableSubCommand() {
super.addOptions(new OptionData(OptionType.STRING, "feature", "The feature to enable", true));
super.addOption(OptionType.STRING, "feature", "The feature to enable", true);
}
@Override

@ -17,10 +17,8 @@ import org.springframework.stereotype.Component;
public class FeatureCommand extends BatCommand {
@Autowired
public FeatureCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(EnableSubCommand.class),
context.getBean(DisableSubCommand.class),
context.getBean(ListSubCommand.class)
);
super.addSubCommand(context.getBean(EnableSubCommand.class));
super.addSubCommand(context.getBean(DisableSubCommand.class));
super.addSubCommand(context.getBean(ListSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.base.commands.server.feature;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.Feature;
@ -19,7 +19,7 @@ import org.springframework.stereotype.Component;
*/
@Component("feature:list.sub")
@CommandInfo(name = "list", description = "Lists the features and their states")
public class ListSubCommand extends BatCommand {
public class ListSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
StringBuilder featureStates = new StringBuilder();

@ -15,13 +15,11 @@ import org.springframework.stereotype.Component;
public class BirthdayCommand extends BatCommand {
@Autowired
public BirthdayCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(SetSubCommand.class),
context.getBean(RemoveSubCommand.class),
context.getBean(ChannelSubCommand.class),
context.getBean(MessageSubCommand.class),
context.getBean(ViewSubCommand.class),
context.getBean(PrivateSubCommand.class)
);
super.addSubCommand(context.getBean(SetSubCommand.class));
super.addSubCommand(context.getBean(RemoveSubCommand.class));
super.addSubCommand(context.getBean(ChannelSubCommand.class));
super.addSubCommand(context.getBean(MessageSubCommand.class));
super.addSubCommand(context.getBean(ViewSubCommand.class));
super.addSubCommand(context.getBean(PrivateSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.birthday.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.TextChannelUtils;
@ -16,7 +16,6 @@ import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -25,10 +24,10 @@ import org.springframework.stereotype.Component;
*/
@Component("birthday:channel.sub")
@CommandInfo(name = "channel", description = "Sets the birthday notification channel", requiredPermissions = Permission.MANAGE_SERVER)
public class ChannelSubCommand extends BatCommand {
public class ChannelSubCommand extends BatSubCommand {
@Autowired
public ChannelSubCommand() {
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel birthdays will be sent in", false));
super.addOption(OptionType.CHANNEL, "channel", "The channel birthdays will be sent in", false);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.birthday.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,10 +22,10 @@ import org.springframework.stereotype.Component;
*/
@Component("birthday:message.sub")
@CommandInfo(name = "message", description = "Changes the message that is sent when it is a user's birthday", requiredPermissions = Permission.MANAGE_SERVER)
public class MessageSubCommand extends BatCommand {
public class MessageSubCommand extends BatSubCommand {
@Autowired
public MessageSubCommand() {
super.addOptions(new OptionData(OptionType.STRING, "message", "The message that is sent. (Placeholders: {user}, {age})", true));
super.addOption(OptionType.STRING, "message", "The message that is sent. (Placeholders: {user}, {age})", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.birthday.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.birthday.UserBirthday;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,10 +22,10 @@ import org.springframework.stereotype.Component;
*/
@Component("birthday:private.sub")
@CommandInfo(name = "private", description = "Changes whether your birthday is private or not")
public class PrivateSubCommand extends BatCommand {
public class PrivateSubCommand extends BatSubCommand {
@Autowired
public PrivateSubCommand() {
super.addOptions(new OptionData(OptionType.BOOLEAN, "enabled", "Whether your birthday is private or not", true));
super.addOption(OptionType.BOOLEAN, "enabled", "Whether your birthday is private or not", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.birthday.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component("birthday:remove.sub")
@CommandInfo(name = "remove", description = "Remove your birthday from this guild")
public class RemoveSubCommand extends BatCommand {
public class RemoveSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
BirthdayProfile profile = guild.getBirthdayProfile();

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.birthday.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.birthday.UserBirthday;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -27,12 +26,12 @@ import java.util.Date;
*/
@Component("birthday:add.sub")
@CommandInfo(name = "set", description = "Add your birthday to this guild")
public class SetSubCommand extends BatCommand {
public class SetSubCommand extends BatSubCommand {
private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd/MM/yyyy");
@Autowired
public SetSubCommand() {
super.addOptions(new OptionData(OptionType.STRING, "birthday", "Your birthday (format: DAY/MONTH/YEAR - 01/05/2004)", true));
super.addOption(OptionType.STRING, "birthday", "Your birthday (format: DAY/MONTH/YEAR - 01/05/2004)", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.birthday.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.birthday.UserBirthday;
@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -24,13 +23,13 @@ import org.springframework.stereotype.Component;
*/
@Component("birthday:view.sub")
@CommandInfo(name = "view", description = "Add your birthday to this guild")
public class ViewSubCommand extends BatCommand {
public class ViewSubCommand extends BatSubCommand {
private final UserService userService;
@Autowired
public ViewSubCommand(@NonNull UserService userService) {
this.userService = userService;
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the birthday of", false));
super.addOption(OptionType.USER, "user", "The user to view the birthday of", false);
}
@Override

@ -15,6 +15,6 @@ import org.springframework.stereotype.Component;
public class DragCommand extends BatCommand {
@Autowired
public DragCommand(@NonNull ApplicationContext context) {
super.addSubCommands(context.getBean(RequestSubCommand.class));
super.addSubCommand(context.getBean(RequestSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.drag.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.TimerUtils;
@ -16,7 +16,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.springframework.stereotype.Component;
@ -31,7 +30,7 @@ import java.util.Set;
*/
@Component
@CommandInfo(name = "request", description = "Request to be moved to a voice channel")
public class RequestSubCommand extends BatCommand implements EventListener {
public class RequestSubCommand extends BatSubCommand implements EventListener {
/**
* A list of join requests
*/
@ -41,7 +40,7 @@ public class RequestSubCommand extends BatCommand implements EventListener {
private final long checkInterval = Duration.ofSeconds(10).toMillis();
public RequestSubCommand() {
super.addOptions(new OptionData(OptionType.USER, "user", "The user you want to join", true));
super.addOption(OptionType.USER, "user", "The user you want to join", true);
TimerUtils.scheduleRepeating(() -> {
Set<DragRequest> toRemove = new HashSet<>();

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.logging.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -30,7 +30,7 @@ import java.util.List;
*/
@Component("logs:list.sub")
@CommandInfo(name = "list", description = "See all the log types and their channels")
public class ListSubCommand extends BatCommand implements EventListener {
public class ListSubCommand extends BatSubCommand implements EventListener {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
List<Button> buttons = new ArrayList<>();

@ -16,10 +16,8 @@ import org.springframework.stereotype.Component;
public class LogsCommand extends BatCommand {
@Autowired
public LogsCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(SetSubCommand.class),
context.getBean(RemoveSubCommand.class),
context.getBean(ListSubCommand.class)
);
super.addSubCommand(context.getBean(SetSubCommand.class));
super.addSubCommand(context.getBean(RemoveSubCommand.class));
super.addSubCommand(context.getBean(ListSubCommand.class));
}
}

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.logging.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -16,7 +16,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
import java.util.List;
@ -26,9 +25,9 @@ import java.util.List;
*/
@Component("logs:remove.sub")
@CommandInfo(name = "remove", description = "Remove the channel for a log type")
public class RemoveSubCommand extends BatCommand {
public class RemoveSubCommand extends BatSubCommand {
public RemoveSubCommand() {
super.addOptions(new OptionData(OptionType.STRING, "type", "The type of log to remove", true));
super.addOption(OptionType.STRING, "type", "The type of log to remove", true);
}
@Override

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.logging.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -17,7 +17,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
import java.util.List;
@ -27,12 +26,10 @@ import java.util.List;
*/
@Component("logs:set.sub")
@CommandInfo(name = "set", description = "Set the channel for a log type")
public class SetSubCommand extends BatCommand {
public class SetSubCommand extends BatSubCommand {
public SetSubCommand() {
super.addOptions(
new OptionData(OptionType.STRING, "type", "The type of log to set", true),
new OptionData(OptionType.CHANNEL, "channel", "The channel to set the log to", true)
);
super.addOption(OptionType.STRING, "type", "The type of log to set", true);
super.addOption(OptionType.CHANNEL, "channel", "The channel to set the log to", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.messagesnipe.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.messagesnipe.MessageSnipeFeature;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component("messagesnipe:clear.sub")
@CommandInfo(name = "clear", description = "Clears the known sniped messages for this guild", requiredPermissions = Permission.MESSAGE_MANAGE)
public class ClearSubCommand extends BatCommand {
public class ClearSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
boolean cleared = MessageSnipeFeature.clearSnipedMessages(guild);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.messagesnipe.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "deleted", description = "Snipe the last deleted message in this channel")
public class DeletedSubCommand extends BatCommand {
public class DeletedSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
SnipedMessage message = MessageSnipeFeature.getDeletedMessage(guild, channel.getId());

@ -13,9 +13,7 @@ import org.springframework.stereotype.Component;
@CommandInfo(name = "snipe", description = "Snipe messages")
public class MessageSnipeCommand extends BatCommand {
public MessageSnipeCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(DeletedSubCommand.class),
context.getBean(ClearSubCommand.class)
);
super.addSubCommand(context.getBean(DeletedSubCommand.class));
super.addSubCommand(context.getBean(ClearSubCommand.class));
}
}

@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
import java.util.List;
@ -29,7 +28,7 @@ public class PurgeCommand extends BatCommand {
private final long MESSAGE_DELETE_DELAY = TimeUnit.SECONDS.toMillis(10);
public PurgeCommand() {
super.addOptions(new OptionData(OptionType.INTEGER, "amount", "The amount of messages to remove", true));
super.addOption(OptionType.INTEGER, "amount", "The amount of messages to remove", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.namehistory.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.namehistory.TrackedName;
@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,13 +22,13 @@ import org.springframework.stereotype.Component;
*/
@Component("namehistory:guild.sub")
@CommandInfo(name = "guild", description = "View the guild nickname history of a user")
public class GuildSubCommand extends BatCommand {
public class GuildSubCommand extends BatSubCommand {
private final UserService userService;
@Autowired
public GuildSubCommand(@NonNull UserService userService) {
this.userService = userService;
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the name history of", false));
super.addOption(OptionType.USER, "user", "The user to view the name history of", false);
}
@Override

@ -15,9 +15,7 @@ import org.springframework.stereotype.Component;
public class NameHistoryCommand extends BatCommand {
@Autowired
public NameHistoryCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(UserSubCommand.class),
context.getBean(GuildSubCommand.class)
);
super.addSubCommand(context.getBean(UserSubCommand.class));
super.addSubCommand(context.getBean(GuildSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.namehistory.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.namehistory.TrackedName;
@ -14,7 +14,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -23,13 +22,13 @@ import org.springframework.stereotype.Component;
*/
@Component("namehistory:user.sub")
@CommandInfo(name = "user", description = "View the global name history of a user", guildOnly = false)
public class UserSubCommand extends BatCommand {
public class UserSubCommand extends BatSubCommand {
private final UserService userService;
@Autowired
public UserSubCommand(@NonNull UserService userService) {
this.userService = userService;
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the name history of", false));
super.addOption(OptionType.USER, "user", "The user to view the name history of", false);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.reminder.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.reminder.ReminderProfile;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("reminder:clear.sub")
@CommandInfo(name = "clear", description = "Clear all your active reminders.")
public class ClearSubCommand extends BatCommand {
public class ClearSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
ReminderProfile profile = guild.getReminderProfile();

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.reminder.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -19,7 +19,7 @@ import org.springframework.stereotype.Component;
*/
@Component("reminder:list.sub")
@CommandInfo(name = "list", description = "View your active reminders.")
public class ListSubCommand extends BatCommand {
public class ListSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
ReminderProfile profile = guild.getReminderProfile();

@ -15,10 +15,8 @@ import org.springframework.stereotype.Component;
public class ReminderCommand extends BatCommand {
@Autowired
public ReminderCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(SetSubCommand.class),
context.getBean(ListSubCommand.class),
context.getBean(ClearSubCommand.class)
);
super.addSubCommand(context.getBean(SetSubCommand.class));
super.addSubCommand(context.getBean(ListSubCommand.class));
super.addSubCommand(context.getBean(ClearSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.reminder.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.TimeUtils;
@ -15,7 +15,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
import java.util.Date;
@ -26,12 +25,10 @@ import java.util.concurrent.TimeUnit;
*/
@Component("reminder:set.sub")
@CommandInfo(name = "set", description = "Set a reminder.")
public class SetSubCommand extends BatCommand {
public class SetSubCommand extends BatSubCommand {
public SetSubCommand() {
super.addOptions(
new OptionData(OptionType.STRING, "reminder", "The reminder to set.", true),
new OptionData(OptionType.STRING, "time", "After how long should the reminder be sent. (eg: 5m)", true)
);
super.addOption(OptionType.STRING, "reminder", "The reminder to set.", true);
super.addOption(OptionType.STRING, "time", "After how long should the reminder be sent. (eg: 5m)", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.numberone;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.TextChannelUtils;
@ -15,7 +15,6 @@ import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -24,10 +23,10 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber-number-one-feed:channel.sub")
@CommandInfo(name = "channel", description = "Sets the feed channel")
public class ChannelSubCommand extends BatCommand {
public class ChannelSubCommand extends BatSubCommand {
@Autowired
public ChannelSubCommand() {
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel scores are sent in", false));
super.addOption(OptionType.CHANNEL, "channel", "The channel scores are sent in", false);
}
@Override

@ -14,9 +14,7 @@ import org.springframework.stereotype.Component;
@CommandInfo(name = "scoresaber-number-one-feed", description = "Modifies the settings for the feed.", requiredPermissions = Permission.MANAGE_SERVER)
public class NumberOneFeedCommand extends BatCommand {
public NumberOneFeedCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(ChannelSubCommand.class),
context.getBean(ResetSubCommand.class)
);
super.addSubCommand(context.getBean(ChannelSubCommand.class));
super.addSubCommand(context.getBean(ResetSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.numberone;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.scoresaber.profile.guild.NumberOneScoreFeedProfile;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber-number-one-feed:reset.sub")
@CommandInfo(name = "reset", description = "Resets the settings")
public class ResetSubCommand extends BatCommand {
public class ResetSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
NumberOneScoreFeedProfile profile = guild.getProfile(NumberOneScoreFeedProfile.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.scoresaber;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -22,12 +21,12 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber:link.sub")
@CommandInfo(name = "link", description = "Links your ScoreSaber profile")
public class LinkSubCommand extends BatCommand {
public class LinkSubCommand extends BatSubCommand {
private final ScoreSaberService scoreSaberService;
@Autowired
public LinkSubCommand(@NonNull ScoreSaberService scoreSaberService) {
super.addOptions(new OptionData(OptionType.STRING, "link", "Link your ScoreSaber profile", true));
super.addOption(OptionType.STRING, "link", "Link your ScoreSaber profile", true);
this.scoreSaberService = scoreSaberService;
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.scoresaber;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.model.BatGuild;
import cc.fascinated.bat.model.BatUser;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber:me.sub")
@CommandInfo(name = "me", description = "Gets your ScoreSaber profile")
public class MeSubCommand extends BatCommand {
public class MeSubCommand extends BatSubCommand {
private final ScoreSaberService scoreSaberService;
@Autowired

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.scoresaber;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.scoresaber.profile.user.ScoreSaberProfile;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber:reset.sub")
@CommandInfo(name = "reset", description = "Reset your settings")
public class ResetSubCommand extends BatCommand {
public class ResetSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
ScoreSaberProfile profile = user.getScoreSaberProfile();

@ -35,12 +35,10 @@ public class ScoreSaberCommand extends BatCommand {
public ScoreSaberCommand(@NonNull ScoreSaberService scoreSaberService, @NonNull ApplicationContext context) {
this.scoreSaberService = scoreSaberService;
super.addSubCommands(
context.getBean(LinkSubCommand.class),
context.getBean(UserSubCommand.class),
context.getBean(MeSubCommand.class),
context.getBean(ResetSubCommand.class)
);
super.addSubCommand(context.getBean(LinkSubCommand.class));
super.addSubCommand(context.getBean(UserSubCommand.class));
super.addSubCommand(context.getBean(MeSubCommand.class));
super.addSubCommand(context.getBean(ResetSubCommand.class));
}
/**

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.scoresaber;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.model.BatGuild;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -22,13 +21,13 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber:user.sub")
@CommandInfo(name = "user", description = "Gets a ScoreSaber profile")
public class UserSubCommand extends BatCommand {
public class UserSubCommand extends BatSubCommand {
private final ScoreSaberService scoreSaberService;
private final UserService userService;
@Autowired
public UserSubCommand(@NonNull ScoreSaberService scoreSaberService, @NonNull UserService userService) {
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the ScoreSaber profile of", true));
super.addOption(OptionType.USER, "user", "The user to view the ScoreSaber profile of", true);
this.scoreSaberService = scoreSaberService;
this.userService = userService;
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.userfeed;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.common.TextChannelUtils;
@ -15,7 +15,6 @@ import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -24,10 +23,10 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber-user-feed:channel.sub")
@CommandInfo(name = "channel", description = "Sets the feed channel")
public class ChannelSubCommand extends BatCommand {
public class ChannelSubCommand extends BatSubCommand {
@Autowired
public ChannelSubCommand() {
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel scores are sent in", false));
super.addOption(OptionType.CHANNEL, "channel", "The channel scores are sent in", false);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.userfeed;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.scoresaber.profile.guild.UserScoreFeedProfile;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber-user-feed:reset.sub")
@CommandInfo(name = "reset", description = "Resets the settings")
public class ResetSubCommand extends BatCommand {
public class ResetSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
UserScoreFeedProfile profile = guild.getProfile(UserScoreFeedProfile.class);

@ -14,10 +14,8 @@ import org.springframework.stereotype.Component;
@CommandInfo(name = "scoresaber-user-feed", description = "Modifies the settings for the feed.", requiredPermissions = Permission.MANAGE_CHANNEL)
public class UserFeedCommand extends BatCommand {
public UserFeedCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(UserSubCommand.class),
context.getBean(ChannelSubCommand.class),
context.getBean(ResetSubCommand.class
));
super.addSubCommand(context.getBean(UserSubCommand.class));
super.addSubCommand(context.getBean(ChannelSubCommand.class));
super.addSubCommand(context.getBean(ResetSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.scoresaber.command.userfeed;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.scoresaber.profile.guild.UserScoreFeedProfile;
@ -16,7 +16,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -25,13 +24,13 @@ import org.springframework.stereotype.Component;
*/
@Component("scoresaber-user-feed:user.sub")
@CommandInfo(name = "user", description = "Adds or removes a user from the feed")
public class UserSubCommand extends BatCommand {
public class UserSubCommand extends BatSubCommand {
private final GuildService guildService;
private final UserService userService;
@Autowired
public UserSubCommand(GuildService guildService, UserService userService) {
super.addOptions(new OptionData(OptionType.USER, "user", "Add or remove a user from the score feed", false));
super.addOption(OptionType.USER, "user", "Add or remove a user from the score feed", false);
this.guildService = guildService;
this.userService = userService;
}

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.spotify.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.event.EventListener;
import cc.fascinated.bat.exception.BatException;
@ -31,7 +31,7 @@ import java.util.concurrent.TimeUnit;
@Component
@Log4j2(topic = "Spotify Current Command")
@CommandInfo(name = "current", description = "Gets the currently playing Spotify track")
public class CurrentSubCommand extends BatCommand implements EventListener {
public class CurrentSubCommand extends BatSubCommand implements EventListener {
private final SpotifyService spotifyService;
@Autowired

@ -2,7 +2,7 @@ package cc.fascinated.bat.features.spotify.command;
import cc.fascinated.bat.Consts;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.event.EventListener;
@ -32,7 +32,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "link", description = "Link your Spotify account")
public class LinkSubCommand extends BatCommand implements EventListener {
public class LinkSubCommand extends BatSubCommand implements EventListener {
private final SpotifyService spotifyService;
@Autowired

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.spotify.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.features.spotify.SpotifyFeature;
import cc.fascinated.bat.model.BatGuild;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "pause", description = "Pause the current Spotify track")
public class PauseSubCommand extends BatCommand {
public class PauseSubCommand extends BatSubCommand {
private final SpotifyService spotifyService;
@Autowired

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.spotify.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.features.spotify.SpotifyFeature;
import cc.fascinated.bat.model.BatGuild;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "resume", description = "Resume the current Spotify track")
public class ResumeSubCommand extends BatCommand {
public class ResumeSubCommand extends BatSubCommand {
private final SpotifyService spotifyService;
@Autowired

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.spotify.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.features.spotify.SpotifyFeature;
import cc.fascinated.bat.model.BatGuild;
@ -20,7 +20,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "skip", description = "Skip the current Spotify track")
public class SkipSubCommand extends BatCommand {
public class SkipSubCommand extends BatSubCommand {
private static final Logger log = LoggerFactory.getLogger(SkipSubCommand.class);
private final SpotifyService spotifyService;

@ -16,13 +16,11 @@ import org.springframework.stereotype.Component;
public class SpotifyCommand extends BatCommand {
@Autowired
public SpotifyCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(LinkSubCommand.class),
context.getBean(UnlinkSubCommand.class),
context.getBean(PauseSubCommand.class),
context.getBean(ResumeSubCommand.class),
context.getBean(CurrentSubCommand.class),
context.getBean(SkipSubCommand.class)
);
super.addSubCommand(context.getBean(LinkSubCommand.class));
super.addSubCommand(context.getBean(UnlinkSubCommand.class));
super.addSubCommand(context.getBean(PauseSubCommand.class));
super.addSubCommand(context.getBean(ResumeSubCommand.class));
super.addSubCommand(context.getBean(CurrentSubCommand.class));
super.addSubCommand(context.getBean(SkipSubCommand.class));
}
}

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.spotify.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.event.EventListener;
@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@CommandInfo(name = "unlink", description = "Unlink your Spotify account")
public class UnlinkSubCommand extends BatCommand implements EventListener {
public class UnlinkSubCommand extends BatSubCommand implements EventListener {
@Override @SneakyThrows
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
SpotifyProfile profile = user.getProfile(SpotifyProfile.class);

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.tmdb.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.event.EventListener;
@ -18,7 +18,6 @@ import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -28,7 +27,7 @@ import java.util.Map;
@Component
@CommandInfo(name = "movie", description = "Get information about a movie")
public class MovieSubCommand extends BatCommand implements EventListener {
public class MovieSubCommand extends BatSubCommand implements EventListener {
private final TMDBService tmdbService;
private final Map<String, Map<String, String>> userCommands; // Map to store user commands and their parameters
@ -38,12 +37,11 @@ public class MovieSubCommand extends BatCommand implements EventListener {
this.tmdbService = tmdbService;
this.userCommands = new HashMap<>();
super.addOptions(
new OptionData(OptionType.STRING, "title", "The title of the movie", true),
new OptionData(OptionType.STRING, "language", "A locale code (en-US) to lookup movies in a specific language", false),
new OptionData(OptionType.STRING, "primary_release_year", "Filter the results so that only the primary release dates have this value", false),
new OptionData(OptionType.STRING, "region", "An ISO 3166-1 code (US) to lookup movies from a specific region", false)
);
super.addOption(OptionType.STRING, "title", "The title of the movie", true);
super.addOption(OptionType.STRING, "language", "A locale code (en-US) to lookup movies in a specific language", false);
super.addOption(OptionType.STRING, "primary_release_year", "Filter the results so that only the primary release dates have this value", false);
super.addOption(OptionType.STRING, "region", "An ISO 3166-1 code (US) to lookup movies from a specific region", false);
super.addOption(OptionType.STRING, "year", "Filter the results release dates to matches that include this value", false);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.tmdb.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.event.EventListener;
@ -18,7 +18,6 @@ import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -28,7 +27,7 @@ import java.util.Map;
@Component
@CommandInfo(name = "series", description = "Get information about a series")
public class SeriesSubCommand extends BatCommand implements EventListener {
public class SeriesSubCommand extends BatSubCommand implements EventListener {
private final TMDBService tmdbService;
private final Map<String, Map<String, String>> userCommands; // Map to store user commands and their parameters
@ -38,12 +37,10 @@ public class SeriesSubCommand extends BatCommand implements EventListener {
this.tmdbService = tmdbService;
this.userCommands = new HashMap<>();
addOptions(
new OptionData(OptionType.STRING, "title", "The title of the series", true),
new OptionData(OptionType.STRING, "language", "A locale code (en-US) to lookup movies in a specific language", false),
new OptionData(OptionType.INTEGER, "first_air_year", "Filter the results so that only the first air year has this value", false),
new OptionData(OptionType.INTEGER, "year", "Filter the results release dates to matches that include this value", false)
);
super.addOption(OptionType.STRING, "title", "The title of the series", true);
super.addOption(OptionType.STRING, "language", "A locale code (en-US) to lookup movies in a specific language", false);
super.addOption(OptionType.INTEGER, "first_air_year", "Filter the results so that only the first air year has this value", false);
super.addOption(OptionType.INTEGER, "year", "Filter the results release dates to matches that include this value", false);
}
@Override

@ -1,7 +1,6 @@
package cc.fascinated.bat.features.tmdb.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.Category;
import cc.fascinated.bat.command.CommandInfo;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
@ -12,13 +11,11 @@ import org.springframework.stereotype.Component;
* @author Nick (okNick)
*/
@Component
@CommandInfo(name = "tmdb", description = "Get information about movies and TV shows", guildOnly = false, userInstall = true, category = Category.MOVIES_TV)
@CommandInfo(name = "tmdb", description = "Get information about movies and TV shows", guildOnly = false, userInstall = true)
public class TMDBCommand extends BatCommand {
@Autowired
public TMDBCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(MovieSubCommand.class),
context.getBean(SeriesSubCommand.class)
);
super.addSubCommand(context.getBean(MovieSubCommand.class));
super.addSubCommand(context.getBean(SeriesSubCommand.class));
}
}

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.welcomer.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
@ -13,7 +13,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -21,9 +20,9 @@ import org.springframework.stereotype.Component;
*/
@Component("welcomer:channel.sub")
@CommandInfo(name = "channel", description = "Set the welcomer channel")
public class ChannelSubCommand extends BatCommand {
public class ChannelSubCommand extends BatSubCommand {
public ChannelSubCommand() {
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel to send the welcomer messages to", true));
super.addOption(OptionType.CHANNEL, "channel", "The channel to send the welcomer messages to", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.welcomer.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.welcomer.WelcomerPlaceholders;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
*/
@Component("welcomer:current.sub")
@CommandInfo(name = "current", description = "View the current welcomer configuration")
public class CurrentSubCommand extends BatCommand {
public class CurrentSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
WelcomerProfile profile = guild.getWelcomerProfile();

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.welcomer.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -15,7 +15,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -23,14 +22,12 @@ import org.springframework.stereotype.Component;
*/
@Component("welcomer:embed.sub")
@CommandInfo(name = "embed", description = "Set the welcomer embed (this will remove the welcomer plain message if set)")
public class EmbedSubCommand extends BatCommand {
public class EmbedSubCommand extends BatSubCommand {
public EmbedSubCommand() {
super.addOptions(
new OptionData(OptionType.BOOLEAN, "ping-before-send", "Should we ping the user before sending the message?", true),
new OptionData(OptionType.STRING, "description", "The description of the embed", true),
new OptionData(OptionType.STRING, "color", "The color of the embed", true),
new OptionData(OptionType.STRING, "title", "The title of the embed (only set if you want a title)", false)
);
super.addOption(OptionType.BOOLEAN, "ping-before-send", "Should we ping the user before sending the message?", true);
super.addOption(OptionType.STRING, "description", "The description of the embed", true);
super.addOption(OptionType.STRING, "color", "The color of the embed", true);
super.addOption(OptionType.STRING, "title", "The title of the embed (only set if you want a title)", false);
}
@Override

@ -1,7 +1,7 @@
package cc.fascinated.bat.features.welcomer.command;
import cc.fascinated.bat.Emojis;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
import cc.fascinated.bat.common.EmbedUtils;
@ -15,7 +15,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import org.springframework.stereotype.Component;
/**
@ -23,9 +22,9 @@ import org.springframework.stereotype.Component;
*/
@Component("welcomer:message.sub")
@CommandInfo(name = "message", description = "Set the welcomer message (this will remove the welcomer embed if set)")
public class MessageSubCommand extends BatCommand {
public class MessageSubCommand extends BatSubCommand {
public MessageSubCommand() {
super.addOptions(new OptionData(OptionType.STRING, "message", "The message to send", true));
super.addOption(OptionType.STRING, "message", "The message to send", true);
}
@Override

@ -1,6 +1,6 @@
package cc.fascinated.bat.features.welcomer.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.BatSubCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
*/
@Component("welcomer:reset.sub")
@CommandInfo(name = "reset", description = "Clear the welcomer configuration")
public class ResetSubCommand extends BatCommand {
public class ResetSubCommand extends BatSubCommand {
@Override
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
WelcomerProfile profile = guild.getWelcomerProfile();

@ -16,12 +16,10 @@ import org.springframework.stereotype.Component;
public class WelcomerCommand extends BatCommand {
@Autowired
public WelcomerCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(MessageSubCommand.class),
context.getBean(EmbedSubCommand.class),
context.getBean(CurrentSubCommand.class),
context.getBean(ChannelSubCommand.class),
context.getBean(ResetSubCommand.class)
);
super.addSubCommand(context.getBean(MessageSubCommand.class));
super.addSubCommand(context.getBean(EmbedSubCommand.class));
super.addSubCommand(context.getBean(CurrentSubCommand.class));
super.addSubCommand(context.getBean(ChannelSubCommand.class));
super.addSubCommand(context.getBean(ResetSubCommand.class));
}
}

@ -1,8 +1,7 @@
package cc.fascinated.bat.service;
import cc.fascinated.bat.Consts;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.Category;
import cc.fascinated.bat.command.*;
import cc.fascinated.bat.common.EmbedUtils;
import cc.fascinated.bat.config.Config;
import cc.fascinated.bat.features.base.profile.FeatureProfile;
@ -22,11 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.*;
/**
* @author Fascinated (fascinated7)
@ -64,11 +59,11 @@ public class CommandService extends ListenerAdapter {
* @param command The command to register
*/
public void registerCommand(@NonNull BatCommand command) {
String commandName = command.getInfo().getName().toLowerCase();
String commandName = command.getCommandInfo().name().toLowerCase();
if (commands.get(commandName) != null) {
return;
}
log.info("Registered command \"{}\"", command.getInfo().getName());
log.info("Registered command \"{}\"", command.getCommandInfo().name());
commands.put(commandName, command);
}
@ -95,7 +90,8 @@ public class CommandService extends ListenerAdapter {
// Unregister all commands that Discord has but we don't
jda.retrieveCommands().complete().forEach(command -> {
if (commands.containsKey(command.getName())
|| commands.get(command.getName()).getInfo().isBotOwnerOnly()) {
&& (commands.get(command.getName()).getCommandInfo().category().isHidden()
|| commands.get(command.getName()).getCommandInfo().botOwnerOnly())) {
jda.deleteCommandById(command.getId()).complete(); // Unregister the command on Discord
log.info("Unregistered hidden command \"{}\" from Discord", command.getName());
return;
@ -110,19 +106,19 @@ public class CommandService extends ListenerAdapter {
// Register all commands
List<Command> discordCommands = jda.updateCommands().addCommands(commands.values().stream()
.filter(command -> !command.getInfo().isBotOwnerOnly())
.filter(command -> !command.getCategory().isHidden() || !command.isBotOwnerOnly())
.map(BatCommand::getCommandData).toList()).complete();
for (Command discordCommand : discordCommands) {
commands.get(discordCommand.getName()).setSnowflake(discordCommand.getIdLong());
commands.get(discordCommand.getName()).setCommandSnowflake(discordCommand.getIdLong());
if (!discordCommand.getSubcommands().isEmpty()) {
for (Command.Subcommand subCommand : discordCommand.getSubcommands()) {
commands.get(discordCommand.getName()).getSubCommands().get(subCommand.getName()).setSnowflake(subCommand.getIdLong());
commands.get(discordCommand.getName()).getSubCommands().get(subCommand.getName()).setCommandSnowflake(subCommand.getIdLong());
}
}
}
if (adminGuild != null) {
adminGuild.updateCommands().addCommands(commands.values().stream()
.filter(command -> command.getInfo().isBotOwnerOnly())
.filter(command -> command.getCategory().isHidden() || command.isBotOwnerOnly())
.map(BatCommand::getCommandData).toList()).complete();
} else {
log.error("Unable to find the admin guild to register hidden commands");
@ -136,79 +132,111 @@ public class CommandService extends ListenerAdapter {
* @param category The category
* @return The commands
*/
public List<BatCommand> getCommandsByCategory(Category category) {
return commands.values().stream().filter(command -> command.getInfo().getCategory() == category).toList();
public List<BatCommand> getCommandsByCategory(Category category, boolean hideHiddenCategories) {
return commands.values().stream().filter(command -> command.getCategory() == category && (hideHiddenCategories && !category.isHidden())).toList();
}
@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
long before = System.currentTimeMillis();
Guild discordGuild = event.getGuild();
if (event.getUser().isBot()) {
return;
}
long before = System.currentTimeMillis();
BatCommand command = commands.get(event.getName());
String commandName = event.getName();
BatCommand command = commands.get(commandName);
if (command == null) {
return;
}
String subcommandName = event.getSubcommandName();
if (subcommandName != null) { // Use the sub command if given
command = command.getSubCommands().get(subcommandName);
}
boolean ranInsideGuild = discordGuild != null;
BatGuild guild = ranInsideGuild ? guildService.getGuild(discordGuild.getId()) : null;
BatUser user = userService.getUser(event.getUser().getId());
BatGuild guild = event.getGuild() == null ? null : guildService.getGuild(event.getGuild().getId());
// Only the bot owner can run this command
if (command.getInfo().isBotOwnerOnly() && !user.getId().equalsIgnoreCase(Consts.BOT_OWNER)) {
if (command.getCommandInfo().botOwnerOnly() && !user.getId().equalsIgnoreCase(Consts.BOT_OWNER)) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("You do not have permission to execute this command")
.build()).setEphemeral(true).queue();
return;
}
// Check if the command is guild only and if it was not ran inside a guild
if (command.getInfo().isGuildOnly() && guild == null) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("This command can only be executed in a guild")
.build()).setEphemeral(true).queue();
return;
}
try {
BatCommandExecutor executor = null;
CommandInfo commandInfo = command.getCommandInfo();
List<Permission> requiredPermissions = new ArrayList<>();
// Check if the feature is disabled in the guild
if (guild != null) {
FeatureProfile featureProfile = guild.getFeatureProfile();
if (featureProfile.isFeatureDisabled(command.getFeature())) {
// No args provided, use the main command executor
if (event.getInteraction().getSubcommandName() == null) {
executor = command;
requiredPermissions.addAll(Arrays.asList(command.getCommandInfo().requiredPermissions()));
} else {
// Subcommand provided, use the subcommand executor
for (Map.Entry<String, BatSubCommand> subCommand : command.getSubCommands().entrySet()) {
if (subCommand.getKey().equalsIgnoreCase(event.getInteraction().getSubcommandName())) {
executor = subCommand.getValue();
requiredPermissions.addAll(Arrays.asList(subCommand.getValue().getCommandInfo().requiredPermissions()));
requiredPermissions.addAll(Arrays.asList(command.getCommandInfo().requiredPermissions())); // not sure if we'd want this, but it's here for now
commandInfo = subCommand.getValue().getCommandInfo();
break;
}
}
}
// Check if the executor is null
if (executor == null) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("The feature `%s` is disabled in this guild".formatted(command.getFeature().getName()))
.setDescription("Unable to find a command executor the command name ):")
.build()).queue();
return;
}
// Check if the user has the required permissions
if (ranInsideGuild && event.getMember() != null) {
List<Permission> missingPermissions = new ArrayList<>();
for (Permission permission : requiredPermissions) {
if (!event.getMember().hasPermission(permission)) {
missingPermissions.add(permission);
}
}
if (!missingPermissions.isEmpty()) {
StringBuilder missing = new StringBuilder();
for (Permission permission : missingPermissions) {
missing.append("`").append(permission.getName()).append("`").append(", ");
}
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("You are missing the following permissions to execute this command:\n" +
missing.substring(0, missing.length() - 2))
.build())
.setEphemeral(true)
.queue();
return;
}
}
// Check if the command is guild only and if it was not ran inside a guild
if (commandInfo.guildOnly() && guild == null) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("This command can only be executed in a guild")
.build()).setEphemeral(true).queue();
return;
}
}
// Check if the user has the required permissions
if (guild != null && event.getMember() != null) {
List<Permission> missingPermissions = new ArrayList<>();
for (Permission permission : command.getInfo().getPermissions()) {
if (!event.getMember().hasPermission(permission)) {
missingPermissions.add(permission);
// Check if the feature is disabled in the guild
if (guild != null) {
FeatureProfile featureProfile = guild.getFeatureProfile();
if (featureProfile.isFeatureDisabled(command.getFeature())) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("The feature `%s` is disabled in this guild".formatted(command.getFeature().getName()))
.build()).setEphemeral(true).queue();
return;
}
}
if (!missingPermissions.isEmpty()) {
event.replyEmbeds(EmbedUtils.errorEmbed()
.setDescription("You are missing the following permissions to execute this command:\n" +
missingPermissions.stream().map(perm -> "`" + perm.name() + "`").collect(Collectors.joining(", ")))
.build())
.setEphemeral(true)
.queue();
return;
}
}
// Execute the command
try {
command.execute(guild, user, event.getChannel(), event.getMember(), event.getInteraction());
log.info("Executed command \"{}\" for user \"{}\" (took: {}ms)", command.getInfo().getName(), user.getName(), System.currentTimeMillis() - before);
// Execute the command
executor.execute(guild, user, event.getChannel(), event.getMember(), event.getInteraction());
log.info("Executed command \"{}\" for user \"{}\" (took: {}ms)", commandName, user.getName(), System.currentTimeMillis() - before);
} catch (Exception ex) {
log.error("An error occurred while executing command \"{}\"", command.getInfo().getName(), ex);
log.error("An error occurred while executing command \"{}\"", commandName, ex);
event.replyEmbeds(EmbedUtils.genericInteractionError(ex).build()).setEphemeral(true).queue();
}
}

@ -2,6 +2,7 @@ package cc.fascinated.bat.service;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.features.Feature;
import cc.fascinated.bat.features.base.commands.server.feature.FeatureCommand;
import jakarta.annotation.PostConstruct;
import lombok.Getter;
import lombok.NonNull;
@ -41,16 +42,21 @@ public class FeatureService {
@PostConstruct
public void init() {
for (Feature feature : context.getBeansOfType(Feature.class).values()) {
features.put(feature.getName().toLowerCase(), feature);
}
context.getBeansOfType(Feature.class)
.values()
.forEach((feature) -> {
features.put(feature.getName().toLowerCase(), feature);
});
for (BatCommand command : context.getBeansOfType(BatCommand.class).values()) {
if (command.getFeature() == null) {
log.error("Command \"{}\" does not belong to a feature, not registering it...", command.getInfo().getName());
}
}
context.getBeansOfType(BatCommand.class)
.values()
.forEach((command) -> {
if (command.getFeature() == null) {
log.error("Command \"{}\" does not belong to a feature, not registering it...", command.getCommandInfo().name());
}
});
commandService.registerCommand(context.getBean(FeatureCommand.class));
commandService.registerSlashCommands(); // Register all slash commands
}

@ -29,7 +29,7 @@ bat:
# Sentry Configuration
sentry:
dsn: ""
dsn: "CHANGE_ME"
tracesSampleRate: 1.0
environment: "development"