Add groundwork for custom protocols such as forge in a really cool manner - has not been tested, so may be a regression on prior build.

This commit is contained in:
md_5 2013-02-10 21:26:49 +11:00
parent 9f4fc4dfac
commit 9c5e02e20a
6 changed files with 44 additions and 53 deletions

View File

@ -5,7 +5,10 @@ import static net.md_5.mendax.PacketDefinitions.OpCode.*;
public class PacketDefinitions public class PacketDefinitions
{ {
public static final OpCode[][] opCodes = new OpCode[ 256 ][]; private static final int MAX_PACKET = 256;
public static final OpCode[][] opCodes = new OpCode[ MAX_PACKET ][];
public static final int VANILLA_PROTOCOL = 0;
public static final int FORGE_PROTOCOL = MAX_PACKET;
public enum OpCode public enum OpCode
{ {
@ -119,7 +122,6 @@ public class PacketDefinitions
{ {
INT, INT, INT, INT, SHORT INT, INT, INT, INT, SHORT
}; };
opCodes[0x1B] = null; // Does not exist
opCodes[0x1C] = new OpCode[] opCodes[0x1C] = new OpCode[]
{ {
INT, SHORT, SHORT, SHORT INT, SHORT, SHORT, SHORT
@ -152,8 +154,6 @@ public class PacketDefinitions
{ {
INT, BYTE INT, BYTE
}; };
opCodes[0x24] = null; // Does not exist
opCodes[0x25] = null; // Does not exist
opCodes[0x26] = new OpCode[] opCodes[0x26] = new OpCode[]
{ {
INT, BYTE INT, BYTE
@ -178,11 +178,6 @@ public class PacketDefinitions
{ {
FLOAT, SHORT, SHORT FLOAT, SHORT, SHORT
}; };
//
//
// 0x2C -> 0x32 Do not exist
//
//
opCodes[0x33] = new OpCode[] opCodes[0x33] = new OpCode[]
{ {
INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE
@ -207,9 +202,6 @@ public class PacketDefinitions
{ {
BULK_CHUNK BULK_CHUNK
}; };
opCodes[0x39] = null; // Does not exist
opCodes[0x3A] = null; // Does not exist
opCodes[0x3B] = null; // Does not exist
opCodes[0x3C] = new OpCode[] opCodes[0x3C] = new OpCode[]
{ {
DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT
@ -222,11 +214,6 @@ public class PacketDefinitions
{ {
STRING, INT, INT, INT, FLOAT, BYTE STRING, INT, INT, INT, FLOAT, BYTE
}; };
//
//
// 0x3F -> 0x45 Do not exist
//
//
opCodes[0x46] = new OpCode[] opCodes[0x46] = new OpCode[]
{ {
BYTE, BYTE BYTE, BYTE
@ -235,11 +222,6 @@ public class PacketDefinitions
{ {
INT, BYTE, INT, INT, INT INT, BYTE, INT, INT, INT
}; };
//
//
// 0x4A -> 0x63 Do not exist
//
//
opCodes[0x64] = new OpCode[] opCodes[0x64] = new OpCode[]
{ {
BYTE, BYTE, STRING, BYTE BYTE, BYTE, STRING, BYTE
@ -276,11 +258,6 @@ public class PacketDefinitions
{ {
BYTE, BYTE BYTE, BYTE
}; };
//
//
// 0x6D -> 0x81 Do not exist
//
//
opCodes[0x82] = new OpCode[] opCodes[0x82] = new OpCode[]
{ {
INT, SHORT, INT, STRING, STRING, STRING, STRING INT, SHORT, INT, STRING, STRING, STRING, STRING
@ -293,11 +270,6 @@ public class PacketDefinitions
{ {
INT, SHORT, INT, BYTE, SHORT_BYTE INT, SHORT, INT, BYTE, SHORT_BYTE
}; };
//
//
// 0x85 -> 0xC7 Do not exist
//
//
opCodes[0xC8] = new OpCode[] opCodes[0xC8] = new OpCode[]
{ {
INT, BYTE INT, BYTE
@ -322,16 +294,10 @@ public class PacketDefinitions
{ {
BYTE BYTE
}; };
//
//
// 0xCE -> 0xF9 Do not exist
//
//
opCodes[0xFA] = new OpCode[] opCodes[0xFA] = new OpCode[]
{ {
STRING, SHORT_BYTE STRING, SHORT_BYTE
}; };
opCodes[0xFB] = null; // Does not exist
opCodes[0xFC] = new OpCode[] opCodes[0xFC] = new OpCode[]
{ {
SHORT_BYTE, SHORT_BYTE SHORT_BYTE, SHORT_BYTE
@ -347,5 +313,10 @@ public class PacketDefinitions
{ {
STRING STRING
}; };
/*========================== Minecraft Forge ===========================*/
opCodes[0x01 + FORGE_PROTOCOL] = new OpCode[]
{
INT, STRING, BYTE, INT, BYTE, BYTE, BYTE
};
} }
} }

View File

@ -16,7 +16,7 @@ public class DataInputPacketReader
{ {
for ( int i = 0; i < instructions.length; i++ ) for ( int i = 0; i < instructions.length; i++ )
{ {
List<Instruction> output = new ArrayList<Instruction>(); List<Instruction> output = new ArrayList<>();
OpCode[] enums = PacketDefinitions.opCodes[i]; OpCode[] enums = PacketDefinitions.opCodes[i];
if ( enums != null ) if ( enums != null )
@ -26,13 +26,13 @@ public class DataInputPacketReader
try try
{ {
output.add( (Instruction) Instruction.class.getDeclaredField( struct.name() ).get( null ) ); output.add( (Instruction) Instruction.class.getDeclaredField( struct.name() ).get( null ) );
} catch ( Exception ex ) } catch ( NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex )
{ {
throw new UnsupportedOperationException( "No definition for " + struct.name() ); throw new UnsupportedOperationException( "No definition for " + struct.name() );
} }
} }
List<Instruction> crushed = new ArrayList<Instruction>(); List<Instruction> crushed = new ArrayList<>();
int nextJumpSize = 0; int nextJumpSize = 0;
for ( Instruction child : output ) for ( Instruction child : output )
{ {
@ -59,14 +59,20 @@ public class DataInputPacketReader
} }
} }
public static void readPacket(DataInput in, byte[] buffer) throws IOException private static void readPacket(int packetId, DataInput in, byte[] buffer, int protocol) throws IOException
{ {
int packetId = in.readUnsignedByte(); Instruction[] packetDef = instructions[packetId + protocol];
Instruction[] packetDef = instructions[packetId];
if ( packetDef == null ) if ( packetDef == null )
{
if ( protocol == PacketDefinitions.VANILLA_PROTOCOL )
{ {
throw new IOException( "Unknown packet id " + packetId ); throw new IOException( "Unknown packet id " + packetId );
} else
{
readPacket( packetId, in, buffer, PacketDefinitions.VANILLA_PROTOCOL );
return;
}
} }
for ( Instruction instruction : packetDef ) for ( Instruction instruction : packetDef )
@ -74,4 +80,10 @@ public class DataInputPacketReader
instruction.read( in, buffer ); instruction.read( in, buffer );
} }
} }
public static void readPacket(DataInput in, byte[] buffer, int protocol) throws IOException
{
int packetId = in.readUnsignedByte();
readPacket( packetId, in, buffer, protocol );
}
} }

View File

@ -15,6 +15,7 @@ import net.md_5.bungee.packet.DefinedPacket;
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.PacketFFKick;
import net.md_5.bungee.packet.PacketStream; import net.md_5.bungee.packet.PacketStream;
import net.md_5.mendax.PacketDefinitions;
public class BungeeServerInfo extends ServerInfo public class BungeeServerInfo extends ServerInfo
{ {
@ -56,7 +57,7 @@ public class BungeeServerInfo extends ServerInfo
out.write( 0xFE ); out.write( 0xFE );
out.write( 0x01 ); out.write( 0x01 );
PacketStream in = new PacketStream( socket.getInputStream() ); PacketStream in = new PacketStream( socket.getInputStream(), PacketDefinitions.VANILLA_PROTOCOL );
PacketFFKick response = new PacketFFKick( in.readPacket() ); PacketFFKick response = new PacketFFKick( in.readPacket() );
String[] split = response.message.split( "\00" ); String[] split = response.message.split( "\00" );

View File

@ -26,6 +26,7 @@ import net.md_5.bungee.packet.PacketFEPing;
import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketFFKick;
import net.md_5.bungee.packet.PacketHandler; import net.md_5.bungee.packet.PacketHandler;
import net.md_5.bungee.packet.PacketStream; import net.md_5.bungee.packet.PacketStream;
import net.md_5.mendax.PacketDefinitions;
import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.io.CipherInputStream;
import org.bouncycastle.crypto.io.CipherOutputStream; import org.bouncycastle.crypto.io.CipherOutputStream;
@ -39,12 +40,13 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo
private Packet2Handshake handshake; private Packet2Handshake handshake;
private PacketFDEncryptionRequest request; private PacketFDEncryptionRequest request;
private State thisState = State.HANDSHAKE; private State thisState = State.HANDSHAKE;
private int protocol = PacketDefinitions.VANILLA_PROTOCOL;
public InitialHandler(Socket socket, ListenerInfo info) throws IOException public InitialHandler(Socket socket, ListenerInfo info) throws IOException
{ {
this.socket = socket; this.socket = socket;
this.listener = info; this.listener = info;
stream = new PacketStream( socket.getInputStream(), socket.getOutputStream() ); stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), protocol );
} }
private enum State private enum State
@ -128,7 +130,7 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo
stream.write( new PacketFCEncryptionResponse() ); stream.write( new PacketFCEncryptionResponse() );
stream = new PacketStream( new CipherInputStream( socket.getInputStream(), stream = new PacketStream( new CipherInputStream( socket.getInputStream(),
EncryptionUtil.getCipher( false, shared ) ), new CipherOutputStream( socket.getOutputStream(), EncryptionUtil.getCipher( true, shared ) ) ); EncryptionUtil.getCipher( false, shared ) ), new CipherOutputStream( socket.getOutputStream(), EncryptionUtil.getCipher( true, shared ) ), protocol );
thisState = State.LOGIN; thisState = State.LOGIN;
} }

View File

@ -19,6 +19,7 @@ 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.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.
@ -46,7 +47,7 @@ public class ServerConnection extends GenericConnection implements Server
socket.connect( info.getAddress(), BungeeCord.getInstance().config.getTimeout() ); socket.connect( info.getAddress(), BungeeCord.getInstance().config.getTimeout() );
BungeeCord.getInstance().setSocketOptions( socket ); BungeeCord.getInstance().setSocketOptions( socket );
PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream() ); PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), PacketDefinitions.VANILLA_PROTOCOL );
stream.write( handshake ); stream.write( handshake );
stream.write( PacketCDClientStatus.CLIENT_LOGIN ); stream.write( PacketCDClientStatus.CLIENT_LOGIN );

View File

@ -7,6 +7,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import net.md_5.mendax.datainput.DataInputPacketReader; import net.md_5.mendax.datainput.DataInputPacketReader;
/** /**
@ -19,19 +20,22 @@ public class PacketStream implements AutoCloseable
private final DataInputStream dataInput; private final DataInputStream dataInput;
@Getter @Getter
private OutputStream out; private OutputStream out;
@Setter
private int protocol;
private final TrackingInputStream tracker; private final TrackingInputStream tracker;
private final byte[] buffer = new byte[ 1 << 18 ]; private final byte[] buffer = new byte[ 1 << 18 ];
public PacketStream(InputStream in) public PacketStream(InputStream in, int protocol)
{ {
this( in, null ); this( in, null, protocol );
} }
public PacketStream(InputStream in, OutputStream out) public PacketStream(InputStream in, OutputStream out, int protocol)
{ {
tracker = new TrackingInputStream( in ); tracker = new TrackingInputStream( in );
dataInput = new DataInputStream( tracker ); dataInput = new DataInputStream( tracker );
this.out = out; this.out = out;
this.protocol = protocol;
} }
public void write(byte[] b) throws IOException public void write(byte[] b) throws IOException
@ -53,7 +57,7 @@ public class PacketStream implements AutoCloseable
public byte[] readPacket() throws IOException public byte[] readPacket() throws IOException
{ {
tracker.out.reset(); tracker.out.reset();
DataInputPacketReader.readPacket( dataInput, buffer ); DataInputPacketReader.readPacket( dataInput, buffer, protocol );
return tracker.out.toByteArray(); return tracker.out.toByteArray();
} }