azalea_client/plugins/packet/config/
mod.rs1mod events;
2
3use std::io::Cursor;
4
5use azalea_entity::LocalEntity;
6use azalea_protocol::{
7 packets::{ConnectionProtocol, config::*},
8 read::{ReadPacketError, deserialize_packet},
9};
10use bevy_ecs::prelude::*;
11pub use events::*;
12use tracing::{debug, warn};
13
14use super::{as_system, declare_packet_handlers};
15use crate::{
16 client::InConfigState,
17 connection::RawConnection,
18 cookies::{RequestCookieEvent, StoreCookieEvent},
19 disconnect::DisconnectEvent,
20 local_player::InstanceHolder,
21 packet::game::{KeepAliveEvent, ResourcePackEvent},
22};
23
24pub fn process_raw_packet(
25 ecs: &mut World,
26 player: Entity,
27 raw_packet: &[u8],
28) -> Result<(), Box<ReadPacketError>> {
29 let packet = deserialize_packet(&mut Cursor::new(raw_packet))?;
30 process_packet(ecs, player, &packet);
31 Ok(())
32}
33
34pub fn process_packet(ecs: &mut World, player: Entity, packet: &ClientboundConfigPacket) {
35 let mut handler = ConfigPacketHandler { player, ecs };
36
37 declare_packet_handlers!(
38 ClientboundConfigPacket,
39 packet,
40 handler,
41 [
42 cookie_request,
43 custom_payload,
44 disconnect,
45 finish_configuration,
46 keep_alive,
47 ping,
48 reset_chat,
49 registry_data,
50 resource_pack_pop,
51 resource_pack_push,
52 store_cookie,
53 transfer,
54 update_enabled_features,
55 update_tags,
56 select_known_packs,
57 custom_report_details,
58 server_links,
59 clear_dialog,
60 show_dialog,
61 code_of_conduct,
62 ]
63 );
64}
65
66pub struct ConfigPacketHandler<'a> {
67 pub ecs: &'a mut World,
68 pub player: Entity,
69}
70impl ConfigPacketHandler<'_> {
71 pub fn registry_data(&mut self, p: &ClientboundRegistryData) {
72 as_system::<Query<&InstanceHolder>>(self.ecs, |mut query| {
73 let instance_holder = query.get_mut(self.player).unwrap();
74 let mut instance = instance_holder.instance.write();
75
76 instance
78 .registries
79 .append(p.registry_id.clone(), p.entries.clone());
80 });
81 }
82
83 pub fn custom_payload(&mut self, p: &ClientboundCustomPayload) {
84 debug!("Got custom payload packet {p:?}");
85 }
86
87 pub fn disconnect(&mut self, p: &ClientboundDisconnect) {
88 warn!("Got disconnect packet {p:?}");
89 as_system::<MessageWriter<_>>(self.ecs, |mut events| {
90 events.write(DisconnectEvent {
91 entity: self.player,
92 reason: Some(p.reason.clone()),
93 });
94 });
95 }
96
97 pub fn finish_configuration(&mut self, _p: &ClientboundFinishConfiguration) {
98 debug!("got FinishConfiguration packet");
99
100 as_system::<(Commands, Query<&mut RawConnection>)>(
101 self.ecs,
102 |(mut commands, mut query)| {
103 let mut raw_conn = query.get_mut(self.player).unwrap();
104 raw_conn.state = ConnectionProtocol::Game;
105
106 commands.trigger(SendConfigPacketEvent::new(
107 self.player,
108 ServerboundFinishConfiguration,
109 ));
110
111 commands
113 .entity(self.player)
114 .remove::<InConfigState>()
115 .insert((
116 crate::JoinedClientBundle::default(),
117 LocalEntity,
120 ));
121 },
122 );
123 }
124
125 pub fn keep_alive(&mut self, p: &ClientboundKeepAlive) {
126 debug!(
127 "Got keep alive packet (in configuration) {p:?} for {:?}",
128 self.player
129 );
130
131 as_system::<(Commands, MessageWriter<_>)>(self.ecs, |(mut commands, mut events)| {
132 events.write(KeepAliveEvent {
133 entity: self.player,
134 id: p.id,
135 });
136 commands.trigger(SendConfigPacketEvent::new(
137 self.player,
138 ServerboundKeepAlive { id: p.id },
139 ));
140 });
141 }
142
143 pub fn ping(&mut self, p: &ClientboundPing) {
144 debug!("Got ping packet (in configuration) {p:?}");
145
146 as_system::<Commands>(self.ecs, |mut commands| {
147 commands.trigger(ConfigPingEvent {
148 entity: self.player,
149 packet: p.clone(),
150 });
151 });
152 }
153
154 pub fn resource_pack_push(&mut self, p: &ClientboundResourcePackPush) {
155 debug!("Got resource pack push packet {p:?}");
156
157 as_system::<MessageWriter<_>>(self.ecs, |mut events| {
158 events.write(ResourcePackEvent {
159 entity: self.player,
160 id: p.id,
161 url: p.url.to_owned(),
162 hash: p.hash.to_owned(),
163 required: p.required,
164 prompt: p.prompt.to_owned(),
165 });
166 });
167 }
168
169 pub fn resource_pack_pop(&mut self, p: &ClientboundResourcePackPop) {
170 debug!("Got resource pack pop packet {p:?}");
171 }
172
173 pub fn update_enabled_features(&mut self, p: &ClientboundUpdateEnabledFeatures) {
174 debug!("Got update enabled features packet {p:?}");
175 }
176
177 pub fn update_tags(&mut self, _p: &ClientboundUpdateTags) {
178 debug!("Got update tags packet");
179 }
180
181 pub fn cookie_request(&mut self, p: &ClientboundCookieRequest) {
182 debug!("Got cookie request packet {p:?}");
183 as_system::<Commands>(self.ecs, |mut commands| {
184 commands.trigger(RequestCookieEvent {
185 entity: self.player,
186 key: p.key.clone(),
187 });
188 });
189 }
190 pub fn store_cookie(&mut self, p: &ClientboundStoreCookie) {
191 debug!("Got store cookie packet {p:?}");
192 as_system::<Commands>(self.ecs, |mut commands| {
193 commands.trigger(StoreCookieEvent {
194 entity: self.player,
195 key: p.key.clone(),
196 payload: p.payload.clone(),
197 });
198 });
199 }
200
201 pub fn reset_chat(&mut self, p: &ClientboundResetChat) {
202 debug!("Got reset chat packet {p:?}");
203 }
204
205 pub fn transfer(&mut self, p: &ClientboundTransfer) {
206 debug!("Got transfer packet {p:?}");
207 }
208
209 pub fn select_known_packs(&mut self, p: &ClientboundSelectKnownPacks) {
210 debug!("Got select known packs packet {p:?}");
211
212 as_system::<Commands>(self.ecs, |mut commands| {
213 commands.trigger(SendConfigPacketEvent::new(
215 self.player,
216 ServerboundSelectKnownPacks {
217 known_packs: vec![],
218 },
219 ));
220 });
221 }
222
223 pub fn server_links(&mut self, p: &ClientboundServerLinks) {
224 debug!("Got server links packet {p:?}");
225 }
226
227 pub fn custom_report_details(&mut self, p: &ClientboundCustomReportDetails) {
228 debug!("Got custom report details packet {p:?}");
229 }
230
231 pub fn clear_dialog(&mut self, p: &ClientboundClearDialog) {
232 debug!("Got clear dialog packet {p:?}");
233 }
234 pub fn show_dialog(&mut self, p: &ClientboundShowDialog) {
235 debug!("Got show dialog packet {p:?}");
236 }
237 pub fn code_of_conduct(&mut self, p: &ClientboundCodeOfConduct) {
238 debug!("Got code of conduct packet {p:?}");
239 }
240}