### Example Relocation Configuration for Maven Shade Plugin Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Maven Provides a concrete example of how to configure the `` tag within the Maven Shade Plugin to specify the source and destination packages for shading the NBT-API. ```xml de.tr7zw.changeme.nbtapi com.yourname.pluginname.nbtapi ``` -------------------------------- ### Add CodeMC Repository to Gradle Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Configures your Gradle build to include the CodeMC Maven repository, which hosts the NBT-API. ```groovy repositories { ... maven { name = "CodeMC" url = uri("https://repo.codemc.io/repository/maven-public/") } ... } ``` -------------------------------- ### Preload NBT-API in Plugin onEnable Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Initializes the NBT-API early in your plugin's onEnable method when shading is used. This checks for proper initialization and provides early feedback. ```java @Override public void onEnable() { if (!NBT.preloadApi()) { getLogger().warning("NBT-API wasn't initialized properly, disabling the plugin"); getPluginLoader().disablePlugin(this); return; } // Load other things } ``` -------------------------------- ### Declare NBT-API Dependency in plugin.yml Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Specifies the NBT-API plugin as a dependency in your plugin's configuration file for Spigot/Bukkit servers. ```yml depend: - NBTAPI ``` -------------------------------- ### Use NBT-API as a Direct Dependency (Gradle) Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Adds the NBT-API as a direct implementation dependency for your Gradle project when shading it. Avoid shading the '-plugin' artifact. ```groovy implementation("de.tr7zw:item-nbt-api:VERSION") ``` -------------------------------- ### Shade NBT-API using Gradle Shadow Plugin Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Applies the Gradle Shadow Plugin to bundle the NBT-API directly into your plugin JAR. This requires configuring the plugin and relocating the API's package. ```groovy plugins { id("com.gradleup.shadow") version "VERSION" } shadowJar { relocate("de.tr7zw.changeme.nbtapi", "YOUR PACKAGE WHERE THE API SHOULD END UP") } build { dependsOn(shadowJar) } ``` -------------------------------- ### Ensure ShadowJar Runs on Build (Gradle) Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Gradle Configures the Gradle build task to automatically depend on the shadowJar task. ```groovy build { dependsOn(shadowJar) } ``` -------------------------------- ### Configure Relocation for Shaded API (Gradle) Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Gradle Configures the Gradle Shadow Plugin to relocate the NBT API package to avoid naming conflicts. ```groovy shadowJar { relocate("de.tr7zw.changeme.nbtapi", "YOUR PACKAGE WHERE THE API SHOULD END UP") } ``` -------------------------------- ### Declare NBT-API Dependency in paper-plugin.yml Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Declares the NBT-API plugin as a server dependency in a paper-plugin.yml file, specifying load order and requirements. ```yml dependencies: server: NBTAPI: load: BEFORE required: true join-classpath: true ``` -------------------------------- ### Shade Item NBT API into Plugin (Gradle) Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Gradle Includes the Item NBT API directly within your plugin's JAR using the Gradle Shadow Plugin. ```groovy plugins { id("com.gradleup.shadow") version "VERSION" } implementation("de.tr7zw:item-nbt-api:VERSION") ``` -------------------------------- ### Use NBT-API as a Plugin Dependency (Gradle) Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Gradle.md Adds the NBT-API plugin as a compile-time dependency for your Gradle project. Ensure you use the correct artifactId and version. ```groovy compileOnly("de.tr7zw:item-nbt-api-plugin:VERSION") ``` -------------------------------- ### Basic NBT Getting and Setting in Java Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to create, set, and retrieve various data types (String, Integer, Double, Boolean) from NBT objects using the ReadWriteNBT interface. It also shows methods for getting values with defaults or null fallbacks, checking tag existence and types, manipulating keys, and working with subtag compounds. ```java ReadWriteNBT nbt = NBT.createNBTObject(); // Setting nbt nbt.setString("Stringtest", "Teststring"); nbt.setInteger("Inttest", 42); nbt.setDouble("Doubletest", 1.5); nbt.setBoolean("Booleantest", true); // More are available! Ask your IDE, or see Javadoc for suggestions! // Getting nbt String s1 = nbt.getString("Stringtest"); int i1 = nbt.getInteger("Inttest"); double d = nbt.getDouble("Doubletest"); boolean b = nbt.getBoolean("Booleantest"); // Or, alternatively String s2 = nbt.getOrDefault("Stringtest", "fallback_value"); Integer i2 = nbt.getOrNull("Inttest", Integer.class); // Keys manipulation nbt.getKeys(); // Get all Tags nbt.hasTag("key"); // Check whether the Tag exists nbt.hasTag("key", NbtType.NBTTagString); // Check whether the Tag exists and matches the type nbt.removeKey("key"); // Remove the Tag NBTType nbtType = nbt.getType("key"); // Get the type of the Tag // Subtag compounds nbt.getCompound("subtag"); // Get a subtag, or null nbt.getOrCreateCompound("subtag"); // Get or create a subtag ``` -------------------------------- ### Accessing/Creating Lists and Data Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Demonstrates how to get or create string and compound lists, add elements, retrieve list types, and access data within lists using various NBT methods. ```java // Get or create a string list ReadWriteNBTList stringList = nbt.getStringList("list_key"); stringList.add("value"); // Get the list type, NBTTagString in this case NBTType type = nbt.getListType("list_key"); // You can obtain the value back just like with normal Lists nbt.getStringList("list_key").get(0); // Or by fetching it nbt.resolveOrNull("list_key[0]", String.class); // Get the first value in list // You can also use negative number to get the value from the end of the list/array nbt.resolveOrDefault("list_key[-1]", "fallback_value"); // Get the last value in list, or use the default // NBT compound lists // Get the list (will create it if needed) ReadWriteNBTCompoundList nbtList = nbt.getOrCreateCompound("foo").getCompoundList("other_key"); // Add new compound to the list ReadWriteNBT nbtListEntry = nbtList.addCompound(); nbtListEntry.setBoolean("bar", true); // Add existing nbt compound to the list ReadWriteNBT otherNbtListEntry = nbtList.addCompound(NBT.parseNBT("{foo_bar:1b}")); // You can fetch compounds in lists nbt.resolveCompound("foo.other_key[0]"); // Get the first compound in list, or null nbt.resolveOrCreateCompound("foo.other_key[1]"); // Get the second compound in list, or create it // Or fetch data from them boolean bar = nbt.resolveOrDefault("foo.other_key[0].bar", false); ``` -------------------------------- ### Configure Maven Shade Plugin for NBT-API Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-Maven.md This XML snippet configures the Maven Shade Plugin to relocate the NBT-API's package. This is used when shading the API directly into your plugin. ```xml org.apache.maven.plugins maven-shade-plugin 3.6.0 shade package shade de.tr7zw.changeme.nbtapi YOUR PACKAGE WHERE THE API SHOULD END UP ``` -------------------------------- ### Define NBTProxy Interface for NBT Access Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Illustrates how to create custom interfaces extending NBTProxy to define methods for interacting with NBT data. Methods starting with 'has', 'get', or 'set' are automatically mapped to NBT operations. ```java interface TestInterface extends NBTProxy { // Runs: return nbt.hasTag("kills"); boolean hasKills(); // Runs: nbt.setInteger("kills", amount); void setKills(int amount); // Runs: return nbt.getInteger("kills"); int getKills(); // Also supported default void addKill() { setKills(getKills() + 1); } } ``` -------------------------------- ### Accessing and Creating NBT Lists Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to get or create string lists and compound lists in NBT data. It also shows how to add elements to these lists and retrieve specific values using various methods. ```java // Get or create a string list ReadWriteNBTList stringList = nbt.getStringList("list_key"); stringList.add("value"); // Get the list type, NBTTagString in this case NBTType type = nbt.getListType("list_key"); // You can obtain the value back just like with normal Lists nbt.getStringList("list_key").get(0); // Or by fetching it nbt.resolveOrNull("list_key[0]", String.class); // Get the first value in list // You can also use negative number to get the value from the end of the list/array nbt.resolveOrDefault("list_key[-1]", "fallback_value"); // Get the last value in list, or use the default // NBT compound lists // Get the list (will create it if needed) ReadWriteNBTCompoundList nbtList = nbt.getOrCreateCompound("foo").getCompoundList("other_key"); // Add new compound to the list ReadWriteNBT nbtListEntry = nbtList.addCompound(); nbtListEntry.setBoolean("bar", true); // Add existing nbt compound to the list ReadWriteNBT otherNbtListEntry = nbtList.addCompound(NBT.parseNBT("{foo_bar:1b}")); // You can fetch compounds in lists nbt.resolveCompound("foo.other_key[0]"); // Get the first compound in list, or null nbt.resolveOrCreateCompound("foo.other_key[1]"); // Get the second compound in list, or create it // Or fetch data from them boolean bar = nbt.resolveOrDefault("foo.other_key[0].bar", false); ``` -------------------------------- ### Configure Maven Shade Plugin for NBT-API Shading Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Maven Sets up the Maven Shade Plugin to relocate the NBT-API's package into your plugin's package structure. This is crucial for shading the API to avoid conflicts. ```xml org.apache.maven.plugins maven-shade-plugin 3.6.0 shade package shade de.tr7zw.changeme.nbtapi YOUR PACKAGE WHERE THE API SHOULD END UP ``` -------------------------------- ### Add CodeMC Repository to Maven POM Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Maven Configures the Maven build to use the CodeMC repository, which hosts the NBT-API artifacts. This is a prerequisite for including the API as a dependency. ```xml ... codemc-repo https://repo.codemc.io/repository/maven-public/ default ... ``` -------------------------------- ### Include NBT-API Plugin as Maven Dependency Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Maven Adds the NBT-API plugin as a provided dependency to your project's Maven POM file. This allows your plugin to utilize the NBT-API functionalities without bundling it directly. ```xml de.tr7zw item-nbt-api-plugin VERSION provided ``` -------------------------------- ### Basic NBT Get/Set Operations in Java Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Demonstrates how to create, set, and retrieve various data types (String, Integer, Double, Boolean) from NBT objects. It also shows methods for getting default values, optional values, and manipulating NBT keys like checking existence, type, and removal. ```java ReadWriteNBT nbt = NBT.createNBTObject(); nbt.setString("Stringtest", "Teststring"); nbt.setInteger("Inttest", 42); nbt.setDouble("Doubletest", 1.5); nbt.setBoolean("Booleantest", true); String s1 = nbt.getString("Stringtest"); int i1 = nbt.getInteger("Inttest"); double d = nbt.getDouble("Doubletest"); boolean b = nbt.getBoolean("Booleantest"); String s2 = nbt.getOrDefault("Stringtest", "fallback_value"); Integer i2 = nbt.getOrNull("Inttest", Integer.class); nbt.getKeys(); nbt.hasTag("key"); nbt.hasTag("key", NbtType.NBTTagString); nbt.removeKey("key"); NBTType nbtType = nbt.getType("key"); nbt.getCompound("subtag"); nbt.getOrCreateCompound("subtag"); ``` -------------------------------- ### Reading Item NBT Data Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Illustrates how to retrieve NBT data from an item stack using NBT.get and NBT.resolveOrDefault methods. It shows how to get specific data types and provide default values. ```java // Reading data NBT.get(itemStack, nbt -> { String stringTest = nbt.getString("Stringtest"); int intTest = nbt.getOrDefault("Inttest", 0); // Do more stuff }); // Getting data String string = NBT.get(itemStack, nbt -> (String) nbt.getString("Stringtest")); ``` -------------------------------- ### Accessing and Modifying Entity/Block Entity NBT Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Demonstrates how to read and modify NBT data for entities and block entities, similar to items. It shows examples of getting a boolean value and setting boolean and byte values. ```java // Obtain data boolean silent = NBT.get(entity, nbt -> (boolean) nbt.getBoolean("Silent")); // Modify data NBT.modify(entity, nbt -> { nbt.setBoolean("Silent", true); nbt.setByte("CanPickUpLoot", (byte) 1); }); ``` -------------------------------- ### Update NBT Data with DataFixerUtil Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Shows how to use DataFixerUtil to update NBT data from older Minecraft versions to more recent ones. It provides an example of converting 1.12.2 item data to 1.20.6 format. ```java DataFixerUtil.fixUpItemData(nbt, DataFixerUtil.VERSION1_12_2, DataFixerUtil.VERSION1_20_6); ``` -------------------------------- ### Include Shaded NBT-API as Maven Dependency Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-Maven Adds the core NBT-API artifact (without '-plugin') as a dependency to your Maven POM when shading it. This is used in conjunction with the Maven Shade Plugin. ```xml de.tr7zw item-nbt-api VERSION ``` -------------------------------- ### Modifying and Reading Item NBT Data Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Shows how to set and retrieve various NBT data types (String, Integer, Double, Boolean) on an item stack using NBT.modify and NBT.get methods. It also covers modifying and getting data in a single operation. ```java // Setting data NBT.modify(itemStack, nbt -> { nbt.setString("Stringtest", "Teststring"); nbt.setInteger("Inttest", 42); nbt.setDouble("Doubletest", 1.5d); nbt.setBoolean("Booleantest", true); // More are available! Ask your IDE, or see Javadoc for suggestions! }); // Reading data NBT.get(itemStack, nbt -> { String stringTest = nbt.getString("Stringtest"); int intTest = nbt.getOrDefault("Inttest", 0); // Do more stuff }); // Getting data String string = NBT.get(itemStack, nbt -> (String) nbt.getString("Stringtest")); // Modifying and getting data int someValue = NBT.modify(itemStack, nbt -> { int i = nbt.getOrDefault("key", 0) + 1; nbt.setInteger(i); return i; }); ``` -------------------------------- ### Read World Data (Java) Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Example-Usages.md Reads data from Minecraft world files, including the main 'level.dat' file to get the world name and player data files (.dat) to access and modify player attributes like health. It utilizes `NBT.getFileHandle` for file access and NBT parsing. ```java // Get main world's folder File worldDataFolder = Bukkit.getWorlds().getFirst().getWorldFolder(); // Read level data NBTFileHandle levelNbtFile = NBT.getFileHandle(new File(worldDataFolder, "level.dat")); // Obtain world name String worldName = levelNbtFile.resolveOrNull("Data.LevelName", String.class); // Read some player's data UUID playerUuid; File playerFile = new File(worldDataFolder, "playerdata/" + playerUuid + ".dat"); if (!playerFile.exists()) { // No offline player data for provided uuid return; } NBTFileHandle playerNbtFile = NBT.getFileHandle(playerFile); // Change player's health float health = playerNbtFile.getFloat("Health"); playerNbtFile.setFloat("Health", health + 5); // Once finished, save the file playerNbtFile.save(); ``` -------------------------------- ### Managing NBT Files with NBTFileHandle Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to use NBTFileHandle to create, modify, and save data to NBT files. This class automatically manages file creation and saving. ```java // Will automatically create the file if it does not exist NBTFileHandle nbtFile = NBT.getFileHandle(new File("directory", "test.nbt")); // Setting data nbtFile.setString("foo", "bar"); // Saving the file after applying changes nbtFile.save(); ``` -------------------------------- ### Custom NBT Handlers Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Guidance on creating custom NBT handlers for unsupported data types. ```APIDOC ## Custom NBT Handlers ### Description If you need to support custom data types not included in `NBTHandlers`, you can create your own `NBTHandler`. Refer to the existing implementations in `NBTHandlers.java` for guidance. ### Resources - `NBTHandlers` class: [https://github.com/tr7zw/Item-NBT-API/blob/master/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/handler/NBTHandlers.java](https://github.com/tr7zw/Item-NBT-API/blob/master/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/handler/NBTHandlers.java) ``` -------------------------------- ### Simulating '/data merge' Command Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Shows how to merge NBT data into an entity, similar to the '/data merge' command in Minecraft. This allows for dynamic modification of entity properties. ```java NBT.modify(zombie, nbt -> { nbt.mergeCompound(NBT.parseNBT("{Silent:1b,Invulnerable:1b,Glowing:1b,IsBaby:1b}")); }); ``` -------------------------------- ### Advanced NBTProxy with @NBTTarget Annotation Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Explains how to use the @NBTTarget annotation to gain finer control over NBT data access within NBTProxy interfaces, allowing specification of data types and keys. ```java interface TestInterface extends NBTProxy { // Will get PointsInterface from data in "other" key @NBTTarget(type = Type.GET, value = "other") PointsInterface getOtherInterface(); } interface PointsInterface extends NBTProxy { int getPoints(); void setPoints(int points); } ``` -------------------------------- ### NBTProxy Interface Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Defines how to create custom interfaces extending NBTProxy for structured NBT data access. ```APIDOC ## Interface Proxies with NBTProxy ### Description Allows defining custom interfaces that extend `NBTProxy` to provide a type-safe and structured way to interact with NBT data. Methods like `has`, `get`, and `set` are automatically mapped to NBT operations. ### Usage Methods starting with `has`, `get`, or `set` are interpreted as NBT tag operations. Getters can also return other `NBTProxy` interfaces. ### Example 1: Basic Interface ```java interface TestInterface extends NBTProxy { // Maps to: nbt.hasTag("kills"); boolean hasKills(); // Maps to: nbt.setInteger("kills", amount); void setKills(int amount); // Maps to: nbt.getInteger("kills"); int getKills(); // Default methods are also supported default void addKill() { setKills(getKills() + 1); } } ``` ### Example 2: Using @NBTTarget for Specific Keys and Types ```java interface TestInterface extends NBTProxy { // Gets 'PointsInterface' from the 'other' NBT tag @NBTTarget(type = Type.GET, value = "other") PointsInterface getOtherInterface(); } interface PointsInterface extends NBTProxy { int getPoints(); void setPoints(int points); } ``` ### Example 3: Registering Custom Handlers To support data types like `ItemStack` or custom types, override the `init` method and register appropriate handlers. ```java interface TestInterface extends NBTProxy { @Override default void init() { // Register handler for ItemStack registerHandler(ItemStack.class, NBTHandlers.ITEM_STACK); // Register handler for ReadableNBT registerHandler(ReadableNBT.class, NBTHandlers.STORE_READABLE_TAG); // Register handler for ReadWriteNBT registerHandler(ReadWriteNBT.class, NBTHandlers.STORE_READWRITE_TAG); } ItemStack getItem(); void setItem(ItemStack item); ReadWriteNBT getBlockStateTag(); void setBlockStateTag(ReadableNBT blockState); } ``` `NBTHandlers` provides pre-defined handlers for common types. ``` -------------------------------- ### Reading and Writing NBT Files Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Provides methods for reading from and writing to NBT files without maintaining a persistent link. This approach is useful for one-off operations or when automatic file creation is not desired. ```java File file = new File("directory", "test.nbt"); // Reading data from file (will return an empty compound if the file does not exist) ReadWriteNBT nbt = NBT.readFile(file); // Saving nbt to file NBT.writeFile(file, nbt); ``` -------------------------------- ### Game Profiles Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Methods for serializing and deserializing game profile data to and from NBT format. ```APIDOC ## Game Profiles ### Description Utilities for converting `GameProfile` objects to and from NBT format, enabling persistent storage of profile data. ### Methods - `NBT.gameProfileToNBT(GameProfile profile)`: Serializes a `GameProfile` to NBT. - `NBT.gameProfileFromNBT(ReadWriteNBT nbt)`: Deserializes a `GameProfile` from NBT. ### Request Example ```java // Saving GameProfile ReadWriteNBT nbt = NBT.gameProfileToNBT(profile); // Restoring GameProfile GameProfile restoredProfile = NBT.gameProfileFromNBT(nbt); ``` ``` -------------------------------- ### Correct ItemMeta and NBT Interaction Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Explains the correct way to modify both ItemMeta and NBT data to avoid conflicts, emphasizing taking ItemMeta snapshots after NBT changes. ```java // Correct, both ItemMeta and NBT will be applied NBT.modify(itemStack, nbt -> nbt.setBoolean("modified", true)); // Taking ItemMeta snapshot after changes to nbt ItemMeta meta = itemStack.getItemMeta(); meta.setDisplayName("Modified!"); itemStack.setItemMeta(meta); // If making any further changes with NBT & ItemMeta, // re-take the item's ItemMeta after changing the nbt! ``` -------------------------------- ### Comparing NBT Data with Difference Extraction in Java Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Shows how to compare two NBT objects for equality and how to extract the differences between them using `extractDifference`. This method returns an NBT object representing the parts that do not match. ```java ReadWriteNBT nbt1 = NBT.parseNBT("{intTag:1,compoundTag:{floatTag:20.0f,booleanTag:1b}},intArray:[I;1,2]"); ReadWriteNBT nbt2 = NBT.parseNBT("{intTag:1,compoundTag:{floatTag:20.0f,booleanTag:0b}},intArray:[I;1,2,3],alsoIntTag:2"); ReadWriteNBT diff1 = nbt1.extractDifference(nbt2); ReadWriteNBT diff2 = nbt2.extractDifference(nbt1); ``` -------------------------------- ### Correct ItemMeta and NBT Interaction Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Illustrates the correct way to modify both ItemMeta and NBT data on an item stack, emphasizing that ItemMeta changes should be applied after NBT modifications to avoid data loss. It also shows how to safely update ItemMeta within an NBT modification scope. ```java // WRONG, do not do this! ItemMeta meta = itemStack.getItemMeta(); meta.setDisplayName("Modified!"); NBT.modify(itemStack, nbt -> nbt.setBoolean("modified", true)); itemStack.setItemMeta(meta); // Will undo all changes to nbt! // Correct, both ItemMeta and NBT will be applied NBT.modify(itemStack, nbt -> nbt.setBoolean("modified", true)); // Taking ItemMeta snapshot after changes to nbt ItemMeta meta = itemStack.getItemMeta(); meta.setDisplayName("Modified!"); itemStack.setItemMeta(meta); // If making any further changes with NBT & ItemMeta, // re-take the item's ItemMeta after changing the nbt! // Updating ItemMeta using NBT NBT.modify(itemStack, nbt -> { nbt.setInteger("kills", nbt.getOrDefault("kills", 0) + 1); nbt.modifyMeta((readOnlyNbt, meta) -> { // Do not modify the nbt while modifying the meta! meta.setDisplayName("Kills: " + readOnlyNbt.getOrDefault("kills", 0)); }); // Do more stuff }); ``` -------------------------------- ### Read World Data Source: https://github.com/tr7zw/item-nbt-api/wiki/Example-Usages Demonstrates reading Minecraft world data, including the level.dat file for world information and playerdata files for player-specific data. It shows how to access and modify player health. ```java // Get main world's folder File worldDataFolder = Bukkit.getWorlds().getFirst().getWorldFolder(); // Read level data NBTFileHandle levelNbtFile = NBT.getFileHandle(new File(worldDataFolder, "level.dat")); // Obtain world name String worldName = levelNbtFile.resolveOrNull("Data.LevelName", String.class); // Read some player's data UUID playerUuid; File playerFile = new File(worldDataFolder, "playerdata/" + playerUuid + ".dat"); if (!playerFile.exists()) { return; } NBTFileHandle playerNbtFile = NBT.getFileHandle(playerFile); // Change player's health float health = playerNbtFile.getFloat("Health"); playerNbtFile.setFloat("Health", health + 5); // Once finished, save the file playerNbtFile.save(); ``` -------------------------------- ### Entities and Block Entities Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Utilities for saving and restoring NBT data for entities and block entities. ```APIDOC ## Entities and Block Entities ### Description Provides methods to save and restore NBT data associated with entities and block entities. Allows merging NBT data into existing entity NBT structures. ### Methods - `NBT.createNBTObject()`: Creates a new NBT object for entity data. - `NBT.get(Object entity, Consumer consumer)`: Retrieves and allows modification of an entity's NBT data. - `NBT.modify(Object entity, Consumer consumer)`: Modifies an entity's NBT data using a provided consumer. ### Request Example ```java // Saving entity NBT ReadWriteNBT entityNbt = NBT.createNBTObject(); NBT.get(entity, entityNbt::mergeCompound); // Restoring entity NBT NBT.modify(entity, nbt -> { // Optionally filter entityNbt before merging nbt.mergeCompound(entityNbt); }); ``` ``` -------------------------------- ### Data Fixer Utilities Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Utilizes DataFixerUtil to update NBT data between different Minecraft versions. ```APIDOC ## Data Fixer Utilities ### Description `DataFixerUtil` provides functionality to update NBT data from older Minecraft versions to more recent ones, ensuring compatibility. ### Usage Use `DataFixerUtil.fixUpItemData` to convert NBT between specified versions. ### Example Update NBT from version 1.12.2 to 1.20.6: ```java // Assuming 'nbt' is a ReadWriteNBT object containing data from 1.12.2 DataFixerUtil.fixUpItemData(nbt, DataFixerUtil.VERSION1_12_2, DataFixerUtil.VERSION1_20_6); ``` To update to the server's current version, use `DataFixerUtil.getCurrentVersion()`: ```java DataFixerUtil.fixUpItemData(nbt, DataFixerUtil.VERSION1_12_2, DataFixerUtil.getCurrentVersion()); ``` ### Input/Output Example **Input (1.12.2):** `{Count:42,id:"cobblestone",tag:{display:{Name:"test"},ench:[{id:34,lvl:3}]}}` **Output (1.20.6):** `{components:{"minecraft:custom_name":'{"text":"test"}',"minecraft:enchantments":{levels:{"minecraft:unbreaking":3}}},count:42,id:"minecraft:cobblestone"}` ``` -------------------------------- ### Register Custom NBT Handlers in NBTProxy Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to override the init method in an NBTProxy interface to register custom handlers for data types like ItemStacks or ReadableNBT. ```java interface TestInterface extends NBTProxy { @Override default void init() { registerHandler(ItemStack.class, NBTHandlers.ITEM_STACK); registerHandler(ReadableNBT.class, NBTHandlers.STORE_READABLE_TAG); registerHandler(ReadWriteNBT.class, NBTHandlers.STORE_READWRITE_TAG); } ItemStack getItem(); void setItem(ItemStack item); ReadWriteNBT getBlockStateTag(); void setBlockStateTag(ReadableNBT blockState); } ``` -------------------------------- ### Serialize/Deserialize Items with NBT API Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to save and load Minecraft ItemStacks and ItemStack arrays to and from NBT format. It also shows how to convert NBT data to and from strings. ```java // Saving ReadWriteNBT nbt = NBT.itemStackToNBT(itemStack); ReadWriteNBT nbt = NBT.itemStackArrayToNBT(itemStacks); // Restoring ItemStack itemStack = NBT.itemStackFromNBT(nbt); ItemStack[] itemStacks = NBT.itemStackArrayFromNBT(nbt); // Reminder (NBT <-> String) String snbt = nbt.toString(); ReadWriteNBT nbt = NBT.parseNBT(snbt); ``` -------------------------------- ### Resolving Nested NBT Tags in Java Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Demonstrates how to access or create nested NBT tags using a dot-separated path string. It simplifies navigating complex NBT structures and handles keys containing dots by escaping them with a backslash. ```java nbt.resolveOrCreateCompound("foo.bar.baz"); nbt.resolveCompound("foo.some.key.baz"); nbt.resolveOrCreateCompound("foo.bar.baz").setInteger("test", 42); nbt.resolveOrCreateCompound("foo.some\.key.baz").setInteger("other", 123); String s = nbt.resolveOrDefault("foo.bar.Stringtest", "fallback_value"); Integer i = nbt.resolveOrNull("foo\.bar.baz.Inttest", Integer.class); ``` -------------------------------- ### Configure Zombie Attributes (Java) Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Example-Usages.md Configures a zombie entity to pick up loot and sets its attack damage. This code demonstrates modifying vanilla NBT data for entity behavior and custom persistent data using `NBT.modify` and `NBT.modifyPersistentData`. ```java Zombie zombie = location.getWorld().spawn(location, Zombie.class); String attributeName = "minecraft:generic.attack_damage"; // Or generic.attackDamage prior to 1.16 double damageValue = 0.5; // Modify vanilla data NBT.modify(zombie, nbt -> { nbt.setBoolean("CanPickUpLoot", true); ReadWriteNBTCompoundList list = nbt.getCompoundList("Attributes"); // Check if zombie already has attribute set. If so, modify it for (ReadWriteNBT listEntryNbt : list) { if (!listEntryNbt.getString("Name").equals(attributeName)) continue; listEntryNbt.setDouble("Base", damageValue); return; } // Attribute is missing, add it instead ReadWriteNBT listEntryNbt = list.addCompound(); listEntryNbt.setString("Name", attributeName); listEntryNbt.setDouble("Base", damageValue); }); // Modify custom data NBT.modifyPersistentData(zombie, nbt -> { // Let's mark our zombie as a custom one nbt.setBoolean("custom_zombie", true); }); ``` -------------------------------- ### Accessing Vanilla NBT Components (1.20.5+) Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Provides the workaround for accessing and modifying vanilla NBT data (specifically custom_name) via item components for Minecraft versions 1.20.5 and later. ```java // NOTE: This code is only for 1.20.5+! // Only reading vanilla data NBT.getComponents(item, nbt -> { if (nbt.hasTag("minecraft:custom_name")) { String customName = nbt.getString("minecraft:custom_name"); } }); // Modifying vanilla data NBT.modifyComponents(item, nbt -> { nbt.setString("minecraft:custom_name", "{\"extra\":[\"foobar\"],\"text\":\"\"}"); }); ``` -------------------------------- ### Item Serialization/Deserialization Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Methods for saving and restoring ItemStack and ItemStack arrays to/from NBT format, including conversion to and from String. ```APIDOC ## Serialization/Deserialization of Items ### Description Methods for saving and restoring ItemStacks and arrays of ItemStacks to and from NBT format. Includes utilities for converting NBT to String (SNBT) and parsing String back to NBT. ### Methods - `itemStackToNBT(ItemStack itemStack)`: Serializes an ItemStack to NBT. - `itemStackArrayToNBT(ItemStack[] itemStacks)`: Serializes an array of ItemStacks to NBT. - `itemStackFromNBT(ReadWriteNBT nbt)`: Deserializes an ItemStack from NBT. - `itemStackArrayFromNBT(ReadWriteNBT nbt)`: Deserializes an array of ItemStacks from NBT. - `nbt.toString()`: Converts an NBT object to its String representation (SNBT). - `NBT.parseNBT(String snbt)`: Parses a String (SNBT) into an NBT object. ### Request Example ```java // Saving an ItemStack ReadWriteNBT nbt = NBT.itemStackToNBT(itemStack); // Restoring an ItemStack ItemStack restoredItemStack = NBT.itemStackFromNBT(nbt); // Converting NBT to String String snbtString = nbt.toString(); // Parsing String to NBT ReadWriteNBT parsedNbt = NBT.parseNBT(snbtString); ``` ``` -------------------------------- ### Save and Restore Entity NBT Data Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Provides methods for saving entity data to NBT and restoring it. It involves creating an NBT object, merging entity data into it, and then applying the NBT data back to the entity. ```java // Saving ReadWriteNBT entityNbt = NBT.createNBTObject(); NBT.get(entity, entityNbt::mergeCompound); // Restoring NBT.modify(entity, nbt -> { // You might also want to filter out entityNbt first, // e.g. remove some data like location, uuid, entityId, etc. nbt.mergeCompound(entityNbt); }); ``` -------------------------------- ### Item NBT Conversion Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Explains the conversion process between Minecraft objects, NBT format, and SNBT (String NBT). It highlights differences in ItemStack NBT structure between Minecraft versions. ```java For example, when ``NBT.get`` looks like this: `{foo:"bar",points:12,test:1b}` The ItemStack object nbt from ``NBT.itemStackToNBT`` may look like this: `{components:{"minecraft:custom_data":{foo:"bar",points:12,test:1b}},count:2,id:"minecraft:stone"}` Or like this in versions prior to 1.20.5: `{Count:2b,id:"minecraft:stone",tag:{foo:"bar",points:12,test:1b}}` ``` -------------------------------- ### Serialize/Deserialize Game Profiles with NBT API Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Shows how to convert Minecraft GameProfile objects to and from NBT format. This is useful for saving and loading player data or other profile-related information. ```java // Saving ReadWriteNBT nbt = NBT.gameProfileToNBT(profile); // Restoring GameProfile profile = NBT.gameProfileFromNBT(nbt); ``` -------------------------------- ### Resolving Nested NBT Tags in Java Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to access or create nested NBT tags using dot notation for compound separation. It covers resolving compounds, setting values in nested structures, and retrieving values with fallback options, including escaping dots within keys. ```java // For example, the following code: nbt.resolveOrCreateCompound("foo.bar.baz"); // Will get/create the same subtag compound as: nbt.getOrCreateCompound("foo").getOrCreateCompound("bar").getOrCreateCompound("baz"); // Get compound if exists, or null otherwise nbt.resolveCompound("foo.some.key.baz"); // Sets foo/bar/baz/test to 42 nbt.resolveOrCreateCompound("foo.bar.baz").setInteger("test", 42); // Example of a key with a . in it. Sets the key foo/some.key/baz/other to 123 nbt.resolveOrCreateCompound("foo.some\\.key.baz").setInteger("other", 123); // Similarly, you may also fetch values from nested compounds String s = nbt.resolveOrDefault("foo.bar.Stringtest", "fallback_value"); Integer i = nbt.resolveOrNull("foo\\.bar.baz.Inttest", Integer.class); ``` -------------------------------- ### NBT to String (SNBT) Conversion and Parsing in Java Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Illustrates the process of converting a String representation of NBT (SNBT) into a NBT object and then converting a NBT object back into its SNBT string format. This is useful for serialization and deserialization of NBT data. ```java ReadWriteNBT nbt = NBT.parseNBT("{Health:20.0f,Motion:[0.0d,10.0d,0.0d],Silent:1b}"); String snbt = nbt.toString(); ReadWriteNBT nbt2 = NBT.parseNBT(snbt); ``` -------------------------------- ### Handling Vanilla Item NBT on 1.20.5+ Source: https://github.com/tr7zw/item-nbt-api/wiki/Using-the-NBT-API Provides a workaround for accessing and modifying vanilla NBT data (specifically custom_name) on Minecraft versions 1.20.5 and later, as ItemStacks only access the 'custom_data' component directly. This involves using NBT.getComponents and NBT.modifyComponents. ```java // NOTE: This code is only for 1.20.5+! // Only reading vanilla data NBT.getComponents(item, nbt -> { if (nbt.hasTag("minecraft:custom_name")) { String customName = nbt.getString("minecraft:custom_name"); } }); // Modifying vanilla data NBT.modifyComponents(item, nbt -> { nbt.setString("minecraft:custom_name", "{\"extra\":[\"foobar\"],\"text\":\"\"}"); }); ``` -------------------------------- ### Accessing and Modifying Entity/Block Entity NBT Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Demonstrates how to read and modify NBT data for entities and block entities, similar to how it's done for items. ```java // Obtain data boolean silent = NBT.get(entity, nbt -> (boolean) nbt.getBoolean("Silent")); // Modify data NBT.modify(entity, nbt -> { nbt.setBoolean("Silent", true); nbt.setByte("CanPickUpLoot", (byte) 1); }); ``` -------------------------------- ### NBT to String Conversion and Parsing in Java Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Using-the-NBT-API.md Illustrates how to convert an NBT object into a String representation (SNBT) and then parse that String back into an NBT object. This is useful for serialization and deserialization of NBT data. ```java // Parse SNBT to nbt ReadWriteNBT nbt = NBT.parseNBT("{Health:20.0f,Motion:[0.0d,10.0d,0.0d],Silent:1b}"); // Get the NBT back as a SNBT (works with any NBT object) String snbt = nbt.toString(); // Turn back into nbt again ReadWriteNBT nbt2 = NBT.parseNBT(snbt); ``` -------------------------------- ### Set Skull Skin (Java) Source: https://github.com/tr7zw/item-nbt-api/blob/master/wiki/Example-Usages.md Applies a custom skin to a Minecraft player head item. Supports different Minecraft versions for item creation and NBT application, including a workaround for newer versions (1.20.5+). It uses `NBT.modify` or `NBT.modifyComponents` for NBT manipulation. ```java final String textureValue = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTQyY2M5MjAzYzkwYjE5YmRhYzFkZjI4NDE2NzI2NmI5NTNkZmViZjNjNDY5MGE3Y2QwYjE1NzkxYTYyZTU4MiJ9fX0="; // For Minecraft 1.12.2 and below final ItemStack item = new ItemStack(Material.SKULL_ITEM); item.setDurability((short) 3); // For Minecraft 1.13 and newer final ItemStack item = new ItemStack(Material.PLAYER_HEAD); // Applying nbt // For Minecraft 1.20.4 and below NBT.modify(item, nbt -> { ReadWriteNBT skullOwnerCompound = nbt.getOrCreateCompound("SkullOwner"); skullOwnerCompound.setUUID("Id", UUID.randomUUID()); skullOwnerCompound.getOrCreateCompound("Properties") .getCompoundList("textures") .addCompound() .setString("Value", textureValue); }); // Workaround for Minecraft 1.20.5+ NBT.modifyComponents(item, nbt -> { ReadWriteNBT profileNbt = nbt.getOrCreateCompound("minecraft:profile"); profileNbt.setUUID("id", uuid); ReadWriteNBT propertiesNbt = profileNbt.getCompoundList("properties").addCompound(); propertiesNbt.setString("name", "textures"); propertiesNbt.setString("value", textureValue); }); ``` ```java SkullMeta meta = (SkullMeta) item.getItemMeta(); PlayerProfile playerProfile = Bukkit.createProfile(uuid); playerProfile.setProperty(new ProfileProperty("textures", textureValue)); meta.setPlayerProfile(playerProfile); item.setItemMeta(meta); ```