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;
15use crate::{
16 client::InConfigState,
17 connection::RawConnection,
18 declare_packet_handlers,
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 ]
62 );
63}
64
65pub struct ConfigPacketHandler<'a> {
66 pub ecs: &'a mut World,
67 pub player: Entity,
68}
69impl ConfigPacketHandler<'_> {
70 pub fn registry_data(&mut self, p: &ClientboundRegistryData) {
71 as_system::<Query<&InstanceHolder>>(self.ecs, |mut query| {
72 let instance_holder = query.get_mut(self.player).unwrap();
73 let mut instance = instance_holder.instance.write();
74
75 instance
77 .registries
78 .append(p.registry_id.clone(), p.entries.clone());
79 });
80 }
81
82 pub fn custom_payload(&mut self, p: &ClientboundCustomPayload) {
83 debug!("Got custom payload packet {p:?}");
84 }
85
86 pub fn disconnect(&mut self, p: &ClientboundDisconnect) {
87 warn!("Got disconnect packet {p:?}");
88 as_system::<EventWriter<_>>(self.ecs, |mut events| {
89 events.write(DisconnectEvent {
90 entity: self.player,
91 reason: Some(p.reason.clone()),
92 });
93 });
94 }
95
96 pub fn finish_configuration(&mut self, _p: &ClientboundFinishConfiguration) {
97 debug!("got FinishConfiguration packet");
98
99 as_system::<(Commands, Query<&mut RawConnection>)>(
100 self.ecs,
101 |(mut commands, mut query)| {
102 let mut raw_conn = query.get_mut(self.player).unwrap();
103 raw_conn.state = ConnectionProtocol::Game;
104
105 commands.trigger(SendConfigPacketEvent::new(
106 self.player,
107 ServerboundFinishConfiguration,
108 ));
109
110 commands
112 .entity(self.player)
113 .remove::<InConfigState>()
114 .insert((
115 crate::JoinedClientBundle::default(),
116 LocalEntity,
119 ));
120 },
121 );
122 }
123
124 pub fn keep_alive(&mut self, p: &ClientboundKeepAlive) {
125 debug!(
126 "Got keep alive packet (in configuration) {p:?} for {:?}",
127 self.player
128 );
129
130 as_system::<(Commands, EventWriter<_>)>(self.ecs, |(mut commands, mut events)| {
131 events.write(KeepAliveEvent {
132 entity: self.player,
133 id: p.id,
134 });
135 commands.trigger(SendConfigPacketEvent::new(
136 self.player,
137 ServerboundKeepAlive { id: p.id },
138 ));
139 });
140 }
141
142 pub fn ping(&mut self, p: &ClientboundPing) {
143 debug!("Got ping packet (in configuration) {p:?}");
144
145 as_system::<Commands>(self.ecs, |mut commands| {
146 commands.trigger_targets(ConfigPingEvent(p.clone()), self.player);
147 });
148 }
149
150 pub fn resource_pack_push(&mut self, p: &ClientboundResourcePackPush) {
151 debug!("Got resource pack push packet {p:?}");
152
153 as_system::<EventWriter<_>>(self.ecs, |mut events| {
154 events.write(ResourcePackEvent {
155 entity: self.player,
156 id: p.id,
157 url: p.url.to_owned(),
158 hash: p.hash.to_owned(),
159 required: p.required,
160 prompt: p.prompt.to_owned(),
161 });
162 });
163 }
164
165 pub fn resource_pack_pop(&mut self, p: &ClientboundResourcePackPop) {
166 debug!("Got resource pack pop packet {p:?}");
167 }
168
169 pub fn update_enabled_features(&mut self, p: &ClientboundUpdateEnabledFeatures) {
170 debug!("Got update enabled features packet {p:?}");
171 }
172
173 pub fn update_tags(&mut self, _p: &ClientboundUpdateTags) {
174 debug!("Got update tags packet");
175 }
176
177 pub fn cookie_request(&mut self, p: &ClientboundCookieRequest) {
178 debug!("Got cookie request packet {p:?}");
179
180 as_system::<Commands>(self.ecs, |mut commands| {
181 commands.trigger(SendConfigPacketEvent::new(
182 self.player,
183 ServerboundCookieResponse {
184 key: p.key.clone(),
185 payload: None,
187 },
188 ));
189 });
190 }
191
192 pub fn reset_chat(&mut self, p: &ClientboundResetChat) {
193 debug!("Got reset chat packet {p:?}");
194 }
195
196 pub fn store_cookie(&mut self, p: &ClientboundStoreCookie) {
197 debug!("Got store cookie packet {p:?}");
198 }
199
200 pub fn transfer(&mut self, p: &ClientboundTransfer) {
201 debug!("Got transfer packet {p:?}");
202 }
203
204 pub fn select_known_packs(&mut self, p: &ClientboundSelectKnownPacks) {
205 debug!("Got select known packs packet {p:?}");
206
207 as_system::<Commands>(self.ecs, |mut commands| {
208 commands.trigger(SendConfigPacketEvent::new(
210 self.player,
211 ServerboundSelectKnownPacks {
212 known_packs: vec![],
213 },
214 ));
215 });
216 }
217
218 pub fn server_links(&mut self, p: &ClientboundServerLinks) {
219 debug!("Got server links packet {p:?}");
220 }
221
222 pub fn custom_report_details(&mut self, p: &ClientboundCustomReportDetails) {
223 debug!("Got custom report details packet {p:?}");
224 }
225
226 pub fn clear_dialog(&mut self, p: &ClientboundClearDialog) {
227 debug!("Got clear dialog packet {p:?}");
228 }
229 pub fn show_dialog(&mut self, p: &ClientboundShowDialog) {
230 debug!("Got show dialog packet {p:?}");
231 }
232}