I want do add a Role which will gave to everyone who reach lvl 5. I already tried something but that didnt worked. Has somebody an idea how to start?
The stats got saved in a .json file like this:
{"719479402953572383": {"504641949068689430": {"experience": 8, "level": 1}}}
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 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('{} has leveled up to Level {}'.format(user.mention, lvl_end))
users[str(user.guild.id)][str(user.id)]['level'] = lvl_end```
Related
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))
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)
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}!')
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.
I have command custom_role:
#Bot.command()
async def custom_role(ctx, colour: str, *, name: str):
colour = discord.Color(value=int(colour, 16))
print(colour)
await open_account(сtx.author)
user = ctx.author
bal = await update_bank(user)
if 1000>bal:
await ctx.send("You don't have that much money")
return
await ctx.guild.create_role(name = name, colour=colour)
await update_bank(user, -1000, "wallet")
role = discord.utils.get(guild.roles, name = name)
await user.add_roles(role)
emb = discord.Embed(description = "You bought custom role for a week!", color = 0x2ecc71)
await ctx.send(embed = emb)
await asyncio.sleep(604800)
await user.remove_roles(role)
But I have two errors:
Undefined variable 'сtx'
Undefined variable 'guild'
Full traceback: raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'сtx' is not defined
This is very weird, because in other commands ctx parameter works well
There are helper functions used in this command:
async def open_account(user):
users = await get_bank_data()
if str(user.id) in users:
return False
else:
users[str(user.id)] = {}
users[str(user.id)]["wallet"] = 0
with open("mainbank.json", "w") as f:
json.dump(users, f)
return True
async def update_bank(user, change = 0, mode = "wallet"):
users = await get_bank_data()
users[str(user.id)][mode] += change
with open("mainbank.json", "w") as f:
json.dump(users, f)
bal = users[str(user.id)]["wallet"]
return bal
async def get_bank_data():
with open("mainbank.json", "r") as f:
users = json.load(f)
return users
If you know how to fix that, please answer
Command should be like this:
#Bot.command()
async def custom_role(ctx, colour: str, *, name: str):
colour = discord.Color(value=int(colour, 16))
print(colour)
user = ctx.author
await open_account(user)
bal = await update_bank(user)
if 1000>bal:
await ctx.send("You don't have that much money")
return
await ctx.guild.create_role(name = name, colour=colour)
await update_bank(user, -1000, "wallet")
role = discord.utils.get(ctx.guild.roles, name = name)
await user.add_roles(role)
emb = discord.Embed(description = "You bought custom role for a week!", color = 0x2ecc71)
await ctx.send(embed = emb)
await asyncio.sleep(604800)
await user.remove_roles(role)
Because I forgot to put "ctx" before "guild.roles"
I have looked all over the web, and couldn't find an answer. I also asked my friend but he didn't know how to do this command. How can I make this level code display in a leaderboard command?
Here is my code:
#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']
endXP = (lvl + 1) ** 4
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP / {endXP} 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']
endXP = (lvl + 1) ** 4
embed = discord.Embed(title = 'Level {}'.format(lvl), description = f"{exp} XP / {endXP} XP" ,color = discord.Color.green())
embed.set_author(name = member, icon_url = member.avatar_url)
await ctx.send(embed = embed)
Another thing. Most of the people that comment on my posts nowadays comment about a certain question that has nothing to do with what I'm asking. If you want to bombard me with those comments, go do it in the question, not on this post. Thank you :)
#client.command()
async def leaderboard(ctx, x=10):
with open('level.json', 'r') as f:
users = json.load(f)
leaderboard = {}
total=[]
for user in list(users[str(ctx.guild.id)]):
name = int(user)
total_amt = users[str(ctx.guild.id)][str(user)]['experience']
leaderboard[total_amt] = name
total.append(total_amt)
total = sorted(total,reverse=True)
em = discord.Embed(
title = f'Top {x} highest leveled members in {ctx.guild.name}',
description = 'The highest leveled people in this server'
)
index = 1
for amt in total:
id_ = leaderboard[amt]
member = client.get_user(id_)
em.add_field(name = f'{index}: {member}', value = f'{amt}', inline=False)
if index == x:
break
else:
index += 1
await ctx.send(embed = em)
here is some code that may help
I have looked over all of the internet but am not able to solve this error. I have no idea what it means as I'm new to json files and python. This is for my Discord.py leveling system. Please help me.
I don't Understand it at all. Its quite new to me. I am really confused. It doesn't make any sense to me.
Here is my code:
#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}!')
levels.json file:
{}
users.json file:
{}
Try putting {} or [] to your json file