From 2a37a88bfe08f682c9e08f10485ffdf55e140626 Mon Sep 17 00:00:00 2001 From: 502647092 Date: Fri, 9 Sep 2016 16:38:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84TellRaw=E7=89=A9?= =?UTF-8?q?=E5=93=81=E6=98=BE=E7=A4=BA=20=E8=B0=83=E6=95=B4=E7=B1=BB?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 502647092 --- .classpath | 16 +- .../yumc/YumCore/tellraw/ItemSerialize.java | 216 ++++++++++++++++++ .../java/pw/yumc/YumCore/tellraw/Tellraw.java | 60 +---- 3 files changed, 228 insertions(+), 64 deletions(-) create mode 100644 src/main/java/pw/yumc/YumCore/tellraw/ItemSerialize.java diff --git a/.classpath b/.classpath index 4ff26bf..2c57f00 100644 --- a/.classpath +++ b/.classpath @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/src/main/java/pw/yumc/YumCore/tellraw/ItemSerialize.java b/src/main/java/pw/yumc/YumCore/tellraw/ItemSerialize.java new file mode 100644 index 0000000..fff13fb --- /dev/null +++ b/src/main/java/pw/yumc/YumCore/tellraw/ItemSerialize.java @@ -0,0 +1,216 @@ +package pw.yumc.YumCore.tellraw; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +/** + * + * @since 2016年9月9日 下午3:47:17 + * @author 喵♂呜 + */ +public abstract class ItemSerialize { + static ItemSerialize itemSerialize; + static { + try { + itemSerialize = new Automatic(); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) { + itemSerialize = new Manual(); + } + } + + public static String $(final ItemStack item) { + return itemSerialize.parse(item); + } + + public abstract String parse(final 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 { + final Class cis = getOBCClass("inventory.CraftItemStack"); + asNMSCopyMethod = cis.getMethod("asNMSCopy", ItemStack.class); + final Class nmsItemStack = getNMSClass("ItemStack"); + nmsNBTTagCompound = getNMSClass("NBTTagCompound"); + nmsSaveNBTMethod = nmsItemStack.getMethod("save", nmsNBTTagCompound); + } + + public Class getNMSClass(final String cname) throws ClassNotFoundException { + return Class.forName("net.minecraft.server" + ver + "." + cname); + } + + public Class getOBCClass(final String cname) throws ClassNotFoundException { + return Class.forName("org.bukkit.craftbukkit." + ver + "." + cname); + } + + @Override + public String parse(final 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 JsonBuilder { + public static final String[] REPLACEMENT_CHARS; + static { + REPLACEMENT_CHARS = new String[128]; + for (int i = 0; i <= 0x1f; i++) { + REPLACEMENT_CHARS[i] = String.format("\\u%04x", i); + } + REPLACEMENT_CHARS['"'] = "\\\""; + REPLACEMENT_CHARS['\\'] = "\\\\"; + REPLACEMENT_CHARS['\t'] = "\\t"; + REPLACEMENT_CHARS['\b'] = "\\b"; + REPLACEMENT_CHARS['\n'] = "\\n"; + REPLACEMENT_CHARS['\r'] = "\\r"; + REPLACEMENT_CHARS['\f'] = "\\f"; + } + StringBuffer json; + + public JsonBuilder() { + json = new StringBuffer(); + } + + public void append(final String value) { + int last = 0; + final int length = value.length(); + for (int i = 0; i < length; i++) { + final char c = value.charAt(i); + String replacement; + if (c < 128) { + replacement = REPLACEMENT_CHARS[c]; + if (replacement == null) { + continue; + } + } else if (c == '\u2028') { + replacement = "\\u2028"; + } else if (c == '\u2029') { + replacement = "\\u2029"; + } else { + continue; + } + if (last < i) { + json.append(value, last, i - last); + } + json.append(replacement); + last = i + 1; + } + if (last < length) { + json.append(value, last, length - last); + } + } + + public void deleteCharAt(final int length) { + json.deleteCharAt(length); + } + + public int length() { + return json.length(); + } + } + + static class Manual extends ItemSerialize { + + @Override + public String parse(final ItemStack item) { + return serialize(item); + } + + /** + * 显示序列化 + * + * @param im + * 物品属性 + * @return 获取显示序列化 + */ + private String getDisplay(final ItemMeta im) { + final JsonBuilder display = new JsonBuilder(); + display.append("{"); + if (im.hasDisplayName()) { + display.append(String.format("Name:\"%s\",", im.getDisplayName())); + } + if (im.hasLore()) { + display.append("Lore:["); + for (final String line : im.getLore()) { + display.append(String.format("\"%s\",", line)); + } + display.deleteCharAt(display.length()); + display.append("],"); + } + display.deleteCharAt(display.length()); + display.append("}"); + return display.toString(); + } + + /** + * 附魔序列化 + * + * @param set + * 附魔集合 + * @return 获得附魔序列化 + */ + private String getEnch(final Set> set) { + final StringBuffer enchs = new StringBuffer(); + for (final Map.Entry ench : set) { + enchs.append(String.format("{id:%s,lvl:%s},", ench.getKey().getId(), ench.getValue())); + } + enchs.deleteCharAt(enchs.length()); + return enchs.toString(); + } + + /** + * 属性序列化 + * + * @param im + * 物品属性 + * @return 获得属性序列化 + */ + private String getTag(final ItemMeta im) { + final StringBuffer meta = new StringBuffer(); + if (im.hasEnchants()) { + meta.append(String.format("ench:[%s],", getEnch(im.getEnchants().entrySet()))); + } + im.getItemFlags(); + if (im.hasDisplayName() || im.hasLore()) { + meta.append(String.format("display:%s,", getDisplay(im))); + } + meta.deleteCharAt(meta.length()); + return meta.toString(); + } + + /** + * 序列化物品 + * + * @param item + * {@link ItemStack} + * @return 物品字符串 + */ + private String serialize(final ItemStack item) { + final StringBuffer json = new StringBuffer("{"); + 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(); + } + } +} diff --git a/src/main/java/pw/yumc/YumCore/tellraw/Tellraw.java b/src/main/java/pw/yumc/YumCore/tellraw/Tellraw.java index 574cda3..561e3fb 100644 --- a/src/main/java/pw/yumc/YumCore/tellraw/Tellraw.java +++ b/src/main/java/pw/yumc/YumCore/tellraw/Tellraw.java @@ -1,13 +1,12 @@ package pw.yumc.YumCore.tellraw; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -22,14 +21,6 @@ import pw.yumc.YumCore.bukkit.compatible.C; * @author 喵♂呜 */ public class Tellraw { - static ItemSerialize is; - static { - try { - is = new Automatic(); - } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) { - is = new Manual(); - } - } List messageParts = new ArrayList<>(); public Tellraw(final String text) { @@ -57,7 +48,8 @@ public class Tellraw { } public static void main(final String[] args) { - System.out.println(Tellraw.create("命令").command("yum list").tip("点击查看插件列表").toJsonString()); + final ItemStack item = new ItemStack(Material.DIAMOND_SWORD); + System.out.println(Tellraw.create("命令").command("yum list").item(item).toJsonString()); } /** @@ -117,7 +109,7 @@ public class Tellraw { * @return {@link Tellraw} */ public Tellraw item(final ItemStack item) { - return item(is.$(item)); + return item(ItemSerialize.$(item)); } /** @@ -351,48 +343,4 @@ public class Tellraw { } return this; } - - static class Automatic implements ItemSerialize { - Method asNMSCopyMethod; - Method nmsSaveNBTMethod; - Class nmsNBTTagCompound; - String ver = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; - - public Automatic() throws ClassNotFoundException, NoSuchMethodException, SecurityException { - final Class cis = getOBCClass("inventory.CraftItemStack"); - asNMSCopyMethod = cis.getMethod("asNMSCopy", ItemStack.class); - final Class nmsItemStack = getNMSClass("ItemStack"); - nmsNBTTagCompound = getNMSClass("NBTTagCompound"); - nmsSaveNBTMethod = nmsItemStack.getMethod("save", nmsNBTTagCompound); - } - - @Override - public String $(final ItemStack item) { - try { - return nmsSaveNBTMethod.invoke(asNMSCopyMethod.invoke(null, item), nmsNBTTagCompound.newInstance()).toString(); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { - is = new Manual(); - return is.$(item); - } - } - - public Class getNMSClass(final String cname) throws ClassNotFoundException { - return Class.forName("net.minecraft.server" + ver + "." + cname); - } - - public Class getOBCClass(final String cname) throws ClassNotFoundException { - return Class.forName("org.bukkit.craftbukkit." + ver + "." + cname); - } - } - - static interface ItemSerialize { - public String $(ItemStack item); - } - - static class Manual implements ItemSerialize { - @Override - public String $(final ItemStack item) { - return null; - } - } }