установить ограничение по времени для ранжирования discord.py

После нескольких поисков я не нашел ничего, что подходило бы мне. Я бы хотел, чтобы пользователи получали XP каждые 30 секунд, но я не знаю как. Если указанный пользователь напишет сообщение, он получит опыт, но если он напишет снова в течение следующих 30 секунд после другого сообщения, он не получит никакого опыта. Это будет происходить до истечения 30 секунд.

@client.event
async def on_message(message):
    if message.author.bot:
        print("Io sono il bot e non posso livellare :(")
        return
    if message.guild.id not in client.msg_dict:
        #print(message.guild.id)
        client.msg_dict[message.guild.id] = {}
        #print(client.msg_dict[message.guild.id])
    #print(message.author.id, client.msg_dict[message.guild.id])
    if message.author.id in client.msg_dict[message.guild.id]:
        #print("Test2")
        if not (time.time() - client.msg_dict[message.guild.id][message.author.id]) > 30:
            #print("Utente bloccato")
            return  # current time - last msg sent time is not > 30
    xp = generateXP()
    print(f"{message.author.name} ha ricevuto {str(xp)} xp")
    cursor = levelsystem_db.cursor()
    cursor.execute(f"SELECT user_xp FROM users WHERE client_id = {str(message.author.id)}")
    result = cursor.fetchall()
    print(result)
    print(len(result))
    if (len(result) == 0):
        print("L'utente non è stato aggiunto al database.")
        cursor.execute(f"INSERT INTO users VALUES({str(message.author.id)} ,{str(xp)} , 0)")
        levelsystem_db.commit()
        print("Aggiunta completata")
        await level_up(cursor, xp, message.author, message)
    else:
        newXP = result[0][0] + xp
        print(f"Gli xp di {message.author.name} sono aggiornati a {newXP}")
        cursor.execute(f"UPDATE users SET user_xp = {str(newXP)} WHERE client_id = {str(message.author.id)}")
        levelsystem_db.commit()
        print(f"Aggiornamento degli xs di {message.author.name} completato.")
        await level_up(cursor, newXP, message.author, message)
def generateXP():
    return random.randint(5,10)

async def level_up(cursor, NewXP, user, message):
    cursor.execute(f"SELECT user_level FROM users WHERE client_id = {str(message.author.id)}")
    level = cursor.fetchall()
    lvl_start = level[0][0]
    lvl_end = int(NewXP ** (1/4))
    print(str(lvl_start))
    print(str(lvl_end))
    if (str(lvl_start) < str(lvl_end)):
        await message.channel.send(f"{user.mention} è salito al livello {lvl_end}")
        print(f"Il livello di {message.author.name} si sta aggiornando al livello {lvl_end}")
        cursor.execute(f"UPDATE users SET user_level = {str(lvl_end)} WHERE client_id = {str(message.author.id)}")
        levelsystem_db.commit()
        print(f"Aggiornamento del livello di {message.author.name} completato.")
    else:
        print("Non è abbastanza!")
        pass

РЕДАКТИРОВАТЬ: Мне абсолютно нужны ответы, которые вы не можете найти, или те, которые вы находите, устарели!


person peppewarrior1    schedule 12.01.2021    source источник


Ответы (2)


Сделайте dict, который содержит идентификаторы пользователей, которые отправили сообщения, и удалите идентификаторы через 30 секунд, и проверьте, используя это в on_message

import time

@client.event
async def on_ready():
    print("Ready")
    client.msg_dict = {}

@client.event
async def on_message(message):
    if message.author.bot:
        print("Io sono il bot e non posso livellare :(")
        return
    if message.guild.id not in client.msg_dict:
        client.msg_dict[message.guild.id] = {}
    if message.author.id in client.msg_dict[message.guild.id]:
        if not (time.time() - client.msg_dict[message.guild.id][message.author.id]) > 30:
            return # current time - last msg sent time is not > 30
    client.msg_dict[message.guild.id][message.author.id] = time.time() # change last msg sent time with current time as the user sent a msg now
    xp = generateXP()
    print(f"{message.author.name} ha ricevuto {str(xp)} xp")
    cursor = levelsystem_db.cursor()
    cursor.execute(f"SELECT user_xp FROM users WHERE client_id = {str(message.author.id)}")
    result = cursor.fetchall()
    print(result)
    print(len(result))
    if (len(result) == 0):
        print("L'utente non è stato aggiunto al database.")
        cursor.execute(f"INSERT INTO users VALUES({str(message.author.id)} ,{str(xp)} , 0)")
        levelsystem_db.commit()
        print("Aggiunta completata")
        await level_up(cursor, xp, message.author, message)
    else:
        newXP = result[0][0] + xp
        print(f"Gli xp di {message.author.name} sono aggiornati a {newXP}")
        cursor.execute(f"UPDATE users SET user_xp = {str(newXP)} WHERE client_id = {str(message.author.id)}")
        levelsystem_db.commit()
        print(f"Aggiornamento degli xs di {message.author.name} completato.")
        await level_up(cursor, newXP, message.author, message)
person Just for fun    schedule 12.01.2021
comment
Я пытался. но он имеет противоположный эффект: он блокирует вас вначале, а затем, по прошествии 30 секунд, он больше не блокирует вас, и проблема возвращается. - person peppewarrior1; 12.01.2021
comment
отредактировал мой ответ, попробуйте это - person Just for fun; 12.01.2021
comment
попробовал еще раз, и на этот раз не прошло два других если. И я заметил, что это ничего не добавляет к client.msg_dict[message.guild.id], что выходит просто {} - person peppewarrior1; 13.01.2021

Я наконец нашел решение, используя MySQL и библиотеку asyncio. Это сценарий, который я применил в соответствии со своими потребностями.

@client.event
async def on_message(message):
    if message.author.bot:
        return
    xp = 5
    cursor = levelsystem_db.cursor()
    cursor.execute(f"SELECT message_id FROM anti_spam WHERE client_id = {str(message.author.id)}")
    check_message = cursor.fetchall()
    if (len(check_message) == 0):
        cursor.execute(f"INSERT INTO anti_spam VALUES({str(message.id)}, {str(message.author.id)}, 1)")
        levelsystem_db.commit()
    else:
        print("Non puoi livellare!")
        return
    
    #In between create your ranking system, giving user experience etc.
    
    await asyncio.sleep(60)
    cursor.execute(f"DELETE FROM anti_spam WHERE message_id = {str(message.id)}")
    levelsystem_db.commit()
    await client.process_commands(message)
person peppewarrior1    schedule 25.01.2021