From 8059a937eb6a3e160e1421206e46d24cc5b70687 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 13 Jan 2019 16:25:17 +0100 Subject: [PATCH] SPIGOT-4577: Fix loss of int/double custom tags when serialized to yaml --- .../util/CraftNBTTagConfigSerializer.java | 20 ++++++++++++++- .../inventory/ItemMetaCustomValueTest.java | 25 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java index 4bd4676928..8b7c29403b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java @@ -11,12 +11,16 @@ import net.minecraft.server.MojangsonParser; import net.minecraft.server.NBTBase; import net.minecraft.server.NBTList; import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagDouble; +import net.minecraft.server.NBTTagInt; import net.minecraft.server.NBTTagList; import net.minecraft.server.NBTTagString; public class CraftNBTTagConfigSerializer { private static final Pattern ARRAY = Pattern.compile("^\\[.*]"); + private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)?i", Pattern.CASE_INSENSITIVE); + private static final Pattern DOUBLE = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", Pattern.CASE_INSENSITIVE); private static final MojangsonParser MOJANGSON_PARSER = new MojangsonParser(new StringReader("")); public static Object serialize(NBTBase base) { @@ -36,6 +40,8 @@ public class CraftNBTTagConfigSerializer { return baseList; } else if (base instanceof NBTTagString) { return base.asString(); + } else if (base instanceof NBTTagInt) { // No need to check for doubles, those are covered by the double itself + return base.toString() + "i"; } return base.toString(); @@ -70,8 +76,20 @@ public class CraftNBTTagConfigSerializer { } catch (CommandSyntaxException e) { throw new RuntimeException("Could not deserialize found list ", e); } + } else if (INTEGER.matcher(string).matches()) { //Read integers on our own + return new NBTTagInt(Integer.parseInt(string.substring(0, string.length() - 1))); + } else if (DOUBLE.matcher(string).matches()) { + return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length() - 1))); } else { - return MOJANGSON_PARSER.parseLiteral(string); + NBTBase nbtBase = MOJANGSON_PARSER.parseLiteral(string); + + if (nbtBase instanceof NBTTagInt) { // If this returns an integer, it did not use our method from above + return new NBTTagString(nbtBase.asString()); // It then is a string that was falsely read as an int + } else if (nbtBase instanceof NBTTagDouble) { + return new NBTTagString(String.valueOf(((NBTTagDouble) nbtBase).asDouble())); // Doubles add "d" at the end + } else { + return nbtBase; + } } } diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaCustomValueTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaCustomValueTest.java index 14e7ae8c25..fa303d1fa7 100644 --- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaCustomValueTest.java +++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaCustomValueTest.java @@ -131,6 +131,29 @@ public class ItemMetaCustomValueTest extends AbstractTestingBase { assertNotEquals(new ItemStack(Material.DIAMOND), loadedConfig.getSerializable("testpath", ItemStack.class)); } + @Test + public void testCorrectType() { + ItemStack stack = new ItemStack(Material.DIAMOND); + CraftMetaItem meta = createComplexItemMeta(); + + meta.getCustomTagContainer().setCustomTag(requestKey("int"), ItemTagType.STRING, "1"); + meta.getCustomTagContainer().setCustomTag(requestKey("double"), ItemTagType.STRING, "1.33"); + stack.setItemMeta(meta); + + YamlConfiguration configuration = new YamlConfiguration(); + configuration.set("testpath", stack); + + String configValue = configuration.saveToString(); + YamlConfiguration loadedConfig = YamlConfiguration.loadConfiguration(new StringReader(configValue)); + ItemStack newStack = loadedConfig.getSerializable("testpath", ItemStack.class); + + assertTrue(newStack.getItemMeta().getCustomTagContainer().hasCustomTag(requestKey("int"), ItemTagType.STRING)); + assertEquals(newStack.getItemMeta().getCustomTagContainer().getCustomTag(requestKey("int"), ItemTagType.STRING), "1"); + + assertTrue(newStack.getItemMeta().getCustomTagContainer().hasCustomTag(requestKey("double"), ItemTagType.STRING)); + assertEquals(newStack.getItemMeta().getCustomTagContainer().getCustomTag(requestKey("double"), ItemTagType.STRING), "1.33"); + } + private CraftMetaItem createComplexItemMeta() { CraftMetaItem itemMeta = (CraftMetaItem) createNewItemMeta(); itemMeta.setDisplayName("Item Display Name"); @@ -140,6 +163,8 @@ public class ItemMetaCustomValueTest extends AbstractTestingBase { 0, 1, 2, 10 }); itemMeta.getCustomTagContainer().setCustomTag(requestKey("custom-string"), ItemTagType.STRING, "Hello there world"); + itemMeta.getCustomTagContainer().setCustomTag(requestKey("custom-int"), ItemTagType.INTEGER, 3); + itemMeta.getCustomTagContainer().setCustomTag(requestKey("custom-double"), ItemTagType.DOUBLE, 3.123); CustomItemTagContainer innerContainer = itemMeta.getCustomTagContainer().getAdapterContext().newTagContainer(); //Add a inner container innerContainer.setCustomTag(VALID_KEY, ItemTagType.LONG, 5L);