diff --git a/client/src/components/browser.rs b/client/src/components/browser.rs index 8dbf08d..fb94048 100644 --- a/client/src/components/browser.rs +++ b/client/src/components/browser.rs @@ -1,4 +1,5 @@ use crate::components::websocket::WebSocketContext; +use leptos::html::Input; use leptos::*; use leptos_use::core::ConnectionReadyState; use lib::models::*; @@ -12,13 +13,17 @@ pub fn Browser() -> impl IntoView { let game_update_context = expect_context::>>(); let (active_games, set_active_games) = create_signal::>(vec![]); - let fake_new_game_request = NewGameRequest { - name: String::from("Ligma"), - }; + let new_game_input_ref = create_node_ref::(); // Game stuff - let new_game_test = move |_| { - (websocket.send)(&to_string(&fake_new_game_request).unwrap()); + let new_game = move |_| { + (websocket.send)( + &to_string(&NewGameRequest { + name: new_game_input_ref.get().unwrap().value(), + }) + .unwrap(), + ); + new_game_input_ref.get().unwrap().set_value(""); }; create_effect(move |_| { @@ -42,9 +47,20 @@ pub fn Browser() -> impl IntoView {

Game Browser

{move || active_games().into_iter().map(|n| view! {
  • {n}
  • }).collect_view()} - +
    + + +
    } } diff --git a/client/src/components/websocket.rs b/client/src/components/websocket.rs index 8b29132..0dfb9d1 100644 --- a/client/src/components/websocket.rs +++ b/client/src/components/websocket.rs @@ -69,13 +69,13 @@ pub fn Websocket() -> impl IntoView { // Contexts for message handler let (state_summary, set_state_summary) = create_signal::>(Option::None); - let (game_object, set_game_object) = create_signal::>(Option::None); + // let (game_object, set_game_object) = create_signal::>(Option::None); let (user_update, set_user_update) = create_signal::>(Option::None); 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::>(Option::None); - provide_context::>>(game_object); + // provide_context::>>(game_object); provide_context::>>(user_update); provide_context::>>(chat_update); provide_context::>>(chat_message); @@ -88,9 +88,10 @@ pub fn Websocket() -> impl IntoView { // Send all messages as strings into chat box if let Some(message) = message_raw { - if let Ok(game) = from_str::(message) { - set_game_object(Some(game)); - } else if let Ok(state_summary) = from_str::(message) { + // if let Ok(game) = from_str::(message) { + // set_game_object(Some(game)); + // } + if let Ok(state_summary) = from_str::(message) { set_state_summary(Some(state_summary)); } else if let Ok(chat_message) = from_str::(message) { set_chat_message(Some(chat_message)); diff --git a/lib/src/game_master.rs b/lib/src/game_master.rs index fd75589..b23b00d 100644 --- a/lib/src/game_master.rs +++ b/lib/src/game_master.rs @@ -1,115 +1,129 @@ -// use anyhow::Result; -// use rand::prelude::IteratorRandom; -// use rand::thread_rng; -// -// use crate::models::*; -// -// impl Game { -// /// Build game decks from input data for game start. -// /// This should only run once and at startup. -// fn _build_decks(&mut self, cards_json: Vec) -> Result<()> { -// for pack in cards_json { -// if let Some(white) = pack.white { -// self.white.extend(white) -// } -// if let Some(black) = pack.black { -// self.black.extend(black) -// } -// } -// -// Ok(()) -// } -// -// pub fn new(request: NewGameRequest) -> Result { -// let mut game = Game { -// ..Default::default() -// }; -// tracing::debug!("Creating game {}", &request.name); -// game.name = request.name; -// -// // game.build_decks(request.packs)?; -// game.create_player(request.host)?; -// game.deal_black()?; -// -// Ok(game) -// } -// -// // pub fn join(request:GameJoinRequest) -// -// /// Log counts of current drawable cards -// /// For testing -// pub fn deck_counts(&self) { -// tracing::debug!( -// "Deck Counts:\n {} White cards\n {} Black cards", -// self.white.len(), -// self.black.len() -// ); -// } -// -// /// Draw one white card at random from play deck. -// fn draw_one_white(&mut self) -> Result { -// let deck = &mut self.white; -// -// // this feels sloppy -// if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) { -// Ok(deck.swap_remove(index)) -// } else { -// Ok(CardWhite { -// text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(), -// pack: 0, -// }) -// } -// } -// -// /// Draw one black card at random from play deck. -// fn draw_one_black(&mut self) -> Result { -// let deck = &mut self.black; -// -// // this feels sloppy -// if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) { -// Ok(deck.swap_remove(index)) -// } else { -// Ok(CardBlack { -// text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(), -// pick: 0, -// pack: 0, -// }) -// } -// } -// -// /// Deal a black card and use it for the current round -// fn deal_black(&mut self) -> Result<()> { -// self.current_black = Some(self.draw_one_black()?); -// -// Ok(()) -// } -// -// /// Create a new player and add them to the game. -// pub fn create_player(&mut self, mut player: Player) -> Result<()> { -// tracing::debug!("Creating player {} as {:?}", &player.name, &player.role); -// -// let mut hand_buf = vec![]; -// for _ in 0..10 { -// hand_buf.push(self.draw_one_white()?); -// } -// tracing::debug!("Dealing hand to {}", &player.name); -// player.white.extend(hand_buf); -// -// self.players.push(player); -// -// Ok(()) -// } -// -// pub fn game_start(&mut self) -> Result<()> { -// self.game_active = true; -// tracing::debug!("Game Active!"); -// -// if let Some(black) = &self.current_black { -// tracing::debug!("{}", black.text); -// } else { -// tracing::debug!("YOU DONE FUCKED UP (no current black card)"); -// } -// -// Ok(()) -// } -// } +use anyhow::Result; +use rand::prelude::IteratorRandom; +use rand::thread_rng; +use std::sync::{Arc, Mutex}; + +use crate::models::*; + +impl Game { + /// Build game decks from input data for game start. + /// This should only run once and at startup. + fn _build_decks(&mut self, cards_json: Vec) -> Result<()> { + for pack in cards_json { + if let Some(white) = pack.white { + self.white.extend(white) + } + if let Some(black) = pack.black { + self.black.extend(black) + } + } + + Ok(()) + } + + pub fn new(request: NewGameManifest) -> Result { + let mut game = Game { + ..Default::default() + }; + tracing::debug!( + "Creating game {} with {} as host", + &request.name, + request.host.lock().unwrap().name + ); + game.name = request.name; + game.host = request.host.clone(); + + // game.build_decks(request.packs)?; + game.create_player(request.host)?; + game.deal_black()?; + + Ok(game) + } + + // pub fn join(request:GameJoinRequest) + + /// Log counts of current drawable cards + /// For testing + pub fn deck_counts(&self) { + tracing::debug!( + "Deck Counts:\n {} White cards\n {} Black cards", + self.white.len(), + self.black.len() + ); + } + + /// Draw one white card at random from play deck. + fn draw_one_white(&mut self) -> Result { + let deck = &mut self.white; + + // this feels sloppy + if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) { + Ok(deck.swap_remove(index)) + } else { + Ok(CardWhite { + text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(), + pack: 0, + }) + } + } + + /// Draw one black card at random from play deck. + fn draw_one_black(&mut self) -> Result { + let deck = &mut self.black; + + // this feels sloppy + if let Some(index) = (0..deck.len()).choose(&mut thread_rng()) { + Ok(deck.swap_remove(index)) + } else { + Ok(CardBlack { + text: "Error.\n\nbtw if you see this tell me I'm lazy :)".to_string(), + pick: 0, + pack: 0, + }) + } + } + + /// Deal a black card and use it for the current round + fn deal_black(&mut self) -> Result<()> { + self.current_black = Some(self.draw_one_black()?); + + Ok(()) + } + + /// Create a new player and add them to the game. + pub fn create_player(&mut self, user: Arc>) -> Result<()> { + let mut new_player = Player { + user: user.clone(), + white: vec![], + black: vec![], + }; + + let new_player_name = user.lock().unwrap().name.clone(); + tracing::debug!("Creating player for {}", &new_player_name); + + let mut hand_buf = vec![]; + for _ in 0..10 { + hand_buf.push(self.draw_one_white()?); + } + tracing::debug!("Dealing hand to {}", &new_player_name); + + new_player.white.extend(hand_buf); + + self.players.push(new_player); + + Ok(()) + } + + pub fn game_start(&mut self) -> Result<()> { + self.game_active = true; + tracing::debug!("Game Active!"); + + if let Some(black) = &self.current_black { + tracing::debug!("{}", black.text); + } else { + tracing::debug!("YOU DONE FUCKED UP (no current black card)"); + } + + Ok(()) + } +} diff --git a/lib/src/models.rs b/lib/src/models.rs index b4ef8c9..ad868e4 100644 --- a/lib/src/models.rs +++ b/lib/src/models.rs @@ -40,7 +40,7 @@ pub struct ServerStateSummary { } /// User -#[derive(Debug, Eq, PartialEq, Hash)] +#[derive(Default, Debug, Eq, PartialEq, Hash)] pub struct User { pub name: String, } @@ -124,12 +124,10 @@ pub enum PlayerRole { } /// A struct that represents a player -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] pub struct Player { /// Player's username - pub name: String, - /// This player's role - pub role: PlayerRole, + pub user: Arc>, /// The player's hand pub white: Vec, /// The player's wins @@ -137,10 +135,12 @@ pub struct Player { } /// The game master -#[derive(Default, Debug, Serialize, Deserialize)] +#[derive(Default, Debug)] pub struct Game { /// The name of the game pub name: String, + /// The host user of the game + pub host: Arc>, /// White draw pile pub white: Vec, /// Black draw pile diff --git a/server/src/api.rs b/server/src/api.rs index 2aa681f..2316d7c 100644 --- a/server/src/api.rs +++ b/server/src/api.rs @@ -156,9 +156,11 @@ fn motd() -> String { /// Generate server summary update - mostly debug stuff fn server_summary_update(state: &Arc) -> String { + let online_users = state.online_users.lock().unwrap().len(); + let active_games = state.games.lock().unwrap().len(); to_string::(&ServerStateSummary { - online_users: state.online_users.lock().unwrap().len(), - active_games: state.games.lock().unwrap().len(), + online_users, + active_games, }) .unwrap() } @@ -169,7 +171,11 @@ fn games_update(state: &Arc) -> String { let mut names = vec![]; for game in state.games.lock().unwrap().iter() { - names.push(game.name.clone()); + names.push(format!( + "Name: {} Host: {}", + game.name, + game.host.lock().unwrap().name + )); } to_string::(&GamesUpdate { games: names }).unwrap() @@ -179,7 +185,15 @@ fn games_update(state: &Arc) -> String { fn announce_join(state: &Arc, addr: &SocketAddr) -> String { let msg = format!( "{} joined.", - state.online_users.lock().unwrap().get(addr).unwrap().lock().unwrap().name + state + .online_users + .lock() + .unwrap() + .get(addr) + .unwrap() + .lock() + .unwrap() + .name ); tracing::debug!("{}", &msg); diff --git a/server/src/api/message_handler.rs b/server/src/api/message_handler.rs index aa787c0..1bd6845 100644 --- a/server/src/api/message_handler.rs +++ b/server/src/api/message_handler.rs @@ -54,31 +54,23 @@ fn handle_new_game( tx: &Sender, addr: SocketAddr, ) -> Result<()> { - let binding = state.online_users.lock().unwrap(); - let user = binding.get(&addr).unwrap(); - - tracing::debug!("{:#?} from {}", new_game, user.lock().unwrap().name); let manifest = NewGameManifest { name: new_game.name, - host: user.clone(), + host: state + .online_users + .lock() + .unwrap() + .get(&addr) + .unwrap() + .clone(), }; // create game - // if let Ok(new_game_object) = Game::new(new_game) { - // if let Ok(game_json) = to_string(&new_game_object) { - // tracing::debug!("Sent new game JSON."); - // // this is a broadcast - // // change this - // tx.send(game_json)?; - // } else { - // // change this - // tracing::error!("Failed to convert Game object to JSON.") - // } - // - // state.games.lock().unwrap().push(new_game_object); - // tx.send(games_update(state))?; - // tx.send(server_summary_update(state))?; - // } + if let Ok(new_game_object) = Game::new(manifest) { + state.games.lock().unwrap().push(new_game_object); + tx.send(games_update(state))?; + tx.send(server_summary_update(state))?; + } Ok(()) }