Skip to content

Commit ca9b5bb

Browse files
fix: use RegistryOps when (de)serializing chat component on 1.21.6+ (#3546)
This fixes an error during serialization when a hover event has an item with `components` (e.g., enchantments).
1 parent d790ded commit ca9b5bb

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

src/main/java/com/comphenix/protocol/utility/MinecraftRegistryAccess.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.lang.reflect.Modifier;
44

5+
import com.comphenix.protocol.wrappers.codecs.WrappedDynamicOps;
56
import org.bukkit.Bukkit;
67

78
import com.comphenix.protocol.reflect.FuzzyReflection;
@@ -17,6 +18,7 @@ public class MinecraftRegistryAccess {
1718

1819
private static MethodAccessor GET_SERVER = null;
1920
private static MethodAccessor REGISTRY_ACCESS = null;
21+
private static MethodAccessor CREATE_SERIALIZATION_CONTEXT = null;
2022

2123
// lazy initialized
2224
private static Object registryAccess = null;
@@ -36,6 +38,14 @@ public class MinecraftRegistryAccess {
3638
.banModifier(Modifier.STATIC)
3739
.returnDerivedOf(MinecraftReflection.getRegistryAccessClass())
3840
.build()));
41+
42+
CREATE_SERIALIZATION_CONTEXT = Accessors.getMethodAccessor(
43+
FuzzyReflection.fromClass(MinecraftReflection.getHolderLookupProviderClass(), false)
44+
.getMethod(FuzzyMethodContract.newBuilder()
45+
.banModifier(Modifier.STATIC)
46+
.returnDerivedOf(MinecraftReflection.getDynamicOpsClass())
47+
.parameterDerivedOf(MinecraftReflection.getDynamicOpsClass())
48+
.build()));
3949
}
4050
}
4151

@@ -57,4 +67,13 @@ public static Object get() {
5767

5868
return registryAccess;
5969
}
70+
71+
/**
72+
* Returns a RegistryOps using the given DynamicOps as the underlying ops.
73+
*
74+
* @return a RegistryOps
75+
*/
76+
public static WrappedDynamicOps createSerializationContext(WrappedDynamicOps dynamicOps) {
77+
return WrappedDynamicOps.fromHandle(CREATE_SERIALIZATION_CONTEXT.invoke(get(), dynamicOps.getHandle()));
78+
}
6079
}

src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import com.comphenix.protocol.wrappers.codecs.WrappedCodec;
88
import com.comphenix.protocol.wrappers.codecs.WrappedDynamicOps;
9-
import com.google.gson.JsonElement;
109
import com.google.gson.JsonParseException;
1110
import com.google.gson.JsonParser;
1211
import org.bukkit.ChatColor;
@@ -42,13 +41,15 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
4241
private static ConstructorAccessor CONSTRUCT_TEXT_COMPONENT = null;
4342

4443
private static WrappedCodec CODEC;
44+
private static WrappedDynamicOps REGISTRY_JSON_OPS;
4545

4646
static {
4747
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER, true);
4848

4949
if (MinecraftVersion.v1_21_6.atOrAbove()) {
5050
Field codecField = fuzzy.getFieldByType("CODEC", MinecraftReflection.getCodecClass());
5151
CODEC = WrappedCodec.fromHandle(Accessors.getFieldAccessor(codecField).get(null));
52+
REGISTRY_JSON_OPS = MinecraftRegistryAccess.createSerializationContext(WrappedDynamicOps.json(false));
5253
} else if (MinecraftVersion.v1_20_5.atOrAbove()) {
5354
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
5455
.returnTypeExact(String.class)
@@ -98,7 +99,7 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
9899

99100
private static Object serialize(Object handle) {
100101
if (CODEC != null) {
101-
Object jobj = CODEC.encode(handle, WrappedDynamicOps.json(false)).getOrThrow(JsonParseException::new);
102+
Object jobj = CODEC.encode(handle, REGISTRY_JSON_OPS).getOrThrow(JsonParseException::new);
102103
return jobj.toString();
103104
}
104105

@@ -111,7 +112,7 @@ private static Object serialize(Object handle) {
111112

112113
private static Object deserialize(String json) {
113114
if (CODEC != null) {
114-
return CODEC.parse(JsonParser.parseString(json), WrappedDynamicOps.json(false)).getOrThrow(JsonParseException::new);
115+
return CODEC.parse(JsonParser.parseString(json), REGISTRY_JSON_OPS).getOrThrow(JsonParseException::new);
115116
}
116117

117118
if (MinecraftVersion.v1_20_5.atOrAbove()) {

0 commit comments

Comments
 (0)