Compare commits

...
53 Commits
Author SHA1 Message Date
tr7zw 35f541d3db Tag 2.15.0 2025-04-17 20:30:44 +02:00
tr7zw d4ee3b998c Fix wiki 2025-04-17 19:46:53 +02:00
tr7zw 2902dca5a5 Follow the javadoc of the list#remove method. Fix #293 2025-04-17 19:45:29 +02:00
tr7zw 1c1e3c8664 Remove "json" wording, add more warnings/info 2025-04-17 19:41:27 +02:00
tr7zw 7f8f021ced Merge pull request #321 from SoSeDiK/diff
Add a method to extract difference between two compounds
2025-04-17 19:24:21 +02:00
SoSeDiK 98ed1850f6 Add a method to extract difference between two compounds 2025-04-12 16:18:22 +03:00
tr7zw 764e01503d Merge pull request #320 from SoSeDiK/wiki
Update "Reading world data" wiki example
2025-03-31 19:04:27 +02:00
SoSeDiK 43d8e2a351 Update "Reading world data" wiki example 2025-03-31 19:09:42 +03:00
tr7zw 689cd4fa3b Remove unused code path 2025-03-31 18:03:11 +02:00
tr7zw c8f68f8b3b Merge pull request #319 from SoSeDiK/dataversion
Add DataVersion for itemstack conversions
2025-03-28 10:22:12 +01:00
tr7zw e52ba209e6 Fix mistake 2025-03-25 22:50:44 +01:00
tr7zw 418f5bea07 1.21.5 update, needs a lot of testing 2025-03-25 22:42:01 +01:00
SoSeDiK 1392e72a8a Only run items through the data fixer on MC1_20_R4+ 2025-03-22 00:37:57 +02:00
SoSeDiK dc39d1d8ef Add DataVersion for itemstack conversions 2025-03-21 23:13:50 +02:00
tr7zw a974142a55 Merge pull request #316 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.14.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.13.0 to 3.14.0
2025-02-23 10:39:14 +00:00
dependabot[bot] f014e71020 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.13.0 to 3.14.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-21 23:13:30 +00:00
tr7zw da6be72d29 Merge pull request #313 from SoSeDiK/wiki
Update wiki
2024-12-28 19:11:29 +00:00
SoSeDiK d9a93e9306 Add info about paper-plugin.yml 2024-12-28 15:57:04 +02:00
SoSeDiK ba374fe69c Update gradle shadow plugin info 2024-12-28 15:53:01 +02:00
SoSeDiK aa35ee8333 Fixup modifyMeta example 2024-12-28 15:51:28 +02:00
SoSeDiK 3bb0bdd74c Clarify persistent data storage availability 2024-12-28 15:50:49 +02:00
tr7zw f3af749b11 Merge pull request #309 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.5.0
Bump org.codehaus.mojo:license-maven-plugin from 2.4.0 to 2.5.0
2024-12-21 23:44:01 +00:00
tr7zw d81c2b4e8e Merge pull request #311 from FireML/patch-1
Add EvenMoreFish to Plugins.md
2024-12-21 23:43:51 +00:00
tr7zw 94192feb8f Merge pull request #312 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.11.2
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.1 to 3.11.2
2024-12-21 23:43:29 +00:00
tr7zw af3d9c8502 Start 2.14.2-SNAPSHOT 2024-12-22 00:42:03 +01:00
tr7zw ae98859524 Tag 2.14.1 2024-12-16 17:11:16 +01:00
tr7zw 70f0bb62f9 Add Util to get ItemStacks in Json Format for hover components 2024-12-14 21:58:53 +01:00
dependabot[bot] 505e172955 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.1 to 3.11.2
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.1 to 3.11.2.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.1...maven-javadoc-plugin-3.11.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 23:45:07 +00:00
FireML d2b2b6a506 Add EvenMoreFish to Plugins.md, and Update CommandAPI URL 2024-12-08 01:31:10 +00:00
tr7zw e2e8aad70a Merge pull request #310 from ArmyFury/patch-1
Update Plugins.md
2024-12-07 13:17:51 +00:00
ArmyFury 4874366e30 Update Plugins.md
added SummonFriendlyMobs to plugins list
2024-12-07 12:47:39 +05:30
tr7zw d2de90ee25 Add 1.21.4 support 2024-12-03 23:28:21 +01:00
dependabot[bot] a0f93e575e Bump org.codehaus.mojo:license-maven-plugin from 2.4.0 to 2.5.0
Bumps [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.4.0...2.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-29 23:30:47 +00:00
tr7zw b339c9e9c2 Merge pull request #306 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.11.1
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.1 to 3.11.1
2024-11-13 23:54:08 +01:00
tr7zw 3425a6672d Merge pull request #308 from SoSeDiK/wiki-changes
Update wiki
2024-11-13 23:53:54 +01:00
tr7zw 67616266da Start snapshots 2.14.1 2024-11-13 23:53:07 +01:00
SoSeDiK b08e4aa12f Update wiki to reflect some 2.14.0 changes
ItemMeta usage clarifications
2024-11-12 14:28:06 +02:00
dependabot[bot] 27411e90da Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.1 to 3.11.1
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.10.1 to 3.11.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.10.1...maven-javadoc-plugin-3.11.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-04 23:48:38 +00:00
tr7zw 73776cfec4 Sneak quick fix into release 2024-11-02 15:18:16 +01:00
tr7zw bd674e31c0 Tag 2.14.0 2024-11-02 15:07:50 +01:00
tr7zw 3405ffe0a3 Fix javadoc deploy 2024-11-02 13:24:22 +01:00
tr7zw f1317bcb04 Fix BlockEntity test. Fix #304 2024-11-02 13:06:19 +01:00
tr7zw 4a32343b95 Add 1.21.3 2024-10-28 18:56:04 +01:00
tr7zw 3de6ed83eb Hide NBTFile/NBTContainer fully behind NBT. Update tests to new format. Add missing addCompound(ReadableNBT comp) to ReadWriteNBTCompoundList 2024-10-22 23:45:16 +02:00
tr7zw e5bdce73ea Merge pull request #300 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.10.1
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.0 to 3.10.1
2024-10-22 22:42:25 +02:00
tr7zw 410e88a35b Add getComponents methods 2024-10-22 22:39:35 +02:00
tr7zw e3142b4869 Add 1.21.2 support 2024-10-22 22:24:59 +02:00
tr7zw 243a5c2bcd Fix really stupid edge case of writeCompound 2024-10-22 22:08:04 +02:00
dependabot[bot] 045c710366 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.0 to 3.10.1
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.10.0 to 3.10.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.10.0...maven-javadoc-plugin-3.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 23:20:24 +00:00
tr7zw 4cd118671f Merge pull request #297 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.10.0
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.8.0 to 3.10.0
2024-08-27 23:03:05 +02:00
dependabot[bot] d86c91f2e6 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.8.0 to 3.10.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.8.0 to 3.10.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.8.0...maven-javadoc-plugin-3.10.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-27 16:08:01 +00:00
tr7zw f8736c8188 Also update old items with "Count" tags 2024-08-27 18:07:27 +02:00
tr7zw b3aec54205 Start 2.13.3-SNAPSHOT 2024-08-27 18:06:56 +02:00
52 changed files with 970 additions and 206 deletions

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ updates:
ignore:
- dependency-name: com.github.ekryd.sortpom:sortpom-maven-plugin
versions:
- 2.13.2
- 2.13.3-SNAPSHOT
- 2.14.0
- 2.14.1
- 2.15.0
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
- name: Copy artifacts
shell: bash
run: |
mkdir -p artifacts/v2-api && cp -r item-nbt-api/target/apidocs/* artifacts/v2-api
mkdir -p artifacts/v2-api && cp -r item-nbt-api/target/reports/apidocs/* artifacts/v2-api
mkdir -p artifacts/v2-plugin && cp -r item-nbt-plugin/target/apidocs/* artifacts/v2-plugin
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.4.1
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.13.2</version>
<version>2.15.0</version>
</parent>
<artifactId>item-nbt-api</artifactId>
@@ -1,5 +1,8 @@
package de.tr7zw.changeme.nbtapi;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Level;
@@ -12,6 +15,7 @@ import org.bukkit.inventory.ItemStack;
import com.mojang.authlib.GameProfile;
import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteItemNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadableItemNBT;
@@ -200,9 +204,9 @@ public class NBT {
}
/**
* It takes a block entity and a function that takes a ReadableNBT and returns
* a generic type T, and returns the result of the function, applied to the
* block entities persistent data container
* It takes a block entity and a function that takes a ReadableNBT and returns a
* generic type T, and returns the result of the function, applied to the block
* entities persistent data container
*
* @param blockState The block state of the block you want to get the data from.
* @param getter A function that takes a ReadableNBT and returns a value of
@@ -269,17 +273,17 @@ public class NBT {
nbtEnt.setClosed();
return ret;
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quiet expensive, so don't overuse it.
* This method is quite expensive, so don't overuse it.
*
* @param item The item you want to modify the components of
* @param consumer The consumer that will be used to modify the components.
*/
public static void modifyComponents(ItemStack item, Consumer<ReadWriteNBT> consumer) {
if(!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
@@ -287,18 +291,18 @@ public class NBT {
ItemStack tmp = NBT.itemStackFromNBT(nbti);
item.setItemMeta(tmp.getItemMeta());
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quiet expensive, so don't overuse it.
* This method is quite expensive, so don't overuse it.
*
* @param item The item you want to modify the components of
* @param function The consumer that will be used to modify the components.
* @return The return type is the same as the return type of the function.
*/
public static <T> T modifyComponents(ItemStack item, Function<ReadWriteNBT, T> function) {
if(!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
@@ -308,6 +312,39 @@ public class NBT {
return ret;
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quite expensive, try to cache the results/use it smartly.
*
* @param item The item you want to read the components of
* @param consumer The consumer that will be used to read the components.
*/
public static void getComponents(ItemStack item, Consumer<ReadableNBT> consumer) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
consumer.accept(nbti.getOrCreateCompound("components"));
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quite expensive, try to cache the results/use it smartly.
*
* @param item The item you want to read the components of
* @param function The consumer that will be used to read the components.
* @return The return type is the same as the return type of the function.
*/
public static <T> T getComponents(ItemStack item, Function<ReadableNBT, T> function) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
return function.apply(nbti.getOrCreateCompound("components"));
}
/**
* It takes an entity and a function that takes a ReadWriteNBT and applies the
* function to the entity
@@ -492,12 +529,70 @@ public class NBT {
* It takes a nbt json string, and returns a ReadWriteNBT object
*
* @param nbtString The NBT string to parse.
* @return A new NBTContainer object.
* @return A new ReadWriteNBT object.
*/
public static ReadWriteNBT parseNBT(String nbtString) {
return new NBTContainer(nbtString);
}
/**
* Reads in an NBT stream and returns a ReadWriteNBT object
*
* @param stream The NBT stream to read.
* @return A new ReadWriteNBT object.
*/
public static ReadWriteNBT readNBT(InputStream stream) {
return new NBTContainer(stream);
}
/**
* Helper method for other developers using NMS. Allows to wrap any
* net.minecraft.nbt.CompoundTag to a NBTAPI ReadWriteNBT object.
*
* @param nmsNbtTag Needs to be a valid net.minecraft.nbt.CompoundTag
* @return A new ReadWriteNBT object.
*/
public static ReadWriteNBT wrapNMSTag(Object nmsNbtTag) {
return new NBTContainer(nmsNbtTag);
}
/**
* Creates a NBTFileHandle that uses @param file to store its data. If this file
* exists, the data will be loaded, otherwise a new file gets created.
*
* @param file
* @throws IOException
*/
public static NBTFileHandle getFileHandle(File file) throws IOException {
return new NBTFile(file);
}
/**
* Reads NBT data from the provided file.
* <p>
* Returns an empty tag if the file does not exist.
*
* @param file file to read
* @return ReadWriteNBT of the files data
* @throws IOException exception
*/
public static ReadWriteNBT readFile(File file) throws IOException {
return NBTFile.readFrom(file);
}
/**
* Saves NBT data to the provided file.
* <p>
* Will fully override the file if it already exists.
*
* @param file file
* @param nbt NBT data
* @throws IOException exception
*/
public static void writeFile(File file, ReadWriteNBT nbt) throws IOException {
NBTFile.saveTo(file, (NBTCompound) nbt);
}
/**
* Create a read only proxy class for NBT, given an annotated interface.
*
@@ -5,6 +5,7 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
@@ -19,6 +20,7 @@ import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.PathUtil;
import de.tr7zw.changeme.nbtapi.utils.UUIDUtil;
import de.tr7zw.changeme.nbtapi.utils.PathUtil.PathSegment;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.Forge1710Mappings;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
@@ -98,10 +100,13 @@ public class NBTCompound implements ReadWriteNBT {
return readOnlyCache;
}
Object rootnbttag = getCompound();
if (rootnbttag instanceof Optional<?>) {
rootnbttag = ((Optional<Object>) rootnbttag).orElse(null);
}
if (rootnbttag == null) {
return null;
}
if (!NBTReflectionUtil.valideCompound(this))
if (!NBTReflectionUtil.validCompound(this))
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
Object workingtag = NBTReflectionUtil.getToCompount(rootnbttag, this);
if (readOnly) {
@@ -657,7 +662,9 @@ public class NBTCompound implements ReadWriteNBT {
public void setUUID(String key, UUID value) {
try {
writeLock.lock();
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
setIntArray(key, UUIDUtil.uuidToIntArray(value));
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) {
NBTReflectionUtil.setData(this, ReflectionMethod.COMPOUND_SET_UUID, key, value);
} else {
setString(key, value.toString());
@@ -678,10 +685,13 @@ public class NBTCompound implements ReadWriteNBT {
public UUID getUUID(String key) {
try {
readLock.lock();
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)
&& getType(key) == NBTType.NBTTagIntArray) {
NBTType type = getType(key);
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4) && type == NBTType.NBTTagIntArray) {
return UUIDUtil.uuidFromIntArray(getIntArray(key));
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)
&& type == NBTType.NBTTagIntArray) {
return (UUID) NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_UUID, key);
} else if (getType(key) == NBTType.NBTTagString) {
} else if (type == NBTType.NBTTagString) {
try {
return UUID.fromString(getString(key));
} catch (IllegalArgumentException ex) {
@@ -786,7 +796,7 @@ public class NBTCompound implements ReadWriteNBT {
if (getType(name) != NBTType.NBTTagCompound)
return null;
NBTCompound next = new NBTCompound(this, name, readOnly);
if (NBTReflectionUtil.valideCompound(next))
if (NBTReflectionUtil.validCompound(next))
return next;
return null;
} finally {
@@ -1343,7 +1353,13 @@ public class NBTCompound implements ReadWriteNBT {
Object nbtbase = NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET, name);
if (nbtbase == null)
return null;
return NBTType.valueOf((byte) ReflectionMethod.COMPOUND_OWN_TYPE.run(nbtbase));
return NBTType.valueOf((byte) ReflectionMethod.COMPOUND_OWN_TYPE_LEGACY.run(nbtbase));
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
Object o = NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET, name);
if (o == null)
return null;
return NBTType.fromName((String)ReflectionMethod.TAGTYPE_GET_NAME.run(ReflectionMethod.TAGTYPE_OWN_TYPE.run(o)));
}
Object o = NBTReflectionUtil.getData(this, ReflectionMethod.COMPOUND_GET_TYPE, name);
if (o == null)
@@ -1460,6 +1476,106 @@ public class NBTCompound implements ReadWriteNBT {
return false;
}
@Override
public NBTCompound extractDifference(ReadableNBT other) {
if (this == other)
return new NBTContainer();
if (other instanceof NBTCompound) {
return saveDiff(new NBTContainer(), this, (NBTCompound) other);
} else {
throw new NbtApiException("Unknown NBT object: " + other);
}
}
private static NBTCompound saveDiff(NBTCompound saveTo, NBTCompound compA, NBTCompound compB) {
for (String key : compA.getKeys()) {
saveDiff(saveTo, compA, compB, key);
}
return saveTo;
}
private static void saveDiff(NBTCompound saveTo, NBTCompound compA, NBTCompound compB, String key) {
boolean typeMismatch = compA.getType(key) != compB.getType(key);
switch (compA.getType(key)) {
case NBTTagByte:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setByte(key, compA.getByte(key));
}
return;
case NBTTagByteArray:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setByteArray(key, compA.getByteArray(key));
}
return;
case NBTTagCompound: {
NBTCompound tmp1 = compA.getCompound(key);
if (tmp1 == null) return;
if (typeMismatch) {
saveTo.addCompound(key).mergeCompound(tmp1);
} else {
NBTCompound tmp2 = compB.getCompound(key);
if (tmp2 == null) {
saveTo.addCompound(key).mergeCompound(tmp1);
return;
}
NBTCompound tmpDiff = tmp1.extractDifference(tmp2);
if (!tmpDiff.getKeys().isEmpty()) {
saveTo.addCompound(key).mergeCompound(tmpDiff);
}
}
return;
}
case NBTTagDouble:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setDouble(key, compA.getDouble(key));
}
return;
case NBTTagEnd:
return; // ??
case NBTTagFloat:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setFloat(key, compA.getFloat(key));
}
return;
case NBTTagInt:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setInteger(key, compA.getInteger(key));
}
return;
case NBTTagIntArray:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setIntArray(key, compA.getIntArray(key));
}
return;
case NBTTagList:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.set(key, NBTReflectionUtil.getEntry(compA, key));
}
return;
case NBTTagLong:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setLong(key, compA.getLong(key));
}
return;
case NBTTagShort:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setShort(key, compA.getShort(key));
}
return;
case NBTTagString:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setString(key, compA.getString(key));
}
return;
case NBTTagLongArray:
if (typeMismatch || !isEqual(compA, compB, key)) {
saveTo.setLongArray(key, compA.getLongArray(key));
}
return;
}
}
private static boolean isEqual(NBTCompound compA, NBTCompound compB, String key) {
if (compA.getType(key) != compB.getType(key))
return false;
@@ -2,6 +2,7 @@ package de.tr7zw.changeme.nbtapi;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
@@ -56,7 +57,8 @@ public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteN
}
}
public NBTCompound addCompound(ReadWriteNBT comp) {
@Override
public ReadWriteNBT addCompound(ReadableNBT comp) {
if (comp instanceof NBTCompound) {
return addCompound((NBTCompound) comp);
}
@@ -21,7 +21,10 @@ public class NBTContainer extends NBTCompound {
/**
* Creates an empty, standalone NBTCompound
*
* @deprecated use {@link NBT#createNBTObject()}
*/
@Deprecated
public NBTContainer() {
super(null, null);
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
@@ -31,7 +34,9 @@ public class NBTContainer extends NBTCompound {
* Takes in any NMS Compound to wrap it
*
* @param nbt
* @deprecated Use NBT.wrapNMSTag
*/
@Deprecated
public NBTContainer(Object nbt) {
super(null, null);
if (nbt == null) {
@@ -47,7 +52,9 @@ public class NBTContainer extends NBTCompound {
* Reads in a NBT InputStream
*
* @param inputsteam
* @deprecated Use NBT.readNBT
*/
@Deprecated
public NBTContainer(InputStream inputsteam) {
super(null, null);
this.nbt = NBTReflectionUtil.readNBT(inputsteam);
@@ -58,7 +65,9 @@ public class NBTContainer extends NBTCompound {
* {@link NbtApiException} in case something goes wrong.
*
* @param nbtString
* @deprecated Use NBT.parseNBT
*/
@Deprecated
public NBTContainer(String nbtString) {
super(null, null);
if (nbtString == null) {
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
/**
@@ -12,7 +13,7 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
* @author tr7zw
*
*/
public class NBTFile extends NBTCompound {
public class NBTFile extends NBTCompound implements NBTFileHandle {
private final File file;
private Object nbt;
@@ -23,7 +24,9 @@ public class NBTFile extends NBTCompound {
*
* @param file
* @throws IOException
* @deprecated Use NBT.getFileHandle(file)
*/
@Deprecated
public NBTFile(File file) throws IOException {
super(null, null);
if (file == null) {
@@ -43,6 +46,7 @@ public class NBTFile extends NBTCompound {
*
* @throws IOException
*/
@Override
public void save() throws IOException {
try {
getWriteLock().lock();
@@ -55,6 +59,7 @@ public class NBTFile extends NBTCompound {
/**
* @return The File used to store the data
*/
@Override
public File getFile() {
return file;
}
@@ -77,7 +82,9 @@ public class NBTFile extends NBTCompound {
* @param file file to read
* @return NBTCompound holding file's nbt data
* @throws IOException exception
* @deprecated Use NBT.readFile(file)
*/
@Deprecated
public static NBTCompound readFrom(File file) throws IOException {
if (!file.exists())
return new NBTContainer();
@@ -92,7 +99,9 @@ public class NBTFile extends NBTCompound {
* @param file file
* @param nbt NBT data
* @throws IOException exception
* @deprecated Use NBT.writeFile(file, nbt)
*/
@Deprecated
public static void saveTo(File file, NBTCompound nbt) throws IOException {
if (!file.exists()) {
file.getParentFile().mkdirs();
@@ -304,8 +304,8 @@ public abstract class NBTList<T> implements List<T>, ReadWriteNBTList<T> {
try {
parent.getWriteLock().lock();
int size = size();
int id = -1;
while ((id = indexOf(o)) != -1) {
int id = indexOf(o);
if (id != -1) {
remove(id);
}
return size != size();
@@ -9,6 +9,7 @@ import java.util.ArrayDeque;
import java.util.Collections;
import java.util.Deque;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@@ -154,6 +155,9 @@ public class NBTReflectionUtil {
public static void writeApiNBT(NBTCompound comp, OutputStream stream) {
try {
Object workingtag = comp.getResolvedObject();
if (workingtag == null) {
workingtag = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
}
ReflectionMethod.NBTFILE_WRITE.run(null, workingtag, stream);
} catch (Exception e) {
throw new NbtApiException("Exception while writing NBT!", e);
@@ -213,11 +217,22 @@ public class NBTReflectionUtil {
try {
Object nmsComp = getToCompount(nbtcompound.getCompound(), nbtcompound);
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
if (nbtcompound.hasTag("tag")) {
nmsComp = DataFixerUtil.fixUpRawItemData(nmsComp, DataFixerUtil.VERSION1_20_4,
DataFixerUtil.getCurrentVersion());
if (nbtcompound.hasTag("DataVersion", NBTType.NBTTagInt)) {
int dataVersion = nbtcompound.getInteger("DataVersion");
int currentVersion = DataFixerUtil.getCurrentVersion();
if (dataVersion < currentVersion) {
nmsComp = DataFixerUtil.fixUpRawItemData(nmsComp, dataVersion, currentVersion);
}
} else if (nbtcompound.hasTag("tag") || nbtcompound.hasTag("Count")) {
nmsComp = DataFixerUtil.fixUpRawItemData(nmsComp, DataFixerUtil.VERSION1_20_4, DataFixerUtil.getCurrentVersion());
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
Optional<Object> opt = (Optional<Object>) ReflectionMethod.NMSITEM_LOAD_MODERN.run(null,
registry_access, nmsComp);
return opt.orElse(null);
} else {
return ReflectionMethod.NMSITEM_LOAD.run(null, registry_access, nmsComp);
}
return ReflectionMethod.NMSITEM_LOAD.run(null, registry_access, nmsComp);
} else if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_11_R1.getVersionId()) {
return ObjectCreator.NMS_COMPOUNDFROMITEM.getInstance(nmsComp);
} else {
@@ -236,13 +251,18 @@ public class NBTReflectionUtil {
*/
public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) {
try {
NBTContainer container;
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
return new NBTContainer(ReflectionMethod.NMSITEM_SAVE_MODERN.run(nmsitem, registry_access));
container = new NBTContainer(ReflectionMethod.NMSITEM_SAVE_MODERN.run(nmsitem, registry_access));
} else {
Object answer = ReflectionMethod.NMSITEM_SAVE.run(nmsitem,
ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance());
return new NBTContainer(answer);
container = new NBTContainer(answer);
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_12_R1)) {
container.setInteger("DataVersion", DataFixerUtil.getCurrentVersion());
}
return container;
} catch (Exception e) {
throw new NbtApiException("Exception while converting NMS ItemStack to NBTCompound!", e);
}
@@ -383,7 +403,11 @@ public class NBTReflectionUtil {
public static Object getSubNBTTagCompound(Object compound, String name) {
try {
if ((boolean) ReflectionMethod.COMPOUND_HAS_KEY.run(compound, name)) {
return ReflectionMethod.COMPOUND_GET_COMPOUND.run(compound, name);
Object comp = ReflectionMethod.COMPOUND_GET_COMPOUND.run(compound, name);
if (comp instanceof Optional) {
return ((Optional<?>) comp).orElse(null);
}
return comp;
} else {
throw new NbtApiException("Tried getting invalid compound '" + name + "' from '" + compound + "'!");
}
@@ -407,7 +431,7 @@ public class NBTReflectionUtil {
if (nbttag == null) {
nbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
if (!valideCompound(comp)) {
if (!validCompound(comp)) {
return;
}
Object workingtag = getToCompount(nbttag, comp);
@@ -424,10 +448,13 @@ public class NBTReflectionUtil {
* Checks if the Compound is correctly linked to it's roots
*
* @param comp
* @return true if this is a valide Compound, else false
* @return true if this is a valid Compound, else false
*/
public static boolean valideCompound(NBTCompound comp) {
public static boolean validCompound(NBTCompound comp) {
Object root = comp.getCompound();
if (root instanceof Optional) {
root = ((Optional<?>) root).orElse(null);
}
if (root == null) {
root = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
@@ -442,9 +469,15 @@ public class NBTReflectionUtil {
structure.add(comp.getName());
comp = comp.getParent();
}
if (nbttag instanceof Optional) {
nbttag = ((Optional<?>) nbttag).orElse(null);
}
while (!structure.isEmpty()) {
String target = structure.pollLast();
nbttag = getSubNBTTagCompound(nbttag, target);
if (nbttag instanceof Optional) {
nbttag = ((Optional<?>) nbttag).orElse(null);
}
if (nbttag == null) {
throw new NbtApiException("Unable to find tag '" + target + "' in " + nbttag);
}
@@ -467,7 +500,7 @@ public class NBTReflectionUtil {
if (rootnbttag == null) {
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
if (!valideCompound(comp))
if (!validCompound(comp))
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
Object workingtag = getToCompount(rootnbttag, comp);
try {
@@ -494,7 +527,7 @@ public class NBTReflectionUtil {
if (rootnbttag == null) {
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
if (!valideCompound(comp)) {
if (!validCompound(comp)) {
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
}
Object workingtag = getToCompount(rootnbttag, comp);
@@ -522,7 +555,18 @@ public class NBTReflectionUtil {
workingtag = dummyNBT.getCompound(); // it creates a new ListTag if needed, but its unlinked
}
try {
Object nbt = ReflectionMethod.COMPOUND_GET_LIST.run(workingtag, key, type.getId());
Object nbt = null;
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
nbt = ReflectionMethod.COMPOUND_GET_LIST.run(workingtag, key);
if (nbt instanceof Optional) {
nbt = ((Optional<?>) nbt).orElse(null);
}
if (nbt == null) {
nbt = ClassWrapper.NMS_NBTTAGLIST.getClazz().newInstance();
}
} else {
nbt = ReflectionMethod.COMPOUND_GET_LIST_LEGACY.run(workingtag, key, type.getId());
}
if (clazz == String.class) {
return (NBTList<T>) new NBTStringList(comp, key, type, nbt);
} else if (clazz == NBTListCompound.class) {
@@ -554,6 +598,26 @@ public class NBTReflectionUtil {
}
try {
Object nbt = ReflectionMethod.COMPOUND_GET.run(workingtag, key);
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
if (nbt instanceof Optional) {
nbt = ((Optional<?>) nbt).orElse(null);
}
if (nbt == null) {
return NBTType.NBTTagEnd;
}
if (new NBTStringList(comp, key, NBTType.NBTTagString, nbt).isEmpty()) {
return NBTType.NBTTagEnd;
}
Object compound = ReflectionMethod.LIST_GET.run(nbt, 0);
if (compound instanceof Optional) {
compound = ((Optional<?>) compound).orElse(null);
}
if (compound == null) {
return NBTType.NBTTagEnd;
}
return NBTType.fromName((String) ReflectionMethod.TAGTYPE_GET_NAME
.run(ReflectionMethod.TAGTYPE_OWN_TYPE.run(compound)));
}
String fieldname = "type";
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
fieldname = "w";
@@ -628,7 +692,7 @@ public class NBTReflectionUtil {
if (rootnbttag == null) {
return;
}
if (!valideCompound(comp))
if (!validCompound(comp))
return;
Object workingtag = getToCompount(rootnbttag, comp);
ReflectionMethod.COMPOUND_REMOVE_KEY.run(workingtag, key);
@@ -667,7 +731,7 @@ public class NBTReflectionUtil {
if (rootnbttag == null) {
rootnbttag = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
if (!valideCompound(comp))
if (!validCompound(comp))
throw new NbtApiException("The Compound wasn't able to be linked back to the root!");
Object workingtag = getToCompount(rootnbttag, comp);
type.run(workingtag, key, data);
@@ -690,7 +754,41 @@ public class NBTReflectionUtil {
if (workingtag == null) {
workingtag = dummyNBT.getCompound();
}
return type.run(workingtag, key);
if (workingtag instanceof Optional<?>) {
workingtag = ((Optional<Object>) workingtag).orElseGet(() -> dummyNBT.getCompound());
}
Object obj = type.run(workingtag, key);
if (obj instanceof Optional<?>) {
return ((Optional<Object>) obj).orElseGet(() -> getDefaultValue(type));
}
return obj;
}
private static Object getDefaultValue(ReflectionMethod type) {
if (type == ReflectionMethod.COMPOUND_GET_STRING) {
return "";
} else if (type == ReflectionMethod.COMPOUND_GET_BYTE) {
return (byte) 0;
} else if (type == ReflectionMethod.COMPOUND_GET_SHORT) {
return (short) 0;
} else if (type == ReflectionMethod.COMPOUND_GET_BOOLEAN) {
return false;
} else if (type == ReflectionMethod.COMPOUND_GET_INT) {
return 0;
} else if (type == ReflectionMethod.COMPOUND_GET_LONG) {
return 0L;
} else if (type == ReflectionMethod.COMPOUND_GET_FLOAT) {
return 0.0f;
} else if (type == ReflectionMethod.COMPOUND_GET_DOUBLE) {
return 0.0d;
} else if (type == ReflectionMethod.COMPOUND_GET_BYTEARRAY) {
return new byte[0];
} else if (type == ReflectionMethod.COMPOUND_GET_INTARRAY) {
return new int[0];
} else if (type == ReflectionMethod.COMPOUND_GET_LONGARRAY) {
return new long[0];
}
return null;
}
}
@@ -2,6 +2,7 @@ package de.tr7zw.changeme.nbtapi;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
@@ -21,7 +22,11 @@ public class NBTStringList extends NBTList<String> {
@Override
public String get(int index) {
try {
return (String) ReflectionMethod.LIST_GET_STRING.run(listObject, index);
Object ret = ReflectionMethod.LIST_GET_STRING.run(listObject, index);
if (ret instanceof Optional<?>) {
return ((Optional<String>) ret).orElse("");
}
return (String) ret;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
@@ -8,14 +8,16 @@ package de.tr7zw.changeme.nbtapi;
*/
@SuppressWarnings("javadoc")
public enum NBTType {
NBTTagEnd(0), NBTTagByte(1), NBTTagShort(2), NBTTagInt(3), NBTTagLong(4), NBTTagFloat(5), NBTTagDouble(6),
NBTTagByteArray(7), NBTTagString(8), NBTTagList(9), NBTTagCompound(10), NBTTagIntArray(11), NBTTagLongArray(12);
NBTTagEnd(0, ""), NBTTagByte(1, "BYTE"), NBTTagShort(2, "SHORT"), NBTTagInt(3, "INT"), NBTTagLong(4, "LONG"), NBTTagFloat(5, "FLOAT"), NBTTagDouble(6, "DOUBLE"),
NBTTagByteArray(7, "BYTE[]"), NBTTagString(8, "STRING"), NBTTagList(9, "LIST"), NBTTagCompound(10, "COMPOUND"), NBTTagIntArray(11, "INT[]"), NBTTagLongArray(12, "LONG[]");
NBTType(int i) {
NBTType(int i, String name) {
id = i;
this.name = name;
}
private final int id;
private final String name;
/**
* @return Id used by Minecraft internally
@@ -23,6 +25,13 @@ public enum NBTType {
public int getId() {
return id;
}
/**
* @return Name of the NBTType
*/
public String getName() {
return name;
}
/**
* @param id Internal Minecraft id
@@ -35,4 +44,11 @@ public enum NBTType {
return NBTType.NBTTagEnd;
}
public static NBTType fromName(String name) {
for (NBTType t : values())
if (t.getName().equals(name))
return t;
return NBTType.NBTTagEnd;
}
}
@@ -0,0 +1,20 @@
package de.tr7zw.changeme.nbtapi.iface;
import java.io.File;
import java.io.IOException;
public interface NBTFileHandle extends ReadWriteNBT {
/**
* Saves the data to the file
*
* @throws IOException
*/
void save() throws IOException;
/**
* @return The File used to store the data
*/
File getFile();
}
@@ -10,6 +10,15 @@ public interface ReadWriteNBTCompoundList extends ReadableNBTList<ReadWriteNBT>
* @return A new instance of the class.
*/
ReadWriteNBT addCompound();
/**
* Adds a copy of the Compound to the end of the List and returns it. When null
* is given, a new Compound will be created
*
* @param comp
* @return
*/
ReadWriteNBT addCompound(ReadableNBT comp);
/**
* Removes the element at the specified position in this list
@@ -344,6 +344,17 @@ public interface ReadableNBT {
*/
void writeCompound(OutputStream stream);
/**
* Compares this readable nbt to the other one
* and returns the difference.
* <p>Note: the result will only contain data that is present
* in this readable nbt and is missing/different in the provided one.
*
* @param other other readable nbt
* @return difference between readable nbts
*/
ReadWriteNBT extractDifference(ReadableNBT other);
/**
* @return The NBT as printable NBT-Json.
*/
@@ -5,6 +5,7 @@ import com.mojang.datafixers.DataFixer;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTReflectionUtil;
@@ -30,6 +31,9 @@ public class DataFixerUtil {
public static final int VERSION1_20_4 = 3700;
public static final int VERSION1_20_5 = 3837;
public static final int VERSION1_21 = 3953;
public static final int VERSION1_21_2 = 4080;
public static final int VERSION1_21_3 = 4189;
public static final int VERSION1_21_5 = 4323;
@SuppressWarnings("unchecked")
public static Object fixUpRawItemData(Object nbt, int fromVersion, int toVersion)
@@ -47,7 +51,7 @@ public class DataFixerUtil {
public static ReadWriteNBT fixUpItemData(ReadWriteNBT nbt, int fromVersion, int toVersion)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
return new NBTContainer(fixUpRawItemData(
return NBT.wrapNMSTag(fixUpRawItemData(
NBTReflectionUtil.getToCompount(((NBTCompound) nbt).getCompound(), ((NBTCompound) nbt)), fromVersion,
toVersion));
}
@@ -62,7 +66,13 @@ public class DataFixerUtil {
* @return
*/
public static int getCurrentVersion() {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R1)) {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
return VERSION1_21_5;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R3)) {
return VERSION1_21_3;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R2)) {
return VERSION1_21_2;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R1)) {
return VERSION1_21;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
return VERSION1_20_5;
@@ -24,7 +24,7 @@ public enum MinecraftVersion {
MC1_13_R1(1131), MC1_13_R2(1132), MC1_14_R1(1141), MC1_15_R1(1151), MC1_16_R1(1161), MC1_16_R2(1162),
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_20_R4(1204, true), MC1_21_R1(1211, true), MC1_21_R2(1212, true), MC1_21_R3(1213, true), MC1_21_R4(1214, true);
private static MinecraftVersion version;
private static Boolean hasGsonSupport;
@@ -39,7 +39,7 @@ public enum MinecraftVersion {
private static Logger logger = Logger.getLogger("NBTAPI");
// NBT-API Version
protected static final String VERSION = "2.13.2";
protected static final String VERSION = "2.15.0";
private final int versionId;
private final boolean mojangMapping;
@@ -57,6 +57,10 @@ public enum MinecraftVersion {
this.put("1.20.6", MC1_20_R4);
this.put("1.21", MC1_21_R1);
this.put("1.21.1", MC1_21_R1);
this.put("1.21.2", MC1_21_R2);
this.put("1.21.3", MC1_21_R2);
this.put("1.21.4", MC1_21_R3);
this.put("1.21.5", MC1_21_R4);
}
};
@@ -0,0 +1,41 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.util.Optional;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonElement;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.JsonOps;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.MojangToMapping;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTJsonUtil {
/**
* 1.20.3-1.21.4 only. Used to convert items into Json, used in Chat Hover Components.
*
* @param itemStack
* @return
* @throws NbtApiException
*/
@SuppressWarnings("unchecked")
public static JsonElement itemStackToJson(ItemStack itemStack) {
try {
Codec<Object> itemStackCodec = (Codec<Object>) ClassWrapper.NMS_ITEMSTACK.getClazz()
.getField(MojangToMapping.getMapping().get("net.minecraft.world.item.ItemStack#CODEC")).get(null);
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, itemStack);
DataResult<JsonElement> result = itemStackCodec.encode(stack, JsonOps.INSTANCE,
JsonOps.INSTANCE.emptyMap());
Optional<JsonElement> opt = (Optional<JsonElement>) result.getClass().getMethod("result").invoke(result);
return opt.orElse(null);
} catch (Exception ex) {
throw new NbtApiException("Error trying to get Json of an ItemStack.", ex);
}
}
}
@@ -24,6 +24,7 @@ public enum ClassWrapper {
CRAFT_PERSISTENTDATACONTAINER(PackageWrapper.CRAFTBUKKIT, "persistence.CraftPersistentDataContainer",
MinecraftVersion.MC1_14_R1, null),
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase", null, null, "net.minecraft.nbt", "net.minecraft.nbt.Tag"),
NMS_TAGTYPE(PackageWrapper.NMS, "NBTTagType", MinecraftVersion.MC1_21_R4, null, "net.minecraft.nbt", "net.minecraft.nbt.TagType"),
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString", null, null, "net.minecraft.nbt",
"net.minecraft.nbt.StringTag"),
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt", null, null, "net.minecraft.nbt", "net.minecraft.nbt.IntTag"),
@@ -145,6 +145,7 @@ public class MojangToMapping {
put("net.minecraft.world.entity.Entity#getEncodeId()", "bw");
put("net.minecraft.world.level.block.entity.BlockEntity#saveWithId()", "p");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "r");
put("net.minecraft.world.item.ItemStack#CODEC", "a");
}
};
@@ -169,6 +170,7 @@ public class MojangToMapping {
put("net.minecraft.util.datafix.DataFixers#getDataFixer()", "a");
put("net.minecraft.util.datafix.fixes.References#ITEM_STACK", "t");
put("net.minecraft.nbt.NbtOps#INSTANCE", "a");
put("net.minecraft.world.item.ItemStack#CODEC", "b");
}
};
@@ -183,10 +185,71 @@ public class MojangToMapping {
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R2 = new HashMap<String, String>() {
{
putAll(MC1_21R1);
put("net.minecraft.server.MinecraftServer#registryAccess()", "ba");
put("net.minecraft.world.entity.Entity#getEncodeId()", "bK");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "m");
put("net.minecraft.world.item.ItemStack#CODEC", "a");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R3 = new HashMap<String, String>() {
{
putAll(MC1_21R2);
put("net.minecraft.world.item.component.CustomData#copyTag()", "d");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R4 = new HashMap<String, String>() {
{
putAll(MC1_21R3);
put("net.minecraft.nbt.CompoundTag#getShort(java.lang.String)", "d");
put("net.minecraft.nbt.CompoundTag#getString(java.lang.String)", "i");
put("net.minecraft.nbt.CompoundTag#contains(java.lang.String)", "b");
put("net.minecraft.nbt.CompoundTag#getDouble(java.lang.String)", "h");
put("net.minecraft.nbt.CompoundTag#getByteArray(java.lang.String)", "j");
put("net.minecraft.nbt.CompoundTag#getFloat(java.lang.String)", "g");
put("net.minecraft.nbt.CompoundTag#get(java.lang.String)", "a");
put("net.minecraft.nbt.CompoundTag#getLong(java.lang.String)", "f");
put("net.minecraft.nbt.CompoundTag#getLongArray(java.lang.String)", "l");
put("net.minecraft.nbt.CompoundTag#getInt(java.lang.String)", "e");
put("net.minecraft.nbt.CompoundTag#getIntArray(java.lang.String)", "k");
put("net.minecraft.nbt.CompoundTag#getCompound(java.lang.String)", "m");
put("net.minecraft.nbt.CompoundTag#getByte(java.lang.String)", "c");
put("net.minecraft.nbt.ListTag#getString(int)", "m");
put("net.minecraft.world.entity.Entity#saveWithoutId(net.minecraft.nbt.CompoundTag)", "h");
put("net.minecraft.world.entity.Entity#getEncodeId()", "bI");
put("net.minecraft.world.entity.Entity#load(net.minecraft.nbt.CompoundTag)", "i");
put("net.minecraft.nbt.Tag#getType()", "c");
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");
}
};
public static Map<String, String> getMapping() {
switch (MinecraftVersion.getVersion()) {
case MC1_21_R4:
return MC1_21R4;
case MC1_21_R3:
return MC1_21R3;
case MC1_21_R2:
return MC1_21R2;
case MC1_21_R1:
return MC1_21R1;
case MC1_20_R4:
@@ -54,7 +54,7 @@ public enum ReflectionMethod {
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean"),
new Since(MinecraftVersion.MC1_18_R1, "putBoolean(java.lang.String,boolean)")),
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, UUID.class },
MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"),
MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_21_R3, new Since(MinecraftVersion.MC1_16_R1, "a"),
new Since(MinecraftVersion.MC1_18_R1, "putUUID(java.lang.String,java.util.UUID)")),
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"),
@@ -65,12 +65,18 @@ public enum ReflectionMethod {
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "get"),
new Since(MinecraftVersion.MC1_18_R1, "get(java.lang.String)")),
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, int.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList"),
COMPOUND_GET_LIST_LEGACY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, int.class },
MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_21_R3, new Since(MinecraftVersion.MC1_7_R4, "getList"),
new Since(MinecraftVersion.MC1_18_R1, "getList(java.lang.String,int)")),
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_21_R4,
MinecraftVersion.MC1_21_R4, new Since(MinecraftVersion.MC1_21_R4, "getList(java.lang.String)")),
// Only needed for 1.7.10 getType
COMPOUND_OWN_TYPE(ClassWrapper.NMS_NBTBASE, new Class[] {}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4,
COMPOUND_OWN_TYPE_LEGACY(ClassWrapper.NMS_NBTBASE, new Class[] {}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getTypeId")),
TAGTYPE_OWN_TYPE(ClassWrapper.NMS_NBTBASE, new Class[] {}, MinecraftVersion.MC1_21_R4,
new Since(MinecraftVersion.MC1_21_R4, "getType()")),
TAGTYPE_GET_NAME(ClassWrapper.NMS_TAGTYPE, new Class[] {}, MinecraftVersion.MC1_21_R4,
new Since(MinecraftVersion.MC1_21_R4, "getName()")),
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getFloat"),
@@ -105,13 +111,14 @@ public enum ReflectionMethod {
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getBoolean"),
new Since(MinecraftVersion.MC1_18_R1, "getBoolean(java.lang.String)")),
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_16_R1,
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_21_R3,
new Since(MinecraftVersion.MC1_16_R1, "a"),
new Since(MinecraftVersion.MC1_18_R1, "getUUID(java.lang.String)")),
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getCompound"),
new Since(MinecraftVersion.MC1_18_R1, "getCompound(java.lang.String)")),
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK, new Class[] {}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_7_R4, "getTag"), new Since(MinecraftVersion.MC1_18_R1, "getTag()")),
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
@@ -294,7 +301,9 @@ public enum ReflectionMethod {
NMSITEM_SAVE_MODERN(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_PROVIDER.getClazz() },
MinecraftVersion.MC1_20_R4, new Since(MinecraftVersion.MC1_20_R4, "save(net.minecraft.core.HolderLookup$Provider)")),
NMSITEM_LOAD(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_PROVIDER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_20_R4, new Since(MinecraftVersion.MC1_20_R4, "parseOptional(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.CompoundTag)")),
MinecraftVersion.MC1_20_R4, MinecraftVersion.MC1_21_R3, new Since(MinecraftVersion.MC1_20_R4, "parseOptional(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.CompoundTag)")),
NMSITEM_LOAD_MODERN(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_PROVIDER.getClazz(), ClassWrapper.NMS_NBTBASE.getClazz() },
MinecraftVersion.MC1_21_R4, new Since(MinecraftVersion.MC1_20_R4, "parse(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.Tag)")),
NMSSERVER_GETREGISTRYACCESS(ClassWrapper.NMS_SERVER, new Class[] {},
MinecraftVersion.MC1_20_R4, new Since(MinecraftVersion.MC1_20_R4, "registryAccess()")),
NMSSERVER_GETSERVER(ClassWrapper.CRAFT_SERVER, new Class[] {},
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.13.2</version>
<version>2.15.0</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.13.2</version>
<version>2.15.0</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -7,7 +7,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import de.tr7zw.changeme.nbtapi.NbtApiException;
@@ -19,6 +18,7 @@ import de.tr7zw.nbtapi.plugin.tests.GameprofileTest;
import de.tr7zw.nbtapi.plugin.tests.NBTFileTest;
import de.tr7zw.nbtapi.plugin.tests.blocks.BlockNBTTest;
import de.tr7zw.nbtapi.plugin.tests.chunks.ChunkNBTPersistentTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.CompoundDifferenceTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.EnumTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.EqualsTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.ForEachTest;
@@ -41,6 +41,7 @@ import de.tr7zw.nbtapi.plugin.tests.items.DirectApplyMetaTest;
import de.tr7zw.nbtapi.plugin.tests.items.DirectApplyTest;
import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemConversionTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemJsonTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemMergingTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemStackConversionTest;
import de.tr7zw.nbtapi.plugin.tests.items.LegacyItemTest;
@@ -99,6 +100,7 @@ public class NBTAPI extends JavaPlugin {
apiTests.add(new ForEachTest());
apiTests.add(new StreamTest());
apiTests.add(new EqualsTest());
apiTests.add(new CompoundDifferenceTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) // 1.7.10 list support is not complete at all
apiTests.add(new IteratorTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1))
@@ -112,6 +114,9 @@ public class NBTAPI extends JavaPlugin {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
apiTests.add(new LegacyItemTest());
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4) && !MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
apiTests.add(new ItemJsonTest());
}
apiTests.add(new ComponentsTest());
apiTests.add(new EmptyItemTest());
apiTests.add(new SmuggleTest());
@@ -4,9 +4,9 @@ import java.util.UUID;
import com.mojang.authlib.GameProfile;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTGameProfile;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
public class GameprofileTest implements Test {
@@ -14,9 +14,9 @@ public class GameprofileTest implements Test {
public void test() throws Exception {
UUID uuid = UUID.randomUUID();
GameProfile profile = new GameProfile(uuid, "random");
NBTCompound nbt = NBTGameProfile.toNBT(profile);
ReadWriteNBT nbt = NBT.gameProfileToNBT(profile);
profile = null;
profile = NBTGameProfile.fromNBT(nbt);
profile = NBT.gameProfileFromNBT(nbt);
if (profile == null || !profile.getId().equals(uuid)) {
throw new NbtApiException("Error when converting a GameProfile from/to NBT!");
}
@@ -3,10 +3,10 @@ package de.tr7zw.nbtapi.plugin.tests;
import java.io.File;
import java.nio.file.Files;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTFile;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.NBTAPI;
public class NBTFileTest implements Test {
@@ -16,18 +16,18 @@ public class NBTFileTest implements Test {
NBTAPI.getInstance().getDataFolder().mkdirs();
File testFile = new File(NBTAPI.getInstance().getDataFolder(), "test.nbt");
Files.deleteIfExists(testFile.toPath());
NBTFile file = new NBTFile(testFile);
file.addCompound("testcomp").setString("test1", "ok");
NBTCompound comp = file.getCompound("testcomp");
NBTFileHandle file = NBT.getFileHandle(testFile);
file.getOrCreateCompound("testcomp").setString("test1", "ok");
ReadWriteNBT comp = file.getOrCreateCompound("testcomp");
if (comp == null) {
throw new NbtApiException("Error getting compound!");
}
comp.setString("test2", "ok");
file.setLong("time", System.currentTimeMillis());
file.setString("test", "test");
NBTCompound chunks = file.addCompound("chunks");
NBTCompound chunk = chunks.addCompound("somechunk");
NBTCompound block = chunk.addCompound("someblock");
ReadWriteNBT chunks = file.getOrCreateCompound("chunks");
ReadWriteNBT chunk = chunks.getOrCreateCompound("somechunk");
ReadWriteNBT block = chunk.getOrCreateCompound("someblock");
block.setString("type", "wool");
file.save();
@@ -35,25 +35,25 @@ public class NBTFileTest implements Test {
throw new NbtApiException("SubCompounds did not work!");
}
NBTFile fileLoaded = new NBTFile(testFile);
NBTFileHandle fileLoaded = NBT.getFileHandle(testFile);
if (!fileLoaded.getString("test").equals("test")) {
throw new NbtApiException("Wasn't able to load NBT File with the correct content!");
}
Files.deleteIfExists(fileLoaded.getFile().toPath());
// String
String str = fileLoaded.toString();
NBTContainer rebuild = new NBTContainer(str);
ReadWriteNBT rebuild = NBT.parseNBT(str);
if (!str.equals(rebuild.toString())) {
throw new NbtApiException("Wasn't able to parse NBT from a String!");
}
NBTCompound dummy = new NBTContainer();
ReadWriteNBT dummy = NBT.createNBTObject();
dummy.setString("test1", "key1");
NBTFile.saveTo(testFile, dummy);
dummy = new NBTContainer();
NBT.writeFile(testFile, dummy);
dummy = NBT.createNBTObject();
dummy.setString("test2", "key2");
NBTFile.saveTo(testFile, dummy);
dummy = NBTFile.readFrom(testFile);
NBT.writeFile(testFile, dummy);
dummy = NBT.readFile(testFile);
if (dummy.hasTag("test1") || !dummy.getString("test2").equals("key2")) {
throw new NbtApiException("Wasn't able to save NBT File with the correct content!");
}
@@ -0,0 +1,69 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
import java.util.Arrays;
public class CompoundDifferenceTest implements Test {
@Override
public void test() throws Exception {
ReadWriteNBT nbt1 = NBT.createNBTObject();
nbt1.setInteger("intTag", 1);
ReadWriteNBT tmp = NBT.createNBTObject();
tmp.setInteger("foo", 1);
nbt1.getCompoundList("compoundList1").addCompound(tmp);
nbt1.setIntArray("intArray", new int[]{1, 2, 3});
tmp = NBT.createNBTObject();
tmp.setIntArray("foo", new int[]{1, 2, 3});
nbt1.getCompoundList("compoundList2").addCompound(tmp);
nbt1.getOrCreateCompound("compoundTag").setFloat("floatTag", 20F);
nbt1.getOrCreateCompound("compoundTag").setBoolean("booleanTag", true);
nbt1.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D));
nbt1.getOrCreateCompound("compoundTag").getFloatList("floatList").addAll(Arrays.asList(1F, 2F));
nbt1.getOrCreateCompound("compoundTagTwo").setString("stringTag", "string");
ReadWriteNBT nbt2 = NBT.createNBTObject();
nbt2.setInteger("intTag", 1);
tmp = NBT.createNBTObject();
tmp.setInteger("foo", 1);
nbt2.getCompoundList("compoundList1").addCompound(tmp);
nbt2.setInteger("alsoIntTag", 2);
tmp = NBT.createNBTObject();
tmp.setInteger("foo", 2);
nbt2.getCompoundList("compoundList2").addCompound(tmp);
nbt2.getOrCreateCompound("compoundTag").setFloat("floatTag", 20F);
nbt2.getOrCreateCompound("compoundTag").setBoolean("booleanTag", false);
nbt2.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D, 4D));
nbt2.getOrCreateCompound("compoundTag").getFloatList("floatList").addAll(Arrays.asList(1F, 2F));
nbt2.getOrCreateCompound("compoundTagTwo").setString("stringTag", "string");
ReadWriteNBT expectedDiff1 = NBT.createNBTObject();
tmp = NBT.createNBTObject();
tmp.setIntArray("foo", new int[]{1, 2, 3});
expectedDiff1.getCompoundList("compoundList2").addCompound(tmp);
expectedDiff1.setIntArray("intArray", new int[]{1, 2, 3});
expectedDiff1.getOrCreateCompound("compoundTag").setBoolean("booleanTag", true);
expectedDiff1.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D));
ReadWriteNBT expectedDiff2 = NBT.createNBTObject();
tmp = NBT.createNBTObject();
tmp.setInteger("foo", 2);
expectedDiff2.getCompoundList("compoundList2").addCompound(tmp);
expectedDiff2.setInteger("alsoIntTag", 2);
expectedDiff2.getOrCreateCompound("compoundTag").setBoolean("booleanTag", false);
expectedDiff2.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D, 4D));
ReadWriteNBT diff1 = nbt1.extractDifference(nbt2);
ReadWriteNBT diff2 = nbt2.extractDifference(nbt1);
if (!expectedDiff1.equals(diff1)) {
throw new NbtApiException("Diff1: Compounds did not match! " + expectedDiff1 + " " + diff1);
}
if (!expectedDiff2.equals(diff2)) {
throw new NbtApiException("Diff2: Compounds did not match! " + expectedDiff2 + " " + diff2);
}
}
}
@@ -1,16 +1,16 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class EnumTest implements Test {
@Override
public void test() throws Exception {
NBTCompound comp = new NBTContainer();
ReadWriteNBT comp = NBT.createNBTObject();
comp.setEnum("test", NBTType.NBTTagEnd);
NBTType type = comp.getEnum("test", NBTType.class);
NBTType typeNonNull = comp.getOrNull("test", NBTType.class);
@@ -5,44 +5,44 @@ import java.util.Arrays;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class EqualsTest implements Test {
@Override
public void test() throws Exception {
NBTContainer cont = new NBTContainer();
ReadWriteNBT cont = NBT.createNBTObject();
cont.setString("hello", "world");
cont.setInteger("theAnswer", 42);
cont.addCompound("sub").setString("me", "too");
cont.getOrCreateCompound("sub").setString("me", "too");
cont.getStringList("somelist").addAll(Arrays.asList("a", "b", "c"));
ItemStack item = new ItemStack(Material.STONE);
NBTItem nbti = new NBTItem(item);
NBTCompound customData = nbti.addCompound("customData");
// reverse order
customData.addCompound("sub").setString("me", "too");
customData.setInteger("theAnswer", 42);
customData.setString("hello", "world");
customData.getStringList("somelist").addAll(Arrays.asList("a", "b", "c"));
if (!customData.equals(cont)) {
throw new NbtApiException("Compounds did not match! " + customData + " " + cont);
}
NBT.modify(item, nbti -> {
ReadWriteNBT customData = nbti.getOrCreateCompound("customData");
// reverse order
customData.getOrCreateCompound("sub").setString("me", "too");
customData.setInteger("theAnswer", 42);
customData.setString("hello", "world");
customData.getStringList("somelist").addAll(Arrays.asList("a", "b", "c"));
if (!customData.equals(cont)) {
throw new NbtApiException("Compounds did not match! " + customData + " " + cont);
}
});
// empty test
if (!new NBTContainer().equals(new NBTContainer())) {
if (!NBT.createNBTObject().equals(NBT.createNBTObject())) {
throw new NbtApiException("Two empty tags did not match!");
}
// not equal test
NBTContainer part1 = new NBTContainer();
ReadWriteNBT part1 = NBT.createNBTObject();
part1.setString("a", "a");
part1.setString("b", "b");
NBTContainer part2 = new NBTContainer();
ReadWriteNBT part2 = NBT.createNBTObject();
part2.setString("a", "a");
part2.setString("b", "a");
if (part1.equals(part2)) {
@@ -3,24 +3,22 @@ package de.tr7zw.nbtapi.plugin.tests.compounds;
import java.util.Arrays;
import java.util.UUID;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTCompoundList;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTList;
import de.tr7zw.changeme.nbtapi.NBTListCompound;
import de.tr7zw.changeme.nbtapi.NBT;
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.ReadWriteNBTList;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class ListTest implements Test {
@Override
public void test() throws Exception {
NBTContainer comp = new NBTContainer();
ReadWriteNBT comp = NBT.createNBTObject();
// Strings
NBTList<String> list = comp.getStringList("testlist");
ReadWriteNBTList<String> list = comp.getStringList("testlist");
list.add("test1");
list.add("test2");
list.add("test3");
@@ -32,14 +30,14 @@ public class ListTest implements Test {
}
// Compound
NBTCompoundList taglist = comp.getCompoundList("complist");
NBTListCompound lcomp = taglist.addCompound();
ReadWriteNBTCompoundList taglist = comp.getCompoundList("complist");
ReadWriteNBT lcomp = taglist.addCompound();
lcomp.setDouble("double1", 0.3333);
lcomp.setInteger("int1", 42);
lcomp.setString("test1", "test1");
lcomp.setString("test2", "test2");
lcomp.removeKey("test1");
NBTCompound subsubcomp = lcomp.addCompound("listsubkey");
ReadWriteNBT subsubcomp = lcomp.getOrCreateCompound("listsubkey");
subsubcomp.setString("deep", "String");
subsubcomp.getCompoundList("deeplist").addCompound().setString("test", "test");
subsubcomp.getCompoundList("clonelist").addCompound(comp);
@@ -73,11 +71,11 @@ public class ListTest implements Test {
}
if (comp.getListType("complist") != NBTType.NBTTagCompound) {
throw new NbtApiException("complist had the wrong type! The Item-NBT-API may not work!");
throw new NbtApiException("complist had the wrong type(" + comp.getListType("complist") + ")! The Item-NBT-API may not work!");
}
// Integer
NBTList<Integer> intlist = comp.getIntegerList("inttest");
ReadWriteNBTList<Integer> intlist = comp.getIntegerList("inttest");
intlist.add(42);
intlist.add(69);
if (intlist.size() == 2 && intlist.get(0) == 42 && intlist.get(1) == 69) {
@@ -91,7 +89,7 @@ public class ListTest implements Test {
}
// Double
NBTList<Double> doublelist = comp.getDoubleList("doubletest");
ReadWriteNBTList<Double> doublelist = comp.getDoubleList("doubletest");
doublelist.add(42.23d);
doublelist.add(69.69d);
if (doublelist.size() == 2 && doublelist.get(0) == 42.23d && doublelist.get(1) == 69.69d) {
@@ -106,7 +104,7 @@ public class ListTest implements Test {
}
// Float
NBTList<Float> floatlist = comp.getFloatList("floattest");
ReadWriteNBTList<Float> floatlist = comp.getFloatList("floattest");
floatlist.add(42.23f);
floatlist.add(69.69f);
if (floatlist.size() == 2 && floatlist.get(0) == 42.23f && floatlist.get(1) == 69.69f) {
@@ -120,7 +118,7 @@ public class ListTest implements Test {
}
// Long
NBTList<Long> longlist = comp.getLongList("longtest");
ReadWriteNBTList<Long> longlist = comp.getLongList("longtest");
longlist.add(1241234124124l);
longlist.add(1231454321312l);
if (longlist.size() == 2 && longlist.get(0) == 1241234124124l && longlist.get(1) == 1231454321312l) {
@@ -134,7 +132,7 @@ public class ListTest implements Test {
}
// int[]
NBTList<int[]> intArrayList = comp.getIntArrayList("intatest");
ReadWriteNBTList<int[]> intArrayList = comp.getIntArrayList("intatest");
intArrayList.add(new int[] { 1, 2, 3 });
intArrayList.add(new int[] { 4, 2, 0 });
if (intArrayList.size() == 2 && Arrays.equals(new int[] { 1, 2, 3 }, intArrayList.get(0))
@@ -149,7 +147,7 @@ public class ListTest implements Test {
}
// UUID
NBTList<UUID> uuidList = comp.getUUIDList("uuidtest");
ReadWriteNBTList<UUID> uuidList = comp.getUUIDList("uuidtest");
uuidList.add(UUID.fromString("fce0323d-7f50-4317-9720-5f6b14cf78ea"));
uuidList.add(UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6"));
if (uuidList.size() == 2 && UUID.fromString("fce0323d-7f50-4317-9720-5f6b14cf78ea").equals(uuidList.get(0))
@@ -3,6 +3,10 @@ package de.tr7zw.nbtapi.plugin.tests.compounds;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.nbtapi.plugin.tests.Test;
@@ -21,6 +25,11 @@ public class StreamTest implements Test {
if (!container.toString().equals(base.getOrCreateCompound("sub").toString())) {
throw new NbtApiException("Component content did not match! " + base.getCompound("sub") + " " + container);
}
ItemStack item = new ItemStack(Material.STICK);
NBT.modify(item, nbt -> {
nbt.writeCompound(outStream);
});
}
}
@@ -1,8 +1,8 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class SubCompoundsTest implements Test {
@@ -19,9 +19,9 @@ public class SubCompoundsTest implements Test {
@Override
public void test() throws Exception {
NBTContainer cont = new NBTContainer();
ReadWriteNBT cont = NBT.createNBTObject();
NBTCompound comp = cont.addCompound(COMP_TEST_KEY);
ReadWriteNBT comp = cont.getOrCreateCompound(COMP_TEST_KEY);
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE + "2");
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE * 2);
comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE * 2);
@@ -1,19 +1,19 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class TypeTest implements Test {
@Override
public void test() throws Exception {
NBTCompound comp = new NBTContainer();
ReadWriteNBT comp = NBT.createNBTObject();
comp.setString("s", "test");
comp.setInteger("i", 42);
comp.addCompound("c");
comp.getOrCreateCompound("c");
if (comp.getType("s") != NBTType.NBTTagString || comp.getType("i") != NBTType.NBTTagInt
|| comp.getType("c") != NBTType.NBTTagCompound)
throw new NbtApiException("One parsed type did not match what it should have been!");
@@ -6,8 +6,7 @@ import org.bukkit.entity.Animals;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Monster;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTEntity;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.nbtapi.plugin.tests.Test;
@@ -23,14 +22,16 @@ public class EntityCustomNbtPersistentTest implements Test {
try {
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
NBTEntity nbtEnt = new NBTEntity(ent);
NBTCompound comp = nbtEnt.getPersistentDataContainer();
comp.setString("Hello", "World");
NBTEntity nbtent = new NBTEntity(ent);
if (!nbtent.toString().contains("Hello:\"World\"")) {
throw new NbtApiException("Custom Data did not save to the Entity!");
}
comp.removeKey("Hello");
NBT.modifyPersistentData(ent, comp -> {
comp.setString("Hello", "World");
});
NBT.modifyPersistentData(ent, comp -> {
if (!comp.toString().contains("Hello:\"World\"")) {
throw new NbtApiException("Custom Data did not save to the Entity!");
}
comp.removeKey("Hello");
});
}
} catch (Exception ex) {
@@ -27,7 +27,11 @@ public class ComponentsTest implements Test {
throw new NbtApiException("ReadComponent didn't work!");
}
NBT.modifyComponents(item, nbt -> {
nbt.setString("minecraft:custom_name", "{\"extra\":[\"foobar\"],\"text\":\"\"}");
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) {
nbt.mergeCompound(NBT.parseNBT("{\"minecraft:custom_name\":[{\"text\":\"foobar\",\"italic\":false}]}"));
} else {
nbt.setString("minecraft:custom_name", "{\"extra\":[\"foobar\"],\"text\":\"\"}");
}
});
if(!item.getItemMeta().getDisplayName().equals("foobar")) {
throw new NbtApiException("ModifyComponent didn't work!");
@@ -1,13 +1,15 @@
package de.tr7zw.nbtapi.plugin.tests.items;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import com.google.common.collect.Lists;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.nbtapi.plugin.tests.Test;
@@ -19,14 +21,21 @@ public class ItemConversionTest implements Test {
ItemMeta meta = item.getItemMeta();
meta.setLore(Lists.newArrayList("Firest Line", "Second Line"));
item.setItemMeta(meta);
String nbt = NBTItem.convertItemtoNBT(item).toString();
if (!nbt.contains("Firest Line") || !nbt.contains("Second Line"))
throw new NbtApiException("The Item nbt '" + nbt + "' didn't contain the lore");
ItemStack rebuild = NBTItem.convertNBTtoItem(new NBTContainer(nbt));
ReadWriteNBT nbt = NBT.itemStackToNBT(item);
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_12_R1)
&& !nbt.hasTag("DataVersion", NBTType.NBTTagInt)) {
throw new NbtApiException("The item nbt '" + nbt + "' didn't contain the data version");
}
String nbtString = nbt.toString();
if (!nbtString.contains("Firest Line") || !nbtString.contains("Second Line"))
throw new NbtApiException("The Item nbt '" + nbtString + "' didn't contain the lore");
ItemStack rebuild = NBT.itemStackFromNBT(NBT.parseNBT(nbtString));
if (!item.isSimilar(rebuild))
throw new NbtApiException("Rebuilt item did not match the original!");
NBTContainer cont = new NBTContainer();
ReadWriteNBT cont = NBT.createNBTObject();
cont.setItemStack("testItem", item);
if (!item.isSimilar(cont.getItemStack("testItem")))
throw new NbtApiException("Rebuilt item did not match the original!");
@@ -0,0 +1,28 @@
package de.tr7zw.nbtapi.plugin.tests.items;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import com.google.gson.JsonElement;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.NBTJsonUtil;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class ItemJsonTest implements Test {
@Override
public void test() throws Exception {
ItemStack item = new ItemStack(Material.STONE);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName("test");
meta.setUnbreakable(true);
item.setItemMeta(meta);
JsonElement elem = NBTJsonUtil.itemStackToJson(item);
if (elem == null) {
throw new NbtApiException("Getting the Json didn't work correctly! " + item);
}
}
}
@@ -3,9 +3,9 @@ package de.tr7zw.nbtapi.plugin.tests.items;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class ItemStackConversionTest implements Test {
@@ -14,8 +14,8 @@ public class ItemStackConversionTest implements Test {
public void test() throws Exception {
ItemStack[] src = new ItemStack[] { new ItemStack(Material.STONE), new ItemStack(Material.STICK),
new ItemStack(Material.AIR), new ItemStack(Material.STONE) };
NBTCompound comp = NBTItem.convertItemArraytoNBT(src);
ItemStack[] recreated = NBTItem.convertNBTtoItemArray(comp);
ReadWriteNBT comp = NBT.itemStackArrayToNBT(src);
ItemStack[] recreated = NBT.itemStackArrayFromNBT(comp);
if (recreated == null || src.length != recreated.length) {
throw new NbtApiException("Size did not match!");
}
@@ -29,6 +29,10 @@ public class LegacyItemTest implements Test {
|| !"test".equals(item.getItemMeta().getDisplayName())) {
throw new NbtApiException("1.12.2 item didn't load correctly! " + item);
}
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);
}
}
@@ -5,6 +5,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
@@ -24,6 +25,14 @@ public class TileTest implements Test {
world.getSpawnLocation().getBlockZ());
if (world.isChunkLoaded(block.getX() >> 4, block.getZ() >> 4) && block.getType() == Material.AIR) {
block.setType(Material.CHEST);
if (MinecraftVersion.isNewerThan(MinecraftVersion.MC1_21_R1)) {
// 1.21 changed the lock logic. So just try to get/set data, dont check for now
NBT.modify(block.getState(), nbt -> {
nbt.setString("foo", "bar");
});
block.setType(Material.AIR);
return;
}
NBTTileEntity tile = new NBTTileEntity(block.getState());
if (!MinecraftVersion.isNewerThan(MinecraftVersion.MC1_17_R1)) {
if (tile.getInteger("y") != 254) {
@@ -5,8 +5,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTTileEntity;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.nbtapi.plugin.tests.Test;
@@ -27,14 +26,16 @@ public class TilesCustomNBTPersistentTest implements Test {
world.getSpawnLocation().getBlockZ());
if (world.isChunkLoaded(block.getX() >> 4, block.getZ() >> 4) && block.getType() == Material.AIR) {
block.setType(Material.CHEST);
NBTTileEntity comp = new NBTTileEntity(block.getState());
NBTCompound persistentData = comp.getPersistentDataContainer();
persistentData.setString("Foo", "Bar");
if (!new NBTTileEntity(block.getState()).getPersistentDataContainer().getString("Foo")
.equals("Bar")) {
block.setType(Material.AIR);
throw new NbtApiException("Custom Data did not save to the Tile!");
}
NBT.modifyPersistentData(block.getState(), persistentData -> {
persistentData.setString("Foo", "Bar");
});
NBT.getPersistentData(block.getState(), persistentData -> {
if (!persistentData.getString("Foo").equals("Bar")) {
block.setType(Material.AIR);
throw new NbtApiException("Custom Data did not save to the Tile!");
}
return null;
});
block.setType(Material.AIR);
}
} catch (Exception ex) {
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.13.2</version>
<version>2.15.0</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.13.2</version>
<version>2.15.0</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.txt");
File input = new File("minecraft_server.1.21.4.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.13.2</version>
<version>2.15.0</version>
</parent>
<artifactId>nbt-data-api</artifactId>
@@ -14,7 +14,7 @@
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.13.2</version>
<version>2.15.0</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.13.2</version>
<version>2.15.0</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.13.2</version>
<version>2.15.0</version>
<scope>compile</scope>
</dependency>
<dependency>
+4 -4
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.13.2</version>
<version>2.15.0</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.13.0</version>
<version>3.14.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -110,7 +110,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.8.0</version>
<version>3.11.2</version>
<configuration>
<source>8</source>
</configuration>
@@ -139,7 +139,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.4.0</version>
<version>2.5.0</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.13.2</version>
<version>2.15.0</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.13.2</version>
<version>2.15.0</version>
</dependency>
...
<plugins>
+2 -2
View File
@@ -100,7 +100,7 @@ NBT.modifyPersistentData(zombie, nbt -> {
File worldDataFolder = Bukkit.getWorlds().getFirst().getWorldFolder();
// Read level data
NBTFile levelNbtFile = new NBTFile(new File(worldDataFolder, "level.dat"));
NBTFileHandle levelNbtFile = NBT.getFileHandle(new File(worldDataFolder, "level.dat"));
// Obtain world name
String worldName = levelNbtFile.resolveOrNull("Data.LevelName", String.class);
@@ -113,7 +113,7 @@ if (!playerFile.exists()) {
return;
}
NBTFile playerNbtFile = new NBTFile(playerFile);
NBTFileHandle playerNbtFile = NBT.getFileHandle(playerFile);
// Change player's health
float health = playerNbtFile.getFloat("Health");
+1 -3
View File
@@ -21,6 +21,4 @@ The experimental NBTInjector became unsupported since Minecraft 1.14 and was rem
NBTInjector is incompatible with reloads and may break things, and thus is not recommended.
If you're using Minecraft 1.14+, you should switch to the persistent storage API instead.
In versions prior to 1.14, you may use a workaround like storing data inside an item's nbt that the entity is wearing (e.g. having a button in mob's helmet, and storing data on that button).
See [this wiki section](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#accessing-custom-data) on how to handle custom entity nbt data without NBTInjector.
+3 -1
View File
@@ -2,9 +2,11 @@
- [IllegalStack](https://github.com/dniym/IllegalStack)
- [Prison](https://github.com/PrisonTeam/Prison)
- [CommandAPI](https://github.com/JorelAli/CommandAPI)
- [CommandAPI](https://github.com/CommandAPI/CommandAPI)
- [SkBee](https://github.com/ShaneBeee/SkBee/)
- [Monumenta](https://github.com/TeamMonumenta/monumenta-plugins-public/)
- [SummonFriendlyMobs](https://github.com/ArmyFury/SummonFriendlyMobs)
- [EvenMoreFish](https://github.com/Oheers/EvenMoreFish)
___
+27 -5
View File
@@ -3,7 +3,10 @@ To start using NB-API, you either need to depend on its plugin version, or shade
> [!IMPORTANT]
> Plugin and shaded versions have different ``artifactId``. Make sure to correctly choose the one you need!
# Option 1) NBT-API as a dependency
> [!IMPORTANT]
> Alternative ways of loading the api like Libby are not supported on Discord/Github issues.
# Option 1) NBT-API as a dependency (recommended)
Add the following entries to your Gradle build at the correct locations:
@@ -30,19 +33,38 @@ Add the API as dependency to your ``plugin.yml``:
depend: [NBTAPI]
```
# Option 2) Shading the NBT-API into your plugin
Or, if you are using ``paper-plugin.yml``:
To include NBT-API directly in your plugin, you can use the gradle shadow plugin.
```yml
dependencies:
server:
NBTAPI:
load: BEFORE
required: true
join-classpath: true
```
# Option 2) Shading the NBT-API into your plugin (Not recommended)
> [!WARNING]
> Due to the increasing amount of pitfalls in modern Paper, shading is not recommended. Please test with the normal plugin dependency before reporting issues.
To include NBT-API directly in your plugin, you can use the [Gradle Shadow Plugin](https://gradleup.com/shadow/).
Create an empty ``.mojang-mapped`` file in the META-INF folder of your plugin for 1.20+ Paper support.
> [!WARNING]
> Not adding this flag will make the shaded api not work on the latest Paper. It might also break other reflections/nms logic!
Add the plugin to the build configuration, as shown here:
```groovy
plugins {
id("com.github.johnrengelman.shadow") version "VERSION"
id("com.gradleup.shadow") version "VERSION"
}
```
The latest version of the shadow plugin can be found [here](https://github.com/johnrengelman/shadow/releases).
The latest version of the shadow plugin can be found [here](https://plugins.gradle.org/plugin/com.gradleup.shadow).
Add NBT-API to your dependencies:
+24 -2
View File
@@ -3,7 +3,10 @@ To start using NB-API, you either need to depend on its plugin version, or shade
> [!IMPORTANT]
> Plugin and shaded versions have different ``artifactId``. Make sure to correctly choose the one you need!
# Option 1) NBT-API as a dependency
> [!IMPORTANT]
> Alternative ways of loading the api like Libby are not supported on Discord/Github issues.
# Option 1) NBT-API as a dependency (recommended)
Add the following entries to your pom at the correct locations:
@@ -37,10 +40,29 @@ Add the API as dependency to your ``plugin.yml``:
depend: [NBTAPI]
```
# Option 2) Shading the NBT-API into your plugin
Or, if you are using ``paper-plugin.yml``:
```yml
dependencies:
server:
NBTAPI:
load: BEFORE
required: true
join-classpath: true
```
# Option 2) Shading the NBT-API into your plugin (Not recommended)
> [!WARNING]
> Due to the increasing amount of pitfalls in modern Paper, shading is not recommended. Please test with the normal plugin dependency before reporting issues.
To include NBT-API directly in your plugin, you can use the maven shade plugin.
Create an empty ``.mojang-mapped`` file in the META-INF folder of your plugin for 1.20+ Paper support.
> [!WARNING]
> Not adding this flag will make the shaded api not work on the latest Paper. It might also break other reflections/nms logic!
Add the plugin to the build configuration, as shown here:
```xml
+89 -24
View File
@@ -2,7 +2,7 @@
### Basics overview
Most of the things are exposed inside the [NBT](https://tr7zw.github.io/Item-NBT-API/v2-api/de/tr7zw/changeme/nbtapi/NBT.html) class. Make sure to explore the Javadoc, or ask your IDE for suggestions!
Most of the things are exposed inside the [NBT](https://tr7zw.github.io/Item-NBT-API/v2-api/de/tr7zw/changeme/nbtapi/NBT.html) class. Your specific use-case might not yet be covered by the wiki, so make sure to explore the [Javadoc](https://tr7zw.github.io/Item-NBT-API/v2-api/), or ask your IDE for suggestions!
#### Basic getting and setting of data
@@ -43,14 +43,34 @@ nbt.getOrCreateCompound("subtag"); // Get or create a subtag
#### Converting NBT to String and the String back to NBT
```java
// Parse Mojang-Json string to nbt
// 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 Mojang-Json string (works with any NBT object)
String json = nbt.toString();
// 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(json);
ReadWriteNBT nbt2 = NBT.parseNBT(snbt);
```
#### Comparing NBT data
As with other objects in Java, you may compare nbt using `equals`.
To see what exactly mismatched, you can use `ReadableNBT#extractDifference`:
```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);
```
For the example above, `ReadableNBT#toString` will produce:
diff1: `{compoundTag:{booleanTag:1b},intArray:[I;1,2]}`
diff2: `{compoundTag:{booleanTag:0b},intArray:[I;1,2,3],alsoIntTag:2}`
#### Merging Compounds
You can "merge" the data from any given Compound onto some other Compound. This will overwrite the tags with the same name.
@@ -115,9 +135,13 @@ nbt.resolveOrDefault("list_key[-1]", "fallback_value"); // Get the last value in
// NBT compound lists
// Get the list (will create it if needed)
ReadWriteNBTCompoundList nbtList = nbt.getOrCreateCompound("foo").getCompoundList("other_key");
ReadWriteNBT nbtListEntry = addCompound();
// 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
@@ -162,12 +186,33 @@ int someValue = NBT.modify(itemStack, nbt -> {
> [!WARNING]
> Never mix the usage of ItemMeta and NBT.
> Setting ItemMeta will override any changes made to item's nbt.
```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!
```
Alternatively, you may safely modify ItemMeta inside the NBT scope:
```java
// Updating ItemMeta using NBT
NBT.modify(itemStack, nbt -> {
nbt.setInteger("kills", nbt.getOrDefault("kills", 0) + 1);
nbt.modifyMeta((meta, readOnlyNbt) -> { // Do not modify the nbt while modifying the meta!
nbt.modifyMeta((readOnlyNbt, meta) -> { // Do not modify the nbt while modifying the meta!
meta.setDisplayName("Kills: " + readOnlyNbt.getOrDefault("kills", 0));
});
// Do more stuff
@@ -184,6 +229,15 @@ NBT.modify(itemStack, nbt -> {
```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\":\"\"}");
});
@@ -209,7 +263,12 @@ NBT.modify(entity, nbt -> {
#### Accessing custom data
For reading/storing custom data on (block-)entities, you should use methods that end with PersistentData.
> [!WARNING]
> Persistent data storage for custom (block-)entity nbt is only available in 1.14+.
>
> If you need to support versions below that, for entities you may use a workaround like storing data inside an item's nbt that the entity is wearing (e.g. having a button in mob's helmet, and storing data on that button).
For reading/storing custom data on (block-)entities, you should use methods that end with ``PersistentData``.
> [!IMPORTANT]
> When working with block entities, make sure that the block entity exists in the world.
@@ -271,26 +330,32 @@ Moreover, since the data is stored inside a Chunk, this will increase the chunk'
### NBT files
```java
// Creating nbt file
// NBTFile will automatically create the file if it does not exist
NBTFile file = new NBTFile(new File("directory"), "test.nbt"); // Will be created at ./directory/test.nbt
// Setting data
file.setString("foo", "bar");
// Saving file
file.save();
NBTFileHandle allows working with nbt files.
// Alternatively, you may use helper methods in NBTFile class
// To read the file without creating it if does not exist:
ReadWriteNBT nbt = NBTFile.readFrom(file);
// To save nbt to the file:
NBTFile.saveTo(file, nbt);
```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();
```
Alternatively, you may read the nbt file without maintaining the link to it.
Unlike NBTFileHandle, the file won't be automatically created if it does not exist.
```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);
```
### Converting Minecraft Objects to NBT and Strings
The basic idea is that you can convert data into different representations:
Minecraft Objects <-> NBT <-> String (Mojang-Json)
Minecraft Objects <-> NBT <-> String (SNBT)
#### Items
@@ -318,8 +383,8 @@ ReadWriteNBT nbt = NBT.itemStackArrayToNBT(itemStacks);
ItemStack itemStack = NBT.itemStackFromNBT(nbt);
ItemStack[] itemStacks = NBT.itemStackArrayFromNBT(nbt);
// Reminder (NBT <-> String)
String json = nbt.toString();
ReadWriteNBT nbt = NBT.parseNBT(json);
String snbt = nbt.toString();
ReadWriteNBT nbt = NBT.parseNBT(snbt);
```
#### Entities and block entities