Skip to content

Commit

Permalink
Correctly version component serialization
Browse files Browse the repository at this point in the history
1.20.3+ has some additional options (EMIT_COMPACT_TEXT_COMPONENT,
EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, VALIDATE_STRICT_EVENTS)
that should be disabled in older versions.

The OptionState is constructed manually due to
KyoriPowered/adventure#1015,
which is a bug that makes JSONOptions.BY_DATA_VERSION
use incorrect options for 1.20.3+ options.

This also fixes incorrect building of the ping serializer, as
it should only use the component serializer to serialize
Component.class and nothing else.
  • Loading branch information
Spottedleaf committed Dec 22, 2023
1 parent a54d8c6 commit e190404
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
23 changes: 13 additions & 10 deletions proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,16 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
.registerTypeHierarchyAdapter(Favicon.class, FaviconSerializer.INSTANCE)
.registerTypeHierarchyAdapter(GameProfile.class, GameProfileSerializer.INSTANCE)
.create();
private static final Gson PRE_1_16_PING_SERIALIZER = ProtocolUtils
.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_15_2)
.serializer()
.newBuilder()
private static final Gson PRE_1_16_PING_SERIALIZER = new GsonBuilder()
.registerTypeHierarchyAdapter(Component.class, ProtocolUtils.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_15_2).serializer().getAdapter(Component.class))
.registerTypeHierarchyAdapter(Favicon.class, FaviconSerializer.INSTANCE)
.create();
private static final Gson POST_1_16_PING_SERIALIZER = ProtocolUtils
.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_16)
.serializer()
.newBuilder()
private static final Gson PRE_1_20_3_PING_SERIALIZER = new GsonBuilder()
.registerTypeHierarchyAdapter(Component.class, ProtocolUtils.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_16).serializer().getAdapter(Component.class))
.registerTypeHierarchyAdapter(Favicon.class, FaviconSerializer.INSTANCE)
.create();
private static final Gson MODERN_PING_SERIALIZER = new GsonBuilder()
.registerTypeHierarchyAdapter(Component.class, ProtocolUtils.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_20_3).serializer().getAdapter(Component.class))
.registerTypeHierarchyAdapter(Favicon.class, FaviconSerializer.INSTANCE)
.create();

Expand Down Expand Up @@ -762,8 +762,11 @@ public AdventureBossBarManager getBossBarManager() {
*/
public static Gson getPingGsonInstance(ProtocolVersion version) {
if (version == ProtocolVersion.UNKNOWN
|| version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
return POST_1_16_PING_SERIALIZER;
|| version.compareTo(ProtocolVersion.MINECRAFT_1_20_3) >= 0) {
return MODERN_PING_SERIALIZER;
}
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
return PRE_1_20_3_PING_SERIALIZER;
}
return PRE_1_16_PING_SERIALIZER;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
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.option.OptionState;

/**
* Utilities for writing and reading data in the Minecraft protocol.
Expand All @@ -58,10 +60,47 @@ public enum ProtocolUtils {
.downsampleColors()
.emitLegacyHoverEvent()
.legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE)
.options(
OptionState.optionState()
// before 1.16
.value(JSONOptions.EMIT_RGB, Boolean.FALSE)
.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.LEGACY_ONLY)
// before 1.20.3
.value(JSONOptions.EMIT_COMPACT_TEXT_COMPONENT, Boolean.FALSE)
.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, Boolean.FALSE)
.value(JSONOptions.VALIDATE_STRICT_EVENTS, Boolean.FALSE)
.build()
)
.build();
private static final GsonComponentSerializer PRE_1_20_3_SERIALIZER =
GsonComponentSerializer.builder()
.legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE)
.options(
OptionState.optionState()
// after 1.16
.value(JSONOptions.EMIT_RGB, Boolean.TRUE)
.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.MODERN_ONLY)
// before 1.20.3
.value(JSONOptions.EMIT_COMPACT_TEXT_COMPONENT, Boolean.FALSE)
.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, Boolean.FALSE)
.value(JSONOptions.VALIDATE_STRICT_EVENTS, Boolean.FALSE)
.build()
)
.build();
private static final GsonComponentSerializer MODERN_SERIALIZER =
GsonComponentSerializer.builder()
.legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE)
.options(
OptionState.optionState()
// after 1.16
.value(JSONOptions.EMIT_RGB, Boolean.TRUE)
.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.MODERN_ONLY)
// after 1.20.3
.value(JSONOptions.EMIT_COMPACT_TEXT_COMPONENT, Boolean.TRUE)
.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, Boolean.TRUE)
.value(JSONOptions.VALIDATE_STRICT_EVENTS, Boolean.TRUE)
.build()
)
.build();

public static final int DEFAULT_MAX_STRING_SIZE = 65536; // 64KiB
Expand Down Expand Up @@ -671,9 +710,12 @@ public static String readStringWithoutLength(ByteBuf buf) {
* @return the appropriate {@link GsonComponentSerializer}
*/
public static GsonComponentSerializer getJsonChatSerializer(ProtocolVersion version) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_20_3) >= 0) {
return MODERN_SERIALIZER;
}
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
return PRE_1_20_3_SERIALIZER;
}
return PRE_1_16_SERIALIZER;
}

Expand Down

0 comments on commit e190404

Please sign in to comment.