Compare commits

...

11 Commits

8 changed files with 485 additions and 173 deletions

320
Cargo.lock generated
View File

@ -43,9 +43,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.90"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95"
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
[[package]]
name = "arrayvec"
@ -355,6 +355,17 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
]
[[package]]
name = "dotenvy"
version = "0.15.7"
@ -842,6 +853,124 @@ dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
dependencies = [
"displaydoc",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_locid"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
dependencies = [
"displaydoc",
"litemap",
"tinystr",
"writeable",
"zerovec",
]
[[package]]
name = "icu_locid_transform"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
dependencies = [
"displaydoc",
"icu_locid",
"icu_locid_transform_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_locid_transform_data"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
[[package]]
name = "icu_normalizer"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
dependencies = [
"displaydoc",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
"icu_provider",
"smallvec",
"utf16_iter",
"utf8_iter",
"write16",
"zerovec",
]
[[package]]
name = "icu_normalizer_data"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
[[package]]
name = "icu_properties"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
dependencies = [
"displaydoc",
"icu_collections",
"icu_locid_transform",
"icu_properties_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_properties_data"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
[[package]]
name = "icu_provider"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
dependencies = [
"displaydoc",
"icu_locid",
"icu_provider_macros",
"stable_deref_trait",
"tinystr",
"writeable",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_provider_macros"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@ -850,12 +979,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.5.0"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
dependencies = [
"unicode-bidi",
"unicode-normalization",
"idna_adapter",
"smallvec",
"utf8_iter",
]
[[package]]
name = "idna_adapter"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
dependencies = [
"icu_normalizer",
"icu_properties",
]
[[package]]
@ -912,6 +1052,12 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "litemap"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
[[package]]
name = "lock_api"
version = "0.4.12"
@ -1126,14 +1272,14 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "playerbot"
version = "0.5.0"
version = "0.6.1"
dependencies = [
"anyhow",
"dotenvy",
"log",
"poise",
"pretty_env_logger",
"reqwest 0.12.8",
"reqwest 0.12.9",
"serde",
"serde_json",
"tokio",
@ -1337,9 +1483,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.12.8"
version = "0.12.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b"
checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f"
dependencies = [
"base64 0.22.1",
"bytes",
@ -1580,9 +1726,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.210"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
@ -1598,9 +1744,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.210"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",
@ -1736,6 +1882,12 @@ version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "strsim"
version = "0.11.1"
@ -1785,6 +1937,17 @@ dependencies = [
"futures-core",
]
[[package]]
name = "synstructure"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
]
[[package]]
name = "system-configuration"
version = "0.5.1"
@ -1907,25 +2070,20 @@ dependencies = [
]
[[package]]
name = "tinyvec"
version = "1.8.0"
name = "tinystr"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"tinyvec_macros",
"displaydoc",
"zerovec",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.40.0"
version = "1.41.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
dependencies = [
"backtrace",
"bytes",
@ -2139,27 +2297,12 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df"
[[package]]
name = "unicode-bidi"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-normalization"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
dependencies = [
"tinyvec",
]
[[package]]
name = "untrusted"
version = "0.9.0"
@ -2168,9 +2311,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.2"
version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada"
dependencies = [
"form_urlencoded",
"idna",
@ -2184,6 +2327,18 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf16_iter"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
[[package]]
name = "utf8_iter"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "vcpkg"
version = "0.2.15"
@ -2532,6 +2687,42 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "write16"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
[[package]]
name = "writeable"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "yoke"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive",
"zerofrom",
]
[[package]]
name = "yoke-derive"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
"synstructure",
]
[[package]]
name = "zerocopy"
version = "0.7.35"
@ -2553,8 +2744,51 @@ dependencies = [
"syn 2.0.82",
]
[[package]]
name = "zerofrom"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
"synstructure",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]]
name = "zerovec"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
dependencies = [
"yoke",
"zerofrom",
"zerovec-derive",
]
[[package]]
name = "zerovec-derive"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.82",
]

View File

@ -1,16 +1,16 @@
[package]
name = "playerbot"
version = "0.5.0"
version = "0.6.1"
edition = "2021"
[dependencies]
anyhow = "1.0.90"
anyhow = "1.0.93"
dotenvy = "0.15.7"
log = "0.4.22"
poise = "0.6.1"
pretty_env_logger = "0.5.0"
reqwest = {version = "0.12.8", features = ["json"]}
serde = {version = "1.0.210", features = ["derive", "serde_derive"]}
reqwest = {version = "0.12.9", features = ["json"]}
serde = {version = "1.0.215", features = ["derive", "serde_derive"]}
serde_json = {version = "1.0.132", features = []}
tokio = {version = "1.40.0", features = ["full"]}
url = "2.5.2"
tokio = {version = "1.41.1", features = ["full"]}
url = "2.5.3"

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Playerbot
Using Tokio to run two futures simultaneously, I put together two discord bots which each update their statuses/presences with information about a corresponding game server.

View File

@ -6,7 +6,11 @@ pub fn set_presence(ctx: &poise::serenity_prelude::Context, status: ServerRespon
ctx.set_presence(
Some(ActivityData::custom(match status.online() {
true => {
format!("{}/{} players online", status.players(), status.max())
format!(
"{}/{} players online",
status.players().unwrap(),
status.max().unwrap()
)
}
false => "Server offline!".to_string(),
})),
@ -18,4 +22,4 @@ pub fn set_presence(ctx: &poise::serenity_prelude::Context, status: ServerRespon
false => OnlineStatus::DoNotDisturb,
},
);
}
}

View File

@ -1,9 +1,12 @@
mod funcs;
mod minecraft;
mod scpsl;
mod types;
mod funcs;
use tokio::join;
use dotenvy::{self, dotenv};
use minecraft::Minecraft;
use scpsl::Scpsl;
use tokio::join;
use url::{self, Url};
#[macro_use]
extern crate log;
@ -12,5 +15,20 @@ extern crate log;
async fn main() {
dotenv().ok();
pretty_env_logger::init();
join!(scpsl::run(), minecraft::run());
let gamerzone = Minecraft::new(
Url::try_from("https://api.mcstatus.io/v2/status/java/bleat.shibedrill.site").unwrap(),
std::env::var("TOKEN_BOT_MC_BLEAT").unwrap(),
"DeersCord SMP".into(),
);
let mchprs = Minecraft::new(
Url::try_from("https://api.mcstatus.io/v2/status/java/mchprs.shibedrill.site").unwrap(),
std::env::var("TOKEN_BOT_MC_MCHPRS").unwrap(),
"Project MCRV".into(),
);
let scpsl = Scpsl::new(
Url::try_from("https://api.scplist.kr/api/servers/81460").unwrap(),
std::env::var("TOKEN_BOT_SCPSL").unwrap(),
"SCP:SL".into(),
);
join!(scpsl.run(), mchprs.run(), gamerzone.run());
}

View File

@ -1,40 +1,89 @@
use poise::serenity_prelude as serenity;
use reqwest::{Client, Request};
use serenity::*;
use url::Url;
use crate::{funcs, types::ServerResponse};
#[derive(serde::Deserialize)]
#[derive(serde::Deserialize, Debug)]
struct ServerSummary {
online: bool,
players: Option<Players>,
}
#[derive(serde::Deserialize)]
#[derive(serde::Deserialize, Debug)]
struct Players {
online: i32,
max: i32,
}
pub struct Data {}
pub struct Data {
controller: Minecraft,
}
async fn get_status() -> Result<ServerResponse, anyhow::Error> {
let http_client = Client::new();
let request = Request::new(
reqwest::Method::GET,
"https://api.mcstatus.io/v2/status/java/gamer.shibedrill.site"
.try_into()?,
);
let response = http_client.execute(request).await?;
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
if let Some(players) = data.players {
Ok(ServerResponse::new(
data.online,
players.online as u32,
players.max as u32,
))
} else {
Ok(ServerResponse::new(data.online, 0, 0))
#[derive(Clone)]
pub struct Minecraft {
url: Url,
token: String,
name: String,
}
impl Minecraft {
pub fn new(url: Url, token: String, name: String) -> Self {
Self { url, token, name }
}
pub async fn get_status(&self) -> Result<ServerResponse, anyhow::Error> {
let http_client = Client::new();
trace!("Created HTTP client");
let request = Request::new(reqwest::Method::GET, self.url.clone());
trace!("Created HTTP request");
let response = http_client.execute(request).await?;
trace!("Ran request using client");
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
trace!("Response JSON for {}: {:#?}", self.name, data); // this
if let Some(players) = data.players {
Ok(ServerResponse::new(
data.online,
Some(players.online as u32),
Some(players.max as u32),
))
} else {
Ok(ServerResponse::new(data.online, None, None))
}
}
pub async fn run(&self) {
let controller = self.clone();
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
event_handler: |ctx, event, framework, data| {
Box::pin(event_handler(ctx, event, framework, data))
},
..Default::default()
})
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
Ok(Data { controller })
})
})
.build();
info!("Built framework successfully.");
let mut discord_client = ClientBuilder::new(
self.token.clone(),
serenity::GatewayIntents::non_privileged(),
)
.framework(framework)
.activity(ActivityData::custom("Waiting on initial status..."))
.await
.inspect_err(|e| error!("Failed to start client: {}", e))
.unwrap();
info!("Built client successfully.");
let _ = discord_client.start().await;
}
}
@ -42,52 +91,28 @@ pub async fn event_handler(
ctx: &serenity::Context,
event: &serenity::FullEvent,
_framework: poise::FrameworkContext<'_, Data, Error>,
_data: &Data,
data: &Data,
) -> Result<(), Error> {
match event {
serenity::FullEvent::Ready {
data_about_bot: _data,
data_about_bot: _bot_data,
} => loop {
let status = get_status()
trace!("Running loop routine");
let status = data
.controller
.get_status()
.await
.inspect_err(|e| error!("Failed to get status: {}", e))
.inspect_err(|e| error!("{}: Failed to get status: {}", data.controller.name, e))
.unwrap();
info!("Got status: {}", status.to_string());
info!(
"{}: Got status: {}",
data.controller.name,
status.to_string()
);
funcs::set_presence(&ctx, status);
funcs::set_presence(ctx, status);
tokio::time::sleep(std::time::Duration::from_secs(30)).await;
},
_ => Ok(()),
}
}
pub async fn run() {
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
event_handler: |ctx, event, framework, data| {
Box::pin(event_handler(ctx, event, framework, data))
},
..Default::default()
})
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
Ok(Data {})
})
})
.build();
info!("Built framework successfully.");
let mut discord_client = ClientBuilder::new(
std::env::var("MINECRAFT_BOT_TOKEN").inspect_err(|e| {error!("Failed to get token: {}", e)}).unwrap(),
serenity::GatewayIntents::non_privileged(),
)
.framework(framework)
.activity(ActivityData::custom("Waiting on initial status..."))
.await
.inspect_err(|e| error!("Failed to start client: {}", e))
.unwrap();
info!("Built client successfully.");
let _ = discord_client.start().await;
}

View File

@ -1,54 +1,110 @@
use crate::{funcs, types::ServerResponse};
use poise::serenity_prelude as serenity;
use reqwest::{Client, Request};
use serenity::*;
use url::Url;
#[derive(serde::Deserialize)]
#[derive(serde::Deserialize, Debug)]
#[allow(non_snake_case)]
struct ServerSummary {
online: bool,
players: String,
}
pub struct Data {}
pub struct Data {
controller: Scpsl,
}
async fn get_status() -> Result<ServerResponse, anyhow::Error> {
let http_client = Client::new();
let request = Request::new(
reqwest::Method::GET,
url::Url::try_from("https://api.scplist.kr/api/servers/81460")?,
);
let response = http_client.execute(request).await?;
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
#[derive(Clone)]
pub struct Scpsl {
name: String,
url: Url,
token: String,
}
let playercount: Result<Vec<u32>, _> =
data.players.split('/').map(|x| x.parse::<u32>()).collect();
impl Scpsl {
pub fn new(url: Url, token: String, name: String) -> Self {
Self { url, token, name }
}
async fn get_status(&self) -> Result<ServerResponse, anyhow::Error> {
let http_client = Client::new();
trace!("Created HTTP client");
let request = Request::new(reqwest::Method::GET, self.url.clone());
trace!("Created HTTP request");
let response = http_client.execute(request).await?;
trace!("Ran request using client");
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
let playercount_unwrapped = playercount?;
trace!("Response JSON for {}: {:#?}", self.name, data); // this is the only thing I added.
Ok(ServerResponse::new(
data.online,
playercount_unwrapped[0],
playercount_unwrapped[1],
))
let playercount: Result<Vec<u32>, _> =
data.players.split('/').map(|x| x.parse::<u32>()).collect();
let playercount_unwrapped = playercount?;
Ok(ServerResponse::new(
data.online,
playercount_unwrapped.first().copied(),
playercount_unwrapped.get(1).copied(),
))
}
pub async fn run(&self) {
let controller = self.clone();
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
initialize_owners: true,
event_handler: |ctx, event, framework, data| {
Box::pin(event_handler(ctx, event, framework, data))
},
..Default::default()
})
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
Ok(Data { controller })
})
})
.build();
info!("Built framework successfully.");
let mut discord_client = ClientBuilder::new(
self.token.clone(),
serenity::GatewayIntents::non_privileged(),
)
.framework(framework)
.activity(ActivityData::custom("Waiting on initial status..."))
.await
.inspect_err(|e| error!("Failed to start client: {}", e))
.unwrap();
info!("Built client successfully.");
let _ = discord_client.start().await;
}
}
pub async fn event_handler(
ctx: &serenity::Context,
event: &serenity::FullEvent,
_framework: poise::FrameworkContext<'_, Data, Error>,
_data: &Data,
data: &Data,
) -> Result<(), Error> {
match event {
serenity::FullEvent::Ready {
data_about_bot: _data,
} => loop {
let status = get_status()
trace!("Running loop routine");
let status = data
.controller
.get_status()
.await
.inspect_err(|e| error!("Failed to get status: {}", e))
.inspect_err(|e| error!("{}: Failed to get status: {}", data.controller.name, e))
.unwrap();
info!("Got status: {}", status.to_string());
info!(
"{}: Got status: {}",
data.controller.name,
status.to_string()
);
funcs::set_presence(ctx, status);
tokio::time::sleep(std::time::Duration::from_secs(30)).await;
@ -56,35 +112,3 @@ pub async fn event_handler(
_ => Ok(()),
}
}
pub async fn run() {
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
initialize_owners: true,
event_handler: |ctx, event, framework, data| {
Box::pin(event_handler(ctx, event, framework, data))
},
..Default::default()
})
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
Ok(Data {})
})
})
.build();
info!("Built framework successfully.");
let mut discord_client = ClientBuilder::new(
std::env::var("SCPSL_BOT_TOKEN").inspect_err(|e| {error!("Failed to get token: {}", e)}).unwrap(),
serenity::GatewayIntents::non_privileged(),
)
.framework(framework)
.activity(ActivityData::custom("Waiting on initial status..."))
.await
.inspect_err(|e| error!("Failed to start client: {}", e))
.unwrap();
info!("Built client successfully.");
let _ = discord_client.start().await;
}

View File

@ -1,11 +1,11 @@
pub struct ServerResponse {
online: bool,
players: u32,
max: u32,
players: Option<u32>,
max: Option<u32>,
}
impl ServerResponse {
pub fn new(online: bool, players: u32, max: u32) -> Self {
pub fn new(online: bool, players: Option<u32>, max: Option<u32>) -> Self {
ServerResponse {
online,
players,
@ -17,19 +17,23 @@ impl ServerResponse {
self.online
}
pub fn players(&self) -> u32 {
pub fn players(&self) -> Option<u32> {
self.players
}
pub fn max(&self) -> u32 {
pub fn max(&self) -> Option<u32> {
self.max
}
pub fn is_full(&self) -> bool {
self.players == self.max
self.players >= self.max
}
pub fn to_string(&self) -> String {
format!("{}/{} ({})", self.players, self.max, self.online)
if let (Some(players), Some(max)) = (self.players, self.max) {
format!("{}/{} ({})", players, max, self.online)
} else {
format!("N/A ({})", self.online)
}
}
}