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> {
log::info!("Creating a new status for {}", uuid);
let lobby = {
let mut conn = self.conn.write().await;
let lobby: u32 = match conn.get_lobby_for_user(uuid).await {
@ -153,6 +154,7 @@ impl GameService {
};
lobby
};
let r =
Ok(self
.running_games
.read()
@ -165,7 +167,9 @@ impl GameService {
.await
.2
.get()
.clone())
.clone());
log::info!("Created a new status for {}", uuid);
r
}
}
@ -175,6 +179,8 @@ impl game_server::Game for GameService {
&self,
request: tonic::Request<CardKind>,
) -> 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 {
client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
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 (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();
image::open(&face)
.expect(&format!("Error loading the image in {:?}", face))
.write_to(&mut face_buf, image::ImageOutputFormat::Png)
.unwrap();
log::info!("Loading back image [{:?}]", time.elapsed());
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();
log::info!("Loaded images [{:?}]", time.elapsed());
Ok(Response::new(Image {
face: face_buf,
back: back_buf,
@ -263,9 +273,10 @@ impl game_server::Game for GameService {
})?;
Ok(Response::new(
self.get_default_status(uuid)
.await?
.ok_or(Status::internal("No status has been set"))?,
self.get_default_status(uuid).await?.unwrap_or({
self.update_status(uuid).await?;
self.get_default_status(uuid).await?.unwrap()
}),
))
}
@ -286,7 +297,8 @@ impl game_server::Game for GameService {
lobby
};
use std::convert::TryInto;
let has_changed = self.running_games
let has_changed = self
.running_games
.read()
.await
.get(&lobby)
@ -304,6 +316,6 @@ impl game_server::Game for GameService {
.try_into()
.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 super::grpc::common::{HasNewStatus, LastStatusTimestamp, Name};
use super::grpc::game::MessageStatus;
use super::grpc::lobby::lobby_server::Lobby;
use super::grpc::lobby::{LobbyStatus, SingleVote, Vote};
use super::grpc::game::MessageStatus;
pub use super::grpc::lobby::lobby_server::LobbyServer;
@ -18,137 +18,143 @@ use super::client_id;
use crate::{db, games::RunningGame};
pub struct LobbyService {
conn: RwLock<db::DbClient>,
games: Arc<Vec<crate::games::Game>>,
voting: votes::VotingSystem,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>>,
conn: RwLock<db::DbClient>,
games: Arc<Vec<crate::games::Game>>,
voting: votes::VotingSystem,
running_games:
Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>>,
}
impl LobbyService {
pub fn new(
conn: db::DbClient,
voting: votes::VotingSystem,
games: Arc<Vec<crate::games::Game>>,
running_games: Arc<RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>>,
) -> Self {
Self {
conn: RwLock::new(conn),
voting,
running_games,
games,
}
}
pub fn new(
conn: db::DbClient,
voting: votes::VotingSystem,
games: Arc<Vec<crate::games::Game>>,
running_games: Arc<
RwLock<HashMap<u32, RwLock<(u32, RunningGame, Modifiable<Option<MessageStatus>>)>>>,
>,
) -> Self {
Self {
conn: RwLock::new(conn),
voting,
running_games,
games,
}
}
}
#[tonic::async_trait]
impl Lobby for LobbyService {
async fn vote(&self, request: Request<SingleVote>) -> Result<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 req = request.into_inner();
self.voting.vote(uuid, req.game).await;
Ok(Response::new(()))
}
async fn ready(&self, request: Request<()>) -> Result<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"),
})?;
if let Some(Some(winner)) = self.voting.ready(uuid).await {
let mut conn = self.conn.write().await;
let lobby = conn.get_lobby_for_user(uuid).await.unwrap();
log::info!("[{}] Starting a game ({})", lobby, winner);
let user_count = conn.get_uuids_in_lobby_where_user_is(uuid).await;
let game = self.games[winner as usize].run(&user_count);
self.running_games
.write()
.await
.insert(lobby, RwLock::new((winner, game, Modifiable::new(None))));
}
Ok(Response::new(()))
}
async fn poll_status(
&self,
request: Request<LastStatusTimestamp>,
) -> Result<Response<HasNewStatus>, 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.acquire().await;
let inner = request.into_inner();
let time = inner
.time
.ok_or(Status::failed_precondition("timestamp musn't be null"))?
.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"),
})?;
let mut conn = self.conn.write().await;
if let Some(l) = conn.get_lobby_for_user(uuid).await {
let (votes, is_starting) = self.voting.status(&l).await.unwrap_or_default();
let names = conn.get_users_in_lobby_where_user_is(uuid).await;
// log::info!("Users: {:?}", names);
Ok(Response::new(LobbyStatus {
names: names.into_iter().map(|x| Name { name: x }).collect(),
votes: votes
.into_iter()
.map(|(player, game, ready)| Vote {
player,
game,
ready,
})
.collect(),
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> {
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;
if let Some(l) = conn.get_lobby_for_user(uuid).await {
// log::info!("Updating lobby status");
self.voting.updated_users(&l).await;
// log::info!("Updated lobby status");
}
conn.leave_lobby(uuid).await;
Ok(Response::new(()))
}
type usersStream = mpsc::UnboundedReceiver<Result<Name, Status>>;
async fn users(&self, request: Request<()>) -> Result<Response<Self::usersStream>, 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 (sender, receiver) = mpsc::unbounded_channel();
let mut conn = self.conn.write().await;
for name in conn.get_users_in_lobby_where_user_is(uuid).await {
sender.send(Ok(Name { name })).unwrap();
}
Ok(Response::new(receiver))
}
async fn vote(&self, request: Request<SingleVote>) -> Result<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 req = request.into_inner();
self.voting.vote(uuid, req.game).await;
Ok(Response::new(()))
}
async fn ready(&self, request: Request<()>) -> Result<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"),
})?;
if let Some(Some(winner)) = self.voting.ready(uuid).await {
let mut conn = self.conn.write().await;
let lobby = conn.get_lobby_for_user(uuid).await.unwrap();
log::info!("[{}] Starting a game ({})", lobby, winner);
let user_count = conn.get_uuids_in_lobby_where_user_is(uuid).await;
let game = self.games[winner as usize].run(&user_count);
self.running_games
.write()
.await
.insert(lobby, RwLock::new((winner, game, Modifiable::new(None))));
log::info!("[{}] Started a game ({})", lobby, winner);
}
log::info!("Player {} is ready", uuid);
Ok(Response::new(()))
}
async fn poll_status(
&self,
request: Request<LastStatusTimestamp>,
) -> Result<Response<HasNewStatus>, 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.acquire().await;
let inner = request.into_inner();
let time = inner
.time
.ok_or(Status::failed_precondition("timestamp musn't be null"))?
.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"),
})?;
let mut conn = self.conn.write().await;
if let Some(l) = conn.get_lobby_for_user(uuid).await {
let (votes, is_starting) = self.voting.status(&l).await.unwrap_or_default();
let names = conn.get_users_in_lobby_where_user_is(uuid).await;
// log::info!("Users: {:?}", names);
Ok(Response::new(LobbyStatus {
names: names.into_iter().map(|x| Name { name: x }).collect(),
votes: votes
.into_iter()
.map(|(player, game, ready)| Vote {
player,
game,
ready,
})
.collect(),
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> {
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;
if let Some(l) = conn.get_lobby_for_user(uuid).await {
// log::info!("Updating lobby status");
self.voting.updated_users(&l).await;
// log::info!("Updated lobby status");
}
conn.leave_lobby(uuid).await;
Ok(Response::new(()))
}
type usersStream = mpsc::UnboundedReceiver<Result<Name, Status>>;
async fn users(&self, request: Request<()>) -> Result<Response<Self::usersStream>, 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 (sender, receiver) = mpsc::unbounded_channel();
let mut conn = self.conn.write().await;
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) }
).Value;
// Debug.Log("HasNewStatus: " + hasNew);
Debug.Log("HasNewStatus: " + hasNew);
if (hasNew) {
lobby_status.Set(lobby_client.getStatus(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }));
hasChanged = true;

2
unity/Assets/Scripts/MainMenuController.cs

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

Loading…
Cancel
Save