From a1746f7c30519abc2f3a293a8f02cc0b2015804d Mon Sep 17 00:00:00 2001 From: Jomar Milan Date: Sun, 7 Jun 2026 19:31:19 -0700 Subject: Respond with hand data after handshake --- assets/session.js | 9 +++++++++ src/play.rs | 24 +++++++++++++++++++++--- src/session.rs | 6 +++--- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/assets/session.js b/assets/session.js index c607594..981cff1 100644 --- a/assets/session.js +++ b/assets/session.js @@ -25,6 +25,9 @@ websocket.addEventListener('message', (event) => { colorSelect.appendChild(selection); }); colorSelect.disabled = false; + } else if (Object.hasOwn(message, 'Hand')) { + const payload = message.Hand; + colorSelect.disabled = false; } }); @@ -33,5 +36,11 @@ websocket.addEventListener('close', () => { }); colorSelect.addEventListener('change', () => { + if (colorSelect.value === '') return; + colorSelect.disabled = true; + + websocket.send(JSON.stringify({ + "Color": colorSelect.value + })); }); \ No newline at end of file diff --git a/src/play.rs b/src/play.rs index e88ae7e..af5314a 100644 --- a/src/play.rs +++ b/src/play.rs @@ -3,15 +3,18 @@ use axum::extract::ws::{Message, Utf8Bytes, WebSocket}; use serde::{Deserialize, Serialize}; use std::error::Error; use std::sync::Arc; +use crate::session::HandObject; #[derive(Deserialize)] enum IncomingPlayMessage { Initialize { id: String }, + Color(String), } #[derive(Serialize)] enum OutgoingPlayMessage<'a> { Initialize { colors: Vec<&'a String> }, + Hand(Vec<&'a HandObject>), } struct PlayState { @@ -22,7 +25,7 @@ pub async fn handle_play(mut socket: WebSocket, app_state: Arc) { let mut play_state = PlayState { id: None }; while let Some(msg) = socket.recv().await { - let mut process = async |msg: Result| -> Result<(), Box> { + let mut process = async |msg: Result, play_state: &mut PlayState| -> Result<(), Box> { let msg: IncomingPlayMessage = serde_json::from_str(msg?.to_text()?)?; match msg { IncomingPlayMessage::Initialize { id } => { @@ -49,13 +52,28 @@ pub async fn handle_play(mut socket: WebSocket, app_state: Arc) { &response, )?))) .await?; - } + }, + IncomingPlayMessage::Color(color) => { + let hand: Vec = { + let sessions = app_state.sessions.lock().unwrap(); + let session = sessions.get(play_state.id.as_ref().ok_or("No session was joined")?).ok_or("Session did not exist")?; + + (*session.hands.get(&color).ok_or("No player seated by that color")?).clone() + }; + + let response = OutgoingPlayMessage::Hand(hand.iter().collect()); + socket + .send(Message::Text(Utf8Bytes::from(serde_json::to_string( + &response, + )?))) + .await?; + }, } Ok(()) }; if let Ok(Message::Text(_)) = msg - && let Err(err) = process(msg).await + && let Err(err) = process(msg, &mut play_state).await { eprintln!( "Encountered an error while handling a message from a player: {}", diff --git a/src/session.rs b/src/session.rs index c105af3..06ec483 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,4 +1,4 @@ -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; pub struct Session { @@ -9,7 +9,7 @@ pub struct Session { // TODO: The values on these variants will be used in the future and there will be more variants. // Once this happens, the dead_code lint should no longer be suppressed. -#[derive(Deserialize)] +#[derive(Clone, Serialize, Deserialize)] #[allow(dead_code)] pub enum HandObject { CustomDeck(CustomDeck), @@ -17,7 +17,7 @@ pub enum HandObject { // TODO: These fields will be used in the future. When they are, the dead_code lint should no longer // be suppressed. -#[derive(Deserialize)] +#[derive(Clone, Serialize, Deserialize)] #[allow(dead_code)] pub struct CustomDeck { /// The path/URL of the face cardsheet. -- cgit v1.2.3