【问题标题】:How to create a leveling system with discord.py with python?如何使用 python 使用 discord.py 创建调平系统?
【发布时间】:2020-09-14 10:44:56
【问题描述】:

我试图在我的机器人中加入一个调平系统,但出了点问题。级别在每条消息之后而不是在指定参数之后上升。如何让它正常工作?如何用discord.py创建调平系统?

这是我的代码:

@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)

【问题讨论】:

  • 你能分享你的代码吗?
  • 请编辑您的问题以包含您现有的代码、任何需要的回溯以及您的预期行为(例如,下一级需要多少 XP)

标签: python bots discord discord.py


【解决方案1】:

我真的要小心不要将 json 文件用作数据库。 Json 文件在覆盖时往往会损坏。有很多关于开发人员落入陷阱并被烧毁的警示故事。对于轻量级、快速的解决方案,我建议使用 sqlite。它是python中的内置模块,比json文件更稳定、更安全。一个非常简单的带有 cmets 的 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.
    
    

【讨论】:

    【解决方案2】:

    这是一个有效的:

    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)
    

    【讨论】:

      【解决方案3】:

      我为你做了一个。它也是特定于服务器的

      @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)
      

      【讨论】:

        【解决方案4】:
        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)
        

        【讨论】:

        • 请解释你的代码是做什么的以及它是怎么做的。切勿自行发布代码。
        【解决方案5】:

        这是一个可能对您有所帮助的关卡系统代码:

        @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}!')
        

        【讨论】:

        • 限制老会员。
        猜你喜欢
        • 2021-07-28
        • 2021-09-02
        • 2020-11-25
        • 2018-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        相关资源
        最近更新 更多