diff options
| -rw-r--r-- | azalea-block/src/blocks.rs | 2 | ||||
| -rw-r--r-- | azalea-block/src/lib.rs | 56 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs | 74 | ||||
| -rwxr-xr-x | azalea-protocol/src/packets/game/mod.rs | 2 | ||||
| -rw-r--r-- | azalea-world/src/lib.rs | 9 | ||||
| -rw-r--r-- | codegen/lib/code/packet.py | 9 | ||||
| -rw-r--r-- | codegen/lib/code/utils.py | 5 | ||||
| -rw-r--r-- | codegen/lib/code/version.py | 2 |
8 files changed, 120 insertions, 39 deletions
diff --git a/azalea-block/src/blocks.rs b/azalea-block/src/blocks.rs index b8d204fd..05973797 100644 --- a/azalea-block/src/blocks.rs +++ b/azalea-block/src/blocks.rs @@ -4951,4 +4951,4 @@ make_block_states! { reinforced_deepslate => BlockBehavior::default(), { }, } -}
\ No newline at end of file +} diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs index 95e8ce37..a6de1e92 100644 --- a/azalea-block/src/lib.rs +++ b/azalea-block/src/lib.rs @@ -7,41 +7,41 @@ pub use blocks::*; use std::mem; impl BlockState { - /// Transmutes a u32 to a block state. UB if the value is not a valid block - /// state. - #[inline] - pub unsafe fn from_u32_unsafe(state_id: u32) -> Self { - mem::transmute::<u32, BlockState>(state_id) - } - - #[inline] - pub fn is_valid_state(state_id: u32) -> bool { - state_id <= Self::max_state() - } + /// Transmutes a u32 to a block state. UB if the value is not a valid block + /// state. + #[inline] + pub unsafe fn from_u32_unsafe(state_id: u32) -> Self { + mem::transmute::<u32, BlockState>(state_id) + } + + #[inline] + pub fn is_valid_state(state_id: u32) -> bool { + state_id <= Self::max_state() + } } impl TryFrom<u32> for BlockState { - type Error = (); - - /// Safely converts a state id to a block state. - fn try_from(state_id: u32) -> Result<Self, Self::Error> { - if Self::is_valid_state(state_id) { - Ok(unsafe { Self::from_u32_unsafe(state_id) }) - } else { - Err(()) - } - } + type Error = (); + + /// Safely converts a state id to a block state. + fn try_from(state_id: u32) -> Result<Self, Self::Error> { + if Self::is_valid_state(state_id) { + Ok(unsafe { Self::from_u32_unsafe(state_id) }) + } else { + Err(()) + } + } } #[cfg(test)] mod tests { - use super::*; + use super::*; - #[test] - fn test_from_u32() { - assert_eq!(BlockState::try_from(0).unwrap(), BlockState::Air); + #[test] + fn test_from_u32() { + assert_eq!(BlockState::try_from(0).unwrap(), BlockState::Air); - assert!(BlockState::try_from(BlockState::max_state()).is_ok()); - assert!(BlockState::try_from(BlockState::max_state() + 1).is_err()); - } + assert!(BlockState::try_from(BlockState::max_state()).is_ok()); + assert!(BlockState::try_from(BlockState::max_state() + 1).is_err()); + } } diff --git a/azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs b/azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs new file mode 100644 index 00000000..3acbd58f --- /dev/null +++ b/azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs @@ -0,0 +1,74 @@ +use azalea_core::Slot; +use packet_macros::{GamePacket, McBuf}; + +use crate::mc_buf::{McBufReadable, McBufWritable}; + +#[derive(Clone, Debug, McBuf, GamePacket)] +pub struct ClientboundSetEquipmentPacket { + #[var] + pub entity: i32, + pub slots: EquipmentSlots, +} + +#[derive(Clone, Debug)] +pub struct EquipmentSlots { + pub slots: Vec<(EquipmentSlot, Slot)>, +} + +impl McBufReadable for EquipmentSlots { + fn read_into(buf: &mut impl std::io::Read) -> Result<Self, String> { + let mut slots = vec![]; + + loop { + let equipment_byte = u8::read_into(buf)?; + let equipment_slot = EquipmentSlot::from_byte(equipment_byte & 127) + .ok_or_else(|| format!("Invalid equipment slot byte {}", equipment_byte))?; + let item = Slot::read_into(buf)?; + slots.push((equipment_slot, item)); + if equipment_byte & 128 == 0 { + break; + }; + } + + Ok(EquipmentSlots { slots }) + } +} +impl McBufWritable for EquipmentSlots { + fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + for i in 0..self.slots.len() { + let (equipment_slot, item) = &self.slots[i]; + let mut equipment_byte = *equipment_slot as u8; + if i != self.slots.len() - 1 { + equipment_byte |= 128; + } + equipment_byte.write_into(buf)?; + item.write_into(buf)?; + } + + Ok(()) + } +} + +#[derive(Clone, Debug, Copy, McBuf)] +pub enum EquipmentSlot { + MainHand = 0, + OffHand = 1, + Feet = 2, + Legs = 3, + Chest = 4, + Head = 5, +} + +impl EquipmentSlot { + pub fn from_byte(byte: u8) -> Option<Self> { + match byte { + 0 => Some(EquipmentSlot::MainHand), + 1 => Some(EquipmentSlot::OffHand), + 2 => Some(EquipmentSlot::Feet), + 3 => Some(EquipmentSlot::Legs), + 4 => Some(EquipmentSlot::Chest), + 5 => Some(EquipmentSlot::Head), + _ => None, + } + } +} diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs index eee36788..c4435636 100755 --- a/azalea-protocol/src/packets/game/mod.rs +++ b/azalea-protocol/src/packets/game/mod.rs @@ -37,6 +37,7 @@ pub mod clientbound_set_default_spawn_position_packet; pub mod clientbound_set_display_chat_preview_packet; pub mod clientbound_set_entity_data_packet; pub mod clientbound_set_entity_link_packet; +pub mod clientbound_set_equipment_packet; pub mod clientbound_set_experience_packet; pub mod clientbound_set_health_packet; pub mod clientbound_set_time_packet; @@ -104,6 +105,7 @@ declare_state_packets!( 0x4b: clientbound_set_display_chat_preview_packet::ClientboundSetDisplayChatPreviewPacket, 0x4d: clientbound_set_entity_data_packet::ClientboundSetEntityDataPacket, 0x4f: clientbound_entity_velocity_packet::ClientboundEntityVelocityPacket, + 0x50: clientbound_set_equipment_packet::ClientboundSetEquipmentPacket, 0x51: clientbound_set_experience_packet::ClientboundSetExperiencePacket, 0x52: clientbound_set_health_packet::ClientboundSetHealthPacket, 0x59: clientbound_set_time_packet::ClientboundSetTimePacket, diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 26566416..e651e455 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -4,11 +4,11 @@ mod bit_storage; mod palette; use crate::palette::PalettedContainerType; +use azalea_block::BlockState; use azalea_core::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos}; use azalea_protocol::mc_buf::{McBufReadable, McBufWritable}; pub use bit_storage::BitStorage; use palette::PalettedContainer; -use azalea_block::BlockState; use std::{ io::{Read, Write}, ops::{Index, IndexMut}, @@ -218,7 +218,8 @@ impl McBufReadable for Section { if !BlockState::is_valid_state(states.storage.get(i) as u32) { return Err(format!( "Invalid block state {} (index {}) found in section.", - states.storage.get(i), i + states.storage.get(i), + i )); } } @@ -245,6 +246,8 @@ impl Section { fn get(&self, pos: ChunkSectionBlockPos) -> BlockState { // TODO: use the unsafe method and do the check earlier self.states - .get(pos.x as usize, pos.y as usize, pos.z as usize).try_into().expect("Invalid block state.") + .get(pos.x as usize, pos.y as usize, pos.z as usize) + .try_into() + .expect("Invalid block state.") } } diff --git a/codegen/lib/code/packet.py b/codegen/lib/code/packet.py index 36e0ba0c..2aabf39a 100644 --- a/codegen/lib/code/packet.py +++ b/codegen/lib/code/packet.py @@ -1,6 +1,6 @@ -from .utils import burger_type_to_rust_type, write_packet_file -from ..utils import padded_hex, to_snake_case, to_camel_case -from ..mappings import Mappings +from lib.code.utils import burger_type_to_rust_type, write_packet_file +from lib.utils import padded_hex, to_snake_case, to_camel_case, get_dir_location +from lib.mappings import Mappings import os @@ -74,7 +74,8 @@ def generate_packet(burger_packets, mappings: Mappings, target_packet_id, target '\n'.join(generated_packet_code)) print() - mod_rs_dir = f'../azalea-protocol/src/packets/{state}/mod.rs' + mod_rs_dir = get_dir_location( + f'../azalea-protocol/src/packets/{state}/mod.rs') with open(mod_rs_dir, 'r') as f: mod_rs = f.read().splitlines() diff --git a/codegen/lib/code/utils.py b/codegen/lib/code/utils.py index 28a5ef3c..ecfff4fb 100644 --- a/codegen/lib/code/utils.py +++ b/codegen/lib/code/utils.py @@ -1,4 +1,5 @@ +from lib.utils import get_dir_location import os # utilities specifically for codegen @@ -67,9 +68,9 @@ def burger_type_to_rust_type(burger_type): def write_packet_file(state, packet_name_snake_case, code): - with open(f'../azalea-protocol/src/packets/{state}/{packet_name_snake_case}.rs', 'w') as f: + with open(get_dir_location(f'../azalea-protocol/src/packets/{state}/{packet_name_snake_case}.rs'), 'w') as f: f.write(code) def fmt(): - os.system('cd .. && cargo fmt') + os.system(f'cd {get_dir_location("..")} && cargo fmt') diff --git a/codegen/lib/code/version.py b/codegen/lib/code/version.py index 4c8500be..511d30d1 100644 --- a/codegen/lib/code/version.py +++ b/codegen/lib/code/version.py @@ -1,6 +1,6 @@ +from lib.utils import get_dir_location import re import os -from lib.utils import get_dir_location README_DIR = get_dir_location('../README.md') VERSION_REGEX = r'\*Currently supported Minecraft version: `(.*)`.\*' |
