use crate::AppState; use crate::CAHd_game::*; use axum::{ extract::{ ws::{Message, WebSocket, WebSocketUpgrade}, State, }, response::IntoResponse, }; use futures::{sink::SinkExt, stream::StreamExt}; use serde::Deserialize; use std::sync::Arc; /// New game request structure #[derive(Debug, Deserialize)] pub struct NewGameRequest { /// Game name pub name: String, /// Game host pub host: CAHPlayer, /// Chosen packs pub packs: Vec, } /// Game join request structure pub struct GameJoinRequest { /// Game id pub id: u8, // increase later /// Game password pub password: String, /// Player info pub player: CAHPlayer, } pub async fn websocket_handler( ws: WebSocketUpgrade, State(state): State>, ) -> impl IntoResponse { ws.on_upgrade(|socket| websocket(socket, state)) } pub async fn websocket(stream: WebSocket, state: Arc) { // By splitting, we can send and receive at the same time. let (mut sender, mut receiver) = stream.split(); let _greeting = sender .send(Message::Text(format!( "Greetings! \n\ {:#?} Card packs loaded\n\ {:#?} Current active games", state.all_cards.lock().unwrap().len(), state.games.lock().unwrap().len(), ))) .await; // Loop until a text message is found. while let Some(Ok(message)) = receiver.next().await { match message { Message::Text(text) => { tracing::debug!("Text: {}", text); if let Ok(new_game) = serde_json::from_str::(&text) { tracing::debug!("{:#?}", &new_game); state.games.lock().unwrap().push(CAHGame::new(new_game).expect("error creating game")); } else { // just echo let _res = sender.send(Message::Text(text)).await; } } Message::Binary(data) => { tracing::debug!("Binary: {:?}", data) } Message::Close(c) => { if let Some(cf) = c { tracing::debug!( "Close received with code: {} and reason: {}", cf.code, cf.reason ) } else { tracing::debug!("close received without close frame") } } Message::Pong(ping) => { tracing::debug!("Pong received with: {:?}", ping); } Message::Ping(pong) => { tracing::debug!("Pong received with: {:?}", pong); } } } }