1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
extern crate planetwars_matchrunner;
extern crate tokio;
use std::collections::HashMap;
use std::io::{self, Write};
use std::path::PathBuf;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use bollard::container::{self, LogOutput};
use bollard::exec::StartExecResults;
use bollard::Docker;
use futures::{Stream, StreamExt};
use planetwars_matchrunner::{
match_context::{EventBus, MatchCtx, PlayerHandle},
pw_match, MatchConfig, MatchMeta, PlayerInfo,
};
use planetwars_rules::protocol as proto;
use planetwars_rules::PwConfig;
use std::env;
use tokio::io::{AsyncWrite, AsyncWriteExt};
const IMAGE: &'static str = "simplebot:latest";
#[tokio::main]
async fn main() {
let args: Vec<String> = env::args().collect();
assert!(args.len() >= 2);
let map_path = args[1].clone();
_run_match(map_path).await;
}
async fn _run_match(map_path: String) {
let docker = Docker::connect_with_socket_defaults().unwrap();
create_player_process(&docker).await.unwrap();
}
async fn create_player_process(docker: &Docker) -> Result<(), bollard::errors::Error> {
let config = container::Config {
image: Some(IMAGE),
..Default::default()
};
let response = docker.create_container::<&str, &str>(None, config).await?;
let container_id = response.id;
docker
.start_container::<String>(&container_id, None)
.await?;
let exec_id = docker
.create_exec::<&str>(
&container_id,
bollard::exec::CreateExecOptions {
attach_stdin: Some(true),
attach_stdout: Some(true),
attach_stderr: Some(true),
cmd: Some(vec!["python", "simplebot.py"]),
..Default::default()
},
)
.await
.unwrap()
.id;
let start_exec_results = docker.start_exec(&exec_id, None).await?;
let (mut input, mut output) = match start_exec_results {
StartExecResults::Detached => panic!("failed to get io channels"),
StartExecResults::Attached { input, output } => (input, output),
};
let state = proto::State {
planets: vec![
proto::Planet {
name: "a".to_string(),
owner: Some(1),
ship_count: 100,
x: -1.0,
y: 0.0,
},
proto::Planet {
name: "b".to_string(),
owner: Some(2),
ship_count: 100,
x: 1.0,
y: 0.0,
},
],
expeditions: vec![],
};
let serialized = serde_json::to_vec(&state).unwrap();
input.write_all(&serialized).await?;
input.write(b"\n").await?;
input.flush().await?;
while let Some(item) = output.next().await {
let log_output = item.expect("failed to get log output");
match log_output {
LogOutput::StdOut { message } => {
println!("stdout: {}", String::from_utf8_lossy(&message));
}
LogOutput::StdErr { message } => {
println!("stderr: {}", String::from_utf8_lossy(&message));
}
_ => (),
}
}
Ok(())
}
|