aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src/client.rs
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-12-03 02:41:09 -0600
committermat <git@matdoes.dev>2023-12-03 02:41:09 -0600
commit1f46ef8c115db0c53e21dfb6a3e633825c6747c3 (patch)
tree74e5fa5e76ac95bb68e6d07b999187e5a4e617c0 /azalea-client/src/client.rs
parent0713223e1204438f839566ce8cf954f0c9ff7f91 (diff)
downloadazalea-drasl-1f46ef8c115db0c53e21dfb6a3e633825c6747c3.tar.xz
make it so plugins can send and receive packets during the login state
Diffstat (limited to 'azalea-client/src/client.rs')
-rw-r--r--azalea-client/src/client.rs82
1 files changed, 58 insertions, 24 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 21d3a80a..16d9442b 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -7,12 +7,16 @@ use crate::{
interact::{CurrentSequenceNumber, InteractPlugin},
inventory::{InventoryComponent, InventoryPlugin},
local_player::{
- death_event, handle_send_packet_event, GameProfileComponent, Hunger, InstanceHolder,
- PermissionLevel, PlayerAbilities, SendPacketEvent, TabList,
+ death_event, GameProfileComponent, Hunger, InstanceHolder, PermissionLevel,
+ PlayerAbilities, TabList,
},
mining::{self, MinePlugin},
movement::{LastSentLookDirection, PhysicsState, PlayerMovePlugin},
- packet_handling::PacketHandlerPlugin,
+ packet_handling::{
+ game::{handle_send_packet_event, SendPacketEvent},
+ login::{self, LoginSendPacketQueue},
+ PacketHandlerPlugin,
+ },
player::retroactively_add_game_profile_component,
raw_connection::RawConnection,
respawn::RespawnPlugin,
@@ -35,6 +39,7 @@ use azalea_protocol::{
packets::{
configuration::{
serverbound_client_information_packet::ClientInformation,
+ serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
ClientboundConfigurationPacket, ServerboundConfigurationPacket,
},
game::ServerboundGamePacket,
@@ -208,8 +213,29 @@ impl Client {
resolved_address: &SocketAddr,
run_schedule_sender: mpsc::UnboundedSender<()>,
) -> Result<(Self, mpsc::UnboundedReceiver<Event>), JoinError> {
+ // check if an entity with our uuid already exists in the ecs and if so then
+ // just use that
+ let entity = {
+ let mut ecs = ecs_lock.lock();
+
+ let entity_uuid_index = ecs.resource::<EntityUuidIndex>();
+ let uuid = account.uuid_or_offline();
+ if let Some(entity) = entity_uuid_index.get(&account.uuid_or_offline()) {
+ debug!("Reusing entity {entity:?} for client");
+ entity
+ } else {
+ let entity = ecs.spawn_empty().id();
+ debug!("Created new entity {entity:?} for client");
+ // add to the uuid index
+ let mut entity_uuid_index = ecs.resource_mut::<EntityUuidIndex>();
+ entity_uuid_index.insert(uuid, entity);
+ entity
+ }
+ };
+
let conn = Connection::new(resolved_address).await?;
- let (mut conn, game_profile) = Self::handshake(conn, account, address).await?;
+ let (mut conn, game_profile) =
+ Self::handshake(ecs_lock.clone(), entity, conn, account, address).await?;
{
// quickly send the brand here
@@ -217,12 +243,13 @@ impl Client {
// they don't have to know :)
"vanilla".write_into(&mut brand_data).unwrap();
conn.write(
- azalea_protocol::packets::configuration::serverbound_custom_payload_packet::ServerboundCustomPayloadPacket {
+ ServerboundCustomPayloadPacket {
identifier: ResourceLocation::new("brand"),
data: brand_data.into(),
}
.get(),
- ).await?;
+ )
+ .await?;
}
let (read_conn, write_conn) = conn.into_split();
@@ -234,22 +261,6 @@ impl Client {
let mut ecs = ecs_lock.lock();
- // check if an entity with our uuid already exists in the ecs and if so then
- // just use that
- let entity = {
- let entity_uuid_index = ecs.resource::<EntityUuidIndex>();
- if let Some(entity) = entity_uuid_index.get(&game_profile.uuid) {
- debug!("Reusing entity {entity:?} for client");
- entity
- } else {
- let entity = ecs.spawn_empty().id();
- debug!("Created new entity {entity:?} for client");
- // add to the uuid index
- let mut entity_uuid_index = ecs.resource_mut::<EntityUuidIndex>();
- entity_uuid_index.insert(game_profile.uuid, entity);
- entity
- }
- };
// we got the ConfigurationConnection, so the client is now connected :)
let client = Client::new(
game_profile.clone(),
@@ -284,6 +295,8 @@ impl Client {
/// This will also automatically refresh the account's access token if
/// it's expired.
pub async fn handshake(
+ ecs_lock: Arc<Mutex<World>>,
+ entity: Entity,
mut conn: Connection<ClientboundHandshakePacket, ServerboundHandshakePacket>,
account: &Account,
address: &ServerAddress,
@@ -307,6 +320,14 @@ impl Client {
.await?;
let mut conn = conn.login();
+ // this makes it so plugins can send an `SendLoginPacketEvent` event to the ecs
+ // and we'll send it to the server
+ let (ecs_packets_tx, mut ecs_packets_rx) = mpsc::unbounded_channel();
+ ecs_lock
+ .lock()
+ .entity_mut(entity)
+ .insert(LoginSendPacketQueue { tx: ecs_packets_tx });
+
// login
conn.write(
ServerboundHelloPacket {
@@ -320,7 +341,20 @@ impl Client {
.await?;
let (conn, profile) = loop {
- let packet = conn.read().await?;
+ let packet = tokio::select! {
+ packet = conn.read() => packet?,
+ Some(packet) = ecs_packets_rx.recv() => {
+ // write this packet to the server
+ conn.write(packet).await?;
+ continue;
+ }
+ };
+
+ ecs_lock.lock().send_event(login::LoginPacketEvent {
+ entity,
+ packet: Arc::new(packet.clone()),
+ });
+
match packet {
ClientboundLoginPacket::Hello(p) => {
debug!("Got encryption request");
@@ -655,7 +689,7 @@ impl Plugin for AzaleaPlugin {
/// [`DefaultPlugins`].
#[doc(hidden)]
pub fn start_ecs_runner(
- mut app: App,
+ app: App,
run_schedule_receiver: mpsc::UnboundedReceiver<()>,
run_schedule_sender: mpsc::UnboundedSender<()>,
) -> Arc<Mutex<World>> {