1mod events;
2
3use std::{collections::HashSet, ops::Add, sync::Arc};
4
5use azalea_core::{
6 game_type::GameMode,
7 math,
8 position::{ChunkPos, Vec3},
9};
10use azalea_entity::{
11 Dead, EntityBundle, EntityKind, LastSentPosition, LoadedBy, LocalEntity, LookDirection,
12 Physics, Position, RelativeEntityUpdate,
13 indexing::{EntityIdIndex, EntityUuidIndex},
14 metadata::{Health, apply_metadata},
15};
16use azalea_protocol::packets::game::*;
17use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId, PartialInstance};
18use bevy_ecs::{prelude::*, system::SystemState};
19pub use events::*;
20use tracing::{debug, error, trace, warn};
21
22use crate::{
23 ClientInformation, PlayerInfo,
24 chat::{ChatPacket, ChatReceivedEvent},
25 chunks, declare_packet_handlers,
26 disconnect::DisconnectEvent,
27 inventory::{
28 ClientSideCloseContainerEvent, Inventory, MenuOpenedEvent, SetContainerContentEvent,
29 },
30 local_player::{
31 GameProfileComponent, Hunger, InstanceHolder, LocalGameMode, PlayerAbilities, TabList,
32 },
33 movement::{KnockbackEvent, KnockbackType},
34 packet::as_system,
35 raw_connection::RawConnection,
36};
37
38pub fn process_packet_events(ecs: &mut World) {
39 let mut events_owned = Vec::<(Entity, Arc<ClientboundGamePacket>)>::new();
40
41 {
42 let mut system_state = SystemState::<EventReader<ReceivePacketEvent>>::new(ecs);
43 let mut events = system_state.get_mut(ecs);
44 for ReceivePacketEvent {
45 entity: player_entity,
46 packet,
47 } in events.read()
48 {
49 events_owned.push((*player_entity, packet.clone()));
51 }
52 }
53
54 for (player_entity, packet) in events_owned {
55 let mut handler = GamePacketHandler {
56 player: player_entity,
57 ecs,
58 };
59
60 declare_packet_handlers!(
62 ClientboundGamePacket,
63 packet.as_ref(),
64 handler,
65 [
66 login,
67 set_chunk_cache_radius,
68 chunk_batch_start,
69 chunk_batch_finished,
70 custom_payload,
71 change_difficulty,
72 commands,
73 player_abilities,
74 set_cursor_item,
75 update_tags,
76 disconnect,
77 update_recipes,
78 entity_event,
79 player_position,
80 player_info_update,
81 player_info_remove,
82 set_chunk_cache_center,
83 chunks_biomes,
84 light_update,
85 level_chunk_with_light,
86 add_entity,
87 set_entity_data,
88 update_attributes,
89 set_entity_motion,
90 set_entity_link,
91 initialize_border,
92 set_time,
93 set_default_spawn_position,
94 set_health,
95 set_experience,
96 teleport_entity,
97 update_advancements,
98 rotate_head,
99 move_entity_pos,
100 move_entity_pos_rot,
101 move_entity_rot,
102 keep_alive,
103 remove_entities,
104 player_chat,
105 system_chat,
106 disguised_chat,
107 sound,
108 level_event,
109 block_update,
110 animate,
111 section_blocks_update,
112 game_event,
113 level_particles,
114 server_data,
115 set_equipment,
116 update_mob_effect,
117 award_stats,
118 block_changed_ack,
119 block_destruction,
120 block_entity_data,
121 block_event,
122 boss_event,
123 command_suggestions,
124 container_set_content,
125 container_set_data,
126 container_set_slot,
127 container_close,
128 cooldown,
129 custom_chat_completions,
130 delete_chat,
131 explode,
132 forget_level_chunk,
133 horse_screen_open,
134 map_item_data,
135 merchant_offers,
136 move_vehicle,
137 open_book,
138 open_screen,
139 open_sign_editor,
140 ping,
141 place_ghost_recipe,
142 player_combat_end,
143 player_combat_enter,
144 player_combat_kill,
145 player_look_at,
146 remove_mob_effect,
147 resource_pack_push,
148 resource_pack_pop,
149 respawn,
150 start_configuration,
151 entity_position_sync,
152 select_advancements_tab,
153 set_action_bar_text,
154 set_border_center,
155 set_border_lerp_size,
156 set_border_size,
157 set_border_warning_delay,
158 set_border_warning_distance,
159 set_camera,
160 set_display_objective,
161 set_objective,
162 set_passengers,
163 set_player_team,
164 set_score,
165 set_simulation_distance,
166 set_subtitle_text,
167 set_title_text,
168 set_titles_animation,
169 clear_titles,
170 sound_entity,
171 stop_sound,
172 tab_list,
173 tag_query,
174 take_item_entity,
175 bundle_delimiter,
176 damage_event,
177 hurt_animation,
178 ticking_state,
179 ticking_step,
180 reset_score,
181 cookie_request,
182 debug_sample,
183 pong_response,
184 store_cookie,
185 transfer,
186 move_minecart_along_track,
187 set_held_slot,
188 set_player_inventory,
189 projectile_power,
190 custom_report_details,
191 server_links,
192 player_rotation,
193 recipe_book_add,
194 recipe_book_remove,
195 recipe_book_settings,
196 test_instance_block_status,
197 ]
198 );
199 }
200}
201
202pub struct GamePacketHandler<'a> {
203 pub ecs: &'a mut World,
204 pub player: Entity,
205}
206impl GamePacketHandler<'_> {
207 pub fn login(&mut self, p: &ClientboundLogin) {
208 debug!("Got login packet");
209
210 as_system::<(
211 Commands,
212 Query<
213 (
214 &GameProfileComponent,
215 &ClientInformation,
216 Option<&mut InstanceName>,
217 Option<&mut LoadedBy>,
218 &mut EntityIdIndex,
219 &mut InstanceHolder,
220 ),
221 With<LocalEntity>,
222 >,
223 EventWriter<InstanceLoadedEvent>,
224 ResMut<InstanceContainer>,
225 ResMut<EntityUuidIndex>,
226 Query<&mut LoadedBy, Without<LocalEntity>>,
227 )>(
228 self.ecs,
229 |(
230 mut commands,
231 mut query,
232 mut instance_loaded_events,
233 mut instance_container,
234 mut entity_uuid_index,
235 mut loaded_by_query,
236 )| {
237 let (
238 game_profile,
239 client_information,
240 instance_name,
241 loaded_by,
242 mut entity_id_index,
243 mut instance_holder,
244 ) = query.get_mut(self.player).unwrap();
245
246 let new_instance_name = p.common.dimension.clone();
247
248 if let Some(mut instance_name) = instance_name {
249 *instance_name = instance_name.clone();
250 } else {
251 commands
252 .entity(self.player)
253 .insert(InstanceName(new_instance_name.clone()));
254 }
255
256 let Some((_dimension_type, dimension_data)) = p
257 .common
258 .dimension_type(&instance_holder.instance.read().registries)
259 else {
260 return;
261 };
262
263 let weak_instance = instance_container.insert(
266 new_instance_name.clone(),
267 dimension_data.height,
268 dimension_data.min_y,
269 &instance_holder.instance.read().registries,
270 );
271 instance_loaded_events.send(InstanceLoadedEvent {
272 entity: self.player,
273 name: new_instance_name.clone(),
274 instance: Arc::downgrade(&weak_instance),
275 });
276
277 *instance_holder.partial_instance.write() = PartialInstance::new(
282 azalea_world::chunk_storage::calculate_chunk_storage_range(
283 client_information.view_distance.into(),
284 ),
285 Some(self.player),
288 );
289 {
290 let map = instance_holder.instance.read().registries.map.clone();
291 let new_registries = &mut weak_instance.write().registries;
292 for (registry_name, registry) in map {
294 new_registries.map.insert(registry_name, registry);
295 }
296 }
297 instance_holder.instance = weak_instance;
298
299 let entity_bundle = EntityBundle::new(
300 game_profile.uuid,
301 Vec3::ZERO,
302 azalea_registry::EntityKind::Player,
303 new_instance_name,
304 );
305 let entity_id = p.player_id;
306 commands.entity(self.player).insert((
308 entity_id,
309 LocalGameMode {
310 current: p.common.game_type,
311 previous: p.common.previous_game_type.into(),
312 },
313 entity_bundle,
314 ));
315
316 azalea_entity::indexing::add_entity_to_indexes(
317 entity_id,
318 self.player,
319 Some(game_profile.uuid),
320 &mut entity_id_index,
321 &mut entity_uuid_index,
322 &mut instance_holder.instance.write(),
323 );
324
325 for mut loaded_by in &mut loaded_by_query.iter_mut() {
327 loaded_by.remove(&self.player);
328 }
329
330 if let Some(mut loaded_by) = loaded_by {
332 loaded_by.insert(self.player);
333 } else {
334 commands
335 .entity(self.player)
336 .insert(LoadedBy(HashSet::from_iter(vec![self.player])));
337 }
338
339 debug!(
341 "Sending client information because login: {:?}",
342 client_information
343 );
344 commands.trigger(SendPacketEvent::new(self.player,
345 azalea_protocol::packets::game::s_client_information::ServerboundClientInformation { information: client_information.clone() },
346 ));
347 },
348 );
349 }
350
351 pub fn set_chunk_cache_radius(&mut self, p: &ClientboundSetChunkCacheRadius) {
352 debug!("Got set chunk cache radius packet {p:?}");
353 }
354
355 pub fn chunk_batch_start(&mut self, _p: &ClientboundChunkBatchStart) {
356 debug!("Got chunk batch start");
359
360 as_system::<EventWriter<_>>(self.ecs, |mut events| {
361 events.send(chunks::ChunkBatchStartEvent {
362 entity: self.player,
363 });
364 });
365 }
366
367 pub fn chunk_batch_finished(&mut self, p: &ClientboundChunkBatchFinished) {
368 debug!("Got chunk batch finished {p:?}");
369
370 as_system::<EventWriter<_>>(self.ecs, |mut events| {
371 events.send(chunks::ChunkBatchFinishedEvent {
372 entity: self.player,
373 batch_size: p.batch_size,
374 });
375 });
376 }
377
378 pub fn custom_payload(&mut self, p: &ClientboundCustomPayload) {
379 debug!("Got custom payload packet {p:?}");
380 }
381
382 pub fn change_difficulty(&mut self, p: &ClientboundChangeDifficulty) {
383 debug!("Got difficulty packet {p:?}");
384 }
385
386 pub fn commands(&mut self, _p: &ClientboundCommands) {
387 debug!("Got declare commands packet");
388 }
389
390 pub fn player_abilities(&mut self, p: &ClientboundPlayerAbilities) {
391 debug!("Got player abilities packet {p:?}");
392
393 as_system::<Query<&mut PlayerAbilities>>(self.ecs, |mut query| {
394 let mut player_abilities = query.get_mut(self.player).unwrap();
395
396 *player_abilities = PlayerAbilities::from(p);
397 });
398 }
399
400 pub fn set_cursor_item(&mut self, p: &ClientboundSetCursorItem) {
401 debug!("Got set cursor item packet {p:?}");
402 }
403
404 pub fn update_tags(&mut self, _p: &ClientboundUpdateTags) {
405 debug!("Got update tags packet");
406 }
407
408 pub fn disconnect(&mut self, p: &ClientboundDisconnect) {
409 warn!("Got disconnect packet {p:?}");
410
411 as_system::<EventWriter<_>>(self.ecs, |mut events| {
412 events.send(DisconnectEvent {
413 entity: self.player,
414 reason: Some(p.reason.clone()),
415 });
416 });
417 }
418
419 pub fn update_recipes(&mut self, _p: &ClientboundUpdateRecipes) {
420 debug!("Got update recipes packet");
421 }
422
423 pub fn entity_event(&mut self, _p: &ClientboundEntityEvent) {
424 }
426
427 pub fn player_position(&mut self, p: &ClientboundPlayerPosition) {
428 debug!("Got player position packet {p:?}");
429
430 as_system::<(
431 Query<(
432 &mut Physics,
433 &mut LookDirection,
434 &mut Position,
435 &mut LastSentPosition,
436 )>,
437 Commands,
438 )>(self.ecs, |(mut query, mut commands)| {
439 let Ok((mut physics, mut direction, mut position, mut last_sent_position)) =
440 query.get_mut(self.player)
441 else {
442 return;
443 };
444
445 **last_sent_position = **position;
446
447 fn apply_change<T: Add<Output = T>>(base: T, condition: bool, change: T) -> T {
448 if condition { base + change } else { change }
449 }
450
451 let new_x = apply_change(position.x, p.relative.x, p.change.pos.x);
452 let new_y = apply_change(position.y, p.relative.y, p.change.pos.y);
453 let new_z = apply_change(position.z, p.relative.z, p.change.pos.z);
454
455 let new_y_rot = apply_change(
456 direction.y_rot,
457 p.relative.y_rot,
458 p.change.look_direction.y_rot,
459 );
460 let new_x_rot = apply_change(
461 direction.x_rot,
462 p.relative.x_rot,
463 p.change.look_direction.x_rot,
464 );
465
466 let mut new_delta_from_rotations = physics.velocity;
467 if p.relative.rotate_delta {
468 let y_rot_delta = direction.y_rot - new_y_rot;
469 let x_rot_delta = direction.x_rot - new_x_rot;
470 new_delta_from_rotations = new_delta_from_rotations
471 .x_rot(math::to_radians(x_rot_delta as f64) as f32)
472 .y_rot(math::to_radians(y_rot_delta as f64) as f32);
473 }
474
475 let new_delta = Vec3::new(
476 apply_change(
477 new_delta_from_rotations.x,
478 p.relative.delta_x,
479 p.change.delta.x,
480 ),
481 apply_change(
482 new_delta_from_rotations.y,
483 p.relative.delta_y,
484 p.change.delta.y,
485 ),
486 apply_change(
487 new_delta_from_rotations.z,
488 p.relative.delta_z,
489 p.change.delta.z,
490 ),
491 );
492
493 physics.velocity = new_delta;
496
497 (direction.y_rot, direction.x_rot) = (new_y_rot, new_x_rot);
498
499 let new_pos = Vec3::new(new_x, new_y, new_z);
500 if new_pos != **position {
501 **position = new_pos;
502 }
503
504 physics.set_old_pos(&position);
506
507 commands.trigger(SendPacketEvent::new(
510 self.player,
511 ServerboundAcceptTeleportation { id: p.id },
512 ));
513 commands.trigger(SendPacketEvent::new(
514 self.player,
515 ServerboundMovePlayerPosRot {
516 pos: new_pos,
517 look_direction: LookDirection::new(new_y_rot, new_x_rot),
518 on_ground: false,
520 },
521 ));
522 });
523 }
524
525 pub fn player_info_update(&mut self, p: &ClientboundPlayerInfoUpdate) {
526 debug!("Got player info packet {p:?}");
527
528 as_system::<(
529 Query<&mut TabList>,
530 EventWriter<AddPlayerEvent>,
531 EventWriter<UpdatePlayerEvent>,
532 ResMut<TabList>,
533 )>(
534 self.ecs,
535 |(
536 mut query,
537 mut add_player_events,
538 mut update_player_events,
539 mut tab_list_resource,
540 )| {
541 let mut tab_list = query.get_mut(self.player).unwrap();
542
543 for updated_info in &p.entries {
544 if p.actions.add_player {
546 let info = PlayerInfo {
547 profile: updated_info.profile.clone(),
548 uuid: updated_info.profile.uuid,
549 gamemode: updated_info.game_mode,
550 latency: updated_info.latency,
551 display_name: updated_info.display_name.clone(),
552 };
553 tab_list.insert(updated_info.profile.uuid, info.clone());
554 add_player_events.send(AddPlayerEvent {
555 entity: self.player,
556 info: info.clone(),
557 });
558 } else if let Some(info) = tab_list.get_mut(&updated_info.profile.uuid) {
559 if p.actions.update_game_mode {
562 info.gamemode = updated_info.game_mode;
563 }
564 if p.actions.update_latency {
565 info.latency = updated_info.latency;
566 }
567 if p.actions.update_display_name {
568 info.display_name.clone_from(&updated_info.display_name);
569 }
570 update_player_events.send(UpdatePlayerEvent {
571 entity: self.player,
572 info: info.clone(),
573 });
574 } else {
575 let uuid = updated_info.profile.uuid;
576 debug!("Ignoring PlayerInfoUpdate for unknown player {uuid}");
577 }
578 }
579
580 *tab_list_resource = tab_list.clone();
581 },
582 );
583 }
584
585 pub fn player_info_remove(&mut self, p: &ClientboundPlayerInfoRemove) {
586 debug!("Got chunk cache center packet {p:?}");
587
588 as_system::<(
589 Query<&mut TabList>,
590 EventWriter<RemovePlayerEvent>,
591 ResMut<TabList>,
592 )>(
593 self.ecs,
594 |(mut query, mut remove_player_events, mut tab_list_resource)| {
595 let mut tab_list = query.get_mut(self.player).unwrap();
596
597 for uuid in &p.profile_ids {
598 if let Some(info) = tab_list.remove(uuid) {
599 remove_player_events.send(RemovePlayerEvent {
600 entity: self.player,
601 info,
602 });
603 }
604 tab_list_resource.remove(uuid);
605 }
606 },
607 );
608 }
609
610 pub fn set_chunk_cache_center(&mut self, p: &ClientboundSetChunkCacheCenter) {
611 debug!("Got chunk cache center packet {p:?}");
612
613 as_system::<Query<&mut InstanceHolder>>(self.ecs, |mut query| {
614 let instance_holder = query.get_mut(self.player).unwrap();
615 let mut partial_world = instance_holder.partial_instance.write();
616
617 partial_world
618 .chunks
619 .update_view_center(ChunkPos::new(p.x, p.z));
620 });
621 }
622
623 pub fn chunks_biomes(&mut self, _p: &ClientboundChunksBiomes) {}
624
625 pub fn light_update(&mut self, _p: &ClientboundLightUpdate) {
626 }
628
629 pub fn level_chunk_with_light(&mut self, p: &ClientboundLevelChunkWithLight) {
630 debug!("Got chunk with light packet {} {}", p.x, p.z);
631
632 as_system::<EventWriter<_>>(self.ecs, |mut events| {
633 events.send(chunks::ReceiveChunkEvent {
634 entity: self.player,
635 packet: p.clone(),
636 });
637 });
638 }
639
640 pub fn add_entity(&mut self, p: &ClientboundAddEntity) {
641 debug!("Got add entity packet {p:?}");
642
643 as_system::<(
644 Commands,
645 Query<(&mut EntityIdIndex, Option<&InstanceName>, Option<&TabList>)>,
646 Query<&mut LoadedBy>,
647 Query<Entity>,
648 Res<InstanceContainer>,
649 ResMut<EntityUuidIndex>,
650 )>(
651 self.ecs,
652 |(
653 mut commands,
654 mut query,
655 mut loaded_by_query,
656 entity_query,
657 instance_container,
658 mut entity_uuid_index,
659 )| {
660 let (mut entity_id_index, instance_name, tab_list) =
661 query.get_mut(self.player).unwrap();
662
663 let entity_id = p.id;
664
665 let Some(instance_name) = instance_name else {
666 warn!("got add player packet but we haven't gotten a login packet yet");
667 return;
668 };
669
670 let instance = instance_container.get(instance_name).unwrap();
672 if let Some(&ecs_entity) = instance.read().entity_by_id.get(&entity_id) {
673 let Ok(mut loaded_by) = loaded_by_query.get_mut(ecs_entity) else {
675 let entity_in_ecs = entity_query.get(ecs_entity).is_ok();
679
680 if entity_in_ecs {
681 error!(
682 "LoadedBy for entity {entity_id:?} ({ecs_entity:?}) isn't in the ecs, but the entity is in entity_by_id"
683 );
684 } else {
685 error!(
686 "Entity {entity_id:?} ({ecs_entity:?}) isn't in the ecs, but the entity is in entity_by_id"
687 );
688 }
689 return;
690 };
691 loaded_by.insert(self.player);
692
693 entity_id_index.insert(entity_id, ecs_entity);
695
696 debug!("added to LoadedBy of entity {ecs_entity:?} with id {entity_id:?}");
697 return;
698 };
699
700 let bundle = p.as_entity_bundle((**instance_name).clone());
703 let mut spawned =
704 commands.spawn((entity_id, LoadedBy(HashSet::from([self.player])), bundle));
705 let ecs_entity: Entity = spawned.id();
706 debug!(
707 "spawned entity {ecs_entity:?} with id {entity_id:?} at {pos:?}",
708 pos = p.position
709 );
710
711 azalea_entity::indexing::add_entity_to_indexes(
712 entity_id,
713 ecs_entity,
714 Some(p.uuid),
715 &mut entity_id_index,
716 &mut entity_uuid_index,
717 &mut instance.write(),
718 );
719
720 if let Some(tab_list) = tab_list {
722 if let Some(player_info) = tab_list.get(&p.uuid) {
726 spawned.insert(GameProfileComponent(player_info.profile.clone()));
727 }
728 }
729
730 p.apply_metadata(&mut spawned);
733 },
734 );
735 }
736
737 pub fn set_entity_data(&mut self, p: &ClientboundSetEntityData) {
738 as_system::<(
739 Commands,
740 Query<(&EntityIdIndex, &InstanceHolder)>,
741 Query<&EntityKind>,
744 )>(self.ecs, |(mut commands, query, entity_kind_query)| {
745 let (entity_id_index, instance_holder) = query.get(self.player).unwrap();
746
747 let entity = entity_id_index.get(p.id);
748
749 let Some(entity) = entity else {
750 debug!(
752 "Server sent an entity data packet for an entity id ({}) that we don't know about",
753 p.id
754 );
755 return;
756 };
757
758 let Ok(entity_kind) = entity_kind_query.get(entity) else {
759 debug!(
760 "Server sent an entity data packet for an entity id ({}) that we have indexed as {entity} but they don't have EntityKind. Maybe a second local client that just disconnected?",
761 p.id
762 );
763 return;
764 };
765 let entity_kind = **entity_kind;
766
767 debug!("Got set entity data packet {p:?} for entity of kind {entity_kind:?}");
768
769 let packed_items = p.packed_items.clone().to_vec();
770
771 commands.entity(entity).queue(RelativeEntityUpdate::new(
774 instance_holder.partial_instance.clone(),
775 move |entity| {
776 let entity_id = entity.id();
777 entity.world_scope(|world| {
778 let mut commands_system_state = SystemState::<Commands>::new(world);
779 let mut commands = commands_system_state.get_mut(world);
780 let mut entity_commands = commands.entity(entity_id);
781 if let Err(e) =
782 apply_metadata(&mut entity_commands, entity_kind, packed_items)
783 {
784 warn!("{e}");
785 }
786 commands_system_state.apply(world);
787 });
788 },
789 ));
790 });
791 }
792
793 pub fn update_attributes(&mut self, _p: &ClientboundUpdateAttributes) {
794 }
796
797 pub fn set_entity_motion(&mut self, p: &ClientboundSetEntityMotion) {
798 as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
802 self.ecs,
803 |(mut commands, query)| {
804 let (entity_id_index, instance_holder) = query.get(self.player).unwrap();
805
806 let Some(entity) = entity_id_index.get(p.id) else {
807 debug!(
811 "Got set entity motion packet for unknown entity id {}",
812 p.id
813 );
814 return;
815 };
816
817 let knockback = KnockbackType::Set(Vec3 {
821 x: p.delta.xa as f64 / 8000.,
822 y: p.delta.ya as f64 / 8000.,
823 z: p.delta.za as f64 / 8000.,
824 });
825
826 commands.entity(entity).queue(RelativeEntityUpdate::new(
827 instance_holder.partial_instance.clone(),
828 move |entity_mut| {
829 entity_mut.world_scope(|world| {
830 world.send_event(KnockbackEvent { entity, knockback })
831 });
832 },
833 ));
834 },
835 );
836 }
837
838 pub fn set_entity_link(&mut self, p: &ClientboundSetEntityLink) {
839 debug!("Got set entity link packet {p:?}");
840 }
841
842 pub fn initialize_border(&mut self, p: &ClientboundInitializeBorder) {
843 debug!("Got initialize border packet {p:?}");
844 }
845
846 pub fn set_time(&mut self, _p: &ClientboundSetTime) {
847 }
849
850 pub fn set_default_spawn_position(&mut self, p: &ClientboundSetDefaultSpawnPosition) {
851 debug!("Got set default spawn position packet {p:?}");
852 }
853
854 pub fn set_health(&mut self, p: &ClientboundSetHealth) {
855 debug!("Got set health packet {p:?}");
856
857 as_system::<Query<(&mut Health, &mut Hunger)>>(self.ecs, |mut query| {
858 let (mut health, mut hunger) = query.get_mut(self.player).unwrap();
859
860 **health = p.health;
861 (hunger.food, hunger.saturation) = (p.food, p.saturation);
862
863 });
867 }
868
869 pub fn set_experience(&mut self, p: &ClientboundSetExperience) {
870 debug!("Got set experience packet {p:?}");
871 }
872
873 pub fn teleport_entity(&mut self, p: &ClientboundTeleportEntity) {
874 as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
875 self.ecs,
876 |(mut commands, mut query)| {
877 let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
878
879 let Some(entity) = entity_id_index.get(p.id) else {
880 warn!("Got teleport entity packet for unknown entity id {}", p.id);
881 return;
882 };
883
884 let new_pos = p.change.pos;
885 let new_look_direction = LookDirection {
886 x_rot: (p.change.look_direction.x_rot as i32 * 360) as f32 / 256.,
887 y_rot: (p.change.look_direction.y_rot as i32 * 360) as f32 / 256.,
888 };
889 commands.entity(entity).queue(RelativeEntityUpdate::new(
890 instance_holder.partial_instance.clone(),
891 move |entity| {
892 let mut position = entity.get_mut::<Position>().unwrap();
893 if new_pos != **position {
894 **position = new_pos;
895 }
896 let position = *position;
897 let mut look_direction = entity.get_mut::<LookDirection>().unwrap();
898 if new_look_direction != *look_direction {
899 *look_direction = new_look_direction;
900 }
901 let mut physics = entity.get_mut::<Physics>().unwrap();
903 physics.set_old_pos(&position);
904 },
905 ));
906 },
907 );
908 }
909
910 pub fn update_advancements(&mut self, p: &ClientboundUpdateAdvancements) {
911 debug!("Got update advancements packet {p:?}");
912 }
913
914 pub fn rotate_head(&mut self, _p: &ClientboundRotateHead) {}
915
916 pub fn move_entity_pos(&mut self, p: &ClientboundMoveEntityPos) {
917 as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
918 self.ecs,
919 |(mut commands, mut query)| {
920 let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
921
922 debug!("Got move entity pos packet {p:?}");
923
924 let entity_id = p.entity_id;
925 let Some(entity) = entity_id_index.get(entity_id) else {
926 debug!("Got move entity pos packet for unknown entity id {entity_id}");
927 return;
928 };
929
930 let new_delta = p.delta.clone();
931 let new_on_ground = p.on_ground;
932 commands.entity(entity).queue(RelativeEntityUpdate::new(
933 instance_holder.partial_instance.clone(),
934 move |entity_mut| {
935 let mut physics = entity_mut.get_mut::<Physics>().unwrap();
936 let new_pos = physics.vec_delta_codec.decode(
937 new_delta.xa as i64,
938 new_delta.ya as i64,
939 new_delta.za as i64,
940 );
941 physics.vec_delta_codec.set_base(new_pos);
942 physics.set_on_ground(new_on_ground);
943
944 let mut position = entity_mut.get_mut::<Position>().unwrap();
945 if new_pos != **position {
946 **position = new_pos;
947 }
948
949 trace!(
950 "Applied movement update for {entity_id} / {entity}",
951 entity = entity_mut.id()
952 );
953 },
954 ));
955 },
956 );
957 }
958
959 pub fn move_entity_pos_rot(&mut self, p: &ClientboundMoveEntityPosRot) {
960 as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
961 self.ecs,
962 |(mut commands, mut query)| {
963 let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
964
965 debug!("Got move entity pos rot packet {p:?}");
966
967 let entity = entity_id_index.get(p.entity_id);
968
969 let Some(entity) = entity else {
970 debug!(
972 "Got move entity pos rot packet for unknown entity id {}",
973 p.entity_id
974 );
975 return;
976 };
977
978 let new_delta = p.delta.clone();
979 let new_look_direction = LookDirection {
980 x_rot: (p.x_rot as i32 * 360) as f32 / 256.,
981 y_rot: (p.y_rot as i32 * 360) as f32 / 256.,
982 };
983
984 let new_on_ground = p.on_ground;
985
986 commands.entity(entity).queue(RelativeEntityUpdate::new(
987 instance_holder.partial_instance.clone(),
988 move |entity_mut| {
989 let mut physics = entity_mut.get_mut::<Physics>().unwrap();
990 let new_pos = physics.vec_delta_codec.decode(
991 new_delta.xa as i64,
992 new_delta.ya as i64,
993 new_delta.za as i64,
994 );
995 physics.vec_delta_codec.set_base(new_pos);
996 physics.set_on_ground(new_on_ground);
997
998 let mut position = entity_mut.get_mut::<Position>().unwrap();
999 if new_pos != **position {
1000 **position = new_pos;
1001 }
1002
1003 let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap();
1004 if new_look_direction != *look_direction {
1005 *look_direction = new_look_direction;
1006 }
1007 },
1008 ));
1009 },
1010 );
1011 }
1012
1013 pub fn move_entity_rot(&mut self, p: &ClientboundMoveEntityRot) {
1014 as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
1015 self.ecs,
1016 |(mut commands, mut query)| {
1017 let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
1018
1019 let entity = entity_id_index.get(p.entity_id);
1020 if let Some(entity) = entity {
1021 let new_look_direction = LookDirection {
1022 x_rot: (p.x_rot as i32 * 360) as f32 / 256.,
1023 y_rot: (p.y_rot as i32 * 360) as f32 / 256.,
1024 };
1025 let new_on_ground = p.on_ground;
1026
1027 commands.entity(entity).queue(RelativeEntityUpdate::new(
1028 instance_holder.partial_instance.clone(),
1029 move |entity_mut| {
1030 let mut physics = entity_mut.get_mut::<Physics>().unwrap();
1031 physics.set_on_ground(new_on_ground);
1032
1033 let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap();
1034 if new_look_direction != *look_direction {
1035 *look_direction = new_look_direction;
1036 }
1037 },
1038 ));
1039 } else {
1040 warn!(
1041 "Got move entity rot packet for unknown entity id {}",
1042 p.entity_id
1043 );
1044 }
1045 },
1046 );
1047 }
1048 pub fn keep_alive(&mut self, p: &ClientboundKeepAlive) {
1049 debug!("Got keep alive packet {p:?} for {:?}", self.player);
1050
1051 as_system::<(EventWriter<KeepAliveEvent>, Commands)>(
1052 self.ecs,
1053 |(mut keepalive_events, mut commands)| {
1054 keepalive_events.send(KeepAliveEvent {
1055 entity: self.player,
1056 id: p.id,
1057 });
1058 commands.trigger(SendPacketEvent::new(
1059 self.player,
1060 ServerboundKeepAlive { id: p.id },
1061 ));
1062 },
1063 );
1064 }
1065
1066 pub fn remove_entities(&mut self, p: &ClientboundRemoveEntities) {
1067 debug!("Got remove entities packet {p:?}");
1068
1069 as_system::<(Query<&mut EntityIdIndex>, Query<&mut LoadedBy>)>(
1070 self.ecs,
1071 |(mut query, mut entity_query)| {
1072 let Ok(mut entity_id_index) = query.get_mut(self.player) else {
1073 warn!("our local player doesn't have EntityIdIndex");
1074 return;
1075 };
1076
1077 for &id in &p.entity_ids {
1078 let Some(entity) = entity_id_index.remove(id) else {
1079 debug!(
1080 "Tried to remove entity with id {id} but it wasn't in the EntityIdIndex. This may be expected on certain server setups (like if they're using VeryManyPlayers)."
1081 );
1082 continue;
1083 };
1084 let Ok(mut loaded_by) = entity_query.get_mut(entity) else {
1085 warn!(
1086 "tried to despawn entity {id} but it doesn't have a LoadedBy component",
1087 );
1088 continue;
1089 };
1090
1091 loaded_by.remove(&self.player);
1098 }
1099 },
1100 );
1101 }
1102 pub fn player_chat(&mut self, p: &ClientboundPlayerChat) {
1103 debug!("Got player chat packet {p:?}");
1104
1105 as_system::<EventWriter<_>>(self.ecs, |mut events| {
1106 events.send(ChatReceivedEvent {
1107 entity: self.player,
1108 packet: ChatPacket::Player(Arc::new(p.clone())),
1109 });
1110 });
1111 }
1112
1113 pub fn system_chat(&mut self, p: &ClientboundSystemChat) {
1114 debug!("Got system chat packet {p:?}");
1115
1116 as_system::<EventWriter<_>>(self.ecs, |mut events| {
1117 events.send(ChatReceivedEvent {
1118 entity: self.player,
1119 packet: ChatPacket::System(Arc::new(p.clone())),
1120 });
1121 });
1122 }
1123
1124 pub fn disguised_chat(&mut self, p: &ClientboundDisguisedChat) {
1125 debug!("Got disguised chat packet {p:?}");
1126
1127 as_system::<EventWriter<_>>(self.ecs, |mut events| {
1128 events.send(ChatReceivedEvent {
1129 entity: self.player,
1130 packet: ChatPacket::Disguised(Arc::new(p.clone())),
1131 });
1132 });
1133 }
1134
1135 pub fn sound(&mut self, _p: &ClientboundSound) {}
1136
1137 pub fn level_event(&mut self, p: &ClientboundLevelEvent) {
1138 debug!("Got level event packet {p:?}");
1139 }
1140
1141 pub fn block_update(&mut self, p: &ClientboundBlockUpdate) {
1142 debug!("Got block update packet {p:?}");
1143
1144 as_system::<Query<&mut InstanceHolder>>(self.ecs, |mut query| {
1145 let local_player = query.get_mut(self.player).unwrap();
1146
1147 let world = local_player.instance.write();
1148
1149 world.chunks.set_block_state(&p.pos, p.block_state);
1150 });
1151 }
1152
1153 pub fn animate(&mut self, p: &ClientboundAnimate) {
1154 debug!("Got animate packet {p:?}");
1155 }
1156
1157 pub fn section_blocks_update(&mut self, p: &ClientboundSectionBlocksUpdate) {
1158 debug!("Got section blocks update packet {p:?}");
1159
1160 as_system::<Query<&mut InstanceHolder>>(self.ecs, |mut query| {
1161 let local_player = query.get_mut(self.player).unwrap();
1162 let world = local_player.instance.write();
1163 for state in &p.states {
1164 world
1165 .chunks
1166 .set_block_state(&(p.section_pos + state.pos), state.state);
1167 }
1168 });
1169 }
1170
1171 pub fn game_event(&mut self, p: &ClientboundGameEvent) {
1172 use azalea_protocol::packets::game::c_game_event::EventType;
1173
1174 debug!("Got game event packet {p:?}");
1175
1176 #[allow(clippy::single_match)]
1177 match p.event {
1178 EventType::ChangeGameMode => {
1179 as_system::<Query<&mut LocalGameMode>>(self.ecs, |mut query| {
1180 let mut local_game_mode = query.get_mut(self.player).unwrap();
1181 if let Some(new_game_mode) = GameMode::from_id(p.param as u8) {
1182 local_game_mode.current = new_game_mode;
1183 }
1184 });
1185 }
1186 _ => {}
1187 }
1188 }
1189
1190 pub fn level_particles(&mut self, p: &ClientboundLevelParticles) {
1191 debug!("Got level particles packet {p:?}");
1192 }
1193
1194 pub fn server_data(&mut self, p: &ClientboundServerData) {
1195 debug!("Got server data packet {p:?}");
1196 }
1197
1198 pub fn set_equipment(&mut self, p: &ClientboundSetEquipment) {
1199 debug!("Got set equipment packet {p:?}");
1200 }
1201
1202 pub fn update_mob_effect(&mut self, p: &ClientboundUpdateMobEffect) {
1203 debug!("Got update mob effect packet {p:?}");
1204 }
1205
1206 pub fn award_stats(&mut self, _p: &ClientboundAwardStats) {}
1207
1208 pub fn block_changed_ack(&mut self, _p: &ClientboundBlockChangedAck) {}
1209
1210 pub fn block_destruction(&mut self, _p: &ClientboundBlockDestruction) {}
1211
1212 pub fn block_entity_data(&mut self, _p: &ClientboundBlockEntityData) {}
1213
1214 pub fn block_event(&mut self, p: &ClientboundBlockEvent) {
1215 debug!("Got block event packet {p:?}");
1216 }
1217
1218 pub fn boss_event(&mut self, _p: &ClientboundBossEvent) {}
1219
1220 pub fn command_suggestions(&mut self, _p: &ClientboundCommandSuggestions) {}
1221
1222 pub fn container_set_content(&mut self, p: &ClientboundContainerSetContent) {
1223 debug!("Got container set content packet {p:?}");
1224
1225 as_system::<(Query<&mut Inventory>, EventWriter<_>)>(
1226 self.ecs,
1227 |(mut query, mut events)| {
1228 let mut inventory = query.get_mut(self.player).unwrap();
1229
1230 if p.container_id == 0 {
1232 for (i, slot) in p.items.iter().enumerate() {
1234 if let Some(slot_mut) = inventory.inventory_menu.slot_mut(i) {
1235 *slot_mut = slot.clone();
1236 }
1237 }
1238 } else {
1239 events.send(SetContainerContentEvent {
1240 entity: self.player,
1241 slots: p.items.clone(),
1242 container_id: p.container_id,
1243 });
1244 }
1245 },
1246 );
1247 }
1248
1249 pub fn container_set_data(&mut self, p: &ClientboundContainerSetData) {
1250 debug!("Got container set data packet {p:?}");
1251
1252 }
1261
1262 pub fn container_set_slot(&mut self, p: &ClientboundContainerSetSlot) {
1263 debug!("Got container set slot packet {p:?}");
1264
1265 as_system::<Query<&mut Inventory>>(self.ecs, |mut query| {
1266 let mut inventory = query.get_mut(self.player).unwrap();
1267
1268 if p.container_id == -1 {
1269 inventory.carried = p.item_stack.clone();
1271 } else if p.container_id == -2 {
1272 if let Some(slot) = inventory.inventory_menu.slot_mut(p.slot.into()) {
1273 *slot = p.item_stack.clone();
1274 }
1275 } else {
1276 let is_creative_mode_and_inventory_closed = false;
1277 if p.container_id == 0 && azalea_inventory::Player::is_hotbar_slot(p.slot.into()) {
1280 if let Some(slot) = inventory.inventory_menu.slot_mut(p.slot.into()) {
1283 *slot = p.item_stack.clone();
1284 }
1285 } else if p.container_id == inventory.id
1286 && (p.container_id != 0 || !is_creative_mode_and_inventory_closed)
1287 {
1288 if let Some(slot) = inventory.menu_mut().slot_mut(p.slot.into()) {
1290 *slot = p.item_stack.clone();
1291 inventory.state_id = p.state_id;
1292 }
1293 }
1294 }
1295 });
1296 }
1297
1298 pub fn container_close(&mut self, p: &ClientboundContainerClose) {
1299 debug!("Got container close packet {p:?}");
1303
1304 as_system::<EventWriter<_>>(self.ecs, |mut events| {
1305 events.send(ClientSideCloseContainerEvent {
1306 entity: self.player,
1307 });
1308 });
1309 }
1310
1311 pub fn cooldown(&mut self, _p: &ClientboundCooldown) {}
1312
1313 pub fn custom_chat_completions(&mut self, _p: &ClientboundCustomChatCompletions) {}
1314
1315 pub fn delete_chat(&mut self, _p: &ClientboundDeleteChat) {}
1316
1317 pub fn explode(&mut self, p: &ClientboundExplode) {
1318 trace!("Got explode packet {p:?}");
1319
1320 as_system::<EventWriter<_>>(self.ecs, |mut knockback_events| {
1321 if let Some(knockback) = p.knockback {
1322 knockback_events.send(KnockbackEvent {
1323 entity: self.player,
1324 knockback: KnockbackType::Set(knockback),
1325 });
1326 }
1327 });
1328 }
1329
1330 pub fn forget_level_chunk(&mut self, p: &ClientboundForgetLevelChunk) {
1331 debug!("Got forget level chunk packet {p:?}");
1332
1333 as_system::<Query<&mut InstanceHolder>>(self.ecs, |mut query| {
1334 let local_player = query.get_mut(self.player).unwrap();
1335
1336 let mut partial_instance = local_player.partial_instance.write();
1337
1338 partial_instance.chunks.limited_set(&p.pos, None);
1339 });
1340 }
1341
1342 pub fn horse_screen_open(&mut self, _p: &ClientboundHorseScreenOpen) {}
1343
1344 pub fn map_item_data(&mut self, _p: &ClientboundMapItemData) {}
1345
1346 pub fn merchant_offers(&mut self, _p: &ClientboundMerchantOffers) {}
1347
1348 pub fn move_vehicle(&mut self, _p: &ClientboundMoveVehicle) {}
1349
1350 pub fn open_book(&mut self, _p: &ClientboundOpenBook) {}
1351
1352 pub fn open_screen(&mut self, p: &ClientboundOpenScreen) {
1353 debug!("Got open screen packet {p:?}");
1354
1355 as_system::<EventWriter<_>>(self.ecs, |mut events| {
1356 events.send(MenuOpenedEvent {
1357 entity: self.player,
1358 window_id: p.container_id,
1359 menu_type: p.menu_type,
1360 title: p.title.to_owned(),
1361 });
1362 });
1363 }
1364
1365 pub fn open_sign_editor(&mut self, _p: &ClientboundOpenSignEditor) {}
1366
1367 pub fn ping(&mut self, p: &ClientboundPing) {
1368 debug!("Got ping packet {p:?}");
1369
1370 as_system::<Commands>(self.ecs, |mut commands| {
1371 commands.trigger_targets(PingEvent(p.clone()), self.player);
1372 });
1373 }
1374
1375 pub fn place_ghost_recipe(&mut self, _p: &ClientboundPlaceGhostRecipe) {}
1376
1377 pub fn player_combat_end(&mut self, _p: &ClientboundPlayerCombatEnd) {}
1378
1379 pub fn player_combat_enter(&mut self, _p: &ClientboundPlayerCombatEnter) {}
1380
1381 pub fn player_combat_kill(&mut self, p: &ClientboundPlayerCombatKill) {
1382 debug!("Got player kill packet {p:?}");
1383
1384 as_system::<(
1385 Commands,
1386 Query<(&MinecraftEntityId, Option<&Dead>)>,
1387 EventWriter<_>,
1388 )>(self.ecs, |(mut commands, mut query, mut events)| {
1389 let (entity_id, dead) = query.get_mut(self.player).unwrap();
1390
1391 if *entity_id == p.player_id && dead.is_none() {
1392 commands.entity(self.player).insert(Dead);
1393 events.send(DeathEvent {
1394 entity: self.player,
1395 packet: Some(p.clone()),
1396 });
1397 }
1398 });
1399 }
1400
1401 pub fn player_look_at(&mut self, _p: &ClientboundPlayerLookAt) {}
1402
1403 pub fn remove_mob_effect(&mut self, _p: &ClientboundRemoveMobEffect) {}
1404
1405 pub fn resource_pack_push(&mut self, p: &ClientboundResourcePackPush) {
1406 debug!("Got resource pack packet {p:?}");
1407
1408 as_system::<EventWriter<_>>(self.ecs, |mut events| {
1409 events.send(ResourcePackEvent {
1410 entity: self.player,
1411 id: p.id,
1412 url: p.url.to_owned(),
1413 hash: p.hash.to_owned(),
1414 required: p.required,
1415 prompt: p.prompt.to_owned(),
1416 });
1417 });
1418 }
1419
1420 pub fn resource_pack_pop(&mut self, _p: &ClientboundResourcePackPop) {}
1421
1422 pub fn respawn(&mut self, p: &ClientboundRespawn) {
1423 debug!("Got respawn packet {p:?}");
1424
1425 as_system::<(
1426 Commands,
1427 Query<
1428 (
1429 &mut InstanceHolder,
1430 &GameProfileComponent,
1431 &ClientInformation,
1432 ),
1433 With<LocalEntity>,
1434 >,
1435 EventWriter<_>,
1436 ResMut<InstanceContainer>,
1437 Query<&mut LoadedBy, Without<LocalEntity>>,
1438 )>(
1439 self.ecs,
1440 |(mut commands, mut query, mut events, mut instance_container, mut loaded_by_query)| {
1441 let (mut instance_holder, game_profile, client_information) =
1442 query.get_mut(self.player).unwrap();
1443
1444 let new_instance_name = p.common.dimension.clone();
1445
1446 let Some((_dimension_type, dimension_data)) = p
1447 .common
1448 .dimension_type(&instance_holder.instance.read().registries)
1449 else {
1450 return;
1451 };
1452
1453 let weak_instance = instance_container.insert(
1456 new_instance_name.clone(),
1457 dimension_data.height,
1458 dimension_data.min_y,
1459 &instance_holder.instance.read().registries,
1460 );
1461 events.send(InstanceLoadedEvent {
1462 entity: self.player,
1463 name: new_instance_name.clone(),
1464 instance: Arc::downgrade(&weak_instance),
1465 });
1466
1467 *instance_holder.partial_instance.write() = PartialInstance::new(
1472 azalea_world::chunk_storage::calculate_chunk_storage_range(
1473 client_information.view_distance.into(),
1474 ),
1475 Some(self.player),
1476 );
1477 instance_holder.instance = weak_instance;
1478
1479 for mut loaded_by in &mut loaded_by_query.iter_mut() {
1481 loaded_by.remove(&self.player);
1482 }
1483
1484 let entity_bundle = EntityBundle::new(
1486 game_profile.uuid,
1487 Vec3::ZERO,
1488 azalea_registry::EntityKind::Player,
1489 new_instance_name,
1490 );
1491 commands.entity(self.player).insert((
1493 LocalGameMode {
1494 current: p.common.game_type,
1495 previous: p.common.previous_game_type.into(),
1496 },
1497 entity_bundle,
1498 ));
1499
1500 commands.entity(self.player).remove::<Dead>();
1502 },
1503 )
1504 }
1505
1506 pub fn start_configuration(&mut self, _p: &ClientboundStartConfiguration) {
1507 debug!("Got start configuration packet");
1508
1509 as_system::<(Query<&RawConnection>, Commands)>(self.ecs, |(query, mut commands)| {
1510 let raw_conn = query.get(self.player).unwrap();
1511 let _ = raw_conn.write_packet(ServerboundConfigurationAcknowledged);
1512
1513 commands
1514 .entity(self.player)
1515 .insert(crate::client::InConfigState)
1516 .remove::<crate::JoinedClientBundle>()
1517 .remove::<EntityBundle>();
1518 });
1519 }
1520
1521 pub fn entity_position_sync(&mut self, p: &ClientboundEntityPositionSync) {
1522 as_system::<(Commands, Query<(&EntityIdIndex, &InstanceHolder)>)>(
1523 self.ecs,
1524 |(mut commands, mut query)| {
1525 let (entity_id_index, instance_holder) = query.get_mut(self.player).unwrap();
1526
1527 let Some(entity) = entity_id_index.get(p.id) else {
1528 debug!("Got teleport entity packet for unknown entity id {}", p.id);
1529 return;
1530 };
1531
1532 let new_position = p.values.pos;
1533 let new_on_ground = p.on_ground;
1534 let new_look_direction = p.values.look_direction;
1535
1536 commands.entity(entity).queue(RelativeEntityUpdate::new(
1537 instance_holder.partial_instance.clone(),
1538 move |entity_mut| {
1539 let is_local_entity = entity_mut.get::<LocalEntity>().is_some();
1540 let mut physics = entity_mut.get_mut::<Physics>().unwrap();
1541
1542 physics.vec_delta_codec.set_base(new_position);
1543
1544 if is_local_entity {
1545 debug!("Ignoring entity position sync packet for local player");
1546 return;
1547 }
1548
1549 physics.set_on_ground(new_on_ground);
1550
1551 let mut last_sent_position =
1552 entity_mut.get_mut::<LastSentPosition>().unwrap();
1553 **last_sent_position = new_position;
1554 let mut position = entity_mut.get_mut::<Position>().unwrap();
1555 **position = new_position;
1556
1557 let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap();
1558 *look_direction = new_look_direction;
1559 },
1560 ));
1561 },
1562 );
1563 }
1564
1565 pub fn select_advancements_tab(&mut self, _p: &ClientboundSelectAdvancementsTab) {}
1566 pub fn set_action_bar_text(&mut self, _p: &ClientboundSetActionBarText) {}
1567 pub fn set_border_center(&mut self, _p: &ClientboundSetBorderCenter) {}
1568 pub fn set_border_lerp_size(&mut self, _p: &ClientboundSetBorderLerpSize) {}
1569 pub fn set_border_size(&mut self, _p: &ClientboundSetBorderSize) {}
1570 pub fn set_border_warning_delay(&mut self, _p: &ClientboundSetBorderWarningDelay) {}
1571 pub fn set_border_warning_distance(&mut self, _p: &ClientboundSetBorderWarningDistance) {}
1572 pub fn set_camera(&mut self, _p: &ClientboundSetCamera) {}
1573 pub fn set_display_objective(&mut self, _p: &ClientboundSetDisplayObjective) {}
1574 pub fn set_objective(&mut self, _p: &ClientboundSetObjective) {}
1575 pub fn set_passengers(&mut self, _p: &ClientboundSetPassengers) {}
1576 pub fn set_player_team(&mut self, _p: &ClientboundSetPlayerTeam) {}
1577 pub fn set_score(&mut self, _p: &ClientboundSetScore) {}
1578 pub fn set_simulation_distance(&mut self, _p: &ClientboundSetSimulationDistance) {}
1579 pub fn set_subtitle_text(&mut self, _p: &ClientboundSetSubtitleText) {}
1580 pub fn set_title_text(&mut self, _p: &ClientboundSetTitleText) {}
1581 pub fn set_titles_animation(&mut self, _p: &ClientboundSetTitlesAnimation) {}
1582 pub fn clear_titles(&mut self, _p: &ClientboundClearTitles) {}
1583 pub fn sound_entity(&mut self, _p: &ClientboundSoundEntity) {}
1584 pub fn stop_sound(&mut self, _p: &ClientboundStopSound) {}
1585 pub fn tab_list(&mut self, _p: &ClientboundTabList) {}
1586 pub fn tag_query(&mut self, _p: &ClientboundTagQuery) {}
1587 pub fn take_item_entity(&mut self, _p: &ClientboundTakeItemEntity) {}
1588 pub fn bundle_delimiter(&mut self, _p: &ClientboundBundleDelimiter) {}
1589 pub fn damage_event(&mut self, _p: &ClientboundDamageEvent) {}
1590 pub fn hurt_animation(&mut self, _p: &ClientboundHurtAnimation) {}
1591 pub fn ticking_state(&mut self, _p: &ClientboundTickingState) {}
1592 pub fn ticking_step(&mut self, _p: &ClientboundTickingStep) {}
1593 pub fn reset_score(&mut self, _p: &ClientboundResetScore) {}
1594 pub fn cookie_request(&mut self, _p: &ClientboundCookieRequest) {}
1595 pub fn debug_sample(&mut self, _p: &ClientboundDebugSample) {}
1596 pub fn pong_response(&mut self, _p: &ClientboundPongResponse) {}
1597 pub fn store_cookie(&mut self, _p: &ClientboundStoreCookie) {}
1598 pub fn transfer(&mut self, _p: &ClientboundTransfer) {}
1599 pub fn move_minecart_along_track(&mut self, _p: &ClientboundMoveMinecartAlongTrack) {}
1600 pub fn set_held_slot(&mut self, _p: &ClientboundSetHeldSlot) {}
1601 pub fn set_player_inventory(&mut self, _p: &ClientboundSetPlayerInventory) {}
1602 pub fn projectile_power(&mut self, _p: &ClientboundProjectilePower) {}
1603 pub fn custom_report_details(&mut self, _p: &ClientboundCustomReportDetails) {}
1604 pub fn server_links(&mut self, _p: &ClientboundServerLinks) {}
1605 pub fn player_rotation(&mut self, _p: &ClientboundPlayerRotation) {}
1606 pub fn recipe_book_add(&mut self, _p: &ClientboundRecipeBookAdd) {}
1607 pub fn recipe_book_remove(&mut self, _p: &ClientboundRecipeBookRemove) {}
1608 pub fn recipe_book_settings(&mut self, _p: &ClientboundRecipeBookSettings) {}
1609 pub fn test_instance_block_status(&mut self, _p: &ClientboundTestInstanceBlockStatus) {}
1610}