html terminal
trace
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/bot/mod.rs | 2 | ||||
| -rw-r--r-- | src/bot/rules.rs | 2 | ||||
| -rw-r--r-- | src/bot/trace.rs | 92 | ||||
| -rw-r--r-- | src/main.rs | 2 |
5 files changed, 96 insertions, 4 deletions
@@ -27,7 +27,6 @@ serenity = { version = "0.12", features = [ "client", "utils", "rustls_backend", - "cache", "gateway", ], default-features = false } poise = { git = "https://github.com/serenity-rs/poise" } @@ -48,7 +47,6 @@ phf = { version = "0.11.2", features = ["macros"] } itertools = "0.11.0" emoji = { git = "https://github.com/Apricot-Conservation-Project/emoji" } serde_derive = "1.0.193" -deser-hjson = "2.2.4" serde_json = "1.0.109" strconv = "0.1.0" diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 592859f..b207868 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -6,6 +6,7 @@ pub mod maps; mod player; mod rules; mod status; +mod trace; mod voting; use crate::webhook::Webhook; @@ -209,6 +210,7 @@ impl Bot { rules::list(), rules::set(), rules::del(), + trace::trace(), start(), end(), help(), diff --git a/src/bot/rules.rs b/src/bot/rules.rs index ddf11ee..ae34acc 100644 --- a/src/bot/rules.rs +++ b/src/bot/rules.rs @@ -198,7 +198,7 @@ pub async fn rules(stdin: &broadcast::Sender<String>) -> tokio::sync::MutexGuard .get_or_init(|| async move { send!(stdin, "rules").unwrap(); let res = get_nextblock().await; - Mutex::new(deser_hjson::from_str(&res).unwrap()) + Mutex::new(serde_json::from_str(&res).unwrap()) }) .await .lock() diff --git a/src/bot/trace.rs b/src/bot/trace.rs new file mode 100644 index 0000000..f514169 --- /dev/null +++ b/src/bot/trace.rs @@ -0,0 +1,92 @@ +use super::{get_nextblock, Context, SUCCESS}; +use anyhow::Result; +use emoji::named::*; +use poise::serenity_prelude::*; +use std::net::Ipv4Addr; + +#[derive(serde_derive::Deserialize)] +struct PlayerInfo { + #[serde(rename = "i")] + id: String, + #[serde(rename = "ln")] + last_name: String, + #[serde(rename = "lp")] + last_ip: Ipv4Addr, + #[serde(rename = "is")] + ips: Vec<Ipv4Addr>, + #[serde(rename = "ns")] + names: Vec<String>, + #[serde(rename = "t")] + times_joined: usize, + #[serde(rename = "a")] + admin: bool, +} + +#[poise::command(slash_command, category = "Info")] +/// trace a player +/// find out all about them +pub async fn trace( + ctx: Context<'_>, + #[autocomplete = "super::player::autocomplete"] player: String, +) -> Result<()> { + super::send_ctx!(ctx, "trace {player}").unwrap(); + let res = get_nextblock().await; + let info = res + .lines() + .filter(|x| !x.is_empty()) + .map(serde_json::from_str::<PlayerInfo>) + .map(Result::unwrap); + let authorized = match ctx { + poise::Context::Application(x) => x + .author_member() + .await + .map(|x| x.roles.clone()) + .unwrap_or(vec![]) + .iter() + .find(|&&x| x == 1133416252791074877) + .is_some(), + _ => unreachable!(), + }; + let mut r = poise::CreateReply::default().ephemeral(authorized); + for found in info { + let mut e = CreateEmbed::new() + .field( + "name", + if found.admin { + format!("{} <{ADMIN}>", found.last_name) + } else { + found.last_name + }, + true, + ) + .field( + "all names used", + found + .names + .into_iter() + .intersperse("|".to_string()) + .fold(String::new(), |acc, x| acc + &x), + true, + ) + .field("has joined", found.times_joined.to_string(), true) + .color(SUCCESS); + if authorized { + e = e + .field("uuid", found.id, true) + .field("last used ip", found.last_ip.to_string(), true) + .field( + "all ips used", + found + .ips + .into_iter() + .map(|x| x.to_string()) + .intersperse("|".to_string()) + .fold(String::new(), |acc, x| acc + &x), + true, + ); + } + r = r.embed(e); + } + poise::send_reply(ctx, r).await?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 8b08b11..a954441 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![feature(lazy_cell, let_chains)] +#![feature(lazy_cell, let_chains, iter_intersperse)] use std::str::FromStr; #[macro_use] mod logging; |