0

私は現在、Minecraft マップ (プレイヤー データとチャンク自体の両方) を編集するための NBT リーダーとライターに取り組んでいます。NBTData の読み取りがすべて完了し、level.dat ファイルを書き込んでプレーヤー データを編集することができました。

残念ながら、Minecraft が圧縮方法を受け入れないため、NBT バイナリ データをリージョン ファイルに書き込むことができません。編集したチャンクを読み込もうとすると、ZLib 圧縮の末尾が見つからない、または圧縮方法が無効であるというエラーが表示されます (ターミナル経由で minecraft を起動すると、これらのエラーが発生しました)。

Mac OSX に付属の ZLib ライブラリを使用しており、エディタは C++ で記述されています。

これが私の圧縮コードです:

compressionData* compress(unsigned char* buf, int size)
{
    vector<char> data = vector<char>();
    for(int i = 0;i<size;i++)
        data.push_back(buf[i]);

    int ret;
    z_stream zs;
    char buff[4096];
    std::vector<char> out_data;

    // initialize zlib structure
    memset(&zs, 0, sizeof(zs));
    if(deflateInit(&zs, Z_BEST_COMPRESSION) != Z_OK)
        return false;
    zs.next_in = (Bytef *) data.data();
    zs.avail_in = data.size();

    // deflate blocks
    do {
        zs.next_out = reinterpret_cast<Bytef *>(buff);
        zs.avail_out = 4096;

        // deflate data and place in out_data
        ret = deflate(&zs, Z_FINISH);
        out_data.insert(out_data.end(), buff, buff + zs.total_out);
    } while(ret == Z_OK);

    // check for errors
    deflateEnd(&zs);
    if (ret != Z_STREAM_END)
        return false;

    // assign to data
    data = out_data;

    compressionData *rett = new compressionData();
    rett->buf = (unsigned char*)malloc(data.size());
    SharedStats::getSharedStats()->mallocated++;
    for(int i = 0;i<data.size();i++)
        rett->buf[i] = data.at(i);

    rett->size = (int)data.size();

    return rett;
}

compressionData オブジェクトは、データを含む unsigned char 配列と、データの長さをバイト単位で示す int のみを保持する構造体です。

Minecraft チャンクにはどの ZLib 暗号化方式を使用すればよいですか? 元の入力チャンクは常に次の 3 バイトで始まります: 02 78 9C、私のチャンクは 02 78 DA で始まります。

チャンクからのすべてのデータはリージョン ファイルに書き込まれ、Minecraft はそれらを認識しますが、圧縮方法が気に入らないだけです。

グレイト、アラン

4

1 に答える 1