[英]How to create a leveling system with discord.py with python?
I tried to make a levelling system into my bot but something went wrong.我试图在我的机器人中加入一个调平系统,但出了点问题。 The level rose after each message and not after the specified parameter.级别在每条消息之后而不是在指定参数之后上升。 How to make it work properly?如何让它正常工作? How to create a leveling system with discord.py
?如何使用discord.py
创建调平系统?
Here is my code:这是我的代码:
@client.event
async def on_message( message ):
if message.author.bot:
return
else:
member = message.author.name
msg_len = len(message.content)
rand_number_1 = randint( 1, 10 )
exp_first = msg_len * rand_number_1
coins_first = exp_first // 10
data_levels_member_first = { 'exp': 0, 'coins': 0, 'level': 0}
filename = f'./Data/Profiles/Profile{message.author.name}{message.guild}.json'
try:
data = load( filename )
except Exception:
dump( filename, data_levels_member_first )
data = load( filename )
exp_member = data['exp']
coins_member = data['coins']
lvl_member = data['level']
exp = exp_first + exp_member
coins = coins_first + coins_member
lvl = exp ** (1/4)
if lvl_member < lvl:
lvl_member += 1
print('You lvl up!')
data_levels_member = { 'exp': exp, 'coins': coins, 'level': lvl_member}
dump( filename, data_levels_member )
await client.process_commands(message)
import json
import discord
try:
with open("users.json") as fp:
users = json.load(fp)
except Exception:
users = {}
def save_users():
with open("users.json", "w+") as fp:
json.dump(users, fp, sort_keys=True, indent=4)
def add_points(user: discord.User, points: int):
id = user.id
if id not in users:
users[id] = {}
users[id]["points"] = users[id].get("points", 0) + points
print("{} now has {} points".format(user.name, users[id]["points"]))
save_users()
def get_points(user: discord.User):
id = user.id
if id in users:
return users[id].get("points", 0)
return 0
@client.event
async def on_message(message):
if message.author == client.user:
return
print("{} sent a message".format(message.author.name))
if message.content.lower().startswith("!lvl"):
msg = "You have {} points!".format(get_points(message.author))
await client.process_commands(message.channel, msg)
add_points(message.author, 1)
client.run(token)
I've made one for you.我给你做了一个。 It's server specific as well它也是特定于服务器的
@client.event
async def on_message(message):
if not message.author.bot:
print('function load')
with open('level.json','r') as f:
users = json.load(f)
print('file load')
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)
with open('level.json','w') as f:
json.dump(users, f)
await client.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('{} has leveled up to Level {}'.format(user.mention, lvl_end))
users[str(user.guild.id)][str(user.id)]['level'] = lvl_end
@client.command(aliases = ['rank','lvl'])
async def level(ctx,member: discord.Member = None):
if not member:
user = ctx.message.author
with open('level.json','r') 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:
with open('level.json','r') 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)
Here's a working one:这是一个有效的:
import discord
from discord.ext import commands
import asyncio
import os
import json
bot = commands.Bot(command_prefix="!")
##### START LEVEL COMMAND #####
with open("users.json", "ab+") as ab:
ab.close()
f = open('users.json','r+')
f.readline()
if os.stat("users.json").st_size == 0:
f.write("{}")
f.close()
else:
pass
with open('users.json', 'r') as f:
users = json.load(f)
@bot.event
async def on_message(message):
if message.author.bot == False:
with open('users.json', 'r') as f:
users = json.load(f)
await add_experience(users, message.author)
await level_up(users, message.author, message)
with open('users.json', 'w') as f:
json.dump(users, f)
await bot.process_commands(message)
async def add_experience(users, user):
if not f'{user.id}' in users:
users[f'{user.id}'] = {}
users[f'{user.id}']['experience'] = 0
users[f'{user.id}']['level'] = 0
users[f'{user.id}']['experience'] += 6
print(f"{users[f'{user.id}']['level']}")
async def level_up(users, user, message):
experience = users[f'{user.id}']["experience"]
lvl_start = users[f'{user.id}']["level"]
lvl_end = int(experience ** (1 / 4))
if lvl_start < lvl_end:
await message.channel.send(f':tada: {user.mention} has reached level {lvl_end}. Congrats! :tada:')
users[f'{user.id}']["level"] = lvl_end
@bot.command()
async def rank(ctx, member: discord.Member = None):
if member == None:
userlvl = users[f'{ctx.author.id}']['level']
await ctx.send(f'{ctx.author.mention} You are at level {userlvl}!')
else:
userlvl2 = users[f'{member.id}']['level']
await ctx.send(f'{member.mention} is at level {userlvl2}!')
##### END LEVEL COMMAND #####
bot.run(TOKEN)
I'd really caution against using a json file as a database.我真的要小心不要使用 json 文件作为数据库。 Json files tend to get corrupted on overwrite. Json 文件在覆盖时往往会损坏。 There are a ton of cautionary tales of developers who have fallen into that trap and gotten burned.有很多关于开发人员落入陷阱并被烧毁的警示故事。 For a lightweight, quick solution, I'd recommend using sqlite.对于轻量级、快速的解决方案,我建议使用 sqlite。 It's a built-in module in python and is much more stable and secure than a json file.它是 python 中的内置模块,比 json 文件更稳定和安全。 A very simple sqlite3 example with comments (intents not included):一个非常简单的带有注释的 sqlite3 示例(不包括意图):
import sqlite3
import discord
bot = commands.Bot(command_prefix="!")
@client.event
async def on_member_join(member): ###add a row in the db for the new member when they join
user = member.id
conn = sqlite3.connect('your_db_here.db')
cur = conn.cursor()
cur.execute('INSERT INTO table_name_here("userid", "xp", "level")VALUES(user, 0, 0)')
conn.commit()
conn.close()
await member.send("Your welcome message here")
@client.event
async def on_message(message):
user = message.author.id
conn = sqlite3.connect('your_db_here.db')
cur = conn.cursor()
cur.execute('SELECT xp, level FROM table_name_here WHERE userid = ?')
results = cur.fetchone()
row = results[0] ### results will be a list and since you're only fetching one record in this instance, you only need the first index
old_xp = row[0] ##the first item in the index, in this case, xp
old_level = row[1] ## the second item in the index, in this case, level
new_xp = old_xp + 1
if new_xp == 25: #this is where you set the threshold for leveling up to the first level
new_level = 1
else:
new_level = old_level
###add more logic here for successive level-ups
cur.execute('UPDATE table_name_here SET xp = ?, level = ? WHERE userid = ?', (new_xp, new_level, user)
conn.commit()
conn.close()
### here is where you'd put any sort of messaging if a person levels up or however you'd like to set it.
Here is a level sytem code that might help you:这是一个可能对您有所帮助的关卡系统代码:
@client.event
async def on_member_join(member):
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, member)
with open('users.json', 'w') as f:
json.dump(users, f)
@client.event
async def on_message(message):
if message.author.bot == False:
with open('users.json', 'r') as f:
users = json.load(f)
await update_data(users, message.author)
await add_experience(users, message.author, 5)
await level_up(users, message.author, message)
with open('users.json', 'w') as f:
json.dump(users, f)
await client.process_commands(message)
async def update_data(users, user):
if not f'{user.id}' in users:
users[f'{user.id}'] = {}
users[f'{user.id}']['experience'] = 0
users[f'{user.id}']['level'] = 1
async def add_experience(users, user, exp):
users[f'{user.id}']['experience'] += exp
async def level_up(users, user, message):
with open('levels.json', 'r') as g:
levels = json.load(g)
experience = users[f'{user.id}']['experience']
lvl_start = users[f'{user.id}']['level']
lvl_end = int(experience ** (1 / 4))
if lvl_start < lvl_end:
await message.channel.send(f'{user.mention} has leveled up to level {lvl_end}')
users[f'{user.id}']['level'] = lvl_end
@client.command()
async def level(ctx, member: discord.Member = None):
if not member:
id = ctx.message.author.id
with open('users.json', 'r') as f:
users = json.load(f)
lvl = users[str(id)]['level']
await ctx.send(f'You are at level {lvl}!')
else:
id = member.id
with open('users.json', 'r') as f:
users = json.load(f)
lvl = users[str(id)]['level']
await ctx.send(f'{member} is at level {lvl}!')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.