Beispiel #1
0
 def make_embed(
     self,
     character: Optional[Characters] = None,
     author: Optional[discord.Member] = None,
     color: Optional[discord.Color] = None,
 ) -> Embed:
     character = character or (self.character1 if self.turn == self.player1
                               else self.character2)
     author = author or (self.player1
                         if character == self.character1 else self.player2)
     embed = Embed()
     embed.title = character.name
     embed.set_image(url=random.choice(character.images))
     embed.set_footer(
         text=
         f'{self.special_moves1 if character == self.character1 else self.special_moves2} special moves left | {self.heal_moves1 if character == self.character1 else self.heal_moves2} heal operations left'
     )
     embed.description = self.percentage_and_progess_bar(
         self.health1 if character == self.character1 else self.health2)
     embed.set_author(name=author.display_name,
                      icon_url=author.display_avatar.url)
     if color is not None:
         embed.color = color
     return embed
    async def new(self, ctx):
        """
        Create a new reaction role using some interactive setup.

        ``Note: You can have upto 15 reaction buttons in a message, if it exceeds that it will automatically proceed to next step``
        """
        if not await ctx.prompt(
                "Welcome to the Reaction Light creation program. Please provide the required information once requested. If you would like to abort the creation then click cancel",
                author_id=ctx.author.id,
        ):
            return

        error_messages = []
        user_messages = []
        rl_object = {}
        sent_reactions_message = await ctx.send(
            "Attach roles and emojis separated by one space (one combination"
            " per message). When you are done type `done`. Example:\n:smile:"
            " `@Role`")
        rl_object["reactions"] = {}

        def check(message):
            return message.author.id == ctx.message.author.id and message.content != ""

        try:
            n = 0
            while True:
                if n > 15:
                    break
                reactions_message = await self.bot.wait_for("message",
                                                            timeout=120,
                                                            check=check)
                user_messages.append(reactions_message)
                if reactions_message.content.lower() != "done":
                    reaction = (reactions_message.content.split())[0]
                    try:
                        role = reactions_message.role_mentions[0].id
                    except IndexError:
                        error_messages.append((await ctx.send(
                            "Mention a role after the reaction. Example:\n:smile:"
                            " `@Role`")))
                        continue

                    if reaction in rl_object["reactions"]:
                        error_messages.append((await ctx.send(
                            "You have already used that reaction for another role. Please choose another reaction"
                        )))
                        continue
                    else:
                        try:
                            await reactions_message.add_reaction(reaction)
                            rl_object["reactions"][reaction] = role
                            n += 1
                        except discord.HTTPException:
                            error_messages.append((await ctx.send(
                                "You can only use reactions uploaded to servers the bot has"
                                " access to or standard emojis.")))
                            continue
                else:
                    break
        except asyncio.TimeoutError:
            await ctx.author.send(
                "Reaction Light creation failed, you took too long to provide the requested information."
            )
            return
        finally:
            await sent_reactions_message.delete()
            for message in error_messages + user_messages:
                await message.delete()

        sent_limited_message = await ctx.send(
            "Would you like to limit users to select only have one of the roles at a given time? Please react with a \U0001f512 to limit users or with a \U0000267e to allow users to select multiple roles."
        )

        def reaction_check(payload):
            return (payload.member.id == ctx.message.author.id
                    and payload.message_id == sent_limited_message.id
                    and str(payload.emoji) in ("\U0001f512", "\U0000267e"))

        try:
            await sent_limited_message.add_reaction("\U0001f512")
            await sent_limited_message.add_reaction("\U0000267e")
            limited_message_response_payload = await self.bot.wait_for(
                "raw_reaction_add", timeout=120, check=reaction_check)

            if str(limited_message_response_payload.emoji) == "\U0001f512":
                rl_object["limit_to_one"] = 1
            else:
                rl_object["limit_to_one"] = 0
        except asyncio.TimeoutError:
            await ctx.author.send(
                "Reaction Light creation failed, you took too long to provide the requested information."
            )
            return
        finally:
            await sent_limited_message.delete()

        sent_channel_message = await ctx.send(
            "Mention the #channel where to send the auto-role message.")
        try:
            while True:
                channel_message = await self.bot.wait_for("message",
                                                          timeout=120,
                                                          check=check)
                if channel_message.channel_mentions:
                    target_channel = channel_message.channel_mentions[0]
                    break
                else:
                    error_messages.append((await message.channel.send(
                        "The channel you mentioned is invalid.")))
        except asyncio.TimeoutError:
            await ctx.author.send(
                "Reaction Light creation failed, you took too long to provide the requested information."
            )
            return
        finally:
            await sent_channel_message.delete()
            for message in error_messages:
                await message.delete()

        error_messages = []
        selector_embed = Embed(
            title="Embed_title",
            description="Embed_content",
        )
        selector_embed.set_footer(text=f"{self.bot.user.name}",
                                  icon_url=self.bot.user.display_avatar.url)

        sent_message_message = await message.channel.send(
            "What would you like the message to say?\nFormatting is:"
            " `Message // Embed_title // Embed_content`.\n\n`Embed_title`"
            " and `Embed_content` are optional. You can type `none` in any"
            " of the argument fields above (e.g. `Embed_title`) to make the"
            " bot ignore it.\n\n\nMessage",
            embed=selector_embed,
        )
        try:
            while True:
                message_message = await self.bot.wait_for("message",
                                                          timeout=120,
                                                          check=check)
                # I would usually end up deleting message_message in the end but users usually want to be able to access the
                # format they once used incase they want to make any minor changes
                msg_values = message_message.content.split(" // ")
                # This whole system could also be re-done using wait_for to make the syntax easier for the user
                # But it would be a breaking change that would be annoying for thoose who have saved their message commands
                # for editing.
                selector_msg_body = (msg_values[0] if
                                     msg_values[0].lower() != "none" else None)
                selector_embed = Embed()
                selector_embed.set_footer(
                    text=self.bot.user.name,
                    icon_url=self.bot.user.display_avatar.url,
                )

                if len(msg_values) > 1:
                    if msg_values[1].lower() != "none":
                        selector_embed.title = msg_values[1]
                    if len(msg_values) > 2 and msg_values[2].lower() != "none":
                        selector_embed.description = msg_values[2]

                    # Prevent sending an empty embed instead of removing it
                selector_embed = (selector_embed if selector_embed.title
                                  or selector_embed.description else None)
                database = await self.database_class()
                if selector_msg_body or selector_embed:
                    sent_final_message = None
                    try:
                        custom_id = [
                            str(uuid.uuid4()) for i in rl_object["reactions"]
                        ]
                        sent_final_message = await target_channel.send(
                            content=selector_msg_body,
                            embed=selector_embed,
                            view=ReactionPersistentView(
                                reactions_dict=rl_object["reactions"],
                                custom_id=custom_id,
                                database=database,
                            ),
                        )
                        rl_object["custom_id"] = custom_id
                        rl_object["jump_url"] = str(
                            sent_final_message.jump_url)
                        break
                    except discord.Forbidden:
                        error_messages.append((await message.channel.send(
                            "I don't have permission to send messages to"
                            f" the channel {target_channel.mention}. Please check my permissions and try again."
                        )))
        except asyncio.TimeoutError:
            await ctx.author.send(
                "Reaction Light creation failed, you took too long to provide the requested information."
            )
            return
        finally:
            await sent_message_message.delete()
            for message in error_messages:
                await message.delete()
        await database.set(sent_final_message.id, rl_object)