use std::sync::Arc; use azalea_protocol::packets::{ Packet, login::{ ClientboundCustomQuery, ClientboundHello, ClientboundLoginPacket, ServerboundLoginPacket, }, }; use bevy_ecs::prelude::*; use tracing::{debug, error}; use super::InLoginState; use crate::{account::Account, connection::RawConnection}; #[derive(Clone, Debug, Message)] pub struct ReceiveLoginPacketEvent { /// The client entity that received the packet. pub entity: Entity, /// The packet that was actually received. pub packet: Arc, } #[derive(Clone, Debug, EntityEvent)] pub struct ReceiveHelloEvent { pub entity: Entity, pub account: Account, pub packet: ClientboundHello, } #[derive(Clone, Debug, Message)] pub struct ReceiveCustomQueryEvent { /// The client entity that received the packet. pub entity: Entity, pub packet: ClientboundCustomQuery, /// A system can set this to `true` to make Azalea not reply to the query. /// You must make sure you modify this before the /// [`reply_to_custom_queries`] system runs. /// /// [`reply_to_custom_queries`]: crate::login::reply_to_custom_queries pub disabled: bool, } /// Event for sending a login packet to the server. #[derive(Clone, Debug, EntityEvent)] pub struct SendLoginPacketEvent { #[event_target] pub sent_by: Entity, pub packet: ServerboundLoginPacket, } impl SendLoginPacketEvent { pub fn new(entity: Entity, packet: impl Packet) -> Self { let packet = packet.into_variant(); Self { sent_by: entity, packet, } } } pub fn handle_outgoing_packets_observer( trigger: On, mut query: Query<(&mut RawConnection, Option<&InLoginState>)>, ) { let event = trigger.event(); if let Ok((mut raw_conn, in_login_state)) = query.get_mut(event.sent_by) { if in_login_state.is_none() { error!( "Tried to send a login packet {:?} while not in login state", event.packet ); return; } debug!("Sending login packet: {:?}", event.packet); if let Err(e) = raw_conn.write(event.packet.clone()) { error!("Failed to send packet: {e}"); } } }