valence_protocol/packets/play/
advancement_update_s2c.rs

1// TODO: simplify this and bound packet fields where appropriate.
2
3use std::borrow::Cow;
4use std::io::Write;
5
6use valence_ident::Ident;
7use valence_text::Text;
8
9use crate::{packet_id, Decode, Encode, ItemStack, Packet, VarInt};
10
11pub type AdvancementUpdateS2c<'a> =
12    GenericAdvancementUpdateS2c<'a, (Ident<Cow<'a, str>>, Advancement<'a, ItemStack>)>;
13
14#[derive(Clone, Debug, Encode, Decode, Packet)]
15#[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)]
16pub struct GenericAdvancementUpdateS2c<'a, AM: 'a> {
17    pub reset: bool,
18    pub advancement_mapping: Vec<AM>,
19    pub identifiers: Vec<Ident<Cow<'a, str>>>,
20    pub progress_mapping: Vec<(Ident<Cow<'a, str>>, Vec<AdvancementCriteria<'a>>)>,
21}
22
23#[derive(Clone, PartialEq, Debug, Encode, Decode)]
24pub struct Advancement<'a, I> {
25    pub parent_id: Option<Ident<Cow<'a, str>>>,
26    pub display_data: Option<AdvancementDisplay<'a, I>>,
27    pub criteria: Vec<(Ident<Cow<'a, str>>, ())>,
28    pub requirements: Vec<AdvancementRequirements<'a>>,
29    pub sends_telemetry_data: bool,
30}
31
32#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
33pub struct AdvancementRequirements<'a> {
34    pub requirement: Vec<&'a str>,
35}
36
37#[derive(Clone, PartialEq, Debug)]
38pub struct AdvancementDisplay<'a, I> {
39    pub title: Cow<'a, Text>,
40    pub description: Cow<'a, Text>,
41    pub icon: I,
42    pub frame_type: VarInt,
43    pub flags: i32,
44    pub background_texture: Option<Ident<Cow<'a, str>>>,
45    pub x_coord: f32,
46    pub y_coord: f32,
47}
48
49#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
50pub struct AdvancementCriteria<'a> {
51    pub criterion_identifier: Ident<Cow<'a, str>>,
52    /// If present, the criteria has been achieved at the
53    /// time wrapped; time represented as millis since epoch
54    pub criterion_progress: Option<i64>,
55}
56
57impl<I: Encode> Encode for AdvancementDisplay<'_, I> {
58    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
59        self.title.encode(&mut w)?;
60        self.description.encode(&mut w)?;
61        self.icon.encode(&mut w)?;
62        self.frame_type.encode(&mut w)?;
63        self.flags.encode(&mut w)?;
64
65        match self.background_texture.as_ref() {
66            None => {}
67            Some(texture) => texture.encode(&mut w)?,
68        }
69
70        self.x_coord.encode(&mut w)?;
71        self.y_coord.encode(&mut w)?;
72
73        Ok(())
74    }
75}
76
77impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplay<'a, I> {
78    fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
79        let title = <Cow<'a, Text>>::decode(r)?;
80        let description = <Cow<'a, Text>>::decode(r)?;
81        let icon = I::decode(r)?;
82        let frame_type = VarInt::decode(r)?;
83        let flags = i32::decode(r)?;
84
85        let background_texture = if flags & 1 == 1 {
86            Some(Ident::decode(r)?)
87        } else {
88            None
89        };
90
91        let x_coord = f32::decode(r)?;
92        let y_coord = f32::decode(r)?;
93
94        Ok(Self {
95            title,
96            description,
97            icon,
98            frame_type,
99            flags,
100            background_texture,
101            x_coord,
102            y_coord,
103        })
104    }
105}