From 02c4d61fc63ee48d6408934683e7507f71eb1f61 Mon Sep 17 00:00:00 2001 From: Mgazul Date: Thu, 11 Jan 2024 19:24:11 +0800 Subject: [PATCH] Add ModernForgeConnectionType to supports Forge-1.20.2+ (#1176) --- .../backend/VelocityServerConnection.java | 4 ++ .../client/HandshakeSessionHandler.java | 6 ++ .../modern/ModernForgeConnectionType.java | 65 +++++++++++++++++++ .../forge/modern/ModernForgeConstants.java | 25 +++++++ 4 files changed, 100 insertions(+) create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConnectionType.java create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConstants.java 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 9a4b7d72d..38a442151 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 @@ -36,6 +36,7 @@ import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; +import com.velocitypowered.proxy.connection.forge.modern.ModernForgeConnectionType; import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl; import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.Handshake; @@ -188,6 +189,9 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation, handshake.setServerAddress(createBungeeGuardForwardingAddress(secret)); } else if (proxyPlayer.getConnection().getType() == ConnectionTypes.LEGACY_FORGE) { handshake.setServerAddress(playerVhost + HANDSHAKE_HOSTNAME_TOKEN); + } else if (proxyPlayer.getConnection().getType() instanceof ModernForgeConnectionType) { + handshake.setServerAddress(playerVhost + ((ModernForgeConnectionType) proxyPlayer + .getConnection().getType()).getModernToken()); } else { handshake.setServerAddress(playerVhost); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java index 2b5c171ae..b3897395d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java @@ -28,6 +28,8 @@ import com.velocitypowered.proxy.connection.ConnectionTypes; import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants; +import com.velocitypowered.proxy.connection.forge.modern.ModernForgeConnectionType; +import com.velocitypowered.proxy.connection.forge.modern.ModernForgeConstants; import com.velocitypowered.proxy.connection.util.VelocityInboundConnection; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.StateRegistry; @@ -152,6 +154,10 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler { } private ConnectionType getHandshakeConnectionType(Handshake handshake) { + if (handshake.getServerAddress().contains(ModernForgeConstants.MODERN_FORGE_TOKEN) + && handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) >= 0) { + return new ModernForgeConnectionType(handshake.getServerAddress()); + } // Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13). if (handshake.getServerAddress().endsWith(LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN) && handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConnectionType.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConnectionType.java new file mode 100644 index 000000000..d58e4eae0 --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConnectionType.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018-2023 Velocity Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.velocitypowered.proxy.connection.forge.modern; + +import static com.velocitypowered.proxy.connection.forge.modern.ModernForgeConstants.MODERN_FORGE_TOKEN; + +import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases; +import com.velocitypowered.proxy.connection.client.ClientConnectionPhases; +import com.velocitypowered.proxy.connection.util.ConnectionTypeImpl; + +/** + * Contains extra logic. + */ +public class ModernForgeConnectionType extends ConnectionTypeImpl { + + public final String hostName; + + /** + * initialize the host name into an internal variable. + * + * @param hostName address from the client + */ + public ModernForgeConnectionType(String hostName) { + super(ClientConnectionPhases.VANILLA, + BackendConnectionPhases.VANILLA); + this.hostName = hostName; + } + + /** + * Align the acquisition logic with the internal code of Forge. + * + * @return returns the final correct hostname + */ + public String getModernToken() { + int natVersion = 0; + int idx = hostName.indexOf('\0'); + if (idx != -1) { + for (var pt : hostName.split("\0")) { + if (pt.startsWith(MODERN_FORGE_TOKEN)) { + if (pt.length() > MODERN_FORGE_TOKEN.length()) { + natVersion = Integer.parseInt( + pt.substring(MODERN_FORGE_TOKEN.length())); + } + } + } + } + return natVersion == 0 ? "\0" + MODERN_FORGE_TOKEN : "\0" + + MODERN_FORGE_TOKEN + natVersion; + } +} diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConstants.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConstants.java new file mode 100644 index 000000000..15add83bc --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/forge/modern/ModernForgeConstants.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2018-2023 Velocity Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.velocitypowered.proxy.connection.forge.modern; + +/** + * Constants for use with Modern Forge systems. + */ +public class ModernForgeConstants { + public static final String MODERN_FORGE_TOKEN = "FORGE"; +}