make game handler
This commit is contained in:
parent
de77007e01
commit
2ab03d64e6
5 changed files with 74 additions and 81 deletions
51
server/src/game_handler.rs
Normal file
51
server/src/game_handler.rs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>>,
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue