如何在discord.py中实现raid保护命令自动定时关闭?
解决Discord.py突袭保护自动过期问题
核心方案
利用asyncio的异步任务机制,单独处理24小时倒计时逻辑,完全不阻塞机器人主事件循环,同时避免重复创建倒计时任务。
完整代码示例
import asyncio import discord from discord.ext import commands # 初始化机器人,记得启用所需权限(比如成员事件权限) bot = commands.Bot(command_prefix="!", intents=discord.Intents.all()) # 全局状态变量 raid_protection = 'Offline' # 用于跟踪自动关闭任务,防止重复触发 auto_disable_task = None async def auto_turn_off_raid(): """异步任务:等待24小时后自动关闭突袭保护""" global raid_protection, auto_disable_task await asyncio.sleep(86400) # 24小时 = 86400秒 raid_protection = 'Offline' auto_disable_task = None print("突袭保护已自动关闭(24小时到期)") @bot.command() async def raid_mod_on(ctx): global raid_protection, auto_disable_task if raid_protection == 'Online': await ctx.send("突袭保护已经是开启状态") return raid_protection = 'Online' print("突袭保护系统已开启") await ctx.send("突袭保护已开启,24小时后将自动关闭") # 仅当没有运行中的自动关闭任务时,创建新任务 if auto_disable_task is None or auto_disable_task.done(): auto_disable_task = asyncio.create_task(auto_turn_off_raid()) @bot.command() async def raid_mod_off(ctx): global raid_protection, auto_disable_task if raid_protection == 'Offline': await ctx.send("突袭保护已经是关闭状态") return raid_protection = 'Offline' # 取消正在运行的自动关闭任务(如果存在) if auto_disable_task is not None and not auto_disable_task.done(): auto_disable_task.cancel() auto_disable_task = None print("突袭保护系统已手动关闭") await ctx.send("突袭保护已手动关闭") # 处理成员加入触发突袭保护的场景 @bot.event async def on_member_join(member): global raid_protection, auto_disable_task # 这里可以添加自定义突袭检测逻辑,比如短时间内大量成员加入 # 示例:默认触发开启(实际使用时请替换为你的检测逻辑) if raid_protection == 'Offline': raid_protection = 'Online' print("突袭保护系统已开启(由成员加入事件触发)") if auto_disable_task is None or auto_disable_task.done(): auto_disable_task = asyncio.create_task(auto_turn_off_raid()) # 启动机器人 bot.run("你的Bot令牌")
关键细节说明
- 无阻塞逻辑:用
asyncio.create_task()将倒计时任务加入事件循环,机器人可以正常处理其他命令、消息和事件,不会被sleep阻塞。 - 重复任务防护:通过
auto_disable_task变量跟踪任务状态,避免多次调用raid_mod_on时创建多个重复的倒计时任务。 - 手动关闭兼容:执行
raid_mod_off时会自动取消正在运行的自动关闭任务,确保状态切换即时生效。 - 权限注意:必须在Discord开发者后台启用
成员特权网关意图,否则on_member_join事件无法触发。
新手实用建议
- 测试时可以把
86400改成小数值(比如10,即10秒),快速验证自动关闭功能是否正常。 - 可以在状态切换时给服务器指定频道发送通知,让管理员实时掌握保护状态。
- 如果需要Bot重启后保留当前保护状态,可以把
raid_protection和剩余倒计时时间写入本地文件或数据库,重启后读取恢复。
内容的提问来源于stack exchange,提问作者Daddy Myers
相关产品推荐
相关产品推荐

