diff options
author | Ilion Beyst <ilion.beyst@gmail.com> | 2022-01-26 20:54:19 +0100 |
---|---|---|
committer | Ilion Beyst <ilion.beyst@gmail.com> | 2022-01-26 20:54:19 +0100 |
commit | 294c75823d323057e07d6791b9b8ffb6d139b03f (patch) | |
tree | c767238a0079a2e515b65c59d14c213ecc3c491b /planetwars-server | |
parent | a79b338e90db1948f6587ab02e149e73bb1842f0 (diff) | |
download | planetwars.dev-294c75823d323057e07d6791b9b8ffb6d139b03f.tar.xz planetwars.dev-294c75823d323057e07d6791b9b8ffb6d139b03f.zip |
add endpoint for standalone upload of bot code
Diffstat (limited to 'planetwars-server')
-rw-r--r-- | planetwars-server/src/lib.rs | 1 | ||||
-rw-r--r-- | planetwars-server/src/routes/demo.rs | 70 | ||||
-rw-r--r-- | planetwars-server/src/routes/mod.rs | 1 |
3 files changed, 72 insertions, 0 deletions
diff --git a/planetwars-server/src/lib.rs b/planetwars-server/src/lib.rs index b5a204e..ea03fc3 100644 --- a/planetwars-server/src/lib.rs +++ b/planetwars-server/src/lib.rs @@ -54,6 +54,7 @@ pub async fn api() -> Router { get(routes::matches::list_matches).post(routes::matches::play_match), ) .route("/matches/:match_id", get(routes::matches::get_match_log)) + .route("/submit-bot", post(routes::demo::submit_bot)) .layer(AddExtensionLayer::new(pool)); api } diff --git a/planetwars-server/src/routes/demo.rs b/planetwars-server/src/routes/demo.rs new file mode 100644 index 0000000..bf375f0 --- /dev/null +++ b/planetwars-server/src/routes/demo.rs @@ -0,0 +1,70 @@ +use std::path::PathBuf; + +use axum::Json; +use hyper::StatusCode; +use planetwars_matchrunner::{docker_runner::DockerBotSpec, run_match, MatchConfig, MatchPlayer}; +use rand::{distributions::Alphanumeric, Rng}; +use serde::{Deserialize, Serialize}; + +use crate::{DatabaseConnection, BOTS_DIR, MAPS_DIR, MATCHES_DIR}; + +const PYTHON_IMAGE: &'static str = "python:3.10-slim-buster"; +const SIMPLEBOT_PATH: &'static str = "../simplebot"; + +#[derive(Serialize, Deserialize, Debug)] +pub struct SubmitBotParams { + pub code: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SubmitBotResponse { + pub match_id: String, +} + +pub fn gen_alphanumeric(length: usize) -> String { + rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(length) + .map(char::from) + .collect() +} + +/// submit python code for a bot, which will face off +/// with a demo bot. Return a played match. +pub async fn submit_bot( + Json(params): Json<SubmitBotParams>, +) -> Result<Json<SubmitBotResponse>, StatusCode> { + let uploaded_bot_id: String = gen_alphanumeric(16); + let match_id = gen_alphanumeric(16); + + let uploaded_bot_dir = PathBuf::from(BOTS_DIR).join(&uploaded_bot_id); + std::fs::create_dir(&uploaded_bot_dir).unwrap(); + std::fs::write(uploaded_bot_dir.join("bot.py"), params.code.as_bytes()).unwrap(); + + run_match(MatchConfig { + map_path: PathBuf::from(MAPS_DIR).join("hex.json"), + map_name: "hex".to_string(), + log_path: PathBuf::from(MATCHES_DIR).join(format!("{}.log", match_id)), + players: vec![ + MatchPlayer { + name: "bot".to_string(), + bot_spec: Box::new(DockerBotSpec { + code_path: PathBuf::from(SIMPLEBOT_PATH), + image: PYTHON_IMAGE.to_string(), + argv: vec!["python".to_string(), "bot.py".to_string()], + }), + }, + MatchPlayer { + name: "simplebot".to_string(), + bot_spec: Box::new(DockerBotSpec { + code_path: PathBuf::from(SIMPLEBOT_PATH), + image: PYTHON_IMAGE.to_string(), + argv: vec!["python".to_string(), "simplebot.py".to_string()], + }), + }, + ], + }) + .await; + + Ok(Json(SubmitBotResponse { match_id })) +} diff --git a/planetwars-server/src/routes/mod.rs b/planetwars-server/src/routes/mod.rs index c2d3c44..b3decb8 100644 --- a/planetwars-server/src/routes/mod.rs +++ b/planetwars-server/src/routes/mod.rs @@ -1,3 +1,4 @@ pub mod bots; +pub mod demo; pub mod matches; pub mod users; |