azalea_protocol/packets/game/
c_section_blocks_update.rs1use 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}