From 8e5e4c189bdbaabfdf98293a83cc007b17735e28 Mon Sep 17 00:00:00 2001 From: Thinkofdeath Date: Thu, 16 Apr 2015 11:01:13 +0100 Subject: [PATCH] SPIGOT-581: Allow for unhandled nbt tags to be serialized to yaml --- .../inventory/CraftMetaBlockState.java | 13 +++- .../craftbukkit/inventory/CraftMetaItem.java | 78 +++++++++++++------ 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java index dd2f6532d9..32d461a312 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -47,7 +47,7 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta static final ItemMetaKey BLOCK_ENTITY_TAG = new ItemMetaKey("BlockEntityTag"); final Material material; - private NBTTagCompound blockEntityTag; + NBTTagCompound blockEntityTag; CraftMetaBlockState(CraftMetaItem meta, Material material) { super(meta); @@ -78,9 +78,13 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta CraftMetaBlockState(Map map) { super(map); - material = Material.AIR; // TODO - - blockEntityTag = null; + String matName = SerializableMeta.getString(map, "blockMaterial", true); + Material m = Material.getMaterial(matName); + if (m != null) { + material = m; + } else { + material = Material.AIR; + } } @Override @@ -95,6 +99,7 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta @Override ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { super.serialize(builder); + builder.put("blockMaterial", material.name()); return builder; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index 40d7fca261..8b18e1f344 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -15,10 +15,7 @@ import java.util.NoSuchElementException; import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagCompound; -import net.minecraft.server.NBTTagDouble; -import net.minecraft.server.NBTTagInt; import net.minecraft.server.NBTTagList; -import net.minecraft.server.NBTTagLong; import net.minecraft.server.NBTTagString; import org.apache.commons.lang.Validate; @@ -37,11 +34,18 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.Arrays; import java.util.EnumSet; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; -import org.bukkit.block.BlockState; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.server.NBTCompressedStreamTools; +import org.apache.commons.codec.binary.Base64; /** * Children must include the following: @@ -213,7 +217,6 @@ class CraftMetaItem implements ItemMeta, Repairable { private Map enchantments; private int repairCost; private int hideFlag; - private final NBTTagList attributes; private static final Set HANDLED_TAGS = Sets.newHashSet(); @@ -221,7 +224,6 @@ class CraftMetaItem implements ItemMeta, Repairable { CraftMetaItem(CraftMetaItem meta) { if (meta == null) { - attributes = null; return; } @@ -236,7 +238,6 @@ class CraftMetaItem implements ItemMeta, Repairable { } this.repairCost = meta.repairCost; - this.attributes = meta.attributes; this.hideFlag = meta.hideFlag; this.unhandledTags.putAll(meta.unhandledTags); } @@ -313,9 +314,7 @@ class CraftMetaItem implements ItemMeta, Repairable { save.add(entry); } - attributes = save; - } else { - attributes = null; + unhandledTags.put(ATTRIBUTES.NBT, save); } Set keys = tag.c(); @@ -359,8 +358,6 @@ class CraftMetaItem implements ItemMeta, Repairable { setRepairCost(repairCost); } - attributes = null; - Set hideFlags = SerializableMeta.getObject(Set.class, map, HIDEFLAGS.BUKKIT, true); if (hideFlags != null) { for (Object hideFlagObject : hideFlags) { @@ -373,6 +370,27 @@ class CraftMetaItem implements ItemMeta, Repairable { } } } + + String internal = SerializableMeta.getString(map, "internal", true); + if (internal != null) { + ByteArrayInputStream buf = new ByteArrayInputStream(Base64.decodeBase64(internal)); + try { + NBTTagCompound tag = NBTCompressedStreamTools.a(buf); + Set keys = tag.c(); + for (String key : keys) { + if (!getHandledTags().contains(key)) { + unhandledTags.put(key, tag.get(key)); + } + if (key.equals(CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT) && this instanceof CraftMetaBlockState) { + if (tag.hasKeyOfType(key, 10)) { + ((CraftMetaBlockState) this).blockEntityTag = tag.getCompound(key); + } + } + } + } catch (IOException ex) { + Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + } + } } static Map buildEnchantments(Map map, ItemMetaKey key) { @@ -413,10 +431,6 @@ class CraftMetaItem implements ItemMeta, Repairable { itemTag.setInt(REPAIR.NBT, repairCost); } - if (attributes != null) { - itemTag.set(ATTRIBUTES.NBT, attributes); - } - for (Map.Entry e : unhandledTags.entrySet()) { itemTag.set(e.getKey(), e.getValue()); } @@ -471,7 +485,7 @@ class CraftMetaItem implements ItemMeta, Repairable { @Overridden boolean isEmpty() { - return !(hasDisplayName() || hasEnchants() || hasLore() || hasAttributes() || hasRepairCost() || !unhandledTags.isEmpty() || hideFlag != 0); + return !(hasDisplayName() || hasEnchants() || hasLore() || hasRepairCost() || !unhandledTags.isEmpty() || hideFlag != 0); } public String getDisplayName() { @@ -490,10 +504,6 @@ class CraftMetaItem implements ItemMeta, Repairable { return this.lore != null && !this.lore.isEmpty(); } - public boolean hasAttributes() { - return this.attributes != null; - } - public boolean hasRepairCost() { return repairCost > 0; } @@ -624,7 +634,6 @@ class CraftMetaItem implements ItemMeta, Repairable { return ((this.hasDisplayName() ? that.hasDisplayName() && this.displayName.equals(that.displayName) : !that.hasDisplayName())) && (this.hasEnchants() ? that.hasEnchants() && this.enchantments.equals(that.enchantments) : !that.hasEnchants()) && (this.hasLore() ? that.hasLore() && this.lore.equals(that.lore) : !that.hasLore()) - && (this.hasAttributes() ? that.hasAttributes() && this.attributes.equals(that.attributes) : !that.hasAttributes()) && (this.hasRepairCost() ? that.hasRepairCost() && this.repairCost == that.repairCost : !that.hasRepairCost()) && (this.unhandledTags.equals(that.unhandledTags)) && (this.hideFlag == that.hideFlag); @@ -651,7 +660,6 @@ class CraftMetaItem implements ItemMeta, Repairable { hash = 61 * hash + (hasDisplayName() ? this.displayName.hashCode() : 0); hash = 61 * hash + (hasLore() ? this.lore.hashCode() : 0); hash = 61 * hash + (hasEnchants() ? this.enchantments.hashCode() : 0); - hash = 61 * hash + (hasAttributes() ? this.attributes.hashCode() : 0); hash = 61 * hash + (hasRepairCost() ? this.repairCost : 0); hash = 61 * hash + unhandledTags.hashCode(); hash = 61 * hash + hideFlag; @@ -707,6 +715,26 @@ class CraftMetaItem implements ItemMeta, Repairable { builder.put(HIDEFLAGS.BUKKIT, hideFlags); } + if (!unhandledTags.isEmpty() || this instanceof CraftMetaBlockState) { + NBTTagCompound internal = new NBTTagCompound(); + for (Map.Entry e : unhandledTags.entrySet()) { + internal.set(e.getKey(), e.getValue()); + } + if (this instanceof CraftMetaBlockState) { + CraftMetaBlockState bs = ((CraftMetaBlockState) this); + if (bs.blockEntityTag != null) { + internal.set(CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, bs.blockEntityTag); + } + } + try { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + NBTCompressedStreamTools.a(internal, buf); + builder.put("internal", Base64.encodeBase64String(buf.toByteArray())); + } catch (IOException ex) { + Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + } + } + return builder; } @@ -772,7 +800,6 @@ class CraftMetaItem implements ItemMeta, Repairable { HANDLED_TAGS.addAll(Arrays.asList( DISPLAY.NBT, REPAIR.NBT, - ATTRIBUTES.NBT, ENCHANTMENTS.NBT, CraftMetaMap.MAP_SCALING.NBT, CraftMetaPotion.POTION_EFFECTS.NBT, @@ -785,7 +812,8 @@ class CraftMetaItem implements ItemMeta, Repairable { CraftMetaBook.GENERATION.NBT, CraftMetaFirework.FIREWORKS.NBT, CraftMetaEnchantedBook.STORED_ENCHANTMENTS.NBT, - CraftMetaCharge.EXPLOSION.NBT + CraftMetaCharge.EXPLOSION.NBT, + CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT )); } return HANDLED_TAGS;