rust/hedgewars-checker/src/main.rs
changeset 13976 a857cd1cc3f0
parent 13974 e98e2fc556a7
child 13978 a4877a16564d
equal deleted inserted replaced
13975:cc312e22592b 13976:a857cd1cc3f0
    32 
    32 
    33 fn check(executable: &str, data_prefix: &str, buffer: &[u8]) -> Result<Vec<Vec<u8>>, CheckError> {
    33 fn check(executable: &str, data_prefix: &str, buffer: &[u8]) -> Result<Vec<Vec<u8>>, CheckError> {
    34     let mut replay = tempfile::NamedTempFile::new()?;
    34     let mut replay = tempfile::NamedTempFile::new()?;
    35 
    35 
    36     for line in buffer.split(|b| *b == '\n' as u8) {
    36     for line in buffer.split(|b| *b == '\n' as u8) {
    37         replay.write(&base64::decode(line)?);
    37         replay.write(&base64::decode(line)?)?;
    38     }
    38     }
    39 
    39 
    40     let temp_file_path = replay.path();
    40     let temp_file_path = replay.path();
    41 
    41 
    42     let mut home_dir = dirs::home_dir().unwrap();
    42     let mut home_dir = dirs::home_dir().unwrap();
    43     home_dir.push(".hedgewars");
    43     home_dir.push(".hedgewars");
       
    44 
       
    45     debug!("Checking replay in {}", temp_file_path.to_string_lossy());
    44 
    46 
    45     let output = Command::new(executable)
    47     let output = Command::new(executable)
    46         .arg("--user-prefix")
    48         .arg("--user-prefix")
    47         .arg(&home_dir)
    49         .arg(&home_dir)
    48         .arg("--prefix")
    50         .arg("--prefix")
    52         .arg("--stats-only")
    54         .arg("--stats-only")
    53         .arg(temp_file_path)
    55         .arg(temp_file_path)
    54         .output()?;
    56         .output()?;
    55 
    57 
    56     let mut result = Vec::new();
    58     let mut result = Vec::new();
    57     for line in output.stdout.split(|b| *b == '\n' as u8) {
    59 
    58         result.push(line.to_vec());
    60     let mut engine_lines = output
    59     }
    61         .stderr
    60 
    62         .split(|b| *b == '\n' as u8)
    61     Ok(result)
    63         .skip_while(|l| *l != b"WINNERS" && *l != b"DRAW");
       
    64 
       
    65     loop {
       
    66         match engine_lines.next() {
       
    67             Some(b"DRAW") => result.push(b"DRAW".to_vec()),
       
    68             Some(b"WINNERS") => {
       
    69                 result.push(b"WINNERS".to_vec());
       
    70                 let winners = engine_lines.next().unwrap();
       
    71                 let winners_num = u32::from_str(&String::from_utf8(winners.to_vec())?)?;
       
    72                 result.push(winners.to_vec());
       
    73 
       
    74                 for _i in 0..winners_num {
       
    75                     result.push(engine_lines.next().unwrap().to_vec());
       
    76                 }
       
    77             }
       
    78             Some(b"GHOST_POINTS") => {
       
    79                 result.push(b"GHOST_POINTS".to_vec());
       
    80                 let points = engine_lines.next().unwrap();
       
    81                 let points_num = u32::from_str(&String::from_utf8(points.to_vec())?)? * 2;
       
    82                 result.push(points.to_vec());
       
    83 
       
    84                 for _i in 0..points_num {
       
    85                     result.push(engine_lines.next().unwrap().to_vec());
       
    86                 }
       
    87             }
       
    88             Some(b"ACHIEVEMENT") => {
       
    89                 result.push(b"ACHIEVEMENT".to_vec());
       
    90                 for _i in 0..4 {
       
    91                     result.push(engine_lines.next().unwrap().to_vec());
       
    92                 }
       
    93             }
       
    94             _ => break,
       
    95         }
       
    96     }
       
    97 
       
    98     if result.len() > 0 {
       
    99         Ok(result)
       
   100     } else {
       
   101         Err("no data from engine".into())
       
   102     }
    62 }
   103 }
    63 
   104 
    64 fn connect_and_run(
   105 fn connect_and_run(
    65     username: &str,
   106     username: &str,
    66     password: &str,
   107     password: &str,
    91             } else if msg[..].starts_with(b"LOGONPASSED") {
   132             } else if msg[..].starts_with(b"LOGONPASSED") {
    92                 info!("Logged in");
   133                 info!("Logged in");
    93                 stream.write(b"READY\n\n")?;
   134                 stream.write(b"READY\n\n")?;
    94             } else if msg[..].starts_with(b"REPLAY") {
   135             } else if msg[..].starts_with(b"REPLAY") {
    95                 info!("Got a replay");
   136                 info!("Got a replay");
    96                 let result = check(executable, data_prefix, &msg[7..])?;
   137                 match check(executable, data_prefix, &msg[7..]) {
    97 
   138                     Ok(result) => {
    98                 debug!(
   139                         info!("Checked");
    99                     "Check result: [{}]",
   140                         debug!(
   100                     String::from_utf8_lossy(&result.join(&(',' as u8)))
   141                             "Check result: [{}]",
   101                 );
   142                             String::from_utf8_lossy(&result.join(&(',' as u8)))
   102 
   143                         );
   103                 stream.write(&result.join(&('\n' as u8)))?;
   144 
   104                 stream.write(b"\n\n")?;
   145                         stream.write(b"CHECKED\nOK\n")?;
       
   146                         stream.write(&result.join(&('\n' as u8)))?;
       
   147                         stream.write(b"\n\nREADY\n\n")?;
       
   148                     }
       
   149                     Err(e) => {
       
   150                         info!("Check failed: {:?}", e);
       
   151                         stream.write(b"CHECKED\nFAIL\nerror\n\nREADY\n\n")?;
       
   152                     }
       
   153                 }
   105             } else if msg[..].starts_with(b"BYE") {
   154             } else if msg[..].starts_with(b"BYE") {
   106                 warn!("Received BYE: {}", String::from_utf8_lossy(&msg[..]));
   155                 warn!("Received BYE: {}", String::from_utf8_lossy(&msg[..]));
   107                 return Ok(());
   156                 return Ok(());
   108             } else if msg[..].starts_with(b"ERROR") {
   157             } else if msg[..].starts_with(b"ERROR") {
   109                 warn!("Received ERROR: {}", String::from_utf8_lossy(&msg[..]));
   158                 warn!("Received ERROR: {}", String::from_utf8_lossy(&msg[..]));