From d9a672f6244bc86e3389a9968fa8aa962ab874ae Mon Sep 17 00:00:00 2001 From: Mark Vainomaa Date: Sun, 17 Mar 2019 21:46:56 +0200 Subject: [PATCH] Fire event on GS4 query diff --git a/src/main/java/net/minecraft/server/RemoteConnectionThread.java b/src/main/java/net/minecraft/server/RemoteConnectionThread.java index 66bfbcf02..d821ef9a7 100644 --- a/src/main/java/net/minecraft/server/RemoteConnectionThread.java +++ b/src/main/java/net/minecraft/server/RemoteConnectionThread.java @@ -15,7 +15,7 @@ public abstract class RemoteConnectionThread implements Runnable { private static final Logger LOGGER = LogManager.getLogger(); private static final AtomicInteger i = new AtomicInteger(0); protected boolean a; - protected final IMinecraftServer b; + protected final IMinecraftServer b; protected IMinecraftServer getServer() { return this.b; } // Paper - OBFHELPER protected final String c; protected Thread d; protected final int e = 5; @@ -94,6 +94,7 @@ public abstract class RemoteConnectionThread implements Runnable { this.b.g(s); } + protected int getPlayerCount() { return this.d(); } // Paper - OBFHELPER protected int d() { return this.b.getPlayerCount(); } diff --git a/src/main/java/net/minecraft/server/RemoteStatusListener.java b/src/main/java/net/minecraft/server/RemoteStatusListener.java index 16bb89af0..1b084f211 100644 --- a/src/main/java/net/minecraft/server/RemoteStatusListener.java +++ b/src/main/java/net/minecraft/server/RemoteStatusListener.java @@ -21,19 +21,19 @@ public class RemoteStatusListener extends RemoteConnectionThread { private long h; private final int i; - private final int j; - private final int k; - private final String l; - private final String m; + private final int j; private int getServerPort() { return this.j; } // Paper - OBFHELPER + private final int k; private int getMaxPlayers() { return this.k; } // Paper - OBFHELPER + private final String l; private String getMotd() { return this.l; } // Paper - OBFHELPER + private final String m; private String getWorldName() { return this.m; } // Paper - OBFHELPER private DatagramSocket n; private final byte[] o = new byte[1460]; private DatagramPacket p; private final Map q; - private String r; + private String r; private String getServerHost() { return this.r; } // Paper - OBFHELPER private String s; private final Map t; private final long u; - private final RemoteStatusReply v; + private final RemoteStatusReply v; private RemoteStatusReply getCachedFullResponse() { return this.v; } // Paper - OBFHELPER private long w; public RemoteStatusListener(IMinecraftServer iminecraftserver) { @@ -91,6 +91,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { remotestatusreply.a((int) 0); remotestatusreply.a(this.a(datagrampacket.getSocketAddress())); + /* Paper start - GS4 Query event remotestatusreply.a(this.l); remotestatusreply.a("SMP"); remotestatusreply.a(this.m); @@ -98,6 +99,31 @@ public class RemoteStatusListener extends RemoteConnectionThread { remotestatusreply.a(Integer.toString(this.k)); remotestatusreply.a((short) this.j); remotestatusreply.a(this.r); + */ + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType = + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.BASIC; + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder() + .motd(this.getMotd()) + .map(this.getWorldName()) + .currentPlayers(this.getPlayerCount()) + .maxPlayers(this.getMaxPlayers()) + .port(this.getServerPort()) + .hostname(this.getServerHost()) + .gameVersion(this.getServer().getVersion()) + .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion()) + .build(); + com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent = + new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, datagrampacket.getAddress(), queryResponse); + queryEvent.callEvent(); + queryResponse = queryEvent.getResponse(); + remotestatusreply.writeString(queryResponse.getMotd()); + remotestatusreply.writeString("SMP"); + remotestatusreply.writeString(queryResponse.getMap()); + remotestatusreply.writeString(Integer.toString(queryResponse.getCurrentPlayers())); + remotestatusreply.writeString(Integer.toString(queryResponse.getMaxPlayers())); + remotestatusreply.writeShort((short) queryResponse.getPort()); + remotestatusreply.writeString(queryResponse.getHostname()); + // Paper end this.a(remotestatusreply.a(), datagrampacket); this.a("Status [" + socketaddress + "]"); } @@ -134,6 +160,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { this.v.a("splitnum"); this.v.a((int) 128); this.v.a((int) 0); + /* Paper start - GS4 Query event this.v.a("hostname"); this.v.a(this.l); this.v.a("gametype"); @@ -169,6 +196,79 @@ public class RemoteStatusListener extends RemoteConnectionThread { } this.v.a((int) 0); + */ + // Pack plugins + java.util.List plugins = java.util.Collections.emptyList(); + org.bukkit.plugin.Plugin[] bukkitPlugins; + if(((DedicatedServer) this.getServer()).server.getQueryPlugins() && (bukkitPlugins = org.bukkit.Bukkit.getPluginManager().getPlugins()).length > 0) { + plugins = java.util.stream.Stream.of(bukkitPlugins) + .map(plugin -> com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation.of(plugin.getName(), plugin.getDescription().getVersion())) + .collect(java.util.stream.Collectors.toList()); + } + + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse queryResponse = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.builder() + .motd(this.getMotd()) + .map(this.getWorldName()) + .currentPlayers(this.getPlayerCount()) + .maxPlayers(this.getMaxPlayers()) + .port(this.getServerPort()) + .hostname(this.getServerHost()) + .plugins(plugins) + .players(this.getServer().getPlayers()) + .gameVersion(this.getServer().getVersion()) + .serverVersion(org.bukkit.Bukkit.getServer().getName() + " on " + org.bukkit.Bukkit.getServer().getBukkitVersion()) + .build(); + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType = + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.FULL; + com.destroystokyo.paper.event.server.GS4QueryEvent queryEvent = + new com.destroystokyo.paper.event.server.GS4QueryEvent(queryType, datagrampacket.getAddress(), queryResponse); + queryEvent.callEvent(); + queryResponse = queryEvent.getResponse(); + this.getCachedFullResponse().writeString("hostname"); + this.getCachedFullResponse().writeString(queryResponse.getMotd()); + this.getCachedFullResponse().writeString("gametype"); + this.getCachedFullResponse().writeString("SMP"); + this.getCachedFullResponse().writeString("game_id"); + this.getCachedFullResponse().writeString("MINECRAFT"); + this.getCachedFullResponse().writeString("version"); + this.getCachedFullResponse().writeString(queryResponse.getGameVersion()); + this.getCachedFullResponse().writeString("plugins"); + java.lang.StringBuilder pluginsString = new java.lang.StringBuilder(); + pluginsString.append(queryResponse.getServerVersion()); + if(!queryResponse.getPlugins().isEmpty()) { + pluginsString.append(": "); + Iterator iter = queryResponse.getPlugins().iterator(); + while(iter.hasNext()) { + com.destroystokyo.paper.event.server.GS4QueryEvent.QueryResponse.PluginInformation info = iter.next(); + pluginsString.append(info.getName()); + if (info.getVersion() != null) { + pluginsString.append(' ').append(info.getVersion().replaceAll(";", ",")); + } + if (iter.hasNext()) { + pluginsString.append(';').append(' '); + } + } + } + this.getCachedFullResponse().writeString(pluginsString.toString()); + this.getCachedFullResponse().writeString("map"); + this.getCachedFullResponse().writeString(queryResponse.getMap()); + this.getCachedFullResponse().writeString("numplayers"); + this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getCurrentPlayers())); + this.getCachedFullResponse().writeString("maxplayers"); + this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getMaxPlayers())); + this.getCachedFullResponse().writeString("hostport"); + this.getCachedFullResponse().writeString(Integer.toString(queryResponse.getPort())); + this.getCachedFullResponse().writeString("hostip"); + this.getCachedFullResponse().writeString(queryResponse.getHostname()); + // The "meaningless data" start, copied from above + this.getCachedFullResponse().writeInt(0); + this.getCachedFullResponse().writeInt(1); + this.getCachedFullResponse().writeString("player_"); + this.getCachedFullResponse().writeInt(0); + // "Meaningless data" end + queryResponse.getPlayers().forEach(this.getCachedFullResponse()::writeStringUnchecked); + this.getCachedFullResponse().writeInt(0); + // Paper end return this.v.a(); } } diff --git a/src/main/java/net/minecraft/server/RemoteStatusReply.java b/src/main/java/net/minecraft/server/RemoteStatusReply.java index 848b5c3f0..73efea7e1 100644 --- a/src/main/java/net/minecraft/server/RemoteStatusReply.java +++ b/src/main/java/net/minecraft/server/RemoteStatusReply.java @@ -18,15 +18,27 @@ public class RemoteStatusReply { this.b.write(abyte, 0, abyte.length); } + public void writeString(String string) throws IOException { this.a(string); } // Paper - OBFHELPER public void a(String s) throws IOException { this.b.writeBytes(s); this.b.write(0); } + // Paper start - unchecked exception variant to use in Stream API + public void writeStringUnchecked(String string) { + try { + writeString(string); + } catch (IOException e) { + com.destroystokyo.paper.util.SneakyThrow.sneaky(e); + } + } + // Paper end + public void writeInt(int i) throws IOException { this.a(i); } // Paper - OBFHELPER public void a(int i) throws IOException { this.b.write(i); } + public void writeShort(short i) throws IOException { this.a(i); } // Paper - OBFHELPER public void a(short short0) throws IOException { this.b.writeShort(Short.reverseBytes(short0)); } -- 2.24.1