From a12bb4ceadad34b3cfb3edcfabc1b24f593ad85b Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 29 Dec 2018 13:01:53 +1100 Subject: [PATCH 01/22] Clarify boolean of connect callback --- .../java/net/md_5/bungee/api/connection/ProxiedPlayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java b/api/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java index e3e999b0db..867e4428ef 100644 --- a/api/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java +++ b/api/src/main/java/net/md_5/bungee/api/connection/ProxiedPlayer.java @@ -107,7 +107,7 @@ public enum MainHand * @param target the new server to connect to * @param callback the method called when the connection is complete, or * when an exception is encountered. The boolean parameter denotes success - * or failure. + * (true) or failure (false). */ void connect(ServerInfo target, Callback callback); @@ -119,7 +119,7 @@ public enum MainHand * @param target the new server to connect to * @param callback the method called when the connection is complete, or * when an exception is encountered. The boolean parameter denotes success - * or failure. + * (true) or failure (false). * @param reason the reason for connecting to the new server */ void connect(ServerInfo target, Callback callback, ServerConnectEvent.Reason reason); From 4fa1d82b8130b1cdfe627ab0f18368b065897625 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 3 Jan 2019 16:35:32 +1100 Subject: [PATCH 02/22] #2572: Add additional APIs regarding server restriction --- .../net/md_5/bungee/api/config/ServerInfo.java | 16 ++++++++++++++++ .../bungee/api/ServerConnectRequestTest.java | 14 +++++++++++++- .../java/net/md_5/bungee/BungeeServerInfo.java | 8 +++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java b/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java index 7b7c987f0e..1977384330 100644 --- a/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java +++ b/api/src/main/java/net/md_5/bungee/api/config/ServerInfo.java @@ -43,6 +43,22 @@ public interface ServerInfo */ String getMotd(); + /** + * Whether this server is restricted and therefore only players with the + * given permission can access it. + * + * @return if restricted + */ + boolean isRestricted(); + + /** + * Get the permission required to access this server. Only enforced when the + * server is restricted. + * + * @return access permission + */ + String getPermission(); + /** * Whether the player can access this server. It will only return false when * the player has no permission and this server is restricted. diff --git a/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java b/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java index 4a02837998..0d1f801a06 100644 --- a/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java +++ b/api/src/test/java/net/md_5/bungee/api/ServerConnectRequestTest.java @@ -38,11 +38,23 @@ public String getMotd() } @Override - public boolean canAccess(CommandSender sender) + public boolean isRestricted() { return false; } + @Override + public String getPermission() + { + return null; + } + + @Override + public boolean canAccess(CommandSender sender) + { + return true; + } + @Override public void sendData(String channel, byte[] data) { 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 c0703afaa4..3ff3446b5a 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java @@ -69,11 +69,17 @@ public Collection getPlayers() return Collections.unmodifiableCollection( new HashSet<>( players ) ); } + @Override + public String getPermission() + { + return "bungeecord.server." + name; + } + @Override public boolean canAccess(CommandSender player) { Preconditions.checkNotNull( player, "player" ); - return !restricted || player.hasPermission( "bungeecord.server." + name ); + return !restricted || player.hasPermission( getPermission() ); } @Override From 9a2acc826e4cc37642219f718cdb8c1eca0c8703 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 3 Jan 2019 16:39:38 +1100 Subject: [PATCH 03/22] #2569: Respect disabled_commands setting for 1.13 tab completion --- .../main/java/net/md_5/bungee/connection/DownstreamBridge.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java index 25b8172215..a007d4540b 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -544,7 +544,7 @@ public void handle(Commands commands) throws Exception { for ( Map.Entry command : bungee.getPluginManager().getCommands() ) { - if ( commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) ) + if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) ) { LiteralCommandNode dummy = LiteralArgumentBuilder.literal( command.getKey() ) .then( RequiredArgumentBuilder.argument( "args", StringArgumentType.greedyString() ) From 8b5a89bf12f67a76b610e908c4536d5a53646c7c Mon Sep 17 00:00:00 2001 From: Virizion <9b717b9d4e5f09e89fa3@gmail.com> Date: Mon, 7 Jan 2019 01:40:48 -0500 Subject: [PATCH 04/22] #2576: Allow plugins to register multiple intents for async events --- .../net/md_5/bungee/api/event/AsyncEvent.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java b/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java index 050da40305..63f34307fe 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java @@ -1,8 +1,7 @@ package net.md_5.bungee.api.event; import com.google.common.base.Preconditions; -import java.util.Collections; -import java.util.Set; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -25,7 +24,7 @@ public class AsyncEvent extends Event { private final Callback done; - private final Set intents = Collections.newSetFromMap( new ConcurrentHashMap() ); + private final Map intents = new ConcurrentHashMap(); private final AtomicBoolean fired = new AtomicBoolean(); private final AtomicInteger latch = new AtomicInteger(); @@ -43,30 +42,40 @@ public void postCall() /** * Register an intent that this plugin will continue to perform work on a * background task, and wishes to let the event proceed once the registered - * background task has completed. + * background task has completed. Multiple intents can be registered by a + * plugin, but the plugin must complete the same amount of intents for the + * event to proceed. * * @param plugin the plugin registering this intent */ public void registerIntent(Plugin plugin) { Preconditions.checkState( !fired.get(), "Event %s has already been fired", this ); - Preconditions.checkState( !intents.contains( plugin ), "Plugin %s already registered intent for event %s", plugin, this ); - intents.add( plugin ); + AtomicInteger intentCount = intents.get( plugin ); + if ( intentCount == null ) + { + intents.put( plugin, new AtomicInteger( 1 ) ); + } else + { + intentCount.incrementAndGet(); + } latch.incrementAndGet(); } /** - * Notifies this event that this plugin has done all its required processing - * and wishes to let the event proceed. + * Notifies this event that this plugin has completed an intent and wishes + * to let the event proceed once all intents have been completed. * * @param plugin a plugin which has an intent registered for this event */ @SuppressWarnings("unchecked") public void completeIntent(Plugin plugin) { - Preconditions.checkState( intents.contains( plugin ), "Plugin %s has not registered intent for event %s", plugin, this ); - intents.remove( plugin ); + AtomicInteger intentCount = intents.get( plugin ); + Preconditions.checkState( intentCount != null && intentCount.get() > 0, "Plugin %s has not registered intents for event %s", plugin, this ); + + intentCount.decrementAndGet(); if ( fired.get() ) { if ( latch.decrementAndGet() == 0 ) From 712a60ffd24ab28130c225391195041ff8a40c89 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 9 Jan 2019 10:19:18 +1100 Subject: [PATCH 05/22] Remove improperly exposed getters from AsyncEvent --- api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java b/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java index 63f34307fe..cf85ca06d7 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java @@ -5,8 +5,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import lombok.AccessLevel; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.ToString; import net.md_5.bungee.api.Callback; import net.md_5.bungee.api.plugin.Event; @@ -18,13 +20,14 @@ * @param Type of this event */ @Data +@Getter(AccessLevel.NONE) @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class AsyncEvent extends Event { private final Callback done; - private final Map intents = new ConcurrentHashMap(); + private final Map intents = new ConcurrentHashMap<>(); private final AtomicBoolean fired = new AtomicBoolean(); private final AtomicInteger latch = new AtomicInteger(); From 3889f8683d75677e35ada48b0477270a85d8411a Mon Sep 17 00:00:00 2001 From: Simon Chuu Date: Sat, 19 Jan 2019 00:15:40 -0500 Subject: [PATCH 06/22] #2578: Add easy way to get proxy command iff it is enabled for that sender --- .../net/md_5/bungee/api/event/ChatEvent.java | 23 +++++++++++++ .../md_5/bungee/api/plugin/PluginManager.java | 33 +++++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java b/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java index 067a800cf4..9b36b91ebe 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java @@ -3,8 +3,11 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.Connection; import net.md_5.bungee.api.plugin.Cancellable; +import net.md_5.bungee.api.plugin.PluginManager; /** * Event called when a player sends a message to a server. @@ -39,4 +42,24 @@ public boolean isCommand() { return message.length() > 0 && message.charAt( 0 ) == '/'; } + + /** + * Checks whether this message is run on this proxy server. + * + * @return if this command runs on the proxy + * @see PluginManager#isExecutableCommand(java.lang.String, net.md_5.bungee.api.CommandSender) + */ + public boolean isProxyCommand() + { + if ( !isCommand() ) + { + return false; + } + + int index = message.indexOf( " " ); + String commandName = ( index == -1 ) ? message.substring( 1 ) : message.substring( 1, index ); + CommandSender sender = ( getSender() instanceof CommandSender ) ? (CommandSender) getSender() : null; + + return ProxyServer.getInstance().getPluginManager().isExecutableCommand( commandName, sender ); + } } diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java index 3a871787f8..bf894e4a21 100644 --- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java +++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java @@ -111,6 +111,32 @@ public void unregisterCommands(Plugin plugin) } } + private Command getCommandIfEnabled(String commandName, CommandSender sender) + { + String commandLower = commandName.toLowerCase( Locale.ROOT ); + + // Check if command is disabled when a player sent the command + if ( ( sender instanceof ProxiedPlayer ) && proxy.getDisabledCommands().contains( commandLower ) ) + { + return null; + } + + return commandMap.get( commandLower ); + } + + /** + * Checks if the command is registered and can possibly be executed by the + * sender (without taking permissions into account). + * + * @param commandName the name of the command + * @param sender the sender executing the command + * @return whether the command will be handled + */ + public boolean isExecutableCommand(String commandName, CommandSender sender) + { + return getCommandIfEnabled( commandName, sender ) != null; + } + public boolean dispatchCommand(CommandSender sender, String commandLine) { return dispatchCommand( sender, commandLine, null ); @@ -133,12 +159,7 @@ public boolean dispatchCommand(CommandSender sender, String commandLine, List Date: Sat, 19 Jan 2019 19:48:29 +0100 Subject: [PATCH 07/22] #2584: Add ComponentBuilder#appendLegacy --- .../net/md_5/bungee/api/chat/ComponentBuilder.java | 13 +++++++++++++ .../net/md_5/bungee/api/chat/ComponentsTest.java | 12 ++++++++++++ 2 files changed, 25 insertions(+) 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 dfdc7bf0b1..6e8306ffd5 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 @@ -146,6 +146,19 @@ public ComponentBuilder append(String text) return append( text, FormatRetention.ALL ); } + /** + * Parse text to BaseComponent[] with colors and format, appends the text to + * the builder and makes it the current target for formatting. The component + * will have all the formatting from previous part. + * + * @param text the text to append + * @return this ComponentBuilder for chaining + */ + public ComponentBuilder appendLegacy(String text) + { + return append( TextComponent.fromLegacyText( text ) ); + } + /** * Appends the text to the builder and makes it the current target for * formatting. You can specify the amount of formatting retained from diff --git a/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java b/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java index 27b5bbeaf9..bb38f1b1cc 100644 --- a/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java +++ b/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java @@ -92,6 +92,18 @@ public void testBuilderAppend() Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) ); } + @Test + public void testBuilderAppendLegacy() + { + ComponentBuilder builder = new ComponentBuilder( "Hello " ).color( ChatColor.YELLOW ); + builder.appendLegacy( "§aworld!" ); + + BaseComponent[] components = builder.create(); + + Assert.assertEquals( "Hello world!", BaseComponent.toPlainText( components ) ); + Assert.assertEquals( ChatColor.YELLOW + "Hello " + ChatColor.GREEN + "world!", BaseComponent.toLegacyText( components ) ); + } + @Test public void testBasicComponent() { From 29c093f83f4f8be42799ee0bf1e1cec97c6b793f Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 30 Jan 2019 11:33:04 +1100 Subject: [PATCH 08/22] #2586: TabCompleteResponseEvent for 1.13 --- .../bungee/connection/DownstreamBridge.java | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java index a007d4540b..75aebc6542 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -1,17 +1,24 @@ package net.md_5.bungee.connection; +import com.google.common.base.Function; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.context.StringRange; +import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.tree.LiteralCommandNode; import java.io.DataInput; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.Unpooled; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import net.md_5.bungee.BungeeCord; @@ -497,16 +504,44 @@ public void handle(SetCompression setCompression) throws Exception @Override public void handle(TabCompleteResponse tabCompleteResponse) throws Exception { - if ( tabCompleteResponse.getCommands() == null ) + List commands = tabCompleteResponse.getCommands(); + if ( commands == null ) { - // Passthrough on 1.13 style command responses - unclear of a sane way to process them at the moment, contributions welcome - return; + commands = Lists.transform( tabCompleteResponse.getSuggestions().getList(), new Function() + { + @Override + public String apply(Suggestion input) + { + return input.getText(); + } + } ); } - TabCompleteResponseEvent tabCompleteResponseEvent = new TabCompleteResponseEvent( server, con, tabCompleteResponse.getCommands() ); - + TabCompleteResponseEvent tabCompleteResponseEvent = new TabCompleteResponseEvent( server, con, new ArrayList<>( commands ) ); if ( !bungee.getPluginManager().callEvent( tabCompleteResponseEvent ).isCancelled() ) { + // Take action only if modified + if ( !commands.equals( tabCompleteResponseEvent.getSuggestions() ) ) + { + if ( tabCompleteResponse.getCommands() != null ) + { + // Classic style + tabCompleteResponse.setCommands( tabCompleteResponseEvent.getSuggestions() ); + } else + { + // Brigadier style + final StringRange range = tabCompleteResponse.getSuggestions().getRange(); + tabCompleteResponse.setSuggestions( new Suggestions( range, Lists.transform( tabCompleteResponseEvent.getSuggestions(), new Function() + { + @Override + public Suggestion apply(String input) + { + return new Suggestion( range, input ); + } + } ) ) ); + } + } + con.unsafe().sendPacket( tabCompleteResponse ); } From 219d55dfda6764aec56478e19ba00c002fa8094e Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 30 Jan 2019 15:45:47 +1100 Subject: [PATCH 09/22] #2592: Fix null tooltip string --- .../net/md_5/bungee/protocol/packet/TabCompleteResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java index 64851ddeae..7206bed56f 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java @@ -79,7 +79,7 @@ public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protoc { writeString( suggestion.getText(), buf ); buf.writeBoolean( suggestion.getTooltip() != null ); - if ( suggestion.getTooltip() != null ) + if ( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null ) { writeString( suggestion.getTooltip().getString(), buf ); } From 96b1fb1f0e5430829dd8a54ed24db5ab75c3c49f Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 30 Jan 2019 16:17:55 +1100 Subject: [PATCH 10/22] #2593: Fix null tooltip string v2 --- .../net/md_5/bungee/protocol/packet/TabCompleteResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java index 7206bed56f..79384bf5f3 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteResponse.java @@ -78,7 +78,7 @@ public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protoc for ( Suggestion suggestion : suggestions.getList() ) { writeString( suggestion.getText(), buf ); - buf.writeBoolean( suggestion.getTooltip() != null ); + buf.writeBoolean( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null ); if ( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null ) { writeString( suggestion.getTooltip().getString(), buf ); From 0dd538f9ff77c20da72c4530b3d21633799bc3a5 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 30 Jan 2019 22:05:59 +1100 Subject: [PATCH 11/22] #2594: Add second way of catching exceptions when handling UDP query --- .../main/java/net/md_5/bungee/query/QueryHandler.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/query/src/main/java/net/md_5/bungee/query/QueryHandler.java b/query/src/main/java/net/md_5/bungee/query/QueryHandler.java index 79d6886a60..9b81197f22 100644 --- a/query/src/main/java/net/md_5/bungee/query/QueryHandler.java +++ b/query/src/main/java/net/md_5/bungee/query/QueryHandler.java @@ -50,6 +50,17 @@ private void writeString(ByteBuf buf, String s) @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception + { + try + { + handleMessage( ctx, msg ); + } catch ( Throwable t ) + { + bungee.getLogger().log( Level.WARNING, "Error whilst handling query packet from " + msg.sender(), t ); + } + } + + private void handleMessage(ChannelHandlerContext ctx, DatagramPacket msg) { ByteBuf in = msg.content(); if ( in.readUnsignedByte() != 0xFE || in.readUnsignedByte() != 0xFD ) From 1a06ebeee018b19a30b68491150cc91a7cf3e298 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 3 Feb 2019 08:26:03 +1100 Subject: [PATCH 12/22] #2599: Remove connection throttle if proxy protocol in use --- proxy/src/main/java/net/md_5/bungee/BungeeCord.java | 6 ++++++ 1 file changed, 6 insertions(+) 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 3550690b44..60382062c5 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -306,6 +306,12 @@ public void startListeners() if ( info.isProxyProtocol() ) { getLogger().log( Level.WARNING, "Using PROXY protocol for listener {0}, please ensure this listener is adequately firewalled.", info.getHost() ); + + if ( connectionThrottle != null ) + { + connectionThrottle = null; + getLogger().log( Level.WARNING, "Since PROXY protocol is in use, internel connection throttle has been disabled." ); + } } ChannelFutureListener listener = new ChannelFutureListener() From 28c82238d0ef880b4ba79bd1516eb652bf2513c5 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 3 Feb 2019 17:58:46 +1100 Subject: [PATCH 13/22] Fix typo in previous commit --- proxy/src/main/java/net/md_5/bungee/BungeeCord.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 60382062c5..6599e38e42 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -310,7 +310,7 @@ public void startListeners() if ( connectionThrottle != null ) { connectionThrottle = null; - getLogger().log( Level.WARNING, "Since PROXY protocol is in use, internel connection throttle has been disabled." ); + getLogger().log( Level.WARNING, "Since PROXY protocol is in use, internal connection throttle has been disabled." ); } } From 0d6f3ee3745a9d551c90ca654e0092b6f173ce0c Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 17 Feb 2019 10:10:41 +1100 Subject: [PATCH 14/22] Make 1.13 command injection normal functionality --- .../net/md_5/bungee/protocol/Protocol.java | 11 ++++------- .../net/md_5/bungee/conf/Configuration.java | 6 ------ .../bungee/connection/DownstreamBridge.java | 19 ++++++++----------- .../bungee/connection/UpstreamBridge.java | 2 +- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java index 6e2abdc54f..e6c3729ccd 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java @@ -180,13 +180,10 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_12, 0x1B ), map( ProtocolConstants.MINECRAFT_1_13, 0x1C ) ); - if ( Boolean.getBoolean( "net.md-5.bungee.protocol.register_commands" ) ) - { - TO_CLIENT.registerPacket( - Commands.class, - map( ProtocolConstants.MINECRAFT_1_13, 0x11 ) - ); - } + TO_CLIENT.registerPacket( + Commands.class, + map( ProtocolConstants.MINECRAFT_1_13, 0x11 ) + ); TO_SERVER.registerPacket( KeepAlive.class, diff --git a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java index 77d2834803..49638c3aad 100644 --- a/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/conf/Configuration.java @@ -61,7 +61,6 @@ public class Configuration implements ProxyConfig private int compressionThreshold = 256; private boolean preventProxyConnections; private boolean forgeSupport; - private boolean injectCommands; public void load() { @@ -93,11 +92,6 @@ public void load() compressionThreshold = adapter.getInt( "network_compression_threshold", compressionThreshold ); preventProxyConnections = adapter.getBoolean( "prevent_proxy_connections", preventProxyConnections ); forgeSupport = adapter.getBoolean( "forge_support", forgeSupport ); - injectCommands = adapter.getBoolean( "inject_commands", injectCommands ); - if ( injectCommands ) - { - System.setProperty( "net.md-5.bungee.protocol.register_commands", "true" ); - } disabledCommands = new CaseInsensitiveSet( (Collection) adapter.getList( "disabled_commands", Arrays.asList( "disabledcommandhere" ) ) ); diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java index 75aebc6542..0f96a79650 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -575,20 +575,17 @@ public void handle(Commands commands) throws Exception { boolean modified = false; - if ( BungeeCord.getInstance().config.isInjectCommands() ) + for ( Map.Entry command : bungee.getPluginManager().getCommands() ) { - for ( Map.Entry command : bungee.getPluginManager().getCommands() ) + if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) ) { - if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) ) - { - LiteralCommandNode dummy = LiteralArgumentBuilder.literal( command.getKey() ) - .then( RequiredArgumentBuilder.argument( "args", StringArgumentType.greedyString() ) - .suggests( Commands.SuggestionRegistry.ASK_SERVER ) ) - .build(); - commands.getRoot().addChild( dummy ); + LiteralCommandNode dummy = LiteralArgumentBuilder.literal( command.getKey() ) + .then( RequiredArgumentBuilder.argument( "args", StringArgumentType.greedyString() ) + .suggests( Commands.SuggestionRegistry.ASK_SERVER ) ) + .build(); + commands.getRoot().addChild( dummy ); - modified = true; - } + modified = true; } } 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 83d7630e03..540cf21348 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 @@ -176,7 +176,7 @@ public void handle(TabCompleteRequest tabComplete) throws Exception if ( con.getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_13 ) { con.unsafe().sendPacket( new TabCompleteResponse( results ) ); - } else if ( BungeeCord.getInstance().config.isInjectCommands() ) + } else { int start = tabComplete.getCursor().lastIndexOf( ' ' ) + 1; int end = tabComplete.getCursor().length(); From 6d6fbb5efa06259166cc2e6f56e6320bf0d6316d Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 17 Feb 2019 10:13:24 +1100 Subject: [PATCH 15/22] Fix two minor formatting issues --- proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java | 2 +- .../java/net/md_5/bungee/util/ChatComponentTransformer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java index af4da07180..1ecee69e51 100644 --- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java @@ -242,7 +242,7 @@ protected static void rewriteMetaVarInt(ByteBuf packet, int oldId, int newId, in private static void readSkipSlot(ByteBuf packet, int protocolVersion) { - if ( (protocolVersion >= ProtocolConstants.MINECRAFT_1_13_2) ? packet.readBoolean() : packet.readShort() != -1 ) + if ( ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13_2 ) ? packet.readBoolean() : packet.readShort() != -1 ) { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13_2 ) { diff --git a/proxy/src/main/java/net/md_5/bungee/util/ChatComponentTransformer.java b/proxy/src/main/java/net/md_5/bungee/util/ChatComponentTransformer.java index ad26893e2b..d69c35d90d 100644 --- a/proxy/src/main/java/net/md_5/bungee/util/ChatComponentTransformer.java +++ b/proxy/src/main/java/net/md_5/bungee/util/ChatComponentTransformer.java @@ -51,7 +51,7 @@ public static ChatComponentTransformer getInstance() */ public BaseComponent[] transform(ProxiedPlayer player, BaseComponent... component) { - if ( component == null || component.length < 1 || ( component.length == 1 && component[0] == null ) ) + if ( component == null || component.length < 1 || ( component.length == 1 && component[0] == null ) ) { return new BaseComponent[] { From 9133a6f511b4cfaca5e6a6671b58a6c3b10821ab Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 26 Feb 2019 13:05:02 +1100 Subject: [PATCH 16/22] Simplify packet registration --- .../net/md_5/bungee/protocol/Protocol.java | 128 ++++++------------ .../bungee/protocol/ProtocolConstants.java | 3 +- 2 files changed, 44 insertions(+), 87 deletions(-) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java index e6c3729ccd..56d8a0de32 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java @@ -1,16 +1,13 @@ package net.md_5.bungee.protocol; import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; import gnu.trove.map.TIntObjectMap; import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TObjectIntHashMap; import java.lang.reflect.Constructor; -import java.util.Arrays; -import java.util.List; +import lombok.Data; import lombok.Getter; -import lombok.RequiredArgsConstructor; import net.md_5.bungee.protocol.packet.BossBar; import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.ClientSettings; @@ -65,21 +62,18 @@ public enum Protocol KeepAlive.class, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ), map( ProtocolConstants.MINECRAFT_1_9, 0x1F ), - map( ProtocolConstants.MINECRAFT_1_12, 0x1F ), map( ProtocolConstants.MINECRAFT_1_13, 0x21 ) ); TO_CLIENT.registerPacket( Login.class, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), map( ProtocolConstants.MINECRAFT_1_9, 0x23 ), - map( ProtocolConstants.MINECRAFT_1_12, 0x23 ), map( ProtocolConstants.MINECRAFT_1_13, 0x25 ) ); TO_CLIENT.registerPacket( Chat.class, map( ProtocolConstants.MINECRAFT_1_8, 0x02 ), map( ProtocolConstants.MINECRAFT_1_9, 0x0F ), - map( ProtocolConstants.MINECRAFT_1_12, 0x0F ), map( ProtocolConstants.MINECRAFT_1_13, 0x0E ) ); TO_CLIENT.registerPacket( @@ -92,15 +86,12 @@ public enum Protocol ); TO_CLIENT.registerPacket( BossBar.class, - map( ProtocolConstants.MINECRAFT_1_9, 0x0C ), - map( ProtocolConstants.MINECRAFT_1_12, 0x0C ), - map( ProtocolConstants.MINECRAFT_1_13, 0x0C ) + map( ProtocolConstants.MINECRAFT_1_9, 0x0C ) ); TO_CLIENT.registerPacket( PlayerListItem.class, // PlayerInfo map( ProtocolConstants.MINECRAFT_1_8, 0x38 ), map( ProtocolConstants.MINECRAFT_1_9, 0x2D ), - map( ProtocolConstants.MINECRAFT_1_12, 0x2D ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x2E ), map( ProtocolConstants.MINECRAFT_1_13, 0x30 ) ); @@ -108,7 +99,6 @@ public enum Protocol TabCompleteResponse.class, map( ProtocolConstants.MINECRAFT_1_8, 0x3A ), map( ProtocolConstants.MINECRAFT_1_9, 0x0E ), - map( ProtocolConstants.MINECRAFT_1_12, 0x0E ), map( ProtocolConstants.MINECRAFT_1_13, 0x10 ) ); TO_CLIENT.registerPacket( @@ -147,14 +137,12 @@ public enum Protocol PluginMessage.class, map( ProtocolConstants.MINECRAFT_1_8, 0x3F ), map( ProtocolConstants.MINECRAFT_1_9, 0x18 ), - map( ProtocolConstants.MINECRAFT_1_12, 0x18 ), map( ProtocolConstants.MINECRAFT_1_13, 0x19 ) ); TO_CLIENT.registerPacket( Kick.class, map( ProtocolConstants.MINECRAFT_1_8, 0x40 ), map( ProtocolConstants.MINECRAFT_1_9, 0x1A ), - map( ProtocolConstants.MINECRAFT_1_12, 0x1A ), map( ProtocolConstants.MINECRAFT_1_13, 0x1B ) ); TO_CLIENT.registerPacket( @@ -177,7 +165,6 @@ public enum Protocol EntityStatus.class, map( ProtocolConstants.MINECRAFT_1_8, 0x1A ), map( ProtocolConstants.MINECRAFT_1_9, 0x1B ), - map( ProtocolConstants.MINECRAFT_1_12, 0x1B ), map( ProtocolConstants.MINECRAFT_1_13, 0x1C ) ); TO_CLIENT.registerPacket( @@ -198,8 +185,7 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), map( ProtocolConstants.MINECRAFT_1_9, 0x02 ), map( ProtocolConstants.MINECRAFT_1_12, 0x03 ), - map( ProtocolConstants.MINECRAFT_1_12_1, 0x02 ), - map( ProtocolConstants.MINECRAFT_1_13, 0x02 ) + map( ProtocolConstants.MINECRAFT_1_12_1, 0x02 ) ); TO_SERVER.registerPacket( TabCompleteRequest.class, @@ -214,8 +200,7 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_8, 0x15 ), map( ProtocolConstants.MINECRAFT_1_9, 0x04 ), map( ProtocolConstants.MINECRAFT_1_12, 0x05 ), - map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 ), - map( ProtocolConstants.MINECRAFT_1_13, 0x04 ) + map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 ) ); TO_SERVER.registerPacket( PluginMessage.class, @@ -294,8 +279,8 @@ public enum Protocol /*========================================================================*/ public static final int MAX_PACKET_ID = 0xFF; /*========================================================================*/ - public final DirectionData TO_SERVER = new DirectionData( this, ProtocolConstants.Direction.TO_SERVER ); - public final DirectionData TO_CLIENT = new DirectionData( this, ProtocolConstants.Direction.TO_CLIENT ); + final DirectionData TO_SERVER = new DirectionData( this, ProtocolConstants.Direction.TO_SERVER ); + final DirectionData TO_CLIENT = new DirectionData( this, ProtocolConstants.Direction.TO_CLIENT ); public static void main(String[] args) { @@ -331,7 +316,7 @@ private static void dump(int version, DirectionData data) } } - @RequiredArgsConstructor + @Data private static class ProtocolData { @@ -340,7 +325,7 @@ private static class ProtocolData private final Constructor[] packetConstructors = new Constructor[ MAX_PACKET_ID ]; } - @RequiredArgsConstructor + @Data private static class ProtocolMapping { @@ -354,66 +339,32 @@ private static ProtocolMapping map(int protocol, int id) return new ProtocolMapping( protocol, id ); } - @RequiredArgsConstructor - public static class DirectionData + static final class DirectionData { - private final Protocol protocolPhase; private final TIntObjectMap protocols = new TIntObjectHashMap<>(); - { - for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS ) - { - protocols.put( protocol, new ProtocolData( protocol ) ); - } - } - private final TIntObjectMap> linkedProtocols = new TIntObjectHashMap<>(); - { - linkedProtocols.put( ProtocolConstants.MINECRAFT_1_8, Arrays.asList( - ProtocolConstants.MINECRAFT_1_9, - ProtocolConstants.MINECRAFT_1_12, - ProtocolConstants.MINECRAFT_1_13 - ) ); - linkedProtocols.put( ProtocolConstants.MINECRAFT_1_9, Arrays.asList( - ProtocolConstants.MINECRAFT_1_9_1, - ProtocolConstants.MINECRAFT_1_9_2, - ProtocolConstants.MINECRAFT_1_9_4 - ) ); - linkedProtocols.put( ProtocolConstants.MINECRAFT_1_9_4, Arrays.asList( - ProtocolConstants.MINECRAFT_1_10, - ProtocolConstants.MINECRAFT_1_11, - ProtocolConstants.MINECRAFT_1_11_1 - ) ); - linkedProtocols.put( ProtocolConstants.MINECRAFT_1_12, Arrays.asList( - ProtocolConstants.MINECRAFT_1_12_1 - ) ); - linkedProtocols.put( ProtocolConstants.MINECRAFT_1_12_1, Arrays.asList( - ProtocolConstants.MINECRAFT_1_12_2 - ) ); - linkedProtocols.put( ProtocolConstants.MINECRAFT_1_13, Arrays.asList( - ProtocolConstants.MINECRAFT_1_13_1, - ProtocolConstants.MINECRAFT_1_13_2 - ) ); - } - + // + private final Protocol protocolPhase; @Getter private final ProtocolConstants.Direction direction; - private ProtocolData getProtocolData(int version) + public DirectionData(Protocol protocolPhase, ProtocolConstants.Direction direction) { - ProtocolData protocol = protocols.get( version ); - if ( protocol == null && ( protocolPhase != Protocol.GAME ) ) + this.protocolPhase = protocolPhase; + this.direction = direction; + + for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS ) { - protocol = Iterables.getFirst( protocols.valueCollection(), null ); + protocols.put( protocol, new ProtocolData( protocol ) ); } - return protocol; } public final DefinedPacket createPacket(int id, int version) { - ProtocolData protocolData = getProtocolData( version ); + ProtocolData protocolData = protocols.get( version ); if ( protocolData == null ) { - throw new BadPacketException( "Unsupported protocol version" ); + throw new BadPacketException( "Unsupported protocol version " + version ); } if ( id > MAX_PACKET_ID ) { @@ -430,33 +381,38 @@ public final DefinedPacket createPacket(int id, int version) } } - protected final void registerPacket(Class packetClass, ProtocolMapping... mappings) + private void registerPacket(Class packetClass, ProtocolMapping... mappings) { try { Constructor constructor = packetClass.getDeclaredConstructor(); - for ( ProtocolMapping mapping : mappings ) + + int mappingIndex = 0; + ProtocolMapping mapping = mappings[mappingIndex]; + for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS ) { - ProtocolData data = protocols.get( mapping.protocolVersion ); - data.packetMap.put( packetClass, mapping.packetID ); - data.packetConstructors[mapping.packetID] = constructor; + if ( protocol < mapping.protocolVersion ) + { + // This is a new packet, skip it till we reach the next protocol + continue; + } - List links = linkedProtocols.get( mapping.protocolVersion ); - if ( links != null ) + if ( mapping.protocolVersion < protocol && mappingIndex + 1 < mappings.length ) { - links: for ( int link : links ) + // Mapping is non current, but the next one may be ok + ProtocolMapping nextMapping = mappings[mappingIndex + 1]; + if ( nextMapping.protocolVersion == protocol ) { - // Check for manual mappings - for ( ProtocolMapping m : mappings ) - { - if ( m == mapping ) continue; - if ( m.protocolVersion == link ) continue links; - List innerLinks = linkedProtocols.get( m.protocolVersion ); - if ( innerLinks != null && innerLinks.contains( link ) ) continue links; - } - registerPacket( packetClass, map( link, mapping.packetID ) ); + Preconditions.checkState( nextMapping.packetID != mapping.packetID, "Duplicate packet mapping (%s, %s)", mapping.protocolVersion, nextMapping.protocolVersion ); + + mapping = nextMapping; + mappingIndex++; } } + + ProtocolData data = protocols.get( protocol ); + data.packetMap.put( packetClass, mapping.packetID ); + data.packetConstructors[mapping.packetID] = constructor; } } catch ( NoSuchMethodException ex ) { @@ -467,7 +423,7 @@ protected final void registerPacket(Class packetClass, final int getId(Class packet, int version) { - ProtocolData protocolData = getProtocolData( version ); + ProtocolData protocolData = protocols.get( version ); if ( protocolData == null ) { throw new BadPacketException( "Unsupported protocol version" ); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java b/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java index 2cc86349f6..09c2bebf61 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java @@ -28,7 +28,8 @@ public class ProtocolConstants "1.12.x", "1.13.x" ); - public static final List SUPPORTED_VERSION_IDS = Arrays.asList( ProtocolConstants.MINECRAFT_1_8, + public static final List SUPPORTED_VERSION_IDS = Arrays.asList( + ProtocolConstants.MINECRAFT_1_8, ProtocolConstants.MINECRAFT_1_9, ProtocolConstants.MINECRAFT_1_9_1, ProtocolConstants.MINECRAFT_1_9_2, From e2bc7ed797c5e8d76d61339d0eb1f067521e5bb7 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 26 Feb 2019 13:11:05 +1100 Subject: [PATCH 17/22] Misc formatting fixes --- .../java/net/md_5/bungee/api/event/ChatEvent.java | 3 ++- .../md_5/bungee/module/cmd/alert/CommandAlertRaw.java | 11 ++++++----- .../md_5/bungee/module/cmd/server/CommandServer.java | 8 ++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java b/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java index 9b36b91ebe..828ede5646 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/ChatEvent.java @@ -47,7 +47,8 @@ public boolean isCommand() * Checks whether this message is run on this proxy server. * * @return if this command runs on the proxy - * @see PluginManager#isExecutableCommand(java.lang.String, net.md_5.bungee.api.CommandSender) + * @see PluginManager#isExecutableCommand(java.lang.String, + * net.md_5.bungee.api.CommandSender) */ public boolean isProxyCommand() { diff --git a/module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/CommandAlertRaw.java b/module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/CommandAlertRaw.java index 24da97b6a2..4d4ef1be0a 100644 --- a/module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/CommandAlertRaw.java +++ b/module/cmd-alert/src/main/java/net/md_5/bungee/module/cmd/alert/CommandAlertRaw.java @@ -40,11 +40,12 @@ public void execute(CommandSender sender, String[] args) } if ( sender instanceof ProxiedPlayer ) { - sender.sendMessage( - new ComponentBuilder( "An error occurred while parsing your message. (Hover for details)" ). - color( ChatColor.RED ).underlined( true ). - event( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( error.getMessage() ).color( ChatColor.RED ).create() ) ). - create() ); + sender.sendMessage( new ComponentBuilder( "An error occurred while parsing your message. (Hover for details)" ) + .color( ChatColor.RED ) + .underlined( true ) + .event( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( error.getMessage() ).color( ChatColor.RED ).create() ) ) + .create() + ); } else { sender.sendMessage( new ComponentBuilder( "An error occurred while parsing your message: " ).color( ChatColor.RED ).append( error.getMessage() ).create() ); diff --git a/module/cmd-server/src/main/java/net/md_5/bungee/module/cmd/server/CommandServer.java b/module/cmd-server/src/main/java/net/md_5/bungee/module/cmd/server/CommandServer.java index ebf9a12dcb..794d571fe7 100644 --- a/module/cmd-server/src/main/java/net/md_5/bungee/module/cmd/server/CommandServer.java +++ b/module/cmd-server/src/main/java/net/md_5/bungee/module/cmd/server/CommandServer.java @@ -49,10 +49,10 @@ public void execute(CommandSender sender, String[] args) { TextComponent serverTextComponent = new TextComponent( first ? server.getName() : ", " + server.getName() ); int count = server.getPlayers().size(); - serverTextComponent.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, - new ComponentBuilder( count + ( count == 1 ? " player" : " players" ) + "\n" ) - .append( "Click to connect to the server" ).italic( true ) - .create() ) ); + serverTextComponent.setHoverEvent( new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new ComponentBuilder( count + ( count == 1 ? " player" : " players" ) + "\n" ).append( "Click to connect to the server" ).italic( true ).create() ) + ); serverTextComponent.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, "/server " + server.getName() ) ); serverList.append( serverTextComponent ); first = false; From caeabb5b62694ef761d5a0524b80cef2fa1d7abd Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 9 Mar 2019 09:08:27 +1100 Subject: [PATCH 18/22] #2610: Fix out of date message for unsupported versions --- .../java/net/md_5/bungee/protocol/Protocol.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java index 56d8a0de32..98be98e83d 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java @@ -1,6 +1,7 @@ package net.md_5.bungee.protocol; import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; import gnu.trove.map.TIntObjectMap; import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TIntObjectHashMap; @@ -359,9 +360,19 @@ public DirectionData(Protocol protocolPhase, ProtocolConstants.Direction directi } } + private ProtocolData getProtocolData(int version) + { + ProtocolData protocol = protocols.get( version ); + if ( protocol == null && ( protocolPhase != Protocol.GAME ) ) + { + protocol = Iterables.getFirst( protocols.valueCollection(), null ); + } + return protocol; + } + public final DefinedPacket createPacket(int id, int version) { - ProtocolData protocolData = protocols.get( version ); + ProtocolData protocolData = getProtocolData( version ); if ( protocolData == null ) { throw new BadPacketException( "Unsupported protocol version " + version ); @@ -423,7 +434,7 @@ private void registerPacket(Class packetClass, Protocol final int getId(Class packet, int version) { - ProtocolData protocolData = protocols.get( version ); + ProtocolData protocolData = getProtocolData( version ); if ( protocolData == null ) { throw new BadPacketException( "Unsupported protocol version" ); From 52a125dded7eccdb9bdfbfca5d801046efda0924 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 17 Mar 2019 12:43:12 +1100 Subject: [PATCH 19/22] Add --help flag --- .../main/java/net/md_5/bungee/BungeeCordLauncher.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCordLauncher.java b/proxy/src/main/java/net/md_5/bungee/BungeeCordLauncher.java index c38b8fc222..13f9812f7f 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCordLauncher.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCordLauncher.java @@ -23,11 +23,17 @@ public static void main(String[] args) throws Exception OptionParser parser = new OptionParser(); parser.allowsUnrecognizedOptions(); - parser.acceptsAll( Arrays.asList( "v", "version" ) ); - parser.acceptsAll( Arrays.asList( "noconsole" ) ); + parser.acceptsAll( Arrays.asList( "help" ), "Show the help" ); + parser.acceptsAll( Arrays.asList( "v", "version" ), "Print version and exit" ); + parser.acceptsAll( Arrays.asList( "noconsole" ), "Disable console input" ); OptionSet options = parser.parse( args ); + if ( options.has( "help" ) ) + { + parser.printHelpOn( System.out ); + return; + } if ( options.has( "version" ) ) { System.out.println( BungeeCord.class.getPackage().getImplementationVersion() ); From 4428409d41acef5495c6d41c9640c99dbb0d6468 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 17 Mar 2019 12:58:05 +1100 Subject: [PATCH 20/22] Netty 4.1.34.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4f8786a53d..6cd54c2d6d 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ unknown - 4.1.32.Final + 4.1.34.Final 1.7 1.7 UTF-8 From 771f1735e5460909175d4a6e9713cdbe60ad8eec Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 18 Mar 2019 13:26:10 +1100 Subject: [PATCH 21/22] Clearer message for illegal IP addresses --- api/src/main/java/net/md_5/bungee/Util.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/net/md_5/bungee/Util.java b/api/src/main/java/net/md_5/bungee/Util.java index cb84917ee6..5e5b53a706 100644 --- a/api/src/main/java/net/md_5/bungee/Util.java +++ b/api/src/main/java/net/md_5/bungee/Util.java @@ -29,7 +29,12 @@ public static InetSocketAddress getAddr(String hostline) uri = new URI( "tcp://" + hostline ); } catch ( URISyntaxException ex ) { - throw new IllegalArgumentException( "Bad hostline", ex ); + throw new IllegalArgumentException( "Bad hostline: " + hostline, ex ); + } + + if ( uri.getHost() == null ) + { + throw new IllegalArgumentException( "Invalid host/address: " + hostline ); } return new InetSocketAddress( uri.getHost(), ( uri.getPort() ) == -1 ? DEFAULT_PORT : uri.getPort() ); From 5aaccd2e9ec554f8f769aa0eb11a7393236aad85 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 6 Apr 2019 19:53:26 +1100 Subject: [PATCH 22/22] #2621: Fix score component serialization --- .../java/net/md_5/bungee/api/chat/BaseComponent.java | 2 ++ .../java/net/md_5/bungee/api/chat/ClickEvent.java | 2 ++ .../java/net/md_5/bungee/api/chat/HoverEvent.java | 2 ++ .../net/md_5/bungee/api/chat/KeybindComponent.java | 2 ++ .../java/net/md_5/bungee/api/chat/ScoreComponent.java | 2 ++ .../net/md_5/bungee/api/chat/SelectorComponent.java | 2 ++ .../java/net/md_5/bungee/api/chat/TextComponent.java | 2 ++ .../md_5/bungee/api/chat/TranslatableComponent.java | 2 ++ .../net/md_5/bungee/chat/BaseComponentSerializer.java | 5 +++-- .../net/md_5/bungee/chat/ComponentSerializer.java | 4 ++-- .../md_5/bungee/chat/ScoreComponentSerializer.java | 11 ++++++----- .../java/net/md_5/bungee/api/chat/ComponentsTest.java | 10 ++++++++++ 12 files changed, 37 insertions(+), 9 deletions(-) diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/BaseComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/BaseComponent.java index 5aa7e68eac..b26e8429c3 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/BaseComponent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/BaseComponent.java @@ -8,11 +8,13 @@ import java.util.ArrayList; import java.util.List; +import lombok.EqualsAndHashCode; import lombok.ToString; import net.md_5.bungee.api.chat.ComponentBuilder.FormatRetention; @Setter @ToString(exclude = "parent") +@EqualsAndHashCode @NoArgsConstructor public abstract class BaseComponent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/ClickEvent.java b/chat/src/main/java/net/md_5/bungee/api/chat/ClickEvent.java index 1fb3111282..2705ce5862 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/ClickEvent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/ClickEvent.java @@ -1,11 +1,13 @@ package net.md_5.bungee.api.chat; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; @Getter @ToString +@EqualsAndHashCode @RequiredArgsConstructor public final class ClickEvent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/HoverEvent.java b/chat/src/main/java/net/md_5/bungee/api/chat/HoverEvent.java index 0f6ec77d53..253ee734be 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/HoverEvent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/HoverEvent.java @@ -1,11 +1,13 @@ package net.md_5.bungee.api.chat; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; @Getter @ToString +@EqualsAndHashCode @RequiredArgsConstructor public final class HoverEvent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java index 0bcb06e449..d0fc17933f 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/KeybindComponent.java @@ -1,5 +1,6 @@ package net.md_5.bungee.api.chat; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -10,6 +11,7 @@ @Setter @ToString @NoArgsConstructor +@EqualsAndHashCode(callSuper = true) public final class KeybindComponent extends BaseComponent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/ScoreComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/ScoreComponent.java index 48ef24aa28..6a4080a033 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/ScoreComponent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/ScoreComponent.java @@ -1,6 +1,7 @@ package net.md_5.bungee.api.chat; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -26,6 +27,7 @@ @Setter @ToString @AllArgsConstructor +@EqualsAndHashCode(callSuper = true) public final class ScoreComponent extends BaseComponent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/SelectorComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/SelectorComponent.java index 3140b32285..4ef2d8cb13 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/SelectorComponent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/SelectorComponent.java @@ -1,6 +1,7 @@ package net.md_5.bungee.api.chat; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -22,6 +23,7 @@ @Setter @ToString @AllArgsConstructor +@EqualsAndHashCode(callSuper = true) public final class SelectorComponent extends BaseComponent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java index e3ef9b7e3a..77bdea5de0 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java @@ -9,10 +9,12 @@ import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; +import lombok.EqualsAndHashCode; @Getter @Setter @AllArgsConstructor +@EqualsAndHashCode(callSuper = true) public final class TextComponent extends BaseComponent { diff --git a/chat/src/main/java/net/md_5/bungee/api/chat/TranslatableComponent.java b/chat/src/main/java/net/md_5/bungee/api/chat/TranslatableComponent.java index 54da446724..a6ee3ff389 100644 --- a/chat/src/main/java/net/md_5/bungee/api/chat/TranslatableComponent.java +++ b/chat/src/main/java/net/md_5/bungee/api/chat/TranslatableComponent.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import lombok.EqualsAndHashCode; import lombok.ToString; import net.md_5.bungee.chat.TranslationRegistry; @@ -15,6 +16,7 @@ @Setter @ToString @NoArgsConstructor +@EqualsAndHashCode(callSuper = true) public final class TranslatableComponent extends BaseComponent { diff --git a/chat/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java b/chat/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java index 7f64751294..9f27f1d69e 100644 --- a/chat/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java +++ b/chat/src/main/java/net/md_5/bungee/chat/BaseComponentSerializer.java @@ -10,7 +10,8 @@ import net.md_5.bungee.api.chat.HoverEvent; import java.util.Arrays; -import java.util.HashSet; +import java.util.Collections; +import java.util.IdentityHashMap; import java.util.Locale; public class BaseComponentSerializer @@ -83,7 +84,7 @@ protected void serialize(JsonObject object, BaseComponent component, JsonSeriali if ( ComponentSerializer.serializedComponents.get() == null ) { first = true; - ComponentSerializer.serializedComponents.set( new HashSet() ); + ComponentSerializer.serializedComponents.set( Collections.newSetFromMap( new IdentityHashMap() ) ); } try { diff --git a/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java b/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java index 0b7cf3b499..eaf9f79fd0 100644 --- a/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java +++ b/chat/src/main/java/net/md_5/bungee/chat/ComponentSerializer.java @@ -16,7 +16,7 @@ import net.md_5.bungee.api.chat.TranslatableComponent; import java.lang.reflect.Type; -import java.util.HashSet; +import java.util.Set; public class ComponentSerializer implements JsonDeserializer { @@ -31,7 +31,7 @@ public class ComponentSerializer implements JsonDeserializer registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ). create(); - public final static ThreadLocal> serializedComponents = new ThreadLocal>(); + public final static ThreadLocal> serializedComponents = new ThreadLocal>(); public static BaseComponent[] parse(String json) { diff --git a/chat/src/main/java/net/md_5/bungee/chat/ScoreComponentSerializer.java b/chat/src/main/java/net/md_5/bungee/chat/ScoreComponentSerializer.java index ecff9beffa..f09c8bf900 100644 --- a/chat/src/main/java/net/md_5/bungee/chat/ScoreComponentSerializer.java +++ b/chat/src/main/java/net/md_5/bungee/chat/ScoreComponentSerializer.java @@ -17,17 +17,18 @@ public class ScoreComponentSerializer extends BaseComponentSerializer implements public ScoreComponent deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException { JsonObject json = element.getAsJsonObject(); - if ( !json.has( "name" ) || !json.has( "objective" ) ) + JsonObject score = json.get( "score" ).getAsJsonObject(); + if ( !score.has( "name" ) || !score.has( "objective" ) ) { throw new JsonParseException( "A score component needs at least a name and an objective" ); } - String name = json.get( "name" ).getAsString(); - String objective = json.get( "objective" ).getAsString(); + String name = score.get( "name" ).getAsString(); + String objective = score.get( "objective" ).getAsString(); ScoreComponent component = new ScoreComponent( name, objective ); - if ( json.has( "value" ) && !json.get( "value" ).getAsString().isEmpty() ) + if ( score.has( "value" ) && !score.get( "value" ).getAsString().isEmpty() ) { - component.setValue( json.get( "value" ).getAsString() ); + component.setValue( score.get( "value" ).getAsString() ); } deserialize( json, component, context ); diff --git a/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java b/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java index bb38f1b1cc..8fa10e4433 100644 --- a/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java +++ b/chat/src/test/java/net/md_5/bungee/api/chat/ComponentsTest.java @@ -75,6 +75,16 @@ public void testBuilderAppendMixedComponents() Assert.assertEquals( scoreComponent.toPlainText(), components[3].toPlainText() ); } + @Test + public void testScore() + { + BaseComponent[] component = ComponentSerializer.parse( "{\"score\":{\"name\":\"@p\",\"objective\":\"TEST\",\"value\":\"hello\"}}" ); + String text = ComponentSerializer.toString( component ); + BaseComponent[] reparsed = ComponentSerializer.parse( text ); + + Assert.assertArrayEquals( component, reparsed ); + } + @Test public void testBuilderAppend() {