mirror of
https://github.com/SpigotMC/BungeeCord.git
synced 2024-11-16 23:35:23 +01:00
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:
parent
9f4fc4dfac
commit
9c5e02e20a
@ -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
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 )
|
||||||
{
|
{
|
||||||
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 )
|
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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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" );
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 );
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user