- * true = online - * false = offline - *
- */ - private boolean lastState; - - /** - * Gets the channel - * - * @return - The channel - */ - public TextChannel getChannel() { - return ChannelUtils.getTextChannel(channelId); - } -} diff --git a/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/LookupPlayerSubCommand.java b/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/LookupPlayerSubCommand.java deleted file mode 100644 index 2673000..0000000 --- a/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/LookupPlayerSubCommand.java +++ /dev/null @@ -1,75 +0,0 @@ -package cc.fascinated.bat.features.minecraft.command.minecraft; - -import cc.fascinated.bat.command.BatCommand; -import cc.fascinated.bat.command.CommandInfo; -import cc.fascinated.bat.common.DescriptionBuilder; -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.Message; -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 xyz.mcutils.McUtilsAPI; -import xyz.mcutils.exception.ErrorResponse; -import xyz.mcutils.models.cache.CachedPlayer; -import xyz.mcutils.models.player.Skin; - -/** - * @author Fascinated (fascinated7) - */ -@Component -@CommandInfo( - name = "lookup-player", - description = "Lookup a Minecraft player" -) -public class LookupPlayerSubCommand extends BatCommand { - public LookupPlayerSubCommand() { - super.addOptions( - new OptionData(OptionType.STRING, "player", "The player to lookup", true) - ); - } - - @Override - public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) { - OptionMapping playerOption = event.getOption("player"); - assert playerOption != null; - String player = playerOption.getAsString(); - - // Check if the player id is valid - if (player.length() > 16 || player.contains(" ")) { - event.reply("The player id `%s` is invalid".formatted(player)).queue(); - return; - } - - // Fetch the player from the API - CachedPlayer cachedPlayer = null; - try { - cachedPlayer = McUtilsAPI.getPlayer(player); - } catch (ErrorResponse ignored) { } // The error response is handled below - if (cachedPlayer == null) { - event.reply("The player `%s` could not be found".formatted(player)).queue(); - return; - } - - String headUrl = cachedPlayer.getSkin() != null ? cachedPlayer.getSkin().getParts().get(Skin.SkinPart.HEAD.getName()) : null; - DescriptionBuilder description = new DescriptionBuilder("Player Lookup") - .appendLine("Username: `%s`".formatted(cachedPlayer.getUsername()), true) - .appendLine("UUID: `%s`".formatted(cachedPlayer.getUniqueId().toString()), true); - if (cachedPlayer.getSkin() != null) { - description.appendLine("Skin: [Click Here](%s)".formatted(headUrl), true); - } - if (cachedPlayer.getCape() != null) { - description.appendLine("Cape: [Click Here](%s)".formatted(cachedPlayer.getCape().getUrl()), true); - } - event.replyEmbeds(EmbedUtils.successEmbed() - .setDescription(description.build()) - .setThumbnail(headUrl) - .build()).queue(); - } -} diff --git a/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/LookupServerSubCommand.java b/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/LookupServerSubCommand.java deleted file mode 100644 index eb7c8be..0000000 --- a/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/LookupServerSubCommand.java +++ /dev/null @@ -1,104 +0,0 @@ -package cc.fascinated.bat.features.minecraft.command.minecraft; - -import cc.fascinated.bat.command.BatCommand; -import cc.fascinated.bat.command.CommandInfo; -import cc.fascinated.bat.common.DescriptionBuilder; -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.Message; -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 xyz.mcutils.McUtilsAPI; -import xyz.mcutils.models.cache.CachedBedrockMinecraftServer; -import xyz.mcutils.models.cache.CachedJavaMinecraftServer; -import xyz.mcutils.models.server.MinecraftServer; - -/** - * @author Fascinated (fascinated7) - */ -@Component -@CommandInfo( - name = "lookup-server", - description = "Lookup a Minecraft server" -) -public class LookupServerSubCommand extends BatCommand { - public LookupServerSubCommand() { - super.addOptions( - new OptionData(OptionType.STRING, "platform", "The platform of the server to lookup", true) - .addChoice("Java", "java") - .addChoice("Bedrock", "bedrock"), - new OptionData(OptionType.STRING, "host", "The host/ip of the server to lookup", true) - ); - } - - @Override - public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) { - OptionMapping platformOption = event.getOption("platform"); - assert platformOption != null; - OptionMapping hostOption = event.getOption("host"); - assert hostOption != null; - - String platform = platformOption.getAsString(); - String host = hostOption.getAsString(); - MinecraftServer server; - try { - if (platform.equalsIgnoreCase("java")) { - server = McUtilsAPI.getJavaServer(host); - } else { - server = McUtilsAPI.getBedrockServer(host); - } - } catch (Exception ex) { - event.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("The server `%s` is invalid or offline".formatted(host)) - .build()).queue(); - return; - } - - int platformDefaultPort = platform.equalsIgnoreCase("java") ? 25565 : 19132; - String hostname = server.getHostname() + (server.getPort() != platformDefaultPort ? ":" + server.getPort() : ""); - DescriptionBuilder description = new DescriptionBuilder("Server Lookup [(Raw Data)](%s)".formatted( - "https://api.mcutils.xyz/server/%s/%s".formatted(platform, hostname) - )); - description.appendLine("Host: `%s`".formatted(hostname), true); - - MinecraftServer.GeoLocation location = server.getLocation(); - if (server instanceof CachedJavaMinecraftServer javaServer) { - description.appendLine("Version: `%s`".formatted(javaServer.getVersion().getName()), true); - if (javaServer.getForgeData() != null) { - description.appendLine("Forge Mods: `%s`".formatted(javaServer.getForgeData().getMods().length), true); - } - if (javaServer.isMojangBlocked()) { - description.appendLine("Mojang Blocked: `Yes`", true); - } - if (javaServer.isEnforcesSecureChat()) { - description.appendLine("Enforces Secure Chat: `Yes`", true); - } - if (javaServer.isPreventsChatReports()) { - description.appendLine("Prevents Chat Reports: `Yes`", true); - } - } - if (server instanceof CachedBedrockMinecraftServer bedrockServer) { - description.appendLine("Version: `%s`".formatted(bedrockServer.getVersion().getName()), true); - } - if (location != null) { - description.appendLine("Location: [%s](%s)".formatted( - (location.getCity() == null ? "" : location.getCity() + ", ") + location.getCountry(), - "https://www.google.com/maps/search/?api=1&query=%s,%s".formatted(location.getLatitude(), location.getLongitude()) - ), true); - } - - event.replyEmbeds(EmbedUtils.successEmbed() - .setDescription(description.build()) - .setThumbnail("https://api.mcutils.xyz/server/icon/%s".formatted(hostname)) - .setImage(server.getMotd().getPreview()) - .setFooter("Powered by mcutils.xyz") - .build()).queue(); - } -} diff --git a/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/MinecraftCommand.java b/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/MinecraftCommand.java deleted file mode 100644 index ddc49b2..0000000 --- a/src/main/java/cc/fascinated/bat/features/minecraft/command/minecraft/MinecraftCommand.java +++ /dev/null @@ -1,29 +0,0 @@ -package cc.fascinated.bat.features.minecraft.command.minecraft; - -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; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; - -/** - * @author Fascinated (fascinated7) - */ -@Component -@CommandInfo( - name = "minecraft", - description = "Minecraft related commands", - userInstall = true, - category = Category.UTILITY -) -public class MinecraftCommand extends BatCommand { - @Autowired - public MinecraftCommand(@NonNull ApplicationContext context) { - super.addSubCommands( - context.getBean(LookupPlayerSubCommand.class), - context.getBean(LookupServerSubCommand.class) - ); - } -} diff --git a/src/main/java/cc/fascinated/bat/features/minecraft/command/serverwatcher/AddSubCommand.java b/src/main/java/cc/fascinated/bat/features/minecraft/command/serverwatcher/AddSubCommand.java deleted file mode 100644 index 7f952c1..0000000 --- a/src/main/java/cc/fascinated/bat/features/minecraft/command/serverwatcher/AddSubCommand.java +++ /dev/null @@ -1,101 +0,0 @@ -package cc.fascinated.bat.features.minecraft.command.serverwatcher; - -import cc.fascinated.bat.command.BatCommand; -import cc.fascinated.bat.command.CommandInfo; -import cc.fascinated.bat.common.EmbedUtils; -import cc.fascinated.bat.features.minecraft.MinecraftProfile; -import cc.fascinated.bat.features.minecraft.ServerWatcher; -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.Message; -import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; -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.stereotype.Component; -import xyz.mcutils.McUtilsAPI; -import xyz.mcutils.models.server.MinecraftServer; -import xyz.mcutils.models.server.ServerPlatform; - -/** - * @author Fascinated (fascinated7) - */ -@Component("minecraft-server-watcher.add:sub") -@CommandInfo( - name = "add", - description = "Add a server to the server watcher" -) -public class AddSubCommand extends BatCommand { - public AddSubCommand() { - super.addOptions( - new OptionData(OptionType.CHANNEL, "channel", "The channel to send the server watcher notifications", true), - new OptionData(OptionType.STRING, "platform", "The platform of the server to lookup", true) - .addChoice("Java", "java") - .addChoice("Bedrock", "bedrock"), - new OptionData(OptionType.STRING, "host", "The host/ip of the server to add", true) - ); - } - - @Override - public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) { - OptionMapping platformOption = event.getOption("platform"); - assert platformOption != null; - OptionMapping hostOption = event.getOption("host"); - assert hostOption != null; - OptionMapping channelOption = event.getOption("channel"); - assert channelOption != null; - - String platform = platformOption.getAsString(); - String host = hostOption.getAsString(); - GuildChannelUnion channelUnion = channelOption.getAsChannel(); - TextChannel textChannel = channelUnion.asTextChannel(); - MinecraftServer server; - try { - if (platform.equalsIgnoreCase("java")) { - server = McUtilsAPI.getJavaServer(host); - } else { - server = McUtilsAPI.getBedrockServer(host); - } - } catch (Exception ex) { - event.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("The server `%s` is invalid or offline".formatted(host)) - .build()).queue(); - return; - } - - MinecraftProfile profile = guild.getMinecraftProfile(); - if (profile.getServerWatchers().size() >= 10) { - event.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("You can only have a maximum of `10` server watchers") - .build()).queue(); - return; - } - - if (profile.getServerWatcher(host, ServerPlatform.valueOf(platform.toUpperCase())) != null) { - event.replyEmbeds(EmbedUtils.errorEmbed() - .setDescription("The server `%s` is already being watched".formatted(host)) - .build()).queue(); - return; - } - - profile.addServerWatcher(new ServerWatcher( - server.getHostname(), - server.getPort(), - ServerPlatform.valueOf(platform.toUpperCase()), - textChannel.getId(), - false - )); - profile.checkServers(); // Force check the servers - - event.replyEmbeds(EmbedUtils.successEmbed() - .setDescription("Setup the server watcher for `%s` in %s".formatted( - server.getHostname(), - textChannel.getAsMention() - )).build()).queue(); - } -} diff --git a/src/main/java/cc/fascinated/bat/features/minecraft/command/serverwatcher/ListSubCommand.java b/src/main/java/cc/fascinated/bat/features/minecraft/command/serverwatcher/ListSubCommand.java deleted file mode 100644 index 60dd541..0000000 --- a/src/main/java/cc/fascinated/bat/features/minecraft/command/serverwatcher/ListSubCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -package cc.fascinated.bat.features.minecraft.command.serverwatcher; - -import cc.fascinated.bat.command.BatCommand; -import cc.fascinated.bat.command.CommandInfo; -import cc.fascinated.bat.common.DescriptionBuilder; -import cc.fascinated.bat.common.EmbedUtils; -import cc.fascinated.bat.common.EnumUtils; -import cc.fascinated.bat.features.minecraft.MinecraftProfile; -import cc.fascinated.bat.features.minecraft.ServerWatcher; -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.Message; -import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; -import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction; -import org.springframework.stereotype.Component; -import xyz.mcutils.models.server.ServerPlatform; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Fascinated (fascinated7) - */ -@Component("minecraft-server-watcher.list:sub") -@CommandInfo( - name = "list", - description = "Shows a list of all the servers being watched" -) -public class ListSubCommand extends BatCommand { - @Override - public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) { - MinecraftProfile profile = guild.getMinecraftProfile(); - - MapSuccessfully authorized your Spotify account!
-Your key is: %s
- """.formatted(key); - } - - /** - * Gets a new Spotify API instance. - * - * @return the Spotify API - */ - @SneakyThrows - public SpotifyApi getSpotifyApi(BatUser user) { - SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - ensureValidToken(profile, user); - return new SpotifyApi.Builder().setAccessToken(profile.getAccessToken()).build(); - } - - /** - * Ensures the user has a valid Spotify access token. - *- * If the token is expired, it will be refreshed. - *
- * - * @param user the user to get the token for - */ - @SneakyThrows - public void ensureValidToken(SpotifyProfile profile, BatUser user) { - // If the token is still valid, return - if (profile.getExpiresAt() > System.currentTimeMillis()) { - return; - } - SpotifyApi api = new SpotifyApi.Builder() - .setClientId(clientId) - .setClientSecret(clientSecret) - .setAccessToken(profile.getAccessToken()) - .setRefreshToken(profile.getRefreshToken()) - .build(); - try { - AuthorizationCodeCredentials credentials = api.authorizationCodeRefresh().build().execute(); - profile.setAccessToken(credentials.getAccessToken()); - profile.setExpiresAt(System.currentTimeMillis() + (credentials.getExpiresIn() * 1000)); - log.info("Refreshed Spotify token for user \"{}\"", user.getName()); - } catch (SpotifyWebApiException ex) { - log.error("Failed to refresh Spotify token", ex); - } - } - - /** - * Links the user's Spotify account with their Discord account. - * - * @param user the user to link the account with - * @param key the key to link the account with - */ - public void linkAccount(BatUser user, String key) { - AuthorizationCodeCredentials credentials = accessToken.get(key); - if (credentials == null) { - return; - } - // Link the user's Spotify account - SpotifyProfile profile = user.getProfile(SpotifyProfile.class); - profile.setAccessToken(credentials.getAccessToken()); - profile.setRefreshToken(credentials.getRefreshToken()); - profile.setExpiresAt(System.currentTimeMillis() + (credentials.getExpiresIn() * 1000)); - log.info("Linked Spotify account for user {}", user.getName()); - } - - /** - * Checks if the link code is valid. - * - * @param code the code to check - * @return if the code is valid - */ - public boolean isValidLinkCode(String code) { - return accessToken.containsKey(code); - } -}