From bfc4600396c11a3082aefb0bf6799695d5cffba6 Mon Sep 17 00:00:00 2001 From: Adam <24621027+adoyle0@users.noreply.github.com> Date: Wed, 14 Aug 2024 00:16:54 -0400 Subject: [PATCH] almost --- client/src/components/game.rs | 2 +- client/src/components/websocket.rs | 6 +- lib/src/lib.rs | 2 +- server/src/game_handler.rs | 233 ++++++++++++++++++++++++++++- server/src/lib.rs | 1 + server/src/message_handler.rs | 8 + 6 files changed, 240 insertions(+), 12 deletions(-) diff --git a/client/src/components/game.rs b/client/src/components/game.rs index e8ab4d0..ef03eb1 100644 --- a/client/src/components/game.rs +++ b/client/src/components/game.rs @@ -5,7 +5,7 @@ use lib::*; #[component] pub fn Game() -> impl IntoView { // let websocket = expect_context::(); - let game_meta = expect_context::>>(); + let game_meta = expect_context::>>(); let (game_name, set_game_name) = create_signal("".to_string()); let (game_host, set_game_host) = create_signal("".to_string()); diff --git a/client/src/components/websocket.rs b/client/src/components/websocket.rs index c4cb983..330c7ce 100644 --- a/client/src/components/websocket.rs +++ b/client/src/components/websocket.rs @@ -73,7 +73,7 @@ pub fn Websocket() -> impl IntoView { let (chat_update, set_chat_update) = create_signal::>(Option::None); let (chat_message, set_chat_message) = create_signal::>(Option::None); let (active_games, set_active_games) = create_signal::>(vec![]); - let (current_game, set_current_game) = create_signal::>(Option::None); + let (current_game, set_current_game) = create_signal::>(Option::None); let (card_packs_meta, set_card_packs_meta) = create_signal::(CardPacksMeta { official_meta: vec![], unofficial_meta: vec![], @@ -84,7 +84,7 @@ pub fn Websocket() -> impl IntoView { provide_context::>>(chat_update); provide_context::>>(chat_message); provide_context::>>(active_games); - provide_context::>>(current_game); + provide_context::>>(current_game); provide_context::>(card_packs_meta); provide_context::>>(state_summary); @@ -107,7 +107,7 @@ pub fn Websocket() -> impl IntoView { set_chat_update(Some(chat_update)); } else if let Ok(games_update) = from_str::(message) { set_active_games(games_update.games); - } else if let Ok(game_update) = from_str::(message) { + } else if let Ok(game_update) = from_str::(message) { set_current_game(Some(game_update)); } else if let Ok(packs_meta_update) = from_str::(message) { set_card_packs_meta(packs_meta_update); diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 9d2f1b5..79fcdce 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -8,7 +8,7 @@ pub struct GameJoinRequest { /// Game meta #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct GameMeta { +pub struct GameStateMeta { pub uuid: String, pub name: String, pub host: String, diff --git a/server/src/game_handler.rs b/server/src/game_handler.rs index 2042b81..aee6a69 100644 --- a/server/src/game_handler.rs +++ b/server/src/game_handler.rs @@ -280,7 +280,7 @@ impl Game { } /// Create a new player and add them to the game. - fn create_player(&mut self, user: Arc>) -> Result<()> { + pub fn create_player(&mut self, user: Arc>) -> Result<()> { let mut new_player = Player { white: vec![], black: vec![], @@ -310,8 +310,8 @@ pub enum GameHandlerMessage { new_game: NewGameRequest, }, JoinGame { - user: Arc, - game_name: String, + addr: SocketAddr, + id: String, }, } pub struct GameHandler { @@ -326,12 +326,224 @@ impl GameHandler { pub async fn handle(&self, message: GameHandlerMessage) { match message { GameHandlerMessage::NewGame { addr, new_game } => self.new_game(addr, new_game).await, + GameHandlerMessage::JoinGame { addr, id } => self.join_game(addr, id).await, _ => { tracing::debug!("Unhandled at game handler"); } } } + async fn join_game(&self, addr: SocketAddr, id: String) { + // Create player + self.state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .write() + .unwrap() + .create_player( + self.state + .online_users + .read() + .unwrap() + .get(&addr) + .unwrap() + .clone(), + ) + .unwrap(); + + // Create update for user's game view + let mut black_card = ("Error".to_string(), 0u8); + if let Some(ref current_black) = self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .current_black + { + black_card = (current_black.text.to_owned(), current_black.pick) + } + let meta = GameStateMeta { + uuid: id.clone(), + name: self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .name + .clone(), + host: self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .host + .read() + .unwrap() + .name + .clone(), + players: self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .players + .iter() + .map(|player| { + self.state + .user_uuid + .read() + .unwrap() + .get(player.0) + .unwrap() + .read() + .unwrap() + .name + .clone() + }) + .collect(), + czar: self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .host + .read() + .unwrap() + .name + .clone(), + black: black_card, + white: self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .players + .get( + &self + .state + .online_users + .read() + .unwrap() + .get(&addr) + .unwrap() + .read() + .unwrap() + .uuid, + ) + .unwrap() + .white + .iter() + .map(|card| card.text.clone()) + .collect(), + packs: self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .packs + .clone(), + }; + + // Send updates for all players + for player in self + .state + .games + .read() + .unwrap() + .get(&id) + .unwrap() + .read() + .unwrap() + .players + .iter() + { + // // Send user's update + // self.state + // .user_uuid + // .read() + // .unwrap() + // .get(&player.0) + // .unwrap() + // .read() + // .unwrap() + // .tx + // .send(serde_json::to_string(&meta).unwrap()) + // .await + // .unwrap(); + tracing::debug! {"y"}; + } + // let _ = self + // .state + // .games + // .read() + // .unwrap() + // .get(&id) + // .unwrap() + // .read() + // .unwrap() + // .players + // .iter() + // .map(async |player: (&Uuid, &Player)| { + // // Send user's update + // self.state + // .user_uuid + // .read() + // .unwrap() + // .get(player.0) + // .unwrap() + // .read() + // .unwrap() + // .tx + // .send(serde_json::to_string(&meta).unwrap()) + // .await + // .unwrap(); + // }) + // .count(); + + // Broadcast game browser update + self.state + .broadcast_tx + .send(meta_games_browser_update(&self.state)) + .unwrap(); + + // Broadcast server meta update + self.state + .broadcast_tx + .send(meta_server_summary_update(&self.state)) + .unwrap(); + } + async fn new_game(&self, addr: SocketAddr, new_game: NewGameRequest) { if new_game.packs.is_empty() { tracing::debug!("Cards are empty"); @@ -354,7 +566,7 @@ impl GameHandler { packs: new_game.packs, }; - // create game + // Create game if let Ok(new_game_object) = Game::new(self.state.clone(), manifest) { let tx = self .state @@ -368,12 +580,12 @@ impl GameHandler { .tx .clone(); + // Create update for user's game view let mut black_card = ("Error".to_string(), 0u8); if let Some(ref current_black) = new_game_object.current_black { black_card = (current_black.text.to_owned(), current_black.pick) } - - let meta = GameMeta { + let meta = GameStateMeta { uuid: new_game_object.uuid.to_string(), name: new_game_object.name.clone(), host: new_game_object.host.read().unwrap().name.clone(), @@ -406,17 +618,24 @@ impl GameHandler { packs: new_game_object.packs.clone(), }; + // Send user's update tx.send(serde_json::to_string(&meta).unwrap()) .await .unwrap(); + + // Add game to active list self.state.games.write().unwrap().insert( - new_game_object.name.clone(), + new_game_object.uuid.to_string(), Arc::new(RwLock::new(new_game_object)), ); + + // Broadcast game browser update self.state .broadcast_tx .send(meta_games_browser_update(&self.state)) .unwrap(); + + // Broadcast server meta update self.state .broadcast_tx .send(meta_server_summary_update(&self.state)) diff --git a/server/src/lib.rs b/server/src/lib.rs index 3589631..8d3c027 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,4 +1,5 @@ #![feature(if_let_guard)] +#![feature(async_closure)] use crate::game_handler::*; use anyhow::{Context, Result}; diff --git a/server/src/message_handler.rs b/server/src/message_handler.rs index 1de58a8..e501870 100644 --- a/server/src/message_handler.rs +++ b/server/src/message_handler.rs @@ -47,6 +47,14 @@ impl MessageHandler { .unwrap(); } + _join_game_request if let Ok(join_request) = from_str::(&text) => { + self.state + .games_tx + .send(GameHandlerMessage::JoinGame { addr, id: join_request.id }) + .await + .unwrap(); + } + _ => tracing::debug!("Unhandled text from {}", addr), }, Message::Binary(data) => tracing::debug!("{} sent binary: {:?}", addr, data),