Browse Source

Implement loading the card (front & back)

new_protocol
ThePerkinrex 5 years ago
parent
commit
9d07c53778
No known key found for this signature in database GPG Key ID: 1F45A7C4BFB41607
  1. 12
      server/schema/game-config.json
  2. 17
      server/src/games/config.rs
  3. 14
      server/src/games/mod.rs
  4. 4
      server/src/games/run.rs
  5. 4
      server/src/server.rs
  6. 45
      server/src/server/game.rs

12
server/schema/game-config.json

@ -23,6 +23,12 @@
"$ref": "#/definitions/Card" "$ref": "#/definitions/Card"
} }
}, },
"default_back": {
"type": [
"string",
"null"
]
},
"name": { "name": {
"type": "string" "type": "string"
}, },
@ -53,6 +59,12 @@
"image" "image"
], ],
"properties": { "properties": {
"back_image": {
"type": [
"string",
"null"
]
},
"image": { "image": {
"type": "string" "type": "string"
} }

17
server/src/games/config.rs

@ -12,6 +12,7 @@ pub struct Config {
pub authors: Vec<String>, pub authors: Vec<String>,
pub script: String, pub script: String,
pub available_cards: HashMap<String, Card>, pub available_cards: HashMap<String, Card>,
pub default_back: Option<PathBuf>,
pub piles: HashMap<String, Pile>, pub piles: HashMap<String, Pile>,
pub player_piles: HashMap<String, Pile>, pub player_piles: HashMap<String, Pile>,
} }
@ -23,6 +24,7 @@ fn default_version() -> String {
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)] #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
pub struct Card { pub struct Card {
pub image: PathBuf, pub image: PathBuf,
pub back_image: Option<PathBuf>,
#[serde(flatten)] #[serde(flatten)]
pub other: HashMap<String, serde_json::Value>, pub other: HashMap<String, serde_json::Value>,
} }
@ -62,7 +64,7 @@ impl Pile {
impl Config { impl Config {
pub fn load<P: AsRef<std::path::Path> + std::fmt::Debug>(file: P) -> Self { pub fn load<P: AsRef<std::path::Path> + std::fmt::Debug>(file: P) -> Self {
serde_json::from_reader(std::fs::File::open(&file).unwrap()) let s: Config = serde_json::from_reader(std::fs::File::open(&file).unwrap())
.map_err(|e| { .map_err(|e| {
log::error!( log::error!(
"Malformed game defintion file @ {}", "Malformed game defintion file @ {}",
@ -71,12 +73,21 @@ impl Config {
log::error!("JSON Error: {}", e); log::error!("JSON Error: {}", e);
panic!() panic!()
}) })
.unwrap() .unwrap();
if s.default_back.is_none() {
for (name, card) in &s.available_cards {
if card.back_image.is_none() {
panic!("Card {} from game {} can not have a default back if there's not default back", name, s.name)
}
}
}
s
} }
} }
pub fn setup() { pub fn setup() {
if cfg!(debug_assertions) { #[cfg(debug_assertions)]
{
if let Ok(e) = std::env::var("CARGO_MANIFEST_DIR") { if let Ok(e) = std::env::var("CARGO_MANIFEST_DIR") {
std::fs::write( std::fs::write(
AsRef::<std::path::Path>::as_ref(&e) AsRef::<std::path::Path>::as_ref(&e)

14
server/src/games/mod.rs

@ -56,10 +56,16 @@ impl Game {
) )
} }
pub fn get_card_path(&self, image: &str) -> std::path::PathBuf { pub fn get_card_paths(&self, image: &str) -> (std::path::PathBuf, std::path::PathBuf) {
self.folder let card = &self.conf.available_cards[image];
.join(&self.conf.available_cards[image].image) let front = self.folder.join(&card.image).to_path_buf();
.to_path_buf() let back = self.folder.join(
&card
.back_image
.as_ref()
.unwrap_or(self.conf.default_back.as_ref().unwrap()),
);
(front, back)
} }
} }

4
server/src/games/run.rs

@ -85,6 +85,10 @@ impl RunningGame {
// Self {setup: Box::new(Func::<(Vec<Pile>, Vec<Vec<Pile>>), ()>::create_from_ast(engine, ast, "setup"))} // Self {setup: Box::new(Func::<(Vec<Pile>, Vec<Vec<Pile>>), ()>::create_from_ast(engine, ast, "setup"))}
} }
pub fn get_player_for_uuid(&self, user: &Uuid) -> Option<u32> {
self.players.get(user).copied()
}
fn data_as_dynamic(&self) -> RhaiResult<Dynamic> { fn data_as_dynamic(&self) -> RhaiResult<Dynamic> {
to_dynamic(Data { to_dynamic(Data {
piles: self.piles.clone(), piles: self.piles.clone(),

4
server/src/server.rs

@ -32,8 +32,8 @@ pub async fn start(
voting: voting.clone(), voting: voting.clone(),
running_games: running_games.clone(), running_games: running_games.clone(),
}; };
let lobby = LobbyService::new(pool.clone().await, voting, games, running_games.clone()); let lobby = LobbyService::new(pool.clone().await, voting, games.clone(), running_games.clone());
let game = GameService::new(pool, running_games); let game = GameService::new(pool, games, running_games);
Server::builder() Server::builder()
.add_service(ConnectionServer::new(connection)) .add_service(ConnectionServer::new(connection))

45
server/src/server/game.rs

@ -1,8 +1,9 @@
use crate::db;
use crate::games::RunningGame; use crate::games::RunningGame;
use crate::{db, games::Game};
use super::grpc::game::game_server; use super::{client_id, grpc::game::{CardKind, Image, game_server}};
pub use game_server::GameServer; pub use game_server::GameServer;
use tonic::{Response, Status};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
@ -11,17 +12,20 @@ use tokio::sync::RwLock;
pub struct GameService { pub struct GameService {
conn: RwLock<db::DbClient>, conn: RwLock<db::DbClient>,
games: Arc<Vec<Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>, running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>,
} }
impl GameService { impl GameService {
pub fn new( pub fn new(
conn: db::DbClient, conn: db::DbClient,
games: Arc<Vec<Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>, running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>,
) -> Self { ) -> Self {
Self { Self {
conn: RwLock::new(conn), conn: RwLock::new(conn),
running_games, running_games,
games,
} }
} }
} }
@ -30,15 +34,44 @@ impl GameService {
impl game_server::Game for GameService { impl game_server::Game for GameService {
async fn get_card_image( async fn get_card_image(
&self, &self,
request: tonic::Request<super::grpc::game::CardKind>, request: tonic::Request<CardKind>,
) -> Result<tonic::Response<super::grpc::game::Image>, tonic::Status> { ) -> Result<tonic::Response<Image>, Status> {
todo!() let uuid = client_id::get(request.metadata()).map_err(|x| match x {
client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?;
let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
Some(l) => l,
None => return Err(Status::failed_precondition("User isn't in a lobby")),
};
let game_id = match self.running_games.read().await.get(&lobby) {
Some(x) => x.read().await.0,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
}
};
let game = &self.games[game_id as usize];
let (face, back) = game.get_card_paths(&request.into_inner().kind);
let mut face_buf = Vec::new();
image::open(&face)
.expect(&format!("Error loading the image in {:?}", face))
.write_to(&mut face_buf, image::ImageOutputFormat::Png)
.unwrap();
let mut back_buf = Vec::new();
image::open(&back)
.expect(&format!("Error loading the image in {:?}", back))
.write_to(&mut back_buf, image::ImageOutputFormat::Png)
.unwrap();
Ok(Response::new(Image { face: face_buf, back: back_buf }))
} }
async fn on_click( async fn on_click(
&self, &self,
request: tonic::Request<super::grpc::game::CardId>, request: tonic::Request<super::grpc::game::CardId>,
) -> Result<tonic::Response<()>, tonic::Status> { ) -> Result<tonic::Response<()>, Status> {
todo!() todo!()
} }
} }

Loading…
Cancel
Save