mirror of
https://github.com/mat-1/azalea.git
synced 2024-09-19 22:52:32 +00:00
properly disconnect on ungraceful disconnect
This commit is contained in:
parent
66094921c8
commit
48640ca303
4 changed files with 38 additions and 25 deletions
|
@ -207,14 +207,6 @@ impl Client {
|
|||
|
||||
let (packet_writer_sender, packet_writer_receiver) = mpsc::unbounded_channel();
|
||||
|
||||
let mut local_player = crate::local_player::LocalPlayer::new(
|
||||
entity,
|
||||
packet_writer_sender,
|
||||
// default to an empty world, it'll be set correctly later when we
|
||||
// get the login packet
|
||||
Arc::new(RwLock::new(World::default())),
|
||||
);
|
||||
|
||||
// start receiving packets
|
||||
let packet_receiver = packet_handling::PacketReceiver {
|
||||
packets: Arc::new(Mutex::new(Vec::new())),
|
||||
|
@ -227,8 +219,16 @@ impl Client {
|
|||
.clone()
|
||||
.write_task(write_conn, packet_writer_receiver),
|
||||
);
|
||||
local_player.tasks.push(read_packets_task);
|
||||
local_player.tasks.push(write_packets_task);
|
||||
|
||||
let local_player = crate::local_player::LocalPlayer::new(
|
||||
entity,
|
||||
packet_writer_sender,
|
||||
// default to an empty world, it'll be set correctly later when we
|
||||
// get the login packet
|
||||
Arc::new(RwLock::new(World::default())),
|
||||
read_packets_task,
|
||||
write_packets_task,
|
||||
);
|
||||
|
||||
ecs.entity_mut(entity).insert(JoinedClientBundle {
|
||||
local_player,
|
||||
|
|
|
@ -3,17 +3,19 @@
|
|||
use azalea_ecs::{
|
||||
app::{App, CoreStage, Plugin},
|
||||
entity::Entity,
|
||||
event::EventReader,
|
||||
system::Commands,
|
||||
event::{EventReader, EventWriter},
|
||||
system::{Commands, Query},
|
||||
AppTickExt,
|
||||
};
|
||||
|
||||
use crate::client::JoinedClientBundle;
|
||||
use crate::{client::JoinedClientBundle, LocalPlayer};
|
||||
|
||||
pub struct DisconnectPlugin;
|
||||
impl Plugin for DisconnectPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_event::<DisconnectEvent>()
|
||||
.add_system_to_stage(CoreStage::PostUpdate, handle_disconnect);
|
||||
.add_system_to_stage(CoreStage::PostUpdate, handle_disconnect)
|
||||
.add_tick_system(disconnect_on_read_packets_ended);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,3 +31,14 @@ pub fn handle_disconnect(mut commands: Commands, mut events: EventReader<Disconn
|
|||
commands.entity(*entity).remove::<JoinedClientBundle>();
|
||||
}
|
||||
}
|
||||
|
||||
fn disconnect_on_read_packets_ended(
|
||||
local_player: Query<(Entity, &LocalPlayer)>,
|
||||
mut disconnect_events: EventWriter<DisconnectEvent>,
|
||||
) {
|
||||
for (entity, local_player) in &local_player {
|
||||
if local_player.read_packets_task.is_finished() {
|
||||
disconnect_events.send(DisconnectEvent { entity });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,11 @@ pub struct LocalPlayer {
|
|||
/// world. (Only relevant if you're using a shared world, i.e. a swarm)
|
||||
pub world: Arc<RwLock<World>>,
|
||||
|
||||
/// A list of async tasks that are running and will stop running when this
|
||||
/// LocalPlayer is dropped or disconnected with [`Self::disconnect`]
|
||||
pub(crate) tasks: Vec<JoinHandle<()>>,
|
||||
/// A task that reads packets from the server. The client is disconnected
|
||||
/// when this task ends.
|
||||
pub(crate) read_packets_task: JoinHandle<()>,
|
||||
/// A task that writes packets from the server.
|
||||
pub(crate) write_packets_task: JoinHandle<()>,
|
||||
}
|
||||
|
||||
/// Component for entities that can move and sprint. Usually only in
|
||||
|
@ -87,6 +89,8 @@ impl LocalPlayer {
|
|||
entity: Entity,
|
||||
packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
|
||||
world: Arc<RwLock<World>>,
|
||||
read_packets_task: JoinHandle<()>,
|
||||
write_packets_task: JoinHandle<()>,
|
||||
) -> Self {
|
||||
let client_information = ClientInformation::default();
|
||||
|
||||
|
@ -102,7 +106,8 @@ impl LocalPlayer {
|
|||
Some(entity),
|
||||
))),
|
||||
|
||||
tasks: Vec::new(),
|
||||
read_packets_task,
|
||||
write_packets_task,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,9 +122,8 @@ impl LocalPlayer {
|
|||
impl Drop for LocalPlayer {
|
||||
/// Stop every active task when the `LocalPlayer` is dropped.
|
||||
fn drop(&mut self) {
|
||||
for task in &self.tasks {
|
||||
task.abort();
|
||||
}
|
||||
self.read_packets_task.abort();
|
||||
self.write_packets_task.abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -961,10 +961,6 @@ impl PacketReceiver {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: it should send a DisconnectEvent here somehow
|
||||
// maybe use a tokio::sync::oneshot that tells it to close and have the
|
||||
// receiver in localplayer and have a system that watches that or
|
||||
// something?
|
||||
}
|
||||
|
||||
/// Consume the [`ServerboundGamePacket`] queue and actually write the
|
||||
|
|
Loading…
Reference in a new issue