Can play against random player
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							
								
								
									
										247
									
								
								rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										247
									
								
								rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -464,11 +464,14 @@ dependencies = [ | ||||
|  "crossterm", | ||||
|  "env_logger", | ||||
|  "futures", | ||||
|  "hostname", | ||||
|  "hyper-rustls", | ||||
|  "lazy_static", | ||||
|  "log", | ||||
|  "num", | ||||
|  "num-derive", | ||||
|  "num-traits", | ||||
|  "rustls", | ||||
|  "sea_battle_backend", | ||||
|  "serde_json", | ||||
|  "serde_urlencoded", | ||||
| @@ -505,6 +508,16 @@ dependencies = [ | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "core-foundation" | ||||
| version = "0.9.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" | ||||
| dependencies = [ | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "core-foundation-sys" | ||||
| version = "0.8.3" | ||||
| @@ -891,6 +904,17 @@ version = "0.4.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" | ||||
|  | ||||
| [[package]] | ||||
| name = "hostname" | ||||
| version = "0.3.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "match_cfg", | ||||
|  "winapi", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "http" | ||||
| version = "0.2.8" | ||||
| @@ -902,6 +926,17 @@ dependencies = [ | ||||
|  "itoa", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "http-body" | ||||
| version = "0.4.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
|  "http", | ||||
|  "pin-project-lite", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "httparse" | ||||
| version = "1.8.0" | ||||
| @@ -920,6 +955,44 @@ version = "2.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" | ||||
|  | ||||
| [[package]] | ||||
| name = "hyper" | ||||
| version = "0.14.20" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
|  "futures-channel", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "http", | ||||
|  "http-body", | ||||
|  "httparse", | ||||
|  "httpdate", | ||||
|  "itoa", | ||||
|  "pin-project-lite", | ||||
|  "socket2", | ||||
|  "tokio", | ||||
|  "tower-service", | ||||
|  "tracing", | ||||
|  "want", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "hyper-rustls" | ||||
| version = "0.23.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" | ||||
| dependencies = [ | ||||
|  "http", | ||||
|  "hyper", | ||||
|  "log", | ||||
|  "rustls", | ||||
|  "rustls-native-certs", | ||||
|  "tokio", | ||||
|  "tokio-rustls", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "iana-time-zone" | ||||
| version = "0.1.51" | ||||
| @@ -1059,6 +1132,12 @@ dependencies = [ | ||||
|  "cfg-if", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "match_cfg" | ||||
| version = "0.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" | ||||
|  | ||||
| [[package]] | ||||
| name = "memchr" | ||||
| version = "2.5.0" | ||||
| @@ -1204,6 +1283,12 @@ version = "1.15.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" | ||||
|  | ||||
| [[package]] | ||||
| name = "openssl-probe" | ||||
| version = "0.1.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" | ||||
|  | ||||
| [[package]] | ||||
| name = "os_str_bytes" | ||||
| version = "6.3.0" | ||||
| @@ -1361,6 +1446,21 @@ version = "0.6.27" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" | ||||
|  | ||||
| [[package]] | ||||
| name = "ring" | ||||
| version = "0.16.20" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "libc", | ||||
|  "once_cell", | ||||
|  "spin", | ||||
|  "untrusted", | ||||
|  "web-sys", | ||||
|  "winapi", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "rustc_version" | ||||
| version = "0.4.0" | ||||
| @@ -1370,12 +1470,55 @@ dependencies = [ | ||||
|  "semver", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "rustls" | ||||
| version = "0.20.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" | ||||
| dependencies = [ | ||||
|  "log", | ||||
|  "ring", | ||||
|  "sct", | ||||
|  "webpki", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "rustls-native-certs" | ||||
| version = "0.6.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" | ||||
| dependencies = [ | ||||
|  "openssl-probe", | ||||
|  "rustls-pemfile", | ||||
|  "schannel", | ||||
|  "security-framework", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "rustls-pemfile" | ||||
| version = "1.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" | ||||
| dependencies = [ | ||||
|  "base64", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "ryu" | ||||
| version = "1.0.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" | ||||
|  | ||||
| [[package]] | ||||
| name = "schannel" | ||||
| version = "0.1.20" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" | ||||
| dependencies = [ | ||||
|  "lazy_static", | ||||
|  "windows-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "scopeguard" | ||||
| version = "1.1.0" | ||||
| @@ -1388,6 +1531,16 @@ version = "1.0.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" | ||||
|  | ||||
| [[package]] | ||||
| name = "sct" | ||||
| version = "0.7.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" | ||||
| dependencies = [ | ||||
|  "ring", | ||||
|  "untrusted", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "sea_battle_backend" | ||||
| version = "0.1.0" | ||||
| @@ -1411,6 +1564,29 @@ dependencies = [ | ||||
|  "uuid", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "security-framework" | ||||
| version = "2.7.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" | ||||
| dependencies = [ | ||||
|  "bitflags", | ||||
|  "core-foundation", | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
|  "security-framework-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "security-framework-sys" | ||||
| version = "2.6.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" | ||||
| dependencies = [ | ||||
|  "core-foundation-sys", | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "semver" | ||||
| version = "1.0.14" | ||||
| @@ -1571,6 +1747,12 @@ dependencies = [ | ||||
|  "winapi", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "spin" | ||||
| version = "0.5.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" | ||||
|  | ||||
| [[package]] | ||||
| name = "strsim" | ||||
| version = "0.10.0" | ||||
| @@ -1693,6 +1875,17 @@ dependencies = [ | ||||
|  "syn", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-rustls" | ||||
| version = "0.23.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" | ||||
| dependencies = [ | ||||
|  "rustls", | ||||
|  "tokio", | ||||
|  "webpki", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-tungstenite" | ||||
| version = "0.17.2" | ||||
| @@ -1701,8 +1894,12 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" | ||||
| dependencies = [ | ||||
|  "futures-util", | ||||
|  "log", | ||||
|  "rustls", | ||||
|  "rustls-native-certs", | ||||
|  "tokio", | ||||
|  "tokio-rustls", | ||||
|  "tungstenite", | ||||
|  "webpki", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -1719,6 +1916,12 @@ dependencies = [ | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tower-service" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" | ||||
|  | ||||
| [[package]] | ||||
| name = "tracing" | ||||
| version = "0.1.37" | ||||
| @@ -1740,6 +1943,12 @@ dependencies = [ | ||||
|  "once_cell", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "try-lock" | ||||
| version = "0.2.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" | ||||
|  | ||||
| [[package]] | ||||
| name = "tui" | ||||
| version = "0.19.0" | ||||
| @@ -1766,10 +1975,12 @@ dependencies = [ | ||||
|  "httparse", | ||||
|  "log", | ||||
|  "rand", | ||||
|  "rustls", | ||||
|  "sha-1", | ||||
|  "thiserror", | ||||
|  "url", | ||||
|  "utf-8", | ||||
|  "webpki", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -1821,6 +2032,12 @@ version = "0.1.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" | ||||
|  | ||||
| [[package]] | ||||
| name = "untrusted" | ||||
| version = "0.7.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" | ||||
|  | ||||
| [[package]] | ||||
| name = "url" | ||||
| version = "2.3.1" | ||||
| @@ -1853,6 +2070,16 @@ version = "0.9.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" | ||||
|  | ||||
| [[package]] | ||||
| name = "want" | ||||
| version = "0.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" | ||||
| dependencies = [ | ||||
|  "log", | ||||
|  "try-lock", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wasi" | ||||
| version = "0.11.0+wasi-snapshot-preview1" | ||||
| @@ -1913,6 +2140,26 @@ version = "0.2.83" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" | ||||
|  | ||||
| [[package]] | ||||
| name = "web-sys" | ||||
| version = "0.3.60" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" | ||||
| dependencies = [ | ||||
|  "js-sys", | ||||
|  "wasm-bindgen", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "webpki" | ||||
| version = "0.22.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" | ||||
| dependencies = [ | ||||
|  "ring", | ||||
|  "untrusted", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "winapi" | ||||
| version = "0.3.9" | ||||
|   | ||||
| @@ -18,7 +18,10 @@ num = "0.4.0" | ||||
| num-traits = "0.2.15" | ||||
| num-derive = "0.3.3" | ||||
| textwrap = "0.15.1" | ||||
| tokio-tungstenite = "0.17.2" | ||||
| tokio-tungstenite = { version = "0.17.2", features = ["__rustls-tls", "rustls-tls-native-roots"] } | ||||
| serde_urlencoded = "0.7.1" | ||||
| futures = "0.3.23" | ||||
| serde_json = "1.0.85" | ||||
| hostname = "0.3.1" | ||||
| rustls = "0.20.6" | ||||
| hyper-rustls = { version = "0.23.0", features = ["rustls-native-certs"] } | ||||
| @@ -13,15 +13,14 @@ pub enum TestDevScreen { | ||||
|  | ||||
| #[derive(Parser, Debug)] | ||||
| pub struct CliArgs { | ||||
|     // TODO: switch default sever uri to real one when we get one | ||||
|     /// Upstream server to use | ||||
|     #[clap( | ||||
|         short, | ||||
|         long, | ||||
|         value_parser, | ||||
|         default_value = "https://fixme.communiquons.org" | ||||
|         default_value = "https://seabattleapi.communiquons.org" | ||||
|     )] | ||||
|     pub server_uri: String, | ||||
|     pub remote_server_uri: String, | ||||
|  | ||||
|     /// Local server listen address | ||||
|     #[clap(short, long, default_value = "127.0.0.1:5679")] | ||||
|   | ||||
| @@ -2,12 +2,14 @@ use crate::cli_args::cli_args; | ||||
| use crate::server; | ||||
| use futures::stream::{SplitSink, SplitStream}; | ||||
| use futures::{SinkExt, StreamExt}; | ||||
| use hyper_rustls::ConfigBuilderExt; | ||||
| use sea_battle_backend::data::GameRules; | ||||
| use sea_battle_backend::human_player_ws::{ClientMessage, ServerMessage}; | ||||
| use sea_battle_backend::server::BotPlayQuery; | ||||
| use sea_battle_backend::server::{BotPlayQuery, PlayRandomQuery}; | ||||
| use sea_battle_backend::utils::{boxed_error, Res}; | ||||
| use std::sync::mpsc; | ||||
| use std::fmt::Display; | ||||
| use std::sync::mpsc::TryRecvError; | ||||
| use std::sync::{mpsc, Arc}; | ||||
| use tokio::net::TcpStream; | ||||
| use tokio_tungstenite::tungstenite::Message; | ||||
| use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; | ||||
| @@ -44,14 +46,41 @@ impl Client { | ||||
|         .await | ||||
|     } | ||||
|  | ||||
|     /// Start to play against a random player | ||||
|     pub async fn start_random_play<D: Display>(player_name: D) -> Res<Self> { | ||||
|         Self::connect_url( | ||||
|             &cli_args().remote_server_uri, | ||||
|             &format!( | ||||
|                 "/play/random?{}", | ||||
|                 serde_urlencoded::to_string(&PlayRandomQuery { | ||||
|                     player_name: player_name.to_string() | ||||
|                 }) | ||||
|                 .unwrap() | ||||
|             ), | ||||
|         ) | ||||
|         .await | ||||
|     } | ||||
|  | ||||
|     /// Do connect to a server, returning | ||||
|     async fn connect_url(server: &str, uri: &str) -> Res<Self> { | ||||
|         let mut url = server.replace("http", "ws"); | ||||
|         url.push_str(uri); | ||||
|         log::debug!("Connecting to {}", url); | ||||
|         let mut ws_url = server.replace("http", "ws"); | ||||
|         ws_url.push_str(uri); | ||||
|         log::debug!("Connecting to {}", ws_url); | ||||
|  | ||||
|         let (socket, _) = if ws_url.starts_with("wss") { | ||||
|             // Perform a connection over TLS | ||||
|             let config = rustls::ClientConfig::builder() | ||||
|                 .with_safe_defaults() | ||||
|                 .with_native_roots() | ||||
|                 .with_no_client_auth(); | ||||
|             let connector = tokio_tungstenite::Connector::Rustls(Arc::new(config)); | ||||
|  | ||||
|             tokio_tungstenite::connect_async_tls_with_config(ws_url, None, Some(connector)).await? | ||||
|         } else { | ||||
|             // Perform an unsecure connection | ||||
|             tokio_tungstenite::connect_async(ws_url).await? | ||||
|         }; | ||||
|  | ||||
|         // Connect to websocket & split streams | ||||
|         let (socket, _) = tokio_tungstenite::connect_async(url).await?; | ||||
|         let (sink, mut stream) = socket.split(); | ||||
|  | ||||
|         // Receive server message on a separate task | ||||
|   | ||||
| @@ -17,11 +17,13 @@ use cli_player::client::Client; | ||||
| use cli_player::server::start_server_if_missing; | ||||
| use cli_player::ui_screens::configure_game_rules::GameRulesConfigurationScreen; | ||||
| use cli_player::ui_screens::game_screen::GameScreen; | ||||
| use cli_player::ui_screens::input_screen::InputScreen; | ||||
| use cli_player::ui_screens::popup_screen::PopupScreen; | ||||
| use cli_player::ui_screens::select_play_mode_screen::{SelectPlayModeResult, SelectPlayModeScreen}; | ||||
| use cli_player::ui_screens::*; | ||||
| use sea_battle_backend::data::GameRules; | ||||
| use sea_battle_backend::human_player_ws::ServerMessage; | ||||
| use sea_battle_backend::utils::Res; | ||||
|  | ||||
| /// Test code screens | ||||
| async fn run_dev<B: Backend>( | ||||
| @@ -70,17 +72,53 @@ async fn run_dev<B: Backend>( | ||||
|     ))? | ||||
| } | ||||
|  | ||||
| async fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> Result<(), Box<dyn Error>> { | ||||
| /// Ask the user to specify its username | ||||
| fn query_username<B: Backend>(terminal: &mut Terminal<B>) -> Res<String> { | ||||
|     let hostname = hostname::get()?.to_string_lossy().to_string(); | ||||
|  | ||||
|     let res = | ||||
|         InputScreen::new("Please specify the name to which other players should identify you:") | ||||
|             .set_title("Player name") | ||||
|             .set_value(&hostname) | ||||
|             .show(terminal)?; | ||||
|  | ||||
|     Ok(res.value().unwrap_or(hostname)) | ||||
| } | ||||
|  | ||||
| async fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> Res { | ||||
|     if let Some(d) = cli_args().dev_screen { | ||||
|         return run_dev(terminal, d).await; | ||||
|     } | ||||
|  | ||||
|     let mut rules = GameRules::default(); | ||||
|  | ||||
|     let mut username = "".to_string(); | ||||
|  | ||||
|     loop { | ||||
|         match SelectPlayModeScreen::default().show(terminal)? { | ||||
|             // TODO : Play against random player | ||||
|             ScreenResult::Ok(SelectPlayModeResult::PlayRandom) => todo!(), | ||||
|         let choice = SelectPlayModeScreen::default().show(terminal)?; | ||||
|  | ||||
|         if let ScreenResult::Ok(c) = choice { | ||||
|             if c.need_user_name() && username.is_empty() { | ||||
|                 username = query_username(terminal)?; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         match choice { | ||||
|             ScreenResult::Ok(SelectPlayModeResult::PlayRandom) => { | ||||
|                 PopupScreen::new("Connecting...").show_once(terminal)?; | ||||
|  | ||||
|                 let client = Client::start_random_play(&username).await?; | ||||
|                 PopupScreen::new("Waiting for opponent...").show_once(terminal)?; | ||||
|  | ||||
|                 // Wait for the server to become ready | ||||
|                 while !matches!( | ||||
|                     client.recv_next_message().await?, | ||||
|                     ServerMessage::OpponentConnected | ||||
|                 ) {} | ||||
|  | ||||
|                 // Display game screen | ||||
|                 GameScreen::new(client).show(terminal).await?; | ||||
|             } | ||||
|  | ||||
|             // Play against bot | ||||
|             ScreenResult::Ok(SelectPlayModeResult::PlayAgainstBot) => { | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| use std::fmt::Display; | ||||
| use std::io; | ||||
| use std::time::{Duration, Instant}; | ||||
| use tui::style::*; | ||||
| @@ -49,6 +50,11 @@ impl<'a> InputScreen<'a> { | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     pub fn set_value<D: Display>(mut self, value: D) -> Self { | ||||
|         self.value = value.to_string(); | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Get error contained in input | ||||
|     fn error(&self) -> Option<&'static str> { | ||||
|         if self.value.len() > self.max_len { | ||||
|   | ||||
| @@ -17,6 +17,13 @@ pub enum ScreenResult<E = ()> { | ||||
| } | ||||
|  | ||||
| impl<E: Debug> ScreenResult<E> { | ||||
|     pub fn value(self) -> Option<E> { | ||||
|         match self { | ||||
|             ScreenResult::Ok(v) => Some(v), | ||||
|             ScreenResult::Canceled => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn as_string(&self) -> String { | ||||
|         format!("{:#?}", self) | ||||
|     } | ||||
|   | ||||
| @@ -20,6 +20,13 @@ pub enum SelectPlayModeResult { | ||||
|     Exit, | ||||
| } | ||||
|  | ||||
| impl SelectPlayModeResult { | ||||
|     /// Specify whether a selected play mode requires a user name or not | ||||
|     pub fn need_user_name(&self) -> bool { | ||||
|         self != &SelectPlayModeResult::PlayAgainstBot && self != &SelectPlayModeResult::Exit | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone)] | ||||
| struct PlayModeDescription { | ||||
|     name: &'static str, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user