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