diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 58e8e11bf..7557ed42c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,8 @@ spotless = "com.diffplug.spotless:6.25.0" [libraries] adventure-bom = "net.kyori:adventure-bom:4.17.0" -adventure-facet = "net.kyori:adventure-platform-facet:4.3.2" +adventure-text-serializer-json-legacy-impl = "net.kyori:adventure-text-serializer-json-legacy-impl:4.17.0" +adventure-facet = "net.kyori:adventure-platform-facet:4.3.4" asm = "org.ow2.asm:asm:9.6" auto-service = "com.google.auto.service:auto-service:1.0.1" auto-service-annotations = "com.google.auto.service:auto-service-annotations:1.0.1" diff --git a/proxy/build.gradle.kts b/proxy/build.gradle.kts index 035ff24de..9b74dae57 100644 --- a/proxy/build.gradle.kts +++ b/proxy/build.gradle.kts @@ -127,7 +127,7 @@ dependencies { runtimeOnly(libs.disruptor) implementation(libs.fastutil) implementation(platform(libs.adventure.bom)) - implementation("net.kyori:adventure-nbt") + implementation(libs.adventure.text.serializer.json.legacy.impl) implementation(libs.adventure.facet) implementation(libs.completablefutures) implementation(libs.nightconfig) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java index 797a58223..ca63c1e56 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java @@ -25,7 +25,6 @@ import com.velocitypowered.api.proxy.crypto.IdentifiedKey; import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.proxy.crypto.IdentifiedKeyImpl; import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder; -import com.velocitypowered.proxy.protocol.util.VelocityLegacyHoverEventSerializer; import com.velocitypowered.proxy.util.except.QuietDecoderException; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; @@ -47,6 +46,7 @@ import net.kyori.adventure.nbt.BinaryTagTypes; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.json.JSONOptions; +import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer; import net.kyori.option.OptionState; /** @@ -58,8 +58,7 @@ public enum ProtocolUtils { private static final GsonComponentSerializer PRE_1_16_SERIALIZER = GsonComponentSerializer.builder() .downsampleColors() - .emitLegacyHoverEvent() - .legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE) + .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get()) .options( OptionState.optionState() // before 1.16 @@ -74,7 +73,7 @@ public enum ProtocolUtils { .build(); private static final GsonComponentSerializer PRE_1_20_3_SERIALIZER = GsonComponentSerializer.builder() - .legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE) + .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get()) .options( OptionState.optionState() // after 1.16 @@ -89,7 +88,7 @@ public enum ProtocolUtils { .build(); private static final GsonComponentSerializer MODERN_SERIALIZER = GsonComponentSerializer.builder() - .legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE) + .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get()) .options( OptionState.optionState() // after 1.16 diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/VelocityLegacyHoverEventSerializer.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/VelocityLegacyHoverEventSerializer.java deleted file mode 100644 index e667a9b16..000000000 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/util/VelocityLegacyHoverEventSerializer.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2020-2023 Velocity Contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.velocitypowered.proxy.protocol.util; - -import java.io.IOException; -import java.util.UUID; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.nbt.TagStringIO; -import net.kyori.adventure.nbt.api.BinaryTagHolder; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.event.HoverEvent.ShowEntity; -import net.kyori.adventure.text.event.HoverEvent.ShowItem; -import net.kyori.adventure.text.serializer.gson.LegacyHoverEventSerializer; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; -import net.kyori.adventure.util.Codec.Decoder; -import net.kyori.adventure.util.Codec.Encoder; -import org.checkerframework.checker.nullness.qual.NonNull; - -/** - * An implementation of {@link LegacyHoverEventSerializer} that implements the interface in the most - * literal, albeit "incompatible" way possible. - */ -public class VelocityLegacyHoverEventSerializer implements LegacyHoverEventSerializer { - - public static final LegacyHoverEventSerializer INSTANCE = - new VelocityLegacyHoverEventSerializer(); - - private VelocityLegacyHoverEventSerializer() { - - } - - private static Key legacyIdToFakeKey(byte id) { - return Key.key("velocity", "legacy_hover/id_" + id); - } - - @Override - public HoverEvent.@NonNull ShowItem deserializeShowItem(@NonNull Component input) - throws IOException { - String snbt = PlainTextComponentSerializer.plainText().serialize(input); - CompoundBinaryTag item = TagStringIO.get().asCompound(snbt); - - Key key; - String idIfString = item.getString("id", ""); - if (idIfString.isEmpty()) { - key = legacyIdToFakeKey(item.getByte("id")); - } else { - key = Key.key(idIfString); - } - - byte count = item.getByte("Count", (byte) 1); - return ShowItem.of(key, count, BinaryTagHolder.binaryTagHolder(snbt)); - } - - @Override - public HoverEvent.@NonNull ShowEntity deserializeShowEntity(@NonNull Component input, - Decoder componentDecoder) throws IOException { - String snbt = PlainTextComponentSerializer.plainText().serialize(input); - CompoundBinaryTag item = TagStringIO.get().asCompound(snbt); - - Component name; - try { - name = componentDecoder.decode(item.getString("name")); - } catch (Exception e) { - name = Component.text(item.getString("name")); - } - - return ShowEntity.of(Key.key(item.getString("type")), - UUID.fromString(item.getString("id")), - name); - } - - @Override - public @NonNull Component serializeShowItem(HoverEvent.@NonNull ShowItem input) - throws IOException { - final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() - .putByte("Count", (byte) input.count()); - - String keyAsString = input.item().asString(); - if (keyAsString.startsWith("velocity:legacy_hover/id_")) { - builder.putByte("id", Byte.parseByte(keyAsString - .substring("velocity:legacy_hover/id_".length()))); - } else { - builder.putString("id", keyAsString); - } - - BinaryTagHolder nbt = input.nbt(); - if (nbt != null) { - builder.put("tag", TagStringIO.get().asCompound(nbt.string())); - } - - return Component.text(TagStringIO.get().asString(builder.build())); - } - - @Override - public @NonNull Component serializeShowEntity(HoverEvent.@NonNull ShowEntity input, - Encoder componentEncoder) throws IOException { - CompoundBinaryTag.Builder tag = CompoundBinaryTag.builder() - .putString("id", input.id().toString()) - .putString("type", input.type().asString()); - Component name = input.name(); - if (name != null) { - tag.putString("name", componentEncoder.encode(name)); - } - return Component.text(TagStringIO.get().asString(tag.build())); - } -}