Exemple #1
0
def restore_cooldown(cld_dict):
    """Assume we already checked it exists (is not None)."""
    rate = cld_dict['rate']
    per = cld_dict['per']
    cdtype = BucketType[cld_dict['type']]
    cooldown = Cooldown(rate, per, cdtype)
    cooldown._window = cld_dict['_window']
    cooldown._tokens = cld_dict['_tokens']
    cooldown._last = cld_dict['_last']
    return cooldown
Exemple #2
0
 async def krab(self, ctx, top: str, bottom: str = None):
     """:crab: HAAN IS HOOG :crab:"""
     x = await ctx.send(':crab: MEEM AAN HET MAKEN, EVEN GEDULD AUB :crab:')
     if not bottom:
         text = top
     else:
         text = ','.join([top, bottom])
     params = {"text": text}
     auth = {"Authorization": self.token}
     async with self.bot.web.get('https://dankmemer.services/api/crab',
                                 params=params,
                                 headers=auth) as r:
         if r.status == 429:
             raise CommandOnCooldown(cooldown=Cooldown(
                 1, 30, BucketType.default),
                                     retry_after=30.0)
         elif r.status != 200:
             raise CommandError
         resp = await r.content.read()
     b = BytesIO(resp)
     f = File(b, filename='krab.mp4')
     await x.delete()
     return await ctx.send(content=':crab: {} :crab:'.format(
         text.replace(",", " ").upper()),
                           file=f)
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self.command_attrs = {
         "cooldown": Cooldown(3, 5.0, BucketType.user),
         "name": "help",
         "aliases": ["h"]
     }
Exemple #4
0
    def decorator(func):
        try:
            cooldown_obj = Cooldown(rate, per, type)  # type: ignore
        except Exception:
            cooldown_obj = Cooldown(rate, per)

        try:
            mapping = CooldownMapping(cooldown_obj)  # type: ignore
        except Exception:
            mapping = CooldownMapping(cooldown_obj, type)

        if isinstance(func, InvokableApplicationCommand):
            func._buckets = mapping
        else:
            func.__slash_cooldown__ = mapping

        return func
 def decorator(func):
     if isinstance(func, Command):
         nonlocal rate, per, type
         db_name = (f"Cooldowns")
         make_db_if_not_exists(path=f"{DBPATH}\\{db_name}.json")
         cooldowns = db_receive(db_name)
         if not rate:
             rate = 1
         if not per:
             if str(func) not in cooldowns:
                 cooldowns[str(func)] = default_cooldown
             db_update(db_name, cooldowns)
             per = cooldowns[str(func)]
         func._buckets = CooldownMapping(Cooldown(rate, per, type))
     else:
         func.__commands_cooldown__ = Cooldown(rate, per, type)
     return func
Exemple #6
0
def cooldown_with_role_bypass(rate: int,
                              per: float,
                              type: BucketType = BucketType.default,
                              *,
                              bypass_roles: Iterable[int]) -> Callable:
    """
    Applies a cooldown to a command, but allows members with certain roles to be ignored.

    NOTE: this replaces the `Command.before_invoke` callback, which *might* introduce problems in the future.
    """
    # Make it a set so lookup is hash based.
    bypass = set(bypass_roles)

    # This handles the actual cooldown logic.
    buckets = CooldownMapping(Cooldown(rate, per, type))

    # Will be called after the command has been parse but before it has been invoked, ensures that
    # the cooldown won't be updated if the user screws up their input to the command.
    async def predicate(cog: Cog, ctx: Context) -> None:
        nonlocal bypass, buckets

        if any(role.id in bypass for role in ctx.author.roles):
            return

        # Cooldown logic, taken from discord.py internals.
        current = ctx.message.created_at.replace(
            tzinfo=datetime.timezone.utc).timestamp()
        bucket = buckets.get_bucket(ctx.message)
        retry_after = bucket.update_rate_limit(current)
        if retry_after:
            raise CommandOnCooldown(bucket, retry_after)

    def wrapper(command: Command) -> Command:
        # NOTE: this could be changed if a subclass of Command were to be used. I didn't see the need for it
        # so I just made it raise an error when the decorator is applied before the actual command object exists.
        #
        # If the `before_invoke` detail is ever a problem then I can quickly just swap over.
        if not isinstance(command, Command):
            raise TypeError(
                'Decorator `cooldown_with_role_bypass` must be applied after the command decorator. '
                'This means it has to be above the command decorator in the code.'
            )

        command._before_invoke = predicate

        return command

    return wrapper
Exemple #7
0
 def __init__(self):
     super().__init__(command_attrs={
         'cooldown': Cooldown(1, 3.0, BucketType.member),
         'help': 'Показывает эту плашку'}
     )
Exemple #8
0
 def __init__(self):
     super().__init__(command_attrs={
         'help': 'Shows help about the bot, a command or a category',
         'cooldown': Cooldown(1, 15, BucketType.channel)})
Exemple #9
0
class Roles:
    def __init__(self, bot):
        self.bot = bot
        self.rules_channel = 434836251766423564
        self.req_channel = 442045140261928960
        self.msg_id = 434842027692130304
        self.emoji_server_id = 417804713413836830

    async def cmdcheck(ctx):
        return ctx.author.id == 111158853839654912 or ctx.author.guild_permissions.manage_roles

    @commands.check(cmdcheck)
    @commands.command(hidden=True)
    async def addrole(self, ctx, role: discord.Role, emoji_name, url=None):
        """Adds a new role to the reaction role manager."""

        c = self.bot.get_channel(self.rules_channel)
        msg = await c.get_message(self.msg_id)

        if emoji_name in self.bot.reaction_manager:
            return await ctx.send("Role has already been added!")
        if len(msg.reactions) == 20:
            return await ctx.send("Cannot add role! Too many roles exist. [Reaction reached 20 Emoji]")

        if url is None:
            if len(ctx.message.attachments) > 0:
                url = ctx.message.attachments[0].url
        resp = await self.bot.session.get(url)
        img = await resp.read()

        try:
            guild = self.bot.get_guild(self.emoji_server_id)
            emoji = await guild.create_custom_emoji(name=emoji_name, image=img)
        except:  # noqa
            return await ctx.send("Could not create emoji!")

        await msg.add_reaction(emoji)
        self.bot.reaction_manager[emoji_name] = role.id

        query = """
            INSERT INTO reaction_roles (emoji_name, role_id) VALUES ($1, $2)
        """

        await self.bot.pool.execute(query, emoji_name, role.id)
        await ctx.send(f"Added `{emoji_name}` as an assignable role!")

    @restricted()
    @commands.group()
    async def request(self, ctx):
        """Request a special role.
        More info on each role is in the rules.
        """

    async def request_body(ctx):
        channel = ctx.guild.get_channel(ctx.bot.get_cog('Roles').req_channel)
        if channel is None:
            return

        role = discord.utils.get(ctx.guild.roles, name=ctx.command.name)
        if role.name not in ('Parasites', 'Verified'):
            return await ctx.send("You can't request that role, Darling!")

        if role in ctx.author.roles:
            return await ctx.send("You already have that role, Darling!")

        embed = discord.Embed(title="Role requested!", timestamp=datetime.now(), color=discord.Color.purple()) \
            .add_field(name='Role', value=role.name) \
            .add_field(name="Joined at", value=ctx.author.joined_at.strftime("%Y-%m-%d %H:%M")) \
            .add_field(name="Account Created", value=ctx.author.created_at.strftime("%Y-%m-%d %H:%M")) \
            .set_author(name=f"{ctx.author} / {ctx.author.id}", icon_url=ctx.author.avatar_url) \
            .set_footer(text=ctx.author.id)
        msg = await channel.send(embed=embed)
        await msg.add_reaction('✅')
        await msg.add_reaction('❌')
        await ctx.send("Request sent!")

    for r_name in ['Parasites', 'Verified']:
        request_body.__commands_cooldown__ = Cooldown(1, 86400, BucketType.user)
        request.command(r_name, aliases=[r_name.lower()])(request_body)

    async def handle_request(self, author, guild, msg_id, emoji):
        emojis = ('✅', '❌')

        perms = author.guild_permissions
        if not (perms.kick_members and perms.ban_members):
            if author.id != self.bot.owner_id:
                return

        channel = guild.get_channel(self.req_channel)
        if channel is None:
            return
        if emoji.name not in emojis:
            return

        msg = await channel.get_message(msg_id)
        if msg is None:
            return
        if sum(1 for r in msg.reactions if r.emoji in emojis and r.count > 1) == 0:
            return

        r_name = msg.embeds[0].fields[0].value
        role = discord.utils.get(guild.roles, name=r_name)
        embed = msg.embeds[0]
        requester = guild.get_member(int(embed.footer.text))
        if emoji.name == '✅':
            embed.color = discord.Color.green()
            await requester.add_roles(role)
            await msg.edit(embed=embed)
            try:
                await requester.send(f"Your request has been accepted! You now have `{role.name}`")
            except:  # give up if we cant send  # noqa
                pass
        elif emoji.name == '❌':
            embed.color = discord.Color.red()
            await msg.edit(embed=embed)
            try:
                await requester.send(f"Your request for `{role.name}` was denied. Please try again later.")
            except:  # rip  # noqa
                pass
        await msg.clear_reactions()

    async def on_raw_reaction_add(self, event):
        guild = self.bot.get_guild(event.guild_id)
        member = guild.get_member(event.user_id)
        await self.handle_request(member, guild, event.message_id, event.emoji)
        if event.message_id != self.msg_id:
            return

        role = guild.get_role(self.bot.reaction_manager[event.emoji.name])
        if role in member.roles:
            return

        await member.add_roles(role)

    async def on_raw_reaction_remove(self, event):
        guild = self.bot.get_guild(event.guild_id)
        member = guild.get_member(event.user_id)
        if event.message_id != self.msg_id:
            return

        role = guild.get_role(self.bot.reaction_manager[event.emoji.name])
        if role not in member.roles:
            return

        await member.remove_roles(role)
Exemple #10
0
                    await channel.delete(reason=translator.translate(
                        "support room is not needed anymore"))


class CustomCooldownMapping(CooldownMapping):
    def _bucket_key(self, member):
        bucket_type = self._cooldown.type
        if bucket_type is BucketType.user:
            return member.id
        elif bucket_type is BucketType.guild:
            return member.guild.id
        elif bucket_type is BucketType.channel:
            return member.voice.channel.id


cooldown = Cooldown(1, 300, BucketType.user)
buckets = CustomCooldownMapping(cooldown)


def setup_voice_state_update_handler(bot):
    async def on_voice_state_update(member, before, after):
        guild = Guild.from_discord_guild(member.guild)

        translator = Translator(Bot._string_translations, guild.language_enum)

        if after.channel is not None:
            channel = after.channel
            category = channel.category

            if category is not None:
                if before.channel != channel and category.id == guild.voice_category: