mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Audio] Added [p]skip voting and perms to stop (#340)
Admins / mods are not counted
This commit is contained in:
parent
5484495d5d
commit
657403c12f
109
cogs/audio.py
109
cogs/audio.py
@ -5,7 +5,7 @@ import os
|
|||||||
from random import shuffle, choice
|
from random import shuffle, choice
|
||||||
from cogs.utils.dataIO import fileIO
|
from cogs.utils.dataIO import fileIO
|
||||||
from cogs.utils import checks
|
from cogs.utils import checks
|
||||||
from __main__ import send_cmd_help
|
from __main__ import send_cmd_help, settings
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
import collections
|
import collections
|
||||||
@ -237,12 +237,14 @@ class Audio:
|
|||||||
self.queue = {} # add deque's, repeat
|
self.queue = {} # add deque's, repeat
|
||||||
self.downloaders = {} # sid: object
|
self.downloaders = {} # sid: object
|
||||||
self.settings = fileIO("data/audio/settings.json", 'load')
|
self.settings = fileIO("data/audio/settings.json", 'load')
|
||||||
self.server_specific_setting_keys = ["VOLUME", "QUEUE_MODE",
|
self.server_specific_setting_keys = ["VOLUME", "VOTE_ENABLED",
|
||||||
"VOTE_THRESHOLD"]
|
"VOTE_THRESHOLD"]
|
||||||
self.cache_path = "data/audio/cache"
|
self.cache_path = "data/audio/cache"
|
||||||
self.local_playlist_path = "data/audio/localtracks"
|
self.local_playlist_path = "data/audio/localtracks"
|
||||||
self._old_game = False
|
self._old_game = False
|
||||||
|
|
||||||
|
self.skip_votes = {}
|
||||||
|
|
||||||
async def _add_song_status(self, song):
|
async def _add_song_status(self, song):
|
||||||
if self._old_game is False:
|
if self._old_game is False:
|
||||||
self._old_game = list(self.bot.servers)[0].me.game
|
self._old_game = list(self.bot.servers)[0].me.game
|
||||||
@ -1038,21 +1040,27 @@ class Audio:
|
|||||||
msg = "Volume must be between 0 and 100."
|
msg = "Volume must be between 0 and 100."
|
||||||
await self.bot.say(msg)
|
await self.bot.say(msg)
|
||||||
|
|
||||||
@audioset.command(pass_context=True, name="vote", no_pm=True,
|
@audioset.command(pass_context=True, name="vote", no_pm=True)
|
||||||
hidden=True, enabled=False)
|
|
||||||
@checks.mod_or_permissions(manage_messages=True)
|
@checks.mod_or_permissions(manage_messages=True)
|
||||||
async def audioset_vote(self, ctx, percent: int):
|
async def audioset_vote(self, ctx, percent: int):
|
||||||
"""Percentage needed for the masses to skip songs."""
|
"""Percentage needed for the masses to skip songs. 0 to disable."""
|
||||||
server = ctx.message.server
|
server = ctx.message.server
|
||||||
|
|
||||||
if percent < 0:
|
if percent < 0:
|
||||||
await self.bot.say("Can't be less than zero.")
|
await self.bot.say("Can't be less than zero.")
|
||||||
return
|
return
|
||||||
|
elif percent > 100:
|
||||||
if percent > 100:
|
|
||||||
percent = 100
|
percent = 100
|
||||||
|
|
||||||
await self.bot.say("Vote percentage set to {}%".format(percent))
|
if percent == 0:
|
||||||
|
enabled = False
|
||||||
|
await self.bot.say("Voting disabled. All users can stop or skip.")
|
||||||
|
else:
|
||||||
|
enabled = True
|
||||||
|
await self.bot.say("Vote percentage set to {}%".format(percent))
|
||||||
|
|
||||||
self.set_server_setting(server, "VOTE_THRESHOLD", percent)
|
self.set_server_setting(server, "VOTE_THRESHOLD", percent)
|
||||||
|
self.set_server_setting(server, "VOTE_ENABLED", enabled)
|
||||||
self.save_settings()
|
self.save_settings()
|
||||||
|
|
||||||
@commands.group(pass_context=True)
|
@commands.group(pass_context=True)
|
||||||
@ -1621,19 +1629,70 @@ class Audio:
|
|||||||
|
|
||||||
await self.bot.say("Queues shuffled.")
|
await self.bot.say("Queues shuffled.")
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, aliases=["next"], no_pm=True)
|
||||||
async def skip(self, ctx):
|
async def skip(self, ctx):
|
||||||
"""Skips the currently playing song"""
|
"""Skips a song, using the set threshold if the requester isn't
|
||||||
|
a mod or admin. Mods, admins and bot owner are not counted in
|
||||||
|
the vote threshold."""
|
||||||
|
msg = ctx.message
|
||||||
server = ctx.message.server
|
server = ctx.message.server
|
||||||
if self.is_playing(server):
|
if self.is_playing(server):
|
||||||
|
vchan = server.me.voice_channel
|
||||||
vc = self.voice_client(server)
|
vc = self.voice_client(server)
|
||||||
vc.audio_player.stop()
|
if msg.author.voice_channel == vchan:
|
||||||
if self._get_queue_repeat(server) is False:
|
if self.can_instaskip(msg.author):
|
||||||
self._set_queue_nowplaying(server, None)
|
vc.audio_player.stop()
|
||||||
await self.bot.say("Skipping...")
|
if self._get_queue_repeat(server) is False:
|
||||||
|
self._set_queue_nowplaying(server, None)
|
||||||
|
await self.bot.say("Skipping...")
|
||||||
|
else:
|
||||||
|
if msg.author.id in self.skip_votes[server.id]:
|
||||||
|
self.skip_votes[server.id].remove(msg.author.id)
|
||||||
|
reply = "I removed your vote to skip."
|
||||||
|
else:
|
||||||
|
self.skip_votes[server.id].append(msg.author.id)
|
||||||
|
reply = "you voted to skip."
|
||||||
|
|
||||||
|
num_votes = len(self.skip_votes[server.id])
|
||||||
|
# Exclude bots and non-plebs
|
||||||
|
num_members = sum(not (m.bot or self.can_instaskip(m)) for m in vchan.voice_members)
|
||||||
|
vote = int(100*num_votes / num_members)
|
||||||
|
thresh = self.get_server_settings(server)["VOTE_THRESHOLD"]
|
||||||
|
|
||||||
|
if vote >= thresh:
|
||||||
|
vc.audio_player.stop()
|
||||||
|
if self._get_queue_repeat(server) is False:
|
||||||
|
self._set_queue_nowplaying(server, None)
|
||||||
|
self.skip_votes[server.id] = []
|
||||||
|
await self.bot.say("Vote threshold met. Skipping...")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
reply += " Votes: %d/%d" % (num_votes, num_members)
|
||||||
|
reply += " (%d%% out of %d%% needed)" % (vote, thresh)
|
||||||
|
await self.bot.reply(reply)
|
||||||
|
else:
|
||||||
|
await self.bot.reply("you aren't in the current playback channel.")
|
||||||
else:
|
else:
|
||||||
await self.bot.say("Can't skip if I'm not playing.")
|
await self.bot.say("Can't skip if I'm not playing.")
|
||||||
|
|
||||||
|
def can_instaskip(self, member):
|
||||||
|
server = member.server
|
||||||
|
|
||||||
|
if not self.get_server_settings(server)["VOTE_ENABLED"]:
|
||||||
|
return True
|
||||||
|
|
||||||
|
admin_role = settings.get_server_admin(server)
|
||||||
|
mod_role = settings.get_server_mod(server)
|
||||||
|
|
||||||
|
is_owner = member.id == settings.owner
|
||||||
|
is_admin = discord.utils.get(member.roles, name=admin_role) is not None
|
||||||
|
is_mod = discord.utils.get(member.roles, name=mod_role) is not None
|
||||||
|
|
||||||
|
nonbots = sum(not m.bot for m in member.voice_channel.voice_members)
|
||||||
|
alone = nonbots <= 1
|
||||||
|
|
||||||
|
return is_owner or is_admin or is_mod or alone
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
async def sing(self, ctx):
|
async def sing(self, ctx):
|
||||||
"""Makes Red sing one of her songs"""
|
"""Makes Red sing one of her songs"""
|
||||||
@ -1674,13 +1733,18 @@ class Audio:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("Darude - Sandstorm.")
|
await self.bot.say("Darude - Sandstorm.")
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
async def stop(self, ctx):
|
async def stop(self, ctx):
|
||||||
"""Stops a currently playing song or playlist. CLEARS QUEUE."""
|
"""Stops a currently playing song or playlist. CLEARS QUEUE."""
|
||||||
# TODO: All those fun checks for permissions
|
|
||||||
server = ctx.message.server
|
server = ctx.message.server
|
||||||
|
if self.is_playing(server):
|
||||||
self._stop(server)
|
if self.can_instaskip(ctx.message.author):
|
||||||
|
await self.bot.say('Stopping...')
|
||||||
|
self._stop(server)
|
||||||
|
else:
|
||||||
|
await self.bot.say("You can't stop music when there are other people in the channel! Vote to skip instead.")
|
||||||
|
else:
|
||||||
|
await self.bot.say("Can't stop if I'm not playing.")
|
||||||
|
|
||||||
@commands.command(name="yt", pass_context=True, no_pm=True)
|
@commands.command(name="yt", pass_context=True, no_pm=True)
|
||||||
async def yt_search(self, ctx, *, search_terms: str):
|
async def yt_search(self, ctx, *, search_terms: str):
|
||||||
@ -1804,6 +1868,7 @@ class Audio:
|
|||||||
if not self.is_playing(server):
|
if not self.is_playing(server):
|
||||||
log.debug("not playing anything on sid {}".format(server.id) +
|
log.debug("not playing anything on sid {}".format(server.id) +
|
||||||
", attempting to start a new song.")
|
", attempting to start a new song.")
|
||||||
|
self.skip_votes[server.id] = [] # Reset skip votes for each new song
|
||||||
if len(temp_queue) > 0:
|
if len(temp_queue) > 0:
|
||||||
# Fake queue for irdumb's temp playlist songs
|
# Fake queue for irdumb's temp playlist songs
|
||||||
log.debug("calling _play because temp_queue is non-empty")
|
log.debug("calling _play because temp_queue is non-empty")
|
||||||
@ -1887,10 +1952,14 @@ class Audio:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
async def voice_state_update(self, before, after):
|
async def voice_state_update(self, before, after):
|
||||||
|
server = after.server
|
||||||
# Member objects
|
# Member objects
|
||||||
|
if server.id in self.skip_votes and\
|
||||||
|
after.id in self.skip_votes[server.id] and\
|
||||||
|
after.voice_channel != before.voice_channel:
|
||||||
|
self.skip_votes[server.id].remove(after.id)
|
||||||
if after is None:
|
if after is None:
|
||||||
return
|
return
|
||||||
server = after.server
|
|
||||||
if server.id not in self.queue:
|
if server.id not in self.queue:
|
||||||
return
|
return
|
||||||
if after != server.me:
|
if after != server.me:
|
||||||
@ -1923,7 +1992,7 @@ def check_folders():
|
|||||||
|
|
||||||
|
|
||||||
def check_files():
|
def check_files():
|
||||||
default = {"VOLUME": 50, "MAX_LENGTH": 3700, "QUEUE_MODE": True,
|
default = {"VOLUME": 50, "MAX_LENGTH": 3700, "VOTE_ENABLED": True,
|
||||||
"MAX_CACHE": 0, "SOUNDCLOUD_CLIENT_ID": None,
|
"MAX_CACHE": 0, "SOUNDCLOUD_CLIENT_ID": None,
|
||||||
"TITLE_STATUS": True, "AVCONV": False, "VOTE_THRESHOLD": 50,
|
"TITLE_STATUS": True, "AVCONV": False, "VOTE_THRESHOLD": 50,
|
||||||
"SERVERS": {}}
|
"SERVERS": {}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user