ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/ComponentParser.java

76 lines
2.8 KiB
Java

/**
* 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.Reader;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
/**
* Handles component parsing in 1.8
* @author dmulloy2
*/
public class ComponentParser {
private static Constructor readerConstructor;
private static Method setLenient;
private static Method getAdapter;
private static Method read;
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 {
if (readerConstructor == null) {
Class<?> readerClass = Class.forName("org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonReader");
readerConstructor = readerClass.getDeclaredConstructor(Reader.class);
readerConstructor.setAccessible(true);
setLenient = readerClass.getDeclaredMethod("setLenient", boolean.class);
setLenient.setAccessible(true);
getAdapter = gson.getClass().getDeclaredMethod("getAdapter", Class.class);
getAdapter.setAccessible(true);
Object adapter = getAdapter.invoke(gson, component);
read = adapter.getClass().getDeclaredMethod("read", readerClass);
read.setAccessible(true);
}
Object reader = readerConstructor.newInstance(str);
setLenient.invoke(reader, true);
Object adapter = getAdapter.invoke(gson, component);
return read.invoke(adapter, reader);
} catch (ReflectiveOperationException ex) {
throw new RuntimeException("Failed to read JSON", ex);
}
}
}