1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

use packet handlers code for login custom_query

This commit is contained in:
mat 2025-04-05 08:06:26 +09:00
parent 7dcc86e266
commit 2ef9860b82
3 changed files with 86 additions and 38 deletions

View file

@ -0,0 +1,24 @@
use std::sync::Arc;
use azalea_protocol::packets::login::ClientboundLoginPacket;
use bevy_ecs::prelude::*;
/// An event that's sent when we receive a login packet from the server. Note
/// that if you want to handle this in a system, you must add
/// `.before(azalea::packet::login::process_packet_events)` to it
/// because that system clears the events.
#[derive(Event, Debug, Clone)]
pub struct LoginPacketEvent {
/// The client entity that received the packet.
pub entity: Entity,
/// The packet that was actually received.
pub packet: Arc<ClientboundLoginPacket>,
}
#[derive(Event, Debug, Clone)]
pub struct ReceiveLoginPacketEvent {
/// The client entity that received the packet.
pub entity: Entity,
/// The packet that was actually received.
pub packet: ClientboundLoginPacket,
}

View file

@ -1,34 +1,26 @@
// login packets aren't actually handled here because compression/encryption
// would make packet handling a lot messier
use std::{collections::HashSet, sync::Arc};
mod events;
use std::collections::HashSet;
use azalea_protocol::packets::{
Packet,
login::{
ClientboundLoginPacket, ServerboundLoginPacket,
s_custom_query_answer::ServerboundCustomQueryAnswer,
ClientboundCookieRequest, ClientboundCustomQuery, ClientboundHello,
ClientboundLoginCompression, ClientboundLoginDisconnect, ClientboundLoginFinished,
ClientboundLoginPacket, ServerboundCustomQueryAnswer, ServerboundLoginPacket,
},
};
use bevy_ecs::{prelude::*, system::SystemState};
use derive_more::{Deref, DerefMut};
pub use events::*;
use tokio::sync::mpsc;
use tracing::error;
// this struct is defined here anyways though so it's consistent with the other
// ones
/// An event that's sent when we receive a login packet from the server. Note
/// that if you want to handle this in a system, you must add
/// `.before(azalea::packet::login::process_packet_events)` to it
/// because that system clears the events.
#[derive(Event, Debug, Clone)]
pub struct LoginPacketEvent {
/// The client entity that received the packet.
pub entity: Entity,
/// The packet that was actually received.
pub packet: Arc<ClientboundLoginPacket>,
}
use super::as_system;
use crate::declare_packet_handlers;
/// Event for sending a login packet to the server.
#[derive(Event)]
@ -73,42 +65,73 @@ pub struct IgnoreQueryIds(HashSet<u32>);
pub fn process_packet_events(ecs: &mut World) {
let mut events_owned = Vec::new();
let mut system_state: SystemState<ResMut<Events<LoginPacketEvent>>> = SystemState::new(ecs);
let mut system_state: SystemState<EventReader<ReceiveLoginPacketEvent>> = SystemState::new(ecs);
let mut events = system_state.get_mut(ecs);
for LoginPacketEvent {
for ReceiveLoginPacketEvent {
entity: player_entity,
packet,
} in events.drain()
} in events.read()
{
// we do this so `ecs` isn't borrowed for the whole loop
events_owned.push((player_entity, packet));
events_owned.push((*player_entity, packet.clone()));
}
for (player_entity, packet) in events_owned {
#[allow(clippy::single_match)]
match packet.as_ref() {
ClientboundLoginPacket::CustomQuery(p) => {
let mut system_state: SystemState<(
EventWriter<SendLoginPacketEvent>,
Query<&IgnoreQueryIds>,
)> = SystemState::new(ecs);
let (mut send_packet_events, query) = system_state.get_mut(ecs);
let mut handler = LoginPacketHandler {
player: player_entity,
ecs,
};
let ignore_query_ids = query.get(player_entity).ok().map(|x| x.0.clone());
declare_packet_handlers!(
ClientboundLoginPacket,
packet,
handler,
[
hello,
login_disconnect,
login_finished,
login_compression,
custom_query,
cookie_request
]
);
}
}
pub struct LoginPacketHandler<'a> {
pub ecs: &'a mut World,
pub player: Entity,
}
impl LoginPacketHandler<'_> {
pub fn hello(&mut self, _p: ClientboundHello) {}
pub fn login_disconnect(&mut self, _p: ClientboundLoginDisconnect) {}
pub fn login_finished(&mut self, _p: ClientboundLoginFinished) {}
pub fn login_compression(&mut self, _p: ClientboundLoginCompression) {
// as_system::<Query<&mut RawConnection>>(self.ecs, |mut query| {
// if let Ok(mut raw_conn) = query.get_mut(self.player) {
// raw_conn.set_compression_threshold(p.compression_threshold);
// }
// });
}
pub fn custom_query(&mut self, p: ClientboundCustomQuery) {
as_system::<(EventWriter<SendLoginPacketEvent>, Query<&IgnoreQueryIds>)>(
self.ecs,
|(mut events, query)| {
let ignore_query_ids = query.get(self.player).ok().map(|x| x.0.clone());
if let Some(ignore_query_ids) = ignore_query_ids {
if ignore_query_ids.contains(&p.transaction_id) {
continue;
return;
}
}
send_packet_events.send(SendLoginPacketEvent::new(
player_entity,
events.send(SendLoginPacketEvent::new(
self.player,
ServerboundCustomQueryAnswer {
transaction_id: p.transaction_id,
data: None,
},
));
}
_ => {}
}
},
);
}
pub fn cookie_request(&mut self, _p: ClientboundCookieRequest) {}
}

View file

@ -344,8 +344,9 @@ impl Connection<ClientboundHandshakePacket, ServerboundHandshakePacket> {
impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
/// Set our compression threshold, i.e. the maximum size that a packet is
/// allowed to be without getting compressed. If you set it to less than 0
/// then compression gets disabled.
/// allowed to be without getting compressed. Setting it to 0 means every
/// packet will be compressed. If you set it to less than 0,
/// then compression is disabled.
pub fn set_compression_threshold(&mut self, threshold: i32) {
// if you pass a threshold of less than 0, compression is disabled
if threshold >= 0 {