1 use anyhow::{bail, Result}; |
1 use anyhow::{anyhow, bail, Result}; |
2 use argparse::{ArgumentParser, Store}; |
2 use argparse::{ArgumentParser, Store}; |
3 use base64::{engine::general_purpose, Engine}; |
3 use base64::{engine::general_purpose, Engine}; |
4 use hedgewars_network_protocol::{ |
4 use hedgewars_network_protocol::{ |
5 messages::HwProtocolMessage as ClientMessage, messages::HwServerMessage::*, parser, |
5 messages::HwProtocolMessage as ClientMessage, messages::HwServerMessage::*, parser, |
6 }; |
6 }; |
7 use ini::Ini; |
7 use ini::Ini; |
8 use log::{debug, info, warn}; |
8 use log::{debug, info, warn}; |
9 use netbuf::Buf; |
9 use netbuf::Buf; |
10 use std::{io::Write, str::FromStr}; |
10 use std::{io::Write, str::FromStr}; |
|
11 use tokio::time::MissedTickBehavior; |
11 use tokio::{io, io::AsyncWriteExt, net::TcpStream, process::Command, sync::mpsc}; |
12 use tokio::{io, io::AsyncWriteExt, net::TcpStream, process::Command, sync::mpsc}; |
12 |
13 |
13 async fn check(executable: &str, data_prefix: &str, buffer: &[String]) -> Result<Vec<String>> { |
14 async fn check(executable: &str, data_prefix: &str, buffer: &[String]) -> Result<Vec<String>> { |
14 let mut replay = tempfile::NamedTempFile::new()?; |
15 let mut replay = tempfile::NamedTempFile::new()?; |
15 |
16 |
17 replay.write_all(&general_purpose::STANDARD.decode(line)?)?; |
18 replay.write_all(&general_purpose::STANDARD.decode(line)?)?; |
18 } |
19 } |
19 |
20 |
20 let temp_file_path = replay.path(); |
21 let temp_file_path = replay.path(); |
21 |
22 |
22 let mut home_dir = dirs::home_dir().unwrap(); |
23 let mut home_dir = dirs::home_dir().ok_or(anyhow!("Home path not detected"))?; |
23 home_dir.push(".hedgewars"); |
24 home_dir.push(".hedgewars"); |
24 |
25 |
25 debug!("Checking replay in {}", temp_file_path.to_string_lossy()); |
26 debug!("Checking replay in {}", temp_file_path.to_string_lossy()); |
26 |
27 |
27 let output = Command::new(executable) |
28 let output = Command::new(executable) |
117 |
118 |
118 let mut stream = TcpStream::connect("hedgewars.org:46631").await?; |
119 let mut stream = TcpStream::connect("hedgewars.org:46631").await?; |
119 |
120 |
120 let mut buf = Buf::new(); |
121 let mut buf = Buf::new(); |
121 |
122 |
|
123 let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(30)); |
|
124 interval.set_missed_tick_behavior(MissedTickBehavior::Delay); |
|
125 |
122 loop { |
126 loop { |
123 let r = tokio::select! { |
127 let r = tokio::select! { |
|
128 _ = interval.tick() => { |
|
129 // Send Ping |
|
130 stream.write_all(ClientMessage::Ping.to_raw_protocol().as_bytes()).await?; |
|
131 None |
|
132 }, |
124 _ = stream.readable() => None, |
133 _ = stream.readable() => None, |
125 r = results_receiver.recv() => r |
134 r = results_receiver.recv() => r |
126 }; |
135 }; |
127 |
136 |
128 //println!("Loop: {:?}", &r); |
137 //println!("Loop: {:?}", &r); |
244 } |
256 } |
245 |
257 |
246 async fn get_protocol_number(executable: &str) -> Result<u16> { |
258 async fn get_protocol_number(executable: &str) -> Result<u16> { |
247 let output = Command::new(executable).arg("--protocol").output().await?; |
259 let output = Command::new(executable).arg("--protocol").output().await?; |
248 |
260 |
249 Ok(u16::from_str(String::from_utf8(output.stdout).unwrap().trim()).unwrap_or(55)) |
261 Ok(u16::from_str(String::from_utf8(output.stdout)?.trim()).unwrap_or(55)) |
250 } |
262 } |
251 |
263 |
252 #[tokio::main] |
264 #[tokio::main] |
253 async fn main() -> Result<()> { |
265 async fn main() -> Result<()> { |
254 stderrlog::new() |
266 stderrlog::new() |
255 .verbosity(3) |
267 .verbosity(3) |
256 .timestamp(stderrlog::Timestamp::Second) |
268 .timestamp(stderrlog::Timestamp::Second) |
257 .module(module_path!()) |
269 .module(module_path!()) |
258 .init() |
270 .init()?; |
259 .unwrap(); |
271 |
260 |
272 let mut frontend_settings = dirs::home_dir().ok_or(anyhow!("Home path not detected"))?; |
261 let mut frontend_settings = dirs::home_dir().unwrap(); |
|
262 frontend_settings.push(".hedgewars/settings.ini"); |
273 frontend_settings.push(".hedgewars/settings.ini"); |
263 |
274 |
264 let i = Ini::load_from_file(frontend_settings.to_str().unwrap()).unwrap(); |
275 let i = Ini::load_from_file(frontend_settings.to_str().unwrap()).unwrap(); |
265 let username = i.get_from(Some("net"), "nick").unwrap(); |
276 let username = i |
266 let password = i.get_from(Some("net"), "passwordhash").unwrap(); |
277 .get_from(Some("net"), "nick") |
|
278 .ok_or(anyhow!("Nickname not found in frontend config"))?; |
|
279 let password = i |
|
280 .get_from(Some("net"), "passwordhash") |
|
281 .ok_or(anyhow!("Password not found in frontend config"))?; |
267 |
282 |
268 let mut exe = "/usr/local/bin/hwengine".to_string(); |
283 let mut exe = "/usr/local/bin/hwengine".to_string(); |
269 let mut prefix = "/usr/local/share/hedgewars/Data".to_string(); |
284 let mut prefix = "/usr/local/share/hedgewars/Data".to_string(); |
270 { |
285 { |
271 let mut ap = ArgumentParser::new(); |
286 let mut ap = ArgumentParser::new(); |
278 } |
293 } |
279 |
294 |
280 info!("Executable: {}", exe); |
295 info!("Executable: {}", exe); |
281 info!("Data dir: {}", prefix); |
296 info!("Data dir: {}", prefix); |
282 |
297 |
283 let protocol_number = get_protocol_number(exe.as_str()).await.unwrap_or_default(); |
298 let protocol_number = get_protocol_number(exe.as_str()).await?; |
284 |
299 |
285 info!("Using protocol number {}", protocol_number); |
300 info!("Using protocol number {}", protocol_number); |
286 |
301 |
287 let (replay_sender, replay_receiver) = mpsc::channel(1); |
302 let (replay_sender, replay_receiver) = mpsc::channel(1); |
288 let (results_sender, results_receiver) = mpsc::channel(1); |
303 let (results_sender, results_receiver) = mpsc::channel(1); |