ChunkAPI

ChunkAPI

在区块中轻松管理自定义数据。

一个用于向区块添加自定义数据的模组,无需编写自定义数据包、事件处理、加载钩子等繁琐操作。

基于 LGPLv3 许可证发布

最初由 FalsePattern 开发

模组徽标由 Houstonruss 制作

目标

本模组的目标是提供一种向区块添加自定义数据的方式,而无需修改任何原版类。API 还将提供一种简单的方法来实现数据的自定义序列化/反序列化,无论是用于网络传输还是 NBT 格式。一个可选目标是提供一种为自定义数据注册 DFU 的方式,但这并非优先事项。

非目标

本模组不打算为除保存/加载和网络代码之外的任何内容提供回调/钩子系统,任何额外的行为都应在使用 ChunkAPI 的模组中实现。

API 不提供存储功能,用户需要自行实现存储系统。一个很好的例子是使用 mixin 向区块类添加一个字段,并使用该字段来存储数据。

动机

修改区块数据包涉及对网络数据包、区块类以及 Anvil 区块加载器进行不兼容的修改,这对于一个简单的功能来说工作量太大。本模组提供了一种向区块添加自定义数据的方式,而无需自己修改任何原版类。

API 与规范

API 提供了向区块添加自定义数据的方式,以及为数据注册自定义序列化器的方式。

ChunkDataManager

ChunkDataManager 本身是用于管理注册的主要类,但其自身并不实现功能。为此,您需要使用包含在 ChunkDataManager 类内部的 PacketDataManager、ChunkNBTDataManager 和 SectionNBTDataManager 接口。

ChunkDataManager.PacketData

此接口用于将数据从服务器同步到客户端。如果您的数据仅在服务器端需要,则可以完全跳过实现此接口。

ChunkDataManager.ChunkNBTData

此接口用于从区块 NBT 中保存/加载数据。如果您希望在重新加载世界后保留持久数据,则这是必需的。请注意,如果您将数据按方块存储在区块中,则应改用 SectionNBTData,因为它是针对内部区块格式设计的。

ChunkDataManager.SectionNBTData

此接口与 ChunkNBTData 基本相同,但专为按方块存储区块中的数据而设计。它不是每个区块调用一次,而是每个区块 section(16x16x16 方块,即 ExtendedBlockStage 类)调用一次。

ChunkDataRegistry

这是您实际注册管理器的地方。您需要在 init 阶段完成所有注册。您也可以通过调用 disableDataManager 来禁用特定的管理器 ID,但不推荐这样做,并且只有在您了解其后果时才应使用。您需要在 postInit 阶段完成所有禁用操作。

数据包规范

ChunkAPI 修改了原版的数据包 S21PacketChunkData 和 S26PacketMapChunkBulk,并覆盖了它们的默认格式。

下表中所有大小均以字节为单位。

S21PacketChunkData 新格式:

大小(字节) 数据类型 名称
4 int X 坐标
4 int Z 坐标
1 bool 强制更新
2 short ExtendedBlockStorage 掩码
4 int 未压缩数据长度
4 int (n) 压缩数据长度
n byte[n] 压缩数据

S26PacketMapChunkBulk 新格式:

大小(字节) 数据类型 名称
2 short (n) 数据包中的区块数量
n * 4 int[n] 未压缩的区块数据长度
4 int (m) 压缩数据长度
1 1 包含天空光照数据
m byte[m] 压缩数据
n * 10 (int, int, short)[n] 区块头(x, z, ebs 掩码)

在这两种情况下,压缩数据都是通过 ChunkDataRegistryImpl.writeToBuffer 方法填充的。此数据的布局如下:

大小(字节) 数据类型 名称
4 int (n) 管理器数量
n * 变化 MGRData 管理器数据

管理器数据:

大小(字节) 数据类型 名称
4 int (n) 管理器名称长度
n UTF-8 字符串 管理器名称
4 int (m) 管理器数据长度
m byte[m] 管理器数据

依赖项

FalsePatternLib

UniMixins