Bedrock World Operator 是一个以 Go 语言为底层,以动态库调用的方式,皆在为 Python 提供一个效率足够的我的世界基岩版存档操作器。
存档操作器的主要目的在于为网易我的世界基岩版(v1.21.0)提供支持(但不包含解密其存档的实现),即,提供了相关的函数可以将子区块解码或编码为网端格式(Network Encoding),以供在网络传输区块上使用。
您可以前往 version.go 并将 const UseNeteaseBlockStates = true
改为 const UseNeteaseBlockStates = false
以将本操作器作为国际版(v1.21.0)的使用。
需要注意的是,为了减少内存开销,我们会先使用 main.go 生成 block_states.bin
,因此您需要确保您已运行此文件以得到正确的 block_states.bin
。
可以通过替换 standard_block_states.nbt 为最新版本的我的世界的方块状态表来将本操作器用于最新版我的世界,而非仅仅 v1.21.0 版本。关于这个表来自哪里,请参见 dragonfly。
另外,version.go 中的 UseNetworkBlockRuntimeID
常量控制是否应当使用方块的哈希作为其运行时 ID(Block Runtime ID),而不是在预期的方块调色板中使用其索引。我们将此选项默认设置为开,这意味着我们使用哈希而非预期的调色板索引。
关于该字段的更多信息,详见 packet.StartGame & UseBlockNetworkIDHashes。
除此外,encoding.go 中的 DecodeBlockState
函数使用了 blockupgrader,它用于将旧版的旧方块状态升级到最新版本。然而,由于我们目前支持的是 v1.21.0
版本的我的世界,所以它只会升级到 v1.21.0
版本的方块状态。如果您有任何需要(例如升级到更高版本的我的世界的方块状态),请自行更改 go.mod 中 blockupgrader
的版本(目前我们使用 v1.0.15
)
需要指出的是,Python 的内存中几乎不会维护存档的任何部分,在大部分情况下,存档中的区块或子区块,甚至是 Python 创建的区块或子区块,都由 Go 进行管理,而 Python 只控制这些内存的回收。
另外,Go 部分的大部分代码参阅并修改自该存储库,您可以通过它进行更深入的研究(如果可能)。
由于 Bedrock World Operator 是基于 Go 提供动态库供 Python 调用的实现,所以不可避免的,未被包含在下述列表内的操作系统及架构不受支持。 当然,我们随时欢迎发起 Pull Request。
- Windows
- x86_64/amd64
- x86/i686
- Darwin (MacOS)
- x86_64/amd64
- arm64/aarch64
- Linux
- x86_64/amd64
- arm64
- aarch64 (Termux on Android)
您可以通过参阅此文件来了解 Bedrock World Operator 加载相应动态库的具体逻辑。
Bedrock World Operator 基于以区块坐标(Chunk Pos)、子区块坐标(Sub Chunk Pos)、区块高度范围(Range)、维度(Dimension)、方块及状态(Block States)的定义,实现了区块(Chunk)、子区块(Sub Chunk)的定义。
在上面定义的基础上,Bedrock World Operator 提供一系列基本函数,允许使用者操作区块或子区块中的成分,然后将修改后的数据存入基岩版我的世界存档。
目前已经实现了区块、子区块、生物群落、区块方块实体数据的读写,还没有支持生物数据、玩家数据的读写。目前不考虑将这些未实现的部分纳入未来的更新计划,但欢迎发起 Pull Request。
除了以上基本的标准基岩版我的世界操作实现外,我们根据我们自己的其他需求提供了其他的一些实现,例如可以保存子区块的 Blob hash,或保存区块的最后更新时间。
当然,除了提供以上操作实现外,我们还提供了一些实用函数,如下。
- 允许将使用者将子区块编码为网端或磁盘端,或把已经编码的二进制解码为子区块。
- 可以把方块运行时(Block Runtime ID)转换为方块名及其状态,或者进行其逆过程。
对于曾经的 0.0.x
版本是不考虑后向兼容性的,因为那时仍处于早期开发阶段。
不过,任何的 1.x.x
版本都将考虑后向兼容性,但不保证 2.x.x
版本可以与 1.x.x
版本兼容。
from .world.chunk import Chunk, new_chunk
from .world.sub_chunk import SubChunk, SubChunkWithIndex, new_sub_chunk
from .world.world import World, new_world
from .world.level_dat import LevelDat, Abilities
from .world.constant import (
EMPTY_COMPOUND,
EMPTY_BLOCK_STATES,
DIMENSION_ID_OVERWORLD,
DIMENSION_ID_NETHER,
DIMENSION_ID_END,
DIMENSION_OVERWORLD,
DIMENSION_NETHER,
DIMENSION_END,
RANGE_OVERWORLD,
RANGE_NETHER,
RANGE_END,
RANGE_INVALID,
AIR_BLOCK_STATES,
AIR_BLOCK_RUNTIME_ID,
)
from .world.define import (
ChunkPos,
SubChunkPos,
Range,
Dimension,
BlockStates,
QuickChunkBlocks,
QuickSubChunkBlocks,
HashWithPosY,
)
from .world.conversion import (
runtime_id_to_state,
state_to_runtime_id,
sub_chunk_network_payload,
from_sub_chunk_network_payload,
sub_chunk_disk_payload,
from_sub_chunk_disk_payload,
)
from nbtlib.tag import Compound, String, Byte, Int
我们默认导出了以上类、常量及函数,下面将阐述几个重要的函数。
new_chunk
- 创建一个新的区块new_sub_chunk
- 创建一个新的子区块new_world
- 打开或创建一个基岩版存档
在通过上面三个函数得到区块、子区块或存档以后,您可以利用这些类下面实现的各个函数来进行更多操作。
我们在所有对外公开的函数中都提供了足够详尽的注释,因此您不必担心太多。所以,我们不会再提供额外的文档。
您不应该调用任何来自 internal
包的函数,因为它们都只是纯粹的内部实现。
如果您希望对此项目进行贡献,那么您可能需要研究这个包,但更多的,请参阅存储库中的 c_api
及 world
所指示的 Go 实现。
我们已将此存储库以 bedrock-world-operator 的名字上载到 Pypi ,您可以通过 pip install bedrock-world-operator
快速安装。
访问 📦 bedrock-world-operator on Pypi 以了解有关此库的更多信息。
我们配置了自动化 CD/CI 工作流,因此如果您是本项目的协作者,您可以通过更改 version 文件或通过手动触发的方式启动工作流,它会自动编译本项目并将将其上载到 Pypi 中。
本项目依照 MIT LICENSE 许可证进行许可和授权。