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
pub fn disconnect(&mut self, user: Uuid) {
// self.leave_lobby(user).await;
self.leave_lobby(user);
log::info!("{} disconnecting", user);
self.conn
.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 super::{
client_id,
grpc::game::{game_server, message_status::Piles, CardKind, Image, MessageStatus},
client_id,
grpc::game::{
game_server,
message_status::Piles,
CardKind, Image, MessageStatus,
},
};
pub use game_server::GameServer;
use tonic::{Response, Status};
@ -14,164 +18,190 @@ use std::sync::Arc;
use tokio::sync::RwLock;
pub struct GameService {
conn: RwLock<db::DbClient>,
games: Arc<Vec<Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame)>>>>,
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,
}
}
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,
}
}
}
#[tonic::async_trait]
impl game_server::Game for GameService {
async fn get_card_image(
&self,
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 get_card_image(
&self,
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<()>, 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 games_lock = self.running_games.read().await;
let mut game_lock = match games_lock.get(&lobby) {
Some(x) => x.write().await,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
}
};
let game = &mut game_lock.1;
let card = request.into_inner();
let idx = match card.card_index.unwrap().pos.unwrap() {
super::grpc::game::card_index::Pos::Bottom(()) => CardIdx::Bottom,
super::grpc::game::card_index::Pos::Top(()) => CardIdx::Top,
super::grpc::game::card_index::Pos::Index(x) => CardIdx::Indexed(x as usize),
};
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::Owned(p) => PileKind::Owned(p),
};
let card: CardId = CardId {
idx,
pile_kind,
pile_name: card.pile_name,
};
game.on_click(card, game.get_player_for_uuid(&uuid).unwrap());
Ok(Response::new(()))
}
async fn on_click(
&self,
request: tonic::Request<super::grpc::game::CardId>,
) -> Result<tonic::Response<()>, 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 games_lock = self.running_games.read().await;
let mut game_lock = match games_lock.get(&lobby) {
Some(x) => x.write().await,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
}
};
let game = &mut game_lock.1;
let card = request.into_inner();
let idx = match card.card_index.unwrap().pos.unwrap() {
super::grpc::game::card_index::Pos::Bottom(()) => CardIdx::Bottom,
super::grpc::game::card_index::Pos::Top(()) => CardIdx::Top,
super::grpc::game::card_index::Pos::Index(x) => CardIdx::Indexed(x as usize),
};
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::Owned(p) => PileKind::Owned(p),
};
let card: CardId = CardId {
idx,
pile_kind,
pile_name: card.pile_name,
};
game.on_click(card, game.get_player_for_uuid(&uuid).unwrap());
Ok(Response::new(()))
}
async fn status(
&self,
request: tonic::Request<()>,
) -> Result<Response<super::grpc::game::MessageStatus>, 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 games_lock = self.running_games.read().await;
let game_lock = match games_lock.get(&lobby) {
Some(x) => x.read().await,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
}
};
let game = &game_lock.1;
let mut names = vec![];
for (uuid, id) in &game.players {
names.push((conn.get_name_for_uuid(uuid.clone()).await, *id))
}
names.sort_by(|(_, a), (_, b)| a.cmp(b));
let names = names.into_iter().map(|(x, _)| super::grpc::common::Name {name: x}).collect();
let status = MessageStatus {
current_turn: game.get_current_player(),
common_piles: Some(Piles {
piles: game
.piles
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.map(|(k, v): (String, Pile)| {
(
k,
super::grpc::game::message_status::Pile {
cards: v
.cards
.into_iter()
.map(|c| super::grpc::game::message_status::Card {
kind: Some(CardKind { kind: c }),
visible: true,
})
.collect(),
},
)
})
.collect(),
}),
player_piles: vec![],
names,
};
Ok(Response::new(status))
}
async fn status(
&self,
request: tonic::Request<()>,
) -> Result<Response<super::grpc::game::MessageStatus>, 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 games_lock = self.running_games.read().await;
let game_lock = match games_lock.get(&lobby) {
Some(x) => x.read().await,
None => {
return Err(Status::failed_precondition(
"User isn't in a lobby with a running game",
))
}
};
let game = &game_lock.1;
let mut names = vec![];
for (uuid, id) in &game.players {
names.push((conn.get_name_for_uuid(uuid.clone()).await, *id))
}
names.sort_by(|(_, a), (_, b)| a.cmp(b));
let names = names
.into_iter()
.map(|(x, _)| super::grpc::common::Name { name: x })
.collect();
let status = MessageStatus {
current_turn: game.get_current_player(),
common_piles: Some(Piles {
piles: game
.piles
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.map(|(k, v): (String, Pile)| {
(
k,
super::grpc::game::message_status::Pile {
cards: v
.cards
.into_iter()
.map(|c| super::grpc::game::message_status::Card {
kind: Some(CardKind { kind: c }),
visible: true,
})
.collect(),
},
)
})
.collect(),
}),
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