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