You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord D&D骰子机器人使用while循环监听用户回复无响应如何修复

问题原因

你的代码存在以下核心错误:

  • 不允许在命令内部嵌套注册on_message事件:Discord.py的事件是全局生效的,嵌套注册会直接覆盖全局的消息处理逻辑,且不会按你预期的层级触发
  • 死循环直接阻塞了异步事件循环:异步框架中普通的无限while循环会卡住机器人的所有任务执行,自然不会有任何响应也不会抛出报错
  • 拼写错误:结束战斗的判断条件中写了message.conent,漏写字母t,应为message.content
  • 没有发送者过滤规则:所有用户发送的消息都会触发逻辑,容易和其他功能冲突
  • 大小写判断逻辑冗余,不需要逐一枚举所有大小写组合

修复方案

使用Discord.py自带的wait_for方法监听用户消息,不需要自行写循环或嵌套注册事件:

  1. 第一次监听用户回复是否启用掷骰机制
  2. 用户确认启用后,循环调用wait_for监听掷骰、结束战斗指令,直到收到结束战斗指令后退出循环
  3. 增加发送者校验,仅响应触发当前战斗的用户的消息
  4. 用字符串转小写方法简化大小写判断逻辑

修正后代码

import random
# 其他你已有的导入、bot初始化代码保持不变

@bot.command()
async def battle(ctx, arg, arg2):
    await ctx.send(f"**{arg} 与 {arg2} 的战斗已经开始!**")
    await ctx.send("_ _")
    await ctx.send("你是否要为本次战斗启用掷骰机制?[yes/no]")

    # 校验函数:只判断触发战斗的用户在当前频道发的消息
    def check(msg):
        return msg.author == ctx.author and msg.channel == ctx.channel

    # 等待用户回复是否启用掷骰
    reply = await bot.wait_for('message', check=check)
    if reply.content.lower() in ["no", "n"]:
        await ctx.send("好的!你可以将战斗消息置顶归档,开始角色扮演吧!")
        return
    if reply.content.lower() in ["yes", "y"]:
        await ctx.send("没问题!当你的角色要采取行动时,发送「roll die」即可投掷20面骰子判断行动效果;发送「end battle」即可结束战斗!")
    
    # 循环监听战斗期间的指令
    while True:
        msg = await bot.wait_for('message', check=check)
        if msg.content.lower() == "roll die":
            roll = random.randint(1, 20)
            await ctx.send(f"你掷出了:{roll}")
        if msg.content.lower() == "end battle":
            await ctx.send("战斗结束!你可以将我发送的战斗开始消息置顶归档本次战斗!")
            break

内容的提问来源于stack exchange,提问作者catloof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:24:03