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";
+}