diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/v1_15_2.rs | 192 |
1 files changed, 189 insertions, 3 deletions
diff --git a/src/v1_15_2.rs b/src/v1_15_2.rs index 03b3ac4..0f5689f 100644 --- a/src/v1_15_2.rs +++ b/src/v1_15_2.rs @@ -562,9 +562,11 @@ define_protocol!(Packet578, PacketDirection, State, i32, Id => { pitch: Angle, on_ground: bool }, - // todo advancements PlayAdvancements, 0x58, Play, ClientBound => PlayAdvancementsSpec { - raw: RemainingBytes + reset: bool, + mappings: VarIntCountedArray<AdvancementMappingEntrySpec>, + identifiers: VarIntCountedArray<String>, + progress: VarIntCountedArray<AdvancementProgressEntrySpec> }, PlayEntityProperties, 0x59, Play, ClientBound => PlayEntityPropertiesSpec { entity_id: VarInt, @@ -720,7 +722,9 @@ define_protocol!(Packet578, PacketDirection, State, i32, Id => { forward: f32, flags: SteerVehicleFlags }, - // todo recipe book data + PlayRecipeBookData, 0x1D, Play, ServerBound => PlayRecipeBookDataSpec { + status: RecipeBookStatus + }, PlayNameItem, 0x1E, Play, ServerBound => PlayNameItemSpec { name: String }, @@ -2379,6 +2383,121 @@ impl TestRandom for ScoreboardObjectiveAction { } } +__protocol_body_def_helper!(AdvancementMappingEntrySpec { + key: String, + value: AdvancementSpec +}); + +__protocol_body_def_helper!(AdvancementSpec { + parent: Option<String>, + display: Option<AdvancementDisplaySpec>, + criteria: VarIntCountedArray<String>, + requirements: VarIntCountedArray<VarIntCountedArray<String>> +}); + +__protocol_body_def_helper!(AdvancementDisplaySpec { + title: Chat, + description: Chat, + icon: Option<Slot>, + frame_type: AdvancementFrameType, + flags: AdvancementDisplayFlags, + x: f32, + y: f32 +}); + +#[derive(Clone, Debug, PartialEq)] +pub struct AdvancementDisplayFlags { + pub background_texture: Option<String>, + pub show_toast: bool, + pub hidden: bool +} + +impl Serialize for AdvancementDisplayFlags { + fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { + let mut raw_flags: i32 = 0; + if self.background_texture.is_some() { + raw_flags |= 0x01; + } + if self.show_toast { + raw_flags |= 0x02; + } + if self.hidden { + raw_flags |= 0x04; + } + + to.serialize_other(&raw_flags)?; + if let Some(texture) = &self.background_texture { + to.serialize_other(texture)?; + } + + Ok(()) + } +} + +impl Deserialize for AdvancementDisplayFlags { + fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { + let Deserialized{ value: raw_flags, data } = i32::mc_deserialize(data)?; + let has_background_texture = raw_flags & 0x01 != 0; + let show_toast = raw_flags & 0x02 != 0; + let hidden = raw_flags & 0x04 != 0; + + Ok(if has_background_texture { + String::mc_deserialize(data)?.map(move |id| Some(id)) + } else { + Deserialized { value: None, data } + }.map(move |background_texture| { + Self { + background_texture, + show_toast, + hidden + } + })) + } +} + +#[cfg(test)] +impl TestRandom for AdvancementDisplayFlags { + fn test_gen_random() -> Self { + let background_texture = if rand::random::<bool>() { + Some(String::test_gen_random()) + } else { + None + }; + let show_toast = rand::random::<bool>(); + let hidden = rand::random::<bool>(); + + Self { + background_texture, + show_toast, + hidden + } + } +} + +proto_varint_enum!(AdvancementFrameType, + 0x00 :: Task, + 0x01 :: Challenge, + 0x02 :: Goal +); + +__protocol_body_def_helper!(AdvancementProgressEntrySpec { + key: String, + value: AdvancementProgressSpec +}); + +__protocol_body_def_helper!(AdvancementProgressSpec { + criteria: VarIntCountedArray<AdvancementCriteriaSpec> +}); + +__protocol_body_def_helper!(AdvancementCriteriaSpec { + identifier: String, + progress: AdvancementCriterionProgressSpec +}); + +__protocol_body_def_helper!(AdvancementCriterionProgressSpec { + achieved_at: Option<i64> +}); + __protocol_body_def_helper!(EntityPropertySpec { key: String, value: f64, @@ -2551,6 +2670,64 @@ proto_byte_flag!(SteerVehicleFlags, 0x02 :: unmount ); +#[derive(Clone, Debug, PartialEq)] +pub enum RecipeBookStatus { + Displayed(String), + States(RecipeBookStates) +} + +impl Serialize for RecipeBookStatus { + fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { + use RecipeBookStatus::*; + to.serialize_other(&VarInt(match self { + Displayed(_) => 0x00, + States(_) => 0x01 + }))?; + + match self { + Displayed(body) => to.serialize_other(body), + States(body) => to.serialize_other(body), + } + } +} + +impl Deserialize for RecipeBookStatus { + fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { + let Deserialized { value: type_id, data } = VarInt::mc_deserialize(data)?; + use RecipeBookStatus::*; + match type_id.0 { + 0x00 => Ok(String::mc_deserialize(data)?.map(move |identifier| Displayed(identifier))), + 0x01 => Ok(RecipeBookStates::mc_deserialize(data)?.map(move |states| States(states))), + other => Err(DeserializeErr::CannotUnderstandValue(format!("invalid recipe book action type {}", other))) + } + } +} + +#[cfg(test)] +impl TestRandom for RecipeBookStatus { + fn test_gen_random() -> Self { + use RecipeBookStatus::*; + + let rand_bool = rand::random::<bool>(); + if rand_bool { + Displayed(String::test_gen_random()) + } else { + States(RecipeBookStates::test_gen_random()) + } + } +} + +__protocol_body_def_helper!(RecipeBookStates { + crafting_book_open: bool, + craftinb_filter_active: bool, + smelting_book_open: bool, + smelting_filter_active: bool, + blasting_book_open: bool, + blasting_filter_active: bool, + smoking_book_open: bool, + smoking_filter_active: bool +}); + proto_varint_enum!(ResourcePackStatus, 0x00 :: Loaded, 0x01 :: Declined, @@ -4412,6 +4589,15 @@ pub mod tests { packet_test_cases!( Packet578, + PlayRecipeBookData, + PlayRecipeBookDataSpec, + test_play_recipe_book_data, + bench_write_play_recipe_book_data, + bench_read_play_recipe_book_data + ); + + packet_test_cases!( + Packet578, PlayNameItem, PlayNameItemSpec, test_play_name_item, |