Browse Source

Add status updates

- Rewritten the whole of the database
 - Cleaned up code
 - Updated protocol
 - Added simple example of status usage on the client
new_protocol
ThePerkinrex 5 years ago
parent
commit
1e41846177
No known key found for this signature in database GPG Key ID: 1F45A7C4BFB41607
  1. 1
      protobuf/game.proto
  2. 7
      server/Cargo.toml
  3. 220
      server/src/db.rs
  4. 27
      server/src/db/types.rs
  5. 2
      server/src/main.rs
  6. 12
      server/src/server.rs
  7. 25
      server/src/server/connection.rs
  8. 2
      server/src/server/grpc/game.rs
  9. 114
      server/src/server/lobby.rs
  10. 66
      server/src/server/votes.rs
  11. 1
      unity/.gitignore
  12. 95
      unity/Assets/Scripts/Client.cs
  13. 11
      unity/Assets/Scripts/Editor/BuildProtos.cs
  14. 12
      unity/Assets/Scripts/MainMenuController.cs
  15. 5
      unity/Assets/Scripts/Utils.cs
  16. 719
      unity/Assets/Scripts/grpc/Game.cs
  17. 206
      unity/Assets/Scripts/grpc/GameGrpc.cs
  18. 8
      unity/Assets/Scripts/utils.meta
  19. 27
      unity/Assets/Scripts/utils/Utilities.cs
  20. 16
      unity/omnisharp.json

1
protobuf/game.proto

@ -44,6 +44,7 @@ message HasNewStatus {
message LastStatusTimestamp {
google.protobuf.Timestamp time = 1;
uint32 lobby = 2;
}
message CardID {

7
server/Cargo.toml

@ -9,9 +9,11 @@ edition = "2018"
[dependencies]
# Utilities
rand = "0.7.3"
image = "0.23.11"
uuid = {version = "0.8.1", features = ["v4"]}
tokio = {version = "0.2", features = ["full"]}
image = "0.23.11"
server_client = {git = "https://github.com/Mr-Llama-s-Wonderful-Soundboard/server_client.git", branch = "main", features = ["tokio2"]}
fallible-iterator = "0.2.0"
# Game loading
rhai = {version = "0.19.4", features = ["serde"]}
@ -26,7 +28,8 @@ prost = "0.6"
prost-types = "0.6.1"
# Database (SQLite)
sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio", "macros", "sqlite" ] }
rusqlite = {version = "0.24.1", features=["bundled"]}
# sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio", "macros", "sqlite" ] }
# TUI
crossterm = "0.18.2"

220
server/src/db.rs

@ -1,59 +1,53 @@
use sqlx::{pool::PoolConnection, prelude::*, query, query_as, SqliteConnection, SqlitePool};
// use sqlx::{pool::PoolConnection, prelude::*, query, query_as, SqliteConnection, SqlitePool};
// use tokio::stream::StreamExt;
pub mod types;
pub struct DbPool {
pool: SqlitePool,
}
impl DbPool {
pub async fn new() -> Self {
// std::env::set_var("DATABASE_URL", );
let pool = SqlitePool::new("sqlite:db.sqlite").await.unwrap();
let mut conn = pool.acquire().await.unwrap();
conn.execute(sqlx::query(include_str!("setup.sql")))
.await
.unwrap();
use tokio::task::spawn;
use rusqlite::{params, Connection, Error as SqliteError};
use server_client::encapsulate;
use fallible_iterator::FallibleIterator;
use uuid::Uuid;
Self { pool }
}
use std::convert::TryInto;
pub async fn acquire(&self) -> DbConnection {
DbConnection::new(self.pool.acquire().await.unwrap())
}
pub async fn start() -> DbClient {
let mut server = DbServer::new(Db::new(Connection::open_in_memory().unwrap()));
let mut client = server.connection();
spawn(async move {
loop {
server.tick();
tokio::task::yield_now().await
}
});
client.load_setup().await;
client
}
// impl Drop for DbPool {
// fn drop(&mut self) {
// tokio::runtime::Handle::current().block_on(future)
// }
// }
pub struct Db {
conn: Connection,
}
pub struct DbConnection {
conn: PoolConnection<SqliteConnection>,
impl Db {
fn new(conn: Connection) -> Self {
Self { conn }
}
}
use uuid::Uuid;
// type LobbyId = (i32,);
// FIXME: return Results intead of crashing
impl DbConnection {
fn new(conn: PoolConnection<SqliteConnection>) -> Self {
Self { conn }
#[encapsulate(pub async ordered)]
impl Db {
pub fn load_setup(&mut self) {
self.conn.execute_batch(include_str!("setup.sql")).unwrap()
}
pub async fn add_user<T: ToString>(&mut self, name: T) -> Uuid {
pub fn add_user(&mut self, name: String) -> Uuid {
let uuid = Uuid::new_v4();
// println!("{:?}", uuid.as_bytes().to_vec());
self.conn
.execute(
query("INSERT INTO Users(uuid, name) VALUES(?, ?)")
.bind(uuid.as_bytes().to_vec())
.bind(name.to_string()),
"INSERT INTO Users(uuid, name) VALUES(?, ?)",
params![uuid.as_bytes().to_vec(), name.to_string()],
)
.await
.unwrap(); // Server crashes if uuids collide
uuid
}
@ -65,146 +59,122 @@ impl DbConnection {
// .unwrap()
// }
pub async fn get_users_in_lobby_where_user_is(&mut self, uuid: Uuid) -> Vec<String> {
query_as::<_, (String, )>("SELECT Name FROM Users WHERE UUID in (SELECT UserId FROM UsersInLobbies WHERE LobbyId = (SELECT LobbyId FROM UsersInLobbies WHERE UserId = ?))").bind(uuid.as_bytes().to_vec())
.fetch_all(&mut self.conn)
.await
.unwrap().into_iter().map(|(x, )| x).collect()
pub fn get_users_in_lobby_where_user_is(&mut self, uuid: Uuid) -> Vec<String> {
let mut prepared = self.conn.prepare_cached("SELECT Name FROM Users WHERE UUID in (SELECT UserId FROM UsersInLobbies WHERE LobbyId = (SELECT LobbyId FROM UsersInLobbies WHERE UserId = ?))").unwrap();
prepared.query(params![uuid.as_bytes().to_vec()]).and_then(|r|r.map(|r|r.get(0)).collect()).unwrap()
}
pub async fn create_lobby(&mut self, public: bool) -> u32 {
pub fn create_lobby(&mut self, public: bool) -> u32 {
let id = rand::random();
log::info!("Created the lobby {}", id);
self.conn
.execute(
query("INSERT INTO Lobbies(id, public) VALUES(?, ?)")
.bind(id as i32)
.bind(public),
"INSERT INTO Lobbies(id, public) VALUES(?, ?)",
params![id as i32, public],
)
.await
.unwrap(); // Server crashes if ids collide
id
}
pub async fn join_lobby(&mut self, user: Uuid, lobby: u32) {
pub fn join_lobby(&mut self, user: Uuid, lobby: u32) {
self.conn
.execute(
query("INSERT INTO UsersInLobbies(UserId, LobbyId) VALUES(?, ?)")
.bind(user.as_bytes().to_vec())
.bind(lobby as i32),
"INSERT INTO UsersInLobbies(UserId, LobbyId) VALUES(?, ?)",
params![user.as_bytes().to_vec(), lobby as i32],
)
.await
.unwrap(); // Server crashes if ids collide
log::info!("{} joined the lobby {}", user, lobby);
}
pub async fn leave_lobby(&mut self, user: &Uuid) {
pub fn leave_lobby(&mut self, user: Uuid) {
log::info!("{} leaving the lobby", user);
self.delete_vote(user).await;
let v = query_as::<_, (i32,)>("SELECT LobbyId FROM UsersInLobbies WHERE UserId = ?")
.bind(user.as_bytes().to_vec())
.fetch_one(&mut self.conn)
.await;
self.delete_vote(user);
let v = self.get_lobby_for_user(user);
self.conn
.execute(
query("DELETE FROM UsersInLobbies WHERE UserId = ?").bind(user.as_bytes().to_vec()),
"DELETE FROM UsersInLobbies WHERE UserId = ?",
params![user.as_bytes().to_vec()],
)
.await
.unwrap();
if let Ok((id,)) = v {
let lines = self.conn.execute(query("DELETE FROM Lobbies WHERE 0 = (SELECT count(*) FROM UsersInLobbies WHERE LobbyID = ?)").bind(id)).await.unwrap();
if let Some(id) = v {
let lines = self.conn.execute("DELETE FROM Lobbies WHERE 0 = (SELECT count(*) FROM UsersInLobbies WHERE LobbyID = ?)", params![id]).unwrap();
log::info!("Deleted {} lobbies ({})", lines, id as u32)
}
}
pub async fn disconnect(&mut self, user: &Uuid) {
pub fn disconnect(&mut self, user: Uuid) {
// self.leave_lobby(user).await;
log::info!("{} disconnecting", user);
self.leave_lobby(user).await;
self.conn
.execute(query("DELETE FROM Users WHERE UUID = ?").bind(user.as_bytes().to_vec()))
.await
.unwrap();
self.conn.execute(
"DELETE FROM Users WHERE UUID = ?",
params![user.as_bytes().to_vec()],
).unwrap();
// log::error!("Disconnect DB result{:?}", r);
}
pub async fn get_lobby_for_user(&mut self, user: &Uuid) -> Option<u32> {
match query_as::<_, (i32,)>("SELECT LobbyID from UsersInLobbies WHERE UserID = ?")
.bind(user.as_bytes().to_vec())
.fetch_one(&mut self.conn)
.await
{
Ok((v,)) => Ok(Some(v as u32)),
pub fn get_lobby_for_user(&mut self, user: Uuid) -> Option<u32> {
match self.conn.query_row(
"SELECT LobbyID from UsersInLobbies WHERE UserID = ?",
params![user.as_bytes().to_vec()],
|r| r.get(0),
) {
Ok(v) => Ok(Some(v)),
Err(e) => match e {
sqlx::Error::RowNotFound => Ok(None),
SqliteError::QueryReturnedNoRows => Ok(None),
e => Err(e),
},
}
.unwrap()
}
pub async fn get_public_lobbies(&mut self) -> Vec<u32> {
query_as::<_, (i32,)>("SELECT ID FROM Lobbies WHERE Public = TRUE")
.fetch_all(&mut self.conn)
.await
.unwrap()
.into_iter()
.map(|(x,)| x as u32)
.collect()
pub fn get_public_lobbies(&mut self) -> Vec<u32> {
let mut prepared = self
.conn
.prepare("SELECT ID FROM Lobbies WHERE Public = TRUE").unwrap();
prepared.query(params![]).and_then(|r| r.map(|r| r.get(0)).collect()).unwrap()
}
async fn delete_vote(&mut self, user: &Uuid) {
self.conn
.execute(query("DELETE FROM Votes WHERE UserId = ?").bind(user.as_bytes().to_vec()));
fn delete_vote(&mut self, user: Uuid) {
self.conn.execute(
"DELETE FROM Votes WHERE UserId = ?",
params![user.as_bytes().to_vec()],
).unwrap();
}
pub async fn vote(&mut self, user: Uuid, game: u32) {
self.delete_vote(&user).await;
pub fn vote(&mut self, user: Uuid, game: u32) {
self.delete_vote(user);
self.conn.execute(
query("INSERT INTO Votes(UserID, GameID) VALUES(?, ?)")
.bind(user.as_bytes().to_vec())
.bind(game as i32),
);
"INSERT INTO Votes(UserID, GameID) VALUES(?, ?)",
params![user.as_bytes().to_vec(), game],
).unwrap();
}
pub async fn vote_ready(&mut self, user: Uuid) {
self.delete_vote(&user).await;
pub fn vote_ready(&mut self, user: Uuid) {
self.delete_vote(user);
self.conn.execute(
query("UPDATE Votes SET Ready = TRUE WHERE UserID = ?").bind(user.as_bytes().to_vec()),
);
"UPDATE Votes SET Ready = TRUE WHERE UserID = ?",
params![user.as_bytes().to_vec()],
).unwrap();
}
pub async fn get_votes(&mut self, lobby: u32) -> Vec<(String, u32, bool)> {
query_as::<_, (String, i32, bool)>("SELECT Users.Name, Votes.GameID, Votes.Ready FROM Votes JOIN Users ON Users.UUID = Votes.UserID WHERE Votes.UserID IN (SELECT UserID FROM UsersInLobbies WHERE LobbyID = ?)").bind(lobby as i32)
.fetch_all(&mut self.conn)
.await
.unwrap()
.into_iter()
.map(|(user, game, ready)| (user, game as u32, ready))
.collect()
pub fn get_votes(&mut self, lobby: u32) -> Vec<(String, u32, bool)> {
let mut prepared = self.conn.prepare_cached("SELECT Users.Name, Votes.GameID, Votes.Ready FROM Votes JOIN Users ON Users.UUID = Votes.UserID WHERE Votes.UserID IN (SELECT UserID FROM UsersInLobbies WHERE LobbyID = ?)").unwrap();
prepared.query(params![lobby]).and_then(|r| r.map(|r| r.try_into()).collect()).unwrap()
}
pub async fn is_poll_finished(&mut self, lobby: u32) -> bool {
query_as::<_, (bool,)>("SELECT (SELECT COUNT(*) FROM UsersInLobbies where LobbyID = ?) = (SELECT COUNT(*) FROM Votes WHERE UserID IN (SELECT UserID FROM UsersInLobbies WHERE LobbyID = ?) AND Ready = TRUE)")
.bind(lobby as i32).bind(lobby as i32)
.fetch_one(&mut self.conn)
.await.unwrap().0
pub fn is_poll_finished(&mut self, lobby: u32) -> bool {
self.conn.query_row(
"SELECT (SELECT COUNT(*) FROM UsersInLobbies where LobbyID = ?) = (SELECT COUNT(*) FROM Votes WHERE UserID IN (SELECT UserID FROM UsersInLobbies WHERE LobbyID = ?) AND Ready = TRUE)",
params![lobby, lobby],
|r| r.get(0)
).unwrap()
}
pub async fn delete_votes(&mut self, lobby: u32) {
pub fn delete_votes(&mut self, lobby: u32) {
self.conn
.execute(query("DELETE FROM Votes WHERE UserId IN (SELECT UserID FROM UsersInLobbies WHERE LobbyID = ?)").bind(lobby as i32));
.execute("DELETE FROM Votes WHERE UserId IN (SELECT UserID FROM UsersInLobbies WHERE LobbyID = ?)", params![lobby]).unwrap();
}
// pub async fn close(self) {
// self.conn.close().await.unwrap();
// }
}
// fn block<T, F: std::future::Future<Output = T>>(fut: F) -> T {
// if let Ok(handle) = tokio::runtime::Handle::try_current() {
// handle.block_on(fut)
// }else{
// tokio::runtime::Runtime::new().unwrap().block_on(fut)
// }
// }

27
server/src/db/types.rs

@ -1,27 +0,0 @@
use uuid::Uuid;
use sqlx::{prelude::*, sqlite::SqliteRow};
pub struct User{
pub name: String,
pub uuid: Uuid
}
impl<'a> FromRow<'a, SqliteRow<'a>> for User {
fn from_row(row: &SqliteRow<'a>) -> sqlx::Result<Self> {
let uuid: String = row.try_get("UUID")?;
// println!("{:?}", uuid.as_bytes());
Ok(Self {uuid: Uuid::from_slice(uuid.as_bytes()).map_err(|x| sqlx::Error::Decode(Box::new(x)))?, name: row.try_get("Name")?})
}
}
impl std::fmt::Display for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}[{}]", self.name, self.uuid)
}
}
impl std::fmt::Debug for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}

2
server/src/main.rs

@ -25,7 +25,7 @@ async fn main() {
log::info!("{:?}", games);
games[0].run(4);
info!(target: "setup", "Loading database");
let pool = db::DbPool::new().await;
let pool = db::start().await;
info!(target: "setup", "Starting server");
server::start(pool, games, p).await;
close.close();

12
server/src/server.rs

@ -1,5 +1,7 @@
use tonic::transport::Server;
use tokio::sync::RwLock;
use std::sync::Arc;
use crate::db;
@ -7,6 +9,7 @@ use crate::db;
mod connection;
mod grpc;
mod lobby;
mod votes;
use grpc::game::connection_server::ConnectionServer;
use grpc::game::lobby_server::LobbyServer;
@ -15,19 +18,20 @@ use connection::ConnectionService;
use lobby::LobbyService;
pub async fn start(
pool: db::DbPool,
mut pool: db::DbClient,
games: Vec<crate::games::Game>,
properties: crate::server_properties::ServerProperties,
) {
let arc = Arc::new(pool);
let properties = Arc::new(properties);
let games = Arc::new(games);
let voting = votes::VotingSystem::new(pool.clone().await);
let connection = ConnectionService {
conn: arc.clone(),
conn: RwLock::new(pool.clone().await),
properties: properties.clone(),
games: games.clone(),
voting: voting.clone(),
};
let lobby = LobbyService::new(arc.clone(), games);
let lobby = LobbyService::new(pool, games, voting);
Server::builder()
.add_service(ConnectionServer::new(connection))

25
server/src/server/connection.rs

@ -2,29 +2,32 @@ use tonic::{Request, Response, Status};
use log::info;
use tokio::sync::mpsc;
use tokio::sync::{mpsc, RwLock};
use std::sync::Arc;
use super::grpc::game::connection_server::Connection;
use super::grpc::game::{LobbyCode, LobbyConfig, Name, UserId, Game};
use super::votes;
use super::client_id;
use crate::db;
pub struct ConnectionService {
pub conn: Arc<db::DbPool>,
pub conn: RwLock<db::DbClient>,
pub properties: Arc<crate::server_properties::ServerProperties>,
pub games: Arc<Vec<crate::games::Game>>,
pub voting: votes::VotingSystem,
}
#[tonic::async_trait]
impl Connection for ConnectionService {
async fn connect(&self, request: Request<Name>) -> Result<Response<UserId>, Status> {
let name = request.into_inner().name;
let mut conn = self.conn.acquire().await;
let uuid = conn.add_user(&name).await;
// let mut conn = self.conn.acquire().await;
let uuid = self.conn.write().await.add_user(name.clone()).await;
info!("Connected {}[{}]", name, uuid);
Ok(Response::new(UserId {
id: uuid.to_hyphenated().to_string(),
@ -40,8 +43,9 @@ impl Connection for ConnectionService {
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?;
let lobby = request.get_ref().code;
let mut conn = self.conn.acquire().await;
let mut conn = self.conn.write().await;
conn.join_lobby(uuid, lobby).await;
self.voting.updated_users(&lobby).await;
Ok(Response::new(()))
}
@ -53,9 +57,10 @@ impl Connection for ConnectionService {
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 mut conn = self.conn.write().await;
let lobby = conn.create_lobby(request.into_inner().public).await;
conn.join_lobby(uuid, lobby).await;
self.voting.updated_users(&lobby).await;
Ok(Response::new(LobbyCode { code: lobby }))
}
@ -89,7 +94,7 @@ impl Connection for ConnectionService {
_request: Request<()>,
) -> Result<Response<Self::getPublicLobbiesStream>, Status> {
let (sender, receiver) = mpsc::unbounded_channel();
let mut conn = self.conn.acquire().await;
let mut conn = self.conn.write().await;
for id in conn.get_public_lobbies().await {
sender.send(Ok(LobbyCode { code: id })).unwrap();
}
@ -101,8 +106,10 @@ impl Connection for ConnectionService {
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;
conn.disconnect(&uuid).await;
let mut conn = self.conn.write().await;
// log::warn!("Trying to disconnect");
conn.disconnect(uuid).await;
// log::warn!("Disconnected");
Ok(Response::new(()))
}
}

2
server/src/server/grpc/game.rs

@ -23,6 +23,8 @@ pub struct HasNewStatus {
pub struct LastStatusTimestamp {
#[prost(message, optional, tag = "1")]
pub time: ::std::option::Option<::prost_types::Timestamp>,
#[prost(uint32, tag = "2")]
pub lobby: u32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CardId {

114
server/src/server/lobby.rs

@ -1,8 +1,6 @@
mod votes;
use tonic::{Request, Response, Status};
use tokio::sync::mpsc;
use tokio::sync::{mpsc, RwLock};
use std::convert::TryInto;
use std::sync::Arc;
@ -12,22 +10,24 @@ use super::grpc::game::{
CardId, HasNewStatus, Image, LastStatusTimestamp, LobbyStatus, Name, SingleVote, Vote,
};
use super::votes;
use super::client_id;
use crate::db;
pub struct LobbyService {
conn: Arc<db::DbPool>,
conn: RwLock<db::DbClient>,
games: Arc<Vec<crate::games::Game>>,
voting: votes::VotingSystem,
}
impl LobbyService {
pub fn new(conn: Arc<db::DbPool>, games: Arc<Vec<crate::games::Game>>) -> Self {
pub fn new(conn: db::DbClient, games: Arc<Vec<crate::games::Game>>, voting: votes::VotingSystem) -> Self {
Self {
games,
conn: conn.clone(),
voting: votes::VotingSystem::new(conn),
conn: RwLock::new(conn),
voting,
}
}
}
@ -68,79 +68,25 @@ impl Lobby for LobbyService {
Ok(Response::new(()))
}
// type subscribeToStatusStream =
// broadcast_stream::BroadcastStream<(Vec<(String, u32, bool)>, bool, u32), Result<LobbyStatus, Status>>;
// async fn subscribe_to_status(
// &self,
// request: Request<()>,
// ) -> Result<Response<Self::subscribeToStatusStream>, 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;
// if let Some(l) = conn.get_lobby_for_user(&uuid).await {
// log::info!("{} subscribing to status for lobby {}", uuid, l);
// let pool = self.conn.clone();
// Ok(Response::new(
// BroadcastStream::new(self.voting.subscribe()).map(move |(x, finished, lobby)| {
// log::info!("[{}] Lobby status for lobby {}: ({:?}, {})",l, lobby, x, finished);
// if lobby == l {
// let names = tokio::runtime::Handle::current().block_on(async {
// let mut conn = pool.acquire().await;
// let res = conn.get_users_in_lobby_where_user_is(uuid).await.into_iter().map(|x| Name {name: x}).collect();
// conn.close().await;
// res
// });
// Some(Ok(LobbyStatus {
// names,
// votes: x
// .into_iter()
// .map(|(player, game, ready)| Vote {
// player,
// game,
// ready,
// })
// .collect(),
// is_starting: finished,
// }))
// } else {
// None
// }
// }),
// ))
// }else{
// Err(Status::failed_precondition("Cannot subscribe to status if not in a lobby"))
// }
// }
async fn has_new_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;
if let Some(l) = conn.get_lobby_for_user(&uuid).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(&l, time).await,
}))
} else {
Err(Status::failed_precondition("User isn't in a lobby"))
}
// 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> {
@ -148,10 +94,11 @@ impl Lobby for LobbyService {
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;
if let Some(l) = conn.get_lobby_for_user(&uuid).await {
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
@ -177,8 +124,13 @@ impl Lobby for LobbyService {
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;
conn.leave_lobby(&uuid).await;
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(()))
}
@ -190,7 +142,7 @@ impl Lobby for LobbyService {
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?;
let (sender, receiver) = mpsc::unbounded_channel();
let mut conn = self.conn.acquire().await;
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();
}

66
server/src/server/lobby/votes.rs → server/src/server/votes.rs

@ -1,14 +1,15 @@
use tokio::sync::RwLock;
use uuid::Uuid;
use std::collections::HashMap;
use std::sync::Arc;
use std::time::SystemTime;
use std::collections::HashMap;
use crate::db;
type Message = (Vec<(String, u32, bool)>, bool);
#[derive(Debug)]
struct Modifiable<T> {
value: T,
last_modified: SystemTime,
@ -16,10 +17,14 @@ struct Modifiable<T> {
impl<T> Modifiable<T> {
pub fn new(value: T) -> Self {
Self {value, last_modified: SystemTime::now()}
Self {
value,
last_modified: SystemTime::now(),
}
}
pub fn has_changed(&self, t: SystemTime) -> bool {
// log::info!("Status: {:?} > {:?}", self.last_modified, t);
self.last_modified > t
}
@ -27,39 +32,45 @@ impl<T> Modifiable<T> {
&self.value
}
pub fn get_mut(&mut self) -> &mut T {
self.last_modified = SystemTime::now();
&mut self.value
}
pub fn set(&mut self, new: T) {
self.last_modified = SystemTime::now();
self.value = new;
}
}
#[derive(Clone)]
pub struct VotingSystem {
conn: Arc<db::DbPool>,
conn: Arc<RwLock<db::DbClient>>,
// games: Arc<Vec<crate::games::Game>>,
// broadcast: broadcast::Sender<Message>,
last_status: Arc<RwLock<HashMap<u32, Arc<RwLock<Modifiable<Message>>>>>>
last_status: Arc<RwLock<HashMap<u32, Arc<RwLock<Modifiable<Message>>>>>>,
}
impl VotingSystem {
pub fn new(
conn: Arc<db::DbPool>,
conn: db::DbClient,
// games: Arc<Vec<crate::games::Game>>,
) -> Self {
// let (tx, rx) = broadcast::channel(1);
// tx.send((Vec::new(), false, 0)).unwrap();
Self {
conn,
last_status: Arc::new(RwLock::new(HashMap::new()))
}
Self {
conn: Arc::new(RwLock::new(conn)),
last_status: Arc::new(RwLock::new(HashMap::new())),
}
}
async fn change_status(&self, lobby: u32, new_message: Message) {
let mut lock = self.last_status.write().await;
if lock.contains_key(&lobby) {
lock.get(&lobby).unwrap().write().await.set(new_message);
}else{
} else {
lock.insert(lobby, Arc::new(RwLock::new(Modifiable::new(new_message))));
}
}
@ -74,30 +85,47 @@ impl VotingSystem {
pub async fn status(&self, lobby: &u32) -> Option<Message> {
match self.last_status.read().await.get(lobby) {
None => None,
Some(v) => Some(v.read().await.get().clone())
Some(v) => Some(v.read().await.get().clone()),
}
}
pub async fn has_new_status(&self, lobby: &u32, t: SystemTime) -> bool {
// log::info!("Status lobby: {}", lobby);
match self.last_status.read().await.get(lobby) {
None => false,
Some(v) => v.read().await.has_changed(t)
Some(v) => v.read().await.has_changed(t),
}
}
pub async fn updated_users(&self, lobby: &u32) {
let status = {
let lock = self.last_status.read().await;
lock.get(lobby).map(Clone::clone)
};
if let Some(v) = status {
v.write().await.get_mut();
} else {
// log::info!("Adding new lobby to voting system");
self.last_status.write().await.insert(
*lobby,
Arc::new(RwLock::new(Modifiable::new(Default::default()))),
);
// log::info!("Added new lobby to voting system");
}
}
pub async fn vote(&self, user: Uuid, game: u32) {
let mut conn = self.conn.acquire().await;
if let Some(lobby) = conn.get_lobby_for_user(&user).await {
let mut conn = self.conn.write().await;
if let Some(lobby) = conn.get_lobby_for_user(user).await {
conn.vote(user, game).await;
let status = conn.get_votes(lobby).await;
self.change_status(lobby, (status, false)).await;
}
}
pub async fn ready(&self, user: Uuid) {
let mut conn = self.conn.acquire().await;
if let Some(lobby) = conn.get_lobby_for_user(&user).await {
let mut conn = self.conn.write().await;
if let Some(lobby) = conn.get_lobby_for_user(user).await {
conn.vote_ready(user).await;
let finished = conn.is_poll_finished(lobby).await;
let status = conn.get_votes(lobby).await;
@ -109,4 +137,4 @@ impl VotingSystem {
tokio::task::yield_now().await;
}
}
}
}

1
unity/.gitignore

@ -47,6 +47,7 @@ ExportedObj/
*.pidb.meta
*.pdb.meta
*.mdb.meta
*.cs.meta
# Unity3D generated file on crash reports
sysinfo.txt

95
unity/Assets/Scripts/Client.cs

@ -2,24 +2,20 @@ using Grpc.Core;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
public static class Client
{
using Utilities;
public static class Client {
private static Connection reference;
public static void Connect(string name, string address = "127.0.0.1:50052")
{
public static void Connect(string name, string address = "127.0.0.1:50052") {
reference = new Connection(name, address);
}
public static ref Connection GetConnection()
{
public static ref Connection GetConnection() {
return ref reference;
}
public static void CloseConnection()
{
if (reference != null)
{
public static void CloseConnection() {
if (reference != null) {
reference.Close();
reference = null;
}
@ -32,8 +28,9 @@ public static class Client
private Channel channel;
private string connId;
private uint? lobby = null;
public Connection(string user, string address)
{
private Modifiable<Game.LobbyStatus> lobby_status = null;
public Connection(string user, string address) {
channel = new Channel(address, ChannelCredentials.Insecure);
connection = new Game.Connection.ConnectionClient(channel);
lobby_client = new Game.Lobby.LobbyClient(channel);
@ -41,39 +38,57 @@ public static class Client
}
public string Name() {
return connection.name(new Game.Null()).Name_;
return connection.name(new Google.Protobuf.WellKnownTypes.Empty()).Name_;
}
public void JoinLobby(string code)
{
public void JoinLobby(string code) {
lobby = Base32.FromString(code);
connection.joinLobbyWithCode(new Game.LobbyCode { Code = (uint)lobby }, new Metadata { new Metadata.Entry("client_id", connId) });
}
public string CreateLobby(bool isPublic)
{
lobby = connection.createLobby(new Game.LobbyConfig {Public = isPublic}, new Metadata { new Metadata.Entry("client_id", connId) }).Code;
public string CreateLobby(bool isPublic) {
lobby = connection.createLobby(new Game.LobbyConfig { Public = isPublic }, new Metadata { new Metadata.Entry("client_id", connId) }).Code;
return Base32.ToString((uint)lobby);
}
public string GetLobby()
{
if (lobby != null)
{
public string GetLobby() {
if (lobby != null) {
return Base32.ToString((uint)lobby);
} else {
return null;
}
else
{
}
public Game.LobbyStatus LobbyStatus() {
if (lobby != null) {
if (lobby_status != null) {
var hasNew = lobby_client.hasNewStatus(
new Game.LastStatusTimestamp {
Time = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(lobby_status.GetLastModfication()),
Lobby = (uint)lobby,
},
new Metadata { new Metadata.Entry("client_id", connId) }
).Value;
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) }));
}
return lobby_status.Get();
} else {
Debug.Log("Getting status");
lobby_status = new Utilities.Modifiable<Game.LobbyStatus>(lobby_client.getStatus(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }));
return lobby_status.Get();
}
} else {
return null;
}
}
public List<string> GetUsersInSameLobby(){
AsyncServerStreamingCall<Game.Name> stream = lobby_client.users(new Game.Null(), new Metadata { new Metadata.Entry("client_id", connId) });
public List<string> GetUsersInSameLobby() {
AsyncServerStreamingCall<Game.Name> stream = lobby_client.users(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) });
List<string> l = new List<string>();
while (runSync(stream.ResponseStream.MoveNext()))
{
while (runSync(stream.ResponseStream.MoveNext())) {
Game.Name g = stream.ResponseStream.Current;
l.Add(g.Name_);
// Debug.Log("Received " + feature.ToString());
@ -83,16 +98,16 @@ public static class Client
}
public void LeaveLobby() {
lobby_client.leave(new Game.Null(), new Metadata { new Metadata.Entry("client_id", connId) });
lobby_status = null;
lobby_client.leave(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) });
lobby = null;
}
public List<string> GetPublicLobbies() {
AsyncServerStreamingCall<Game.LobbyCode> stream = connection.getPublicLobbies(new Game.Null());
AsyncServerStreamingCall<Game.LobbyCode> stream = connection.getPublicLobbies(new Google.Protobuf.WellKnownTypes.Empty());
List<string> l = new List<string>();
while (runSync(stream.ResponseStream.MoveNext()))
{
while (runSync(stream.ResponseStream.MoveNext())) {
Game.LobbyCode g = stream.ResponseStream.Current;
l.Add(Base32.ToString(g.Code));
// Debug.Log("Received " + feature.ToString());
@ -101,13 +116,11 @@ public static class Client
return l;
}
public List<Game.Game> GetGames()
{
AsyncServerStreamingCall<Game.Game> stream = connection.getGames(new Game.Null());
public List<Game.Game> GetGames() {
AsyncServerStreamingCall<Game.Game> stream = connection.getGames(new Google.Protobuf.WellKnownTypes.Empty());
List<Game.Game> l = new List<Game.Game>();
while (runSync(stream.ResponseStream.MoveNext()))
{
while (runSync(stream.ResponseStream.MoveNext())) {
Game.Game g = stream.ResponseStream.Current;
l.Add(g);
// Debug.Log("Received " + feature.ToString());
@ -116,15 +129,13 @@ public static class Client
return l;
}
static T runSync<T>(Task<T> task)
{
static T runSync<T>(Task<T> task) {
task.Wait();
return task.Result;
}
public void Close()
{
connection.disconnect(new Game.Null(), new Metadata { new Metadata.Entry("client_id", connId) });
public void Close() {
connection.disconnect(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) });
channel.ShutdownAsync().Wait();
}
}

11
unity/Assets/Scripts/Editor/BuildProtos.cs

@ -25,18 +25,22 @@ public class ScriptBatch
string basePath = Application.dataPath.Substring(0, Application.dataPath.Length - "/Assets".Length);
string protobufPath = Path.Combine(Application.dataPath.Substring(0, Application.dataPath.Length - "/unity/Assets".Length), "protobuf");
string outDir = Path.Combine(Application.dataPath, "Scripts", "grpc");
string includeDir = null;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
includeDir = basePath + "/Packages/Grpc.Tools.2.33.1/tools/include";
protoc = basePath + "/Packages/Grpc.Tools.2.33.1/tools/linux_" + arch + "/protoc";
plugin = basePath + "/Packages/Grpc.Tools.2.33.1/tools/linux_" + arch + "/grpc_csharp_plugin";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
includeDir = basePath + "\\Packages\\Grpc.Tools.2.33.1\\tools\\include";
protoc = basePath + "\\Packages\\Grpc.Tools.2.33.1\\tools\\windows_" + arch + "\\protoc.exe";
plugin = basePath + "\\Packages\\Grpc.Tools.2.33.1\\tools\\windows_" + arch + "\\grpc_csharp_plugin.exe";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
includeDir = basePath + "/Packages/Grpc.Tools.2.33.1/tools/include";
protoc = basePath + "/Packages/Grpc.Tools.2.33.1/tools/macosx_" + arch + "/protoc";
plugin = basePath + "/Packages/Grpc.Tools.2.33.1/tools/macosx_" + arch + "/grpc_csharp_plugin";
}
@ -58,7 +62,7 @@ public class ScriptBatch
foreach (string currentFile in protoFiles)
{
compile_file(protoc, plugin, protobufPath, outDir, currentFile);
compile_file(protoc, plugin, protobufPath, includeDir, outDir, currentFile);
}
} catch (Exception e) {
UnityEngine.Debug.LogException(e);
@ -79,7 +83,7 @@ public class ScriptBatch
// }
}
public static void compile_file(string protoc, string plugin, string protobufPath, string outDir, string file) {
public static void compile_file(string protoc, string plugin, string protobufPath, string includeDir, string outDir, string file) {
// -I protobuf --csharp_out=unity/Assets/Scripts/grpc --grpc_out=unity/Assets/Scripts/grpc --plugin=protoc-gen-grpc=unity/Packages/Grpc.Tools.2.33.1/tools/linux_x64/grpc_csharp_plugin file
Process myProcess = new Process();
@ -87,8 +91,7 @@ public class ScriptBatch
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = protoc;
// string path = "C:\\Users\\Brian\\Desktop\\testFile.bat";
myProcess.StartInfo.Arguments = $"-I \"{protobufPath}\" --csharp_out=\"{outDir}\" --grpc_out=\"{outDir}\" --plugin=protoc-gen-grpc=\"{plugin}\" \"{file}\"";
myProcess.StartInfo.Arguments = $"-I \"{protobufPath}\" -I \"{includeDir}\" --csharp_out=\"{outDir}\" --grpc_out=\"{outDir}\" --plugin=protoc-gen-grpc=\"{plugin}\" \"{file}\"";
myProcess.EnableRaisingEvents = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.Start();

12
unity/Assets/Scripts/MainMenuController.cs

@ -3,6 +3,8 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Grpc.Core;
using Utilities;
public class MainMenuController : MonoBehaviour {
[Header("Prefabs")]
@ -66,7 +68,15 @@ public class MainMenuController : MonoBehaviour {
if (conn != null) conn.Close();
}
void Update() {}
void Update() {
if (lobbyMenu.activeSelf) {
var conn = Client.GetConnection();
if (conn != null) {
var status = conn.LobbyStatus();
Debug.Log(status.ToString());
}
}
}
public void ConnectServer() {
try {

5
unity/Assets/Scripts/Utils.cs

@ -1,8 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
public static class Utils {
public static GameObject FindRecursive(this GameObject go, string child) {
var foundChild = go.transform.Find(child);
if (foundChild != null) {

719
unity/Assets/Scripts/grpc/Game.cs

File diff suppressed because it is too large

206
unity/Assets/Scripts/grpc/GameGrpc.cs

@ -45,18 +45,18 @@ namespace Game {
return parser.ParseFrom(context.PayloadAsNewBuffer());
}
static readonly grpc::Marshaller<global::Game.Null> __Marshaller_game_Null = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Null.Parser));
static readonly grpc::Marshaller<global::Google.Protobuf.WellKnownTypes.Empty> __Marshaller_google_protobuf_Empty = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Google.Protobuf.WellKnownTypes.Empty.Parser));
static readonly grpc::Marshaller<global::Game.Name> __Marshaller_game_Name = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Name.Parser));
static readonly grpc::Marshaller<global::Game.UserID> __Marshaller_game_UserID = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.UserID.Parser));
static readonly grpc::Marshaller<global::Game.LobbyCode> __Marshaller_game_LobbyCode = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LobbyCode.Parser));
static readonly grpc::Marshaller<global::Game.LobbyConfig> __Marshaller_game_LobbyConfig = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LobbyConfig.Parser));
static readonly grpc::Marshaller<global::Game.Game> __Marshaller_game_Game = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Game.Parser));
static readonly grpc::Method<global::Game.Null, global::Game.Name> __Method_name = new grpc::Method<global::Game.Null, global::Game.Name>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Name> __Method_name = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Name>(
grpc::MethodType.Unary,
__ServiceName,
"name",
__Marshaller_game_Null,
__Marshaller_google_protobuf_Empty,
__Marshaller_game_Name);
static readonly grpc::Method<global::Game.Name, global::Game.UserID> __Method_connect = new grpc::Method<global::Game.Name, global::Game.UserID>(
@ -66,12 +66,12 @@ namespace Game {
__Marshaller_game_Name,
__Marshaller_game_UserID);
static readonly grpc::Method<global::Game.LobbyCode, global::Game.Null> __Method_joinLobbyWithCode = new grpc::Method<global::Game.LobbyCode, global::Game.Null>(
static readonly grpc::Method<global::Game.LobbyCode, global::Google.Protobuf.WellKnownTypes.Empty> __Method_joinLobbyWithCode = new grpc::Method<global::Game.LobbyCode, global::Google.Protobuf.WellKnownTypes.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"joinLobbyWithCode",
__Marshaller_game_LobbyCode,
__Marshaller_game_Null);
__Marshaller_google_protobuf_Empty);
static readonly grpc::Method<global::Game.LobbyConfig, global::Game.LobbyCode> __Method_createLobby = new grpc::Method<global::Game.LobbyConfig, global::Game.LobbyCode>(
grpc::MethodType.Unary,
@ -80,26 +80,26 @@ namespace Game {
__Marshaller_game_LobbyConfig,
__Marshaller_game_LobbyCode);
static readonly grpc::Method<global::Game.Null, global::Game.Game> __Method_getGames = new grpc::Method<global::Game.Null, global::Game.Game>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Game> __Method_getGames = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Game>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"getGames",
__Marshaller_game_Null,
__Marshaller_google_protobuf_Empty,
__Marshaller_game_Game);
static readonly grpc::Method<global::Game.Null, global::Game.LobbyCode> __Method_getPublicLobbies = new grpc::Method<global::Game.Null, global::Game.LobbyCode>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.LobbyCode> __Method_getPublicLobbies = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.LobbyCode>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"getPublicLobbies",
__Marshaller_game_Null,
__Marshaller_google_protobuf_Empty,
__Marshaller_game_LobbyCode);
static readonly grpc::Method<global::Game.Null, global::Game.Null> __Method_disconnect = new grpc::Method<global::Game.Null, global::Game.Null>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty> __Method_disconnect = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"disconnect",
__Marshaller_game_Null,
__Marshaller_game_Null);
__Marshaller_google_protobuf_Empty,
__Marshaller_google_protobuf_Empty);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@ -111,7 +111,7 @@ namespace Game {
[grpc::BindServiceMethod(typeof(Connection), "BindService")]
public abstract partial class ConnectionBase
{
public virtual global::System.Threading.Tasks.Task<global::Game.Name> name(global::Game.Null request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Game.Name> name(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
@ -121,7 +121,7 @@ namespace Game {
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.Null> joinLobbyWithCode(global::Game.LobbyCode request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Google.Protobuf.WellKnownTypes.Empty> joinLobbyWithCode(global::Game.LobbyCode request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
@ -131,17 +131,17 @@ namespace Game {
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task getGames(global::Game.Null request, grpc::IServerStreamWriter<global::Game.Game> responseStream, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task getGames(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::IServerStreamWriter<global::Game.Game> responseStream, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task getPublicLobbies(global::Game.Null request, grpc::IServerStreamWriter<global::Game.LobbyCode> responseStream, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task getPublicLobbies(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::IServerStreamWriter<global::Game.LobbyCode> responseStream, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.Null> disconnect(global::Game.Null request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Google.Protobuf.WellKnownTypes.Empty> disconnect(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
@ -171,19 +171,19 @@ namespace Game {
{
}
public virtual global::Game.Name name(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Game.Name name(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return name(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Name name(global::Game.Null request, grpc::CallOptions options)
public virtual global::Game.Name name(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_name, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Name> nameAsync(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Game.Name> nameAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return nameAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Name> nameAsync(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Game.Name> nameAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_name, null, options, request);
}
@ -203,19 +203,19 @@ namespace Game {
{
return CallInvoker.AsyncUnaryCall(__Method_connect, null, options, request);
}
public virtual global::Game.Null joinLobbyWithCode(global::Game.LobbyCode request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Google.Protobuf.WellKnownTypes.Empty joinLobbyWithCode(global::Game.LobbyCode request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return joinLobbyWithCode(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Null joinLobbyWithCode(global::Game.LobbyCode request, grpc::CallOptions options)
public virtual global::Google.Protobuf.WellKnownTypes.Empty joinLobbyWithCode(global::Game.LobbyCode request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_joinLobbyWithCode, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> joinLobbyWithCodeAsync(global::Game.LobbyCode request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> joinLobbyWithCodeAsync(global::Game.LobbyCode request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return joinLobbyWithCodeAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> joinLobbyWithCodeAsync(global::Game.LobbyCode request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> joinLobbyWithCodeAsync(global::Game.LobbyCode request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_joinLobbyWithCode, null, options, request);
}
@ -235,35 +235,35 @@ namespace Game {
{
return CallInvoker.AsyncUnaryCall(__Method_createLobby, null, options, request);
}
public virtual grpc::AsyncServerStreamingCall<global::Game.Game> getGames(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncServerStreamingCall<global::Game.Game> getGames(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return getGames(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncServerStreamingCall<global::Game.Game> getGames(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncServerStreamingCall<global::Game.Game> getGames(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncServerStreamingCall(__Method_getGames, null, options, request);
}
public virtual grpc::AsyncServerStreamingCall<global::Game.LobbyCode> getPublicLobbies(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncServerStreamingCall<global::Game.LobbyCode> getPublicLobbies(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return getPublicLobbies(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncServerStreamingCall<global::Game.LobbyCode> getPublicLobbies(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncServerStreamingCall<global::Game.LobbyCode> getPublicLobbies(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncServerStreamingCall(__Method_getPublicLobbies, null, options, request);
}
public virtual global::Game.Null disconnect(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Google.Protobuf.WellKnownTypes.Empty disconnect(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return disconnect(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Null disconnect(global::Game.Null request, grpc::CallOptions options)
public virtual global::Google.Protobuf.WellKnownTypes.Empty disconnect(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_disconnect, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> disconnectAsync(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> disconnectAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return disconnectAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> disconnectAsync(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> disconnectAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_disconnect, null, options, request);
}
@ -294,13 +294,13 @@ namespace Game {
/// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
public static void BindService(grpc::ServiceBinderBase serviceBinder, ConnectionBase serviceImpl)
{
serviceBinder.AddMethod(__Method_name, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.Name>(serviceImpl.name));
serviceBinder.AddMethod(__Method_name, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Name>(serviceImpl.name));
serviceBinder.AddMethod(__Method_connect, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Name, global::Game.UserID>(serviceImpl.connect));
serviceBinder.AddMethod(__Method_joinLobbyWithCode, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.LobbyCode, global::Game.Null>(serviceImpl.joinLobbyWithCode));
serviceBinder.AddMethod(__Method_joinLobbyWithCode, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.LobbyCode, global::Google.Protobuf.WellKnownTypes.Empty>(serviceImpl.joinLobbyWithCode));
serviceBinder.AddMethod(__Method_createLobby, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.LobbyConfig, global::Game.LobbyCode>(serviceImpl.createLobby));
serviceBinder.AddMethod(__Method_getGames, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::Game.Null, global::Game.Game>(serviceImpl.getGames));
serviceBinder.AddMethod(__Method_getPublicLobbies, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::Game.Null, global::Game.LobbyCode>(serviceImpl.getPublicLobbies));
serviceBinder.AddMethod(__Method_disconnect, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.Null>(serviceImpl.disconnect));
serviceBinder.AddMethod(__Method_getGames, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Game>(serviceImpl.getGames));
serviceBinder.AddMethod(__Method_getPublicLobbies, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.LobbyCode>(serviceImpl.getPublicLobbies));
serviceBinder.AddMethod(__Method_disconnect, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty>(serviceImpl.disconnect));
}
}
@ -343,9 +343,11 @@ namespace Game {
static readonly grpc::Marshaller<global::Game.CardID> __Marshaller_game_CardID = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.CardID.Parser));
static readonly grpc::Marshaller<global::Game.Image> __Marshaller_game_Image = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Image.Parser));
static readonly grpc::Marshaller<global::Game.Null> __Marshaller_game_Null = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Null.Parser));
static readonly grpc::Marshaller<global::Google.Protobuf.WellKnownTypes.Empty> __Marshaller_google_protobuf_Empty = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Google.Protobuf.WellKnownTypes.Empty.Parser));
static readonly grpc::Marshaller<global::Game.Name> __Marshaller_game_Name = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Name.Parser));
static readonly grpc::Marshaller<global::Game.Vote> __Marshaller_game_Vote = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Vote.Parser));
static readonly grpc::Marshaller<global::Game.SingleVote> __Marshaller_game_SingleVote = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.SingleVote.Parser));
static readonly grpc::Marshaller<global::Game.LastStatusTimestamp> __Marshaller_game_LastStatusTimestamp = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LastStatusTimestamp.Parser));
static readonly grpc::Marshaller<global::Game.HasNewStatus> __Marshaller_game_HasNewStatus = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.HasNewStatus.Parser));
static readonly grpc::Marshaller<global::Game.LobbyStatus> __Marshaller_game_LobbyStatus = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LobbyStatus.Parser));
static readonly grpc::Method<global::Game.CardID, global::Game.Image> __Method_getCardImage = new grpc::Method<global::Game.CardID, global::Game.Image>(
@ -355,40 +357,47 @@ namespace Game {
__Marshaller_game_CardID,
__Marshaller_game_Image);
static readonly grpc::Method<global::Game.Null, global::Game.Name> __Method_users = new grpc::Method<global::Game.Null, global::Game.Name>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Name> __Method_users = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Name>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"users",
__Marshaller_game_Null,
__Marshaller_google_protobuf_Empty,
__Marshaller_game_Name);
static readonly grpc::Method<global::Game.Vote, global::Game.Null> __Method_vote = new grpc::Method<global::Game.Vote, global::Game.Null>(
static readonly grpc::Method<global::Game.SingleVote, global::Google.Protobuf.WellKnownTypes.Empty> __Method_vote = new grpc::Method<global::Game.SingleVote, global::Google.Protobuf.WellKnownTypes.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"vote",
__Marshaller_game_Vote,
__Marshaller_game_Null);
__Marshaller_game_SingleVote,
__Marshaller_google_protobuf_Empty);
static readonly grpc::Method<global::Game.Null, global::Game.Null> __Method_ready = new grpc::Method<global::Game.Null, global::Game.Null>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty> __Method_ready = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"ready",
__Marshaller_game_Null,
__Marshaller_game_Null);
__Marshaller_google_protobuf_Empty,
__Marshaller_google_protobuf_Empty);
static readonly grpc::Method<global::Game.Null, global::Game.LobbyStatus> __Method_status = new grpc::Method<global::Game.Null, global::Game.LobbyStatus>(
static readonly grpc::Method<global::Game.LastStatusTimestamp, global::Game.HasNewStatus> __Method_hasNewStatus = new grpc::Method<global::Game.LastStatusTimestamp, global::Game.HasNewStatus>(
grpc::MethodType.Unary,
__ServiceName,
"status",
__Marshaller_game_Null,
"hasNewStatus",
__Marshaller_game_LastStatusTimestamp,
__Marshaller_game_HasNewStatus);
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.LobbyStatus> __Method_getStatus = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.LobbyStatus>(
grpc::MethodType.Unary,
__ServiceName,
"getStatus",
__Marshaller_google_protobuf_Empty,
__Marshaller_game_LobbyStatus);
static readonly grpc::Method<global::Game.Null, global::Game.Null> __Method_leave = new grpc::Method<global::Game.Null, global::Game.Null>(
static readonly grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty> __Method_leave = new grpc::Method<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty>(
grpc::MethodType.Unary,
__ServiceName,
"leave",
__Marshaller_game_Null,
__Marshaller_game_Null);
__Marshaller_google_protobuf_Empty,
__Marshaller_google_protobuf_Empty);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@ -405,27 +414,32 @@ namespace Game {
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task users(global::Game.Null request, grpc::IServerStreamWriter<global::Game.Name> responseStream, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task users(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::IServerStreamWriter<global::Game.Name> responseStream, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Google.Protobuf.WellKnownTypes.Empty> vote(global::Game.SingleVote request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.Null> vote(global::Game.Vote request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Google.Protobuf.WellKnownTypes.Empty> ready(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.Null> ready(global::Game.Null request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Game.HasNewStatus> hasNewStatus(global::Game.LastStatusTimestamp request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.LobbyStatus> status(global::Game.Null request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Game.LobbyStatus> getStatus(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.Null> leave(global::Game.Null request, grpc::ServerCallContext context)
public virtual global::System.Threading.Tasks.Task<global::Google.Protobuf.WellKnownTypes.Empty> leave(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
@ -471,75 +485,91 @@ namespace Game {
{
return CallInvoker.AsyncUnaryCall(__Method_getCardImage, null, options, request);
}
public virtual grpc::AsyncServerStreamingCall<global::Game.Name> users(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncServerStreamingCall<global::Game.Name> users(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return users(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncServerStreamingCall<global::Game.Name> users(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncServerStreamingCall<global::Game.Name> users(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncServerStreamingCall(__Method_users, null, options, request);
}
public virtual global::Game.Null vote(global::Game.Vote request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Google.Protobuf.WellKnownTypes.Empty vote(global::Game.SingleVote request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return vote(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Null vote(global::Game.Vote request, grpc::CallOptions options)
public virtual global::Google.Protobuf.WellKnownTypes.Empty vote(global::Game.SingleVote request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_vote, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> voteAsync(global::Game.Vote request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> voteAsync(global::Game.SingleVote request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return voteAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> voteAsync(global::Game.Vote request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> voteAsync(global::Game.SingleVote request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_vote, null, options, request);
}
public virtual global::Game.Null ready(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Google.Protobuf.WellKnownTypes.Empty ready(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return ready(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Null ready(global::Game.Null request, grpc::CallOptions options)
public virtual global::Google.Protobuf.WellKnownTypes.Empty ready(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_ready, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> readyAsync(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> readyAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return readyAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> readyAsync(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> readyAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_ready, null, options, request);
}
public virtual global::Game.LobbyStatus status(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Game.HasNewStatus hasNewStatus(global::Game.LastStatusTimestamp request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return hasNewStatus(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.HasNewStatus hasNewStatus(global::Game.LastStatusTimestamp request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_hasNewStatus, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.HasNewStatus> hasNewStatusAsync(global::Game.LastStatusTimestamp request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return hasNewStatusAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.HasNewStatus> hasNewStatusAsync(global::Game.LastStatusTimestamp request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_hasNewStatus, null, options, request);
}
public virtual global::Game.LobbyStatus getStatus(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return status(request, new grpc::CallOptions(headers, deadline, cancellationToken));
return getStatus(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.LobbyStatus status(global::Game.Null request, grpc::CallOptions options)
public virtual global::Game.LobbyStatus getStatus(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_status, null, options, request);
return CallInvoker.BlockingUnaryCall(__Method_getStatus, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.LobbyStatus> statusAsync(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Game.LobbyStatus> getStatusAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return statusAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
return getStatusAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.LobbyStatus> statusAsync(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Game.LobbyStatus> getStatusAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_status, null, options, request);
return CallInvoker.AsyncUnaryCall(__Method_getStatus, null, options, request);
}
public virtual global::Game.Null leave(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual global::Google.Protobuf.WellKnownTypes.Empty leave(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return leave(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Null leave(global::Game.Null request, grpc::CallOptions options)
public virtual global::Google.Protobuf.WellKnownTypes.Empty leave(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_leave, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> leaveAsync(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> leaveAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return leaveAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> leaveAsync(global::Game.Null request, grpc::CallOptions options)
public virtual grpc::AsyncUnaryCall<global::Google.Protobuf.WellKnownTypes.Empty> leaveAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_leave, null, options, request);
}
@ -559,7 +589,8 @@ namespace Game {
.AddMethod(__Method_users, serviceImpl.users)
.AddMethod(__Method_vote, serviceImpl.vote)
.AddMethod(__Method_ready, serviceImpl.ready)
.AddMethod(__Method_status, serviceImpl.status)
.AddMethod(__Method_hasNewStatus, serviceImpl.hasNewStatus)
.AddMethod(__Method_getStatus, serviceImpl.getStatus)
.AddMethod(__Method_leave, serviceImpl.leave).Build();
}
@ -570,11 +601,12 @@ namespace Game {
public static void BindService(grpc::ServiceBinderBase serviceBinder, LobbyBase serviceImpl)
{
serviceBinder.AddMethod(__Method_getCardImage, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.CardID, global::Game.Image>(serviceImpl.getCardImage));
serviceBinder.AddMethod(__Method_users, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::Game.Null, global::Game.Name>(serviceImpl.users));
serviceBinder.AddMethod(__Method_vote, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Vote, global::Game.Null>(serviceImpl.vote));
serviceBinder.AddMethod(__Method_ready, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.Null>(serviceImpl.ready));
serviceBinder.AddMethod(__Method_status, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.LobbyStatus>(serviceImpl.status));
serviceBinder.AddMethod(__Method_leave, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.Null>(serviceImpl.leave));
serviceBinder.AddMethod(__Method_users, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.Name>(serviceImpl.users));
serviceBinder.AddMethod(__Method_vote, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.SingleVote, global::Google.Protobuf.WellKnownTypes.Empty>(serviceImpl.vote));
serviceBinder.AddMethod(__Method_ready, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty>(serviceImpl.ready));
serviceBinder.AddMethod(__Method_hasNewStatus, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.LastStatusTimestamp, global::Game.HasNewStatus>(serviceImpl.hasNewStatus));
serviceBinder.AddMethod(__Method_getStatus, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Game.LobbyStatus>(serviceImpl.getStatus));
serviceBinder.AddMethod(__Method_leave, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Google.Protobuf.WellKnownTypes.Empty, global::Google.Protobuf.WellKnownTypes.Empty>(serviceImpl.leave));
}
}

8
unity/Assets/Scripts/utils.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 48755fccaa2f939fb8819464be7a3663
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

27
unity/Assets/Scripts/utils/Utilities.cs

@ -0,0 +1,27 @@
using System;
namespace Utilities
{
public class Modifiable<T>{
private DateTime lastModified;
private T value;
public Modifiable(T value) {
lastModified = DateTime.Now.ToUniversalTime();
this.value = value;
}
public void Set(T value) {
lastModified = DateTime.Now.ToUniversalTime();
this.value = value;
}
public T Get() {
return value;
}
public DateTime GetLastModfication() {
return lastModified;
}
}
}

16
unity/omnisharp.json

@ -0,0 +1,16 @@
{
"FormattingOptions": {
"NewLinesForBracesInLambdaExpressionBody": false,
"NewLinesForBracesInAnonymousMethods": false,
"NewLinesForBracesInAnonymousTypes": false,
"NewLinesForBracesInControlBlocks": false,
"NewLinesForBracesInTypes": false,
"NewLinesForBracesInMethods": false,
"NewLinesForBracesInProperties": false,
"NewLinesForBracesInObjectCollectionArrayInitializers": false,
"NewLinesForBracesInAccessors": false,
"NewLineForElse": false,
"NewLineForCatch": false,
"NewLineForFinally": false
}
}
Loading…
Cancel
Save