Browse Source

Add leave lobby

new_protocol
ThePerkinrex 5 years ago
parent
commit
b9ab4e5ade
No known key found for this signature in database GPG Key ID: 1F45A7C4BFB41607
  1. 1
      protobuf/game.proto
  2. 18
      server/src/db.rs
  3. 17
      server/src/grpc.rs
  4. 32
      server/src/grpc/game.rs
  5. 2
      server/src/logger.rs
  6. 9
      unity/Assets/Scripts/Client.cs
  7. 4
      unity/Assets/Scripts/MainMenuController.cs
  8. 5
      unity/Assets/Scripts/grpc/Game.cs
  9. 32
      unity/Assets/Scripts/grpc/GameGrpc.cs

1
protobuf/game.proto

@ -20,6 +20,7 @@ service Lobby {
rpc vote(Vote) returns(Null);
rpc ready(Null) returns(Null);
rpc status(Null) returns(LobbyStatus);
rpc leave (Null) returns (Null);
}
message UserID { string id = 1; }

18
server/src/db.rs

@ -71,6 +71,8 @@ impl DbConnection {
pub async fn create_lobby(&mut self, public: bool) -> u32 {
let id = rand::random();
log::info!("Created the lobby {}", id);
self.conn
.execute(query_unchecked!(
"INSERT INTO Lobbies(id, public) VALUES(?, ?)",
@ -83,6 +85,7 @@ impl DbConnection {
}
pub async fn join_lobby(&mut self, user: Uuid, lobby: u32) {
log::info!("{} joined the lobby {}", user, lobby);
self.conn
.execute(query_unchecked!(
"INSERT INTO UsersInLobbies(UserId, LobbyId) VALUES(?, ?)",
@ -93,8 +96,15 @@ impl DbConnection {
.unwrap(); // Server crashes if ids collide
}
pub async fn close(self) {
self.conn.close().await.unwrap();
pub async fn leave(&mut self, user: Uuid) {
log::info!("{} leaving the lobby", user);
self.conn
.execute(query_unchecked!(
"DELETE FROM UsersInLobbies WHERE UserId = ?",
user.as_bytes().to_vec(),
))
.await
.unwrap();
}
pub async fn getPublicLobbies(&mut self) -> Vec<u32> {
@ -103,4 +113,8 @@ impl DbConnection {
.await
.unwrap().into_iter().map(|(x,)| x as u32).collect()
}
pub async fn close(self) {
self.conn.close().await.unwrap();
}
}

17
server/src/grpc.rs

@ -98,7 +98,7 @@ impl Connection for ConnectionService {
.send(Ok(LobbyCode{code: id}))
.unwrap();
}
conn.close();
conn.close().await;
Ok(Response::new(receiver))
}
}
@ -138,6 +138,17 @@ impl Lobby for LobbyService {
async fn status(&self, _request: Request<Null>) -> Result<Response<game::LobbyStatus>, Status> {
todo!()
}
async fn leave(&self, request: tonic::Request<Null>) -> Result<tonic::Response<Null>, tonic::Status> {
let uuid = client_id::get(request.metadata()).map_err(|x| match x {
client_id::Error::NotSet => Status::failed_precondition("client_id must be set"),
client_id::Error::MalformedUuid => Status::failed_precondition("malformed client_id"),
})?;
let mut conn = self.conn.acquire().await;
conn.leave(uuid).await;
conn.close().await;
Ok(Response::new(Null{}))
}
}
pub async fn start(
@ -150,7 +161,7 @@ pub async fn start(
let games = Arc::new(games);
let connection = ConnectionService {
conn: arc.clone(),
properties,
properties: properties.clone(),
games: games.clone(),
};
let lobby = LobbyService {
@ -161,7 +172,7 @@ pub async fn start(
Server::builder()
.add_service(ConnectionServer::new(connection))
.add_service(LobbyServer::new(lobby))
.serve("0.0.0.0:50052".parse().unwrap())
.serve(properties.addr)
.await
.unwrap();
}

32
server/src/grpc/game.rs

@ -371,6 +371,10 @@ pub mod lobby_server {
&self,
request: tonic::Request<super::Null>,
) -> Result<tonic::Response<super::LobbyStatus>, tonic::Status>;
async fn leave(
&self,
request: tonic::Request<super::Null>,
) -> Result<tonic::Response<super::Null>, tonic::Status>;
}
#[doc = " Lobby functionality (client_id required for most of them)"]
#[derive(Debug)]
@ -517,6 +521,34 @@ pub mod lobby_server {
};
Box::pin(fut)
}
"/game.Lobby/leave" => {
#[allow(non_camel_case_types)]
struct leaveSvc<T: Lobby>(pub Arc<T>);
impl<T: Lobby> tonic::server::UnaryService<super::Null> for leaveSvc<T> {
type Response = super::Null;
type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
fn call(&mut self, request: tonic::Request<super::Null>) -> Self::Future {
let inner = self.0.clone();
let fut = async move { (*inner).leave(request).await };
Box::pin(fut)
}
}
let inner = self.inner.clone();
let fut = async move {
let interceptor = inner.1.clone();
let inner = inner.0;
let method = leaveSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = if let Some(interceptor) = interceptor {
tonic::server::Grpc::with_interceptor(codec, interceptor)
} else {
tonic::server::Grpc::new(codec)
};
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
_ => Box::pin(async move {
Ok(http::Response::builder()
.status(200)

2
server/src/logger.rs

@ -55,7 +55,7 @@ pub fn setup(
fern::Dispatch::new()
.level(log::LevelFilter::Debug)
.level_for("h2::codec", log::LevelFilter::Info)
.level_for("h2", log::LevelFilter::Info)
.level_for("tokio::codec", log::LevelFilter::Info)
.level_for("sqlx::query", log::LevelFilter::Info)
.chain(stdout_logger)

9
unity/Assets/Scripts/Client.cs

@ -68,7 +68,12 @@ public static class Client
}
}
public List<string> getPublicLobbies() {
public void LeaveLobby() {
lobby_client.leave(new Game.Null(), new Metadata { new Metadata.Entry("client_id", connId) });
lobby = null;
}
public List<string> GetPublicLobbies() {
AsyncServerStreamingCall<Game.LobbyCode> stream = connection.getPublicLobbies(new Game.Null());
List<string> l = new List<string>();
@ -82,7 +87,7 @@ public static class Client
return l;
}
public List<Game.Game> getGames()
public List<Game.Game> GetGames()
{
AsyncServerStreamingCall<Game.Game> stream = connection.getGames(new Game.Null());
List<Game.Game> l = new List<Game.Game>();

4
unity/Assets/Scripts/MainMenuController.cs

@ -140,7 +140,7 @@ public class MainMenuController : MonoBehaviour {
// Simulate Lobbies in a Server
var conn = Client.GetConnection();
if(conn != null) {
foreach(string lobby in conn.getPublicLobbies()) {
foreach(string lobby in conn.GetPublicLobbies()) {
Debug.Log(lobby);
}
// conn.Close();
@ -160,7 +160,7 @@ public class MainMenuController : MonoBehaviour {
// Add Lobby Games to list when function exists
var conn = Client.GetConnection();
if(conn != null) {
var games = conn.getGames();
var games = conn.GetGames();
foreach(Game.Game game in games) {
var gameGO = Instantiate(lobbyScroll.transform.GetChild(0), lobbyScroll.transform);
gameGO.GetComponentsInChildren<Text>()[0].text = game.Name;

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

@ -39,10 +39,11 @@ namespace Game {
"Lk51bGwSMQoLY3JlYXRlTG9iYnkSES5nYW1lLkxvYmJ5Q29uZmlnGg8uZ2Ft",
"ZS5Mb2JieUNvZGUSJAoIZ2V0R2FtZXMSCi5nYW1lLk51bGwaCi5nYW1lLkdh",
"bWUwARIxChBnZXRQdWJsaWNMb2JiaWVzEgouZ2FtZS5OdWxsGg8uZ2FtZS5M",
"b2JieUNvZGUwATKcAQoFTG9iYnkSKQoMZ2V0Q2FyZEltYWdlEgwuZ2FtZS5D",
"b2JieUNvZGUwATK9AQoFTG9iYnkSKQoMZ2V0Q2FyZEltYWdlEgwuZ2FtZS5D",
"YXJkSUQaCy5nYW1lLkltYWdlEh4KBHZvdGUSCi5nYW1lLlZvdGUaCi5nYW1l",
"Lk51bGwSHwoFcmVhZHkSCi5nYW1lLk51bGwaCi5nYW1lLk51bGwSJwoGc3Rh",
"dHVzEgouZ2FtZS5OdWxsGhEuZ2FtZS5Mb2JieVN0YXR1c2IGcHJvdG8z"));
"dHVzEgouZ2FtZS5OdWxsGhEuZ2FtZS5Mb2JieVN0YXR1cxIfCgVsZWF2ZRIK",
"LmdhbWUuTnVsbBoKLmdhbWUuTnVsbGIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {

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

@ -345,6 +345,13 @@ namespace Game {
__Marshaller_game_Null,
__Marshaller_game_LobbyStatus);
static readonly grpc::Method<global::Game.Null, global::Game.Null> __Method_leave = new grpc::Method<global::Game.Null, global::Game.Null>(
grpc::MethodType.Unary,
__ServiceName,
"leave",
__Marshaller_game_Null,
__Marshaller_game_Null);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
{
@ -375,6 +382,11 @@ namespace Game {
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
public virtual global::System.Threading.Tasks.Task<global::Game.Null> leave(global::Game.Null request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
}
/// <summary>Client for Lobby</summary>
@ -464,6 +476,22 @@ namespace Game {
{
return CallInvoker.AsyncUnaryCall(__Method_status, 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))
{
return leave(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual global::Game.Null leave(global::Game.Null request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_leave, null, options, request);
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> leaveAsync(global::Game.Null request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return leaveAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
public virtual grpc::AsyncUnaryCall<global::Game.Null> leaveAsync(global::Game.Null request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_leave, null, options, request);
}
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
protected override LobbyClient NewInstance(ClientBaseConfiguration configuration)
{
@ -479,7 +507,8 @@ namespace Game {
.AddMethod(__Method_getCardImage, serviceImpl.getCardImage)
.AddMethod(__Method_vote, serviceImpl.vote)
.AddMethod(__Method_ready, serviceImpl.ready)
.AddMethod(__Method_status, serviceImpl.status).Build();
.AddMethod(__Method_status, serviceImpl.status)
.AddMethod(__Method_leave, serviceImpl.leave).Build();
}
/// <summary>Register service method with a service binder with or without implementation. Useful when customizing the service binding logic.
@ -492,6 +521,7 @@ namespace Game {
serviceBinder.AddMethod(__Method_vote, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Vote, global::Game.Null>(serviceImpl.vote));
serviceBinder.AddMethod(__Method_ready, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.Null>(serviceImpl.ready));
serviceBinder.AddMethod(__Method_status, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.LobbyStatus>(serviceImpl.status));
serviceBinder.AddMethod(__Method_leave, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Game.Null, global::Game.Null>(serviceImpl.leave));
}
}

Loading…
Cancel
Save