diff options
-rw-r--r-- | server/protocol/src/lib.rs | 3 | ||||
-rw-r--r-- | server/src/server.rs | 14 | ||||
-rw-r--r-- | server/src/state.rs | 36 |
3 files changed, 40 insertions, 13 deletions
diff --git a/server/protocol/src/lib.rs b/server/protocol/src/lib.rs index 90106317..c32bff39 100644 --- a/server/protocol/src/lib.rs +++ b/server/protocol/src/lib.rs @@ -125,10 +125,11 @@ pub enum PacketS { timeout: Option<f32>, pin: Option<bool>, }, - Idle { paused: bool, }, + Ready, + /// For use in replay sessions only ReplayTick { dt: f64, diff --git a/server/src/server.rs b/server/src/server.rs index f97ca69c..a1a849c4 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -40,9 +40,16 @@ use std::{ }; use tokio::sync::broadcast::Sender; +#[derive(Debug, Default)] +pub struct ConnectionData { + pub players: HashSet<PlayerID>, + pub idle: bool, + pub ready: bool, +} + pub struct Server { pub tx: Sender<PacketC>, - pub connections: HashMap<ConnectionID, (HashSet<PlayerID>, bool)>, + pub connections: HashMap<ConnectionID, ConnectionData>, pub paused: bool, pub start_pause_timer: f32, @@ -329,8 +336,7 @@ impl Server { score_changed: false, packet_loopback: VecDeque::new(), last_movement_update: HashMap::default(), - scoreboard: ScoreboardStore::load() - .context("Failed to load scoreboards")?, + scoreboard: ScoreboardStore::load().context("Failed to load scoreboards")?, editor_address: None, paused: false, }) @@ -649,7 +655,7 @@ impl Server { self.score_changed = true; } PacketS::ReplayTick { .. } => return Err(tre!("s.error.packet_not_supported")), - PacketS::Idle { .. } => (), + PacketS::Idle { .. } | PacketS::Ready => (), } Ok(()) } diff --git a/server/src/state.rs b/server/src/state.rs index 2209fc5d..b4a8ce1f 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -25,7 +25,7 @@ impl Server { if self.start_pause_timer > 0. { self.start_pause_timer -= dt } - let should_pause = self.start_pause_timer > 0. || self.connections.iter().all(|c| c.1 .1); + let should_pause = self.start_pause_timer > 0. || self.connections.values().all(|c| c.idle); if should_pause != self.paused { info!("Game paused: {should_pause}"); self.paused = should_pause; @@ -66,7 +66,13 @@ impl Server { packet: PacketS, ) -> Result<Vec<PacketC>, TrError> { if let Some(p) = get_packet_player(&packet) { - if !self.connections.entry(conn).or_default().0.contains(&p) { + if !self + .connections + .entry(conn) + .or_default() + .players + .contains(&p) + { return Err(tre!("s.error.packet_sender_invalid")); } } @@ -88,12 +94,21 @@ impl Server { } } } - PacketS::Idle { paused } => self.connections.entry(conn).or_default().1 = *paused, + PacketS::Ready => { + self.connections.entry(conn).or_default().ready = true; + } + PacketS::Idle { paused } => { + self.connections.entry(conn).or_default().idle = *paused; + } PacketS::Leave { player } => { - self.connections.entry(conn).or_default().0.remove(player); + self.connections + .entry(conn) + .or_default() + .players + .remove(player); } PacketS::Join { .. } => { - if self.connections.entry(conn).or_default().0.len() > 8 { + if self.connections.entry(conn).or_default().players.len() > 8 { return Err(tre!("s.error.conn_too_many_players")); } } @@ -103,7 +118,11 @@ impl Server { for p in &replies { if let PacketC::Joined { id } = p { - self.connections.entry(conn).or_default().0.insert(*id); + self.connections + .entry(conn) + .or_default() + .players + .insert(*id); } } @@ -125,8 +144,8 @@ impl Server { } pub async fn disconnect(&mut self, conn: ConnectionID) { - if let Some((players, _)) = self.connections.get(&conn) { - for player in players.clone() { + if let Some(cd) = self.connections.get(&conn) { + for player in cd.players.clone() { let _ = self.packet_in_outer(conn, PacketS::Leave { player }).await; } } @@ -144,6 +163,7 @@ fn get_packet_player(packet: &PacketS) -> Option<PlayerID> { PacketS::Communicate { player, .. } => Some(*player), PacketS::ReplaceHand { player, .. } => Some(*player), PacketS::Effect { player, .. } => Some(*player), + PacketS::Ready => None, PacketS::ApplyScore(_) => None, PacketS::ReplayTick { .. } => None, } |