diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml index 55220af..e2b5f9b 100644 --- a/.idea/dataSources.local.xml +++ b/.idea/dataSources.local.xml @@ -1,6 +1,6 @@ - + master_key diff --git a/Cargo.lock b/Cargo.lock index c143cef..aa41ba4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2017,7 +2017,7 @@ dependencies = [ [[package]] name = "soundfx-rs" -version = "1.5.6" +version = "1.5.7" dependencies = [ "dashmap", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index 9cedff8..48f878d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "soundfx-rs" -version = "1.5.6" +version = "1.5.7" authors = ["jellywx "] edition = "2018" diff --git a/migrations/20230322-disable-user-greets.sql b/migrations/20230322-disable-user-greets.sql new file mode 100644 index 0000000..11fa41e --- /dev/null +++ b/migrations/20230322-disable-user-greets.sql @@ -0,0 +1 @@ +ALTER TABLE servers MODIFY COLUMN allow_greets INT NOT NULL DEFAULT 1; diff --git a/src/cmds/settings.rs b/src/cmds/settings.rs index d54e10e..ec1e0a9 100644 --- a/src/cmds/settings.rs +++ b/src/cmds/settings.rs @@ -2,7 +2,11 @@ use poise::serenity_prelude::{GuildId, User}; use crate::{ cmds::autocomplete_sound, - models::{guild_data::CtxGuildData, join_sound::JoinSoundCtx, sound::SoundCtx}, + models::{ + guild_data::{AllowGreet, CtxGuildData}, + join_sound::JoinSoundCtx, + sound::SoundCtx, + }, Context, Error, }; @@ -46,7 +50,7 @@ pub async fn guild_greet_sound(_ctx: Context<'_>) -> Result<(), Error> { Ok(()) } -/// Set a user's guild-specific join sound +/// Set a user's server-specific join sound #[poise::command(slash_command, rename = "set")] pub async fn set_guild_greet_sound( ctx: Context<'_>, @@ -98,7 +102,7 @@ pub async fn set_guild_greet_sound( Ok(()) } -/// Unset your global join sound +/// Unset a user's server-specific join sound #[poise::command(slash_command, rename = "unset", guild_only = true)] pub async fn unset_guild_greet_sound( ctx: Context<'_>, @@ -189,7 +193,7 @@ pub async fn unset_user_greet_sound(ctx: Context<'_>) -> Result<(), Error> { Ok(()) } -/// Disable greet sounds on this server +/// Disable all greet sounds on this server #[poise::command( slash_command, rename = "disable", @@ -200,7 +204,7 @@ pub async fn disable_greet_sound(ctx: Context<'_>) -> Result<(), Error> { let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await; if let Ok(guild_data) = guild_data_opt { - guild_data.write().await.allow_greets = false; + guild_data.write().await.allow_greets = AllowGreet::Disabled; guild_data.read().await.commit(&ctx.data().database).await?; } @@ -211,7 +215,29 @@ pub async fn disable_greet_sound(ctx: Context<'_>) -> Result<(), Error> { Ok(()) } -/// Enable greet sounds on this server +/// Enable only server greet sounds on this server +#[poise::command( + slash_command, + rename = "enable", + guild_only = true, + required_permissions = "MANAGE_GUILD" +)] +pub async fn enable_guild_greet_sound(ctx: Context<'_>) -> Result<(), Error> { + let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await; + + if let Ok(guild_data) = guild_data_opt { + guild_data.write().await.allow_greets = AllowGreet::GuildOnly; + + guild_data.read().await.commit(&ctx.data().database).await?; + } + + ctx.say("Greet sounds have been partially enable in this server. Use \"/greet server set\" to configure server greet sounds.") + .await?; + + Ok(()) +} + +/// Enable all greet sounds on this server #[poise::command( slash_command, rename = "enable", @@ -222,7 +248,7 @@ pub async fn enable_greet_sound(ctx: Context<'_>) -> Result<(), Error> { let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await; if let Ok(guild_data) = guild_data_opt { - guild_data.write().await.allow_greets = true; + guild_data.write().await.allow_greets = AllowGreet::Enabled; guild_data.read().await.commit(&ctx.data().database).await?; } diff --git a/src/event_handlers.rs b/src/event_handlers.rs index f13acae..bcdf4ff 100644 --- a/src/event_handlers.rs +++ b/src/event_handlers.rs @@ -11,7 +11,11 @@ use poise::serenity_prelude::{ use crate::{ cmds::search::SoundPager, - models::{guild_data::CtxGuildData, join_sound::JoinSoundCtx, sound::Sound}, + models::{ + guild_data::{AllowGreet, CtxGuildData}, + join_sound::JoinSoundCtx, + sound::Sound, + }, utils::{join_channel, play_audio, play_from_query}, Data, Error, }; @@ -89,8 +93,14 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R allowed_greets = read.allow_greets; } - if allowed_greets { - if let Some(join_id) = data.join_sound(new.user_id, new.guild_id).await + if allowed_greets != AllowGreet::Disabled { + if let Some(join_id) = data + .join_sound( + new.user_id, + new.guild_id, + allowed_greets == AllowGreet::GuildOnly, + ) + .await { let mut sound = sqlx::query_as_unchecked!( Sound, diff --git a/src/main.rs b/src/main.rs index 3e289c7..459378f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,6 +103,7 @@ async fn main() -> Result<(), Box> { subcommands: vec![ cmds::settings::set_guild_greet_sound(), cmds::settings::unset_guild_greet_sound(), + cmds::settings::enable_guild_greet_sound(), ], ..cmds::settings::guild_greet_sound() }, diff --git a/src/models/guild_data.rs b/src/models/guild_data.rs index f48aa41..e7e2b0b 100644 --- a/src/models/guild_data.rs +++ b/src/models/guild_data.rs @@ -1,17 +1,25 @@ use std::sync::Arc; use poise::serenity_prelude::{async_trait, model::id::GuildId}; -use sqlx::Executor; +use sqlx::{Executor, Type}; use tokio::sync::RwLock; use crate::{Context, Data, Database}; +#[derive(Copy, Clone, Type, PartialEq)] +#[repr(i32)] +pub enum AllowGreet { + Enabled = 1, + GuildOnly = 0, + Disabled = -1, +} + #[derive(Clone)] pub struct GuildData { pub id: u64, pub prefix: String, pub volume: u8, - pub allow_greets: bool, + pub allow_greets: AllowGreet, pub allowed_role: Option, } @@ -109,7 +117,7 @@ INSERT INTO servers (id) id: guild_id.as_u64().to_owned(), prefix: String::from("?"), volume: 100, - allow_greets: true, + allow_greets: AllowGreet::Enabled, allowed_role: None, }) } diff --git a/src/models/join_sound.rs b/src/models/join_sound.rs index 9eef3f8..0726529 100644 --- a/src/models/join_sound.rs +++ b/src/models/join_sound.rs @@ -8,6 +8,7 @@ pub trait JoinSoundCtx { &self, user_id: U, guild_id: Option, + guild_only: bool, ) -> Option; async fn update_join_sound + Send + Sync, G: Into + Send + Sync>( &self, @@ -17,12 +18,17 @@ pub trait JoinSoundCtx { ) -> Result<(), sqlx::Error>; } +struct JoinSound { + join_sound_id: u32, +} + #[async_trait] impl JoinSoundCtx for Data { async fn join_sound + Send + Sync, G: Into + Send + Sync>( &self, user_id: U, guild_id: Option, + guild_only: bool, ) -> Option { let user_id = user_id.into(); let guild_id = guild_id.map(|g| g.into()); @@ -37,19 +43,37 @@ impl JoinSoundCtx for Data { join_sound_id } else { let join_sound_id = { - let join_id_res = sqlx::query!( - " + let join_id_res = if guild_only { + sqlx::query_as!( + JoinSound, + " +SELECT join_sound_id + FROM join_sounds + WHERE user = ? + AND guild = ? + ORDER BY guild IS NULL + ", + user_id.as_u64(), + guild_id.map(|g| g.0) + ) + .fetch_one(&self.database) + .await + } else { + sqlx::query_as!( + JoinSound, + " SELECT join_sound_id FROM join_sounds WHERE user = ? AND (guild IS NULL OR guild = ?) ORDER BY guild IS NULL ", - user_id.as_u64(), - guild_id.map(|g| g.0) - ) - .fetch_one(&self.database) - .await; + user_id.as_u64(), + guild_id.map(|g| g.0) + ) + .fetch_one(&self.database) + .await + }; if let Ok(row) = join_id_res { Some(row.join_sound_id)