如何为Disnake Python机器人的普通与付费用户设置不同命令冷却
实现分层冷却(付费用户更短冷却)的两种方案
方案一:自定义冷却检查装饰器(无异常)
这种方式完全不依赖异常抛出,通过命令前置检查处理冷却逻辑,灵活度更高,可自定义提示内容。
import disnake from disnake.ext import commands from disnake.ext.commands import CooldownMapping pro_users = [1234567890, 907508957384] intents = disnake.Intents.all() client = commands.InteractionBot(intents=intents) def tiered_cooldown(): def decorator(command): # 分别创建付费用户和普通用户的冷却规则 pro_cooldown = CooldownMapping.from_cooldown(1, 3, commands.BucketType.user) regular_cooldown = CooldownMapping.from_cooldown(1, 10, commands.BucketType.user) async def check_cooldown(inter): # 根据用户ID判断是否为付费用户,选择对应冷却桶 if inter.author.id in pro_users: bucket = pro_cooldown.get_bucket(inter) else: bucket = regular_cooldown.get_bucket(inter) # 计算剩余冷却时间 current_timestamp = inter.created_at.timestamp() retry_after = bucket.update_rate_limit(current_timestamp) if retry_after: # 冷却未结束,发送提示并阻止命令执行 await inter.response.send_message( f"冷却中,请等待{retry_after:.1f}秒后再使用", ephemeral=True # 仅发送给当前用户 ) return False # 冷却已结束,允许执行命令 return True # 将冷却检查添加为命令的前置检查 command.add_check(check_cooldown) return command return decorator # 使用自定义分层冷却装饰器 @client.slash_command() @tiered_cooldown() async def super_command(inter): await inter.response.send_message('Hello') client.run('TOKEN')
原理说明
- 封装
tiered_cooldown装饰器,内部维护两套独立的冷却映射规则 - 通过
check_cooldown函数作为命令前置检查:- 识别用户类型并匹配对应冷却规则
- 调用
update_rate_limit更新冷却状态并获取剩余时间 - 冷却未结束时发送提示并返回
False阻止命令执行;冷却结束则返回True允许执行
方案二:重写Cooldown类(利用系统自带冷却处理)
这种方式基于disnake自带的冷却系统,通过重写Cooldown类动态调整冷却参数,无需手动处理提示,系统会自动响应冷却触发情况。
import disnake from disnake.ext import commands from disnake.ext.commands import Cooldown pro_users = [1234567890, 907508957384] intents = disnake.Intents.all() client = commands.InteractionBot(intents=intents) class TieredCooldown(Cooldown): def __init__(self): # 初始化默认的普通用户冷却参数 super().__init__(1, 10, commands.BucketType.user) def get_bucket(self, interaction): # 获取用户对应的冷却桶 bucket = super().get_bucket(interaction) # 根据用户类型动态修改冷却参数 if interaction.author.id in pro_users: bucket.rate = 1 # 允许的使用次数 bucket.per = 3 # 冷却时长(秒) else: bucket.rate = 1 bucket.per = 10 return bucket # 使用自定义冷却类替换默认冷却 @client.slash_command() @commands.cooldown_with_cooldown(TieredCooldown()) async def super_command(inter): await inter.response.send_message('Hello') client.run('TOKEN')
原理说明
- 继承
commands.Cooldown类并重写get_bucket方法 - 在获取冷却桶时,根据用户是否为付费用户动态修改桶的
rate(允许次数)和per(冷却时长)参数 - 通过
commands.cooldown_with_cooldown装饰器将自定义冷却应用到命令上,系统自动处理冷却检查与提示
内容的提问来源于stack exchange,提问作者Brevnoo
相关产品推荐
相关产品推荐

