简体   繁体   中英

Discord Python Bot: Levels and EXP System

So I have a Discord bot I'm building in Python and I made a level system for it. It's working in the most part but I'm having two issues with it.

It's leveling up a tad bit too fast, and also it's reading both bots and webhooks as members.

I've tried adjusting the numbers in the if cur_xp >= round((4 * (cur_lvl ** 3)) / 5) statement but it either speeds it up or does nothing at all.

Here is my code:

import discord
from discord.ext import commands

import json
import asyncio


class Levels(commands.Cog):
    def __init__(self, client):
        self.client = client

        with open(r"path\to\json\file\users.json", "r") as f:
            self.users = json.load(f)

        self.client.loop.create_task(self.save_users())

    async def save_users(self):
        await self.client.wait_until_ready()
        while not self.client.is_closed():
            with open(r"path\to\json\file\users.json", "w") as f:
                json.dump(self.users, f, indent=4)

            await asyncio.sleep(5)

    def lvl_up(self, author_id):
        cur_xp = self.users[author_id]["exp"]
        cur_lvl = self.users[author_id]["level"]

        if cur_xp >= round((4 * (cur_lvl ** 3)) / 5):
            self.users[author_id]["level"] += 1
            return True
        else:
            return False

    @commands.Cog.listener()
    async def on_message(self, message):
        if message.author == self.client.user:
            return

        author_id = str(message.author.id)

        if not author_id in self.users:
            self.users[author_id] = {}
            self.users[author_id]["level"] = 0
            self.users[author_id]["exp"] = 0

        self.users[author_id]["exp"] += 1

        if self.lvl_up(author_id):
            await message.channel.send(f"{message.author.mention} is now level {self.users[author_id]['level']}")

    @commands.command(brief="Displays the user's level and experience.")
    async def level(self, ctx, member: discord.Member = None):
        member = ctx.author if not member else member
        member_id = str(member.id)

        if not member_id in self.users:
            await ctx.send(f"{member} doesn't have a level")
        else:
            embed = discord.Embed(color=member.color, timestamp=ctx.message.created_at)

            embed.set_author(name=f"Member = {member}", icon_url=self.client.user.avatar_url)

            embed.add_field(name="Level", value=self.users[member_id]["level"])
            embed.add_field(name="XP", value=self.users[member_id]["exp"])

            await ctx.send(embed=embed)


def setup(client):
    client.add_cog(Levels(client))

What I'm needing is to slow down the EXP gain a little bit more and also make it stop giving EXP to bots and webhooks.

Any help would be appreciated. As the guide I found to build this didn't give a good explanation of how the variables used fr the XP actually measure it so I'm not sure what numbers to change.

I'd say this is between knowing what the formula's curve looks like and stopping the user from spamming for XP. Great examples of formulas to use and breakdowns of their uses can be found in this questions answers.

As for limiting to only users put a check in your on_message function for if not user.bot: before your leveling code to exclude bots/webhooks.

And to time limit xp gain record the time users last message then subtract that time from the current time and ensure it's greater than a minute or whatever time limit you see fit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM