diff --git a/pom.xml b/pom.xml index 96b2401..e45a643 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.68 + 4.69 UTF-8 diff --git a/src/main/java/me/skymc/taboolib/json/tellraw/TellrawJson.java b/src/main/java/me/skymc/taboolib/json/tellraw/TellrawJson.java index 1bd311f..f7f87c5 100644 --- a/src/main/java/me/skymc/taboolib/json/tellraw/TellrawJson.java +++ b/src/main/java/me/skymc/taboolib/json/tellraw/TellrawJson.java @@ -25,10 +25,28 @@ import java.util.stream.Collectors; */ public class TellrawJson { + private int bukkitVersion = TabooLib.getVersionNumber(); private List components = new ArrayList<>(); private List componentsLatest = new ArrayList<>(); private Map itemTag = new HashMap<>(); - private int bukkitVersion = TabooLib.getVersionNumber(); + private List nbtWhitelist = ArrayUtils.asList( + // 附魔 + "ench", + // 附魔书 + "StoredEnchantments", + // 展示 + "display", + // 属性 + "AttributeModifiers", + // 药水 + "Potion", + // 特殊药水 + "CustomPotionEffects", + // 隐藏标签 + "HideFlags", + // 方块标签 + "BlockEntityTag" + ); TellrawJson() { } @@ -101,6 +119,7 @@ public class TellrawJson { } public TellrawJson hoverItem(ItemStack itemStack, boolean supportVersion) { + itemStack = TellrawCreator.getAbstractTellraw().optimizeNBT(itemStack, nbtWhitelist); 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) { @@ -175,4 +194,20 @@ public class TellrawJson { public BaseComponent[] getComponents() { return components.toArray(new BaseComponent[0]); } + + public int getBukkitVersion() { + return bukkitVersion; + } + + public List getComponentsLatest() { + return componentsLatest; + } + + public Map getItemTag() { + return itemTag; + } + + public List getNBTWhitelist() { + return nbtWhitelist; + } } diff --git a/src/main/java/me/skymc/taboolib/json/tellraw/internal/AbstractTellraw.java b/src/main/java/me/skymc/taboolib/json/tellraw/internal/AbstractTellraw.java index 5bbf71e..f20ad06 100644 --- a/src/main/java/me/skymc/taboolib/json/tellraw/internal/AbstractTellraw.java +++ b/src/main/java/me/skymc/taboolib/json/tellraw/internal/AbstractTellraw.java @@ -4,6 +4,8 @@ import me.skymc.taboolib.json.tellraw.TellrawVersion; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import java.util.List; + /** * @Author 坏黑 * @Since 2018-11-07 22:52 @@ -16,4 +18,8 @@ public interface AbstractTellraw { String getItemComponent(ItemStack itemStack, TellrawVersion version); + ItemStack optimizeNBT(ItemStack itemStack, List nbtWhitelist); + + ItemStack optimizeShulkerBox(ItemStack itemStack); + } diff --git a/src/main/java/me/skymc/taboolib/json/tellraw/internal/InternalTellraw.java b/src/main/java/me/skymc/taboolib/json/tellraw/internal/InternalTellraw.java index 0592f45..925a59f 100644 --- a/src/main/java/me/skymc/taboolib/json/tellraw/internal/InternalTellraw.java +++ b/src/main/java/me/skymc/taboolib/json/tellraw/internal/InternalTellraw.java @@ -3,14 +3,16 @@ 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.inventory.ItemUtils; 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 net.minecraft.server.v1_8_R3.*; +import org.bukkit.Material; +import org.bukkit.block.ShulkerBox; import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; import java.util.List; import java.util.Map; @@ -43,6 +45,58 @@ public class InternalTellraw implements AbstractTellraw { return nbtToString(CraftItemStack.asNMSCopy(itemStack).save(new NBTTagCompound()), version); } + @Override + public ItemStack optimizeNBT(ItemStack itemStack, List nbtWhitelist) { + Object nmsItem = CraftItemStack.asNMSCopy(itemStack); + if (((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).hasTag()) { + Object nbtTag = new NBTTagCompound(); + Map mapNew = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, nbtTag, "map"); + Map mapOrigin = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getTag(), "map"); + for (Map.Entry entry : mapOrigin.entrySet()) { + if (nbtWhitelist.contains(entry.getKey())) { + mapNew.put(entry.getKey(), entry.getValue()); + } + } + ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).setTag((NBTTagCompound) nbtTag); + return CraftItemStack.asBukkitCopy(((net.minecraft.server.v1_8_R3.ItemStack) nmsItem)); + } + return itemStack; + } + + @Override + public ItemStack optimizeShulkerBox(ItemStack item) { + if (item.getType().name().endsWith("SHULKER_BOX")) { + ItemStack itemClone = item.clone(); + BlockStateMeta blockStateMeta = (BlockStateMeta) itemClone.getItemMeta(); + ShulkerBox shulkerBox = (ShulkerBox) blockStateMeta.getBlockState(); + ItemStack[] contents = shulkerBox.getInventory().getContents(); + ItemStack[] contentsClone = new ItemStack[contents.length]; + for (int i = 0; i < contents.length; i++) { + ItemStack content = contents[i]; + if (!ItemUtils.isNull(content)) { + ItemStack contentClone = new ItemStack(Material.STONE, content.getAmount(), content.getDurability()); + if (content.getItemMeta().hasDisplayName()) { + ItemUtils.setName(contentClone, content.getItemMeta().getDisplayName()); + } + contentsClone[i] = contentClone; + } + } + shulkerBox.getInventory().setContents(contentsClone); + blockStateMeta.setBlockState(shulkerBox); + itemClone.setItemMeta(blockStateMeta); + return itemClone; + } else if (item.getItemMeta() instanceof BlockStateMeta && ((BlockStateMeta) item.getItemMeta()).getBlockState() instanceof InventoryHolder) { + ItemStack itemClone = item.clone(); + BlockStateMeta blockStateMeta = (BlockStateMeta) itemClone.getItemMeta(); + InventoryHolder inventoryHolder = (InventoryHolder) blockStateMeta.getBlockState(); + inventoryHolder.getInventory().clear(); + blockStateMeta.setBlockState((org.bukkit.block.BlockState) inventoryHolder); + itemClone.setItemMeta(blockStateMeta); + return itemClone; + } + return item; + } + private String nbtToString(Object nbtTagCompound, TellrawVersion version) { StringBuilder builder = new StringBuilder("{"); Map map = (Map) SimpleReflection.getFieldValue(NBTTagCompound.class, nbtTagCompound, "map");