Rewrite login process in preparation for both forge and netty.
This commit is contained in:
parent
51e2570ddd
commit
05a6b566b2
@ -6,20 +6,13 @@ import java.util.Queue;
|
|||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.md_5.bungee.api.Callback;
|
import net.md_5.bungee.api.Callback;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.ServerPing;
|
import net.md_5.bungee.api.ServerPing;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.connection.Server;
|
import net.md_5.bungee.api.connection.Server;
|
||||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
|
||||||
import net.md_5.bungee.packet.DefinedPacket;
|
import net.md_5.bungee.packet.DefinedPacket;
|
||||||
import net.md_5.bungee.packet.Packet1Login;
|
import net.md_5.bungee.packet.Packet1Login;
|
||||||
import net.md_5.bungee.packet.Packet2Handshake;
|
|
||||||
import net.md_5.bungee.packet.PacketCDClientStatus;
|
|
||||||
import net.md_5.bungee.packet.PacketFAPluginMessage;
|
import net.md_5.bungee.packet.PacketFAPluginMessage;
|
||||||
import net.md_5.bungee.packet.PacketFFKick;
|
|
||||||
import net.md_5.bungee.packet.PacketStream;
|
import net.md_5.bungee.packet.PacketStream;
|
||||||
import net.md_5.mendax.PacketDefinitions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing a connection from the proxy to the server; ie upstream.
|
* Class representing a connection from the proxy to the server; ie upstream.
|
||||||
@ -39,84 +32,6 @@ public class ServerConnection extends GenericConnection implements Server
|
|||||||
this.loginPacket = loginPacket;
|
this.loginPacket = loginPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ServerConnection connect(UserConnection user, ServerInfo info, Packet2Handshake handshake, boolean retry)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Socket socket = new Socket();
|
|
||||||
socket.connect( info.getAddress(), BungeeCord.getInstance().config.getTimeout() );
|
|
||||||
BungeeCord.getInstance().setSocketOptions( socket );
|
|
||||||
|
|
||||||
PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), user.stream.getProtocol() );
|
|
||||||
|
|
||||||
if ( user.forgeLogin != null )
|
|
||||||
{
|
|
||||||
stream.write( user.forgeLogin );
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.write( handshake );
|
|
||||||
stream.write( PacketCDClientStatus.CLIENT_LOGIN );
|
|
||||||
stream.readPacket();
|
|
||||||
|
|
||||||
byte[] loginResponse = null;
|
|
||||||
boolean forgeIHateYou = false;
|
|
||||||
loop:
|
|
||||||
while ( true )
|
|
||||||
{
|
|
||||||
loginResponse = stream.readPacket();
|
|
||||||
int id = Util.getId( loginResponse );
|
|
||||||
switch ( id )
|
|
||||||
{
|
|
||||||
case 0x01:
|
|
||||||
break loop;
|
|
||||||
case 0xFA:
|
|
||||||
if ( !forgeIHateYou )
|
|
||||||
{
|
|
||||||
for ( PacketFAPluginMessage message : user.loginMessages )
|
|
||||||
{
|
|
||||||
stream.write( message );
|
|
||||||
}
|
|
||||||
forgeIHateYou = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0xFF:
|
|
||||||
throw new KickException( "[Kicked] " + new PacketFFKick( loginResponse ).message );
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException( "Unknown login packet " + Util.hex( id ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Packet1Login login = new Packet1Login( loginResponse );
|
|
||||||
|
|
||||||
ServerConnection server = new ServerConnection( socket, info, stream, login );
|
|
||||||
ServerConnectedEvent event = new ServerConnectedEvent( user, server );
|
|
||||||
ProxyServer.getInstance().getPluginManager().callEvent( event );
|
|
||||||
|
|
||||||
stream.write( BungeeCord.getInstance().registerChannels() );
|
|
||||||
|
|
||||||
Queue<DefinedPacket> packetQueue = ( (BungeeServerInfo) info ).getPacketQueue();
|
|
||||||
while ( !packetQueue.isEmpty() )
|
|
||||||
{
|
|
||||||
stream.write( packetQueue.poll() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return server;
|
|
||||||
} catch ( KickException ex )
|
|
||||||
{
|
|
||||||
throw ex;
|
|
||||||
} catch ( Exception ex )
|
|
||||||
{
|
|
||||||
ServerInfo def = ProxyServer.getInstance().getServers().get( user.getPendingConnection().getListener().getDefaultServer() );
|
|
||||||
if ( retry && !info.equals( def ) )
|
|
||||||
{
|
|
||||||
user.sendMessage( ChatColor.RED + "Could not connect to target server, you have been moved to the default server" );
|
|
||||||
return connect( user, def, handshake, false );
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
throw new RuntimeException( "Could not connect to target server " + Util.exception( ex ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendData(String channel, byte[] data)
|
public void sendData(String channel, byte[] data)
|
||||||
{
|
{
|
||||||
|
93
proxy/src/main/java/net/md_5/bungee/ServerConnector.java
Normal file
93
proxy/src/main/java/net/md_5/bungee/ServerConnector.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package net.md_5.bungee;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.packet.DefinedPacket;
|
||||||
|
import net.md_5.bungee.packet.Packet1Login;
|
||||||
|
import net.md_5.bungee.packet.PacketCDClientStatus;
|
||||||
|
import net.md_5.bungee.packet.PacketFDEncryptionRequest;
|
||||||
|
import net.md_5.bungee.packet.PacketHandler;
|
||||||
|
import net.md_5.bungee.packet.PacketStream;
|
||||||
|
|
||||||
|
public class ServerConnector extends PacketHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
private final PacketStream stream;
|
||||||
|
private Packet1Login loginPacket;
|
||||||
|
private State thisState = State.ENCRYPT_REQUEST;
|
||||||
|
|
||||||
|
public ServerConnector(PacketStream stream)
|
||||||
|
{
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum State
|
||||||
|
{
|
||||||
|
|
||||||
|
ENCRYPT_REQUEST, LOGIN, FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Packet1Login login) throws Exception
|
||||||
|
{
|
||||||
|
Preconditions.checkState( thisState == State.LOGIN, "Not exepcting LOGIN" );
|
||||||
|
loginPacket = login;
|
||||||
|
thisState = State.FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(PacketFDEncryptionRequest encryptRequest) throws Exception
|
||||||
|
{
|
||||||
|
Preconditions.checkState( thisState == State.ENCRYPT_REQUEST, "Not expecting ENCRYPT_REQUEST" );
|
||||||
|
thisState = State.LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServerConnection connect(UserConnection user, ServerInfo server, boolean retry)
|
||||||
|
{
|
||||||
|
Socket socket = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket = new Socket();
|
||||||
|
socket.connect( server.getAddress(), BungeeCord.getInstance().config.getTimeout() );
|
||||||
|
BungeeCord.getInstance().setSocketOptions( socket );
|
||||||
|
PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), user.stream.getProtocol() );
|
||||||
|
|
||||||
|
ServerConnector connector = new ServerConnector( stream );
|
||||||
|
stream.write( user.handshake );
|
||||||
|
stream.write( PacketCDClientStatus.CLIENT_LOGIN );
|
||||||
|
|
||||||
|
while ( connector.thisState != State.FINISHED )
|
||||||
|
{
|
||||||
|
byte[] buf = stream.readPacket();
|
||||||
|
DefinedPacket packet = DefinedPacket.packet( buf );
|
||||||
|
packet.handle( connector );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServerConnection( socket, server, stream, connector.loginPacket );
|
||||||
|
} catch ( Exception ex )
|
||||||
|
{
|
||||||
|
if ( socket != null )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.close();
|
||||||
|
} catch ( IOException ioe )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ServerInfo def = ProxyServer.getInstance().getServers().get( user.getPendingConnection().getListener().getDefaultServer() );
|
||||||
|
if ( retry && !server.equals( def ) )
|
||||||
|
{
|
||||||
|
user.sendMessage( ChatColor.RED + "Could not connect to target server, you have been moved to the default server" );
|
||||||
|
return connect( user, def, false );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
throw new RuntimeException( "Could not connect to target server " + Util.exception( ex ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -113,7 +113,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer
|
|||||||
stream.write( new Packet9Respawn( (byte) -1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" ) );
|
stream.write( new Packet9Respawn( (byte) -1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerConnection newServer = ServerConnection.connect( this, target, handshake, true );
|
ServerConnection newServer = ServerConnector.connect( this, target, true );
|
||||||
if ( server == null )
|
if ( server == null )
|
||||||
{
|
{
|
||||||
// Once again, first connection
|
// Once again, first connection
|
||||||
@ -157,8 +157,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer
|
|||||||
destroySelf( ex.getMessage() );
|
destroySelf( ex.getMessage() );
|
||||||
} catch ( Exception ex )
|
} catch ( Exception ex )
|
||||||
{
|
{
|
||||||
ex.printStackTrace(); // TODO: Remove
|
destroySelf( "Could not connect to server - " + Util.exception( ex ) );
|
||||||
destroySelf( "Could not connect to server - " + ex.getClass().getSimpleName() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.md_5.bungee.packet;
|
package net.md_5.bungee.packet;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@ -213,6 +214,8 @@ public abstract class DefinedPacket implements DataOutput
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Preconditions.checkState( ret != null, "Don't know how to deal with packet ID {0}", Util.hex( id ) );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +230,7 @@ public abstract class DefinedPacket implements DataOutput
|
|||||||
classes[0xCD] = PacketCDClientStatus.class;
|
classes[0xCD] = PacketCDClientStatus.class;
|
||||||
classes[0xFA] = PacketFAPluginMessage.class;
|
classes[0xFA] = PacketFAPluginMessage.class;
|
||||||
classes[0xFC] = PacketFCEncryptionResponse.class;
|
classes[0xFC] = PacketFCEncryptionResponse.class;
|
||||||
|
classes[0xFD] = PacketFDEncryptionRequest.class;
|
||||||
classes[0xFE] = PacketFEPing.class;
|
classes[0xFE] = PacketFEPing.class;
|
||||||
classes[0xFF] = PacketFFKick.class;
|
classes[0xFF] = PacketFFKick.class;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user