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 4a1b28ce7a..7ffc8357f6 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -397,6 +397,13 @@ public void run() connectionLock.readLock().unlock(); } + try + { + Thread.sleep( 500 ); + } catch ( InterruptedException ex ) + { + } + getLogger().info( "Closing IO threads" ); eventLoops.shutdownGracefully(); try 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 8c1260af32..b795bf9052 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -52,17 +52,7 @@ public void disconnect(BaseComponent... reason) { Preconditions.checkArgument( reason.length == 0, "Server cannot have disconnect reason" ); - if ( !ch.isClosed() ) - { - ch.getHandle().eventLoop().schedule( new Runnable() - { - @Override - public void run() - { - ch.getHandle().close(); - } - }, 100, TimeUnit.MILLISECONDS ); - } + ch.delayedClose( null ); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 65ace9cd2e..812dec3e19 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -372,15 +372,7 @@ public void disconnect0(final BaseComponent... reason) getName(), BaseComponent.toLegacyText( reason ) } ); - ch.delayedClose( new Runnable() - { - - @Override - public void run() - { - unsafe().sendPacket( new Kick( ComponentSerializer.toString( reason ) ) ); - } - } ); + ch.delayedClose( new Kick( ComponentSerializer.toString( reason ) ) ); if ( server != null ) { @@ -624,7 +616,7 @@ public String getExtraDataInHandshake() public void setCompressionThreshold(int compressionThreshold) { - if ( ch.getHandle().isActive() && this.compressionThreshold == -1 && getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_8 && compressionThreshold >= 0 ) + if ( !ch.isClosing() && this.compressionThreshold == -1 && getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_8 && compressionThreshold >= 0 ) { this.compressionThreshold = compressionThreshold; unsafe.sendPacket( new SetCompression( compressionThreshold ) ); 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 8a67a1f08f..16782e58f9 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 @@ -140,8 +140,7 @@ public void handle(PluginMessage pluginMessage) throws Exception public void handle(LegacyHandshake legacyHandshake) throws Exception { this.legacy = true; - ch.getHandle().writeAndFlush( bungee.getTranslation( "outdated_client" ) ); - ch.close(); + ch.close( bungee.getTranslation( "outdated_client" ) ); } @Override @@ -492,7 +491,7 @@ public void done(LoginEvent result, Throwable error) @Override public void run() { - if ( ch.getHandle().isActive() ) + if ( !ch.isClosing() ) { UserConnection userCon = new UserConnection( bungee, ch, getName(), InitialHandler.this ); userCon.setCompressionThreshold( BungeeCord.getInstance().config.getCompressionThreshold() ); @@ -544,18 +543,13 @@ public void disconnect(String reason) @Override public void disconnect(final BaseComponent... reason) { - ch.delayedClose( new Runnable() + if ( thisState != State.STATUS && thisState != State.PING ) { - - @Override - public void run() - { - if ( thisState != State.STATUS && thisState != State.PING ) - { - unsafe().sendPacket( new Kick( ComponentSerializer.toString( reason ) ) ); - } - } - } ); + ch.delayedClose( new Kick( ComponentSerializer.toString( reason ) ) ); + } else + { + ch.close(); + } } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java index 0b0dd736e5..28a4f17604 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java @@ -2,6 +2,7 @@ import com.google.common.base.Preconditions; import io.netty.channel.Channel; +import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import java.util.concurrent.TimeUnit; @@ -12,6 +13,7 @@ import net.md_5.bungee.protocol.MinecraftEncoder; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.packet.Kick; public class ChannelWrapper { @@ -56,41 +58,53 @@ public void write(Object packet) } public void close() + { + close( null ); + } + + public void close(Object packet) { if ( !closed ) { closed = closing = true; - ch.flush(); - ch.close(); + + if ( packet != null && ch.isActive() ) + { + ch.writeAndFlush( packet ).addListeners( ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, ChannelFutureListener.CLOSE ); + ch.eventLoop().schedule( new Runnable() + { + @Override + public void run() + { + ch.close(); + } + }, 250, TimeUnit.MILLISECONDS ); + } else + { + ch.flush(); + ch.close(); + } } } - public void delayedClose(final Runnable runnable) + public void delayedClose(final Kick kick) { - Preconditions.checkArgument( runnable != null, "runnable" ); - if ( !closing ) { closing = true; // Minecraft client can take some time to switch protocols. // Sending the wrong disconnect packet whilst a protocol switch is in progress will crash it. - // Delay 500ms to ensure that the protocol switch (if any) has definitely taken place. + // Delay 250ms to ensure that the protocol switch (if any) has definitely taken place. ch.eventLoop().schedule( new Runnable() { @Override public void run() { - try - { - runnable.run(); - } finally - { - ChannelWrapper.this.close(); - } + close( kick ); } - }, 500, TimeUnit.MILLISECONDS ); + }, 250, TimeUnit.MILLISECONDS ); } }