Discord机器人多on_reaction_add事件冲突问题解决咨询
问题
我做了一个可用的Discord机器人,添加命令时遇到问题:创建了多个on_reaction_add函数,但无法同时生效。尝试改函数名比如on_react_add也没用,始终只能运行其中一个。以下是两个相关的on_reaction_add事件代码,怎么让两者都正常工作?
第一个无法生效的on_reaction_add:
@client.event async def reaction_add(reaction, user): await bot_events.on_reaction_add(reaction, user)
bot_events.on_reaction_add代码:
async def on_reaction_add(reaction, user): if user.bot: return if user.id not in players: return emoji = reaction.emoji await reaction.remove(user) if reaction.message != players[user.id]['game']: return if emoji == "⬅️": players[user.id]['dir'] = "left" if emoji == "➡️": players[user.id]['dir'] = "right" if emoji == "⬇️": players[user.id]['dir'] = "down" if emoji == "⬆️": players[user.id]['dir'] = "up"
另一个on_reaction_add:
@client.event async def on_reaction_add(reaction, user): global h_movement global rotation_pos if user != client.user: msg = reaction.message if str(reaction.emoji) == "▶": #Play button pressed print('User pressed play') await reset_game() await msg.remove_reaction("❌", client.user) #Remove delete embed = discord.Embed(description=format_board_as_str(), color=embed_colour) await msg.remove_reaction("▶", user) await msg.remove_reaction("▶", client.user) await msg.edit(embed=embed) await msg.add_reaction("⬅") #Left await msg.add_reaction("⬇") #Down await msg.add_reaction("➡") #Right await msg.add_reaction("🔃") #Rotate await msg.add_reaction("❌") #Stop game starting_shape = get_random_shape() await run_game(msg, starting_shape) if str(reaction.emoji) == "⬅": #Left button pressed print('Left button pressed') h_movement = -1 #move 1 left await msg.remove_reaction("⬅", user) if str(reaction.emoji) == "➡": #Right button pressed print('Right button pressed') h_movement = 1 #move +1 right await msg.remove_reaction("➡", user) if str(reaction.emoji) == "⬇": #Down button pressed print('Down button pressed') global down_pressed down_pressed = True await msg.remove_reaction("⬇", user) if str(reaction.emoji) == "🔃": #Rotate clockwise button pressed print('Rotate clockwise button pressed') global rotate_clockwise rotate_clockwise = True if rotation_pos < 3: rotation_pos += 1 else: rotation_pos = 0 #go back to original pos await msg.remove_reaction("🔃", user) if str(reaction.emoji) == "❌": await reset_game() await msg.delete() if str(reaction.emoji) == "🔴": await message.edit(content="")
解决方案
discord.py中,同一个事件只能保留一个用@client.event装饰的处理函数——后面装饰的会直接覆盖前面的,所以你之前的两个on_reaction_add只会运行最后定义的那个。要让两个逻辑都生效,有两种可行方法:
方法1:合并逻辑到同一个事件处理函数
把两个on_reaction_add里的逻辑整合到一个函数中,依次执行:
@client.event async def on_reaction_add(reaction, user): # 先处理方向控制的逻辑 await bot_events.on_reaction_add(reaction, user) # 再处理俄罗斯方块的操作逻辑 global h_movement, rotation_pos, down_pressed, rotate_clockwise if user != client.user: msg = reaction.message if str(reaction.emoji) == "▶": #Play button pressed print('User pressed play') await reset_game() await msg.remove_reaction("❌", client.user) #Remove delete embed = discord.Embed(description=format_board_as_str(), color=embed_colour) await msg.remove_reaction("▶", user) await msg.remove_reaction("▶", client.user) await msg.edit(embed=embed) await msg.add_reaction("⬅") #Left await msg.add_reaction("⬇") #Down await msg.add_reaction("➡") #Right await msg.add_reaction("🔃") #Rotate await msg.add_reaction("❌") #Stop game starting_shape = get_random_shape() await run_game(msg, starting_shape) if str(reaction.emoji) == "⬅": #Left button pressed print('Left button pressed') h_movement = -1 #move 1 left await msg.remove_reaction("⬅", user) if str(reaction.emoji) == "➡": #Right button pressed print('Right button pressed') h_movement = 1 #move +1 right await msg.remove_reaction("➡", user) if str(reaction.emoji) == "⬇": #Down button pressed print('Down button pressed') down_pressed = True await msg.remove_reaction("⬇", user) if str(reaction.emoji) == "🔃": #Rotate clockwise button pressed print('Rotate clockwise button pressed') rotate_clockwise = True if rotation_pos < 3: rotation_pos += 1 else: rotation_pos = 0 #go back to original pos await msg.remove_reaction("🔃", user) if str(reaction.emoji) == "❌": await reset_game() await msg.delete() if str(reaction.emoji) == "🔴": await msg.edit(content="") # 原代码此处用了未定义的message,修正为msg
方法2:使用add_listener注册多个事件处理函数
discord.py允许用client.add_listener()方法注册多个同一事件的处理函数,这样两个逻辑都会被触发:
首先修改第一个函数的注册方式:
# 定义方向控制的事件处理函数 async def handle_game_direction_reaction(reaction, user): await bot_events.on_reaction_add(reaction, user) # 将函数注册为on_reaction_add事件的监听器 client.add_listener(handle_game_direction_reaction, "on_reaction_add")
然后保留第二个函数的逻辑,也用add_listener注册(或者继续用@client.event,不冲突):
# 定义俄罗斯方块操作的事件处理函数 async def handle_tetris_reaction(reaction, user): global h_movement, rotation_pos if user != client.user: msg = reaction.message # 以下逻辑和原代码完全一致... # 注册为监听器 client.add_listener(handle_tetris_reaction, "on_reaction_add")
这样两个监听器都会在on_reaction_add事件触发时被调用执行。
内容的提问来源于stack exchange,提问作者ColdX
相关产品推荐
相关产品推荐

