From e6e16a7a08fb6e43bdaa379f8c99caa479f3eaf8 Mon Sep 17 00:00:00 2001 From: mworzala Date: Thu, 28 Dec 2023 07:58:33 -0500 Subject: [PATCH] fix: do not send login disconnect packet before switching to login state (cherry picked from commit 6d5b1ea77e5e7368cfa8906390499af9fb52d672) --- .../listener/preplay/HandshakeListener.java | 149 +++++++++--------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java b/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java index 4fb4402d2..a3acb0259 100644 --- a/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java +++ b/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java @@ -39,95 +39,94 @@ public final class HandshakeListener { public static void listener(@NotNull ClientHandshakePacket packet, @NotNull PlayerConnection connection) { String address = packet.serverAddress(); - // Bungee support (IP forwarding) - if (BungeeCordProxy.isEnabled() && connection instanceof PlayerSocketConnection socketConnection && packet.intent() == 2) { - final String[] split = address.split("\00"); - - if (split.length == 3 || split.length == 4) { - boolean hasProperties = split.length == 4; - if (BungeeCordProxy.isBungeeGuardEnabled() && !hasProperties) { - bungeeDisconnect(socketConnection); - return; - } - - address = split[0]; - - final SocketAddress socketAddress = new java.net.InetSocketAddress(split[1], - ((java.net.InetSocketAddress) connection.getRemoteAddress()).getPort()); - socketConnection.setRemoteAddress(socketAddress); - - UUID playerUuid = java.util.UUID.fromString( - split[2] - .replaceFirst( - "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5" - ) - ); - - List properties = new ArrayList<>(); - if (hasProperties) { - boolean foundBungeeGuardToken = false; - final String rawPropertyJson = split[3]; - final JsonArray propertyJson = JsonParser.parseString(rawPropertyJson).getAsJsonArray(); - for (JsonElement element : propertyJson) { - final JsonObject jsonObject = element.getAsJsonObject(); - final JsonElement name = jsonObject.get("name"); - final JsonElement value = jsonObject.get("value"); - final JsonElement signature = jsonObject.get("signature"); - if (name == null || value == null) continue; - - final String nameString = name.getAsString(); - final String valueString = value.getAsString(); - final String signatureString = signature == null ? null : signature.getAsString(); - - if (BungeeCordProxy.isBungeeGuardEnabled() && nameString.equals("bungeeguard-token")) { - if (foundBungeeGuardToken || !BungeeCordProxy.isValidBungeeGuardToken(valueString)) { - bungeeDisconnect(socketConnection); - return; - } - - foundBungeeGuardToken = true; - } - - properties.add(new GameProfile.Property(nameString, valueString, signatureString)); - } - - if (BungeeCordProxy.isBungeeGuardEnabled() && !foundBungeeGuardToken) { - bungeeDisconnect(socketConnection); - return; - } - } - - final GameProfile gameProfile = new GameProfile(playerUuid, "test", properties); - socketConnection.UNSAFE_setProfile(gameProfile); - } else { - bungeeDisconnect(socketConnection); - return; - } - } - - if (connection instanceof PlayerSocketConnection) { - // Give to the connection the server info that the client used - ((PlayerSocketConnection) connection).refreshServerInformation(address, packet.serverPort(), packet.protocolVersion()); - } - switch (packet.intent()) { case 1 -> { connection.setClientState(ConnectionState.STATUS); connection.setServerState(ConnectionState.STATUS); } case 2 -> { - if (packet.protocolVersion() == MinecraftServer.PROTOCOL_VERSION) { - connection.setClientState(ConnectionState.LOGIN); - connection.setServerState(ConnectionState.LOGIN); - } else { + connection.setClientState(ConnectionState.LOGIN); + connection.setServerState(ConnectionState.LOGIN); + if (packet.protocolVersion() != MinecraftServer.PROTOCOL_VERSION) { // Incorrect client version disconnect(connection, INVALID_VERSION_TEXT); } + + // Bungee support (IP forwarding) + if (BungeeCordProxy.isEnabled() && connection instanceof PlayerSocketConnection socketConnection) { + final String[] split = address.split("\00"); + + if (split.length == 3 || split.length == 4) { + boolean hasProperties = split.length == 4; + if (BungeeCordProxy.isBungeeGuardEnabled() && !hasProperties) { + bungeeDisconnect(socketConnection); + return; + } + + address = split[0]; + + final SocketAddress socketAddress = new java.net.InetSocketAddress(split[1], + ((java.net.InetSocketAddress) connection.getRemoteAddress()).getPort()); + socketConnection.setRemoteAddress(socketAddress); + + UUID playerUuid = java.util.UUID.fromString( + split[2] + .replaceFirst( + "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5" + ) + ); + + List properties = new ArrayList<>(); + if (hasProperties) { + boolean foundBungeeGuardToken = false; + final String rawPropertyJson = split[3]; + final JsonArray propertyJson = JsonParser.parseString(rawPropertyJson).getAsJsonArray(); + for (JsonElement element : propertyJson) { + final JsonObject jsonObject = element.getAsJsonObject(); + final JsonElement name = jsonObject.get("name"); + final JsonElement value = jsonObject.get("value"); + final JsonElement signature = jsonObject.get("signature"); + if (name == null || value == null) continue; + + final String nameString = name.getAsString(); + final String valueString = value.getAsString(); + final String signatureString = signature == null ? null : signature.getAsString(); + + if (BungeeCordProxy.isBungeeGuardEnabled() && nameString.equals("bungeeguard-token")) { + if (foundBungeeGuardToken || !BungeeCordProxy.isValidBungeeGuardToken(valueString)) { + bungeeDisconnect(socketConnection); + return; + } + + foundBungeeGuardToken = true; + } + + properties.add(new GameProfile.Property(nameString, valueString, signatureString)); + } + + if (BungeeCordProxy.isBungeeGuardEnabled() && !foundBungeeGuardToken) { + bungeeDisconnect(socketConnection); + return; + } + } + + final GameProfile gameProfile = new GameProfile(playerUuid, "test", properties); + socketConnection.UNSAFE_setProfile(gameProfile); + } else { + bungeeDisconnect(socketConnection); + return; + } + } } default -> { // Unexpected error } } + + if (connection instanceof PlayerSocketConnection) { + // Give to the connection the server info that the client used + ((PlayerSocketConnection) connection).refreshServerInformation(address, packet.serverPort(), packet.protocolVersion()); + } } private static void disconnect(@NotNull PlayerConnection connection, @NotNull Component reason) {