我希望仅当满足函数中的条件时才开始命令之一的冷却,例如:
@bot.command
async def move(ctx, destination):
destinations=["d1", "d2", "d3"] # List of valid arguments for the command
if destination in destinations:
movement(destination) # Function to actually move, not important for the question
# Start cooldown only here
else:
await ctx.send("This is not a valid destination")
这样,如果用户输错了目的地,他们将不会因冷却时间而受到惩罚。我该如何实现?
EDIT1:通常会使用discord.py的内置@ commands.cooldown装饰器,这是源代码:
def cooldown(rate, per, type=BucketType.default):
def decorator(func):
if isinstance(func, Command):
func._buckets = CooldownMapping(Cooldown(rate, per, type))
else:
func.__commands_cooldown__ = Cooldown(rate, per, type)
return func
return decorator
但这适用于整个命令。(通常放置在@ bot.command装饰器之后)
答案 0 :(得分:2)
可以有很多方法来制作自己的冷却时间,这里有一个简单的方法可以解决问题。其背后的想法是让机器人“记住”某人上次使用此特定命令的时间,并在允许玩家移动之前对其进行检查。
from datetime import datetime, timedelta
on_cooldown = {} # Dictionary with user IDs as keys and datetime as values
destinations=["d1", "d2", "d3"] # List of valid arguments for the command
move_cooldown = 5 # cooldown of the move command in seconds
@bot.command()
async def move(ctx, destination):
if destination in destinations:
author = ctx.author.id
try:
# calculate the amount of time since the last (successful) use of the command
last_move = datetime.now() - on_cooldown[author]
except KeyError:
# the key doesn't exist, the player used the command for the first time
# or the bot has been shut down since
last_move = None
on_cooldown[author] = datetime.now()
if last_move is None or last_move.seconds > move_cooldown:
# move(...)
on_cooldown[author] = datetime.now() # the player successfully moved so we start his cooldown again
await ctx.send("You moved!")
else:
await ctx.send("You're still on cooldown.")
else:
await ctx.send("This is not a valid destination")
注意:您可能需要删除@bot.command
装饰符后的括号。
答案 1 :(得分:0)