From 0f5f09b6c5f073130515c8cd435541c5c68bcba8 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 28 Oct 2023 12:57:19 +1100 Subject: [PATCH] Minecraft 23w43b support --- .../md_5/bungee/api/chat/TextComponent.java | 22 ++ .../md_5/bungee/chat/ComponentSerializer.java | 32 ++- .../bungee/chat/TextComponentSerializer.java | 5 +- .../md_5/bungee/api/chat/ComponentsTest.java | 4 +- protocol/pom.xml | 18 +- .../md_5/bungee/protocol/DefinedPacket.java | 45 ++++ .../bungee/protocol/MinecraftDecoder.java | 2 +- .../bungee/protocol/MinecraftEncoder.java | 2 +- .../net/md_5/bungee/protocol/Protocol.java | 6 +- .../bungee/protocol/ProtocolConstants.java | 3 +- .../net/md_5/bungee/protocol/TagUtil.java | 218 ++++++++++++++++++ .../md_5/bungee/protocol/packet/BossBar.java | 11 +- .../net/md_5/bungee/protocol/packet/Kick.java | 26 ++- .../packet/PlayerListHeaderFooter.java | 13 +- .../protocol/packet/PlayerListItem.java | 11 +- .../protocol/packet/PlayerListItemUpdate.java | 4 +- .../protocol/packet/ScoreboardObjective.java | 7 +- .../bungee/protocol/packet/ServerData.java | 7 +- .../md_5/bungee/protocol/packet/Subtitle.java | 7 +- .../bungee/protocol/packet/SystemChat.java | 7 +- .../protocol/packet/TabCompleteResponse.java | 26 ++- .../net/md_5/bungee/protocol/packet/Team.java | 27 +-- .../md_5/bungee/protocol/packet/Title.java | 11 +- .../java/net/md_5/bungee/BungeeTitle.java | 28 +-- .../java/net/md_5/bungee/ServerConnector.java | 8 +- .../java/net/md_5/bungee/UserConnection.java | 77 +++---- .../bungee/connection/DownstreamBridge.java | 17 +- .../bungee/connection/InitialHandler.java | 18 +- .../net/md_5/bungee/entitymap/EntityMap.java | 2 + .../bungee/entitymap/EntityMap_1_16_2.java | 1 + .../bungee/util/ChatComponentTransformer.java | 68 +++--- 31 files changed, 527 insertions(+), 206 deletions(-) create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/TagUtil.java 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 4371374a9..b76b8d71b 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 @@ -160,6 +160,28 @@ public final class TextComponent extends BaseComponent return components.toArray( new BaseComponent[ 0 ] ); } + /** + * Internal compatibility method to transform an array of components to a + * single component. + * + * @param components array + * @return single component + */ + public static BaseComponent fromArray(BaseComponent... components) + { + if ( components == null ) + { + return null; + } + + if ( components.length == 1 ) + { + return components[0]; + } + + return new TextComponent( components ); + } + /** * The text of the component that will be displayed to the client */ 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 82a181202..699678b7d 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 @@ -8,6 +8,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; import java.lang.reflect.Type; import java.util.Set; import net.md_5.bungee.api.chat.BaseComponent; @@ -87,14 +88,43 @@ public class ComponentSerializer implements JsonDeserializer public static BaseComponent deserialize(String json) { JsonElement jsonElement = JsonParser.parseString( json ); + + return deserialize( jsonElement ); + } + + /** + * Deserialize a JSON element as a single component. The input is expected + * to be a JSON object that represents only one component. + * + * @param jsonElement the component json to parse + * @return the deserialized component + * @throws IllegalArgumentException if anything other than a JSON object is + * passed as input + */ + public static BaseComponent deserialize(JsonElement jsonElement) + { + if ( jsonElement instanceof JsonPrimitive ) + { + JsonPrimitive primitive = (JsonPrimitive) jsonElement; + if ( primitive.isString() ) + { + return new TextComponent( primitive.getAsString() ); + } + } + if ( !jsonElement.isJsonObject() ) { - throw new IllegalArgumentException( "Malformatted JSON. Expected object, got array for input \"" + json + "\"." ); + throw new IllegalArgumentException( "Malformatted JSON. Expected object, got array for input \"" + jsonElement + "\"." ); } return gson.fromJson( jsonElement, BaseComponent.class ); } + public static JsonElement toJson(BaseComponent component) + { + return gson.toJsonTree( component ); + } + public static String toString(Object object) { return gson.toJson( object ); diff --git a/chat/src/main/java/net/md_5/bungee/chat/TextComponentSerializer.java b/chat/src/main/java/net/md_5/bungee/chat/TextComponentSerializer.java index 8a7e98195..2542ed571 100644 --- a/chat/src/main/java/net/md_5/bungee/chat/TextComponentSerializer.java +++ b/chat/src/main/java/net/md_5/bungee/chat/TextComponentSerializer.java @@ -18,11 +18,10 @@ public class TextComponentSerializer extends BaseComponentSerializer implements { TextComponent component = new TextComponent(); JsonObject object = json.getAsJsonObject(); - if ( !object.has( "text" ) ) + if ( object.has( "text" ) ) { - throw new JsonParseException( "Could not parse JSON: missing 'text' property" ); + component.setText( object.get( "text" ).getAsString() ); } - component.setText( object.get( "text" ).getAsString() ); deserialize( object, component, context ); return component; } 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 4dba2546b..5319ecf31 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 @@ -8,7 +8,6 @@ import java.util.function.Function; import java.util.function.ObjIntConsumer; import java.util.function.Supplier; import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.hover.content.Item; import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.chat.ComponentSerializer; import org.junit.jupiter.api.Test; @@ -72,6 +71,8 @@ public class ComponentsTest assertEquals( hoverVal, ComponentSerializer.toString( (BaseComponent[]) contentText.getValue() ) ); testDissembleReassemble( components ); ////////// + // TODO: now ambiguous since "text" to distinguish Text from Item is not required + /* TextComponent component1 = new TextComponent( "HoverableText" ); String nbt = "{display:{Name:{text:Hello},Lore:[{text:Line_1},{text:Line_2}]},ench:[{id:49,lvl:5}],Unbreakable:1}}"; Item contentItem = new Item( "minecraft:wood", 1, ItemTag.ofNbt( nbt ) ); @@ -84,6 +85,7 @@ public class ComponentsTest assertEquals( contentItem.getCount(), parsedContentItem.getCount() ); assertEquals( contentItem.getId(), parsedContentItem.getId() ); assertEquals( nbt, parsedContentItem.getTag().getNbt() ); + */ } @Test diff --git a/protocol/pom.xml b/protocol/pom.xml index f1c169a9e..4d6111018 100644 --- a/protocol/pom.xml +++ b/protocol/pom.xml @@ -18,26 +18,20 @@ BungeeCord-Protocol Minimal implementation of the Minecraft protocol for use in BungeeCord - + - sonatype-nexus-snapshots - Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots - - false - - - true - + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net/ - net.md-5 + com.mojang brigadier - 1.0.16-SNAPSHOT + 1.2.9 compile 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 d7f66e0d6..2959d8c07 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 @@ -2,6 +2,7 @@ package net.md_5.bungee.protocol; import com.google.common.base.Charsets; import com.google.common.base.Preconditions; +import com.google.gson.JsonElement; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; @@ -15,6 +16,8 @@ import java.util.EnumSet; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; import se.llbit.nbt.ErrorTag; import se.llbit.nbt.NamedTag; import se.llbit.nbt.SpecificTag; @@ -70,6 +73,38 @@ public abstract class DefinedPacket return s; } + public static BaseComponent readBaseComponent(ByteBuf buf, int protocolVersion) + { + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 ) + { + SpecificTag nbt = (SpecificTag) readTag( buf, protocolVersion ); + JsonElement json = TagUtil.toJson( nbt ); + + return ComponentSerializer.deserialize( json ); + } else + { + String string = readString( buf ); + + return ComponentSerializer.deserialize( string ); + } + } + + public static void writeBaseComponent(BaseComponent message, ByteBuf buf, int protocolVersion) + { + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_20_3 ) + { + JsonElement json = ComponentSerializer.toJson( message ); + SpecificTag nbt = TagUtil.fromJson( json ); + + writeTag( nbt, buf, protocolVersion ); + } else + { + String string = ComponentSerializer.toString( message ); + + writeString( string, buf ); + } + } + public static void writeArray(byte[] b, ByteBuf buf) { if ( b.length > Short.MAX_VALUE ) @@ -395,6 +430,11 @@ public abstract class DefinedPacket throw new UnsupportedOperationException( "Packet must implement read method" ); } + public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) + { + read( buf, direction, protocolVersion ); + } + public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { read( buf ); @@ -405,6 +445,11 @@ public abstract class DefinedPacket throw new UnsupportedOperationException( "Packet must implement write method" ); } + public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) + { + write( buf, direction, protocolVersion ); + } + public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { write( buf ); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java index 482341efe..d79d5e5cc 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java @@ -39,7 +39,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder DefinedPacket packet = prot.createPacket( packetId, protocolVersion ); if ( packet != null ) { - packet.read( in, prot.getDirection(), protocolVersion ); + packet.read( in, protocol, prot.getDirection(), protocolVersion ); if ( in.isReadable() ) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java index 2245dc56b..b9d6fb006 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java @@ -24,6 +24,6 @@ public class MinecraftEncoder extends MessageToByteEncoder { Protocol.DirectionData prot = ( server ) ? protocol.TO_CLIENT : protocol.TO_SERVER; DefinedPacket.writeVarInt( prot.getId( msg.getClass(), protocolVersion ), out ); - msg.write( out, prot.getDirection(), protocolVersion ); + msg.write( out, protocol, prot.getDirection(), protocolVersion ); } } 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 b6985feef..2eeca50b5 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 @@ -451,7 +451,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x12 ), - map( ProtocolConstants.MINECRAFT_1_20_2, 0x14 ) + map( ProtocolConstants.MINECRAFT_1_20_2, 0x14 ), + map( ProtocolConstants.MINECRAFT_1_20_3, 0x15 ) ); TO_SERVER.registerPacket( Chat.class, Chat::new, @@ -517,7 +518,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D ), map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ), map( ProtocolConstants.MINECRAFT_1_19_4, 0x0D ), - map( ProtocolConstants.MINECRAFT_1_20_2, 0x0F ) + map( ProtocolConstants.MINECRAFT_1_20_2, 0x0F ), + map( ProtocolConstants.MINECRAFT_1_20_3, 0x10 ) ); TO_SERVER.registerPacket( StartConfiguration.class, 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 7d5e2635a..d92a66d9e 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 @@ -44,6 +44,7 @@ public class ProtocolConstants public static final int MINECRAFT_1_19_4 = 762; public static final int MINECRAFT_1_20 = 763; public static final int MINECRAFT_1_20_2 = 764; + public static final int MINECRAFT_1_20_3 = 1073741984; public static final List SUPPORTED_VERSIONS; public static final List SUPPORTED_VERSION_IDS; @@ -107,7 +108,7 @@ public class ProtocolConstants if ( SNAPSHOT_SUPPORT ) { // supportedVersions.add( "1.20.x" ); - // supportedVersionIds.add( ProtocolConstants.MINECRAFT_1_20_2 ); + supportedVersionIds.add( ProtocolConstants.MINECRAFT_1_20_3 ); } SUPPORTED_VERSIONS = supportedVersions.build(); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/TagUtil.java b/protocol/src/main/java/net/md_5/bungee/protocol/TagUtil.java new file mode 100644 index 000000000..dfb1c8f01 --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/TagUtil.java @@ -0,0 +1,218 @@ +package net.md_5.bungee.protocol; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import se.llbit.nbt.ByteArrayTag; +import se.llbit.nbt.ByteTag; +import se.llbit.nbt.CompoundTag; +import se.llbit.nbt.DoubleTag; +import se.llbit.nbt.FloatTag; +import se.llbit.nbt.IntArrayTag; +import se.llbit.nbt.IntTag; +import se.llbit.nbt.ListTag; +import se.llbit.nbt.LongArrayTag; +import se.llbit.nbt.LongTag; +import se.llbit.nbt.NamedTag; +import se.llbit.nbt.ShortTag; +import se.llbit.nbt.SpecificTag; +import se.llbit.nbt.StringTag; +import se.llbit.nbt.Tag; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class TagUtil +{ + + public static SpecificTag fromJson(JsonElement json) + { + if ( json instanceof JsonPrimitive ) + { + JsonPrimitive jsonPrimitive = (JsonPrimitive) json; + if ( jsonPrimitive.isNumber() ) + { + Number number = json.getAsNumber(); + + if ( number instanceof Byte ) + { + return new ByteTag( (Byte) number ); + } else if ( number instanceof Short ) + { + return new ShortTag( (Short) number ); + } else if ( number instanceof Integer ) + { + return new IntTag( (Integer) number ); + } else if ( number instanceof Long ) + { + return new LongTag( (Long) number ); + } else if ( number instanceof Float ) + { + return new FloatTag( (Float) number ); + } else if ( number instanceof Double ) + { + return new DoubleTag( (Double) number ); + } + } else if ( jsonPrimitive.isString() ) + { + return new StringTag( jsonPrimitive.getAsString() ); + } else if ( jsonPrimitive.isBoolean() ) + { + return new ByteTag( jsonPrimitive.getAsBoolean() ? 1 : 0 ); + } else + { + throw new IllegalArgumentException( "Unknown JSON primitive: " + jsonPrimitive ); + } + } else if ( json instanceof JsonObject ) + { + CompoundTag compoundTag = new CompoundTag(); + for ( Map.Entry property : ( (JsonObject) json ).entrySet() ) + { + compoundTag.add( property.getKey(), fromJson( property.getValue() ) ); + } + + return compoundTag; + } else if ( json instanceof JsonArray ) + { + List jsonArray = ( (JsonArray) json ).asList(); + + if ( jsonArray.isEmpty() ) + { + return new ListTag( Tag.TAG_END, Collections.emptyList() ); + } + + SpecificTag listTag; + int listType = fromJson( jsonArray.get( 0 ) ).tagType(); + switch ( listType ) + { + case Tag.TAG_BYTE: + byte[] bytes = new byte[ jsonArray.size() ]; + for ( int i = 0; i < bytes.length; i++ ) + { + bytes[i] = (Byte) ( (JsonPrimitive) jsonArray.get( i ) ).getAsNumber(); + } + + listTag = new ByteArrayTag( bytes ); + break; + case Tag.TAG_INT: + int[] ints = new int[ jsonArray.size() ]; + for ( int i = 0; i < ints.length; i++ ) + { + ints[i] = (Integer) ( (JsonPrimitive) jsonArray.get( i ) ).getAsNumber(); + } + + listTag = new IntArrayTag( ints ); + break; + case Tag.TAG_LONG: + long[] longs = new long[ jsonArray.size() ]; + for ( int i = 0; i < longs.length; i++ ) + { + longs[i] = (Long) ( (JsonPrimitive) jsonArray.get( i ) ).getAsNumber(); + } + + listTag = new LongArrayTag( longs ); + break; + default: + List tagItems = new ArrayList<>( jsonArray.size() ); + + for ( JsonElement jsonEl : jsonArray ) + { + SpecificTag subTag = fromJson( jsonEl ); + if ( subTag.tagType() != listType ) + { + throw new IllegalArgumentException( "Cannot convert mixed JsonArray to Tag" ); + } + + tagItems.add( subTag ); + } + + listTag = new ListTag( listType, tagItems ); + break; + } + + return listTag; + } else if ( json instanceof JsonNull ) + { + return Tag.END; + } + + throw new IllegalArgumentException( "Unknown JSON element: " + json ); + } + + public static JsonElement toJson(SpecificTag tag) + { + switch ( tag.tagType() ) + { + case Tag.TAG_BYTE: + return new JsonPrimitive( (byte) ( (ByteTag) tag ).getData() ); + case Tag.TAG_SHORT: + return new JsonPrimitive( ( (ShortTag) tag ).getData() ); + case Tag.TAG_INT: + return new JsonPrimitive( ( (IntTag) tag ).getData() ); + case Tag.TAG_LONG: + return new JsonPrimitive( ( (LongTag) tag ).getData() ); + case Tag.TAG_FLOAT: + return new JsonPrimitive( ( (FloatTag) tag ).getData() ); + case Tag.TAG_DOUBLE: + return new JsonPrimitive( ( (DoubleTag) tag ).getData() ); + case Tag.TAG_BYTE_ARRAY: + byte[] byteArray = ( (ByteArrayTag) tag ).getData(); + + JsonArray jsonByteArray = new JsonArray( byteArray.length ); + for ( byte b : byteArray ) + { + jsonByteArray.add( new JsonPrimitive( b ) ); + } + + return jsonByteArray; + case Tag.TAG_STRING: + return new JsonPrimitive( ( (StringTag) tag ).getData() ); + case Tag.TAG_LIST: + List items = ( (ListTag) tag ).items; + + JsonArray jsonList = new JsonArray( items.size() ); + for ( SpecificTag subTag : items ) + { + jsonList.add( toJson( subTag ) ); + } + + return jsonList; + case Tag.TAG_COMPOUND: + JsonObject jsonObject = new JsonObject(); + for ( NamedTag subTag : (CompoundTag) tag ) + { + jsonObject.add( subTag.name(), toJson( subTag.getTag() ) ); + } + + return jsonObject; + case Tag.TAG_INT_ARRAY: + int[] intArray = ( (IntArrayTag) tag ).getData(); + + JsonArray jsonIntArray = new JsonArray( intArray.length ); + for ( int i : intArray ) + { + jsonIntArray.add( new JsonPrimitive( i ) ); + } + + return jsonIntArray; + case Tag.TAG_LONG_ARRAY: + long[] longArray = ( (LongArrayTag) tag ).getData(); + + JsonArray jsonLongArray = new JsonArray( longArray.length ); + for ( long l : longArray ) + { + jsonLongArray.add( new JsonPrimitive( l ) ); + } + + return jsonLongArray; + default: + throw new IllegalArgumentException( "Unknown NBT tag: " + tag ); + } + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/BossBar.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/BossBar.java index a26fba6e5..991a1ab9e 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/BossBar.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/BossBar.java @@ -5,6 +5,7 @@ import java.util.UUID; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -17,7 +18,7 @@ public class BossBar extends DefinedPacket private UUID uuid; private int action; - private String title; + private BaseComponent title; private float health; private int color; private int division; @@ -39,7 +40,7 @@ public class BossBar extends DefinedPacket { // Add case 0: - title = readString( buf ); + title = readBaseComponent( buf, protocolVersion ); health = buf.readFloat(); color = readVarInt( buf ); division = readVarInt( buf ); @@ -51,7 +52,7 @@ public class BossBar extends DefinedPacket break; // Title case 3: - title = readString( buf ); + title = readBaseComponent( buf, protocolVersion ); break; // Style case 4: @@ -75,7 +76,7 @@ public class BossBar extends DefinedPacket { // Add case 0: - writeString( title, buf ); + writeBaseComponent( title, buf, protocolVersion ); buf.writeFloat( health ); writeVarInt( color, buf ); writeVarInt( division, buf ); @@ -87,7 +88,7 @@ public class BossBar extends DefinedPacket break; // Title case 3: - writeString( title, buf ); + writeBaseComponent( title, buf, protocolVersion ); break; // Style case 4: diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Kick.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Kick.java index 3976d91c0..14539b4b8 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Kick.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Kick.java @@ -5,8 +5,12 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.ProtocolConstants; @Data @NoArgsConstructor @@ -15,18 +19,30 @@ import net.md_5.bungee.protocol.DefinedPacket; public class Kick extends DefinedPacket { - private String message; + private BaseComponent message; @Override - public void read(ByteBuf buf) + public void read(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) { - message = readString( buf ); + if ( protocol == Protocol.LOGIN ) + { + message = ComponentSerializer.deserialize( readString( buf ) ); + } else + { + message = readBaseComponent( buf, protocolVersion ); + } } @Override - public void write(ByteBuf buf) + public void write(ByteBuf buf, Protocol protocol, ProtocolConstants.Direction direction, int protocolVersion) { - writeString( message, buf ); + if ( protocol == Protocol.LOGIN ) + { + writeString( ComponentSerializer.toString( message ), buf ); + } else + { + writeBaseComponent( message, buf, protocolVersion ); + } } @Override diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListHeaderFooter.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListHeaderFooter.java index 470deab09..98dbae4a9 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListHeaderFooter.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListHeaderFooter.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -16,21 +17,21 @@ import net.md_5.bungee.protocol.ProtocolConstants; public class PlayerListHeaderFooter extends DefinedPacket { - private String header; - private String footer; + private BaseComponent header; + private BaseComponent footer; @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - header = readString( buf ); - footer = readString( buf ); + header = readBaseComponent( buf, protocolVersion ); + footer = readBaseComponent( buf, protocolVersion ); } @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - writeString( header, buf ); - writeString( footer, buf ); + writeBaseComponent( header, buf, protocolVersion ); + writeBaseComponent( footer, buf, protocolVersion ); } @Override diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java index 9b9c412da..34a12a80e 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java @@ -5,6 +5,7 @@ import java.util.UUID; import lombok.Data; import lombok.EqualsAndHashCode; 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.PlayerPublicKey; @@ -38,7 +39,7 @@ public class PlayerListItem extends DefinedPacket item.ping = DefinedPacket.readVarInt( buf ); if ( buf.readBoolean() ) { - item.displayName = DefinedPacket.readString( buf ); + item.displayName = DefinedPacket.readBaseComponent( buf, protocolVersion ); } if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) { @@ -54,7 +55,7 @@ public class PlayerListItem extends DefinedPacket case UPDATE_DISPLAY_NAME: if ( buf.readBoolean() ) { - item.displayName = DefinedPacket.readString( buf ); + item.displayName = DefinedPacket.readBaseComponent( buf, protocolVersion ); } } } @@ -78,7 +79,7 @@ public class PlayerListItem extends DefinedPacket buf.writeBoolean( item.displayName != null ); if ( item.displayName != null ) { - DefinedPacket.writeString( item.displayName, buf ); + DefinedPacket.writeBaseComponent( item.displayName, buf, protocolVersion ); } if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) { @@ -95,7 +96,7 @@ public class PlayerListItem extends DefinedPacket buf.writeBoolean( item.displayName != null ); if ( item.displayName != null ) { - DefinedPacket.writeString( item.displayName, buf ); + DefinedPacket.writeBaseComponent( item.displayName, buf, protocolVersion ); } break; } @@ -142,7 +143,7 @@ public class PlayerListItem extends DefinedPacket Integer ping; // ADD_PLAYER & UPDATE_DISPLAY_NAME - String displayName; + BaseComponent displayName; } } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java index 21d87c29e..f6708b062 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java @@ -58,7 +58,7 @@ public class PlayerListItemUpdate extends DefinedPacket case UPDATE_DISPLAY_NAME: if ( buf.readBoolean() ) { - item.displayName = DefinedPacket.readString( buf ); + item.displayName = DefinedPacket.readBaseComponent( buf, protocolVersion ); } break; } @@ -106,7 +106,7 @@ public class PlayerListItemUpdate extends DefinedPacket buf.writeBoolean( item.displayName != null ); if ( item.displayName != null ) { - DefinedPacket.writeString( item.displayName, buf ); + DefinedPacket.writeBaseComponent( item.displayName, buf, protocolVersion ); } break; } 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 3c7905d54..e0a12af80 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 @@ -6,6 +6,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -18,7 +19,7 @@ public class ScoreboardObjective extends DefinedPacket { private String name; - private String value; + private BaseComponent value; private HealthDisplay type; /** * 0 to create, 1 to remove, 2 to update display text. @@ -32,7 +33,7 @@ public class ScoreboardObjective extends DefinedPacket action = buf.readByte(); if ( action == 0 || action == 2 ) { - value = readString( buf ); + value = readBaseComponent( buf, protocolVersion ); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { type = HealthDisplay.values()[readVarInt( buf )]; @@ -50,7 +51,7 @@ public class ScoreboardObjective extends DefinedPacket buf.writeByte( action ); if ( action == 0 || action == 2 ) { - writeString( value, buf ); + writeBaseComponent( 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/ServerData.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java index 8536bae77..d3427f38d 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -16,7 +17,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; public class ServerData extends DefinedPacket { - private String motd; + private BaseComponent motd; private Object icon; private boolean preview; private boolean enforceSecure; @@ -26,7 +27,7 @@ public class ServerData extends DefinedPacket { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 || buf.readBoolean() ) { - motd = readString( buf, 262144 ); + motd = readBaseComponent( buf, protocolVersion ); } if ( buf.readBoolean() ) { @@ -59,7 +60,7 @@ public class ServerData extends DefinedPacket { buf.writeBoolean( true ); } - writeString( motd, buf, 262144 ); + writeBaseComponent( motd, buf, protocolVersion ); } else { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_4 ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Subtitle.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Subtitle.java index 6c842f031..69e0b8403 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Subtitle.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Subtitle.java @@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -14,18 +15,18 @@ import net.md_5.bungee.protocol.ProtocolConstants; public class Subtitle extends DefinedPacket { - private String text; + private BaseComponent text; @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - text = readString( buf ); + text = readBaseComponent( buf, protocolVersion ); } @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - writeString( text, buf ); + writeBaseComponent( text, buf, protocolVersion ); } @Override diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/SystemChat.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/SystemChat.java index 3f1fc2672..36dea9753 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/SystemChat.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/SystemChat.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import net.md_5.bungee.api.ChatMessageType; +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.ProtocolConstants; @@ -17,20 +18,20 @@ import net.md_5.bungee.protocol.ProtocolConstants; public class SystemChat extends DefinedPacket { - private String message; + private BaseComponent message; private int position; @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - message = readString( buf, 262144 ); + message = readBaseComponent( buf, protocolVersion ); position = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) ? ( ( buf.readBoolean() ) ? ChatMessageType.ACTION_BAR.ordinal() : 0 ) : readVarInt( buf ); } @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - writeString( message, buf, 262144 ); + writeBaseComponent( message, buf, protocolVersion ); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { buf.writeBoolean( position == ChatMessageType.ACTION_BAR.ordinal() ); 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 21aa96750..2ea141bc7 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 @@ -1,6 +1,6 @@ package net.md_5.bungee.protocol.packet; -import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.Message; import com.mojang.brigadier.context.StringRange; import com.mojang.brigadier.suggestion.Suggestion; import com.mojang.brigadier.suggestion.Suggestions; @@ -10,6 +10,7 @@ import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -51,9 +52,9 @@ public class TabCompleteResponse extends DefinedPacket for ( int i = 0; i < cnt; i++ ) { String match = readString( buf ); - String tooltip = buf.readBoolean() ? readString( buf ) : null; + BaseComponent tooltip = buf.readBoolean() ? readBaseComponent( buf, protocolVersion ) : null; - matches.add( new Suggestion( range, match, new LiteralMessage( tooltip ) ) ); + matches.add( new Suggestion( range, match, ( tooltip != null ) ? new ComponentMessage( tooltip ) : null ) ); } suggestions = new Suggestions( range, matches ); @@ -76,10 +77,10 @@ public class TabCompleteResponse extends DefinedPacket for ( Suggestion suggestion : suggestions.getList() ) { writeString( suggestion.getText(), buf ); - buf.writeBoolean( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null ); - if ( suggestion.getTooltip() != null && suggestion.getTooltip().getString() != null ) + buf.writeBoolean( suggestion.getTooltip() != null ); + if ( suggestion.getTooltip() != null ) { - writeString( suggestion.getTooltip().getString(), buf ); + writeBaseComponent( ( (ComponentMessage) suggestion.getTooltip() ).getComponent(), buf, protocolVersion ); } } } else @@ -93,4 +94,17 @@ public class TabCompleteResponse extends DefinedPacket { handler.handle( this ); } + + @Data + private static class ComponentMessage implements Message + { + + private final BaseComponent component; + + @Override + public String getString() + { + return component.toPlainText(); + } + } } 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 a5555f6af..016b7e149 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 @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -21,9 +22,9 @@ public class Team extends DefinedPacket * 0 - create, 1 remove, 2 info update, 3 player add, 4 player remove. */ private byte mode; - private String displayName; - private String prefix; - private String suffix; + private BaseComponent displayName; + private BaseComponent prefix; + private BaseComponent suffix; private String nameTagVisibility; private String collisionRule; private int color; @@ -48,11 +49,11 @@ public class Team extends DefinedPacket mode = buf.readByte(); if ( mode == 0 || mode == 2 ) { - displayName = readString( buf ); + displayName = readBaseComponent( buf, protocolVersion ); if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) { - prefix = readString( buf ); - suffix = readString( buf ); + prefix = readBaseComponent( buf, protocolVersion ); + suffix = readBaseComponent( buf, protocolVersion ); } friendlyFire = buf.readByte(); nameTagVisibility = readString( buf ); @@ -63,8 +64,8 @@ public class Team extends DefinedPacket color = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) ? readVarInt( buf ) : buf.readByte(); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { - prefix = readString( buf ); - suffix = readString( buf ); + prefix = readBaseComponent( buf, protocolVersion ); + suffix = readBaseComponent( buf, protocolVersion ); } } if ( mode == 0 || mode == 3 || mode == 4 ) @@ -85,11 +86,11 @@ public class Team extends DefinedPacket buf.writeByte( mode ); if ( mode == 0 || mode == 2 ) { - writeString( displayName, buf ); + writeBaseComponent( displayName, buf, protocolVersion ); if ( protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) { - writeString( prefix, buf ); - writeString( suffix, buf ); + writeBaseComponent( prefix, buf, protocolVersion ); + writeBaseComponent( suffix, buf, protocolVersion ); } buf.writeByte( friendlyFire ); writeString( nameTagVisibility, buf ); @@ -101,8 +102,8 @@ public class Team extends DefinedPacket if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_13 ) { writeVarInt( color, buf ); - writeString( prefix, buf ); - writeString( suffix, buf ); + writeBaseComponent( prefix, buf, protocolVersion ); + writeBaseComponent( suffix, buf, protocolVersion ); } else { buf.writeByte( color ); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Title.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Title.java index 331ac5c9f..125cbeb77 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Title.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Title.java @@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf; import lombok.Data; import lombok.EqualsAndHashCode; 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.ProtocolConstants; @@ -17,7 +18,7 @@ public class Title extends DefinedPacket private Action action; // TITLE & SUBTITLE - private String text; + private BaseComponent text; // TIMES private int fadeIn; @@ -34,7 +35,7 @@ public class Title extends DefinedPacket { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_17 ) { - text = readString( buf ); + text = readBaseComponent( buf, protocolVersion ); return; } @@ -52,7 +53,7 @@ public class Title extends DefinedPacket case TITLE: case SUBTITLE: case ACTIONBAR: - text = readString( buf ); + text = readBaseComponent( buf, protocolVersion ); break; case TIMES: fadeIn = buf.readInt(); @@ -67,7 +68,7 @@ public class Title extends DefinedPacket { if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_17 ) { - writeString( text, buf ); + writeBaseComponent( text, buf, protocolVersion ); return; } @@ -85,7 +86,7 @@ public class Title extends DefinedPacket case TITLE: case SUBTITLE: case ACTIONBAR: - writeString( text, buf ); + writeBaseComponent( text, buf, protocolVersion ); break; case TIMES: buf.writeInt( fadeIn ); diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java b/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java index c1686a939..9a6ef7a5f 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java @@ -3,8 +3,8 @@ package net.md_5.bungee; import lombok.Data; import net.md_5.bungee.api.Title; import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.packet.ClearTitles; @@ -53,21 +53,14 @@ public class BungeeTitle implements Title title = new TitlePacketHolder<>( packet, packet ); } - title.oldPacket.setText( ComponentSerializer.toString( text ) ); // = newPacket + title.oldPacket.setText( text ); // = newPacket return this; } @Override public Title title(BaseComponent... text) { - if ( title == null ) - { - net.md_5.bungee.protocol.packet.Title packet = new net.md_5.bungee.protocol.packet.Title( Action.TITLE ); - title = new TitlePacketHolder<>( packet, packet ); - } - - title.oldPacket.setText( ComponentSerializer.toString( text ) ); // = newPacket - return this; + return title( TextComponent.fromArray( text ) ); } @Override @@ -78,24 +71,15 @@ public class BungeeTitle implements Title subtitle = new TitlePacketHolder<>( new net.md_5.bungee.protocol.packet.Title( Action.SUBTITLE ), new Subtitle() ); } - String serialized = ComponentSerializer.toString( text ); - subtitle.oldPacket.setText( serialized ); - subtitle.newPacket.setText( serialized ); + subtitle.oldPacket.setText( text ); + subtitle.newPacket.setText( text ); return this; } @Override public Title subTitle(BaseComponent... text) { - if ( subtitle == null ) - { - subtitle = new TitlePacketHolder<>( new net.md_5.bungee.protocol.packet.Title( Action.SUBTITLE ), new Subtitle() ); - } - - String serialized = ComponentSerializer.toString( text ); - subtitle.oldPacket.setText( serialized ); - subtitle.newPacket.setText( serialized ); - return this; + return subTitle( TextComponent.fromArray( text ) ); } @Override 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 409464d25..5ca53d81d 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -14,6 +14,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.api.event.ServerConnectedEvent; @@ -278,7 +279,7 @@ public class ServerConnector extends PacketHandler Scoreboard serverScoreboard = user.getServerSentScoreboard(); for ( Objective objective : serverScoreboard.getObjectives() ) { - user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), objective.getValue(), ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), (byte) 1 ) ); + user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), ComponentSerializer.deserialize( objective.getValue() ), ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), (byte) 1 ) ); } for ( Score score : serverScoreboard.getScores() ) { @@ -383,7 +384,10 @@ public class ServerConnector extends PacketHandler public void handle(Kick kick) throws Exception { ServerInfo def = user.updateAndGetNextServer( target ); - ServerKickEvent event = new ServerKickEvent( user, target, ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTING ); + ServerKickEvent event = new ServerKickEvent( user, target, new BaseComponent[] + { + kick.getMessage() + }, def, ServerKickEvent.State.CONNECTING ); if ( event.getKickReason().toLowerCase( Locale.ROOT ).contains( "outdated" ) && def != null ) { // Pre cancel the event if we are going to try another server diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index be65c3ada..9e0f68cbf 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -406,13 +406,13 @@ public final class UserConnection implements ProxiedPlayer @Override public void disconnect(String reason) { - disconnect0( TextComponent.fromLegacyText( reason ) ); + disconnect( TextComponent.fromLegacyText( reason ) ); } @Override public void disconnect(BaseComponent... reason) { - disconnect0( reason ); + disconnect( TextComponent.fromArray( reason ) ); } @Override @@ -421,7 +421,7 @@ public final class UserConnection implements ProxiedPlayer disconnect0( reason ); } - public void disconnect0(final BaseComponent... reason) + public void disconnect0(final BaseComponent reason) { if ( !ch.isClosing() ) { @@ -430,7 +430,7 @@ public final class UserConnection implements ProxiedPlayer getName(), BaseComponent.toLegacyText( reason ) } ); - ch.close( new Kick( ComponentSerializer.toString( reason ) ) ); + ch.close( new Kick( reason ) ); if ( server != null ) { @@ -481,7 +481,7 @@ public final class UserConnection implements ProxiedPlayer @Override public void sendMessage(ChatMessageType position, BaseComponent... message) { - sendMessage( position, null, message ); + sendMessage( position, null, TextComponent.fromArray( message ) ); } @Override @@ -493,7 +493,7 @@ public final class UserConnection implements ProxiedPlayer @Override public void sendMessage(UUID sender, BaseComponent... message) { - sendMessage( ChatMessageType.CHAT, sender, message ); + sendMessage( ChatMessageType.CHAT, sender, TextComponent.fromArray( message ) ); } @Override @@ -502,8 +502,28 @@ public final class UserConnection implements ProxiedPlayer sendMessage( ChatMessageType.CHAT, sender, message ); } - private void sendMessage(ChatMessageType position, UUID sender, String message) + private void sendMessage(ChatMessageType position, UUID sender, BaseComponent message) { + // transform score components + message = ChatComponentTransformer.getInstance().transform( this, true, message ); + + if ( position == ChatMessageType.ACTION_BAR && getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_17 ) + { + // Versions older than 1.11 cannot send the Action bar with the new JSON formattings + // Fix by converting to a legacy message, see https://bugs.mojang.com/browse/MC-119145 + if ( getPendingConnection().getVersion() <= ProtocolConstants.MINECRAFT_1_10 ) + { + message = new TextComponent( BaseComponent.toLegacyText( message ) ); + } else + { + net.md_5.bungee.protocol.packet.Title title = new net.md_5.bungee.protocol.packet.Title(); + title.setAction( net.md_5.bungee.protocol.packet.Title.Action.ACTIONBAR ); + title.setText( message ); + sendPacketQueued( title ); + return; + } + } + if ( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19 ) { // Align with Spigot and remove client side formatting for now @@ -515,32 +535,7 @@ public final class UserConnection implements ProxiedPlayer sendPacketQueued( new SystemChat( message, position.ordinal() ) ); } else { - sendPacketQueued( new Chat( message, (byte) position.ordinal(), sender ) ); - } - } - - private void sendMessage(ChatMessageType position, UUID sender, BaseComponent... message) - { - // transform score components - message = ChatComponentTransformer.getInstance().transform( this, true, message ); - - if ( position == ChatMessageType.ACTION_BAR && getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_17 ) - { - // Versions older than 1.11 cannot send the Action bar with the new JSON formattings - // Fix by converting to a legacy message, see https://bugs.mojang.com/browse/MC-119145 - if ( getPendingConnection().getVersion() <= ProtocolConstants.MINECRAFT_1_10 ) - { - sendMessage( position, sender, ComponentSerializer.toString( new TextComponent( BaseComponent.toLegacyText( message ) ) ) ); - } else - { - net.md_5.bungee.protocol.packet.Title title = new net.md_5.bungee.protocol.packet.Title(); - title.setAction( net.md_5.bungee.protocol.packet.Title.Action.ACTIONBAR ); - title.setText( ComponentSerializer.toString( message ) ); - sendPacketQueued( title ); - } - } else - { - sendMessage( position, sender, ComponentSerializer.toString( message ) ); + sendPacketQueued( new Chat( ComponentSerializer.toString( message ), (byte) position.ordinal(), sender ) ); } } @@ -720,25 +715,19 @@ public final class UserConnection implements ProxiedPlayer @Override public void setTabHeader(BaseComponent header, BaseComponent footer) { - header = ChatComponentTransformer.getInstance().transform( this, true, header )[0]; - footer = ChatComponentTransformer.getInstance().transform( this, true, footer )[0]; + header = ChatComponentTransformer.getInstance().transform( this, true, header ); + footer = ChatComponentTransformer.getInstance().transform( this, true, footer ); sendPacketQueued( new PlayerListHeaderFooter( - ComponentSerializer.toString( header ), - ComponentSerializer.toString( footer ) + header, + footer ) ); } @Override public void setTabHeader(BaseComponent[] header, BaseComponent[] footer) { - header = ChatComponentTransformer.getInstance().transform( this, true, header ); - footer = ChatComponentTransformer.getInstance().transform( this, true, footer ); - - sendPacketQueued( new PlayerListHeaderFooter( - ComponentSerializer.toString( header ), - ComponentSerializer.toString( footer ) - ) ); + setTabHeader( TextComponent.fromArray( header ), TextComponent.fromArray( footer ) ); } @Override 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 117ebb763..8f955fdca 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(), objective.getValue(), objective.getType().toString() ) ); + serverScoreboard.addObjective( new Objective( objective.getName(), ComponentSerializer.toString( objective.getValue() ), 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( objective.getValue() ); + oldObjective.setValue( ComponentSerializer.toString( objective.getValue() ) ); oldObjective.setType( objective.getType().toString() ); } break; @@ -254,9 +254,9 @@ public class DownstreamBridge extends PacketHandler { if ( team.getMode() == 0 || team.getMode() == 2 ) { - t.setDisplayName( team.getDisplayName() ); - t.setPrefix( team.getPrefix() ); - t.setSuffix( team.getSuffix() ); + t.setDisplayName( ComponentSerializer.toString( team.getDisplayName() ) ); + t.setPrefix( ComponentSerializer.toString( team.getPrefix() ) ); + t.setSuffix( ComponentSerializer.toString( team.getSuffix() ) ); t.setFriendlyFire( team.getFriendlyFire() ); t.setNameTagVisibility( team.getNameTagVisibility() ); t.setCollisionRule( team.getCollisionRule() ); @@ -620,13 +620,16 @@ public class DownstreamBridge extends PacketHandler public void handle(Kick kick) throws Exception { ServerInfo def = con.updateAndGetNextServer( server.getInfo() ); - ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, server.getInfo(), ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTED ) ); + ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, server.getInfo(), new BaseComponent[] + { + kick.getMessage() + }, def, ServerKickEvent.State.CONNECTED ) ); if ( event.isCancelled() && event.getCancelServer() != null ) { con.connectNow( event.getCancelServer(), ServerConnectEvent.Reason.KICK_REDIRECT ); } else { - con.disconnect0( event.getKickReasonComponent() ); // TODO: Prefix our own stuff. + con.disconnect( event.getKickReasonComponent() ); // TODO: Prefix our own stuff. } server.setObsolete( true ); throw CancelSendSignal.INSTANCE; diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 09080f36b..4189bc12a 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -39,7 +39,6 @@ import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.event.PreLoginEvent; import net.md_5.bungee.api.event.ProxyPingEvent; import net.md_5.bungee.api.event.ServerConnectEvent; -import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.http.HttpClient; import net.md_5.bungee.jni.cipher.BungeeCipher; import net.md_5.bungee.netty.ChannelWrapper; @@ -656,22 +655,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection @Override public void disconnect(final BaseComponent... reason) { - if ( canSendKickMessage() ) - { - ch.delayedClose( new Kick( ComponentSerializer.toString( reason ) ) ); - } else - { - ch.close(); - } + disconnect( TextComponent.fromArray( reason ) ); } @Override public void disconnect(BaseComponent reason) { - disconnect( new BaseComponent[] + if ( canSendKickMessage() ) { - reason - } ); + ch.delayedClose( new Kick( reason ) ); + } else + { + ch.close(); + } } @Override 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 30cc36a48..9a47f2ec4 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 @@ -84,6 +84,8 @@ public abstract class EntityMap return EntityMap_1_16_2.INSTANCE_1_19_4; case ProtocolConstants.MINECRAFT_1_20_2: return EntityMap_1_16_2.INSTANCE_1_20_2; + case ProtocolConstants.MINECRAFT_1_20_3: + return EntityMap_1_16_2.INSTANCE_1_20_3; } throw new RuntimeException( "Version " + version + " has no entity map" ); } diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java index 5815ebf9c..007957a8c 100644 --- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_16_2.java @@ -21,6 +21,7 @@ class EntityMap_1_16_2 extends EntityMap static final EntityMap_1_16_2 INSTANCE_1_19_1 = new EntityMap_1_16_2( 0x02, 0x30 ); static final EntityMap_1_16_2 INSTANCE_1_19_4 = new EntityMap_1_16_2( 0x03, 0x30 ); static final EntityMap_1_16_2 INSTANCE_1_20_2 = new EntityMap_1_16_2( -1, 0x33 ); + static final EntityMap_1_16_2 INSTANCE_1_20_3 = new EntityMap_1_16_2( -1, 0x34 ); // private final int spawnPlayerId; private final int spectateId; 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 faca17fae..298e4118d 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 @@ -1,9 +1,9 @@ package net.md_5.bungee.util; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; import java.util.List; import java.util.regex.Pattern; +import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; import net.md_5.bungee.api.chat.BaseComponent; @@ -34,30 +34,25 @@ public final class ChatComponentTransformer */ private static final Pattern SELECTOR_PATTERN = Pattern.compile( "^@([pares])(?:\\[([^ ]*)\\])?$" ); - public BaseComponent[] legacyHoverTransform(ProxiedPlayer player, BaseComponent... components) + public BaseComponent legacyHoverTransform(ProxiedPlayer player, BaseComponent next) { if ( player.getPendingConnection().getVersion() < ProtocolConstants.MINECRAFT_1_16 ) { - for ( int i = 0; i < components.length; i++ ) + if ( next.getHoverEvent() == null || next.getHoverEvent().isLegacy() ) { - BaseComponent next = components[i]; - if ( next.getHoverEvent() == null || next.getHoverEvent().isLegacy() ) - { - continue; - } - next = next.duplicate(); - next.getHoverEvent().setLegacy( true ); - if ( next.getHoverEvent().getContents().size() > 1 ) - { - Content exception = next.getHoverEvent().getContents().get( 0 ); - next.getHoverEvent().getContents().clear(); - next.getHoverEvent().getContents().add( exception ); - } - components[i] = next; + return next; + } + next = next.duplicate(); + next.getHoverEvent().setLegacy( true ); + if ( next.getHoverEvent().getContents().size() > 1 ) + { + Content exception = next.getHoverEvent().getContents().get( 0 ); + next.getHoverEvent().getContents().clear(); + next.getHoverEvent().getContents().add( exception ); } } - return components; + return next; } public static ChatComponentTransformer getInstance() @@ -77,7 +72,7 @@ public final class ChatComponentTransformer * TextComponent if the components are null or empty * @throws IllegalArgumentException if an entity selector pattern is present */ - public BaseComponent[] transform(ProxiedPlayer player, BaseComponent... components) + public BaseComponent transform(ProxiedPlayer player, BaseComponent components) { return transform( player, false, components ); } @@ -91,40 +86,35 @@ public final class ChatComponentTransformer * @param player player * @param transformHover if the hover event should replace contents with * value - * @param components the component to transform + * @param root the component to transform * @return the transformed component, or an array containing a single empty * TextComponent if the components are null or empty * @throws IllegalArgumentException if an entity selector pattern is present */ - public BaseComponent[] transform(ProxiedPlayer player, boolean transformHover, BaseComponent... components) + public BaseComponent transform(ProxiedPlayer player, boolean transformHover, BaseComponent root) { - if ( components == null || components.length < 1 || ( components.length == 1 && components[0] == null ) ) + if ( root == null ) { - return new BaseComponent[] - { - new TextComponent( "" ) - }; + return new TextComponent( "" ); } if ( transformHover ) { - components = legacyHoverTransform( player, components ); + root = legacyHoverTransform( player, root ); } - for ( BaseComponent root : components ) + if ( root.getExtra() != null && !root.getExtra().isEmpty() ) { - if ( root.getExtra() != null && !root.getExtra().isEmpty() ) - { - List list = Lists.newArrayList( transform( player, transformHover, root.getExtra().toArray( new BaseComponent[ 0 ] ) ) ); - root.setExtra( list ); - } - - if ( root instanceof ScoreComponent ) - { - transformScoreComponent( player, (ScoreComponent) root ); - } + List list = root.getExtra().stream().map( (extra) -> transform( player, transformHover, extra ) ).collect( Collectors.toList() ); + root.setExtra( list ); } - return components; + + if ( root instanceof ScoreComponent ) + { + transformScoreComponent( player, (ScoreComponent) root ); + } + + return root; } /**