# HG changeset patch # User unc0rr # Date 1540407849 -7200 # Node ID a857cd1cc3f07403848eb91cea8868b41e330db9 # Parent cc312e22592bef87b267ed8d11eeded01e86959f Finish hedgewars-checker implementation diff -r cc312e22592b -r a857cd1cc3f0 rust/hedgewars-checker/src/main.rs --- a/rust/hedgewars-checker/src/main.rs Wed Oct 24 11:05:44 2018 -0400 +++ b/rust/hedgewars-checker/src/main.rs Wed Oct 24 21:04:09 2018 +0200 @@ -34,7 +34,7 @@ let mut replay = tempfile::NamedTempFile::new()?; for line in buffer.split(|b| *b == '\n' as u8) { - replay.write(&base64::decode(line)?); + replay.write(&base64::decode(line)?)?; } let temp_file_path = replay.path(); @@ -42,6 +42,8 @@ let mut home_dir = dirs::home_dir().unwrap(); home_dir.push(".hedgewars"); + debug!("Checking replay in {}", temp_file_path.to_string_lossy()); + let output = Command::new(executable) .arg("--user-prefix") .arg(&home_dir) @@ -54,11 +56,50 @@ .output()?; let mut result = Vec::new(); - for line in output.stdout.split(|b| *b == '\n' as u8) { - result.push(line.to_vec()); + + let mut engine_lines = output + .stderr + .split(|b| *b == '\n' as u8) + .skip_while(|l| *l != b"WINNERS" && *l != b"DRAW"); + + loop { + match engine_lines.next() { + Some(b"DRAW") => result.push(b"DRAW".to_vec()), + Some(b"WINNERS") => { + result.push(b"WINNERS".to_vec()); + let winners = engine_lines.next().unwrap(); + let winners_num = u32::from_str(&String::from_utf8(winners.to_vec())?)?; + result.push(winners.to_vec()); + + for _i in 0..winners_num { + result.push(engine_lines.next().unwrap().to_vec()); + } + } + Some(b"GHOST_POINTS") => { + result.push(b"GHOST_POINTS".to_vec()); + let points = engine_lines.next().unwrap(); + let points_num = u32::from_str(&String::from_utf8(points.to_vec())?)? * 2; + result.push(points.to_vec()); + + for _i in 0..points_num { + result.push(engine_lines.next().unwrap().to_vec()); + } + } + Some(b"ACHIEVEMENT") => { + result.push(b"ACHIEVEMENT".to_vec()); + for _i in 0..4 { + result.push(engine_lines.next().unwrap().to_vec()); + } + } + _ => break, + } } - Ok(result) + if result.len() > 0 { + Ok(result) + } else { + Err("no data from engine".into()) + } } fn connect_and_run( @@ -93,15 +134,23 @@ stream.write(b"READY\n\n")?; } else if msg[..].starts_with(b"REPLAY") { info!("Got a replay"); - let result = check(executable, data_prefix, &msg[7..])?; + match check(executable, data_prefix, &msg[7..]) { + Ok(result) => { + info!("Checked"); + debug!( + "Check result: [{}]", + String::from_utf8_lossy(&result.join(&(',' as u8))) + ); - debug!( - "Check result: [{}]", - String::from_utf8_lossy(&result.join(&(',' as u8))) - ); - - stream.write(&result.join(&('\n' as u8)))?; - stream.write(b"\n\n")?; + stream.write(b"CHECKED\nOK\n")?; + stream.write(&result.join(&('\n' as u8)))?; + stream.write(b"\n\nREADY\n\n")?; + } + Err(e) => { + info!("Check failed: {:?}", e); + stream.write(b"CHECKED\nFAIL\nerror\n\nREADY\n\n")?; + } + } } else if msg[..].starts_with(b"BYE") { warn!("Received BYE: {}", String::from_utf8_lossy(&msg[..])); return Ok(());