diff --git a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java index 2407fb74..57eb988f 100644 --- a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java @@ -4,6 +4,8 @@ import com.google.common.base.Preconditions; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; +import java.util.ArrayList; +import java.util.List; import javax.crypto.SecretKey; import lombok.Getter; import net.md_5.bungee.api.ChatColor; @@ -37,16 +39,17 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo @Getter private final ListenerInfo listener; private PacketStream stream; + private Packet1Login forgeLogin; private Packet2Handshake handshake; private PacketFDEncryptionRequest request; + private List loginMessages = new ArrayList<>(); private State thisState = State.HANDSHAKE; - private int protocol = PacketDefinitions.VANILLA_PROTOCOL; public InitialHandler(Socket socket, ListenerInfo info) throws IOException { this.socket = socket; this.listener = info; - stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), protocol ); + stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), PacketDefinitions.VANILLA_PROTOCOL ); } private enum State @@ -58,11 +61,16 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo @Override public void handle(Packet1Login login) throws Exception { + Preconditions.checkState( thisState == State.HANDSHAKE, "Not expecting FORGE LOGIN" ); + Preconditions.checkState( forgeLogin == null, "Already received FORGE LOGIN" ); + forgeLogin = login; + stream.setProtocol( PacketDefinitions.FORGE_PROTOCOL ); } @Override public void handle(PacketFAPluginMessage pluginMessage) throws Exception { + loginMessages.add( pluginMessage ); } @Override @@ -131,7 +139,7 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo stream.write( new PacketFCEncryptionResponse() ); stream = new PacketStream( new CipherInputStream( socket.getInputStream(), - EncryptionUtil.getCipher( false, shared ) ), new CipherOutputStream( socket.getOutputStream(), EncryptionUtil.getCipher( true, shared ) ), protocol ); + EncryptionUtil.getCipher( false, shared ) ), new CipherOutputStream( socket.getOutputStream(), EncryptionUtil.getCipher( true, shared ) ), stream.getProtocol() ); thisState = State.LOGIN; } @@ -141,7 +149,7 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo { Preconditions.checkState( thisState == State.LOGIN, "Not expecting LOGIN" ); - UserConnection userCon = new UserConnection( socket, this, stream, handshake ); + UserConnection userCon = new UserConnection( socket, this, stream, handshake,forgeLogin,loginMessages ); String server = ProxyServer.getInstance().getReconnectHandler().getServer( userCon ); ServerInfo s = BungeeCord.getInstance().config.getServers().get( server ); userCon.connect( s, true ); diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java index 9282ae8a..da3cd2d5 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -47,9 +47,19 @@ public class ServerConnection extends GenericConnection implements Server socket.connect( info.getAddress(), BungeeCord.getInstance().config.getTimeout() ); BungeeCord.getInstance().setSocketOptions( socket ); - PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), PacketDefinitions.VANILLA_PROTOCOL ); + PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), user.stream.getProtocol() ); + + if ( user.forgeLogin != null ) + { + stream.write( user.forgeLogin ); + } stream.write( handshake ); + for ( PacketFAPluginMessage message : user.loginMessages ) + { + stream.write( message ); + } + stream.write( PacketCDClientStatus.CLIENT_LOGIN ); stream.readPacket(); 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 e67937a0..36575972 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -11,6 +11,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; @@ -30,6 +31,8 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer { public final Packet2Handshake handshake; + final Packet1Login forgeLogin; + final List loginMessages; public Queue packetQueue = new ConcurrentLinkedQueue<>(); @Getter private final PendingConnection pendingConnection; @@ -54,11 +57,13 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer private ServerInfo nextServer; private volatile boolean clientConnected = true; - public UserConnection(Socket socket, PendingConnection pendingConnection, PacketStream stream, Packet2Handshake handshake) + public UserConnection(Socket socket, PendingConnection pendingConnection, PacketStream stream, Packet2Handshake handshake, Packet1Login forgeLogin, List loginMessages) { super( socket, stream ); this.handshake = handshake; this.pendingConnection = pendingConnection; + this.forgeLogin = forgeLogin; + this.loginMessages = loginMessages; name = handshake.username; displayName = handshake.username; diff --git a/proxy/src/main/java/net/md_5/bungee/packet/PacketStream.java b/proxy/src/main/java/net/md_5/bungee/packet/PacketStream.java index 76b6fadf..01413568 100644 --- a/proxy/src/main/java/net/md_5/bungee/packet/PacketStream.java +++ b/proxy/src/main/java/net/md_5/bungee/packet/PacketStream.java @@ -20,6 +20,7 @@ public class PacketStream implements AutoCloseable private final DataInputStream dataInput; @Getter private OutputStream out; + @Getter @Setter private int protocol; private final TrackingInputStream tracker;