use crate::common::set_roles::normal::get_server_member_bulk; use crate::Config; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use serenity::model::id::GuildId; use sqlx::sqlite::SqliteRow; use sqlx::{Error, FromRow, Pool, Row, Sqlite}; #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Minecraft { pub discord: GuildId, pub minecraft: String, } impl<'r> FromRow<'r, SqliteRow> for Minecraft { fn from_row(row: &'r SqliteRow) -> Result { let server_tmp: i64 = row.try_get("server_discord")?; let discord = GuildId::from(server_tmp as u64); Ok(Self { discord, minecraft: row.try_get("server_minecraft")?, }) } } /** loop through all members of server get a list of folks with mc accounts that are members and a list that arent members */ pub async fn update_server(server_id: &str, db: &Pool, g_id: &GuildId, config: &Config) { let mut usernames = vec![]; for member in get_server_member_bulk(db, g_id).await { if let Some(x) = member.minecraft { usernames.push((x, true)); } if let Some(x) = member.minecraft_uid { usernames.push((x, false)); } } if !usernames.is_empty() { whitelist_update(&usernames, server_id, &config.discord_token_minecraft).await; } } pub async fn post(url: &str, bearer: &str, data: &T) { match surf::post(url) .header("Authorization", bearer) .header("Content-Type", "application/json") .header("Accept", "Application/vnd.pterodactyl.v1+json") .body_json(&data) { Ok(req) => { req.await.ok(); } Err(e) => { dbg!(e); } } } #[derive(Deserialize, Serialize, Debug)] pub struct ServerDetailsResSub { pub identifier: String, pub name: String, pub description: String, pub is_suspended: bool, } #[derive(Deserialize, Serialize, Debug)] pub struct ServerDetailsRes { pub attributes: ServerDetailsResSub, } async fn get(url: &str, bearer: &str) -> Option { match surf::get(url) .header("Authorization", bearer) .header("Content-Type", "application/json") .header("Accept", "Application/vnd.pterodactyl.v1+json") .recv_json() .await { Ok(res) => Some(res), Err(e) => { dbg!(e); None } } } #[derive(Deserialize, Serialize, Debug)] struct BodyCommand { command: String, } #[derive(Deserialize, Serialize, Debug)] struct BodyDelete { root: String, files: Vec, } pub async fn whitelist_wipe(server: &str, token: &str) { let url_base = format!("https://panel.games.skynet.ie/api/client/servers/{server}"); let bearer = format!("Bearer {token}"); // delete whitelist let deletion = BodyDelete { root: "/".to_string(), files: vec!["whitelist.json".to_string()], }; post(&format!("{url_base}/files/delete"), &bearer, &deletion).await; // recreate teh file, passing in the type here so the compiler knows what type of vec it is post::>(&format!("{url_base}/files/write?file=%2Fwhitelist.json"), &bearer, &vec![]).await; // reload the whitelist let data = BodyCommand { command: "whitelist reload".to_string(), }; post(&format!("{url_base}/command"), &bearer, &data).await; } pub async fn server_information(server: &str, token: &str) -> Option { let url_base = format!("https://panel.games.skynet.ie/api/client/servers/{server}"); let bearer = format!("Bearer {token}"); get::(&format!("{url_base}/"), &bearer).await } pub async fn get_minecraft_config(db: &Pool) -> Vec { sqlx::query_as::<_, Minecraft>( r#" SELECT * FROM minecraft "#, ) .fetch_all(db) .await .unwrap_or_default() } pub async fn get_minecraft_config_server(db: &Pool, g_id: GuildId) -> Vec { sqlx::query_as::<_, Minecraft>( r#" SELECT * FROM minecraft WHERE server_discord = ?1 "#, ) .bind(g_id.get() as i64) .fetch_all(db) .await .unwrap_or_default() } pub async fn whitelist_update(add: &Vec<(String, bool)>, server: &str, token: &str) { println!("Update whitelist for {}", server); let url_base = format!("https://panel.games.skynet.ie/api/client/servers/{server}"); let bearer = format!("Bearer {token}"); for (name, java) in add { let data = if *java { BodyCommand { command: format!("whitelist add {name}"), } } else { BodyCommand { command: format!("fwhitelist add {name}"), } }; post(&format!("{url_base}/command"), &bearer, &data).await; } }