html terminal
Diffstat (limited to 'src/bot/mod.rs')
-rw-r--r--src/bot/mod.rs85
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![]),
})