1use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite};
2use azalea_core::bitset::FixedBitSet;
3use bevy_ecs::component::Component;
4
5#[derive(Clone, Debug, AzBuf, PartialEq, Eq, Component)]
9pub struct ClientInformation {
10 pub language: String,
12 pub view_distance: u8,
15 pub chat_visibility: ChatVisibility,
18 pub chat_colors: bool,
21 pub model_customization: ModelCustomization,
22 pub main_hand: HumanoidArm,
23 pub text_filtering_enabled: bool,
24 pub allows_listing: bool,
27 pub particle_status: ParticleStatus,
28}
29
30impl Default for ClientInformation {
31 fn default() -> Self {
32 Self {
33 language: "en_us".to_string(),
34 view_distance: 8,
35 chat_visibility: ChatVisibility::default(),
36 chat_colors: true,
37 model_customization: ModelCustomization::default(),
38 main_hand: HumanoidArm::Right,
39 text_filtering_enabled: false,
40 allows_listing: false,
41 particle_status: ParticleStatus::default(),
42 }
43 }
44}
45
46#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Eq, Default)]
47pub enum ChatVisibility {
48 #[default]
50 Full = 0,
51 System = 1,
54 Hidden = 2,
56}
57
58#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Eq, Default)]
59pub enum HumanoidArm {
60 Left = 0,
61 #[default]
62 Right = 1,
63}
64
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub struct ModelCustomization {
67 pub cape: bool,
68 pub jacket: bool,
69 pub left_sleeve: bool,
70 pub right_sleeve: bool,
71 pub left_pants: bool,
72 pub right_pants: bool,
73 pub hat: bool,
74}
75
76#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Eq, Default)]
77pub enum ParticleStatus {
78 #[default]
79 All,
80 Decreased,
81 Minimal,
82}
83
84impl Default for ModelCustomization {
85 fn default() -> Self {
86 Self {
87 cape: true,
88 jacket: true,
89 left_sleeve: true,
90 right_sleeve: true,
91 left_pants: true,
92 right_pants: true,
93 hat: true,
94 }
95 }
96}
97
98impl AzaleaRead for ModelCustomization {
99 fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
100 let set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::azalea_read(buf)?;
101 Ok(Self {
102 cape: set.index(0),
103 jacket: set.index(1),
104 left_sleeve: set.index(2),
105 right_sleeve: set.index(3),
106 left_pants: set.index(4),
107 right_pants: set.index(5),
108 hat: set.index(6),
109 })
110 }
111}
112
113impl AzaleaWrite for ModelCustomization {
114 fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
115 let mut set = FixedBitSet::<{ 7_usize.div_ceil(8) }>::new();
116 if self.cape {
117 set.set(0);
118 }
119 if self.jacket {
120 set.set(1);
121 }
122 if self.left_sleeve {
123 set.set(2);
124 }
125 if self.right_sleeve {
126 set.set(3);
127 }
128 if self.left_pants {
129 set.set(4);
130 }
131 if self.right_pants {
132 set.set(5);
133 }
134 if self.hat {
135 set.set(6);
136 }
137 set.azalea_write(buf)
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use std::io::Cursor;
144
145 use azalea_buf::{AzaleaRead, AzaleaWrite};
146
147 use super::*;
148
149 #[test]
150 fn test_client_information() {
151 {
152 let data = ClientInformation::default();
153 let mut buf = Vec::new();
154 data.azalea_write(&mut buf).unwrap();
155 let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf);
156
157 let read_data = ClientInformation::azalea_read(&mut data_cursor).unwrap();
158 assert_eq!(read_data, data);
159 }
160
161 let data = ClientInformation {
162 language: "en_gb".to_string(),
163 view_distance: 24,
164 chat_visibility: ChatVisibility::Hidden,
165 chat_colors: false,
166 model_customization: ModelCustomization {
167 cape: false,
168 jacket: false,
169 left_sleeve: true,
170 right_sleeve: false,
171 left_pants: true,
172 right_pants: false,
173 hat: true,
174 },
175 main_hand: HumanoidArm::Left,
176 text_filtering_enabled: true,
177 allows_listing: true,
178 particle_status: ParticleStatus::Decreased,
179 };
180 let mut buf = Vec::new();
181 data.azalea_write(&mut buf).unwrap();
182 let mut data_cursor: Cursor<&[u8]> = Cursor::new(&buf);
183
184 let read_data = ClientInformation::azalea_read(&mut data_cursor).unwrap();
185 assert_eq!(read_data, data);
186 }
187}