184 lines
6.4 KiB
Java
184 lines
6.4 KiB
Java
package pw.yumc.YumCore.tellraw;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.enchantments.Enchantment;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
import pw.yumc.YumCore.bukkit.Log;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* 物品序列化类
|
|
*
|
|
* @since 2016年9月9日 下午3:47:17
|
|
* @author 喵♂呜
|
|
*/
|
|
public abstract class ItemSerialize {
|
|
static ItemSerialize itemSerialize = new Manual();
|
|
static {
|
|
try {
|
|
itemSerialize = new Automatic();
|
|
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
|
|
itemSerialize = new Manual();
|
|
Log.d("初始化自动物品序列化失败!", e);
|
|
}
|
|
}
|
|
|
|
public static String $(ItemStack item) {
|
|
String result = itemSerialize.parse(item);
|
|
Log.d("%s物品序列化结果: %s", itemSerialize.getName(), result);
|
|
return result;
|
|
}
|
|
|
|
public abstract String getName();
|
|
|
|
public abstract String parse(ItemStack item);
|
|
|
|
static class Automatic extends ItemSerialize {
|
|
Method asNMSCopyMethod;
|
|
Method nmsSaveNBTMethod;
|
|
Class<?> nmsNBTTagCompound;
|
|
String ver = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
|
|
|
public Automatic() throws ClassNotFoundException, NoSuchMethodException, SecurityException {
|
|
Class<?> cis = getOBCClass("inventory.CraftItemStack");
|
|
asNMSCopyMethod = cis.getMethod("asNMSCopy", ItemStack.class);
|
|
Class<?> nmsItemStack = asNMSCopyMethod.getReturnType();
|
|
for (Method method : nmsItemStack.getMethods()) {
|
|
Class<?> rt = method.getReturnType();
|
|
if (method.getParameterTypes().length == 0 && "NBTTagCompound".equals(rt.getSimpleName())) {
|
|
nmsNBTTagCompound = rt;
|
|
}
|
|
}
|
|
for (Method method : nmsItemStack.getMethods()) {
|
|
Class<?>[] paras = method.getParameterTypes();
|
|
Class<?> rt = method.getReturnType();
|
|
if (paras.length == 1 && "NBTTagCompound".equals(paras[0].getSimpleName()) && "NBTTagCompound".equals(rt.getSimpleName())) {
|
|
nmsSaveNBTMethod = method;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "Automatic";
|
|
}
|
|
|
|
public Class getOBCClass(String cname) throws ClassNotFoundException {
|
|
return Class.forName("org.bukkit.craftbukkit." + ver + "." + cname);
|
|
}
|
|
|
|
@Override
|
|
public String parse(ItemStack item) {
|
|
try {
|
|
return nmsSaveNBTMethod.invoke(asNMSCopyMethod.invoke(null, item), nmsNBTTagCompound.newInstance()).toString();
|
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
|
|
itemSerialize = new Manual();
|
|
return itemSerialize.parse(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
static class Manual extends ItemSerialize {
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "Manual";
|
|
}
|
|
|
|
@Override
|
|
public String parse(ItemStack item) {
|
|
return serialize(item);
|
|
}
|
|
|
|
/**
|
|
* 显示序列化
|
|
*
|
|
* @param im
|
|
* 物品属性
|
|
* @return 获取显示序列化
|
|
*/
|
|
private String getDisplay(ItemMeta im) {
|
|
StringBuilder display = new StringBuilder();
|
|
display.append("{");
|
|
if (im.hasDisplayName()) {
|
|
display.append(String.format("Name:\"%s\",", im.getDisplayName()));
|
|
}
|
|
if (im.hasLore()) {
|
|
display.append("Lore:[");
|
|
int i = 0;
|
|
for (String line : im.getLore()) {
|
|
display.append(String.format("%s:\"%s\",", i, new JsonBuilder(line).toString()));
|
|
i++;
|
|
}
|
|
display.deleteCharAt(display.length() - 1);
|
|
display.append("],");
|
|
}
|
|
display.deleteCharAt(display.length() - 1);
|
|
display.append("}");
|
|
return display.toString();
|
|
}
|
|
|
|
/**
|
|
* 附魔序列化
|
|
*
|
|
* @param set
|
|
* 附魔集合
|
|
* @return 获得附魔序列化
|
|
*/
|
|
private String getEnch(Set<Entry<Enchantment, Integer>> set) {
|
|
StringBuilder enchs = new StringBuilder();
|
|
for (Map.Entry<Enchantment, Integer> ench : set) {
|
|
enchs.append(String.format("{id:%s,lvl:%s},", ench.getKey().getId(), ench.getValue()));
|
|
}
|
|
enchs.deleteCharAt(enchs.length() - 1);
|
|
return enchs.toString();
|
|
}
|
|
|
|
/**
|
|
* 属性序列化
|
|
*
|
|
* @param im
|
|
* 物品属性
|
|
* @return 获得属性序列化
|
|
*/
|
|
private String getTag(ItemMeta im) {
|
|
StringBuilder meta = new StringBuilder("{");
|
|
if (im.hasEnchants()) {
|
|
meta.append(String.format("ench:[%s],", getEnch(im.getEnchants().entrySet())));
|
|
}
|
|
if (im.hasDisplayName() || im.hasLore()) {
|
|
meta.append(String.format("display:%s,", getDisplay(im)));
|
|
}
|
|
meta.deleteCharAt(meta.length() - 1);
|
|
meta.append("}");
|
|
return meta.toString();
|
|
}
|
|
|
|
/**
|
|
* 序列化物品
|
|
*
|
|
* @param item
|
|
* {@link ItemStack}
|
|
* @return 物品字符串
|
|
*/
|
|
private String serialize(ItemStack item) {
|
|
StringBuilder json = new StringBuilder("{");
|
|
json.append(String.format("id:\"%s\",Damage:\"%s\"", item.getTypeId(), item.getDurability()));
|
|
if (item.getAmount() > 1) {
|
|
json.append(String.format(",Count:%s", item.getAmount()));
|
|
}
|
|
if (item.hasItemMeta()) {
|
|
json.append(String.format(",tag:%s", getTag(item.getItemMeta())));
|
|
}
|
|
json.append("}");
|
|
return json.toString();
|
|
}
|
|
}
|
|
}
|