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