You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取Minecraft .mca文件Chunk偏移量错误,求原因及解决方法

问题分析与修复方案

你的程序出现错误主要是三个核心问题导致的:


1. 数组索引偏移错误

你将DataUnsigned8的索引从1开始存储,但文件读取的原始数据是从0开始存放在DataRaw中的。计算每个chunk条目位置时,你用id+1、id+2等取值,相当于把每个4字节的条目整体向后偏移了1位,完全读错了头部数据。

比如第一个chunk的正确字节应该是DataUnsigned8[id]、DataUnsigned8[id+1]、DataUnsigned8[id+2](对应offset的3个字节),以及DataUnsigned8[id+3](对应size的1个字节),而非从id+1开始取值。

2. Offset未转换为实际字节位置

根据Minecraft区域文件规则,头部存储的offset是以4KB(8192字节)为单位的块数,不是直接的字节偏移。你需要将计算出的offset值乘以8192,才能得到chunk在文件中的实际起始字节位置——这也是你预期从8192开始的原因。

3. 不必要的二进制数据修改

你给二进制数据添加了DataRaw[n]='\0',这不仅毫无意义,还可能破坏原始数据(甚至触发数组越界风险),二进制数据不需要以字符串结束符收尾。


修复后的完整代码

#include<bits/stdc++.h>
#include<fstream>
using namespace std;
char DataRaw[4100];
uint8_t DataUnsigned8[4100];
struct F4K{int pos,sz,dfn;} _chunk[40][40];
int main()
{
    ifstream file("first4K.sample",ios::binary|ios::in|ios::ate);
    ifstream::pos_type n=file.tellg();
    freopen("offset.out","w",stdout);
    file.seekg(0);
    file.read((char*)(&DataRaw),n);
    file.close();
    // 索引从0开始,直接映射原始数据
    for (int i=0;i<n;i++)
        DataUnsigned8[i]=uint8_t(DataRaw[i]);
    for (int x=0;x<32;x++)
    {
        for (int z=0;z<32;z++)
        {
            int id=4*(x + z*32);
            // 解析大端字节序的offset,并转换为实际字节位置
            _chunk[x][z].pos = ((DataUnsigned8[id]<<16)|(DataUnsigned8[id+1]<<8)|DataUnsigned8[id+2]) * 8192;
            _chunk[x][z].sz = DataUnsigned8[id+3];
        }
    }
    cout<<" X  Z   offset  sz\n-------------------"<<endl;
    for (int x=0;x<32;x++)
    {
        for (int z=0;z<32;z++)
            cout<<setw(2)<<x<<setw(3)<<z<<setw(9)<<_chunk[x][z].pos<<setw(4)<<_chunk[x][z].sz<<endl;
    }
    return 0;
}

额外提示

如果某个chunk的offset计算后为0,说明该位置的chunk未被生成,后续处理时可以直接跳过这些条目。

内容的提问来源于stack exchange,提问作者CoderCharlie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:40:23