diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java b/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java index 58ee44a78b..dea76a94e2 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java @@ -24,5 +24,6 @@ public enum PlayerInfoForwarding { NONE, LEGACY, BUNGEEGUARD, - MODERN + MODERN, + SECURE_MIX } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java index 8dd8d3279f..20bc84cb1e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -159,7 +159,7 @@ public boolean validate() { switch (playerInfoForwardingMode) { case NONE -> logger.warn("Player info forwarding is disabled! All players will appear to be connecting " + "from the proxy and will have offline-mode UUIDs."); - case MODERN, BUNGEEGUARD -> { + case MODERN, BUNGEEGUARD, SECURE_MIX -> { if (forwardingSecret == null || forwardingSecret.length == 0) { logger.error("You don't have a forwarding secret set. This is required for security."); valid = false; @@ -565,7 +565,8 @@ public static VelocityConfiguration read(Path path) throws IOException { // forwarding mode that requires it. if (forwardingSecret.length == 0 && (forwardingMode == PlayerInfoForwarding.MODERN - || forwardingMode == PlayerInfoForwarding.BUNGEEGUARD)) { + || forwardingMode == PlayerInfoForwarding.BUNGEEGUARD + || forwardingMode == PlayerInfoForwarding.SECURE_MIX)) { throw new RuntimeException("The forwarding-secret file must not be empty."); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java index 14884af467..9ff29ffdc8 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java @@ -83,7 +83,9 @@ public boolean handle(EncryptionRequestPacket packet) { public boolean handle(LoginPluginMessagePacket packet) { MinecraftConnection mc = serverConn.ensureConnected(); VelocityConfiguration configuration = server.getConfiguration(); - if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + if ((configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + || (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.SECURE_MIX + && mc.getProtocolVersion().greaterThan(ProtocolVersion.MINECRAFT_1_13))) && packet.getChannel().equals(PlayerDataForwarding.CHANNEL)) { int requestedForwardingVersion = PlayerDataForwarding.MODERN_DEFAULT; @@ -143,7 +145,12 @@ public boolean handle(SetCompressionPacket packet) { @Override public boolean handle(ServerLoginSuccessPacket packet) { - if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && !informationForwarded) { + MinecraftConnection smc = serverConn.ensureConnected(); + + if ((server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN + || (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.SECURE_MIX + && !smc.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13))) + && !informationForwarded) { resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE, serverConn.getServer())); serverConn.disconnect(); return true; @@ -153,7 +160,6 @@ public boolean handle(ServerLoginSuccessPacket packet) { // other problems that could arise before we get a JoinGame packet from the server. // Move into the PLAY phase. - MinecraftConnection smc = serverConn.ensureConnected(); if (smc.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_20_2)) { smc.setActiveSessionHandler(StateRegistry.PLAY, new TransitionSessionHandler(server, serverConn, resultFuture)); } else { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java index c40a7aaac6..242879e19e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java @@ -175,7 +175,8 @@ private void startHandshake() { handshake.setProtocolVersion(protocolVersion); if (forwardingMode == PlayerInfoForwarding.LEGACY) { handshake.setServerAddress(createLegacyForwardingAddress()); - } else if (forwardingMode == PlayerInfoForwarding.BUNGEEGUARD) { + } else if (forwardingMode == PlayerInfoForwarding.BUNGEEGUARD + || (forwardingMode == PlayerInfoForwarding.SECURE_MIX && protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_13))) { byte[] secret = server.getConfiguration().getForwardingSecret(); handshake.setServerAddress(createBungeeGuardForwardingAddress(secret)); } else if (proxyPlayer.getConnection().getType() == ConnectionTypes.LEGACY_FORGE) { diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml index 4d71e589b9..291e91cf93 100644 --- a/proxy/src/main/resources/default-velocity.toml +++ b/proxy/src/main/resources/default-velocity.toml @@ -34,6 +34,9 @@ prevent-client-proxy-connections = false # unable to implement network level firewalling (on a shared host). # - "modern": Forward player IPs and UUIDs as part of the login process using # Velocity's native forwarding. Only applicable for Minecraft 1.13 or higher. +# - "secure_mix": Forward player IPs and UUIDs as part of the login process using +# Velocity's native forwarding on Minecraft 1.13 or higher servers or in a +# format supported by the BungeeGuard plugin on others. player-info-forwarding-mode = "NONE" # If you are using modern or BungeeGuard IP forwarding, configure a file that contains a unique secret here.