diff --git a/api/src/main/java/net/md_5/bungee/api/event/TabCompleteResponseEvent.java b/api/src/main/java/net/md_5/bungee/api/event/TabCompleteResponseEvent.java new file mode 100644 index 00000000..ea0ce89c --- /dev/null +++ b/api/src/main/java/net/md_5/bungee/api/event/TabCompleteResponseEvent.java @@ -0,0 +1,38 @@ +package net.md_5.bungee.api.event; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.plugin.Cancellable; +import java.util.List; + +/** + * Event called when a backend server sends a response to a player asking to + * tab-complete a chat message or command. Note that this is not called when + * BungeeCord or a plugin responds to a tab-complete request. Use + * {@link TabCompleteEvent} for that. + */ +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class TabCompleteResponseEvent extends TargetedEvent implements Cancellable +{ + + /** + * Whether the event is cancelled. + */ + private boolean cancelled; + + /** + * Mutable list of suggestions sent back to the player. If this list is + * empty, an empty list is sent back to the client. + */ + private final List suggestions; + + public TabCompleteResponseEvent(Connection sender, Connection receiver, List suggestions) + { + super( sender, receiver ); + this.suggestions = suggestions; + } +} 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 735d3d35..01c6eec8 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 @@ -4,7 +4,6 @@ import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import java.io.DataInput; import java.util.Objects; - import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.Unpooled; @@ -12,6 +11,7 @@ import lombok.RequiredArgsConstructor; import net.md_5.bungee.ServerConnection; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.event.ServerDisconnectEvent; +import net.md_5.bungee.api.event.TabCompleteResponseEvent; import net.md_5.bungee.UserConnection; import net.md_5.bungee.Util; import net.md_5.bungee.api.ProxyServer; @@ -38,6 +38,7 @@ import net.md_5.bungee.protocol.packet.ScoreboardDisplay; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.Kick; import net.md_5.bungee.protocol.packet.SetCompression; +import net.md_5.bungee.protocol.packet.TabCompleteResponse; import net.md_5.bungee.tab.TabList; @RequiredArgsConstructor @@ -236,7 +237,8 @@ public class DownstreamBridge extends PacketHandler DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand ); pluginMessage.setData( brand.array().clone() ); brand.release(); - } catch ( Exception ignored ) { + } catch ( Exception ignored ) + { // TODO: Remove this // Older spigot protocol builds sent the brand incorrectly return; @@ -479,6 +481,19 @@ public class DownstreamBridge extends PacketHandler server.getCh().setCompressionThreshold( setCompression.getThreshold() ); } + @Override + public void handle(TabCompleteResponse tabCompleteResponse) throws Exception + { + TabCompleteResponseEvent tabCompleteResponseEvent = new TabCompleteResponseEvent( con.getServer(), con, tabCompleteResponse.getCommands() ); + + if ( !bungee.getPluginManager().callEvent( tabCompleteResponseEvent ).isCancelled() ) + { + con.unsafe().sendPacket( tabCompleteResponse ); + } + + throw CancelSendSignal.INSTANCE; + } + @Override public String toString() {