1
1
package com .comphenix .protocol .wrappers ;
2
2
3
- import java .lang .reflect .Method ;
4
- import java .util .List ;
3
+ import java .io .StringReader ;
5
4
6
5
import org .bukkit .ChatColor ;
7
6
7
+ import com .comphenix .protocol .reflect .FieldUtils ;
8
8
import com .comphenix .protocol .reflect .FuzzyReflection ;
9
9
import com .comphenix .protocol .reflect .accessors .Accessors ;
10
10
import com .comphenix .protocol .reflect .accessors .ConstructorAccessor ;
19
19
public class WrappedChatComponent extends AbstractWrapper {
20
20
private static final Class <?> SERIALIZER = MinecraftReflection .getChatSerializerClass ();
21
21
private static final Class <?> COMPONENT = MinecraftReflection .getIChatBaseComponentClass ();
22
+ private static final Class <?> GSON_CLASS = MinecraftReflection .getMinecraftGsonClass ();
23
+
24
+ private static Object GSON = null ;
25
+ private static MethodAccessor DESERIALIZE = null ;
26
+
22
27
private static MethodAccessor SERIALIZE_COMPONENT = null ;
23
- private static MethodAccessor DESERIALIZE_COMPONENT = null ;
24
28
private static MethodAccessor CONSTRUCT_COMPONENT = null ;
25
29
private static ConstructorAccessor CONSTRUCT_TEXT_COMPONENT = null ;
26
-
30
+
27
31
static {
28
- FuzzyReflection fuzzy = FuzzyReflection .fromClass (SERIALIZER );
32
+ FuzzyReflection fuzzy = FuzzyReflection .fromClass (SERIALIZER , true );
29
33
30
34
// Retrieve the correct methods
31
35
SERIALIZE_COMPONENT = Accessors .getMethodAccessor (fuzzy .getMethodByParameters ("serialize" , /* a */
32
36
String .class , new Class <?>[] { COMPONENT }));
33
- DESERIALIZE_COMPONENT = findDeserialize (fuzzy );
37
+
38
+ try {
39
+ GSON = FieldUtils .readStaticField (fuzzy .getFieldByType ("gson" , GSON_CLASS ), true );
40
+ } catch (IllegalAccessException ex ) {
41
+ throw new RuntimeException ("Failed to obtain GSON field" , ex );
42
+ }
43
+
44
+ try {
45
+ DESERIALIZE = Accessors .getMethodAccessor (FuzzyReflection .fromClass (MinecraftReflection .getMinecraftClass ("ChatDeserializer" ), true )
46
+ .getMethodByParameters ("deserialize" , Object .class , new Class <?>[] { GSON_CLASS , String .class , Class .class , boolean .class }));
47
+ } catch (IllegalArgumentException ex ) {
48
+ // We'll handle it in the ComponentParser
49
+ DESERIALIZE = null ;
50
+ }
34
51
35
52
// Get a component from a standard Minecraft message
36
53
CONSTRUCT_COMPONENT = Accessors .getMethodAccessor (MinecraftReflection .getCraftChatMessage (), "fromString" , String .class );
@@ -39,23 +56,17 @@ public class WrappedChatComponent extends AbstractWrapper {
39
56
CONSTRUCT_TEXT_COMPONENT = Accessors .getConstructorAccessor (MinecraftReflection .getChatComponentTextClass (), String .class );
40
57
}
41
58
42
- private static MethodAccessor findDeserialize (FuzzyReflection fuzzy ) {
43
- List <Method > methods = fuzzy .getMethodListByParameters (COMPONENT , new Class <?>[] { String .class });
44
- if (methods .isEmpty ()) {
45
- throw new IllegalArgumentException ("Unable to find deserialize method in " + fuzzy .getSource ().getName ());
46
- }
47
-
48
- // Try to find b, we want leniency
49
- for (Method method : methods ) {
50
- if (method .getName ().equals ("b" )) {
51
- return Accessors .getMethodAccessor (method );
52
- }
59
+ private static Object deserialize (String json ) {
60
+ // Should be non-null on 1.9 and up
61
+ if (DESERIALIZE != null ) {
62
+ return DESERIALIZE .invoke (null , GSON , json , COMPONENT , true );
53
63
}
54
64
55
- // Oh well
56
- return Accessors .getMethodAccessor (methods .get (0 ));
65
+ // Mock leniency behavior in 1.8
66
+ StringReader str = new StringReader (json );
67
+ return ComponentParser .deserialize (GSON , COMPONENT , str );
57
68
}
58
-
69
+
59
70
private transient String cache ;
60
71
61
72
private WrappedChatComponent (Object handle , String cache ) {
@@ -79,7 +90,7 @@ public static WrappedChatComponent fromHandle(Object handle) {
79
90
* @return The chat component wrapper.
80
91
*/
81
92
public static WrappedChatComponent fromJson (String json ) {
82
- return new WrappedChatComponent (DESERIALIZE_COMPONENT . invoke ( null , json ), json );
93
+ return new WrappedChatComponent (deserialize ( json ), json );
83
94
}
84
95
85
96
/**
@@ -127,7 +138,7 @@ public String getJson() {
127
138
* @param obj - the JSON that represents the new component.
128
139
*/
129
140
public void setJson (String obj ) {
130
- this .handle = DESERIALIZE_COMPONENT . invoke ( null , obj );
141
+ this .handle = deserialize ( obj );
131
142
this .cache = obj ;
132
143
}
133
144
0 commit comments