From 9414de24d42e93cc6270efe8113b2d7edc26f43e Mon Sep 17 00:00:00 2001 From: Kowlin Date: Fri, 3 May 2019 16:08:25 +0200 Subject: [PATCH] [Mod] Added voice kicking. (#2639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added voice kicking. * Reversed exceptions. * Lets use a check that works for this task 👀 * Update abc.py * Black formatting --- redbot/cogs/mod/abc.py | 7 +++++ redbot/cogs/mod/casetypes.py | 6 +++++ redbot/cogs/mod/kickban.py | 50 ++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/redbot/cogs/mod/abc.py b/redbot/cogs/mod/abc.py index ce0905e8d..2dc233783 100644 --- a/redbot/cogs/mod/abc.py +++ b/redbot/cogs/mod/abc.py @@ -20,6 +20,13 @@ class MixinMeta(ABC): self.ban_queue: List[Tuple[int, int]] self.unban_queue: List[Tuple[int, int]] + @staticmethod + @abstractmethod + async def _voice_perm_check( + ctx: commands.Context, user_voice_state: Optional[discord.VoiceState], **perms: bool + ) -> bool: + raise NotImplementedError() + @classmethod @abstractmethod async def get_audit_entry_info( diff --git a/redbot/cogs/mod/casetypes.py b/redbot/cogs/mod/casetypes.py index e5aad3ca4..3696aeb2e 100644 --- a/redbot/cogs/mod/casetypes.py +++ b/redbot/cogs/mod/casetypes.py @@ -97,4 +97,10 @@ CASETYPES = [ "case_str": "Server Unmute", "audit_type": "overwrite_update", }, + { + "name": "vkick", + "default_setting": False, + "image": "\N{SPEAKER WITH CANCELLATION STROKE}", + "case_str": "Voice Kick", + }, ] diff --git a/redbot/cogs/mod/kickban.py b/redbot/cogs/mod/kickban.py index f595845bd..883ca4fec 100644 --- a/redbot/cogs/mod/kickban.py +++ b/redbot/cogs/mod/kickban.py @@ -495,6 +495,56 @@ class KickBanMixin(MixinMeta): await ctx.send(e) await ctx.send(_("Done. Enough chaos.")) + @commands.command() + @commands.guild_only() + @commands.mod_or_permissions(move_members=True) + async def voicekick( + self, ctx: commands.Context, member: discord.Member, *, reason: str = None + ): + """Kick a member from a voice channel.""" + author = ctx.author + guild = ctx.guild + user_voice_state: discord.VoiceState = member.voice + + if await self._voice_perm_check(ctx, user_voice_state, move_members=True) is False: + return + elif not await is_allowed_by_hierarchy(self.bot, self.settings, guild, author, member): + await ctx.send( + _( + "I cannot let you do that. You are " + "not higher than the user in the role " + "hierarchy." + ) + ) + return + case_channel = member.voice.channel + # Store this channel for the case channel. + + try: + await member.move_to(discord.Object(id=None)) + # Work around till we get D.py 1.1.0, whereby we can directly do None. + except discord.Forbidden: # Very unlikely that this will ever occur + await ctx.send(_("I am unable to kick this member from the voice channel.")) + return + except discord.HTTPException: + await ctx.send(_("Something went wrong while attempting to kick that member")) + return + else: + try: + await modlog.create_case( + self.bot, + guild, + ctx.message.created_at, + "vkick", + member, + author, + reason, + until=None, + channel=case_channel, + ) + except RuntimeError as e: + await ctx.send(e) + @commands.command() @commands.guild_only() @commands.bot_has_permissions(ban_members=True)