mirror of
https://github.com/tr7zw/Item-NBT-API.git
synced 2026-11-14 12:52:04 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35f541d3db | ||
|
|
d4ee3b998c | ||
|
|
2902dca5a5 | ||
|
|
1c1e3c8664 | ||
|
|
7f8f021ced | ||
|
|
98ed1850f6 | ||
|
|
764e01503d | ||
|
|
43d8e2a351 | ||
|
|
689cd4fa3b | ||
|
|
c8f68f8b3b | ||
|
|
e52ba209e6 | ||
|
|
418f5bea07 | ||
|
|
1392e72a8a | ||
|
|
dc39d1d8ef | ||
|
|
a974142a55 | ||
|
|
f014e71020 | ||
|
|
da6be72d29 | ||
|
|
d9a93e9306 | ||
|
|
ba374fe69c | ||
|
|
aa35ee8333 | ||
|
|
3bb0bdd74c | ||
|
|
f3af749b11 | ||
|
|
d81c2b4e8e | ||
|
|
94192feb8f | ||
|
|
af3d9c8502 | ||
|
|
ae98859524 | ||
|
|
70f0bb62f9 | ||
|
|
505e172955 | ||
|
|
d2b2b6a506 | ||
|
|
e2e8aad70a | ||
|
|
4874366e30 | ||
|
|
d2de90ee25 | ||
|
|
a0f93e575e | ||
|
|
b339c9e9c2 | ||
|
|
3425a6672d | ||
|
|
67616266da | ||
|
|
b08e4aa12f | ||
|
|
27411e90da |
No files matched your search
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.14.0</version>
|
||||
<version>2.15.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -21,6 +21,8 @@ public class NBTContainer extends NBTCompound {
|
||||
|
||||
/**
|
||||
* Creates an empty, standalone NBTCompound
|
||||
*
|
||||
* @deprecated use {@link NBT#createNBTObject()}
|
||||
*/
|
||||
@Deprecated
|
||||
public NBTContainer() {
|
||||
|
||||
@@ -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,7 +155,7 @@ public class NBTReflectionUtil {
|
||||
public static void writeApiNBT(NBTCompound comp, OutputStream stream) {
|
||||
try {
|
||||
Object workingtag = comp.getResolvedObject();
|
||||
if(workingtag == null) {
|
||||
if (workingtag == null) {
|
||||
workingtag = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
|
||||
}
|
||||
ReflectionMethod.NBTFILE_WRITE.run(null, workingtag, stream);
|
||||
@@ -216,11 +217,22 @@ public class NBTReflectionUtil {
|
||||
try {
|
||||
Object nmsComp = getToCompount(nbtcompound.getCompound(), nbtcompound);
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
|
||||
if (nbtcompound.hasTag("tag") || nbtcompound.hasTag("Count")) {
|
||||
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 {
|
||||
@@ -239,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);
|
||||
}
|
||||
@@ -386,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 + "'!");
|
||||
}
|
||||
@@ -410,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);
|
||||
@@ -427,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();
|
||||
}
|
||||
@@ -445,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);
|
||||
}
|
||||
@@ -470,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 {
|
||||
@@ -497,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);
|
||||
@@ -525,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) {
|
||||
@@ -557,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";
|
||||
@@ -631,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);
|
||||
@@ -670,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);
|
||||
@@ -693,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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
@@ -31,6 +32,8 @@ public class DataFixerUtil {
|
||||
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)
|
||||
@@ -48,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));
|
||||
}
|
||||
@@ -63,7 +66,11 @@ public class DataFixerUtil {
|
||||
* @return
|
||||
*/
|
||||
public static int getCurrentVersion() {
|
||||
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R2)) {
|
||||
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;
|
||||
|
||||
@@ -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_21_R2(1212, 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.14.0";
|
||||
protected static final String VERSION = "2.15.0";
|
||||
|
||||
private final int versionId;
|
||||
private final boolean mojangMapping;
|
||||
@@ -59,6 +59,8 @@ public enum MinecraftVersion {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -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"),
|
||||
|
||||
+47
@@ -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");
|
||||
}
|
||||
|
||||
};
|
||||
@@ -193,14 +195,59 @@ public class MojangToMapping {
|
||||
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:
|
||||
|
||||
+16
-7
@@ -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[] {},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.14.0</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.14.0</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());
|
||||
|
||||
+69
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,7 +71,7 @@ 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
|
||||
|
||||
+5
-1
@@ -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!");
|
||||
|
||||
+16
-7
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.14.0</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.14.0</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.2.txt");
|
||||
File input = new File("minecraft_server.1.21.4.txt");
|
||||
List<String> lines = Files.readAllLines(input.toPath());
|
||||
|
||||
Map<String, ClassWrapper> classes = new HashMap<>();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.14.0</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.14.0</version>
|
||||
<version>2.15.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.14.0</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.14.0</version>
|
||||
<version>2.15.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.14.0</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.10.1</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>
|
||||
|
||||
@@ -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.14.0</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.14.0</version>
|
||||
<version>2.15.0</version>
|
||||
</dependency>
|
||||
...
|
||||
<plugins>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user