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 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; 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}