diff --git a/protocol/pom.xml b/protocol/pom.xml
index a347f5cc..6b972fe5 100644
--- a/protocol/pom.xml
+++ b/protocol/pom.xml
@@ -23,6 +23,7 @@
io.netty
netty-buffer
4.0.0.Beta2
+ provided
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 52127e97..880e24e2 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -6,6 +6,7 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.channel.MultithreadEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
import net.md_5.bungee.config.Configuration;
import java.io.BufferedReader;
import java.io.File;
@@ -38,7 +39,7 @@ 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.PipelineUtils;
import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.PacketFAPluginMessage;
@@ -186,9 +187,11 @@ public class BungeeCord extends ProxyServer
for ( ListenerInfo info : config.getListeners() )
{
Channel server = new ServerBootstrap()
- .childHandler( ChannelBootstrapper.SERVER )
- .localAddress( info.getHost() )
+ .channel( NioServerSocketChannel.class)
+ .childHandler( PipelineUtils.SERVER_CHILD )
.group( eventLoops )
+ .localAddress( info.getHost() )
+ .attr( PipelineUtils.LISTENER, info)
.bind().channel();
listeners.add( server );
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 3bd3d24a..cd691b7c 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
@@ -9,6 +9,9 @@ import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.Server;
+import net.md_5.bungee.connection.PingHandler;
+import net.md_5.bungee.netty.HandlerBoss;
+import net.md_5.bungee.netty.PipelineUtils;
import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.PacketFAPluginMessage;
@@ -39,5 +42,6 @@ public class BungeeServerInfo extends ServerInfo
@Override
public void ping(final Callback callback)
{
+ PipelineUtils.connectClient( getAddress() ).channel().pipeline().get( HandlerBoss.class ).setHandler( new PingHandler( callback ) );
}
}
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 a1a4a83a..19d78af4 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -11,7 +11,8 @@ import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.event.ServerConnectedEvent;
-import net.md_5.bungee.netty.ChannelBootstrapper;
+import net.md_5.bungee.netty.HandlerBoss;
+import net.md_5.bungee.netty.PipelineUtils;
import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.Packet1Login;
import net.md_5.bungee.packet.Packet9Respawn;
@@ -25,7 +26,7 @@ public class ServerConnector extends PacketHandler
{
private final ProxyServer bungee;
- private final Channel ch;
+ private Channel ch;
private final UserConnection user;
private final ServerInfo target;
private State thisState = State.ENCRYPT_REQUEST;
@@ -36,6 +37,14 @@ public class ServerConnector extends PacketHandler
ENCRYPT_REQUEST, LOGIN, FINISHED;
}
+ @Override
+ public void connected(Channel channel) throws Exception
+ {
+ this.ch = channel;
+ channel.write( user.handshake );
+ channel.write( PacketCDClientStatus.CLIENT_LOGIN );
+ }
+
@Override
public void handle(Packet1Login login) throws Exception
{
@@ -112,16 +121,12 @@ public class ServerConnector extends PacketHandler
ProxyServer.getInstance().getPluginManager().callEvent( event );
final ServerInfo target = event.getTarget(); // Update in case the event changed target
- ChannelBootstrapper.CLIENT.connectClient( info.getAddress() ).addListener( new ChannelFutureListener()
+ PipelineUtils.connectClient( info.getAddress() ).addListener( new ChannelFutureListener()
{
@Override
public void operationComplete(ChannelFuture future) throws Exception
{
- if ( future.isSuccess() )
- {
- future.channel().write( user.handshake );
- future.channel().write( PacketCDClientStatus.CLIENT_LOGIN );
- } else
+ if ( !future.isSuccess() )
{
future.channel().close();
ServerInfo def = ProxyServer.getInstance().getServers().get( user.getPendingConnection().getListener().getDefaultServer() );
@@ -132,6 +137,6 @@ public class ServerConnector extends PacketHandler
}
}
}
- } ).channel();
+ } ).channel().pipeline().get( HandlerBoss.class).setHandler( new ServerConnector( ProxyServer.getInstance(), user, target));
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index 76921b60..a8ee0278 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -47,7 +47,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
private final ProxyServer bungee;
- private final Channel ch;
+ private Channel ch;
@Getter
private final ListenerInfo listener;
private Packet1Login forgeLogin;
@@ -66,6 +66,12 @@ public class InitialHandler extends PacketHandler implements PendingConnection
HANDSHAKE, ENCRYPT, LOGIN, FINISHED;
}
+ @Override
+ public void connected(Channel channel) throws Exception
+ {
+ this.ch = channel;
+ }
+
@Override
public void handle(Packet1Login login) throws Exception
{
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
deleted file mode 100644
index e4c81e7d..00000000
--- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelBootstrapper.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package net.md_5.bungee.netty;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelException;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.handler.timeout.ReadTimeoutHandler;
-import java.lang.reflect.Constructor;
-import java.net.SocketAddress;
-import java.util.concurrent.TimeUnit;
-import net.md_5.bungee.BungeeCord;
-import net.md_5.bungee.connection.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;
-
- public ChannelFuture connectClient(SocketAddress remoteAddress)
- {
- return new Bootstrap()
- .channel( NioSocketChannel.class )
- .group( BungeeCord.getInstance().eventLoops )
- .handler( this )
- .remoteAddress( remoteAddress )
- .connect();
- }
-
- 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/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
index f57b53cb..8dcbddef 100644
--- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
@@ -12,12 +12,12 @@ import net.md_5.bungee.packet.PacketHandler;
* channels to maintain simple states, and only call the required, adapted
* methods when the channel is connected.
*/
-class HandlerBoss extends ChannelInboundMessageHandlerAdapter
+public class HandlerBoss extends ChannelInboundMessageHandlerAdapter
{
private PacketHandler handler;
- HandlerBoss(PacketHandler handler)
+ public void setHandler(PacketHandler handler)
{
Preconditions.checkArgument( handler != null, "handler" );
this.handler = handler;
@@ -26,19 +26,25 @@ class HandlerBoss extends ChannelInboundMessageHandlerAdapter
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
{
- handler.connected( ctx.channel() );
+ if ( handler != null )
+ {
+ handler.connected( ctx.channel() );
+ }
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception
{
- handler.disconnected( ctx.channel() );
+ if ( handler != null )
+ {
+ handler.disconnected( ctx.channel() );
+ }
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf msg) throws Exception
{
- if ( ctx.channel().isActive() )
+ if ( handler != null && ctx.channel().isActive() )
{
DefinedPacket packet = DefinedPacket.packet( msg );
if ( packet != null )
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
new file mode 100644
index 00000000..56e69bac
--- /dev/null
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
@@ -0,0 +1,63 @@
+package net.md_5.bungee.netty;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelException;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.util.AttributeKey;
+import java.net.SocketAddress;
+import java.util.concurrent.TimeUnit;
+import net.md_5.bungee.BungeeCord;
+import net.md_5.bungee.connection.InitialHandler;
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.config.ListenerInfo;
+import net.md_5.bungee.protocol.PacketDefinitions;
+
+public class PipelineUtils
+{
+
+ public static final AttributeKey LISTENER = new AttributeKey<>( "ListerInfo" );
+ public static final ChannelInitializer SERVER_CHILD = new ChannelInitializer()
+ {
+ @Override
+ protected void initChannel(Channel ch) throws Exception
+ {
+ BASE.initChannel( ch );
+ ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( ProxyServer.getInstance(), ch.attr( LISTENER ).get() ) );
+ }
+ };
+ private static final Base BASE = new Base();
+
+ private final static class Base extends ChannelInitializer
+ {
+
+ @Override
+ public 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() );
+ }
+ };
+
+ public static ChannelFuture connectClient(SocketAddress remoteAddress)
+ {
+ return new Bootstrap()
+ .channel( NioSocketChannel.class )
+ .group( BungeeCord.getInstance().eventLoops )
+ .handler( BASE )
+ .remoteAddress( remoteAddress )
+ .connect();
+ }
+}