From 9c5e02e20aa90dea54f527dc36556be4dc1caaf9 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 10 Feb 2013 21:26:49 +1100 Subject: [PATCH] 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. --- .../net/md_5/mendax/PacketDefinitions.java | 47 ++++--------------- .../datainput/DataInputPacketReader.java | 26 +++++++--- .../net/md_5/bungee/BungeeServerInfo.java | 3 +- .../java/net/md_5/bungee/InitialHandler.java | 6 ++- .../net/md_5/bungee/ServerConnection.java | 3 +- .../net/md_5/bungee/packet/PacketStream.java | 12 +++-- 6 files changed, 44 insertions(+), 53 deletions(-) diff --git a/protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java b/protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java index b4219d63..c80a0599 100644 --- a/protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -5,7 +5,10 @@ import static net.md_5.mendax.PacketDefinitions.OpCode.*; 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 { @@ -119,7 +122,6 @@ public class PacketDefinitions { INT, INT, INT, INT, SHORT }; - opCodes[0x1B] = null; // Does not exist opCodes[0x1C] = new OpCode[] { INT, SHORT, SHORT, SHORT @@ -152,8 +154,6 @@ public class PacketDefinitions { INT, BYTE }; - opCodes[0x24] = null; // Does not exist - opCodes[0x25] = null; // Does not exist opCodes[0x26] = new OpCode[] { INT, BYTE @@ -178,11 +178,6 @@ public class PacketDefinitions { FLOAT, SHORT, SHORT }; - // - // - // 0x2C -> 0x32 Do not exist - // - // opCodes[0x33] = new OpCode[] { INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE @@ -207,9 +202,6 @@ public class PacketDefinitions { BULK_CHUNK }; - opCodes[0x39] = null; // Does not exist - opCodes[0x3A] = null; // Does not exist - opCodes[0x3B] = null; // Does not exist opCodes[0x3C] = new OpCode[] { DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT @@ -222,11 +214,6 @@ public class PacketDefinitions { STRING, INT, INT, INT, FLOAT, BYTE }; - // - // - // 0x3F -> 0x45 Do not exist - // - // opCodes[0x46] = new OpCode[] { BYTE, BYTE @@ -235,11 +222,6 @@ public class PacketDefinitions { INT, BYTE, INT, INT, INT }; - // - // - // 0x4A -> 0x63 Do not exist - // - // opCodes[0x64] = new OpCode[] { BYTE, BYTE, STRING, BYTE @@ -276,11 +258,6 @@ public class PacketDefinitions { BYTE, BYTE }; - // - // - // 0x6D -> 0x81 Do not exist - // - // opCodes[0x82] = new OpCode[] { INT, SHORT, INT, STRING, STRING, STRING, STRING @@ -293,11 +270,6 @@ public class PacketDefinitions { INT, SHORT, INT, BYTE, SHORT_BYTE }; - // - // - // 0x85 -> 0xC7 Do not exist - // - // opCodes[0xC8] = new OpCode[] { INT, BYTE @@ -322,16 +294,10 @@ public class PacketDefinitions { BYTE }; - // - // - // 0xCE -> 0xF9 Do not exist - // - // opCodes[0xFA] = new OpCode[] { STRING, SHORT_BYTE }; - opCodes[0xFB] = null; // Does not exist opCodes[0xFC] = new OpCode[] { SHORT_BYTE, SHORT_BYTE @@ -347,5 +313,10 @@ public class PacketDefinitions { STRING }; + /*========================== Minecraft Forge ===========================*/ + opCodes[0x01 + FORGE_PROTOCOL] = new OpCode[] + { + INT, STRING, BYTE, INT, BYTE, BYTE, BYTE + }; } } diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java b/protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java index a40e2ee2..61f55d14 100644 --- a/protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java +++ b/protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java @@ -16,7 +16,7 @@ public class DataInputPacketReader { for ( int i = 0; i < instructions.length; i++ ) { - List output = new ArrayList(); + List output = new ArrayList<>(); OpCode[] enums = PacketDefinitions.opCodes[i]; if ( enums != null ) @@ -26,13 +26,13 @@ public class DataInputPacketReader try { 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() ); } } - List crushed = new ArrayList(); + List crushed = new ArrayList<>(); int nextJumpSize = 0; 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]; + Instruction[] packetDef = instructions[packetId + protocol]; if ( packetDef == null ) { - throw new IOException( "Unknown packet id " + packetId ); + if ( protocol == PacketDefinitions.VANILLA_PROTOCOL ) + { + throw new IOException( "Unknown packet id " + packetId ); + } else + { + readPacket( packetId, in, buffer, PacketDefinitions.VANILLA_PROTOCOL ); + return; + } } for ( Instruction instruction : packetDef ) @@ -74,4 +80,10 @@ public class DataInputPacketReader 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 ); + } } diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java index 00d38fd7..a17e08f7 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java @@ -15,6 +15,7 @@ import net.md_5.bungee.packet.DefinedPacket; 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.mendax.PacketDefinitions; public class BungeeServerInfo extends ServerInfo { @@ -56,7 +57,7 @@ public class BungeeServerInfo extends ServerInfo out.write( 0xFE ); out.write( 0x01 ); - PacketStream in = new PacketStream( socket.getInputStream() ); + PacketStream in = new PacketStream( socket.getInputStream(), PacketDefinitions.VANILLA_PROTOCOL ); PacketFFKick response = new PacketFFKick( in.readPacket() ); String[] split = response.message.split( "\00" ); 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 14298d38..57998411 100644 --- a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java @@ -26,6 +26,7 @@ import net.md_5.bungee.packet.PacketFEPing; import net.md_5.bungee.packet.PacketFFKick; import net.md_5.bungee.packet.PacketHandler; import net.md_5.bungee.packet.PacketStream; +import net.md_5.mendax.PacketDefinitions; import org.bouncycastle.crypto.io.CipherInputStream; import org.bouncycastle.crypto.io.CipherOutputStream; @@ -39,12 +40,13 @@ public class InitialHandler extends PacketHandler implements Runnable, PendingCo private Packet2Handshake handshake; private PacketFDEncryptionRequest request; 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() ); + stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), protocol ); } private enum State @@ -128,7 +130,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 ) ) ); + EncryptionUtil.getCipher( false, shared ) ), new CipherOutputStream( socket.getOutputStream(), EncryptionUtil.getCipher( true, shared ) ), protocol ); thisState = State.LOGIN; } 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 b29a5c0c..9282ae8a 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -19,6 +19,7 @@ import net.md_5.bungee.packet.PacketCDClientStatus; 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.mendax.PacketDefinitions; /** * 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() ); 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( PacketCDClientStatus.CLIENT_LOGIN ); 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 70b43bbb..76b6fadf 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 @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import lombok.Getter; +import lombok.Setter; import net.md_5.mendax.datainput.DataInputPacketReader; /** @@ -19,19 +20,22 @@ public class PacketStream implements AutoCloseable private final DataInputStream dataInput; @Getter private OutputStream out; + @Setter + private int protocol; private final TrackingInputStream tracker; 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 ); dataInput = new DataInputStream( tracker ); this.out = out; + this.protocol = protocol; } public void write(byte[] b) throws IOException @@ -53,7 +57,7 @@ public class PacketStream implements AutoCloseable public byte[] readPacket() throws IOException { tracker.out.reset(); - DataInputPacketReader.readPacket( dataInput, buffer ); + DataInputPacketReader.readPacket( dataInput, buffer, protocol ); return tracker.out.toByteArray(); }