diff --git a/protobuf/game.proto b/protobuf/game.proto index d588ec5..d12531d 100644 --- a/protobuf/game.proto +++ b/protobuf/game.proto @@ -48,6 +48,7 @@ message GameStatus { message Card { CardKind kind = 1; bool visible = 2; + string uuid = 3; } message Pile { repeated Card cards = 1; diff --git a/server/Cargo.toml b/server/Cargo.toml index 8f7cf86..2d149f5 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" # Utilities rand = "0.8" image = "0.23" -uuid = {version = "0.8", features = ["v4"]} +uuid = {version = "0.8", features = ["v4", "serde"]} tokio = {version = "1", features = ["full"]} tokio-stream = "0.1" server_client = {git = "https://github.com/Mr-Llama-s-Wonderful-Soundboard/server_client.git", branch = "main", features = ["tokio1"]} diff --git a/server/src/games/config.rs b/server/src/games/config.rs index 778ca92..e13c4b3 100644 --- a/server/src/games/config.rs +++ b/server/src/games/config.rs @@ -1,5 +1,6 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use uuid::Uuid; use std::io::Write; use std::path::PathBuf; use std::{collections::HashMap, fs::File, io::ErrorKind, path::Path}; @@ -38,31 +39,6 @@ pub struct Pile { pub other: HashMap, } -impl Pile { - pub fn from_rhai_map(map: rhai::Map) -> Result> { - // println!("{}", map.get("cards") - // .ok_or("Pile doesn't have property cards")?.type_name()); - let cards: Vec = - rhai::serde::from_dynamic(map.get("cards").ok_or("Pile doesn't have property cards")?)?; - - let other_fallible: Vec>> = - map.into_iter() - .map(|(x, v)| (x.to_string(), v)) - .filter(|(s, _)| s != &"cards".to_string()) - .map(|(k, v)| Ok((k, rhai::serde::from_dynamic::(&v)?))) - .collect(); - - let mut other = HashMap::new(); - - for x in other_fallible { - let (k, v) = x?; - other.insert(k, v); - } - - Ok(Self { cards, other }) - } -} - impl Config { pub fn load + std::fmt::Debug>(file: P) -> Self { let s: Config = serde_json::from_reader(std::fs::File::open(&file).unwrap()) diff --git a/server/src/games/mod.rs b/server/src/games/mod.rs index c68e71a..d7bebc8 100644 --- a/server/src/games/mod.rs +++ b/server/src/games/mod.rs @@ -4,7 +4,7 @@ mod config; mod run; pub use config::{Pile, Config}; -pub use run::{CardId, CardIdx, PileKind, RunningGame}; +pub use run::{CardId, CardIdx, PileKind, RunningGame, RunningPile}; use uuid::Uuid; #[derive(Clone)] diff --git a/server/src/games/run.rs b/server/src/games/run.rs index 6820bed..e5a216a 100644 --- a/server/src/games/run.rs +++ b/server/src/games/run.rs @@ -5,7 +5,6 @@ use rhai::{ use uuid::Uuid; use std::collections::HashMap; - use super::config::{Config, Pile}; mod engine; @@ -13,14 +12,16 @@ use engine::setup_engine; mod functions; use functions::Functions; mod types; -pub use types::{CardId, CardIdx, PileKind}; +pub use types::{CardId, CardIdx, PileKind, RunningPile}; use types::{Data, Player, RhaiResult}; + + pub struct RunningGame { #[allow(unused)] // TODO Remove name: String, - pub piles: HashMap, - pub player_piles: Vec>, + pub piles: HashMap, + pub player_piles: Vec>, functions: Functions, current_player: Player, data: HashMap, @@ -55,8 +56,8 @@ impl RunningGame { let engine = setup_engine(); let setup = Func::<(Dynamic,), Dynamic>::create_from_ast(engine, ast, "setup"); - let piles = conf.piles.clone(); - let player_piles = vec![conf.player_piles.clone(); current_players.len()]; + let piles = conf.piles.clone().into_iter().map(|(k,v)| (k, v.into())).collect(); + let player_piles = vec![conf.player_piles.clone().into_iter().map(|(k,v)| (k, v.into())).collect(); current_players.len()]; let Data { piles, player_piles, @@ -76,8 +77,8 @@ impl RunningGame { log::info!("Players in game {}: {:?}", name, players); Self { name, - piles, - player_piles, + piles: piles, + player_piles: player_piles, functions, current_player: Player::new(0, current_players.len() as u32), data: other, diff --git a/server/src/games/run/engine.rs b/server/src/games/run/engine.rs index 6252b72..df4feb7 100644 --- a/server/src/games/run/engine.rs +++ b/server/src/games/run/engine.rs @@ -7,8 +7,7 @@ use rhai::{ use std::fmt::{Debug, Display}; use super::{ - types::{CardId, Data, Player, RhaiResult}, - Pile, + types::{CardId, Data, Player, RhaiResult, RunningPile}, }; // TODO Write somekind of documentation on functions available & stuff pub fn setup_engine() -> Engine { @@ -59,7 +58,7 @@ pub fn setup_engine() -> Engine { } fn shuffle_pile(pile: Map) -> Result> { - let mut pile = Pile::from_rhai_map(pile)?; + let mut pile = RunningPile::from_rhai_map(pile)?; let mut rng = rand::thread_rng(); pile.cards.shuffle(&mut rng); to_dynamic(pile) diff --git a/server/src/games/run/types.rs b/server/src/games/run/types.rs index 6ff1ce5..a41b6db 100644 --- a/server/src/games/run/types.rs +++ b/server/src/games/run/types.rs @@ -1,5 +1,6 @@ use rhai::{Dynamic, EvalAltResult}; use serde::{Deserialize, Serialize}; +use uuid::Uuid; use std::collections::HashMap; use std::fmt::Display; @@ -116,8 +117,8 @@ impl Display for CardId { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Data { - pub piles: HashMap, - pub player_piles: Vec>, + pub piles: HashMap, + pub player_piles: Vec>, pub players: u32, #[serde(flatten)] pub other: HashMap, @@ -125,8 +126,8 @@ pub struct Data { impl Data { pub fn new( - piles: HashMap, - player_piles: Vec>, + piles: HashMap, + player_piles: Vec>, players: u32, ) -> Self { Self { @@ -137,3 +138,43 @@ impl Data { } } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RunningPile { + pub cards: Vec<(String, Uuid)>, + pub other: HashMap, +} + +impl From for RunningPile { + fn from(p: Pile) -> Self { + Self { + cards: p.cards.into_iter().map(|x| (x, Uuid::new_v4())).collect(), + other: p.other + } + } +} + +impl RunningPile { + pub fn from_rhai_map(map: rhai::Map) -> Result> { + // println!("{}", map.get("cards") + // .ok_or("Pile doesn't have property cards")?.type_name()); + let cards: Vec<(String, Uuid)> = + rhai::serde::from_dynamic(map.get("cards").ok_or("Pile doesn't have property cards")?)?; + + let other_fallible: Vec>> = + map.into_iter() + .map(|(x, v)| (x.to_string(), v)) + .filter(|(s, _)| s != &"cards".to_string()) + .map(|(k, v)| Ok((k, rhai::serde::from_dynamic::(&v)?))) + .collect(); + + let mut other = HashMap::new(); + + for x in other_fallible { + let (k, v) = x?; + other.insert(k, v); + } + + Ok(Self { cards, other }) + } +} diff --git a/server/src/server/game.rs b/server/src/server/game.rs index a93d91b..3c2df3f 100644 --- a/server/src/server/game.rs +++ b/server/src/server/game.rs @@ -3,10 +3,7 @@ use super::{ socket_manager::SocketManager, ServiceData, }; -use crate::{ - games::{CardId, CardIdx, Pile, PileKind}, - server::protos::protocol::server_client_packet::Data, -}; +use crate::{games::{CardId, CardIdx, PileKind, RunningPile}, server::protos::protocol::server_client_packet::Data}; use anyhow::{anyhow, Result}; pub(super) async fn get_status(data: &mut ServiceData) -> Result { @@ -40,7 +37,7 @@ pub(super) async fn get_status(data: &mut ServiceData) -> Result { .piles .iter() .map(|(k, v)| (k.clone(), v.clone())) - .map(|(k, v): (String, Pile)| { + .map(|(k, v): (String, RunningPile)| { ( k, super::protos::game::game_status::Pile { @@ -48,8 +45,9 @@ pub(super) async fn get_status(data: &mut ServiceData) -> Result { .cards .into_iter() .map(|c| super::protos::game::game_status::Card { - kind: Some(CardKind { kind: c }), + kind: Some(CardKind { kind: c.0 }), visible: true, + uuid: c.1.to_string() }) .collect(), }, @@ -72,8 +70,9 @@ pub(super) async fn get_status(data: &mut ServiceData) -> Result { .cards .into_iter() .map(|x| super::protos::game::game_status::Card { - kind: Some(CardKind { kind: x }), + kind: Some(CardKind { kind: x.0 }), visible: true, + uuid: x.1.to_string() }) .collect(), }, diff --git a/server/src/server/protos/game.rs b/server/src/server/protos/game.rs index 318a143..f53dbf7 100644 --- a/server/src/server/protos/game.rs +++ b/server/src/server/protos/game.rs @@ -82,6 +82,8 @@ pub mod game_status { pub kind: ::core::option::Option, #[prost(bool, tag="2")] pub visible: bool, + #[prost(string, tag="3")] + pub uuid: ::prost::alloc::string::String, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Pile {