azalea_client/plugins/packet/config/
events.rs

1use std::sync::Arc;
2
3use azalea_protocol::packets::{
4    Packet,
5    config::{ClientboundConfigPacket, ServerboundConfigPacket},
6};
7use bevy_ecs::prelude::*;
8use tracing::{debug, error};
9
10use crate::{InConfigState, connection::RawConnection};
11
12#[derive(Event, Debug, Clone)]
13pub struct ReceiveConfigPacketEvent {
14    /// The client entity that received the packet.
15    pub entity: Entity,
16    /// The packet that was actually received.
17    pub packet: Arc<ClientboundConfigPacket>,
18}
19
20/// An event for sending a packet to the server while we're in the
21/// `configuration` state.
22#[derive(Event, Clone)]
23pub struct SendConfigPacketEvent {
24    pub sent_by: Entity,
25    pub packet: ServerboundConfigPacket,
26}
27impl SendConfigPacketEvent {
28    pub fn new(sent_by: Entity, packet: impl Packet<ServerboundConfigPacket>) -> Self {
29        let packet = packet.into_variant();
30        Self { sent_by, packet }
31    }
32}
33
34pub fn handle_outgoing_packets_observer(
35    trigger: Trigger<SendConfigPacketEvent>,
36    mut query: Query<(&mut RawConnection, Option<&InConfigState>)>,
37) {
38    let event = trigger.event();
39    if let Ok((mut raw_conn, in_configuration_state)) = query.get_mut(event.sent_by) {
40        if in_configuration_state.is_none() {
41            error!(
42                "Tried to send a configuration packet {:?} while not in configuration state",
43                event.packet
44            );
45            return;
46        }
47        debug!("Sending config packet: {:?}", event.packet);
48        if let Err(e) = raw_conn.write(event.packet.clone()) {
49            error!("Failed to send packet: {e}");
50        }
51    }
52}
53/// A system that converts [`SendConfigPacketEvent`] events into triggers so
54/// they get received by [`handle_outgoing_packets_observer`].
55pub fn handle_outgoing_packets(
56    mut commands: Commands,
57    mut events: EventReader<SendConfigPacketEvent>,
58) {
59    for event in events.read() {
60        commands.trigger(event.clone());
61    }
62}
63
64/// A Bevy trigger that's sent when our client receives a [`ClientboundPing`]
65/// packet in the config state.
66///
67/// See [`PingEvent`] for more information.
68///
69/// [`ClientboundPing`]: azalea_protocol::packets::config::ClientboundPing
70/// [`PingEvent`]: crate::packet::game::PingEvent
71#[derive(Event, Debug, Clone)]
72pub struct ConfigPingEvent(pub azalea_protocol::packets::config::ClientboundPing);