diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java b/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java index 4aa2d70637..84490c63bf 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/ComponentBuilder.java @@ -1,5 +1,6 @@ package net.md_5.bungee.api.chat; +import com.google.common.base.Preconditions; import net.md_5.bungee.api.ChatColor; import java.util.ArrayList; import java.util.List; @@ -25,7 +26,7 @@ public class ComponentBuilder { - private TextComponent current; + private BaseComponent current; private final List parts = new ArrayList(); /** @@ -53,6 +54,41 @@ public ComponentBuilder(String text) current = new TextComponent( text ); } + /** + * Appends the components to the builder and makes it the current target for + * formatting. The text will have all the formatting from the previous part. + * + * @param components the components to append + * @return this ComponentBuilder for chaining + */ + public ComponentBuilder append(BaseComponent[] components) + { + return append( components, FormatRetention.ALL ); + } + + /** + * Appends the components to the builder and makes it the current target for + * formatting. You can specify the amount of formatting retained. + * + * @param components the components to append + * @param retention the formatting to retain + * @return this ComponentBuilder for chaining + */ + public ComponentBuilder append(BaseComponent[] components, FormatRetention retention) + { + Preconditions.checkArgument( components.length != 0, "No components to append" ); + + for ( BaseComponent component : components ) + { + parts.add( current ); + + current = component.duplicate(); + retain( retention ); + } + + return this; + } + /** * Appends the text to the builder and makes it the current target for * formatting. The text will have all the formatting from the previous part. @@ -77,8 +113,8 @@ public ComponentBuilder append(String text, FormatRetention retention) { parts.add( current ); - current = new TextComponent( current ); - current.setText( text ); + current = new TextComponent( (TextComponent) current ); + ( (TextComponent) current ).setText( text ); retain( retention ); return this; @@ -215,13 +251,29 @@ public ComponentBuilder retain(FormatRetention retention) switch ( retention ) { case NONE: - current = new TextComponent( current.getText() ); + if ( current instanceof TextComponent ) + { + current = new TextComponent( ( (TextComponent) current ).getText() ); + } else if ( current instanceof TranslatableComponent ) + { + TranslatableComponent oldComponent = (TranslatableComponent) current; + current = new TranslatableComponent( oldComponent.getTranslate(), oldComponent.getWith() ); + } + break; case ALL: // No changes are required break; case EVENTS: - current = new TextComponent( current.getText() ); + if ( current instanceof TextComponent ) + { + current = new TextComponent( ( (TextComponent) current ).getText() ); + } else if ( current instanceof TranslatableComponent ) + { + TranslatableComponent oldComponent = (TranslatableComponent) current; + current = new TranslatableComponent( oldComponent.getTranslate(), oldComponent.getWith() ); + } + current.setInsertion( previous.getInsertion() ); current.setClickEvent( previous.getClickEvent() ); current.setHoverEvent( previous.getHoverEvent() ); diff --git a/pom.xml b/pom.xml index 8125d6375a..87bf735183 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ unknown - 4.1.13.Final + 4.1.15.Final 1.7 1.7 UTF-8 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 23b55ed454..0d51263c8a 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -39,6 +39,7 @@ import net.md_5.bungee.protocol.packet.Handshake; import net.md_5.bungee.protocol.packet.Kick; import net.md_5.bungee.protocol.packet.Login; +import net.md_5.bungee.protocol.packet.LoginRequest; import net.md_5.bungee.protocol.packet.LoginSuccess; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.Respawn; @@ -135,8 +136,8 @@ else if (!user.getExtraDataInHandshake().isEmpty()) { channel.write(copiedHandshake); channel.setProtocol(Protocol.LOGIN); - channel.write(user.getPendingConnection().getLoginRequest()); - } + channel.write(new LoginRequest(user.getName())); +} @Override public void disconnected(ChannelWrapper channel) throws Exception diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java index 2d65436a03..55c9804968 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java @@ -1,6 +1,7 @@ package net.md_5.bungee.connection; import com.google.common.base.Preconditions; +import io.netty.channel.Channel; import java.util.ArrayList; import java.util.List; import net.md_5.bungee.BungeeCord; @@ -83,6 +84,22 @@ public void disconnected(ChannelWrapper channel) throws Exception } } + @Override + public void writabilityChanged(ChannelWrapper channel) throws Exception + { + if ( con.getServer() != null ) + { + Channel server = con.getServer().getCh().getHandle(); + if ( channel.getHandle().isWritable() ) + { + server.config().setAutoRead( true ); + } else + { + server.config().setAutoRead( false ); + } + } + } + @Override public boolean shouldHandle(PacketWrapper packet) throws Exception { 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 93776626f9..bf8ec29f4d 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 @@ -64,6 +64,15 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception } } + @Override + public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception + { + if ( handler != null ) + { + handler.writabilityChanged( channel ); + } + } + @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java b/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java index 7958eaa368..7bd223d9ca 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java @@ -28,4 +28,8 @@ public void connected(ChannelWrapper channel) throws Exception public void disconnected(ChannelWrapper channel) throws Exception { } + + public void writabilityChanged(ChannelWrapper channel) throws Exception + { + } } 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 index f239c7d834..551ae1e193 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java @@ -7,6 +7,7 @@ import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.ServerChannel; +import io.netty.channel.WriteBufferWaterMark; import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollDatagramChannel; import io.netty.channel.epoll.EpollEventLoopGroup; @@ -115,6 +116,10 @@ public static Class getDatagramChannel() return epoll ? EpollDatagramChannel.class : NioDatagramChannel.class; } + private static final int LOW_MARK = Integer.getInteger( "net.md_5.bungee.low_mark", 2 << 18 ); // 0.5 mb + private static final int HIGH_MARK = Integer.getInteger( "net.md_5.bungee.high_mark", 2 << 20 ); // 2 mb + private static final WriteBufferWaterMark MARK = new WriteBufferWaterMark( LOW_MARK, HIGH_MARK ); + public final static class Base extends ChannelInitializer { @@ -129,6 +134,7 @@ public void initChannel(Channel ch) throws Exception // IP_TOS is not supported (Windows XP / Windows Server 2003) } ch.config().setAllocator( PooledByteBufAllocator.DEFAULT ); + ch.config().setWriteBufferWaterMark( MARK ); ch.pipeline().addLast( TIMEOUT_HANDLER, new ReadTimeoutHandler( BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS ) ); ch.pipeline().addLast( FRAME_DECODER, new Varint21FrameDecoder() ); diff --git a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java index 004a2b7a88..c844dab595 100644 --- a/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java +++ b/proxy/src/test/java/net/md_5/bungee/chat/ComponentsTest.java @@ -13,6 +13,23 @@ public class ComponentsTest { + @Test + public void testBuilderAppend() + { + ClickEvent clickEvent = new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/help " ); + HoverEvent hoverEvent = new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( "Hello world" ).create() ); + + ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW ); + builder.append( new ComponentBuilder( "world!" ).color( ChatColor.GREEN ).event( hoverEvent ).event( clickEvent ).create() ); + + BaseComponent[] components = builder.create(); + + Assert.assertEquals( components[1].getHoverEvent(), hoverEvent ); + Assert.assertEquals( components[1].getClickEvent(), clickEvent ); + Assert.assertEquals( "Hello world!", BaseComponent.toPlainText( components ) ); + Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) ); + } + @Test public void testBasicComponent() {