azalea_protocol/packets/game/
c_section_blocks_update.rs

1use std::io::{Cursor, Write};
2
3use azalea_block::BlockState;
4use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
5use azalea_core::position::{ChunkSectionBlockPos, ChunkSectionPos};
6use azalea_protocol_macros::ClientboundGamePacket;
7
8#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
9pub struct ClientboundSectionBlocksUpdate {
10    pub section_pos: ChunkSectionPos,
11    pub states: Vec<BlockStateWithPosition>,
12}
13
14#[derive(Clone, Debug)]
15pub struct BlockStateWithPosition {
16    pub pos: ChunkSectionBlockPos,
17    pub state: BlockState,
18}
19
20impl AzaleaRead for BlockStateWithPosition {
21    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
22        let data = u64::azalea_read_var(buf)?;
23        let position_part = data & 4095;
24        let state = (data >> 12) as u32;
25        let state = BlockState::try_from(state)
26            .map_err(|_| BufReadError::UnexpectedEnumVariant { id: state as i32 })?;
27        let pos = ChunkSectionBlockPos {
28            x: ((position_part >> 8) & 15) as u8,
29            y: (position_part & 15) as u8,
30            z: ((position_part >> 4) & 15) as u8,
31        };
32        Ok(BlockStateWithPosition { pos, state })
33    }
34}
35
36impl AzaleaWrite for BlockStateWithPosition {
37    fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
38        let data = ((self.state.id as u64) << 12)
39            | ((u64::from(self.pos.x) << 8) | (u64::from(self.pos.z) << 4) | u64::from(self.pos.y));
40        u64::azalea_write_var(&data, buf)?;
41        Ok(())
42    }
43}