Home > Software engineering >  How do I add ranks to experience leveling system to discord.py bot?
How do I add ranks to experience leveling system to discord.py bot?

Time:11-08

How do I add ranks to experience leveling system to discord.py bot. This is the code that I've been using ,any help would be appreciated

import discord
from discord.ext import commands
from discord.utils import get
import json
client = commands.Bot(command_prefix="!")


@client.event
async def on_message(message):
    if not message.author.bot:
        await open_account_level(message.author)
        users = await get_level_data()

        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)

#command to check your level details
@client.command()
async def level(ctx):
    await open_account_level(ctx.author)

    users = await get_level_data()

    user = ctx.author

    exp_level = users[str(user.id)]["Exp"]
    bank_amt = users[str(user.id)]["Exp Level"]

    em = discord.Embed(title=f"{ctx.author.name}'s balance", color=discord.Color.red())
    em.add_field(name="Exp", value=exp_level)
    em.add_field(name="Exp Level", value=bank_amt)
    await ctx.send(embed=em)

#adds exp to your account
async def add_experience(users, user, exp):
    users[f'{user.id}']['Exp']  = exp


#levels you up after an exp limit
async def level_up(users, user, message):
    with open('users.json', 'r') as g:
        levels = json.load(g)
    experience = users[f'{user.id}']['Exp']
    lvl_start = users[f'{user.id}']['Exp 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}']['Exp Level'] = lvl_end


#creates an account for you in a json file
async def open_account_level(user):
    users = await get_level_data()
    if str(user.id) in users:
        return False
    else:
        users[str(user.id)] = {}
        users[str(user.id)]["Exp"] = 0
        users[str(user.id)]["Exp Level"] = 0

    with open("users.json", "w") as f:
        json.dump(users, f)
    return True


async def get_level_data():
    with open("users.json", "r") as f:
        users = json.load(f)
    return users
TOKEN = 'token'
client.run(TOKEN)

I want the ranks so that it shows how has the highest exp level and returns their rank among the others in the server Also feel free to point out any mistakes in my code, help would be appreciated.

CodePudding user response:

It's really simple to index a JSON-built database and simply sort through the data. In my example, I use a class to easily access each user's exp.

import discord
import json

@client.command()
async def level(ctx):
    await open_account_level(ctx.author)

    users = await get_level_data()

    class LeaderBoardPosition:
        def __init__(self, id, exp):
            self.id = id
            self.exp = exp

    leaderboard = []

    for user in users:
        leaderboard.append(LeaderBoardPosition(user, users[user]["exp"]))

    top = sorted(leaderboard, key=lambda x: x.exp, reverse=True)

    for user in top:
        if user.id == str(ctx.author.id):
            ranking = top.index(user)   1

    exp_level = users[str(ctx.author.id)]["exp"]
    bank_amt = users[str(ctx.author.id)]["exp_level"]

    embed = discord.Embed(title=f"{ctx.author.name}'s Balance", 
                          color=discord.Color.red())
    
    embed.add_field(name="EXP", value=exp_level, inline=True)
    embed.add_field(name="EXP Level", value=bank_amt, inline=True)
    embed.add_field(name="Ranking", value=ranking, inline=True)

    await ctx.send(embed=embed)

async def open_account_level(user):
    users = await get_level_data()

    if str(user.id) in users:
        return False
    else:
        users[str(user.id)] = {}
        users[str(user.id)]["exp"] = 0
        users[str(user.id)]["exp_level"] = 0

    with open("users.json", "w") as file:
        json.dump(users, file)

    return True

async def get_level_data():
    with open("users.json", "r") as file:
        return json.load(file)
  • Related