34
34
import java .util .concurrent .atomic .AtomicReference ;
35
35
import net .kyori .adventure .text .Component ;
36
36
import net .kyori .adventure .text .serializer .ComponentSerializer ;
37
- import net .kyori .adventure .text .serializer .gson .GsonComponentSerializer ;
38
37
import org .jetbrains .annotations .ApiStatus ;
39
38
import org .jetbrains .annotations .NotNull ;
40
39
import org .jetbrains .annotations .Nullable ;
@@ -93,11 +92,15 @@ public static boolean isSupported() {
93
92
private static final Object MC_TEXT_GSON ;
94
93
private static final MethodHandle TEXT_SERIALIZER_DESERIALIZE ;
95
94
private static final MethodHandle TEXT_SERIALIZER_SERIALIZE ;
95
+ private static final MethodHandle TEXT_SERIALIZER_DESERIALIZE_TREE ;
96
+ private static final MethodHandle TEXT_SERIALIZER_SERIALIZE_TREE ;
96
97
97
98
static {
98
99
Object gson = null ;
99
100
MethodHandle textSerializerDeserialize = null ;
100
101
MethodHandle textSerializerSerialize = null ;
102
+ MethodHandle textSerializerDeserializeTree = null ;
103
+ MethodHandle textSerializerSerializeTree = null ;
101
104
102
105
try {
103
106
if (CLASS_CHAT_COMPONENT != null ) {
@@ -126,26 +129,45 @@ public static boolean isSupported() {
126
129
if (gsonField != null ) {
127
130
gsonField .setAccessible (true );
128
131
gson = gsonField .get (null );
129
- } else {
130
- final Method [] declaredMethods = chatSerializerClass .getDeclaredMethods ();
131
- final Method deserialize = Arrays .stream (declaredMethods )
132
- .filter (m -> Modifier .isStatic (m .getModifiers ()))
133
- .filter (m -> CLASS_CHAT_COMPONENT .isAssignableFrom (m .getReturnType ()))
134
- .filter (m -> m .getParameterCount () == 1 && m .getParameterTypes ()[0 ].equals (String .class ))
135
- .min (Comparator .comparing (Method ::getName )) // prefer the #a method
136
- .orElse (null );
137
- final Method serialize = Arrays .stream (declaredMethods )
138
- .filter (m -> Modifier .isStatic (m .getModifiers ()))
139
- .filter (m -> m .getReturnType ().equals (String .class ))
140
- .filter (m -> m .getParameterCount () == 1 && CLASS_CHAT_COMPONENT .isAssignableFrom (m .getParameterTypes ()[0 ]))
141
- .findFirst ()
142
- .orElse (null );
143
- if (deserialize != null ) {
144
- textSerializerDeserialize = lookup ().unreflect (deserialize );
145
- }
146
- if (serialize != null ) {
147
- textSerializerSerialize = lookup ().unreflect (serialize );
148
- }
132
+ }
133
+ }
134
+ for (final Class <?> serializerClass : CLASS_CHAT_COMPONENT .getClasses ()) {
135
+ final Method [] declaredMethods = serializerClass .getDeclaredMethods ();
136
+ final Method deserialize = Arrays .stream (declaredMethods )
137
+ .filter (m -> Modifier .isStatic (m .getModifiers ()))
138
+ .filter (m -> CLASS_CHAT_COMPONENT .isAssignableFrom (m .getReturnType ()))
139
+ .filter (m -> m .getParameterCount () == 1 && m .getParameterTypes ()[0 ].equals (String .class ))
140
+ .min (Comparator .comparing (Method ::getName )) // prefer the #a method
141
+ .orElse (null );
142
+ final Method serialize = Arrays .stream (declaredMethods )
143
+ .filter (m -> Modifier .isStatic (m .getModifiers ()))
144
+ .filter (m -> m .getReturnType ().equals (String .class ))
145
+ .filter (m -> m .getParameterCount () == 1 && CLASS_CHAT_COMPONENT .isAssignableFrom (m .getParameterTypes ()[0 ]))
146
+ .findFirst ()
147
+ .orElse (null );
148
+ final Method deserializeTree = Arrays .stream (declaredMethods )
149
+ .filter (m -> Modifier .isStatic (m .getModifiers ()))
150
+ .filter (m -> CLASS_CHAT_COMPONENT .isAssignableFrom (m .getReturnType ()))
151
+ .filter (m -> m .getParameterCount () == 1 && m .getParameterTypes ()[0 ].equals (JsonElement .class ))
152
+ .findFirst ()
153
+ .orElse (null );
154
+ final Method serializeTree = Arrays .stream (declaredMethods )
155
+ .filter (m -> Modifier .isStatic (m .getModifiers ()))
156
+ .filter (m -> m .getReturnType ().equals (JsonElement .class ))
157
+ .filter (m -> m .getParameterCount () == 1 && CLASS_CHAT_COMPONENT .isAssignableFrom (m .getParameterTypes ()[0 ]))
158
+ .findFirst ()
159
+ .orElse (null );
160
+ if (deserialize != null ) {
161
+ textSerializerDeserialize = lookup ().unreflect (deserialize );
162
+ }
163
+ if (serialize != null ) {
164
+ textSerializerSerialize = lookup ().unreflect (serialize );
165
+ }
166
+ if (deserializeTree != null ) {
167
+ textSerializerDeserializeTree = lookup ().unreflect (deserializeTree );
168
+ }
169
+ if (serializeTree != null ) {
170
+ textSerializerSerializeTree = lookup ().unreflect (serializeTree );
149
171
}
150
172
}
151
173
}
@@ -156,20 +178,26 @@ public static boolean isSupported() {
156
178
MC_TEXT_GSON = gson ;
157
179
TEXT_SERIALIZER_DESERIALIZE = textSerializerDeserialize ;
158
180
TEXT_SERIALIZER_SERIALIZE = textSerializerSerialize ;
181
+ TEXT_SERIALIZER_DESERIALIZE_TREE = textSerializerDeserializeTree ;
182
+ TEXT_SERIALIZER_SERIALIZE_TREE = textSerializerSerializeTree ;
159
183
}
160
184
161
- private static final boolean SUPPORTED = MC_TEXT_GSON != null || (TEXT_SERIALIZER_DESERIALIZE != null && TEXT_SERIALIZER_SERIALIZE != null );
185
+ private static final boolean SUPPORTED = MC_TEXT_GSON != null || (TEXT_SERIALIZER_DESERIALIZE != null && TEXT_SERIALIZER_SERIALIZE != null ) || ( TEXT_SERIALIZER_DESERIALIZE_TREE != null && TEXT_SERIALIZER_SERIALIZE_TREE != null ) ;
162
186
163
187
@ Override
164
188
public @ NotNull Component deserialize (final @ NotNull Object input ) {
165
189
if (!SUPPORTED ) throw INITIALIZATION_ERROR .get ();
166
190
167
191
try {
168
- if (MC_TEXT_GSON != null ) {
169
- final JsonElement element = ((Gson ) MC_TEXT_GSON ).toJsonTree (input );
170
- return gson ().serializer ().fromJson (element , Component .class );
192
+ final JsonElement element ;
193
+ if (TEXT_SERIALIZER_SERIALIZE_TREE != null ) {
194
+ element = (JsonElement ) TEXT_SERIALIZER_SERIALIZE_TREE .invoke (input );
195
+ } else if (MC_TEXT_GSON != null ) {
196
+ element = ((Gson ) MC_TEXT_GSON ).toJsonTree (input );
197
+ } else {
198
+ return gson ().deserialize ((String ) TEXT_SERIALIZER_SERIALIZE .invoke (input ));
171
199
}
172
- return GsonComponentSerializer . gson ().deserialize (( String ) TEXT_SERIALIZER_SERIALIZE . invoke ( input ) );
200
+ return gson ().serializer (). fromJson ( element , Component . class );
173
201
} catch (final Throwable error ) {
174
202
throw new UnsupportedOperationException (error );
175
203
}
@@ -179,9 +207,12 @@ public static boolean isSupported() {
179
207
public @ NotNull Object serialize (final @ NotNull Component component ) {
180
208
if (!SUPPORTED ) throw INITIALIZATION_ERROR .get ();
181
209
182
- if (MC_TEXT_GSON != null ) {
210
+ if (TEXT_SERIALIZER_DESERIALIZE_TREE != null || MC_TEXT_GSON != null ) {
183
211
final JsonElement json = gson ().serializer ().toJsonTree (component );
184
212
try {
213
+ if (TEXT_SERIALIZER_DESERIALIZE_TREE != null ) {
214
+ return TEXT_SERIALIZER_DESERIALIZE_TREE .invoke (json );
215
+ }
185
216
return ((Gson ) MC_TEXT_GSON ).fromJson (json , CLASS_CHAT_COMPONENT );
186
217
} catch (final Throwable error ) {
187
218
throw new UnsupportedOperationException (error );
0 commit comments