Beispiel #1
0
    async def on_message_without_command(self, message: discord.Message):
        if (not self._event.is_set()) or self.mention_regex is None:
            return
        if not self.mention_regex.match(message.content):
            return
        channel = message.channel
        author = message.author
        guild = message.guild
        guild_id = guild.id if guild else None
        if guild_id in self.disable_in:
            return
        if guild_id not in self.antispam:
            self.antispam[guild_id] = {}
        if author.id not in self.antispam[guild_id]:
            self.antispam[guild_id][author.id] = AntiSpam(self.intervals)
        if self.antispam[guild_id][author.id].spammy:
            return
        if guild:
            if (not channel.permissions_for(guild.me).send_messages
                    or (await self.bot.cog_disabled_in_guild(self, guild))
                    or not (await self.bot.ignored_channel_or_guild(message))):
                return
        if not (await self.bot.allowed_by_whitelist_blacklist(author)):
            return

        self.antispam[guild_id][author.id].stamp()
        prefixes = await self.bot.get_valid_prefixes(guild=guild)
        prefixes = sorted(prefixes, key=len)
        counter = 0
        prefix_list = [
            pf for p in prefixes
            if (pf := f"`{discord.utils.escape_markdown(p)}`")
            and len(pf) < 1800 and (
                (counter + len(pf)) < 1800) and (counter := counter + len(pf))
        ]
Beispiel #2
0
    async def on_voice_state_update(
        self,
        member: discord.Member,
        before: discord.VoiceState,
        after: discord.VoiceState,
    ):
        """
        handles logic
        """

        if before.channel == after.channel:
            return

        if member.id not in self._antispam:
            self._antispam[member.id] = AntiSpam(self.antispam_intervals)
        if not self._antispam[member.id].spammy:
            if after.channel:
                if await self.config.guild(after.channel.guild).active():
                    conf = self.config.channel(after.channel)
                    if await conf.autoroom() or await conf.gameroom():
                        await self.generate_room_for(who=member,
                                                     source=after.channel)

        if before.channel:
            await self._cleanup(before.channel.guild)
Beispiel #3
0
    async def request(
        self,
        ctx,
        *,
        request: str = "",
    ):
        """
        Request something.

        Options
        channel : Mention channel to specify which channel to post your request
        """
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}

        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([])

        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(_("You've send too many requests recently."))

        channels = await self.config.guild(ctx.guild).boxes()
        if not request:
            return await ctx.send(_("Please try again while including a request."))

        embed = discord.Embed(color=(await ctx.embed_color()), description=request)

        embed.set_author(
            name=_("New bounty from {author_info}").format(
                author_info=f"{ctx.author.display_name} ({ctx.author.id})"
            ),
            icon_url=ctx.author.avatar_url,
        )

        try:
            msg = await self.bot.get_channel(channels).send(embed=embed)
        except discord.HTTPException:
            return await ctx.send(_("An unexpected error occured."))
        else:
            grp = self.config.custom("REQUEST", msg.id)
            async with grp.data() as data:
                data.update(
                    channel=channels, request=request, author=ctx.author.id
                )
            self.antispam[ctx.guild][ctx.author].stamp()
            await ctx.send(
                f'{ctx.author.mention}: {_("Your request has been sent")}'
            )

        if ctx.channel.permissions_for(ctx.guild.me).manage_messages:
            try:
                await ctx.message.delete()
            except discord.HTTPException:
                pass

        if await self.config.guild(ctx.guild).add_reactions():

            for reaction in await self.config.guild(ctx.guild).reactions():
                await msg.add_reaction(reaction)
Beispiel #4
0
    async def generate_room_for(self, *, who: discord.Member,
                                source: discord.VoiceChannel):
        """
        makes autorooms
        """
        # avoid object creation for comparison, it's slower
        # manage_channels + move_members + connect
        #  i.e 16 | 16777216 | = 17825808
        if not source.guild.me.guild_permissions.value & 17825808 == 17825808:
            return

        if await self.bot.cog_disabled_in_guild_raw(self.qualified_name,
                                                    source.guild.id):
            return

        cdata = await self.ar_config.channel(source).all(acquire_lock=False)

        ownership = cdata["ownership"]
        if ownership is None:
            ownership = await self.ar_config.guild(source.guild).ownership()

        category = source.category

        overwrites: dict = self._ar_get_overwrites(source,
                                                   who=who,
                                                   ownership=ownership)

        if cdata["gameroom"]:
            cname = next((a.name for a in who.activities if a.type.value == 0),
                         "???")
        elif cdata["creatorname"]:
            cname = f"{source.name} {who.name}"
        # Stuff here might warrant a schema change to do this better.
        # Don't add this yet.
        # elif cdata["personalnamed"]:
        #     cname = f"{who}'s room"
        # elif cdata["randomname"]:
        #     pass   # TODO
        else:
            cname = source.name

        try:
            chan = await source.guild.create_voice_channel(
                cname, category=category, overwrites=overwrites)
        except discord.Forbidden:
            await self.ar_config.guild(source.guild).active.set(False)
            return
        except discord.HTTPException:
            pass
        else:
            await self.ar_config.channel(chan).clone.set(True)
            if who.id not in self._antispam:
                self._antispam[who.id] = AntiSpam(self.antispam_intervals)
            self._antispam[who.id].stamp()
            await who.move_to(chan, reason="autoroom")
            await asyncio.sleep(0.5)
            await chan.edit(bitrate=source.bitrate,
                            user_limit=source.user_limit)
Beispiel #5
0
    async def create_temp(self, ctx: commands.Context, *, channeldata: ChannelData):
        """
        Creates a temporary channel

        You can add `-u N` for some number `N` to add a user limit
        """
        if ctx.author.id not in self._antispam:
            self._antispam[ctx.author.id] = AntiSpam(self.antispam_intervals)
        if self._antispam[ctx.author.id].spammy:
            return

        channelname, user_limit = channeldata

        if not channelname:
            return await ctx.send_help()

        cat_id = await self.tmpc_config.guild(ctx.guild).category()
        if cat_id:
            cat = discord.utils.get(ctx.guild.categories, id=cat_id)
        elif await self.tmpc_config.guild(ctx.guild).current():
            cat = ctx.channel.category
        else:
            cat = None

        overwrites = dict(cat.overwrites) if cat else {}

        for target in (ctx.guild.me, ctx.author):
            p = overwrites.get(target, None) or discord.PermissionOverwrite()
            # Connect is NOT optional.
            p.update(manage_channels=True, manage_roles=True, connect=True)
            overwrites[target] = p

        opts: Dict[str, Any] = {"overwrites": overwrites}
        if cat:
            opts.update(category=cat)

        if user_limit:
            opts.update(user_limit=user_limit)

        try:
            created = await ctx.guild.create_voice_channel(channelname, **opts)
        except discord.Forbidden:
            # how?
            await self.tmpc_config.guild(ctx.guild).active.set(False)
            return
        except discord.HTTPException:
            # *sigh*
            return

        await self.tmpc_config.channel(created).is_temp.set(True)
        self._antispam[ctx.author.id].stamp()
        asyncio.create_task(self._delayed_check(ctx.guild))
        current_voice = None
        with contextlib.suppress(AttributeError):
            current_voice = ctx.author.voice.channel
            if current_voice and ctx.guild.me.guild_permissions.move_members:
                await ctx.author.move(created)
Beispiel #6
0
    async def generate_room_for(self, *, who: discord.Member,
                                source: discord.VoiceChannel):
        """
        makes autorooms
        """

        ownership = await self.config.channel(source).ownership()
        if ownership is None:
            ownership = await self.config.guild(source.guild).ownership()

        category = source.category

        editargs = {"bitrate": source.bitrate, "user_limit": source.user_limit}
        overwrites = {}
        for perm in source.overwrites:
            overwrites.update({perm[0]: perm[1]})
        if ownership:
            overwrites.update({
                who:
                discord.PermissionOverwrite(manage_channels=True,
                                            manage_roles=True)
            })

        cname = None
        if await self.config.channel(source).gameroom():
            with contextlib.suppress(Exception):
                cname = who.activity.name
            if cname is None:
                cname = "???"
        else:
            cname = source.name

        try:
            chan = await source.guild.create_voice_channel(
                cname, category=category, overwrites=overwrites)
        except discord.Forbidden:
            await self.config.guild(source.guild).active.set(False)
            return
        except discord.HTTPException:
            pass
        else:
            await self.config.channel(chan).clone.set(True)
            if who.id not in self._antispam:
                self._antispam[who.id] = AntiSpam(self.antispam_intervals)
            self._antispam[who.id].stamp()
            await who.move_to(chan, reason="autoroom")
            await asyncio.sleep(0.5)
            await chan.edit(**editargs)
    async def process_intervals(self, message: discord.Message) -> bool:
        """

        Processes the interval check for messages.

        Parameters
        ----------
        message
            A message to process
        Returns
        -------
        bool
            If action was taken on against the author of the message.
        """
        guild = message.guild
        assert guild is not None, "mypy"  # nosec
        author = message.author

        data = await self.config.guild(guild).all()

        thresh, secs = data["threshold"], data["interval"]

        if not (thresh > 0 and secs > 0):
            return False

        if guild.id not in self.antispam:
            self.antispam[guild.id] = {}

        if author.id not in self.antispam[guild.id]:
            self.antispam[guild.id][author.id] = AntiSpam(
                [(timedelta(seconds=secs), thresh)]
            )

        for _ in message.mentions:
            self.antispam[guild.id][author.id].stamp()

        if self.antispam[guild.id][author.id].spammy and not await self.is_immune(
            message
        ):
            await self.maybe_punish(message)
            return True

        return False
Beispiel #8
0
 async def pingable(
     self, ctx: commands.Context, role: discord.Role, *, message: str
 ):
     """Ping a role."""
     if await self.config.role(role).pingable() is False:
         return
     if await self.config.role(role).channel() is not None:
         if await self.config.role(role).channel() != ctx.channel.id:
             return
     if ctx.guild not in self.antispam:
         self.antispam[ctx.guild] = {}
     if ctx.author not in self.antispam[ctx.guild]:
         self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(hours=1), 1)])
     if self.antispam[ctx.guild][ctx.author].spammy:
         return await ctx.send("Uh oh, you're doing this way too frequently.", **SANITIZE_ROLES_KWARG)
     await ctx.message.delete()
     await role.edit(mentionable=True)
     await ctx.send(f"{role.mention}\n{ctx.author.mention}: {message}")
     await role.edit(mentionable=False)
     self.antispam[ctx.guild][ctx.author].stamp()
Beispiel #9
0
    async def create_temp(self, ctx: commands.Context, *, channelname: str):
        """
        Creates a temporary channel
        """
        if ctx.author.id not in self._antispam:
            self._antispam[ctx.author.id] = AntiSpam(self.antispam_intervals)
        if self._antispam[ctx.author.id].spammy:
            return

        if not channelname:
            return await ctx.send_help()

        cat_id = await self.config.guild(ctx.guild).category()
        cat = discord.utils.get(ctx.guild.categories, id=cat_id)

        ow = discord.PermissionOverwrite(manage_channels=True, manage_roles=True)
        overwrites = {ctx.guild.me: ow, ctx.author: ow}

        try:
            created = await ctx.guild.create_voice_channel(
                channelname, category=cat, overwrites=overwrites
            )
        except discord.Forbidden:
            # how?
            await self.config.guild(ctx.guild).active.set(False)
            return
        except discord.HTTPException:
            # *sigh*
            return

        await self.config.channel(created).is_temp.set(True)
        self._antispam[ctx.author.id].stamp()

        with contextlib.suppress(Exception):
            current_voice = None
            current_voice = ctx.author.voice.channel
            if current_voice and ctx.guild.me.guild_permissions.move_members:
                await ctx.author.move(created)
Beispiel #10
0
    async def suggest(self, ctx: commands.Context, *, suggestion: str):
        """Suggest something. Message is required."""
        suggest_id = await self.config.guild(ctx.guild).suggest_id()
        if suggest_id is None:
            if await self.config.toggle() is True:
                if ctx.guild.id in await self.config.ignore():
                    return await ctx.send("Uh oh, suggestions aren't enabled.")
                global_guild = self.bot.get_guild(await self.config.server_id())
                channel = get(
                    global_guild.text_channels, id=await self.config.channel_id()
                )
            else:
                return await ctx.send("Uh oh, suggestions aren't enabled.")
        else:
            channel = get(ctx.guild.text_channels, id=suggest_id)
        if channel is None:
            return await ctx.send(
                "Uh oh, looks like your Admins haven't added the required channel."
            )
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(days=1), 6)])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send("Uh oh, you're doing this way too frequently.")
        embed = discord.Embed(color=await ctx.embed_colour(), description=suggestion)
        embed.set_author(
            name=f"Suggestion by {ctx.author.display_name}",
            icon_url=ctx.author.avatar_url,
        )
        embed.set_footer(
            text=f"Suggested by {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )

        if suggest_id is None:
            if await self.config.toggle() is True:
                s_id = await self.config.next_id()
                await self.config.next_id.set(s_id + 1)
                server = 1
                content = f"Global suggestion #{s_id}"
        else:
            s_id = await self.config.guild(ctx.guild).next_id()
            await self.config.guild(ctx.guild).next_id.set(s_id + 1)
            server = ctx.guild.id
            content = f"Suggestion #{s_id}"
        msg = await channel.send(content=content, embed=embed)
        await msg.add_reaction("✅")
        await msg.add_reaction("❎")

        async with self.config.custom("SUGGESTION", server, s_id).author() as author:
            author.append(ctx.author.id)
            author.append(ctx.author.name)
            author.append(ctx.author.discriminator)
        await self.config.custom("SUGGESTION", server, s_id).stext.set(suggestion)
        await self.config.custom("SUGGESTION", server, s_id).msg_id.set(msg.id)

        self.antispam[ctx.guild][ctx.author].stamp()
        await ctx.tick()
        try:
            await ctx.author.send(
                content="Your suggestion has been sent for approval!", embed=embed
            )
        except discord.Forbidden:
            pass
Beispiel #11
0
    async def skysave(
        self,
        ctx,
        channel: Optional[discord.TextChannel] = None,
        *,
        savecontent: str = "",
    ):
        """
        Save something, anything, ill even save dick pics (forever.....)
        Options
        channel : Mention channel to specify the save destination
        """

        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}

        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([])

        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                _("Ok... Cool your f*****g jets, you've been cut off from saving anything for a bit."
                  ))

        ids = await self.config.guild(ctx.guild).boxes()
        channels = [c for c in ctx.guild.text_channels if c.id in ids]
        if channel is None:

            if not channels:
                return await ctx.send(
                    _("Cannot find channels to send to, even though configured."
                      ))

            if len(channels) == 1:
                channel, = channels
            else:
                base_error = _(
                    "Multiple save boxes available, "
                    "Specify one of the proper destinations next time, k?")
                output = f'{base_error}\n{", ".join(c.mention for c in channels)}'
                return await ctx.send(output)

        elif channel not in channels:
            return await ctx.send(
                _("Does that look like a proper save destination? Come on... try again."
                  ))

        if not savecontent:
            return await ctx.send(
                _("Please try again while including something to save"))

        perms = channel.permissions_for(ctx.guild.me)
        if not (perms.send_messages and perms.embed_links):
            return await ctx.send(
                _("I don't have the required permissions... I am useless, self-destruct initiated."
                  ))

        embed = discord.Embed(color=(await ctx.embed_color()),
                              description=savecontent)
        # embed = discord.Embed(color=(await ctx.embed_color()), description=suggestion)
        embed.set_author(
            name=_("Saved by {author_info}").format(
                author_info=f"{ctx.author.display_name} ({ctx.author.id})"),
            icon_url=ctx.author.avatar_url,
        )

        try:
            msg = await channel.send(embed=embed)
        except discord.HTTPException:
            return await ctx.send(_("An unexpected error occured."))
        else:
            grp = self.config.custom("SUGGESTION", msg.id)
            async with grp.data() as data:
                data.update(channel=channel.id,
                            savecontent=savecontent,
                            author=ctx.author.id)
            self.antispam[ctx.guild][ctx.author].stamp()
            await ctx.send(
                f'{ctx.author.mention}: {_("Your... whatever that is... was successfully saved")}'
            )

        if ctx.channel.permissions_for(ctx.guild.me).manage_messages:
            try:
                await ctx.message.delete()
            except discord.HTTPException:
                pass

        if await self.config.guild(ctx.guild).add_reactions():

            for reaction in await self.config.guild(ctx.guild).reactions():
                await msg.add_reaction(reaction)
Beispiel #12
0
    async def apply(self, ctx: commands.Context):
        """Apply to be a staff member."""
        if not await self.config.guild(ctx.guild).is_set():
            return await ctx.send(
                "Uh oh, the configuration is not correct. Ask the Admins to set it."
            )

        if await self.config.guild(ctx.guild).applicant_role():
            try:
                role_add = get(ctx.guild.roles,
                               id=await
                               self.config.guild(ctx.guild).applicant_id())
            except TypeError:
                role_add = None
            if not role_add:
                role_add = get(ctx.guild.roles, name="Staff Applicant")
                if not role_add:
                    return await ctx.send(
                        "Uh oh, the configuration is not correct. Ask the Admins to set it."
                    )
        try:
            channel = get(ctx.guild.text_channels,
                          id=await self.config.guild(ctx.guild).channel_id())
        except TypeError:
            channel = None
        if not channel:
            channel = get(ctx.guild.text_channels, name="applications")
            if not channel:
                return await ctx.send(
                    "Uh oh, the configuration is not correct. Ask the Admins to set it."
                )
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([
                (timedelta(days=2), 1)
            ])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                "Uh oh, you're doing this way too frequently.")
        if not role_add:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required role."
            )
        if not channel:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )
        try:
            await ctx.author.send("Let's start right away!")
        except discord.Forbidden:
            return await ctx.send(
                "I don't seem to be able to DM you. Do you have closed DMs?")
        await ctx.send(f"Okay, {ctx.author.mention}, I've sent you a DM.")

        embed = discord.Embed(color=await ctx.embed_colour(),
                              timestamp=datetime.now())
        embed.set_author(name="New application!",
                         icon_url=ctx.author.avatar_url)
        embed.set_footer(
            text=
            f"{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})")
        embed.title = (
            f"User: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )

        def check(m):
            return m.author == ctx.author and m.channel == ctx.author.dm_channel

        questions = await self.config.guild(ctx.guild
                                            ).questions()  # list of lists
        default_questions = await self._default_questions_list(
        )  # default list of lists just in case
        for i, question in enumerate(questions):  # for list in lists
            try:
                await ctx.author.send(question[0])
                timeout = question[2]
                shortcut = question[1]
            except TypeError:
                await ctx.author.send(default_questions[i][0])
                timeout = default_questions[i][2]
                shortcut = default_questions[i][1]
            try:
                answer = await self.bot.wait_for("message",
                                                 timeout=timeout,
                                                 check=check)
            except asyncio.TimeoutError:
                return await ctx.author.send(
                    "You took too long. Try again, please.")
            embed.add_field(name=shortcut + ":", value=answer.content)

        await channel.send(embed=embed)

        await ctx.author.add_roles(role_add)
        await ctx.author.send(
            "Your application has been sent to the Admins, thank you!")
        self.antispam[ctx.guild][ctx.author].stamp()
Beispiel #13
0
    async def suggest(self, ctx: commands.Context, *, suggestion: str):
        """Suggest something. Message is required."""
        suggest_id = await self.config.guild(ctx.guild).suggest_id()
        if not suggest_id:
            if await self.config.toggle():
                if ctx.guild.id in await self.config.ignore():
                    return await ctx.send("Uh oh, suggestions aren't enabled.")
                global_guild = self.bot.get_guild(await
                                                  self.config.server_id())
                channel = get(global_guild.text_channels,
                              id=await self.config.channel_id())
            else:
                return await ctx.send("Uh oh, suggestions aren't enabled.")
        else:
            channel = get(ctx.guild.text_channels, id=suggest_id)
        if not channel:
            return await ctx.send(
                "Uh oh, looks like your Admins haven't added the required channel."
            )
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([
                (timedelta(days=1), 6)
            ])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                "Uh oh, you're doing this way too frequently.")
        embed = discord.Embed(color=await ctx.embed_colour(),
                              description=suggestion)
        embed.set_author(
            name=f"Suggestion by {ctx.author.display_name}",
            icon_url=ctx.author.avatar_url,
        )
        embed.set_footer(
            text=
            f"Suggested by {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )

        if not suggest_id:
            if await self.config.toggle():
                s_id = await self.config.next_id()
                await self.config.next_id.set(s_id + 1)
                server = 1
                content = f"Global suggestion #{s_id}"
        else:
            s_id = await self.config.guild(ctx.guild).next_id()
            await self.config.guild(ctx.guild).next_id.set(s_id + 1)
            server = ctx.guild.id
            content = f"Suggestion #{s_id}"
        msg = await channel.send(content=content, embed=embed)

        up_emoji = self.bot.get_emoji(await
                                      self.config.guild(ctx.guild).up_emoji())
        if not up_emoji:
            up_emoji = "✅"
        down_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild
                                                                ).down_emoji())
        if not down_emoji:
            down_emoji = "❎"
        await msg.add_reaction(up_emoji)
        await msg.add_reaction(down_emoji)

        async with self.config.custom("SUGGESTION", server,
                                      s_id).author() as author:
            author.append(ctx.author.id)
            author.append(ctx.author.name)
            author.append(ctx.author.discriminator)
        await self.config.custom("SUGGESTION", server,
                                 s_id).stext.set(suggestion)
        await self.config.custom("SUGGESTION", server, s_id).msg_id.set(msg.id)

        self.antispam[ctx.guild][ctx.author].stamp()
        if await self.config.guild(ctx.guild).delete_suggest():
            await ctx.message.delete()
        else:
            await ctx.tick()

        if await self.config.guild(ctx.guild).create_threads():
            # always use max archive, function will clip it if needed
            try:
                thread = await create_thread(self.bot,
                                             channel,
                                             msg,
                                             name=content,
                                             archive=10080)
                await add_user_thread(self.bot, thread, ctx.author)
            except:
                await ctx.send(
                    "Error in creating a thread for this suggestion, please check permissions!"
                )

        try:
            await ctx.author.send(
                content="Your suggestion has been sent for approval!",
                embed=embed)
        except discord.Forbidden:
            pass
Beispiel #14
0
    async def apply(self, ctx: commands.Context):
        """Apply to be a staff member."""
        author = ctx.author
        guild = ctx.guild
        bot = self.bot
        role_add = get(guild.roles, name="Staff Applicant")
        channel = get(guild.text_channels, name="applications")
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([
                (timedelta(days=2), 1)
            ])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                "Uh oh, you're doing this way too frequently.")

        if role_add is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required role."
            )

        if channel is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )

        try:
            await author.send(
                "Let's start right away! You have maximum of 5 hours for each question.\nWhat position are you applying for?"
            )
        except discord.Forbidden:
            return await ctx.send(
                "I don't seem to be able to DM you. Do you have closed DMs?")

        await ctx.send("Okay, {0}, I've sent you a DM.".format(author.mention))

        def check(m):
            return m.author == author and m.channel == author.dm_channel

        try:
            position = await bot.wait_for("message",
                                          timeout=18000,
                                          check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send("What is your Steam IGN?")
        try:
            steamname = await bot.wait_for("message",
                                           timeout=18000,
                                           check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send(
            "What is your Steam ID? (Get it here: https://steamid.io/)")
        try:
            steamid = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send("What is your age?")
        try:
            age = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send("What is your time zone? (Google is your bestfriend)"
                          )
        try:
            timezone = await bot.wait_for("message",
                                          timeout=18000,
                                          check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send("What is your availability?")
        try:
            availability = await bot.wait_for("message",
                                              timeout=18000,
                                              check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send("Tell us about your self:")
        try:
            tellus = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send(
            "What experiences have you had before as an admin/moderator before?"
        )
        try:
            admexp = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send(
            "How many hours have you put in as an Admin/Moderator?:")
        try:
            hoursmod = await bot.wait_for("message",
                                          timeout=18000,
                                          check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send(
            "What can you bring to Omega Rust if you were selected?")
        try:
            bringomega = await bot.wait_for("message",
                                            timeout=18000,
                                            check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send("Have you ever used a hacked client before?:")
        try:
            hackedclient = await bot.wait_for("message",
                                              timeout=18000,
                                              check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        await author.send(
            "Have you ever been banned on a Rust server? If so, why and where?:"
        )
        try:
            banned = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await author.send("What do you consider your greatest strength?:")
        try:
            strength = await bot.wait_for("message",
                                          timeout=18000,
                                          check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await author.send("What do you consider your greatest weakness?:")
        try:
            weakness = await bot.wait_for("message",
                                          timeout=18000,
                                          check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await author.send("How active do you consider your self on Omega?:")
        try:
            active = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await author.send(
            "What would you do if someone breaks a rule in-game? Scenario (as a staff member): You log onto one of our servers, and you’re told that a clan is hacking."
        )
        try:
            Scenario = await bot.wait_for("message",
                                          timeout=18000,
                                          check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await author.send("Do you have a working microphone?")
        try:
            mic = await bot.wait_for("message", timeout=18000, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await author.send("Anything else we should know about you?")
        try:
            elseabout = await bot.wait_for("message",
                                           timeout=18000,
                                           check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        embed = discord.Embed(color=await ctx.embed_colour(),
                              timestamp=datetime.now())
        embed.set_author(name="New application!", icon_url=author.avatar_url)
        embed.set_footer(text="{0}#{1} ({2})".format(
            author.name, author.discriminator, author.id))
        embed.title = "User: {0}#{1} ({2})".format(author.name,
                                                   author.discriminator,
                                                   author.id)
        embed.add_field(name="Position:", value=position.content, inline=True)
        embed.add_field(name="Steam:", value=steamname.content, inline=True)
        embed.add_field(name="Steam ID:", value=steamid.content, inline=True)
        embed.add_field(name="Age:", value=age.content, inline=True)
        embed.add_field(name="Timezone:", value=timezone.content, inline=True)
        embed.add_field(name="Availability:",
                        value=availability.content,
                        inline=True)
        embed.add_field(
            name="How many hours have you put in as an Admin/Moderator?:",
            value=hoursmod.content,
            inline=False)
        embed.add_field(
            name="What can you bring to Omega Rust if you were selected?:",
            value=bringomega.content,
            inline=False)
        embed.add_field(name="Have you ever used a hacked client before?:",
                        value=hackedclient.content,
                        inline=False)
        embed.add_field(
            name=
            "Have you ever been banned on a Rust server? If so, why and where?:",
            value=banned.content,
            inline=False)
        embed.add_field(name="What do you consider your greatest strength?:",
                        value=strength.content,
                        inline=False)
        embed.add_field(name="What do you consider your greatest weakness?:",
                        value=weakness.content,
                        inline=False)
        embed.add_field(name="How active do you consider your self on Omega?:",
                        value=active.content,
                        inline=False)
        embed.add_field(
            name=
            "What would you do if someone breaks a rule in-game? Scenario (as a staff member): You log onto one of our servers, and you’re told that a clan is hacking.:",
            value=Scenario.content,
            inline=False)
        embed.add_field(name="Do you have a working microphone?:",
                        value=mic.content,
                        inline=False)
        embed.add_field(name="Anything else we should know about you?:",
                        value=elseabout.content,
                        inline=False)

        await channel.send(embed=embed)

        await author.add_roles(role_add)

        await author.send(
            "Your application has been sent to the Admins, thank you!")
        self.antispam[ctx.guild][ctx.author].stamp()
    async def suggest(self, ctx: commands.Context, *, suggestion: str):
        """Suggest something. Message is required."""
        suggest_id = await self.config.guild(ctx.guild).suggest_id()
        if not suggest_id:
            if await self.config.toggle():
                if ctx.guild.id in await self.config.ignore():
                    return await ctx.send("Uh oh, suggestions aren't enabled.")
                global_guild = self.bot.get_guild(await
                                                  self.config.server_id())
                channel = get(global_guild.text_channels,
                              id=await self.config.channel_id())
            else:
                return await ctx.send("Uh oh, suggestions aren't enabled.")
        else:
            channel = get(ctx.guild.text_channels, id=suggest_id)
        if not channel:
            return await ctx.send(
                "Uh oh, looks like your Admins haven't added the required channel."
            )
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([
                (timedelta(days=1), 6)
            ])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                "Uh oh, you're doing this way too frequently.")
        embed = discord.Embed(color=await ctx.embed_colour(),
                              description=suggestion)
        embed.set_author(
            name=f"Suggestion by {ctx.author.display_name}",
            icon_url=ctx.author.avatar_url,
        )
        embed.set_footer(
            text=
            f"Suggested by {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )

        if not suggest_id:
            if await self.config.toggle():
                s_id = await self.config.next_id()
                await self.config.next_id.set(s_id + 1)
                server = 1
                content = f"Global suggestion #{s_id}"
        else:
            s_id = await self.config.guild(ctx.guild).next_id()
            await self.config.guild(ctx.guild).next_id.set(s_id + 1)
            server = ctx.guild.id
            content = f"Suggestion #{s_id}"
        msg = await channel.send(content=content, embed=embed)

        up_emoji = self.bot.get_emoji(await
                                      self.config.guild(ctx.guild).up_emoji())
        if not up_emoji:
            up_emoji = "✅"
        down_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild
                                                                ).down_emoji())
        if not down_emoji:
            down_emoji = "❎"
        await msg.add_reaction(up_emoji)
        await msg.add_reaction(down_emoji)

        async with self.config.custom("SUGGESTION", server,
                                      s_id).author() as author:
            author.append(ctx.author.id)
            author.append(ctx.author.name)
            author.append(ctx.author.discriminator)
        await self.config.custom("SUGGESTION", server,
                                 s_id).stext.set(suggestion)
        await self.config.custom("SUGGESTION", server, s_id).msg_id.set(msg.id)

        message = ctx.message
        await asyncio.sleep(4)
        await message.delete()
Beispiel #16
0
    async def report(self, ctx: commands.Context, *, _report: str = ""):
        """Send a report.

        Use without arguments for interactive reporting, or do
        `[p]report <text>` to use it non-interactively.
        """
        author = ctx.author
        guild = ctx.guild
        if guild is None:
            guild = await self.discover_guild(
                author,
                prompt=_("Select a server to make a report in by number."))
        if guild is None:
            return
        g_active = await self.config.guild(guild).active()
        if not g_active:
            return await author.send(
                _("Reporting has not been enabled for this server"))
        if guild.id not in self.antispam:
            self.antispam[guild.id] = {}
        if author.id not in self.antispam[guild.id]:
            self.antispam[guild.id][author.id] = AntiSpam(self.intervals)
        if self.antispam[guild.id][author.id].spammy:
            return await author.send(
                _("You've sent too many reports recently. "
                  "Please contact a server admin if this is important matter, "
                  "or please wait and try again later."))
        if author.id in self.user_cache:
            return await author.send(
                _("Please finish making your prior report before trying to make an "
                  "additional one!"))
        self.user_cache.append(author.id)

        if _report:
            _m = copy(ctx.message)
            _m.content = _report
            _m.content = _m.clean_content
            val = await self.send_report(_m, guild)
        else:
            try:
                await author.send(
                    _("Please respond to this message with your Report."
                      "\nYour report should be a single message"))
            except discord.Forbidden:
                return await ctx.send(_("This requires DMs enabled."))

            try:
                message = await self.bot.wait_for(
                    "message",
                    check=MessagePredicate.same_context(
                        ctx, channel=author.dm_channel),
                    timeout=180,
                )
            except asyncio.TimeoutError:
                return await author.send(
                    _("You took too long. Try again later."))
            else:
                val = await self.send_report(message, guild)

        with contextlib.suppress(discord.Forbidden, discord.HTTPException):
            if val is None:
                if await self.config.guild(ctx.guild).output_channel() is None:
                    await author.send(
                        _("This server has no reports channel set up. Please contact a server admin."
                          ))
                else:
                    await author.send(
                        _("There was an error sending your report, please contact a server admin."
                          ))
            else:
                await author.send(
                    _("Your report was submitted. (Ticket #{})").format(val))
                self.antispam[guild.id][author.id].stamp()
Beispiel #17
0
    async def suggest(
        self,
        ctx: commands.GuildContext,
        channel: Optional[discord.TextChannel] = None,
        *,
        suggestion: str = "",
    ):
        """
        Suggest something.

        Options
        channel : Mention channel to specify which channel to suggest to
        """

        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}

        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([])

        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                _("You've sent too many suggestions recently."))

        if not suggestion:
            return await ctx.send(
                _("Please try again while including a suggestion."))

        channel = await self.get_suggestion_channel(ctx, channel)
        if not channel:
            return

        perms = channel.permissions_for(ctx.guild.me)
        if not (perms.send_messages and perms.embed_links):
            return await ctx.send(_("I don't have the required permissions"))

        embed = discord.Embed(color=(await ctx.embed_color()),
                              description=suggestion)

        embed.set_author(
            name=_("New suggestion from {author_info}").format(
                author_info=f"{ctx.author.display_name} ({ctx.author.id})"),
            icon_url=ctx.author.avatar_url,
        )

        try:
            msg = await channel.send(embed=embed)
        except discord.HTTPException:
            return await ctx.send(_("An unexpected error occured."))
        else:
            grp = self.config.custom("SUGGESTION", msg.id)
            async with grp.data() as data:
                data.update(channel=channel.id,
                            suggestion=suggestion,
                            author=ctx.author.id)
            self.antispam[ctx.guild][ctx.author].stamp()
            await ctx.send(
                f'{ctx.author.mention}: {_("Your suggestion has been sent")}')

        if ctx.channel.permissions_for(ctx.guild.me).manage_messages:
            try:
                await ctx.message.delete()
            except discord.HTTPException:
                pass

        if await self.config.guild(ctx.guild).add_reactions():

            for reaction in await self.config.guild(ctx.guild).reactions():
                await msg.add_reaction(reaction)
Beispiel #18
0
    async def apply(self, ctx: commands.Context):
        """Apply for free agency."""
        role_add = get(ctx.guild.roles, name="Free Agent")
        channel = get(ctx.guild.text_channels, name="free-agent-applications")
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(days=2), 1)])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send("Uh oh, you're doing this way too frequently.")
        if role_add is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required role."
            )
        if channel is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )
        try:
            await ctx.author.send(
                "Let's start right away! You have maximum of 2 minutes for each question. Are you applying for free agency?"
            )
        except discord.Forbidden:
            return await ctx.send(
                "I don't seem to be able to DM you. Do you have closed DMs?"
            )
        await ctx.send(f"Okay, {ctx.author.mention}, I've sent you a DM.")

        def check(m):
            return m.author == ctx.author and m.channel == ctx.author.dm_channel

        try:
            position = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("What is your name?")
        try:
            name = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("rank?")
        try:
            age = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("Region?")
        try:
            timezone = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("Strengths?")
        try:
            days = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("Weaknesses?")
        try:
            hours = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "Please tell the teams about you."
        )
        try:
            experience = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("What teams are you interested in?")
        try:
            reason = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        embed = discord.Embed(color=await ctx.embed_colour(), timestamp=datetime.now())
        embed.set_author(name="Free Agent Application!", icon_url=ctx.author.avatar_url)
        embed.set_footer(
            text=f"{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.title = (
            f"User: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.add_field(name="Name:", value=name.content, inline=True)
        embed.add_field(name="Rank:", value=age.content, inline=True)
        embed.add_field(name="Region:", value=timezone.content, inline=True)
        embed.add_field(name="Free Agent:", value=position.content, inline=True)
        embed.add_field(name="Strengths:", value=days.content, inline=True)
        embed.add_field(name="Weaknesses:", value=hours.content, inline=True)
        embed.add_field(
            name="About me:", value=experience.content, inline=False
        )
        embed.add_field(name="Teams interested in:", value=reason.content, inline=False)

        await channel.send(embed=embed)

        await ctx.author.add_roles(role_add)

        await ctx.author.send(
            "Your application has been sent to the Admins, thank you!"
        )
        self.antispam[ctx.guild][ctx.author].stamp()
    async def apply(self, ctx: commands.Context):
        """Apply to be a staff member."""
        try:
            role_add = get(
                ctx.guild.roles, id=await self.config.guild(ctx.guild).applicant_id()
            )
        except TypeError:
            role_add = None
        if not role_add:
            role_add = get(ctx.guild.roles, name="Staff Applicant")
            if not role_add:
                return await ctx.send(
                    "Uh oh, the configuration is not correct. Ask the Admins to set it."
                )
        try:
            channel = get(
                ctx.guild.text_channels,
                id=await self.config.guild(ctx.guild).channel_id(),
            )
        except TypeError:
            channel = None
        if not channel:
            channel = get(ctx.guild.text_channels, name="applications")
            if not channel:
                return await ctx.send(
                    "Uh oh, the configuration is not correct. Ask the Admins to set it."
                )
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(days=2), 1)])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send("Uh oh, you're doing this way too frequently.")
        if not role_add:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required role."
            )
        if not channel:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )
        try:
            await ctx.author.send(
                "Let's start right away! You have maximum of 2 minutes for each question.\nWhat position are you applying for?"
            )
        except discord.Forbidden:
            return await ctx.send(
                "I don't seem to be able to DM you. Do you have closed DMs?"
            )
        await ctx.send(f"Okay, {ctx.author.mention}, I've sent you a DM.")

        def check(m):
            return m.author == ctx.author and m.channel == ctx.author.dm_channel

        try:
            position = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("What is your name?")
        try:
            name = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("How old are you?")
        try:
            age = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("What timezone are you in? (Google is your friend.)")
        try:
            timezone = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("How many days per week can you be active?")
        try:
            days = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("How many hours per day can you be active?")
        try:
            hours = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "Do you have any previous experience? If so, please describe."
        )
        try:
            experience = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("Tell us a bit about yourself?")
        try:
            about = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("What do you like the most about our server?")
        try:
            like = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "How do you suppose you can help the server by being a staff member?"
        )
        try:
            helpz = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "Do you have any other skills except moderation? (like gfx designing/coding) [If yes, describe briefly and provide proof of some of your work] (Send 0 or i dont if you don't want to answer)"
        )
        try:
            skills = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "Are you fully aware of our server rules and Discord TOS?"
        )
        try:
            tos = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")

        embed = discord.Embed(color=await ctx.embed_colour(), timestamp=datetime.now())
        embed.set_author(name="New application!", icon_url=ctx.author.avatar_url)
        embed.set_footer(
            text=f"{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.title = (
            f"User: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.add_field(name="Name:", value=name.content, inline=True)
        embed.add_field(name="Age:", value=age.content, inline=True)
        embed.add_field(name="Timezone:", value=timezone.content, inline=True)
        embed.add_field(name="Desired position:", value=position.content, inline=True)
        embed.add_field(name="Active days/week:", value=days.content, inline=True)
        embed.add_field(name="Active hours/day:", value=hours.content, inline=True)
        embed.add_field(
            name="Previous experience:", value=experience.content, inline=False
        )
        embed.add_field(name="About:", value=about.content, inline=False)
        embed.add_field(name="Like About The Server:", value=like.content, inline=False)
        embed.add_field(name="Help The Server:", value=helpz.content, inline=False)
        embed.add_field(name="Additional Skill:", value=skills.content, inline=False)
        embed.add_field(name="Rules & TOS:", value=tos.content, inline=False)

        await channel.send(embed=embed)

        await ctx.author.add_roles(role_add)

        await ctx.author.send(
            "Your application has been sent to the Admins, thank you!"
        )
        self.antispam[ctx.guild][ctx.author].stamp()
Beispiel #20
0
    async def apply(self, ctx: commands.Context):
        """Apply to be a staff member."""
        role_add = get(ctx.guild.roles, name="Staff Applicant")
        app_data = await self.config.guild(ctx.guild).app_questions.all()
        user_data = self.config.member(ctx.author)

        channel = get(ctx.guild.text_channels, name="staff-applications")
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(hours=6), 1)])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                f"{ctx.author.mention} uh you're doing this way too frequently, and we don't need more than one application from you. Don't call us, we will maybe call you...LOL",
                delete_after=10,
            )
        if role_add is None:
            return await ctx.send("Uh oh. Looks like your Admins haven't added the required role.")
        if role_add.position > ctx.guild.me.top_role.position:
            return await ctx.send(
                "The staff applicant role is above me, and I need it below me if I am to assign it on completion. Tell your admins"
            )

        if channel is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )
        available_positions = await self.config.guild(ctx.guild).positions_available()
        if available_positions is None:
            fill_this = "Reply with the position you are applying for to continue."
        else:
            list_positions = "\n".join(available_positions)
            fill_this = "Reply with the desired position from this list to continue\n`{}`".format(
                list_positions
            )
        try:
            await ctx.author.send(
                f"Let's do this! You have maximum of __5 minutes__ for each question.\n{fill_this}\n\n*To cancel at anytime respond with `cancel`*\n\n*DISCLAIMER: Your responses are stored for proper function of this feature*"
            )
        except discord.Forbidden:
            return await ctx.send(
                f"{ctx.author.mention} I can't DM you. Do you have them closed?", delete_after=10
            )
        await ctx.send(f"Okay, {ctx.author.mention}, I've sent you a DM.", delete_after=7)

        def check(m):
            return m.author == ctx.author and m.channel == ctx.author.dm_channel

        try:
            position = await self.bot.wait_for("message", timeout=300, check=check)
            if position.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.position.set(position.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        await ctx.author.send(app_data["name"])
        try:
            name = await self.bot.wait_for("message", timeout=300, check=check)
            if name.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.name.set(name.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        await ctx.author.send(app_data["timezone"])
        try:
            timezone = await self.bot.wait_for("message", timeout=300, check=check)
            if timezone.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.timezone.set(timezone.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        await ctx.author.send(app_data["age"])
        try:
            age = await self.bot.wait_for("message", timeout=300, check=check)
            if age.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            a = age.content
            b = str(datetime.today())
            c = b[:4]
            d = int(c)
            try:
                e = int(a)
                yearmath = d - e
                total_age = f"YOB: {a}\n{yearmath} years old"
            except Exception:
                total_age = f"Recorded response of `{a}`. Could not calculate age."

            await user_data.age.set(total_age)

        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return

        await ctx.author.send(app_data["days"])
        try:
            days = await self.bot.wait_for("message", timeout=300, check=check)
            if days.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.days.set(days.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        await ctx.author.send(app_data["hours"])
        try:
            hours = await self.bot.wait_for("message", timeout=300, check=check)
            if hours.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.hours.set(hours.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        await ctx.author.send(app_data["experience"])
        try:
            experience = await self.bot.wait_for("message", timeout=300, check=check)
            if experience.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.experience.set(experience.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        await ctx.author.send(app_data["reasonforinterest"])
        try:
            reasonforinterest = await self.bot.wait_for("message", timeout=300, check=check)
            if reasonforinterest.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.reasonforinterest.set(reasonforinterest.content)
        except asyncio.TimeoutError:
            try:
                await ctx.author.send("You took too long. Try again, please.")
            except discord.HTTPException:
                return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
            return
        check_8 = app_data["question8"]
        if check_8 is not None:
            await ctx.author.send(app_data["question8"])
            try:
                answer8 = await self.bot.wait_for("message", timeout=300, check=check)
                if answer8.content.lower() == "cancel":
                    return await ctx.author.send("Application has been canceled.")
                await user_data.answer8.set(answer8.content)
            except asyncio.TimeoutError:
                try:
                    await ctx.author.send("You took too long. Try again, please.")
                except discord.HTTPException:
                    return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
                return
        check_9 = app_data["question9"]
        if check_9 is not None:
            await ctx.author.send(app_data["question9"])
            try:
                answer9 = await self.bot.wait_for("message", timeout=300, check=check)
                if answer9.content.lower() == "cancel":
                    return await ctx.author.send("Application has been canceled.")
                await user_data.answer9.set(answer9.content)
            except asyncio.TimeoutError:
                try:
                    await ctx.author.send("You took too long. Try again, please.")
                except discord.HTTPException:
                    return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
                return
        check_10 = app_data["question10"]
        if check_10 is not None:
            await ctx.author.send(app_data["question10"])
            try:
                answer10 = await self.bot.wait_for("message", timeout=300, check=check)
                if answer10.content.lower() == "cancel":
                    return await ctx.author.send("Application has been canceled.")
                await user_data.answer10.set(answer10.content)
            except asyncio.TimeoutError:
                try:
                    await ctx.author.send("You took too long. Try again, please.")
                except discord.HTTPException:
                    return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
                return
        check_11 = app_data["question11"]
        if check_11 is not None:
            await ctx.author.send(app_data["question11"])
            try:
                answer11 = await self.bot.wait_for("message", timeout=300, check=check)
                if answer11.content.lower() == "cancel":
                    return await ctx.author.send("Application has been canceled.")
                await user_data.answer11.set(answer11.content)
            except asyncio.TimeoutError:
                try:
                    await ctx.author.send("You took too long. Try again, please.")
                except discord.HTTPException:
                    return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
                return
        check_12 = app_data["question12"]
        if check_12 is not None:
            await ctx.author.send(app_data["question12"])
            try:
                answer12 = await self.bot.wait_for("message", timeout=300, check=check)
                if answer12.content.lower() == "cancel":
                    return await ctx.author.send("Application has been canceled.")
                await user_data.answer12.set(answer12.content)
            except asyncio.TimeoutError:
                try:
                    await ctx.author.send("You took too long. Try again, please.")
                except discord.HTTPException:
                    return await ctx.send(f"Thanks for nothing, {ctx.author.mention}")
                return

        await ctx.author.send(app_data["finalcomments"])
        try:
            finalcomments = await self.bot.wait_for("message", timeout=300, check=check)
            if finalcomments.content.lower() == "cancel":
                return await ctx.author.send("Application has been canceled.")
            await user_data.finalcomments.set(finalcomments.content)
        except asyncio.TimeoutError:
            return await ctx.author.send("You took too long. Try again, please.")

        embed = discord.Embed(color=await ctx.embed_colour(), timestamp=datetime.utcnow())
        embed.set_author(
            name=f"Applicant: {ctx.author.name} | ID: {ctx.author.id}",
            icon_url=ctx.author.avatar_url,
        )
        embed.set_footer(
            text=f"{ctx.author.name}#{ctx.author.discriminator} UserID: {ctx.author.id}"
        )
        embed.title = f"Application for {position.content}"
        embed.add_field(
            name="Applicant Name:",
            value=f"Mention: {ctx.author.mention}\nPreferred: " + name.content,
            inline=True,
        )
        embed.add_field(
            name="Age",
            value=total_age,
            inline=True,
        )
        embed.add_field(name="Timezone:", value=timezone.content, inline=True)
        embed.add_field(name="Desired position:", value=position.content, inline=True)
        embed.add_field(name="Active days/week:", value=days.content, inline=True)
        embed.add_field(name="Active hours/day:", value=hours.content, inline=True)
        embed.add_field(
            name="{}...".format(app_data["reasonforinterest"][:197]).replace("$", "\\$"),
            value=reasonforinterest.content,
            inline=False,
        )
        embed.add_field(name="Previous experience:", value=experience.content, inline=False)

        if check_8 is not None:
            embed.add_field(
                name="{}...".format(app_data["question8"][:197]).replace("$", "\\$"),
                value=answer8.content,
                inline=False,
            )
        if check_9 is not None:
            embed.add_field(
                name="{}...".format(app_data["question9"][:197]).replace("$", "\\$"),
                value=answer9.content,
                inline=False,
            )
        if check_10 is not None:
            embed.add_field(
                name="{}...".format(app_data["question10"][:197]).replace("$", "\\$"),
                value=answer10.content,
                inline=False,
            )
        if check_11 is not None:
            embed.add_field(
                name="{}...".format(app_data["question11"][:197]).replace("$", "\\$"),
                value=answer11.content,
                inline=False,
            )
        if check_12 is not None:
            embed.add_field(
                name="{}...".format(app_data["question12"][:197]).replace("$", "\\$"),
                value=answer12.content,
                inline=False,
            )
        embed.add_field(name="Final Comments", value=finalcomments.content, inline=False)
        try:
            webhook = None
            for hook in await channel.webhooks():
                if hook.name == ctx.guild.me.name:
                    webhook = hook
            if webhook is None:
                webhook = await channel.create_webhook(name=ctx.guild.me.name)

            await webhook.send(
                embed=embed, username=ctx.guild.me.display_name, avatar_url=ctx.guild.me.avatar_url
            )
        except Exception as e:
            log.info(f"{e} occurred in {ctx.author.name} | {ctx.author.id} application")
            try:
                return await ctx.author.send(
                    "Seems your responses were too verbose. Let's try again, but without the life stories."
                )
            except Exception:
                return
        # except discord.HTTPException:
        #     return await ctx.author.send(
        #         "Your final application was too long to resolve as an embed. Give this another shot, keeping answers a bit shorter."
        #     )
        # except commands.CommandInvokeError:
        #     return await ctx.author.send(
        #         "You need to start over but this time when it asks for year of birth, respond only with a 4 digit year i.e `1999`"
        #     )
        await ctx.author.add_roles(role_add)

        try:
            await ctx.author.send(
                f"Your application has been sent to {ctx.guild.name} Admins! Thanks for your interest!"
            )
        except commands.CommandInvokeError:
            return await ctx.send(
                f"{ctx.author.mention} I sent your app to the admins. Thanks for closing dms early tho rude ass"
            )
        self.antispam[ctx.guild][ctx.author].stamp()
        # lets save the embed instead of calling on it again
        await self.save_application(embed=embed, applicant=ctx.author)

        await self.config.member(ctx.author).app_check.set(True)
Beispiel #21
0
    async def volunteer(self, ctx: commands.Context):
        """Apply to be a staff member."""
        try:
            role_add = get(ctx.guild.roles, id = await self.config.guild(ctx.guild).applicant_id())
        except TypeError:
            role_add = None
        if not role_add:
            role_add = get(ctx.guild.roles, name = "Volunteering")
            if not role_add:
                return await ctx.send("Uh oh, the configuration is not correct. Ask the Admins to set it.")
        try:
            channel = get(ctx.guild.text_channels, id = await self.config.guild(ctx.guild).channel_id())
        except TypeError:
            channel = None
        if not channel:
            channel = get(ctx.guild.text_channels, name = "volunteer applications")
            if not channel:
                return await ctx.send("Uh oh, the configuration is not correct. Ask the Admins to set it.")
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(minutes=30), 1)])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send("Uh oh, you're doing this way too frequently.")
        if not role_add:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required role."
            )
        if not channel:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )
        try:
            await ctx.author.send(
                """
**Looking to join one of the xH Community Support Teams?**
The roles listed below are currently looking for volunteers.  We have a few questions just to get a little background/info.

**__Moderator Team:__** Volunteers that help monitor and maintain the communities rules and values in our discord.

**__Development Team:__** A group of hobbyist and professionals that assist in gameserver creation, server management, game modding, website development, support the Community Outreach Team, etc.

**__Design Team:__** They make the community look awesome...  The creative members of the community that have talent in the design world and help with logos, website design, gameserver design, support the Community Outreach Team, etc..

**__Community Outreach:__** This group contains the approved community streamers, social media platform team, community youtube content creators, coordinates community Events, giveaways and raffles. 

~~**__Game Server Admins__** - Volunteers to assist in our active game servers.~~ *Coming soon! Check back later.*

```diff\n- Applications will be reviewed by the xH Community Council.  A update from the team will be sent to you no longer then 7 days after app is submitted.  We tend to move faster then this, however life has been difficult for all this year.
```
***What position are you applying for?***
*You have maximum of 15 minutes for each following question.*              
                """
            )
        except discord.Forbidden:
            return await ctx.send(
                "I don't seem to be able to DM you. Do you have DM's turned off?"
            )
        await ctx.send(f"Okay, {ctx.author.mention}, i've sent your a DM.")

        def check(m):
            return m.author == ctx.author and m.channel == ctx.author.dm_channel

        try:
            position = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        await ctx.author.send("What is your name?")
        try:
            name = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("You took too long. Try again, please.")
        await ctx.author.send("How old are you?")
        try:
            age = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        await ctx.author.send("What timezone are you in? (Google is your friend.)")
        try:
            timezone = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        await ctx.author.send("How many days per week can you be active?")
        try:
            days = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        await ctx.author.send("How many hours per day can you be active?")
        try:
            hours = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        await ctx.author.send(
            "Do you have any previous experience? If so, please describe."
        )
        try:
            experience = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        await ctx.author.send("Why do you want to be a member of our team?")
        try:
            reason = await self.bot.wait_for("message", timeout=900, check=check)
        except asyncio.TimeoutError:
            return await ctx.author.send("```diff\n- You took too long. Try again, please.```")
        embed = discord.Embed(color=await ctx.embed_colour(), timestamp=datetime.now())
        embed.set_author(name="Volunteer Application!", icon_url=ctx.author.avatar_url)
        embed.set_footer(
            text=f"{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.title = (
            f"User: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.add_field(name="Name:", value=name.content, inline=True)
        embed.add_field(name="Age:", value=age.content, inline=True)
        embed.add_field(name="Timezone:", value=timezone.content, inline=True)
        embed.add_field(name="Desired position:", value=position.content, inline=True)
        embed.add_field(name="Active days/week:", value=days.content, inline=True)
        embed.add_field(name="Active hours/day:", value=hours.content, inline=True)
        embed.add_field(
            name="Previous experience:", value=experience.content, inline=False
        )
        embed.add_field(name="Reason:", value=reason.content, inline=False)

        await channel.send(embed=embed)

        await ctx.author.add_roles(role_add)

        await ctx.author.send(
            "Thank you, I have sent your application to the team.  As mentioned above I will provide you an update in no later the 7 days."
        )
        self.antispam[ctx.guild][ctx.author].stamp()
Beispiel #22
0
        #     pass   # TODO
        else:
            cname = source.name

        try:
            chan = await source.guild.create_voice_channel(
                cname, category=category, overwrites=overwrites)
        except discord.Forbidden:
            await self.ar_config.guild(source.guild).active.set(False)
            return
        except discord.HTTPException:
            pass
        else:
            await self.ar_config.channel(chan).clone.set(True)
            if who.id not in self._antispam:
                self._antispam[who.id] = AntiSpam(self.antispam_intervals)
            self._antispam[who.id].stamp()
            await who.move_to(chan, reason="autoroom")
            await asyncio.sleep(0.5)
            await chan.edit(bitrate=source.bitrate,
                            user_limit=source.user_limit)
            # TODO:
            # discord.HTTP to avoid needing the edit
            # This extra API call is avoidable when working with the lower level tools.

    @commands.bot_has_permissions(manage_channels=True)
    @checks.admin_or_permissions(manage_channels=True)
    @commands.group(autohelp=True)
    async def autoroomset(self, ctx: GuildContext):
        """
        Commands for configuring autorooms
Beispiel #23
0
    async def on_voice_state_update(
        self,
        member: discord.Member,
        before: discord.VoiceState,
        after: discord.VoiceState,
    ):
        guild = member.guild
        has_perm = guild.me.guild_permissions.manage_channels
        if not has_perm:
            return
        if member.bot:
            return
        if "dynamic_channels" not in self.config_cache[member.guild.id]:
            self.config_cache[
                member.guild.id]["dynamic_channels"] = await self.config.guild(
                    member.guild).dynamic_channels()
        if not self.config_cache[member.guild.id]["dynamic_channels"]:
            return
        if "blacklist" not in self.config_cache[member.guild.id]:
            self.config_cache[
                member.guild.id]["blacklist"] = await self.config.guild(
                    member.guild).blacklist()
        if member.id in self.config_cache[member.guild.id]["blacklist"]:
            return
        if guild.id not in self.antispam:
            self.antispam[guild.id] = {}

        if member.id not in self.antispam[guild.id]:
            self.antispam[guild.id][member.id] = AntiSpam([
                (timedelta(seconds=60), 2)
            ])

        delete = {}
        whitelist = await self.config.guild(member.guild
                                            ).dynamic_channels.get_raw()
        guild_channels = member.guild.by_category()
        for category, _ in guild_channels:
            if (after and after.channel and before.channel != after.channel
                    and after.channel.category
                    and after.channel.category == category
                    and f"{after.channel.category.id}" in whitelist):
                voice_channels = category.voice_channels
                voice_channels_empty = [
                    channel for channel in voice_channels
                    if sum(1 for _ in channel.members) < 1
                ]
                category_config = whitelist[f"{after.channel.category.id}"]
                for room_name, room_size in category_config:
                    keyword = room_name.split(" -")[0]
                    keyword = f"{keyword} -"
                    type_room = [(channel.name, channel.position, channel)
                                 for channel in voice_channels_empty
                                 if keyword in channel.name]
                    channel_count = [
                        channel for channel in voice_channels
                        if keyword in channel.name
                    ]

                    type_room.sort(key=itemgetter(1))

                    if room_size < 2:
                        room_size = 0

                    if not type_room and not self.antispam[guild.id][
                            member.id].spammy:
                        self.antispam[guild.id][member.id].stamp()
                        created_channel = await member.guild.create_voice_channel(
                            user_limit=room_size,
                            name=room_name.format(number=len(channel_count) +
                                                  1),
                            reason=f"We need extra rooms in {category.name}",
                            category=category,
                            bitrate=member.guild.bitrate_limit,
                        )
                        guild_group = self.config.guild(member.guild)
                        async with guild_group.user_created_voice_channels(
                        ) as user_voice:
                            user_voice.update(
                                {created_channel.id: created_channel.id})

                    elif len(type_room) > 1:
                        for channel_name, position, channel in type_room:
                            if channel_name != room_name.format(number=1):
                                delete.update(
                                    {channel.id: (channel, position)})
            elif (before and before.channel and before.channel != after.channel
                  and before.channel.category
                  and before.channel.category == category
                  and f"{before.channel.category.id}" in whitelist):
                category = before.channel.category
                voice_channels = category.voice_channels
                voice_channels_empty = [
                    channel for channel in voice_channels
                    if sum(1 for _ in channel.members) < 1
                ]
                category_config = whitelist[f"{before.channel.category.id}"]
                for room_name, room_size in category_config:
                    keyword = room_name.split(" -")[0]
                    keyword = f"{keyword} -"
                    type_room = [(channel.name, channel.position, channel)
                                 for channel in voice_channels_empty
                                 if keyword in channel.name]
                    channel_count = [
                        channel for channel in voice_channels
                        if keyword in channel.name
                    ]
                    type_room.sort(key=itemgetter(1))
                    if room_size < 3:
                        room_size = 0

                    if not type_room and not self.antispam[guild.id][
                            member.id].spammy:
                        self.antispam[guild.id][member.id].stamp()
                        log.debug(
                            f"We need extra dynamic rooms in {category.name}")
                        created_channel = await member.guild.create_voice_channel(
                            user_limit=room_size,
                            name=room_name.format(number=len(channel_count) +
                                                  1),
                            reason=f"We need extra rooms in {category.name}",
                            category=category,
                            bitrate=member.guild.bitrate_limit,
                        )
                        log.debug(
                            f"New dynamic channel has been created: {created_channel.name}"
                        )
                        guild_group = self.config.guild(member.guild)
                        async with guild_group.user_created_voice_channels(
                        ) as user_voice:
                            user_voice.update(
                                {created_channel.id: created_channel.id})

                    elif len(type_room) > 1:
                        for channel_name, position, channel in type_room:
                            if channel_name != room_name.format(number=1):
                                delete.update(
                                    {channel.id: (channel, position)})
        if delete and len(delete) >= 1:
            log.debug(f"Some dynamic channels need to be deleted")
            guild_group = self.config.guild(member.guild)
            async with guild_group.user_created_voice_channels() as user_voice:
                for _, channel_data in delete.items():
                    channel, _ = channel_data
                    log.debug(f"{channel.name} will be deleted")
                    with contextlib.suppress(discord.HTTPException):
                        await channel.delete(
                            reason="Deleting channel due to it being empty")
                        log.debug(f"{channel.name} has been deleted")
                    if f"{channel.id}" in user_voice:
                        del user_voice[f"{channel.id}"]
Beispiel #24
0
    async def apply(self, ctx: commands.Context):
        """Apply to be a staff member."""
        role_add = get(ctx.guild.roles, name="Staff Applicant")
        channel = get(ctx.guild.text_channels, name="applications")
        if ctx.guild not in self.antispam:
            self.antispam[ctx.guild] = {}
        if ctx.author not in self.antispam[ctx.guild]:
            self.antispam[ctx.guild][ctx.author] = AntiSpam([
                (timedelta(days=2), 1)
            ])
        if self.antispam[ctx.guild][ctx.author].spammy:
            return await ctx.send(
                "Uh oh, you're doing this way too frequently.")
        if role_add is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required role."
            )
        if channel is None:
            return await ctx.send(
                "Uh oh. Looks like your Admins haven't added the required channel."
            )
        try:
            await ctx.author.send(
                "Let's start right away! You have maximum of 2 minutes for each question.\nWhat position are you applying for?"
            )
        except discord.Forbidden:
            return await ctx.send(
                "I don't seem to be able to DM you. Do you have closed DMs?")
        await ctx.send(f"Okay, {ctx.author.mention}, I've sent you a DM.")

        def check(m):
            return m.author == ctx.author and m.channel == ctx.author.dm_channel

        try:
            position = await self.bot.wait_for("message",
                                               timeout=120,
                                               check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("What is your name?")
        try:
            name = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("How old are you?")
        try:
            age = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "What timezone are you in? (Google is your friend.)")
        try:
            timezone = await self.bot.wait_for("message",
                                               timeout=120,
                                               check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("How many days per week can you be active?")
        try:
            days = await self.bot.wait_for("message", timeout=120, check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("How many hours per day can you be active?")
        try:
            hours = await self.bot.wait_for("message",
                                            timeout=120,
                                            check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send(
            "Do you have any previous experience? If so, please describe.")
        try:
            experience = await self.bot.wait_for("message",
                                                 timeout=120,
                                                 check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        await ctx.author.send("Why do you want to be a member of our staff?")
        try:
            reason = await self.bot.wait_for("message",
                                             timeout=120,
                                             check=check)
        except asyncio.TimeoutError:
            return await ctx.send("You took too long. Try again, please.")
        embed = discord.Embed(color=await ctx.embed_colour(),
                              timestamp=datetime.now())
        embed.set_author(name="New application!", icon_url=author.avatar_url)
        embed.set_footer(
            text=
            f"{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})")
        embed.title = (
            f"User: {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})"
        )
        embed.add_field(name="Name:", value=name.content, inline=True)
        embed.add_field(name="Age:", value=age.content, inline=True)
        embed.add_field(name="Timezone:", value=timezone.content, inline=True)
        embed.add_field(name="Desired position:",
                        value=position.content,
                        inline=True)
        embed.add_field(name="Active days/week:",
                        value=days.content,
                        inline=True)
        embed.add_field(name="Active hours/day:",
                        value=hours.content,
                        inline=True)
        embed.add_field(name="Previous experience:",
                        value=experience.content,
                        inline=False)
        embed.add_field(name="Reason:", value=reason.content, inline=False)

        await channel.send(embed=embed)

        await ctx.author.add_roles(role_add)

        await ctx.author.send(
            "Your application has been sent to the Admins, thank you!")
        self.antispam[ctx.guild][ctx.author].stamp()
Beispiel #25
0
    async def on_voice_state_update(
        self,
        member: discord.Member,
        before: discord.VoiceState,
        after: discord.VoiceState,
    ):
        guild = member.guild
        has_perm = guild.me.guild_permissions.manage_channels
        if not has_perm:
            return

        if guild.id not in self.antispam:
            self.antispam[guild.id] = {}

        if "blacklist" not in self.config_cache[member.guild.id]:
            self.config_cache[member.guild.id]["blacklist"] = await self.config.guild(
                member.guild
            ).blacklist()

        if member.id not in self.antispam[guild.id]:
            self.antispam[guild.id][member.id] = AntiSpam([(timedelta(seconds=600), 1)])
        if member.id in self.config_cache[member.guild.id]["blacklist"]:
            return

        if "category_with_button" not in self.config_cache[member.guild.id]:
            self.config_cache[member.guild.id][
                "category_with_button"
            ] = await self.config.guild(member.guild).category_with_button()
        if "user_created_voice_channels" not in self.config_cache[member.guild.id]:
            self.config_cache[member.guild.id][
                "user_created_voice_channels"
            ] = await self.config.guild(member.guild).user_created_voice_channels()

        whitelist = self.config_cache[member.guild.id]["category_with_button"]
        user_created_channels = self.config_cache[member.guild.id][
            "user_created_voice_channels"
        ]

        if (
            after
            and not self.antispam[guild.id][member.id].spammy
            and after.channel
            and after.channel.category
            and f"{after.channel.category.id}" in whitelist
            and after.channel.id == whitelist[f"{after.channel.category.id}"]
        ):
            self.antispam[guild.id][member.id].stamp()
            logger.debug(f"User joined {after.channel.name} creating a new room")
            max_position = max(
                [channel.position for channel in after.channel.category.channels]
            )
            overwrites = await self._get_overrides(
                after.channel or before.channel, member
            )
            logger.debug(f"Creating channel: Rename me - {member}")
            created_channel = await member.guild.create_voice_channel(
                name=f"Rename me - {member}",
                category=after.channel.category,
                overwrites=overwrites,
                position=max_position + 1,
                reason=f"{member.display_name} created a custom voice room",
                bitrate=member.guild.bitrate_limit,
            )
            logger.debug(f"Moving {member.display_name} to : Rename me - {member}")
            await member.edit(
                voice_channel=created_channel,
                reason=f"Moving {member.display_name} to newly created custom room",
            )
            logger.debug(
                f"User {member.display_name} has been moved to: Rename me - {member}"
            )
            guild_group = self.config.guild(member.guild)
            async with guild_group.user_created_voice_channels() as user_voice:
                logger.debug(
                    f"Adding {created_channel.name} to the database ({created_channel.id})"
                )
                user_voice.update({created_channel.id: created_channel.id})
            self.config_cache[member.guild.id][
                "user_created_voice_channels"
            ] = await self.config.guild(member.guild).user_created_voice_channels()
            member_group = self.config.member(member)
            async with member_group.currentRooms() as user_voice:
                logger.debug(
                    f"Adding {created_channel.name} to user rooms ({created_channel.id})"
                )
                user_voice.update({created_channel.id: created_channel.id})

        await self.channel_cleaner(before, after, member.guild, user_created_channels)