2022-07-14 20:53:08 +02:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
2022-02-27 22:57:06 +01:00
|
|
|
use crate::db;
|
2022-04-28 21:31:49 +02:00
|
|
|
use crate::db::matches::{FullMatchData, FullMatchPlayerData};
|
2022-07-07 19:13:55 +02:00
|
|
|
use crate::modules::bots::save_code_string;
|
2022-07-14 21:50:42 +02:00
|
|
|
use crate::modules::matches::{MatchPlayer, RunMatch};
|
2022-04-28 21:31:49 +02:00
|
|
|
use crate::ConnectionPool;
|
2022-07-14 21:50:42 +02:00
|
|
|
use crate::GlobalConfig;
|
2022-02-08 20:13:24 +01:00
|
|
|
use axum::extract::Extension;
|
|
|
|
use axum::Json;
|
2022-01-26 20:54:19 +01:00
|
|
|
use hyper::StatusCode;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2022-02-08 20:13:24 +01:00
|
|
|
use super::matches::ApiMatch;
|
2022-01-26 20:54:19 +01:00
|
|
|
|
2022-04-28 21:31:49 +02:00
|
|
|
const DEFAULT_OPPONENT_NAME: &str = "simplebot";
|
2022-01-26 20:54:19 +01:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
|
pub struct SubmitBotParams {
|
|
|
|
pub code: String,
|
2022-03-03 21:12:16 +01:00
|
|
|
// TODO: would it be better to pass an ID here?
|
|
|
|
pub opponent_name: Option<String>,
|
2022-01-26 20:54:19 +01:00
|
|
|
}
|
|
|
|
|
2022-02-08 20:13:24 +01:00
|
|
|
#[derive(Serialize, Deserialize)]
|
2022-01-26 20:54:19 +01:00
|
|
|
pub struct SubmitBotResponse {
|
2022-02-08 20:13:24 +01:00
|
|
|
#[serde(rename = "match")]
|
|
|
|
pub match_data: ApiMatch,
|
2022-01-26 20:54:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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>,
|
2022-02-08 20:13:24 +01:00
|
|
|
Extension(pool): Extension<ConnectionPool>,
|
2022-07-14 21:50:42 +02:00
|
|
|
Extension(config): Extension<Arc<GlobalConfig>>,
|
2022-01-26 20:54:19 +01:00
|
|
|
) -> Result<Json<SubmitBotResponse>, StatusCode> {
|
2022-02-08 20:13:24 +01:00
|
|
|
let conn = pool.get().await.expect("could not get database connection");
|
|
|
|
|
2022-03-03 21:12:16 +01:00
|
|
|
let opponent_name = params
|
|
|
|
.opponent_name
|
2022-04-28 21:31:49 +02:00
|
|
|
.unwrap_or_else(|| DEFAULT_OPPONENT_NAME.to_string());
|
2022-03-03 21:12:16 +01:00
|
|
|
|
2022-07-09 20:01:05 +02:00
|
|
|
let opponent_bot =
|
2022-03-03 21:12:16 +01:00
|
|
|
db::bots::find_bot_by_name(&opponent_name, &conn).map_err(|_| StatusCode::BAD_REQUEST)?;
|
2022-07-09 20:01:05 +02:00
|
|
|
let opponent_bot_version = db::bots::active_bot_version(opponent_bot.id, &conn)
|
|
|
|
.map_err(|_| StatusCode::BAD_REQUEST)?;
|
2022-02-27 22:57:06 +01:00
|
|
|
|
2022-07-07 19:13:55 +02:00
|
|
|
let player_bot_version = save_code_string(¶ms.code, None, &conn)
|
2022-02-27 20:35:22 +01:00
|
|
|
// TODO: can we recover from this?
|
|
|
|
.expect("could not save bot code");
|
2022-01-26 20:54:19 +01:00
|
|
|
|
2022-07-14 20:53:08 +02:00
|
|
|
let run_match = RunMatch::from_players(
|
2022-07-14 21:50:42 +02:00
|
|
|
config,
|
2022-07-14 20:53:08 +02:00
|
|
|
vec![
|
|
|
|
MatchPlayer::BotVersion {
|
|
|
|
bot: None,
|
|
|
|
version: player_bot_version.clone(),
|
|
|
|
},
|
|
|
|
MatchPlayer::BotVersion {
|
|
|
|
bot: Some(opponent_bot.clone()),
|
|
|
|
version: opponent_bot_version.clone(),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
);
|
2022-07-13 19:36:07 +02:00
|
|
|
let (match_data, _) = run_match
|
|
|
|
.run(pool.clone())
|
|
|
|
.await
|
|
|
|
.expect("failed to run match");
|
2022-02-15 19:54:29 +01:00
|
|
|
|
2022-03-11 00:41:18 +01:00
|
|
|
// TODO: avoid clones
|
|
|
|
let full_match_data = FullMatchData {
|
|
|
|
base: match_data.base,
|
|
|
|
match_players: vec![
|
|
|
|
FullMatchPlayerData {
|
|
|
|
base: match_data.match_players[0].clone(),
|
2022-07-06 22:41:27 +02:00
|
|
|
bot_version: Some(player_bot_version),
|
2022-03-11 00:41:18 +01:00
|
|
|
bot: None,
|
|
|
|
},
|
|
|
|
FullMatchPlayerData {
|
|
|
|
base: match_data.match_players[1].clone(),
|
2022-07-06 22:41:27 +02:00
|
|
|
bot_version: Some(opponent_bot_version),
|
2022-07-09 20:01:05 +02:00
|
|
|
bot: Some(opponent_bot),
|
2022-03-11 00:41:18 +01:00
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
let api_match = super::matches::match_data_to_api(full_match_data);
|
2022-02-08 20:13:24 +01:00
|
|
|
Ok(Json(SubmitBotResponse {
|
|
|
|
match_data: api_match,
|
|
|
|
}))
|
|
|
|
}
|