Autorecovery on failure
This commit is contained in:
parent
6729de5894
commit
9f0ba79d91
2 changed files with 58 additions and 38 deletions
2
pom.xml
2
pom.xml
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<groupId>net.rubeta</groupId>
|
<groupId>net.rubeta</groupId>
|
||||||
<artifactId>LegacyPing</artifactId>
|
<artifactId>LegacyPing</artifactId>
|
||||||
<version>1.5</version>
|
<version>1.6</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>LegacyPing</name>
|
<name>LegacyPing</name>
|
||||||
|
|
|
||||||
|
|
@ -13,26 +13,26 @@ public class ServerThread extends Thread {
|
||||||
|
|
||||||
private static final String MODERN_RESPONSE =
|
private static final String MODERN_RESPONSE =
|
||||||
"{\"version\": {\"name\": \"%version%\",\"protocol\": %protocol%}," +
|
"{\"version\": {\"name\": \"%version%\",\"protocol\": %protocol%}," +
|
||||||
"\"players\": {\"max\": %max%,\"online\": %now%}," +
|
"\"players\": {\"max\": %max%,\"online\": %now%}," +
|
||||||
"\"description\": {\"text\": \"%motd%\"}," +
|
"\"description\": {\"text\": \"%motd%\"}," +
|
||||||
"\"enforcesSecureChat\": false,\"previewsChat\": true}";
|
"\"enforcesSecureChat\": false,\"previewsChat\": true}";
|
||||||
private static final String DISCONNECT_REASON = "[\"\",{\"text\":\"This is b1.7.3 server. Visit \"}," +
|
private static final String DISCONNECT_REASON = "[\"\",{\"text\":\"This is b1.7.3 server. Visit \"}," +
|
||||||
"{\"text\":\"https://rubeta.net\",\"underlined\":true},{\"text\":\" for more information.\"}]";
|
"{\"text\":\"https://rubeta.net\",\"underlined\":true},{\"text\":\" for more information.\"}]";
|
||||||
private final ServerSocket serverSocket;
|
|
||||||
private final AtomicBoolean working = new AtomicBoolean(false);
|
private final AtomicBoolean working = new AtomicBoolean(false);
|
||||||
private final Server minecraftServer;
|
private final Server minecraftServer;
|
||||||
private final String version;
|
private final String version;
|
||||||
private final int protocol;
|
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 {
|
public ServerThread(final Server server, final String host, int port, String version, int protocol) throws IOException {
|
||||||
this.minecraftServer = server;
|
this.minecraftServer = server;
|
||||||
this.setName("LegacyPing thread listening " + host + ":" + port);
|
this.setName("LegacyPing thread listening " + host + ":" + port);
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.protocol = protocol;
|
this.protocol = protocol;
|
||||||
final InetAddress address = InetAddress.getByName(host);
|
this.address = InetAddress.getByName(host);
|
||||||
this.serverSocket = new ServerSocket(port, 10, address);
|
this.port = port;
|
||||||
this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L));
|
|
||||||
this.serverSocket.setPerformancePreferences(0, 2, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerThread(final String host, int port) throws IOException {
|
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.setName("LegacyPing thread listening " + host + ":" + port);
|
||||||
this.version = "dummy";
|
this.version = "dummy";
|
||||||
this.protocol = 0;
|
this.protocol = 0;
|
||||||
final InetAddress address = InetAddress.getByName(host);
|
this.address = InetAddress.getByName(host);
|
||||||
this.serverSocket = new ServerSocket(port, 10, address);
|
this.port = port;
|
||||||
this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L));
|
|
||||||
this.serverSocket.setPerformancePreferences(0, 2, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
@ -54,33 +52,48 @@ public class ServerThread extends Thread {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
this.working.set(true);
|
this.working.set(true);
|
||||||
while (this.working.get() && !this.serverSocket.isClosed()) {
|
while (this.working.get()) {
|
||||||
try (final Socket socket = this.serverSocket.accept();
|
try {
|
||||||
final DataInputStream inputStream = new DataInputStream(socket.getInputStream());
|
this.serverSocket = new ServerSocket(port, 10, address);
|
||||||
final DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) {
|
this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L));
|
||||||
socket.setTrafficClass(SocketOptions.TCP_NODELAY & SocketOptions.IP_TOS);
|
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
|
while (!this.serverSocket.isClosed()) {
|
||||||
final int protocolVersion = this.readVarInt(inputStream);
|
if (!this.working.get()) {
|
||||||
final String hostname = this.readUtf(inputStream);
|
break;
|
||||||
final int port = inputStream.readShort();
|
}
|
||||||
final int status = this.readVarInt(inputStream);
|
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
|
// System.out.println(packetLength + "; Protocol version: " + protocolVersion + ", host: " + hostname
|
||||||
// + ", port: " + port + ", status: " + status);
|
// + ", port: " + port + ", status: " + status);
|
||||||
if (status != 2) {
|
if (status != 2) {
|
||||||
this.responseForModernPing(outputStream, MODERN_RESPONSE);
|
this.responseForModernPing(outputStream, MODERN_RESPONSE);
|
||||||
} else {
|
} else {
|
||||||
this.responseForModernPing(outputStream, DISCONNECT_REASON);
|
this.responseForModernPing(outputStream, DISCONNECT_REASON);
|
||||||
}
|
}
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
|
|
||||||
inputStream.readShort(); // legacy data
|
inputStream.readShort(); // legacy data
|
||||||
this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet length (9)
|
this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet length (9)
|
||||||
this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet id (1)
|
this.writeVarInt(outputStream, this.readVarInt(inputStream)); // Packet id (1)
|
||||||
outputStream.writeLong(inputStream.readLong()); // timestamp
|
outputStream.writeLong(inputStream.readLong()); // timestamp
|
||||||
} catch (SocketTimeoutException | EOFException ignore) {
|
} catch (SocketTimeoutException | EOFException ignore) {
|
||||||
} catch (IOException ex) {
|
} catch (Exception ex) {
|
||||||
System.out.println("Exception caught: " + 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 {
|
private void responseForModernPing(final DataOutputStream outputStream, String response) throws IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
DataOutputStream dos = new DataOutputStream(baos);
|
DataOutputStream dos = new DataOutputStream(baos);
|
||||||
|
|
@ -131,12 +151,12 @@ public class ServerThread extends Thread {
|
||||||
if (j > 5) {
|
if (j > 5) {
|
||||||
throw new RuntimeException("VarInt too big");
|
throw new RuntimeException("VarInt too big");
|
||||||
}
|
}
|
||||||
} while((b0 & 128) == 128);
|
} while ((b0 & 128) == 128);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
|
private void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
|
||||||
while((paramInt & 0xffffff80) != 0) {
|
while ((paramInt & 0xffffff80) != 0) {
|
||||||
out.writeByte(paramInt & 0x7f | 0x80);
|
out.writeByte(paramInt & 0x7f | 0x80);
|
||||||
paramInt >>>= 7;
|
paramInt >>>= 7;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue