Example #1
0
 async def unlockdown(self, ctx, target_channel=None):
     """Iterate through the channels in the lockdown list and clear the send_message, add_reaction, and speak permissions for the everyone role (bot-admin only)."""
     if not await Utils.is_bot_admin_reply(ctx): return
     if target_channel:
         c = DisplayName.channelForName(target_channel, ctx.guild)
         if not c:
             return await ctx.send(
                 "The passed value is not a valid channel or category!")
         orphaned, channels = self._verify_lockdown(ctx, c.id)
         lockdown = channels
     else:
         lockdown, channels = self._get_lockdown(ctx)
         if not await self._check_lockdown(lockdown, ctx): return
     message = await Message.EmbedText(
         title="Unlockdown",
         description="🟢 Unlocking {:,} entr{}...".format(
             len(lockdown), "y" if len(lockdown) == 1 else "ies"),
         color=ctx.author).send(ctx)
     cats, chans = await self._perform_lockdown(ctx, channels, unlock=True)
     if cats == chans == 0:
         return await Message.EmbedText(
             title="Unlockdown",
             description="**UNLOCKDOWN FAILED!**").edit(ctx, message)
     await Message.EmbedText(
         title="Unlockdown",
         description="🟢 Unlocked {}{}.".format(
             "{:,} categor{}".format(cats, "y" if cats == 1 else "ies") if
             cats else "", "" if not chans else "{}{:,} channel{}.".format(
                 ", " if cats else "", chans,
                 "" if chans == 1 else "s"))).edit(ctx, message)
Example #2
0
 async def remlock(self, ctx, *, channel_list=None):
     """Removes the passed space-delimited list of channels and categories from the lockdown list (bot-admin only)."""
     if not await Utils.is_bot_admin_reply(ctx): return
     lockdown, channels = self._get_lockdown(ctx)
     if not await self._check_lockdown(lockdown, ctx): return
     if not channel_list:
         return await ctx.send("Usage: `{}remlock [channel list]`".format(
             ctx.prefix))
     resolved = []
     resolved_id = []
     for channel in channel_list.split():
         c = DisplayName.channelForName(channel, ctx.guild)
         if c and c.id in lockdown:
             resolved.append(c)
             resolved_id.append(c.id)
         # Also consider child channels as needed
         if isinstance(c, discord.CategoryChannel):
             for c_child in c.channels:
                 if c_child and c_child.id in lockdown:
                     resolved.append(c_child)
                     resolved_id.append(c_child.id)
     if not len(resolved):
         return await ctx.send(
             "No valid channels passed!\nUsage: `{}remlock [channel list]`".
             format(ctx.prefix))
     lockdown = [x for x in lockdown if not x in resolved_id]
     self.settings.setServerStat(ctx.guild, "LockdownList", lockdown)
     desc = "\n".join([self._get_mention(x) for x in resolved])
     await Message.EmbedText(
         title="{:,} Entr{} Removed from Lockdown List".format(
             len(resolved), "y" if len(resolved) == 1 else "ies"),
         description=desc,
         color=ctx.author,
         footer=self.key).send(ctx)
Example #3
0
    async def antiraidping(self, ctx, user_or_role=None, channel=None):
        """Sets up what user or role to ping and in what channel when anti-raid is activated (bot-admin only)."""

        if not await Utils.is_bot_admin_reply(ctx): return
        if user_or_role == None:  # print the settings
            user_role = self.settings.getServerStat(ctx.guild, "AntiRaidPing",
                                                    None)
            if user_role:
                u = DisplayName.memberForName(user_role, ctx.guild)
                if not u: u = DisplayName.roleForName(user_role, ctx.guild)
                user_role = u
            chan = self.settings.getServerStat(ctx.guild, "AntiRaidChannel",
                                               None)
            if chan: chan = DisplayName.channelForName(chan, ctx.guild)
            if not user_role or not chan:
                return await ctx.send("Anti-raid ping is not setup.")
            return await ctx.send(
                "Anti-raid activity will mention {} and be announced in {}!".
                format(
                    Nullify.escape_all(user_role.display_name) if isinstance(
                        user_role, discord.Member) else Nullify.escape_all(
                            user_role.name), chan.mention))
        if channel == None:
            return await ctx.send(
                "Usage: `{}antiraidping user_or_role channel`".format(
                    ctx.prefix))
        # We're setting it up - let's check the user first, then role, then channel
        ur = DisplayName.memberForName(user_or_role, ctx.guild)
        if not ur: ur = DisplayName.roleForName(user_or_role, ctx.guild)
        if not ur: return await ctx.send("I couldn't find that user or role.")
        ch = DisplayName.channelForName(channel, ctx.guild)
        if not ch: return await ctx.send("I couldn't find that channel.")
        # Got them! - Save and report
        self.settings.setServerStat(ctx.guild, "AntiRaidPing", ur.id)
        self.settings.setServerStat(ctx.guild, "AntiRaidChannel", ch.id)
        return await ctx.send(
            "Anti-raid activity will mention {} and be announced in {}!".
            format(
                Nullify.escape_all(ur.display_name) if isinstance(
                    ur, discord.Member) else Nullify.escape_all(ur.name),
                ch.mention))
    async def tr(self, ctx, *, translate=None):
        """Translate some stuff!  Takes a phrase, the from language identifier (optional), and the to language identifier.
        To see a number of potential language identifiers, use the langlist command.
        
        Example Translation:
        $tr Hello there, how are you? en es
        
        Would translate from English to Spanish resulting in:
        ¿Hola como estás?
        
        If you do not specify the from language, Google translate will attempt to automatically determine it."""

        usage = "Usage: `&tr [input] [from code (optional)] [to code]`".format(
            ctx.prefix)
        if translate == None: return await ctx.send(usage)

        word_list = translate.split(" ")

        if len(word_list) < 2: return await ctx.send(usage)

        to_lang = word_list[len(word_list) - 1]
        from_lang = word_list[len(word_list) -
                              2] if len(word_list) >= 3 else ""

        # Get the from language name from the passed code
        from_lang_name = googletrans.LANGUAGES.get(from_lang.lower(), None)
        # Get the to language name from the passed code
        to_lang_name = googletrans.LANGUAGES.get(to_lang.lower(), None)
        if not to_lang_name:  # No dice on the language :(
            return await Message.EmbedText(
                title="Error",
                description="Specified language can't be found",
                color=ctx.author).send(ctx)
        # Get all but our language codes joined with spaces
        trans = " ".join(word_list[:-2] if from_lang_name else word_list[:-1])
        # If our from_lang_name is None, we need to auto-detect it
        if not from_lang_name:
            from_output = await self.bot.loop.run_in_executor(
                None, self.translator.detect, trans)
            from_lang = from_output.lang
            from_lang_name = googletrans.LANGUAGES.get(from_lang, "Unknown")
        # Let's actually translate now
        result_output = await self.bot.loop.run_in_executor(
            None,
            functools.partial(self.translator.translate,
                              trans,
                              dest=to_lang,
                              src=from_lang))
        result = result_output.text

        # Explore the results!
        if not result:
            await Message.EmbedText(title="Error",
                                    description="Unable to translate input",
                                    color=ctx.author).send(ctx)
            return

        if result == trans:
            # We got back what we put in...
            await Message.EmbedText(
                title="Error",
                description=
                "The text returned from Google was the same as the text input.  Either the translation failed - or you were translating from/to the same language (en -> en)",
                color=ctx.author).send(ctx)
            return

        await Message.EmbedText(
            title="{}, your translation is:".format(
                DisplayName.name(ctx.author)),
            force_pm=True,
            color=ctx.author,
            description=result,
            footer="{} --> {} - Powered by Google Translate".format(
                string.capwords(from_lang_name),
                string.capwords(to_lang_name))).send(ctx)
Example #5
0
async def checkroles(user,
                     channel,
                     settings,
                     bot,
                     suppress: bool = False,
                     **kwargs):
    # This method checks whether we need to promote, demote, or whatever
    # then performs the said action, and outputs.
    if user.bot: return  # Don't apply roles to bots
    DisplayName = bot.get_cog("DisplayName")
    Utils = bot.get_cog("Utils")
    if not DisplayName or not Utils: return  # We are missing dependencies

    if type(channel) is discord.Guild:
        server = channel
        channel = None
    else:
        server = channel.guild

    # Get our preliminary vars
    msg = None
    xpPromote = kwargs.get("xp_promote",
                           settings.getServerStat(server, "XPPromote"))
    xpDemote = kwargs.get("xp_demote",
                          settings.getServerStat(server, "XPDemote"))
    userXP = int(settings.getUserStat(user, server, "XP"))
    suppProm = kwargs.get("suppress_promotions",
                          settings.getServerStat(server, "SuppressPromotions"))
    suppDem = kwargs.get("suppress_demotions",
                         settings.getServerStat(server, "SuppressDemotions"))
    onlyOne = kwargs.get("only_one_role",
                         settings.getServerStat(server, "OnlyOneRole"))

    # Check if we're suppressing @here and @everyone mentions
    if settings.getServerStat(server, "SuppressMentions"):
        suppressed = True
    else:
        suppressed = False

    changed = False
    promoArray = settings.getServerStat(server, "PromotionArray")
    promoArray = sorted(promoArray, key=lambda x: int(x['XP']))

    addRoles = []
    remRoles = []

    # Final checks for singular role-holding.  Will find a better system at
    # some point - probably...
    if onlyOne:
        # Only one role allowed, make sure we don't have the rest
        # Get the role we're supposed to be at
        current_role = None
        is_higher = False
        target_role = None
        for role in promoArray:
            test_role = DisplayName.roleForID(role['ID'], server)
            # Check if it's a real role
            if not test_role:
                continue
            if int(role["XP"]) > userXP:
                # We don't have xp for this role
                # Set it if we already have it though
                if test_role in user.roles:
                    current_role = test_role
                    is_higher = True
            else:
                # We've got the resources for it
                target_role = test_role
                # Set it if we already have it though
                if test_role in user.roles:
                    current_role = test_role

        # Remove all roles except current
        if current_role == target_role:
            for role in promoArray:
                test_role = DisplayName.roleForID(role['ID'], server)
                if test_role != target_role and test_role in user.roles:
                    changed = True
                    remRoles.append(test_role)
        else:
            # Demote if needed
            if is_higher:
                if xpDemote:
                    # We can remove roles above - but keep the last one
                    msg = '*{}* was demoted from **{}**!'.format(
                        DisplayName.name(user), current_role.name)
                    for role in promoArray:
                        test_role = DisplayName.roleForID(role['ID'], server)
                        if test_role != target_role and test_role in user.roles:
                            remRoles.append(test_role)
                    addRoles.append(target_role)
                    changed = True
                else:
                    # We're not demoting - but let's add only the current role to the list
                    for role in promoArray:
                        test_role = DisplayName.roleForID(role['ID'], server)
                        if test_role != current_role and test_role in user.roles:
                            remRoles.append(test_role)
                            changed = True
            # Promote if needed
            else:
                if xpPromote:
                    # Remove all roles below
                    msg = '*{}* was promoted to **{}**!'.format(
                        DisplayName.name(user), target_role.name)
                    for role in promoArray:
                        test_role = DisplayName.roleForID(role['ID'], server)
                        if test_role != target_role and test_role in user.roles:
                            remRoles.append(test_role)
                    addRoles.append(target_role)
                    changed = True
                else:
                    # We're not promoting - but let's add only the current role to the list
                    for role in promoArray:
                        test_role = DisplayName.roleForID(role['ID'], server)
                        if test_role != current_role and test_role in user.roles:
                            remRoles.append(test_role)
                            changed = True

    else:
        # Check promotions first
        if xpPromote:
            # This is, by far, the more functional way
            for role in promoArray:
                # Iterate through the roles, and add which we have xp for
                if int(role['XP']) <= userXP:
                    # We *can* have this role, let's add it to a list
                    addRole = DisplayName.roleForID(role['ID'], server)
                    if addRole:
                        if not addRole in user.roles:
                            addRoles.append(addRole)
                            if not suppProm:
                                msg = '*{}* was promoted to **{}**!'.format(
                                    DisplayName.name(user), addRole.name)
                            changed = True
        # Allow independent promotion/demotion
        if xpDemote:
            for role in promoArray:
                # Iterate through the roles, and add which we have xp for
                if int(role['XP']) > userXP:
                    # We *can* have this role, let's add it to a list
                    remRole = DisplayName.roleForID(role['ID'], server)
                    if remRole:
                        if remRole in user.roles:
                            remRoles.append(remRole)
                            if not suppDem:
                                msg = '*{}* was demoted from **{}**!'.format(
                                    DisplayName.name(user), remRole.name)
                            changed = True

    # Add and remove roles as needed
    if len(addRoles) or len(remRoles):
        settings.role.change_roles(user,
                                   add_roles=addRoles,
                                   rem_roles=remRoles)

    # Check if we have a message to display - and display it
    if msg and channel and (not suppress):
        msg = Utils.suppressed(server, msg)
        await channel.send(msg)
    return changed
Example #6
0
 async def on_member_join(self, member):
     if not self.settings.getServerStat(member.guild, "AntiRaidEnabled",
                                        False):
         return  # Not enabled, ignore
     if self.settings.getServerStat(member.guild, "AntiRaidActive", False):
         # Currently in anti-raid mode, find out what to do with the new join
         ar_cooldown = self.settings.getServerStat(member.guild,
                                                   "AntiRaidCooldown",
                                                   600)  # 10 minute default
         ar_lastjoin = self.settings.getServerStat(member.guild,
                                                   "AntiRaidLastJoin", 0)
         if time.time(
         ) - ar_lastjoin >= ar_cooldown:  # No longer watching - disable anti-raid
             self.settings.setServerStat(member.guild, "AntiRaidActive",
                                         False)
         else:  # Gather our response to the new user and put it into effect
             await self._anti_raid_respond(member)
         # Save the last join timestamp in the anti-raid list
         self.settings.setServerStat(member.guild, "AntiRaidLastJoin",
                                     time.time())
     # Gather the settings and go from there
     ar_joins = self.settings.getServerStat(member.guild, "AntiRaidJoins",
                                            [])
     ar_maxj = self.settings.getServerStat(member.guild, "AntiRaidMax", 10)
     ar_time = self.settings.getServerStat(member.guild, "AntiRaidTime", 10)
     ar_joins.insert(
         0,
         (member.id,
          time.time()))  # Add (mem_id,timestamp) to the front of the list
     ar_joins = ar_joins[:
                         ar_maxj]  # Ensure the list is only as long as the max joins allowed
     self.settings.setServerStat(member.guild, "AntiRaidJoins",
                                 ar_joins)  # Save the updated list
     if len(ar_joins) < ar_maxj:
         return  # List isn't long enough to consider - bail
     # Compare the first and last join times to the threshold
     if ar_joins[0][1] - ar_joins[-1][1] <= ar_time:  # Enable anti-raid!
         if not self.settings.getServerStat(member.guild, "AntiRaidActive",
                                            False):
             self.settings.setServerStat(member.guild, "AntiRaidActive",
                                         True)
             mention = self.settings.getServerStat(member.guild,
                                                   "AntiRaidPing", None)
             if mention:
                 m = DisplayName.memberForName(mention, member.guild)
                 if not m:
                     m = DisplayName.roleForName(mention, member.guild)
                 if m:  # Got a member or role - let's get the channel
                     channel = self.settings.getServerStat(
                         member.guild, "AntiRaidChannel", None)
                     if channel:
                         c = DisplayName.channelForName(
                             channel, member.guild)
                         if c:  # Got a member/role and a channel - try to post the ping
                             try:
                                 await c.send(
                                     "{} - Anti-raid has been enabled!".
                                     format(m.mention))
                             except:
                                 pass
         self.settings.setServerStat(member.guild, "AntiRaidLastJoin",
                                     time.time())
         for m_id, t in ar_joins:
             # Resolve the ids and react accordingly
             m = member.guild.get_member(m_id)
             if m: await self._anti_raid_respond(m)