feat: support relative volume adjustment (+N/-N)
!volume +10 increases by 10, !volume -5 decreases by 5. Out-of-range results (below 0 or above 100) are rejected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -405,13 +405,14 @@ async def cmd_testtone(bot, message):
|
||||
await bot.reply(message, "Test tone complete")
|
||||
|
||||
|
||||
@command("volume", help="Music: !volume [0-100]")
|
||||
@command("volume", help="Music: !volume [0-100|+N|-N]")
|
||||
async def cmd_volume(bot, message):
|
||||
"""Get or set playback volume.
|
||||
|
||||
Usage:
|
||||
!volume Show current volume
|
||||
!volume <0-100> Set volume (takes effect immediately)
|
||||
!volume +N/-N Adjust volume relatively
|
||||
"""
|
||||
if not _is_mumble(bot):
|
||||
return
|
||||
@@ -422,12 +423,18 @@ async def cmd_volume(bot, message):
|
||||
await bot.reply(message, f"Volume: {ps['volume']}%")
|
||||
return
|
||||
|
||||
arg = parts[1].strip()
|
||||
relative = arg.startswith("+") or (arg.startswith("-") and arg != "-")
|
||||
|
||||
try:
|
||||
val = int(parts[1])
|
||||
val = int(arg)
|
||||
except ValueError:
|
||||
await bot.reply(message, "Usage: !volume <0-100>")
|
||||
await bot.reply(message, "Usage: !volume <0-100|+N|-N>")
|
||||
return
|
||||
|
||||
if relative:
|
||||
val = ps["volume"] + val
|
||||
|
||||
if val < 0 or val > 100:
|
||||
await bot.reply(message, "Volume must be 0-100")
|
||||
return
|
||||
|
||||
@@ -319,8 +319,41 @@ class TestVolumeCommand:
|
||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||
assert any("0-100" in r for r in bot.replied)
|
||||
|
||||
def test_volume_negative(self):
|
||||
def test_volume_negative_absolute(self):
|
||||
"""Bare negative that underflows clamps at 0-100 error."""
|
||||
bot = _FakeBot()
|
||||
_mod._ps(bot)["volume"] = 5
|
||||
msg = _Msg(text="!volume -10")
|
||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||
assert any("0-100" in r for r in bot.replied)
|
||||
|
||||
def test_volume_relative_up(self):
|
||||
bot = _FakeBot()
|
||||
msg = _Msg(text="!volume +15")
|
||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||
ps = _mod._ps(bot)
|
||||
assert ps["volume"] == 65
|
||||
assert any("65%" in r for r in bot.replied)
|
||||
|
||||
def test_volume_relative_down(self):
|
||||
bot = _FakeBot()
|
||||
_mod._ps(bot)["volume"] = 80
|
||||
msg = _Msg(text="!volume -20")
|
||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||
ps = _mod._ps(bot)
|
||||
assert ps["volume"] == 60
|
||||
assert any("60%" in r for r in bot.replied)
|
||||
|
||||
def test_volume_relative_clamp_over(self):
|
||||
bot = _FakeBot()
|
||||
_mod._ps(bot)["volume"] = 95
|
||||
msg = _Msg(text="!volume +10")
|
||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||
assert any("0-100" in r for r in bot.replied)
|
||||
|
||||
def test_volume_relative_clamp_under(self):
|
||||
bot = _FakeBot()
|
||||
_mod._ps(bot)["volume"] = 5
|
||||
msg = _Msg(text="!volume -10")
|
||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||
assert any("0-100" in r for r in bot.replied)
|
||||
|
||||
Reference in New Issue
Block a user