Use 'rcon' to get the player list
authorGreg Burri <greg.burri@gmail.com>
Wed, 23 Jun 2021 10:16:29 +0000 (12:16 +0200)
committerGreg Burri <greg.burri@gmail.com>
Wed, 23 Jun 2021 10:16:29 +0000 (12:16 +0200)
Cargo.lock
backend/Cargo.toml
backend/src/main.rs
backend/src/minecraft_controller.rs

index b10c767..041b868 100644 (file)
@@ -289,9 +289,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.18"
+version = "0.7.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
 dependencies = [
  "memchr",
 ]
@@ -352,7 +352,7 @@ checksum = "2582b77e0f3c506ec4838a25fa8a5f97b9bed72bb6d3d272ea1c031d8bd373bc"
 dependencies = [
  "askama_escape",
  "humansize",
- "nom 6.1.2",
+ "nom 6.2.0",
  "num-traits",
  "percent-encoding",
  "proc-macro2",
@@ -480,12 +480,6 @@ dependencies = [
  "bytes 0.5.6",
 ]
 
-[[package]]
-name = "build-env"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1522ac6ee801a11bf9ef3f80403f4ede6eb41291fac3dde3de09989679305f25"
-
 [[package]]
 name = "bumpalo"
 version = "3.7.0"
@@ -685,16 +679,6 @@ 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 = "darling"
 version = "0.10.2"
@@ -814,33 +798,6 @@ 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"
@@ -1188,17 +1145,6 @@ version = "0.2.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
 
-[[package]]
-name = "libsystemd-sys"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68c9b25d61a54754b491e1cb848e644ff90b6c11f6f11f9d2c170b7d2cd83b3"
-dependencies = [
- "build-env",
- "libc",
- "pkg-config",
-]
-
 [[package]]
 name = "linked-hash-map"
 version = "0.5.4"
@@ -1246,9 +1192,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
 
 [[package]]
 name = "memchr"
-version = "2.4.0"
+version = "2.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
 [[package]]
 name = "memoffset"
@@ -1275,6 +1221,12 @@ dependencies = [
  "unicase",
 ]
 
+[[package]]
+name = "minecraft-client-rs"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f2fd9077229b5f03f3ee911866e75126ecf102ee9163993a120dcf5433af2b5"
+
 [[package]]
 name = "minecraft_web"
 version = "1.0.0"
@@ -1288,10 +1240,10 @@ dependencies = [
  "common",
  "futures",
  "itertools",
+ "minecraft-client-rs",
  "ron",
  "serde",
  "sysinfo",
- "systemd",
 ]
 
 [[package]]
@@ -1369,9 +1321,9 @@ dependencies = [
 
 [[package]]
 name = "nom"
-version = "6.1.2"
+version = "6.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
+checksum = "046a595c7251e2f48b291c1b65d98ef1df51dbfbad46e99a1ff09729535a779e"
 dependencies = [
  "bitvec",
  "funty",
@@ -1519,12 +1471,6 @@ 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"
@@ -1650,9 +1596,9 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.5.4"
+version = "1.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1913,21 +1859,6 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
-[[package]]
-name = "systemd"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe03808323f01aefb68591de263b994ffeb671af1fe040858dc820ed7b681996"
-dependencies = [
- "cstr-argument",
- "foreign-types",
- "libc",
- "libsystemd-sys",
- "log",
- "memchr",
- "utf8-cstr",
-]
-
 [[package]]
 name = "tap"
 version = "1.0.1"
@@ -2197,12 +2128,6 @@ 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.15.0"
index 1c51617..139cf2f 100644 (file)
@@ -7,6 +7,10 @@ edition = "2018"
 [dependencies]
 actix-web = "3"
 actix-files = "0.5"
+askama_actix = "0.11"
+
+minecraft-client-rs = "0.1"
+
 serde = { version = "1.0", features = ["derive"] }
 
 ron = "0.6" # Rust object notation, to load configuration files.
@@ -22,12 +26,7 @@ futures = "0.3" # Needed by askam with the feature 'with-actix-web'.
 
 common = { path = "../common" }
 
-askama_actix = "0.11"
-
 # Template system.
 [dependencies.askama]
 version = "0.10"
-features = ["with-actix-web"]
-
-[target.'cfg(unix)'.dependencies]
-systemd = "0.9"
\ No newline at end of file
+features = ["with-actix-web"]
\ No newline at end of file
index 53fbe68..2129033 100644 (file)
@@ -28,15 +28,15 @@ struct MainTemplate {
 const VALUE_UNKNOWN: &str = "-";
 
 #[cached(size = 1, time = 10)]
-fn get_minecraft_executable_information_cached(world_path: String, backup_path: String) -> Option<minecraft_controller::MinecraftExe> {
-    minecraft_controller::get_minecraft_executable_information(&world_path, &backup_path)
+fn get_minecraft_executable_information_cached(world_path: String, backup_path: String, rcon_password: String) -> Option<minecraft_controller::MinecraftExe> {
+    minecraft_controller::get_minecraft_executable_information(&world_path, &backup_path, &rcon_password)
 }
 
 #[get("/")]
 async fn main_page(config_shared: web::Data<Mutex<Config>>) -> impl Responder {
     let config = config_shared.lock().unwrap();
 
-    match get_minecraft_executable_information_cached(config.world_path.clone(), config.backup_path.clone()) {
+    match get_minecraft_executable_information_cached(config.world_path.clone(), config.backup_path.clone(), config.rcon_password.clone()) {
         Some(info) =>
             MainTemplate {
                 text_status: String::from("Minecraft server is up and running :)"),
@@ -144,7 +144,7 @@ fn process_args(config: &Config) -> bool {
         print_usage();
         return true
     } else if args.iter().any(|arg| arg == "--status") {
-        println!("{:?}", minecraft_controller::get_minecraft_executable_information(&config.world_path, &config.backup_path));
+        println!("{:?}", minecraft_controller::get_minecraft_executable_information(&config.world_path, &config.backup_path, &config.rcon_password));
         return true
     }
 
index 05ffeb3..260a6e4 100644 (file)
@@ -76,7 +76,7 @@ fn format_byte_size(bytes: u64, precision: usize) -> String {
     String::from("")\r
 }\r
 \r
-const MINECRAFT_PROCESS_NAME: &str = "minecraft_server";\r
+const MINECRAFT_PROCESS_NAME: &str = "java";\r
 \r
 #[cfg(target_os = "linux")]\r
 const STRING_BEFORE_CHARACTER_NAME: &str = "Got character ZDOID from";\r
@@ -85,58 +85,32 @@ const STRING_BEFORE_CHARACTER_NAME: &str = "Got character ZDOID from";
 const STRING_BEFORE_NB_OF_CONNECTIONS: &str = "Connections";\r
 \r
 // It doesn't work for the moment, it only scan the connection event and do not treat disconnections.\r
-#[cfg(target_os = "linux")]\r
-fn get_active_players() -> Vec<String> {\r
-    let mut journal =\r
-        journal::OpenOptions::default().current_user(true).open().unwrap();\r
-\r
-    journal.seek_tail().unwrap();\r
-\r
-    let mut number_of_connections = -1i32;\r
-    let mut players : Vec<String> = Vec::new();\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 == "minecraft.service" {\r
-                        if let Some(pos) = mess.find(STRING_BEFORE_CHARACTER_NAME) {\r
-                            let character_str = mess.get(pos+STRING_BEFORE_CHARACTER_NAME.len()+1..).unwrap();\r
-                            if let Some(pos_end) = character_str.find(" : ") {\r
-                                let player_name = String::from(character_str.get(0..pos_end).unwrap());\r
-                                if !players.contains(&player_name) {\r
-                                    players.push(player_name);\r
-                                    if players.len() as i32 == number_of_connections {\r
-                                        return players;\r
-                                    }\r
-                                }\r
-                            }\r
-                        }\r
-                        else if let Some(pos) = mess.find(STRING_BEFORE_NB_OF_CONNECTIONS) {\r
-                            let nb_of_connections_str = mess.get(pos+STRING_BEFORE_NB_OF_CONNECTIONS.len()+1..).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::<i32>() {\r
-                                    if number_of_connections == -1 {\r
-                                        number_of_connections = n;\r
-\r
-                                        if players.len() as i32 >= number_of_connections {\r
-                                            return players;\r
-                                        }\r
-                                    }\r
-                                }\r
-                            }\r
-                        }\r
-                    }\r
+fn get_active_players(rcon_password: &str) -> Vec<String> {\r
+    let mut client = minecraft_client_rs::Client::new("127.0.0.1:25575".to_string()).unwrap();\r
+\r
+    let players =\r
+        match client.authenticate(rcon_password.to_string()) {\r
+            Ok(_) => {\r
+                match client.send_command("list".to_string()) {\r
+                    Ok(resp) => {\r
+                        println!("{}", resp.body);\r
+                        Vec::new()\r
+                    },\r
+                    Err(_e) => {\r
+                        println!("Error asking seed");\r
+                        Vec::new()\r
+                    },\r
                 }\r
             },\r
-            _ => return players\r
-        }\r
-    }\r
-}\r
+            Err(_e) => {\r
+                println!("Authentication error");\r
+                Vec::new()\r
+            },\r
+        };\r
+\r
+    client.close().unwrap();\r
 \r
-#[cfg(target_os = "windows")]\r
-fn get_active_players() -> Vec<String> {\r
-    Vec::new()\r
+    players\r
 }\r
 \r
 fn get_last_backup_datetime(backup_path: &str) -> Option<SystemTime> {\r
@@ -154,11 +128,12 @@ fn get_last_backup_datetime(backup_path: &str) -> Option<SystemTime> {
     Some(times.last()?.clone())\r
 }\r
 \r
-pub fn get_minecraft_executable_information(world_path: &str, backup_path: &str) -> Option<MinecraftExe> {\r
+pub fn get_minecraft_executable_information(world_path: &str, backup_path: &str, rcon_password: &str) -> Option<MinecraftExe> {\r
     let mut system = sysinfo::System::new_all();\r
     system.refresh_system();\r
     let processes = system.get_process_by_name(MINECRAFT_PROCESS_NAME);\r
 \r
+    // TODO: find the correct process by checking the correct jar name in parameters.\r
     if processes.len() >= 1 {\r
         let process = processes.first().unwrap();\r
 \r
@@ -170,7 +145,7 @@ pub fn get_minecraft_executable_information(world_path: &str, backup_path: &str)
                 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
-                active_players: get_active_players(),\r
+                active_players: get_active_players(rcon_password),\r
                 last_backup: get_last_backup_datetime(backup_path)\r
             }\r
         )\r