From 7f83aacdf83490e180556a10ef8cd6a1da0d4e0e Mon Sep 17 00:00:00 2001 From: Adamaq01 Date: Sat, 10 Aug 2019 03:47:19 +0100 Subject: [PATCH] Implemented some packets + the keepalive system so the client doesn't timeout after 20 seconds --- src/main/java/fr/themode/minestom/Main.java | 17 ++++++++++++- .../fr/themode/minestom/entity/Player.java | 12 ++++++++++ .../minestom/net/ConnectionManager.java | 2 +- .../themode/minestom/net/PacketProcessor.java | 8 +++++++ .../handler/ClientPlayPacketsHandler.java | 3 +++ .../client/play/ClientKeepAlivePacket.java | 24 +++++++++++++++++++ .../play/ClientPlayerAbilitiesPacket.java | 24 +++++++++++++++++++ .../packet/server/play/DisconnectPacket.java | 24 +++++++++++++++++++ .../packet/server/play/KeepAlivePacket.java | 23 ++++++++++++++++++ 9 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/main/java/fr/themode/minestom/net/packet/client/play/ClientKeepAlivePacket.java create mode 100644 src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerAbilitiesPacket.java create mode 100644 src/main/java/fr/themode/minestom/net/packet/server/play/DisconnectPacket.java create mode 100644 src/main/java/fr/themode/minestom/net/packet/server/play/KeepAlivePacket.java diff --git a/src/main/java/fr/themode/minestom/Main.java b/src/main/java/fr/themode/minestom/Main.java index 632f43132..11417846e 100644 --- a/src/main/java/fr/themode/minestom/Main.java +++ b/src/main/java/fr/themode/minestom/Main.java @@ -7,6 +7,7 @@ import fr.adamaq01.ozao.net.server.ServerHandler; import fr.adamaq01.ozao.net.server.backend.tcp.TCPServer; import fr.themode.minestom.net.ConnectionManager; import fr.themode.minestom.net.PacketProcessor; +import fr.themode.minestom.net.packet.server.play.KeepAlivePacket; import fr.themode.minestom.net.protocol.MinecraftProtocol; import java.lang.reflect.InvocationTargetException; @@ -56,6 +57,20 @@ public class Main { server.bind(25565); System.out.println("Server started"); - } + long lastTime = System.currentTimeMillis(); + while (true) { + if (System.currentTimeMillis() - lastTime >= 50) { + lastTime = System.currentTimeMillis(); + // Tick + // Keep Alive Handling + server.getConnections().stream().filter(connection -> packetProcessor.hasPlayerConnection(connection) && connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)) != null && System.currentTimeMillis() - connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)).getLastKeepAlive() > 20000).map(connection -> connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection))).forEach(player -> { + long id = System.currentTimeMillis(); + player.refreshKeepAlive(id); + KeepAlivePacket keepAlivePacket = new KeepAlivePacket(id); + player.getPlayerConnection().sendPacket(keepAlivePacket); + }); + } + } + } } diff --git a/src/main/java/fr/themode/minestom/entity/Player.java b/src/main/java/fr/themode/minestom/entity/Player.java index 0b40f255e..2be39cf1b 100644 --- a/src/main/java/fr/themode/minestom/entity/Player.java +++ b/src/main/java/fr/themode/minestom/entity/Player.java @@ -7,9 +7,14 @@ public class Player { private double x, y, z; private float yaw, pitch; private boolean onGround; + private long lastKeepAlive; private PlayerConnection playerConnection; + public Player(PlayerConnection playerConnection) { + this.playerConnection = playerConnection; + } + public PlayerConnection getPlayerConnection() { return playerConnection; } @@ -29,4 +34,11 @@ public class Player { this.onGround = onGround; } + public void refreshKeepAlive(long lastKeepAlive) { + this.lastKeepAlive = lastKeepAlive; + } + + public long getLastKeepAlive() { + return lastKeepAlive; + } } diff --git a/src/main/java/fr/themode/minestom/net/ConnectionManager.java b/src/main/java/fr/themode/minestom/net/ConnectionManager.java index 3e547aa4f..b8b4d6a00 100644 --- a/src/main/java/fr/themode/minestom/net/ConnectionManager.java +++ b/src/main/java/fr/themode/minestom/net/ConnectionManager.java @@ -19,6 +19,6 @@ public class ConnectionManager { // Is only used at LoginStartPacket#process public void createPlayer(PlayerConnection connection) { - this.connectionPlayerMap.put(connection, new Player()); + this.connectionPlayerMap.put(connection, new Player(connection)); } } diff --git a/src/main/java/fr/themode/minestom/net/PacketProcessor.java b/src/main/java/fr/themode/minestom/net/PacketProcessor.java index 6a87230de..416cf9361 100644 --- a/src/main/java/fr/themode/minestom/net/PacketProcessor.java +++ b/src/main/java/fr/themode/minestom/net/PacketProcessor.java @@ -77,4 +77,12 @@ public class PacketProcessor { break; } } + + public PlayerConnection getPlayerConnection(Connection connection) { + return connectionPlayerConnectionMap.get(connection); + } + + public boolean hasPlayerConnection(Connection connection) { + return connectionPlayerConnectionMap.containsKey(connection); + } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java index 36b085228..7821680d1 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java @@ -10,6 +10,9 @@ public class ClientPlayPacketsHandler extends ClientPacketsHandler { register(0x11, ClientPlayerPositionPacket.class); register(0x12, ClientPlayerPositionAndLookPacket.class); register(0x00, ClientTeleportConfirmPacket.class); + register(0x0F, ClientKeepAlivePacket.class); + register(0x19, ClientPlayerAbilitiesPacket.class); + register(0x13, ClientPlayerLookPacket.class); } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientKeepAlivePacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientKeepAlivePacket.java new file mode 100644 index 000000000..a020fb389 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientKeepAlivePacket.java @@ -0,0 +1,24 @@ +package fr.themode.minestom.net.packet.client.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.entity.Player; +import fr.themode.minestom.net.packet.client.ClientPlayPacket; +import fr.themode.minestom.net.packet.server.play.DisconnectPacket; + +public class ClientKeepAlivePacket implements ClientPlayPacket { + + private long id; + + @Override + public void process(Player player) { + if (id != player.getLastKeepAlive()) { + player.getPlayerConnection().sendPacket(new DisconnectPacket("{\"text\": \"Bad Keep Alive packet\"}")); + player.getPlayerConnection().getConnection().close(); + } + } + + @Override + public void read(Buffer buffer) { + this.id = buffer.getLong(); + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerAbilitiesPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerAbilitiesPacket.java new file mode 100644 index 000000000..73d258b34 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientPlayerAbilitiesPacket.java @@ -0,0 +1,24 @@ +package fr.themode.minestom.net.packet.client.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.entity.Player; +import fr.themode.minestom.net.packet.client.ClientPlayPacket; + +public class ClientPlayerAbilitiesPacket implements ClientPlayPacket { + + private byte flags; + private float flyingSpeed; + private float walkingSpeed; + + @Override + public void process(Player player) { + + } + + @Override + public void read(Buffer buffer) { + this.flags = buffer.getByte(); + this.flyingSpeed = buffer.getFloat(); + this.walkingSpeed = buffer.getFloat(); + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/DisconnectPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/DisconnectPacket.java new file mode 100644 index 000000000..54afe38b7 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/DisconnectPacket.java @@ -0,0 +1,24 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +public class DisconnectPacket implements ServerPacket { + + private String message; + + public DisconnectPacket(String message) { + this.message = message; + } + + @Override + public void write(Buffer buffer) { + Utils.writeString(buffer, this.message); + } + + @Override + public int getId() { + return 0x1A; + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/KeepAlivePacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/KeepAlivePacket.java new file mode 100644 index 000000000..2fbc98c82 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/KeepAlivePacket.java @@ -0,0 +1,23 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; + +public class KeepAlivePacket implements ServerPacket { + + private long id; + + public KeepAlivePacket(long id) { + this.id = id; + } + + @Override + public void write(Buffer buffer) { + buffer.putLong(id); + } + + @Override + public int getId() { + return 0x20; + } +}