From 054a2bfe069ed4118d2f9fd1f01428632049057b Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 22:38:25 +0200 Subject: Add a client handling system --- game_server/src/backend_connection.rs | 21 +++++++++++++--- game_server/src/group.rs | 8 +++++- game_server/src/lobby.rs | 30 ++++++++++++++++++++-- game_server/src/main.rs | 4 +-- game_server/src/scribble_group.rs | 42 +++++++++++++++++++++++++++++++ game_server/src/server.rs | 47 +++++++++++++++++++---------------- game_server/src/test_group.rs | 28 --------------------- 7 files changed, 122 insertions(+), 58 deletions(-) create mode 100644 game_server/src/scribble_group.rs delete mode 100644 game_server/src/test_group.rs (limited to 'game_server/src') diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index ed112d9..e1844ee 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,7 +1,8 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use super::server::Token; +use super::server::{UserId, Token}; +use super::group::GroupId; pub struct BackendConnection { host: String, @@ -18,10 +19,17 @@ pub enum BackendError { BadResponse(Response), } -pub type TokenValidity = Result<(), BackendError>; +pub type TokenValidity = Result; pub type RequestData = Url; pub type ResponseResult = Result; +pub struct TokenResponse { + pub group_id: GroupId, + pub group_type: String, + pub group_name: String, + pub user_id: UserId, +} + impl BackendConnection { fn run_background(req_rec: Receiver, res_sender: Sender) { let client = Client::new(); @@ -60,7 +68,14 @@ impl BackendConnection { self.request(&location).map_err(|err| BackendError::UrlError(err))?; let response = self.get_response().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { - Ok(()) + // zu Testzwecken werden noch keine JSON-Daten deserialisiert + // Dennis Server gibt ja noch nix zurück + Ok(TokenResponse { + group_id: 12, + group_type: "scribble".to_string(), + group_name: "Scribble".to_string(), + user_id: 420 + }) } else if response.status() == reqwest::StatusCode::NOT_FOUND { Err(BackendError::InvalidToken) } else if response.status().is_client_error() { diff --git a/game_server/src/group.rs b/game_server/src/group.rs index 55e4fbf..6356a14 100644 --- a/game_server/src/group.rs +++ b/game_server/src/group.rs @@ -1,8 +1,14 @@ +use super::server::{UserId, GameClient}; + pub type GroupId = u32; pub trait Group { fn id(&self) -> GroupId; + fn group_type(&self) -> String; fn name(&self) -> String; - fn run(&self); + fn run(&mut self); + + fn add_client(&mut self, id: UserId, client: GameClient); + fn get_client(&self, client_id: UserId) -> Option<&GameClient>; } diff --git a/game_server/src/lobby.rs b/game_server/src/lobby.rs index fe3bdee..d03bd45 100644 --- a/game_server/src/lobby.rs +++ b/game_server/src/lobby.rs @@ -1,23 +1,49 @@ use std::collections::HashMap; use super::group::{Group, GroupId}; +use super::scribble_group::ScribbleGroup; + +use super::server::{UserId, GameClient}; pub struct Lobby { groups: HashMap>, } impl Lobby { - pub fn new() -> Lobby { + pub fn new() -> Self { Self { groups: HashMap::new(), } } + fn generate_group(group_type: &str, id: GroupId, name: &str) -> Option> { + match group_type { + "scribble" => { + Some(Box::new(ScribbleGroup::new(id, name.to_string()))) + }, + other => None, + } + } + pub fn add_group(&mut self, group: Box) { self.groups.insert(group.id(), group); } - pub fn iter<'a>(&'a self) -> GroupIterator<'a> { + pub fn add_client(&mut self, group_type: &str, group_id: GroupId, group_name: &str, + user_id: UserId, client: GameClient) { + if !self.groups.contains_key(&group_id) { + let mut group = match Self::generate_group(group_type, group_id, group_name) { + Some(x) => x, + _ => return, + }; + group.run(); + self.groups.insert(group_id, group); + } + let group = self.groups.get_mut(&group_id).unwrap(); + group.add_client(user_id, client); + } + + pub fn iter<'b>(&'b self) -> GroupIterator<'b> { GroupIterator { groups: self.groups.values() } } } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 628062e..8ff8f97 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,5 +1,5 @@ mod group; -mod test_group; +mod scribble_group; mod lobby; mod server; mod backend_connection; @@ -13,7 +13,7 @@ fn main() { let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); - let gameserver = server::GameServer::new(addr); + let mut gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); } diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs new file mode 100644 index 0000000..c240264 --- /dev/null +++ b/game_server/src/scribble_group.rs @@ -0,0 +1,42 @@ +use super::group::{Group, GroupId}; +use super::server::{UserId, GameClient}; +use std::collections::HashMap; + +pub struct ScribbleGroup { + id: GroupId, + name: String, + clients: HashMap +} + +impl Group for ScribbleGroup { + fn id(&self) -> GroupId { + self.id + } + + fn group_type(&self) -> String { + "scribble".to_string() + } + + fn name(&self) -> String { + self.name.clone() + } + + fn run(&mut self) { + info!("a new group {}:'{}' runs now", self.id, self.name); + } + + fn add_client(&mut self, id: UserId, client: GameClient) { + debug!("user {} joined the group {}:'{}'", id, self.id, self.name); + self.clients.insert(id, client); + } + + fn get_client(&self, client_id: UserId) -> Option<&GameClient> { + self.clients.get(&client_id) + } +} + +impl ScribbleGroup { + pub fn new(id: GroupId, name: String) -> Self { + Self { id, name, clients: HashMap::new() } + } +} diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 7a9c5b0..c87594b 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -14,6 +14,7 @@ use super::backend_connection::BackendConnection; const PROTOCOL: &str = "tuesday"; pub type Token = u32; +pub type UserId = u32; #[derive(Debug)] pub enum GameServerError { @@ -26,8 +27,7 @@ pub enum GameServerError { pub struct GameServer { addr: SocketAddr, lobby: Lobby, - backend: Arc>, - clients: Arc>>, + backend: BackendConnection, } pub struct GameClient { @@ -73,13 +73,12 @@ impl GameServer { info!("got a C# backend connection"); GameServer { addr, - lobby, - backend: Arc::new(Mutex::new(backend)), - clients: Arc::new(Mutex::new(HashMap::new())), + lobby: lobby, + backend: backend, } } - pub fn run(&self) -> Result<(), GameServerError> { + pub fn run(&mut self) -> Result<(), GameServerError> { let reader = self.read_clients(); loop { let connection = reader.recv().unwrap()?; @@ -87,25 +86,29 @@ impl GameServer { } } - fn add_client(&self, mut client: GameClient) { - let clients = Arc::clone(&self.clients); - let backend = Arc::clone(&self.backend); - std::thread::spawn(move || { - let token = client.require_token(); - if let Some(token) = token { - let locked_backend = backend.lock().unwrap(); - let result = locked_backend.validate_token(&token); - if let Err(err) = result { - warn!("client's token {} is not valid: '{:?}'", token, err); - } else { + fn add_client(&mut self, mut client: GameClient) { + let token = client.require_token(); + if let Some(token) = token { + let result = self.backend.validate_token(&token); + match result { + Err(err) => warn!("client's token {} is not valid: '{:?}'", + token, err), + Ok(result) => { debug!("client validation was successfull"); - debug!("add client: ({}, {})", token, client.host_name()); - clients.lock().unwrap().insert(token, client); + let user_id = result.user_id; + let group_id = result.group_id; + let group_type = result.group_type; + let group_name = result.group_name; + debug!("add client: (id:{}, token:{}, host:{}) to \"{}\"", + user_id, token, client.host_name(), group_name); + //clients.lock().unwrap().insert(token, client); + self.lobby.add_client(&group_type, group_id, + &group_name, user_id, client); } - } else { - warn!("client sent invalid token"); } - }); + } else { + warn!("client sent invalid token"); + } } fn read_clients(&self) -> Receiver { diff --git a/game_server/src/test_group.rs b/game_server/src/test_group.rs deleted file mode 100644 index bd570e3..0000000 --- a/game_server/src/test_group.rs +++ /dev/null @@ -1,28 +0,0 @@ -use super::group::{Group, GroupId}; - -pub struct TestGroup { - id: GroupId, - name: String, -} - -impl Group for TestGroup { - fn id(&self) -> GroupId { - self.id - } - - fn name(&self) -> String { - self.name.clone() - } - - fn run(&self) { - let id = self.id; - let name = self.name.to_owned(); - std::thread::spawn(move || /*loop { println!("> group nr.{} wishes you: '{}'", id, name) }*/()); - } -} - -impl TestGroup { - pub fn new(id: GroupId, name: String) -> Self { - TestGroup { id, name } - } -} -- cgit v1.2.3-54-g00ecf