Anvil: Added LV4 Compression
This commit is contained in:
parent
df80ac2837
commit
3eacf1e6c0
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -1446,6 +1446,25 @@ version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "lz4"
|
||||
version = "1.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d1febb2b4a79ddd1980eede06a8f7902197960aa0383ffcfdd62fe723036725"
|
||||
dependencies = [
|
||||
"lz4-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lz4-sys"
|
||||
version = "1.11.1+lz4-1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
version = "0.4.2"
|
||||
@ -2022,6 +2041,7 @@ dependencies = [
|
||||
"futures",
|
||||
"itertools 0.13.0",
|
||||
"log",
|
||||
"lz4",
|
||||
"noise",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
|
||||
@ -14,7 +14,12 @@ derive_more.workspace = true
|
||||
itertools.workspace = true
|
||||
thiserror = "1.0"
|
||||
futures = "0.3"
|
||||
|
||||
|
||||
# Compression
|
||||
flate2 = "1.0"
|
||||
lz4 = "1.11.1"
|
||||
|
||||
serde.workspace = true
|
||||
serde_json = "1.0"
|
||||
log.workspace = true
|
||||
|
||||
@ -26,41 +26,60 @@ impl AnvilChunkReader {
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Compression {
|
||||
Gzip,
|
||||
Zlib,
|
||||
/// GZip Compression
|
||||
GZip,
|
||||
/// ZLib Compression
|
||||
ZLib,
|
||||
/// Uncompressed (since a version before 1.15.1)
|
||||
None,
|
||||
/// LZ4 Compression (since 24w04a)
|
||||
LZ4,
|
||||
/// Custom compression algorithm (since 24w05a)
|
||||
Custom,
|
||||
}
|
||||
|
||||
impl Compression {
|
||||
pub fn from_byte(byte: u8) -> Option<Self> {
|
||||
match byte {
|
||||
1 => Some(Self::Gzip),
|
||||
2 => Some(Self::Zlib),
|
||||
1 => Some(Self::GZip),
|
||||
2 => Some(Self::ZLib),
|
||||
3 => Some(Self::None),
|
||||
4 => Some(Self::LZ4),
|
||||
// Creative i guess?
|
||||
127 => Some(Self::Custom),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn decompress_data(&self, compressed_data: Vec<u8>) -> Result<Vec<u8>, CompressionError> {
|
||||
match self {
|
||||
Compression::Gzip => {
|
||||
let mut z = GzDecoder::new(&compressed_data[..]);
|
||||
let mut chunk_data = Vec::with_capacity(compressed_data.len());
|
||||
z.read_to_end(&mut chunk_data)
|
||||
Compression::GZip => {
|
||||
let mut decoder = GzDecoder::new(&compressed_data[..]);
|
||||
let mut chunk_data = Vec::new();
|
||||
decoder
|
||||
.read_to_end(&mut chunk_data)
|
||||
.map_err(CompressionError::GZipError)?;
|
||||
Ok(chunk_data)
|
||||
}
|
||||
Compression::Zlib => {
|
||||
let mut z = ZlibDecoder::new(&compressed_data[..]);
|
||||
let mut chunk_data = Vec::with_capacity(compressed_data.len());
|
||||
z.read_to_end(&mut chunk_data)
|
||||
Compression::ZLib => {
|
||||
let mut decoder = ZlibDecoder::new(&compressed_data[..]);
|
||||
let mut chunk_data = Vec::new();
|
||||
decoder
|
||||
.read_to_end(&mut chunk_data)
|
||||
.map_err(CompressionError::ZlibError)?;
|
||||
Ok(chunk_data)
|
||||
}
|
||||
Compression::None => Ok(compressed_data),
|
||||
Compression::LZ4 => todo!(),
|
||||
Compression::LZ4 => {
|
||||
let mut decoder = lz4::Decoder::new(compressed_data.as_slice())
|
||||
.map_err(CompressionError::LZ4Error)?;
|
||||
let mut decompressed_data = Vec::new();
|
||||
decoder
|
||||
.read_to_end(&mut decompressed_data)
|
||||
.map_err(CompressionError::LZ4Error)?;
|
||||
Ok(decompressed_data)
|
||||
}
|
||||
Compression::Custom => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,8 @@ pub enum CompressionError {
|
||||
ZlibError(std::io::Error),
|
||||
#[error("Error while working with Gzip compression: {0}")]
|
||||
GZipError(std::io::Error),
|
||||
#[error("Error while working with LZ4 compression: {0}")]
|
||||
LZ4Error(std::io::Error),
|
||||
}
|
||||
|
||||
pub struct ChunkData {
|
||||
|
||||
@ -3,7 +3,6 @@ use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
||||
use parking_lot::Mutex;
|
||||
use pumpkin_core::math::vector2::Vector2;
|
||||
use rayon::prelude::*;
|
||||
use thiserror::Error;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
@ -33,9 +32,6 @@ pub struct SaveFile {
|
||||
pub region_folder: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum WorldError {}
|
||||
|
||||
impl Level {
|
||||
pub fn from_root_folder(root_folder: PathBuf) -> Self {
|
||||
let world_gen = get_world_gen(Seed(0)); // TODO Read Seed from config.
|
||||
@ -79,7 +75,7 @@ impl Level {
|
||||
pub fn fetch_chunks(
|
||||
&self,
|
||||
chunks: &[Vector2<i32>],
|
||||
channel: mpsc::Sender<Result<Arc<ChunkData>, WorldError>>,
|
||||
channel: mpsc::Sender<Arc<ChunkData>>,
|
||||
is_alive: bool,
|
||||
) {
|
||||
chunks.into_par_iter().for_each(|at| {
|
||||
@ -92,7 +88,7 @@ impl Level {
|
||||
// Check if chunks is already loaded
|
||||
if loaded_chunks.contains_key(at) {
|
||||
channel
|
||||
.blocking_send(Ok(loaded_chunks.get(at).unwrap().clone()))
|
||||
.blocking_send(loaded_chunks.get(at).unwrap().clone())
|
||||
.expect("Failed sending ChunkData.");
|
||||
return;
|
||||
}
|
||||
@ -116,7 +112,7 @@ impl Level {
|
||||
.unwrap();
|
||||
let data = Arc::new(data);
|
||||
channel
|
||||
.blocking_send(Ok(data.clone()))
|
||||
.blocking_send(data.clone())
|
||||
.expect("Failed sending ChunkData.");
|
||||
loaded_chunks.insert(at, data);
|
||||
})
|
||||
|
||||
@ -235,10 +235,6 @@ impl World {
|
||||
|
||||
while let Some(chunk_data) = chunk_receiver.recv().await {
|
||||
// dbg!(chunk_pos);
|
||||
let chunk_data = match chunk_data {
|
||||
Ok(d) => d,
|
||||
Err(_) => continue,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
if chunk_data.position == (0, 0).into() {
|
||||
use pumpkin_protocol::bytebuf::ByteBuffer;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user