1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-05-19 17:27:45 +00:00

Begin adding disconnection handling

This doesn't work 100% reliably yet, but the world server should now try
to commit your player back to the database if it detects you disconnect.

I also fixed a mistake where the global server state never removed
clients when they errored out. There's now code to remove your actor
from the instance when disconnecting, but this doesn't work reliably yet
either.
This commit is contained in:
Joshua Goins 2025-05-12 01:17:15 -04:00
parent f37aa53011
commit a88b9037d4
4 changed files with 702 additions and 643 deletions

File diff suppressed because it is too large Load diff

View file

@ -207,7 +207,9 @@ pub async fn send_packet<T: ReadWriteIpcSegment>(
let buffer = cursor.into_inner();
socket.write_all(&buffer).await.unwrap();
if let Err(e) = socket.write_all(&buffer).await {
tracing::warn!("Failed to send packet: {e}");
}
}
// temporary

View file

@ -1,6 +1,7 @@
use std::{
net::SocketAddr,
sync::{Arc, Mutex},
time::Instant,
};
use tokio::net::TcpStream;
@ -87,6 +88,11 @@ pub struct ZoneConnection {
pub exit_position: Option<Position>,
pub exit_rotation: Option<f32>,
pub last_keep_alive: Instant,
/// Whether the player was gracefully logged out
pub gracefully_logged_out: bool,
}
impl ZoneConnection {
@ -612,6 +618,8 @@ impl ZoneConnection {
}
pub async fn begin_log_out(&mut self) {
self.gracefully_logged_out = true;
// write the player back to the database
self.database.commit_player_data(&self.player_data);

View file

@ -313,10 +313,25 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> Result<(), std::i
}
ToServer::FatalError(err) => return Err(err),
}
}
// Remove any clients that errored out
for id in to_remove {
data.clients.remove(&id);
// Remove any clients that errored out
for remove_id in &to_remove {
// remove any actors they had
let mut actor_id = None;
for (id, (handle, _)) in &mut data.clients {
if *id == *remove_id {
actor_id = Some(handle.actor_id);
}
}
if let Some(actor_id) = actor_id {
// remove them from the instance
let current_instance = data.find_actor_instance_mut(actor_id).unwrap();
current_instance.actors.remove(&ObjectId(actor_id));
}
data.clients.remove(&remove_id);
}
}
Ok(())
}