Minecraft 的 chunk/region 数据中是否缺少 zlib 未压缩大小?
Is Minecraft missing zlib uncompressed size in it's chunk/region data?
关于我的世界区域文件的信息
Minecraft 的区域文件存储在 3 个部分中,前两个部分提供有关区块存储位置的信息,以及有关区块本身的信息。在最后一节中,块以 4 字节数字长度给出,它使用的压缩类型(几乎总是 zlib,RFC1950)
这里有更多(可能更好)的信息:https://minecraft.gamepedia.com/Region_file_format
问题
我有一个程序可以成功加载块数据。但是,我无法找到解压缩时块的大小,因此我只使用分配 space.
时可能需要的最大数量
在播放器数据文件中,它们做给出解压缩时需要的大小,并且(我认为)它使用相同类型的压缩。
player.dat 文件的结尾给出了解压缩数据的大小(在 little-endian 中):
这是块数据的开始,前 4 个字节给出了以下压缩数据中的字节数:
神秘数据
但是,如果我查看压缩数据具体“结束”的位置,它后面还有很多数据。此数据似乎没有用处,但如果我尝试将其中的任何数据与块的其余部分一起解压缩,则会出现错误。
高亮的区块数据和未高亮的神秘数据:
缺少解压大小(header?)
并且没有给出解压缩后的大小(或者 header?我这里可能是错的)。
这个示例块的最终大小是 32,562 字节,这个数字(或任何近邻)在块数据或神秘数据中无处可寻。 (检查了 big-endian 和 little-endian)
解压后的数据终止于索引 32562,(Visual Studio 本地人观看):
最后的问题
有什么我想念的吗?这种压缩实际上与播放器数据压缩不同吗?什么是神秘数据?每次我想从区域文件加载块时,我是否都卡在 1<<20 字节的加载中?
感谢您的任何回答或建议
使用的文件
独立区块数据:https://drive.google.com/file/d/1n3Ix8V8DAgR9v0rkUCXMUuW4LJjT1L8B/view?usp=sharing
全区数据:https://drive.google.com/file/d/15aVdyyKazySaw9ZpXATR4dyvhVtrL6ZW/view?usp=sharing
(出于可能的安全原因未链接玩家数据)
在区域数据中,块数据从索引1208320(或0x127000)开始
您链接的格式信息非常有用。你看过了吗?
在那里它说:“文件的其余部分包含最多 1024 个块的数据,散布着未使用的 space。”此外,“Minecraft 总是 将最后一个块的数据 填充为 multiple-of-4096B 的长度”(斜体字是我的。)所有内容都是 4K 的倍数,所以每个结尾块被填充到下一个 4K 边界。
所以您的“神秘”数据根本不是什么神秘的东西,因为根据格式文档完全可以预期。这些数据简直就是垃圾,可以忽略不计。
请注意,根据文档,块的前三个字节中的数据“长度”实际上比块中数据的字节数多一个(在 five-byte header).
另外从文档来看,格式中确实没有提供未压缩的大小。
zlib 专为流式数据而设计,您无法提前知道会有多少数据。您可以使用 inflate()
解压缩到您喜欢的任何缓冲区大小。如果没有足够的空间来完成,您可以对该数据执行一些操作,然后重复到同一个缓冲区中,或者您可以使用 C 中的 realloc()
或您正在使用的任何语言的等效项来增加缓冲区。 (未在问题或标签中注明。)
关于我的世界区域文件的信息
Minecraft 的区域文件存储在 3 个部分中,前两个部分提供有关区块存储位置的信息,以及有关区块本身的信息。在最后一节中,块以 4 字节数字长度给出,它使用的压缩类型(几乎总是 zlib,RFC1950)
这里有更多(可能更好)的信息:https://minecraft.gamepedia.com/Region_file_format
问题
我有一个程序可以成功加载块数据。但是,我无法找到解压缩时块的大小,因此我只使用分配 space.
时可能需要的最大数量在播放器数据文件中,它们做给出解压缩时需要的大小,并且(我认为)它使用相同类型的压缩。
player.dat 文件的结尾给出了解压缩数据的大小(在 little-endian 中):
这是块数据的开始,前 4 个字节给出了以下压缩数据中的字节数:
神秘数据
但是,如果我查看压缩数据具体“结束”的位置,它后面还有很多数据。此数据似乎没有用处,但如果我尝试将其中的任何数据与块的其余部分一起解压缩,则会出现错误。
高亮的区块数据和未高亮的神秘数据:
缺少解压大小(header?)
并且没有给出解压缩后的大小(或者 header?我这里可能是错的)。 这个示例块的最终大小是 32,562 字节,这个数字(或任何近邻)在块数据或神秘数据中无处可寻。 (检查了 big-endian 和 little-endian)
解压后的数据终止于索引 32562,(Visual Studio 本地人观看):
最后的问题
有什么我想念的吗?这种压缩实际上与播放器数据压缩不同吗?什么是神秘数据?每次我想从区域文件加载块时,我是否都卡在 1<<20 字节的加载中?
感谢您的任何回答或建议
使用的文件
独立区块数据:https://drive.google.com/file/d/1n3Ix8V8DAgR9v0rkUCXMUuW4LJjT1L8B/view?usp=sharing
全区数据:https://drive.google.com/file/d/15aVdyyKazySaw9ZpXATR4dyvhVtrL6ZW/view?usp=sharing
(出于可能的安全原因未链接玩家数据)
在区域数据中,块数据从索引1208320(或0x127000)开始
您链接的格式信息非常有用。你看过了吗?
在那里它说:“文件的其余部分包含最多 1024 个块的数据,散布着未使用的 space。”此外,“Minecraft 总是 将最后一个块的数据 填充为 multiple-of-4096B 的长度”(斜体字是我的。)所有内容都是 4K 的倍数,所以每个结尾块被填充到下一个 4K 边界。
所以您的“神秘”数据根本不是什么神秘的东西,因为根据格式文档完全可以预期。这些数据简直就是垃圾,可以忽略不计。
请注意,根据文档,块的前三个字节中的数据“长度”实际上比块中数据的字节数多一个(在 five-byte header).
另外从文档来看,格式中确实没有提供未压缩的大小。
zlib 专为流式数据而设计,您无法提前知道会有多少数据。您可以使用 inflate()
解压缩到您喜欢的任何缓冲区大小。如果没有足够的空间来完成,您可以对该数据执行一些操作,然后重复到同一个缓冲区中,或者您可以使用 C 中的 realloc()
或您正在使用的任何语言的等效项来增加缓冲区。 (未在问题或标签中注明。)