FU510N
FU510N

Reputation: 27

How do I make a leaderboard command? Discord.py

This is my event that configures levels for each member and stores the information in a JSON file. I would like a leaderboard that lists the top 10 people with the highest level but I am unsure how to go about doing this. Thanks in advance.

class on_message(commands.Cog):
    def __init__(self, bot):
        self.bot = bot


    @commands.Cog.listener()
    async def on_message(self, message):
        channel = self.bot.get_channel(config.server_chat)
        with open("users.json", "r") as f:
            users = json.load(f)
            await update_data(users, message.author)
            await add_experience(users, message.author, 1)
            await level_up(users, message.author, message, channel)
            with open("users.json", "w") as f:
                json.dump(users, f)


async def update_data(users, user):
    if not str(user.id) in users:
        users[str(user.id)] = {}
        users[str(user.id)]["experience"] = 0
        users[str(user.id)]["level"] = 1
        users[str(user.id)]["messages"] = 0


async def add_experience(users, user, exp):
    users[str(user.id)]["experience"] += exp
    users[str(user.id)]["messages"] += exp


async def level_up(users, user, message, channel):
    experience = users[str(user.id)]["experience"]
    lvl_start = users[str(user.id)]["level"]
    lvl_end = int(lvl_start * 5)
    update = lvl_start + 1
    if experience >= lvl_end:
        users[str(user.id)]["experience"] = 0
        users[str(user.id)]["level"] = lvl_start + 1
        if not message.author.bot:
            lvl = users[str(user.id)]["level"]
            await channel.send(f"**{user.mention} reached level {update}**")


def setup(bot):
    bot.add_cog(on_message(bot))

Upvotes: 0

Views: 332

Answers (1)

Ratery
Ratery

Reputation: 2917

You can sort JSON data and get first 10 users:

@commands.command()
async def leaderboard(self, ctx):
    with open("users.json", "w") as f:
        data = json.load(f)
    embed = discord.Embed(title="Leaderboard")
    for user_id, user_data in sorted(data.items(), key=lambda x: x[1]['experience'], reverse=True)[:10]:
        embed.add_field(name=self.bot.get_user(user_id), value=f"Experience: {user_data['experience']}\nLevel: {user_data['level']}", inline=False)
    await ctx.send(embed=embed)

Upvotes: 1

Related Questions