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