use std::io::{Result}; use std::net::{ToSocketAddrs}; use std::env; use mcstatusface::http::{HttpServer, StatusCode}; use mcstatusface::{MinecraftStatus}; fn main() -> Result<()> { let args: Vec = env::args().collect(); if args.len() < 2 { eprintln!("Usage: {} [serve] ", args[0]); std::process::exit(1); } if args[1] != "serve" { let mut address = String::from(args[1].as_str()); if !address.contains(":") { address += ":25565"; } let mut addrs_iter = args[1].to_socket_addrs().unwrap(); let address = addrs_iter.next().unwrap(); let status = MinecraftStatus::fetch(address).unwrap(); println!("\nVersion: {} ({})", status.version.name, status.version.protocol); println!("Players: {}/{}", status.players.online, status.players.max); println!("MOTD:"); println!("{}", status.parse_description()); return Ok(()); } let mut address = "0.0.0.0:8080".to_string(); if args.len() > 2 { address = args[2].to_string() } HttpServer::new(address, 64).start(|request, mut response| { response.status(StatusCode::OK); response.set_header("x-powered-by", "GIRL FUEL".to_string()); if request.method() != "GET" { response.status(StatusCode::NotFound); return response.send() } if !request.query().contains_key("s") { response.status(StatusCode::BadRequest); // TODO: nice index landing page for browsers response.body("?s=\n".to_string()); return response.send() } let mut address = request.query().get("s").unwrap().to_string(); if !address.contains(":") { address.push_str(":25565"); } let mut addrs_iter = address.to_socket_addrs().unwrap(); let address = addrs_iter.next().unwrap(); let status = MinecraftStatus::fetch(address).unwrap(); #[derive(serde::Serialize)] struct MinecraftStatusResponse<'a> { version: &'a String, players: u32, max_players: u32, motd: String, } let minecraft_status = MinecraftStatusResponse{ version: &status.version.name, players: status.players.online, max_players: status.players.max, motd: status.parse_description(), }; match serde_json::to_string(&minecraft_status) { Ok(json) => { response.status(StatusCode::OK); response.set_header("Content-Type", "application/json".to_string()); response.body(json); } Err(e) => { eprintln!("Request to {address} failed: {e}"); response.status(StatusCode::InternalServerError); response.set_header("Content-Type", "text/plain".to_string()); response.body("Unable to reach the requested server.\n".to_string()); } } response.send() }).unwrap(); Ok(()) }