diff --git a/protobuf/game.proto b/protobuf/game.proto index d12531d..6e39cda 100644 --- a/protobuf/game.proto +++ b/protobuf/game.proto @@ -52,6 +52,7 @@ message GameStatus { } message Pile { repeated Card cards = 1; + bool faceDown = 2; } message Piles { map piles = 1; diff --git a/server/schema/game-config.json b/server/schema/game-config.json index 5dda872..c6e1ac6 100644 --- a/server/schema/game-config.json +++ b/server/schema/game-config.json @@ -80,6 +80,10 @@ "items": { "type": "string" } + }, + "face_down": { + "default": false, + "type": "boolean" } }, "additionalProperties": true diff --git a/server/src/games/config.rs b/server/src/games/config.rs index e13c4b3..cd873fe 100644 --- a/server/src/games/config.rs +++ b/server/src/games/config.rs @@ -1,6 +1,5 @@ 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}; @@ -35,6 +34,8 @@ pub struct Card { pub struct Pile { #[serde(default)] pub cards: Vec, + #[serde(default)] + pub face_down: bool, #[serde(flatten)] pub other: HashMap, } diff --git a/server/src/games/run/engine.rs b/server/src/games/run/engine.rs index df4feb7..9838bc6 100644 --- a/server/src/games/run/engine.rs +++ b/server/src/games/run/engine.rs @@ -6,6 +6,8 @@ use rhai::{ use std::fmt::{Debug, Display}; +use crate::games::run::types::Card; + use super::{ types::{CardId, Data, Player, RhaiResult, RunningPile}, }; @@ -33,6 +35,16 @@ pub fn setup_engine() -> Engine { .register_fn("==", |a: Player, b: Player| a.num == b.num) .register_fn("==", |a: Player, b: i64| a.num == b as u32) .register_fn("==", |a: i64, b: Player| b.num == a as u32); + + engine + .register_type::() + .register_get("kind", Card::get_kind) + .register_get("uuid", Card::get_uuid) + .register_fn("to_string", |c: &mut Card| c.to_string()) + .register_fn("print", |c: &mut Card| c.to_string()) + .register_fn("debug", |c: &mut Card| format!("{:?}", c)) + .register_fn("+", |s: &str, c: Card| format!("{}{}", s, c)) + .register_fn("+", |c: Card, s: &str| c.to_string().push_str(s)); engine .register_type::() // TODO add constructor for CardId diff --git a/server/src/games/run/types.rs b/server/src/games/run/types.rs index a41b6db..0753155 100644 --- a/server/src/games/run/types.rs +++ b/server/src/games/run/types.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; use std::collections::HashMap; -use std::fmt::Display; +use std::fmt::{Debug, Display}; use super::engine::rhai_error; use super::Pile; @@ -139,17 +139,47 @@ impl Data { } } +#[derive(Serialize, Deserialize, Clone)] +pub struct Card { + pub kind: String, + pub uuid: Uuid +} + +impl Card { + pub fn get_kind(&mut self) -> String { + self.kind.clone() + } + + pub fn get_uuid(&mut self) -> Uuid { + self.uuid + } +} + +impl Display for Card { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Card {}", self.kind) + } +} + +impl Debug for Card { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Card {} [{}]", self.kind, self.uuid) + } +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RunningPile { - pub cards: Vec<(String, Uuid)>, + pub cards: Vec, + pub face_down: bool, 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 + cards: p.cards.into_iter().map(|kind| Card {kind, uuid: Uuid::new_v4()}).collect(), + other: p.other, + face_down: p.face_down, } } } @@ -158,8 +188,10 @@ 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)> = + let cards: Vec = rhai::serde::from_dynamic(map.get("cards").ok_or("Pile doesn't have property cards")?)?; + + let face_down: bool = rhai::serde::from_dynamic(map.get("face_down").ok_or("Pile doesn't have property face_down")?)?; let other_fallible: Vec>> = map.into_iter() @@ -175,6 +207,6 @@ impl RunningPile { other.insert(k, v); } - Ok(Self { cards, other }) + Ok(Self { cards, other, face_down }) } } diff --git a/server/src/server/game.rs b/server/src/server/game.rs index 3c2df3f..9be6621 100644 --- a/server/src/server/game.rs +++ b/server/src/server/game.rs @@ -3,7 +3,10 @@ use super::{ socket_manager::SocketManager, ServiceData, }; -use crate::{games::{CardId, CardIdx, PileKind, RunningPile}, 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 { @@ -45,11 +48,12 @@ 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.0 }), + kind: Some(CardKind { kind: c.kind }), visible: true, - uuid: c.1.to_string() + uuid: c.uuid.to_string(), }) .collect(), + face_down: v.face_down, }, ) }) @@ -70,11 +74,12 @@ 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.0 }), + kind: Some(CardKind { kind: x.kind }), visible: true, - uuid: x.1.to_string() + uuid: x.uuid.to_string(), }) .collect(), + face_down: v.face_down, }, ) }) diff --git a/server/src/server/protos/game.rs b/server/src/server/protos/game.rs index f53dbf7..c80a2f4 100644 --- a/server/src/server/protos/game.rs +++ b/server/src/server/protos/game.rs @@ -89,6 +89,8 @@ pub mod game_status { pub struct Pile { #[prost(message, repeated, tag="1")] pub cards: ::prost::alloc::vec::Vec, + #[prost(bool, tag="2")] + pub face_down: bool, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Piles { diff --git a/unity/Assets/Scripts/grpc/Game.cs b/unity/Assets/Scripts/grpc/Game.cs index 3a79e37..d8bb9cf 100644 --- a/unity/Assets/Scripts/grpc/Game.cs +++ b/unity/Assets/Scripts/grpc/Game.cs @@ -33,16 +33,17 @@ namespace Game { "CgVvd25lZBgBIAEoDUgAEigKBmNvbW1vbhgCIAEoCzIWLmdvb2dsZS5wcm90", "b2J1Zi5FbXB0eUgAQgYKBGtpbmQiYAoGQ2FyZElkEiAKCHBpbGVLaW5kGAEg", "ASgLMg4uZ2FtZS5QaWxlS2luZBIQCghwaWxlTmFtZRgCIAEoCRIiCgljYXJk", - "SW5kZXgYAyABKAsyDy5nYW1lLkNhcmRJbmRleCKLAwoKR2FtZVN0YXR1cxIr", + "SW5kZXgYAyABKAsyDy5nYW1lLkNhcmRJbmRleCKdAwoKR2FtZVN0YXR1cxIr", "Cgtjb21tb25QaWxlcxgBIAEoCzIWLmdhbWUuR2FtZVN0YXR1cy5QaWxlcxIr", "CgtwbGF5ZXJQaWxlcxgCIAMoCzIWLmdhbWUuR2FtZVN0YXR1cy5QaWxlcxIb", "CgVuYW1lcxgDIAMoCzIMLmNvbW1vbi5OYW1lEhMKC2N1cnJlbnRUdXJuGAQg", "ASgNGkMKBENhcmQSHAoEa2luZBgBIAEoCzIOLmdhbWUuQ2FyZEtpbmQSDwoH", - "dmlzaWJsZRgCIAEoCBIMCgR1dWlkGAMgASgJGiwKBFBpbGUSJAoFY2FyZHMY", - "ASADKAsyFS5nYW1lLkdhbWVTdGF0dXMuQ2FyZBp+CgVQaWxlcxIwCgVwaWxl", - "cxgBIAMoCzIhLmdhbWUuR2FtZVN0YXR1cy5QaWxlcy5QaWxlc0VudHJ5GkMK", - "ClBpbGVzRW50cnkSCwoDa2V5GAEgASgJEiQKBXZhbHVlGAIgASgLMhUuZ2Ft", - "ZS5HYW1lU3RhdHVzLlBpbGU6AjgBYgZwcm90bzM=")); + "dmlzaWJsZRgCIAEoCBIMCgR1dWlkGAMgASgJGj4KBFBpbGUSJAoFY2FyZHMY", + "ASADKAsyFS5nYW1lLkdhbWVTdGF0dXMuQ2FyZBIQCghmYWNlRG93bhgCIAEo", + "CBp+CgVQaWxlcxIwCgVwaWxlcxgBIAMoCzIhLmdhbWUuR2FtZVN0YXR1cy5Q", + "aWxlcy5QaWxlc0VudHJ5GkMKClBpbGVzRW50cnkSCwoDa2V5GAEgASgJEiQK", + "BXZhbHVlGAIgASgLMhUuZ2FtZS5HYW1lU3RhdHVzLlBpbGU6AjgBYgZwcm90", + "bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, global::Common.CommonReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -52,7 +53,7 @@ namespace Game { new pbr::GeneratedClrTypeInfo(typeof(global::Game.PileKind), global::Game.PileKind.Parser, new[]{ "Owned", "Common" }, new[]{ "Kind" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.CardId), global::Game.CardId.Parser, new[]{ "PileKind", "PileName", "CardIndex" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.GameStatus), global::Game.GameStatus.Parser, new[]{ "CommonPiles", "PlayerPiles", "Names", "CurrentTurn" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Game.GameStatus.Types.Card), global::Game.GameStatus.Types.Card.Parser, new[]{ "Kind", "Visible", "Uuid" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Game.GameStatus.Types.Pile), global::Game.GameStatus.Types.Pile.Parser, new[]{ "Cards" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Game.GameStatus.Types.Pile), global::Game.GameStatus.Types.Pile.Parser, new[]{ "Cards", "FaceDown" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.GameStatus.Types.Piles), global::Game.GameStatus.Types.Piles.Parser, new[]{ "Piles_" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, })}) })); } @@ -1852,6 +1853,7 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Pile(Pile other) : this() { cards_ = other.cards_.Clone(); + faceDown_ = other.faceDown_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -1870,6 +1872,17 @@ namespace Game { get { return cards_; } } + /// Field number for the "faceDown" field. + public const int FaceDownFieldNumber = 2; + private bool faceDown_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool FaceDown { + get { return faceDown_; } + set { + faceDown_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as Pile); @@ -1884,6 +1897,7 @@ namespace Game { return true; } if(!cards_.Equals(other.cards_)) return false; + if (FaceDown != other.FaceDown) return false; return Equals(_unknownFields, other._unknownFields); } @@ -1891,6 +1905,7 @@ namespace Game { public override int GetHashCode() { int hash = 1; hash ^= cards_.GetHashCode(); + if (FaceDown != false) hash ^= FaceDown.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -1908,6 +1923,10 @@ namespace Game { output.WriteRawMessage(this); #else cards_.WriteTo(output, _repeated_cards_codec); + if (FaceDown != false) { + output.WriteRawTag(16); + output.WriteBool(FaceDown); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -1918,6 +1937,10 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { cards_.WriteTo(ref output, _repeated_cards_codec); + if (FaceDown != false) { + output.WriteRawTag(16); + output.WriteBool(FaceDown); + } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); } @@ -1928,6 +1951,9 @@ namespace Game { public int CalculateSize() { int size = 0; size += cards_.CalculateSize(_repeated_cards_codec); + if (FaceDown != false) { + size += 1 + 1; + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -1940,6 +1966,9 @@ namespace Game { return; } cards_.Add(other.cards_); + if (other.FaceDown != false) { + FaceDown = other.FaceDown; + } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1958,6 +1987,10 @@ namespace Game { cards_.AddEntriesFrom(input, _repeated_cards_codec); break; } + case 16: { + FaceDown = input.ReadBool(); + break; + } } } #endif @@ -1976,6 +2009,10 @@ namespace Game { cards_.AddEntriesFrom(ref input, _repeated_cards_codec); break; } + case 16: { + FaceDown = input.ReadBool(); + break; + } } } }