|
@@ -6,6 +6,8 @@ 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 rand::thread_rng;
|
|
|
|
+use rand::seq::SliceRandom;
|
|
use crate::game;
|
|
use crate::game;
|
|
use crate::websocket;
|
|
use crate::websocket;
|
|
use crate::websocket::*;
|
|
use crate::websocket::*;
|
|
@@ -29,6 +31,11 @@ struct SubmitWordMsg{ word: String, nick: String }
|
|
#[rtype(result = "Result<game::Game, ()>")]
|
|
#[rtype(result = "Result<game::Game, ()>")]
|
|
struct GetGame;
|
|
struct GetGame;
|
|
|
|
|
|
|
|
+
|
|
|
|
+#[derive(Message)]
|
|
|
|
+#[rtype(result = "()")]
|
|
|
|
+struct LobbyJoined(Addr<GameLobby>);
|
|
|
|
+
|
|
#[derive(Message)]
|
|
#[derive(Message)]
|
|
#[rtype(result = "()")]
|
|
#[rtype(result = "()")]
|
|
struct GameUpdate{ game_data: GameData }
|
|
struct GameUpdate{ game_data: GameData }
|
|
@@ -115,16 +122,17 @@ pub struct GameLobby {
|
|
impl Actor for GameLobby {
|
|
impl Actor for GameLobby {
|
|
type Context = Context<Self>;
|
|
type Context = Context<Self>;
|
|
fn started(&mut self, ctx: &mut Self::Context) {
|
|
fn started(&mut self, ctx: &mut Self::Context) {
|
|
|
|
+ self.game.new_round();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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 {
|
|
|
|
+ jr.p.do_send(LobbyJoined(ctx.address()));
|
|
self.connected_players.insert(jr.nick.clone(), jr.p);
|
|
self.connected_players.insert(jr.nick.clone(), jr.p);
|
|
self.game.player_join(jr.nick);
|
|
self.game.player_join(jr.nick);
|
|
self.send_game_to_all();
|
|
self.send_game_to_all();
|
|
-
|
|
|
|
Answer::LobbyJoined(ctx.address())
|
|
Answer::LobbyJoined(ctx.address())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -140,6 +148,10 @@ impl Handler<SubmitWordMsg> for GameLobby {
|
|
type Result = ();
|
|
type Result = ();
|
|
fn handle(&mut self, swm: SubmitWordMsg, ctx: &mut Self::Context) -> Self::Result {
|
|
fn handle(&mut self, swm: SubmitWordMsg, ctx: &mut Self::Context) -> Self::Result {
|
|
self.game.submit_creation(&swm.nick, swm.word);
|
|
self.game.submit_creation(&swm.nick, swm.word);
|
|
|
|
+ if self.game.all_submitted() {
|
|
|
|
+ self.game.next_state();
|
|
|
|
+ self.send_game_to_all();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -162,7 +174,39 @@ impl GameLobby {
|
|
pub fn create_opaque_message(&self, nick: &str) -> GameData {
|
|
pub fn create_opaque_message(&self, nick: &str) -> GameData {
|
|
GameData {
|
|
GameData {
|
|
players: self.game.players.iter().map(|p| websocket::PlayerData{ nick: p.nick.clone(), points: 0 }).collect::<Vec<_>>(),
|
|
players: self.game.players.iter().map(|p| websocket::PlayerData{ nick: p.nick.clone(), points: 0 }).collect::<Vec<_>>(),
|
|
- state_data: GameStateData::Creating{ available_chars: vec!['a', 'b', 'c'] }
|
|
|
|
|
|
+ state_data: match self.game.state {
|
|
|
|
+ game::GameState::Creating => {
|
|
|
|
+ GameStateData::Creating{
|
|
|
|
+ question: "Ein Gerät um Elche zu häuten".to_owned(),
|
|
|
|
+ available_chars: vec!['a', 'b', 'c']
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ game::GameState::Guessing => {
|
|
|
|
+ self.create_guessing()
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pub fn create_guessing(&self) -> GameStateData {
|
|
|
|
+ let chars = self.game.round.exercises.iter()
|
|
|
|
+ .map(|x| x.letters.clone())
|
|
|
|
+ .collect::<Vec<_>>();
|
|
|
|
+
|
|
|
|
+ let words_with_chars = self.game.players.iter()
|
|
|
|
+ .map(|p| p.submitted_word.clone().unwrap_or("".to_owned()))
|
|
|
|
+ .zip(chars)
|
|
|
|
+ .collect::<Vec<_>>();
|
|
|
|
+
|
|
|
|
+ let mut questions = self.game.round.exercises.iter()
|
|
|
|
+ .map(|x| x.question.clone())
|
|
|
|
+ .collect::<Vec<_>>();
|
|
|
|
+
|
|
|
|
+ questions.shuffle(&mut thread_rng());
|
|
|
|
+
|
|
|
|
+ GameStateData::Guessing {
|
|
|
|
+ submitted_words: words_with_chars,
|
|
|
|
+ questions: questions
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -186,6 +230,13 @@ impl Actor for GameConnection {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+impl Handler<LobbyJoined> for GameConnection {
|
|
|
|
+ type Result = ();
|
|
|
|
+ fn handle(&mut self, gu: LobbyJoined, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
+ self.game_lobby = Some(gu.0);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
impl Handler<GameUpdate> for GameConnection {
|
|
impl Handler<GameUpdate> for GameConnection {
|
|
type Result = ();
|
|
type Result = ();
|
|
fn handle(&mut self, gu: GameUpdate, ctx: &mut Self::Context) -> Self::Result {
|
|
fn handle(&mut self, gu: GameUpdate, ctx: &mut Self::Context) -> Self::Result {
|
|
@@ -199,7 +250,6 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for GameConnection {
|
|
msg: Result<ws::Message, ws::ProtocolError>,
|
|
msg: Result<ws::Message, ws::ProtocolError>,
|
|
ctx: &mut Self::Context,
|
|
ctx: &mut Self::Context,
|
|
) {
|
|
) {
|
|
- // process websocket messages
|
|
|
|
match msg {
|
|
match msg {
|
|
Ok(ws::Message::Ping(msg)) => {
|
|
Ok(ws::Message::Ping(msg)) => {
|
|
self.heartbeat = Instant::now();
|
|
self.heartbeat = Instant::now();
|
|
@@ -251,48 +301,28 @@ impl GameConnection {
|
|
}
|
|
}
|
|
|
|
|
|
pub fn received_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);
|
|
let parsed: Result<ClientMessage, _> = serde_json::from_str(text);
|
|
if let Ok(msg) = parsed {
|
|
if let Ok(msg) = parsed {
|
|
match msg {
|
|
match msg {
|
|
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 = 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 = lobby_addr.do_send(GetGame);
|
|
|
|
- self.send_message(&UpdateMessage::GameState(gm.unwrap()), ctx);
|
|
|
|
- },
|
|
|
|
- _ => {
|
|
|
|
- println!("internal error creating lobby");
|
|
|
|
- }
|
|
|
|
- }*/
|
|
|
|
|
|
+ self.server.do_send(CreateLobbyRequest{ lobby_id: game_id.clone(), p: ctx.address() });
|
|
},
|
|
},
|
|
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.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);
|
|
- /*match lobby_addr {
|
|
|
|
- Ok(Answer::NoSuchLobby) => {
|
|
|
|
- self.send_message(&UpdateMessage::GameNotFound{ game_id: game_id.clone() }, ctx);
|
|
|
|
- },
|
|
|
|
- Ok(Answer::LobbyJoined(lobby_addr)) => {
|
|
|
|
- //let gm = lobby_addr.send(GetGame));
|
|
|
|
- //self.send_message(&UpdateMessage::GameState(gm.unwrap()), ctx);
|
|
|
|
- },
|
|
|
|
- _ => {
|
|
|
|
- println!("internal error joining lobby");
|
|
|
|
- }
|
|
|
|
- }*/
|
|
|
|
},
|
|
},
|
|
ClientMessage::SubmitWord{ word } => {
|
|
ClientMessage::SubmitWord{ word } => {
|
|
- if let Some(lobby) = &self.game_lobby {
|
|
|
|
- if let Some(nick) = &self.nick {
|
|
|
|
- lobby.do_send(SubmitWordMsg{ word: word, nick: nick.clone() });
|
|
|
|
|
|
+ match &self.game_lobby {
|
|
|
|
+ Some(lobby) => {
|
|
|
|
+ if let Some(nick) = &self.nick {
|
|
|
|
+ lobby.do_send(SubmitWordMsg{ word: word, nick: nick.clone() });
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ None => {
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|