NewAction { action: UserAction },
TakeActionSuccess { action: UserAction },
TakeActionFailure { action: UserAction, reason: String },
- NewMessage { username: Username, message: String },
LeaveGameSuccess,
LeaveGameFailure { reason: String },
LeaveLobbySuccess,
LeaveLobbyFailure { reason: String },
- HandHistory { games: Vec<(GameSummary, Vec<UserAction>)> }, // TODO
ProtocolError { reason: String },
}
self.client = ClientState::LoggedIn{username, state: LoggedInState::Idle};
ServerMessage::LeaveLobbySuccess
}
- (&mut ClientState::LoggedIn{username, ..}, ClientMessage::LeaveLobby) => {
+ (&mut ClientState::LoggedIn{..}, ClientMessage::LeaveLobby) => {
ServerMessage::LeaveLobbyFailure{reason: "Not in lobby".to_string()}
}
(&mut ClientState::LoggedIn{username, state: LoggedInState::InGame{..}}, ClientMessage::LeaveGame) => {
self.client = ClientState::LoggedIn{username, state: LoggedInState::Idle};
ServerMessage::LeaveGameSuccess
}
+ (&mut ClientState::LoggedIn{..}, ClientMessage::LeaveGame) => {
+ ServerMessage::LeaveGameFailure{reason: "Not in game".to_string()}
+ }
(&mut ClientState::LoggedIn{..}, ClientMessage::Logout) => {
self.client = ClientState::Connected;
ServerMessage::LogoutSuccess
-use std::collections::{HashMap, HashSet};
+use std::collections::HashSet;
use async_std::stream::StreamExt;
use futures::channel::mpsc::Receiver;
-use rand::prelude::*;
use redis::{ErrorKind, RedisError, RedisResult};
use crate::client::ClientInterest;
-use crate::game::{Action, Game, ValidatedUserAction};
+use crate::game::{Game, ValidatedUserAction};
use crate::server::{ActionStatus, ServerState};
pub struct Dealer {
server.register_interests(interests).await;
let summary = server.game_summary(id).await?;
let seed = server.game_seed(id).await?;
- let mut game = Game::new(summary, seed);
+ let game = Game::new(summary, seed);
let mut dealer = Dealer{server, dealer: DealerState{game}};
dealer.retrieve_updates().await?;
Ok(dealer)
mod whist;
use std::collections::HashSet;
-use std::fmt::{Debug, Display, Formatter};
+use std::fmt::Debug;
use crate::rng::Seed;
use crate::username::Username;
pub use self::action::{Action, ActionError, UserAction, ValidatedUserAction};
-pub trait Game : Debug + CloneBox + Send + Sync {
+pub trait Game : Debug + CloneBoxGame + Send + Sync {
fn id(&self) -> i64;
fn players(&self) -> HashSet<Username>;
fn actions_len(&self) -> usize;
fn next_dealer_action(&self) -> Option<ValidatedUserAction>;
}
-trait CloneBox {
+pub trait CloneBoxGame {
fn clone_box(&self) -> Box<dyn Game>;
}
-impl<T: Clone + Game + 'static> CloneBox for T {
+impl<T: Clone + Game + 'static> CloneBoxGame for T {
fn clone_box(&self) -> Box<dyn Game> {
Box::new(self.clone())
}
self.draws as f64 / (self.player1_wins + self.player2_wins + self.draws) as f64
}
+ #[allow(unused)] // FIXME
pub fn favourite(&self) -> Player {
match self.player1_wins.cmp(&self.player2_wins) {
Ordering::Greater => Player::Player1,
use std::convert::TryInto;
use itertools::Itertools;
-use rand::seq::IteratorRandom;
-use rand::Rng;
-use crate::card::{Card, Suit, FIFTY_TWO_CARD_DECK};
+use crate::card::{Card, FIFTY_TWO_CARD_DECK};
use crate::seats::Seats;
use crate::username::Username;
use crate::util::max::IteratorMaxItems;
Ok(ValidatedUserAction(UserAction{username, action: Action::Leave}))
}
(_, _) if !self.seats.contains_player(username) => Err(ActionError::NotAuthorised),
- (State::NotStarted, Action::Leave) => {
- Ok(ValidatedUserAction(UserAction{username, action: Action::Leave}))
- }
(State::Completed, _) => Err(ActionError::GameHasEnded),
(_, Action::Leave) => Err(ActionError::GameHasStarted),
(State::Dealing, _) | (State::DealingFlop, _) | (State::DealingTurn, _) | (State::DealingRiver, _) => {
use signal_hook_async_std::Signals;
use tide::{Body, Request, Error, Response, StatusCode};
use tide::utils::After;
-use tide_rustls::TlsListener;
+//use tide_rustls::TlsListener;
use tide_websockets::{Message, WebSocket, WebSocketConnection};
mod api;
use getrandom::getrandom;
use itertools::Itertools;
-use rand::{SeedableRng, CryptoRng, RngCore, Rng, Error, seq::IteratorRandom};
+use rand::{SeedableRng, CryptoRng, Rng, RngCore, Error, seq::IteratorRandom};
use rand_chacha::ChaCha20Rng;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
use std::collections::HashSet;
- use rand::Rng;
-
#[test]
fn chacha_true_values() {
let seed_json = r#"{"rng":"ChaCha20","seed":"0000000000000000000000000000000000000000000000000000000000000000"}"#;
use std::collections::HashSet;
use std::convert::TryFrom;
-use futures::{channel::mpsc::{Receiver, Sender, channel}, SinkExt, future::try_join_all};
+use futures::{channel::mpsc::{Receiver, Sender, channel}, SinkExt};
use redis::{AsyncCommands, ErrorKind, FromRedisValue, Msg, RedisError, RedisResult, RedisWrite, Script, ToRedisArgs, Value, aio::MultiplexedConnection};
use serde::{Serialize, Deserialize};
use crate::auth::Auth;
use crate::client::ClientInterest;
-use crate::game::{GameList, GameSettings, GameSummary, UserAction, ValidatedUserAction};
+use crate::game::{GameSettings, GameSummary, ValidatedUserAction};
use crate::rng::Seed;
use crate::username::Username;
for id in games {
match self.game_summary(id).await {
Ok(summary) => summaries.push(summary),
- Err(err) => error!("Could not find summary for game {}", id),
+ Err(err) => error!("Could not find summary for game {}: {}", id, err),
}
}
Ok(summaries)