aboutsummaryrefslogtreecommitdiff
path: root/planetwars-server/src
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2022-01-26 20:54:19 +0100
committerIlion Beyst <ilion.beyst@gmail.com>2022-01-26 20:54:19 +0100
commit294c75823d323057e07d6791b9b8ffb6d139b03f (patch)
treec767238a0079a2e515b65c59d14c213ecc3c491b /planetwars-server/src
parenta79b338e90db1948f6587ab02e149e73bb1842f0 (diff)
downloadplanetwars.dev-294c75823d323057e07d6791b9b8ffb6d139b03f.tar.xz
planetwars.dev-294c75823d323057e07d6791b9b8ffb6d139b03f.zip
add endpoint for standalone upload of bot code
Diffstat (limited to 'planetwars-server/src')
-rw-r--r--planetwars-server/src/lib.rs1
-rw-r--r--planetwars-server/src/routes/demo.rs70
-rw-r--r--planetwars-server/src/routes/mod.rs1
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;