Identify server software if querying is enabled

This commit is contained in:
Braydon 2024-04-22 20:57:33 -04:00
parent c689434ec4
commit 1a4929d8b5
5 changed files with 73 additions and 8 deletions

@ -56,6 +56,11 @@ public final class JavaMinecraftServer extends MinecraftServer {
*/ */
private final Favicon favicon; private final Favicon favicon;
/**
* The software of this server, present if query is on.
*/
private final String software;
/** /**
* The plugins on this server, present if * The plugins on this server, present if
* query is on and plugins are present. * query is on and plugins are present.
@ -119,11 +124,13 @@ public final class JavaMinecraftServer extends MinecraftServer {
private boolean mojangBanned; private boolean mojangBanned;
private JavaMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records, @NonNull Version version, private JavaMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records, @NonNull Version version,
@NonNull Players players, @NonNull MOTD motd, Favicon favicon, Plugin[] plugins, ModInfo modInfo, ForgeData forgeData, @NonNull Players players, @NonNull MOTD motd, Favicon favicon, String software, Plugin[] plugins,
String world, boolean queryEnabled, boolean previewsChat, boolean enforcesSecureChat, boolean preventsChatReports, boolean mojangBanned) { ModInfo modInfo, ForgeData forgeData, String world, boolean queryEnabled, boolean previewsChat,
boolean enforcesSecureChat, boolean preventsChatReports, boolean mojangBanned) {
super(hostname, ip, port, records, players, motd); super(hostname, ip, port, records, players, motd);
this.version = version; this.version = version;
this.favicon = favicon; this.favicon = favicon;
this.software = software;
this.plugins = plugins; this.plugins = plugins;
this.modInfo = modInfo; this.modInfo = modInfo;
this.forgeData = forgeData; this.forgeData = forgeData;
@ -153,6 +160,7 @@ public final class JavaMinecraftServer extends MinecraftServer {
if (motdString == null) { // Not a string motd, convert from Json if (motdString == null) { // Not a string motd, convert from Json
motdString = new TextComponent(ComponentSerializer.parse(AppConfig.GSON.toJson(statusToken.getDescription()))).toLegacyText(); motdString = new TextComponent(ComponentSerializer.parse(AppConfig.GSON.toJson(statusToken.getDescription()))).toLegacyText();
} }
String software = challengeStatusToken == null ? null : challengeStatusToken.getSoftware(); // The server software
// Get the plugins from the challenge token // Get the plugins from the challenge token
Plugin[] plugins = null; Plugin[] plugins = null;
@ -163,12 +171,12 @@ public final class JavaMinecraftServer extends MinecraftServer {
} }
plugins = list.toArray(new Plugin[0]); plugins = list.toArray(new Plugin[0]);
} }
String world = challengeStatusToken == null ? null : challengeStatusToken.getMap(); String world = challengeStatusToken == null ? null : challengeStatusToken.getMap(); // The main server world
return new JavaMinecraftServer(hostname, ip, port, records, statusToken.getVersion().detailedCopy(), Players.create(statusToken.getPlayers()), return new JavaMinecraftServer(hostname, ip, port, records, statusToken.getVersion().detailedCopy(), Players.create(statusToken.getPlayers()),
MOTD.create(motdString), Favicon.create(statusToken.getFavicon(), hostname), plugins, statusToken.getModInfo(), statusToken.getForgeData(), MOTD.create(motdString), Favicon.create(statusToken.getFavicon(), hostname), software, plugins, statusToken.getModInfo(),
world, challengeStatusToken != null, statusToken.isPreviewsChat(), statusToken.isEnforcesSecureChat(), statusToken.getForgeData(), world, challengeStatusToken != null, statusToken.isPreviewsChat(),
statusToken.isPreventsChatReports(), false statusToken.isEnforcesSecureChat(), statusToken.isPreventsChatReports(), false
); );
} }

@ -44,6 +44,11 @@ public final class JavaServerChallengeStatusToken {
*/ */
@NonNull private final String map; @NonNull private final String map;
/**
* The software of this server.
*/
@NonNull private final String software;
/** /**
* The plugins of this server. * The plugins of this server.
*/ */
@ -58,11 +63,14 @@ public final class JavaServerChallengeStatusToken {
*/ */
@NonNull @NonNull
public static JavaServerChallengeStatusToken create(@NonNull Map<String, String> rawData) { public static JavaServerChallengeStatusToken create(@NonNull Map<String, String> rawData) {
String[] splitPlugins = rawData.get("plugins").split(": ");
String software = splitPlugins[0]; // The server software
Map<String, String> plugins = new HashMap<>(); Map<String, String> plugins = new HashMap<>();
for (String plugin : rawData.get("plugins").split(": ")[1].split("; ")) { for (String plugin : splitPlugins[1].split("; ")) {
String[] split = plugin.split(" "); String[] split = plugin.split(" ");
plugins.put(split[0], split[1]); plugins.put(split[0], split[1]);
} }
return new JavaServerChallengeStatusToken(rawData.get("map"), plugins); return new JavaServerChallengeStatusToken(rawData.get("map"), software, plugins);
} }
} }

@ -0,0 +1,36 @@
/*
* MIT License
*
* Copyright (c) 2024 Braydon (Rainnny).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.braydon.mc.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @author Braydon
*/
@Service
public final class MaxMindService {
@Value("${maxmind.license}")
private String license;
}

@ -139,6 +139,14 @@ public final class JavaMinecraftServerPinger implements MinecraftServerPinger<Ja
} }
} }
/**
* Ping a server and retrieve its challenge status token.
*
* @param hostname the hostname to ping
* @param port the port to ping
* @return the challenge token
* @throws IOException if an I/O error occurs
*/
@NonNull @NonNull
private JavaServerChallengeStatusToken retrieveChallengeStatusToken(@NonNull String hostname, int port) throws IOException { private JavaServerChallengeStatusToken retrieveChallengeStatusToken(@NonNull String hostname, int port) throws IOException {
log.info("Opening UDP connection to {}:{}...", hostname, port); log.info("Opening UDP connection to {}:{}...", hostname, port);

@ -11,6 +11,11 @@ logging:
file: file:
path: "./logs" path: "./logs"
# MaxMind Configuration
# Used for IP Geo location
maxmind:
license: "CHANGE_ME"
# Spring Configuration # Spring Configuration
spring: spring:
data: data: