1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00
azalea/azalea-client/src/plugins/packet/config/mod.rs

221 lines
6.9 KiB
Rust

mod events;
use std::io::Cursor;
use azalea_entity::LocalEntity;
use azalea_protocol::packets::ConnectionProtocol;
use azalea_protocol::packets::config::*;
use azalea_protocol::read::ReadPacketError;
use azalea_protocol::read::deserialize_packet;
use bevy_ecs::prelude::*;
pub use events::*;
use tracing::{debug, warn};
use super::as_system;
use crate::client::InConfigState;
use crate::connection::RawConnection;
use crate::disconnect::DisconnectEvent;
use crate::packet::game::KeepAliveEvent;
use crate::packet::game::ResourcePackEvent;
use crate::{InstanceHolder, declare_packet_handlers};
pub fn process_raw_packet(
ecs: &mut World,
player: Entity,
raw_packet: &[u8],
) -> Result<(), Box<ReadPacketError>> {
let packet = deserialize_packet(&mut Cursor::new(&raw_packet))?;
process_packet(ecs, player, &packet);
Ok(())
}
pub fn process_packet(ecs: &mut World, player: Entity, packet: &ClientboundConfigPacket) {
let mut handler = ConfigPacketHandler { player, ecs };
declare_packet_handlers!(
ClientboundConfigPacket,
packet,
handler,
[
cookie_request,
custom_payload,
disconnect,
finish_configuration,
keep_alive,
ping,
reset_chat,
registry_data,
resource_pack_pop,
resource_pack_push,
store_cookie,
transfer,
update_enabled_features,
update_tags,
select_known_packs,
custom_report_details,
server_links,
]
);
}
pub struct ConfigPacketHandler<'a> {
pub ecs: &'a mut World,
pub player: Entity,
}
impl ConfigPacketHandler<'_> {
pub fn registry_data(&mut self, p: &ClientboundRegistryData) {
as_system::<Query<&mut InstanceHolder>>(self.ecs, |mut query| {
let instance_holder = query.get_mut(self.player).unwrap();
let mut instance = instance_holder.instance.write();
// add the new registry data
instance
.registries
.append(p.registry_id.clone(), p.entries.clone());
});
}
pub fn custom_payload(&mut self, p: &ClientboundCustomPayload) {
debug!("Got custom payload packet {p:?}");
}
pub fn disconnect(&mut self, p: &ClientboundDisconnect) {
warn!("Got disconnect packet {p:?}");
as_system::<EventWriter<_>>(self.ecs, |mut events| {
events.send(DisconnectEvent {
entity: self.player,
reason: Some(p.reason.clone()),
});
});
}
pub fn finish_configuration(&mut self, p: &ClientboundFinishConfiguration) {
debug!("got FinishConfiguration packet: {p:?}");
as_system::<(Commands, Query<&mut RawConnection>)>(
self.ecs,
|(mut commands, mut query)| {
let mut raw_conn = query.get_mut(self.player).unwrap();
commands.trigger(SendConfigPacketEvent::new(
self.player,
ServerboundFinishConfiguration,
));
raw_conn.state = ConnectionProtocol::Game;
// these components are added now that we're going to be in the Game state
commands
.entity(self.player)
.remove::<InConfigState>()
.insert((
crate::JoinedClientBundle::default(),
// localentity should already be added, but in case the user forgot or
// something we also add it here
LocalEntity,
));
},
);
}
pub fn keep_alive(&mut self, p: &ClientboundKeepAlive) {
debug!(
"Got keep alive packet (in configuration) {p:?} for {:?}",
self.player
);
as_system::<(Commands, EventWriter<_>)>(self.ecs, |(mut commands, mut events)| {
events.send(KeepAliveEvent {
entity: self.player,
id: p.id,
});
commands.trigger(SendConfigPacketEvent::new(
self.player,
ServerboundKeepAlive { id: p.id },
));
});
}
pub fn ping(&mut self, p: &ClientboundPing) {
debug!("Got ping packet (in configuration) {p:?}");
as_system::<Commands>(self.ecs, |mut commands| {
commands.trigger_targets(ConfigPingEvent(p.clone()), self.player);
});
}
pub fn resource_pack_push(&mut self, p: &ClientboundResourcePackPush) {
debug!("Got resource pack push packet {p:?}");
as_system::<EventWriter<_>>(self.ecs, |mut events| {
events.send(ResourcePackEvent {
entity: self.player,
id: p.id,
url: p.url.to_owned(),
hash: p.hash.to_owned(),
required: p.required,
prompt: p.prompt.to_owned(),
});
});
}
pub fn resource_pack_pop(&mut self, p: &ClientboundResourcePackPop) {
debug!("Got resource pack pop packet {p:?}");
}
pub fn update_enabled_features(&mut self, p: &ClientboundUpdateEnabledFeatures) {
debug!("Got update enabled features packet {p:?}");
}
pub fn update_tags(&mut self, _p: &ClientboundUpdateTags) {
debug!("Got update tags packet");
}
pub fn cookie_request(&mut self, p: &ClientboundCookieRequest) {
debug!("Got cookie request packet {p:?}");
as_system::<Commands>(self.ecs, |mut commands| {
commands.trigger(SendConfigPacketEvent::new(
self.player,
ServerboundCookieResponse {
key: p.key.clone(),
// cookies aren't implemented
payload: None,
},
));
});
}
pub fn reset_chat(&mut self, p: &ClientboundResetChat) {
debug!("Got reset chat packet {p:?}");
}
pub fn store_cookie(&mut self, p: &ClientboundStoreCookie) {
debug!("Got store cookie packet {p:?}");
}
pub fn transfer(&mut self, p: &ClientboundTransfer) {
debug!("Got transfer packet {p:?}");
}
pub fn select_known_packs(&mut self, p: &ClientboundSelectKnownPacks) {
debug!("Got select known packs packet {p:?}");
as_system::<Commands>(self.ecs, |mut commands| {
// resource pack management isn't implemented
commands.trigger(SendConfigPacketEvent::new(
self.player,
ServerboundSelectKnownPacks {
known_packs: vec![],
},
));
});
}
pub fn server_links(&mut self, p: &ClientboundServerLinks) {
debug!("Got server links packet {p:?}");
}
pub fn custom_report_details(&mut self, p: &ClientboundCustomReportDetails) {
debug!("Got custom report details packet {p:?}");
}
}