From d3a21672fd223db393d1308571c69e9820b76a19 Mon Sep 17 00:00:00 2001 From: Dereku Date: Fri, 10 Mar 2023 09:55:53 +0700 Subject: [PATCH] Bruh --- .../net/rubeta/legacyping/ServerThread.java | 84 ++++++++++--------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/rubeta/legacyping/ServerThread.java b/src/main/java/net/rubeta/legacyping/ServerThread.java index 70c3249..b46531b 100644 --- a/src/main/java/net/rubeta/legacyping/ServerThread.java +++ b/src/main/java/net/rubeta/legacyping/ServerThread.java @@ -1,24 +1,19 @@ package net.rubeta.legacyping; -import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.craftbukkit.CraftServer; import java.io.*; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Arrays; +import java.net.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; public class ServerThread extends Thread { - // Queries start - private static final byte[] RUBETA_MODDED_CLIENT = new byte[]{0, 0, 0, 1, (byte) 254}; - private static final byte[] LEGACY_PING_B1_8_TO_R1_3 = new byte[]{(byte) 254}; - private static final byte[] PING_R1_4_TO_R1_5 = new byte[]{(byte) 254, 1}; - // Queries end + private static final String MODERN_RESPONSE = + "{\"version\": {\"name\": \"b1.7.3\",\"protocol\": -17}," + + "\"players\": {\"max\": %max%,\"online\": %now%,\"sample\": []}," + + "\"description\": {\"text\": \"%motd%\"},\"enforcesSecureChat\": false}"; private final ServerSocket serverSocket; private final AtomicBoolean working = new AtomicBoolean(false); private final Server minecraftServer; @@ -28,6 +23,7 @@ public class ServerThread extends Thread { final InetAddress address = InetAddress.getByName(host); this.serverSocket = new ServerSocket(port, 10, address); this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L)); + this.serverSocket.setPerformancePreferences(0, 2, 1); } @Override @@ -35,23 +31,23 @@ public class ServerThread extends Thread { this.working.set(true); while (this.working.get() || !this.serverSocket.isClosed()) { try { - final Socket newConnection = this.serverSocket.accept(); - final InputStream inputStream = newConnection.getInputStream(); - final ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[16]; - for (int length; (length = inputStream.read(buffer)) != -1; ) { - result.write(buffer, 0, length); + final Socket socket = this.serverSocket.accept(); + socket.setTrafficClass(SocketOptions.TCP_NODELAY & SocketOptions.IP_TOS); + final InputStream inputStream = socket.getInputStream(); + final OutputStream outputStream = socket.getOutputStream(); + final int firstByte = inputStream.read(); + switch (firstByte) { + case 0: + this.responseForRuBetaModdedClient(outputStream); + break; + case 254: + this.responseForLegacyPing(outputStream); + break; + default: + this.responseForModernPing(outputStream); } - final byte[] query = result.toByteArray(); - final OutputStream outputStream = newConnection.getOutputStream(); - if (Arrays.equals(RUBETA_MODDED_CLIENT, query)) { - this.responseForRuBetaModdedClient(outputStream); - } else if (Arrays.equals(LEGACY_PING_B1_8_TO_R1_3, query)) { - this.responseForLegacyPing(outputStream); - } else if (Arrays.equals(PING_R1_4_TO_R1_5, query)) { - this.responseForR14Ping(outputStream); - } - newConnection.close(); + outputStream.flush(); + socket.close(); } catch (IOException ignore) { } } @@ -82,12 +78,13 @@ public class ServerThread extends Thread { clientOutput.write(result.toByteArray()); } + @SuppressWarnings("UnnecessaryUnicodeEscape") private void responseForLegacyPing(final OutputStream outputStream) throws IOException { final DataOutputStream clientOutput = new DataOutputStream(outputStream); - clientOutput.write(255); // Packet 0xFF (PacketDisconnect) + clientOutput.write(255); final String response = ((CraftServer) this.minecraftServer).getServer().motd - + '\u0000' + this.minecraftServer.getOnlinePlayers().length - + '\u0000' + this.minecraftServer.getMaxPlayers(); + + '\u00a7' + this.minecraftServer.getOnlinePlayers().length + + '\u00a7' + this.minecraftServer.getMaxPlayers(); clientOutput.writeShort(response.length()); for (char c : response.toCharArray()) { clientOutput.writeChar(c); @@ -95,16 +92,27 @@ public class ServerThread extends Thread { // Packet data end } - private void responseForR14Ping(final OutputStream outputStream) throws IOException { + private void responseForModernPing(final OutputStream outputStream) throws IOException { + final String responseJson = MODERN_RESPONSE.replace("%max%", "" + this.minecraftServer.getMaxPlayers()) + .replace("%now%", "" + this.minecraftServer.getOnlinePlayers().length) + .replace("%motd%", ((CraftServer) this.minecraftServer).getServer().motd); + byte[] bytes = responseJson.getBytes(); final DataOutputStream clientOutput = new DataOutputStream(outputStream); - clientOutput.write(255); // Packet 0xFF (PacketDisconnect) - final String response = 'ยง' + 1 - + '\u0000' + "b1.7.3m" + '\u0000' + 17 // Protocol version - + '\u0000' + ((CraftServer) this.minecraftServer).getServer().motd - + '\u0000' + this.minecraftServer.getOnlinePlayers().length - + '\u0000' + this.minecraftServer.getMaxPlayers(); - clientOutput.writeShort(response.length()); - clientOutput.writeUTF(response); + this.writeVarInt(clientOutput, bytes.length + 3); + this.writeVarInt(clientOutput, 0); + this.writeVarInt(clientOutput, bytes.length); + clientOutput.write(bytes); // Packet data end } + + private void writeVarInt(DataOutputStream out, int paramInt) throws IOException { + while (true) { + if ((paramInt & 0xFFFFFF80) == 0) { + out.writeByte(paramInt); + return; + } + out.writeByte(paramInt & 0x7F | 0x80); + paramInt >>>= 7; + } + } }