MCPcopy Create free account
hub / github.com/HairlessVillager/minecommit / read_region

Function read_region

minecommit/src/utils/region.rs:11–88  ·  view source on GitHub ↗
(
    mut buf: B,
    region_x: i32,
    region_z: i32,
)

Source from the content-addressed store, hash-verified

9/// Returns None if the file is empty or has no chunks.
10#[must_use]
11pub fn read_region<B: Read + Seek>(
12 mut buf: B,
13 region_x: i32,
14 region_z: i32,
15) -> Result<Option<([u8; 4096], Vec<(i32, i32, Vec<u8>)>)>> {
16 let mut locations = [0u8; 4096];
17 if let Err(err) = buf.read_exact(&mut locations) {
18 if err.kind() == std::io::ErrorKind::UnexpectedEof {
19 return Ok(None);
20 }
21 }
22
23 let mut timestamps = [0u8; 4096];
24 buf.read_exact(&mut timestamps)
25 .context("buffer's length < 8192")?;
26
27 let mut compressed_chunks = Vec::new();
28
29 for i in 0..1024usize {
30 let loc = &locations[i * 4..(i + 1) * 4];
31 let offset = u32::from_be_bytes([0, loc[0], loc[1], loc[2]]) as usize;
32 let size = loc[3] as usize;
33
34 if offset == 0 && size == 0 {
35 continue;
36 }
37
38 let byte_offset = offset * SECTOR_SIZE;
39 buf.seek(SeekStart(byte_offset as u64))
40 .with_context(|| format!("at chunk #{i}: failed to seek {byte_offset}"))?;
41
42 let mut header = [0u8; 5];
43 buf.read_exact(&mut header)
44 .with_context(|| format!("at chunk #{i}: failed to read chunk header"))?;
45
46 let data_length = u32::from_be_bytes([header[0], header[1], header[2], header[3]]) as usize;
47 let compression_type = header[4];
48
49 let compressed_len = data_length.saturating_sub(1);
50 let mut compressed_data = vec![0u8; compressed_len];
51 buf.read_exact(&mut compressed_data).with_context(|| {
52 format!("at chunk #{i}: failed to read chunk body (length: {compressed_len})")
53 })?;
54
55 compressed_chunks.push((i, compression_type, compressed_data));
56 }
57
58 let chunks: Vec<(i32, i32, Vec<u8>)> = compressed_chunks
59 .into_par_iter()
60 .filter_map(|(i, compression_type, compressed)| {
61 if compression_type == 2 {
62 let mut decoder = ZlibDecoder::new(&compressed[..]);
63 let mut nbt = Vec::new();
64 match decoder.read_to_end(&mut nbt) {
65 Ok(_) => {
66 let local_x = (i % 32) as i32;
67 let local_z = (i / 32) as i32;
68 return Some((region_x * 32 + local_x, region_z * 32 + local_z, nbt));

Callers 4

mainFunction · 0.85
flattenMethod · 0.85
flattenMethod · 0.85
flattenMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected