Пример #1
0
    async def start(self, ctx: commands.context,
                    system_member: discord.Member):
        """
        Starts a suspended instance

        :param ctx: Discord Context
        :param system_member: System Member
        """
        # TODO: Provide more verbose feedback from command
        await ctx.message.delete()
        member = get_member_by_discord_id(system_member.id)
        if member is not None:
            if not member["member_enabled"]:
                c.execute(
                    "UPDATE members SET member_enabled = 1 WHERE member_account_id = ?",
                    [system_member.id],
                )
                instances.append(create_member_instance(member))
                await ctx.send(
                    f"{system_member.mention} started by {ctx.message.author.mention}"
                )
                log.info(
                    f"{system_member} has been started by {ctx.message.author}"
                )
            else:
                await ctx.send(f"{system_member.mention} is already running")
Пример #2
0
    async def disable(self, ctx: commands.context,
                      system_member: discord.Member):
        """
        Disables a system member permanently by deleting it from the database and kicking it from the server. Bot token cannot be reused.

        :param ctx: Discord Context
        :param system_member: System Member
        """
        # TODO: Provide more verbose feedback from command
        instance = get_member_by_discord_id(system_member.id)
        if instance:
            log.debug(f"Disabling {system_member}")
            confirmation = BotConfirmation(ctx, discord.Color.red())
            await confirmation.confirm(
                f"Disable member {system_member} permanently?")
            if confirmation.confirmed:
                await confirmation.message.delete()
                with conn:
                    c.execute(
                        "DELETE FROM members WHERE token = ?",
                        [instance["token"]],
                    )
                await self.suspend(ctx, system_member)
                await ctx.send(
                    f"{system_member.mention} disabled permanently by {ctx.message.author}"
                )
                log.info(
                    f"{system_member} has been disabled permanently by {ctx.message.author}"
                )
                log.debug(f"Disabled {system_member}")
            else:
                await confirmation.message.delete()
                await ctx.send(f"{system_member.mention} was __not__ disabled")
                log.debug(f"Canceled disable of {system_member}")
Пример #3
0
    async def suspend(self, ctx: commands.context,
                      system_member: discord.Member):
        """
        Pulls the member instance offline.

        :param ctx: Discord Context
        :param system_member: System Member
        """
        # TODO: Provide more verbose feedback from command
        await ctx.message.delete()
        for i, instance in enumerate(instances):
            if instance.user.id == system_member.id:
                await instance.close()
                with conn:
                    c.execute(
                        "UPDATE members SET member_enabled = 0 WHERE token = ?",
                        [instance.get_token()],
                    )
                del instances[i]
                await ctx.send(
                    f"{system_member.mention} suspended by {ctx.author.mention}"
                )
                log.info(
                    f"{system_member} has been suspended by {ctx.message.author}"
                )
Пример #4
0
    async def whoarewe(self, ctx: commands.context):
        """
        List members of system belonging to user who executes command

        :param ctx: Discord Context
        """
        log.debug(f"Listing members for {ctx.author.display_name}...")
        c.execute(
            "SELECT * FROM members WHERE discord_account_id == ?",
            [ctx.author.id],
        )
        member_list = c.fetchall()
        embed = discord.Embed(title=f"Members of System")
        embed.set_author(name=f"{ctx.author}", icon_url=ctx.author.avatar_url)

        if member_list is None:
            embed.add_field(name="No members where found",
                            value="Ask a mod to add some!")

        for member in member_list:
            member_user = ctx.guild.get_member_named(
                f"p.{member['member_name']}")
            tags = []
            for tag in json.loads(member["pk_proxy_tags"]):
                tags.append("`" + (tag.get("prefix") or "") + "text" +
                            (tag.get("suffix") or "") + "`")
            embed.add_field(
                name=dict(member).get("display_name", member["member_name"]),
                value=
                f"""**User:** {member_user.mention}\n**PluralKit Member ID:** `{member['pk_member_id']}`\n**Tags:** {' or '.join(tags)}\n**Enabled:** `{'Yes' if member['member_enabled'] else 'No'}`""",
                inline=True,
            )

        await ctx.send(embed=embed)
Пример #5
0
    async def tokens(self, ctx: commands.context, *tokens: str):
        """
        Add tokens to queue

        :param ctx: Discord Context
        :param tokens: List of tokens
        """
        async def session(self, author: discord.Member):
            self.token_session.append(author)
            await asyncio.sleep(300)
            self.token_session.remove(author)

        if (ctx.channel.type is discord.ChannelType.private
                and ctx.message.author in self.token_session):
            await ctx.send("Adding tokens...")
            log.debug(tokens)
            for index, token in enumerate(tokens):
                logger = LogMessage(ctx, title=f"Adding token #{index+1}...")
                await logger.init()
                # Check token
                await logger.log(f"Checking token #{index+1}...")
                check_result, client_id = await check_token(token)
                if not check_result:
                    logger.title = f"Token #{index+1} Invalid"
                    logger.color = discord.Color.red()
                    await logger.log("Bot token is invalid")
                else:
                    await logger.log("Token valid")
                    if get_token(token) is None:
                        log.info("Adding new token to database")
                        insert_token(token, False)
                        logger.title = f"Bot token #{index+1} added"
                        logger.color = discord.Color.green()
                        c.execute("SELECT * FROM tokens WHERE used = 0")
                        slots = c.fetchall()
                        from polyphony.bot import bot

                        await logger.send(
                            f"[Invite to Server]({discord.utils.oauth_url(client_id, permissions=discord.Permissions(DEFAULT_INSTANCE_PERMS), guild=bot.get_guild(GUILD_ID))})\n\n**Client ID:** {client_id}\nThere are now {len(slots)} slot(s) available"
                        )
                    else:
                        logger.title = f"Token #{index+1} already in database"
                        logger.color = discord.Color.orange()
                        await logger.log("Bot token already in database")
        elif ctx.channel.type is not discord.ChannelType.private:
            await ctx.message.delete()
            if any(role.name in MODERATOR_ROLES
                   for role in ctx.message.author.roles):
                await ctx.message.author.send(
                    f"Token mode enabled for 5 minutes. Add tokens with `{self.bot.command_prefix}tokens [token] (more tokens...)` right here.\n\n*Don't paste a bot token in a server*"
                )
                await session(self, ctx.message.author)
        elif any(role.name in MODERATOR_ROLES
                 for role in ctx.message.author.roles):
            ctx.message.delete()
            await ctx.channel.send(
                f"To add tokens, execute `{self.bot.command_prefix}tokens` as a moderator on a server **WITHOUT A BOT TOKEN**. Then in DMs, use `{self.bot.command_prefix}tokens [token] (more tokens...)`\n\n*Seriously don't paste a bot token in a server*"
            )
Пример #6
0
 def pk_proxy_tags(self, value: dict):
     self._pk_proxy_tags = value
     with conn:
         log.debug(
             f"{self.user} ({self.pk_member_id}): Updating proxy tags to {value}"
         )
         c.execute(
             "UPDATE members SET pk_proxy_tags = ? WHERE token = ?",
             [json.dumps(value), self._token],
         )
Пример #7
0
    async def on_ready(self):
        """Execute on bot initialization with the Discord API."""
        log.info(
            f"Instance started as {self.user} ({self.pk_member_id}). Initializing..."
        )

        state = await self.check_for_invalid_states()
        if state == 1:
            log.warning(
                f"Failed to start {self.user} (`{self.pk_member_id}`) because main user left. Instance has been suspended."
            )
            await self.close()
            return

        # Update Member Name
        self.member_name: str = self.__member_name
        if self.__display_name:
            self.display_name: str = self.__display_name
        else:
            self.display_name: str = self.__member_name

        # Update Username
        await self.user.edit(username=self.member_name)

        # Update Roles
        await self.update_default_roles()

        # Update Avatar
        self.pk_avatar_url: str = self.__pk_avatar_url

        # Update Proxy Tags
        self.pk_proxy_tags = self.__pk_proxy_tags

        # Update Nickname in Guilds
        await self.push_nickname_updates()

        # Update Presence
        await self.change_presence(activity=discord.Activity(
            name=f"{self.get_user(self.main_user_account_id)}",
            type=discord.ActivityType.listening,
        ))

        # Update Self ID in Database
        with conn:
            log.debug(
                f"{self.user} ({self.pk_member_id}): Updating Self Account ID: {self.user.id}"
            )
            c.execute(
                "UPDATE members SET member_account_id = ? WHERE pk_member_id = ?",
                [self.user.id, self.pk_member_id],
            )

        log.info(f"{self.user} ({self.pk_member_id}): Initialization complete")

        self.initialized = True
Пример #8
0
 async def system(self, ctx: commands.context, member: discord.Member):
     log.debug(f"Listing members for {member.display_name}...")
     c.execute(
         "SELECT * FROM members WHERE discord_account_id == ?",
         [member.id],
     )
     member_list = c.fetchall()
     embed = discord.Embed(title=f"Members of System")
     embed.set_author(name=f"{member} ({member.id})",
                      icon_url=member.avatar_url)
     await self.send_member_list(ctx, embed, member_list)
Пример #9
0
 def display_name(self, value: str):
     """
     Requires calling the "update" method to push to Discord
     """
     self._display_name = value
     with conn:
         log.debug(
             f"{self.user} ({self.pk_member_id}): Updating Display Name")
         c.execute(
             "UPDATE members SET display_name = ? WHERE token = ?",
             [value, self._token],
         )
Пример #10
0
 def pk_avatar_url(self, value: str):
     """
     Requires calling the "update" method to push to Discord
     """
     self._pk_avatar_url = value
     with conn:
         log.debug(
             f"{self.user} ({self.pk_member_id}): Updating avatar URL to {value}"
         )
         c.execute(
             "UPDATE members SET pk_avatar_url = ? WHERE token = ?",
             [value, self._token],
         )
Пример #11
0
    async def list(self, ctx: commands.context):
        """
        list: Shows all active Polyphony members sorted by main account

        :param ctx: Discord Context
        """
        if ctx.invoked_subcommand is not None:
            return
        log.debug("Listing active members...")
        c.execute("SELECT * FROM members WHERE member_enabled == 1")
        member_list = c.fetchall()
        embed = discord.Embed(title="Active Members")
        await send_member_list(ctx, embed, member_list)
Пример #12
0
 def member_name(self, value: str):
     log.debug(
         f"{self.user} ({self.pk_member_id}): Username updating to p.{value}"
     )
     self._member_name = f"p.{value}"
     self.user.name = f"p.{value}"
     with conn:
         log.debug(
             f"{self.user} ({self.pk_member_id}): Updating Member Name")
         c.execute(
             "UPDATE members SET member_name = ? WHERE token = ?",
             [value, self._token],
         )
Пример #13
0
    async def whoarewe(self, ctx: commands.context):
        """
        List members of system belonging to user who executes command

        :param ctx: Discord Context
        """
        log.debug(f"Listing members for {ctx.author.display_name}...")
        c.execute(
            "SELECT * FROM members WHERE main_account_id == ?",
            [ctx.author.id],
        )
        member_list = c.fetchall()
        embed = discord.Embed(title=f"Members of System")
        embed.set_author(name=f"{ctx.author}", icon_url=ctx.author.avatar_url)
        await send_member_list(ctx, embed, member_list, whoarewe=True)
Пример #14
0
 async def edit(
     self,
     ctx: commands.context,
     message: Optional[discord.Message] = None,
     *,
     content: str,
 ):
     """
     edit (message id) [message]: Edits the last message or message with ID
     
     :param ctx: Discord Context
     :param message: (optional) ID of message
     :param content: Message Content
     """
     await ctx.message.delete()
     if message is not None:
         log.debug(
             f"Editing message {message.id} by {message.author} for {ctx.author}"
         )
         c.execute(
             "SELECT * FROM members WHERE discord_account_id == ? AND member_account_id == ?",
             [ctx.author.id, message.author.id],
         )
         if c.fetchone():
             for instance in instances:
                 if instance.user.id == message.author.id:
                     message = await instance.get_channel(
                         message.channel.id).fetch_message(message.id)
                     await message.edit(content=content)
                     break
     else:
         log.debug(f"Editing last Polyphony message for {ctx.author}")
         c.execute(
             "SELECT * FROM members WHERE discord_account_id == ?",
             [ctx.author.id],
         )
         member_ids = [
             member["member_account_id"] for member in c.fetchall()
         ]
         async for message in ctx.channel.history():
             if message.author.id in member_ids:
                 for instance in instances:
                     if instance.user.id == message.author.id:
                         message = await instance.get_channel(
                             message.channel.id).fetch_message(message.id)
                         await message.edit(content=content)
                         break
                 break
Пример #15
0
    async def delete(
        self,
        ctx: commands.context,
        message: Optional[discord.Message] = None,
    ):
        """
        del (id): Deletes the last message unless a message ID parameter is provided. Can be run multiple times. n max limited by config.

        :param ctx: Discord Context
        :param message: ID of message to delete
        """
        await ctx.message.delete()
        if message is not None:
            log.debug(
                f"Deleting message {message.id} by {message.author} for {ctx.author}"
            )
            c.execute(
                "SELECT * FROM members WHERE discord_account_id == ? AND member_account_id == ?",
                [ctx.author.id, message.author.id],
            )
            if c.fetchone():
                for instance in instances:
                    if instance.user.id == message.author.id:
                        message = await instance.get_channel(
                            message.channel.id).fetch_message(message.id)
                        await message.delete()
                        break
        else:
            log.debug(f"Deleting last Polyphony message for {ctx.author}")
            c.execute(
                "SELECT * FROM members WHERE discord_account_id == ?",
                [ctx.author.id],
            )
            member_ids = [
                member["member_account_id"] for member in c.fetchall()
            ]
            async for message in ctx.channel.history():
                if message.author.id in member_ids:
                    for instance in instances:
                        if instance.user.id == message.author.id:
                            message = await instance.get_channel(
                                message.channel.id).fetch_message(message.id)
                            await message.delete()
                            break
                    break
Пример #16
0
    async def check_for_invalid_states(self) -> int:
        log.debug(
            f"{self.user} ({self.pk_member_id}): Checking for invalid states..."
        )
        if await self.check_if_main_account_left():
            log.warning(
                f"{self.user} ({self.pk_member_id}): Main user left. Suspending self."
            )
            embed = discord.Embed(
                title="Main account left",
                description=
                f"Main account left for {self.user.mention}\n\n*Instance has been suspended.*",
                color=discord.Color.red(),
            )
            embed.set_footer(
                text=f"Main Account ID: {self.main_user_account_id}")
            await send_to_log_channel(embed=embed)
            from polyphony.helpers.instances import instances

            for i, instance in enumerate(instances):
                if instance.user.id == self.user.id:
                    await instance.close()
                    with conn:
                        c.execute(
                            "UPDATE members SET member_enabled = 0 WHERE token = ?",
                            [instance.get_token()],
                        )
                    del instances[i]
            return 1

        elif await self.check_if_not_in_guild():
            log.debug(f"{self.user} ({self.pk_member_id}) is not in the guild")
            from polyphony.bot import bot

            embed = discord.Embed(
                title="Member started but is not in server",
                description=
                f"[Invite to Server]({discord.utils.oauth_url(self.user.id, permissions=discord.Permissions(DEFAULT_INSTANCE_PERMS), guild=bot.get_guild(GUILD_ID))})",
                color=discord.Color.red(),
            )
            await send_to_log_channel(embed=embed)
            return 2
        return 0
Пример #17
0
 async def whois(self, ctx: commands.context,
                 system_member: discord.Member):
     c.execute("SELECT * FROM members WHERE member_account_id == ?",
               [system_member.id])
     member = c.fetchone()
     embed = discord.Embed(
         description=
         f"{system_member.mention} is part of the {self.bot.get_user(member['discord_account_id']).mention} system",
     )
     embed.add_field(name="User ID",
                     value=self.bot.get_user(
                         member["member_account_id"]).id)
     embed.add_field(
         name="System Owner ID",
         value=self.bot.get_user(member["discord_account_id"]).id,
     )
     embed.set_thumbnail(
         url=self.bot.get_user(member["member_Account_id"]).avatar_url)
     await ctx.channel.send(embed=embed)
Пример #18
0
 async def whois(self, ctx: commands.context,
                 system_member: discord.Member):
     c.execute("SELECT * FROM members WHERE id == ?", [system_member.id])
     member = c.fetchone()
     try:
         embed = discord.Embed(
             description=
             f"{system_member.mention} is part of the {self.bot.get_user(member['main_account_id']).mention} system",
         )
     except AttributeError:
         embed = discord.Embed(
             description=
             f":x: It appears the user for {system_member.mention} has left the server.",
         )
     embed.add_field(name="User ID", value=member["id"])
     embed.add_field(
         name="System Owner ID",
         value=member["main_account_id"],
     )
     embed.set_thumbnail(url=self.bot.get_user(member["id"]).avatar_url)
     await ctx.channel.send(embed=embed)
Пример #19
0
    async def slots(self, ctx: commands.context):
        """
        Show number of slots available

        :param ctx: Discord Context
        """
        await ctx.message.delete()
        c.execute("SELECT * FROM tokens WHERE used = 0")
        slots = c.fetchall()
        if 2 > len(slots) >= 1:
            embed = discord.Embed(title=f"There is 1 slot available.",
                                  color=discord.Color.green())
        elif len(slots) > 1:
            embed = discord.Embed(
                title=f"There are {len(slots)} slots available",
                color=discord.Color.green(),
            )
        else:
            embed = discord.Embed(
                title=f"Sorry, there are currently no slots available",
                description="Contact a moderator",
            )
        await ctx.channel.send(embed=embed)
Пример #20
0
    async def register(
        self,
        ctx: commands.context,
        pluralkit_member_id: str,
        account: discord.Member,
    ):
        """
        Creates a new Polyphony member instance

        :param ctx: Discord Context
        :param pluralkit_member_id: PluralKit system or member id
        :param account: Main Account to be extended from
        """

        log.debug("Registering new member...")

        logger = LogMessage(ctx, title="Registering...")
        await logger.init()

        instance = None

        async with ctx.channel.typing():
            await logger.log("Fetching member from PluralKit...")
            member = await pk_get_member(pluralkit_member_id)

            # Member exists
            if member is not None:
                system_names = [f"{member['name']} (`{member['id']}`)"]
                await logger.log(
                    f"Fetched member -> {member['name']} (`{member['id']}`)")
                tokens = get_unused_tokens()

                # Fail: No Slots Available
                if len(tokens) == 0:
                    logger.title = "Error Registering: No Slots Available"
                    logger.color = discord.Color.red()
                    await logger.log(
                        f"No tokens in queue. Run `{self.bot.command_prefix}tokens` for information on how to add more."
                    )
                    return

                # Confirm add
                confirmation = BotConfirmation(ctx, discord.Color.blue())
                await confirmation.confirm(
                    f"Create member for {account} with member {', '.join(system_names)}?"
                )
                if confirmation.confirmed:
                    await confirmation.message.delete()
                    await logger.log("Adding to database...")
                else:
                    await confirmation.message.delete()
                    logger.title = "Extend Cancelled"
                    logger.color = discord.Color.red()
                    await logger.log("Registration cancelled by user")
                    return

                # Get a token and update as used
                bot_token = tokens[0]
                update_token_as_used(bot_token["token"])

                # Insert new user into users database
                if get_user(account.id) is None:
                    await logger.log(
                        f"{account.mention} is a new user! Registering them with Polyphony"
                    )
                    insert_user(account.id)

                # Insert member unless already registered
                if get_member(pluralkit_member_id) is None:
                    insert_member(
                        bot_token["token"],
                        member["id"],
                        account.id,
                        0,
                        member["name"],
                        member["display_name"],
                        member["avatar_url"],
                        member["proxy_tags"][0],
                        member["keep_proxy"],
                        member_enabled=True,
                    )

                # Fail: Member Already Registered
                else:
                    logger.title = "Member Already Registered with Polyphony"
                    logger.color = discord.Color.light_grey()
                    await logger.log(
                        f"Member ID `{pluralkit_member_id}` was already registered with Polyphony"
                    )
                    return
                await logger.log("Creating member instance...")
                instance = create_member_instance(get_member(member["id"]))

            # Fail: Invalid ID
            else:
                logger.title = "Error Registering: Member ID invalid"
                logger.color = discord.Color.red()
                await logger.log(
                    f"Member ID `{pluralkit_member_id}` was not found")
                return

        # Success State
        logger.title = f"Registration of {member['name']} Successful"
        logger.color = discord.Color.green()
        c.execute("SELECT * FROM tokens WHERE used = 0")
        slots = c.fetchall()
        await logger.log(f"There are now {len(slots)} slots available")
        await logger.log(f"\nUser is {instance.user.mention}")
        log.info("New member instance extended and activated")
Пример #21
0
 async def all(self, ctx: commands.context):
     log.debug("Listing all members...")
     c.execute("SELECT * FROM members")
     member_list = c.fetchall()
     embed = discord.Embed(title="All Members")
     await self.send_member_list(ctx, embed, member_list)
Пример #22
0
    async def rolesync(self, ctx: commands.context,
                       system_member: discord.Member):
        """
        Sync current roles to system member until typing `done`

        :param system_member: System member to sync roles with
        :param ctx: Discord Context
        """
        if any([
                role.name in DISABLE_ROLESYNC_ROLES
                for role in ctx.message.author.roles
        ]):
            # Don't execute if has role that disables rolesync
            return
        c.execute(
            "SELECT * FROM members WHERE main_account_id == ? AND id == ?",
            [ctx.author.id, system_member.id],
        )
        if c.fetchone():

            # Get User's Roles
            user_roles = []
            for role in ctx.author.roles[1:]:
                if role.name not in ALWAYS_SYNC_ROLES and not role.managed:
                    user_roles.append(role)
            # Get Member's Roles
            member_roles = []
            for role in system_member.roles[1:]:
                if role.name not in NEVER_SYNC_ROLES:
                    member_roles.append(role)

            embed = discord.Embed(
                title=":hourglass: Syncing roles...",
                description=
                f"Assign yourself the roles you want for {system_member.mention} and then type `done`",
                color=discord.Color.orange(),
            )
            saved_roles_str = " ".join(
                [role.mention for role in ctx.author.roles[1:]])
            embed.add_field(
                name=
                f":file_folder: __{ctx.author.display_name}__'s Roles *(saved)*",
                value=saved_roles_str if len(saved_roles_str) < 1024 else
                ":hushed: Too many to show" or "None",
            )
            embed_member_original_roles = " ".join(
                [role.mention for role in system_member.roles[1:]])
            embed.add_field(
                name=f"__{system_member.display_name}__'s Original Roles",
                value=embed_member_original_roles
                if len(embed_member_original_roles) else
                ":hushed: Too many to show" or "None",
            )
            embed.set_footer(
                text=
                "Will timeout in 5 minutes. Changes may take a moment to update."
            )
            embed.set_author(
                name=system_member.display_name,
                icon_url=system_member.avatar_url,
            )
            instructions = await ctx.channel.send(ctx.author.mention,
                                                  embed=embed)
            loading_embed = discord.Embed(
                title=":hourglass: *Hold on while I update your roles...*",
                color=discord.Color.orange(),
            )
            loading = await ctx.channel.send(embed=loading_embed)

            # Remove user's roles and give member's roles
            async with ctx.channel.typing():
                await ctx.author.remove_roles(*user_roles)
                await ctx.author.add_roles(*member_roles)
            loading_embed = discord.Embed(
                title="Type `done` to sync your roles.",
                color=discord.Color.green())
            await loading.edit(embed=loading_embed)

            # Wait for "done"
            try:
                await self.bot.wait_for(
                    "message",
                    check=lambda message: message.author == ctx.author and
                    message.content.lower() == "done",
                    timeout=60 * 5,  # 5 mins
                )
                loading_embed = discord.Embed(
                    title=":hourglass: *Hold on while I sync and update...*",
                    color=discord.Color.orange(),
                )
                await loading.edit(embed=loading_embed)

                # On done, add new roles to member, remove new roles from user, and old roles to user
                async with ctx.channel.typing():
                    new_roles = [role for role in ctx.author.roles[1:]]

                    roles_to_remove = []
                    for role in new_roles:
                        if role.name not in ALWAYS_SYNC_ROLES:
                            roles_to_remove.append(role)

                    # Remove all roles from member and main user
                    await asyncio.gather(
                        system_member.remove_roles(*member_roles),
                        ctx.author.remove_roles(*roles_to_remove),
                    )

                    # Add new roles to member and restore user roles
                    await asyncio.gather(
                        system_member.add_roles(*new_roles),
                        ctx.author.add_roles(*user_roles),
                    )
                    embed = discord.Embed(
                        title=":white_check_mark: Role Sync Complete",
                        description=
                        f"Finished syncing roles from {ctx.author.mention} to {system_member.mention}\n{ctx.author.mention}'s original roles have been restored",
                        color=discord.Color.green(),
                    )
                    embed.add_field(
                        name=f"__{system_member.display_name}__'s Old Roles",
                        value=embed_member_original_roles
                        if len(embed_member_original_roles) < 1024 else
                        ":hushed: Too many to show" or "None",
                    )
                    new_roles_str = " ".join(
                        [role.mention for role in system_member.roles[1:]])
                    embed.add_field(
                        name=f"__{system_member.display_name}__'s New Roles",
                        value=new_roles_str if len(new_roles_str) < 1024 else
                        ":hushed: Too many to show" or "None",
                    )
                    embed.set_author(
                        name=system_member.display_name,
                        icon_url=system_member.avatar_url,
                    )
                    await instructions.edit(content="", embed=embed)
                    await loading.delete()
            except asyncio.TimeoutError:
                unsynced_roles = system_member.roles[1:]
                roles_to_remove = []
                for role in system_member.roles[1:]:
                    if role.name not in ALWAYS_SYNC_ROLES:
                        roles_to_remove.append(role)
                loading_embed = discord.Embed(
                    title="*Timed out. Hold on while I restore your roles...*",
                    color=discord.Color.orange(),
                )
                await loading.edit(embed=loading_embed)
                async with ctx.channel.typing():
                    await system_member.add_roles(*member_roles)
                    await ctx.author.remove_roles(*roles_to_remove)
                    await ctx.author.add_roles(*user_roles)
                embed = discord.Embed(
                    title="Role Sync Timed Out",
                    description=
                    f"Restored original roles for {system_member.mention}",
                    color=discord.Color.dark_orange(),
                )
                embed.add_field(
                    name=f"`{system_member.display_name}`'s Restored Roles",
                    value=embed_member_original_roles
                    if len(embed_member_original_roles) < 1024 else
                    ":hushed: Too many to show" or "None",
                )
                unsynced_roles_str = " ".join(
                    [role.mention for role in unsynced_roles])
                embed.add_field(
                    name=
                    f"`{system_member.display_name}`'s Unsaved Roles Due to Timeout",
                    value=unsynced_roles_str if len(unsynced_roles_str) < 1024
                    else ":hushed: Too many to show" or "None",
                )
                embed.set_footer(
                    text=
                    'Role sync times out after 5 minutes. Type "done" next time to save changes.'
                )
                embed.set_author(
                    name=system_member.display_name,
                    icon_url=system_member.avatar_url,
                )
                await instructions.edit(content="", embed=embed)
                await loading.delete()
Пример #23
0
    async def tokens(self, ctx: commands.context, *tokens: str):
        """
        Add tokens to queue

        :param ctx: Discord Context
        :param tokens: List of tokens
        """
        async def session(self, author: discord.Member):
            self.token_session.append(author)
            await asyncio.sleep(300)
            self.token_session.remove(author)

        if (ctx.channel.type is discord.ChannelType.private
                and ctx.message.author in self.token_session):
            await ctx.send("Adding tokens...")
            for index, token in enumerate(tokens):
                logger = LogMessage(ctx, title=f"Adding token #{index+1}...")
                await logger.init()
                # Check token
                await logger.log(f"Checking token #{index+1}...")
                all_tokens = conn.execute("SELECT * FROM tokens").fetchall()
                chk = False
                token_client = decode_token(token)
                for chk_token in all_tokens:
                    if decode_token(str(chk_token["token"])) == token_client:
                        chk = True
                check_result, client_id = await check_token(token)
                if chk:
                    logger.title = f"Token #{index + 1} Client ID already in database"
                    logger.color = discord.Color.red()
                    await logger.log("Client ID already exists in database")
                elif not check_result:
                    logger.title = f"Token #{index+1} Invalid"
                    logger.color = discord.Color.red()
                    await logger.log("Bot token is invalid")
                else:
                    await logger.log("Token valid")
                    if (conn.execute("SELECT * FROM tokens WHERE token = ?",
                                     [token]).fetchone() is None):
                        conn.execute("INSERT INTO tokens VALUES(?, ?)",
                                     [token, False])
                        conn.commit()
                        logger.title = f"Bot token #{index+1} added"
                        logger.color = discord.Color.green()
                        c.execute("SELECT * FROM tokens WHERE used = 0")
                        slots = c.fetchall()
                        from polyphony.bot import bot

                        await logger.send(
                            f"[Invite to Server]({discord.utils.oauth_url(client_id, permissions=discord.Permissions(DEFAULT_INSTANCE_PERMS), guild=bot.get_guild(GUILD_ID))})\n\n**Client ID:** {client_id}\nThere are now {len(slots)} slot(s) available"
                        )
                        log.info(
                            f"New token added by {ctx.author} (There are now {len(slots)} slots)"
                        )
                    else:
                        logger.title = f"Token #{index+1} already in database"
                        logger.color = discord.Color.orange()
                        await logger.log("Bot token already in database")
        elif ctx.channel.type is not discord.ChannelType.private:
            await ctx.message.delete()
            if any(role.name in MODERATOR_ROLES
                   for role in ctx.message.author.roles) or ctx.bot.is_owner(
                       ctx.author):
                try:
                    await ctx.message.author.send(
                        f"Token mode enabled for 5 minutes. Add tokens with `{self.bot.command_prefix}tokens [token] (more tokens...)` right here.\n\n*Don't paste a bot token in a server*"
                    )
                except discord.errors.Forbidden:
                    await ctx.send("Enable server DMs to use token command",
                                   delete_after=10.0)
                await session(self, ctx.message.author)
            elif any(role.name in MODERATOR_ROLES
                     for role in ctx.message.author.roles) or ctx.bot.is_owner(
                         ctx.author):
                await ctx.channel.send(
                    f"To add tokens, execute `{self.bot.command_prefix}tokens` as a moderator on a server **WITHOUT A BOT TOKEN**. Then in DMs, use `{self.bot.command_prefix}tokens [token] (more tokens...)`\n\n*Seriously don't paste a bot token in a server*",
                    delete_after=10.0,
                )
Пример #24
0
 async def suspended(self, ctx: commands.context):
     log.debug("Listing suspended members...")
     c.execute("SELECT * FROM members WHERE member_enabled == 0")
     member_list = c.fetchall()
     embed = discord.Embed(title="Suspended Members")
     await self.send_member_list(ctx, embed, member_list)