Basically done with login

This commit is contained in:
md_5 2013-10-11 21:36:28 +11:00
parent 7121c20338
commit dbdae87ec6
14 changed files with 257 additions and 64 deletions

View File

@ -13,7 +13,7 @@ public class ServerPing
/**
* Numeric protocol version supported by the server.
*/
private final byte protocolVersion;
private final int protocolVersion;
/**
* Human readable game version.
*/

View File

@ -19,10 +19,25 @@ import net.md_5.bungee.protocol.packet.Handshake;
import net.md_5.bungee.protocol.packet.EncryptionResponse;
import net.md_5.bungee.protocol.packet.LoginRequest;
import net.md_5.bungee.protocol.packet.LoginSuccess;
import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.StatusRequest;
import net.md_5.bungee.protocol.packet.StatusResponse;
public abstract class AbstractPacketHandler
{
public void handle(PingPacket ping) throws Exception
{
}
public void handle(StatusRequest statusRequest) throws Exception
{
}
public void handle(StatusResponse statusResponse) throws Exception
{
}
public void handle(Handshake handshake) throws Exception
{
}

View File

@ -23,6 +23,8 @@ 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 );
}
@Override

View File

@ -1,5 +1,6 @@
package net.md_5.bungee.protocol;
import com.google.common.base.Preconditions;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import java.lang.reflect.Constructor;
@ -13,12 +14,15 @@ import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.Login;
import net.md_5.bungee.protocol.packet.LoginRequest;
import net.md_5.bungee.protocol.packet.LoginSuccess;
import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.Respawn;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.ScoreboardScore;
import net.md_5.bungee.protocol.packet.StatusRequest;
import net.md_5.bungee.protocol.packet.StatusResponse;
import net.md_5.bungee.protocol.packet.TabComplete;
import net.md_5.bungee.protocol.packet.Team;
@ -63,6 +67,11 @@ public enum Protocol
{
{
TO_CLIENT.registerPacket( 0x00, StatusResponse.class );
TO_CLIENT.registerPacket( 0x01, PingPacket.class );
TO_SERVER.registerPacket( 0x00, StatusRequest.class );
TO_SERVER.registerPacket( 0x01, PingPacket.class );
}
},
//2
@ -140,6 +149,8 @@ public enum Protocol
final int getId(Class<? extends DefinedPacket> packet)
{
Preconditions.checkArgument( packetMap.containsKey( packet ), "Cannot get ID for packet " + packet );
return packetMap.get( packet );
}
}

View File

@ -17,7 +17,7 @@ public class Varint21LengthFieldPrepender extends MessageToByteEncoder<ByteBuf>
out.ensureWritable( headerLen + bodyLen );
DefinedPacket.writeVarInt( bodyLen, out );
out.writeBytes( msg, msg.readerIndex(), bodyLen );
out.writeBytes( msg );
}
private static int varintSize(int paramInt)

View File

@ -0,0 +1,37 @@
package net.md_5.bungee.protocol.packet;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class PingPacket extends DefinedPacket
{
private long time;
@Override
public void read(ByteBuf buf)
{
time = buf.readLong();
}
@Override
public void write(ByteBuf buf)
{
buf.writeLong( time );
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
}

View File

@ -0,0 +1,31 @@
package net.md_5.bungee.protocol.packet;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class StatusRequest extends DefinedPacket
{
@Override
public void read(ByteBuf buf)
{
}
@Override
public void write(ByteBuf buf)
{
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
}

View File

@ -0,0 +1,37 @@
package net.md_5.bungee.protocol.packet;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class StatusResponse extends DefinedPacket
{
private String response;
@Override
public void read(ByteBuf buf)
{
response = readString( buf );
}
@Override
public void write(ByteBuf buf)
{
writeString( response, buf );
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
}

View File

@ -0,0 +1,40 @@
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.command.ConsoleCommandSender;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author michael
*/
public class Test
{
public static void main(String[] args) throws Exception
{
System.setProperty( "java.net.preferIPv4Stack", "true" );
BungeeCord bungee = new BungeeCord();
ProxyServer.setInstance( bungee );
bungee.getLogger().info( "Enabled BungeeCord version " + bungee.getVersion() );
bungee.start();
while ( bungee.isRunning )
{
String line = bungee.getConsoleReader().readLine( ">" );
if ( line != null )
{
if ( !bungee.getPluginManager().dispatchCommand( ConsoleCommandSender.getInstance(), line ) )
{
bungee.getConsole().sendMessage( ChatColor.RED + "Command not found" );
}
}
}
}
}

View File

@ -3,10 +3,11 @@ package net.md_5.bungee.connection;
import com.google.common.base.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.netty.util.concurrent.ScheduledFuture;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.net.URLEncoder;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
@ -16,7 +17,6 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.EncryptionUtil;
import net.md_5.bungee.PacketConstants;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.Util;
import net.md_5.bungee.api.Callback;
@ -37,7 +37,6 @@ import net.md_5.bungee.netty.CipherDecoder;
import net.md_5.bungee.netty.CipherEncoder;
import net.md_5.bungee.netty.PacketHandler;
import net.md_5.bungee.netty.PipelineUtils;
import net.md_5.bungee.protocol.MinecraftInput;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.packet.Login;
import net.md_5.bungee.protocol.packet.Handshake;
@ -48,8 +47,12 @@ import net.md_5.bungee.protocol.packet.EncryptionRequest;
import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.api.AbstractReconnectHandler;
import net.md_5.bungee.api.event.PlayerHandshakeEvent;
import net.md_5.bungee.protocol.PacketWrapper;
import net.md_5.bungee.protocol.Protocol;
import net.md_5.bungee.protocol.packet.LoginRequest;
import net.md_5.bungee.protocol.packet.LoginSuccess;
import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.StatusRequest;
@RequiredArgsConstructor
public class InitialHandler extends PacketHandler implements PendingConnection
@ -82,7 +85,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection
};
@Getter
private boolean onlineMode = BungeeCord.getInstance().config.isOnlineMode();
private ScheduledFuture<?> pingFuture;
private InetSocketAddress vHost;
private byte version = -1;
@Getter
@ -91,7 +93,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
private enum State
{
HANDSHAKE, ENCRYPT, LOGIN, FINISHED;
HANDSHAKE, STATUS, PING, USERNAME, ENCRYPT, LOGIN, FINISHED;
}
@Override
@ -100,6 +102,14 @@ public class InitialHandler extends PacketHandler implements PendingConnection
this.ch = channel;
}
@Override
public void handle(PacketWrapper packet) throws Exception
{
int len = DefinedPacket.readVarInt( packet.buf );
int id = DefinedPacket.readVarInt( packet.buf );
throw new UnsupportedOperationException( "Cannot handle unknown packet at login!" );
}
@Override
public void exception(Throwable t) throws Exception
{
@ -109,22 +119,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public void handle(PluginMessage pluginMessage) throws Exception
{
if ( pluginMessage.getTag().equals( "MC|PingHost" ) )
{
if ( pingFuture.cancel( false ) )
{
MinecraftInput in = pluginMessage.getMCStream();
version = in.readByte();
String connectHost = in.readString();
int connectPort = in.readInt();
this.vHost = new InetSocketAddress( connectHost, connectPort );
respondToPing();
}
return;
}
// TODO: Unregister?
if ( pluginMessage.getTag().equals( "REGISTER" ) )
{
@ -135,7 +129,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
}
private void respondToPing()
@Override
public void handle(StatusRequest statusRequest) throws Exception
{
ServerInfo forced = AbstractReconnectHandler.getForcedHost( this );
final String motd = ( forced != null ) ? forced.getMotd() : listener.getMotd();
@ -167,22 +162,17 @@ public class InitialHandler extends PacketHandler implements PendingConnection
forced.ping( pingBack );
} else
{
// pingBack.done( new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(), motd, bungee.getOnlineCount(), listener.getMaxPlayers() ), null );
pingBack.done( new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(), motd, bungee.getOnlineCount(), listener.getMaxPlayers() ), null );
}
}
/*
@Override
public void handle(PacketFEPing ping) throws Exception
public void handle(PingPacket ping) throws Exception
{
pingFuture = ch.getHandle().eventLoop().schedule( new Runnable()
{
@Override
public void run()
{
respondToPing();
Preconditions.checkState( thisState == State.PING, "Not expecting PING" );
unsafe.sendPacket( ping );
disconnect( "" );
}
}, 200, TimeUnit.MILLISECONDS );
}*/
@Override
public void handle(Handshake handshake) throws Exception
@ -206,9 +196,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
case 1:
// Ping
thisState = State.STATUS;
ch.setProtocol( Protocol.STATUS );
break;
case 2:
thisState = State.USERNAME;
ch.setProtocol( Protocol.LOGIN );
// Login
break;
@ -220,6 +212,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public void handle(LoginRequest loginRequest) throws Exception
{
Preconditions.checkState( thisState == State.USERNAME, "Not expecting USERNAME" );
this.loginRequest = loginRequest;
if ( getName().length() > 16 )
@ -242,8 +235,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection
return;
}
unsafe().sendPacket( PacketConstants.I_AM_BUNGEE );
unsafe().sendPacket( PacketConstants.FORGE_MOD_REQUEST );
// TODO: Nuuuu Mojang why u do this
// unsafe().sendPacket( PacketConstants.I_AM_BUNGEE );
// unsafe().sendPacket( PacketConstants.FORGE_MOD_REQUEST );
unsafe().sendPacket( request = EncryptionUtil.encryptRequest( this.onlineMode ) );
thisState = State.ENCRYPT;
@ -261,9 +255,18 @@ public class InitialHandler extends PacketHandler implements PendingConnection
if ( this.onlineMode )
{
String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
String encID = URLEncoder.encode( InitialHandler.this.request.getServerId(), "UTF-8" );
String authURL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + encName + "&serverId=" + encID;
MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
for ( byte[] bit : new byte[][]
{
request.getServerId().getBytes( "ISO_8859_1" ), sharedKey.getEncoded(), EncryptionUtil.keys.getPublic().getEncoded()
} )
{
sha.update( bit );
}
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
String authURL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + encName + "&serverId=" + encodedHash;
Callback<String> handler = new Callback<String>()
{
@ -272,17 +275,13 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
if ( error == null )
{
JsonObject obj = BungeeCord.getInstance().gson.fromJson( result, JsonObject.class );
LoginResult obj = BungeeCord.getInstance().gson.fromJson( result, LoginResult.class );
if ( obj != null )
{
JsonElement id = obj.get( "id" );
if ( id != null )
{
UUID = id.getAsString();
UUID = obj.getId();
finish();
return;
}
}
disconnect( "Not authenticated with Minecraft.net" );
} else
{
@ -329,6 +328,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection
public void run()
{
if ( ch.getHandle().isActive() )
{
if ( onlineMode )
{
unsafe().sendPacket( new EncryptionResponse( new byte[ 0 ], new byte[ 0 ] ) );
try
@ -340,6 +342,14 @@ public class InitialHandler extends PacketHandler implements PendingConnection
disconnect( "Cipher error: " + Util.exception( ex ) );
}
}
if ( UUID == null )
{
UUID = java.util.UUID.randomUUID().toString();
}
unsafe.sendPacket( new LoginSuccess( BungeeCord.getInstance().gson.toJson( new LoginResult( UUID ) ) ) );
ch.setProtocol( Protocol.GAME );
}
}
} );
}
@ -380,7 +390,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
if ( !ch.isClosed() )
{
unsafe().sendPacket( new Kick( reason ) );
unsafe().sendPacket( new Kick( BungeeCord.getInstance().gson.toJson( reason ) ) );
ch.close();
}
}

View File

@ -0,0 +1,12 @@
package net.md_5.bungee.connection;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class LoginResult
{
private String id;
}

View File

@ -33,10 +33,10 @@ public class ChannelWrapper
if ( packet instanceof PacketWrapper )
{
( (PacketWrapper) packet ).setReleased( true );
ch.write( ( (PacketWrapper) packet ).buf );
ch.write( ( (PacketWrapper) packet ).buf, ch.voidPromise() );
} else
{
ch.write( packet );
ch.write( packet, ch.voidPromise() );
}
ch.flush();
}

View File

@ -12,8 +12,6 @@ import net.md_5.bungee.connection.CancelSendSignal;
import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.connection.PingHandler;
import net.md_5.bungee.protocol.BadPacketException;
import net.md_5.bungee.protocol.MinecraftCodec;
import net.md_5.bungee.protocol.Protocol;
/**
* This class is a primitive wrapper for {@link PacketHandler} instances tied to

View File

@ -76,10 +76,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() );
}
};