2.12.0 - 候选版本 1
大家好,这是迄今为止最大的 NBTAPI 更新,这就是为什么我决定在完整的 2.12.0 版本发布之前先推出一个 Minecraft 风格的候选版本(最佳情况下无需任何更改)。此版本包含总共 563 次提交中的 84 次提交(占过去 6-7 年所有提交的近 15%?!),所以请准备好迎接这些变化。
(另外小提醒一下,支持 本项目背后的开发者会非常好,尤其是当您使用此 API 制作付费插件时 😅)
主要变更
- 添加对 Mojang 映射服务器(Paper-Mojmap/Paper 开发模式)的支持
- 添加对 Folia 的支持
- 针对 NBT.get 和 NBT.modify 的重大性能改进(见下文)
- 预览:接口代理,无需编写代码即可访问 NBT(见下文)
- 实体/方块实体修改现在是原子操作且更快,以防止潜在问题
- 实体/方块实体只读操作现在快得多,因为只需获取一次标签
- 添加了 resolveOrNull/resolveOrDefault/resolveCompound/resolveOrCreateCompound。它们接受以
.分隔的字符串作为键,例如tag.othertag.key(示例见下文)
值得注意的变更
- 将 bStats 从版本 1? 更新至 3.0.2
- 减少了 Gson 的日志记录
- 添加了 long[] 支持,通过 setLongArray/getLongArray(1.16+)
- 在错误信息中包含 NBTAPI 版本
- 移除了用户可能注意到的 "functional-annotations" 依赖项遮蔽
- 修复了 NBTFile.saveTo 总是保存根节点而不是传入标签的问题
- 在一些关键位置添加了 @Nullable
- 当 NBT.modify 结束时标签为空,该标签将从物品中移除,而不是保存一个空的
{}标签 - 防止了对 NBT.get/NBT.modify 方法的一些误用
- 新增
set(String key, T value, NBTHandler<T> handler)方法,用于使用提供的处理程序设置您的自定义数据 - 新增
get(String key, NBTHandler<T> handler)方法,用于使用提供的处理程序获取您的自定义数据
其他变更/文档
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/229 中将 license-maven-plugin 从 2.0.1 升级至 2.1.0
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/232 中将 maven-shade-plugin 从 3.4.1 升级至 3.5.0
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/235 中将 license-maven-plugin 从 2.1.0 升级至 2.2.0
- 由 @tr7zw 在 https://github.com/tr7zw/Item-NBT-API/pull/236 中进行只读优化
- 由 @BlackBaroness 在 https://github.com/tr7zw/Item-NBT-API/pull/237 中更新“设置骷髅皮肤”文档
- 由 @BlackBaroness 在 https://github.com/tr7zw/Item-NBT-API/pull/238 中修复文档中的轻微英语错误
- 由 @U5B 在 https://github.com/tr7zw/Item-NBT-API/pull/242 中添加荣誉插件列表提及
- 由 @SoSeDiK 在 https://github.com/tr7zw/Item-NBT-API/pull/243 中修复 Folia 检测和瓷砖实体的 NBT#modify
性能
此版本在底层进行了大量性能优化,主要针对 ItemStacks/Entities/BlockEntities 的 NBT.get 和 NBT.modify 方法。我强烈建议所有人开始更新他们的 NBTItem/NBTEntity/NBTTileEntity 代码以使用这些新方法。
所有基准测试均在我的本地 PC 上的 Paper-171 上进行,对比版本为 2.11.3 与 2.12.0-RC1。数字表示测试用例在一秒内能够运行的次数(JVM 在这些方法上确实有一些预热时间)。但由于这只是单次运行,这些值可能存在 +/-5% 的误差范围,它们仅用于提供大致概念。
物品堆
运行代码的链接。传统测试使用 new NBTItem,而其他测试使用 NBT 类。两个测试获取/设置相同的数据,只是在新旧语法之间切换!
NMS 支持的物品堆:
- LegacyGet: 880.620 -> 909.369 = 快约 3%
- NBT.get: 884.326 -> 4.214.210 = 快约 376%
- LegacySet: 762.453 -> 804.732 = 快约 5%
- NBT.modify: 298.238 -> 1.781.667 = 快约 497%
仅 Bukkit 的物品堆:
- LegacyGet: 215.992 -> 202.413 = 慢约 6%
- NBT.get: 223.998 -> 649.626 = 快约 190%
- LegacySet: 229.485 -> 239.910 = 快约 4%
- NBT.modify: 166.048 -> 567.107 = 快 241%
基本上,切换到新的 NBT.get/NBT.modify 方法,即可获得至少比之前高 200% 的性能。
持久数据容器
为了更好地了解使用 NBTAPI 在物品上存储数据与 Spigot 的持久数据容器 API 的性能,我也检查并比较了这些。同样是在 2.12.0-RC1 上的 Paper-171。在 NMS 支持的物品堆上,普通 PDC 的速度与 NBT.get 大致相同。只有当在 final 类字段中缓存 NamespacedKey 时,PDC 才会领先。写入数据,尤其是在仅 Bukkit 的物品上,要慢得多,但仍然轻松达到每秒 500,000+ 次,因此怀疑这不会是大问题(尤其是考虑到获得了更灵活的 API 和对 1.14 之前版本的支持)。
Resolve 方法
为了简化处理深度嵌套的 NBT,resolve 方法现在允许直接获取或操作这些标签。
复合标签由 . 分隔。如果您需要在键中使用 .,可以使用 \ 进行转义。
示例:
// 将 foo/bar/baz/test 设置为 42
nbt.resolveOrCreateCompound("foo.bar.baz").setInteger("test", 42);
// 获取我们刚刚设置的值或 0
nbt.resolveOrDefault("foo.bar.baz.test", 0);
// 获取我们刚刚设置的值或 null
nbt.resolveOrNull("foo.bar.baz.test", int.class);
// 包含 . 的键示例。设置键 foo/some.key/baz/other
nbt.resolveOrCreateCompound("foo.some\\.key.baz").setInteger("other", 123)
// 获取标签,如果不存在则返回 null
nbt.resolveCompound("some.nested.key");
接口代理
这是一个包含在此版本中的预览功能,API 可能会根据反馈/开发情况进行更改。它允许定义一个具有普通方法/默认方法的接口,NBTAPI 会将 NBT 包装在此接口的自动生成实现中。
以 has/get/set 开头的方法将被解释为各自的调用:
public boolean hasKills(); 运行 return nbt.hasTag("kills");
public void setKills(int amount); 运行 nbt.setInteger("kills", amount);
public int getKills(); 运行 return nbt.getInteger("kills");
支持接口内的默认方法,例如:
public default void addKill() {
setKills(getKills() + 1);
}
也支持让 getter 返回另一个同样扩展了 NBTProxy 的接口。
为了支持像 ItemStacks 这样的其他数据类型,可以使用默认方法重写 init 方法,并使用 registerHandler 方法添加处理程序。例如:
@Override
default void init() {
registerHandler(ItemStack.class, NBTHandlers.ITEM_STACK);
}
要使用您的接口,只需像这样调用 NBT.modify 或 NBT.readNbt:
NBT.modify(item, TestInterface.class, ti -> {
ti.addKill();
//或您接口中的任何其他方法
});
// 此实例只能运行只读方法。调用任何 setter 都将导致异常
TestInterface yourInterface = NBT.readNbt(item, TestInterface.class);
yourInterface .getKills();
完整示例请查看 内置启动测试 或 进行中的 NBT-ItemMeta 代理。也欢迎在 Discord 上提问。
新贡献者
- @BlackBaroness 在 https://github.com/tr7zw/Item-NBT-API/pull/237 中做出了首次贡献
- @U5B 在 https://github.com/tr7zw/Item-NBT-API/pull/242 中做出了首次贡献
完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.11.3...2.12.0-RC1
变更内容
- 更新至 1.21
- 弃用了大量旧方法/构造函数。请迁移至 NBT 类以使用更快且抽象的替代方案
- 为 1.20.5+ 版本添加了新的 NBT.modifyComponents API,用于修改原版组件
- 移除了 nbt-injector(您确实不应使用此功能)和 nbt-data-api(从未完成)。此举大幅减少了 jar 文件的冗余
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/279 中将 org.apache.maven.plugins:maven-javadoc-plugin 从 3.6.3 升级至 3.7.0
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/278 中将 org.apache.maven.plugins:maven-shade-plugin 从 3.5.3 升级至 3.6.0
完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.12.4...2.13.0
变更内容
- 添加对 1.20.5 和 1.20.6 的支持
- 添加 Datafixer 支持,用于将物品 NBT 升级到更新版本
- 在使用
NBT.itemStackFromNBT及相关方法时自动升级旧的 ItemStack(它将假设 NBT 为 1.20.4 数据,否则请先使用 Datafixer 自行升级 NBT) - 修复 Mojang 映射服务器上的 BlockEntity 错误
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/273 中将 org.apache.maven.plugins:maven-source-plugin 从 3.3.0 升级到 3.3.1
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/277 中将 org.apache.maven.plugins:maven-shade-plugin 从 3.5.2 升级到 3.5.3
注意
由于 Mojang 更改了 ItemStack 在运行时的处理方式,在 1.20.5+ 版本中,已加载的 ItemStack 上将不再显示原版 NBT。因此,修改原版数据的方式将不再与 1.8-1.20.4 相同,所有插件都需要更新以适配此变化。如有疑问,欢迎在 Discord 上提问。
完整更新日志:https://github.com/tr7zw/Item-NBT-API/compare/2.12.3...2.12.4
变更内容
- 添加对未重映射的 Paper 1.20+ 的支持
其他变更
- 将 org.apache.maven.plugins:maven-compiler-plugin 从 3.11.0 升级至 3.12.0,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/261 完成
- 将 org.apache.maven.plugins:maven-compiler-plugin 从 3.12.0 升级至 3.12.1,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/263 完成
- 更新 LICENSE 版权年份至 2024,由 @SmartGecko44 在 https://github.com/tr7zw/Item-NBT-API/pull/264 完成
- 将 org.codehaus.mojo:license-maven-plugin 从 2.3.0 升级至 2.4.0,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/265 完成
- 将 org.apache.maven.plugins:maven-shade-plugin 从 3.5.1 升级至 3.5.2,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/267 完成
- 将 org.apache.maven.plugins:maven-compiler-plugin 从 3.12.1 升级至 3.13.0,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/270 完成
新贡献者
- @SmartGecko44 在 https://github.com/tr7zw/Item-NBT-API/pull/264 中完成了首次贡献
完整变更日志:https://github.com/tr7zw/Item-NBT-API/compare/2.12.2...2.12.3
变更内容
- 添加 1.20.4 支持
- 将 org.apache.maven.plugins:maven-javadoc-plugin 从 3.6.0 升级至 3.6.2,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/256 完成
- 将 org.apache.maven.plugins:maven-javadoc-plugin 从 3.6.2 升级至 3.6.3,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/258 完成
完整更新日志: https://github.com/tr7zw/Item-NBT-API/compare/2.12.1...2.12.2
变更内容
- 修复 1.19R3 使用了错误的映射,导致测试失败
- 修复 1.20R2 的内部版本 ID
- 将 org.apache.maven.plugins:maven-shade-plugin 从 3.5.0 升级到 3.5.1,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/250 完成
- 将 org.codehaus.mojo:license-maven-plugin 从 2.2.0 升级到 2.3.0,由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/253 完成
完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.12.0...2.12.1
2.12.0
大家好,这是迄今为止最大的 NBTAPI 更新。此次发布包含了总共 580 次提交中的 100 次提交(占过去 7 年所有提交的 17%?!),所以请系好安全带准备迎接这些变化。
(另外小提醒一下,支持 本项目背后的开发者会非常好,尤其是当您使用此 API 制作付费插件时 😅)
2.12.0-RC1 和 2.12.0 之间的后期变更:
- 添加 1.20.2 支持
- 修复空 ItemStack 上的 getKeys
- 修复空 ItemStack 上的 modifyMeta
- 添加对 ProxiedLists 的支持
- 添加在 resolve 方法中使用如 [123] 或 [-1] 等索引的支持
- 强制阻止 Jitpack。如果您因任何原因使用 Jitpack,请查看 wiki 以使用正确的仓库!
主要变更
- 添加对 Mojang 映射服务器(Paper-Mojmap/Paper 开发模式)的支持
- 添加对 Folia 的支持
- NBT.get 和 NBT.modify 的重大性能改进(见下文)
- 预览:接口代理,无需编写代码即可访问 NBT(见下文)
- Entity/BlockEntity 修改现在是原子的且更快,以防止陷阱
- Entity/BlockEntity 只读现在快得多,因为只获取一次标签
- 添加了 resolveOrNull/resolveOrDefault/resolveCompound/resolveOrCreateCompound。它们接受用
.分隔的字符串作为键,例如tag.othertag.key(示例见下文)
值得注意的变更
- 将 bStats 从版本 1? 更新至 3.0.2
- 减少了 Gson 的日志记录
- 通过 setLongArray/getLongArray 添加 long[] 支持(1.16+)
- 在错误中包含 NBTAPI 版本
- 移除了用户可能注意到的 "functional-annotations" 依赖阴影
- 修复了 NBTFile.saveTo 总是保存根节点而不是传入的标签的问题
- 在一些关键位置添加了 @Nullable
- 当 NBT.modify 结束时标签为空,该标签将从物品中移除,而不是保存一个空的
{}标签 - 防止了对 NBT.get/NBT.modify 方法的一些误用
- 新的
set(String key, T value, NBTHandler<T> handler)方法,用于使用提供的处理程序设置您的自定义数据 - 新的
get(String key, NBTHandler<T> handler)方法,用于使用提供的处理程序获取您的自定义数据
其他变更/文档
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/229 中将 license-maven-plugin 从 2.0.1 升级至 2.1.0
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/232 中将 maven-shade-plugin 从 3.4.1 升级至 3.5.0
- 由 @dependabot 在 https://github.com/tr7zw/Item-NBT-API/pull/235 中将 license-maven-plugin 从 2.1.0 升级至 2.2.0
- 由 @tr7zw 在 https://github.com/tr7zw/Item-NBT-API/pull/236 中进行只读优化
- 由 @BlackBaroness 在 https://github.com/tr7zw/Item-NBT-API/pull/237 中更新“设置头颅皮肤”文档
- 由 @BlackBaroness 在 https://github.com/tr7zw/Item-NBT-API/pull/238 中修复文档中的轻微英语错误
- 由 @U5B 在 https://github.com/tr7zw/Item-NBT-API/pull/242 中添加荣誉插件列表提及
- 由 @SoSeDiK 在 https://github.com/tr7zw/Item-NBT-API/pull/243 中修复 Folia 检测和 Tile Entities 的 NBT#modify
性能
此版本在底层进行了大量性能优化,主要针对 ItemStacks/Entities/BlockEntities 的 NBT.get 和 NBT.modify 方法。我强烈建议所有人开始更新他们的 NBTItem/NBTEntity/NBTTileEntity 代码以使用这些新方法。
所有基准测试均在我本地 PC 的 Paper-171 上完成,对比版本为 2.11.3 与 2.12.0-RC1。数字表示测试用例在一秒内能够运行的次数(JVM 在这些方法上之前有一些预热时间)。但由于这只是单次运行,这些值可能存在 +-5% 的误差范围,它们仅用于提供大致概念。
Itemstacks
运行代码的链接。遗留测试使用 new NBTItem,而其他测试使用 NBT 类。两个测试获取/设置相同的数据,只是在新旧语法之间切换!
NMS 支持的 Itemstacks:
- LegacyGet: 880.620 -> 909.369 = 快约 3%
- NBT.get: 884.326 -> 4.214.210 = 快约 376%
- LegacySet: 762.453 -> 804.732 = 快约 5%
- NBT.modify: 298.238 -> 1.781.667 = 快约 497%
仅 Bukkit 的 Itemstacks:
- LegacyGet: 215.992 -> 202.413 = 慢约 6%
- NBT.get: 223.998 -> 649.626 = 快约 190%
- LegacySet: 229.485 -> 239.910 = 快约 4%
- NBT.modify: 166.048 -> 567.107 = 快 241%
基本上,切换到新的 NBT.get/NBT.modify 方法,即可获得比之前至少 200% 的性能提升。
Persistent Data Container
为了更好地理解使用 NBTAPI 在物品上存储数据与 Spigot 的 Persistent Data Container API 的性能差异,我也检查并比较了这些。同样是在 2.12.0-RC1 的 Paper-171 上。在 NMS 支持的 Itemstacks 上,普通 PDC 的速度与 NBT.get 大致相同。只有当将 NamespacedKey 缓存到 final 类字段中时,PDC 才会领先。写入数据,尤其是在仅 Bukkit 的物品上,要慢得多,但仍然轻松达到每秒 500,000+ 次,因此怀疑这不会是大问题(特别是考虑到获得了更灵活的 API 和对 1.14 之前版本的支持)。
Resolve 方法
为了简化处理深度嵌套的 NBT,resolve 方法现在允许直接获取或操作这些标签。
复合标签由 . 分隔。如果您需要在键中使用 .,可以用 \ 进行转义。
示例:
// 将 foo/bar/baz/test 设置为 42
nbt.resolveOrCreateCompound("foo.bar.baz").setInteger("test", 42);
// 获取我们刚刚设置的值或 0
nbt.resolveOrDefault("foo.bar.baz.test", 0);
// 获取我们刚刚设置的值或 null
nbt.resolveOrNull("foo.bar.baz.test", int.class);
// 包含 . 的键的示例。设置键 foo/some.key/baz/other
nbt.resolveOrCreateCompound("foo.some\\.key.baz").setInteger("other", 123)
// 获取标签,如果不存在则返回 null
nbt.resolveCompound("some.nested.key");
接口代理
这是一个包含在此版本中的预览功能,API 可能会根据反馈/开发情况进行更改。它允许定义一个具有普通方法/默认方法的接口,NBTAPI 会将 NBT 包装在此接口的自动生成实现中。
以 has/get/set 开头的方法将被解释为相应的调用:
public boolean hasKills(); 运行 return nbt.hasTag("kills");
public void setKills(int amount); 运行 nbt.setInteger("kills", amount);
public int getKills(); 运行 return nbt.getInteger("kills");
支持接口内的默认方法,例如:
public default void addKill() {
setKills(getKills() + 1);
}
也支持让 getter 返回另一个同样扩展了 NBTProxy 的接口。
为了支持像 ItemStacks 这样的其他数据类型,可以使用默认方法重写 init 方法,并使用 registerHandler 方法添加处理程序。例如:
@Override
default void init() {
registerHandler(ItemStack.class, NBTHandlers.ITEM_STACK);
}
现在要使用您的接口,只需像这样调用 NBT.modify 或 NBT.readNbt:
NBT.modify(item, TestInterface.class, ti -> {
ti.addKill();
//或您接口中的任何其他方法
});
// 此实例只能运行只读方法。调用任何 setter 都将导致异常
TestInterface yourInterface = NBT.readNbt(item, TestInterface.class);
yourInterface .getKills();
完整示例请查看 内置启动测试 或 进行中的 NBT-ItemMeta 代理。也欢迎在 Discord 上提问。
新贡献者
- @BlackBaroness 在 https://github.com/tr7zw/Item-NBT-API/pull/237 中做出了首次贡献
- @U5B 在 https://github.com/tr7zw/Item-NBT-API/pull/242 中做出了首次贡献
完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.11.3...2.12.0-RC1
变更内容
- 修复合并 ReadableNBT 时出现的 StackOverflowError,由 @Kevin-OVI 在 https://github.com/tr7zw/Item-NBT-API/pull/204 中提交
新贡献者
- @Kevin-OVI 在 https://github.com/tr7zw/Item-NBT-API/pull/204 中完成了首次贡献
完整更新日志: https://github.com/tr7zw/Item-NBT-API/compare/2.11.0...2.11.1
新的 NBTAPI 主要版本发布,增加了 1.19.3 支持以及一种与 API 交互的新方式。
变更:
- 支持 1.19.3
- 为大多数 NBT 逻辑添加了接口,包括只读版本
- 添加了一个新的工具类
NBT,它提供简洁的 Lambda 访问方式来读写 NBT。https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API 已更新关于如何使用该类的示例。 - 为 NBTFile 添加了实用方法
readFrom/saveTo hasTag作为hasKey的替代方案,返回boolean而非Boolean- 添加了
getOrDefault方法 - 添加了
getOrNull方法 - 弃用
setObject/getObject,请使用您喜欢的库/设置自行进行序列化 getUUID/setUUID现在将自动正确处理 1.16 之前和之后的格式- 如果未找到标签,
getItemStack现在将返回 null getKeys现在是 Set 的副本,不再链接到 NMS 内部对象- 添加了
setItemStackArray/getItemStackArray方法 - 为 ItemStacks 添加了
modifyMeta方法。不要在 modifyMeta 作用域内修改 NBT - Wiki 现已移至 Github 仓库中,因此任何人都可以提交 Pull Request 以添加示例、澄清说明等。
NBTItem现在将正确拒绝大小为 0 的 ItemStacks- 更新了大量 Javadoc
- 完整的 API Javadoc 现可在 https://tr7zw.github.io/Item-NBT-API/v2-api/ 获取
- 通过 Maven/Gradle 拉取 NBTAPI 插件现在也将正确包含 API Javadoc(此前仅包含插件 Javadoc)
- 修复了错误报告期间的小型 NPE 错误(颇具讽刺意味)
NBTCompoundList现在扩展NBTList<ReadWriteNBT>而非NBTList<NBTListCompound>。这是一个编译时破坏性变更,代码需要相应更新。已发布的插件不应受此影响。

Bukkit
Folia
Paper
Spigot