diff --git a/server/src/game_handler.rs b/server/src/game_handler.rs new file mode 100644 index 0000000..b596f58 --- /dev/null +++ b/server/src/game_handler.rs @@ -0,0 +1,51 @@ +use crate::user_handler::*; +use crate::AppState; +use crate::Game; +use crate::NewGameManifest; +use crate::NewGameRequest; +use std::net::SocketAddr; +use std::sync::{Arc, RwLock}; + +/// Handle incoming messages over the WebSocket + +pub struct GameHandler { + state: Arc, +} + +impl GameHandler { + pub fn new(state: Arc) -> Self { + GameHandler { state } + } + + pub async fn handle(&self, message: (SocketAddr, NewGameRequest)) { + let manifest = NewGameManifest { + name: message.1.name, + host: self + .state + .online_users + .read() + .unwrap() + .get(&message.0) + .unwrap() + .clone(), + }; + tracing::debug!("Game Packs {:?}", message.1.packs); + + // create game + if let Ok(new_game_object) = Game::new(manifest) { + self.state + .games + .write() + .unwrap() + .insert(new_game_object.name.clone(), RwLock::new(new_game_object)); + self.state + .broadcast_tx + .send(meta_games_browser_update(&self.state)) + .unwrap(); + self.state + .broadcast_tx + .send(meta_server_summary_update(&self.state)) + .unwrap(); + } + } +} diff --git a/server/src/lib.rs b/server/src/lib.rs index 8fcdf79..59faccd 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -16,6 +16,7 @@ use std::{ use tokio::sync::mpsc::Sender; use tokio::sync::{broadcast, mpsc}; use user_handler::UserHandlerMessage; +pub mod game_handler; pub mod message_handler; pub mod user_handler; pub mod websocket; @@ -363,6 +364,7 @@ pub struct AppState { pub broadcast_tx: broadcast::Sender, pub users_tx: mpsc::Sender, pub messages_tx: mpsc::Sender<(SocketAddr, Message)>, + pub games_tx: mpsc::Sender<(SocketAddr, NewGameRequest)>, pub first_names: Vec, pub last_names: Vec, pub reserved_names: RwLock>, diff --git a/server/src/main.rs b/server/src/main.rs index 9222b9e..6ddcdcd 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,3 +1,4 @@ +use crate::game_handler::*; use crate::message_handler::*; use crate::websocket::*; use anyhow::{Context, Result}; @@ -28,6 +29,7 @@ async fn main() -> Result<()> { let (broadcast_tx, _rx) = broadcast::channel(100); let (users_tx, mut users_rx) = mpsc::channel(100); let (messages_tx, mut messages_rx) = mpsc::channel(100); + let (games_tx, mut games_rx) = mpsc::channel(100); let first_names = load_names("data/first.txt")?; let last_names = load_names("data/last.txt")?; let reserved_names = RwLock::new(HashSet::::new()); @@ -40,6 +42,7 @@ async fn main() -> Result<()> { broadcast_tx, users_tx, messages_tx, + games_tx, first_names, last_names, reserved_names, @@ -50,6 +53,7 @@ async fn main() -> Result<()> { games, }); + // Spawn task to handle incoming messages, also handles outging messages let message_handler = MessageHandler::new(app_state.clone()); tokio::spawn(async move { while let Some((addr, message)) = messages_rx.recv().await { @@ -57,6 +61,9 @@ async fn main() -> Result<()> { } }); + // Make an outgoing message handler handler + + // Spawn task to handle User things let user_handler = UserHandler::new(app_state.clone()); tokio::spawn(async move { while let Some(message) = users_rx.recv().await { @@ -64,6 +71,14 @@ async fn main() -> Result<()> { } }); + // Spawn task to handle Game things + let game_handler = GameHandler::new(app_state.clone()); + tokio::spawn(async move { + while let Some(message) = games_rx.recv().await { + game_handler.handle(message).await; + } + }); + // Router let app = Router::new() .route("/websocket", get(websocket_connection_handler)) diff --git a/server/src/message_handler.rs b/server/src/message_handler.rs index 283dc6f..faebf1e 100644 --- a/server/src/message_handler.rs +++ b/server/src/message_handler.rs @@ -40,6 +40,9 @@ impl MessageHandler { .unwrap(); tracing::debug!("passed login to user handler"); } + _new_game if let Ok(new_game) = from_str::(&text) => { + self.state.games_tx.send((addr, new_game)).await.unwrap(); + } _ => tracing::debug!("Unhandled text from {}", addr), }, diff --git a/server/src/websocket.rs b/server/src/websocket.rs index c4d80fd..9deb6c9 100644 --- a/server/src/websocket.rs +++ b/server/src/websocket.rs @@ -1,9 +1,6 @@ use crate::user_handler::*; use crate::AppState; -use crate::Game; -use crate::NewGameManifest; use crate::User; -use anyhow::Result; use axum::{ extract::{ ws::{Message, WebSocket}, @@ -12,15 +9,11 @@ use axum::{ response::IntoResponse, }; use futures::{SinkExt, StreamExt}; -use lib::*; use rand::prelude::SliceRandom; -use serde_json::from_str; use std::collections::HashMap; -use std::{ - net::SocketAddr, - sync::{Arc, RwLock}, -}; -use tokio::sync::{broadcast::Sender, mpsc}; +use std::net::SocketAddr; +use std::sync::Arc; +use tokio::sync::mpsc; /// Establish the WebSocket connection pub async fn websocket_connection_handler( @@ -96,9 +89,6 @@ pub async fn websocket_on_connection(stream: WebSocket, state: Arc, ad .send((addr.clone(), message.clone())) .await .unwrap(); - websocket_message_handler(state.clone(), addr, message) - .await - .expect("Message Handler exploded!") } }); @@ -108,71 +98,3 @@ pub async fn websocket_on_connection(stream: WebSocket, state: Arc, ad _ = (&mut recv_task) => send_task.abort(), }; } - -/// Handle incoming messages over the WebSocket -pub async fn websocket_message_handler( - state: Arc, - addr: SocketAddr, - message: Message, -) -> Result<()> { - let tx = &state.broadcast_tx; - - match message { - Message::Text(text) => match text { - _new_game if let Ok(_new_game) = from_str::(&text) => { - tracing::debug!("New game request received."); - game_handle_new_game(_new_game, &state, tx, addr)?; - } - _ => { - tracing::debug!("Unhandled text message: {}", &text); - } - }, - Message::Binary(data) => { - tracing::debug!("Binary: {:?}", data) - } - Message::Close(_close_frame) => { - // websocket_handle_close(close_frame, &state, tx, addr)?; - } - Message::Pong(ping) => { - tracing::debug!("Pong received with: {:?}", ping); - } - Message::Ping(pong) => { - tracing::debug!("Pong received with: {:?}", pong); - } - } - - Ok(()) -} - -/// This runs when a NewGameRequest is received -fn game_handle_new_game( - new_game: NewGameRequest, - state: &Arc, - tx: &Sender, - addr: SocketAddr, -) -> Result<()> { - let manifest = NewGameManifest { - name: new_game.name, - host: state - .online_users - .read() - .unwrap() - .get(&addr) - .unwrap() - .clone(), - }; - tracing::debug!("Game Packs {:?}", new_game.packs); - - // create game - if let Ok(new_game_object) = Game::new(manifest) { - state - .games - .write() - .unwrap() - .insert(new_game_object.name.clone(), RwLock::new(new_game_object)); - tx.send(meta_games_browser_update(state))?; - tx.send(meta_server_summary_update(state))?; - } - - Ok(()) -}