mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-27 21:26:17 +01:00
parent
087913ab3a
commit
144723af18
@ -25,7 +25,6 @@ import net.md_5.bungee.chat.ComponentSerializer;
|
||||
* Note: The BungeeCord Chat API is not included in CraftBukkit.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class ComponentConverter {
|
||||
|
||||
private ComponentConverter() {
|
||||
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2016 dmulloy2
|
||||
*
|
||||
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Handles component parsing in 1.8
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class ComponentParser {
|
||||
|
||||
private ComponentParser() {
|
||||
}
|
||||
|
||||
public static Object deserialize(Object gson, Class<?> component, StringReader str) {
|
||||
try {
|
||||
com.google.gson.stream.JsonReader reader = new com.google.gson.stream.JsonReader(str);
|
||||
reader.setLenient(true);
|
||||
return ((com.google.gson.Gson) gson).getAdapter(component).read(reader);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to read JSON", ex);
|
||||
} catch (LinkageError er) {
|
||||
return deserializeLegacy(gson, component, str);
|
||||
}
|
||||
}
|
||||
|
||||
// Should only be needed on 1.8.
|
||||
private static Object deserializeLegacy(Object gson, Class<?> component, StringReader str) {
|
||||
try {
|
||||
Class<?> readerClass = Class.forName("org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonReader");
|
||||
Object reader = readerClass.getConstructor(StringReader.class).newInstance(str);
|
||||
Method setLenient = readerClass.getMethod("setLenienent", boolean.class);
|
||||
setLenient.invoke(reader, true);
|
||||
Method getAdapter = gson.getClass().getMethod("getAdapter", Class.class);
|
||||
Object adapter = getAdapter.invoke(gson, component);
|
||||
Method read = adapter.getClass().getMethod("read", readerClass);
|
||||
return read.invoke(adapter, reader);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to read JSON", ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
@ -19,18 +19,35 @@ import com.google.common.base.Preconditions;
|
||||
public class WrappedChatComponent extends AbstractWrapper {
|
||||
private static final Class<?> SERIALIZER = MinecraftReflection.getChatSerializerClass();
|
||||
private static final Class<?> COMPONENT = MinecraftReflection.getIChatBaseComponentClass();
|
||||
private static final Class<?> GSON_CLASS = MinecraftReflection.getMinecraftGsonClass();
|
||||
|
||||
private static Object GSON = null;
|
||||
private static MethodAccessor DESERIALIZE = null;
|
||||
|
||||
private static MethodAccessor SERIALIZE_COMPONENT = null;
|
||||
private static MethodAccessor DESERIALIZE_COMPONENT = null;
|
||||
private static MethodAccessor CONSTRUCT_COMPONENT = null;
|
||||
private static ConstructorAccessor CONSTRUCT_TEXT_COMPONENT = null;
|
||||
|
||||
static {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER);
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER, true);
|
||||
|
||||
// Retrieve the correct methods
|
||||
SERIALIZE_COMPONENT = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("serialize", /* a */
|
||||
String.class, new Class<?>[] { COMPONENT }));
|
||||
DESERIALIZE_COMPONENT = findDeserialize(fuzzy);
|
||||
|
||||
try {
|
||||
GSON = FieldUtils.readStaticField(fuzzy.getFieldByType("gson", GSON_CLASS), true);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Failed to obtain GSON field", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getMinecraftClass("ChatDeserializer"), true)
|
||||
.getMethodByParameters("deserialize", Object.class, new Class<?>[] { GSON_CLASS, String.class, Class.class, boolean.class }));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// We'll handle it in the ComponentParser
|
||||
DESERIALIZE = null;
|
||||
}
|
||||
|
||||
// Get a component from a standard Minecraft message
|
||||
CONSTRUCT_COMPONENT = Accessors.getMethodAccessor(MinecraftReflection.getCraftChatMessage(), "fromString", String.class);
|
||||
@ -39,21 +56,15 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
CONSTRUCT_TEXT_COMPONENT = Accessors.getConstructorAccessor(MinecraftReflection.getChatComponentTextClass(), String.class);
|
||||
}
|
||||
|
||||
private static MethodAccessor findDeserialize(FuzzyReflection fuzzy) {
|
||||
List<Method> methods = fuzzy.getMethodListByParameters(COMPONENT, new Class<?>[] { String.class });
|
||||
if (methods.isEmpty()) {
|
||||
throw new IllegalArgumentException("Unable to find deserialize method in " + fuzzy.getSource().getName());
|
||||
private static Object deserialize(String json) {
|
||||
// Should be non-null on 1.9 and up
|
||||
if (DESERIALIZE != null) {
|
||||
return DESERIALIZE.invoke(null, GSON, json, COMPONENT, true);
|
||||
}
|
||||
|
||||
// Try to find b, we want leniency
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals("b")) {
|
||||
return Accessors.getMethodAccessor(method);
|
||||
}
|
||||
}
|
||||
|
||||
// Oh well
|
||||
return Accessors.getMethodAccessor(methods.get(0));
|
||||
// Mock leniency behavior in 1.8
|
||||
StringReader str = new StringReader(json);
|
||||
return ComponentParser.deserialize(GSON, COMPONENT, str);
|
||||
}
|
||||
|
||||
private transient String cache;
|
||||
@ -79,7 +90,7 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
* @return The chat component wrapper.
|
||||
*/
|
||||
public static WrappedChatComponent fromJson(String json) {
|
||||
return new WrappedChatComponent(DESERIALIZE_COMPONENT.invoke(null, json), json);
|
||||
return new WrappedChatComponent(deserialize(json), json);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +138,7 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
* @param obj - the JSON that represents the new component.
|
||||
*/
|
||||
public void setJson(String obj) {
|
||||
this.handle = DESERIALIZE_COMPONENT.invoke(null, obj);
|
||||
this.handle = deserialize(obj);
|
||||
this.cache = obj;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user