diff --git a/src/main/java/cc/fascinated/bat/common/EmbedUtils.java b/src/main/java/cc/fascinated/bat/common/EmbedUtils.java index 536483d..ac164eb 100644 --- a/src/main/java/cc/fascinated/bat/common/EmbedUtils.java +++ b/src/main/java/cc/fascinated/bat/common/EmbedUtils.java @@ -1,5 +1,6 @@ package cc.fascinated.bat.common; +import lombok.experimental.UtilityClass; import net.dv8tion.jda.api.EmbedBuilder; import java.time.LocalDateTime; @@ -7,6 +8,7 @@ import java.time.LocalDateTime; /** * @author Fascinated (fascinated7) */ +@UtilityClass public class EmbedUtils { /** diff --git a/src/main/java/cc/fascinated/bat/common/NumberUtils.java b/src/main/java/cc/fascinated/bat/common/NumberUtils.java index a23b691..5784e62 100644 --- a/src/main/java/cc/fascinated/bat/common/NumberUtils.java +++ b/src/main/java/cc/fascinated/bat/common/NumberUtils.java @@ -1,10 +1,13 @@ package cc.fascinated.bat.common; +import lombok.experimental.UtilityClass; + import java.text.NumberFormat; /** * @author Fascinated (fascinated7) */ +@UtilityClass public class NumberUtils { /** * Formats a number with commas. diff --git a/src/main/java/cc/fascinated/bat/common/ScoreSaberUtils.java b/src/main/java/cc/fascinated/bat/common/ScoreSaberUtils.java index ba41d74..0145133 100644 --- a/src/main/java/cc/fascinated/bat/common/ScoreSaberUtils.java +++ b/src/main/java/cc/fascinated/bat/common/ScoreSaberUtils.java @@ -1,8 +1,11 @@ package cc.fascinated.bat.common; +import lombok.experimental.UtilityClass; + /** * @author Fascinated (fascinated7) */ +@UtilityClass public class ScoreSaberUtils { /** * Gets the formatted difficulty of a song. diff --git a/src/main/java/cc/fascinated/bat/common/TextChannelUtils.java b/src/main/java/cc/fascinated/bat/common/TextChannelUtils.java index 073e7f3..1efcd82 100644 --- a/src/main/java/cc/fascinated/bat/common/TextChannelUtils.java +++ b/src/main/java/cc/fascinated/bat/common/TextChannelUtils.java @@ -1,10 +1,12 @@ package cc.fascinated.bat.common; import cc.fascinated.bat.service.DiscordService; +import lombok.experimental.UtilityClass; /** * @author Fascinated (fascinated7) */ +@UtilityClass public class TextChannelUtils { /** * Checks if a channel is valid diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/ScoreSaberScoreFeedListener.java b/src/main/java/cc/fascinated/bat/features/scoresaber/UserScoreFeedListener.java similarity index 82% rename from src/main/java/cc/fascinated/bat/features/scoresaber/ScoreSaberScoreFeedListener.java rename to src/main/java/cc/fascinated/bat/features/scoresaber/UserScoreFeedListener.java index 888982e..e659f83 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/ScoreSaberScoreFeedListener.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/UserScoreFeedListener.java @@ -12,21 +12,23 @@ import cc.fascinated.bat.model.guild.BatGuild; import cc.fascinated.bat.model.guild.profiles.ScoreSaberUserScoreFeedProfile; import cc.fascinated.bat.service.DiscordService; import cc.fascinated.bat.service.GuildService; +import lombok.extern.log4j.Log4j2; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component -public class ScoreSaberScoreFeedListener implements EventListener { +@Component @Log4j2 +public class UserScoreFeedListener implements EventListener { private final GuildService guildService; @Autowired - public ScoreSaberScoreFeedListener(GuildService guildService) { + public UserScoreFeedListener(GuildService guildService) { this.guildService = guildService; } @@ -38,19 +40,19 @@ public class ScoreSaberScoreFeedListener implements EventListener { if (batGuild == null) { continue; } - ScoreSaberUserScoreFeedProfile profile = batGuild.getProfile(ScoreSaberUserScoreFeedProfile.class); - if (profile == null) { - continue; - } - if (profile.getChannelId() == null) { - continue; - } - if (!profile.getTrackedUsers().contains(player.getId())) { + if (profile == null || profile.getChannelId() == null || !profile.getTrackedUsers().contains(player.getId())) { continue; } - profile.getAsTextChannel().sendMessageEmbeds(this.buildScoreEmbed(score)).queue(); + TextChannel channel = profile.getAsTextChannel(); + if (channel == null) { + log.error("Scoresaber user feed channel is null for guild {}, removing the stored channel.", guild.getId()); + profile.setChannelId(null); + guildService.saveGuild(batGuild); + continue; + } + channel.sendMessageEmbeds(this.buildScoreEmbed(score)).queue(); } } @@ -78,7 +80,7 @@ public class ScoreSaberScoreFeedListener implements EventListener { leaderboardToken.getMaxScore() == 0 ? "N/A" : NumberUtils.formatNumberCommas(((double) scoreToken.getBaseScore() / leaderboardToken.getMaxScore()) * 100) ), true) .addField("Raw PP", scoreToken.getPp() == 0 ? "Unranked" : NumberUtils.formatNumberCommas(scoreToken.getPp()), true) - .addField("Global Rank", "#%s".formatted(NumberUtils.formatNumberCommas(scoreToken.getRank())), true) + .addField("Rank", "#%s".formatted(NumberUtils.formatNumberCommas(scoreToken.getRank())), true) .addField("Misses", "%s".formatted(scoreToken.getMissedNotes()), true) .addField("Bad Cuts", "%s".formatted(scoreToken.getBadCuts()), true) .addField("Max Combo", "%s %s".formatted( diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/LinkSubCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/LinkSubCommand.java index 2c46f70..37d191f 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/LinkSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/LinkSubCommand.java @@ -19,7 +19,7 @@ import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component +@Component("scoresaber:link.sub") public class LinkSubCommand extends BatSubCommand { private final ScoreSaberService scoreSaberService; private final UserService userService; diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/MeSubCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/MeSubCommand.java new file mode 100644 index 0000000..4536b86 --- /dev/null +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/MeSubCommand.java @@ -0,0 +1,30 @@ +package cc.fascinated.bat.features.scoresaber.command.scoresaber; + +import cc.fascinated.bat.command.BatSubCommand; +import cc.fascinated.bat.model.guild.BatGuild; +import cc.fascinated.bat.model.user.BatUser; +import cc.fascinated.bat.service.ScoreSaberService; +import lombok.NonNull; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author Fascinated (fascinated7) + */ +@Component("scoresaber:me.sub") +public class MeSubCommand extends BatSubCommand { + private final ScoreSaberService scoreSaberService; + + @Autowired + public MeSubCommand(@NonNull ScoreSaberService scoreSaberService) { + this.scoreSaberService = scoreSaberService; + } + + @Override + public void execute(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull TextChannel channel, @NonNull Member member, @NonNull SlashCommandInteraction interaction) { + ScoreSaberCommand.sendProfileEmbed(true, user, scoreSaberService, interaction); + } +} diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/ScoreSaberCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/ScoreSaberCommand.java index ca0b397..46fa476 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/ScoreSaberCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/ScoreSaberCommand.java @@ -45,6 +45,7 @@ public class ScoreSaberCommand extends BatCommand { .addSubcommands(new SubcommandData("user", "View a user's ScoreSaber profile") .addOptions(new OptionData(OptionType.USER, "user", "The user to view the ScoreSaber profile of", true)) ) + .addSubcommands(new SubcommandData("me", "View your ScoreSaber profile")) ); } diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/UserSubCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/UserSubCommand.java index 9bf1b45..2ed99af 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/UserSubCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/scoresaber/UserSubCommand.java @@ -17,7 +17,7 @@ import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component +@Component("scoresaber:user.sub") public class UserSubCommand extends BatSubCommand { private final ScoreSaberService scoreSaberService; private final UserService userService; diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedChannelCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ChannelSubCommand.java similarity index 94% rename from src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedChannelCommand.java rename to src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ChannelSubCommand.java index ffde758..a9db633 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedChannelCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ChannelSubCommand.java @@ -20,12 +20,12 @@ import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component -public class ScoreFeedChannelCommand extends BatSubCommand { +@Component("scoresaber-userfeed:channel.sub") +public class ChannelSubCommand extends BatSubCommand { private final GuildService guildService; @Autowired - public ScoreFeedChannelCommand(GuildService guildService) { + public ChannelSubCommand(GuildService guildService) { this.guildService = guildService; } diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedClearUsersCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ClearUsersSubCommand.java similarity index 88% rename from src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedClearUsersCommand.java rename to src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ClearUsersSubCommand.java index 73a82ab..e35a1cb 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedClearUsersCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ClearUsersSubCommand.java @@ -17,12 +17,12 @@ import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component -public class ScoreFeedClearUsersCommand extends BatSubCommand { +@Component("scoresaber-userfeed:clearusers.sub") +public class ClearUsersSubCommand extends BatSubCommand { private final GuildService guildService; @Autowired - public ScoreFeedClearUsersCommand(GuildService guildService, UserService userService) { + public ClearUsersSubCommand(GuildService guildService, UserService userService) { this.guildService = guildService; } diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreSaberUserFeedCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/UserFeedCommand.java similarity index 93% rename from src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreSaberUserFeedCommand.java rename to src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/UserFeedCommand.java index b41fb8c..85970d8 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreSaberUserFeedCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/UserFeedCommand.java @@ -12,9 +12,9 @@ import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component -public class ScoreSaberUserFeedCommand extends BatCommand { - public ScoreSaberUserFeedCommand() { +@Component("scoresaber-userfeed:feed.sub") +public class UserFeedCommand extends BatCommand { + public UserFeedCommand() { super("scoresaber-userfeed"); super.setCategory(Category.BEAT_SABER); diff --git a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedUserCommand.java b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/UserSubCommand.java similarity index 95% rename from src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedUserCommand.java rename to src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/UserSubCommand.java index f235c5e..16144ef 100644 --- a/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/ScoreFeedUserCommand.java +++ b/src/main/java/cc/fascinated/bat/features/scoresaber/command/userfeed/UserSubCommand.java @@ -20,13 +20,13 @@ import org.springframework.stereotype.Component; /** * @author Fascinated (fascinated7) */ -@Component -public class ScoreFeedUserCommand extends BatSubCommand { +@Component("scoresaber-userfeed:user.sub") +public class UserSubCommand extends BatSubCommand { private final GuildService guildService; private final UserService userService; @Autowired - public ScoreFeedUserCommand(GuildService guildService, UserService userService) { + public UserSubCommand(GuildService guildService, UserService userService) { this.guildService = guildService; this.userService = userService; } diff --git a/src/main/java/cc/fascinated/bat/service/CommandService.java b/src/main/java/cc/fascinated/bat/service/CommandService.java index 0750284..c11674d 100644 --- a/src/main/java/cc/fascinated/bat/service/CommandService.java +++ b/src/main/java/cc/fascinated/bat/service/CommandService.java @@ -4,12 +4,12 @@ import cc.fascinated.bat.command.BatCommand; import cc.fascinated.bat.command.BatSubCommand; import cc.fascinated.bat.common.EmbedUtils; import cc.fascinated.bat.features.scoresaber.command.scoresaber.LinkSubCommand; +import cc.fascinated.bat.features.scoresaber.command.scoresaber.MeSubCommand; import cc.fascinated.bat.features.scoresaber.command.scoresaber.ScoreSaberCommand; -import cc.fascinated.bat.features.scoresaber.command.scoresaber.UserSubCommand; -import cc.fascinated.bat.features.scoresaber.command.userfeed.ScoreFeedChannelCommand; -import cc.fascinated.bat.features.scoresaber.command.userfeed.ScoreFeedClearUsersCommand; -import cc.fascinated.bat.features.scoresaber.command.userfeed.ScoreFeedUserCommand; -import cc.fascinated.bat.features.scoresaber.command.userfeed.ScoreSaberUserFeedCommand; +import cc.fascinated.bat.features.scoresaber.command.userfeed.ChannelSubCommand; +import cc.fascinated.bat.features.scoresaber.command.userfeed.ClearUsersSubCommand; +import cc.fascinated.bat.features.scoresaber.command.userfeed.UserFeedCommand; +import cc.fascinated.bat.features.scoresaber.command.userfeed.UserSubCommand; import cc.fascinated.bat.model.guild.BatGuild; import cc.fascinated.bat.model.user.BatUser; import lombok.NonNull; @@ -60,12 +60,13 @@ public class CommandService extends ListenerAdapter { // Global commands registerCommand(context.getBean(ScoreSaberCommand.class) .addSubCommand("link", context.getBean(LinkSubCommand.class)) - .addSubCommand("user", context.getBean(UserSubCommand.class)) + .addSubCommand("user", context.getBean(cc.fascinated.bat.features.scoresaber.command.scoresaber.UserSubCommand.class)) + .addSubCommand("me", context.getBean(MeSubCommand.class)) ); - registerCommand(context.getBean(ScoreSaberUserFeedCommand.class) - .addSubCommand("user", context.getBean(ScoreFeedUserCommand.class)) - .addSubCommand("channel", context.getBean(ScoreFeedChannelCommand.class)) - .addSubCommand("clear-users", context.getBean(ScoreFeedClearUsersCommand.class)) + registerCommand(context.getBean(UserFeedCommand.class) + .addSubCommand("user", context.getBean(UserSubCommand.class)) + .addSubCommand("channel", context.getBean(ChannelSubCommand.class)) + .addSubCommand("clear-users", context.getBean(ClearUsersSubCommand.class)) ); registerSlashCommands(); // Register all slash commands @@ -106,13 +107,7 @@ public class CommandService extends ListenerAdapter { @Override public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { Guild discordGuild = event.getGuild(); - if (discordGuild == null) { - return; - } - if (event.getUser().isBot()) { - return; - } - if (event.getMember() == null) { + if (discordGuild == null || event.getUser().isBot() || event.getMember() == null) { return; } @@ -124,17 +119,18 @@ public class CommandService extends ListenerAdapter { BatGuild guild = guildService.getGuild(discordGuild.getId()); BatUser user = userService.getUser(event.getUser().getId()); - - // No args provided, use the main command executor try { + // No args provided, use the main command executor if (event.getInteraction().getSubcommandName() == null) { command.execute(guild, user, event.getChannel().asTextChannel(), event.getMember(), event.getInteraction()); - } else { - for (Map.Entry subCommand : command.getSubCommands().entrySet()) { - if (subCommand.getKey().equalsIgnoreCase(event.getInteraction().getSubcommandName())) { - subCommand.getValue().execute(guild, user, event.getChannel().asTextChannel(), event.getMember(), event.getInteraction()); - break; - } + return; + } + + // Subcommand provided, use the subcommand executor + for (Map.Entry subCommand : command.getSubCommands().entrySet()) { + if (subCommand.getKey().equalsIgnoreCase(event.getInteraction().getSubcommandName())) { + subCommand.getValue().execute(guild, user, event.getChannel().asTextChannel(), event.getMember(), event.getInteraction()); + break; } } } catch (Exception ex) { diff --git a/src/main/java/cc/fascinated/bat/service/EventService.java b/src/main/java/cc/fascinated/bat/service/EventService.java index 376fffa..2985fd7 100644 --- a/src/main/java/cc/fascinated/bat/service/EventService.java +++ b/src/main/java/cc/fascinated/bat/service/EventService.java @@ -1,7 +1,7 @@ package cc.fascinated.bat.service; import cc.fascinated.bat.event.EventListener; -import cc.fascinated.bat.features.scoresaber.ScoreSaberScoreFeedListener; +import cc.fascinated.bat.features.scoresaber.UserScoreFeedListener; import lombok.NonNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; @@ -24,7 +24,7 @@ public class EventService { @Autowired public EventService(@NonNull ApplicationContext context) { registerListeners( - context.getBean(ScoreSaberScoreFeedListener.class) + context.getBean(UserScoreFeedListener.class) ); log.info("Registered {} listeners.", LISTENERS.size()); }