diff --git a/.gitignore b/.gitignore index ea8c4bf..4a3b37d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +config.toml diff --git a/Cargo.lock b/Cargo.lock index 73cacec..d624f74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "err-derive" version = "0.3.1" @@ -44,6 +50,22 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "libc" version = "0.2.180" @@ -64,9 +86,17 @@ name = "mc-proxy-controller" version = "0.1.0" dependencies = [ "rcon", + "serde", "tokio", + "toml", ] +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + [[package]] name = "mio" version = "1.1.1" @@ -180,6 +210,45 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -268,6 +337,47 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -380,3 +490,12 @@ name = "windows_x86_64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index ec3eeb9..553891c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,5 @@ edition = "2024" [dependencies] rcon = { version = "0.6.0", features = ["rt-tokio"] } tokio = { version = "1.49.0", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } +toml = "0.8" diff --git a/src/main.rs b/src/main.rs index dfc4d1c..ce93342 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,31 @@ use std::error::Error; +use std::fs; use std::time::Duration; use rcon::Connection; +use serde::Deserialize; use tokio::time::Instant; use tokio::{io::copy_bidirectional, main}; use tokio::net::{TcpListener, TcpStream}; +#[derive(Debug, Deserialize)] +struct Config { + listen_addr: String, + server_addr: String, + rcon_addr: String, + rcon_password: String, + idle_timeout_secs: u64, + polling_interval_millis: u64, +} + +impl Config { + fn load(path: &str) -> Result> { + let content = fs::read_to_string(path)?; + let config: Config = toml::from_str(&content)?; + Ok(config) + } +} + fn parse_players_online(s: &str) -> Option { s.split_whitespace() .find_map(|tok| tok.parse::().ok()) @@ -13,24 +33,24 @@ fn parse_players_online(s: &str) -> Option { #[main] async fn main() -> Result<(), Box> { - let listen_addr = "0.0.0.0:8080"; - let server_addr = "127.0.0.1:25565"; - let rcon_addr = "127.0.0.1:25575"; + let config = Config::load("config.toml")?; - println!("Listening on {listen_addr}"); - println!("Proxying to {server_addr}"); + println!("Listening on {}", config.listen_addr); + println!("Proxying to {}", config.server_addr); - let listener = TcpListener::bind(listen_addr).await?; + let listener = TcpListener::bind(&config.listen_addr).await?; + let server_addr = config.server_addr.clone(); tokio::spawn(async move { let mut conn = >::builder() .enable_minecraft_quirks(true) - .connect(rcon_addr, "Lusia669") + .connect(&config.rcon_addr, &config.rcon_password) .await.unwrap(); let mut idle = false; let mut last_online = Instant::now(); - let idle_timeout = Duration::from_secs(10); + let idle_timeout = Duration::from_secs(config.idle_timeout_secs); + let polling_interval = Duration::from_millis(config.polling_interval_millis); loop { let players_cmd_output = conn.cmd("list").await.unwrap(); @@ -50,12 +70,12 @@ async fn main() -> Result<(), Box> { idle = false; } - tokio::time::sleep(Duration::from_millis(250)).await; + tokio::time::sleep(polling_interval).await; }; }); while let Ok((mut inbound, _)) = listener.accept().await { - let mut outbound = TcpStream::connect(server_addr).await?; + let mut outbound = TcpStream::connect(&server_addr).await?; tokio::spawn(async move { if let Err(e) = copy_bidirectional(&mut inbound, &mut outbound).await {