From 6614a1f056b00385839fcf2f5171cddcfa4a979a Mon Sep 17 00:00:00 2001 From: CoCo_Sol007 Date: Tue, 26 Mar 2024 10:07:12 +0000 Subject: [PATCH 1/2] Remove unless todo (#85) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.tipragot.fr/fish-canard/border-wars/pulls/85 Reviewed-by: Raphaël Co-authored-by: CoCo_Sol007 Co-committed-by: CoCo_Sol007 --- crates/border-wars/src/scenes/lobby.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/border-wars/src/scenes/lobby.rs b/crates/border-wars/src/scenes/lobby.rs index 89201c9..b734f2c 100644 --- a/crates/border-wars/src/scenes/lobby.rs +++ b/crates/border-wars/src/scenes/lobby.rs @@ -44,7 +44,6 @@ fn lobby_ui( return; } ui.label("Game ID: "); - // TODO : get the game ID and display it. ui.text_edit_singleline(&mut connection.identifier().unwrap_or_default().to_string()); }); From fa78c56049a42522188f5ba9edc2518b0b9bf3a5 Mon Sep 17 00:00:00 2001 From: CoCo_Sol007 Date: Sat, 30 Mar 2024 14:41:57 +0000 Subject: [PATCH 2/2] Add check connection system (#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.tipragot.fr/fish-canard/border-wars/pulls/84 Reviewed-by: Raphaël Co-authored-by: CoCo_Sol007 Co-committed-by: CoCo_Sol007 --- crates/border-wars/src/lib.rs | 2 +- .../src/networking/check_connection.rs | 118 ++++++++++++++++++ crates/border-wars/src/networking/mod.rs | 7 +- 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 crates/border-wars/src/networking/check_connection.rs diff --git a/crates/border-wars/src/lib.rs b/crates/border-wars/src/lib.rs index a97d7ec..6f144ae 100644 --- a/crates/border-wars/src/lib.rs +++ b/crates/border-wars/src/lib.rs @@ -26,7 +26,7 @@ pub enum CurrentScene { } /// A player in the game. -#[derive(Serialize, Deserialize, Clone, Debug, Component, Resource)] +#[derive(Serialize, Deserialize, Clone, Debug, Component, Resource, PartialEq, Eq, Hash)] pub struct Player { /// The name of the player. pub name: String, diff --git a/crates/border-wars/src/networking/check_connection.rs b/crates/border-wars/src/networking/check_connection.rs new file mode 100644 index 0000000..53c05f2 --- /dev/null +++ b/crates/border-wars/src/networking/check_connection.rs @@ -0,0 +1,118 @@ +//! All the code related to the check connection (check every X seconds if any +//! player is still connected). + +use std::time::Instant; + +use bevnet::{Connection, NetworkAppExt, Receive, SendTo}; +use bevy::prelude::*; +use bevy::utils::HashMap; +use serde::{Deserialize, Serialize}; + +use crate::Player; + +/// A plugin that check if a player is still connected. +pub struct CheckConnectionPlugin; + +/// An event that is trigger when a player is disconnected. +#[derive(Event)] +pub struct PlayerDisconnected(pub Player); + +/// An event that is send between all players to check if a player is still +/// connected. +#[derive(Event, Serialize, Deserialize)] +struct IAmConnected(Player); + +impl Plugin for CheckConnectionPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + Update, + ( + check_connection, + send_check_connection, + handle_disconnect_player, + ), + ) + .add_event::() + .add_network_event::(); + } +} + +/// The interval to check if a player is still connected. +/// We put this into a const because we don't want to change it. +const CHECK_CONNECTION_INTERVAL: std::time::Duration = std::time::Duration::from_secs(5); + +/// A fonction that check if a player is still connected. +fn check_connection( + all_players_query: Query<&Player>, + mut disconnect_event: EventWriter, + mut checked_players: Local>, + mut connect_event: EventReader>, +) { + for Receive(_, IAmConnected(player)) in connect_event.read() { + checked_players.insert(player.clone(), Instant::now()); + } + for player in all_players_query.iter() { + if !(*checked_players).contains_key(player) { + checked_players.insert(player.clone(), Instant::now()); + } + + let Some(last_seen) = (*checked_players).get_mut(player) else { + continue; + }; + if last_seen.elapsed() > CHECK_CONNECTION_INTERVAL { + disconnect_event.send(PlayerDisconnected(player.clone())); + checked_players.remove(player); + } + } +} + +/// A simple time/instant that implement Default. +struct Time(std::time::Instant); + +impl Default for Time { + fn default() -> Self { + Self(std::time::Instant::now()) + } +} + +/// A fonction that send a check connection event to all players. +fn send_check_connection( + mut check_connection_event: EventWriter>, + all_players_query: Query<&Player>, + connection: Res, + mut timer: Local