From 5524f3b7203144565ea609ade0d5925bf93bfa3d Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Fri, 17 May 2019 18:16:28 -0400 Subject: [PATCH] Ensure empty (un)register packets are never sent. Bukkit 1.13+, in particular, doesn't seem to like it very much. This was also a bug in ViaVersion. --- .../connection/client/ClientPlaySessionHandler.java | 13 +++++++------ .../proxy/protocol/util/PluginMessageUtil.java | 7 ++++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java index 0fbc0cbc6..9593108a8 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java @@ -1,6 +1,7 @@ package com.velocitypowered.proxy.connection.client; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13; +import static com.velocitypowered.proxy.protocol.util.PluginMessageUtil.constructChannelsPacket; import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.event.player.PlayerChatEvent; @@ -72,10 +73,11 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { public void activated() { Collection channels = server.getChannelRegistrar().getChannelsForProtocol(player .getProtocolVersion()); - PluginMessage register = PluginMessageUtil.constructChannelsPacket(player.getProtocolVersion(), - channels); - player.getMinecraftConnection().write(register); - player.getKnownChannels().addAll(channels); + if (!channels.isEmpty()) { + PluginMessage register = constructChannelsPacket(player.getProtocolVersion(), channels); + player.getMinecraftConnection().write(register); + player.getKnownChannels().addAll(channels); + } } @Override @@ -366,8 +368,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { // Tell the server about this client's plugin message channels. ProtocolVersion serverVersion = serverMc.getProtocolVersion(); if (!player.getKnownChannels().isEmpty()) { - serverMc.delayedWrite(PluginMessageUtil.constructChannelsPacket(serverVersion, - player.getKnownChannels())); + serverMc.delayedWrite(constructChannelsPacket(serverVersion, player.getKnownChannels())); } // If we had plugin messages queued during login/FML handshake, send them now. diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/PluginMessageUtil.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/PluginMessageUtil.java index 3366de6ca..9fef82a1f 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/PluginMessageUtil.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/PluginMessageUtil.java @@ -93,6 +93,11 @@ public class PluginMessageUtil { checkNotNull(message, "message"); checkArgument(isRegister(message) || isUnregister(message), "Unknown channel type %s", message.getChannel()); + if (message.getData().length == 0) { + // If we try to split this, we will get an one-element array with the empty string, which + // has caused issues with 1.13+ compatibility. Just return an empty list. + return ImmutableList.of(); + } String channels = new String(message.getData(), StandardCharsets.UTF_8); return ImmutableList.copyOf(channels.split("\0")); } @@ -103,10 +108,10 @@ public class PluginMessageUtil { * @param channels the channels to register * @return the plugin message to send */ - public static PluginMessage constructChannelsPacket(ProtocolVersion protocolVersion, Collection channels) { Preconditions.checkNotNull(channels, "channels"); + Preconditions.checkArgument(channels.size() > 0, "no channels specified"); String channelName = protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0 ? REGISTER_CHANNEL : REGISTER_CHANNEL_LEGACY; PluginMessage message = new PluginMessage();