From 61642f165b6659f7b259bf282614fadd2486b28c Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 24 Oct 2022 18:20:18 +0000 Subject: [PATCH] fix out of bounds y position --- azalea-world/src/chunk_storage.rs | 43 +++++++++++++++++++++++-------- azalea-world/src/lib.rs | 4 +-- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index 0c60376a..64e85093 100644 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -79,23 +79,21 @@ impl ChunkStorage { && (chunk_pos.z - self.view_center.z).unsigned_abs() <= self.chunk_radius } - pub fn get_block_state(&self, pos: &BlockPos, min_y: i32) -> Option { + pub fn get_block_state(&self, pos: &BlockPos) -> Option { + if pos.y < self.min_y || pos.y >= (self.min_y + self.height as i32) { + return None; + } let chunk_pos = ChunkPos::from(pos); let chunk = self[&chunk_pos].as_ref()?; let chunk = chunk.lock().unwrap(); - Some(chunk.get(&ChunkBlockPos::from(pos), min_y)) + Some(chunk.get(&ChunkBlockPos::from(pos), self.min_y)) } - pub fn set_block_state( - &self, - pos: &BlockPos, - state: BlockState, - min_y: i32, - ) -> Option { + pub fn set_block_state(&self, pos: &BlockPos, state: BlockState) -> Option { let chunk_pos = ChunkPos::from(pos); let chunk = self[&chunk_pos].as_ref()?; let mut chunk = chunk.lock().unwrap(); - Some(chunk.get_and_set(&ChunkBlockPos::from(pos), state, min_y)) + Some(chunk.get_and_set(&ChunkBlockPos::from(pos), state, self.min_y)) } pub fn replace_with_packet_data( @@ -166,9 +164,14 @@ impl Chunk { } pub fn get(&self, pos: &ChunkBlockPos, min_y: i32) -> BlockState { - let section_index = self.section_index(pos.y, min_y); + let section_index = self.section_index(pos.y, min_y) as usize; + assert!( + section_index < self.sections.len(), + "Given y position ({}) is out of bounds", + pos.y + ); // TODO: make sure the section exists - let section = &self.sections[section_index as usize]; + let section = &self.sections[section_index]; let chunk_section_pos = ChunkSectionBlockPos::from(pos); section.get(chunk_section_pos) } @@ -304,4 +307,22 @@ mod tests { assert_eq!(chunk.section_index(-48, -64), 1); assert_eq!(chunk.section_index(128, -64), 12); } + + #[test] + fn test_out_of_bounds_y() { + let mut chunk_storage = ChunkStorage::default(); + chunk_storage[&ChunkPos { x: 0, z: 0 }] = Some(Arc::new(Mutex::new(Chunk::default()))); + assert!(chunk_storage + .get_block_state(&BlockPos { x: 0, y: 319, z: 0 }) + .is_some()); + assert!(chunk_storage + .get_block_state(&BlockPos { x: 0, y: 320, z: 0 }) + .is_none()); + assert!(chunk_storage + .get_block_state(&BlockPos { x: 0, y: -64, z: 0 }) + .is_some()); + assert!(chunk_storage + .get_block_state(&BlockPos { x: 0, y: -65, z: 0 }) + .is_none()); + } } diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 08b7ebf4..5fbb7b4d 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -62,11 +62,11 @@ impl Dimension { } pub fn get_block_state(&self, pos: &BlockPos) -> Option { - self.chunk_storage.get_block_state(pos, self.min_y()) + self.chunk_storage.get_block_state(pos) } pub fn set_block_state(&mut self, pos: &BlockPos, state: BlockState) -> Option { - self.chunk_storage.set_block_state(pos, state, self.min_y()) + self.chunk_storage.set_block_state(pos, state) } pub fn set_entity_pos(&mut self, entity_id: u32, new_pos: Vec3) -> Result<(), MoveEntityError> {