from redbot.core import Config import asyncio import discord class UserProfile: def __init__(self): self.data = Config.get_conf(self, identifier=1099710897114110101) default_guild = { "wlchannels": [], "blchannels": [], "defaultrole": None, "defaultbg": None, "roles": {}, "database": [], "autoregister": False, "cooldown": 60.0, "whitelist": True, "blacklist": False, "lvlup_announce": False, } default_member = {"exp": 0, "level": 1, "today": 0, "lastmessage": 0.0, "background": None, "description": ""} self.data.register_member(**default_member) self.data.register_guild(**default_guild) @staticmethod def level_func(curr_level: int): return 5 * ((curr_level - 1) ** 2) + (50 * (curr_level - 1)) + 50 async def _set_guild_background(self, guild, bg): await self.data.guild(guild).defaultbg.set(bg) async def _give_exp(self, member, exp): current = await self.data.member(member).exp() await self.data.member(member).exp.set(current + exp) await self._check_exp(member) async def _set_exp(self, member, exp): await self.data.member(member).exp.set(exp) await self._check_exp(member) async def _set_level(self, member, level): await self.data.member(member).level.set(level) async def _is_registered(self, member): async with self.data.guild(member.guild).database() as db: return member.id in db async def _register_user(self, member): data = await self.data.guild(member.guild).database() if data is None: await self.data.guild(member.guild).database.set([]) async with self.data.guild(member.guild).database() as db: db.append(member.id) await self.data.member(member).exp.set(0) async def _set_user_lastmessage(self, member, lastmessage: float): await self.data.member(member).lastmessage.set(lastmessage) async def _get_user_lastmessage(self, member): return await self.data.member(member).lastmessage() async def _downgrade_level(self, member): lvl = await self.data.member(member).level() pastlvl = self.level_func(lvl - 1) xp = await self.data.member(member).exp() while xp < pastlvl and not lvl <= 1: lvl -= 1 pastlvl = self.level_func(lvl) await self.data.member(member).level.set(lvl) async def _check_exp(self, member): lvl = await self.data.member(member).level() lvlup = self.level_func(lvl) xp = await self.data.member(member).exp() if xp >= lvlup: lvl += 1 await self.data.member(member).level.set(lvl) lvlup = self.level_func(lvl) if xp >= lvlup: await self._check_exp(member) elif xp < lvlup and lvl > 1: await self._downgrade_level(member) async def _check_role_member(self, member): # only checks and adds the highest level's role obtainable roles = await self.data.guild(member.guild).roles() lvl = await self.data.member(member).level() to_add = None levels = sorted([int(k) for k in roles.keys()], reverse=True) for k in levels: if lvl >= k: rl = discord.utils.get(member.guild.roles, id=roles[str(k)]) if rl not in member.roles: to_add = rl break if to_add: await member.add_roles(rl) return True else: return False async def _add_guild_role(self, guild, level, roleid): role = discord.utils.get(guild.roles, id=roleid) if role is None: return False rl = await self.data.guild(guild).roles() if isinstance(rl, list): rl = {} rl.update({str(level): roleid}) await self.data.guild(guild).roles.set(rl) async def _remove_guild_role(self, guild, role): rolelist = await self.data.guild(guild).roles() for k, v in rolelist.items(): if v == role.id: del rolelist[k] await self.data.guild(guild).roles.set(rolelist) return async def _get_guild_roles(self, guild): return await self.data.guild(guild).roles() async def _add_guild_channel(self, guild, channel): async with self.data.guild(guild).wlchannels() as chanlist: chanlist.append(channel) async def _remove_guild_channel(self, guild, channel): async with self.data.guild(guild).wlchannels() as chanlist: chanlist.remove(channel) async def _get_guild_channels(self, guild): return await self.data.guild(guild).wlchannels() async def _add_guild_blacklist(self, guild, channel): async with self.data.guild(guild).blchannels() as chanlist: chanlist.append(channel) async def _remove_guild_blacklist(self, guild, channel): async with self.data.guild(guild).blchannels() as chanlist: chanlist.remove(channel) async def _get_guild_blchannels(self, guild): return await self.data.guild(guild).blchannels() async def _toggle_whitelist(self, guild): wl = await self.data.guild(guild).whitelist() if wl: await self.data.guild(guild).whitelist.set(False) return False else: await self.data.guild(guild).whitelist.set(True) return True async def _toggle_blacklist(self, guild): bl = await self.data.guild(guild).blacklist() if bl: await self.data.guild(guild).blacklist.set(False) return False else: await self.data.guild(guild).blacklist.set(True) return True async def _get_exp(self, member): return await self.data.member(member).exp() async def _get_level(self, member): return await self.data.member(member).level() async def _get_level_exp(self, member): lvl = await self.data.member(member).level() return self.level_func(lvl) async def _get_today(self, member): return await self.data.member(member).today() async def _today_addone(self, member): await self.data.member(member).today.set(await self._get_today(member) + 1) async def _set_auto_register(self, guild, autoregister: bool): await self.data.guild(guild).autoregister.set(autoregister) async def _get_auto_register(self, guild): return await self.data.guild(guild).autoregister() async def _set_cooldown(self, guild, cooldown: float): await self.data.guild(guild).cooldown.set(cooldown) async def _get_cooldown(self, guild): return await self.data.guild(guild).cooldown() async def _set_background(self, member, background): await self.data.member(member).background.set(background) async def _get_background(self, member): userbg = await self.data.member(member).background() if userbg is None: return await self.data.guild(member.guild).defaultbg() else: return userbg async def _set_description(self, member, description: str): await self.data.member(member).description.set(description) async def _get_description(self, member): return await self.data.member(member).description() async def _get_leaderboard_pos(self, guild, member): datas = await self.data.all_members(guild) infos = sorted(datas, key=lambda x: datas[x]["exp"], reverse=True) return infos.index(member.id) + 1 async def _get_leaderboard(self, guild): datas = await self.data.all_members(guild) infos = sorted(datas, key=lambda x: datas[x]["exp"], reverse=True) res = [] count = 1 for i in infos: tmp = {} tmp["id"] = i cur = datas[i] tmp["xp"] = cur["exp"] tmp["lvl"] = cur["level"] tmp["today"] = cur["today"] res.append(tmp) count += 1 if count == 10: break return res