Compare commits

..

2 Commits

3 changed files with 41 additions and 2 deletions

View File

@@ -98,8 +98,8 @@ The offset of a chunk (x,z) (in chunk coordinates) in the first table can be fou
| data | locations (4B) | timestamps (4B) | chunks and unused space | | data | locations (4B) | timestamps (4B) | chunks and unused space |
##### chunk location ##### chunk location
Location info for a chunk is stored as a 32 bit big-endian integer, where the first three bytes are an offset in 4KiB sectors from the start of the file. Location info for a chunk is stored as a 32 bit big-endian integer, where the first three bytes (0xFFFFFF00) are an offset in 4KiB sectors from the start of the file.
The last byte gives the length of the chunk in 4KiB sectors. (rounded up, of course). Where chunks are always less than 1MiB in size. The last byte (0x000000FF) gives the length of the chunk in 4KiB sectors. (rounded up, of course). Where chunks are always less than 1MiB in size.
If a chunk isn't present in the region file (e.g. because it hasn't been generated or migrated yet), both fields are zero. If a chunk isn't present in the region file (e.g. because it hasn't been generated or migrated yet), both fields are zero.
##### timestamps ##### timestamps

24
src/dat/mcx.c Normal file
View File

@@ -0,0 +1,24 @@
#include "mcx.h"
#include <endian.h>
#include <stdint.h>
#include <stdlib.h>
#include "../util/compat/endian.h"
#include "../util/intdef.h"
/* an `*.mcX` contains a `0x2000` byte long table, the first `0x1000` containing
* `0x400` entries of chunk data.
* This chunk data is big-endian, where bytes `0xFFFFFF00` represent the `0x1000` sector offset.
* From the start, and bytes `0x000000FF` represent the length in `0x1000` sectors. */
void mcx_index(const u8 *restrict buf, struct mcx_chunk *restrict chunks) {
const u32 *ptr = (u32 *)buf;
for (uint i = 0; i < 0x400; i++) {
u32 dat = be32toh(ptr[i]);
chunks[i] = (struct mcx_chunk){
.offset = (dat >> 8) * 0x1000,
.length = (dat & 0xFF) * 0x1000,
.time = be32toh(ptr[i + 0x400]),
};
}
}

View File

@@ -2,6 +2,21 @@
// Licensed under the MIT Licence. See LICENSE for details // Licensed under the MIT Licence. See LICENSE for details
#pragma once #pragma once
#include <stdlib.h>
#include "../util/atrb.h"
#include "../util/intdef.h"
/* contains chunk metadata */
struct mcx_chunk {
size_t offset; // byte offset for start of chunk data
u32 length; // byte length of chunk (+ padding)
u32 time; // modification time in epoch seconds
};
/* indexes the chunks in an `*.mcX` file, writing `0x400` of entries to `chunks` */
void mcx_index(const u8 *restrict buf, struct mcx_chunk *restrict chunks) NONNULL((1, 2));
/* the MCR (Minecraft region) and MCA (Minecraft anvil) files are similar /* the MCR (Minecraft region) and MCA (Minecraft anvil) files are similar
* MCA is the newer variant, where it includes: * MCA is the newer variant, where it includes:
* - a world height of 256, rather than 128. * - a world height of 256, rather than 128.