示例#1
0
    async def user_speaks(self, user):
        user_id = user.id
        xp = 0
        next_role = None
        curr_time = datetime.datetime.now()
        out_message = None

        if user_id not in self.user_cache:
            # First, if user is not in cache, try and fetch from DB
            xp_db = db.fetch_user_xp(user_id)

            if xp_db is not None:
                # If user is in the DB, use that value
                xp = xp_db
            else:
                # Otherwise, give them starting XP value
                xp = STARTING_XP

            # Since they weren't in the cache, make sure they have the correct roles
            next_role = await self.check_roles(user, xp)
        else:
            # If user is in cache, get that value instead
            user_data = self.user_cache[user_id]

            # Check their last timestamp.
            # NOTE: Mayor Lewis used to only give XP if they spoke in a "new" minute. But that would involve rounding a datetime, and I can't be bothered.
            last_mes_time = user_data.timestamp
            dt = curr_time - last_mes_time
            # Users only get XP every minute, so if not enough time has elapsed, ignore them
            if dt < datetime.timedelta(minutes=1):
                return None

            # Else, grab their data
            xp = user_data.xp
            next_role = user_data.next_role_at

        xp += XP_PER_MINUTE * self.xp_multiplier

        # If we have earned enough XP to level up, award and find next role
        if next_role != None and xp >= next_role:
            # Find what the congratulatory message should be
            # Not very efficient, but there will likely only be a handful of ranks
            for rank in RANKS:
                rank_xp = rank["level"] * XP_PER_LVL
                if rank_xp == next_role:
                    out_message = rank["message"]
                    break

            next_role = await self.check_roles(user, xp)

        username = "******".format(user.name, user.discriminator)
        avatar = user.avatar

        # Update their entry in the cache
        self.user_cache[user_id] = UserData(xp, curr_time, username, avatar,
                                            next_role)
        # Update their entry in the database
        db.set_user_xp(user_id, xp, username, avatar)

        return out_message
示例#2
0
    async def refresh_db(self, server):
        leaders = db.get_leaders()

        # Iterate thru every leader on the leaderboard and collect data
        for leader in leaders:
            leader_id = leader[0]
            leader_xp = leader[1]
            user = discord.utils.get(server.members, id=leader_id)

            # Update users that are still in the server
            if user != None:
                leader_name = f"{user.name}#{user.discriminator}"
                leader_avatar = user.avatar

                # NOTE: May be worth to populate the cache here as well
                db.set_user_xp(leader_id, leader_xp, leader_name,
                               leader_avatar)
            # Otherwise, prune their username/avatar so that they don't appear on the leaderboard
            else:
                db.set_user_xp(leader_id, leader_xp, None, None)
示例#3
0
    async def give_xp(self, user, server, xp_add=None):
        user_id = user.id
        xp = 0
        monthly_xp = 0
        next_role = None
        curr_time = datetime.datetime.now()
        out_message = None

        if user_id not in self.user_cache:
            xp = db.fetch_user_xp(user_id)
            monthly_xp = db.fetch_user_monthly_xp(user_id)

            # Since they weren't in the cache, make sure they have the correct roles
            next_role = await self.check_roles(user, xp)
        else:
            # If user is in cache, get that value instead
            user_data = self.user_cache[user_id]
            last_mes_time = user_data.timestamp

            # Check their last timestamp if we aren't manually adding XP
            # NOTE: Mayor Lewis used to only give XP if they spoke in a "new" minute. But that would involve rounding a datetime, and I can't be bothered.
            if xp_add == None:
                dt = curr_time - last_mes_time
                # Users only get XP every minute, so if not enough time has elapsed, ignore them
                if dt < datetime.timedelta(minutes=1):
                    return None

            # Else, grab their data
            xp = user_data.xp
            monthly_xp = user_data.monthly_xp
            next_role = user_data.next_role_at

            # Check if we've rolled over to a new month
            if last_mes_time.month != curr_time.month:
                monthly_xp = 0

        if not xp_add:
            xp_add = XP_PER_MINUTE * self.xp_multiplier

        xp += xp_add
        monthly_xp += xp_add

        # If we have earned enough XP to level up, award and find next role
        if next_role != None and xp >= next_role:
            # Find what the congratulatory message should be
            # Not very efficient, but there will likely only be a handful of ranks
            for rank in RANKS:
                rank_xp = rank["level"] * XP_PER_LVL
                if rank_xp == next_role:
                    if rank['message'] != "":
                        out_message = f"<@{user_id}> {rank['message']}"

                    if rank['welcome']['message'] != "":
                        for welcome_id in rank['welcome']['channels']:
                            chan = discord.utils.get(server.channels,
                                                     id=welcome_id)
                            await chan.send(
                                f"Hello <@{user_id}>! {rank['welcome']['message']}"
                            )
                    break

            next_role = await self.check_roles(user, xp)

        username = f"{user.name}#{user.discriminator}"
        avatar = user.avatar

        # Update their entry in the cache
        self.user_cache[user_id] = UserData(xp, monthly_xp, curr_time,
                                            username, avatar, next_role)
        # Update their entry in the database
        db.set_user_xp(user_id, xp, username, avatar, monthly_xp,
                       curr_time.month)

        return out_message