aboutsummaryrefslogtreecommitdiff
path: root/src/commands/sound_levels.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/sound_levels.rs')
-rw-r--r--src/commands/sound_levels.rs71
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(())
+ })
+}