diff options
Diffstat (limited to 'src/commands/sound_levels.rs')
| -rw-r--r-- | src/commands/sound_levels.rs | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/src/commands/sound_levels.rs b/src/commands/sound_levels.rs index 4946f47..2b9048e 100644 --- a/src/commands/sound_levels.rs +++ b/src/commands/sound_levels.rs @@ -1,10 +1,18 @@ +use std::error::Error; + +use serenity::all::{ + Context, + Message, +}; + use crate::{ commands::playback::songbird, + util, PoiseContext, }; /// Mute audio (don't pause). -#[poise::command(prefix_command, guild_only)] +#[poise::command(prefix_command, guild_only, category = "playback")] pub async fn mute(ctx: PoiseContext<'_>) -> anyhow::Result<()> { let (_sb, call) = songbird(ctx).await?; @@ -15,7 +23,7 @@ pub async fn mute(ctx: PoiseContext<'_>) -> anyhow::Result<()> { } /// Unmute audio. -#[poise::command(prefix_command, guild_only)] +#[poise::command(prefix_command, guild_only, category = "playback")] pub async fn unmute(ctx: PoiseContext<'_>) -> anyhow::Result<()> { let (_sb, call) = songbird(ctx).await?; @@ -24,3 +32,62 @@ pub async fn unmute(ctx: PoiseContext<'_>) -> anyhow::Result<()> { Ok(()) } + +#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] +struct PercentArg(f64); + +lazy_static::lazy_static! { + static ref ARG_PCT: regex::Regex = regex::Regex::new(r#"(\d+(?:\.\d+)?)\s*%?(.*)"#).unwrap(); +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, thiserror::Error)] +#[error("expected a number with an optional trailing %")] +struct NonPctError; + +#[poise::async_trait] +impl<'a> poise::PopArgument<'a> for PercentArg { + async fn pop_from( + args: &'a str, + attachment_index: usize, + _ctx: &Context, + _msg: &Message, + ) -> Result<(&'a str, usize, Self), (Box<dyn Error + Send + Sync>, Option<String>)> { + let Some(mtch) = ARG_PCT.captures(args) else { + return Err((Box::new(NonPctError), None)); + }; + + let pct = mtch.get(1).unwrap().as_str().parse::<f64>().unwrap(); + let prop = pct / 100.; + let rest = mtch.get(2).unwrap().as_str(); + + Ok((rest, attachment_index, Self(prop))) + } +} + +/// Set volume by percent. +#[poise::command(prefix_command, guild_only, category = "playback")] +pub async fn volume(ctx: PoiseContext<'_>, volume: Option<PercentArg>) -> anyhow::Result<()> { + let Some(volume) = volume else { + let cur_vol = util::volume(ctx).await * 100.; + + util::reply(ctx, format!("{cur_vol:.0}%")).await?; + return Ok(()); + }; + + { + let data = ctx.serenity_context().data.read().await; + let vol = data.get::<crate::bot::VolumeKey>().unwrap(); + vol.insert(util::guild_id(ctx)?, volume.0); + } + + let (_sb, call) = songbird(ctx).await?; + let call = call.lock().await; + + call.queue().modify_queue(|q| { + for elt in q { + elt.set_volume(volume.0 as _)?; + } + + anyhow::Ok(()) + }) +} |
