From 19ff43d9e1d50539e40c7eb6abec0fa1b67f02ac Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 24 Jul 2018 10:49:48 +1000 Subject: [PATCH] SPIGOT-4128: Greatly improve spawn egg deserialization --- .../inventory/CraftMetaBlockState.java | 2 +- .../craftbukkit/inventory/CraftMetaItem.java | 6 ++-- .../craftbukkit/inventory/CraftMetaSkull.java | 2 +- .../inventory/CraftMetaSpawnEgg.java | 28 ++++++++++++++++--- .../bukkit/craftbukkit/util/CraftLegacy.java | 24 +++++++++++++++- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java index e0b3df84fd..1d0fe14e1a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -110,7 +110,7 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta } @Override - void deserializeInternal(NBTTagCompound tag) { + void deserializeInternal(NBTTagCompound tag, Object context) { if (tag.hasKeyOfType(BLOCK_ENTITY_TAG.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND)) { blockEntityTag = tag.getCompound(BLOCK_ENTITY_TAG.NBT); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index c9933be3bc..f47a36236a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -264,7 +264,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { this.internalTag = meta.internalTag; if (this.internalTag != null) { - deserializeInternal(internalTag); + deserializeInternal(internalTag, meta); } } @@ -434,7 +434,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { ByteArrayInputStream buf = new ByteArrayInputStream(Base64.decodeBase64(internal)); try { internalTag = NBTCompressedStreamTools.a(buf); - deserializeInternal(internalTag); + deserializeInternal(internalTag, map); Set keys = internalTag.getKeys(); for (String key : keys) { if (!getHandledTags().contains(key)) { @@ -447,7 +447,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } } - void deserializeInternal(NBTTagCompound tag) { + void deserializeInternal(NBTTagCompound tag, Object context) { } static Map buildEnchantments(Map map, ItemMetaKey key) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java index 58c07e964a..b513120e50 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java @@ -56,7 +56,7 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { } @Override - void deserializeInternal(NBTTagCompound tag) { + void deserializeInternal(NBTTagCompound tag, Object context) { if (tag.hasKeyOfType(SKULL_PROFILE.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND)) { profile = GameProfileSerializer.deserialize(tag.getCompound(SKULL_PROFILE.NBT)); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java index 503a1cf0ea..ebf5e18bd9 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java @@ -58,13 +58,33 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { } @Override - void deserializeInternal(NBTTagCompound tag) { - super.deserializeInternal(tag); + void deserializeInternal(NBTTagCompound tag, Object context) { + super.deserializeInternal(tag, context); if (tag.hasKey(ENTITY_TAG.NBT)) { entityTag = tag.getCompound(ENTITY_TAG.NBT); - entityTag = (NBTTagCompound) MinecraftServer.getServer().dataConverterManager.update(DataConverterTypes.ENTITY, new Dynamic(DynamicOpsNBT.a, entityTag), -1, CraftMagicNumbers.DATA_VERSION).getValue(); + if (context instanceof Map) { + Map map = (Map) context; + + // Duplicated from constructor + String entityType = SerializableMeta.getString(map, ENTITY_ID.BUKKIT, true); + if (entityType != null) { + this.spawnedType = EntityType.fromName(entityType); + } + } + + if (this.spawnedType != null) { + // We have a valid spawn type, just remove the ID now + entityTag.remove(ENTITY_ID.NBT); + } + + // Tag still has some other data, lets try our luck with a conversion + if (!entityTag.isEmpty()) { + entityTag = (NBTTagCompound) MinecraftServer.getServer().dataConverterManager.update(DataConverterTypes.ENTITY, new Dynamic(DynamicOpsNBT.a, entityTag), -1, CraftMagicNumbers.DATA_VERSION).getValue(); + } + + // See if we can read a converted ID tag if (entityTag.hasKey(ENTITY_ID.NBT)) { this.spawnedType = EntityType.fromName(new MinecraftKey(entityTag.getString(ENTITY_ID.NBT)).getKey()); } @@ -73,7 +93,7 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { @Override void serializeInternal(Map internalTags) { - if (entityTag != null) { + if (entityTag != null && !entityTag.isEmpty()) { internalTags.put(ENTITY_TAG.NBT, entityTag); } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java index ea6b88853c..781fd65b18 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java @@ -241,30 +241,52 @@ public class CraftLegacy { SPAWN_EGGS.put((byte) EntityType.BLAZE.getTypeId(), Material.BLAZE_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.CAVE_SPIDER.getTypeId(), Material.CAVE_SPIDER_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.CHICKEN.getTypeId(), Material.CHICKEN_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.COD.getTypeId(), Material.COD_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.COW.getTypeId(), Material.COW_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.CREEPER.getTypeId(), Material.CREEPER_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.DOLPHIN.getTypeId(), Material.DOLPHIN_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.DONKEY.getTypeId(), Material.DONKEY_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.ELDER_GUARDIAN.getTypeId(), Material.ELDER_GUARDIAN_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.ENDERMAN.getTypeId(), Material.ENDERMAN_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.ENDERMITE.getTypeId(), Material.ENDERMITE_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.EVOKER.getTypeId(), Material.EVOKER_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.GHAST.getTypeId(), Material.GHAST_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.GUARDIAN.getTypeId(), Material.GUARDIAN_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.HORSE.getTypeId(), Material.HORSE_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.HUSK.getTypeId(), Material.HUSK_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.LLAMA.getTypeId(), Material.LLAMA_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.MAGMA_CUBE.getTypeId(), Material.MAGMA_CUBE_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.MUSHROOM_COW.getTypeId(), Material.MOOSHROOM_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.MULE.getTypeId(), Material.MULE_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.OCELOT.getTypeId(), Material.OCELOT_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.PARROT.getTypeId(), Material.PARROT_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.PIG.getTypeId(), Material.PIG_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.PHANTOM.getTypeId(), Material.PHANTOM_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.POLAR_BEAR.getTypeId(), Material.POLAR_BEAR_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.PUFFERFISH.getTypeId(), Material.PUFFERFISH_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.RABBIT.getTypeId(), Material.RABBIT_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.SALMON.getTypeId(), Material.SALMON_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SHEEP.getTypeId(), Material.SHEEP_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SHULKER.getTypeId(), Material.SHULKER_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SILVERFISH.getTypeId(), Material.SILVERFISH_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SKELETON.getTypeId(), Material.SKELETON_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.SKELETON_HORSE.getTypeId(), Material.SKELETON_HORSE_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SLIME.getTypeId(), Material.SLIME_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SPIDER.getTypeId(), Material.SPIDER_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.SQUID.getTypeId(), Material.SQUID_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.STRAY.getTypeId(), Material.STRAY_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.TROPICAL_FISH.getTypeId(), Material.TROPICAL_FISH_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.TURTLE.getTypeId(), Material.TURTLE_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.VEX.getTypeId(), Material.VEX_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.VILLAGER.getTypeId(), Material.VILLAGER_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.VINDICATOR.getTypeId(), Material.VINDICATOR_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.WITCH.getTypeId(), Material.WITCH_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.WITHER_SKELETON.getTypeId(), Material.WITHER_SKELETON_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.WOLF.getTypeId(), Material.WOLF_SPAWN_EGG); - SPAWN_EGGS.put((byte) EntityType.PIG_ZOMBIE.getTypeId(), Material.ZOMBIE_PIGMAN_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.ZOMBIE.getTypeId(), Material.ZOMBIE_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.ZOMBIE_HORSE.getTypeId(), Material.ZOMBIE_HORSE_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.PIG_ZOMBIE.getTypeId(), Material.ZOMBIE_PIGMAN_SPAWN_EGG); + SPAWN_EGGS.put((byte) EntityType.ZOMBIE_VILLAGER.getTypeId(), Material.ZOMBIE_VILLAGER_SPAWN_EGG); DispenserRegistry.c();