diff --git a/src/main/java/cc/fascinated/bat/command/impl/server/channel/ChannelCommand.java b/src/main/java/cc/fascinated/bat/command/impl/server/channel/ChannelCommand.java new file mode 100644 index 0000000..65f5193 --- /dev/null +++ b/src/main/java/cc/fascinated/bat/command/impl/server/channel/ChannelCommand.java @@ -0,0 +1,22 @@ +package cc.fascinated.bat.command.impl.server.channel; + +import cc.fascinated.bat.command.BatCommand; +import cc.fascinated.bat.command.CommandInfo; +import lombok.NonNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +/** + * @author Nick (okNick) + */ +@Component +@CommandInfo(name = "channel", description = "View or set information about a channel") +public class ChannelCommand extends BatCommand { + @Autowired + public ChannelCommand(@NonNull ApplicationContext context) { + super.addSubCommand(context.getBean(ViewTopicSubCommand.class)); + super.addSubCommand(context.getBean(SetTopicSubCommand.class)); + super.addSubCommand(context.getBean(RemoveTopicSubCommand.class)); + } +} \ No newline at end of file diff --git a/src/main/java/cc/fascinated/bat/command/impl/server/channel/RemoveTopicSubCommand.java b/src/main/java/cc/fascinated/bat/command/impl/server/channel/RemoveTopicSubCommand.java new file mode 100644 index 0000000..9735985 --- /dev/null +++ b/src/main/java/cc/fascinated/bat/command/impl/server/channel/RemoveTopicSubCommand.java @@ -0,0 +1,53 @@ +package cc.fascinated.bat.command.impl.server.channel; + +import cc.fascinated.bat.command.BatSubCommand; +import cc.fascinated.bat.command.CommandInfo; +import cc.fascinated.bat.common.EmbedUtils; +import cc.fascinated.bat.model.BatGuild; +import cc.fascinated.bat.model.BatUser; +import lombok.NonNull; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.Channel; +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 org.springframework.stereotype.Component; + +/** + * @author Nick (okNick) + */ +@Component +@CommandInfo(name = "removetopic", description = "Remove the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL) +public class RemoveTopicSubCommand extends BatSubCommand { + public RemoveTopicSubCommand() { + super.addOption(OptionType.CHANNEL, "channel", "The channel to remove the topic of", false); + } + + @Override + public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) { + Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel(); + if (!(target instanceof TextChannel textChannel)) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("<#%s> is not a text channel!".formatted(target.getId())) + .build()) + .queue(); + return; + } + + if (textChannel.getTopic() == null) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("<#%s> does not have a topic!".formatted(textChannel.getId())) + .build()) + .queue(); + return; + } + + textChannel.getManager().setTopic(null).queue(); + interaction.replyEmbeds(EmbedUtils.successEmbed() + .setDescription("Successfully removed the topic of <#%s>".formatted(textChannel.getId())) + .build() + ).queue(); + } +} \ No newline at end of file diff --git a/src/main/java/cc/fascinated/bat/command/impl/server/channel/SetTopicSubCommand.java b/src/main/java/cc/fascinated/bat/command/impl/server/channel/SetTopicSubCommand.java new file mode 100644 index 0000000..7a86419 --- /dev/null +++ b/src/main/java/cc/fascinated/bat/command/impl/server/channel/SetTopicSubCommand.java @@ -0,0 +1,55 @@ +package cc.fascinated.bat.command.impl.server.channel; + +import cc.fascinated.bat.command.BatSubCommand; +import cc.fascinated.bat.command.CommandInfo; +import cc.fascinated.bat.common.EmbedUtils; +import cc.fascinated.bat.model.BatGuild; +import cc.fascinated.bat.model.BatUser; +import lombok.NonNull; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.Channel; +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 org.springframework.stereotype.Component; + +/** + * @author Nick (okNick) + */ +@Component +@CommandInfo(name = "settopic", description = "Set the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL) +public class SetTopicSubCommand extends BatSubCommand { + public SetTopicSubCommand() { + 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 interaction) { + Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel(); + if (!(target instanceof TextChannel textChannel)) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("<#%s> is not a text channel!".formatted(target.getId())) + .build()) + .queue(); + return; + } + + String topic = interaction.getOption("topic").getAsString(); + if (topic.length() > 1024) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("The topic must be less than 1024 characters!") + .build()) + .queue(); + return; + } + + textChannel.getManager().setTopic(topic).queue(); + interaction.replyEmbeds(EmbedUtils.successEmbed() + .setDescription("Successfully set the topic of <#%s> to: \"%s\"".formatted(textChannel.getId(), topic)) + .build() + ).queue(); + } +} \ No newline at end of file diff --git a/src/main/java/cc/fascinated/bat/command/impl/server/channel/ViewTopicSubCommand.java b/src/main/java/cc/fascinated/bat/command/impl/server/channel/ViewTopicSubCommand.java new file mode 100644 index 0000000..c8d6ccd --- /dev/null +++ b/src/main/java/cc/fascinated/bat/command/impl/server/channel/ViewTopicSubCommand.java @@ -0,0 +1,52 @@ +package cc.fascinated.bat.command.impl.server.channel; + +import cc.fascinated.bat.command.BatSubCommand; +import cc.fascinated.bat.command.CommandInfo; +import cc.fascinated.bat.common.EmbedUtils; +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.Channel; +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 org.springframework.stereotype.Component; + +/** + * @author Nick (okNick) + */ +@Component +@CommandInfo(name = "viewtopic", description = "View the topic of a channel") +public class ViewTopicSubCommand extends BatSubCommand { + public ViewTopicSubCommand() { + super.addOption(OptionType.CHANNEL, "channel", "The channel to view the topic of", false); + } + + @Override + public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) { + Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel(); + if (!(target instanceof TextChannel textChannel)) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("<#%s> is not a text channel!".formatted(target.getId())) + .build()) + .queue(); + return; + } + + String topic = textChannel.getTopic(); + if (topic == null) { + interaction.replyEmbeds(EmbedUtils.errorEmbed() + .setDescription("<#%s> does not have a topic!".formatted(textChannel.getId())) + .build()) + .queue(); + return; + } + + interaction.replyEmbeds(EmbedUtils.genericEmbed() + .setDescription("The topic of <#%s> is: \"%s\"".formatted(textChannel.getId(), topic)) + .build() + ).queue(); + } +} \ No newline at end of file diff --git a/src/main/java/cc/fascinated/bat/service/CommandService.java b/src/main/java/cc/fascinated/bat/service/CommandService.java index 6894ab1..9ad85fe 100644 --- a/src/main/java/cc/fascinated/bat/service/CommandService.java +++ b/src/main/java/cc/fascinated/bat/service/CommandService.java @@ -1,7 +1,10 @@ package cc.fascinated.bat.service; import cc.fascinated.bat.Consts; -import cc.fascinated.bat.command.*; +import cc.fascinated.bat.command.BatCommand; +import cc.fascinated.bat.command.BatCommandExecutor; +import cc.fascinated.bat.command.BatSubCommand; +import cc.fascinated.bat.command.Category; import cc.fascinated.bat.common.EmbedUtils; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.model.BatUser; @@ -75,10 +78,10 @@ public class CommandService extends ListenerAdapter { // Unregister all commands that Discord has but we don't jda.retrieveCommands().complete().forEach(command -> { - CommandInfo commandInfo = commands.get(command.getName()).getCommandInfo(); - if (commands.containsKey(command.getName()) && (commandInfo.category().isHidden() || commandInfo.botOwnerOnly())) { + BatCommand batCommand = commands.get(command.getName()); + if (batCommand == null) { jda.deleteCommandById(command.getId()).complete(); // Unregister the command on Discord - log.info("Unregistered hidden command \"{}\" from Discord", command.getName()); + log.info("Unregistered unknown command \"{}\" from Discord", command.getName()); return; } if (commands.containsKey(command.getName())) {