diff --git a/Cargo.lock b/Cargo.lock index 74ab5a1..85bbbad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,10 +290,32 @@ dependencies = [ ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-deque" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" dependencies = [ "cfg-if", ] @@ -394,6 +416,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -733,7 +761,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.51.1", ] [[package]] @@ -794,7 +822,7 @@ dependencies = [ [[package]] name = "kon" -version = "0.1.6" +version = "0.1.7" dependencies = [ "cargo_toml", "gamedig", @@ -803,7 +831,9 @@ dependencies = [ "reqwest", "serde_json", "serenity 0.12.0", + "sysinfo", "tokio", + "uptime_lib", ] [[package]] @@ -921,6 +951,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -1199,6 +1238,26 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -1725,6 +1784,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sysinfo" +version = "0.30.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb4f3438c8f6389c864e61221cbc97e9bca98b4daf39a5beb7bea660f528bb2" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -2132,6 +2206,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "uptime_lib" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e71ddbefed856d5881821d6ada4e606bbb91fd332296963ed596e2ad2100f3" +dependencies = [ + "libc", + "thiserror", + "windows", +] + [[package]] name = "url" version = "2.5.0" @@ -2338,6 +2423,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.0", +] + [[package]] name = "windows-core" version = "0.51.1" @@ -2347,6 +2442,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 86f86dc..5629217 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kon" -version = "0.1.6" +version = "0.1.7" rust-version = "1.74" edition = "2021" @@ -14,7 +14,9 @@ poise = "0.5.7" reqwest = "0.11.23" serde_json = "1.0.111" serenity = "0.12.0" +sysinfo = "0.30.5" tokio = { version = "1.35.1", features = ["macros", "signal", "rt-multi-thread"] } +uptime_lib = "0.3.0" [[bin]] name = "kon" diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 2ac1c6c..2cd38c3 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,2 +1,3 @@ pub mod ping; pub mod status; +pub mod uptime; diff --git a/src/commands/uptime.rs b/src/commands/uptime.rs new file mode 100644 index 0000000..287cafd --- /dev/null +++ b/src/commands/uptime.rs @@ -0,0 +1,52 @@ +use crate::Error; + +use sysinfo::System; +use uptime_lib::get; +use std::time::{ + Duration, + SystemTime, + UNIX_EPOCH +}; + +/// Retrieve host and bot uptimes +#[poise::command(slash_command)] +pub async fn uptime(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> { + let mut sys = System::new_all(); + sys.refresh_all(); + + // Fetch system's uptime + let sys_uptime = get().unwrap().as_secs(); + + // Fetch bot's process uptime + let curr_pid = sysinfo::get_current_pid().unwrap(); + let now = SystemTime::now(); + let mut proc_uptime = 0; + if let Some(process) = sys.process(curr_pid) { + let time_started = UNIX_EPOCH + Duration::from_secs(process.start_time()); + proc_uptime = now.duration_since(time_started).unwrap().as_secs(); + } + + ctx.reply(format!("System: `{}`\nProcess: `{}`", format_duration(sys_uptime), format_duration(proc_uptime))).await?; + Ok(()) +} + +fn format_duration(secs: u64) -> String { + let days = secs / 86400; + let hours = (secs % 86400) / 3600; + let minutes = (secs % 3600) / 60; + let seconds = secs % 60; + + let mut formatted_string = String::new(); + if days > 0 { + formatted_string.push_str(&format!("{}d, ", days)); + } + if hours > 0 || days > 0 { + formatted_string.push_str(&format!("{}h, ", hours)); + } + if minutes > 0 || hours > 0 { + formatted_string.push_str(&format!("{}m, ", minutes)); + } + formatted_string.push_str(&format!("{}s", seconds)); + + formatted_string +} diff --git a/src/main.rs b/src/main.rs index 807b980..9b4e2c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,7 @@ async fn main() { .options(poise::FrameworkOptions { commands: vec![ commands::ping::ping(), + commands::uptime::uptime(), commands::status::status() ], pre_command: |ctx| Box::pin(async move {