Add new command for querying ATS server
Some checks failed
Build and push container image / build (push) Has been cancelled

This commit is contained in:
toast 2023-12-29 23:00:44 +11:00
parent a3de6f2635
commit 6e5e6d31fb
8 changed files with 157 additions and 9 deletions

View File

@ -2,4 +2,6 @@
target
.env
.gitignore
docker-compose.yml
renovate.json
run.sh

74
Cargo.lock generated
View File

@ -155,6 +155,16 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[package]]
name = "bzip2-rs"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beeb59e7e4c811ab37cc73680c798c7a5da77fc9989c62b09138e31ee740f735"
dependencies = [
"crc32fast",
"tinyvec",
]
[[package]]
name = "camino"
version = "1.1.6"
@ -550,6 +560,19 @@ dependencies = [
"byteorder",
]
[[package]]
name = "gamedig"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe80214345cf917eff180f20b889a8e951d285b40215501c12eb754142359b"
dependencies = [
"byteorder",
"bzip2-rs",
"crc32fast",
"phf",
"serde_json",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -771,9 +794,10 @@ dependencies = [
[[package]]
name = "kon"
version = "0.1.2"
version = "0.1.3"
dependencies = [
"cargo_toml",
"gamedig",
"lazy_static",
"poise",
"reqwest",
@ -1013,6 +1037,48 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "phf"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_macros",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.13"
@ -1557,6 +1623,12 @@ dependencies = [
"libc",
]
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "skeptic"
version = "0.13.7"

View File

@ -1,6 +1,6 @@
[package]
name = "kon"
version = "0.1.2"
version = "0.1.3"
rust-version = "1.74"
edition = "2021"
@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
cargo_toml = "0.17.2"
gamedig = "0.4.1"
lazy_static = "1.4.0"
poise = "0.5.7"
reqwest = "0.11.23"

View File

@ -1,4 +1,4 @@
FROM rust:1.75-alpine3.18@sha256:fc996ca91d162fe869ca93c1bbc641ef77279c02a9bfead2732f237dd10d16ee AS compiler
FROM rust:1.75-alpine3.19 AS compiler
ENV RUSTFLAGS="-C target-feature=-crt-static"
RUN apk add --no-cache openssl-dev musl-dev
WORKDIR /usr/src/kon

View File

@ -0,0 +1,65 @@
use crate::{Error, COLOR};
use gamedig::protocols::{
valve::{
Engine, GatheringSettings, Response
},
types::TimeoutSettings,
valve,
};
use std::{
str::FromStr,
net::SocketAddr,
time::Duration,
env::var
};
#[allow(dead_code)] // Smh...
fn query_server() -> Result<Response, Error> {
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(())
}

View File

@ -1,2 +1,3 @@
pub mod ping;
pub mod status;
pub mod wg_status;
pub mod ats_status;

View File

@ -1,18 +1,24 @@
use crate::{Error, COLOR};
use reqwest::{
Client,
header::USER_AGENT
};
use std::{
collections::HashMap,
env::var
};
use cargo_toml::Manifest;
use reqwest::{Client, header::USER_AGENT};
use std::collections::HashMap;
use serde_json::Value;
use tokio::join;
lazy_static::lazy_static! {
static ref PMS_BASE: String = std::env::var("WG_PMS").expect("Expected a \"WG_PMS\" in the envvar but none was found");
static ref PMS_BASE: String = var("WG_PMS").expect("Expected a \"WG_PMS\" in the envvar but none was found");
}
/// Retrieve the server statuses from Wargaming
#[poise::command(slash_command)]
pub async fn status(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
pub async fn wg_status(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
let pms_asia = &PMS_BASE;
let pms_eu = PMS_BASE.replace("asia", "eu");

View File

@ -52,7 +52,8 @@ async fn main() {
.options(poise::FrameworkOptions {
commands: vec![
commands::ping::ping(),
commands::status::status()
commands::wg_status::wg_status(),
commands::ats_status::ats_status()
],
pre_command: |ctx| Box::pin(async move {
let get_guild_name = match ctx.guild() {