Implement pinging of the server every 30 seconds
authorunC0Rr
Tue, 03 Oct 2023 21:13:41 +0200
changeset 16009 39ae4ed7de6e
parent 16008 1635ce22b214
child 16010 5ba4d3a0c3eb
Implement pinging of the server every 30 seconds
rust/hedgewars-checker/src/main.rs
--- a/rust/hedgewars-checker/src/main.rs	Mon Oct 02 21:36:13 2023 +0200
+++ b/rust/hedgewars-checker/src/main.rs	Tue Oct 03 21:13:41 2023 +0200
@@ -1,4 +1,4 @@
-use anyhow::{bail, Result};
+use anyhow::{anyhow, bail, Result};
 use argparse::{ArgumentParser, Store};
 use base64::{engine::general_purpose, Engine};
 use hedgewars_network_protocol::{
@@ -8,6 +8,7 @@
 use log::{debug, info, warn};
 use netbuf::Buf;
 use std::{io::Write, str::FromStr};
+use tokio::time::MissedTickBehavior;
 use tokio::{io, io::AsyncWriteExt, net::TcpStream, process::Command, sync::mpsc};
 
 async fn check(executable: &str, data_prefix: &str, buffer: &[String]) -> Result<Vec<String>> {
@@ -19,7 +20,7 @@
 
     let temp_file_path = replay.path();
 
-    let mut home_dir = dirs::home_dir().unwrap();
+    let mut home_dir = dirs::home_dir().ok_or(anyhow!("Home path not detected"))?;
     home_dir.push(".hedgewars");
 
     debug!("Checking replay in {}", temp_file_path.to_string_lossy());
@@ -119,8 +120,16 @@
 
     let mut buf = Buf::new();
 
+    let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(30));
+    interval.set_missed_tick_behavior(MissedTickBehavior::Delay);
+
     loop {
         let r = tokio::select! {
+            _ = interval.tick() => {
+                // Send Ping
+                stream.write_all(ClientMessage::Ping.to_raw_protocol().as_bytes()).await?;
+                None
+            },
             _ = stream.readable() => None,
             r = results_receiver.recv() => r
         };
@@ -200,6 +209,9 @@
                         .write_all(ClientMessage::Pong.to_raw_protocol().as_bytes())
                         .await?;
                 }
+                Pong => {
+                    // do nothing
+                }
                 LogonPassed => {
                     stream
                         .write_all(ClientMessage::CheckerReady.to_raw_protocol().as_bytes())
@@ -246,7 +258,7 @@
 async fn get_protocol_number(executable: &str) -> Result<u16> {
     let output = Command::new(executable).arg("--protocol").output().await?;
 
-    Ok(u16::from_str(String::from_utf8(output.stdout).unwrap().trim()).unwrap_or(55))
+    Ok(u16::from_str(String::from_utf8(output.stdout)?.trim()).unwrap_or(55))
 }
 
 #[tokio::main]
@@ -255,15 +267,18 @@
         .verbosity(3)
         .timestamp(stderrlog::Timestamp::Second)
         .module(module_path!())
-        .init()
-        .unwrap();
+        .init()?;
 
-    let mut frontend_settings = dirs::home_dir().unwrap();
+    let mut frontend_settings = dirs::home_dir().ok_or(anyhow!("Home path not detected"))?;
     frontend_settings.push(".hedgewars/settings.ini");
 
     let i = Ini::load_from_file(frontend_settings.to_str().unwrap()).unwrap();
-    let username = i.get_from(Some("net"), "nick").unwrap();
-    let password = i.get_from(Some("net"), "passwordhash").unwrap();
+    let username = i
+        .get_from(Some("net"), "nick")
+        .ok_or(anyhow!("Nickname not found in frontend config"))?;
+    let password = i
+        .get_from(Some("net"), "passwordhash")
+        .ok_or(anyhow!("Password not found in frontend config"))?;
 
     let mut exe = "/usr/local/bin/hwengine".to_string();
     let mut prefix = "/usr/local/share/hedgewars/Data".to_string();
@@ -280,7 +295,7 @@
     info!("Executable: {}", exe);
     info!("Data dir: {}", prefix);
 
-    let protocol_number = get_protocol_number(exe.as_str()).await.unwrap_or_default();
+    let protocol_number = get_protocol_number(exe.as_str()).await?;
 
     info!("Using protocol number {}", protocol_number);