Browse Source

Fix server & add logs

new_protocol
ThePerkinrex 5 years ago
parent
commit
f29bfb88b5
No known key found for this signature in database GPG Key ID: 1F45A7C4BFB41607
  1. 24
      server/src/server/game.rs
  2. 260
      server/src/server/lobby.rs
  3. 2
      unity/Assets/Scripts/Client.cs
  4. 2
      unity/Assets/Scripts/MainMenuController.cs

24
server/src/server/game.rs

@ -145,6 +145,7 @@ impl GameService {
} }
async fn get_default_status(&self, uuid: uuid::Uuid) -> Result<Option<MessageStatus>, Status> { async fn get_default_status(&self, uuid: uuid::Uuid) -> Result<Option<MessageStatus>, Status> {
log::info!("Creating a new status for {}", uuid);
let lobby = { let lobby = {
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 {
@ -153,6 +154,7 @@ impl GameService {
}; };
lobby lobby
}; };
let r =
Ok(self Ok(self
.running_games .running_games
.read() .read()
@ -165,7 +167,9 @@ impl GameService {
.await .await
.2 .2
.get() .get()
.clone()) .clone());
log::info!("Created a new status for {}", uuid);
r
} }
} }
@ -175,6 +179,8 @@ impl game_server::Game for GameService {
&self, &self,
request: tonic::Request<CardKind>, request: tonic::Request<CardKind>,
) -> Result<tonic::Response<Image>, Status> { ) -> Result<tonic::Response<Image>, Status> {
log::info!("Getting image location");
let time = std::time::Instant::now();
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"),
@ -194,16 +200,20 @@ impl game_server::Game for GameService {
}; };
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);
log::info!("Loading face image [{:?}]", time.elapsed()); // TODO Create a cache for loaded images, so that they don't have to be parsed and reformatted each time
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();
log::info!("Loading back image [{:?}]", time.elapsed());
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();
log::info!("Loaded images [{:?}]", time.elapsed());
Ok(Response::new(Image { Ok(Response::new(Image {
face: face_buf, face: face_buf,
back: back_buf, back: back_buf,
@ -263,9 +273,10 @@ impl game_server::Game for GameService {
})?; })?;
Ok(Response::new( Ok(Response::new(
self.get_default_status(uuid) self.get_default_status(uuid).await?.unwrap_or({
.await? self.update_status(uuid).await?;
.ok_or(Status::internal("No status has been set"))?, self.get_default_status(uuid).await?.unwrap()
}),
)) ))
} }
@ -286,7 +297,8 @@ impl game_server::Game for GameService {
lobby lobby
}; };
use std::convert::TryInto; use std::convert::TryInto;
let has_changed = self.running_games let has_changed = self
.running_games
.read() .read()
.await .await
.get(&lobby) .get(&lobby)
@ -304,6 +316,6 @@ impl game_server::Game for GameService {
.try_into() .try_into()
.unwrap(), .unwrap(),
); );
Ok(Response::new(HasNewStatus {value: has_changed})) Ok(Response::new(HasNewStatus { value: has_changed }))
} }
} }

260
server/src/server/lobby.rs

@ -5,9 +5,9 @@ use tokio::sync::{mpsc, RwLock};
use std::{collections::HashMap, convert::TryInto, sync::Arc}; use std::{collections::HashMap, convert::TryInto, sync::Arc};
use super::grpc::common::{HasNewStatus, LastStatusTimestamp, Name}; use super::grpc::common::{HasNewStatus, LastStatusTimestamp, Name};
use super::grpc::game::MessageStatus;
use super::grpc::lobby::lobby_server::Lobby; use super::grpc::lobby::lobby_server::Lobby;
use super::grpc::lobby::{LobbyStatus, SingleVote, Vote}; use super::grpc::lobby::{LobbyStatus, SingleVote, Vote};
use super::grpc::game::MessageStatus;
pub use super::grpc::lobby::lobby_server::LobbyServer; pub use super::grpc::lobby::lobby_server::LobbyServer;
@ -18,137 +18,143 @@ use super::client_id;
use crate::{db, games::RunningGame}; use crate::{db, games::RunningGame};
pub struct LobbyService { pub struct LobbyService {
conn: RwLock<db::DbClient>, conn: RwLock<db::DbClient>,
games: Arc<Vec<crate::games::Game>>, games: Arc<Vec<crate::games::Game>>,
voting: votes::VotingSystem, voting: votes::VotingSystem,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>>, running_games:
Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>>,
} }
impl LobbyService { impl LobbyService {
pub fn new( pub fn new(
conn: db::DbClient, conn: db::DbClient,
voting: votes::VotingSystem, voting: votes::VotingSystem,
games: Arc<Vec<crate::games::Game>>, games: Arc<Vec<crate::games::Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>>, running_games: Arc<
) -> Self { RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>,
Self { >,
conn: RwLock::new(conn), ) -> Self {
voting, Self {
running_games, conn: RwLock::new(conn),
games, voting,
} running_games,
} games,
}
}
} }
#[tonic::async_trait] #[tonic::async_trait]
impl Lobby for LobbyService { impl Lobby for LobbyService {
async fn vote(&self, request: Request<SingleVote>) -> Result<Response<()>, Status> { async fn vote(&self, request: Request<SingleVote>) -> Result<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 req = request.into_inner(); let req = request.into_inner();
self.voting.vote(uuid, req.game).await; self.voting.vote(uuid, req.game).await;
Ok(Response::new(())) Ok(Response::new(()))
} }
async fn ready(&self, request: Request<()>) -> Result<Response<()>, Status> { async fn ready(&self, request: Request<()>) -> Result<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"),
})?; })?;
if let Some(Some(winner)) = self.voting.ready(uuid).await { if let Some(Some(winner)) = self.voting.ready(uuid).await {
let mut conn = self.conn.write().await; let mut conn = self.conn.write().await;
let lobby = conn.get_lobby_for_user(uuid).await.unwrap(); let lobby = conn.get_lobby_for_user(uuid).await.unwrap();
log::info!("[{}] Starting a game ({})", lobby, winner); log::info!("[{}] Starting a game ({})", lobby, winner);
let user_count = conn.get_uuids_in_lobby_where_user_is(uuid).await; let user_count = conn.get_uuids_in_lobby_where_user_is(uuid).await;
let game = self.games[winner as usize].run(&user_count); let game = self.games[winner as usize].run(&user_count);
self.running_games self.running_games
.write() .write()
.await .await
.insert(lobby, RwLock::new((winner, game, Modifiable::new(None)))); .insert(lobby, RwLock::new((winner, game, Modifiable::new(None))));
} log::info!("[{}] Started a game ({})", lobby, winner);
Ok(Response::new(())) }
} log::info!("Player {} is ready", uuid);
async fn poll_status( Ok(Response::new(()))
&self, }
request: Request<LastStatusTimestamp>,
) -> Result<Response<HasNewStatus>, Status> { async fn poll_status(
// let uuid = client_id::get(request.metadata()).map_err(|x| match x { &self,
// client_id::Error::NotSet => Status::failed_precondition("client_id must be set"), request: Request<LastStatusTimestamp>,
// client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"), ) -> Result<Response<HasNewStatus>, Status> {
// })?; // let uuid = client_id::get(request.metadata()).map_err(|x| match x {
// let mut conn = self.conn.acquire().await; // client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
// client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
let inner = request.into_inner(); // })?;
let time = inner // let mut conn = self.conn.acquire().await;
.time
.ok_or(Status::failed_precondition("timestamp musn't be null"))? let inner = request.into_inner();
.try_into() let time = inner
.unwrap(); .time
Ok(Response::new(HasNewStatus { .ok_or(Status::failed_precondition("timestamp musn't be null"))?
value: self.voting.has_new_status(&inner.lobby, time).await, .try_into()
})) .unwrap();
} Ok(Response::new(HasNewStatus {
value: self.voting.has_new_status(&inner.lobby, time).await,
async fn get_status(&self, request: Request<()>) -> Result<Response<LobbyStatus>, 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"), async fn get_status(&self, request: Request<()>) -> Result<Response<LobbyStatus>, Status> {
})?; let uuid = client_id::get(request.metadata()).map_err(|x| match x {
let mut conn = self.conn.write().await; client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
if let Some(l) = conn.get_lobby_for_user(uuid).await { client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
let (votes, is_starting) = self.voting.status(&l).await.unwrap_or_default(); })?;
let names = conn.get_users_in_lobby_where_user_is(uuid).await; let mut conn = self.conn.write().await;
// log::info!("Users: {:?}", names); if let Some(l) = conn.get_lobby_for_user(uuid).await {
Ok(Response::new(LobbyStatus { let (votes, is_starting) = self.voting.status(&l).await.unwrap_or_default();
names: names.into_iter().map(|x| Name { name: x }).collect(), let names = conn.get_users_in_lobby_where_user_is(uuid).await;
votes: votes // log::info!("Users: {:?}", names);
.into_iter() Ok(Response::new(LobbyStatus {
.map(|(player, game, ready)| Vote { names: names.into_iter().map(|x| Name { name: x }).collect(),
player, votes: votes
game, .into_iter()
ready, .map(|(player, game, ready)| Vote {
}) player,
.collect(), game,
is_starting, ready,
})) })
} else { .collect(),
Err(Status::failed_precondition("User isn't in a lobby")) is_starting,
} }))
} } else {
Err(Status::failed_precondition("User isn't in a lobby"))
async fn leave( }
&self, }
request: tonic::Request<()>,
) -> Result<tonic::Response<()>, tonic::Status> { async fn leave(
let uuid = client_id::get(request.metadata()).map_err(|x| match x { &self,
client_id::Error::NotSet => Status::failed_precondition("client_id must be set"), request: tonic::Request<()>,
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"), ) -> Result<tonic::Response<()>, tonic::Status> {
})?; let uuid = client_id::get(request.metadata()).map_err(|x| match x {
let mut conn = self.conn.write().await; client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
if let Some(l) = conn.get_lobby_for_user(uuid).await { client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
// log::info!("Updating lobby status"); })?;
self.voting.updated_users(&l).await; let mut conn = self.conn.write().await;
// log::info!("Updated lobby status"); if let Some(l) = conn.get_lobby_for_user(uuid).await {
} // log::info!("Updating lobby status");
conn.leave_lobby(uuid).await; self.voting.updated_users(&l).await;
Ok(Response::new(())) // log::info!("Updated lobby status");
} }
conn.leave_lobby(uuid).await;
type usersStream = mpsc::UnboundedReceiver<Result<Name, Status>>; Ok(Response::new(()))
}
async fn users(&self, request: Request<()>) -> Result<Response<Self::usersStream>, Status> {
let uuid = client_id::get(request.metadata()).map_err(|x| match x { type usersStream = mpsc::UnboundedReceiver<Result<Name, Status>>;
client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"), async fn users(&self, request: Request<()>) -> Result<Response<Self::usersStream>, Status> {
})?; let uuid = client_id::get(request.metadata()).map_err(|x| match x {
let (sender, receiver) = mpsc::unbounded_channel(); client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
let mut conn = self.conn.write().await; client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
for name in conn.get_users_in_lobby_where_user_is(uuid).await { })?;
sender.send(Ok(Name { name })).unwrap(); let (sender, receiver) = mpsc::unbounded_channel();
} let mut conn = self.conn.write().await;
Ok(Response::new(receiver)) for name in conn.get_users_in_lobby_where_user_is(uuid).await {
} sender.send(Ok(Name { name })).unwrap();
}
Ok(Response::new(receiver))
}
} }

2
unity/Assets/Scripts/Client.cs

@ -103,7 +103,7 @@ public static class Client
}, },
new Metadata { new Metadata.Entry("client_id", connId) } new Metadata { new Metadata.Entry("client_id", connId) }
).Value; ).Value;
// Debug.Log("HasNewStatus: " + hasNew); Debug.Log("HasNewStatus: " + hasNew);
if (hasNew) { if (hasNew) {
lobby_status.Set(lobby_client.getStatus(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) })); lobby_status.Set(lobby_client.getStatus(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }));
hasChanged = true; hasChanged = true;

2
unity/Assets/Scripts/MainMenuController.cs

@ -70,7 +70,7 @@ public class MainMenuController : MonoBehaviour {
} }
} }
void FixedUpdate() { void Update() {
var conn = Client.GetConnection(); var conn = Client.GetConnection();
if (conn != null) { if (conn != null) {
if(SceneManager.GetActiveScene().buildIndex == 0) { if(SceneManager.GetActiveScene().buildIndex == 0) {

Loading…
Cancel
Save