make things into types
This commit is contained in:
parent
00f8253ee1
commit
b04157e4ae
@ -6,7 +6,11 @@ pub fn set_presence(ctx: &poise::serenity_prelude::Context, status: ServerRespon
|
|||||||
ctx.set_presence(
|
ctx.set_presence(
|
||||||
Some(ActivityData::custom(match status.online() {
|
Some(ActivityData::custom(match status.online() {
|
||||||
true => {
|
true => {
|
||||||
format!("{}/{} players online", status.players(), status.max())
|
format!(
|
||||||
|
"{}/{} players online",
|
||||||
|
status.players().unwrap(),
|
||||||
|
status.max().unwrap()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
false => "Server offline!".to_string(),
|
false => "Server offline!".to_string(),
|
||||||
})),
|
})),
|
||||||
@ -18,4 +22,4 @@ pub fn set_presence(ctx: &poise::serenity_prelude::Context, status: ServerRespon
|
|||||||
false => OnlineStatus::DoNotDisturb,
|
false => OnlineStatus::DoNotDisturb,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
21
src/main.rs
21
src/main.rs
@ -1,9 +1,12 @@
|
|||||||
|
mod funcs;
|
||||||
mod minecraft;
|
mod minecraft;
|
||||||
mod scpsl;
|
mod scpsl;
|
||||||
mod types;
|
mod types;
|
||||||
mod funcs;
|
|
||||||
use tokio::join;
|
|
||||||
use dotenvy::{self, dotenv};
|
use dotenvy::{self, dotenv};
|
||||||
|
use minecraft::Minecraft;
|
||||||
|
use scpsl::SCPSL;
|
||||||
|
use tokio::join;
|
||||||
|
use url::{self, Url};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
@ -12,5 +15,17 @@ extern crate log;
|
|||||||
async fn main() {
|
async fn main() {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
join!(scpsl::run(), minecraft::run());
|
let gamerzone = Minecraft::new(
|
||||||
|
Url::try_from("https://api.mcstatus.io/v2/status/java/gamer.shibedrill.site").unwrap(),
|
||||||
|
std::env::var("TOKEN_BOT_MC_GAMER").unwrap(),
|
||||||
|
);
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
let scpsl = SCPSL::new(
|
||||||
|
Url::try_from("https://api.scplist.kr/api/servers/81460").unwrap(),
|
||||||
|
std::env::var("TOKEN_BOT_SCPSL").unwrap(),
|
||||||
|
);
|
||||||
|
join!(scpsl.run(), mchprs.run(), gamerzone.run());
|
||||||
}
|
}
|
||||||
|
117
src/minecraft.rs
117
src/minecraft.rs
@ -1,6 +1,7 @@
|
|||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use reqwest::{Client, Request};
|
use reqwest::{Client, Request};
|
||||||
use serenity::*;
|
use serenity::*;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{funcs, types::ServerResponse};
|
use crate::{funcs, types::ServerResponse};
|
||||||
|
|
||||||
@ -16,25 +17,66 @@ struct Players {
|
|||||||
max: i32,
|
max: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Data {}
|
pub struct Data {
|
||||||
|
controller: Minecraft,
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_status() -> Result<ServerResponse, anyhow::Error> {
|
#[derive(Clone)]
|
||||||
let http_client = Client::new();
|
pub struct Minecraft {
|
||||||
let request = Request::new(
|
url: Url,
|
||||||
reqwest::Method::GET,
|
token: String,
|
||||||
"https://api.mcstatus.io/v2/status/java/gamer.shibedrill.site"
|
}
|
||||||
.try_into()?,
|
|
||||||
);
|
impl Minecraft {
|
||||||
let response = http_client.execute(request).await?;
|
pub fn new(url: Url, token: String) -> Self {
|
||||||
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
|
Self { url, token }
|
||||||
if let Some(players) = data.players {
|
}
|
||||||
Ok(ServerResponse::new(
|
|
||||||
data.online,
|
pub async fn get_status(&self) -> Result<ServerResponse, anyhow::Error> {
|
||||||
players.online as u32,
|
let http_client = Client::new();
|
||||||
players.max as u32,
|
let request = Request::new(reqwest::Method::GET, self.url.clone());
|
||||||
))
|
let response = http_client.execute(request).await?;
|
||||||
} else {
|
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
|
||||||
Ok(ServerResponse::new(data.online, 0, 0))
|
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,13 +84,15 @@ pub async fn event_handler(
|
|||||||
ctx: &serenity::Context,
|
ctx: &serenity::Context,
|
||||||
event: &serenity::FullEvent,
|
event: &serenity::FullEvent,
|
||||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||||
_data: &Data,
|
data: &Data,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match event {
|
match event {
|
||||||
serenity::FullEvent::Ready {
|
serenity::FullEvent::Ready {
|
||||||
data_about_bot: _data,
|
data_about_bot: _bot_data,
|
||||||
} => loop {
|
} => loop {
|
||||||
let status = get_status()
|
let status = data
|
||||||
|
.controller
|
||||||
|
.get_status()
|
||||||
.await
|
.await
|
||||||
.inspect_err(|e| error!("Failed to get status: {}", e))
|
.inspect_err(|e| error!("Failed to get status: {}", e))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -60,34 +104,3 @@ pub async fn event_handler(
|
|||||||
_ => Ok(()),
|
_ => 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;
|
|
||||||
}
|
|
||||||
|
117
src/scpsl.rs
117
src/scpsl.rs
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
use crate::{funcs, types::ServerResponse};
|
use crate::{funcs, types::ServerResponse};
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use reqwest::{Client, Request};
|
use reqwest::{Client, Request};
|
||||||
use serenity::*;
|
use serenity::*;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
@ -11,40 +11,85 @@ struct ServerSummary {
|
|||||||
players: String,
|
players: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Data {}
|
pub struct Data {
|
||||||
|
controller: SCPSL,
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_status() -> Result<ServerResponse, anyhow::Error> {
|
#[derive(Clone)]
|
||||||
let http_client = Client::new();
|
pub struct SCPSL {
|
||||||
let request = Request::new(
|
url: Url,
|
||||||
reqwest::Method::GET,
|
token: String,
|
||||||
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?)?;
|
|
||||||
|
|
||||||
let playercount: Result<Vec<u32>, _> =
|
impl SCPSL {
|
||||||
data.players.split('/').map(|x| x.parse::<u32>()).collect();
|
pub fn new(url: Url, token: String) -> Self {
|
||||||
|
Self { url, token }
|
||||||
|
}
|
||||||
|
async fn get_status(&self) -> Result<ServerResponse, anyhow::Error> {
|
||||||
|
let http_client = Client::new();
|
||||||
|
let request = Request::new(reqwest::Method::GET, self.url.clone());
|
||||||
|
let response = http_client.execute(request).await?;
|
||||||
|
let data: ServerSummary = serde_json::from_str(&response.text().await?)?;
|
||||||
|
|
||||||
let playercount_unwrapped = playercount?;
|
let playercount: Result<Vec<u32>, _> =
|
||||||
|
data.players.split('/').map(|x| x.parse::<u32>()).collect();
|
||||||
|
|
||||||
Ok(ServerResponse::new(
|
let playercount_unwrapped = playercount?;
|
||||||
data.online,
|
|
||||||
playercount_unwrapped[0],
|
Ok(ServerResponse::new(
|
||||||
playercount_unwrapped[1],
|
data.online,
|
||||||
))
|
playercount_unwrapped.get(0).map(|u| u.clone()),
|
||||||
|
playercount_unwrapped.get(1).map(|u| u.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
pub async fn event_handler(
|
||||||
ctx: &serenity::Context,
|
ctx: &serenity::Context,
|
||||||
event: &serenity::FullEvent,
|
event: &serenity::FullEvent,
|
||||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||||
_data: &Data,
|
data: &Data,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match event {
|
match event {
|
||||||
serenity::FullEvent::Ready {
|
serenity::FullEvent::Ready {
|
||||||
data_about_bot: _data,
|
data_about_bot: _data,
|
||||||
} => loop {
|
} => loop {
|
||||||
let status = get_status()
|
let status = data
|
||||||
|
.controller
|
||||||
|
.get_status()
|
||||||
.await
|
.await
|
||||||
.inspect_err(|e| error!("Failed to get status: {}", e))
|
.inspect_err(|e| error!("Failed to get status: {}", e))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -56,35 +101,3 @@ pub async fn event_handler(
|
|||||||
_ => Ok(()),
|
_ => 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;
|
|
||||||
}
|
|
||||||
|
16
src/types.rs
16
src/types.rs
@ -1,11 +1,11 @@
|
|||||||
pub struct ServerResponse {
|
pub struct ServerResponse {
|
||||||
online: bool,
|
online: bool,
|
||||||
players: u32,
|
players: Option<u32>,
|
||||||
max: u32,
|
max: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerResponse {
|
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 {
|
ServerResponse {
|
||||||
online,
|
online,
|
||||||
players,
|
players,
|
||||||
@ -17,11 +17,11 @@ impl ServerResponse {
|
|||||||
self.online
|
self.online
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn players(&self) -> u32 {
|
pub fn players(&self) -> Option<u32> {
|
||||||
self.players
|
self.players
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max(&self) -> u32 {
|
pub fn max(&self) -> Option<u32> {
|
||||||
self.max
|
self.max
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +30,10 @@ impl ServerResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string(&self) -> String {
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user