如何让Discord Bot在wait_for()完成前禁用全部功能?
解决Discord Bot检测验证码后暂停所有功能的问题
需求说明
我在Discord Bot的on_message(message)函数中使用wait_for(),当前检测到验证码时只会停止垃圾信息发送及部分功能,但其他命令仍可正常运行。需要实现:Bot的所有功能暂停,直到管理员在聊天中发送completed指令后才恢复。
解决方案
核心是通过全局状态变量控制Bot的运行状态,替代原有的wait_for()阻塞逻辑(避免事件循环被单一任务占用),具体修改如下:
1. 定义全局状态变量
在代码最外层添加全局变量,标记Bot是否处于暂停状态:
import asyncio import re import random # 导入其他必要的库... is_paused = False # 控制Bot是否暂停的全局开关 owner_id = 804967354970669057 # 替换为实际的管理员ID # 其他全局变量(ping_id、catch_id、log_id等)...
2. 修改on_message函数逻辑
在函数开头添加暂停状态检查,拦截所有非恢复指令的消息;同时调整验证码检测部分的逻辑,设置暂停状态:
@client.event async def on_message(message): global is_paused, rare1, rare2, num_animal, rare3 # 暂停状态下仅响应管理员的completed指令 if is_paused: if message.author.id == owner_id and message.content.strip().lower() == 'completed': is_paused = False await message.channel.send('Bot功能已恢复') spam.start() return # 其他消息直接忽略,不处理任何功能 ping = client.get_user(int(ping_id)) channel = client.get_channel(int(catch_id)) if message.channel.id == int(catch_id): if message.author.id == Abot: if message.embeds: embed_title = message.embeds[0].title if 'animal in wild has appeared!' in embed_title: spam.cancel() await asyncio.sleep(1) await channel.send('.hint') else: content = message.content if 'The animal is ' in content: if not len(solve(content)): print('animal not found.') else: for i in solve(content): await asyncio.sleep(1) await channel.send(f'.catch {i}') check = random.randint(1, 60) if check == 1: await asyncio.sleep(900) spam.start() else: await asyncio.sleep(1) spam.start() elif 'Congratulations' in content: num_animal += 1 split = content.split(' ') animal = split[7].replace('!','') if 'unusual...' in content: rare1 += 1 print(f'rare1 animal caught! animal: {animal}') print(f'rare1: {rare1} | rare2: {rare2} | rare3: {rare3}') elif re.findall(f'^{animal}$', rare1_list, re.MULTILINE): rare1 += 1 print(f'rare1 animal caught! Animal: {animal}') print(f'rare1: {rare1}') elif re.findall(f'^{animal}$', rare3_list, re.MULTILINE): rare3 += 1 print(f'rare3 animal caught! animal: {animal}') print(f'rare3: {rare3}') else: print(f'Total Animal Caught: {num_animal}') elif 'whoa!' in content: spam.cancel() msg_id = message.id id = message.guild.id await channel.send('Captcha Detected <@868169393866178570>') await ping.send('Hello <@804967354970669057> Captcha detected') log = client.get_channel(int(log_id)) await log.send(f'https://discord.com/channels/{id}/{catch_id}/{msg_id}') print('Captcha detected') # 设置Bot进入暂停状态 is_paused = True if not message.author.bot: await client.process_commands(message)
关键改动说明
- 全局状态变量
is_paused:作为开关控制所有功能的执行,暂停状态下除了管理员的completed指令,其他所有消息都会被直接忽略。 - 移除
wait_for():原有的wait_for()会阻塞事件循环,导致Bot无法处理其他消息;改用状态变量后,事件循环可以正常运行,但所有功能逻辑被拦截,实现真正的全局暂停。 - 恢复逻辑:管理员发送
completed后,重置is_paused为False,并恢复垃圾信息发送任务spam.start()。
内容的提问来源于stack exchange,提问作者Bhavy Upreti
相关产品推荐
相关产品推荐

