packet handler (own thread), buffer fix, moved packets into own packages, disconnect after pong

This commit is contained in:
bixilon 2020-06-02 20:30:03 +02:00
parent 8928f9b922
commit a09d2614ad
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
12 changed files with 132 additions and 59 deletions

View File

@ -28,4 +28,9 @@ public class ServerListPing {
public String getBase64EncodedFavicon() {
return raw.getString("favicon");
}
public String getMotd() {
//ToDo TextComponent handling
return raw.getString("description");
}
}

View File

@ -1,15 +1,22 @@
package de.bixilon.minosoft.protocol.network;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.packets.serverbound.handshaking.PacketHandshake;
import de.bixilon.minosoft.protocol.packets.serverbound.handshaking.PacketStatusPing;
import de.bixilon.minosoft.protocol.packets.serverbound.handshaking.PacketStatusRequest;
import de.bixilon.minosoft.protocol.packets.serverbound.status.PacketStatusPing;
import de.bixilon.minosoft.protocol.packets.serverbound.status.PacketStatusRequest;
import de.bixilon.minosoft.protocol.protocol.ConnectionState;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
import de.bixilon.minosoft.util.Util;
import java.util.ArrayList;
public class Connection {
private final String host;
private final int port;
private final Network network;
private final PacketHandler handler;
private final ArrayList<ClientboundPacket> handlingQueue;
private ConnectionState state = ConnectionState.DISCONNECTED;
private boolean onlyPing;
@ -18,6 +25,18 @@ public class Connection {
this.host = host;
this.port = port;
network = new Network(this);
handlingQueue = new ArrayList<>();
handler = new PacketHandler(this);
Thread handleThread = new Thread(() -> {
while (getConnectionState() != ConnectionState.DISCONNECTING) {
while (handlingQueue.size() > 0) {
handlingQueue.get(0).handle(getHandler());
handlingQueue.remove(0);
}
Util.sleep(1);
}
});
handleThread.start();
}
/**
@ -26,7 +45,6 @@ public class Connection {
public void ping() {
onlyPing = true;
network.connect();
}
/**
@ -65,7 +83,7 @@ public class Connection {
setConnectionState(next);
break;
case STATUS:
// send staus request and ping
// send status request and ping
network.sendPacket(new PacketStatusRequest());
network.sendPacket(new PacketStatusPing(0));
break;
@ -76,4 +94,20 @@ public class Connection {
//ToDo: static right now
return ProtocolVersion.VERSION_1_7_10;
}
public PacketHandler getHandler() {
return this.handler;
}
public void handle(ClientboundPacket p) {
handlingQueue.add(p);
}
public boolean isOnlyPing() {
return onlyPing;
}
public void disconnect() {
setConnectionState(ConnectionState.DISCONNECTING);
}
}

View File

@ -5,7 +5,6 @@ import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
import de.bixilon.minosoft.protocol.protocol.ConnectionState;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.Protocol;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.Util;
import java.io.DataInputStream;
@ -60,7 +59,7 @@ public class Network {
dOut.write(b);
dOut.flush();
binQueue.remove(0);
System.out.println(String.format("Sent packet (%s)", b[1]));
System.out.println(String.format("[OUT] (%s)", b[1]));
}
// everything sent for now, waiting for data
@ -89,6 +88,7 @@ public class Network {
Util.sleep(1);
}
connection.setConnectionState(ConnectionState.DISCONNECTED);
} catch (IOException e) {
// Could not connect
connection.setConnectionState(ConnectionState.DISCONNECTED);
@ -114,17 +114,17 @@ public class Network {
// read data
InPacketBuffer inPacketBuffer = new InPacketBuffer(binQueueIn.get(0));
System.out.println("Received packet with command=" + inPacketBuffer.getCommand());
Class<? extends ClientboundPacket> clazz = Protocol.getPacketByPacket(connection.getVersion().getProtocol().getPacketByCommand(connection.getConnectionState(), inPacketBuffer.getCommand()));
if (clazz == null) {
System.out.println("Unknown packet received with command=" + inPacketBuffer.getCommand());
System.out.println("[IN] Unknown: " + inPacketBuffer.getCommand());
binQueueIn.remove(0);
continue;
}
try {
ClientboundPacket packet = clazz.getConstructor().newInstance();
packet.read(inPacketBuffer, connection.getVersion());
connection.handle(packet);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
// safety first, but will not occur
e.printStackTrace();
@ -141,11 +141,6 @@ public class Network {
}
public void disconnect() {
connection.setConnectionState(ConnectionState.DISCONNECTING);
}
public void sendPacket(ServerboundPacket p) {
queue.add(p);

View File

@ -1,9 +1,12 @@
package de.bixilon.minosoft.protocol.packets;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
// packet to send to client
public interface ClientboundPacket extends Packet {
void read(InPacketBuffer buffer, ProtocolVersion v);
void handle(PacketHandler h);
}

View File

@ -1,18 +1,29 @@
package de.bixilon.minosoft.protocol.packets.clientbound.handshaking;
package de.bixilon.minosoft.protocol.packets.clientbound.status;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketStatusPong implements ClientboundPacket {
Long id;
@Override
public void read(InPacketBuffer buffer, ProtocolVersion v) {
System.out.println("Pong received");
this.id = buffer.readLong();
}
@Override
public void log() {
// ToDo
}
@Override
public void handle(PacketHandler h) {
h.handle(this);
}
public Long getID() {
return this.id;
}
}

View File

@ -1,8 +1,9 @@
package de.bixilon.minosoft.protocol.packets.clientbound.handshaking;
package de.bixilon.minosoft.protocol.packets.clientbound.status;
import de.bixilon.minosoft.objects.ServerListPing;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketStatusResponse implements ClientboundPacket {
@ -18,4 +19,13 @@ public class PacketStatusResponse implements ClientboundPacket {
public void log() {
// ToDo
}
@Override
public void handle(PacketHandler h) {
h.handle(this);
}
public ServerListPing getResponse() {
return this.response;
}
}

View File

@ -1,4 +1,4 @@
package de.bixilon.minosoft.protocol.packets.serverbound.handshaking;
package de.bixilon.minosoft.protocol.packets.serverbound.status;
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
@ -6,21 +6,21 @@ import de.bixilon.minosoft.protocol.protocol.Packets;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketStatusPing implements ServerboundPacket {
final Long ms;
final Long id;
public PacketStatusPing(Long ms) {
this.ms = ms;
public PacketStatusPing(Long id) {
this.id = id;
}
public PacketStatusPing(int ms) {
this.ms = (long) ms;
public PacketStatusPing(int id) {
this.id = (long) id;
}
@Override
public OutPacketBuffer write(ProtocolVersion v) {
// no version checking, is the same in all versions (1.7.x - 1.15.2)
OutPacketBuffer buffer = new OutPacketBuffer(v.getPacketCommand(Packets.Serverbound.STATUS_PING));
buffer.writeLong(ms);
buffer.writeLong(id);
return buffer;
}

View File

@ -1,7 +1,9 @@
package de.bixilon.minosoft.protocol.packets.serverbound.handshaking;
package de.bixilon.minosoft.protocol.packets.serverbound.status;
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
import de.bixilon.minosoft.protocol.protocol.*;
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.Packets;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketStatusRequest implements ServerboundPacket {

View File

@ -4,7 +4,6 @@ import de.bixilon.minosoft.objects.BlockPosition;
import org.json.JSONObject;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@ -39,36 +38,31 @@ public class InByteBuffer {
public short readShort() {
ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES);
buffer.put(readBytes(Short.BYTES));
buffer.order(ByteOrder.BIG_ENDIAN);
return buffer.getShort();
return buffer.getShort(0);
}
public int readInteger() {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.put(readBytes(Integer.BYTES));
buffer.order(ByteOrder.BIG_ENDIAN);
return buffer.getInt();
return buffer.getInt(0);
}
public Long readLong() {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.put(readBytes(Long.BYTES));
buffer.order(ByteOrder.BIG_ENDIAN);
return buffer.getLong();
return buffer.getLong(0);
}
public Float readFloat() {
ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
buffer.put(readBytes(Float.BYTES));
buffer.order(ByteOrder.BIG_ENDIAN);
return buffer.getFloat();
return buffer.getFloat(0);
}
public Double readDouble() {
ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES);
buffer.put(readBytes(Double.BYTES));
buffer.order(ByteOrder.BIG_ENDIAN);
return buffer.getDouble();
return buffer.getDouble(0);
}
public String readString() {
@ -83,7 +77,6 @@ public class InByteBuffer {
public UUID readUUID() {
ByteBuffer buffer = ByteBuffer.allocate(16); // UUID.BYTES
buffer.put(readBytes(16));
buffer.order(ByteOrder.BIG_ENDIAN);
return new UUID(buffer.getLong(0), buffer.getLong(1));
}

View File

@ -4,14 +4,13 @@ import de.bixilon.minosoft.objects.BlockPosition;
import org.json.JSONObject;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class OutByteBuffer {
private List<Byte> bytes = new ArrayList<>();
private final List<Byte> bytes = new ArrayList<>();
public OutByteBuffer() {
}
@ -37,7 +36,6 @@ public class OutByteBuffer {
public void writeShort(short s) {
ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES);
buffer.putShort(s);
buffer.order(ByteOrder.BIG_ENDIAN);
for (byte b : buffer.array()) {
bytes.add(b);
}
@ -46,7 +44,6 @@ public class OutByteBuffer {
public void writeInteger(int i) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.putInt(i);
buffer.order(ByteOrder.BIG_ENDIAN);
for (byte b : buffer.array()) {
bytes.add(b);
}
@ -55,7 +52,6 @@ public class OutByteBuffer {
public void writeLong(Long l) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(l);
buffer.order(ByteOrder.BIG_ENDIAN);
for (byte b : buffer.array()) {
bytes.add(b);
}
@ -64,7 +60,6 @@ public class OutByteBuffer {
public void writeFloat(Float f) {
ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
buffer.putFloat(f);
buffer.order(ByteOrder.BIG_ENDIAN);
for (byte b : buffer.array()) {
bytes.add(b);
}
@ -73,7 +68,6 @@ public class OutByteBuffer {
public void writeDouble(Double d) {
ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES);
buffer.putDouble(d);
buffer.order(ByteOrder.BIG_ENDIAN);
for (byte b : buffer.array()) {
bytes.add(b);
}
@ -94,7 +88,6 @@ public class OutByteBuffer {
ByteBuffer buffer = ByteBuffer.allocate(16); // UUID.BYTES
buffer.putLong(u.getMostSignificantBits());
buffer.putLong(u.getLeastSignificantBits());
buffer.order(ByteOrder.BIG_ENDIAN);
for (byte b : buffer.array()) {
bytes.add(b);
}

View File

@ -0,0 +1,27 @@
package de.bixilon.minosoft.protocol.protocol;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusPong;
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusResponse;
public class PacketHandler {
Connection connection;
public PacketHandler(Connection connection) {
this.connection = connection;
}
public void handle(PacketStatusResponse pkg) {
System.out.println(String.format("Status response received: %s/%s online. MotD: '%s'", pkg.getResponse().getPlayerOnline(), pkg.getResponse().getMaxPlayers(), pkg.getResponse().getMotd()));
}
public void handle(PacketStatusPong pkg) {
System.out.println("Pong: " + pkg.getID());
if (connection.isOnlyPing()) {
// pong arrived, closing connection
connection.disconnect();
}
}
}

View File

@ -1,8 +1,8 @@
package de.bixilon.minosoft.protocol.protocol;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.packets.clientbound.handshaking.PacketStatusPong;
import de.bixilon.minosoft.protocol.packets.clientbound.handshaking.PacketStatusResponse;
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusPong;
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusResponse;
import java.util.HashMap;