Reputation: 11
Hi I was wondering how I would make a leaderboard cmd in discord.py rewrite I have a fully working lvling system but I'm wondering how to show the top ten ppl that are the highest lvl. I tried this but nothing comes up when I type -leaderboard ok so I need to type more to upload this so just ignore what I'm typing now damn I need to write even more ok is this enough hopfully
async def leaderboard(ctx):
with open('users.json', 'r') as f:
data = json.load(f)
top_users = {k: v for k, v in sorted(data.items(), key=lambda item: item[1], reverse=True)}
names = ''
for postion, user in enumerate(top_users):
# add 1 to postion to make the index start from 1
names += f'{postion+1} - <@!{user}> with {top_users[user]}\n'
embed = discord.Embed(title="Leaderboard")
embed.add_field(name="Names", value=names, inline=False)
await ctx.send(embed=embed)
in my users.json folder its user id then xp then lvl.
here is the code for my mainfile
@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}!')
Upvotes: 0
Views: 216
Reputation: 105
Remember that commands in discord.py should use the command decorator to specify that the function is meant to be processed as a command.
Therefore, in your main file, please add:
@client.command()
async def leaderboard(ctx):
with open('users.json', 'r') as f:
data = json.load(f)
top_users = {k: v for k, v in sorted(data.items(), key=lambda item: item[1], reverse=True)}
names = ''
for postion, user in enumerate(top_users):
# add 1 to postion to make the index start from 1
names += f'{postion+1} - <@!{user}> with {top_users[user]}\n'
embed = discord.Embed(title="Leaderboard")
embed.add_field(name="Names", value=names, inline=False)
await ctx.send(embed=embed)
The client.command()
decorator has been added here.
Upvotes: 1