diff --git a/protobuf/game.proto b/protobuf/game.proto index 7015037..e929e6b 100644 --- a/protobuf/game.proto +++ b/protobuf/game.proto @@ -44,6 +44,7 @@ message HasNewStatus { message LastStatusTimestamp { google.protobuf.Timestamp time = 1; + uint32 lobby = 2; } message CardID { diff --git a/server/Cargo.toml b/server/Cargo.toml index 48329e6..e49667c 100644 --- a/server/Cargo.toml +++ b/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" diff --git a/server/src/db.rs b/server/src/db.rs index 4cea89b..95ccb14 100644 --- a/server/src/db.rs +++ b/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, +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) -> 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(&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 { - 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 { + 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 { - 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 { + 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 { - 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 { + 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>(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) -// } -// } \ No newline at end of file diff --git a/server/src/db/types.rs b/server/src/db/types.rs deleted file mode 100644 index 4118956..0000000 --- a/server/src/db/types.rs +++ /dev/null @@ -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 { - 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) - } -} \ No newline at end of file diff --git a/server/src/main.rs b/server/src/main.rs index 3e45b85..ec24c1d 100644 --- a/server/src/main.rs +++ b/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(); diff --git a/server/src/server.rs b/server/src/server.rs index 93b6765..6526a8a 100644 --- a/server/src/server.rs +++ b/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, 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)) diff --git a/server/src/server/connection.rs b/server/src/server/connection.rs index 2ac6573..86200b8 100644 --- a/server/src/server/connection.rs +++ b/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, + pub conn: RwLock, pub properties: Arc, pub games: Arc>, + pub voting: votes::VotingSystem, } #[tonic::async_trait] impl Connection for ConnectionService { async fn connect(&self, request: Request) -> Result, 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, 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(())) } } \ No newline at end of file diff --git a/server/src/server/grpc/game.rs b/server/src/server/grpc/game.rs index 75988e3..bbf039c 100644 --- a/server/src/server/grpc/game.rs +++ b/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 { diff --git a/server/src/server/lobby.rs b/server/src/server/lobby.rs index 067ed50..a09ffea 100644 --- a/server/src/server/lobby.rs +++ b/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, + conn: RwLock, games: Arc>, voting: votes::VotingSystem, } impl LobbyService { - pub fn new(conn: Arc, games: Arc>) -> Self { + pub fn new(conn: db::DbClient, games: Arc>, 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>; - - // async fn subscribe_to_status( - // &self, - // request: Request<()>, - // ) -> Result, 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, ) -> Result, 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, 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(); } diff --git a/server/src/server/lobby/votes.rs b/server/src/server/votes.rs similarity index 62% rename from server/src/server/lobby/votes.rs rename to server/src/server/votes.rs index e75fa57..de3ff3f 100644 --- a/server/src/server/lobby/votes.rs +++ b/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 { value: T, last_modified: SystemTime, @@ -16,10 +17,14 @@ struct Modifiable { impl Modifiable { 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 Modifiable { &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, + conn: Arc>, // games: Arc>, // broadcast: broadcast::Sender, - last_status: Arc>>>>> + last_status: Arc>>>>>, } impl VotingSystem { pub fn new( - conn: Arc, + conn: db::DbClient, // games: Arc>, ) -> 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 { 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; } } -} \ No newline at end of file +} diff --git a/unity/.gitignore b/unity/.gitignore index 8af868e..1537ec6 100644 --- a/unity/.gitignore +++ b/unity/.gitignore @@ -47,6 +47,7 @@ ExportedObj/ *.pidb.meta *.pdb.meta *.mdb.meta +*.cs.meta # Unity3D generated file on crash reports sysinfo.txt diff --git a/unity/Assets/Scripts/Client.cs b/unity/Assets/Scripts/Client.cs index 7173b91..00447ba 100644 --- a/unity/Assets/Scripts/Client.cs +++ b/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 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(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 GetUsersInSameLobby(){ - AsyncServerStreamingCall stream = lobby_client.users(new Game.Null(), new Metadata { new Metadata.Entry("client_id", connId) }); + public List GetUsersInSameLobby() { + AsyncServerStreamingCall stream = lobby_client.users(new Google.Protobuf.WellKnownTypes.Empty(), new Metadata { new Metadata.Entry("client_id", connId) }); List l = new List(); - 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 GetPublicLobbies() { - AsyncServerStreamingCall stream = connection.getPublicLobbies(new Game.Null()); + AsyncServerStreamingCall stream = connection.getPublicLobbies(new Google.Protobuf.WellKnownTypes.Empty()); List l = new List(); - 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 GetGames() - { - AsyncServerStreamingCall stream = connection.getGames(new Game.Null()); + public List GetGames() { + AsyncServerStreamingCall stream = connection.getGames(new Google.Protobuf.WellKnownTypes.Empty()); List l = new List(); - 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(Task task) - { + static T runSync(Task 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(); } } diff --git a/unity/Assets/Scripts/Editor/BuildProtos.cs b/unity/Assets/Scripts/Editor/BuildProtos.cs index 32ced0a..9e7c29f 100644 --- a/unity/Assets/Scripts/Editor/BuildProtos.cs +++ b/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(); diff --git a/unity/Assets/Scripts/MainMenuController.cs b/unity/Assets/Scripts/MainMenuController.cs index 8bc6a35..1671eec 100644 --- a/unity/Assets/Scripts/MainMenuController.cs +++ b/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 { diff --git a/unity/Assets/Scripts/Utils.cs b/unity/Assets/Scripts/Utils.cs index 9672f15..c3811d2 100644 --- a/unity/Assets/Scripts/Utils.cs +++ b/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) { diff --git a/unity/Assets/Scripts/grpc/Game.cs b/unity/Assets/Scripts/grpc/Game.cs index f537513..55436fb 100644 --- a/unity/Assets/Scripts/grpc/Game.cs +++ b/unity/Assets/Scripts/grpc/Game.cs @@ -24,42 +24,52 @@ namespace Game { static GameReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "CgpnYW1lLnByb3RvEgRnYW1lIhQKBlVzZXJJRBIKCgJpZBgBIAEoCSIUCgRO", - "YW1lEgwKBG5hbWUYASABKAkiHQoLTG9iYnlDb25maWcSDgoGcHVibGljGAEg", - "ASgIIgYKBE51bGwiKAoGQ2FyZElEEg4KBmdhbWVJZBgBIAEoDRIOCgZjYXJk", - "SWQYAiABKAkiGAoFSW1hZ2USDwoHY29udGVudBgBIAEoDCIZCglMb2JieUNv", - "ZGUSDAoEY29kZRgBIAEoDSJCCgRHYW1lEgwKBG5hbWUYASABKAkSDwoHdmVy", - "c2lvbhgCIAEoCRIPCgdhdXRob3JzGAMgAygJEgoKAmlkGAQgASgNIhIKBFZv", - "dGUSCgoCaWQYASABKAQiWQoLTG9iYnlTdGF0dXMSGQoFdm90ZXMYASADKAsy", - "Ci5nYW1lLlZvdGUSGwoFcmVhZHkYAiADKAsyDC5nYW1lLlBsYXllchISCgpp", - "c1N0YXJ0aW5nGAMgASgIIiIKBlBsYXllchIMCgRuYW1lGAEgASgJEgoKAmlk", - "GAIgASgNMrUCCgpDb25uZWN0aW9uEh4KBG5hbWUSCi5nYW1lLk51bGwaCi5n", - "YW1lLk5hbWUSIwoHY29ubmVjdBIKLmdhbWUuTmFtZRoMLmdhbWUuVXNlcklE", - "EjAKEWpvaW5Mb2JieVdpdGhDb2RlEg8uZ2FtZS5Mb2JieUNvZGUaCi5nYW1l", - "Lk51bGwSMQoLY3JlYXRlTG9iYnkSES5nYW1lLkxvYmJ5Q29uZmlnGg8uZ2Ft", - "ZS5Mb2JieUNvZGUSJAoIZ2V0R2FtZXMSCi5nYW1lLk51bGwaCi5nYW1lLkdh", - "bWUwARIxChBnZXRQdWJsaWNMb2JiaWVzEgouZ2FtZS5OdWxsGg8uZ2FtZS5M", - "b2JieUNvZGUwARIkCgpkaXNjb25uZWN0EgouZ2FtZS5OdWxsGgouZ2FtZS5O", - "dWxsMuABCgVMb2JieRIpCgxnZXRDYXJkSW1hZ2USDC5nYW1lLkNhcmRJRBoL", - "LmdhbWUuSW1hZ2USIQoFdXNlcnMSCi5nYW1lLk51bGwaCi5nYW1lLk5hbWUw", - "ARIeCgR2b3RlEgouZ2FtZS5Wb3RlGgouZ2FtZS5OdWxsEh8KBXJlYWR5Egou", - "Z2FtZS5OdWxsGgouZ2FtZS5OdWxsEicKBnN0YXR1cxIKLmdhbWUuTnVsbBoR", - "LmdhbWUuTG9iYnlTdGF0dXMSHwoFbGVhdmUSCi5nYW1lLk51bGwaCi5nYW1l", - "Lk51bGxiBnByb3RvMw==")); + "CgpnYW1lLnByb3RvEgRnYW1lGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1w", + "LnByb3RvGhtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8iFAoGVXNlcklE", + "EgoKAmlkGAEgASgJIhQKBE5hbWUSDAoEbmFtZRgBIAEoCSIdCgtMb2JieUNv", + "bmZpZxIOCgZwdWJsaWMYASABKAgiHQoMSGFzTmV3U3RhdHVzEg0KBXZhbHVl", + "GAEgASgIIk4KE0xhc3RTdGF0dXNUaW1lc3RhbXASKAoEdGltZRgBIAEoCzIa", + "Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDQoFbG9iYnkYAiABKA0iKAoG", + "Q2FyZElEEg4KBmdhbWVJZBgBIAEoDRIOCgZjYXJkSWQYAiABKAkiGAoFSW1h", + "Z2USDwoHY29udGVudBgBIAEoDCIZCglMb2JieUNvZGUSDAoEY29kZRgBIAEo", + "DSJCCgRHYW1lEgwKBG5hbWUYASABKAkSDwoHdmVyc2lvbhgCIAEoCRIPCgdh", + "dXRob3JzGAMgAygJEgoKAmlkGAQgASgNIjMKBFZvdGUSDgoGcGxheWVyGAEg", + "ASgJEgwKBGdhbWUYAiABKA0SDQoFcmVhZHkYAyABKAgiGgoKU2luZ2xlVm90", + "ZRIMCgRnYW1lGAIgASgNIlcKC0xvYmJ5U3RhdHVzEhkKBW5hbWVzGAEgAygL", + "MgouZ2FtZS5OYW1lEhkKBXZvdGVzGAIgAygLMgouZ2FtZS5Wb3RlEhIKCmlz", + "U3RhcnRpbmcYAyABKAgy/QIKCkNvbm5lY3Rpb24SKgoEbmFtZRIWLmdvb2ds", + "ZS5wcm90b2J1Zi5FbXB0eRoKLmdhbWUuTmFtZRIjCgdjb25uZWN0EgouZ2Ft", + "ZS5OYW1lGgwuZ2FtZS5Vc2VySUQSPAoRam9pbkxvYmJ5V2l0aENvZGUSDy5n", + "YW1lLkxvYmJ5Q29kZRoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRIxCgtjcmVh", + "dGVMb2JieRIRLmdhbWUuTG9iYnlDb25maWcaDy5nYW1lLkxvYmJ5Q29kZRIw", + "CghnZXRHYW1lcxIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRoKLmdhbWUuR2Ft", + "ZTABEj0KEGdldFB1YmxpY0xvYmJpZXMSFi5nb29nbGUucHJvdG9idWYuRW1w", + "dHkaDy5nYW1lLkxvYmJ5Q29kZTABEjwKCmRpc2Nvbm5lY3QSFi5nb29nbGUu", + "cHJvdG9idWYuRW1wdHkaFi5nb29nbGUucHJvdG9idWYuRW1wdHky/AIKBUxv", + "YmJ5EikKDGdldENhcmRJbWFnZRIMLmdhbWUuQ2FyZElEGgsuZ2FtZS5JbWFn", + "ZRItCgV1c2VycxIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRoKLmdhbWUuTmFt", + "ZTABEjAKBHZvdGUSEC5nYW1lLlNpbmdsZVZvdGUaFi5nb29nbGUucHJvdG9i", + "dWYuRW1wdHkSNwoFcmVhZHkSFi5nb29nbGUucHJvdG9idWYuRW1wdHkaFi5n", + "b29nbGUucHJvdG9idWYuRW1wdHkSPQoMaGFzTmV3U3RhdHVzEhkuZ2FtZS5M", + "YXN0U3RhdHVzVGltZXN0YW1wGhIuZ2FtZS5IYXNOZXdTdGF0dXMSNgoJZ2V0", + "U3RhdHVzEhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5GhEuZ2FtZS5Mb2JieVN0", + "YXR1cxI3CgVsZWF2ZRIWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eRoWLmdvb2ds", + "ZS5wcm90b2J1Zi5FbXB0eWIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { }, + new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Game.UserID), global::Game.UserID.Parser, new[]{ "Id" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.Name), global::Game.Name.Parser, new[]{ "Name_" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.LobbyConfig), global::Game.LobbyConfig.Parser, new[]{ "Public" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Game.Null), global::Game.Null.Parser, null, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Game.HasNewStatus), global::Game.HasNewStatus.Parser, new[]{ "Value" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Game.LastStatusTimestamp), global::Game.LastStatusTimestamp.Parser, new[]{ "Time", "Lobby" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.CardID), global::Game.CardID.Parser, new[]{ "GameId", "CardId" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.Image), global::Game.Image.Parser, new[]{ "Content" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.LobbyCode), global::Game.LobbyCode.Parser, new[]{ "Code" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Game.Game), global::Game.Game.Parser, new[]{ "Name", "Version", "Authors", "Id" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Game.Vote), global::Game.Vote.Parser, new[]{ "Id" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Game.LobbyStatus), global::Game.LobbyStatus.Parser, new[]{ "Votes", "Ready", "IsStarting" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Game.Player), global::Game.Player.Parser, new[]{ "Name", "Id" }, null, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Game.Vote), global::Game.Vote.Parser, new[]{ "Player", "Game", "Ready" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Game.SingleVote), global::Game.SingleVote.Parser, new[]{ "Game" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Game.LobbyStatus), global::Game.LobbyStatus.Parser, new[]{ "Names", "Votes", "IsStarting" }, null, null, null, null) })); } #endregion @@ -585,15 +595,15 @@ namespace Game { } - public sealed partial class Null : pb::IMessage + public sealed partial class HasNewStatus : pb::IMessage #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE , pb::IBufferMessage #endif { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Null()); + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HasNewStatus()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } + public static pb::MessageParser Parser { get { return _parser; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { @@ -606,41 +616,241 @@ namespace Game { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Null() { + public HasNewStatus() { OnConstruction(); } partial void OnConstruction(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Null(Null other) : this() { + public HasNewStatus(HasNewStatus other) : this() { + value_ = other.value_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Null Clone() { - return new Null(this); + public HasNewStatus Clone() { + return new HasNewStatus(this); + } + + /// Field number for the "value" field. + public const int ValueFieldNumber = 1; + private bool value_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Value { + get { return value_; } + set { + value_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as HasNewStatus); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(HasNewStatus other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Value != other.Value) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Value != false) hash ^= Value.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Value != false) { + size += 1 + 1; + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(HasNewStatus other) { + if (other == null) { + return; + } + if (other.Value != false) { + Value = other.Value; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + + } + + public sealed partial class LastStatusTimestamp : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new LastStatusTimestamp()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Game.GameReflection.Descriptor.MessageTypes[4]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public LastStatusTimestamp() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public LastStatusTimestamp(LastStatusTimestamp other) : this() { + time_ = other.time_ != null ? other.time_.Clone() : null; + lobby_ = other.lobby_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public LastStatusTimestamp Clone() { + return new LastStatusTimestamp(this); + } + + /// Field number for the "time" field. + public const int TimeFieldNumber = 1; + private global::Google.Protobuf.WellKnownTypes.Timestamp time_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.WellKnownTypes.Timestamp Time { + get { return time_; } + set { + time_ = value; + } + } + + /// Field number for the "lobby" field. + public const int LobbyFieldNumber = 2; + private uint lobby_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public uint Lobby { + get { return lobby_; } + set { + lobby_ = value; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { - return Equals(other as Null); + return Equals(other as LastStatusTimestamp); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Null other) { + public bool Equals(LastStatusTimestamp other) { if (ReferenceEquals(other, null)) { return false; } if (ReferenceEquals(other, this)) { return true; } + if (!object.Equals(Time, other.Time)) return false; + if (Lobby != other.Lobby) return false; return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; + if (time_ != null) hash ^= Time.GetHashCode(); + if (Lobby != 0) hash ^= Lobby.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -657,6 +867,14 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE output.WriteRawMessage(this); #else + if (time_ != null) { + output.WriteRawTag(10); + output.WriteMessage(Time); + } + if (Lobby != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Lobby); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -666,6 +884,14 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (time_ != null) { + output.WriteRawTag(10); + output.WriteMessage(Time); + } + if (Lobby != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Lobby); + } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); } @@ -675,6 +901,12 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; + if (time_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Time); + } + if (Lobby != 0) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Lobby); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -682,10 +914,19 @@ namespace Game { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Null other) { + public void MergeFrom(LastStatusTimestamp other) { if (other == null) { return; } + if (other.time_ != null) { + if (time_ == null) { + Time = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + } + Time.MergeFrom(other.Time); + } + if (other.Lobby != 0) { + Lobby = other.Lobby; + } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -700,6 +941,17 @@ namespace Game { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; + case 10: { + if (time_ == null) { + Time = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + } + input.ReadMessage(Time); + break; + } + case 16: { + Lobby = input.ReadUInt32(); + break; + } } } #endif @@ -714,6 +966,17 @@ namespace Game { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; + case 10: { + if (time_ == null) { + Time = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + } + input.ReadMessage(Time); + break; + } + case 16: { + Lobby = input.ReadUInt32(); + break; + } } } } @@ -733,7 +996,7 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[4]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[5]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -941,7 +1204,7 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[5]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[6]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1113,7 +1376,7 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[6]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[7]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1285,7 +1548,7 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[7]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[8]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1554,7 +1817,7 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[8]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[9]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1571,7 +1834,9 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Vote(Vote other) : this() { - id_ = other.id_; + player_ = other.player_; + game_ = other.game_; + ready_ = other.ready_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -1580,14 +1845,36 @@ namespace Game { return new Vote(this); } - /// Field number for the "id" field. - public const int IdFieldNumber = 1; - private ulong id_; + /// Field number for the "player" field. + public const int PlayerFieldNumber = 1; + private string player_ = ""; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public ulong Id { - get { return id_; } + public string Player { + get { return player_; } set { - id_ = value; + player_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "game" field. + public const int GameFieldNumber = 2; + private uint game_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public uint Game { + get { return game_; } + set { + game_ = value; + } + } + + /// Field number for the "ready" field. + public const int ReadyFieldNumber = 3; + private bool ready_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Ready { + get { return ready_; } + set { + ready_ = value; } } @@ -1604,14 +1891,18 @@ namespace Game { if (ReferenceEquals(other, this)) { return true; } - if (Id != other.Id) return false; + if (Player != other.Player) return false; + if (Game != other.Game) return false; + if (Ready != other.Ready) return false; return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (Id != 0UL) hash ^= Id.GetHashCode(); + if (Player.Length != 0) hash ^= Player.GetHashCode(); + if (Game != 0) hash ^= Game.GetHashCode(); + if (Ready != false) hash ^= Ready.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -1628,9 +1919,17 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE output.WriteRawMessage(this); #else - if (Id != 0UL) { - output.WriteRawTag(8); - output.WriteUInt64(Id); + if (Player.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Player); + } + if (Game != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Game); + } + if (Ready != false) { + output.WriteRawTag(24); + output.WriteBool(Ready); } if (_unknownFields != null) { _unknownFields.WriteTo(output); @@ -1641,9 +1940,17 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { - if (Id != 0UL) { - output.WriteRawTag(8); - output.WriteUInt64(Id); + if (Player.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Player); + } + if (Game != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Game); + } + if (Ready != false) { + output.WriteRawTag(24); + output.WriteBool(Ready); } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); @@ -1654,8 +1961,14 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (Id != 0UL) { - size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Id); + if (Player.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Player); + } + if (Game != 0) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Game); + } + if (Ready != false) { + size += 1 + 1; } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); @@ -1668,8 +1981,14 @@ namespace Game { if (other == null) { return; } - if (other.Id != 0UL) { - Id = other.Id; + if (other.Player.Length != 0) { + Player = other.Player; + } + if (other.Game != 0) { + Game = other.Game; + } + if (other.Ready != false) { + Ready = other.Ready; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1685,8 +2004,16 @@ namespace Game { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; - case 8: { - Id = input.ReadUInt64(); + case 10: { + Player = input.ReadString(); + break; + } + case 16: { + Game = input.ReadUInt32(); + break; + } + case 24: { + Ready = input.ReadBool(); break; } } @@ -1703,8 +2030,16 @@ namespace Game { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; - case 8: { - Id = input.ReadUInt64(); + case 10: { + Player = input.ReadString(); + break; + } + case 16: { + Game = input.ReadUInt32(); + break; + } + case 24: { + Ready = input.ReadBool(); break; } } @@ -1714,19 +2049,19 @@ namespace Game { } - public sealed partial class LobbyStatus : pb::IMessage + public sealed partial class SingleVote : pb::IMessage #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE , pb::IBufferMessage #endif { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new LobbyStatus()); + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SingleVote()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } + public static pb::MessageParser Parser { get { return _parser; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[9]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[10]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1735,81 +2070,55 @@ namespace Game { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public LobbyStatus() { + public SingleVote() { OnConstruction(); } partial void OnConstruction(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public LobbyStatus(LobbyStatus other) : this() { - votes_ = other.votes_.Clone(); - ready_ = other.ready_.Clone(); - isStarting_ = other.isStarting_; + public SingleVote(SingleVote other) : this() { + game_ = other.game_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public LobbyStatus Clone() { - return new LobbyStatus(this); + public SingleVote Clone() { + return new SingleVote(this); } - /// Field number for the "votes" field. - public const int VotesFieldNumber = 1; - private static readonly pb::FieldCodec _repeated_votes_codec - = pb::FieldCodec.ForMessage(10, global::Game.Vote.Parser); - private readonly pbc::RepeatedField votes_ = new pbc::RepeatedField(); + /// Field number for the "game" field. + public const int GameFieldNumber = 2; + private uint game_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public pbc::RepeatedField Votes { - get { return votes_; } - } - - /// Field number for the "ready" field. - public const int ReadyFieldNumber = 2; - private static readonly pb::FieldCodec _repeated_ready_codec - = pb::FieldCodec.ForMessage(18, global::Game.Player.Parser); - private readonly pbc::RepeatedField ready_ = new pbc::RepeatedField(); - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public pbc::RepeatedField Ready { - get { return ready_; } - } - - /// Field number for the "isStarting" field. - public const int IsStartingFieldNumber = 3; - private bool isStarting_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool IsStarting { - get { return isStarting_; } + public uint Game { + get { return game_; } set { - isStarting_ = value; + game_ = value; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { - return Equals(other as LobbyStatus); + return Equals(other as SingleVote); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(LobbyStatus other) { + public bool Equals(SingleVote other) { if (ReferenceEquals(other, null)) { return false; } if (ReferenceEquals(other, this)) { return true; } - if(!votes_.Equals(other.votes_)) return false; - if(!ready_.Equals(other.ready_)) return false; - if (IsStarting != other.IsStarting) return false; + if (Game != other.Game) return false; return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - hash ^= votes_.GetHashCode(); - hash ^= ready_.GetHashCode(); - if (IsStarting != false) hash ^= IsStarting.GetHashCode(); + if (Game != 0) hash ^= Game.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -1826,11 +2135,9 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE output.WriteRawMessage(this); #else - votes_.WriteTo(output, _repeated_votes_codec); - ready_.WriteTo(output, _repeated_ready_codec); - if (IsStarting != false) { - output.WriteRawTag(24); - output.WriteBool(IsStarting); + if (Game != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Game); } if (_unknownFields != null) { _unknownFields.WriteTo(output); @@ -1841,11 +2148,9 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { - votes_.WriteTo(ref output, _repeated_votes_codec); - ready_.WriteTo(ref output, _repeated_ready_codec); - if (IsStarting != false) { - output.WriteRawTag(24); - output.WriteBool(IsStarting); + if (Game != 0) { + output.WriteRawTag(16); + output.WriteUInt32(Game); } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); @@ -1856,10 +2161,8 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - size += votes_.CalculateSize(_repeated_votes_codec); - size += ready_.CalculateSize(_repeated_ready_codec); - if (IsStarting != false) { - size += 1 + 1; + if (Game != 0) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Game); } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); @@ -1868,14 +2171,12 @@ namespace Game { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(LobbyStatus other) { + public void MergeFrom(SingleVote other) { if (other == null) { return; } - votes_.Add(other.votes_); - ready_.Add(other.ready_); - if (other.IsStarting != false) { - IsStarting = other.IsStarting; + if (other.Game != 0) { + Game = other.Game; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1891,16 +2192,8 @@ namespace Game { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; - case 10: { - votes_.AddEntriesFrom(input, _repeated_votes_codec); - break; - } - case 18: { - ready_.AddEntriesFrom(input, _repeated_ready_codec); - break; - } - case 24: { - IsStarting = input.ReadBool(); + case 16: { + Game = input.ReadUInt32(); break; } } @@ -1917,16 +2210,8 @@ namespace Game { default: _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; - case 10: { - votes_.AddEntriesFrom(ref input, _repeated_votes_codec); - break; - } - case 18: { - ready_.AddEntriesFrom(ref input, _repeated_ready_codec); - break; - } - case 24: { - IsStarting = input.ReadBool(); + case 16: { + Game = input.ReadUInt32(); break; } } @@ -1936,19 +2221,19 @@ namespace Game { } - public sealed partial class Player : pb::IMessage + public sealed partial class LobbyStatus : pb::IMessage #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE , pb::IBufferMessage #endif { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Player()); + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new LobbyStatus()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } + public static pb::MessageParser Parser { get { return _parser; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Game.GameReflection.Descriptor.MessageTypes[10]; } + get { return global::Game.GameReflection.Descriptor.MessageTypes[11]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1957,69 +2242,81 @@ namespace Game { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Player() { + public LobbyStatus() { OnConstruction(); } partial void OnConstruction(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Player(Player other) : this() { - name_ = other.name_; - id_ = other.id_; + public LobbyStatus(LobbyStatus other) : this() { + names_ = other.names_.Clone(); + votes_ = other.votes_.Clone(); + isStarting_ = other.isStarting_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Player Clone() { - return new Player(this); + public LobbyStatus Clone() { + return new LobbyStatus(this); } - /// Field number for the "name" field. - public const int NameFieldNumber = 1; - private string name_ = ""; + /// Field number for the "names" field. + public const int NamesFieldNumber = 1; + private static readonly pb::FieldCodec _repeated_names_codec + = pb::FieldCodec.ForMessage(10, global::Game.Name.Parser); + private readonly pbc::RepeatedField names_ = new pbc::RepeatedField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string Name { - get { return name_; } - set { - name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } + public pbc::RepeatedField Names { + get { return names_; } } - /// Field number for the "id" field. - public const int IdFieldNumber = 2; - private uint id_; + /// Field number for the "votes" field. + public const int VotesFieldNumber = 2; + private static readonly pb::FieldCodec _repeated_votes_codec + = pb::FieldCodec.ForMessage(18, global::Game.Vote.Parser); + private readonly pbc::RepeatedField votes_ = new pbc::RepeatedField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public uint Id { - get { return id_; } + public pbc::RepeatedField Votes { + get { return votes_; } + } + + /// Field number for the "isStarting" field. + public const int IsStartingFieldNumber = 3; + private bool isStarting_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool IsStarting { + get { return isStarting_; } set { - id_ = value; + isStarting_ = value; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { - return Equals(other as Player); + return Equals(other as LobbyStatus); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Player other) { + public bool Equals(LobbyStatus other) { if (ReferenceEquals(other, null)) { return false; } if (ReferenceEquals(other, this)) { return true; } - if (Name != other.Name) return false; - if (Id != other.Id) return false; + if(!names_.Equals(other.names_)) return false; + if(!votes_.Equals(other.votes_)) return false; + if (IsStarting != other.IsStarting) return false; return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (Name.Length != 0) hash ^= Name.GetHashCode(); - if (Id != 0) hash ^= Id.GetHashCode(); + hash ^= names_.GetHashCode(); + hash ^= votes_.GetHashCode(); + if (IsStarting != false) hash ^= IsStarting.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -2036,13 +2333,11 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE output.WriteRawMessage(this); #else - if (Name.Length != 0) { - output.WriteRawTag(10); - output.WriteString(Name); - } - if (Id != 0) { - output.WriteRawTag(16); - output.WriteUInt32(Id); + names_.WriteTo(output, _repeated_names_codec); + votes_.WriteTo(output, _repeated_votes_codec); + if (IsStarting != false) { + output.WriteRawTag(24); + output.WriteBool(IsStarting); } if (_unknownFields != null) { _unknownFields.WriteTo(output); @@ -2053,13 +2348,11 @@ namespace Game { #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { - if (Name.Length != 0) { - output.WriteRawTag(10); - output.WriteString(Name); - } - if (Id != 0) { - output.WriteRawTag(16); - output.WriteUInt32(Id); + names_.WriteTo(ref output, _repeated_names_codec); + votes_.WriteTo(ref output, _repeated_votes_codec); + if (IsStarting != false) { + output.WriteRawTag(24); + output.WriteBool(IsStarting); } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); @@ -2070,11 +2363,10 @@ namespace Game { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (Name.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); - } - if (Id != 0) { - size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Id); + size += names_.CalculateSize(_repeated_names_codec); + size += votes_.CalculateSize(_repeated_votes_codec); + if (IsStarting != false) { + size += 1 + 1; } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); @@ -2083,15 +2375,14 @@ namespace Game { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Player other) { + public void MergeFrom(LobbyStatus other) { if (other == null) { return; } - if (other.Name.Length != 0) { - Name = other.Name; - } - if (other.Id != 0) { - Id = other.Id; + names_.Add(other.names_); + votes_.Add(other.votes_); + if (other.IsStarting != false) { + IsStarting = other.IsStarting; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -2108,11 +2399,15 @@ namespace Game { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { - Name = input.ReadString(); + names_.AddEntriesFrom(input, _repeated_names_codec); break; } - case 16: { - Id = input.ReadUInt32(); + case 18: { + votes_.AddEntriesFrom(input, _repeated_votes_codec); + break; + } + case 24: { + IsStarting = input.ReadBool(); break; } } @@ -2130,11 +2425,15 @@ namespace Game { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 10: { - Name = input.ReadString(); + names_.AddEntriesFrom(ref input, _repeated_names_codec); break; } - case 16: { - Id = input.ReadUInt32(); + case 18: { + votes_.AddEntriesFrom(ref input, _repeated_votes_codec); + break; + } + case 24: { + IsStarting = input.ReadBool(); break; } } diff --git a/unity/Assets/Scripts/grpc/GameGrpc.cs b/unity/Assets/Scripts/grpc/GameGrpc.cs index 4eee091..7eb166c 100644 --- a/unity/Assets/Scripts/grpc/GameGrpc.cs +++ b/unity/Assets/Scripts/grpc/GameGrpc.cs @@ -45,18 +45,18 @@ namespace Game { return parser.ParseFrom(context.PayloadAsNewBuffer()); } - static readonly grpc::Marshaller __Marshaller_game_Null = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Null.Parser)); + static readonly grpc::Marshaller __Marshaller_google_protobuf_Empty = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Google.Protobuf.WellKnownTypes.Empty.Parser)); static readonly grpc::Marshaller __Marshaller_game_Name = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Name.Parser)); static readonly grpc::Marshaller __Marshaller_game_UserID = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.UserID.Parser)); static readonly grpc::Marshaller __Marshaller_game_LobbyCode = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LobbyCode.Parser)); static readonly grpc::Marshaller __Marshaller_game_LobbyConfig = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LobbyConfig.Parser)); static readonly grpc::Marshaller __Marshaller_game_Game = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Game.Parser)); - static readonly grpc::Method __Method_name = new grpc::Method( + static readonly grpc::Method __Method_name = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "name", - __Marshaller_game_Null, + __Marshaller_google_protobuf_Empty, __Marshaller_game_Name); static readonly grpc::Method __Method_connect = new grpc::Method( @@ -66,12 +66,12 @@ namespace Game { __Marshaller_game_Name, __Marshaller_game_UserID); - static readonly grpc::Method __Method_joinLobbyWithCode = new grpc::Method( + static readonly grpc::Method __Method_joinLobbyWithCode = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "joinLobbyWithCode", __Marshaller_game_LobbyCode, - __Marshaller_game_Null); + __Marshaller_google_protobuf_Empty); static readonly grpc::Method __Method_createLobby = new grpc::Method( grpc::MethodType.Unary, @@ -80,26 +80,26 @@ namespace Game { __Marshaller_game_LobbyConfig, __Marshaller_game_LobbyCode); - static readonly grpc::Method __Method_getGames = new grpc::Method( + static readonly grpc::Method __Method_getGames = new grpc::Method( grpc::MethodType.ServerStreaming, __ServiceName, "getGames", - __Marshaller_game_Null, + __Marshaller_google_protobuf_Empty, __Marshaller_game_Game); - static readonly grpc::Method __Method_getPublicLobbies = new grpc::Method( + static readonly grpc::Method __Method_getPublicLobbies = new grpc::Method( grpc::MethodType.ServerStreaming, __ServiceName, "getPublicLobbies", - __Marshaller_game_Null, + __Marshaller_google_protobuf_Empty, __Marshaller_game_LobbyCode); - static readonly grpc::Method __Method_disconnect = new grpc::Method( + static readonly grpc::Method __Method_disconnect = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "disconnect", - __Marshaller_game_Null, - __Marshaller_game_Null); + __Marshaller_google_protobuf_Empty, + __Marshaller_google_protobuf_Empty); /// Service descriptor 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 name(global::Game.Null request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 joinLobbyWithCode(global::Game.LobbyCode request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 responseStream, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task getGames(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::IServerStreamWriter 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 responseStream, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task getPublicLobbies(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) { throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); } - public virtual global::System.Threading.Tasks.Task disconnect(global::Game.Null request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 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 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 nameAsync(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall 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 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 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 joinLobbyWithCodeAsync(global::Game.LobbyCode request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall 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 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 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 getGames(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncServerStreamingCall getGames(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options) { return CallInvoker.AsyncServerStreamingCall(__Method_getGames, null, options, request); } - public virtual grpc::AsyncServerStreamingCall 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 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 getPublicLobbies(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncServerStreamingCall 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 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 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 disconnectAsync(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall disconnectAsync(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::CallOptions options) { return CallInvoker.AsyncUnaryCall(__Method_disconnect, null, options, request); } @@ -294,13 +294,13 @@ namespace Game { /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, ConnectionBase serviceImpl) { - serviceBinder.AddMethod(__Method_name, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.name)); + serviceBinder.AddMethod(__Method_name, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.name)); serviceBinder.AddMethod(__Method_connect, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.connect)); - serviceBinder.AddMethod(__Method_joinLobbyWithCode, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.joinLobbyWithCode)); + serviceBinder.AddMethod(__Method_joinLobbyWithCode, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.joinLobbyWithCode)); serviceBinder.AddMethod(__Method_createLobby, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.createLobby)); - serviceBinder.AddMethod(__Method_getGames, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.getGames)); - serviceBinder.AddMethod(__Method_getPublicLobbies, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.getPublicLobbies)); - serviceBinder.AddMethod(__Method_disconnect, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.disconnect)); + serviceBinder.AddMethod(__Method_getGames, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.getGames)); + serviceBinder.AddMethod(__Method_getPublicLobbies, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.getPublicLobbies)); + serviceBinder.AddMethod(__Method_disconnect, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.disconnect)); } } @@ -343,9 +343,11 @@ namespace Game { static readonly grpc::Marshaller __Marshaller_game_CardID = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.CardID.Parser)); static readonly grpc::Marshaller __Marshaller_game_Image = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Image.Parser)); - static readonly grpc::Marshaller __Marshaller_game_Null = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Null.Parser)); + static readonly grpc::Marshaller __Marshaller_google_protobuf_Empty = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Google.Protobuf.WellKnownTypes.Empty.Parser)); static readonly grpc::Marshaller __Marshaller_game_Name = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Name.Parser)); - static readonly grpc::Marshaller __Marshaller_game_Vote = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.Vote.Parser)); + static readonly grpc::Marshaller __Marshaller_game_SingleVote = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.SingleVote.Parser)); + static readonly grpc::Marshaller __Marshaller_game_LastStatusTimestamp = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LastStatusTimestamp.Parser)); + static readonly grpc::Marshaller __Marshaller_game_HasNewStatus = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.HasNewStatus.Parser)); static readonly grpc::Marshaller __Marshaller_game_LobbyStatus = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Game.LobbyStatus.Parser)); static readonly grpc::Method __Method_getCardImage = new grpc::Method( @@ -355,40 +357,47 @@ namespace Game { __Marshaller_game_CardID, __Marshaller_game_Image); - static readonly grpc::Method __Method_users = new grpc::Method( + static readonly grpc::Method __Method_users = new grpc::Method( grpc::MethodType.ServerStreaming, __ServiceName, "users", - __Marshaller_game_Null, + __Marshaller_google_protobuf_Empty, __Marshaller_game_Name); - static readonly grpc::Method __Method_vote = new grpc::Method( + static readonly grpc::Method __Method_vote = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "vote", - __Marshaller_game_Vote, - __Marshaller_game_Null); + __Marshaller_game_SingleVote, + __Marshaller_google_protobuf_Empty); - static readonly grpc::Method __Method_ready = new grpc::Method( + static readonly grpc::Method __Method_ready = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "ready", - __Marshaller_game_Null, - __Marshaller_game_Null); + __Marshaller_google_protobuf_Empty, + __Marshaller_google_protobuf_Empty); - static readonly grpc::Method __Method_status = new grpc::Method( + static readonly grpc::Method __Method_hasNewStatus = new grpc::Method( grpc::MethodType.Unary, __ServiceName, - "status", - __Marshaller_game_Null, + "hasNewStatus", + __Marshaller_game_LastStatusTimestamp, + __Marshaller_game_HasNewStatus); + + static readonly grpc::Method __Method_getStatus = new grpc::Method( + grpc::MethodType.Unary, + __ServiceName, + "getStatus", + __Marshaller_google_protobuf_Empty, __Marshaller_game_LobbyStatus); - static readonly grpc::Method __Method_leave = new grpc::Method( + static readonly grpc::Method __Method_leave = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "leave", - __Marshaller_game_Null, - __Marshaller_game_Null); + __Marshaller_google_protobuf_Empty, + __Marshaller_google_protobuf_Empty); /// Service descriptor 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 responseStream, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task users(global::Google.Protobuf.WellKnownTypes.Empty request, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) + { + throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); + } + + public virtual global::System.Threading.Tasks.Task 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 vote(global::Game.Vote request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 ready(global::Game.Null request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 status(global::Game.Null request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 leave(global::Game.Null request, grpc::ServerCallContext context) + public virtual global::System.Threading.Tasks.Task 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 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 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 users(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncServerStreamingCall 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 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 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 voteAsync(global::Game.Vote request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall 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 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 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 readyAsync(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall 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 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 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 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 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 statusAsync(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall 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 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 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 leaveAsync(global::Game.Null request, grpc::CallOptions options) + public virtual grpc::AsyncUnaryCall 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(serviceImpl.getCardImage)); - serviceBinder.AddMethod(__Method_users, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.users)); - serviceBinder.AddMethod(__Method_vote, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.vote)); - serviceBinder.AddMethod(__Method_ready, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.ready)); - serviceBinder.AddMethod(__Method_status, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.status)); - serviceBinder.AddMethod(__Method_leave, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.leave)); + serviceBinder.AddMethod(__Method_users, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.users)); + serviceBinder.AddMethod(__Method_vote, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.vote)); + serviceBinder.AddMethod(__Method_ready, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.ready)); + serviceBinder.AddMethod(__Method_hasNewStatus, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.hasNewStatus)); + serviceBinder.AddMethod(__Method_getStatus, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.getStatus)); + serviceBinder.AddMethod(__Method_leave, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.leave)); } } diff --git a/unity/Assets/Scripts/utils.meta b/unity/Assets/Scripts/utils.meta new file mode 100644 index 0000000..f8014c4 --- /dev/null +++ b/unity/Assets/Scripts/utils.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 48755fccaa2f939fb8819464be7a3663 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Assets/Scripts/utils/Utilities.cs b/unity/Assets/Scripts/utils/Utilities.cs new file mode 100644 index 0000000..e71b301 --- /dev/null +++ b/unity/Assets/Scripts/utils/Utilities.cs @@ -0,0 +1,27 @@ +using System; + +namespace Utilities +{ + public class Modifiable{ + 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; + } + } +} \ No newline at end of file diff --git a/unity/omnisharp.json b/unity/omnisharp.json new file mode 100644 index 0000000..6048437 --- /dev/null +++ b/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 + } +} \ No newline at end of file