+ fix JSON

This commit is contained in:
坏黑 2018-11-08 23:42:14 +08:00
parent b8ab5ebc1a
commit 47faa031eb
8 changed files with 309 additions and 41 deletions

14
pom.xml
View File

@ -237,6 +237,20 @@
<scope>system</scope>
<systemPath>${basedir}/libs/BossBarAPI.jar</systemPath>
</dependency>
<dependency>
<groupId>viaversion</groupId>
<artifactId>viaversion</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${basedir}/libs/ViaVersion.jar</systemPath>
</dependency>
<dependency>
<groupId>protocolsupport</groupId>
<artifactId>protocolsupport</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${basedir}/libs/ProtocolSupport.jar</systemPath>
</dependency>
<dependency>
<groupId>deprecated</groupId>
<artifactId>deprecated</artifactId>

View File

@ -2,7 +2,6 @@ package com.ilummc.tlib.resources;
import com.ilummc.tlib.TLib;
import com.ilummc.tlib.bungee.api.ChatColor;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.TextComponent;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.inject.TLoggerManager;
@ -10,15 +9,11 @@ import com.ilummc.tlib.util.Ref;
import com.ilummc.tlib.util.Strings;
import me.clip.placeholderapi.PlaceholderAPI;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.nms.NMSUtil19;
import me.skymc.taboolib.nms.NMSUtils;
import me.skymc.taboolib.json.tellraw.TellrawCreator;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@ -139,23 +134,12 @@ public class TLocale {
public static class Tellraw extends TLocale {
private static final Class<?> chatSerializer = NMSUtils.getNMSClassSilent("ChatSerializer", "IChatBaseComponent");
private static final Method chatSerializerA = NMSUtils.getMethodSilent(chatSerializer, "a", String.class);
private static final Field playerConnection = NMSUtils.getFieldSilent(NMSUtil19.class_EntityPlayer, "playerConnection");
private static final Method sendPacket = NMSUtils.getMethodSilent(NMSUtil19.class_PlayerConnection, "sendPacket", NMSUtil19.class_Packet);
private static final Constructor<?> PacketPlayOutChat = NMSUtils.getConstructorSilent(NMSUtil19.class_PacketPlayOutChat, NMSUtil19.class_IChatBaseComponent);
public static void send(CommandSender sender, String rawMessage) {
if (sender instanceof Player) {
try {
sendPacket.invoke(playerConnection.get(NMSUtils.getHandle(sender)), PacketPlayOutChat.newInstance(chatSerializerA.invoke(null, rawMessage)));
} catch (Exception e) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + rawMessage);
}
TellrawCreator.getAbstractTellraw().sendRawMessage((Player) sender, rawMessage);
} else {
sender.sendMessage(TextComponent.toLegacyText(ComponentSerializer.parse(rawMessage)));
}
}
}
}

View File

@ -0,0 +1,85 @@
package me.skymc.taboolib.common.util;
import com.google.common.collect.Maps;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Map;
/**
* @Author 坏黑
* @Since 2018-10-25 22:51
*/
public class SimpleReflection {
private static Map<String, Map<String, Field>> fieldCached = Maps.newHashMap();
public static void saveFiled(Class<?> nmsClass) {
try {
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveFiled(nmsClass, declaredField.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void saveFiled(Class<?> nmsClass, String fieldName) {
try {
Field declaredField = nmsClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
fieldCached.computeIfAbsent(nmsClass.getName(), name -> Maps.newHashMap()).put(fieldName, declaredField);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setFieldValue(Class<?> nmsClass, Object instance, String fieldName, Object value) {
try {
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
if (fields == null) {
return;
}
Field field = fields.get(fieldName);
if (value == null) {
return;
}
field.set(instance, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getFieldValue(Class<?> nmsClass, Object instance, String fieldName) {
try {
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
if (fields == null) {
return null;
}
Field field = fields.get(fieldName);
if (field == null) {
return null;
}
return field.get(instance);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> T getFieldValue(Class<?> nmsClass, Object instance, String fieldName, T def) {
try {
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
if (fields == null) {
return def;
}
Field field = fields.get(fieldName);
if (field == null) {
return def;
}
return (T) field.get(instance);
} catch (Exception e) {
e.printStackTrace();
}
return def;
}
}

View File

@ -0,0 +1,50 @@
package me.skymc.taboolib.json.tellraw;
import me.skymc.taboolib.common.loader.Instantiable;
import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl;
import me.skymc.taboolib.json.tellraw.internal.AbstractTellraw;
import org.bukkit.Bukkit;
/**
* @Author 坏黑
* @Since 2018-11-07 22:58
*/
@Instantiable("TabooLib|TellrawCreator")
public class TellrawCreator {
private static AbstractTellraw abstractTellraw;
private static boolean viaVersionLoaded;
private static boolean protocolSupportLoaded;
public TellrawCreator() {
viaVersionLoaded = Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
protocolSupportLoaded = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
try {
abstractTellraw = (AbstractTellraw) SimpleVersionControl.create()
.from("v1_8_R3")
.target("me.skymc.taboolib.json.tellraw.internal.InternalTellraw")
.translate()
.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static AbstractTellraw getAbstractTellraw() {
return abstractTellraw;
}
public static boolean isViaVersionLoaded() {
return viaVersionLoaded;
}
public static boolean isProtocolSupportLoaded() {
return protocolSupportLoaded;
}
}

View File

@ -2,17 +2,20 @@ package me.skymc.taboolib.json.tellraw;
import com.ilummc.tlib.bungee.api.chat.*;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.logger.TLogger;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.methods.ReflectionUtils;
import me.skymc.taboolib.nms.NMSUtils;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.string.ArrayUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import protocolsupport.api.ProtocolSupportAPI;
import us.myles.ViaVersion.api.Via;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -24,10 +27,8 @@ public class TellrawJson {
private List<BaseComponent> components = new ArrayList<>();
private List<BaseComponent> componentsLatest = new ArrayList<>();
private static final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
private static final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
private static final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
private static final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
private Map<String, String[]> itemTag = new HashMap<>();
private int bukkitVersion = TabooLib.getVersionNumber();
TellrawJson() {
}
@ -37,13 +38,38 @@ public class TellrawJson {
}
public void send(CommandSender sender) {
TLocale.Tellraw.send(sender, toRawMessage());
send(sender, new String[0]);
}
public void send(CommandSender sender, String... args) {
if (sender instanceof Player) {
if (TellrawCreator.isViaVersionLoaded()) {
TLocale.Tellraw.send(sender, Strings.replaceWithOrder(toRawMessage(Via.getAPI().getPlayerVersion(sender) > 316 ? TellrawVersion.HIGH_VERSION : TellrawVersion.LOW_VERSION), args));
} else if (TellrawCreator.isProtocolSupportLoaded()) {
TLocale.Tellraw.send(sender, Strings.replaceWithOrder(toRawMessage(ProtocolSupportAPI.getProtocolVersion((Player) sender).getId() > 316 ? TellrawVersion.HIGH_VERSION : TellrawVersion.LOW_VERSION), args));
} else {
TLocale.Tellraw.send(sender, Strings.replaceWithOrder(toRawMessage(), args));
}
} else {
TLocale.Tellraw.send(sender, Strings.replaceWithOrder(toRawMessage(), args));
}
}
public String toRawMessage() {
return ComponentSerializer.toString(getComponentsAll());
}
public String toRawMessage(TellrawVersion version) {
String rawMessage = toRawMessage();
if (version == TellrawVersion.CURRENT_VERSION) {
return rawMessage;
}
for (Map.Entry<String, String[]> stringEntry : itemTag.entrySet()) {
rawMessage = rawMessage.replace(stringEntry.getKey(), version == TellrawVersion.HIGH_VERSION ? stringEntry.getValue()[1] : stringEntry.getValue()[0]);
}
return rawMessage;
}
public String toLegacyText() {
return TextComponent.toLegacyText(getComponentsAll());
}
@ -61,6 +87,7 @@ public class TellrawJson {
public TellrawJson append(TellrawJson json) {
appendComponents();
componentsLatest.addAll(ArrayUtils.asList(json.getComponentsAll()));
itemTag.putAll(json.itemTag);
return this;
}
@ -70,7 +97,18 @@ public class TellrawJson {
}
public TellrawJson hoverItem(ItemStack itemStack) {
getLatestComponent().forEach(component -> component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(getItemComponent(itemStack)).create())));
return hoverItem(itemStack, true);
}
public TellrawJson hoverItem(ItemStack itemStack, boolean supportVersion) {
BaseComponent[] itemComponentCurrentVersion = new ComponentBuilder(TellrawCreator.getAbstractTellraw().getItemComponent(itemStack, TellrawVersion.CURRENT_VERSION)).create();
getLatestComponent().forEach(component -> component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, itemComponentCurrentVersion)));
if (supportVersion) {
itemTag.put(ComponentSerializer.toString(itemComponentCurrentVersion), new String[] {
ComponentSerializer.toString(new ComponentBuilder(TellrawCreator.getAbstractTellraw().getItemComponent(itemStack, TellrawVersion.LOW_VERSION)).create()),
ComponentSerializer.toString(new ComponentBuilder(TellrawCreator.getAbstractTellraw().getItemComponent(itemStack, TellrawVersion.HIGH_VERSION)).create())
});
}
return this;
}
@ -100,19 +138,6 @@ public class TellrawJson {
return components.toArray(new BaseComponent[0]);
}
public String getItemComponent(ItemStack itemStack) {
try {
Method asNMSCopyMethod = ReflectionUtils.getMethod(craftItemStackClazz, "asNMSCopy", ItemStack.class);
Method saveNmsItemStackMethod = ReflectionUtils.getMethod(nmsItemStackClazz, "save", nbtTagCompoundClazz);
Object nmsNbtTagCompoundObj = nbtTagCompoundClazz.newInstance();
Object nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack);
return saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
} catch (Throwable t) {
TLogger.getGlobalLogger().error("failed to serialize bukkit item to nms item: " + t.toString());
return INVALID_ITEM;
}
}
// *********************************
//
// Private Methods

View File

@ -0,0 +1,10 @@
package me.skymc.taboolib.json.tellraw;
/**
* @Author 坏黑
* @Since 2018-11-07 22:53
*/
public enum TellrawVersion {
LOW_VERSION, HIGH_VERSION, CURRENT_VERSION
}

View File

@ -0,0 +1,19 @@
package me.skymc.taboolib.json.tellraw.internal;
import me.skymc.taboolib.json.tellraw.TellrawVersion;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
/**
* @Author 坏黑
* @Since 2018-11-07 22:52
*/
public interface AbstractTellraw {
void sendRawMessage(Player player, String rawMessage);
String getItemComponent(ItemStack itemStack);
String getItemComponent(ItemStack itemStack, TellrawVersion version);
}

View File

@ -0,0 +1,81 @@
package me.skymc.taboolib.json.tellraw.internal;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.common.packet.TPacketHandler;
import me.skymc.taboolib.common.util.SimpleReflection;
import me.skymc.taboolib.json.tellraw.TellrawVersion;
import net.minecraft.server.v1_8_R3.IChatBaseComponent;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.NBTTagList;
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
/**
* @Author 坏黑
* @Since 2018-11-07 22:54
*/
public class InternalTellraw implements AbstractTellraw {
private int bukkitVersion = TabooLib.getVersionNumber();
public InternalTellraw() {
SimpleReflection.saveFiled(NBTTagCompound.class, "map");
SimpleReflection.saveFiled(NBTTagList.class, "list");
}
@Override
public void sendRawMessage(Player player, String rawMessage) {
TPacketHandler.sendPacket(player, new PacketPlayOutChat(IChatBaseComponent.ChatSerializer.a(rawMessage)));
}
@Override
public String getItemComponent(ItemStack itemStack) {
return getItemComponent(itemStack, TellrawVersion.CURRENT_VERSION);
}
@Override
public String getItemComponent(ItemStack itemStack, TellrawVersion version) {
return nbtToString(CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()), version);
}
private String nbtToString(Object nbtTagCompound, TellrawVersion version) {
StringBuilder builder = new StringBuilder("{");
Map map = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, nbtTagCompound, "map");
int index = 0;
for (Object nbtBaseEntry : map.entrySet()) {
if (index++ != 0) {
builder.append(",");
}
Object value = ((Map.Entry) nbtBaseEntry).getValue();
if (value instanceof NBTTagList ) {
builder.append(((Map.Entry) nbtBaseEntry).getKey()).append(":").append(nbtListToString(value, version));
} else if (value instanceof NBTTagCompound) {
builder.append(((Map.Entry) nbtBaseEntry).getKey()).append(":").append(nbtToString(value, version));
} else {
builder.append(((Map.Entry) nbtBaseEntry).getKey()).append(":").append(value);
}
}
return builder.append('}').toString();
}
private String nbtListToString(Object nbtTagList, TellrawVersion version) {
StringBuilder builder = new StringBuilder("[");
List list = (List) SimpleReflection.getFieldValue(NBTTagList.class, nbtTagList, "list");
for (int i = 0; i < list.size(); ++i) {
if (i != 0) {
builder.append(',');
}
if (version == TellrawVersion.HIGH_VERSION || (this.bukkitVersion >= 11200 && version == TellrawVersion.CURRENT_VERSION)) {
builder.append(list.get(i));
} else {
builder.append(i).append(':').append(list.get(i));
}
}
return builder.append(']').toString();
}
}