Display the number of active player
authorGreg Burri <greg.burri@gmail.com>
Mon, 15 Mar 2021 10:37:19 +0000 (11:37 +0100)
committerGreg Burri <greg.burri@gmail.com>
Mon, 15 Mar 2021 10:37:19 +0000 (11:37 +0100)
Cargo.lock
backend/Cargo.toml
backend/src/main.rs
backend/src/valheim_controller.rs
backend/templates/main.html

index 0d1303a..cd8fd77 100644 (file)
@@ -480,6 +480,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "build-env"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cf89846ef2b2674ef1c153256cec98fba587c72bf4ea2c4b2f6d91a19f55926"
+
 [[package]]
 name = "byteorder"
 version = "1.4.3"
@@ -608,6 +614,16 @@ dependencies = [
  "lazy_static",
 ]
 
+[[package]]
+name = "cstr-argument"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20bd4e8067c20c7c3a4dea759ef91d4b18418ddb5bd8837ef6e2f2f93ca7ccbb"
+dependencies = [
+ "cfg-if 0.1.10",
+ "memchr",
+]
+
 [[package]]
 name = "derive_more"
 version = "0.99.11"
@@ -698,6 +714,33 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
+[[package]]
+name = "foreign-types"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
+dependencies = [
+ "foreign-types-macros",
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-macros"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63f713f8b2aa9e24fec85b0e290c56caee12e3b6ae0aeeda238a75b28251afd6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7684cf33bb7f28497939e8c7cf17e3e4e3b8d9a0080ffa4f8ae2f515442ee855"
+
 [[package]]
 name = "form_urlencoded"
 version = "1.0.1"
@@ -1014,6 +1057,17 @@ version = "0.2.88"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
 
+[[package]]
+name = "libsystemd-sys"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e03fd580bcecda68dcdcd5297085ade6a3dc552cd8b030d2b94a9b089ef7ab8"
+dependencies = [
+ "build-env",
+ "libc",
+ "pkg-config",
+]
+
 [[package]]
 name = "linked-hash-map"
 version = "0.5.4"
@@ -1312,6 +1366,12 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
+[[package]]
+name = "pkg-config"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.10"
@@ -1606,6 +1666,21 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "systemd"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f722cabda922e471742300045f56dbaa53fafbb4520fca304e51258019bfe91d"
+dependencies = [
+ "cstr-argument",
+ "foreign-types",
+ "libc",
+ "libsystemd-sys",
+ "log",
+ "memchr",
+ "utf8-cstr",
+]
+
 [[package]]
 name = "thread_local"
 version = "1.1.3"
@@ -1828,6 +1903,12 @@ dependencies = [
  "percent-encoding",
 ]
 
+[[package]]
+name = "utf8-cstr"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55bcbb425141152b10d5693095950b51c3745d019363fc2929ffd8f61449b628"
+
 [[package]]
 name = "v_escape"
 version = "0.7.4"
@@ -1873,6 +1954,7 @@ dependencies = [
  "ron",
  "serde",
  "sysinfo",
+ "systemd",
 ]
 
 [[package]]
index 5a4b1e1..1b5f3d0 100644 (file)
@@ -14,6 +14,7 @@ ron = "0.6" # Rust object notation, to load configuration files.
 itertools = "0.10"
 
 sysinfo = "0.16"
+systemd = "0.8"
 
 futures = "0.3" # Needed by askam with the feature 'with-actix-web'.
 
index c4c51a0..84485c2 100644 (file)
@@ -19,7 +19,8 @@ struct MainTemplate {
     memory: String,
     load_average: String,
     uptime: String,
-    world_size: String
+    world_size: String,
+    nb_of_players: u32,
 }
 
 const VALUE_UNKNOWN: &str = "-";
@@ -35,11 +36,12 @@ async fn main_page(config_shared: web::Data<Mutex<Config>>) -> impl Responder {
                 memory: info.format_memory(),
                 load_average: info.format_load_average(),
                 uptime: info.format_uptime(),
-                world_size: info.format_world_size()
+                world_size: info.format_world_size(),
+                nb_of_players: info.get_nb_of_player()
             },
         None => {
             let value_unknown = String::from(VALUE_UNKNOWN);
-            MainTemplate { text_status: String::from("Valheim server is down :("), memory: value_unknown.clone(), load_average: value_unknown.clone(), uptime: value_unknown.clone(), world_size: value_unknown.clone() }
+            MainTemplate { text_status: String::from("Valheim server is down :("), memory: value_unknown.clone(), load_average: value_unknown.clone(), uptime: value_unknown.clone(), world_size: value_unknown.clone(), nb_of_players: 0 }
         }
     }
 }
index a483756..457abc1 100644 (file)
@@ -1,4 +1,5 @@
-use sysinfo::{ProcessExt, SystemExt};\r
+use sysinfo::{ ProcessExt, SystemExt };\r
+use systemd::journal;\r
 \r
 #[derive(Debug)]\r
 pub struct ValheimExe {\r
@@ -6,24 +7,32 @@ pub struct ValheimExe {
     load_average_5min: f64, // [%].\r
     uptime: u64, // [s].\r
     world_size: u64, // [B].\r
+    nb_of_players: u32,\r
 }\r
 \r
 impl ValheimExe {\r
     pub fn format_memory(&self) -> String {\r
         format_byte_size(self.memory * 1024, 2)\r
     }\r
+\r
     pub fn format_load_average(&self) -> String {\r
         format!("{:.2} %", self.load_average_5min)\r
     }\r
+\r
     pub fn format_uptime(&self) -> String {\r
         let mins = self.uptime / 60;\r
         let hours = mins / 60;\r
         let days = hours / 24;\r
         format!("{}d{}h{}min", days, hours - 24 * days, mins - 60 * hours)\r
     }\r
+\r
     pub fn format_world_size(&self) -> String {\r
         format_byte_size(self.world_size, 2)\r
     }\r
+\r
+    pub fn get_nb_of_player(&self) -> u32 {\r
+        self.nb_of_players\r
+    }\r
 }\r
 \r
 const BINARY_PREFIXES: [&str; 8] = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"];\r
@@ -46,6 +55,33 @@ fn format_byte_size(bytes: u64, precision: usize) -> String {
 \r
 const VALHEIM_PROCESS_NAME: &str = "valheim_server";\r
 \r
+fn get_number_of_players() -> u32 {\r
+    let mut journal =\r
+        journal::OpenOptions::default().current_user(true).open().unwrap();\r
+\r
+    journal.seek_tail().unwrap();\r
+\r
+    loop {\r
+        match journal.previous_entry() {\r
+            Ok(Some(entry)) => {\r
+                if let (Some(unit), Some(mess)) = (entry.get("_SYSTEMD_UNIT"), entry.get("MESSAGE")) {\r
+                    if unit == "valheim.service" {\r
+                        if let Some(pos) = mess.find("Connections") {\r
+                            let nb_of_connections_str = mess.get(pos+12..).unwrap();\r
+                            if let Some(pos_end) = nb_of_connections_str.find(' ') {\r
+                                if let Ok(n) = nb_of_connections_str.get(0..pos_end).unwrap().parse() {\r
+                                    return n;\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            },\r
+            _ => return 0\r
+        }\r
+    }\r
+}\r
+\r
 pub fn get_valheim_executable_information(world_path : &str) -> Option<ValheimExe> {\r
     let mut system = sysinfo::System::new_all();\r
     system.refresh_system();\r
@@ -61,7 +97,8 @@ pub fn get_valheim_executable_information(world_path : &str) -> Option<ValheimEx
                 memory: process.memory(),\r
                 load_average_5min: system.get_load_average().five / system.get_processors().len() as f64 * 100.,\r
                 uptime: std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs() - process.start_time(),\r
-                world_size\r
+                world_size,\r
+                nb_of_players: get_number_of_players()\r
             }\r
         )\r
     } else {\r
index 7f6dcb1..7b78f12 100644 (file)
@@ -10,6 +10,7 @@
     <body>\r
         <div class="container">\r
             <h1>{{ text_status }}</h1>\r
+            <p>Number of active player: {{ nb_of_players }}</p>\r
             <p>World size: {{ world_size }}</p>\r
             <p>Memory used: {{ memory }}</p>\r
             <p>Load average (5 min): {{ load_average }}</p>\r