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