Compare commits

...
57 Commits
Author SHA1 Message Date
tr7zw 5bdddc134a Release 2.16.1 2026-09-17 20:06:29 +02:00
tr7zw 733b871c09 Merge pull request #359 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.16.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.15.0 to 3.16.0
2026-09-17 20:04:44 +02:00
tr7zw bc48239fdd Start 2.16.1-SNAPSHOT 2026-09-16 18:52:12 +02:00
tr7zw f182204b2f Merge pull request #360 from NriotHrreion/fix/paper-26.3-as-bukkit-mirror
Add Minecraft 26.3 item stack compatibility
2026-09-16 18:51:06 +02:00
NriotHrreion a424ce1e85 Add Minecraft 26.3 item stack compatibility 2026-09-16 14:44:15 +08:00
dependabot[bot] c881566c14 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.15.0 to 3.16.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.15.0...maven-compiler-plugin-3.16.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-version: 3.16.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-02 23:12:40 +00:00
tr7zw 2d6aa142de Bump version 2.16.0 2026-07-27 18:21:45 +02:00
tr7zw cc1436cd09 Merge pull request #353 from SoSeDiK/blocks
Migrate NBTBlock & NBTChunk to NBT
2026-07-27 18:12:50 +02:00
tr7zw 4506dd37da Remove setClosed calls
They do nothing in this case
2026-07-27 18:09:51 +02:00
tr7zw bbc02e1299 Merge pull request #356 from EverNife/master
Fix 'GET_LIST' and 'OWN_TYPE' to their 'LEGACY' sufixed name on Forge at 1.7.10
2026-07-24 21:28:43 +02:00
Petrus Pradella ca9d5ad140 Fix 'GET_LIST' and 'OWN_TYPE' to thier 'LEGACY' sufixed name on Forge at Minecraft 1.7.10 2026-07-13 03:04:12 -03:00
tr7zw 25c82a5ad0 Merge pull request #354 from SoSeDiK/badges
Update readme badges
2026-07-08 20:06:33 +02:00
tr7zw 17d40445d2 Remove ko-fi 2026-07-08 20:06:04 +02:00
SoSeDiK 47ad3591df Migrate NBTBlock & NBTChunk to NBT 2026-06-26 22:35:25 +03:00
SoSeDiK b3652ecf7d Update readme badges 2026-06-26 12:55:36 +03:00
tr7zw 46a9116613 Start 2.15.8-SNAPSHOT, add 26.2 support 2026-06-16 20:02:53 +02:00
tr7zw 5776be4a35 Add support for 26.1.x, paper 26.1.x support, bump version 2026-04-06 16:07:15 +02:00
tr7zw 9fbee68966 Release 2.15.6 2026-03-28 17:05:22 +01:00
tr7zw b277f0b01d Update the DataVersion when upgrading Item NBT 2026-03-28 16:59:38 +01:00
tr7zw e4793a0d46 Merge pull request #348 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.6.2
Bump org.apache.maven.plugins:maven-shade-plugin from 3.6.1 to 3.6.2
2026-03-28 16:11:44 +01:00
tr7zw 7c34542b86 Add 26.1 2026-03-28 16:08:13 +01:00
dependabot[bot] 856bf5ed6d Bump org.apache.maven.plugins:maven-shade-plugin from 3.6.1 to 3.6.2
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.6.1 to 3.6.2.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.6.1...maven-shade-plugin-3.6.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-version: 3.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 23:17:37 +00:00
tr7zw 123da87a3a Merge pull request #341 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.7.1
Bump org.codehaus.mojo:license-maven-plugin from 2.7.0 to 2.7.1
2026-03-05 21:45:13 +01:00
tr7zw f3d7545c6b Merge pull request #344 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.15.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.1 to 3.15.0
2026-03-05 21:45:02 +01:00
tr7zw 3b29fe399e Merge pull request #347 from tr7zw/dependabot/maven/org.bstats-bstats-bukkit-3.2.1
Bump org.bstats:bstats-bukkit from 3.1.0 to 3.2.1
2026-03-05 21:44:50 +01:00
tr7zw c368318bb6 Start 2.15.6-SNAPSHOT 2026-03-05 21:44:05 +01:00
dependabot[bot] c1473dfa97 Bump org.bstats:bstats-bukkit from 3.1.0 to 3.2.1
Bumps [org.bstats:bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.1.0 to 3.2.1.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.1.0...v3.2.1)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-version: 3.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-24 23:13:02 +00:00
dependabot[bot] a360ca50f4 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.1 to 3.15.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.14.1...maven-compiler-plugin-3.15.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-version: 3.15.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-03 04:12:03 +00:00
dependabot[bot] 8b1ca8447e Bump org.codehaus.mojo:license-maven-plugin from 2.7.0 to 2.7.1
Bumps [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.7.0...2.7.1)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-version: 2.7.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-05 23:02:18 +00:00
tr7zw b66353d0d0 Release 2.15.5 2025-12-09 20:19:44 +01:00
tr7zw 5bec1371d2 Add missing line so the api doesn't complain 2025-12-09 19:11:20 +01:00
tr7zw 8cbb6af964 Start 2.15.5-SNAPSHOT 2025-12-09 19:09:48 +01:00
tr7zw 309455ecfc Merge branch 'master' of https://github.com/tr7zw/Item-NBT-API 2025-12-09 18:44:38 +01:00
tr7zw 22c0b0385b Release 2.15.4 2025-12-09 18:44:30 +01:00
tr7zw bc6bd56ce9 Merge pull request #339 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.4.0
Bump org.apache.maven.plugins:maven-source-plugin from 3.3.1 to 3.4.0
2025-12-09 18:43:18 +01:00
tr7zw fcdf0929f9 Add 1.21.11 support 2025-12-09 18:37:52 +01:00
tr7zw e1c6ce2575 Start 2.15.4-SNAPSHOT 2025-12-09 18:36:41 +01:00
dependabot[bot] 2fcc1d82ab Bump org.apache.maven.plugins:maven-source-plugin from 3.3.1 to 3.4.0
Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.1 to 3.4.0.
- [Release notes](https://github.com/apache/maven-source-plugin/releases)
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.1...maven-source-plugin-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-source-plugin
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-02 02:01:29 +00:00
tr7zw eec2c0980e tag 2.15.3 2025-10-11 17:05:48 +02:00
tr7zw 3ddf3e53dc Add 1.21.10 support 2025-10-04 20:09:20 +02:00
tr7zw 70d5ab12eb Add 1.21.9 spigot support 2025-09-30 19:25:28 +02:00
tr7zw a63e9ba8f4 Add 1.21.9 Paper support, Fix Gameprofile reading/writing 2025-09-30 19:14:54 +02:00
tr7zw d8a59d6383 Merge pull request #335 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.6.1
Bump org.apache.maven.plugins:maven-shade-plugin from 3.6.0 to 3.6.1
2025-09-28 11:53:27 +02:00
tr7zw 943c7d23d6 Merge pull request #336 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.7.0
Bump org.codehaus.mojo:license-maven-plugin from 2.6.0 to 2.7.0
2025-09-28 11:53:18 +02:00
tr7zw 6c70ce2ccc Merge pull request #337 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.14.1
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1
2025-09-28 11:53:09 +02:00
tr7zw c1b7854fbb Merge pull request #338 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.12.0
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0
2025-09-28 11:52:59 +02:00
tr7zw f9f1c204b6 Start 2.15.3-SNAPSHOT 2025-09-28 11:52:38 +02:00
dependabot[bot] 789f1fea96 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.3 to 3.12.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.3...maven-javadoc-plugin-3.12.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-version: 3.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 23:02:47 +00:00
dependabot[bot] 0e40144f09 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.0 to 3.14.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.14.0...maven-compiler-plugin-3.14.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-version: 3.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 23:02:10 +00:00
dependabot[bot] 1c6315e014 Bump org.codehaus.mojo:license-maven-plugin from 2.6.0 to 2.7.0
Bumps [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.6.0 to 2.7.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.6.0...2.7.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-version: 2.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 23:02:05 +00:00
dependabot[bot] 91f345adf2 Bump org.apache.maven.plugins:maven-shade-plugin from 3.6.0 to 3.6.1
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.6.0 to 3.6.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.6.0...v3.6.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-version: 3.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 23:09:04 +00:00
tr7zw 71783a8dc9 Release 2.15.2 2025-08-26 21:59:51 +02:00
tr7zw 5d06ae9275 Fix version variables in DataFixerUtil 2025-08-26 21:51:54 +02:00
tr7zw 835fdf48cd Fix codec mapping issue in 1.21.5. Fix #332 2025-08-26 21:35:36 +02:00
tr7zw 31d77d25f9 Merge pull request #333 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.11.3
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3
2025-08-20 21:55:57 +02:00
dependabot[bot] 6cb08ac919 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.2 to 3.11.3.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.2...maven-javadoc-plugin-3.11.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-version: 3.11.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-19 10:47:34 +00:00
tr7zw 08a92ac06c 2.15.2-SNAPSHOT, add 1.21.8 2025-07-17 20:29:51 +02:00
25 changed files with 665 additions and 119 deletions

No files matched your search

+3 -2
View File
@@ -1,13 +1,14 @@
# Item-NBT-API
[![Modrinth](https://img.shields.io/modrinth/dt/nbtapi?logo=modrinth&label=Modrinth%20downloads)](https://modrinth.com/plugin/nbtapi)
[![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM)
Add custom NBT tags to Items/Tiles/Entities without NMS! Modify NBT and store it in Files, other NBT, or as String in yaml/json/SQL/Redis.
[Server Owner/Developer Wiki](https://github.com/tr7zw/Item-NBT-API/wiki)
### Build/Maven/Sonar Status
[![Build Status](https://ci.codemc.org/buildStatus/icon?job=Tr7zw%2FItem-NBT-API)](https://ci.codemc.org/job/Tr7zw/job/Item-NBT-API/)[![](https://sonarcloud.io/api/project_badges/measure?project=tr7zw_Item-NBT-API&metric=ncloc)](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)[![](https://sonarcloud.io/api/project_badges/measure?project=tr7zw_Item-NBT-API&metric=duplicated_lines_density)](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)[![](https://sonarcloud.io/api/project_badges/measure?project=tr7zw_Item-NBT-API&metric=sqale_rating)](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)
[![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM)
[![Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dtr7zw%26type%3Dpatrons&style=for-the-badge)](https://www.patreon.com/tr7zw)
### SpigotMC Status
+3 -3
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</parent>
<artifactId>item-nbt-api</artifactId>
@@ -21,7 +21,7 @@
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.1.0</version>
<version>3.2.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -38,7 +38,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
<configuration>
<relocations>
<relocation>
@@ -9,6 +9,9 @@ import java.util.logging.Level;
import javax.annotation.Nullable;
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
import org.bukkit.Chunk;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
@@ -727,4 +730,204 @@ public class NBT {
return val;
}
/**
* Reads block‑specific data that was previously stored in the chunk's
* persistent data container.
* <p>
* The data is stored inside the {@code blocks} compound of the chunk's
* persistent data container, using a key formed as {@code X_Y_Z} where
* X, Y, Z are the block's coordinates.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param block the block whose stored data is to be read
* @param consumer the consumer that receives a {@link ReadableNBT} view of the data
*/
public static void readChunkPDC(Block block, Consumer<ReadableNBT> consumer) {
processBlockChunkPDC(block, false, nbt -> {
consumer.accept(nbt);
return null;
});
}
/**
* Reads block‑specific data from the chunk's persistent data container and
* applies a function to produce a result.
* <p>
* The data is stored inside the {@code blocks} compound of the chunk's
* persistent data container, using a key formed as {@code X_Y_Z} where
* X, Y, Z are the block's coordinates.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param block the block whose stored data is to be read
* @param function the function that processes the {@link ReadableNBT} and
* returns a value
* @param <T> the type of the returned value
* @return the result of the function applied to the data
*/
public static <T> T readAndGetChunkPDC(Block block, Function<ReadableNBT, T> function) {
return processBlockChunkPDC(block, false, function::apply);
}
/**
* Modifies block‑specific data stored in the chunk's persistent data container.
* <p>
* The data is stored inside the {@code blocks} compound of the chunk's
* persistent data container, using a key formed as {@code X_Y_Z} where
* X, Y, Z are the block's coordinates.
* <p>
* <b>Caution:</b> the data remains even if the block is broken, replaced, moved,
* or exploded, etc. You should manually remove the data when it is no longer needed.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param block the block whose data is to be modified
* @param consumer the consumer that receives the {@link ReadWriteNBT} and
* applies modifications
*/
public static void modifyChunkPDC(Block block, Consumer<ReadWriteNBT> consumer) {
processBlockChunkPDC(block, true, nbt -> {
consumer.accept(nbt);
return null;
});
}
/**
* Modifies block‑specific data in the chunk's persistent data container and
* returns a result computed from the modified data.
* <p>
* The data is stored inside the {@code blocks} compound of the chunk's
* persistent data container, using a key formed as {@code X_Y_Z} where
* X, Y, Z are the block's coordinates.
* <p>
* <b>Caution:</b> the data remains even if the block is broken, replaced, moved,
* or exploded, etc. You should manually remove the data when it is no longer needed.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param block the block whose data is to be modified
* @param function the function that receives the {@link ReadWriteNBT}, modifies
* it, and returns a value
* @param <T> the type of the returned value
* @return the result of the function after modification
*/
public static <T> T modifyAndGetChunkPDC(Block block, Function<ReadWriteNBT, T> function) {
return processBlockChunkPDC(block, true, function::apply);
}
private static <T> T processBlockChunkPDC(Block block, boolean createIfAbsent, Function<NBTCompound, T> action) {
CheckUtil.assertAvailable(MinecraftVersion.MC1_16_R3);
String blockKey = block.getX() + "_" + block.getY() + "_" + block.getZ();
NBTCompound chunkData = new NBTPersistentDataContainer(block.getChunk().getPersistentDataContainer(), !createIfAbsent);
NBTCompound blocksData = createIfAbsent
? chunkData.getOrCreateCompound("blocks")
: chunkData.getCompound("blocks");
NBTCompound blockData;
if (createIfAbsent) {
blockData = blocksData.getOrCreateCompound(blockKey);
} else {
blockData = blocksData == null ? null : blocksData.getCompound(blockKey);
if (blockData == null) {
blockData = new NBTContainer().setReadOnly(true);
}
}
T result = action.apply(blockData);
if (createIfAbsent) {
if (blockData.isEmpty()) {
blocksData.removeKey(blockKey);
}
if (blocksData.isEmpty()) {
chunkData.removeKey("blocks");
}
}
if (result instanceof ReadableNBT || result instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
return result;
}
/**
* Reads the chunk's persistent data container.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param chunk the chunk whose persistent data is to be read
* @param consumer the consumer that receives a {@link ReadableNBT} view of the data
*/
public static void readChunkPDC(Chunk chunk, Consumer<ReadableNBT> consumer) {
processChunkPDC(chunk, false, nbt -> {
consumer.accept(nbt);
return null;
});
}
/**
* Reads the chunk's persistent data container and applies a function to produce a result.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param chunk the chunk whose persistent data is to be read
* @param function the function that processes the {@link ReadableNBT} and
* returns a value
* @param <T> the type of the returned value
* @return the result of the function applied to the data
*/
public static <T> T readAndGetChunkPDC(Chunk chunk, Function<ReadableNBT, T> function) {
return processChunkPDC(chunk, false, function::apply);
}
/**
* Modifies the chunk's persistent data container.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param chunk the chunk whose persistent data is to be modified
* @param consumer the consumer that receives the {@link ReadWriteNBT} and
* applies modifications
*/
public static void modifyChunkPDC(Chunk chunk, Consumer<ReadWriteNBT> consumer) {
processChunkPDC(chunk, true, nbt -> {
consumer.accept(nbt);
return null;
});
}
/**
* Modifies the chunk's persistent data container and returns a result computed from the modified data.
* <p>
* <b>Minecraft version:</b> this method requires <b>1.16.4 or newer</b>.
*
* @param chunk the chunk whose persistent data is to be modified
* @param function the function that receives the {@link ReadWriteNBT}, modifies
* it, and returns a value
* @param <T> the type of the returned value
* @return the result of the function after modification
*/
public static <T> T modifyAndGetChunkPDC(Chunk chunk, Function<ReadWriteNBT, T> function) {
return processChunkPDC(chunk, true, function::apply);
}
private static <T> T processChunkPDC(Chunk chunk, boolean createIfAbsent, Function<NBTCompound, T> action) {
CheckUtil.assertAvailable(MinecraftVersion.MC1_16_R3);
NBTCompound chunkData = new NBTPersistentDataContainer(chunk.getPersistentDataContainer(), !createIfAbsent);
T result = action.apply(chunkData);
if (result instanceof ReadableNBT || result instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
return result;
}
}
@@ -7,16 +7,17 @@ import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
/**
* Helper class to store NBT data to Block Locations. Use getData() to get the
* NBT instance. Important notes:
*
* <p>
* - Non BlockEntities can not have NBT data. This stores the data to the chunk
* instead!
*
* <p>
* - The data is really just on the location. If the block gets
* broken/changed/exploded/moved etc., the data is still on that location!
*
* @author tr7zw
*
* @deprecated use methods in {@link NBT} class to read/modify block's NBT
*/
@Deprecated
public class NBTBlock {
private final Block block;
@@ -30,6 +31,13 @@ public class NBTBlock {
nbtChunk = new NBTChunk(block.getChunk());
}
/**
* Gets the block NBT data stored within the chunk's PDC.
*
* @return block NBT data
* @deprecated use methods in {@link NBT} class to read/modify block's NBT
*/
@Deprecated
public NBTCompound getData() {
return nbtChunk.getPersistentDataContainer().getOrCreateCompound("blocks")
.getOrCreateCompound(block.getX() + "_" + block.getY() + "_" + block.getZ());
@@ -5,6 +5,12 @@ import org.bukkit.Chunk;
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
/**
* Helper class to store NBT data to {@link Chunk}'s PDC (persistent data container).
*
* @deprecated use methods in {@link NBT} class to read/modify chunk's nbt
*/
@Deprecated
public class NBTChunk {
private final Chunk chunk;
@@ -11,7 +11,11 @@ public class NBTPersistentDataContainer extends NBTCompound {
private final PersistentDataContainer container;
public NBTPersistentDataContainer(PersistentDataContainer container) {
super(null, null);
this(container, false);
}
protected NBTPersistentDataContainer(PersistentDataContainer container, boolean readOnly) {
super(null, null, readOnly);
this.container = container;
}
@@ -174,6 +174,15 @@ public interface ReadableNBT {
*/
Set<String> getKeys();
/**
* Checks whether this NBT is empty (has no stored data).
*
* @return whether this NBT is empty
*/
default boolean isEmpty() {
return getKeys().isEmpty();
}
/**
* @param name
* @return The Compound instance or null
@@ -274,7 +283,7 @@ public interface ReadableNBT {
* {@code Boolean, Byte, Short, Integer, Long, Float, Double, byte[], int[], long[]},
* {@link String}, {@link UUID}, and {@link Enum}
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz". Dots can
* @param key Path key, separated by '.'. For example: "foo.bar.baz". Dots can
* be escaped with a backslash.
* @param type data type
* @param <T> value type
@@ -290,7 +299,7 @@ public interface ReadableNBT {
* {@code Boolean, Byte, Short, Integer, Long, Float, Double, byte[], int[], long[]},
* {@link String}, {@link UUID}, and {@link Enum}
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz".
* @param key Path key, separated by '.'. For example: "foo.bar.baz".
* Dots can be escaped with a backslash.
* @param defaultValue default non-null value
* @param <T> value type
@@ -302,7 +311,7 @@ public interface ReadableNBT {
* Returns the resolved Compound if exists, or null.
* <p>
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz". Dots can
* @param key Path key, separated by '.'. For example: "foo.bar.baz". Dots can
* be escaped with a backslash.
* @return The resolved value if exists, or null.
*/
@@ -15,23 +15,58 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class DataFixerUtil {
// these values can be found in DetectedVersion inside mc
// Finding pre 1.12.2 values is left as an exercise for the reader,
// as DetectedVersion is not a thing there
// https://minecraft.wiki/w/Data_version
public static final int VERSION1_12R1 = 1343;
public static final int VERSION1_16R1 = 2586;
public static final int VERSION1_17R1 = 2730;
public static final int VERSION1_18R1 = 2975;
public static final int VERSION1_19R1 = 3120;
public static final int VERSION1_19R3 = 3337;
public static final int VERSION1_20R1 = 3465;
public static final int VERSION1_20R2 = 3578;
public static final int VERSION1_20R3 = 3700;
public static final int VERSION1_20R4 = 3837;
public static final int VERSION1_21R1 = 3953;
public static final int VERSION1_21R2 = 4080;
public static final int VERSION1_21R3 = 4189;
public static final int VERSION1_21R4 = 4323;
public static final int VERSION1_21R5 = 4435;
public static final int VERSION1_21R6 = 4554;
public static final int VERSION1_21R7 = 4671;
public static final int VERSION_26_1 = 4786;
public static final int VERSION_26_2 = 4903;
public static final int VERSION_26_3 = 5023;
// There was a mixup between version numbers and revisions, kept for compatibility, use the above revision numbers
@Deprecated
public static final int VERSION1_12_2 = 1343;
@Deprecated
public static final int VERSION1_16_5 = 2586;
@Deprecated
public static final int VERSION1_17_1 = 2730;
@Deprecated
public static final int VERSION1_18_2 = 2975;
@Deprecated
public static final int VERSION1_19_2 = 3120;
@Deprecated
public static final int VERSION1_19_4 = 3337;
@Deprecated
public static final int VERSION1_20_1 = 3465;
@Deprecated
public static final int VERSION1_20_2 = 3578;
@Deprecated
public static final int VERSION1_20_4 = 3700;
@Deprecated
public static final int VERSION1_20_5 = 3837;
// the 1.21 versions use Revision instead of patch versions, unlike the other above. kept for compatibility
@Deprecated
public static final int VERSION1_21 = 3953;
@Deprecated
public static final int VERSION1_21_2 = 4080;
@Deprecated
public static final int VERSION1_21_3 = 4189;
@Deprecated
public static final int VERSION1_21_4 = 4323;
@Deprecated
public static final int VERSION1_21_5 = 4435;
@SuppressWarnings("unchecked")
@@ -47,9 +82,16 @@ public class DataFixerUtil {
public static ReadWriteNBT fixUpItemData(ReadWriteNBT nbt, int fromVersion, int toVersion)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
return NBT.wrapNMSTag(fixUpRawItemData(
ReadWriteNBT tag = NBT.wrapNMSTag(fixUpRawItemData(
NBTReflectionUtil.getToCompount(((NBTCompound) nbt).getCompound(), ((NBTCompound) nbt)), fromVersion,
toVersion));
tag.setInteger("DataVersion", toVersion);
return tag;
}
public static ReadWriteNBT fixUpItemData(ReadWriteNBT nbt, int fromVersion)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
return fixUpItemData(nbt, fromVersion, getCurrentVersion());
}
/**
@@ -62,34 +104,44 @@ public class DataFixerUtil {
* @return
*/
public static int getCurrentVersion() {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R5)) {
return VERSION1_21_5;
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC26_3)) {
return VERSION_26_3;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC26_2)) {
return VERSION_26_2;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC26_1)) {
return VERSION_26_1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R7)) {
return VERSION1_21R7;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
return VERSION1_21R6;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R5)) {
return VERSION1_21R5;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
return VERSION1_21_4;
return VERSION1_21R4;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R3)) {
return VERSION1_21_3;
return VERSION1_21R3;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R2)) {
return VERSION1_21_2;
return VERSION1_21R2;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R1)) {
return VERSION1_21;
return VERSION1_21R1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
return VERSION1_20_5;
return VERSION1_20R4;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R3)) {
return VERSION1_20_4;
return VERSION1_20R3;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R1)) {
return VERSION1_20_1;
return VERSION1_20R1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_19_R3)) {
return VERSION1_19_4;
return VERSION1_19R3;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_19_R1)) {
return VERSION1_19_2;
return VERSION1_19R1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1)) {
return VERSION1_18_2;
return VERSION1_18R1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
return VERSION1_17_1;
return VERSION1_17R1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) {
return VERSION1_16_5;
return VERSION1_16R1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_12_R1)) {
return VERSION1_12_2;
return VERSION1_12R1;
}
throw new NbtApiException(
"Trying to update data *to* a version before 1.12.2? Something is probably going wrong, contact the plugin author.");
@@ -1,12 +1,16 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
import javax.annotation.Nullable;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.PropertyMap;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
@@ -14,15 +18,42 @@ import de.tr7zw.changeme.nbtapi.iface.ReadableNBTList;
public class GameprofileUtil {
private static Method GET_NAME = null;
private static Method GET_ID = null;
private static Method GET_VALUE = null;
private static Method GET_SIGNATURE = null;
private static Method GET_PROPERTY_NAME = null;
private static Method GET_PROPERTIES = null;
static {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
GET_NAME = GameProfile.class.getDeclaredMethod("name");
GET_ID = GameProfile.class.getDeclaredMethod("id");
GET_VALUE = com.mojang.authlib.properties.Property.class.getDeclaredMethod("value");
GET_SIGNATURE = com.mojang.authlib.properties.Property.class.getDeclaredMethod("signature");
GET_PROPERTY_NAME = com.mojang.authlib.properties.Property.class.getDeclaredMethod("name");
GET_PROPERTIES = GameProfile.class.getDeclaredMethod("properties");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
@Nullable
public static GameProfile readGameProfile(ReadableNBT arg) {
String string = null;
UUID uUID = null;
if (arg.hasTag("Name") && arg.getType("Name") == NBTType.NBTTagString) {
string = arg.getString("Name");
} else if (arg.hasTag("name") && arg.getType("name") == NBTType.NBTTagString) {
string = arg.getString("name");
}
if (arg.hasTag("Id") && arg.getType("Id") == NBTType.NBTTagIntArray && arg.getIntArray("Id").length == 4) {
uUID = arg.getUUID("Id");
} else if (arg.hasTag("id") && arg.getType("id") == NBTType.NBTTagIntArray
&& arg.getIntArray("id").length == 4) {
uUID = arg.getUUID("id");
}
try {
GameProfile gameProfile = new GameProfile(uUID, string);
@@ -43,6 +74,21 @@ public class GameprofileUtil {
}
}
}
} else if (arg.getType("properties") == NBTType.NBTTagList) { // 1.20.5+
ReadableNBTList<ReadWriteNBT> listTag = arg.getCompoundList("properties");
for (int i = 0; i < listTag.size(); ++i) {
ReadableNBT compoundTag2 = listTag.get(i);
String string2 = compoundTag2.getString("name");
String string3 = compoundTag2.getString("value");
if (compoundTag2.hasTag("signature")
&& compoundTag2.getType("signature") == NBTType.NBTTagString) {
gameProfile.getProperties().put(string2, new com.mojang.authlib.properties.Property(string2,
string3, compoundTag2.getString("signature")));
} else {
gameProfile.getProperties().put(string2,
new com.mojang.authlib.properties.Property(string2, string3));
}
}
}
return gameProfile;
} catch (Throwable var11) {
@@ -51,26 +97,115 @@ public class GameprofileUtil {
}
public static ReadWriteNBT writeGameProfile(ReadWriteNBT arg, GameProfile gameProfile) {
if (!(gameProfile.getName() == null || gameProfile.getName().isEmpty())) {
arg.setString("Name", gameProfile.getName());
String name = getName(gameProfile);
if (!(name == null || name.isEmpty())) {
String nameKey = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4) ? "name" : "Name";
arg.setString(nameKey, getName(gameProfile));
}
if (gameProfile.getId() != null) {
arg.setUUID("Id", gameProfile.getId());
UUID id = getId(gameProfile);
if (id != null) {
String idKey = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4) ? "id" : "Id";
arg.setUUID(idKey, id);
}
if (!gameProfile.getProperties().isEmpty()) {
ReadWriteNBT compoundTag = arg.getOrCreateCompound("Properties");
for (String string : gameProfile.getProperties().keySet()) {
ReadWriteNBTCompoundList list = compoundTag.getCompoundList(string);
for (com.mojang.authlib.properties.Property property : gameProfile.getProperties().get(string)) {
ReadWriteNBT tag = list.addCompound();
tag.setString("Value", property.getValue());
if (property.hasSignature()) {
tag.setString("Signature", property.getSignature());
PropertyMap properties = getProperties(gameProfile);
if (!properties.isEmpty()) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
ReadWriteNBTCompoundList list = arg.getCompoundList("properties");
for (com.mojang.authlib.properties.Property property : properties.values()) {
ReadWriteNBT tag = list.addCompound();
tag.setString("name", getPropertyName(property));
tag.setString("value", getValue(property));
if (property.hasSignature()) {
tag.setString("signature", getSignature(property));
}
}
} else {
ReadWriteNBT compoundTag = arg.getOrCreateCompound("Properties");
for (String string : gameProfile.getProperties().keySet()) {
ReadWriteNBTCompoundList list = compoundTag.getCompoundList(string);
for (com.mojang.authlib.properties.Property property : properties.get(string)) {
ReadWriteNBT tag = list.addCompound();
tag.setString("Value", getValue(property));
if (property.hasSignature()) {
tag.setString("Signature", getSignature(property));
}
}
}
}
}
return arg;
}
private static String getName(GameProfile profile) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
return GET_NAME.invoke(profile).toString();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Failed to get GameProfile name via reflection", e);
}
} else {
return profile.getName();
}
}
private static UUID getId(GameProfile profile) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
return (UUID) GET_ID.invoke(profile);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Failed to get GameProfile id via reflection", e);
}
} else {
return profile.getId();
}
}
private static String getValue(com.mojang.authlib.properties.Property property) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
return GET_VALUE.invoke(property).toString();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Failed to get Property value via reflection", e);
}
} else {
return property.getValue();
}
}
private static String getSignature(com.mojang.authlib.properties.Property property) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
return GET_SIGNATURE.invoke(property).toString();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Failed to get Property signature via reflection", e);
}
} else {
return property.getSignature();
}
}
private static String getPropertyName(com.mojang.authlib.properties.Property property) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
return GET_PROPERTY_NAME.invoke(property).toString();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Failed to get Property name via reflection", e);
}
} else {
return property.getName();
}
}
private static PropertyMap getProperties(GameProfile profile) {
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R6)) {
try {
return (PropertyMap) GET_PROPERTIES.invoke(profile);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Failed to get GameProfile properties via reflection", e);
}
} else {
return profile.getProperties();
}
}
}
@@ -2,6 +2,7 @@ package de.tr7zw.changeme.nbtapi.utils;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -31,7 +32,8 @@ public enum MinecraftVersion {
MC1_16_R3(1163), MC1_17_R1(1171), MC1_18_R1(1181, true), MC1_18_R2(1182, true), MC1_19_R1(1191, true),
MC1_19_R2(1192, true), MC1_19_R3(1193, true), MC1_20_R1(1201, true), MC1_20_R2(1202, true), MC1_20_R3(1203, true),
MC1_20_R4(1204, true), MC1_21_R1(1211, true), MC1_21_R2(1212, true), MC1_21_R3(1213, true), MC1_21_R4(1214, true),
MC1_21_R5(1215, true);
MC1_21_R5(1215, true), MC1_21_R6(1216, true), MC1_21_R7(1217, true), MC26_1(260100, true), MC26_2(260200, true),
MC26_3(260300, true);
private static MinecraftVersion version;
private static Boolean hasGsonSupport;
@@ -48,13 +50,12 @@ public enum MinecraftVersion {
private static Logger logger = Logger.getLogger("NBTAPI");
// NBT-API Version
protected static final String VERSION = "2.15.1";
protected static final String VERSION = "2.16.1";
private final int versionId;
private final boolean mojangMapping;
// TODO: not nice
@SuppressWarnings("serial")
private static final Map<String, MinecraftVersion> VERSION_TO_REVISION = new HashMap<String, MinecraftVersion>() {
{
this.put("1.20", MC1_20_R1);
@@ -72,6 +73,13 @@ public enum MinecraftVersion {
this.put("1.21.5", MC1_21_R4);
this.put("1.21.6", MC1_21_R5);
this.put("1.21.7", MC1_21_R5);
this.put("1.21.8", MC1_21_R5);
this.put("1.21.9", MC1_21_R6);
this.put("1.21.10", MC1_21_R6);
this.put("1.21.11", MC1_21_R7);
this.put("26.1", MC26_1);
this.put("26.2", MC26_2);
this.put("26.3", MC26_3);
}
};
@@ -153,8 +161,22 @@ public enum MinecraftVersion {
} catch (Exception ex) {
logger.info("[NBTAPI] Found Minecraft: " + Bukkit.getServer().getBukkitVersion().split("-")[0]
+ "! Trying to find NMS support");
version = VERSION_TO_REVISION.getOrDefault(Bukkit.getServer().getBukkitVersion().split("-")[0],
MinecraftVersion.UNKNOWN);
version = VERSION_TO_REVISION.get(Bukkit.getServer().getBukkitVersion().split("-")[0]);
if (version == null) {
// check for modern versions with the new versioning scheme, also the new paper version format
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0].split(".build")[0];
for (Entry<String, MinecraftVersion> entry : VERSION_TO_REVISION.entrySet()) {
if (versionString.startsWith(entry.getKey()) && version == null) {
version = entry.getValue();
// pick the highest revision that matches the version string, in case 26.1.3 is somehow different to 26.1
} else if (versionString.startsWith(entry.getKey()) && entry.getValue().getVersionId() > version.getVersionId()) {
version = entry.getValue();
}
}
}
if (version == null) {
version = UNKNOWN;
}
}
if (version != UNKNOWN) {
logger.info("[NBTAPI] NMS support '" + version.name() + "' loaded!");
@@ -56,8 +56,8 @@ public class Forge1710Mappings {
methodMap.put("COMPOUND_MERGE", "merge");// Only present on Crucible
methodMap.put("COMPOUND_SET", "func_74782_a");
methodMap.put("COMPOUND_GET", "func_74781_a");
methodMap.put("COMPOUND_GET_LIST", "func_150295_c");
methodMap.put("COMPOUND_OWN_TYPE", "func_74732_a");
methodMap.put("COMPOUND_GET_LIST_LEGACY", "func_150295_c");
methodMap.put("COMPOUND_OWN_TYPE_LEGACY", "func_74732_a");
methodMap.put("COMPOUND_GET_FLOAT", "func_74760_g");
methodMap.put("COMPOUND_GET_STRING", "func_74779_i");
methodMap.put("COMPOUND_GET_INT", "func_74762_e");
@@ -1,5 +1,6 @@
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -238,6 +239,7 @@ public class MojangToMapping {
put("net.minecraft.nbt.TagType#getName()", "a");
put("net.minecraft.nbt.CompoundTag#getList(java.lang.String)", "o");
put("net.minecraft.world.item.ItemStack#parse(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.Tag)", "a");
put("net.minecraft.world.item.ItemStack#CODEC", "b");
}
};
@@ -283,9 +285,49 @@ public class MojangToMapping {
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R6 = new HashMap<String, String>() {
{
putAll(MC1_21R5);
put("net.minecraft.server.MinecraftServer#registryAccess()", "bg");
put("net.minecraft.world.entity.Entity#load(net.minecraft.world.level.storage.ValueInput)", "d");
put("net.minecraft.world.entity.Entity#getEncodeId()", "bW");
put("net.minecraft.world.item.component.CustomData#copyTag()", "b");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "o");
put("net.minecraft.util.datafix.fixes.References#ITEM_STACK", "v");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R7 = new HashMap<String, String>() {
{
putAll(MC1_21R6);
put("net.minecraft.nbt.NbtAccounter#unlimitedHeap()", "c");
put("net.minecraft.server.MinecraftServer#registryAccess()", "bc");
put("net.minecraft.world.entity.Entity#getEncodeId()", "ca");
put("net.minecraft.util.datafix.fixes.References#ITEM_STACK", "x");
}
};
public static Map<String, String> getMapping() {
// No mappings after 26.1
if(MinecraftVersion.getVersion() != MinecraftVersion.UNKNOWN && MinecraftVersion.getVersion().isAtLeastVersion(MinecraftVersion.MC26_1)) {
return Collections.EMPTY_MAP;
}
switch (MinecraftVersion.getVersion()) {
case MC1_21_R7:
return MC1_21R7;
case MC1_21_R6:
return MC1_21R6;
case MC1_21_R5:
return MC1_21R5;
case MC1_21_R4:
@@ -315,7 +357,7 @@ public class MojangToMapping {
case MC1_18_R1:
return MC1_18R1;
case UNKNOWN:
return MC1_20R2; // assume it's a future version, so try the latest known mappings
return MC1_21R7; // assume it's a future version, so try the latest known mappings
default:
// this should never happen, unless a version is forgotten here(like 1.19R3 which uses the 1.19R2 mappings)
throw new NbtApiException("No fitting mapping found for version " + MinecraftVersion.getVersion() + ". This is a bug!");
@@ -175,7 +175,8 @@ public enum ReflectionMethod {
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK, new Class[] { ItemStack.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK, new Class[] { ClassWrapper.NMS_ITEMSTACK.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, resolveItemStackBukkitMirrorMethodName())),
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD, new Class[] {}, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
@@ -413,6 +414,16 @@ public enum ReflectionMethod {
this(targetClass, args, addedSince, null, methodnames);
}
private static String resolveItemStackBukkitMirrorMethodName() {
try {
ClassWrapper.CRAFT_ITEMSTACK.getClazz().getDeclaredMethod("asCraftMirror",
ClassWrapper.NMS_ITEMSTACK.getClazz());
return "asCraftMirror";
} catch (NullPointerException | NoSuchMethodException | SecurityException ignored) {
return "asBukkitMirror";
}
}
/**
* Runs the method on a given target object using the given args.
*
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</parent>
<artifactId>item-nbt-api-plugin</artifactId>
<packaging>jar</packaging>
@@ -12,7 +12,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -24,7 +24,7 @@
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.1.0</version>
<version>3.2.1</version>
<!-- Overwrite to provided -->
<scope>provided</scope>
</dependency>
@@ -40,7 +40,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<version>3.6.2</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<relocations>
@@ -15,9 +15,8 @@ public class GameprofileTest implements Test {
UUID uuid = UUID.randomUUID();
GameProfile profile = new GameProfile(uuid, "random");
ReadWriteNBT nbt = NBT.gameProfileToNBT(profile);
profile = null;
profile = NBT.gameProfileFromNBT(nbt);
if (profile == null || !profile.getId().equals(uuid)) {
GameProfile profile2 = NBT.gameProfileFromNBT(nbt);
if (profile == null || !profile.equals(profile2)) {
throw new NbtApiException("Error when converting a GameProfile from/to NBT!");
}
}
@@ -1,40 +1,77 @@
package de.tr7zw.nbtapi.plugin.tests.blocks;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import de.tr7zw.changeme.nbtapi.NBTBlock;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.nbtapi.plugin.tests.Test;
import java.util.List;
public class BlockNBTTest implements Test {
@Override
public void test() throws Exception {
if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_16_R3.getVersionId())
return;
if (!Bukkit.getWorlds().isEmpty()) {
World world = Bukkit.getWorlds().get(0);
try {
if (world.getLoadedChunks().length > 1) {
Chunk chunk = world.getLoadedChunks()[0];
Block block = chunk.getBlock(0, 254, 0);
NBTBlock comp = new NBTBlock(block);
comp.getData().removeKey("Too");
if (comp.getData().hasTag("Too")) {
throw new NbtApiException("Unable to remove key from Block!");
}
comp.getData().setString("Too", "Bar");
if (!new NBTBlock(block).getData().getString("Too").equals("Bar")) {
throw new NbtApiException("Custom Data did not save to a Block!");
}
}
} catch (Exception ex) {
throw new NbtApiException("Wasn't able to use NBTBlocks!", ex);
List<World> loadedWorlds = Bukkit.getWorlds();
if (loadedWorlds.isEmpty())
return;
World world = loadedWorlds.get(0);
Chunk[] loadedChunks = world.getLoadedChunks();
if (loadedChunks.length == 0)
return;
try {
Chunk chunk = loadedChunks[0];
Block block = chunk.getBlock(0, 254, 0);
String blockKey = block.getX() + "_" + block.getY() + "_" + block.getZ();
NBT.modifyChunkPDC(block, nbt -> nbt.setString("Too", "Bar"));
boolean storedDataPresent = NBT.readAndGetChunkPDC(chunk, nbt -> {
if (!nbt.hasTag("blocks", NBTType.NBTTagCompound)) return false;
ReadableNBT blocksNbt = nbt.getCompound("blocks");
if (blocksNbt == null || !blocksNbt.hasTag(blockKey, NBTType.NBTTagCompound)) return false;
ReadableNBT blockNbt = blocksNbt.getCompound(blockKey);
return blockNbt != null && blockNbt.hasTag("Too", NBTType.NBTTagString) && "Bar".equals(blockNbt.getString("Too"));
});
if (!storedDataPresent) {
throw new NbtApiException("Custom Data did not save to a Block!");
}
if (!NBT.readAndGetChunkPDC(block, nbt -> nbt.hasTag("Too"))) {
throw new NbtApiException("Custom Data did not save to a Block!");
}
boolean blockHadOnlyTestKey = NBT.readAndGetChunkPDC(block, nbt -> nbt.getKeys().size() == 1);
boolean chunkHadOnlyOneBlock = NBT.readAndGetChunkPDC(chunk, nbt -> nbt.getCompound("blocks").getKeys().size() == 1);
NBT.modifyChunkPDC(block, nbt -> nbt.removeKey("Too"));
if (NBT.readAndGetChunkPDC(block, nbt -> nbt.hasTag("Too"))) {
throw new NbtApiException("Unable to remove key from Block!");
}
if (chunkHadOnlyOneBlock) {
if (NBT.readAndGetChunkPDC(chunk, nbt -> nbt.hasTag("blocks"))) {
throw new NbtApiException("Chunk data wasn't cleaned up (hanging \"blocks\" compound)!");
}
} else if (blockHadOnlyTestKey) {
if (NBT.readAndGetChunkPDC(chunk, nbt -> nbt.getCompound("blocks").hasTag(blockKey))) {
throw new NbtApiException("Chunk data wasn't cleaned up (hanging block location compound)!");
}
}
} catch (Exception ex) {
throw new NbtApiException("Wasn't able to use NBTBlocks!", ex);
}
}
@@ -1,40 +1,46 @@
package de.tr7zw.nbtapi.plugin.tests.chunks;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import de.tr7zw.changeme.nbtapi.NBTChunk;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.nbtapi.plugin.tests.Test;
import java.util.List;
public class ChunkNBTPersistentTest implements Test {
@Override
public void test() throws Exception {
if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_16_R3.getVersionId())
return;
if (!Bukkit.getWorlds().isEmpty()) {
World world = Bukkit.getWorlds().get(0);
try {
if (world.getLoadedChunks().length > 1) {
Chunk chunk = world.getLoadedChunks()[0];
NBTChunk comp = new NBTChunk(chunk);
NBTCompound persistentData = comp.getPersistentDataContainer();
persistentData.removeKey("Foo");
if (persistentData.hasTag("Foo")) {
throw new NbtApiException("Unable to remove key from Chunk!");
}
persistentData.setString("Foo", "Bar");
if (!new NBTChunk(chunk).getPersistentDataContainer().getString("Foo").equals("Bar")) {
throw new NbtApiException("Custom Data did not save to the Chunk!");
}
}
} catch (Exception ex) {
throw new NbtApiException("Wasn't able to use NBTChunks!", ex);
List<World> loadedWorlds = Bukkit.getWorlds();
if (loadedWorlds.isEmpty())
return;
World world = loadedWorlds.get(0);
Chunk[] loadedChunks = world.getLoadedChunks();
if (loadedChunks.length == 0)
return;
Chunk chunk = loadedChunks[0];
try {
NBT.modifyChunkPDC(chunk, nbt -> nbt.setString("Foo", "Bar"));
if (!NBT.readAndGetChunkPDC(chunk, nbt -> nbt.hasTag("Foo", NBTType.NBTTagString) && "Bar".equals(nbt.getString("Foo")))) {
throw new NbtApiException("Custom Data did not save to the Chunk!");
}
NBT.modifyChunkPDC(chunk, nbt -> nbt.removeKey("Foo"));
if (NBT.readAndGetChunkPDC(chunk, nbt -> nbt.hasTag("Foo"))) {
throw new NbtApiException("Unable to remove key from Chunk!");
}
} catch (Exception ex) {
throw new NbtApiException("Wasn't able to use NBTChunks!", ex);
}
}
@@ -33,6 +33,11 @@ public class LegacyItemTest implements Test {
ItemStack item2 = NBT.itemStackFromNBT(NBT.parseNBT("{DataVersion:" + DataFixerUtil.VERSION1_12_2 + ",id:cobblestone,Count:42,tag:{display:{Name:\"test\"},ench:[{lvl:3,id:34}]}}"));
if (!item.equals(item2))
throw new NbtApiException("Data-fixed 1.12.2 item didn't load correctly! " + item2);
ReadWriteNBT testNBT = NBT.parseNBT("{id:cobblestone,Count:42,tag:{display:{Name:\"test\"},ench:[{lvl:3,id:34}]},DataVersion:1343}");
testNBT = DataFixerUtil.fixUpItemData(testNBT, DataFixerUtil.VERSION1_12R1);
if (testNBT.getInteger("DataVersion") != DataFixerUtil.getCurrentVersion())
throw new NbtApiException("DataVersion wasn't updated correctly! " + testNBT);
}
}
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</parent>
<artifactId>mappings-parser</artifactId>
<packaging>jar</packaging>
@@ -12,7 +12,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -24,7 +24,7 @@ public class MappingsParser {
public static StringBuilder builder = new StringBuilder();
public static void main(String[] args) throws IOException {
File input = new File("minecraft_server.1.21.6.txt");
File input = new File("minecraft_server.1.21.9.txt");
List<String> lines = Files.readAllLines(input.toPath());
Map<String, ClassWrapper> classes = new HashMap<>();
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</parent>
<artifactId>nbt-data-api</artifactId>
@@ -14,7 +14,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</parent>
<artifactId>nbt-injector</artifactId>
<packaging>jar</packaging>
@@ -12,7 +12,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
<dependency>
+5 -5
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
<packaging>pom</packaging>
<inceptionYear>2015</inceptionYear>
<organization>
@@ -88,7 +88,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<version>3.16.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -97,7 +97,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<version>3.4.0</version>
<executions>
<execution>
<id>attach-sources</id>
@@ -110,7 +110,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<version>3.12.0</version>
<configuration>
<source>8</source>
</configuration>
@@ -139,7 +139,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.6.0</version>
<version>2.7.1</version>
<configuration>
<licenseName>mit</licenseName>
<licenseFile>LICENSE</licenseFile>
+2 -2
View File
@@ -112,7 +112,7 @@ Just use the Plugin as Maven dependency and remember to add "NBTAPI" as dependen
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api-plugin</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</dependency>
[/CODE]
[/SPOILER]
@@ -122,7 +122,7 @@ Using this method the API gets copied into your plugin. Server owners don't have
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.15.1</version>
<version>2.16.1</version>
</dependency>
...
<plugins>
+12 -6
View File
@@ -306,20 +306,26 @@ You can store data in block entities (block entities like chest, furnace, etc.)
Thus, you have to use your own block data storage to store custom block data.
You can store data inside Chunks since 1.16.4, and NBT-API allows you to do so by using ``NBTChunk``:
You can store data inside Chunks using their PDC (Persistent Data Container) since Minecraft **1.16.4**. The NBT‑API provides read and modify methods in the `NBT` class to interact with it:
```java
ReadWriteNBT nbt = new NBTChunk(chunk).getPersistentDataContainer();
// Read the entire PDC or a specific value
NBT.readChunkPDC(chunk, nbt -> { /* ... */ });
String str = NBT.readAndGetChunkPDC(chunk, nbt -> nbt.getOrNull("key", String.class));
```
Similarly, there is ``NBTBlock``, which allows you to store block data inside chunk's data.
For convenience, you can also pass Blocks into `NBT#read/modify[AndGet]ChunkPDC` methods to store block data inside Chunk's PDC.
Blocks are stored inside their chunk's PDC under a `blocks` compound, using the block's location (`X_Y_Z`) as the key for a subcompound.
```java
// Block's data will be stored in Chunk's data in "blocks.x_y_z" subtag
ReadWriteNBT nbt = new NBTBlock(block).getData();
// Modify and retrieve data for a specific block
boolean bool = NBT.modifyAndGetChunkPDC(block, nbt -> {
nbt.setString("owner_name", "Player123");
return nbt.getOrDefault("key", false);
});
```
**However**, keep in mind that this data is linked only to the location, and if the block gets broken/changed/exploded/moved/etc., the data will still be on that location unless manually cleared/moved!
**However**, keep in mind that the block's data is linked only to the location, and if the block gets broken/changed/exploded/moved/etc., the data will still be on that location unless manually cleared/moved!
Moreover, since the data is stored inside a Chunk, this will increase the chunk's size on the disk.