rust/hedgewars-checker/src/main.rs
author Wuzzy <Wuzzy2@mail.ru>
Thu, 25 Apr 2019 23:01:05 +0200
changeset 14844 e239378a9400
parent 14401 694c96fb3a06
permissions -rw-r--r--
Prevent entering “/”, “\” and “:” in team and scheme names. The name of teams and schems is saved in the file name itself, so these characters would cause trouble as they are used in path names in Linux and Windows.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
     1
use argparse::{ArgumentParser, Store};
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
     2
use ini::Ini;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
     3
use netbuf::Buf;
14212
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
     4
use log::{debug, warn, info};
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
     5
use std::{
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
     6
    io::Write,
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
     7
    net::TcpStream,
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
     8
    process::Command,
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
     9
    str::FromStr
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
    10
};
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    11
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    12
type CheckError = Box<std::error::Error>;
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    13
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    14
fn extract_packet(buf: &mut Buf) -> Option<netbuf::Buf> {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    15
    let packet_end = (&buf[..]).windows(2).position(|window| window == b"\n\n")?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    16
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    17
    let mut tail = buf.split_off(packet_end);
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    18
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    19
    std::mem::swap(&mut tail, buf);
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    20
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    21
    buf.consume(2);
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    22
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    23
    Some(tail)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    24
}
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    25
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    26
fn check(executable: &str, data_prefix: &str, buffer: &[u8]) -> Result<Vec<Vec<u8>>, CheckError> {
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    27
    let mut replay = tempfile::NamedTempFile::new()?;
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    28
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    29
    for line in buffer.split(|b| *b == '\n' as u8) {
13960
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    30
        replay.write(&base64::decode(line)?)?;
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    31
    }
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    32
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    33
    let temp_file_path = replay.path();
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    34
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    35
    let mut home_dir = dirs::home_dir().unwrap();
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    36
    home_dir.push(".hedgewars");
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    37
13960
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    38
    debug!("Checking replay in {}", temp_file_path.to_string_lossy());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    39
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    40
    let output = Command::new(executable)
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    41
        .arg("--user-prefix")
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    42
        .arg(&home_dir)
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    43
        .arg("--prefix")
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    44
        .arg(data_prefix)
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    45
        .arg("--nomusic")
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    46
        .arg("--nosound")
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    47
        .arg("--stats-only")
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    48
        .arg(temp_file_path)
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    49
        .output()?;
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    50
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    51
    let mut result = Vec::new();
13960
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    52
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    53
    let mut engine_lines = output
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    54
        .stderr
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    55
        .split(|b| *b == '\n' as u8)
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    56
        .skip_while(|l| *l != b"WINNERS" && *l != b"DRAW");
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    57
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    58
    loop {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    59
        match engine_lines.next() {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    60
            Some(b"DRAW") => result.push(b"DRAW".to_vec()),
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    61
            Some(b"WINNERS") => {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    62
                result.push(b"WINNERS".to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    63
                let winners = engine_lines.next().unwrap();
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    64
                let winners_num = u32::from_str(&String::from_utf8(winners.to_vec())?)?;
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    65
                result.push(winners.to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    66
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    67
                for _i in 0..winners_num {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    68
                    result.push(engine_lines.next().unwrap().to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    69
                }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    70
            }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    71
            Some(b"GHOST_POINTS") => {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    72
                result.push(b"GHOST_POINTS".to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    73
                let points = engine_lines.next().unwrap();
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    74
                let points_num = u32::from_str(&String::from_utf8(points.to_vec())?)? * 2;
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    75
                result.push(points.to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    76
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    77
                for _i in 0..points_num {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    78
                    result.push(engine_lines.next().unwrap().to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    79
                }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    80
            }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    81
            Some(b"ACHIEVEMENT") => {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    82
                result.push(b"ACHIEVEMENT".to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    83
                for _i in 0..4 {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    84
                    result.push(engine_lines.next().unwrap().to_vec());
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    85
                }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    86
            }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    87
            _ => break,
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    88
        }
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    89
    }
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    90
13960
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    91
    if result.len() > 0 {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    92
        Ok(result)
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    93
    } else {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    94
        Err("no data from engine".into())
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
    95
    }
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    96
}
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
    97
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    98
fn connect_and_run(
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
    99
    username: &str,
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   100
    password: &str,
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   101
    protocol_number: u32,
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   102
    executable: &str,
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   103
    data_prefix: &str,
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   104
) -> Result<(), CheckError> {
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   105
    info!("Connecting...");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   106
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   107
    let mut stream = TcpStream::connect("hedgewars.org:46631")?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   108
    stream.set_nonblocking(false)?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   109
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   110
    let mut buf = Buf::new();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   111
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   112
    loop {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   113
        buf.read_from(&mut stream)?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   114
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   115
        while let Some(msg) = extract_packet(&mut buf) {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   116
            if msg[..].starts_with(b"CONNECTED") {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   117
                info!("Connected");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   118
                let p = format!(
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   119
                    "CHECKER\n{}\n{}\n{}\n\n",
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   120
                    protocol_number, username, password
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   121
                );
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   122
                stream.write(p.as_bytes())?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   123
            } else if msg[..].starts_with(b"PING") {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   124
                stream.write(b"PONG\n\n")?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   125
            } else if msg[..].starts_with(b"LOGONPASSED") {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   126
                info!("Logged in");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   127
                stream.write(b"READY\n\n")?;
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   128
            } else if msg[..].starts_with(b"REPLAY") {
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   129
                info!("Got a replay");
13960
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   130
                match check(executable, data_prefix, &msg[7..]) {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   131
                    Ok(result) => {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   132
                        info!("Checked");
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   133
                        debug!(
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   134
                            "Check result: [{}]",
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   135
                            String::from_utf8_lossy(&result.join(&(',' as u8)))
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   136
                        );
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   137
13960
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   138
                        stream.write(b"CHECKED\nOK\n")?;
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   139
                        stream.write(&result.join(&('\n' as u8)))?;
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   140
                        stream.write(b"\n\nREADY\n\n")?;
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   141
                    }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   142
                    Err(e) => {
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   143
                        info!("Check failed: {:?}", e);
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   144
                        stream.write(b"CHECKED\nFAIL\nerror\n\nREADY\n\n")?;
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   145
                    }
a857cd1cc3f0 Finish hedgewars-checker implementation
unc0rr
parents: 13958
diff changeset
   146
                }
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   147
            } else if msg[..].starts_with(b"BYE") {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   148
                warn!("Received BYE: {}", String::from_utf8_lossy(&msg[..]));
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   149
                return Ok(());
13962
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   150
            } else if msg[..].starts_with(b"CHAT") {
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   151
                let body = String::from_utf8_lossy(&msg[5..]);
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   152
                let mut l = body.lines();
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   153
                info!("Chat [{}]: {}", l.next().unwrap(), l.next().unwrap());
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   154
            } else if msg[..].starts_with(b"ROOM") {
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   155
                let body = String::from_utf8_lossy(&msg[5..]);
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   156
                let mut l = body.lines();
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   157
                if let Some(action) = l.next() {
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   158
                    if action == "ADD" {
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   159
                        info!("Room added: {}", l.skip(1).next().unwrap());
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   160
                    }
a4877a16564d Also report chat and added rooms in log
unc0rr
parents: 13960
diff changeset
   161
                }
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   162
            } else if msg[..].starts_with(b"ERROR") {
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   163
                warn!("Received ERROR: {}", String::from_utf8_lossy(&msg[..]));
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   164
                return Ok(());
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   165
            } else {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   166
                warn!(
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   167
                    "Unknown protocol command: {}",
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   168
                    String::from_utf8_lossy(&msg[..])
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   169
                )
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   170
            }
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   171
        }
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   172
    }
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   173
}
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   174
13958
e98e2fc556a7 Create replay file, run engine, result from it and send it to the server. Not implemented: filtering of engine output.
unc0rr
parents: 13957
diff changeset
   175
fn get_protocol_number(executable: &str) -> std::io::Result<u32> {
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   176
    let output = Command::new(executable).arg("--protocol").output()?;
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   177
14401
694c96fb3a06 Fix fail to parse protocol number from engine
unc0rr
parents: 14212
diff changeset
   178
    Ok(u32::from_str(&String::from_utf8(output.stdout).unwrap().trim()).unwrap_or(55))
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   179
}
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   180
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   181
fn main() {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   182
    stderrlog::new()
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   183
        .verbosity(3)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   184
        .timestamp(stderrlog::Timestamp::Second)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   185
        .module(module_path!())
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   186
        .init()
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   187
        .unwrap();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   188
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   189
    let mut frontend_settings = dirs::home_dir().unwrap();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   190
    frontend_settings.push(".hedgewars/settings.ini");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   191
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   192
    let i = Ini::load_from_file(frontend_settings.to_str().unwrap()).unwrap();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   193
    let username = i.get_from(Some("net"), "nick").unwrap();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   194
    let password = i.get_from(Some("net"), "passwordhash").unwrap();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   195
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   196
    let mut exe = "/usr/local/bin/hwengine".to_string();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   197
    let mut prefix = "/usr/local/share/hedgewars/Data".to_string();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   198
    {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   199
        let mut ap = ArgumentParser::new();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   200
        ap.set_description("Game replay checker for hedgewars.");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   201
        ap.refer(&mut exe)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   202
            .add_option(&["--exe"], Store, "Path to hwengine executable");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   203
        ap.refer(&mut prefix)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   204
            .add_option(&["--prefix"], Store, "Path main Data dir");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   205
        ap.parse_args_or_exit();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   206
    }
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   207
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   208
    info!("Executable: {}", exe);
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   209
    info!("Data dir: {}", prefix);
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   210
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   211
    let protocol_number = get_protocol_number(&exe.as_str()).unwrap_or_default();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   212
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   213
    info!("Using protocol number {}", protocol_number);
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   214
14212
bb2f301d4fe0 2018ize everything
alfadur
parents: 13962
diff changeset
   215
    connect_and_run(&username, &password, protocol_number, &exe, &prefix).unwrap();
13957
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   216
}
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   217
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   218
#[cfg(test)]
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   219
#[test]
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   220
fn test() {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   221
    let mut buf = Buf::new();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   222
    buf.extend(b"Hell");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   223
    if let Some(_) = extract_packet(&mut buf) {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   224
        assert!(false)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   225
    }
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   226
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   227
    buf.extend(b"o\n\nWorld");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   228
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   229
    let packet2 = extract_packet(&mut buf).unwrap();
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   230
    assert_eq!(&buf[..], b"World");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   231
    assert_eq!(&packet2[..], b"Hello");
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   232
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   233
    if let Some(_) = extract_packet(&mut buf) {
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   234
        assert!(false)
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   235
    }
d12ca66054aa Start checker implementation in rust
unc0rr
parents:
diff changeset
   236
}