Replaced redundant .map with .for_each
This commit is contained in:
parent
a8d9c89da2
commit
bef3ddef50
@ -107,125 +107,121 @@ impl Level {
|
|||||||
chunks: Vec<ChunkCoordinates>,
|
chunks: Vec<ChunkCoordinates>,
|
||||||
channel: mpsc::Sender<(ChunkCoordinates, Result<ChunkData, WorldError>)>,
|
channel: mpsc::Sender<(ChunkCoordinates, Result<ChunkData, WorldError>)>,
|
||||||
) {
|
) {
|
||||||
chunks
|
chunks.into_par_iter().for_each(|chunk| {
|
||||||
.into_par_iter()
|
let region = (
|
||||||
.map(|chunk| {
|
((chunk.x as f32) / 32.0).floor() as i32,
|
||||||
let region = (
|
((chunk.z as f32) / 32.0).floor() as i32,
|
||||||
((chunk.x as f32) / 32.0).floor() as i32,
|
);
|
||||||
((chunk.z as f32) / 32.0).floor() as i32,
|
let channel = channel.clone();
|
||||||
);
|
|
||||||
let channel = channel.clone();
|
|
||||||
|
|
||||||
// return different error when file is not found (because that means that the chunks have just not been generated yet)
|
// return different error when file is not found (because that means that the chunks have just not been generated yet)
|
||||||
let mut region_file = match OpenOptions::new().read(true).open(
|
let mut region_file = match OpenOptions::new().read(true).open(
|
||||||
self.region_folder
|
self.region_folder
|
||||||
.join(format!("r.{}.{}.mca", region.0, region.1)),
|
.join(format!("r.{}.{}.mca", region.0, region.1)),
|
||||||
) {
|
) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => match err.kind() {
|
Err(err) => match err.kind() {
|
||||||
std::io::ErrorKind::NotFound => {
|
std::io::ErrorKind::NotFound => {
|
||||||
let _ = channel.blocking_send((chunk, Err(WorldError::RegionNotFound)));
|
let _ = channel.blocking_send((chunk, Err(WorldError::RegionNotFound)));
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let _ = channel
|
|
||||||
.blocking_send((chunk, Err(WorldError::IoError(err.kind()))));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut location_table: [u8; 4096] = [0; 4096];
|
|
||||||
let mut timestamp_table: [u8; 4096] = [0; 4096];
|
|
||||||
|
|
||||||
// fill the location and timestamp tables
|
|
||||||
{
|
|
||||||
match region_file.read_exact(&mut location_table) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(err) => {
|
|
||||||
let _ = channel
|
|
||||||
.blocking_send((chunk, Err(WorldError::IoError(err.kind()))));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
match region_file.read_exact(&mut timestamp_table) {
|
_ => {
|
||||||
Ok(_) => {}
|
let _ =
|
||||||
Err(err) => {
|
channel.blocking_send((chunk, Err(WorldError::IoError(err.kind()))));
|
||||||
let _ = channel
|
return;
|
||||||
.blocking_send((chunk, Err(WorldError::IoError(err.kind()))));
|
}
|
||||||
return;
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let mut location_table: [u8; 4096] = [0; 4096];
|
||||||
|
let mut timestamp_table: [u8; 4096] = [0; 4096];
|
||||||
|
|
||||||
|
// fill the location and timestamp tables
|
||||||
|
{
|
||||||
|
match region_file.read_exact(&mut location_table) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
let _ =
|
||||||
|
channel.blocking_send((chunk, Err(WorldError::IoError(err.kind()))));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
match region_file.read_exact(&mut timestamp_table) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
let _ =
|
||||||
|
channel.blocking_send((chunk, Err(WorldError::IoError(err.kind()))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let modulus = |a: i32, b: i32| ((a % b) + b) % b;
|
let modulus = |a: i32, b: i32| ((a % b) + b) % b;
|
||||||
let chunk_x = modulus(chunk.x, 32) as u32;
|
let chunk_x = modulus(chunk.x, 32) as u32;
|
||||||
let chunk_z = modulus(chunk.z, 32) as u32;
|
let chunk_z = modulus(chunk.z, 32) as u32;
|
||||||
let channel = channel.clone();
|
let channel = channel.clone();
|
||||||
let table_entry = (chunk_x + chunk_z * 32) * 4;
|
let table_entry = (chunk_x + chunk_z * 32) * 4;
|
||||||
|
|
||||||
let mut offset = vec![0u8];
|
let mut offset = vec![0u8];
|
||||||
offset.extend_from_slice(
|
offset
|
||||||
&location_table[table_entry as usize..table_entry as usize + 3],
|
.extend_from_slice(&location_table[table_entry as usize..table_entry as usize + 3]);
|
||||||
);
|
let offset = u32::from_be_bytes(offset.try_into().unwrap()) as u64 * 4096;
|
||||||
let offset = u32::from_be_bytes(offset.try_into().unwrap()) as u64 * 4096;
|
let size = location_table[table_entry as usize + 3] as usize * 4096;
|
||||||
let size = location_table[table_entry as usize + 3] as usize * 4096;
|
|
||||||
|
|
||||||
if offset == 0 && size == 0 {
|
if offset == 0 && size == 0 {
|
||||||
let _ = channel.blocking_send((chunk, Err(WorldError::ChunkNotFound)));
|
let _ = channel.blocking_send((chunk, Err(WorldError::ChunkNotFound)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Read the file using the offset and size
|
||||||
|
let mut file_buf = {
|
||||||
|
let seek_result = region_file.seek(std::io::SeekFrom::Start(offset));
|
||||||
|
if seek_result.is_err() {
|
||||||
|
let _ = channel.blocking_send((chunk, Err(WorldError::RegionIsInvalid)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Read the file using the offset and size
|
let mut out = vec![0; size];
|
||||||
let mut file_buf = {
|
let read_result = region_file.read_exact(&mut out);
|
||||||
let seek_result = region_file.seek(std::io::SeekFrom::Start(offset));
|
if read_result.is_err() {
|
||||||
if seek_result.is_err() {
|
let _ = channel.blocking_send((chunk, Err(WorldError::RegionIsInvalid)));
|
||||||
let _ = channel.blocking_send((chunk, Err(WorldError::RegionIsInvalid)));
|
return;
|
||||||
return;
|
}
|
||||||
}
|
out
|
||||||
let mut out = vec![0; size];
|
};
|
||||||
let read_result = region_file.read_exact(&mut out);
|
|
||||||
if read_result.is_err() {
|
|
||||||
let _ = channel.blocking_send((chunk, Err(WorldError::RegionIsInvalid)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
out
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: check checksum to make sure chunk is not corrupted
|
// TODO: check checksum to make sure chunk is not corrupted
|
||||||
let header = file_buf.drain(0..5).collect_vec();
|
let header = file_buf.drain(0..5).collect_vec();
|
||||||
|
|
||||||
let compression = match Compression::from_byte(header[4]) {
|
let compression = match Compression::from_byte(header[4]) {
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
None => {
|
None => {
|
||||||
let _ = channel.blocking_send((
|
let _ = channel.blocking_send((
|
||||||
chunk,
|
chunk,
|
||||||
Err(WorldError::Compression(
|
Err(WorldError::Compression(
|
||||||
CompressionError::UnknownCompression,
|
CompressionError::UnknownCompression,
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = u32::from_be_bytes(header[..4].try_into().unwrap());
|
let size = u32::from_be_bytes(header[..4].try_into().unwrap());
|
||||||
|
|
||||||
// size includes the compression scheme byte, so we need to subtract 1
|
// size includes the compression scheme byte, so we need to subtract 1
|
||||||
let chunk_data = file_buf.drain(0..size as usize - 1).collect_vec();
|
let chunk_data = file_buf.drain(0..size as usize - 1).collect_vec();
|
||||||
let decompressed_chunk = match Self::decompress_data(compression, chunk_data) {
|
let decompressed_chunk = match Self::decompress_data(compression, chunk_data) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
channel
|
channel
|
||||||
.blocking_send((chunk, Err(WorldError::Compression(e))))
|
.blocking_send((chunk, Err(WorldError::Compression(e))))
|
||||||
.expect("Failed to send Compression error");
|
.expect("Failed to send Compression error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
channel
|
channel
|
||||||
.blocking_send((chunk, ChunkData::from_bytes(decompressed_chunk, chunk)))
|
.blocking_send((chunk, ChunkData::from_bytes(decompressed_chunk, chunk)))
|
||||||
.expect("Error sending decompressed chunk");
|
.expect("Error sending decompressed chunk");
|
||||||
})
|
})
|
||||||
.collect::<Vec<()>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decompress_data(
|
fn decompress_data(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user