| 
					
				 | 
			
			
				@@ -6,16 +6,15 @@ use actix::dev::{MessageResponse, ResponseChannel}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use actix::prelude::*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use actix_web::{web, Error, HttpRequest, HttpResponse}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use actix_web_actors::ws; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use futures::executor::block_on; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use crate::game; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use crate::websocket::{ClientMessage, UpdateMessage}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use crate::websocket::*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const CLIENT_TIMEOUT: Duration = Duration::from_secs(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[derive(Message)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[rtype(result = "Answer")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-struct JoinRequest{ lobby_id: String, p: Addr<GameConnection> } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct JoinRequest{ lobby_id: String, nick: String, p: Addr<GameConnection> } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[derive(Message)] 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -23,9 +22,13 @@ struct JoinRequest{ lobby_id: String, p: Addr<GameConnection> } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct CreateLobbyRequest{ lobby_id: String, p: Addr<GameConnection> } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[derive(Message)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#[rtype(result = "game::Game")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#[rtype(result = "Result<game::Game, ()>")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct GetGame; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#[derive(Message)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#[rtype(result = "()")] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct GameUpdate{ game_data: GameData } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 enum Answer { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     LobbyJoined(Addr<GameLobby>), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     LobbyCreated(Addr<GameLobby>), 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -75,7 +78,7 @@ impl Handler<JoinRequest> for Server { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let mb_lobby = self.lobbies.get(&jr.lobby_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         match mb_lobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Some(lobby) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                let _sent = lobby.send(jr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let _sent = lobby.do_send(jr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Answer::LobbyJoined(lobby.clone()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             None => Answer::NoSuchLobby 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,7 +95,7 @@ impl Handler<CreateLobbyRequest> for Server { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             None => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let lobby = GameLobby::new(clr.lobby_id.clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 let lobby_addr = lobby.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                self.lobbies.insert(clr.lobby_id, lobby_addr.clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.lobbies.insert(clr.lobby_id.clone(), lobby_addr.clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Answer::LobbyCreated(lobby_addr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -100,7 +103,7 @@ impl Handler<CreateLobbyRequest> for Server { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub struct GameLobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    connected_players: Vec<Addr<GameConnection>>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    connected_players: BTreeMap<String, Addr<GameConnection>>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     game_id: String, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     game: game::Game, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -114,26 +117,43 @@ impl Actor for GameLobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl Handler<JoinRequest> for GameLobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     type Result = Answer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn handle(&mut self, jr: JoinRequest, ctx: &mut Self::Context) -> Self::Result { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.connected_players.push(jr.p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Answer::NoSuchLobby 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.connected_players.insert(jr.nick.clone(), jr.p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.game.player_join(jr.nick); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.send_game_to_all(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Answer::LobbyJoined(ctx.address()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl Handler<GetGame> for GameLobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    type Result = game::Game; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    type Result = Result<game::Game, ()>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn handle(&mut self, gg: GetGame, ctx: &mut Self::Context) -> Self::Result { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.game.clone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Ok(self.game.clone()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl GameLobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub fn new(gi: String) -> Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         GameLobby { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            connected_players: vec![], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            connected_players: BTreeMap::new(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             game_id: gi, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             game: game::Game::new() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub fn send_game_to_all(&self) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (nick, player) in &self.connected_players { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let game_state = self.create_opaque_message(nick); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            player.do_send(GameUpdate{ game_data: game_state }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub fn create_opaque_message(&self, nick: &str) -> GameData { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        GameData { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            players: self.game.players.iter().map(|p| p.nick.clone()).collect::<Vec<_>>(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            state_data: GameStateData::Creating{ available_chars: vec!['a', 'b', 'c'] } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /// 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -155,6 +175,13 @@ impl Actor for GameConnection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+impl Handler<GameUpdate> for GameConnection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    type Result = (); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn handle(&mut self, gu: GameUpdate, ctx: &mut Self::Context) -> Self::Result { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.send_message(&UpdateMessage::GameState(gu.game_data), ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for GameConnection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn handle( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         &mut self, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -172,7 +199,7 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for GameConnection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Ok(ws::Message::Text(text)) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 println!("hmmm: {:?}", text); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                self.handle_message(&text, ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.received_message(&text, ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Ok(ws::Message::Binary(bin)) => ctx.binary(bin), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Ok(ws::Message::Close(reason)) => { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -212,7 +239,7 @@ impl GameConnection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ctx.text(txt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub fn handle_message(&mut self, text: &str, ctx: &mut <Self as Actor>::Context) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub fn received_message(&mut self, text: &str, ctx: &mut <Self as Actor>::Context) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         println!("hm: {:?}", text); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let parsed: Result<ClientMessage, _> = serde_json::from_str(text); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if let Ok(msg) = parsed { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -220,36 +247,36 @@ impl GameConnection { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ClientMessage::CreateGame{game_id, nick} => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.game_id = Some(game_id.clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.nick = Some(nick); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    let lobby_addr = block_on(self.server.send(CreateLobbyRequest{ lobby_id: game_id.clone(), p: ctx.address() })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    match lobby_addr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    let lobby_addr = self.server.do_send(CreateLobbyRequest{ lobby_id: game_id.clone(), p: ctx.address() }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    /*match lobby_addr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         Ok(Answer::LobbyAlreadyExists) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             self.send_message(&UpdateMessage::GameAlreadyExists{ game_id: game_id.clone() }, ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         Ok(Answer::LobbyCreated(lobby_addr)) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            let gm = block_on(lobby_addr.send(GetGame)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            let gm = lobby_addr.do_send(GetGame); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             self.send_message(&UpdateMessage::GameState(gm.unwrap()), ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         _ => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             println!("internal error creating lobby"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ClientMessage::Join{game_id, nick} => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    let lobby_addr = self.server.do_send(JoinRequest{ lobby_id: game_id.clone(), nick: nick.clone(), p: ctx.address() }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.game_id = Some(game_id.clone()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.nick = Some(nick); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    let lobby_addr = block_on(self.server.send(JoinRequest{ lobby_id: game_id.clone(), p: ctx.address() })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    match lobby_addr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    /*match lobby_addr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         Ok(Answer::NoSuchLobby) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             self.send_message(&UpdateMessage::GameNotFound{ game_id: game_id.clone() }, ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         Ok(Answer::LobbyJoined(lobby_addr)) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            let gm = block_on(lobby_addr.send(GetGame)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            self.send_message(&UpdateMessage::GameState(gm.unwrap()), ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            //let gm = lobby_addr.send(GetGame)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            //self.send_message(&UpdateMessage::GameState(gm.unwrap()), ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         _ => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             println!("internal error joining lobby"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 |