valence_protocol/packets/play/
player_list_s2c.rs
1use std::borrow::Cow;
2use std::io::Write;
3
4use bitfield_struct::bitfield;
5use uuid::Uuid;
6use valence_text::Text;
7
8use crate::profile::Property;
9use crate::{Decode, Encode, GameMode, Packet, VarInt};
10
11#[derive(Clone, Debug, Packet)]
12pub struct PlayerListS2c<'a> {
13 pub actions: PlayerListActions,
14 pub entries: Cow<'a, [PlayerListEntry<'a>]>,
15}
16
17impl Encode for PlayerListS2c<'_> {
18 fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
19 self.actions.0.encode(&mut w)?;
20
21 VarInt(self.entries.len() as i32).encode(&mut w)?;
23
24 for entry in self.entries.as_ref() {
25 entry.player_uuid.encode(&mut w)?;
26
27 if self.actions.add_player() {
28 entry.username.encode(&mut w)?;
29 entry.properties.encode(&mut w)?;
30 }
31
32 if self.actions.initialize_chat() {
33 entry.chat_data.encode(&mut w)?;
34 }
35
36 if self.actions.update_game_mode() {
37 entry.game_mode.encode(&mut w)?;
38 }
39
40 if self.actions.update_listed() {
41 entry.listed.encode(&mut w)?;
42 }
43
44 if self.actions.update_latency() {
45 VarInt(entry.ping).encode(&mut w)?;
46 }
47
48 if self.actions.update_display_name() {
49 entry.display_name.encode(&mut w)?;
50 }
51 }
52
53 Ok(())
54 }
55}
56
57impl<'a> Decode<'a> for PlayerListS2c<'a> {
58 fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
59 let actions = PlayerListActions(u8::decode(r)?);
60
61 let mut entries = vec![];
62
63 for _ in 0..VarInt::decode(r)?.0 {
64 let mut entry = PlayerListEntry {
65 player_uuid: Uuid::decode(r)?,
66 ..Default::default()
67 };
68
69 if actions.add_player() {
70 entry.username = Decode::decode(r)?;
71 entry.properties = Decode::decode(r)?;
72 }
73
74 if actions.initialize_chat() {
75 entry.chat_data = Decode::decode(r)?;
76 }
77
78 if actions.update_game_mode() {
79 entry.game_mode = Decode::decode(r)?;
80 }
81
82 if actions.update_listed() {
83 entry.listed = Decode::decode(r)?;
84 }
85
86 if actions.update_latency() {
87 entry.ping = VarInt::decode(r)?.0;
88 }
89
90 if actions.update_display_name() {
91 entry.display_name = Decode::decode(r)?;
92 }
93
94 entries.push(entry);
95 }
96
97 Ok(Self {
98 actions,
99 entries: entries.into(),
100 })
101 }
102}
103
104#[bitfield(u8)]
105pub struct PlayerListActions {
106 pub add_player: bool,
107 pub initialize_chat: bool,
108 pub update_game_mode: bool,
109 pub update_listed: bool,
110 pub update_latency: bool,
111 pub update_display_name: bool,
112 #[bits(2)]
113 _pad: u8,
114}
115
116#[derive(Clone, Default, Debug)]
117pub struct PlayerListEntry<'a> {
118 pub player_uuid: Uuid,
119 pub username: &'a str,
120 pub properties: Cow<'a, [Property]>,
121 pub chat_data: Option<ChatData<'a>>,
122 pub listed: bool,
123 pub ping: i32,
124 pub game_mode: GameMode,
125 pub display_name: Option<Cow<'a, Text>>,
126}
127
128#[derive(Clone, PartialEq, Debug, Encode, Decode)]
129pub struct ChatData<'a> {
130 pub session_id: Uuid,
131 pub key_expiry_time: i64,
133 pub public_key: &'a [u8],
134 pub public_key_signature: &'a [u8],
135}