From bd009ca52d7fd508a682cb3494b7d8aafcd65663 Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 6 Nov 2023 20:14:57 +1100 Subject: [PATCH] #3559: Fix serialisation of certain scoreboard packets < 1.13 --- .../md_5/bungee/protocol/DefinedPacket.java | 16 +++++++++ .../java/net/md_5/bungee/protocol/Either.java | 34 +++++++++++++++++++ .../protocol/packet/ScoreboardObjective.java | 8 +++-- .../net/md_5/bungee/protocol/packet/Team.java | 30 +++++++++------- .../java/net/md_5/bungee/ServerConnector.java | 8 ++++- .../bungee/connection/DownstreamBridge.java | 4 +-- 6 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/Either.java diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java b/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java index ee323696..ad7f9c25 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java @@ -73,6 +73,11 @@ public abstract class DefinedPacket return s; } + public static Either readEitherBaseComponent(ByteBuf buf, int protocolVersion, boolean string) + { + return ( string ) ? Either.left( readString( buf ) ) : Either.right( readBaseComponent( buf, protocolVersion ) ); + } + public static BaseComponent readBaseComponent(ByteBuf buf, int protocolVersion) { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 ) @@ -89,6 +94,17 @@ public abstract class DefinedPacket } } + public static void writeEitherBaseComponent(Either message, ByteBuf buf, int protocolVersion) + { + if ( message.isLeft() ) + { + writeString( message.getLeft(), buf ); + } else + { + writeBaseComponent( message.getRight(), buf, protocolVersion ); + } + } + public static void writeBaseComponent(BaseComponent message, ByteBuf buf, int protocolVersion) { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Either.java b/protocol/src/main/java/net/md_5/bungee/protocol/Either.java new file mode 100644 index 00000000..42d174e0 --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Either.java @@ -0,0 +1,34 @@ +package net.md_5.bungee.protocol; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public final class Either +{ + + private final L left; + private final R right; + + public boolean isLeft() + { + return this.left != null; + } + + public boolean isRight() + { + return this.right != null; + } + + public static Either left(L left) + { + return new Either<>( left, null ); + } + + public static Either right(R right) + { + return new Either<>( null, right ); + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java index e0a12af8..5ed8216c 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java @@ -9,6 +9,7 @@ import lombok.NoArgsConstructor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.Either; import net.md_5.bungee.protocol.ProtocolConstants; @Data @@ -19,7 +20,7 @@ public class ScoreboardObjective extends DefinedPacket { private String name; - private BaseComponent value; + private Either value; private HealthDisplay type; /** * 0 to create, 1 to remove, 2 to update display text. @@ -33,12 +34,13 @@ public class ScoreboardObjective extends DefinedPacket action = buf.readByte(); if ( action == 0 || action == 2 ) { - value = readBaseComponent( buf, protocolVersion ); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { + value = readEitherBaseComponent( buf, protocolVersion, false ); type = HealthDisplay.values()[readVarInt( buf )]; } else { + value = readEitherBaseComponent( buf, protocolVersion, true ); type = HealthDisplay.fromString( readString( buf ) ); } } @@ -51,7 +53,7 @@ public class ScoreboardObjective extends DefinedPacket buf.writeByte( action ); if ( action == 0 || action == 2 ) { - writeBaseComponent( value, buf, protocolVersion ); + writeEitherBaseComponent( value, buf, protocolVersion ); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { writeVarInt( type.ordinal(), buf ); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java index 016b7e14..7a14e6a6 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.Either; import net.md_5.bungee.protocol.ProtocolConstants; @Data @@ -22,9 +23,9 @@ public class Team extends DefinedPacket * 0 - create, 1 remove, 2 info update, 3 player add, 4 player remove. */ private byte mode; - private BaseComponent displayName; - private BaseComponent prefix; - private BaseComponent suffix; + private Either displayName; + private Either prefix; + private Either suffix; private String nameTagVisibility; private String collisionRule; private int color; @@ -49,11 +50,14 @@ public class Team extends DefinedPacket mode = buf.readByte(); if ( mode == 0 || mode == 2 ) { - displayName = readBaseComponent( buf, protocolVersion ); if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) { - prefix = readBaseComponent( buf, protocolVersion ); - suffix = readBaseComponent( buf, protocolVersion ); + displayName = readEitherBaseComponent( buf, protocolVersion, true ); + prefix = readEitherBaseComponent( buf, protocolVersion, true ); + suffix = readEitherBaseComponent( buf, protocolVersion, true ); + } else + { + displayName = readEitherBaseComponent( buf, protocolVersion, false ); } friendlyFire = buf.readByte(); nameTagVisibility = readString( buf ); @@ -64,8 +68,8 @@ public class Team extends DefinedPacket color = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) ? readVarInt( buf ) : buf.readByte(); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { - prefix = readBaseComponent( buf, protocolVersion ); - suffix = readBaseComponent( buf, protocolVersion ); + prefix = readEitherBaseComponent( buf, protocolVersion, false ); + suffix = readEitherBaseComponent( buf, protocolVersion, false ); } } if ( mode == 0 || mode == 3 || mode == 4 ) @@ -86,11 +90,11 @@ public class Team extends DefinedPacket buf.writeByte( mode ); if ( mode == 0 || mode == 2 ) { - writeBaseComponent( displayName, buf, protocolVersion ); + writeEitherBaseComponent( displayName, buf, protocolVersion ); if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) { - writeBaseComponent( prefix, buf, protocolVersion ); - writeBaseComponent( suffix, buf, protocolVersion ); + writeEitherBaseComponent( prefix, buf, protocolVersion ); + writeEitherBaseComponent( suffix, buf, protocolVersion ); } buf.writeByte( friendlyFire ); writeString( nameTagVisibility, buf ); @@ -102,8 +106,8 @@ public class Team extends DefinedPacket if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { writeVarInt( color, buf ); - writeBaseComponent( prefix, buf, protocolVersion ); - writeBaseComponent( suffix, buf, protocolVersion ); + writeEitherBaseComponent( prefix, buf, protocolVersion ); + writeEitherBaseComponent( suffix, buf, protocolVersion ); } else { buf.writeByte( color ); 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 5ca53d81..6d660bab 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -35,6 +35,7 @@ import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.Either; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; import net.md_5.bungee.protocol.ProtocolConstants; @@ -279,7 +280,12 @@ public class ServerConnector extends PacketHandler Scoreboard serverScoreboard = user.getServerSentScoreboard(); for ( Objective objective : serverScoreboard.getObjectives() ) { - user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), ComponentSerializer.deserialize( objective.getValue() ), ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), (byte) 1 ) ); + user.unsafe().sendPacket( new ScoreboardObjective( + objective.getName(), + ( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ) ? Either.right( ComponentSerializer.deserialize( objective.getValue() ) ) : Either.left( objective.getValue() ), + ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), + (byte) 1 ) + ); } for ( Score score : serverScoreboard.getScores() ) { 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 8f955fdc..172cc8e5 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 @@ -183,7 +183,7 @@ public class DownstreamBridge extends PacketHandler switch ( objective.getAction() ) { case 0: - serverScoreboard.addObjective( new Objective( objective.getName(), ComponentSerializer.toString( objective.getValue() ), objective.getType().toString() ) ); + serverScoreboard.addObjective( new Objective( objective.getName(), ( objective.getValue().isLeft() ) ? objective.getValue().getLeft() : ComponentSerializer.toString( objective.getValue().getRight() ), objective.getType().toString() ) ); break; case 1: serverScoreboard.removeObjective( objective.getName() ); @@ -192,7 +192,7 @@ public class DownstreamBridge extends PacketHandler Objective oldObjective = serverScoreboard.getObjective( objective.getName() ); if ( oldObjective != null ) { - oldObjective.setValue( ComponentSerializer.toString( objective.getValue() ) ); + oldObjective.setValue( ( objective.getValue().isLeft() ) ? objective.getValue().getLeft() : ComponentSerializer.toString( objective.getValue().getRight() ) ); oldObjective.setType( objective.getType().toString() ); } break;