Discord.py - 更改频道权限

时间:2021-02-08 09:47:50

标签: python python-3.x discord discord.py

我现在正在开发一款不和谐的游戏。目标是口袋妖怪格斗游戏。

为此,一名玩家用 ?attack <name> 挑战另一名玩家。然后他有 30 秒的时间来接受或拒绝挑战。

攻击命令:

@commands.command()
async def attack(self, ctx, member : Union[discord.Member, int] = None):

    with open("attack.json", "r") as f:
        data = json.load(f)

        attack_dict = {
            "player_1": 1,
            "player_2": 1,
            "attack_message": 1,
        }

        data[str(ctx.guild.id)] = attack_dict

        with open("attack.json", "w") as f:
            json.dump(data, f, indent=4)

        valid_reactions = ["✅", "❌"]

        if member == ctx.message.author:

            embed = discord.Embed(
                title="You can not fight yourself!",
                color=0xf7fcfd
            )

            await ctx.send(embed=embed)
            return

        else:

            embed = discord.Embed(
                title=f"{ctx.message.author.name} wants to fight against {member.display_name}",
                description="Click on the check mark to accept the fight!",
                color=0xf7fcfd
            )

            message_fight_player = await ctx.send(embed=embed)
            await message_fight_player.add_reaction("✅")
            await message_fight_player.add_reaction("❌")

            def check(reaction, user):
                return user == member and user != ctx.author and user.bot is False and str(reaction.emoji) in valid_reactions

            try:

                reaction, user = await self.client.wait_for("reaction_add", timeout=30.0, check=check)

                if str(reaction.emoji) == "✅":

                    await message_fight_player.delete()

                    embed = discord.Embed(
                        title=f"{user.display_name} accepted the fight against {ctx.message.author.display_name}! :eyes:",
                        description="Click on the emoji to watch the fight!",
                        color=0xf7fcfd
                    )

                    message_accept_player = await ctx.send(embed=embed)

                    with open("attack.json", "r") as f:
                        data = json.load(f)

                        data[str(ctx.guild.id)]["player_1"] = ctx.message.author.id
                        data[str(ctx.guild.id)]["player_2"] = member.id
                        data[str(ctx.guild.id)]["attack_message"] = message_accept_player.id

                        with open("attack.json", "w") as f:
                            json.dump(data, f, indent=4)

                    await message_accept_player.add_reaction("?")
                    await message_accept_player.delete(delay=30)

                    await asyncio.sleep(30)

                    with open("attack.json", "r") as f:
                        data = json.load(f)

                        del data[str(ctx.guild.id)]

                        with open("attack.json", "w") as f:
                            json.dump(data, f, indent=2)

                else:

                    await message_fight_player.delete()

                    with open("attack.json", "r") as f:
                        data = json.load(f)

                        del data[str(ctx.guild.id)]

                        with open("attack.json", "w") as f:
                            json.dump(data, f, indent=2)

                    embed = discord.Embed(
                        title=f"{member.display_name} did not want to fight against {ctx.message.author.name}! :thinking:",
                        color=0xf7fcfd
                    )

                    message_declare_player = await ctx.send(embed=embed)
                    await message_declare_player.delete(delay=10)

            except asyncio.TimeoutError:

                await message_fight_player.delete()

                embed = discord.Embed(
                    title=f"{member.display_name} did not want to fight against {ctx.message.author.name}! :thinking:",
                    color=0xf7fcfd
                )

                message_timeout_player = await ctx.send(embed=embed)
                await message_timeout_player.delete(delay=10)

                with open("attack.json", "r") as f:
                    data = json.load(f)

                    del data[str(ctx.guild.id)]

                    with open("attack.json", "w") as f:
                        json.dump(data, f, indent=2)

命令运行正常,但现在问题来了,我想发送一条消息说战斗已被接受。然后应将表情符号 (?) 添加到此消息中,如果您单击此表情符号,您应该可以观看战斗。

我已经尝试过使用 on_raw_reaction_add,但问题是每次有人点击表情符号时它都会创建一个新频道。

@commands.Cog.listener()
async def on_raw_reaction_add(self, payload):

    guild_id = payload.guild_id
    guild = self.client.get_guild(guild_id)

    user_id = payload.user_id
    user = self.client.get_user(user_id)

    channel_id = payload.channel_id
    channel = self.client.get_channel(channel_id)

    message_id = payload.message_id
    emoji = payload.emoji.name

    member = discord.utils.find(lambda m : m.id == payload.user_id, guild.members)

    try:

        with open("attack.json", "r") as jsonData:
            data = json.load(jsonData)

            attack_message_id = data[str(guild_id)]["attack_message"]
            player_1 = data[str(guild_id)]["player_1"]
            player_2 = data[str(guild_id)]["player_2"]

        if message_id == attack_message_id and emoji == "?" and user.bot is False:

            message = await channel.fetch_message(message_id)
            await message.remove_reaction("?",user)

            category = discord.utils.get(guild.categories, name = "Pokemon")

            if category is None:

                category = await guild.create_category(name="Pokemon")

            player_1_name = self.client.get_user(player_1)
            player_2_name = self.client.get_user(player_2)

            overwrites = {
                guild.default_role: discord.PermissionOverwrite(read_messages=False),
                player_1_name: discord.PermissionOverwrite(read_messages=True, send_messages=True),
                player_2_name: discord.PermissionOverwrite(read_messages=True, send_messages=True),
                member: discord.PermissionOverwrite(read_messages=True, send_messages=False)
            }

            attack_channel = await category.create_text_channel("⁉️ poke-fight", overwrites=overwrites)

    except:

        return

因此,每当有人点击表情符号时,我都希望将该人添加到频道中。与 player_1player_2 相同,但查看者应具有 read_messages = True 和 send_messages = False。

1 个答案:

答案 0 :(得分:0)

您专门使用

在所有? raw_reaction_add(s)上创建了一个新的文本频道

attack_channel = await category.create_text_channel("⁉️ poke-fight", overwrites=overwrites)

据我所知,discord 没有将用户移动到其他 text 频道的 bultin 功能,只有使用 await move_to(channel)voice 频道 最接近的是生成一个指向用户必须点击的频道的文本链接:

await channel.send(f'view fight in {attack_channel.mention}')