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"
}
},
"default_back": {
"type": [
"string",
"null"
]
},
"name": {
"type": "string"
},
@ -53,6 +59,12 @@
"image"
],
"properties": {
"back_image": {
"type": [
"string",
"null"
]
},
"image": {
"type": "string"
}

17
server/src/games/config.rs

@ -12,6 +12,7 @@ pub struct Config {
pub authors: Vec<String>,
pub script: String,
pub available_cards: HashMap<String, Card>,
pub default_back: Option<PathBuf>,
pub piles: HashMap<String, Pile>,
pub player_piles: HashMap<String, Pile>,
}
@ -23,6 +24,7 @@ fn default_version() -> String {
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone)]
pub struct Card {
pub image: PathBuf,
pub back_image: Option<PathBuf>,
#[serde(flatten)]
pub other: HashMap<String, serde_json::Value>,
}
@ -62,7 +64,7 @@ impl Pile {
impl Config {
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| {
log::error!(
"Malformed game defintion file @ {}",
@ -71,12 +73,21 @@ impl Config {
log::error!("JSON Error: {}", e);
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() {
if cfg!(debug_assertions) {
#[cfg(debug_assertions)]
{
if let Ok(e) = std::env::var("CARGO_MANIFEST_DIR") {
std::fs::write(
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 {
self.folder
.join(&self.conf.available_cards[image].image)
.to_path_buf()
pub fn get_card_paths(&self, image: &str) -> (std::path::PathBuf, std::path::PathBuf) {
let card = &self.conf.available_cards[image];
let front = self.folder.join(&card.image).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"))}
}
pub fn get_player_for_uuid(&self, user: &Uuid) -> Option<u32> {
self.players.get(user).copied()
}
fn data_as_dynamic(&self) -> RhaiResult<Dynamic> {
to_dynamic(Data {
piles: self.piles.clone(),

4
server/src/server.rs

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

45
server/src/server/game.rs

@ -1,8 +1,9 @@
use crate::db;
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;
use tonic::{Response, Status};
use std::collections::HashMap;
use std::sync::Arc;
@ -11,17 +12,20 @@ use tokio::sync::RwLock;
pub struct GameService {
conn: RwLock<db::DbClient>,
games: Arc<Vec<Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>,
}
impl GameService {
pub fn new(
conn: db::DbClient,
games: Arc<Vec<Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>,
) -> Self {
Self {
conn: RwLock::new(conn),
running_games,
games,
}
}
}
@ -30,15 +34,44 @@ impl GameService {
impl game_server::Game for GameService {
async fn get_card_image(
&self,
request: tonic::Request<super::grpc::game::CardKind>,
) -> Result<tonic::Response<super::grpc::game::Image>, tonic::Status> {
todo!()
request: tonic::Request<CardKind>,
) -> Result<tonic::Response<Image>, Status> {
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(
&self,
request: tonic::Request<super::grpc::game::CardId>,
) -> Result<tonic::Response<()>, tonic::Status> {
) -> Result<tonic::Response<()>, Status> {
todo!()
}
}

Loading…
Cancel
Save