diff options
Diffstat (limited to 'game_server')
-rw-r--r-- | game_server/Cargo.toml | 3 | ||||
-rwxr-xr-x | game_server/build.sh | 21 | ||||
-rw-r--r-- | game_server/err | 73 | ||||
-rw-r--r-- | game_server/rbuild.sh | 2 | ||||
-rw-r--r-- | game_server/src/backend_connection.rs | 57 | ||||
-rw-r--r-- | game_server/src/game_logger.rs | 29 | ||||
-rw-r--r-- | game_server/src/gameserver.rs | 33 | ||||
-rw-r--r-- | game_server/src/main.rs | 5 |
8 files changed, 106 insertions, 117 deletions
diff --git a/game_server/Cargo.toml b/game_server/Cargo.toml index 97c0e77..bc14942 100644 --- a/game_server/Cargo.toml +++ b/game_server/Cargo.toml @@ -7,7 +7,8 @@ description = "A general game server for connections to web clients. Currently ( [dependencies] log = "0.4" -pretty_env_logger = "0.3" +fern = "0.5.8" +colored = "1.8" reqwest = "0.9" websocket = "0.22" hyper = "0.10" diff --git a/game_server/build.sh b/game_server/build.sh deleted file mode 100755 index 1eb61a1..0000000 --- a/game_server/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env sh - -case $1 in - ("") - if rustup run stable cargo --color always build; then - echo build success! - RUST_LOG=debug target/debug/game-server - else - echo build failed! - fi - ;; - -r) - sh build.sh &> err && cat err | tac - ;; - -c) - rustup run stable cargo clean - ;; - *) - echo invalid argument - ;; -esac diff --git a/game_server/err b/game_server/err deleted file mode 100644 index 6ca8a6f..0000000 --- a/game_server/err +++ /dev/null @@ -1,73 +0,0 @@ -[0m[0m[1m[32m Compiling[0m game-server v0.1.0 (/home/jan/projects/DiscoBot/game_server) -[0m[1m[38;5;9merror[E0277][0m[0m[1m: the trait bound `(): futures::future::Future` is not satisfied[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:32:24[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m32[0m[0m [0m[0m[1m[38;5;12m| [0m[0m hyper::rt::run(hyper::rt::lazy(|| {[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^^[0m[0m [0m[0m[1m[38;5;9mthe trait `futures::future::Future` is not implemented for `()`[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required by `futures::future::lazy::lazy`[0m - -[0m[1m[38;5;9merror[E0599][0m[0m[1m: no method named `wait` found for type `std::result::Result<futures::future::map_err::MapErr<futures::future::map::Map<hyper::client::ResponseFuture, [closure@src/backend_connection.rs:54:34: 54:68]>, [closure@src/backend_connection.rs:55:38: 55:73]>, http::uri::InvalidUri>` in the current scope[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:56:24[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m56[0m[0m [0m[0m[1m[38;5;12m| [0m[0m }).wait();[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: the method `wait` exists but the following trait bounds were not satisfied:[0m -[0m `&mut std::result::Result<futures::future::map_err::MapErr<futures::future::map::Map<hyper::client::ResponseFuture, [closure@src/backend_connection.rs:54:34: 54:68]>, [closure@src/backend_connection.rs:55:38: 55:73]>, http::uri::InvalidUri> : futures::future::Future`[0m - -[0m[1m[38;5;9merror[E0308][0m[0m[1m: mismatched types[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:58:17[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m58[0m[0m [0m[0m[1m[38;5;12m| [0m[0m res[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^[0m[0m [0m[0m[1m[38;5;9mexpected (), found enum `std::result::Result`[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: expected type `[0m[0m[1m()[0m[0m`[0m -[0m found type `[0m[0m[1mstd::result::Result<http::response::Response<hyper::body::body::Body>, http::uri::InvalidUri>[0m[0m`[0m - -[0m[1m[38;5;9merror[E0277][0m[0m[1m: the trait bound `(): futures::future::Future` is not satisfied[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:32:24[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m32[0m[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m hyper::rt::run(hyper::rt::lazy(|| {[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m________________________^[0m -[0m[1m[38;5;12m33[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m let client = hyper::Client::builder()[0m -[0m[1m[38;5;12m34[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m .build::<_, hyper::Body>([0m -[0m[1m[38;5;12m35[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m HttpsConnector::new(4).unwrap()[0m -[0m[1m[38;5;12m...[0m[0m [0m[0m[1m[38;5;9m|[0m -[0m[1m[38;5;12m59[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m }[0m -[0m[1m[38;5;12m60[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m }));[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|__________^[0m[0m [0m[0m[1m[38;5;9mthe trait `futures::future::Future` is not implemented for `()`[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required by `futures::future::lazy::Lazy`[0m - -[0m[1m[38;5;9merror[E0277][0m[0m[1m: the trait bound `(): futures::future::Future` is not satisfied[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:32:9[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m32[0m[0m [0m[0m[1m[38;5;12m| [0m[0m hyper::rt::run(hyper::rt::lazy(|| {[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^[0m[0m [0m[0m[1m[38;5;9mthe trait `futures::future::Future` is not implemented for `()`[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`[0m -[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required by `hyper::rt::run`[0m - -[0m[1m[38;5;9merror[E0063][0m[0m[1m: missing field `res_receiver` in initializer of `backend_connection::BackendConnection`[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:62:9[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m62[0m[0m [0m[0m[1m[38;5;12m| [0m[0m BackendConnection {[0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^^^^[0m[0m [0m[0m[1m[38;5;9mmissing `res_receiver`[0m - -[0m[1m[38;5;9merror[E0609][0m[0m[1m: no field `request_sender` on type `&backend_connection::BackendConnection`[0m -[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:69:14[0m -[0m [0m[0m[1m[38;5;12m|[0m -[0m[1m[38;5;12m69[0m[0m [0m[0m[1m[38;5;12m| [0m[0m self.request_sender.send([0m -[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^[0m - -[0m[1m[38;5;9merror[0m[0m[1m: aborting due to 7 previous errors[0m - -[0m[1mSome errors have detailed explanations: E0063, E0277, E0308, E0599, E0609.[0m -[0m[1mFor more information about an error, try `rustc --explain E0063`.[0m -[0m[0m[1m[31merror:[0m Could not compile `game-server`. - -To learn more, run the command again with --verbose. -build failed! diff --git a/game_server/rbuild.sh b/game_server/rbuild.sh deleted file mode 100644 index 22b10b5..0000000 --- a/game_server/rbuild.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sh build.sh &> err && cat err | tac diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 9307c4a..11642f2 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,31 +1,68 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; +use std::sync::mpsc::{Sender, Receiver}; +use std::sync::mpsc; +use super::gameserver::Token; pub struct BackendConnection { host: String, - client: Client, - last_response: Option<Result<Response, ReqError>> + req_sender: Sender<RequestData>, + res_rec: Receiver<ResponseResult>, } +#[derive(Debug)] +pub enum BackendError { + UrlError(UrlError), + RequestError(ReqError), + InvalidTokenFormat, + InvalidToken, +} + +pub type TokenValidity = Result<(), BackendError>; +pub type RequestData = Url; +pub type ResponseResult = Result<Response, ReqError>; + impl BackendConnection { + fn run_background(req_rec: Receiver<RequestData>, res_sender: Sender<ResponseResult>) { + let client = Client::new(); + loop { + let request_data = req_rec.recv().unwrap(); + let location = request_data; + let request = client.get(location); + let response = request.send(); + res_sender.send(response).unwrap(); + } + } + pub fn new(host: &str) -> Self { + let (req_sender, req_rec): (Sender<RequestData>, Receiver<RequestData>) + = mpsc::channel(); + let (res_sender, res_rec): (Sender<ResponseResult>, Receiver<ResponseResult>) + = mpsc::channel(); + std::thread::spawn(move || Self::run_background(req_rec, res_sender)); BackendConnection { host: host.to_string(), - client: Client::new(), - last_response: None + req_sender, + res_rec, } } - pub fn request(&mut self, location: &str) -> Result<(), UrlError> { - Ok(self.last_response = - Some(self.client.get(Url::parse(&format!("{}{}", self.host, location))?) - .send())) + pub fn request(&self, location: &str) -> Result<(), UrlError> { + Ok(self.req_sender.send(Url::parse(&format!("{}{}", self.host, location))?).unwrap()) } - pub fn get_response(&self) -> &Option<Result<Response, ReqError>> { - &self.last_response + pub fn get_response(&self) -> ResponseResult { + self.res_rec.recv().unwrap() } pub fn host_name<'a>(&'a self) -> &'a str { &self.host } + + pub fn validate_token(&self, token: &Token) -> TokenValidity { + let location = format!("/api/lobby/tokens/{}", token); + self.request(&location).map_err(|err| BackendError::UrlError(err))?; + let response = self.get_response(); + println!("backend response: {:?}", response); + Ok(()) + } } diff --git a/game_server/src/game_logger.rs b/game_server/src/game_logger.rs new file mode 100644 index 0000000..e49ebe8 --- /dev/null +++ b/game_server/src/game_logger.rs @@ -0,0 +1,29 @@ +use colored::*; + +fn color_level(level: log::Level) -> colored::ColoredString { + let text = format!("{: <8}", level); + match level { + log::Level::Error => text.red().bold(), + log::Level::Warn => text.yellow(), + log::Level::Info => text.green(), + log::Level::Debug => text.cyan(), + log::Level::Trace => text.magenta(), + } +} + +pub fn init_logger() { + fern::Dispatch::new().format(|out, message, record|{ + out.finish(format_args!( + "{} {} > {}", + color_level(record.level()), + record.target(), + message + ) + ) + }) + .level(log::LevelFilter::Debug) + .level_for("hyper", log::LevelFilter::Off) + .level_for("tokio-reactor", log::LevelFilter::Off) + .chain(std::io::stdout()) + .apply().unwrap(); +} diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs index 9334a27..a4b1ed5 100644 --- a/game_server/src/gameserver.rs +++ b/game_server/src/gameserver.rs @@ -4,14 +4,16 @@ use websocket::{OwnedMessage, server::{NoTlsAcceptor, InvalidConnection, sync::AcceptResult}}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; -use std::sync::mpsc; -use std::sync::mpsc::{Sender, Receiver}; +use std::sync::{mpsc, + mpsc::{Sender, Receiver}, + Arc, Mutex}; +use std::collections::HashMap; use super::lobby::Lobby; use super::backend_connection::BackendConnection; const PROTOCOL: &str = "tuesday"; -type Token = u32; +pub type Token = u32; #[derive(Debug)] pub enum GameServerError { @@ -24,7 +26,8 @@ pub enum GameServerError { pub struct GameServer { addr: SocketAddr, lobby: Lobby, - backend: BackendConnection, + backend: Arc<Mutex<BackendConnection>>, + clients: Arc<Mutex<HashMap<Token, GameClient>>>, } pub struct GameClient { @@ -47,7 +50,7 @@ impl GameClient { .recv_message() .ok()?; if let OwnedMessage::Text(text) = message { - text.parse::<Token>().ok() + text.parse().ok() } else { None } @@ -67,7 +70,8 @@ impl GameServer { GameServer { addr, lobby, - backend, + backend: Arc::new(Mutex::new(backend)), + clients: Arc::new(Mutex::new(HashMap::new())), } } @@ -81,9 +85,22 @@ 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 || { - println!("Token: {:?}", client.require_token()); - loop { std::thread::sleep(std::time::Duration::from_millis(100)); } + let token = client.require_token(); + if let Some(token) = token { + println!("Token: {}", token); + let locked_backend = backend.lock().unwrap(); + let result = locked_backend.validate_token(&token); + if let Err(err) = result { + warn!("token {} is invalid: '{:?}'", token, err); + } else { + clients.lock().unwrap().insert(token, client); + } + } else { + warn!("client sent invalid token"); + } }); } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index e129283..76e7a39 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -4,13 +4,14 @@ mod lobby; mod gameserver; mod backend_connection; +mod game_logger; + #[macro_use] extern crate log; -use pretty_env_logger; use backend_connection::BackendConnection; fn main() { - pretty_env_logger::init(); + game_logger::init_logger(); let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); |