Browse Source

Fix player_piles

new_protocol
ThePerkinrex 5 years ago
parent
commit
a456ebc9b4
No known key found for this signature in database GPG Key ID: 1F45A7C4BFB41607
  1. 2
      server/src/db.rs
  2. 336
      server/src/server/game.rs

2
server/src/db.rs

@ -149,7 +149,7 @@ impl Db {
} }
// FIXME: return Results intead of crashing // FIXME: return Results intead of crashing
pub fn disconnect(&mut self, user: Uuid) { pub fn disconnect(&mut self, user: Uuid) {
// self.leave_lobby(user).await; self.leave_lobby(user);
log::info!("{} disconnecting", user); log::info!("{} disconnecting", user);
self.conn self.conn
.execute( .execute(

336
server/src/server/game.rs

@ -2,8 +2,12 @@ use crate::games::{CardId, CardIdx, Pile, PileKind, RunningGame};
use crate::{db, games::Game}; use crate::{db, games::Game};
use super::{ use super::{
client_id, client_id,
grpc::game::{game_server, message_status::Piles, CardKind, Image, MessageStatus}, grpc::game::{
game_server,
message_status::Piles,
CardKind, Image, MessageStatus,
},
}; };
pub use game_server::GameServer; pub use game_server::GameServer;
use tonic::{Response, Status}; use tonic::{Response, Status};
@ -14,164 +18,190 @@ use std::sync::Arc;
use tokio::sync::RwLock; use tokio::sync::RwLock;
pub struct GameService { pub struct GameService {
conn: RwLock<db::DbClient>, conn: RwLock<db::DbClient>,
games: Arc<Vec<Game>>, 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>>, 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, games,
} }
} }
} }
#[tonic::async_trait] #[tonic::async_trait]
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<CardKind>, request: tonic::Request<CardKind>,
) -> Result<tonic::Response<Image>, Status> { ) -> Result<tonic::Response<Image>, Status> {
let uuid = client_id::get(request.metadata()).map_err(|x| match x { 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::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"), client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?; })?;
let mut conn = self.conn.write().await; let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await { let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
Some(l) => l, Some(l) => l,
None => return Err(Status::failed_precondition("User isn't in a lobby")), None => return Err(Status::failed_precondition("User isn't in a lobby")),
}; };
let game_id = match self.running_games.read().await.get(&lobby) { let game_id = match self.running_games.read().await.get(&lobby) {
Some(x) => x.read().await.0, Some(x) => x.read().await.0,
None => { None => {
return Err(Status::failed_precondition( return Err(Status::failed_precondition(
"User isn't in a lobby with a running game", "User isn't in a lobby with a running game",
)) ))
} }
}; };
let game = &self.games[game_id as usize]; let game = &self.games[game_id as usize];
let (face, back) = game.get_card_paths(&request.into_inner().kind); let (face, back) = game.get_card_paths(&request.into_inner().kind);
let mut face_buf = Vec::new(); let mut face_buf = Vec::new();
image::open(&face) image::open(&face)
.expect(&format!("Error loading the image in {:?}", face)) .expect(&format!("Error loading the image in {:?}", face))
.write_to(&mut face_buf, image::ImageOutputFormat::Png) .write_to(&mut face_buf, image::ImageOutputFormat::Png)
.unwrap(); .unwrap();
let mut back_buf = Vec::new(); let mut back_buf = Vec::new();
image::open(&back) image::open(&back)
.expect(&format!("Error loading the image in {:?}", back)) .expect(&format!("Error loading the image in {:?}", back))
.write_to(&mut back_buf, image::ImageOutputFormat::Png) .write_to(&mut back_buf, image::ImageOutputFormat::Png)
.unwrap(); .unwrap();
Ok(Response::new(Image { Ok(Response::new(Image {
face: face_buf, face: face_buf,
back: back_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<()>, Status> { ) -> Result<tonic::Response<()>, Status> {
let uuid = client_id::get(request.metadata()).map_err(|x| match x { 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::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"), client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?; })?;
let mut conn = self.conn.write().await; let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await { let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
Some(l) => l, Some(l) => l,
None => return Err(Status::failed_precondition("User isn't in a lobby")), None => return Err(Status::failed_precondition("User isn't in a lobby")),
}; };
let games_lock = self.running_games.read().await; let games_lock = self.running_games.read().await;
let mut game_lock = match games_lock.get(&lobby) { let mut game_lock = match games_lock.get(&lobby) {
Some(x) => x.write().await, Some(x) => x.write().await,
None => { None => {
return Err(Status::failed_precondition( return Err(Status::failed_precondition(
"User isn't in a lobby with a running game", "User isn't in a lobby with a running game",
)) ))
} }
}; };
let game = &mut game_lock.1; let game = &mut game_lock.1;
let card = request.into_inner(); let card = request.into_inner();
let idx = match card.card_index.unwrap().pos.unwrap() { let idx = match card.card_index.unwrap().pos.unwrap() {
super::grpc::game::card_index::Pos::Bottom(()) => CardIdx::Bottom, super::grpc::game::card_index::Pos::Bottom(()) => CardIdx::Bottom,
super::grpc::game::card_index::Pos::Top(()) => CardIdx::Top, super::grpc::game::card_index::Pos::Top(()) => CardIdx::Top,
super::grpc::game::card_index::Pos::Index(x) => CardIdx::Indexed(x as usize), super::grpc::game::card_index::Pos::Index(x) => CardIdx::Indexed(x as usize),
}; };
let pile_kind = match card.pile_kind.unwrap().kind.unwrap() { let pile_kind = match card.pile_kind.unwrap().kind.unwrap() {
super::grpc::game::pile_kind::Kind::Common(()) => PileKind::Common, super::grpc::game::pile_kind::Kind::Common(()) => PileKind::Common,
super::grpc::game::pile_kind::Kind::Owned(p) => PileKind::Owned(p), super::grpc::game::pile_kind::Kind::Owned(p) => PileKind::Owned(p),
}; };
let card: CardId = CardId { let card: CardId = CardId {
idx, idx,
pile_kind, pile_kind,
pile_name: card.pile_name, pile_name: card.pile_name,
}; };
game.on_click(card, game.get_player_for_uuid(&uuid).unwrap()); game.on_click(card, game.get_player_for_uuid(&uuid).unwrap());
Ok(Response::new(())) Ok(Response::new(()))
} }
async fn status( async fn status(
&self, &self,
request: tonic::Request<()>, request: tonic::Request<()>,
) -> Result<Response<super::grpc::game::MessageStatus>, Status> { ) -> Result<Response<super::grpc::game::MessageStatus>, Status> {
let uuid = client_id::get(request.metadata()).map_err(|x| match x { 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::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"), client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?; })?;
let mut conn = self.conn.write().await; let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await { let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
Some(l) => l, Some(l) => l,
None => return Err(Status::failed_precondition("User isn't in a lobby")), None => return Err(Status::failed_precondition("User isn't in a lobby")),
}; };
let games_lock = self.running_games.read().await; let games_lock = self.running_games.read().await;
let game_lock = match games_lock.get(&lobby) { let game_lock = match games_lock.get(&lobby) {
Some(x) => x.read().await, Some(x) => x.read().await,
None => { None => {
return Err(Status::failed_precondition( return Err(Status::failed_precondition(
"User isn't in a lobby with a running game", "User isn't in a lobby with a running game",
)) ))
} }
}; };
let game = &game_lock.1; let game = &game_lock.1;
let mut names = vec![]; let mut names = vec![];
for (uuid, id) in &game.players { for (uuid, id) in &game.players {
names.push((conn.get_name_for_uuid(uuid.clone()).await, *id)) names.push((conn.get_name_for_uuid(uuid.clone()).await, *id))
} }
names.sort_by(|(_, a), (_, b)| a.cmp(b)); names.sort_by(|(_, a), (_, b)| a.cmp(b));
let names = names.into_iter().map(|(x, _)| super::grpc::common::Name {name: x}).collect(); let names = names
let status = MessageStatus { .into_iter()
current_turn: game.get_current_player(), .map(|(x, _)| super::grpc::common::Name { name: x })
common_piles: Some(Piles { .collect();
piles: game let status = MessageStatus {
.piles current_turn: game.get_current_player(),
.iter() common_piles: Some(Piles {
.map(|(k, v)| (k.clone(), v.clone())) piles: game
.map(|(k, v): (String, Pile)| { .piles
( .iter()
k, .map(|(k, v)| (k.clone(), v.clone()))
super::grpc::game::message_status::Pile { .map(|(k, v): (String, Pile)| {
cards: v (
.cards k,
.into_iter() super::grpc::game::message_status::Pile {
.map(|c| super::grpc::game::message_status::Card { cards: v
kind: Some(CardKind { kind: c }), .cards
visible: true, .into_iter()
}) .map(|c| super::grpc::game::message_status::Card {
.collect(), kind: Some(CardKind { kind: c }),
}, visible: true,
) })
}) .collect(),
.collect(), },
}), )
player_piles: vec![], })
names, .collect(),
}; }),
Ok(Response::new(status)) player_piles: game
} .player_piles.clone()
.into_iter()
.map(|piles| Piles {
piles: piles
.into_iter()
.map(|(k, v)| {
(
k,
super::grpc::game::message_status::Pile {
cards: v
.cards
.into_iter()
.map(|x| super::grpc::game::message_status::Card {
kind: Some(CardKind {kind: x}),
visible: true,
})
.collect(),
},
)
})
.collect(),
})
.collect(),
names,
};
Ok(Response::new(status))
}
} }

Loading…
Cancel
Save