Browse Source

Finish connection service methods

new_protocol
ThePerkinrex 5 years ago
parent
commit
e28d2b380c
No known key found for this signature in database GPG Key ID: FD81DE6D75E20917
  1. 52
      server/src/server.rs
  2. 122
      server/src/server/connection.rs

52
server/src/server.rs

@ -10,7 +10,14 @@ use tokio::{
use std::{collections::HashMap, net::SocketAddr, sync::Arc}; 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; use prost::Message;
@ -31,7 +38,9 @@ pub async fn start(
games: Vec<crate::games::Game>, games: Vec<crate::games::Game>,
properties: crate::server_properties::ServerProperties, properties: crate::server_properties::ServerProperties,
) { ) {
serve(pool, games, properties).await.expect("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") serve(pool, games, properties)
.await
.expect("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
// let connection = ConnectionService { // let connection = ConnectionService {
// conn: RwLock::new(pool.clone().await), // conn: RwLock::new(pool.clone().await),
// properties: properties.clone(), // properties: properties.clone(),
@ -111,7 +120,7 @@ pub async fn serve(
running_games: running_games.clone(), running_games: running_games.clone(),
voting: voting.clone(), voting: voting.clone(),
addr, addr,
db: pool.clone().await db: pool.clone().await,
}; };
tokio::spawn(async move { tokio::spawn(async move {
loop { loop {
@ -130,18 +139,30 @@ pub async fn serve(
.data .data
.expect("Unexpected data in packet recieved"); .expect("Unexpected data in packet recieved");
use protos::protocol::client_server_packet::Data; use protos::protocol::client_server_packet::Data;
match packet { match packet {
// CONNECTION // CONNECTION
Data::QueryName(()) => {} Data::QueryName(()) => name(&mut service_data)
Data::Connect(name) => { .await
connection::connect(&mut service_data, name).await.expect("Error handling connect") .expect("Error handling name query"),
} Data::Connect(name) => connect(&mut service_data, name)
Data::Disconnect(()) => {} .await
Data::JoinLobby(code) => {} .expect("Error handling connect"),
Data::CreateLobby(config) => {} Data::Disconnect(()) => disconnect(&mut service_data)
Data::QueryGames(()) => {} .await
Data::QueryPublicLobbies(()) => {} .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 // LOBBY
Data::QueryUsers(()) => {} Data::QueryUsers(()) => {}
@ -163,13 +184,14 @@ struct MessageWriter {
} }
impl 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(); let length = packet.encoded_len();
if length > u32::MAX as usize { if length > u32::MAX as usize {
panic!("Can't send a message larger than {} bytes", u32::MAX); panic!("Can't send a message larger than {} bytes", u32::MAX);
} }
let mut data = vec![0u8; length]; 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 self.writer
.write_all(&(length as u32).to_le_bytes()) .write_all(&(length as u32).to_le_bytes())

122
server/src/server/connection.rs

@ -2,6 +2,7 @@ use anyhow::Result;
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
// use tonic::{Request, Response, Status}; // use tonic::{Request, Response, Status};
use anyhow::anyhow;
use log::info; use log::info;
use tokio::sync::{mpsc, RwLock}; 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; // 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 super::client_id;
use crate::server::protos::protocol::ServerClientPacket;
use crate::server::protos::protocol::server_client_packet::Data; use crate::server::protos::protocol::server_client_packet::Data;
use crate::server::protos::protocol::ServerClientPacket;
use crate::{db, games::RunningGame}; use crate::{db, games::RunningGame};
pub(super) async fn connect(data: &mut ServiceData, name: Name) -> Result<()> { 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);
let uuid = data.db.add_user(name.name.clone()).await?; data.user_id = Some(uuid);
info!("Connected {}[{}] from {}", name.name, uuid, data.addr); data.writer
data.user_id = Some(uuid); .write(Data::ReturnConnect(UserId {
data.writer.write(ServerClientPacket { id: uuid.to_string(),
data: Some(Data::ReturnConnect(UserId { }))
id: uuid.to_string(), .await?;
})) Ok(())
}).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 struct ConnectionService {
// pub conn: RwLock<db::DbClient>, // pub conn: RwLock<db::DbClient>,
@ -46,9 +137,6 @@ pub(super) async fn connect(data: &mut ServiceData, name: Name) -> Result<()> {
// pub voting: votes::VotingSystem, // pub voting: votes::VotingSystem,
// } // }
// #[tonic::async_trait] // #[tonic::async_trait]
// impl Connection for ConnectionService { // impl Connection for ConnectionService {
// async fn connect(&self, request: Request<Name>) -> Result<Response<UserId>, Status> { // async fn connect(&self, request: Request<Name>) -> Result<Response<UserId>, Status> {

Loading…
Cancel
Save