diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index 9b1ac0fb..257606d6 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -92,6 +92,13 @@ public class ServerConnector extends PacketHandler } copiedHandshake.setHost( newHost ); } + else if ( !user.getExtraDataInHandshake().isEmpty() ) + { + // Only restore the extra data if IP forwarding is off. + // TODO: Add support for this data with IP forwarding. + copiedHandshake.setHost( copiedHandshake.getHost() + user.getExtraDataInHandshake() ); + } + channel.write( copiedHandshake ); channel.setProtocol( Protocol.LOGIN ); diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index e69544d1..936e6845 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -38,6 +38,7 @@ import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.entitymap.EntityMap; import net.md_5.bungee.forge.ForgeClientHandler; +import net.md_5.bungee.forge.ForgeConstants; import net.md_5.bungee.forge.ForgeServerHandler; import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.HandlerBoss; @@ -166,6 +167,9 @@ public final class UserConnection implements ProxiedPlayer } forgeClientHandler = new ForgeClientHandler( this ); + + // Set whether the connection has a 1.8 FML marker in the handshake. + forgeClientHandler.setFmlTokenInHandshake( this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN ) ); } public void sendPacket(PacketWrapper packet) @@ -567,6 +571,11 @@ public final class UserConnection implements ProxiedPlayer title.send( this ); } + public String getExtraDataInHandshake() + { + return this.getPendingConnection().getExtraDataInHandshake(); + } + public void setCompressionThreshold(int compressionThreshold) { if ( this.compressionThreshold == -1 ) diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 5bee22ca..8dfcc3cb 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -94,6 +94,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection private LoginResult loginProfile; @Getter private boolean legacy; + @Getter + private String extraDataInHandshake = ""; private enum State { @@ -250,6 +252,18 @@ public class InitialHandler extends PacketHandler implements PendingConnection this.handshake = handshake; ch.setVersion( handshake.getProtocolVersion() ); + // Starting with FML 1.8, a "\0FML\0" token is appended to the handshake. This interferes + // with Bungee's IP forwarding, so we detect it, and remove it from the host string, for now. + // We know FML appends \00FML\00. However, we need to also consider that other systems might + // add their own data to the end of the string. So, we just take everything from the \0 character + // and save it for later. + if ( handshake.getHost().contains( "\0" ) ) + { + String[] split = handshake.getHost().split( "\0", 2 ); + handshake.setHost( split[0] ); + extraDataInHandshake = "\0" + split[1]; + } + // SRV records can end with a . depending on DNS / client. if ( handshake.getHost().endsWith( "." ) ) { diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java index c624ee0c..ebde27ea 100644 --- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java @@ -41,6 +41,14 @@ public class ForgeClientHandler private PluginMessage serverModList = null; private PluginMessage serverIdList = null; + /** + * Gets or sets a value indicating whether the '\00FML\00' token was found in + * the handshake. + */ + @Getter + @Setter + private boolean fmlTokenInHandshake = false; + /** * Handles the Forge packet. * @@ -143,12 +151,14 @@ public class ForgeClientHandler /** * Returns whether we know if the user is a forge user. + * In FML 1.8, a "FML" token is included in the initial handshake. + * We can use that to determine if the user is a Forge 1.8 user. * * @return true if the user is a forge user. */ public boolean isForgeUser() { - return clientModList != null; + return fmlTokenInHandshake || clientModList != null; } /** diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java index e78bda6a..6dca2048 100644 --- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java +++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeConstants.java @@ -14,6 +14,11 @@ public class ForgeConstants public static final String FML_HANDSHAKE_TAG = "FML|HS"; public static final String FML_REGISTER = "REGISTER"; + /** + * The FML 1.8 handshake token. + */ + public static final String FML_HANDSHAKE_TOKEN = "\0FML\0"; + public static final PluginMessage FML_RESET_HANDSHAKE = new PluginMessage( FML_HANDSHAKE_TAG, new byte[] { -2, 0