Discord.py如何检测频道内特定消息是否存在 处理四子棋面板被删异常
解决方案
你的思路完全可行,以下是两种可直接落地的实现方案:
方案1:单局游戏内异步监听双事件(适配单局/少局运行场景)
无需修改全局事件逻辑,直接在现有游戏循环中调整,通过asyncio.wait同时监听「用户添加反应」和「面板消息被删除」两个事件,哪个先触发就优先处理哪个:
import asyncio turn = 0 game_over = False # 此处的board_msg是你发送的四子棋面板消息对象,需要提前保存 board_msg_id = board_msg.id while not game_over: try: # 定义两个待监听的任务 wait_reaction = asyncio.create_task(client.wait_for("reaction_add", check=check)) wait_delete = asyncio.create_task(client.wait_for( "raw_message_delete", check=lambda payload: payload.message_id == board_msg_id )) # 等待任意一个任务完成 done, pending = await asyncio.wait( [wait_reaction, wait_delete], return_when=asyncio.FIRST_COMPLETED ) # 取消未完成的任务,避免内存泄漏 for task in pending: task.cancel() # 判断触发的是哪个事件 if wait_delete in done: # 面板被删除,结束游戏 await board_msg.channel.send("Board was not found") game_over = True continue # 否则是用户添加反应事件,走原有逻辑 reaction, user = wait_reaction.result() if turn == 0: # 原有玩家1的落子逻辑 if winning_move(): game_over = True else: # 原有玩家2的落子逻辑 if winning_move(): game_over = True except Exception as e: # 异常兜底处理 game_over = True
方案2:全局事件关联游戏实例(适配多局同时运行场景)
如果机器人要同时支持多频道多局游戏,推荐用全局事件监听+游戏实例映射的方式实现:
- 先定义全局字典存储活跃游戏关联关系
# key为面板消息ID,value为对应游戏的game_over状态(用列表包裹保证可修改) active_games = {}
- 发送完游戏面板消息后,把当前游戏存入全局字典
# 发送面板代码省略,得到board_msg对象 active_games[board_msg.id] = [False] # 列表第0位存储game_over状态 game_over_ref = active_games[board_msg.id]
- 全局监听消息删除事件
@client.event async def on_raw_message_delete(payload): if payload.message_id in active_games: # 获取对应游戏的状态引用,设置为结束 game_over_ref = active_games[payload.message_id] game_over_ref[0] = True # 发送提示,可从payload中获取频道ID发消息 channel = client.get_channel(payload.channel_id) if channel: await channel.send("Board was not found") # 从活跃字典中移除 del active_games[payload.message_id]
- 原有游戏循环的判断条件改为读取引用值
while not game_over_ref[0]: # 原有逻辑不变
注意事项
- 所有游戏结束场景(正常获胜、平局、主动退出、面板删除)都要及时把对应消息ID从
active_games字典中移除,避免内存泄漏 - 优先使用
raw_message_delete事件而非message_delete,前者不受客户端消息缓存限制,消息未存入缓存时删除也能正常触发,稳定性更高 - 可在每次处理用户反应前加兜底校验:尝试
fetch_message获取面板消息,获取失败直接结束游戏,避免极端场景漏判
内容的提问来源于stack exchange,提问作者Minylugin
相关产品推荐
相关产品推荐

