diff options
| author | mat <git@matdoes.dev> | 2024-02-22 22:41:54 -0600 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2024-02-22 22:41:54 -0600 |
| commit | 038807e607c55757b3d9a9d51f0b9e65a781772b (patch) | |
| tree | f162c7397e7ff17f2c7cb1f3fde7178dea60b645 /azalea-world/src | |
| parent | 69f7eebcb300bbefdc8b10c191a09db250bde630 (diff) | |
| download | azalea-drasl-038807e607c55757b3d9a9d51f0b9e65a781772b.tar.xz | |
fix for hypixel limbo
Diffstat (limited to 'azalea-world/src')
| -rwxr-xr-x | azalea-world/src/bit_storage.rs | 3 | ||||
| -rwxr-xr-x | azalea-world/src/chunk_storage.rs | 5 | ||||
| -rwxr-xr-x | azalea-world/src/palette.rs | 32 |
3 files changed, 31 insertions, 9 deletions
diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 58ff28c4..0456d727 100755 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -114,8 +114,7 @@ impl BitStorage { } } - // vanilla has this assert but it's not always true for some reason?? - // assert!(bits >= 1 && bits <= 32); + debug_assert!((1..=32).contains(&bits)); let values_per_long = 64 / bits; let magic_index = values_per_long - 1; diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index 8bc0b32c..512f231b 100755 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -450,9 +450,8 @@ impl McBufReadable for Section { for i in 0..states.storage.size() { if !BlockState::is_valid_state(states.storage.get(i) as u32) { return Err(BufReadError::Custom(format!( - "Invalid block state {} (index {}) found in section.", - states.storage.get(i), - i + "Invalid block state {} (index {i}) found in section.", + states.storage.get(i) ))); } } diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 5e57989c..278524ca 100755 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -1,5 +1,7 @@ use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable}; +use azalea_core::math; use std::io::{Cursor, Write}; +use tracing::warn; use crate::BitStorage; @@ -41,17 +43,39 @@ impl PalettedContainer { buf: &mut Cursor<&[u8]>, container_type: &'static PalettedContainerKind, ) -> Result<Self, BufReadError> { - let bits_per_entry = u8::read_from(buf)?; - let palette_type = PaletteKind::from_bits_and_type(bits_per_entry, container_type); + let server_bits_per_entry = u8::read_from(buf)?; + let palette_type = PaletteKind::from_bits_and_type(server_bits_per_entry, container_type); let palette = palette_type.read(buf)?; let size = container_type.size(); - let data = Vec::<u64>::read_from(buf)?; + + // if there's too much data that the bits per entry would be global, we have to + // figure out the bits per entry ourselves by checking the number of bits in the + // length of the data. + // this almost never matters, except on some custom servers like hypixel limbo + let calculated_bits_per_entry = math::ceil_log2(data.len() as u32) as u8; + let calculated_bits_per_entry_palette_kind = + PaletteKind::from_bits_and_type(calculated_bits_per_entry, container_type); + let bits_per_entry = if calculated_bits_per_entry_palette_kind == PaletteKind::Global { + server_bits_per_entry + } else { + calculated_bits_per_entry + }; + debug_assert!( bits_per_entry != 0 || data.is_empty(), "Bits per entry is 0 but data is not empty." ); - let storage = BitStorage::new(bits_per_entry.into(), size, Some(data)).unwrap(); + + let storage = match BitStorage::new(bits_per_entry.into(), size, Some(data)) { + Ok(storage) => storage, + Err(e) => { + warn!("Failed to create bit storage: {:?}", e); + return Err(BufReadError::Custom( + "Failed to create bit storage".to_string(), + )); + } + }; Ok(PalettedContainer { bits_per_entry, |
