use actix_cors::Cors; use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder}; use actix_web_actors::ws; use clap::Parser; use env_logger::Env; use sea_battle_backend::data::{GameRules, PlayConfiguration}; use sea_battle_backend::human_player_ws::{HumanPlayerWS, StartMode}; /// Simple sea battle server #[derive(Parser, Debug, Clone)] #[clap(author, version, about, long_about = None)] struct Args { /// The address this server will listen to #[clap(short, long, value_parser, default_value = "0.0.0.0:7000")] listen_address: String, /// CORS (allowed origin) set to '*' to allow all origins #[clap(short, long, value_parser)] cors: Option, } /// The default '/' route async fn index() -> impl Responder { HttpResponse::Ok().json("Sea battle backend") } /// The default 404 route async fn not_found() -> impl Responder { HttpResponse::NotFound().json("You missed your strike lol") } /// Get bot configuration async fn bot_configuration() -> impl Responder { HttpResponse::Ok().json(PlayConfiguration::default()) } /// Start bot game async fn start_bot_play( req: HttpRequest, stream: web::Payload, query: web::Query, ) -> Result { let errors = query.0.get_errors(); if !errors.is_empty() { return Ok(HttpResponse::BadRequest().json(errors)); } let mut player_ws = HumanPlayerWS::default(); player_ws.start_mode = StartMode::Bot(query.0.clone()); let resp = ws::start(player_ws, &req, stream); log::info!("New bot play with configuration: {:?}", &query.0); resp } /// Multi-players configuration async fn multi_players_config() -> impl Responder { HttpResponse::Ok().json(GameRules::multi_players_rules()) } #[actix_web::main] async fn main() -> std::io::Result<()> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); let args: Args = Args::parse(); let args_clone = args.clone(); HttpServer::new(move || { let mut cors = Cors::default(); match args_clone.cors.as_deref() { Some("*") => cors = cors.allow_any_origin(), Some(orig) => cors = cors.allowed_origin(orig), None => {} } App::new() .wrap(cors) .route("/bot/config", web::get().to(bot_configuration)) .route("/bot/play", web::get().to(start_bot_play)) .route("/random/config", web::get().to(multi_players_config)) .route("/", web::get().to(index)) .route("{tail:.*}", web::get().to(not_found)) }) .bind(args.listen_address)? .run() .await }