diff --git a/pom.xml b/pom.xml index 6427ea9..3edbb1e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.rubeta LegacyPing - 1.5 + 1.6 jar LegacyPing diff --git a/src/main/java/net/rubeta/legacyping/ServerThread.java b/src/main/java/net/rubeta/legacyping/ServerThread.java index bf2aae1..97edb4d 100644 --- a/src/main/java/net/rubeta/legacyping/ServerThread.java +++ b/src/main/java/net/rubeta/legacyping/ServerThread.java @@ -13,26 +13,26 @@ public class ServerThread extends Thread { private static final String MODERN_RESPONSE = "{\"version\": {\"name\": \"%version%\",\"protocol\": %protocol%}," + - "\"players\": {\"max\": %max%,\"online\": %now%}," + - "\"description\": {\"text\": \"%motd%\"}," + - "\"enforcesSecureChat\": false,\"previewsChat\": true}"; + "\"players\": {\"max\": %max%,\"online\": %now%}," + + "\"description\": {\"text\": \"%motd%\"}," + + "\"enforcesSecureChat\": false,\"previewsChat\": true}"; private static final String DISCONNECT_REASON = "[\"\",{\"text\":\"This is b1.7.3 server. Visit \"}," + "{\"text\":\"https://rubeta.net\",\"underlined\":true},{\"text\":\" for more information.\"}]"; - private final ServerSocket serverSocket; private final AtomicBoolean working = new AtomicBoolean(false); private final Server minecraftServer; private final String version; private final int protocol; + private final InetAddress address; + private final int port; + private ServerSocket serverSocket; public ServerThread(final Server server, final String host, int port, String version, int protocol) throws IOException { this.minecraftServer = server; this.setName("LegacyPing thread listening " + host + ":" + port); this.version = version; this.protocol = protocol; - 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); + this.address = InetAddress.getByName(host); + this.port = port; } public ServerThread(final String host, int port) throws IOException { @@ -40,10 +40,8 @@ public class ServerThread extends Thread { this.setName("LegacyPing thread listening " + host + ":" + port); this.version = "dummy"; this.protocol = 0; - 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); + this.address = InetAddress.getByName(host); + this.port = port; } public static void main(String[] args) throws IOException { @@ -54,33 +52,48 @@ public class ServerThread extends Thread { @Override public void run() { this.working.set(true); - while (this.working.get() && !this.serverSocket.isClosed()) { - try (final Socket socket = this.serverSocket.accept(); - final DataInputStream inputStream = new DataInputStream(socket.getInputStream()); - final DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) { - socket.setTrafficClass(SocketOptions.TCP_NODELAY & SocketOptions.IP_TOS); + while (this.working.get()) { + try { + this.serverSocket = new ServerSocket(port, 10, address); + this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L)); + this.serverSocket.setPerformancePreferences(0, 2, 1); + } catch (IOException e) { + System.out.println("Failed to start ServerSocket: " + e); + this.pause(); + continue; + } - final int packetLength = inputStream.readByte() | inputStream.readByte() << 1; // idk why it doesn't a VarInt - final int protocolVersion = this.readVarInt(inputStream); - final String hostname = this.readUtf(inputStream); - final int port = inputStream.readShort(); - final int status = this.readVarInt(inputStream); + while (!this.serverSocket.isClosed()) { + if (!this.working.get()) { + break; + } + try (final Socket socket = this.serverSocket.accept()) { + final DataInputStream inputStream = new DataInputStream(socket.getInputStream()); + final DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); + socket.setTrafficClass(SocketOptions.TCP_NODELAY & SocketOptions.IP_TOS); + + final int packetLength = inputStream.readByte() | inputStream.readByte() << 1; // idk why it doesn't a VarInt + final int protocolVersion = this.readVarInt(inputStream); + final String hostname = this.readUtf(inputStream); + final int port = inputStream.readShort(); + final int status = this.readVarInt(inputStream); // System.out.println(packetLength + "; Protocol version: " + protocolVersion + ", host: " + hostname // + ", port: " + port + ", status: " + status); - if (status != 2) { - this.responseForModernPing(outputStream, MODERN_RESPONSE); - } else { - this.responseForModernPing(outputStream, DISCONNECT_REASON); - } - outputStream.flush(); + if (status != 2) { + this.responseForModernPing(outputStream, MODERN_RESPONSE); + } else { + this.responseForModernPing(outputStream, DISCONNECT_REASON); + } + outputStream.flush(); - inputStream.readShort(); // legacy data - this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet length (9) - this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet id (1) - outputStream.writeLong(inputStream.readLong()); // timestamp - } catch (SocketTimeoutException | EOFException ignore) { - } catch (IOException ex) { - System.out.println("Exception caught: " + ex); + inputStream.readShort(); // legacy data + this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet length (9) + this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet id (1) + outputStream.writeLong(inputStream.readLong()); // timestamp + } catch (SocketTimeoutException | EOFException ignore) { + } catch (Exception ex) { + System.out.println("Exception caught: " + ex); + } } } } @@ -93,6 +106,13 @@ public class ServerThread extends Thread { } } + void pause() { + try { + Thread.sleep(TimeUnit.SECONDS.toMillis(30L)); + } catch (InterruptedException ignored) { + } + } + private void responseForModernPing(final DataOutputStream outputStream, String response) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); @@ -131,12 +151,12 @@ public class ServerThread extends Thread { if (j > 5) { throw new RuntimeException("VarInt too big"); } - } while((b0 & 128) == 128); + } while ((b0 & 128) == 128); return i; } private void writeVarInt(DataOutputStream out, int paramInt) throws IOException { - while((paramInt & 0xffffff80) != 0) { + while ((paramInt & 0xffffff80) != 0) { out.writeByte(paramInt & 0x7f | 0x80); paramInt >>>= 7; }