diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java index 2051972ff..9144fc441 100644 --- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java +++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerModInfoEvent.java @@ -4,6 +4,9 @@ import com.google.common.base.Preconditions; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.util.ModInfo; +/** + * This event is fired when the players ModInfo is changed. + */ public final class PlayerModInfoEvent { private final Player player; private final ModInfo modInfo; 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 cf0695dfa..acfedf1cd 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 @@ -145,9 +145,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { player.getConnectedServer().getConnection().write(PluginMessageUtil.rewriteMCBrand(packet)); } else if (player.getConnectedServer().isLegacyForge() && !player.getConnectedServer().hasCompletedJoin()) { if (packet.getChannel().equals(VelocityConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) { - List mods = PluginMessageUtil.readModList(packet); - if (!mods.isEmpty()) { - player.setModInfo(new ModInfo("FML", mods)); + if (!player.getModInfo().isPresent()) { + PluginMessageUtil.readModList(packet).ifPresent(mods -> player.setModInfo(new ModInfo("FML", mods))); } // Always forward the FML handshake to the remote server. 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 203936690..bf2f48cf9 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 @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.velocitypowered.api.util.ModInfo; +import com.velocitypowered.proxy.connection.VelocityConstants; import com.velocitypowered.proxy.protocol.ProtocolConstants; import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.packet.PluginMessage; @@ -13,6 +14,7 @@ import io.netty.buffer.Unpooled; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; +import java.util.Optional; public class PluginMessageUtil { public static final String BRAND_CHANNEL_LEGACY = "MC|Brand"; @@ -79,22 +81,31 @@ public class PluginMessageUtil { return newMsg; } - public static List readModList(PluginMessage message) { - List mods = Lists.newArrayList(); + public static Optional> readModList(PluginMessage message) { + Preconditions.checkNotNull(message, "message"); + Preconditions.checkArgument(message.getChannel().equals(VelocityConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL), + "message is not a FML HS plugin message"); ByteBuf byteBuf = Unpooled.wrappedBuffer(message.getData()); - byte discriminator = byteBuf.readByte(); - - if (discriminator == 2) { - int modCount = ProtocolUtils.readVarInt(byteBuf); + try { + byte discriminator = byteBuf.readByte(); - for (int index = 0; index < modCount; index++) { - String id = ProtocolUtils.readString(byteBuf); - String version = ProtocolUtils.readString(byteBuf); - mods.add(new ModInfo.Mod(id, version)); + if (discriminator == 2) { + ImmutableList.Builder mods = ImmutableList.builder(); + int modCount = ProtocolUtils.readVarInt(byteBuf); + + for (int index = 0; index < modCount; index++) { + String id = ProtocolUtils.readString(byteBuf); + String version = ProtocolUtils.readString(byteBuf); + mods.add(new ModInfo.Mod(id, version)); + } + + return Optional.of(mods.build()); } + + return Optional.empty(); + } finally { + byteBuf.release(); } - - return ImmutableList.copyOf(mods); } }