summaryrefslogtreecommitdiff
path: root/game_server/src
diff options
context:
space:
mode:
authorDennis Kobert <d-kobert@web.de>2019-06-11 23:53:30 +0200
committerDennis Kobert <d-kobert@web.de>2019-06-11 23:53:30 +0200
commit3a3d0fc3d4733f8908e23a03f860d76340479ec4 (patch)
treecf4b82f61d01d2a24836e9820d73972436847982 /game_server/src
parentc28c9fafa2c74b101f7ce777aac722dcdeecefc6 (diff)
Reorganize Project structure
Diffstat (limited to 'game_server/src')
-rw-r--r--game_server/src/backend_connection.rs90
-rw-r--r--game_server/src/collide.rs238
-rw-r--r--game_server/src/game_logger.rs30
-rw-r--r--game_server/src/group.rs13
-rw-r--r--game_server/src/lobby.rs63
-rw-r--r--game_server/src/main.rs23
-rw-r--r--game_server/src/maths.rs370
-rw-r--r--game_server/src/scribble_group.rs65
-rw-r--r--game_server/src/server.rs198
-rw-r--r--game_server/src/webhogg_game.rs13
-rw-r--r--game_server/src/webhogg_group.rs71
-rw-r--r--game_server/src/webhogg_player.rs3
-rw-r--r--game_server/src/ws_test.html74
13 files changed, 0 insertions, 1251 deletions
diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs
deleted file mode 100644
index a751b30..0000000
--- a/game_server/src/backend_connection.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-use reqwest::{Response, Client, Url, UrlError, Error as ReqError};
-use std::sync::mpsc::{Sender, Receiver};
-use std::sync::mpsc;
-use crate::server::{UserId, Token};
-use crate::group::GroupId;
-
-pub struct BackendConnection {
- host: String,
- req_sender: Sender<RequestData>,
- res_rec: Receiver<ResponseResult>,
- max_uid: u32,
-}
-
-#[derive(Debug)]
-pub enum BackendError {
- UrlError(UrlError),
- RequestError(ReqError),
- InvalidTokenFormat,
- InvalidToken,
- BadResponse(Response),
-}
-
-pub type TokenValidity = Result<TokenResponse, BackendError>;
-pub type RequestData = Url;
-pub type ResponseResult = Result<Response, ReqError>;
-
-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<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(),
- req_sender,
- res_rec,
- max_uid: 420,
- }
- }
-
- 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) -> ResponseResult {
- self.res_rec.recv().unwrap()
- }
-
- pub fn validate_token(&mut 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().map_err(|err| BackendError::RequestError(err))?;
- if response.status().is_success() {
- // zu Testzwecken werden noch keine JSON-Daten deserialisiert
- // Dennis Server gibt ja noch nix zurück
- self.max_uid += 1;
- Ok(TokenResponse {
- group_id: 12,
- group_type: "scribble".to_string(),
- group_name: "Scribble".to_string(),
- user_id: self.max_uid - 1,
- })
- } else if response.status() == reqwest::StatusCode::NOT_FOUND {
- Err(BackendError::InvalidToken)
- } else if response.status().is_client_error() {
- Err(BackendError::InvalidTokenFormat)
- } else {
- Err(BackendError::BadResponse(response))
- }
- }
-}
diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs
deleted file mode 100644
index 16b5357..0000000
--- a/game_server/src/collide.rs
+++ /dev/null
@@ -1,238 +0,0 @@
-use crate::maths::{Vec2, AABox, RBox};
-
-pub trait Collide<Rhs> {
- fn collides(&self, other: &Rhs) -> bool;
-}
-
-impl Collide<Vec2> for Vec2 {
- fn collides(&self, other: &Self) -> bool {
- self == other
- }
-}
-
-impl Collide<Vec2> for AABox {
- fn collides(&self, other: &Vec2) -> bool {
- self.pos < *other && other < &(self.pos + self.size)
- }
-}
-
-impl Collide<AABox> for AABox {
- fn collides(&self, other: &Self) -> bool {
- self.pos.x < other.pos.x + other.size.x && other.pos.x < self.pos.x + self.size.x
- && self.pos.y < other.pos.y + other.size.y && other.pos.y < self.pos.y + self.size.y
- }
-}
-
-impl Collide<Vec2> for RBox {
- fn collides(&self, other: &Vec2) -> bool {
- let v1_diff = *other + self.v1 * (-self.v1.scalar(&(*other - self.pos)) / self.v1.distance2());
- let v2_diff = *other + self.v2 * (-self.v2.scalar(&(*other - self.pos)) / self.v2.distance2());
-
- let v1_dist = ((v1_diff - self.pos) / self.v2).x;
- let v2_dist = ((v2_diff - self.pos) / self.v1).x;
- 0.0 <= v1_dist && v2_dist <= 1.0
- && 0.0 <= v2_dist && v2_dist <= 1.0
- //v1_diff < self.pos + self.v2 && self.pos < v1_diff
- //&& v2_diff < self.pos + self.v1 && self.pos < v2_diff
- }
-}
-
-impl Collide<AABox> for RBox {
- fn collides(&self, other: &AABox) -> bool {
- let other_size = other.pos + other.size;
-
- // project points onto a orthogonal line
- let v1_diff = other.pos + self.v1 * (-self.v1.scalar(&(other.pos - self.pos)) / self.v1.distance2());
- let v2_diff = other.pos + self.v2 * (-self.v2.scalar(&other.pos) / self.v2.distance2());
- let v1_diff_size = other_size + self.v1 * (-self.v1.scalar(&(other_size - self.pos)) / self.v1.distance2());
- let v2_diff_size = other_size + self.v2 * (-self.v2.scalar(&(other_size - self.pos)) / self.v2.distance2());
-
- // calculate the distance
- let v1_dist = ((v1_diff - self.pos) / self.v2);
- let v2_dist = ((v2_diff - self.pos) / self.v1);
- let v1_dist_size = ((v1_diff_size - self.pos) / self.v2);
- let v2_dist_size = ((v2_diff_size - self.pos) / self.v1);
-
- let v1_dist = if v1_dist.x.is_finite() {v1_dist.x} else {v1_dist.y};
- let v2_dist = if v2_dist.x.is_finite() {v2_dist.x} else {v2_dist.y};
- let v1_dist_size = if v1_dist_size.x.is_finite() {v1_dist_size.x} else {v1_dist_size.y};
- let v2_dist_size = if v2_dist_size.x.is_finite() {v2_dist_size.x} else {v2_dist_size.y};
-
- let minx = f32::min(self.pos.x, f32::min((self.pos + self.v1).x, (self.pos + self.v2).x));
- let maxx = f32::max(self.pos.x, f32::max((self.pos + self.v1).x, (self.pos + self.v2).x));
- let miny = f32::min(self.pos.y, f32::min((self.pos + self.v1).y, (self.pos + self.v2).y));
- let maxy = f32::max(self.pos.y, f32::max((self.pos + self.v1).y, (self.pos + self.v2).y));
-
- 0.0 <= v1_dist_size && v1_dist <= 1.0
- && 0.0 <= v2_dist_size && v2_dist <= 1.0
- && other.pos.x <= maxx && minx <= other.pos.x + other.size.x
- && other.pos.y <= maxy && miny <= other.pos.y + other.size.y
- }
-}
-
-impl<S, T: Collide<S>> Collide<S> for Vec<T> {
- fn collides(&self, other: &S) -> bool {
- self.iter().any(|x| x.collides(other))
- }
-}
-
-#[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn test_collide_dot_dot() {
- let a = Vec2{x: 1.0, y: 7.5};
- assert!(a.collides(&a));
- }
-
- #[test]
- fn test_not_collide_dot_dot() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: 5.0, y: 7.5};
- assert!(!a.collides(&b));
- }
-
- #[test]
- fn test_collide_aabox_dot() {
- let a = Vec2{x: 1.0, y: 2.5};
- let b = Vec2{x: 3.0, y: 7.5};
- let c = Vec2{x: 1.5, y: 5.0};
- let aa_box = AABox{pos: a, size: b};
-
- assert!(aa_box.collides(&c));
- }
-
- #[test]
- fn test_not_collide_aabox_dot() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: 3.0, y: 2.5};
- let c = Vec2{x: 0.5, y: 5.0};
- let aa_box = AABox{pos: a, size: b};
-
- assert!(!(aa_box.collides(&c)));
- }
-
- #[test]
- fn test_collide_aabox_aabox_intersecting() {
- let a = Vec2{x: 1.0, y: 2.5};
- let b = Vec2{x: 3.0, y: 2.5};
- let aa_box = AABox{pos: a, size: b};
- let a = Vec2{x: 2.0, y: 3.5};
- let b = Vec2{x: 3.0, y: 7.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(aa_box.collides(&bb_box));
- }
-
- #[test]
- fn test_collide_aabox_aabox_crossed() {
- let a = Vec2{x: 2.0, y: 0.5};
- let b = Vec2{x: 1.0, y: 7.5};
- let aa_box = AABox{pos: a, size: b};
- let a = Vec2{x: 1.0, y: 3.5};
- let b = Vec2{x: 5.0, y: 4.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(aa_box.collides(&bb_box));
- }
-
- #[test]
- fn test_not_collide_aabox_aabox() {
- let a = Vec2{x: 1.0, y: 1.0};
- let b = Vec2{x: 1.0, y: 1.0};
- let aa_box = AABox{pos: a, size: b};
- let a = Vec2{x: 3.0, y: 3.5};
- let b = Vec2{x: 3.0, y: 7.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(!(aa_box.collides(&bb_box)));
- }
-
- #[test]
- fn test_collide_Rbox_dot() {
- let a = Vec2{x: 1.0, y: 1.0};
- let b = Vec2{x: 1.0, y: 1.0};
- let c = Vec2{x: 1.0, y: -1.0};
- let aa_box = RBox{pos: a, v1: b, v2: c};
-
- let c = Vec2{x: 1.6, y: 0.6};
-
- assert!(aa_box.collides(&c));
- }
-
- #[test]
- fn test_not_collide_rbox_dot() {
- let a = Vec2{x: 1.0, y: 1.0};
- let b = Vec2{x: 1.0, y: 1.0};
- let c = Vec2{x: 1.0, y: -1.0};
- let aa_box = RBox{pos: a, v1: b, v2: c};
-
- let c = Vec2{x: 1.4, y: 0.4};
-
- assert!(!(aa_box.collides(&c)));
- }
-
- #[test]
- fn test_collide_rbox_aabox_intersecting() {
- let a = Vec2{x: 1.0, y: 2.5};
- let b = Vec2{x: 0.0, y: 2.5};
- let c = Vec2{x: 3.0, y: 0.5};
- let aa_box = RBox{pos: a, v1: b, v2: c};
- let a = Vec2{x: 2.0, y: 3.5};
- let b = Vec2{x: 3.0, y: 7.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(aa_box.collides(&bb_box));
- }
-
- #[test]
- fn test_collide_rbox_aabox_edges_touch() {
- let a = Vec2{x: 4.0, y: 5.5};
- let b = Vec2{x: 1.0, y: 7.5};
- let aa_box = RBox::new(a, b, 3.9);
- let a = Vec2{x: 0.0, y: 0.5};
- let b = Vec2{x: 4.0, y: 5.0};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(aa_box.collides(&bb_box));
- }
-
- #[test]
- fn test_collide_rbox_aabox_crossed() {
- let a = Vec2{x: 2.0, y: 0.5};
- let b = Vec2{x: 1.0, y: 7.5};
- let aa_box = RBox::new(a, b, 3.9);
- let a = Vec2{x: 0.0, y: 4.5};
- let b = Vec2{x: 15.0, y: 1.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(aa_box.collides(&bb_box));
- }
-
- #[test]
- fn test_not_collide_rbox_aabox_next_to() {
- let a = Vec2{x: 2.0, y: 0.5};
- let b = Vec2{x: 1.0, y: 7.5};
- let aa_box = RBox::new(a, b, 3.9);
- let a = Vec2{x: 5.0, y: 40.5};
- let b = Vec2{x: 15.0, y: 1.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(!aa_box.collides(&bb_box));
- }
-
- #[test]
- fn test_not_collide_rbox_aabox() {
- let a = Vec2{x: 1.0, y: 1.0};
- let b = Vec2{x: 0.0, y: 1.0};
- let c = Vec2{x: 1.0, y: 0.0};
- let aa_box = RBox{pos: a, v1: b, v2: c};
- let a = Vec2{x: 3.0, y: 3.5};
- let b = Vec2{x: 3.0, y: 7.5};
- let bb_box = AABox{pos: a, size: b};
-
- assert!(!(aa_box.collides(&bb_box)));
- }
-
-}
diff --git a/game_server/src/game_logger.rs b/game_server/src/game_logger.rs
deleted file mode 100644
index c51bfc5..0000000
--- a/game_server/src/game_logger.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-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)
- .level_for("reqwest", log::LevelFilter::Off)
- .chain(std::io::stdout())
- .apply().unwrap();
-}
diff --git a/game_server/src/group.rs b/game_server/src/group.rs
deleted file mode 100644
index 74a04f7..0000000
--- a/game_server/src/group.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use crate::server::{UserId, GameClient, GameServerError};
-
-pub type GroupId = u32;
-
-pub trait Group {
- fn id(&self) -> GroupId;
- fn group_type(&self) -> String;
- fn name(&self) -> String;
-
- fn run(&mut self);
-
- fn add_client(&mut self, id: UserId, client: GameClient) -> Result<(), GameServerError>;
-}
diff --git a/game_server/src/lobby.rs b/game_server/src/lobby.rs
deleted file mode 100644
index 6d11a5f..0000000
--- a/game_server/src/lobby.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use std::collections::HashMap;
-
-use crate::group::{Group, GroupId};
-use crate::scribble_group::ScribbleGroup;
-
-use crate::server::{UserId, GameClient, GameServerError};
-
-pub struct Lobby {
- groups: HashMap<GroupId, Box<Group>>,
-}
-
-#[allow(dead_code)]
-impl Lobby {
- pub fn new() -> Self {
- Self {
- groups: HashMap::new(),
- }
- }
-
- fn generate_group(group_type: &str, id: GroupId, name: &str) -> Option<Box<Group>> {
- match group_type {
- "scribble" => {
- Some(Box::new(ScribbleGroup::new(id, name.to_string())))
- },
- _ => None,
- }
- }
-
- pub fn add_group(&mut self, group: Box<Group>) {
- self.groups.insert(group.id(), group);
- }
-
- pub fn add_client(&mut self, group_type: &str, group_id: GroupId, group_name: &str,
- user_id: UserId, client: GameClient) -> Result<(), GameServerError> {
- if !self.groups.contains_key(&group_id) {
- let mut group = match Self::generate_group(group_type, group_id, group_name) {
- Some(x) => x,
- _ => return Err(GameServerError::GroupCreationError(format!("failed to generate '{}' group", group_type))),
- };
- 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() }
- }
-}
-
-#[allow(dead_code)]
-pub struct GroupIterator<'a> {
- groups: std::collections::hash_map::Values<'a, GroupId, Box<Group>>
-}
-
-impl<'a> Iterator for GroupIterator<'a> {
- type Item = &'a Box<Group>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.groups.next()
- }
-}
diff --git a/game_server/src/main.rs b/game_server/src/main.rs
deleted file mode 100644
index cfd9787..0000000
--- a/game_server/src/main.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-mod group;
-mod maths;
-mod scribble_group;
-mod webhogg_group;
-mod webhogg_game;
-mod collide;
-mod lobby;
-mod server;
-mod backend_connection;
-
-mod game_logger;
-
-#[macro_use] extern crate log;
-
-fn main() {
- game_logger::init_logger();
-
- let addr = ("0.0.0.0", 5001);
- info!("create game server on {:?}", addr);
- let mut gameserver = server::GameServer::new(addr);
- gameserver.run().unwrap();
-
-}
diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs
deleted file mode 100644
index b9303af..0000000
--- a/game_server/src/maths.rs
+++ /dev/null
@@ -1,370 +0,0 @@
-#[derive(Clone, Copy, Debug)]
-pub struct Vec2 {
- pub x: f32,
- pub y: f32,
-}
-
-impl std::ops::Add for Vec2 {
- type Output = Self;
- fn add(self, other: Self) -> Self {
- Self {
- x: self.x + other.x,
- y: self.y + other.y
- }
- }
-}
-
-impl std::ops::AddAssign<Vec2> for Vec2 {
- fn add_assign(&mut self, other: Vec2) {
- self.x += other.x;
- self.y += other.y;
- }
-}
-
-impl std::ops::Sub for Vec2 {
- type Output = Self;
- fn sub(self, other: Self) -> Self {
- Self {
- x: self.x - other.x,
- y: self.y - other.y
- }
- }
-}
-
-impl std::ops::SubAssign<Vec2> for Vec2 {
- fn sub_assign(&mut self, other: Vec2) {
- self.x -= other.x;
- self.y -= other.y;
- }
-}
-
-impl std::ops::Neg for Vec2 {
- type Output = Self;
- fn neg(self) -> Self {
- Self {
- x: -self.x,
- y: -self.y
- }
- }
-}
-
-impl std::ops::Mul<f32> for Vec2 {
- type Output = Self;
- fn mul(self, scale: f32) -> Self {
- Self {
- x: self.x * scale,
- y: self.y * scale
- }
- }
-}
-
-impl std::ops::Div<f32> for Vec2 {
- type Output = Self;
- fn div(self, scale: f32) -> Self {
- Self {
- x: self.x / scale,
- y: self.y / scale
- }
- }
-}
-
-impl std::ops::Div<Vec2> for Vec2 {
- type Output = Self;
- fn div(self, scale: Vec2) -> Self {
- Self {
- x: self.x / scale.x,
- y: self.y / scale.y
- }
- }
-}
-
-
-impl std::cmp::PartialOrd for Vec2 {
- fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
- if self.x <= other.x && self.y <= other.y {
- Some(std::cmp::Ordering::Less)
- } else if self.x > other.x && self.y > other.y {
- Some(std::cmp::Ordering::Greater)
- } else {
- None
- }
- }
-}
-
-impl std::cmp::PartialEq for Vec2 {
- fn eq(&self, other: &Self) -> bool {
- f32::abs(self.x - other.x) < 1e-8
- && f32::abs(self.y - other.y) < 1e-8
- }
-}
-
-impl std::cmp::Eq for Vec2 {}
-
-impl Vec2 {
- pub fn distance(&self) -> f32 {
- f32::sqrt(self.distance2())
- }
-
- pub fn distance2(&self) -> f32 {
- self.scalar(self)
- }
-
- pub fn scalar(&self, other: &Vec2) -> f32 {
- self.x * other.x + self.y * other.y
- }
-
- pub fn norm(&self) -> Vec2 {
- let len = self.distance();
- Vec2 {
- x: self.x / len,
- y: self.y / len,
- }
- }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub struct AABox {
- pub pos: Vec2,
- /// the size may not be smaller than zero
- pub size: Vec2,
-}
-
-impl std::ops::Add<Vec2> for AABox {
- type Output = Self;
- fn add(self, other: Vec2) -> Self {
- Self {
- pos: self.pos + other,
- size: self.size,
- }
- }
-}
-
-impl std::ops::AddAssign<Vec2> for AABox {
- fn add_assign(&mut self, other: Vec2) {
- self.pos += other
- }
-}
-
-impl std::ops::Sub<Vec2> for AABox {
- type Output = Self;
- fn sub(self, other: Vec2) -> Self {
- Self {
- pos: self.pos + other,
- size: self.size
- }
- }
-}
-
-impl std::ops::SubAssign<Vec2> for AABox {
- fn sub_assign(&mut self, other: Vec2) {
- self.pos -= other
- }
-}
-
-impl std::cmp::PartialEq for AABox {
- fn eq(&self, other: &Self) -> bool {
- self.pos == other.pos
- && self.size == other.size
- }
-}
-
-impl std::cmp::Eq for AABox {}
-
-#[derive(Clone, Copy, Debug)]
-pub struct RBox {
- /// origin
- pub pos: Vec2,
- /// Vwctor1
- pub v1: Vec2,
- /// Vector2
- pub v2: Vec2,
-}
-
-impl RBox {
- pub fn new(pos: Vec2, orientation: Vec2, width: f32) -> Self {
- let scale = width / orientation.distance();
- let orth = Vec2 {x: orientation.x / scale, y: -orientation.y / scale};
- Self {
- pos: pos,
- v1: orientation,
- v2: orth,
- }
- }
-}
-
-impl std::ops::Add<Vec2> for RBox {
- type Output = Self;
- fn add(self, other: Vec2) -> Self {
- Self {
- pos: self.pos + other,
- v1: self.v1,
- v2: self.v2,
- }
- }
-}
-
-impl std::ops::AddAssign<Vec2> for RBox {
- fn add_assign(&mut self, other: Vec2) {
- self.pos += other
- }
-}
-
-impl std::ops::Sub<Vec2> for RBox {
- type Output = Self;
- fn sub(self, other: Vec2) -> Self {
- Self {
- pos: self.pos + other,
- v1: self.v1 + other,
- v2: self.v2,
- }
- }
-}
-
-impl std::ops::SubAssign<Vec2> for RBox {
- fn sub_assign(&mut self, other: Vec2) {
- self.pos -= other
- }
-}
-
-impl std::cmp::PartialEq for RBox {
- fn eq(&self, other: &Self) -> bool {
- self.pos == other.pos
- && self.v1 == other.v1
- && self.v1 == self.v2
- }
-}
-
-impl std::cmp::Eq for RBox {}
-
-#[cfg(test)]
-mod tests {
- // Note this useful idiom: importing names from outer (for mod tests) scope.
- use super::*;
-
- #[test]
- fn test_less_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
-
- assert!(b < a);
- }
-
- #[test]
- fn test_less_vec2_fail() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: 3.0, y: 2.5};
-
- assert!(!(a < b));
- }
-
- #[test]
- fn test_greater_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
-
- assert!(a > b);
- }
-
- #[test]
- fn test_greater_vec2_fail() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: 3.0, y: 2.5};
-
- assert!(!(a > b));
- }
-
-
- #[test]
- fn test_add_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
- let c = Vec2{x: -2.0, y: 10.0};
-
- assert_eq!(a + b, c);
- }
-
- #[test]
- fn test_neg_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -1.0, y: -7.5};
-
- assert_eq!(-a, b);
- }
-
- #[test]
- fn test_sub_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
- let c = Vec2{x: 4.0, y: 5.0};
-
- assert_eq!(a - b, c);
- }
-
- #[test]
- fn test_distance_vec2() {
- let a = Vec2{x: 2.0, y: 2.0};
-
- assert!(f32::abs(a.distance() - 2.0) < 1e8);
- }
-
- #[test]
- fn test_distance2_vec2() {
- let a = Vec2{x: 1.0, y: 2.0};
-
- assert!(f32::abs(a.distance2() - 5.0) < 1e8);
- }
-
- #[test]
- fn test_norm_vec2() {
- let a = Vec2{x: 2.0, y: -2.0};
- let b = Vec2{x: std::f32::consts::FRAC_1_SQRT_2, y: -std::f32::consts::FRAC_1_SQRT_2};
-
- assert_eq!(a.norm(), b);
- }
-
- #[test]
- fn test_add_aabox_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
- let mut aa_box = AABox{pos: a, size: b};
- let bb_box = AABox{pos: a + b,size: b};
- aa_box += b;
-
- assert_eq!(aa_box, bb_box);
- }
-
- #[test]
- fn test_sub_aabox_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
- let mut aa_box = AABox{pos: a, size: b};
- let bb_box = AABox{pos: a - b,size: b};
- aa_box -= b;
-
- assert_eq!(aa_box, bb_box);
- }
-
- #[test]
- fn test_add_rbox_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
- let c = Vec2{x: -3.0, y: 2.5};
- let mut aa_box = RBox{pos: a, v1: b, v2: c};
- let bb_box = RBox{pos: a + b, v1: b, v2: c};
- aa_box += b;
-
- assert_eq!(aa_box, bb_box);
- }
-
- #[test]
- fn test_sub_rbox_vec2() {
- let a = Vec2{x: 1.0, y: 7.5};
- let b = Vec2{x: -3.0, y: 2.5};
- let c = Vec2{x: -3.0, y: 2.5};
- let mut aa_box = RBox{pos: a, v1: b, v2: c};
- let bb_box = RBox{pos: a - b, v1: b, v2: c};
- aa_box -= b;
-
- assert_eq!(aa_box, bb_box);
- }
-}
diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs
deleted file mode 100644
index 8980e7b..0000000
--- a/game_server/src/scribble_group.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use crate::group::{Group, GroupId};
-use crate::server::{UserId, GameClient,
- ClientSender, ClientReceiver,
- GameServerError};
-use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
-
-pub struct ScribbleGroup {
- id: GroupId,
- name: String,
- senders: Arc<Mutex<HashMap<UserId, ClientSender>>>
-}
-
-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) -> Result<(), GameServerError> {
- debug!("user {} joined the group {}:'{}'", id, self.id, self.name);
- let (sen, rec) = client.split();
- self.senders.lock().unwrap().insert(id, sen);
- let senders_mutex = self.senders.clone();
- let self_uid = id;
- std::thread::spawn(move || Self::broadcast_clients(self_uid, rec, senders_mutex));
- Ok(())
- }
-}
-
-impl ScribbleGroup {
- pub fn new(id: GroupId, name: String) -> Self {
- Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) }
- }
-
- fn broadcast_clients(self_uid: UserId, mut rec: ClientReceiver, senders_mutex: Arc<Mutex<HashMap<UserId, ClientSender>>>) {
- loop {
- let message = match rec.recv_message() {
- Ok(x) => x,
- _ => break
- };
- //trace!("got message: '{:?}'", message);
- let mut senders = senders_mutex.lock().unwrap();
- for (uid, sender) in senders.iter_mut() {
- if self_uid != *uid {
- sender.send_message(&message)
- .unwrap_or_else(|_| debug!("tried to send message to {}, but failed", *uid));
- }
- }
- }
- senders_mutex.lock().unwrap().remove(&self_uid);
- info!("client {} has left", self_uid);
- }
-}
diff --git a/game_server/src/server.rs b/game_server/src/server.rs
deleted file mode 100644
index 5b1a7a9..0000000
--- a/game_server/src/server.rs
+++ /dev/null
@@ -1,198 +0,0 @@
-use websocket::{OwnedMessage,
- stream::sync::Splittable,
- sync::Server,
- client::sync::Client,
- server::{NoTlsAcceptor,
- sync::AcceptResult},
- receiver, sender};
-use std::net::{SocketAddr, ToSocketAddrs, TcpStream};
-use std::sync::{mpsc,
- mpsc::{Sender, Receiver}};
-use crate::lobby::Lobby;
-use crate::backend_connection::BackendConnection;
-
-pub type ClientReceiver = receiver::Reader<<TcpStream as Splittable>::Reader>;
-pub type ClientSender = sender::Writer<<TcpStream as Splittable>::Writer>;
-
-const PROTOCOL: &str = "tuesday";
-
-pub type Token = u32;
-pub type UserId = u32;
-
-#[derive(Debug)]
-pub enum GameServerError {
- BindError(std::io::Error),
- HandshakeRequestError,
- InvalidProtocolError,
- AcceptError(std::io::Error),
- GroupError(String),
- GroupCreationError(String),
-}
-
-impl std::fmt::Display for GameServerError {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
- match self {
- GameServerError::BindError(e) => write!(f, "BindError: {}", e),
- GameServerError::HandshakeRequestError => write!(f, "HandshakeRequestError"),
- GameServerError::InvalidProtocolError => write!(f, "InvalidProtocolError"),
- GameServerError::AcceptError(e) => write!(f, "AcceptError: {}", e),
- GameServerError::GroupError(e) => write!(f, "GroupError: {}", e),
- GameServerError::GroupCreationError(e) => write!(f, "GroupCreationError: {}", e),
- }
- }
-}
-
-pub struct GameServer {
- addr: SocketAddr,
- lobby: Lobby,
- backend: BackendConnection,
-}
-
-pub struct GameClient {
- addr: SocketAddr,
- client: Client<TcpStream>,
-}
-
-impl GameClient {
- fn from_raw(client: Client<TcpStream>) -> Result<Self, ()> {
- let addr = client.peer_addr().map_err(|_| ())?;
- info!("got a client connection from: {}", addr);
- Ok(GameClient {
- addr,
- client,
- })
- }
-
- fn require_token(&mut self) -> Option<Token> {
- let message = self.client
- .recv_message()
- .ok()?;
- if let OwnedMessage::Text(text) = message {
- text.parse().ok()
- } else {
- None
- }
- }
-
- fn host_name(&self) -> SocketAddr {
- self.addr
- }
-
- pub fn split(self) -> (ClientSender, ClientReceiver) {
- let (rec, sen) = self.client.split().unwrap();
- (sen, rec)
- }
-}
-
-type ClientConnection = Result<GameClient, GameServerError>;
-
-impl GameServer {
- pub fn new<T: ToSocketAddrs>(addr: T) -> Self {
- let addr = addr.to_socket_addrs().unwrap().next().unwrap();
- debug!("ws address: {}", addr);
- info!("create lobby");
- let lobby = Lobby::new();
- let backend = BackendConnection::new("https://kobert.dev");
- info!("got a C# backend connection");
- GameServer {
- addr,
- lobby: lobby,
- backend: backend,
- }
- }
-
- pub fn run(&mut self) -> Result<(), GameServerError> {
- let reader = self.read_clients();
- loop {
- let connection = reader.recv().unwrap()?;
- self.add_client(connection);
- }
- }
-
- 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");
- 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)
- .unwrap_or_else(|e| warn!("failed to add client: {}", e));
- }
- }
- } else {
- warn!("client sent invalid token");
- }
- }
-
- fn read_clients(&self) -> Receiver<ClientConnection> {
- let (sen, rec): (Sender<ClientConnection>, Receiver<ClientConnection>)
- = mpsc::channel();
- let addr = self.addr;
- std::thread::spawn(move || {
- match Self::handle_requests(addr, &sen) {
- Err(e) => sen.send(Err(e)).unwrap(),
- _ => (),
- }
- });
- rec
- }
-
- fn handle_requests(addr: SocketAddr, sen: &Sender<ClientConnection>) -> Result<(), GameServerError> {
- let server = match Server::<NoTlsAcceptor>::bind(addr) {
- Ok(v) => v,
- Err(e) => {
- error!("websocket binding error");
- Err(GameServerError::BindError(e))?
- },
- };
- info!("webserver is being launched");
- for req in server {
- sen.send(Ok(Self::handle_request(req)?)).unwrap();
- }
- info!("webserver is being shut down");
- Ok(())
- }
-
- fn handle_request(req: AcceptResult<TcpStream>) -> ClientConnection {
- match req {
- Ok(req) => {
- if !req.protocols().contains(&PROTOCOL.to_string()) {
- warn!("a client tried to connect without {} protocol", PROTOCOL);
- req.reject().unwrap();
- Err(GameServerError::InvalidProtocolError)
- } else {
- match req.use_protocol(PROTOCOL).accept() {
- Ok(client) => {
- match GameClient::from_raw(client) {
- Ok(client) => Ok(client),
- Err(_) => {
- error!("could not create a client");
- Err(GameServerError::HandshakeRequestError)
- }
- }
- },
- Err((_, e)) => {
- warn!("client handshake failed");
- Err(GameServerError::AcceptError(e))
- }
- }
- }
- },
- Err(_) => {
- warn!("invalid client request");
- Err(GameServerError::HandshakeRequestError)
- }
- }
- }
-}
diff --git a/game_server/src/webhogg_game.rs b/game_server/src/webhogg_game.rs
deleted file mode 100644
index 7b94fcb..0000000
--- a/game_server/src/webhogg_game.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use crate::maths::Vec2;
-
-pub struct WebhoggPlayer {
- pos: Vec2,
-}
-
-pub struct WebhoggGame {
- player1: WebhoggPlayer,
- player2: WebhoggPlayer,
-}
-
-impl WebhoggGame {
-}
diff --git a/game_server/src/webhogg_group.rs b/game_server/src/webhogg_group.rs
deleted file mode 100644
index 091f7f8..0000000
--- a/game_server/src/webhogg_group.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-use crate::group::{Group, GroupId};
-use crate::server::{UserId, GameClient,
- ClientSender, ClientReceiver,
- GameServerError};
-use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
-
-pub struct WebhoggGroup {
- id: GroupId,
- name: String,
- senders: Arc<Mutex<HashMap<UserId, ClientSender>>>
-}
-
-impl Group for WebhoggGroup {
- fn id(&self) -> GroupId {
- self.id
- }
-
- fn group_type(&self) -> String {
- "webhogg".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) -> Result<(), GameServerError> {
- if self.senders.lock().unwrap().len() > 1 {
- return Err(GameServerError::GroupError(
- format!("user {} was not able to join the {} group, {}",
- "because the client limit has been exceeded",
- id, self.name)));
- }
- debug!("user {} joined the group {}:'{}'", id, self.id, self.name);
- let (sen, rec) = client.split();
- self.senders.lock().unwrap().insert(id, sen);
- let senders_mutex = self.senders.clone();
- let self_uid = id;
- std::thread::spawn(move || Self::broadcast_clients(self_uid, rec, senders_mutex));
- Ok(())
- }
-}
-
-impl WebhoggGroup {
- pub fn new(id: GroupId, name: String) -> Self {
- Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) }
- }
-
- fn broadcast_clients(self_uid: UserId, mut rec: ClientReceiver, senders_mutex: Arc<Mutex<HashMap<UserId, ClientSender>>>) {
- loop {
- let message = match rec.recv_message() {
- Ok(x) => x,
- _ => break
- };
- //trace!("got message: '{:?}'", message);
- let mut senders = senders_mutex.lock().unwrap();
- for (uid, sender) in senders.iter_mut() {
- if self_uid != *uid {
- sender.send_message(&message)
- .unwrap_or_else(|_| debug!("tried to send message to {}, but failed", *uid));
- }
- }
- }
- senders_mutex.lock().unwrap().remove(&self_uid);
- info!("client {} has left", self_uid);
- }
-}
diff --git a/game_server/src/webhogg_player.rs b/game_server/src/webhogg_player.rs
deleted file mode 100644
index 38b9596..0000000
--- a/game_server/src/webhogg_player.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub struct WebhoggPlayer {
-
-}
diff --git a/game_server/src/ws_test.html b/game_server/src/ws_test.html
deleted file mode 100644
index 3b3d4ce..0000000
--- a/game_server/src/ws_test.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>WS Test</title>
- <style>
-.b {
- border-bottom: 1px solid black;
-}
- </style>
- </head>
- <body style='background: black; color: white'>
- <div id='cons'>connected</div><br>
- <button onclick='test_connection()'>Launch</button><br>
- <span>Server address: </span><input id='addr'></input>
- <div align='right'><span>Message</span><input id='msg'></input> <button onclick='send_text()'>Send</button></div>
- <div id='chat' style='background: rgb(20, 20, 20); padding-left: 20px; margin: 40px' />
- </body>
- <script>
-function get_addr() {
- return document.getElementById('addr').value;
-}
-
-function test_connection() {
- let a = 'ws://' + get_addr();
- add_text('create a new connection at "' + a + '"');
- ws = new WebSocket(a, 'tuesday');
- ws.addEventListener('open', function (event) {
- add_text('connection established');
- toggle_connected(true);
- // send token
- ws.send('42');
- });
- ws.addEventListener('error', function (event) {
- add_text('ws error occured: "' + event + '"');
- toggle_connected(false);
- });
- ws.addEventListener('close', function (event) {
- add_text('ws is closed now');
- toggle_connected(false);
- });
- ws.addEventListener('message', function (event) {
- add_text('got ws message: "' + event.data + '"');
- });
-}
-
-function send_text() {
- let msg = document.getElementById('msg').value;
- ws.send(msg);
- add_text('sent message: "' + msg + '"');
-}
-
-function add_text(text, color='white') {
- let c = document.getElementById('chat');
- let n = document.createElement('span');
- n.setAttribute('class', 'b');
- n.style = 'color: ' + color;
- n.textContent = (new Date()).toTimeString().substring(0, 8) + '|> '+ text;
- c.appendChild(n);
- c.appendChild(document.createElement('br'));
-}
-function toggle_connected(con) {
- let c = document.getElementById('cons');
- if (con) {
- c.style = 'background: green'
- c.textContent = 'connected';
- } else {
- c.style = 'background: red'
- c.textContent = 'not connected';
- }
-}
-toggle_connected(false);
-add_text("JS loaded");
- </script>
-</html>