diff --git a/Cargo.lock b/Cargo.lock index ed76786..cf3375a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,7 +794,7 @@ dependencies = [ [[package]] name = "kon" -version = "0.1.4" +version = "0.1.5" dependencies = [ "cargo_toml", "gamedig", diff --git a/Cargo.toml b/Cargo.toml index 9daf4e1..5405774 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kon" -version = "0.1.4" +version = "0.1.5" rust-version = "1.74" edition = "2021" diff --git a/src/commands/ats_status.rs b/src/commands/ats_status.rs deleted file mode 100644 index 0be1f21..0000000 --- a/src/commands/ats_status.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::{Error, COLOR}; - -use gamedig::protocols::{ - valve::{ - Engine, GatheringSettings, Response - }, - types::TimeoutSettings, - valve, -}; -use std::{ - str::FromStr, - net::SocketAddr, - time::Duration, - env::var -}; - -fn query_server() -> Result { - let server_ip = var("ATS_SERVER_IP").expect("Expected a \"ATS_SERVER_IP\" in the envvar but none was found"); - let addr = SocketAddr::from_str(&server_ip).unwrap(); - let engine = Engine::Source(None); - let gather_settings = GatheringSettings { - players: true, - rules: false, - check_app_id: false - }; - - let read_timeout = Duration::from_secs(2); - let write_timeout = Duration::from_secs(2); - let retries = 1; - let timeout_settings = TimeoutSettings::new( - Some(read_timeout), - Some(write_timeout), - retries - ).unwrap(); - - let response = valve::query( - &addr, - engine, - Some(gather_settings), - Some(timeout_settings) - ); - - Ok(response?) -} - -/// Retrieve the server status from ATS -#[poise::command(slash_command)] -pub async fn ats_status(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> { - match query_server() { - Ok(response) => { - ctx.send(|m| m.embed(|e| - e.color(COLOR) - .title("American Truck Simulator Server Status") - .fields(vec![ - ("Name", format!("{}", response.info.name), true), - ("Players", format!("{}/{}", response.info.players_online, response.info.players_maximum), true) - ]) - )).await?; - } - Err(why) => println!("Error querying the server: {:?}", why) - } - - Ok(()) -} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index ae30187..2ac1c6c 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,3 +1,2 @@ pub mod ping; -pub mod wg_status; -pub mod ats_status; +pub mod status; diff --git a/src/commands/wg_status.rs b/src/commands/status.rs similarity index 50% rename from src/commands/wg_status.rs rename to src/commands/status.rs index 5e87a60..c8dfc35 100644 --- a/src/commands/wg_status.rs +++ b/src/commands/status.rs @@ -1,13 +1,23 @@ use crate::{Error, COLOR}; +use gamedig::protocols::{ + valve::{ + Engine, GatheringSettings, Response + }, + types::TimeoutSettings, + valve, +}; +use std::{ + str::FromStr, + net::SocketAddr, + time::Duration, + collections::HashMap, + env::var +}; use reqwest::{ Client, header::USER_AGENT }; -use std::{ - collections::HashMap, - env::var -}; use cargo_toml::Manifest; use serde_json::Value; use tokio::join; @@ -16,9 +26,78 @@ lazy_static::lazy_static! { static ref PMS_BASE: String = var("WG_PMS").expect("Expected a \"WG_PMS\" in the envvar but none was found"); } +fn query_server() -> Result { + let server_ip = var("ATS_SERVER_IP").expect("Expected a \"ATS_SERVER_IP\" in the envvar but none was found"); + let addr = SocketAddr::from_str(&server_ip).unwrap(); + let engine = Engine::Source(None); + let gather_settings = GatheringSettings { + players: true, + rules: false, + check_app_id: false + }; + + let read_timeout = Duration::from_secs(2); + let write_timeout = Duration::from_secs(2); + let retries = 1; + let timeout_settings = TimeoutSettings::new( + Some(read_timeout), + Some(write_timeout), + retries + ).unwrap(); + + let response = valve::query( + &addr, + engine, + Some(gather_settings), + Some(timeout_settings) + ); + + Ok(response?) +} + +async fn pms_serverstatus(url: &str) -> Result, Error> { + let bot_version = Manifest::from_path("Cargo.toml").unwrap().package.unwrap().version.unwrap(); + + let client = Client::new(); + let req = client.get(url) + .header(USER_AGENT, format!("Kon/{}/Rust", bot_version)) + .send() + .await?; + let response = req.json::>().await?; + let servers = response["data"].as_array().unwrap()[0]["servers_statuses"]["data"].as_array().unwrap().clone(); + + Ok(servers) +} + +/// Query the server statuses +#[poise::command(slash_command, subcommands("ats", "wg"), subcommand_required)] +pub async fn status(_: poise::Context<'_, (), Error>) -> Result<(), Error> { + Ok(()) +} + +/// Retrieve the server status from ATS +#[poise::command(slash_command)] +pub async fn ats(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> { + match query_server() { + Ok(response) => { + ctx.send(|m| m.embed(|e| + e.color(COLOR) + .title("American Truck Simulator Server Status") + .fields(vec![ + ("Name", format!("{}", response.info.name), true), + ("Players", format!("{}/{}", response.info.players_online, response.info.players_maximum), true) + ]) + )).await?; + } + Err(why) => println!("Error querying the server: {:?}", why) + } + + Ok(()) +} + /// Retrieve the server statuses from Wargaming #[poise::command(slash_command)] -pub async fn wg_status(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> { +pub async fn wg(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> { let pms_asia = &PMS_BASE; let pms_eu = PMS_BASE.replace("asia", "eu"); @@ -53,17 +132,3 @@ pub async fn wg_status(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> Ok(()) } - -async fn pms_serverstatus(url: &str) -> Result, Error> { - let bot_version = Manifest::from_path("Cargo.toml").unwrap().package.unwrap().version.unwrap(); - - let client = Client::new(); - let req = client.get(url) - .header(USER_AGENT, format!("Kon/{}/Rust", bot_version)) - .send() - .await?; - let response = req.json::>().await?; - let servers = response["data"].as_array().unwrap()[0]["servers_statuses"]["data"].as_array().unwrap().clone(); - - Ok(servers) -} diff --git a/src/main.rs b/src/main.rs index 521543b..807b980 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod commands; use poise::serenity_prelude::{self as serenity}; +use std::env::var; type Error = Box; @@ -21,7 +22,7 @@ async fn on_ready( ) )).await?; - let register_commands = std::env::var("REGISTER_CMDS").unwrap_or_else(|_| String::from("true")).parse::().unwrap_or(true); + let register_commands = var("REGISTER_CMDS").unwrap_or_else(|_| String::from("true")).parse::().unwrap_or(true); if register_commands { let builder = poise::builtins::create_application_commands(&framework.options().commands); @@ -31,11 +32,9 @@ async fn on_ready( }).await; match commands { - Ok(cmdmap) => { - for command in cmdmap.iter() { + Ok(cmdmap) => for command in cmdmap.iter() { println!("Registered command globally: {}", command.name); - } - }, + }, Err(why) => println!("Error registering commands: {:?}", why) } } @@ -45,15 +44,14 @@ async fn on_ready( #[tokio::main] async fn main() { - let token = std::env::var("DISCORD_TOKEN").expect("Expected a \"DISCORD_TOKEN\" in the envvar but none was found"); + let token = var("DISCORD_TOKEN").expect("Expected a \"DISCORD_TOKEN\" in the envvar but none was found"); let client = poise::Framework::builder().token(token) - .intents(serenity::GatewayIntents::MESSAGE_CONTENT | serenity::GatewayIntents::GUILDS) + .intents(serenity::GatewayIntents::GUILDS) .options(poise::FrameworkOptions { commands: vec![ commands::ping::ping(), - commands::wg_status::wg_status(), - commands::ats_status::ats_status() + commands::status::status() ], pre_command: |ctx| Box::pin(async move { let get_guild_name = match ctx.guild() {