add minecraft server and player lookups
All checks were successful
Deploy to Dokku / docker (ubuntu-latest) (push) Successful in 1m28s

This commit is contained in:
Lee 2024-07-06 05:34:50 +01:00
parent 6de1e8b2b1
commit ee7e8b64c5
7 changed files with 231 additions and 0 deletions

10
pom.xml
View File

@ -75,6 +75,11 @@
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>fascinated-repo-public</id>
<name>Fascinated's Repository</name>
<url>https://repo.fascinated.cc/public</url>
</repository>
</repositories>
<dependencies>
@ -181,5 +186,10 @@
<artifactId>commons-text</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>xyz.mcutils</groupId>
<artifactId>mcutils-java-library</artifactId>
<version>1.2.4</version>
</dependency>
</dependencies>
</project>

View File

@ -7,6 +7,8 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.lang.reflect.Member;
/**
* @author Fascinated (fascinated7)
*/

View File

@ -0,0 +1,23 @@
package cc.fascinated.bat.features.minecraft;
import cc.fascinated.bat.features.Feature;
import cc.fascinated.bat.features.FeatureProfile;
import cc.fascinated.bat.features.minecraft.command.MinecraftCommand;
import cc.fascinated.bat.service.CommandService;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
/**
* @author Fascinated (fascinated7)
*/
@Component
public class MinecraftFeature extends Feature {
@Autowired
public MinecraftFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
super("Minecraft", FeatureProfile.FeatureState.DISABLED, true);
super.registerCommand(commandService, context.getBean(MinecraftCommand.class));
}
}

View File

@ -0,0 +1,65 @@
package cc.fascinated.bat.features.minecraft.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
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.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.CachedPlayer;
import xyz.mcutils.models.player.Skin;
/**
* @author Fascinated (fascinated7)
*/
@Component
@CommandInfo(
name = "lookup-player",
description = "Lookup a Minecraft player"
)
public class LookupPlayerCommand extends BatCommand {
public LookupPlayerCommand() {
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, @NonNull SlashCommandInteraction event) {
OptionMapping playerOption = event.getOption("player");
if (playerOption == null) {
return;
}
String player = playerOption.getAsString();
CachedPlayer cachedPlayer = McUtilsAPI.getPlayer(player);
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;
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("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();
}
}

View File

@ -0,0 +1,104 @@
package cc.fascinated.bat.features.minecraft.command;
import cc.fascinated.bat.command.BatCommand;
import cc.fascinated.bat.command.CommandInfo;
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
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.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 LookupServerCommand extends BatCommand {
public LookupServerCommand() {
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, @NonNull SlashCommandInteraction event) {
OptionMapping platformOption = event.getOption("platform");
OptionMapping hostOption = event.getOption("host");
if (platformOption == null || hostOption == null) {
return;
}
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() : "");
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("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();
}
}

View File

@ -0,0 +1,26 @@
package cc.fascinated.bat.features.minecraft.command;
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 Fascinated (fascinated7)
*/
@Component
@CommandInfo(
name = "minecraft",
description = "Minecraft related commands"
)
public class MinecraftCommand extends BatCommand {
@Autowired
public MinecraftCommand(@NonNull ApplicationContext context) {
super.addSubCommands(
context.getBean(LookupPlayerCommand.class),
context.getBean(LookupServerCommand.class)
);
}
}

View File

@ -18,6 +18,7 @@ import net.dv8tion.jda.api.events.emoji.EmojiRemovedEvent;
import net.dv8tion.jda.api.events.emoji.update.EmojiUpdateNameEvent;
import net.dv8tion.jda.api.events.guild.GuildBanEvent;
import net.dv8tion.jda.api.events.guild.GuildUnbanEvent;
import net.dv8tion.jda.api.events.guild.invite.GenericGuildInviteEvent;
import net.dv8tion.jda.api.events.guild.invite.GuildInviteCreateEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;