aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea-block/src/blocks.rs2
-rw-r--r--azalea-block/src/lib.rs56
-rw-r--r--azalea-protocol/src/packets/game/clientbound_set_equipment_packet.rs74
-rwxr-xr-xazalea-protocol/src/packets/game/mod.rs2
-rw-r--r--azalea-world/src/lib.rs9
-rw-r--r--codegen/lib/code/packet.py9
-rw-r--r--codegen/lib/code/utils.py5
-rw-r--r--codegen/lib/code/version.py2
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: `(.*)`.\*'