html terminal
Diffstat (limited to 'src/bot/mod.rs')
| -rw-r--r-- | src/bot/mod.rs | 85 |
1 files changed, 81 insertions, 4 deletions
diff --git a/src/bot/mod.rs b/src/bot/mod.rs index eb41fe0..81d259d 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -10,26 +10,37 @@ mod voting; use crate::webhook::Webhook; use anyhow::Result; +use dashmap::DashMap; use maps::Maps; -use poise::serenity_prelude::GuildId; +use poise::serenity_prelude::*; use serenity::http::Http; use serenity::model::channel::Message; -use serenity::prelude::*; use std::fmt::Write; use std::fs::read_to_string; +use std::ops::ControlFlow; use std::sync::{ atomic::{AtomicU8, Ordering}, Arc, OnceLock, }; +use std::time::Duration; use tokio::sync::broadcast; #[derive(Debug)] pub struct Data { + // message -> resp + tracker: Arc<DashMap<MessageId, Message>>, stdin: broadcast::Sender<String>, vote_data: voting::Votes, } +pub struct SMsg { + author: String, + content: String, + channel: ChannelId, + attachments: Vec<Attachment>, +} + static SKIPPING: OnceLock<(Arc<AtomicU8>, broadcast::Sender<String>)> = OnceLock::new(); #[macro_export] @@ -169,7 +180,7 @@ pub async fn safe(m: &Message, c: &serenity::client::Context) -> String { for id in &m.mention_roles { let mention = id.mention().to_string(); - if let Some(role) = id.to_role_cached(&c) { + if let Some(role) = id.to_role_cached(c) { result = result.replace(&mention, &["@", &role.name].concat()); } else { result = result.replace(&mention, "@deleted-role"); @@ -239,13 +250,65 @@ impl Bot { { return Ok(()); } - if schematic::with(new_message, c).await?.is_break() { + if let ControlFlow::Break(m) = schematic::with( + SMsg { + author: new_message + .author_nick(c) + .await + .unwrap_or(new_message.author.name.clone()), + attachments: new_message.attachments.clone(), + content: new_message.content.clone(), + channel: new_message.channel_id, + }, + c, + ) + .await? + { + d.tracker.insert(new_message.id, m); return Ok(()); } if CHANNEL == new_message.channel_id.0 { say(c, new_message, d).await?; } } + poise::Event::MessageUpdate { event, .. } => { + let MessageUpdateEvent { + author: Some(author), + guild_id: Some(guild_id), + content: Some(content), + attachments: Some(attachments), + .. + } = event.clone() + else { + return Ok(()); + }; + if let Some((_, r)) = d.tracker.remove(&event.id) { + r.delete(c).await.unwrap(); + if let ControlFlow::Break(m) = schematic::with( + SMsg { + author: author + .nick_in(c, guild_id) + .await + .unwrap_or(author.name.clone()), + content, + attachments, + channel: event.channel_id, + }, + c, + ) + .await? + { + d.tracker.insert(event.id, m); + } + } + } + poise::Event::MessageDelete { + deleted_message_id, .. + } => { + if let Some((_, r)) = d.tracker.remove(deleted_message_id) { + r.delete(c).await.unwrap(); + } + } _ => {} }; Ok(()) @@ -274,7 +337,21 @@ impl Bot { poise::builtins::register_globally(ctx, &framework.options().commands[18..]) .await?; println!("registered"); + let tracker = Arc::new(DashMap::new()); + let tc = Arc::clone(&tracker); + tokio::spawn(async move { + loop { + // every 10 minutes + tokio::time::sleep(Duration::from_secs(60 * 10)).await; + tc.retain(|_, v: &mut Message| { + // prune messagees older than 3 hours + Timestamp::now().unix_timestamp() - v.timestamp.unix_timestamp() + < 60 * 60 * 3 + }); + } + }); Ok(Data { + tracker, stdin, vote_data: voting::Votes::new(vec![]), }) |