From 847634e9434352e17e60d0ac8cea5f79762b9e0c Mon Sep 17 00:00:00 2001 From: CircuitSacul Date: Wed, 3 Aug 2022 12:10:44 -0400 Subject: [PATCH] skip handling reactions for non-vote emojis (#30) * skip handling reactions for non-vote emojis * fix logic to work for overrides * fix typo * update cache for relevant commands --- sqlx-data.json | 50 +++++++++++++++++++ src/cache/cache.rs | 3 +- src/core/starboard/config.rs | 38 +++++++++++++- src/core/starboard/reaction_events.rs | 7 ++- src/database/models/starboard_override.rs | 13 +++++ .../commands/chat/starboard/create.rs | 4 ++ .../commands/chat/starboard/delete.rs | 4 ++ .../chat/starboard/edit/requirements.rs | 12 +++++ 8 files changed, 128 insertions(+), 3 deletions(-) diff --git a/sqlx-data.json b/sqlx-data.json index fafda330..9364b351 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -2334,6 +2334,56 @@ }, "query": "INSERT INTO permrole_starboards\n (permrole_id, starboard_id)\n VALUES ($1, $2)\n RETURNING *" }, + "e0d3435ac460506de5e62af8dea8bf9151a123a5e958a706241e15206499076c": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int4" + }, + { + "name": "guild_id", + "ordinal": 1, + "type_info": "Int8" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "starboard_id", + "ordinal": 3, + "type_info": "Int4" + }, + { + "name": "channel_ids", + "ordinal": 4, + "type_info": "Int8Array" + }, + { + "name": "overrides", + "ordinal": 5, + "type_info": "Json" + } + ], + "nullable": [ + false, + false, + false, + false, + false, + false + ], + "parameters": { + "Left": [ + "Int4" + ] + } + }, + "query": "SELECT * FROM overrides WHERE starboard_id=$1" + }, "e605d15eeb3e0939bc83e98b98b9ac9814bf2f0983ebdc30c235d8b530bf0ada": { "describe": { "columns": [ diff --git a/src/cache/cache.rs b/src/cache/cache.rs index 6be56779..cc474a6f 100644 --- a/src/cache/cache.rs +++ b/src/cache/cache.rs @@ -32,6 +32,7 @@ pub struct Cache { // database side pub autostar_channel_ids: AsyncDashSet>, + pub guild_vote_emojis: AsyncDashMap>, // autocomplete pub guild_autostar_channel_names: stretto::AsyncCache, Vec>, @@ -50,6 +51,7 @@ impl Cache { ) .unwrap(), autostar_channel_ids: autostar_channel_ids.into(), + guild_vote_emojis: DashMap::new().into(), guild_autostar_channel_names: stretto::AsyncCache::new( (constants::MAX_NAMES * 10).try_into().unwrap(), constants::MAX_NAMES.into(), @@ -95,7 +97,6 @@ impl Cache { }) } - // "fetch or get" methods pub async fn fog_message( &self, bot: &StarboardBot, diff --git a/src/core/starboard/config.rs b/src/core/starboard/config.rs index 1aad1764..0d2567df 100644 --- a/src/core/starboard/config.rs +++ b/src/core/starboard/config.rs @@ -9,7 +9,7 @@ use crate::{ helpers::settings::overrides::call_with_override_settings, Starboard, StarboardOverride, StarboardSettings, }, - errors::StarboardError, + errors::{StarboardError, StarboardResult}, unwrap_id, }; @@ -68,4 +68,40 @@ impl StarboardConfig { Ok(configs) } + + pub async fn is_guild_vote_emoji( + bot: &StarboardBot, + guild_id: i64, + emoji_raw: &String, + ) -> StarboardResult { + if let Some(is_vote_emoji) = bot.cache.guild_vote_emojis.with(&guild_id, |_, emojis| { + emojis.as_ref().map(|emojis| emojis.contains(emoji_raw)) + }) { + Ok(is_vote_emoji) + } else { + let mut emojis = Vec::new(); + let starboards = Starboard::list_by_guild(&bot.pool, guild_id).await?; + for sb in starboards { + emojis.extend(sb.settings.upvote_emojis); + emojis.extend(sb.settings.downvote_emojis); + + let configs = StarboardOverride::list_by_starboard(&bot.pool, sb.id).await?; + for c in configs { + let ov = c.get_overrides()?; + if let Some(upvote_emojis) = ov.upvote_emojis { + emojis.extend(upvote_emojis); + } + if let Some(downvote_emojis) = ov.downvote_emojis { + emojis.extend(downvote_emojis); + } + } + } + + let is_vote_emoji = emojis.contains(emoji_raw); + // cache the value + bot.cache.guild_vote_emojis.insert(guild_id, emojis); + + Ok(is_vote_emoji) + } + } } diff --git a/src/core/starboard/reaction_events.rs b/src/core/starboard/reaction_events.rs index 742334ed..427a4a9d 100644 --- a/src/core/starboard/reaction_events.rs +++ b/src/core/starboard/reaction_events.rs @@ -30,6 +30,12 @@ pub async fn handle_reaction_add( return Ok(()); } + let emoji = SimpleEmoji::from(event.emoji.clone()); + + if !StarboardConfig::is_guild_vote_emoji(bot, unwrap_id!(guild_id), &emoji.raw).await? { + return Ok(()); + } + let orig_msg = Message::get_original(&bot.pool, unwrap_id!(event.message_id)).await?; let orig_msg = match orig_msg { None => { @@ -84,7 +90,6 @@ pub async fn handle_reaction_add( Some(msg) => msg, }; - let emoji = SimpleEmoji::from(event.emoji.clone()); let configs = StarboardConfig::list_for_channel(bot, guild_id, event.channel_id).await?; let status = VoteStatus::get_vote_status(bot, &emoji, configs, event.message_id, event.channel_id).await; diff --git a/src/database/models/starboard_override.rs b/src/database/models/starboard_override.rs index 6cf825b6..a0f7de08 100644 --- a/src/database/models/starboard_override.rs +++ b/src/database/models/starboard_override.rs @@ -54,6 +54,19 @@ impl StarboardOverride { .await } + pub async fn list_by_starboard( + pool: &sqlx::PgPool, + starboard_id: i32, + ) -> sqlx::Result> { + sqlx::query_as!( + Self, + "SELECT * FROM overrides WHERE starboard_id=$1", + starboard_id, + ) + .fetch_optional(pool) + .await + } + pub fn get_overrides(&self) -> serde_json::Result { serde_json::from_value(self.overrides.clone()).map_err(|e| e.into()) } diff --git a/src/interactions/commands/chat/starboard/create.rs b/src/interactions/commands/chat/starboard/create.rs index 3d676686..be854d74 100644 --- a/src/interactions/commands/chat/starboard/create.rs +++ b/src/interactions/commands/chat/starboard/create.rs @@ -47,6 +47,10 @@ impl CreateStarboard { .await?; } else { ctx.bot.cache.guild_starboard_names.remove(&guild_id).await; + ctx.bot + .cache + .guild_vote_emojis + .remove(&unwrap_id!(guild_id)); ctx.respond_str( &format!("Created starboard '{}' in <#{}>.", name, channel_id), diff --git a/src/interactions/commands/chat/starboard/delete.rs b/src/interactions/commands/chat/starboard/delete.rs index bc0875f0..bfcf6cdf 100644 --- a/src/interactions/commands/chat/starboard/delete.rs +++ b/src/interactions/commands/chat/starboard/delete.rs @@ -25,6 +25,10 @@ impl DeleteStarboard { .guild_autostar_channel_names .remove(&guild_id) .await; + ctx.bot + .cache + .guild_vote_emojis + .remove(&unwrap_id!(guild_id)); ctx.respond_str(&format!("Deleted starboard '{}'.", self.name), false) .await?; } diff --git a/src/interactions/commands/chat/starboard/edit/requirements.rs b/src/interactions/commands/chat/starboard/edit/requirements.rs index 2e64bd8e..3024803c 100644 --- a/src/interactions/commands/chat/starboard/edit/requirements.rs +++ b/src/interactions/commands/chat/starboard/edit/requirements.rs @@ -97,6 +97,12 @@ impl EditRequirements { return Ok(()); } starboard.settings.upvote_emojis = emojis; + + // delete cached value + ctx.bot + .cache + .guild_vote_emojis + .remove(&unwrap_id!(guild_id)); } if let Some(val) = self.downvote_emojis { let emojis = Vec::::from_user_input(val, &ctx.bot, guild_id) @@ -110,6 +116,12 @@ impl EditRequirements { return Ok(()); } starboard.settings.downvote_emojis = emojis; + + // delete cached value + ctx.bot + .cache + .guild_vote_emojis + .remove(&unwrap_id!(guild_id)); } if let Some(val) = self.self_vote { starboard.settings.self_vote = val;