diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c5f2e89..809808b 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -465,8 +465,10 @@ dependencies = [ "clap", "crossterm", "env_logger", + "lazy_static", "log", "sea_battle_backend", + "tokio", "tui", ] @@ -925,6 +927,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.134" diff --git a/rust/cli_player/Cargo.toml b/rust/cli_player/Cargo.toml index e5ec10c..81d3d61 100644 --- a/rust/cli_player/Cargo.toml +++ b/rust/cli_player/Cargo.toml @@ -11,4 +11,6 @@ clap = { version = "3.2.17", features = ["derive"] } log = "0.4.17" env_logger = "0.9.0" tui = "0.19.0" -crossterm = "0.25.0" \ No newline at end of file +crossterm = "0.25.0" +lazy_static = "1.4.0" +tokio = "1.21.2" \ No newline at end of file diff --git a/rust/cli_player/src/cli_args.rs b/rust/cli_player/src/cli_args.rs index 736b025..2427eb8 100644 --- a/rust/cli_player/src/cli_args.rs +++ b/rust/cli_player/src/cli_args.rs @@ -10,5 +10,32 @@ pub struct CliArgs { value_parser, default_value = "https://fixme.communiquons.org" )] - server_uri: String, + pub server_uri: String, + + /// Local server listen address + #[clap(short, long, default_value = "127.0.0.1:5679")] + pub listen_address: String, +} + +impl CliArgs { + /// Get local listen port + pub fn listen_port(&self) -> u16 { + self.listen_address + .rsplit(':') + .next() + .expect("Failed to split listen address!") + .parse::() + .expect("Failed to parse listen port!") + } +} + +lazy_static::lazy_static! { + static ref ARGS: CliArgs = { + CliArgs::parse() + }; +} + +/// Get parsed command line arguments +pub fn cli_args() -> &'static CliArgs { + &ARGS } diff --git a/rust/cli_player/src/lib.rs b/rust/cli_player/src/lib.rs index 14ea756..0a9c1b1 100644 --- a/rust/cli_player/src/lib.rs +++ b/rust/cli_player/src/lib.rs @@ -1,2 +1,3 @@ pub mod cli_args; +pub mod server; pub mod ui_screens; diff --git a/rust/cli_player/src/main.rs b/rust/cli_player/src/main.rs index fdde1ef..8931974 100644 --- a/rust/cli_player/src/main.rs +++ b/rust/cli_player/src/main.rs @@ -12,9 +12,13 @@ use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use env_logger::Env; use tui::backend::CrosstermBackend; use tui::Terminal; +use cli_player::server::start_server_if_missing; -pub fn main() -> Result<(), Box> { - env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); +#[tokio::main] +pub async fn main() -> Result<(), Box> { + env_logger::Builder::from_env(Env::default()).init(); + + start_server_if_missing().await; // setup terminal enable_raw_mode()?; diff --git a/rust/cli_player/src/server.rs b/rust/cli_player/src/server.rs new file mode 100644 index 0000000..2ae5560 --- /dev/null +++ b/rust/cli_player/src/server.rs @@ -0,0 +1,30 @@ +use tokio::runtime::Builder; +use tokio::task; + +use sea_battle_backend::args::Args; +use sea_battle_backend::utils::network_utils; + +use crate::cli_args::cli_args; + +pub async fn start_server_if_missing() { + if !network_utils::is_port_open(cli_args().listen_port()).await { + log::info!( + "Local server will start on {}...", + cli_args().listen_address + ); + std::thread::spawn(move || { + let rt = Builder::new_current_thread().enable_all().build().unwrap(); + + let local_set = task::LocalSet::new(); + + rt.block_on(local_set.run_until(async move { + sea_battle_backend::server::start_server(Args { + listen_address: cli_args().listen_address.clone(), + cors: None, + }) + .await + .expect("Failed to run local server!") + })); + }); + } +} diff --git a/rust/sea_battle_backend/Cargo.toml b/rust/sea_battle_backend/Cargo.toml index 4003717..b9e3a21 100644 --- a/rust/sea_battle_backend/Cargo.toml +++ b/rust/sea_battle_backend/Cargo.toml @@ -19,9 +19,9 @@ actix-rt = "2.7.0" uuid = { version = "1.1.2", features = ["v4"] } rand = "0.8.5" serde_with = "2.0.1" +tokio = { version = "1", features = ["full"] } [dev-dependencies] -tokio = { version = "1", features = ["full"] } #reqwest = { version = "0.11.11", default-features = false, features = ["json", "rustls-tls"] } tokio-tungstenite = "0.17.2" serde_urlencoded = "0.7.1" diff --git a/rust/sea_battle_backend/src/dispatcher_actor.rs b/rust/sea_battle_backend/src/dispatcher_actor.rs index 790d501..bcdfb6f 100644 --- a/rust/sea_battle_backend/src/dispatcher_actor.rs +++ b/rust/sea_battle_backend/src/dispatcher_actor.rs @@ -11,7 +11,7 @@ use crate::consts::INVITE_CODE_LENGTH; use crate::data::GameRules; use crate::game::Game; use crate::human_player_ws::{CloseConnection, HumanPlayerWS, ServerMessage, SetGame}; -use crate::utils::rand_str; +use crate::utils::string_utils::rand_str; /// How often garbage collector is run const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(60); diff --git a/rust/sea_battle_backend/src/test/bot_intermediate_play.rs b/rust/sea_battle_backend/src/test/bot_intermediate_play.rs index 8188967..2d0b019 100644 --- a/rust/sea_battle_backend/src/test/bot_intermediate_play.rs +++ b/rust/sea_battle_backend/src/test/bot_intermediate_play.rs @@ -5,8 +5,8 @@ use crate::data::{BotType, CurrentGameStatus, GameRules}; use crate::human_player_ws::ServerMessage; use crate::server::start_server; use crate::test::bot_client::ClientEndResult; -use crate::test::network_utils::wait_for_port; use crate::test::{bot_client, TestPort}; +use crate::utils::network_utils::wait_for_port; #[tokio::test] async fn full_game() { diff --git a/rust/sea_battle_backend/src/test/bot_linear_play.rs b/rust/sea_battle_backend/src/test/bot_linear_play.rs index 77e87b9..99b0cc0 100644 --- a/rust/sea_battle_backend/src/test/bot_linear_play.rs +++ b/rust/sea_battle_backend/src/test/bot_linear_play.rs @@ -5,9 +5,9 @@ use crate::data::{BoatsLayout, BotType, Coordinates, GameRules}; use crate::human_player_ws::ServerMessage; use crate::server::start_server; use crate::test::bot_client::ClientEndResult; -use crate::test::network_utils::wait_for_port; use crate::test::play_utils::check_no_replay_on_hit; use crate::test::{bot_client, TestPort}; +use crate::utils::network_utils::wait_for_port; fn check_strikes_are_linear(msg: &ServerMessage) { if let ServerMessage::RequestFire { status } = msg { diff --git a/rust/sea_battle_backend/src/test/bot_random_play.rs b/rust/sea_battle_backend/src/test/bot_random_play.rs index 0344605..6acf5d2 100644 --- a/rust/sea_battle_backend/src/test/bot_random_play.rs +++ b/rust/sea_battle_backend/src/test/bot_random_play.rs @@ -5,9 +5,9 @@ use crate::data::{BoatsLayout, GameRules}; use crate::server::start_server; use crate::test::bot_client; use crate::test::bot_client::ClientEndResult; -use crate::test::network_utils::wait_for_port; use crate::test::play_utils::check_no_replay_on_hit; use crate::test::TestPort; +use crate::utils::network_utils::wait_for_port; #[tokio::test] async fn invalid_port() { diff --git a/rust/sea_battle_backend/src/test/bot_smart_play.rs b/rust/sea_battle_backend/src/test/bot_smart_play.rs index ad9ce1b..c4386d2 100644 --- a/rust/sea_battle_backend/src/test/bot_smart_play.rs +++ b/rust/sea_battle_backend/src/test/bot_smart_play.rs @@ -5,8 +5,8 @@ use crate::data::{BotType, CurrentGameStatus, GameRules}; use crate::human_player_ws::ServerMessage; use crate::server::start_server; use crate::test::bot_client::ClientEndResult; -use crate::test::network_utils::wait_for_port; use crate::test::{bot_client, TestPort}; +use crate::utils::network_utils::wait_for_port; #[tokio::test] async fn full_game() { diff --git a/rust/sea_battle_backend/src/test/invite_mode.rs b/rust/sea_battle_backend/src/test/invite_mode.rs index a8612ab..f7a8508 100644 --- a/rust/sea_battle_backend/src/test/invite_mode.rs +++ b/rust/sea_battle_backend/src/test/invite_mode.rs @@ -9,8 +9,8 @@ use crate::data::BotType; use crate::human_player_ws::ServerMessage; use crate::server::start_server; use crate::test::bot_client::{ClientEndResult, RunMode}; -use crate::test::network_utils::wait_for_port; use crate::test::{bot_client, TestPort}; +use crate::utils::network_utils::wait_for_port; #[tokio::test] async fn invalid_accept_code() { diff --git a/rust/sea_battle_backend/src/test/mod.rs b/rust/sea_battle_backend/src/test/mod.rs index 6282283..f89c97b 100644 --- a/rust/sea_battle_backend/src/test/mod.rs +++ b/rust/sea_battle_backend/src/test/mod.rs @@ -46,6 +46,5 @@ mod bot_linear_play; mod bot_random_play; mod bot_smart_play; mod invite_mode; -mod network_utils; mod play_utils; mod random_mode; diff --git a/rust/sea_battle_backend/src/test/random_mode.rs b/rust/sea_battle_backend/src/test/random_mode.rs index f0a98a9..72858ee 100644 --- a/rust/sea_battle_backend/src/test/random_mode.rs +++ b/rust/sea_battle_backend/src/test/random_mode.rs @@ -1,8 +1,8 @@ use crate::args::Args; use crate::server::start_server; use crate::test::bot_client::{ClientEndResult, RunMode}; -use crate::test::network_utils::wait_for_port; use crate::test::{bot_client, TestPort}; +use crate::utils::network_utils::wait_for_port; use std::error::Error; use tokio::task; diff --git a/rust/sea_battle_backend/src/utils/mod.rs b/rust/sea_battle_backend/src/utils/mod.rs new file mode 100644 index 0000000..3e5d5a4 --- /dev/null +++ b/rust/sea_battle_backend/src/utils/mod.rs @@ -0,0 +1,2 @@ +pub mod network_utils; +pub mod string_utils; diff --git a/rust/sea_battle_backend/src/test/network_utils.rs b/rust/sea_battle_backend/src/utils/network_utils.rs similarity index 81% rename from rust/sea_battle_backend/src/test/network_utils.rs rename to rust/sea_battle_backend/src/utils/network_utils.rs index 922abf9..f13346a 100644 --- a/rust/sea_battle_backend/src/test/network_utils.rs +++ b/rust/sea_battle_backend/src/utils/network_utils.rs @@ -5,10 +5,7 @@ use tokio::time; /// Check whether a given port is open or not pub async fn is_port_open(port: u16) -> bool { - match TcpStream::connect(("127.0.0.1", port)).await { - Ok(_) => true, - Err(_) => false, - } + TcpStream::connect(("127.0.0.1", port)).await.is_ok() } /// Wait for a port to become available diff --git a/rust/sea_battle_backend/src/utils.rs b/rust/sea_battle_backend/src/utils/string_utils.rs similarity index 90% rename from rust/sea_battle_backend/src/utils.rs rename to rust/sea_battle_backend/src/utils/string_utils.rs index aa34d9e..9994226 100644 --- a/rust/sea_battle_backend/src/utils.rs +++ b/rust/sea_battle_backend/src/utils/string_utils.rs @@ -12,7 +12,7 @@ pub fn rand_str(len: usize) -> String { #[cfg(test)] mod test { - use crate::utils::rand_str; + use crate::utils::string_utils::rand_str; #[test] fn test_rand_str() {