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::mpsc::Sender;
|
||||||
use tokio::sync::{broadcast, mpsc};
|
use tokio::sync::{broadcast, mpsc};
|
||||||
use user_handler::UserHandlerMessage;
|
use user_handler::UserHandlerMessage;
|
||||||
|
pub mod game_handler;
|
||||||
pub mod message_handler;
|
pub mod message_handler;
|
||||||
pub mod user_handler;
|
pub mod user_handler;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
@ -363,6 +364,7 @@ pub struct AppState {
|
||||||
pub broadcast_tx: broadcast::Sender<String>,
|
pub broadcast_tx: broadcast::Sender<String>,
|
||||||
pub users_tx: mpsc::Sender<UserHandlerMessage>,
|
pub users_tx: mpsc::Sender<UserHandlerMessage>,
|
||||||
pub messages_tx: mpsc::Sender<(SocketAddr, Message)>,
|
pub messages_tx: mpsc::Sender<(SocketAddr, Message)>,
|
||||||
|
pub games_tx: mpsc::Sender<(SocketAddr, NewGameRequest)>,
|
||||||
pub first_names: Vec<String>,
|
pub first_names: Vec<String>,
|
||||||
pub last_names: Vec<String>,
|
pub last_names: Vec<String>,
|
||||||
pub reserved_names: RwLock<HashSet<String>>,
|
pub reserved_names: RwLock<HashSet<String>>,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::game_handler::*;
|
||||||
use crate::message_handler::*;
|
use crate::message_handler::*;
|
||||||
use crate::websocket::*;
|
use crate::websocket::*;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
@ -28,6 +29,7 @@ async fn main() -> Result<()> {
|
||||||
let (broadcast_tx, _rx) = broadcast::channel(100);
|
let (broadcast_tx, _rx) = broadcast::channel(100);
|
||||||
let (users_tx, mut users_rx) = mpsc::channel(100);
|
let (users_tx, mut users_rx) = mpsc::channel(100);
|
||||||
let (messages_tx, mut messages_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 first_names = load_names("data/first.txt")?;
|
||||||
let last_names = load_names("data/last.txt")?;
|
let last_names = load_names("data/last.txt")?;
|
||||||
let reserved_names = RwLock::new(HashSet::<String>::new());
|
let reserved_names = RwLock::new(HashSet::<String>::new());
|
||||||
|
@ -40,6 +42,7 @@ async fn main() -> Result<()> {
|
||||||
broadcast_tx,
|
broadcast_tx,
|
||||||
users_tx,
|
users_tx,
|
||||||
messages_tx,
|
messages_tx,
|
||||||
|
games_tx,
|
||||||
first_names,
|
first_names,
|
||||||
last_names,
|
last_names,
|
||||||
reserved_names,
|
reserved_names,
|
||||||
|
@ -50,6 +53,7 @@ async fn main() -> Result<()> {
|
||||||
games,
|
games,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Spawn task to handle incoming messages, also handles outging messages
|
||||||
let message_handler = MessageHandler::new(app_state.clone());
|
let message_handler = MessageHandler::new(app_state.clone());
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while let Some((addr, message)) = messages_rx.recv().await {
|
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());
|
let user_handler = UserHandler::new(app_state.clone());
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while let Some(message) = users_rx.recv().await {
|
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
|
// Router
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/websocket", get(websocket_connection_handler))
|
.route("/websocket", get(websocket_connection_handler))
|
||||||
|
|
|
@ -40,6 +40,9 @@ impl MessageHandler {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
tracing::debug!("passed login to user handler");
|
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),
|
_ => tracing::debug!("Unhandled text from {}", addr),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use crate::user_handler::*;
|
use crate::user_handler::*;
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use crate::Game;
|
|
||||||
use crate::NewGameManifest;
|
|
||||||
use crate::User;
|
use crate::User;
|
||||||
use anyhow::Result;
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{
|
extract::{
|
||||||
ws::{Message, WebSocket},
|
ws::{Message, WebSocket},
|
||||||
|
@ -12,15 +9,11 @@ use axum::{
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
use lib::*;
|
|
||||||
use rand::prelude::SliceRandom;
|
use rand::prelude::SliceRandom;
|
||||||
use serde_json::from_str;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::{
|
use std::net::SocketAddr;
|
||||||
net::SocketAddr,
|
use std::sync::Arc;
|
||||||
sync::{Arc, RwLock},
|
use tokio::sync::mpsc;
|
||||||
};
|
|
||||||
use tokio::sync::{broadcast::Sender, mpsc};
|
|
||||||
|
|
||||||
/// Establish the WebSocket connection
|
/// Establish the WebSocket connection
|
||||||
pub async fn websocket_connection_handler(
|
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()))
|
.send((addr.clone(), message.clone()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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(),
|
_ = (&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