diff --git a/config/pom.xml b/config/pom.xml
index 9df700073..ad8761be5 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -17,4 +17,18 @@
BungeeCord-Config
Generic java configuration API intended for use with BungeeCord
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.yaml
+ snakeyaml
+ 1.11
+
+
diff --git a/config/src/main/java/net/md_5/bungee/config/Configuration.java b/config/src/main/java/net/md_5/bungee/config/Configuration.java
index f9d32c824..43af0fffb 100644
--- a/config/src/main/java/net/md_5/bungee/config/Configuration.java
+++ b/config/src/main/java/net/md_5/bungee/config/Configuration.java
@@ -2,6 +2,7 @@ package net.md_5.bungee.config;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
@@ -13,8 +14,8 @@ public final class Configuration
private static final char SEPARATOR = '.';
private final Map self;
- private final Map comments;
- private final Map defaults;
+ private Map comments = new HashMap<>();
+ private final Configuration defaults;
private Map getHolder(String path, Map parent, boolean create)
{
@@ -41,12 +42,17 @@ public final class Configuration
public T get(String path, T def)
{
Object val = get( path, self );
- return ( val != null && val.getClass().isInstance( def ) ) ? (T) val : (T) get( path, defaults );
+ return ( val != null && val.getClass().isInstance( def ) ) ? (T) val : (T) defaults.get( path );
+ }
+
+ public Object get(String path)
+ {
+ return get( path, null );
}
public Object getDefault(String path)
{
- return get( path, defaults );
+ return defaults.get( path );
}
public void set(String path, Object value, String comment)
diff --git a/config/src/main/java/net/md_5/bungee/config/ConfigurationProvider.java b/config/src/main/java/net/md_5/bungee/config/ConfigurationProvider.java
new file mode 100644
index 000000000..7d1b53273
--- /dev/null
+++ b/config/src/main/java/net/md_5/bungee/config/ConfigurationProvider.java
@@ -0,0 +1,29 @@
+package net.md_5.bungee.config;
+
+import java.io.File;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class ConfigurationProvider
+{
+
+ private static final Map, ConfigurationProvider> providers = new HashMap<>();
+
+ static
+ {
+ providers.put( YamlConfiguration.class, new YamlConfiguration() );
+ }
+
+ public ConfigurationProvider getProvider(Class extends ConfigurationProvider> provider)
+ {
+ return providers.get( provider );
+ }
+ /*------------------------------------------------------------------------*/
+
+ public abstract Configuration load(File file);
+
+ public abstract Configuration load(Reader reader);
+
+ public abstract Configuration load(String string);
+}
diff --git a/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java b/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java
new file mode 100644
index 000000000..74d84ab87
--- /dev/null
+++ b/config/src/main/java/net/md_5/bungee/config/YamlConfiguration.java
@@ -0,0 +1,53 @@
+package net.md_5.bungee.config;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Map;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
+
+public class YamlConfiguration extends ConfigurationProvider
+{
+
+ private final ThreadLocal yaml = new ThreadLocal()
+ {
+ @Override
+ protected Yaml initialValue()
+ {
+ DumperOptions options = new DumperOptions();
+ options.setDefaultFlowStyle( DumperOptions.FlowStyle.BLOCK );
+ return new Yaml( options );
+ }
+ };
+
+ @Override
+ public Configuration load(File file)
+ {
+ try ( FileReader reader = new FileReader( file ) )
+ {
+ return load( reader );
+ } catch ( IOException ex )
+ {
+ return null;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Configuration load(Reader reader)
+ {
+ Configuration conf = new Configuration( (Map) yaml.get().loadAs( reader, Map.class ), null );
+ return conf;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Configuration load(String string)
+ {
+ Configuration conf = new Configuration( (Map) yaml.get().loadAs( string, Map.class ), null );
+ return conf;
+ }
+}
diff --git a/protocol/pom.xml b/protocol/pom.xml
index c87c81716..a347f5cc2 100644
--- a/protocol/pom.xml
+++ b/protocol/pom.xml
@@ -17,4 +17,12 @@
BungeeCord-Protocol
Minimal implementation of the Minecraft protocol for use in BungeeCord
+
+
+
+ io.netty
+ netty-buffer
+ 4.0.0.Beta2
+
+
diff --git a/protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java b/protocol/src/main/java/net/md_5/bungee/protocol/PacketDefinitions.java
similarity index 95%
rename from protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/PacketDefinitions.java
index 4fdd1be66..bbe4243a1 100644
--- a/protocol/src/main/java/net/md_5/mendax/PacketDefinitions.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/PacketDefinitions.java
@@ -1,14 +1,13 @@
-package net.md_5.mendax;
+package net.md_5.bungee.protocol;
-import static net.md_5.mendax.PacketDefinitions.OpCode.*;
+import static net.md_5.bungee.protocol.PacketDefinitions.OpCode.*;
public class PacketDefinitions
{
- private static final int MAX_PACKET = 256;
- public static final OpCode[][] opCodes = new OpCode[ MAX_PACKET * 2 ][];
+ public static final OpCode[][] opCodes = new OpCode[ 512 ][];
public static final int VANILLA_PROTOCOL = 0;
- public static final int FORGE_PROTOCOL = MAX_PACKET;
+ public static final int FORGE_PROTOCOL = 256;
public enum OpCode
{
@@ -312,7 +311,8 @@ public class PacketDefinitions
};
opCodes[0xFE] = new OpCode[]
{
- }; // Should be byte, screw you too bitchy server admins!
+ BYTE
+ };
opCodes[0xFF] = new OpCode[]
{
STRING
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/BulkChunk.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/BulkChunk.java
similarity index 54%
rename from protocol/src/main/java/net/md_5/mendax/datainput/BulkChunk.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/BulkChunk.java
index 5f1b31b03..374990182 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/BulkChunk.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/BulkChunk.java
@@ -1,17 +1,17 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
public class BulkChunk extends Instruction
{
@Override
- void read(DataInput in, byte[] buffer) throws IOException
+ void read(ByteBuf in) throws IOException
{
short count = in.readShort();
int size = in.readInt();
in.readBoolean();
- skip( in, buffer, size + count * 12 );
+ skip( in, size + count * 12 );
}
}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/ByteHeader.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/ByteHeader.java
similarity index 65%
rename from protocol/src/main/java/net/md_5/mendax/datainput/ByteHeader.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/ByteHeader.java
index a4bc11da4..24fd1ac4c 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/ByteHeader.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/ByteHeader.java
@@ -1,6 +1,6 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
class ByteHeader extends Instruction
@@ -14,12 +14,12 @@ class ByteHeader extends Instruction
}
@Override
- void read(DataInput in, byte[] buffer) throws IOException
+ void read(ByteBuf in) throws IOException
{
byte size = in.readByte();
for ( byte b = 0; b < size; b++ )
{
- child.read( in, buffer );
+ child.read( in );
}
}
}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/Instruction.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/Instruction.java
similarity index 82%
rename from protocol/src/main/java/net/md_5/mendax/datainput/Instruction.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/Instruction.java
index d246558a6..6b84dc59b 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/Instruction.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/Instruction.java
@@ -1,6 +1,6 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
abstract class Instruction
@@ -27,10 +27,10 @@ abstract class Instruction
// Illegal forward references below this line
static final Instruction BYTE_INT = new ByteHeader( INT );
- abstract void read(DataInput in, byte[] buffer) throws IOException;
+ abstract void read(ByteBuf in) throws IOException;
- final void skip(DataInput in, byte[] buffer, int len) throws IOException
+ final void skip(ByteBuf in, int len) throws IOException
{
- in.readFully( buffer, 0, len );
+ in.readerIndex( in.readerIndex() + len );
}
}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/IntHeader.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/IntHeader.java
similarity index 65%
rename from protocol/src/main/java/net/md_5/mendax/datainput/IntHeader.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/IntHeader.java
index 31a5c18d9..2f1a011b2 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/IntHeader.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/IntHeader.java
@@ -1,6 +1,6 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
class IntHeader extends Instruction
@@ -14,12 +14,12 @@ class IntHeader extends Instruction
}
@Override
- void read(DataInput in, byte[] buffer) throws IOException
+ void read(ByteBuf in) throws IOException
{
int size = in.readInt();
for ( int i = 0; i < size; i++ )
{
- child.read( in, buffer );
+ child.read( in );
}
}
}
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/netty/Item.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/Item.java
new file mode 100644
index 000000000..5026b521d
--- /dev/null
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/Item.java
@@ -0,0 +1,19 @@
+package net.md_5.bungee.protocol.netty;
+
+import io.netty.buffer.ByteBuf;
+import java.io.IOException;
+
+class Item extends Instruction
+{
+
+ @Override
+ void read(ByteBuf in) throws IOException
+ {
+ short type = in.readShort();
+ if ( type >= 0 )
+ {
+ skip( in, 3 );
+ SHORT_BYTE.read( in );
+ }
+ }
+}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/Jump.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/Jump.java
similarity index 62%
rename from protocol/src/main/java/net/md_5/mendax/datainput/Jump.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/Jump.java
index 5bf82fc7a..0c9ed2a4b 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/Jump.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/Jump.java
@@ -1,6 +1,6 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
class Jump extends Instruction
@@ -18,8 +18,8 @@ class Jump extends Instruction
}
@Override
- void read(DataInput in, byte[] buffer) throws IOException
+ void read(ByteBuf in) throws IOException
{
- skip( in, buffer, len );
+ skip( in, len );
}
}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/MetaData.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/MetaData.java
similarity index 63%
rename from protocol/src/main/java/net/md_5/mendax/datainput/MetaData.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/MetaData.java
index 6dc045840..7ebc3c166 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/MetaData.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/MetaData.java
@@ -1,13 +1,13 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
class MetaData extends Instruction
{
@Override
- void read(DataInput in, byte[] buffer) throws IOException
+ void read(ByteBuf in) throws IOException
{
int x = in.readUnsignedByte();
while ( x != 127 )
@@ -16,25 +16,25 @@ class MetaData extends Instruction
switch ( type )
{
case 0:
- BYTE.read( in, buffer );
+ BYTE.read( in );
break;
case 1:
- SHORT.read( in, buffer );
+ SHORT.read( in );
break;
case 2:
- INT.read( in, buffer );
+ INT.read( in );
break;
case 3:
- FLOAT.read( in, buffer );
+ FLOAT.read( in );
break;
case 4:
- STRING.read( in, buffer );
+ STRING.read( in );
break;
case 5:
- ITEM.read( in, buffer );
+ ITEM.read( in );
break;
case 6:
- skip( in, buffer, 12 ); // int, int, int
+ skip( in, 12 ); // int, int, int
break;
default:
throw new IllegalArgumentException( "Unknown metadata type " + type );
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/netty/OptionalMotion.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/OptionalMotion.java
new file mode 100644
index 000000000..7e3040071
--- /dev/null
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/OptionalMotion.java
@@ -0,0 +1,18 @@
+package net.md_5.bungee.protocol.netty;
+
+import io.netty.buffer.ByteBuf;
+import java.io.IOException;
+
+class OptionalMotion extends Instruction
+{
+
+ @Override
+ void read(ByteBuf in) throws IOException
+ {
+ int data = in.readInt();
+ if ( data > 0 )
+ {
+ skip( in, 6 );
+ }
+ }
+}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/PacketReader.java
similarity index 80%
rename from protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/PacketReader.java
index c697b9a07..0adfb8642 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/PacketReader.java
@@ -1,16 +1,16 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import net.md_5.mendax.PacketDefinitions;
-import net.md_5.mendax.PacketDefinitions.OpCode;
+import net.md_5.bungee.protocol.PacketDefinitions;
+import net.md_5.bungee.protocol.PacketDefinitions.OpCode;
-public class DataInputPacketReader
+public class PacketReader
{
- private static final Instruction[][] instructions = new Instruction[ 256 ][];
+ private static final Instruction[][] instructions = new Instruction[ PacketDefinitions.opCodes.length ][];
static
{
@@ -59,7 +59,7 @@ public class DataInputPacketReader
}
}
- private static void readPacket(int packetId, DataInput in, byte[] buffer, int protocol) throws IOException
+ private static void readPacket(int packetId, ByteBuf in, int protocol) throws IOException
{
Instruction[] packetDef = null;
if ( packetId + protocol < instructions.length )
@@ -74,20 +74,20 @@ public class DataInputPacketReader
throw new IOException( "Unknown packet id " + packetId );
} else
{
- readPacket( packetId, in, buffer, PacketDefinitions.VANILLA_PROTOCOL );
+ readPacket( packetId, in, PacketDefinitions.VANILLA_PROTOCOL );
return;
}
}
for ( Instruction instruction : packetDef )
{
- instruction.read( in, buffer );
+ instruction.read( in );
}
}
- public static void readPacket(DataInput in, byte[] buffer, int protocol) throws IOException
+ public static void readPacket(ByteBuf in, int protocol) throws IOException
{
int packetId = in.readUnsignedByte();
- readPacket( packetId, in, buffer, protocol );
+ readPacket( packetId, in, protocol );
}
}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/ShortHeader.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/ShortHeader.java
similarity index 66%
rename from protocol/src/main/java/net/md_5/mendax/datainput/ShortHeader.java
rename to protocol/src/main/java/net/md_5/bungee/protocol/netty/ShortHeader.java
index b274af61c..ece0ae3cf 100644
--- a/protocol/src/main/java/net/md_5/mendax/datainput/ShortHeader.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/ShortHeader.java
@@ -1,6 +1,6 @@
-package net.md_5.mendax.datainput;
+package net.md_5.bungee.protocol.netty;
-import java.io.DataInput;
+import io.netty.buffer.ByteBuf;
import java.io.IOException;
class ShortHeader extends Instruction
@@ -14,12 +14,12 @@ class ShortHeader extends Instruction
}
@Override
- void read(DataInput in, byte[] buffer) throws IOException
+ void read(ByteBuf in) throws IOException
{
short size = in.readShort();
for ( short s = 0; s < size; s++ )
{
- child.read( in, buffer );
+ child.read( in );
}
}
}
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/netty/UnsignedShortByte.java b/protocol/src/main/java/net/md_5/bungee/protocol/netty/UnsignedShortByte.java
new file mode 100644
index 000000000..2b4098844
--- /dev/null
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/netty/UnsignedShortByte.java
@@ -0,0 +1,15 @@
+package net.md_5.bungee.protocol.netty;
+
+import io.netty.buffer.ByteBuf;
+import java.io.IOException;
+
+class UnsignedShortByte extends Instruction
+{
+
+ @Override
+ void read(ByteBuf in) throws IOException
+ {
+ int size = in.readUnsignedShort();
+ skip( in, size );
+ }
+}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/Item.java b/protocol/src/main/java/net/md_5/mendax/datainput/Item.java
deleted file mode 100644
index 411c931bd..000000000
--- a/protocol/src/main/java/net/md_5/mendax/datainput/Item.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package net.md_5.mendax.datainput;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-class Item extends Instruction
-{
-
- @Override
- void read(DataInput in, byte[] buffer) throws IOException
- {
- short type = in.readShort();
- if ( type >= 0 )
- {
- skip( in, buffer, 3 );
- SHORT_BYTE.read( in, buffer );
- }
- }
-}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java b/protocol/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java
deleted file mode 100644
index 55c36f654..000000000
--- a/protocol/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.md_5.mendax.datainput;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-public class OptionalMotion extends Instruction
-{
-
- @Override
- void read(DataInput in, byte[] buffer) throws IOException
- {
- int data = in.readInt();
- if ( data > 0 )
- {
- skip( in, buffer, 6 );
- }
- }
-}
diff --git a/protocol/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java b/protocol/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java
deleted file mode 100644
index 4b1db5a25..000000000
--- a/protocol/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.md_5.mendax.datainput;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-public class UnsignedShortByte extends Instruction
-{
-
- @Override
- void read(DataInput in, byte[] buffer) throws IOException
- {
- int size = in.readUnsignedShort();
- skip( in, buffer, size );
- }
-}
diff --git a/proxy/pom.xml b/proxy/pom.xml
index 7163f7f9f..210fde517 100644
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -19,6 +19,11 @@
Proxy component of the Elastic Portal Suite
+
+ io.netty
+ netty-all
+ 4.0.0.Beta2
+
net.md-5
bungeecord-protocol
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index c9dd9ad0d..4ffd581f2 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -1,5 +1,15 @@
package net.md_5.bungee;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelException;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.MultithreadEventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.handler.timeout.ReadTimeoutHandler;
import net.md_5.bungee.config.Configuration;
import java.io.BufferedReader;
import java.io.File;
@@ -10,13 +20,10 @@ import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -36,6 +43,9 @@ import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginManager;
import net.md_5.bungee.command.*;
import net.md_5.bungee.config.YamlConfig;
+import net.md_5.bungee.netty.ChannelBootstrapper;
+import net.md_5.bungee.netty.HandlerBoss;
+import net.md_5.bungee.netty.PacketDecoder;
import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.PacketFAPluginMessage;
@@ -64,7 +74,7 @@ public class BungeeCord extends ProxyServer
/**
* Thread pool.
*/
- public final ExecutorService threadPool = Executors.newCachedThreadPool();
+ public final MultithreadEventLoopGroup eventLoops = new NioEventLoopGroup( 8, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread - %1$d" ).build() );
/**
* locations.yml save thread.
*/
@@ -72,7 +82,7 @@ public class BungeeCord extends ProxyServer
/**
* Server socket listener.
*/
- private Collection listeners = new HashSet<>();
+ private Collection listeners = new HashSet<>();
/**
* Fully qualified connections.
*/
@@ -149,6 +159,7 @@ public class BungeeCord extends ProxyServer
*
* @throws IOException
*/
+ @Override
public void start() throws IOException
{
File plugins = new File( "plugins" );
@@ -181,30 +192,26 @@ public class BungeeCord extends ProxyServer
{
for ( ListenerInfo info : config.getListeners() )
{
- try
- {
- ListenThread listener = new ListenThread( info );
- listener.start();
- listeners.add( listener );
- $().info( "Listening on " + info.getHost() );
- } catch ( IOException ex )
- {
- $().log( Level.SEVERE, "Could not start listener " + info, ex );
- }
+ Channel server = new ServerBootstrap()
+ .childHandler( ChannelBootstrapper.SERVER )
+ .localAddress( info.getHost() )
+ .group( eventLoops )
+ .bind().channel();
+ listeners.add( server );
+
+ $().info( "Listening on " + info.getHost() );
}
}
public void stopListeners()
{
- for ( ListenThread listener : listeners )
+ for ( Channel listener : listeners )
{
- $().log( Level.INFO, "Closing listen thread {0}", listener.socket );
+ $().log( Level.INFO, "Closing listener {0}", listener );
try
{
- listener.interrupt();
- listener.socket.close();
- listener.join();
- } catch ( InterruptedException | IOException ex )
+ listener.close().syncUninterruptibly();
+ } catch ( ChannelException ex )
{
$().severe( "Could not close listen thread" );
}
@@ -219,7 +226,6 @@ public class BungeeCord extends ProxyServer
stopListeners();
$().info( "Closing pending connections" );
- threadPool.shutdown();
$().info( "Disconnecting " + connections.size() + " connections" );
for ( UserConnection user : connections.values() )
@@ -227,6 +233,9 @@ public class BungeeCord extends ProxyServer
user.disconnect( "Proxy restarting, brb." );
}
+ $().info( "Closing IO threads" );
+ eventLoops.shutdown();
+
$().info( "Saving reconnect locations" );
reconnectHandler.save();
saveThread.cancel();
@@ -241,20 +250,6 @@ public class BungeeCord extends ProxyServer
System.exit( 0 );
}
- /**
- * Miscellaneous method to set options on a socket based on those in the
- * configuration.
- *
- * @param socket to set the options on
- * @throws IOException when the underlying set methods thrown an exception
- */
- public void setSocketOptions(Socket socket) throws IOException
- {
- socket.setSoTimeout( config.getTimeout() );
- socket.setTrafficClass( 0x18 );
- socket.setTcpNoDelay( true );
- }
-
/**
* Broadcasts a packet to all clients that is connected to this instance.
*
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 a17e08f77..efe6d0c25 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
@@ -15,7 +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;
+import net.md_5.bungee.protocol.PacketDefinitions;
public class BungeeServerInfo extends ServerInfo
{
diff --git a/proxy/src/main/java/net/md_5/bungee/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/EntityMap.java
index ce9ad4cbb..5a7a4b364 100644
--- a/proxy/src/main/java/net/md_5/bungee/EntityMap.java
+++ b/proxy/src/main/java/net/md_5/bungee/EntityMap.java
@@ -1,5 +1,7 @@
package net.md_5.bungee;
+import io.netty.buffer.ByteBuf;
+
/**
* Class to rewrite integers within packets.
*/
@@ -113,20 +115,20 @@ public class EntityMap
};
}
- public static void rewrite(byte[] packet, int oldId, int newId)
+ public static void rewrite(ByteBuf packet, int oldId, int newId)
{
- int packetId = Util.getId( packet );
+ int packetId = packet.getUnsignedShort( 0 );
if ( packetId == 0x1D )
{ // bulk entity
- for ( int pos = 2; pos < packet.length; pos += 4 )
+ for ( int pos = 2; pos < packet.writerIndex(); pos += 4 )
{
- int readId = readInt( packet, pos );
+ int readId = packet.getInt( pos );
if ( readId == oldId )
{
- setInt( packet, pos, newId );
+ packet.setInt( pos, newId );
} else if ( readId == newId )
{
- setInt( packet, pos, oldId );
+ packet.setInt( pos, oldId );
}
}
} else
@@ -136,29 +138,16 @@ public class EntityMap
{
for ( int pos : idArray )
{
- int readId = readInt( packet, pos );
+ int readId = packet.getInt( pos );
if ( readId == oldId )
{
- setInt( packet, pos, newId );
+ packet.setInt( pos, newId );
} else if ( readId == newId )
{
- setInt( packet, pos, oldId );
+ packet.setInt( pos, oldId );
}
}
}
}
}
-
- private static void setInt(byte[] buf, int pos, int i)
- {
- buf[pos] = (byte) ( i >> 24 );
- buf[pos + 1] = (byte) ( i >> 16 );
- buf[pos + 2] = (byte) ( i >> 8 );
- buf[pos + 3] = (byte) i;
- }
-
- private static int readInt(byte[] buf, int pos)
- {
- return ( ( ( buf[pos] & 0xFF ) << 24 ) | ( ( buf[pos + 1] & 0xFF ) << 16 ) | ( ( buf[pos + 2] & 0xFF ) << 8 ) | buf[pos + 3] & 0xFF );
- }
}
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 ab57c741b..9238998f4 100644
--- a/proxy/src/main/java/net/md_5/bungee/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/InitialHandler.java
@@ -32,7 +32,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 net.md_5.bungee.protocol.PacketDefinitions;
public class InitialHandler extends PacketHandler implements Runnable, PendingConnection
{
diff --git a/proxy/src/main/java/net/md_5/bungee/ListenThread.java b/proxy/src/main/java/net/md_5/bungee/ListenThread.java
deleted file mode 100644
index d0e52973c..000000000
--- a/proxy/src/main/java/net/md_5/bungee/ListenThread.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package net.md_5.bungee;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import static net.md_5.bungee.Logger.$;
-import net.md_5.bungee.api.config.ListenerInfo;
-
-/**
- * Thread to listen and dispatch incoming connections to the proxy.
- */
-public class ListenThread extends Thread
-{
-
- public final ServerSocket socket;
- private final ListenerInfo info;
-
- public ListenThread(ListenerInfo info) throws IOException
- {
- super( "Listen Thread - " + info );
- this.info = info;
- socket = new ServerSocket();
- socket.bind( info.getHost() );
- }
-
- @Override
- public void run()
- {
- while ( !isInterrupted() )
- {
- try
- {
- Socket client = socket.accept();
- BungeeCord.getInstance().setSocketOptions( client );
- $().info( client.getInetAddress() + " has connected" );
- InitialHandler handler = new InitialHandler( client, info );
- BungeeCord.getInstance().threadPool.submit( handler );
- } catch ( SocketException ex )
- {
- ex.printStackTrace(); // Now people can see why their operating system is failing them and stop bitching at me!
- } catch ( IOException ex )
- {
- ex.printStackTrace(); // TODO
- }
- }
- }
-}
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
index b080164ed..6b5ebe385 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -1,13 +1,16 @@
package net.md_5.bungee;
import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.net.Socket;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.socket.nio.NioSocketChannel;
import java.util.Queue;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectedEvent;
+import net.md_5.bungee.netty.ChannelBootstrapper;
import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.Packet1Login;
import net.md_5.bungee.packet.PacketCDClientStatus;
@@ -39,6 +42,18 @@ public class ServerConnector extends PacketHandler
{
Preconditions.checkState( thisState == State.LOGIN, "Not exepcting LOGIN" );
loginPacket = login;
+
+ ServerConnection server = new ServerConnection( socket, info, stream, connector.loginPacket );
+ ServerConnectedEvent event = new ServerConnectedEvent( user, server );
+ ProxyServer.getInstance().getPluginManager().callEvent( event );
+
+ stream.write( BungeeCord.getInstance().registerChannels() );
+
+ Queue packetQueue = ( (BungeeServerInfo) info ).getPacketQueue();
+ while ( !packetQueue.isEmpty() )
+ {
+ stream.write( packetQueue.poll() );
+ }
thisState = State.FINISHED;
}
@@ -55,63 +70,33 @@ public class ServerConnector extends PacketHandler
throw new KickException( kick.message );
}
- public static ServerConnection connect(UserConnection user, ServerInfo info, boolean retry)
+ public static void connect(final UserConnection user, final ServerInfo info, final boolean retry)
{
- Socket socket = null;
- try
+ new Bootstrap()
+ .channel( NioSocketChannel.class )
+ .group( BungeeCord.getInstance().eventLoops )
+ .handler( ChannelBootstrapper.CLIENT )
+ .remoteAddress( info.getAddress() )
+ .connect().addListener( new ChannelFutureListener()
{
- socket = new Socket();
- socket.connect( info.getAddress(), BungeeCord.getInstance().config.getTimeout() );
- BungeeCord.getInstance().setSocketOptions( socket );
- PacketStream stream = new PacketStream( socket.getInputStream(), socket.getOutputStream(), user.stream.getProtocol() );
-
- ServerConnector connector = new ServerConnector( stream );
- stream.write( user.handshake );
- stream.write( PacketCDClientStatus.CLIENT_LOGIN );
-
- while ( connector.thisState != State.FINISHED )
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception
{
- byte[] buf = stream.readPacket();
- DefinedPacket packet = DefinedPacket.packet( buf );
- packet.handle( connector );
- }
-
- ServerConnection server = new ServerConnection( socket, info, stream, connector.loginPacket );
- ServerConnectedEvent event = new ServerConnectedEvent( user, server );
- ProxyServer.getInstance().getPluginManager().callEvent( event );
-
- stream.write( BungeeCord.getInstance().registerChannels() );
-
- Queue packetQueue = ( (BungeeServerInfo) info ).getPacketQueue();
- while ( !packetQueue.isEmpty() )
- {
- stream.write( packetQueue.poll() );
- }
- return server;
- } catch ( Exception ex )
- {
- if ( socket != null )
- {
- try
+ if ( future.isSuccess() )
{
- socket.close();
- } catch ( IOException ioe )
+ future.channel().write( user.handshake );
+ future.channel().write( PacketCDClientStatus.CLIENT_LOGIN );
+ } else
{
+ future.channel().close();
+ ServerInfo def = ProxyServer.getInstance().getServers().get( user.getPendingConnection().getListener().getDefaultServer() );
+ if ( retry && !info.equals( def ) )
+ {
+ user.sendMessage( ChatColor.RED + "Could not connect to target server, you have been moved to the default server" );
+ connect( user, def, false );
+ }
}
}
- ServerInfo def = ProxyServer.getInstance().getServers().get( user.getPendingConnection().getListener().getDefaultServer() );
- if ( retry && !info.equals( def ) )
- {
- user.sendMessage( ChatColor.RED + "Could not connect to target server, you have been moved to the default server" );
- return connect( user, def, false );
- } else
- {
- if ( ex instanceof RuntimeException )
- {
- throw (RuntimeException) ex;
- }
- throw new RuntimeException( "Could not connect to target server " + Util.exception( ex ) );
- }
- }
+ } ).channel();
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/Util.java b/proxy/src/main/java/net/md_5/bungee/Util.java
index a96755bb3..605cbe222 100644
--- a/proxy/src/main/java/net/md_5/bungee/Util.java
+++ b/proxy/src/main/java/net/md_5/bungee/Util.java
@@ -27,18 +27,6 @@ public class Util
return new InetSocketAddress( split[0], port );
}
- /**
- * Gets the value of the first unsigned byte of the specified array. Useful
- * for getting the id of a packet array .
- *
- * @param b the array to read from
- * @return the unsigned value of the first byte
- */
- public static int getId(byte[] b)
- {
- return b[0] & 0xFF;
- }
-
/**
* Normalizes a config path by prefix upper case letters with '_' and
* turning them to lowercase.
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelBootstrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelBootstrapper.java
new file mode 100644
index 000000000..928ec25d6
--- /dev/null
+++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelBootstrapper.java
@@ -0,0 +1,49 @@
+package net.md_5.bungee.netty;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelException;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import java.lang.reflect.Constructor;
+import java.util.concurrent.TimeUnit;
+import net.md_5.bungee.BungeeCord;
+import net.md_5.bungee.InitialHandler;
+import net.md_5.bungee.ServerConnector;
+import net.md_5.bungee.packet.PacketHandler;
+import net.md_5.bungee.protocol.PacketDefinitions;
+
+public class ChannelBootstrapper extends ChannelInitializer
+{
+
+ public static ChannelBootstrapper CLIENT = new ChannelBootstrapper( InitialHandler.class );
+ public static ChannelBootstrapper SERVER = new ChannelBootstrapper( ServerConnector.class );
+ private final Constructor extends PacketHandler> initial;
+
+ private ChannelBootstrapper(Class extends PacketHandler> initialHandler)
+ {
+ try
+ {
+ this.initial = initialHandler.getDeclaredConstructor();
+ } catch ( NoSuchMethodException ex )
+ {
+ throw new ExceptionInInitializerError( ex );
+ }
+ }
+
+ @Override
+ protected void initChannel(Channel ch) throws Exception
+ {
+ try
+ {
+ ch.config().setOption( ChannelOption.IP_TOS, 0x18 );
+ } catch ( ChannelException ex )
+ {
+ // IP_TOS is not supported (Windows XP / Windows Server 2003)
+ }
+ ch.pipeline().addLast( "timer", new ReadTimeoutHandler( BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS ) );
+ ch.pipeline().addLast( "decoder", new PacketDecoder( PacketDefinitions.VANILLA_PROTOCOL ) );
+
+ ch.pipeline().addLast( "handler", new HandlerBoss( initial.newInstance() ) );
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java b/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java
new file mode 100644
index 000000000..b569e4068
--- /dev/null
+++ b/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java
@@ -0,0 +1,76 @@
+package net.md_5.bungee.netty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToByteCodec;
+import javax.crypto.Cipher;
+import javax.crypto.ShortBufferException;
+
+/**
+ * This class is a complete solution for encrypting and decoding bytes in a
+ * Netty stream. It takes two {@link BufferedBlockCipher} instances, used for
+ * encryption and decryption respectively.
+ */
+public class CipherCodec extends ByteToByteCodec
+{
+
+ private Cipher encrypt;
+ private Cipher decrypt;
+ private ByteBuf heapOut;
+
+ public CipherCodec(Cipher encrypt, Cipher decrypt)
+ {
+ this.encrypt = encrypt;
+ this.decrypt = decrypt;
+ }
+
+ @Override
+ public void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception
+ {
+ if ( heapOut == null )
+ {
+ heapOut = ctx.alloc().heapBuffer();
+ }
+ cipher( encrypt, in, heapOut );
+ out.writeBytes( heapOut );
+ heapOut.discardSomeReadBytes();
+ }
+
+ @Override
+ public void decode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception
+ {
+ cipher( decrypt, in, out );
+ }
+
+ @Override
+ public void freeInboundBuffer(ChannelHandlerContext ctx) throws Exception
+ {
+ super.freeInboundBuffer( ctx );
+ decrypt = null;
+ }
+
+ @Override
+ public void freeOutboundBuffer(ChannelHandlerContext ctx) throws Exception
+ {
+ super.freeOutboundBuffer( ctx );
+ if ( heapOut != null )
+ {
+ heapOut.release();
+ heapOut = null;
+ }
+ encrypt = null;
+ }
+
+ private void cipher(Cipher cipher, ByteBuf in, ByteBuf out) throws ShortBufferException
+ {
+ int available = in.readableBytes();
+ int outputSize = cipher.getOutputSize( available );
+ if ( out.capacity() < outputSize )
+ {
+ out.capacity( outputSize );
+ }
+ int processed = cipher.update( in.array(), in.arrayOffset() + in.readerIndex(), available, out.array(), out.arrayOffset() + out.writerIndex() );
+ in.readerIndex( in.readerIndex() + processed );
+ out.writerIndex( out.writerIndex() + processed );
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
new file mode 100644
index 000000000..38f37419b
--- /dev/null
+++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
@@ -0,0 +1,45 @@
+package net.md_5.bungee.netty;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundMessageHandlerAdapter;
+import net.md_5.bungee.packet.DefinedPacket;
+import net.md_5.bungee.packet.PacketHandler;
+
+public class HandlerBoss extends ChannelInboundMessageHandlerAdapter
+{
+
+ private PacketHandler handler;
+
+ HandlerBoss(PacketHandler handler)
+ {
+ Preconditions.checkArgument( handler != null, "handler" );
+ this.handler = handler;
+ }
+
+ @Override
+ protected void messageReceived(ChannelHandlerContext ctx, ByteBuf msg) throws Exception
+ {
+ if ( ctx.channel().isActive() )
+ {
+ DefinedPacket packet = DefinedPacket.packet( msg );
+ if ( packet != null )
+ {
+ handler.handle( packet );
+ } else
+ {
+ handler.handle( msg );
+ }
+ }
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
+ {
+ if ( ctx.channel().isActive() )
+ {
+ ctx.close();
+ }
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java b/proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java
new file mode 100644
index 000000000..5dffe828a
--- /dev/null
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java
@@ -0,0 +1,25 @@
+package net.md_5.bungee.netty;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ReplayingDecoder;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import net.md_5.bungee.protocol.netty.PacketReader;
+
+@AllArgsConstructor
+public class PacketDecoder extends ReplayingDecoder
+{
+
+ @Getter
+ @Setter
+ private int protocol;
+
+ @Override
+ protected ByteBuf decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception
+ {
+ PacketReader.readPacket( in, protocol );
+ return in.copy();
+ }
+}
diff --git a/proxy/src/main/java/net/md_5/bungee/packet/DefinedPacket.java b/proxy/src/main/java/net/md_5/bungee/packet/DefinedPacket.java
index d7c20ccea..a3f53fcaf 100644
--- a/proxy/src/main/java/net/md_5/bungee/packet/DefinedPacket.java
+++ b/proxy/src/main/java/net/md_5/bungee/packet/DefinedPacket.java
@@ -3,6 +3,7 @@ package net.md_5.bungee.packet;
import com.google.common.base.Preconditions;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
+import io.netty.buffer.ByteBuf;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutput;
@@ -196,9 +197,9 @@ public abstract class DefinedPacket implements DataOutput
public abstract void handle(PacketHandler handler) throws Exception;
private static Class extends DefinedPacket>[] classes = new Class[ 256 ];
- public static DefinedPacket packet(byte[] buf)
+ public static DefinedPacket packet(ByteBuf buf)
{
- int id = Util.getId( buf );
+ int id = buf.getUnsignedShort( 0);
Class extends DefinedPacket> clazz = classes[id];
DefinedPacket ret = null;
if ( clazz != null )
@@ -213,6 +214,8 @@ public abstract class DefinedPacket implements DataOutput
} catch ( IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException ex )
{
}
+ } else {
+ return null;
}
Preconditions.checkState( ret != null, "Don't know how to deal with packet ID %s", Util.hex( id ) );
diff --git a/proxy/src/main/java/net/md_5/bungee/packet/PacketHandler.java b/proxy/src/main/java/net/md_5/bungee/packet/PacketHandler.java
index 041842566..7826d0af2 100644
--- a/proxy/src/main/java/net/md_5/bungee/packet/PacketHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/packet/PacketHandler.java
@@ -1,11 +1,23 @@
package net.md_5.bungee.packet;
+import io.netty.buffer.ByteBuf;
+
public abstract class PacketHandler
{
- private void nop(DefinedPacket packet)
+ private void nop(Object msg)
{
- throw new UnsupportedOperationException( "No handler defined for packet " + packet.getClass() );
+ throw new UnsupportedOperationException( "No handler defined for packet " + msg.getClass() );
+ }
+
+ public void handle(ByteBuf buf) throws Exception
+ {
+ nop( buf );
+ }
+
+ public void handle(DefinedPacket packet) throws Exception
+ {
+ nop( packet );
}
public void handle(Packet0KeepAlive alive) throws Exception
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
deleted file mode 100644
index 01413568b..000000000
--- a/proxy/src/main/java/net/md_5/bungee/packet/PacketStream.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package net.md_5.bungee.packet;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.FilterInputStream;
-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;
-
-/**
- * A specialized input stream to parse packets using the Mojang packet
- * definitions and then return them as a byte array.
- */
-public class PacketStream implements AutoCloseable
-{
-
- private final DataInputStream dataInput;
- @Getter
- private OutputStream out;
- @Getter
- @Setter
- private int protocol;
- private final TrackingInputStream tracker;
- private final byte[] buffer = new byte[ 1 << 18 ];
-
- public PacketStream(InputStream in, int protocol)
- {
- this( in, null, protocol );
- }
-
- 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
- {
- out.write( b );
- }
-
- public void write(DefinedPacket packet) throws IOException
- {
- out.write( packet.getPacket() );
- }
-
- /**
- * Read an entire packet from the stream and return it as a byte array.
- *
- * @return the read packet
- * @throws IOException when the underlying input stream throws an exception
- */
- public byte[] readPacket() throws IOException
- {
- tracker.out.reset();
- DataInputPacketReader.readPacket( dataInput, buffer, protocol );
- return tracker.out.toByteArray();
- }
-
- @Override
- public void close() throws Exception
- {
- dataInput.close();
- }
-
- /**
- * Input stream which will wrap another stream and copy all bytes read to a
- * {@link ByteArrayOutputStream}.
- */
- private class TrackingInputStream extends FilterInputStream
- {
-
- private final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- public TrackingInputStream(InputStream in)
- {
- super( in );
- }
-
- @Override
- public int read() throws IOException
- {
- int ret = in.read();
- out.write( ret );
- return ret;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException
- {
- int ret = in.read( b, off, len );
- out.write( b, off, ret );
- return ret;
- }
- }
-}