跳转到内容
我的世界XyeBBS论坛3群 进群吹水聊天!众多整合包作者、插件作者、玩家在内哦!不定时发福利,公布重要通知!
...

NBT-API

(NBT-API)
无需 NMS 即可为物品/方块/实体添加自定义 NBT 标签
仅客户端前置API
NBT-API - 2.12.0-RC12026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

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) 方法,用于使用提供的处理程序获取您的自定义数据

其他变更/文档

性能

此版本在底层进行了大量性能优化,主要针对 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 上提问。

新贡献者

完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.11.3...2.12.0-RC1

NBT-API - 2.13.02026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

变更内容

  • 更新至 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

NBT-API - 2.12.42026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

变更内容

  • 添加对 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

NBT-API - 2.12.32026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

变更内容

  • 添加对未重映射的 Paper 1.20+ 的支持

其他变更

新贡献者

完整变更日志:https://github.com/tr7zw/Item-NBT-API/compare/2.12.2...2.12.3

NBT-API - 2.12.22026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

变更内容

完整更新日志: https://github.com/tr7zw/Item-NBT-API/compare/2.12.1...2.12.2

NBT-API - 2.12.12026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

变更内容

完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.12.0...2.12.1

NBT-API - 2.12.02026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

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) 方法,用于使用提供的处理程序获取您的自定义数据

其他变更/文档

性能

此版本在底层进行了大量性能优化,主要针对 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 上提问。

新贡献者

完整变更日志: https://github.com/tr7zw/Item-NBT-API/compare/2.11.3...2.12.0-RC1

NBT-API - 2.11.12026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

变更内容

新贡献者

完整更新日志: https://github.com/tr7zw/Item-NBT-API/compare/2.11.0...2.11.1

NBT-API - 2.10.02026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

已添加:

  • 支持 1.19
  • 支持 1.7.10 Crucible(请使用最新版本)。感谢 EverNife
NBT-API - 2.11.02026-09-14 05:09:39
核心/平台支持
运行环境/下载方式
客户端站外下载

新的 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>。这是一个编译时破坏性变更,代码需要相应更新。已发布的插件不应受此影响。