Checkpoint

This commit is contained in:
md_5 2013-10-12 11:36:53 +11:00
parent b358fd25f5
commit 1b41682e37
10 changed files with 66 additions and 96 deletions

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.protocol;
import com.google.common.base.Charsets;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
@ -23,7 +24,7 @@ public class MinecraftCodec extends MessageToMessageCodec<ByteBuf, DefinedPacket
ByteBuf buf = ctx.alloc().buffer();
DefinedPacket.writeVarInt( prot.getId( msg.getClass() ), buf );
msg.write( buf );
out.add( buf );
}
@ -31,15 +32,20 @@ public class MinecraftCodec extends MessageToMessageCodec<ByteBuf, DefinedPacket
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception
{
Protocol.ProtocolDirection prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT;
ByteBuf copy = msg.copy();
int packetId = DefinedPacket.readVarInt( msg );
ByteBuf copy = msg.copy();
DefinedPacket packet = null;
if ( prot.hasPacket( packetId ) )
{
packet = prot.createPacket( packetId );
packet.read( msg );
if ( msg.readableBytes() != 0 )
{
System.out.println( msg.toString( Charsets.UTF_8 ) );
throw new BadPacketException( "Did not read all bytes from packet " + packetId + " Protocol " + protocol + " Direction " + prot );
}
}
out.add( new PacketWrapper( packet, copy ) );

View File

@ -3,7 +3,6 @@ package net.md_5.bungee.protocol;
import io.netty.buffer.ByteBuf;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.md_5.bungee.protocol.DefinedPacket;
@RequiredArgsConstructor
public class PacketWrapper

View File

@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import java.lang.reflect.Constructor;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.protocol.packet.Chat;
import net.md_5.bungee.protocol.packet.ClientSettings;
import net.md_5.bungee.protocol.packet.EncryptionRequest;
@ -92,12 +93,14 @@ public enum Protocol
public static final int PROTOCOL_VERSION = 0x00;
public static final String MINECRAFT_VERSION = "13w41a";
/*========================================================================*/
public final ProtocolDirection TO_SERVER = new ProtocolDirection();
public final ProtocolDirection TO_CLIENT = new ProtocolDirection();
public final ProtocolDirection TO_SERVER = new ProtocolDirection( "TO_SERVER" );
public final ProtocolDirection TO_CLIENT = new ProtocolDirection( "TO_CLIENT" );
@RequiredArgsConstructor
public class ProtocolDirection
{
private final String name;
private final TObjectIntMap<Class<? extends DefinedPacket>> packetMap = new TObjectIntHashMap<>( MAX_PACKET_ID );
private final Class<? extends DefinedPacket>[] packetClasses = new Class[ MAX_PACKET_ID ];
private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ MAX_PACKET_ID ];
@ -107,6 +110,12 @@ public enum Protocol
return id < MAX_PACKET_ID && packetConstructors[id] != null;
}
@Override
public String toString()
{
return name;
}
public final DefinedPacket createPacket(int id)
{
if ( id > MAX_PACKET_ID )

View File

@ -15,18 +15,21 @@ import net.md_5.bungee.protocol.AbstractPacketHandler;
public class LoginSuccess extends DefinedPacket
{
private String data;
private String uuid;
private String username;
@Override
public void read(ByteBuf buf)
{
data = readString( buf );
uuid = readString( buf );
username = readString( buf );
}
@Override
public void write(ByteBuf buf)
{
writeString( data, buf );
writeString( uuid, buf );
writeString( username, buf );
}
@Override

View File

@ -3,11 +3,8 @@ package net.md_5.bungee;
import com.google.common.base.Preconditions;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.io.DataInput;
import java.util.Objects;
import java.util.Queue;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer;
@ -22,17 +19,17 @@ import net.md_5.bungee.connection.CancelSendSignal;
import net.md_5.bungee.connection.DownstreamBridge;
import net.md_5.bungee.netty.HandlerBoss;
import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.netty.CipherDecoder;
import net.md_5.bungee.netty.PacketHandler;
import net.md_5.bungee.netty.PipelineUtils;
import net.md_5.bungee.protocol.MinecraftOutput;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.packet.Login;
import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.EncryptionResponse;
import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.LoginSuccess;
@RequiredArgsConstructor
public class ServerConnector extends PacketHandler
@ -42,14 +39,12 @@ public class ServerConnector extends PacketHandler
private ChannelWrapper ch;
private final UserConnection user;
private final BungeeServerInfo target;
private State thisState = State.ENCRYPT_REQUEST;
private SecretKey secretkey;
private boolean sentMessages;
private State thisState = State.LOGIN_SUCCESS;
private enum State
{
ENCRYPT_REQUEST, ENCRYPT_RESPONSE, LOGIN, FINISHED;
LOGIN_SUCCESS, ENCRYPT_RESPONSE, LOGIN, FINISHED;
}
@Override
@ -74,15 +69,12 @@ public class ServerConnector extends PacketHandler
out.writeUTF( "Login" );
out.writeUTF( user.getAddress().getHostString() );
out.writeInt( user.getAddress().getPort() );
channel.write( new PluginMessage( "BungeeCord", out.toByteArray() ) );
// channel.write( new PluginMessage( "BungeeCord", out.toByteArray() ) ); MOJANG
// channel.write( user.getPendingConnection().getHandshake() ); FIX
channel.write( user.getPendingConnection().getHandshake() );
// Skip encryption if we are not using Forge
if ( user.getPendingConnection().getForgeLogin() == null )
{
channel.write( PacketConstants.CLIENT_LOGIN );
}
channel.setProtocol( Protocol.LOGIN );
channel.write( user.getPendingConnection().getLoginRequest() );
}
@Override
@ -91,6 +83,24 @@ public class ServerConnector extends PacketHandler
user.getPendingConnects().remove( target );
}
@Override
public void handle(PacketWrapper packet) throws Exception
{
int packetID = DefinedPacket.readVarInt( packet.buf );
System.out.println( packetID + " : " + packet.packet );
super.handle( packet ); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void handle(LoginSuccess loginSuccess) throws Exception
{
Preconditions.checkState( thisState == State.LOGIN_SUCCESS, "Not exepcting LOGIN_SUCCESS" );
ch.setProtocol( Protocol.GAME );
thisState = State.LOGIN;
throw new CancelSendSignal();
}
@Override
public void handle(Login login) throws Exception
{
@ -114,13 +124,6 @@ public class ServerConnector extends PacketHandler
{
ch.write( message );
}
if ( !sentMessages )
{
for ( PluginMessage message : user.getPendingConnection().getLoginMessages() )
{
ch.write( message );
}
}
if ( user.getSettings() != null )
{
@ -194,20 +197,6 @@ public class ServerConnector extends PacketHandler
throw new CancelSendSignal();
}
@Override
public void handle(EncryptionResponse encryptResponse) throws Exception
{
Preconditions.checkState( thisState == State.ENCRYPT_RESPONSE, "Not expecting ENCRYPT_RESPONSE" );
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, secretkey );
ch.addBefore( PipelineUtils.FRAME_DECODER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) );
ch.write( user.getPendingConnection().getForgeLogin() );
ch.write( PacketConstants.CLIENT_LOGIN );
thisState = State.LOGIN;
}
@Override
public void handle(Kick kick) throws Exception
{
@ -233,39 +222,6 @@ public class ServerConnector extends PacketHandler
}
}
@Override
public void handle(PluginMessage pluginMessage) throws Exception
{
if ( pluginMessage.equals( PacketConstants.I_AM_BUNGEE ) )
{
throw new IllegalStateException( "May not connect to another BungeCord!" );
}
DataInput in = pluginMessage.getStream();
if ( pluginMessage.getTag().equals( "FML" ) && in.readUnsignedByte() == 0 )
{
int count = in.readInt();
for ( int i = 0; i < count; i++ )
{
in.readUTF();
}
if ( in.readByte() != 0 )
{
// TODO: Using forge flag
}
}
user.unsafe().sendPacket( pluginMessage ); // We have to forward these to the user, especially with Forge as stuff might break
if ( !sentMessages && user.getPendingConnection().getForgeLogin() != null )
{
for ( PluginMessage message : user.getPendingConnection().getLoginMessages() )
{
ch.write( message );
}
sentMessages = true;
}
}
@Override
public String toString()
{

View File

@ -32,7 +32,11 @@ import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.netty.HandlerBoss;
import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.netty.PipelineUtils;
import static net.md_5.bungee.netty.PipelineUtils.FRAME_DECODER;
import static net.md_5.bungee.netty.PipelineUtils.PACKET_CODEC;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.MinecraftCodec;
import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.packet.Chat;
import net.md_5.bungee.protocol.packet.ClientSettings;
import net.md_5.bungee.protocol.packet.PluginMessage;
@ -200,6 +204,7 @@ public final class UserConnection implements ProxiedPlayer
protected void initChannel(Channel ch) throws Exception
{
PipelineUtils.BASE.initChannel( ch );
ch.pipeline().addAfter( FRAME_DECODER, PACKET_CODEC, new MinecraftCodec( Protocol.HANDSHAKE, false ) );
ch.pipeline().get( HandlerBoss.class ).setHandler( new ServerConnector( bungee, UserConnection.this, target ) );
}
};

View File

@ -74,7 +74,7 @@ public class DownstreamBridge extends PacketHandler
{
if ( !server.isObsolete() )
{
EntityMap.rewrite( packet.buf, con.getServerEntityId(), con.getClientEntityId() );
// EntityMap.rewrite( packet.buf, con.getServerEntityId(), con.getClientEntityId() );
con.sendPacket( packet );
}
}

View File

@ -104,7 +104,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
int len = DefinedPacket.readVarInt( packet.buf );
int id = DefinedPacket.readVarInt( packet.buf );
throw new UnsupportedOperationException( "Cannot handle unknown packet at login!" );
// throw new UnsupportedOperationException( "Cannot handle unknown packet at login!" );
}
@Override
@ -343,7 +343,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
UUID = java.util.UUID.randomUUID().toString();
}
unsafe.sendPacket( new LoginSuccess( BungeeCord.getInstance().gson.toJson( new LoginResult( UUID ) ) ) );
System.out.println( ch.getHandle().pipeline() );
unsafe.sendPacket( new LoginSuccess( UUID, getName() ) );
ch.setProtocol( Protocol.GAME );
UserConnection userCon = new UserConnection( bungee, ch, getName(), InitialHandler.this );
@ -361,7 +362,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
server = AbstractReconnectHandler.getForcedHost( InitialHandler.this );
}
userCon.connect( server, true );
// userCon.connect( server, true );
thisState = State.FINISHED;
}

View File

@ -59,7 +59,7 @@ public class UpstreamBridge extends PacketHandler
@Override
public void handle(PacketWrapper packet) throws Exception
{
EntityMap.rewrite( packet.buf, con.getClientEntityId(), con.getServerEntityId() );
// EntityMap.rewrite( packet.buf, con.getClientEntityId(), con.getServerEntityId() );
if ( con.getServer() != null )
{
con.getServer().getCh().write( packet );

View File

@ -10,7 +10,6 @@ import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.BungeeServerInfo;
import net.md_5.bungee.ServerConnector;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.api.ProxyServer;
@ -40,19 +39,10 @@ public class PipelineUtils
BASE.initChannel( ch );
ch.pipeline().addAfter( FRAME_DECODER, PACKET_CODEC, new MinecraftCodec( Protocol.HANDSHAKE, true ) );
System.out.println( ch.pipeline() );
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( ProxyServer.getInstance(), ch.attr( LISTENER ).get() ) );
}
};
public static final ChannelInitializer<Channel> CLIENT = new ChannelInitializer<Channel>()
{
@Override
protected void initChannel(Channel ch) throws Exception
{
BASE.initChannel( ch );
ch.pipeline().addAfter( FRAME_DECODER, PACKET_CODEC, new MinecraftCodec( Protocol.LOGIN, false) );
ch.pipeline().get( HandlerBoss.class ).setHandler( new ServerConnector( ProxyServer.getInstance(), ch.attr( USER ).get(), ch.attr( TARGET ).get() ) );
}
};
public static final Base BASE = new Base();
private static final Varint21LengthFieldPrepender framePrepender = new Varint21LengthFieldPrepender();
public static String TIMEOUT_HANDLER = "timeout";
@ -76,9 +66,10 @@ public class PipelineUtils
{
// IP_TOS is not supported (Windows XP / Windows Server 2003)
}
ch.pipeline().addLast( FRAME_PREPENDER, framePrepender );
ch.pipeline().addLast( TIMEOUT_HANDLER, new ReadTimeoutHandler( BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS ) );
ch.pipeline().addLast( FRAME_DECODER, new Varint21FrameDecoder() );
ch.pipeline().addLast( FRAME_PREPENDER, framePrepender );
ch.pipeline().addLast( BOSS_HANDLER, new HandlerBoss() );
}