Esempio n. 1
0
    async def prompt_for_reaction(self, ctx, reactions):
        text = "Please add the reaction to this message that you want to watch for (or :white_check_mark: to finish or cancel if nothing set so far)"
        if reactions:
            text += "\n\n**Current reactions**"
            for r in reactions:
                text += f"\n{r} <@&{reactions[r]}>"

        prompt_reaction_message = await ctx.send_success(
            description=text, title="Reaction roles")
        prompt_reaction = context.PromptDataReaction(
            message=prompt_reaction_message,
            reactions=[],
            timeout=30,
            delete_after=True,
            raw_emoji=True)

        reaction, _ = await ctx.prompt_reaction(prompt_reaction)
        return reaction
Esempio n. 2
0
    async def report(self, msg, user, word, invite=None):
        channel = msg.guild.get_channel(
            self.bot.settings.guild().channel_reports)
        ping_string = await self.prepare_ping_string(msg)
        embed = await self.prepare_embed(user, msg, word)

        if invite:
            report_msg = await channel.send(
                f"{ping_string}\nMessage contained invite: {invite}",
                embed=embed)
        else:
            report_msg = await channel.send(ping_string, embed=embed)
        report_reactions = ['βœ…', 'πŸ†”', '🧹']

        ctx = await self.bot.get_context(report_msg, cls=context.Context)
        prompt_data = context.PromptDataReaction(report_msg, report_reactions)

        while True:
            self.pending_tasks[report_msg.id] = "NOT TERMINATED"
            reaction, reactor = await ctx.prompt_reaction(prompt_data)
            if reaction == "TERMINATE":
                return

            if not self.bot.settings.permissions.hasAtLeast(
                    user.guild, user, 5) or reaction not in report_reactions:
                await report_msg.remove_reaction(reaction, reactor)

            if reaction == 'βœ…':
                try:
                    await report_msg.delete()
                except Exception:
                    pass
                return
            elif reaction == 'πŸ†”':
                await channel.send(user.id)
            elif reaction == '🧹':
                await channel.purge(limit=100)
                return
Esempio n. 3
0
    async def report_spam(self, msg, user, title):
        channel = msg.guild.get_channel(
            self.bot.settings.guild().channel_reports)
        ping_string = await self.prepare_ping_string(msg)

        embed = await self.prepare_embed(user, msg, title=title)
        embed.set_footer(text="βœ… to pardon, πŸ’€ to ban, ⚠️ to temp mute.")

        report_msg = await channel.send(ping_string, embed=embed)
        report_reactions = ['βœ…', 'πŸ’€', '⚠️']

        ctx = await self.bot.get_context(report_msg, cls=context.Context)
        prompt_data = context.PromptDataReaction(report_msg, report_reactions)

        while True:
            self.pending_tasks[report_msg.id] = "NOT TERMINATED"
            reaction, reactor = await ctx.prompt_reaction(prompt_data)
            if reaction == "TERMINATE":
                return

            if not self.bot.settings.permissions.hasAtLeast(
                    user.guild, user, 5) or reaction not in report_reactions:
                await report_msg.remove_reaction(reaction, reactor)

            if reaction == 'βœ…':
                ctx.author = ctx.message.author = reactor
                unmute = self.bot.get_command("unmute")
                if unmute is not None:
                    try:
                        await unmute(ctx=ctx,
                                     user=user,
                                     reason="Reviewed by a moderator.")
                    except Exception:
                        pass
                    await report_msg.delete()
                else:
                    await ctx.send_warning("I wasn't able to unmute them.")
                return

            elif reaction == 'πŸ’€':
                ctx.author = ctx.message.author = reactor
                ban = self.bot.get_command("ban")
                if ban is not None:
                    try:
                        await ban(ctx=ctx, user=user, reason="Spam detected")
                    except Exception:
                        pass
                    await report_msg.delete()
                else:
                    await ctx.send_warning("I wasn't able to ban them.")
                return
            elif reaction == '⚠️':
                ctx.author = ctx.message.author = reactor
                now = datetime.datetime.now()
                delta = await self.prompt_time(ctx)
                if delta is None:
                    continue

                try:
                    time = now + datetime.timedelta(seconds=delta)
                    ctx.tasks.schedule_unmute(user.id, time)

                    await ctx.send_success(
                        title="Done!",
                        description=
                        f"{user.mention} was muted for {humanize.naturaldelta(time - now)}.",
                        delete_after=5)
                    await report_msg.delete()

                    try:
                        await user.send(embed=discord.Embed(
                            title="Ping spam unmute",
                            description=
                            f"A moderator has reviewed your ping spam report. You will be unmuted in {humanize.naturaldelta(time - now)}.",
                            color=discord.Color.orange()))
                    except Exception:
                        pass

                    return
                except Exception:
                    return
Esempio n. 4
0
    async def report_possible_raid_phrase(self, msg, user, domain):
        channel = msg.guild.get_channel(
            self.bot.settings.guild().channel_reports)
        ping_string = await self.prepare_ping_string(msg)
        ping_string = ""

        embed = await self.prepare_embed(
            user,
            msg,
            word=domain,
            title=f"Possible new raid phrase detected\n{domain}")
        embed.set_footer(text="βœ… to pardon, πŸ’€ to ban and add new raid phrase")

        report_msg = await channel.send(ping_string, embed=embed)
        report_reactions = ['βœ…', 'πŸ’€']

        ctx = await self.bot.get_context(report_msg, cls=context.Context)
        prompt_data = context.PromptDataReaction(report_msg, report_reactions)

        while True:
            self.pending_tasks[report_msg.id] = "NOT TERMINATED"
            reaction, reactor = await ctx.prompt_reaction(prompt_data)
            if reaction == "TERMINATE":
                return

            if not self.bot.settings.permissions.hasAtLeast(
                    user.guild, user, 5) or reaction not in report_reactions:
                await report_msg.remove_reaction(reaction, reactor)

            if reaction == 'βœ…':
                ctx.author = ctx.message.author = reactor
                unmute = self.bot.get_command("unmute")
                if unmute is not None:
                    try:
                        await unmute(ctx=ctx,
                                     user=user,
                                     reason="Reviewed by a moderator.")
                    except Exception:
                        pass
                    await report_msg.delete()
                else:
                    await ctx.send_warning("I wasn't able to unmute them.")
                return
            elif reaction == 'πŸ’€':
                ctx.author = ctx.message.author = reactor
                ban = self.bot.get_command("ban")
                if ban is not None:
                    try:
                        await ban(ctx=ctx,
                                  user=user,
                                  reason="Raid phrase detected")
                    except Exception:
                        pass
                    await report_msg.delete()
                else:
                    await ctx.send_warning("I wasn't able to ban them.")

                done = await self.bot.settings.add_raid_phrase(domain)
                if done:
                    await channel.send(
                        f"{domain} was added to the raid phrase list.",
                        delete_after=5)
                else:
                    await channel.send(
                        f"{domain} was already in the raid phrase list.",
                        delete_after=5)
                return
Esempio n. 5
0
    async def batchraid(self, ctx: context.Context, *, phrases: str) -> None:
        """Add a list of (newline-separated) phrases to the raid filter.

        Example usage
        --------------
        !raid <phrase>

        Parameters
        ----------
        phrases : str
            "Phrases to add, separated with enter"
        """

        async with ctx.typing():
            phrases = list(set(phrases.split("\n")))
            phrases = [phrase.strip() for phrase in phrases]

            phrases_contenders = set(phrases)
            phrases_already_in_db = set(
                [phrase.word for phrase in ctx.settings.guild().raid_phrases])

            duplicate_count = len(
                phrases_already_in_db
                & phrases_contenders)  # count how many duplicates we have
            new_phrases = list(phrases_contenders - phrases_already_in_db)

        if not new_phrases:
            raise commands.BadArgument(
                "All the phrases you supplied are already in the database.")

        phrases_prompt_string = "\n".join(
            [f"**{i+1}**. {phrase}" for i, phrase in enumerate(new_phrases)])
        if len(phrases_prompt_string) > 3900:
            phrases_prompt_string = phrases_prompt_string[:3500] + "\n... (and some more)"

        embed = Embed(
            title="Confirm raidphrase batch",
            color=discord.Color.dark_orange(),
            description=
            f"{phrases_prompt_string}\n\nShould we add these {len(new_phrases)} phrases?"
        )

        if duplicate_count > 0:
            embed.set_footer(
                text=
                f"Note: we found {duplicate_count} duplicates in your list.")

        message = await ctx.send(embed=embed)

        prompt_data = context.PromptDataReaction(message=message,
                                                 reactions=['βœ…', '❌'],
                                                 timeout=120,
                                                 delete_after=True)
        response, _ = await ctx.prompt_reaction(info=prompt_data)

        if response == 'βœ…':
            async with ctx.typing():
                for phrase in new_phrases:
                    await ctx.settings.add_raid_phrase(phrase)

            await ctx.send_success(
                f"Added {len(new_phrases)} phrases to the raid filter.",
                delete_after=5)
        else:
            await ctx.send_warning("Cancelled.", delete_after=5)

        await ctx.message.delete(delay=5)
Esempio n. 6
0
    async def adddevice(self, ctx: context.Context, *, device: str) -> None:
        """Add device name to your nickname, i.e `SlimShadyIAm [iPhone 12, 14.2]`. See !listdevices to see the list of possible devices.

        Example usage
        -------------
        !adddevice <device name>

        Parameters
        ----------
        device : str
            "device user wants to use"

        """
        new_nick = ctx.author.display_name
        # check if user already has a device in their nick
        if re.match(self.devices_test, ctx.author.display_name):
            # they already have a device set
            prompt = await ctx.send_warning(
                description=
                "You already have a device nickname set. Would you like to modify it?"
            )
            prompt_data = context.PromptDataReaction(prompt, ['βœ…', '❌'],
                                                     timeout=15,
                                                     delete_after=True)
            response, _ = await ctx.prompt_reaction(prompt_data)

            if response is None or response == '❌':
                # timeout or X reacted
                await ctx.send_warning(
                    description="Cancelled adding device to your name.",
                    delete_after=5)
                await ctx.message.delete(delay=5)
                return
            elif response == 'βœ…':
                # user wants to remove existing device, let's do that
                new_nick = re.sub(self.devices_remove_re, "",
                                  ctx.author.display_name).strip()
                if len(new_nick) > 32:
                    raise commands.BadArgument("Nickname too long")

                await ctx.send_success("Alright, we'll swap your device!",
                                       delete_after=5)

        if not device.split(" ")[0].lower() in self.possible_devices:
            raise commands.BadArgument(
                "Unsupported device. Please see `!listdevices` for possible devices."
            )

        the_device = await self.find_device_from_ipsw_me(device)

        # did we find a device with given name?
        if the_device is None:
            raise commands.BadArgument("Device doesn't exist!")

        # prompt user for which firmware they want in their name
        firmware = await self.prompt_for_firmware(ctx, the_device)

        # change the user's nickname!
        if firmware is not None:
            name = the_device["name"]
            name = name.replace(' Plus', '+')
            name = name.replace('Pro Max', 'PM')
            new_nick = f"{new_nick} [{name}, {firmware}]"

            if len(new_nick) > 32:
                raise commands.BadArgument("Nickname too long! Aborting.")

            await ctx.author.edit(nick=new_nick)
            await ctx.send_success("Changed your nickname!", delete_after=5)
            await ctx.message.delete(delay=5)