valence_protocol/packets/play/
chat_message_s2c.rs

1use std::borrow::Cow;
2use std::io::Write;
3
4use uuid::Uuid;
5use valence_text::Text;
6
7use crate::{Bounded, Decode, Encode, Packet, VarInt};
8
9#[derive(Clone, PartialEq, Debug, Packet)]
10pub struct ChatMessageS2c<'a> {
11    pub sender: Uuid,
12    pub index: VarInt,
13    pub message_signature: Option<&'a [u8; 256]>,
14    pub message: Bounded<&'a str, 256>,
15    pub timestamp: u64,
16    pub salt: u64,
17    pub previous_messages: Vec<MessageSignature<'a>>,
18    pub unsigned_content: Option<Cow<'a, Text>>,
19    pub filter_type: MessageFilterType,
20    pub filter_type_bits: Option<u8>,
21    pub chat_type: VarInt,
22    pub network_name: Cow<'a, Text>,
23    pub network_target_name: Option<Cow<'a, Text>>,
24}
25
26#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
27pub enum MessageFilterType {
28    PassThrough,
29    FullyFiltered,
30    PartiallyFiltered,
31}
32
33impl Encode for ChatMessageS2c<'_> {
34    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
35        self.sender.encode(&mut w)?;
36        self.index.encode(&mut w)?;
37        self.message_signature.encode(&mut w)?;
38        self.message.encode(&mut w)?;
39        self.timestamp.encode(&mut w)?;
40        self.salt.encode(&mut w)?;
41        self.previous_messages.encode(&mut w)?;
42        self.unsigned_content.encode(&mut w)?;
43        self.filter_type.encode(&mut w)?;
44
45        if self.filter_type == MessageFilterType::PartiallyFiltered {
46            match self.filter_type_bits {
47                // Filler data
48                None => 0_u8.encode(&mut w)?,
49                Some(bits) => bits.encode(&mut w)?,
50            }
51        }
52
53        self.chat_type.encode(&mut w)?;
54        self.network_name.encode(&mut w)?;
55        self.network_target_name.encode(&mut w)?;
56
57        Ok(())
58    }
59}
60
61impl<'a> Decode<'a> for ChatMessageS2c<'a> {
62    fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
63        let sender = Uuid::decode(r)?;
64        let index = VarInt::decode(r)?;
65        let message_signature = Option::<&'a [u8; 256]>::decode(r)?;
66        let message = Decode::decode(r)?;
67        let time_stamp = u64::decode(r)?;
68        let salt = u64::decode(r)?;
69        let previous_messages = Vec::<MessageSignature>::decode(r)?;
70        let unsigned_content = Option::<Cow<'a, Text>>::decode(r)?;
71        let filter_type = MessageFilterType::decode(r)?;
72
73        let filter_type_bits = match filter_type {
74            MessageFilterType::PartiallyFiltered => Some(u8::decode(r)?),
75            _ => None,
76        };
77
78        let chat_type = VarInt::decode(r)?;
79        let network_name = <Cow<'a, Text>>::decode(r)?;
80        let network_target_name = Option::<Cow<'a, Text>>::decode(r)?;
81
82        Ok(Self {
83            sender,
84            index,
85            message_signature,
86            message,
87            timestamp: time_stamp,
88            salt,
89            previous_messages,
90            unsigned_content,
91            filter_type,
92            filter_type_bits,
93            chat_type,
94            network_name,
95            network_target_name,
96        })
97    }
98}
99
100#[derive(Copy, Clone, PartialEq, Debug)]
101pub struct MessageSignature<'a> {
102    pub message_id: i32,
103    pub signature: Option<&'a [u8; 256]>,
104}
105
106impl Encode for MessageSignature<'_> {
107    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
108        VarInt(self.message_id + 1).encode(&mut w)?;
109
110        match self.signature {
111            None => {}
112            Some(signature) => signature.encode(&mut w)?,
113        }
114
115        Ok(())
116    }
117}
118
119impl<'a> Decode<'a> for MessageSignature<'a> {
120    fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
121        let message_id = VarInt::decode(r)?.0 - 1; // TODO: this can underflow.
122
123        let signature = if message_id == -1 {
124            Some(<&[u8; 256]>::decode(r)?)
125        } else {
126            None
127        };
128
129        Ok(Self {
130            message_id,
131            signature,
132        })
133    }
134}