make game handler

This commit is contained in:
Adam 2024-08-08 05:29:32 -04:00
parent de77007e01
commit 2ab03d64e6
5 changed files with 74 additions and 81 deletions

View file

@ -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<AppState>,
}
impl GameHandler {
pub fn new(state: Arc<AppState>) -> 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();
}
}
}

View file

@ -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<String>,
pub users_tx: mpsc::Sender<UserHandlerMessage>,
pub messages_tx: mpsc::Sender<(SocketAddr, Message)>,
pub games_tx: mpsc::Sender<(SocketAddr, NewGameRequest)>,
pub first_names: Vec<String>,
pub last_names: Vec<String>,
pub reserved_names: RwLock<HashSet<String>>,

View file

@ -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::<String>::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))

View file

@ -40,6 +40,9 @@ impl MessageHandler {
.unwrap();
tracing::debug!("passed login to user handler");
}
_new_game if let Ok(new_game) = from_str::<NewGameRequest>(&text) => {
self.state.games_tx.send((addr, new_game)).await.unwrap();
}
_ => tracing::debug!("Unhandled text from {}", addr),
},

View file

@ -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<AppState>, 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<AppState>, ad
_ = (&mut recv_task) => send_task.abort(),
};
}
/// Handle incoming messages over the WebSocket
pub async fn websocket_message_handler(
state: Arc<AppState>,
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::<NewGameRequest>(&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<AppState>,
tx: &Sender<String>,
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(())
}