K
K
Korol_Kotov2021-06-01 15:38:49
Python
Korol_Kotov, 2021-06-01 15:38:49

How to make a cooldown on the discord.py command?

I'm trying to make a cooldown per command with asyncio.sleep(time) and a json database:

@commands.command()
  async def work(self, ctx):
    with open('Databases/economy.json','r') as f:
      money = json.load(f)

    with open('Databases/queue.json','r') as f:
      queue = json.load(f)

    if not str(ctx.guild.id) in queue:
      queue[str(ctx.guild.id)] = {}
      queue[str(ctx.guild.id)]["Work"] = {}
      queue[str(ctx.guild.id)]["Rob"] = {}

      with open('Databases/queue.json','w') as f:
          json.dump(queue, f, indent=4)

    if not str(ctx.author.id) in money[str(ctx.guild.id)]["Users"]:
      money[str(ctx.guild.id)]["Banks"][str(ctx.author.id)] = 0
      money[str(ctx.guild.id)]["Users"][str(ctx.author.id)] = 0
      
      with open('Databases/queue.json','w') as f:
          json.dump(queue, f, indent=4)

    if not str(ctx.author.id) in queue[str(ctx.guild.id)]["Work"]:
      NotQueueWork = discord.Embed(description = f'**{ctx.author.mention}, вы поработали и получили `{money[str(ctx.guild.id)]["Settings"]["WorkMoney"]}` {money[str(ctx.guild.id)]["Settings"]["EconomyEmoji"]}!**', color = 0xd6ff8f)
      NotQueueWork.set_author(name = f'Работа', icon_url = self.client.user.avatar_url)

      await ctx.send(embed = NotQueueWork)

      money[str(ctx.guild.id)]["Users"][str(ctx.author.id)] += money[str(ctx.guild.id)]["Settings"]["WorkMoney"]

      with open('Databases/economy.json','w') as f:
          json.dump(money, f, indent=4)
          
      needMoney = int(money[str(ctx.guild.id)]["Settings"]["WorkTime"])
      
      timestamp = datetime.timestamp(datetime.now(timezone.utc))
      
      nowdate = int(timestamp) + 10800 + needMoney
      
      nowtimestamp = datetime.fromtimestamp(nowdate, timezone.utc)

      queue[str(ctx.guild.id)]["Work"][str(ctx.author.id)] = {}
      queue[str(ctx.guild.id)]["Work"][str(ctx.author.id)]["WorkGG"] = str(nowtimestamp.strftime("%Y.%m.%d %H:%M:%S"))

      with open('Databases/queue.json','w') as f:
          json.dump(queue, f, indent=4)

      await wait(needMoney)

      del queue[str(ctx.guild.id)]["Work"][str(ctx.author.id)]

      with open('Databases/queue.json','w') as f:
          json.dump(queue, f, indent=4)
      
    if str(ctx.author.id) in queue[str(ctx.guild.id)]["Work"]:   
        InQueueWork = discord.Embed(description = f'**{ctx.author.mention}, вы устали, приходите в `{queue[str(ctx.guild.id)]["Work"][str(ctx.author.id)]["WorkGG"]}` по МСК!**', color = 0xff0303)
        InQueueWork.set_author(name = f'Работа', icon_url = self.client.user.avatar_url)
        
        return await ctx.send(embed = InQueueWork)

But, this is the situation:
I have a cooldown of 3 hours, I write a command, get coins and wait 3 hours. 4 hours pass, I write a command, but it says: you are tired, come at 16:35:36. My time is 17:35:36
I'm waiting for more, but the result is the same, that is, the cooldown does not work.
I tried to make it through @cooldown.cooldown(rate, per, type)
But, there is also a problem here:
I want to make it take the time that is set in the database and set it to per cooldown, but nothing works for me.
Help, tell me how to make a good cooldown? If you need something, please clarify.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
soremix, 2021-06-01
@Korol_Kotov

I didn’t understand the code, I quickly looked, but in my opinion you overloaded it a lot. If you want to do a check by hand, then I don’t know why wait through sleep and so on.
Your team is called work, money is given to a person. The output timestamp is written to your json file. Here it depends on the need, you can only record the time of the last issue, you can record the time of the last issue + the time when the next time you need to issue it, and so on. Suppose, for example, there will be only one field - the time of the last command execution in the form of a timestamp. Then you just take the time of the last execution and add it to your delay for the command (in seconds, of course), and if the resulting number is less than the current timestamp, execute the command.

def work():
    with open('users.json', 'r', encoding='utf-8') as f:
        users = json.load(f)

    if ctx.author.id not in users:
        users[ctx.author.id] = {'last_work_time': 0}

    current_timestamp = int(time.time())
    work_cooldown = 60*60 # допустим задержка 1 час

    last_work_time = users[ctx.author.id]['last_work_time']

    if last_work_time + work_cooldown <= current_timestamp or last_work_time == 0:
        send_message('Ваша оплата: xxx')
        users[ctx.author.id]['last_work_time'] = current_timestamp

        with open('users.json', 'w', encoding='utf-8') as f:
            json.dump(users, f)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question