From c16548ff4e19a7f60ef2bbf3b3d3943fb9e01ef1 Mon Sep 17 00:00:00 2001 From: tr7zw Date: Thu, 13 Jun 2024 20:26:39 +0200 Subject: [PATCH] New "modifyComponents" api --- .../java/de/tr7zw/changeme/nbtapi/NBT.java | 40 +++++++++++++++++++ .../java/de/tr7zw/nbtapi/plugin/NBTAPI.java | 2 + .../plugin/tests/items/ComponentsTest.java | 37 +++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ComponentsTest.java diff --git a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBT.java b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBT.java index 5e12c7623..1859403bc 100644 --- a/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBT.java +++ b/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBT.java @@ -18,6 +18,7 @@ import de.tr7zw.changeme.nbtapi.wrapper.NBTProxy; import de.tr7zw.changeme.nbtapi.wrapper.ProxyBuilder; import de.tr7zw.changeme.nbtapi.iface.ReadableNBTList; +import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; /** * General utility class for a clean and simple nbt access. @@ -25,6 +26,7 @@ * @author tr7zw * */ +@SuppressWarnings("deprecation") public class NBT { private NBT() { @@ -225,6 +227,44 @@ public static T modify(Entity entity, Function function) { nbtEnt.setClosed(); return ret; } + + /** + * It takes an ItemStack and a Consumer<ReadWriteNBT>, and then applies + * the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only. + * This method is quiet expensive, so don't overuse it. + * + * @param item The item you want to modify the components of + * @param consumer The consumer that will be used to modify the components. + */ + public static void modifyComponents(ItemStack item, Consumer consumer) { + if(!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { + throw new NbtApiException("This method only works for 1.20.5+!"); + } + ReadWriteNBT nbti = NBT.itemStackToNBT(item); + consumer.accept(nbti.getOrCreateCompound("components")); + ItemStack tmp = NBT.itemStackFromNBT(nbti); + item.setItemMeta(tmp.getItemMeta()); + } + + /** + * It takes an ItemStack and a Consumer<ReadWriteNBT>, and then applies + * the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only. + * This method is quiet expensive, so don't overuse it. + * + * @param item The item you want to modify the components of + * @param function The consumer that will be used to modify the components. + * @return The return type is the same as the return type of the function. + */ + public static T modifyComponents(ItemStack item, Function function) { + if(!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { + throw new NbtApiException("This method only works for 1.20.5+!"); + } + ReadWriteNBT nbti = NBT.itemStackToNBT(item); + T ret = function.apply(nbti.getOrCreateCompound("components")); + ItemStack tmp = NBT.itemStackFromNBT(nbti); + item.setItemMeta(tmp.getItemMeta()); + return ret; + } /** * It takes an entity and a function that takes a ReadWriteNBT and applies the 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 a4f5c2959..9963341c6 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 @@ -41,6 +41,7 @@ import de.tr7zw.nbtapi.plugin.tests.injector.MergeTileSubCompoundTest; import de.tr7zw.nbtapi.plugin.tests.injector.SpawnEntityCustomNbtInjectorTest; import de.tr7zw.nbtapi.plugin.tests.injector.TilesCustomNBTInjectorTest; +import de.tr7zw.nbtapi.plugin.tests.items.ComponentsTest; import de.tr7zw.nbtapi.plugin.tests.items.DirectApplyMetaTest; import de.tr7zw.nbtapi.plugin.tests.items.DirectApplyTest; import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest; @@ -132,6 +133,7 @@ public void onLoad() { if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { apiTests.add(new LegacyItemTest()); } + apiTests.add(new ComponentsTest()); 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/ComponentsTest.java b/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ComponentsTest.java new file mode 100644 index 000000000..1c26b7187 --- /dev/null +++ b/item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ComponentsTest.java @@ -0,0 +1,37 @@ +package de.tr7zw.nbtapi.plugin.tests.items; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.NbtApiException; +import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; +import de.tr7zw.nbtapi.plugin.tests.Test; + +public class ComponentsTest implements Test { + + @Override + public void test() throws Exception { + if(!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { + return; + } + ItemStack item = new ItemStack(Material.STICK); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName("test"); + item.setItemMeta(meta); + String comp = NBT.modifyComponents(item, n -> { + return n.toString(); + }); + if(!comp.contains("test")) { + throw new NbtApiException("ReadComponent didn't work!"); + } + NBT.modifyComponents(item, nbt -> { + nbt.setString("minecraft:custom_name", "{\"extra\":[\"foobar\"],\"text\":\"\"}"); + }); + if(!item.getItemMeta().getDisplayName().equals("foobar")) { + throw new NbtApiException("ModifyComponent didn't work!"); + } + } + +}