|
@@ -1,504 +0,0 @@
|
|
-use std::collections::BTreeMap;
|
|
|
|
-use std::collections::BTreeSet;
|
|
|
|
-use std::time::{Duration, Instant};
|
|
|
|
-use std::sync::{Mutex, RwLock, Arc};
|
|
|
|
-use actix::dev::{MessageResponse, ResponseChannel};
|
|
|
|
-use actix::prelude::*;
|
|
|
|
-use actix_web::{web, Error, HttpRequest, HttpResponse};
|
|
|
|
-use actix_web_actors::ws;
|
|
|
|
-use rand::thread_rng;
|
|
|
|
-use rand::seq::SliceRandom;
|
|
|
|
-use crate::game;
|
|
|
|
-use crate::websocket;
|
|
|
|
-use crate::websocket::*;
|
|
|
|
-use crate::datasource;
|
|
|
|
-
|
|
|
|
-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, nick: String, p: Addr<GameConnection> }
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "Answer")]
|
|
|
|
-struct CreateLobbyRequest{ lobby_id: String, p: Addr<GameConnection> }
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct ReadyMsg(String);
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct SubmitWordMsg{ word: String, nick: String }
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct SubmitGuessMsg{ guesses: Vec<(String, String)>, nick: String }
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct ResultMsg{ results: RoundResultData }
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "Result<game::Game, ()>")]
|
|
|
|
-struct GetGame;
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct NoSuchLobby(String);
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct LobbyJoined(Addr<GameLobby>);
|
|
|
|
-
|
|
|
|
-#[derive(Message)]
|
|
|
|
-#[rtype(result = "()")]
|
|
|
|
-struct GameUpdate{ game_data: GameData }
|
|
|
|
-
|
|
|
|
-enum Answer {
|
|
|
|
- LobbyJoined(Addr<GameLobby>),
|
|
|
|
- LobbyCreated(Addr<GameLobby>),
|
|
|
|
- LobbyAlreadyExists,
|
|
|
|
- NoSuchLobby,
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-impl<A, M> MessageResponse<A, M> for Answer
|
|
|
|
-where
|
|
|
|
- A: Actor,
|
|
|
|
- M: Message<Result = Answer>,
|
|
|
|
-{
|
|
|
|
- fn handle<R: ResponseChannel<M>>(self, _: &mut A::Context, tx: Option<R>) {
|
|
|
|
- if let Some(tx) = tx {
|
|
|
|
- tx.send(self);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-impl<A, M> MessageResponse<A, M> for game::Game
|
|
|
|
-where
|
|
|
|
- A: Actor,
|
|
|
|
- M: Message<Result = game::Game>,
|
|
|
|
-{
|
|
|
|
- fn handle<R: ResponseChannel<M>>(self, _: &mut A::Context, tx: Option<R>) {
|
|
|
|
- if let Some(tx) = tx {
|
|
|
|
- tx.send(self);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-pub struct Server {
|
|
|
|
- pub lobbies: BTreeMap<String, Addr<GameLobby>>,
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Actor for Server {
|
|
|
|
- type Context = Context<Self>;
|
|
|
|
- fn started(&mut self, ctx: &mut Self::Context) {
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<JoinRequest> for Server {
|
|
|
|
- type Result = Answer;
|
|
|
|
- fn handle(&mut self, jr: JoinRequest, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- let mb_lobby = self.lobbies.get(&jr.lobby_id);
|
|
|
|
- match mb_lobby {
|
|
|
|
- Some(lobby) => {
|
|
|
|
- let _sent = lobby.do_send(jr);
|
|
|
|
- Answer::LobbyJoined(lobby.clone())
|
|
|
|
- },
|
|
|
|
- None => {
|
|
|
|
- jr.p.do_send(NoSuchLobby(jr.lobby_id));
|
|
|
|
- Answer::NoSuchLobby
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<CreateLobbyRequest> for Server {
|
|
|
|
- type Result = Answer;
|
|
|
|
- fn handle(&mut self, clr: CreateLobbyRequest, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- let existing_lobby = self.lobbies.get(&clr.lobby_id);
|
|
|
|
- match existing_lobby {
|
|
|
|
- Some(_) => Answer::LobbyAlreadyExists,
|
|
|
|
- None => {
|
|
|
|
- let lobby = GameLobby::new(clr.lobby_id.clone());
|
|
|
|
- let lobby_addr = lobby.start();
|
|
|
|
- self.lobbies.insert(clr.lobby_id.clone(), lobby_addr.clone());
|
|
|
|
- Answer::LobbyCreated(lobby_addr)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#[derive(PartialEq)]
|
|
|
|
-enum LobbyState {
|
|
|
|
- Starting,
|
|
|
|
- Creating,
|
|
|
|
- Guessing,
|
|
|
|
- Revealing
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-pub struct GameLobby {
|
|
|
|
- connected_players: BTreeMap<String, Addr<GameConnection>>,
|
|
|
|
- game_id: String,
|
|
|
|
- game: game::Game,
|
|
|
|
- waiting_players: BTreeMap<String, Addr<GameConnection>>,
|
|
|
|
- ready_players: Vec<String>,
|
|
|
|
- lobby_state: LobbyState,
|
|
|
|
- data_source: Box<dyn datasource::DataSource<String>>,
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Actor for GameLobby {
|
|
|
|
- type Context = Context<Self>;
|
|
|
|
- fn started(&mut self, ctx: &mut Self::Context) {
|
|
|
|
- self.lobby_state = LobbyState::Starting;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<JoinRequest> for GameLobby {
|
|
|
|
- type Result = Answer;
|
|
|
|
- fn handle(&mut self, jr: JoinRequest, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- if self.lobby_state == LobbyState::Starting {
|
|
|
|
- jr.p.do_send(LobbyJoined(ctx.address()));
|
|
|
|
- self.connected_players.insert(jr.nick.clone(), jr.p);
|
|
|
|
- self.game.player_join(jr.nick);
|
|
|
|
- self.send_game_to_all();
|
|
|
|
- Answer::LobbyJoined(ctx.address())
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- self.waiting_players.insert(jr.nick.clone(), jr.p);
|
|
|
|
- Answer::NoSuchLobby
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<ReadyMsg> for GameLobby {
|
|
|
|
- type Result = ();
|
|
|
|
- fn handle(&mut self, rm: ReadyMsg, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- if !self.ready_players.contains(&rm.0) {
|
|
|
|
- self.ready_players.push(rm.0);
|
|
|
|
- }
|
|
|
|
- if self.ready_players.len() >= self.connected_players.len() {
|
|
|
|
- self.set_state(LobbyState::Creating);
|
|
|
|
- self.send_game_to_all();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<GetGame> for GameLobby {
|
|
|
|
- type Result = Result<game::Game, ()>;
|
|
|
|
- fn handle(&mut self, gg: GetGame, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- Ok(self.game.clone())
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<SubmitWordMsg> for GameLobby {
|
|
|
|
- type Result = ();
|
|
|
|
- fn handle(&mut self, swm: SubmitWordMsg, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- let correct = self.game.submit_creation(&swm.nick, swm.word);
|
|
|
|
- if self.game.all_words_submitted() {
|
|
|
|
- self.set_state(LobbyState::Guessing);
|
|
|
|
- self.game.next_state();
|
|
|
|
- self.send_game_to_all();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Handler<SubmitGuessMsg> for GameLobby {
|
|
|
|
- type Result = ();
|
|
|
|
- fn handle(&mut self, sgm: SubmitGuessMsg, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- self.game.submit_guess(&sgm.nick, sgm.guesses);
|
|
|
|
- if self.game.all_guesses_submitted() {
|
|
|
|
- self.set_state(LobbyState::Revealing);
|
|
|
|
- let results = self.create_result_data();
|
|
|
|
- self.broadcast_results(results);
|
|
|
|
-
|
|
|
|
- self.game.next_state();
|
|
|
|
- self.send_game_to_all();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl GameLobby {
|
|
|
|
- pub fn new(gi: String) -> Self {
|
|
|
|
- GameLobby {
|
|
|
|
- connected_players: BTreeMap::new(),
|
|
|
|
- game_id: gi,
|
|
|
|
- game: game::Game::new(),
|
|
|
|
- waiting_players: BTreeMap::new(),
|
|
|
|
- ready_players: Vec::new(),
|
|
|
|
- lobby_state: LobbyState::Starting,
|
|
|
|
- data_source: Box::new(datasource::ArraySource::create(vec![
|
|
|
|
- "Delikatessfutter für Hunde".to_owned(),
|
|
|
|
- "Ein Hotel für die ganze Familie".to_owned(),
|
|
|
|
- "Brasilianischer Superstar".to_owned(),
|
|
|
|
- "Buchstabe des griechischen Alphabets".to_owned(),
|
|
|
|
- ]))
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fn set_state(&mut self, new_state: LobbyState) {
|
|
|
|
-
|
|
|
|
- match new_state {
|
|
|
|
- LobbyState::Starting => {
|
|
|
|
- for (nick, _addr) in &self.waiting_players {
|
|
|
|
- self.game.player_join(nick.clone());
|
|
|
|
- }
|
|
|
|
- self.connected_players.append(&mut self.waiting_players);
|
|
|
|
- self.ready_players.clear();
|
|
|
|
- },
|
|
|
|
- LobbyState::Creating => {
|
|
|
|
- let ds = &self.data_source;
|
|
|
|
- let mut index = 0;
|
|
|
|
- self.game.start_round(|| {
|
|
|
|
- index += 1;
|
|
|
|
- ds.get_ith(index - 1).unwrap().clone()
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- _ => {}
|
|
|
|
- }
|
|
|
|
- self.lobby_state = new_state;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- 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_result_data(&self) -> RoundResultData {
|
|
|
|
- let results_table = self.game.create_results();
|
|
|
|
-
|
|
|
|
- let words = self.game.players.iter()
|
|
|
|
- .map(|p| p.submitted_word.clone().unwrap())
|
|
|
|
- .collect::<Vec<_>>();
|
|
|
|
- let questions = self.game.players.iter()
|
|
|
|
- .map(|x| x.creating_exercise.as_ref().unwrap().question.clone())
|
|
|
|
- .chain(self.game.additional_questions.clone().into_iter())
|
|
|
|
- .collect::<Vec<_>>();
|
|
|
|
- let solutions = words.iter()
|
|
|
|
- .map(|x| x.clone())
|
|
|
|
- .zip(questions.iter().map(|x| x.clone()))
|
|
|
|
- .collect::<Vec<_>>();
|
|
|
|
-
|
|
|
|
- let guesses = self.game.create_results();
|
|
|
|
-
|
|
|
|
- RoundResultData {
|
|
|
|
- words,
|
|
|
|
- questions,
|
|
|
|
- solutions,
|
|
|
|
- guesses
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn broadcast_results(&self, results: RoundResultData) {
|
|
|
|
- for (_nick, player) in &self.connected_players {
|
|
|
|
- player.do_send(ResultMsg{ results: results.clone() });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn create_opaque_message(&self, nick: &str) -> GameData {
|
|
|
|
-
|
|
|
|
- let player = self.game.players.iter()
|
|
|
|
- .find(|p| p.nick == nick);
|
|
|
|
- GameData {
|
|
|
|
- players: self.game.players.iter()
|
|
|
|
- .map(|p| websocket::PlayerData{ nick: p.nick.clone(), points: 0 })
|
|
|
|
- .collect::<Vec<_>>(),
|
|
|
|
- state_data:
|
|
|
|
- match self.game.state {
|
|
|
|
- game::GameState::Starting => {
|
|
|
|
- GameStateData::Starting
|
|
|
|
- },
|
|
|
|
- game::GameState::Creating => {
|
|
|
|
- GameStateData::Creating{
|
|
|
|
- question: player.unwrap().creating_exercise.as_ref().unwrap().question.clone(),
|
|
|
|
- available_chars: player.unwrap().creating_exercise.as_ref().unwrap().letters.clone()
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- game::GameState::Guessing => {
|
|
|
|
- self.create_guessing()
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn check_optionals(&self) {
|
|
|
|
- for p in &self.game.players {
|
|
|
|
- println!("{:?}", p);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn create_guessing(&self) -> GameStateData {
|
|
|
|
- self.check_optionals();
|
|
|
|
- let words_with_chars = self.game.players.iter()
|
|
|
|
- .map(|p|
|
|
|
|
- (p.submitted_word.clone().unwrap(),
|
|
|
|
- p.creating_exercise.clone().unwrap().letters))
|
|
|
|
- .collect::<Vec<_>>();
|
|
|
|
-
|
|
|
|
- let mut questions = self.game.players.iter()
|
|
|
|
- .map(|p| p.creating_exercise.clone().unwrap().question)
|
|
|
|
- .collect::<Vec<_>>();
|
|
|
|
- questions.append(&mut self.game.additional_questions.iter()
|
|
|
|
- .map(|x| x.clone())
|
|
|
|
- .collect::<Vec<_>>()
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- questions.shuffle(&mut thread_rng());
|
|
|
|
-
|
|
|
|
- GameStateData::Guessing {
|
|
|
|
- submitted_words: words_with_chars,
|
|
|
|
- questions: questions
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-///
|
|
|
|
-/// connection to one single client
|
|
|
|
-///
|
|
|
|
-pub struct GameConnection {
|
|
|
|
- heartbeat: Instant,
|
|
|
|
- nick: Option<String>,
|
|
|
|
- game_id: Option<String>,
|
|
|
|
- server: Addr<Server>,
|
|
|
|
- game_lobby: Option<Addr<GameLobby>>
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl Actor for GameConnection {
|
|
|
|
- type Context = ws::WebsocketContext<Self>;
|
|
|
|
-
|
|
|
|
- fn started(&mut self, ctx: &mut Self::Context) {
|
|
|
|
- self.initiate_heartbeat(ctx);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-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<NoSuchLobby> for GameConnection {
|
|
|
|
- type Result = ();
|
|
|
|
- fn handle(&mut self, nsl: NoSuchLobby, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- self.send_message(&UpdateMessage::GameNotFound{ game_id: nsl.0 }, ctx);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-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 Handler<ResultMsg> for GameConnection {
|
|
|
|
- type Result = ();
|
|
|
|
- fn handle(&mut self, rm: ResultMsg, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
- self.send_message(&UpdateMessage::RoundResult(rm.results), ctx);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for GameConnection {
|
|
|
|
- fn handle(
|
|
|
|
- &mut self,
|
|
|
|
- msg: Result<ws::Message, ws::ProtocolError>,
|
|
|
|
- ctx: &mut Self::Context,
|
|
|
|
- ) {
|
|
|
|
- match msg {
|
|
|
|
- Ok(ws::Message::Ping(msg)) => {
|
|
|
|
- self.heartbeat = Instant::now();
|
|
|
|
- ctx.pong(&msg);
|
|
|
|
- }
|
|
|
|
- Ok(ws::Message::Pong(_)) => {
|
|
|
|
- self.heartbeat = Instant::now();
|
|
|
|
- }
|
|
|
|
- Ok(ws::Message::Text(text)) => {
|
|
|
|
- println!("hmmm: {:?}", text);
|
|
|
|
- self.received_message(&text, ctx);
|
|
|
|
- },
|
|
|
|
- Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
|
|
|
|
- Ok(ws::Message::Close(reason)) => {
|
|
|
|
- ctx.close(reason);
|
|
|
|
- ctx.stop();
|
|
|
|
- }
|
|
|
|
- _ => ctx.stop(),
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-impl GameConnection {
|
|
|
|
- pub fn new(server_addr: Addr<Server>) -> Self {
|
|
|
|
- GameConnection {
|
|
|
|
- heartbeat: Instant::now(),
|
|
|
|
- nick: None,
|
|
|
|
- game_id: None,
|
|
|
|
- server: server_addr,
|
|
|
|
- game_lobby: None
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn initiate_heartbeat(&self, ctx: &mut <Self as Actor>::Context) {
|
|
|
|
- ctx.run_interval(HEARTBEAT_INTERVAL, |act, ctx| {
|
|
|
|
- if Instant::now().duration_since(act.heartbeat) > CLIENT_TIMEOUT {
|
|
|
|
- //println!("Websocket Client heartbeat failed, disconnecting!");
|
|
|
|
- ctx.stop();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- ctx.ping(b"");
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn send_message(&self, m: &UpdateMessage, ctx: &mut <Self as Actor>::Context) {
|
|
|
|
- let txt = serde_json::to_string(m).unwrap();
|
|
|
|
- println!("{:?}", txt);
|
|
|
|
- ctx.text(txt);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pub fn received_message(&mut self, text: &str, ctx: &mut <Self as Actor>::Context) {
|
|
|
|
- let parsed: Result<ClientMessage, _> = serde_json::from_str(text);
|
|
|
|
- if let Ok(msg) = parsed {
|
|
|
|
- match msg {
|
|
|
|
- ClientMessage::CreateGame{game_id, nick} => {
|
|
|
|
- self.game_id = Some(game_id.clone());
|
|
|
|
- self.nick = Some(nick);
|
|
|
|
- self.server.do_send(CreateLobbyRequest{ lobby_id: game_id.clone(), p: ctx.address() });
|
|
|
|
- },
|
|
|
|
- ClientMessage::Join{game_id, nick} => {
|
|
|
|
- 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);
|
|
|
|
- },
|
|
|
|
- ClientMessage::Ready => {
|
|
|
|
- if let Some(lobby) = &self.game_lobby {
|
|
|
|
- if let Some(nick) = &self.nick {
|
|
|
|
- lobby.do_send(ReadyMsg(nick.clone()));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- 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() });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- ClientMessage::SubmitGuess{ guesses } => {
|
|
|
|
- if let Some(lobby) = &self.game_lobby {
|
|
|
|
- if let Some(nick) = &self.nick {
|
|
|
|
- lobby.do_send(SubmitGuessMsg{ guesses: guesses, nick: nick.clone() });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- println!("error parsing json");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|