From e57d4a3cbf6c83674a4f8fed6f4d4dcf3bed3f11 Mon Sep 17 00:00:00 2001 From: emilis Date: Fri, 17 Oct 2025 22:03:28 +0100 Subject: [PATCH] GameStory for client on game end --- werewolves-proto/src/message.rs | 7 ++- werewolves-server/src/connection.rs | 14 ++++++ werewolves-server/src/game.rs | 55 ++++++++++++++++----- werewolves/src/clients/client/client.rs | 9 +++- werewolves/src/clients/client/connection.rs | 1 + 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/werewolves-proto/src/message.rs b/werewolves-proto/src/message.rs index 24d0c29..a93005d 100644 --- a/werewolves-proto/src/message.rs +++ b/werewolves-proto/src/message.rs @@ -7,7 +7,11 @@ use core::num::NonZeroU8; pub use ident::*; use serde::{Deserialize, Serialize}; -use crate::{character::CharacterId, game::GameOver, role::RoleTitle}; +use crate::{ + character::CharacterId, + game::{GameOver, story::GameStory}, + role::RoleTitle, +}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum ClientMessage { @@ -46,6 +50,7 @@ pub enum ServerMessage { InvalidMessageForGameState, NoSuchTarget, GameOver(GameOver), + Story(GameStory), Update(PlayerUpdate), Sleep, Reset, diff --git a/werewolves-server/src/connection.rs b/werewolves-server/src/connection.rs index f9696d6..f83b932 100644 --- a/werewolves-server/src/connection.rs +++ b/werewolves-server/src/connection.rs @@ -77,6 +77,20 @@ impl JoinedPlayers { } } + pub async fn send_to(&self, player_ids: &[PlayerId], message: ServerMessage) { + let players: tokio::sync::MutexGuard<'_, HashMap> = + self.players.lock().await; + let senders = players + .iter() + .filter(|(pid, _)| player_ids.contains(*pid)) + .map(|(pid, p)| (*pid, p.sender.clone())) + .collect::>(); + core::mem::drop(players); + for (_, send) in senders { + send.send(message.clone()).log_debug(); + } + } + pub async fn send_all_lobby(&self, in_lobby: Box<[PublicIdentity]>, in_lobby_ids: &[PlayerId]) { let players: tokio::sync::MutexGuard<'_, HashMap> = self.players.lock().await; diff --git a/werewolves-server/src/game.rs b/werewolves-server/src/game.rs index 299f34b..b020413 100644 --- a/werewolves-server/src/game.rs +++ b/werewolves-server/src/game.rs @@ -277,11 +277,17 @@ impl GameRunner { } } +enum ProcessOutcome { + Lobby(Lobby), + SendPlayer(PlayerId, ServerMessage), +} + pub struct GameEnd { game: Option, page: Option, result: GameOver, last_error_log: Instant, + notified_connected: bool, } impl GameEnd { @@ -290,6 +296,7 @@ impl GameEnd { result, page: None, game: Some(game), + notified_connected: false, last_error_log: Instant::now() - core::time::Duration::from_secs(60), } } @@ -302,6 +309,20 @@ impl GameEnd { } pub async fn next(&mut self) -> Option { + if !self.notified_connected { + self.notified_connected = true; + let game = self.game().ok()?; + let story = game.game.story(); + let player_ids = game + .player_sender + .iter() + .map(|(i, _)| i.player_id) + .collect::>(); + + game.joined_players + .send_to(&player_ids, ServerMessage::Story(story)) + .await; + } let msg = match self.game().unwrap().comms.message().await { Ok(msg) => msg, Err(err) => { @@ -313,10 +334,22 @@ impl GameEnd { } }; - self.process(msg) + match self.process(msg)? { + ProcessOutcome::Lobby(lobby) => Some(lobby), + ProcessOutcome::SendPlayer(player_id, msg) => { + self.game() + .ok()? + .joined_players + .get_sender(player_id) + .await? + .send(msg) + .log_debug(); + None + } + } } - fn process(&mut self, message: Message) -> Option { + fn process(&mut self, message: Message) -> Option { match message { Message::Host(HostMessage::Echo(msg)) => { self.game().unwrap().comms.host().send(msg).log_debug(); @@ -366,7 +399,7 @@ impl GameEnd { .send(ServerToHostMessage::Lobby(Box::new([]))) .log_debug(); let lobby = self.game.take()?.into_lobby(); - return Some(lobby); + return Some(ProcessOutcome::Lobby(lobby)); } Message::Host(_) => self @@ -378,16 +411,12 @@ impl GameEnd { GameError::InvalidMessageForGameState, )) .log_debug(), - Message::Client(IdentifiedClientMessage { - identity, - message: _, - }) => { - let result = self.result; - self.game() - .ok()? - .player_sender - .send_if_present(identity.player_id, ServerMessage::GameOver(result)) - .log_debug(); + Message::Client(IdentifiedClientMessage { identity, .. }) => { + let story = self.game().ok()?.game.story(); + return Some(ProcessOutcome::SendPlayer( + identity.player_id, + ServerMessage::Story(story), + )); } Message::ConnectedList(_) => {} } diff --git a/werewolves/src/clients/client/client.rs b/werewolves/src/clients/client/client.rs index 1dfca82..934ba6a 100644 --- a/werewolves/src/clients/client/client.rs +++ b/werewolves/src/clients/client/client.rs @@ -2,6 +2,7 @@ use std::rc::Rc; use gloo::storage::errors::StorageError; use werewolves_proto::{ + game::story::GameStory, message::{ClientMessage, Identification, PublicIdentity}, player::PlayerId, role::RoleTitle, @@ -11,7 +12,7 @@ use yew::prelude::*; use crate::{ clients::client::connection::{Connection2, ConnectionError}, components::{ - Button, CoverOfDarkness, Identity, + Button, CoverOfDarkness, Identity, Story, client::{ClientNav, Signin}, }, storage::StorageKey, @@ -29,6 +30,7 @@ pub enum ClientEvent2 { joined: bool, players: Rc<[PublicIdentity]>, }, + Story(GameStory), } #[derive(Default, Clone, PartialEq)] @@ -79,6 +81,11 @@ pub fn Client2(ClientProps { auto_join }: &ClientProps) -> Html { let connection = use_mut_ref(|| Connection2::new(client_state.setter(), ident.clone(), recv)); let content = match &*client_state { + ClientEvent2::Story(story) => html! { +
+ +
+ }, ClientEvent2::Sleep => html! { }, diff --git a/werewolves/src/clients/client/connection.rs b/werewolves/src/clients/client/connection.rs index 1f4e9d6..6617cbe 100644 --- a/werewolves/src/clients/client/connection.rs +++ b/werewolves/src/clients/client/connection.rs @@ -218,6 +218,7 @@ impl Connection2 { fn message_to_client_state(&self, msg: ServerMessage) -> Option { log::debug!("received message: {msg:?}"); Some(match msg { + ServerMessage::Story(story) => ClientEvent2::Story(story), ServerMessage::Sleep => ClientEvent2::Sleep, ServerMessage::Disconnect => ClientEvent2::Disconnected, ServerMessage::LobbyInfo {