2025-06-23 09:48:28 +01:00
|
|
|
use core::time::Duration;
|
2025-10-04 09:26:37 +01:00
|
|
|
use std::sync::Arc;
|
2025-06-23 09:48:28 +01:00
|
|
|
|
|
|
|
|
use werewolves_proto::{
|
|
|
|
|
message::{ClientMessage, Identification, host::HostMessage},
|
|
|
|
|
player::PlayerId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use crate::{
|
2025-09-26 21:15:52 +01:00
|
|
|
LogError,
|
2025-06-23 09:48:28 +01:00
|
|
|
communication::lobby::LobbyComms,
|
|
|
|
|
connection::JoinedPlayers,
|
|
|
|
|
game::{GameEnd, GameRunner},
|
|
|
|
|
lobby::Lobby,
|
|
|
|
|
saver::Saver,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
|
pub struct IdentifiedClientMessage {
|
|
|
|
|
pub identity: Identification,
|
|
|
|
|
pub message: ClientMessage,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn run_game(joined_players: JoinedPlayers, comms: LobbyComms, mut saver: impl Saver) {
|
|
|
|
|
let mut state = RunningState::Lobby(Lobby::new(joined_players, comms));
|
|
|
|
|
loop {
|
|
|
|
|
match &mut state {
|
|
|
|
|
RunningState::Lobby(lobby) => {
|
|
|
|
|
if let Some(game) = lobby.next().await {
|
|
|
|
|
state = RunningState::Game(game)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RunningState::Game(game) => {
|
|
|
|
|
if let Some(result) = game.next().await {
|
|
|
|
|
match saver.save(game.proto_game()) {
|
|
|
|
|
Ok(path) => {
|
|
|
|
|
log::info!("saved game to {path}");
|
|
|
|
|
}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
log::error!("saving game: {err}");
|
|
|
|
|
let game_clone = game.proto_game().clone();
|
|
|
|
|
let mut saver_clone = saver.clone();
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
let started = chrono::Utc::now();
|
|
|
|
|
loop {
|
|
|
|
|
tokio::time::sleep(Duration::from_secs(30)).await;
|
|
|
|
|
match saver_clone.save(&game_clone) {
|
|
|
|
|
Ok(path) => {
|
|
|
|
|
log::info!("saved game from {started} to {path}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
log::error!("saving game from {started}: {err}")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
state = match state {
|
|
|
|
|
RunningState::Game(game) => {
|
|
|
|
|
RunningState::GameOver(GameEnd::new(game, result))
|
|
|
|
|
}
|
|
|
|
|
_ => unsafe { core::hint::unreachable_unchecked() },
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
RunningState::GameOver(end) => {
|
|
|
|
|
if let Some(mut new_lobby) = end.next().await {
|
|
|
|
|
new_lobby.send_lobby_info_to_clients().await;
|
2025-09-26 21:15:52 +01:00
|
|
|
new_lobby.send_lobby_info_to_host().await.log_debug();
|
2025-06-23 09:48:28 +01:00
|
|
|
state = RunningState::Lobby(new_lobby)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
|
pub enum Message {
|
|
|
|
|
Host(HostMessage),
|
|
|
|
|
Client(IdentifiedClientMessage),
|
2025-10-04 09:26:37 +01:00
|
|
|
ConnectedList(Arc<[PlayerId]>),
|
2025-06-23 09:48:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub enum RunningState {
|
|
|
|
|
Lobby(Lobby),
|
|
|
|
|
Game(GameRunner),
|
|
|
|
|
GameOver(GameEnd),
|
|
|
|
|
}
|