mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Add network-layer multiplayer disconnect handling
This commit is contained in:
@@ -21,10 +21,10 @@ atomic_float = "1.1"
|
||||
num-quaternion.workspace = true
|
||||
rand.workspace = true
|
||||
|
||||
#literustlib_server = { version = "0.3", path = "../../LiteRustLib/server" }
|
||||
#literustlib = { version = "0.3", path = "../../LiteRustLib" }
|
||||
literustlib_server = { version = "0.3" }
|
||||
literustlib = { version = "0.3" }
|
||||
literustlib_server = { version = "0.4", path = "../../LiteRustLib/server" }
|
||||
literustlib = { version = "0.4", path = "../../LiteRustLib" }
|
||||
#literustlib_server = { version = "0.4" }
|
||||
#literustlib = { version = "0.4" }
|
||||
rlnl = { version = "0.1", path = "../../rlnl" }
|
||||
|
||||
oj_serdes.workspace = true
|
||||
|
||||
29
rc_multiplayer/src/disconnect.rs
Normal file
29
rc_multiplayer/src/disconnect.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
pub struct ClientDisconnecter {
|
||||
msg_router: tokio::sync::mpsc::Sender<crate::matches::GameMessage>,
|
||||
}
|
||||
|
||||
pub(super) fn handler(init_ctx: &crate::InitConfig) -> ClientDisconnecter {
|
||||
ClientDisconnecter::new(init_ctx)
|
||||
}
|
||||
|
||||
impl ClientDisconnecter {
|
||||
fn new(init_ctx: &crate::InitConfig) -> Self {
|
||||
Self {
|
||||
msg_router: init_ctx.matches_chann.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl crate::DisconnectHandler for ClientDisconnecter {
|
||||
async fn handle(&self, _peer: &std::sync::Arc<literustlib_server::Connection<crate::PacketData>>, user: &crate::UserData) {
|
||||
if let Some(user_info) = user.user().await {
|
||||
crate::events::log_channel_send_failure(self.msg_router.send(crate::matches::GameMessage::EndConnection {
|
||||
user_id: user_info.user_id(),
|
||||
is_unregister: false,
|
||||
}).await);
|
||||
} else {
|
||||
log::error!("Failed to handle disconnect for unknown user");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ impl crate::handlers::DatalessEventCodeHandler for ClientUnregisterer {
|
||||
if let Some(user_info) = user.user().await {
|
||||
super::log_channel_send_failure(self.msg_router.send(crate::matches::GameMessage::EndConnection {
|
||||
user_id: user_info.user_id(),
|
||||
is_unregister: true,
|
||||
}).await);
|
||||
} else {
|
||||
log::error!("Failed to handle sync loading request for unknown user");
|
||||
|
||||
@@ -19,7 +19,11 @@ mod player_leave;
|
||||
mod heal_assist_bonus;
|
||||
|
||||
pub async fn handler(init_ctx: &crate::InitConfig) -> crate::handler::LnlEventHandler {
|
||||
crate::handler::LnlEventHandler::new(init_ctx.users.clone(), crate::vehicle_motion::handler(init_ctx))
|
||||
crate::handler::LnlEventHandler::new(
|
||||
init_ctx.users.clone(),
|
||||
crate::vehicle_motion::handler(init_ctx),
|
||||
crate::disconnect::handler(init_ctx),
|
||||
)
|
||||
.add(validate_game_guid::handler(init_ctx))
|
||||
.add(loading_progress::handler(init_ctx))
|
||||
.add(all_loading_progress::handler(init_ctx))
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
pub struct LnlEventHandler {
|
||||
event_handlers: std::collections::HashMap<i16, Box<dyn super::EventCodeHandler>>,
|
||||
motion_handler: Box<dyn super::RobotMotionHandler>,
|
||||
disconnect_handler: Box<dyn super::DisconnectHandler>,
|
||||
user_provider: std::sync::Arc<oj_rc_core::persist::user::UserImpl>
|
||||
}
|
||||
|
||||
impl LnlEventHandler {
|
||||
pub fn new<M: super::RobotMotionHandler + 'static>(user_provider: std::sync::Arc<oj_rc_core::persist::user::UserImpl>, motion_handler: M) -> Self {
|
||||
pub fn new<M: super::RobotMotionHandler + 'static, D: super::DisconnectHandler + 'static>(user_provider: std::sync::Arc<oj_rc_core::persist::user::UserImpl>, motion_handler: M, disconnect_handler: D) -> Self {
|
||||
Self {
|
||||
event_handlers: std::collections::HashMap::new(),
|
||||
motion_handler: Box::new(motion_handler),
|
||||
disconnect_handler: Box::new(disconnect_handler),
|
||||
user_provider,
|
||||
}
|
||||
}
|
||||
@@ -75,12 +77,12 @@ impl literustlib_server::EventHandler for LnlEventHandler {
|
||||
}
|
||||
|
||||
async fn on_disconnect(&self, peer: &std::sync::Arc<literustlib_server::Connection<Self::PacketData>>, user: &Self::UserData) {
|
||||
self.disconnect_handler.handle(peer, user).await;
|
||||
if let Some(user_info) = user.user().await {
|
||||
log::info!("Disconnect from user {} ({})", user_info.user_id(), peer.id());
|
||||
} else {
|
||||
log::debug!("Disconnect from connection {}", peer.id());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
mod cli;
|
||||
mod handler;
|
||||
mod traits;
|
||||
pub use traits::{EventCodeHandler, UserData, PacketData, EventCode, RobotMotionHandler, Broadcastable};
|
||||
pub use traits::{EventCodeHandler, UserData, PacketData, EventCode, RobotMotionHandler, DisconnectHandler, Broadcastable};
|
||||
mod data;
|
||||
mod events;
|
||||
mod handlers;
|
||||
mod user;
|
||||
mod matches;
|
||||
mod vehicle_motion;
|
||||
mod disconnect;
|
||||
|
||||
pub struct InitConfig {
|
||||
pub config: oj_rc_core::persist::config::ConfigImpl,
|
||||
|
||||
@@ -427,8 +427,8 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
||||
super::GameMessage::NewConnection { user, game_guid, connection, response, sender } => {
|
||||
self.on_new_connection(user, game_guid, connection, response, sender).await;
|
||||
},
|
||||
super::GameMessage::EndConnection { user_id } => {
|
||||
is_engaged = self.on_end_connection(user_id).await;
|
||||
super::GameMessage::EndConnection { user_id, is_unregister } => {
|
||||
is_engaged = self.on_end_connection(user_id, is_unregister).await;
|
||||
},
|
||||
super::GameMessage::RequestLeave { user_id } => {
|
||||
self.on_request_leave(user_id).await;
|
||||
@@ -569,7 +569,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn on_end_connection(&self, user_id: i32) -> bool {
|
||||
async fn on_end_connection(&self, user_id: i32, _is_unregister: bool) -> bool {
|
||||
if let Some(player_id) = self.user_key_by_user_id(user_id) {
|
||||
let conn_opt = self.users.write().await.remove(&player_id);
|
||||
if let Some(conn) = conn_opt {
|
||||
@@ -642,7 +642,14 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
for user in self.descriptors.values() {
|
||||
if user.descriptor.user_id.is_none() { continue; } // skip non-players
|
||||
let mode = ConnectionMode::from_u8(user.state.mode.load(std::sync::atomic::Ordering::Relaxed));
|
||||
if !matches!(mode, ConnectionMode::Disconnected) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
async fn on_request_leave(&self, user_id: i32) {
|
||||
|
||||
@@ -8,6 +8,7 @@ pub enum GameMessage {
|
||||
},
|
||||
EndConnection {
|
||||
user_id: i32,
|
||||
is_unregister: bool,
|
||||
},
|
||||
RequestLeave {
|
||||
user_id: i32,
|
||||
|
||||
@@ -15,4 +15,9 @@ pub trait RobotMotionHandler: Send + Sync {
|
||||
async fn handle(&self, data: &bytes::Bytes, user: &UserData);
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait DisconnectHandler: Send + Sync {
|
||||
async fn handle(&self, peer: &std::sync::Arc<literustlib_server::Connection<PacketData>>, user: &UserData);
|
||||
}
|
||||
|
||||
pub trait Broadcastable: byteserde::ser_heap::ByteSerializeHeap + core::any::Any + Send + Sync + 'static {}
|
||||
|
||||
Reference in New Issue
Block a user