From e28d2b380cd26b74f9cb5e9a522e98cc93cee56e Mon Sep 17 00:00:00 2001 From: ThePerkinrex Date: Mon, 28 Jun 2021 22:51:11 +0200 Subject: [PATCH] Finish connection service methods --- server/src/server.rs | 52 ++++++++++---- server/src/server/connection.rs | 122 +++++++++++++++++++++++++++----- 2 files changed, 142 insertions(+), 32 deletions(-) diff --git a/server/src/server.rs b/server/src/server.rs index c0609f3..0a3885a 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -10,7 +10,14 @@ use tokio::{ use std::{collections::HashMap, net::SocketAddr, sync::Arc}; -use crate::{db, games::RunningGame, server_properties::ServerProperties}; +use crate::{ + db, + games::RunningGame, + server::connection::{ + connect, create_lobby, disconnect, get_public_lobbies, join_lobby_with_code, name, + }, + server_properties::ServerProperties, +}; use prost::Message; @@ -31,7 +38,9 @@ pub async fn start( games: Vec, properties: crate::server_properties::ServerProperties, ) { - serve(pool, games, properties).await.expect("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") + serve(pool, games, properties) + .await + .expect("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") // let connection = ConnectionService { // conn: RwLock::new(pool.clone().await), // properties: properties.clone(), @@ -111,7 +120,7 @@ pub async fn serve( running_games: running_games.clone(), voting: voting.clone(), addr, - db: pool.clone().await + db: pool.clone().await, }; tokio::spawn(async move { loop { @@ -130,18 +139,30 @@ pub async fn serve( .data .expect("Unexpected data in packet recieved"); use protos::protocol::client_server_packet::Data; - + match packet { // CONNECTION - Data::QueryName(()) => {} - Data::Connect(name) => { - connection::connect(&mut service_data, name).await.expect("Error handling connect") - } - Data::Disconnect(()) => {} - Data::JoinLobby(code) => {} - Data::CreateLobby(config) => {} - Data::QueryGames(()) => {} - Data::QueryPublicLobbies(()) => {} + Data::QueryName(()) => name(&mut service_data) + .await + .expect("Error handling name query"), + Data::Connect(name) => connect(&mut service_data, name) + .await + .expect("Error handling connect"), + Data::Disconnect(()) => disconnect(&mut service_data) + .await + .expect("Error handling disconnect"), + Data::JoinLobby(code) => join_lobby_with_code(&mut service_data, code) + .await + .expect("Error handling join with code"), + Data::CreateLobby(config) => create_lobby(&mut service_data, config) + .await + .expect("Error handling create lobby"), + Data::QueryGames(()) => connection::games(&mut service_data) + .await + .expect("Error handling games query"), + Data::QueryPublicLobbies(()) => get_public_lobbies(&mut service_data) + .await + .expect("Error handling public lobbies query"), // LOBBY Data::QueryUsers(()) => {} @@ -163,13 +184,14 @@ struct MessageWriter { } impl MessageWriter { - async fn write(&mut self, packet: protos::protocol::ServerClientPacket) -> Result<()> { + async fn write(&mut self, packet: protos::protocol::server_client_packet::Data) -> Result<()> { let length = packet.encoded_len(); if length > u32::MAX as usize { panic!("Can't send a message larger than {} bytes", u32::MAX); } let mut data = vec![0u8; length]; - packet.encode(&mut data.as_mut_slice())?; + protos::protocol::ServerClientPacket { data: Some(packet) } + .encode(&mut data.as_mut_slice())?; self.writer .write_all(&(length as u32).to_le_bytes()) diff --git a/server/src/server/connection.rs b/server/src/server/connection.rs index e7deba1..67d1c47 100644 --- a/server/src/server/connection.rs +++ b/server/src/server/connection.rs @@ -2,6 +2,7 @@ use anyhow::Result; use tokio_stream::wrappers::UnboundedReceiverStream; // use tonic::{Request, Response, Status}; +use anyhow::anyhow; use log::info; use tokio::sync::{mpsc, RwLock}; @@ -14,29 +15,119 @@ use super::protos::connection::{Game, LobbyCode, LobbyConfig, UserId}; // pub use super::protos::connection_service::connection_server::ConnectionServer; -use super::{ServiceData, votes}; +use super::protos::protocol::{Games, LobbyCodes}; +use super::{votes, ServiceData}; // use super::client_id; -use crate::server::protos::protocol::ServerClientPacket; use crate::server::protos::protocol::server_client_packet::Data; +use crate::server::protos::protocol::ServerClientPacket; use crate::{db, games::RunningGame}; - pub(super) async fn connect(data: &mut ServiceData, name: Name) -> Result<()> { - // let mut conn = self.conn.acquire().await; - - let uuid = data.db.add_user(name.name.clone()).await?; - info!("Connected {}[{}] from {}", name.name, uuid, data.addr); - data.user_id = Some(uuid); - data.writer.write(ServerClientPacket { - data: Some(Data::ReturnConnect(UserId { - id: uuid.to_string(), - })) - }).await?; - Ok(()) + let uuid = data.db.add_user(name.name.clone()).await?; + info!("Connected {}[{}] from {}", name.name, uuid, data.addr); + data.user_id = Some(uuid); + data.writer + .write(Data::ReturnConnect(UserId { + id: uuid.to_string(), + })) + .await?; + Ok(()) } +pub(super) async fn join_lobby_with_code( + data: &mut ServiceData, + lobby_code: LobbyCode, +) -> Result<()> { + if data + .running_games + .read() + .await + .contains_key(&lobby_code.code) + { + return Err(anyhow!("Can't join a lobby where a game is running")); + } + data.db + .join_lobby( + data.user_id.ok_or(anyhow!("User should have connected"))?, + lobby_code.code, + ) + .await; + data.voting.updated_users(&lobby_code.code).await; + Ok(()) +} + +pub(super) async fn create_lobby(data: &mut ServiceData, config: LobbyConfig) -> Result<()> { + // 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 lobby = data.db.create_lobby(config.public).await; + data.db + .join_lobby( + data.user_id.ok_or(anyhow!("User should have connected"))?, + lobby, + ) + .await; + data.voting.updated_users(&lobby).await; + data.writer + .write(Data::ReturnCreateLobby(LobbyCode { code: lobby })) + .await?; + Ok(()) +} + +pub(super) async fn name(data: &mut ServiceData) -> Result<()> { + data.writer + .write(Data::ReturnName(Name { + name: data.properties.name.clone(), + })) + .await +} + +pub(super) async fn games(data: &mut ServiceData) -> Result<()> { + data.writer + .write(Data::ReturnGames(Games { + games: data + .games + .iter() + .enumerate() + .map(|(id, game)| Game { + id: id as u32, + name: game.name.clone(), + version: game.version.clone(), + authors: game.authors.clone(), + }) + .collect(), + })) + .await?; + Ok(()) +} + +pub(super) async fn get_public_lobbies(data: &mut ServiceData) -> Result<()> { + data.writer + .write(Data::ReturnPublicLobbies(LobbyCodes { + lobby_codes: data + .db + .get_public_lobbies() + .await + .into_iter() + .map(|code| LobbyCode { code }) + .collect(), + })) + .await +} + +pub(super) async fn disconnect(data: &mut ServiceData) -> Result<()> { + data.db + .disconnect( + data.user_id + .ok_or(anyhow!("Expected user to be connected"))?, + ) + .await; + // log::warn!("Disconnected"); + Ok(()) +} // pub struct ConnectionService { // pub conn: RwLock, @@ -46,9 +137,6 @@ pub(super) async fn connect(data: &mut ServiceData, name: Name) -> Result<()> { // pub voting: votes::VotingSystem, // } - - - // #[tonic::async_trait] // impl Connection for ConnectionService { // async fn connect(&self, request: Request) -> Result, Status> {