diff --git a/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs b/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs index 36da93a..89e7726 100644 --- a/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs +++ b/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs @@ -1,4 +1,5 @@ use super::super::super::super::model::state::room::Room; +use super::super::super::super::model::state::event::Event; use super::super::lobby::Lobby; use super::super::player::Player; use super::super::policy::Policy; @@ -6,8 +7,10 @@ use super::super::role::Role; use super::super::gameevent::GameEventType; use super::super::gameevent::GameEvent; -use log::{info, error}; +use log::{info, debug, error}; use std::collections::HashMap; +use std::thread; +use std::time; #[derive(Debug)] pub struct GameMaster { @@ -85,6 +88,23 @@ impl GameMaster { pub fn player(&mut self, id: String) -> Option<&mut Player> { self.lobby.players.get_mut(&id) } + + pub fn scrape_until_gameeventtype(&mut self, get: GameEventType) -> Result, String> { + let mut scraped = vec![]; + loop { + let events = self.room.sync(); + for e in &events { + scraped.push(e.clone()); + let ge = GameEvent::new(e.clone()); + debug!("scrape_until {:?}: ge: {:?}", get, ge); + if ge.mode() == get { + self.room.rollback(e.since.clone()); + return Ok(scraped); + } + } + thread::sleep(time::Duration::new(1, 0)); + } + } } #[cfg(test)] @@ -116,4 +136,25 @@ mod tests { let r = mrs.create(); let _ = GameMaster::new(r); } + + #[test] + fn scrape_until_get() { + let mut mrs = MockRooms::new(); + let r = mrs.create(); + let room_id = r.room_id().clone(); + let r2 = mrs.join(room_id); + assert!(r2.is_ok()); + let mut r2 = r2.unwrap(); + let mut gm = GameMaster::new(r); + gm.room.sync(); + r2.send(GameEventType::Null.build().serialize()).unwrap(); + let scraped = gm.scrape_until_gameeventtype(GameEventType::Null); + assert!(scraped.is_ok()); + let scraped = scraped.unwrap(); + assert!(scraped.len() == 1); + assert!(scraped.first().is_some()); + let e = scraped.first().unwrap(); + assert!(GameEvent::new(e.clone()).mode() == GameEventType::Null, "{:?}", e); + assert!(gm.room.sync().len() == 0); + } } diff --git a/secert-hitler/src/controller/gamemaster/gamemaster/lobby.rs b/secert-hitler/src/controller/gamemaster/gamemaster/lobby.rs index 1cc3ede..64d0fa8 100644 --- a/secert-hitler/src/controller/gamemaster/gamemaster/lobby.rs +++ b/secert-hitler/src/controller/gamemaster/gamemaster/lobby.rs @@ -5,7 +5,6 @@ use super::super::gameevent::GameEventType; use std::thread; use std::time; -use log::{debug, LevelFilter}; impl GameMaster { pub fn run_lobby(&mut self) -> Result { @@ -22,18 +21,17 @@ impl GameMaster { } pub fn run_lobby_scrape(&mut self) -> Result { - debug!("run_lobby_scrape:"); - let events = self.room.sync(); + let events = self.scrape_until_gameeventtype(GameEventType::GameStart)?; for e in &events { - let ge = GameEvent::new(e.clone()); - debug!("run_lobby_scrape: ge: {:?}", ge); - if ge.mode() == GameEventType::GameStart { - self.room.rollback(e.since.clone()); - self.lobby.lock(); - return self.lobby.ready(); - } self.lobby.eat(e.clone()); } + if events.len() > 0 { + let last = events.last().unwrap(); + let ge = GameEvent::new(last.clone()); + if ge.mode() == GameEventType::GameStart { + self.lobby.lock(); + } + } return self.lobby.ready(); } } @@ -44,6 +42,7 @@ mod tests { use super::super::super::super::super::model::state::mockrooms::MockRooms; use super::super::super::super::super::model::state::rooms::Rooms; use super::super::super::super::super::config; + use log::{LevelFilter}; fn init() { let _ = env_logger::builder() @@ -73,6 +72,11 @@ mod tests { for k in gm.lobby.players.keys() { players1.push(k.clone()); } + let mut r2 = mrs.join(room_id.clone()).unwrap(); + r2.send(format!(r#"{{ + "msgtype": "m.text", + "body": "{{\"GameEventType\": \"GameStart\"}}" + }}"#)).unwrap(); assert!(gm.run_lobby().is_ok()); assert!(gm.lobby.players.len() == 5, "secnd run_lobby players: {:?}, sync: {:?}", gm.lobby.players, gm.room.sync()); let players2 = gm.lobby.players.keys();