From 2483f9b947b9e4f563d6b0d05de8e593a857de47 Mon Sep 17 00:00:00 2001 From: tr7zw Date: Wed, 24 Apr 2024 15:59:20 +0200 Subject: [PATCH] Add Datafixer. Auto update 1.20.4 items to 1.20.5 --- item-nbt-api/pom.xml | 9 +++++ .../de/tr7zw/changeme/nbtapi/NBTCompound.java | 2 +- .../tr7zw/changeme/nbtapi/NBTGameProfile.java | 2 +- .../changeme/nbtapi/NBTReflectionUtil.java | 22 +++++++---- .../changeme/nbtapi/utils/DataFixerUtil.java | 38 +++++++++++++++++++ .../utils/nmsmappings/ClassWrapper.java | 6 +++ .../utils/nmsmappings/MojangToMapping.java | 3 ++ .../utils/nmsmappings/ReflectionMethod.java | 2 + item-nbt-plugin/pom.xml | 6 +++ .../java/de/tr7zw/nbtapi/plugin/NBTAPI.java | 4 ++ .../plugin/tests/items/LegacyItemTest.java | 21 ++++++++++ 11 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/DataFixerUtil.java create mode 100644 item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/LegacyItemTest.java diff --git a/item-nbt-api/pom.xml b/item-nbt-api/pom.xml index 136f1f1f9..9942c01a4 100644 --- a/item-nbt-api/pom.xml +++ b/item-nbt-api/pom.xml @@ -11,6 +11,15 @@ item-nbt-api jar + + + com.mojang + datafixerupper + 7.0.14 + provided + + + clean install javadoc:javadoc diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTCompound.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTCompound.java index 99316c838..6d2614908 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTCompound.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTCompound.java @@ -103,7 +103,7 @@ protected Object getResolvedObject() { } if (!NBTReflectionUtil.valideCompound(this)) throw new NbtApiException("The Compound wasn't able to be linked back to the root!"); - Object workingtag = NBTReflectionUtil.gettoCompount(rootnbttag, this); + Object workingtag = NBTReflectionUtil.getToCompount(rootnbttag, this); if (readOnly) { this.readOnlyCache = workingtag; } diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTGameProfile.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTGameProfile.java index 7eee1f86a..3fe69c56a 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTGameProfile.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTGameProfile.java @@ -34,7 +34,7 @@ public static GameProfile fromNBT(NBTCompound compound) { return GameprofileUtil.readGameProfile(compound); } return (GameProfile) ReflectionMethod.GAMEPROFILE_DESERIALIZE.run(null, - NBTReflectionUtil.gettoCompount(compound.getCompound(), compound)); + NBTReflectionUtil.getToCompount(compound.getCompound(), compound)); } } diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTReflectionUtil.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTReflectionUtil.java index 1dafd25ce..a7300bd2d 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTReflectionUtil.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTReflectionUtil.java @@ -19,6 +19,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import com.mojang.datafixers.DataFixerUpper; + +import de.tr7zw.changeme.nbtapi.utils.DataFixerUtil; import de.tr7zw.changeme.nbtapi.utils.GsonWrapper; import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; @@ -211,8 +214,11 @@ public static void setItemStackCompound(Object nmsItem, Object compound) { */ public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) { try { - Object nmsComp = gettoCompount(nbtcompound.getCompound(), nbtcompound); + Object nmsComp = getToCompount(nbtcompound.getCompound(), nbtcompound); if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { + if(nbtcompound.hasTag("tag")) { + nmsComp = DataFixerUtil.fixUpRawItemData(nmsComp, DataFixerUtil.VERSION1_20_4, DataFixerUtil.VERSION1_20_5); + } return ReflectionMethod.NMSITEM_LOAD.run(null, registry_access, nmsComp); } else if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_11_R1.getVersionId()) { return ObjectCreator.NMS_COMPOUNDFROMITEM.getInstance(nmsComp); @@ -401,7 +407,7 @@ public static void addNBTTagCompound(NBTCompound comp, String name) { if (!valideCompound(comp)) { return; } - Object workingtag = gettoCompount(nbttag, comp); + Object workingtag = getToCompount(nbttag, comp); try { ReflectionMethod.COMPOUND_SET.run(workingtag, name, ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance()); @@ -422,12 +428,12 @@ public static boolean valideCompound(NBTCompound comp) { if (root == null) { root = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(); } - Object tmp = gettoCompount(root, comp); + Object tmp = getToCompount(root, comp); comp.setResolvedObject(tmp); return tmp != null; } - protected static Object gettoCompount(Object nbttag, NBTCompound comp) { + public static Object getToCompount(Object nbttag, NBTCompound comp) { Deque structure = new ArrayDeque<>(); while (comp.getParent() != null) { structure.add(comp.getName()); @@ -460,7 +466,7 @@ public static void mergeOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompou } if (!valideCompound(comp)) throw new NbtApiException("The Compound wasn't able to be linked back to the root!"); - Object workingtag = gettoCompount(rootnbttag, comp); + Object workingtag = getToCompount(rootnbttag, comp); try { ReflectionMethod.COMPOUND_MERGE.run(workingtag, workingtagSrc); comp.setCompound(rootnbttag); @@ -488,7 +494,7 @@ public static void set(NBTCompound comp, String key, Object val) { if (!valideCompound(comp)) { throw new NbtApiException("The Compound wasn't able to be linked back to the root!"); } - Object workingtag = gettoCompount(rootnbttag, comp); + Object workingtag = getToCompount(rootnbttag, comp); try { ReflectionMethod.COMPOUND_SET.run(workingtag, key, val); comp.setCompound(rootnbttag); @@ -621,7 +627,7 @@ public static void remove(NBTCompound comp, String key) { } if (!valideCompound(comp)) return; - Object workingtag = gettoCompount(rootnbttag, comp); + Object workingtag = getToCompount(rootnbttag, comp); ReflectionMethod.COMPOUND_REMOVE_KEY.run(workingtag, key); comp.setCompound(rootnbttag); } @@ -660,7 +666,7 @@ public static void setData(NBTCompound comp, ReflectionMethod type, String key, } if (!valideCompound(comp)) throw new NbtApiException("The Compound wasn't able to be linked back to the root!"); - Object workingtag = gettoCompount(rootnbttag, comp); + Object workingtag = getToCompount(rootnbttag, comp); type.run(workingtag, key, data); comp.setCompound(rootnbttag); } diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/DataFixerUtil.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/DataFixerUtil.java new file mode 100644 index 000000000..536c62372 --- /dev/null +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/DataFixerUtil.java @@ -0,0 +1,38 @@ +package de.tr7zw.changeme.nbtapi.utils; + +import com.mojang.datafixers.DSL.TypeReference; +import com.mojang.datafixers.DataFixer; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.DynamicOps; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTContainer; +import de.tr7zw.changeme.nbtapi.NBTReflectionUtil; +import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; +import de.tr7zw.changeme.nbtapi.utils.nmsmappings.MojangToMapping; +import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; + +public class DataFixerUtil { + + public static final int VERSION1_20_4 = 3817; // 1.20.4 + public static final int VERSION1_20_5 = 3825; // 1.20.5 + + @SuppressWarnings("unchecked") + public static Object fixUpRawItemData(Object nbt, int fromVersion, int toVersion) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + DataFixer dataFixer = (DataFixer) ReflectionMethod.GET_DATAFIXER.run(null); + TypeReference itemStackReference = (TypeReference) ClassWrapper.NMS_REFERENCES.getClazz() + .getField(MojangToMapping.getMapping().get("net.minecraft.util.datafix.fixes.References#ITEM_STACK")) + .get(null); + DynamicOps nbtOps = (DynamicOps) ClassWrapper.NMS_NBTOPS.getClazz() + .getField(MojangToMapping.getMapping().get("net.minecraft.nbt.NbtOps#INSTANCE")).get(null); + Dynamic fixed = dataFixer.update(itemStackReference, new Dynamic(nbtOps, nbt), fromVersion, toVersion); + return fixed.getValue(); + } + + public static NBTCompound fixUpItemData(NBTCompound nbt, int fromVersion, int toVersion) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + return new NBTContainer(fixUpRawItemData(NBTReflectionUtil.getToCompount(nbt.getCompound(), nbt), fromVersion, toVersion)); + } + +} diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ClassWrapper.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ClassWrapper.java index 7b031394e..c74b5a9cd 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ClassWrapper.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ClassWrapper.java @@ -79,6 +79,12 @@ public enum ClassWrapper { "net.minecraft.core", "net.minecraft.core.HolderLookup$Provider"), NMS_SERVER(PackageWrapper.NMS, "MinecraftServer", MinecraftVersion.MC1_20_R4, null, "net.minecraft.server", "net.minecraft.server.MinecraftServer"), + NMS_DATAFIXERS(PackageWrapper.NMS, "DataConverterRegistry", MinecraftVersion.MC1_20_R4, null, + "net.minecraft.util.datafix", "net.minecraft.util.datafix.DataFixers"), + NMS_REFERENCES(PackageWrapper.NMS, "DataConverterTypes", MinecraftVersion.MC1_20_R4, null, + "net.minecraft.util.datafix.fixes", "net.minecraft.util.datafix.fixes.References"), + NMS_NBTOPS(PackageWrapper.NMS, "DynamicOpsNBT", MinecraftVersion.MC1_20_R4, null, + "net.minecraft.nbt", "net.minecraft.nbt.NbtOps"), GAMEPROFILE(PackageWrapper.NONE, "com.mojang.authlib.GameProfile", MinecraftVersion.MC1_8_R3, null); private Class clazz; diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/MojangToMapping.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/MojangToMapping.java index 5983aa54e..e1f673928 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/MojangToMapping.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/MojangToMapping.java @@ -165,6 +165,9 @@ public class MojangToMapping { put("net.minecraft.world.item.ItemStack#parseOptional(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.CompoundTag)", "a"); put("net.minecraft.world.level.block.entity.BlockEntity#saveWithId(net.minecraft.core.HolderLookup$Provider)", "c"); put("net.minecraft.world.level.block.entity.BlockEntity#loadWithComponents(net.minecraft.nbt.CompoundTag,net.minecraft.core.HolderLookup$Provider)", "c"); + put("net.minecraft.util.datafix.DataFixers#getDataFixer()", "a"); + put("net.minecraft.util.datafix.fixes.References#ITEM_STACK", "t"); + put("net.minecraft.nbt.NbtOps#INSTANCE", "a"); } }; diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ReflectionMethod.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ReflectionMethod.java index 639c2ab68..5c40ec499 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ReflectionMethod.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ReflectionMethod.java @@ -313,6 +313,8 @@ MinecraftVersion.MC1_20_R4, new Since(MinecraftVersion.MC1_20_R4, "getServer()") new Since(MinecraftVersion.MC1_20_R4, "saveWithId(net.minecraft.core.HolderLookup$Provider)")), TILEENTITY_SET_NBT_1205(ClassWrapper.NMS_TILEENTITY, new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.NMS_PROVIDER.getClazz() }, MinecraftVersion.MC1_20_R4, new Since(MinecraftVersion.MC1_20_R4, "loadWithComponents(net.minecraft.nbt.CompoundTag,net.minecraft.core.HolderLookup$Provider)")), + GET_DATAFIXER(ClassWrapper.NMS_DATAFIXERS, new Class[] {}, MinecraftVersion.MC1_20_R4, + new Since(MinecraftVersion.MC1_20_R4, "getDataFixer()")), ; private MinecraftVersion removedAfter; diff --git a/item-nbt-plugin/pom.xml b/item-nbt-plugin/pom.xml index 1840e3f18..829530adf 100644 --- a/item-nbt-plugin/pom.xml +++ b/item-nbt-plugin/pom.xml @@ -27,6 +27,12 @@ 2.12.4-SNAPSHOT compile + + com.mojang + datafixerupper + 7.0.14 + provided + diff --git a/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/NBTAPI.java b/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/NBTAPI.java index 031d6aabe..a4f5c2959 100644 --- a/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/NBTAPI.java +++ b/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/NBTAPI.java @@ -50,6 +50,7 @@ import de.tr7zw.nbtinjector.NBTInjector; import de.tr7zw.nbtapi.plugin.tests.items.ItemMergingTest; import de.tr7zw.nbtapi.plugin.tests.items.ItemStackConversionTest; +import de.tr7zw.nbtapi.plugin.tests.items.LegacyItemTest; import de.tr7zw.nbtapi.plugin.tests.proxy.DataItemProxyTest; import de.tr7zw.nbtapi.plugin.tests.proxy.SimpleProxyTest; import de.tr7zw.nbtapi.plugin.tests.items.MetaTest; @@ -128,6 +129,9 @@ public void onLoad() { apiTests.add(new ItemConversionTest()); apiTests.add(new ItemStackConversionTest()); } + if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { + apiTests.add(new LegacyItemTest()); + } apiTests.add(new EmptyItemTest()); apiTests.add(new SmuggleTest()); apiTests.add(new DataItemProxyTest()); diff --git a/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/LegacyItemTest.java b/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/LegacyItemTest.java new file mode 100644 index 000000000..8d226a7e7 --- /dev/null +++ b/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/LegacyItemTest.java @@ -0,0 +1,21 @@ +package de.tr7zw.nbtapi.plugin.tests.items; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.NbtApiException; +import de.tr7zw.nbtapi.plugin.tests.Test; + +public class LegacyItemTest implements Test { + + @Override + public void test() throws Exception { + ItemStack item = NBT.itemStackFromNBT(NBT.parseNBT("{id:cobblestone,Count:42,tag:{Enchantments:[{lvl:3,id:unbreaking}]}}")); + if(item.getType() != Material.COBBLESTONE || item.getAmount() != 42 || item.getEnchantmentLevel(Enchantment.DURABILITY) != 3) { + throw new NbtApiException("1.20 item didn't load correctly! " + item); + } + } + +}