use anyhow::Result; use tracing::info; use super::rcon::RconClient; /// Player information from Minecraft RCON. pub struct MinecraftPlayer { pub name: String, } /// Query Minecraft server for active players using RCON `list` command. pub async fn get_players(rcon_address: &str, rcon_password: &str) -> Result<(Vec, u32)> { let mut client = RconClient::connect(rcon_address, rcon_password).await?; let response = client.command("list").await?; // Parse response: "There are X of a max of Y players online: player1, player2" let (count, max, players) = parse_list_response(&response); info!( count = count, max = max, "Minecraft player list retrieved" ); Ok((players, max)) } fn parse_list_response(response: &str) -> (u32, u32, Vec) { // Format: "There are X of a max of Y players online: player1, player2, ..." // Or: "There are X of a max Y players online:" let parts: Vec<&str> = response.splitn(2, ':').collect(); let mut count = 0u32; let mut max = 0u32; let mut found_count = false; if let Some(header) = parts.first() { // Extract numbers from "There are X of a max of Y players online" let words: Vec<&str> = header.split_whitespace().collect(); for word in words.iter() { if let Ok(n) = word.parse::() { if !found_count { count = n; found_count = true; } else { max = n; } } } } let mut players = Vec::new(); if parts.len() > 1 { let player_list = parts[1].trim(); if !player_list.is_empty() { for name in player_list.split(',') { let name = name.trim(); if !name.is_empty() { players.push(MinecraftPlayer { name: name.to_string(), }); } } } } (count, max, players) } #[cfg(test)] mod tests { use super::*; #[test] fn test_parse_list_response() { let (count, max, players) = parse_list_response( "There are 3 of a max of 20 players online: Steve, Alex, Notch", ); assert_eq!(count, 3); assert_eq!(max, 20); assert_eq!(players.len(), 3); assert_eq!(players[0].name, "Steve"); assert_eq!(players[1].name, "Alex"); assert_eq!(players[2].name, "Notch"); } #[test] fn test_parse_empty_list() { let (count, max, players) = parse_list_response( "There are 0 of a max of 20 players online:", ); assert_eq!(count, 0); assert_eq!(max, 20); assert_eq!(players.len(), 0); } }