Start of history after removing tokens
This commit is contained in:
commit
f3021fa860
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
.env
|
2560
Cargo.lock
generated
Normal file
2560
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "playerbot"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.90"
|
||||
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"]}
|
||||
serde_json = {version = "1.0.132", features = []}
|
||||
tokio = {version = "1.40.0", features = ["full"]}
|
||||
url = "2.5.2"
|
21
src/funcs.rs
Normal file
21
src/funcs.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use poise::serenity_prelude::{ActivityData, OnlineStatus};
|
||||
|
||||
use crate::types::ServerResponse;
|
||||
|
||||
pub fn set_presence(ctx: &poise::serenity_prelude::Context, status: ServerResponse) {
|
||||
ctx.set_presence(
|
||||
Some(ActivityData::custom(match status.online() {
|
||||
true => {
|
||||
format!("{}/{} players online", status.players(), status.max())
|
||||
}
|
||||
false => "Server offline!".to_string(),
|
||||
})),
|
||||
match status.online() {
|
||||
true => match status.is_full() {
|
||||
true => OnlineStatus::Idle,
|
||||
false => OnlineStatus::Online,
|
||||
},
|
||||
false => OnlineStatus::DoNotDisturb,
|
||||
},
|
||||
);
|
||||
}
|
16
src/main.rs
Normal file
16
src/main.rs
Normal file
@ -0,0 +1,16 @@
|
||||
mod minecraft;
|
||||
mod scpsl;
|
||||
mod types;
|
||||
mod funcs;
|
||||
use tokio::join;
|
||||
use dotenvy::{self, dotenv};
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
dotenv().ok();
|
||||
pretty_env_logger::init();
|
||||
join!(scpsl::run(), minecraft::run());
|
||||
}
|
93
src/minecraft.rs
Normal file
93
src/minecraft.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use poise::serenity_prelude as serenity;
|
||||
use reqwest::{Client, Request};
|
||||
use serenity::*;
|
||||
|
||||
use crate::{funcs, types::ServerResponse};
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct ServerSummary {
|
||||
online: bool,
|
||||
players: Option<Players>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Players {
|
||||
online: i32,
|
||||
max: i32,
|
||||
}
|
||||
|
||||
pub struct Data {}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn event_handler(
|
||||
ctx: &serenity::Context,
|
||||
event: &serenity::FullEvent,
|
||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||
_data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
match event {
|
||||
serenity::FullEvent::Ready {
|
||||
data_about_bot: _data,
|
||||
} => loop {
|
||||
let status = get_status()
|
||||
.await
|
||||
.inspect_err(|e| error!("Failed to get status: {}", e))
|
||||
.unwrap();
|
||||
info!("Got status: {}", status.to_string());
|
||||
|
||||
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;
|
||||
}
|
90
src/scpsl.rs
Normal file
90
src/scpsl.rs
Normal file
@ -0,0 +1,90 @@
|
||||
|
||||
use crate::{funcs, types::ServerResponse};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use reqwest::{Client, Request};
|
||||
use serenity::*;
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[allow(non_snake_case)]
|
||||
struct ServerSummary {
|
||||
online: bool,
|
||||
players: String,
|
||||
}
|
||||
|
||||
pub struct Data {}
|
||||
|
||||
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?)?;
|
||||
|
||||
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[0],
|
||||
playercount_unwrapped[1],
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn event_handler(
|
||||
ctx: &serenity::Context,
|
||||
event: &serenity::FullEvent,
|
||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||
_data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
match event {
|
||||
serenity::FullEvent::Ready {
|
||||
data_about_bot: _data,
|
||||
} => loop {
|
||||
let status = get_status()
|
||||
.await
|
||||
.inspect_err(|e| error!("Failed to get status: {}", e))
|
||||
.unwrap();
|
||||
info!("Got status: {}", status.to_string());
|
||||
|
||||
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 {
|
||||
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;
|
||||
}
|
35
src/types.rs
Normal file
35
src/types.rs
Normal file
@ -0,0 +1,35 @@
|
||||
pub struct ServerResponse {
|
||||
online: bool,
|
||||
players: u32,
|
||||
max: u32,
|
||||
}
|
||||
|
||||
impl ServerResponse {
|
||||
pub fn new(online: bool, players: u32, max: u32) -> Self {
|
||||
ServerResponse {
|
||||
online,
|
||||
players,
|
||||
max,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn online(&self) -> bool {
|
||||
self.online
|
||||
}
|
||||
|
||||
pub fn players(&self) -> u32 {
|
||||
self.players
|
||||
}
|
||||
|
||||
pub fn max(&self) -> u32 {
|
||||
self.max
|
||||
}
|
||||
|
||||
pub fn is_full(&self) -> bool {
|
||||
self.players == self.max
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
format!("{}/{} ({})", self.players, self.max, self.online)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user