Я работаю над ботом для прокачки. Я обнаружил серьезную проблему с получением опыта, и ею можно чрезвычайно злоупотреблять. Я хочу, чтобы у него было время восстановления после того, как пользователь отправляет сообщение, поэтому, когда пользователь спамит в канале для фарма XP, у него есть время восстановления 0,5 секунды для каждого сообщения, чтобы предотвратить спам. Если вы рассылаете много спама, вы легко можете попасть на первое место, а я не хочу, чтобы это произошло. С ним работает все: получение опыта, таблица лидеров и сообщение о повышении уровня. Я искал в Интернете ответ на этот вопрос, и ни один из них не помог. Кто-нибудь знает? Пожалуйста и спасибо вам!!! :)
Код:
@bot.event
async def on_message(message):
if not message.author.bot:
# specify the encoding as utf-8 when opening the file
with open('level.json','r', encoding='utf-8') as f:
users = json.load(f)
await update_data(users, message.author,message.guild)
await add_experience(users, message.author, 4, message.guild)
await level_up(users, message.author,message.channel, message.guild)
# specify the encoding as utf-8 when writing the file
with open('level.json','w', encoding='utf-8') as f:
json.dump(users, f)
await bot.process_commands(message)
async def update_data(users, user,server):
if not str(server.id) in users:
users[str(server.id)] = {}
if not str(user.id) in users[str(server.id)]:
users[str(server.id)][str(user.id)] = {}
users[str(server.id)][str(user.id)]['experience'] = 0
users[str(server.id)][str(user.id)]['level'] = 1
elif not str(user.id) in users[str(server.id)]:
users[str(server.id)][str(user.id)] = {}
users[str(server.id)][str(user.id)]['experience'] = 0
users[str(server.id)][str(user.id)]['level'] = 1
async def add_experience(users, user, exp, server):
users[str(user.guild.id)][str(user.id)]['experience'] += exp
async def level_up(users, user, channel, server):
experience = users[str(user.guild.id)][str(user.id)]['experience']
lvl_start = users[str(user.guild.id)][str(user.id)]['level']
lvl_end = int(experience ** (1/4))
if str(user.guild.id) != '757383943116030074':
if lvl_start < lvl_end:
await channel.send(':fire: {} has leveled up to **Level {}!**'.format(user.mention, lvl_end))
users[str(user.guild.id)][str(user.id)]['level'] = lvl_end
embed=discord.Embed(title=':fire: {} has leveled up to **Level {}!**'.format(user.mention, lvl_end), color=0x38ff6a)
await bot.get_channel(log_channel_id).send(embed=embed)
@bot.command(aliases = ['rank','lvl'])
async def level(ctx,member: discord.Member = None):
if not member:
user = ctx.message.author
# specify the encoding as utf-8 when opening the file
with open('level.json','r', encoding='utf-8') as f:
users = json.load(f)
lvl = users[str(ctx.guild.id)][str(user.id)]['level']
exp = users[str(ctx.guild.id)][str(user.id)]['experience']
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP " ,color = discord.Color.green())
embed.set_author(name = ctx.author, icon_url = ctx.author.avatar.url)
await ctx.send(embed = embed)
else:
# specify the encoding as utf-8 when opening the file
with open('level.json','r', encoding='utf-8') as f:
users = json.load(f)
lvl = users[str(ctx.guild.id)][str(member.id)]['level']
exp = users[str(ctx.guild.id)][str(member.id)]['experience']
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP" ,color = discord.Color.green())
embed.set_author(name = member, icon_url = member.avatar.url)
await ctx.send(embed = embed)
Пример файла JSON:
{
"757383943116030074": {
"123456789012345678": {
"experience": 0,
"level": 1
}
}
}
2 ответа
Вы можете использовать словарь, чтобы отслеживать время последнего сообщения для каждого пользователя, а затем проверять эту временную метку, чтобы установить время восстановления.
# Create a dictionary to keep track of last message times
message_cooldown = {}
@bot.event
async def on_message(message):
if not message.author.bot:
# Check if the user is in the cooldown dictionary
if message.author.id in message_cooldown:
current_time = time.time()
last_message_time = message_cooldown[message.author.id]
# Check if the user's cooldown has expired (0.5 seconds cooldown)
if current_time - last_message_time < 0.5:
return
with open('level.json', 'r', encoding='utf-8') as f:
users = json.load(f)
await update_data(users, message.author, message.guild)
await add_experience(users, message.author, 4, message.guild)
await level_up(users, message.author, message.channel, message.guild)
# Update the last message time for the user
message_cooldown[message.author.id] = time.time()
with open('level.json', 'w', encoding='utf-8') as f:
json.dump(users, f)
await bot.process_commands(message)
Здесь мы используем модуль времени для расчета времени, прошедшего между сообщениями для каждого пользователя, и устанавливаем время восстановления в 0,5 секунды. Словарь message_cooldown хранит время последнего сообщения для каждого пользователя. Если время восстановления не истекло, сообщение игнорируется.
У меня нет опыта работы с ботами Discord, поэтому, возможно, есть лучший способ сделать это, но, посмотрев на ваш код и файл Ссылка на API, вот как я мог бы это сделать. Переданный объект сообщения содержит время created_at
, которое можно использовать для отслеживания времени восстановления.
Псевдокод будет примерно таким:
async def on_message(message):
# open json file
if message.created_at > users[...][...]['cooldown_end']:
# add xp
users[...][...]['cooldown_end'] = message.created_at + 0.5 seconds
Таким образом, пользователь может получать XP не чаще одного раза в 0,5 секунды.
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.