Created
March 5, 2019 21:33
-
-
Save Malarne/78234524e045b5342e58dc5fba26c865 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import re | |
from redbot.core import checks, Config | |
import discord | |
from redbot.core import commands | |
from redbot.core.data_manager import bundled_data_path | |
import asyncio | |
import datetime | |
from .userprofile import UserProfile | |
from PIL import Image, ImageDraw, ImageFont | |
from math import floor, ceil | |
import os | |
import aiohttp | |
from redbot.core.i18n import Translator, cog_i18n | |
from io import BytesIO | |
import functools | |
import textwrap | |
_ = Translator("Leveler", __file__) | |
@cog_i18n(_) | |
class Leveler(commands.Cog): | |
"""A leveler cog !""" | |
def __init__(self, bot): | |
self.bot = bot | |
self.profiles = UserProfile() | |
self.loop = self.bot.loop.create_task(self.start()) | |
self.restart = True | |
self.defaultrole = _("New") | |
self._session = aiohttp.ClientSession() | |
__version__ = "1.0.0" | |
__author__ = "Malarne#1418" | |
__info__ = { | |
"bot_version": "3.0.0rc2", | |
"description": ( | |
"A leveler cog for Red V3\n", | |
"Inspired by Stevy's v2 leveler cog\n", | |
"Please consult the docs at ayrobot.netlify.com for setup informations.\n", | |
"Thanks for using my cog !" | |
), | |
"hidden": False, | |
"install_msg": ( | |
"Thank you for installing this leveler !\n", | |
"Please consult the docs at ayrobot.netlify.com for setup informations." | |
), | |
"required_cogs": [], | |
"requirements": ["pillow"], | |
"short": "Leveler tool, better than MEE6", | |
"tags": ["leveler", "pillow", "fun"] | |
} | |
def __unload(self): | |
asyncio.get_event_loop().create_task(self._session.close()) | |
self.loop.cancel() | |
async def start(self): | |
await self.bot.wait_until_ready() | |
while True: | |
if not self.restart: | |
guilds = self.bot.guilds | |
for i in guilds: | |
profils = await self.profiles.data.all_members(i) | |
for j in profils.keys(): | |
member = i.get_member(j) | |
if member is None: | |
await self._reset_member(i, j) | |
else: | |
await self.profiles.data.member(member).today.set(0) | |
self.restart = True | |
if datetime.datetime.now().strftime('%H:%M') in ["05:00", "05:01", "05:02", "05:03", "05:04", "05:05"]: | |
self.restart = False | |
await asyncio.sleep(30) | |
async def _reset_member(self, guild, memberid): | |
try: | |
base = self.profiles.data._get_base_group(self.profiles.data.MEMBER) | |
await base.clear_raw(str(guild.id), memberid) | |
except: | |
pass | |
@commands.command(hidden=True) | |
@checks.is_owner() | |
async def testreset(self, ctx): | |
self.restart = False | |
await ctx.send(_("Resets in 30 seconds max"), delete_after=30) | |
async def get_avatar(self, user): | |
async with self._session.get(user.avatar_url_as(format="png", size=1024)) as f: | |
data = await f.read() | |
return BytesIO(data) | |
async def get_background(self, url): | |
async with self._session.get(url) as f: | |
data = await f.read() | |
return Image.open(BytesIO(data)) | |
def round_corner(self, radius): | |
"""Draw a round corner""" | |
corner = Image.new('L', (radius, radius), 0) | |
draw = ImageDraw.Draw(corner) | |
draw.pieslice((0, 0, radius * 2, radius * 2), 180, 270, fill=255) | |
return corner | |
def add_corners(self, im, rad): | |
# https://stackoverflow.com/questions/7787375/python-imaging-library-pil-drawing-rounded-rectangle-with-gradient | |
width, height = im.size | |
alpha = Image.new('L', im.size, 255) | |
origCorner = self.round_corner(rad) | |
corner = origCorner | |
alpha.paste(corner, (0,0)) | |
corner = origCorner.rotate(90) | |
alpha.paste(corner, (0, height-rad)) | |
corner = origCorner.rotate(180) | |
alpha.paste(corner, (width - rad, height - rad)) | |
corner = origCorner.rotate(270) | |
alpha.paste(corner, (width - rad, 0)) | |
im.putalpha(alpha) | |
return im | |
def make_full_profile(self, avatar_data, user, xp, nxp, lvl, minone, elo, ldb, desc, bg=None): | |
img = Image.new("RGBA", (340, 390), (17, 17, 17, 255)) | |
if bg is not None: | |
bg_width, bg_height = bg.size | |
ratio = bg_height/390 | |
bg = bg.resize((int(bg_width/(ratio)), int(bg_height/ratio))) | |
if bg.size[0] <340: | |
ratio = bg_width/340 | |
bg = bg.resize((int(bg_width/(ratio)), int(bg_height/ratio))) | |
bg = bg.convert("RGBA") | |
bg.putalpha(128) | |
offset = 0 | |
if bg.size[0] >= 340: | |
offset = (int((-(bg.size[0]-340)/2)), 0) | |
if bg.size[0] <340: | |
offset = (0, int((-(bg.size[1]-390)/2))) | |
img.paste(bg, offset, bg) | |
img = self.add_corners(img, 10) | |
draw = ImageDraw.Draw(img) | |
usercolor = (255, 255, 0) # user.color.to_rgb() | |
aviholder = self.add_corners(Image.new("RGBA", (140, 140), (255, 255, 255, 255)), 10) | |
nameplate = self.add_corners(Image.new("RGBA", (180, 60), (0, 0, 0, 255)), 10) | |
xptot = self.add_corners(Image.new("RGBA", (310, 20), (215, 215, 215, 255)), 10) | |
img.paste(aviholder, (10, 10), aviholder) | |
img.paste(nameplate, (155, 10), nameplate) | |
img.paste(xptot, (15, 340), xptot) | |
fontpath = str(bundled_data_path(self) / "cambria.ttc") | |
font1 = ImageFont.truetype(fontpath, 18) | |
font2 = ImageFont.truetype(fontpath, 22) | |
font3 = ImageFont.truetype(fontpath, 32) | |
avatar = Image.open(avatar_data) | |
avatar_size = 130, 130 | |
avatar.thumbnail(avatar_size) | |
img.paste(avatar, (15, 15)) | |
lxp = xp - minone | |
lnxp = nxp - minone | |
lprc = ceil(lxp / (lnxp / 100)) | |
b_offset = floor(lprc * 3.1) | |
xpbar = self.add_corners(Image.new("RGBA", (b_offset, 20), usercolor), 10) | |
img.paste(xpbar, (12, 340), xpbar) | |
lvl_str = _("Level:") | |
ldb_str = _("Ranking:") | |
rank_str = _("Role:") | |
prog_str = _("Progress:") | |
draw.text((10, 180), lvl_str, fill='white', font=font3) | |
draw.text((10, 220), ldb_str, fill='white', font=font3) | |
draw.text((10, 260), rank_str, fill='white', font=font3) | |
nick = user.display_name | |
if font2.getsize(nick)[0] > 150: | |
nick = nick[:15] + "..." | |
draw.text((154, 316), f"{lprc}%", fill=usercolor, font=font1) | |
draw.text((100, 360), (prog_str + f" {xp}/{nxp}"), fill=usercolor, font=font1) | |
draw.text(((font3.getsize(lvl_str)[0]+20), 180), f"{lvl}", fill=usercolor, font=font3) | |
draw.text(((font3.getsize(ldb_str)[0]+20), 220), f"{ldb}", fill=usercolor, font=font3) | |
draw.text(((font3.getsize(rank_str)[0]+20), 260), f"{elo}", fill=usercolor, font=font3) | |
draw.text((162, 14), f"{nick}", fill=usercolor, font=font2) | |
draw.text((162, 40), f"{user.name}#{user.discriminator}", fill=usercolor, font=font1) | |
margin = 162 | |
offset = 70 | |
count = 0 | |
for line in textwrap.wrap(desc, width=20): | |
count += 1 | |
if count == 6: | |
draw.text((margin, offset), f"{line}...", fill=usercolor, font=font1) | |
break | |
draw.text((margin, offset), f"{line}", fill=usercolor, font=font1) | |
offset += font1.getsize(line)[1] | |
temp = BytesIO() | |
img.save(temp, format="PNG") | |
temp.name = "profile.png" | |
return temp | |
async def profile_data(self, user): | |
"""Async get user profile data to pass to image creator""" | |
avatar = await self.get_avatar(user) | |
try: | |
bg = await self.get_background(await self.profiles._get_background(user)) | |
except: | |
bg = None | |
default = await self.profiles.data.guild(user.guild).defaultrole() | |
data = {"avatar_data":avatar, | |
"user":user, | |
"xp":0, | |
"nxp":100, | |
"lvl":1, | |
"minone":0, | |
"elo": default if default else _("New"), | |
"ldb":0, | |
"desc":"", | |
"bg":bg} | |
if not await self.profiles._is_registered(user): | |
return data | |
else: | |
data["xp"] = await self.profiles._get_exp(user) | |
data["nxp"] = await self.profiles._get_level_exp(user) | |
data["lvl"] = lvl = await self.profiles._get_level(user) | |
data["ldb"] = await self.profiles._get_leaderboard_pos(user.guild, user) | |
data["desc"] = await self.profiles._get_description(user) | |
if data["lvl"] != 1: | |
data["minone"] = await self.profiles._get_xp_for_level(lvl -1) | |
else: | |
data["minone"] = 0 | |
roles = await self.profiles._get_guild_roles(user.guild) | |
if len(roles) == 0: | |
default = await self.profiles.data.guild(user.guild).defaultrole() | |
data["elo"] = default if default else self.defaultrole | |
else: | |
roles = await self.profiles._get_guild_roles(user.guild) | |
if lvl in roles.keys(): | |
data["elo"] = roles[lvl] | |
else: | |
tmp = 0 | |
for k in roles.keys(): | |
if int(k) < lvl: | |
tmp = int(k) | |
pass | |
elif int(k) >= lvl: | |
if tmp == 0: | |
data["elo"] = default if default else self.defaultrole | |
break | |
else: | |
rl = discord.utils.get(user.guild.roles, id=roles[tmp]) | |
data["elo"] = rl.name | |
break | |
return data | |
@commands.command() | |
@commands.guild_only() | |
async def profile(self, ctx, user : discord.Member = None): | |
"""Show your leveler progress. Default to yourself.""" | |
if user is None: | |
user = ctx.author | |
data = await self.profile_data(user) | |
task = functools.partial(self.make_full_profile, **data) | |
task = self.bot.loop.run_in_executor(None, task) | |
try: | |
img = await asyncio.wait_for(task, timeout=60) | |
except asyncio.TimeoutError: | |
return | |
img.seek(0) | |
await ctx.send(file=discord.File(img)) | |
async def on_message(self, message): | |
if type(message.author) != discord.Member: | |
# throws an error when webhooks talk, this fixes it | |
return | |
if type(message.channel) != discord.channel.TextChannel: | |
return | |
if message.author.bot: | |
return | |
if await self.profiles.data.guild(message.guild).whitelist(): | |
if message.channel.id not in await self.profiles._get_guild_channels(message.author.guild): | |
return | |
elif await self.profiles.data.guild(message.guild).blacklist(): | |
if message.channel.id in await self.profiles._get_guild_blchannels(message.author.guild): | |
return | |
if not await self.profiles._is_registered(message.author): | |
if await self.profiles._get_auto_register(message.guild): | |
await self.profiles._register_user(message.author) | |
return | |
elif await self.profiles._is_registered(message.author): | |
if message.content: | |
if message.content[0] in await self.bot.get_prefix(message): | |
return | |
timenow = datetime.datetime.now().timestamp() | |
lastmessage = await self.profiles._get_user_lastmessage(message.author) | |
cooldown = await self.profiles._get_cooldown(message.guild) | |
if timenow - lastmessage < cooldown: | |
# check if we've passed the cooldown | |
# return None if messages are sent too soon | |
return | |
mots = len(message.content.split(" ")) | |
if mots <= 10: | |
xp = 1 | |
elif mots > 10: | |
xp = 2 | |
oldlvl = await self.profiles._get_level(message.author) | |
await self.profiles._today_addone(message.author) | |
await self.profiles._give_exp(message.author, xp) | |
await self.profiles._set_user_lastmessage(message.author, timenow) | |
lvl = await self.profiles._get_level(message.author) | |
if lvl == oldlvl +1 and await self.profiles.data.guild(message.guild).lvlup_announce(): | |
await message.channel.send(_("{} is now level {} !".format(message.author.mention, lvl))) | |
await self.profiles._check_exp(message.author) | |
await self.profiles._check_role_member(message.author) | |
@commands.command() | |
@commands.guild_only() | |
async def register(self, ctx): | |
"""Allow you to start earning experience !""" | |
if await self.profiles._is_registered(ctx.author): | |
await ctx.send(_("You are already registered !")) | |
return | |
else: | |
await self.profiles._register_user(ctx.author) | |
await ctx.send(_("You have been successfully registered !")) | |
return | |
@commands.command() | |
@commands.guild_only() | |
async def toplevel(self, ctx): | |
"""Show the server leaderboard !""" | |
ld = await self.profiles._get_leaderboard(ctx.guild) | |
emb = discord.Embed(title=_("Ranking")) | |
for i in range(len(ld)): | |
cur = ld[i] | |
user = ctx.guild.get_member(cur["id"]) | |
if user is None: | |
await self._reset_member(ctx.guild, cur["id"]) | |
else: | |
txt = _("Level:")+" {} | {} XP | {} ".format(cur["lvl"], | |
cur["xp"], | |
cur["today"]) +_("Messages Today!") | |
emb.add_field(name="{}".format(user.display_name), value=txt) | |
await ctx.send(embed=emb) | |
@commands.group() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def levelerset(self, ctx): | |
"""Configuration commands.""" | |
pass | |
@levelerset.group() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def channel(self, ctx): | |
"""Configure channels whitelist/blacklist.""" | |
pass | |
@channel.group() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def whitelist(self, ctx): | |
"""Whitelist configuration.""" | |
pass | |
@channel.group() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def blacklist(self, ctx): | |
"""Blacklist configuration.""" | |
pass | |
@levelerset.group() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def roles(self, ctx): | |
"""Configuration of roles obtainable from experience.""" | |
pass | |
@commands.group() | |
@commands.guild_only() | |
async def profileset(self, ctx): | |
"""Change settings of your profile.""" | |
pass | |
@profileset.command() | |
@commands.guild_only() | |
async def background(self, ctx, *, link:str=None): | |
"""Change background image of your profile.""" | |
await self.profiles._set_background(ctx.author, link) | |
await ctx.send(_("Background image is now:") + str(link)) | |
@profileset.command() | |
@commands.guild_only() | |
async def description(self, ctx, *, description:str=None): | |
"""Change your profile description""" | |
await self.profiles._set_description(ctx.author, description) | |
await ctx.send(_("Profile description set to: ") + str(description)) | |
@roles.command() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def add(self, ctx, level : int, role : discord.Role): | |
"""Add a role to be given at chosen level.""" | |
await self.profiles._add_guild_role(ctx.guild, level, role.id) | |
await ctx.send(_("Role configured")) | |
@roles.command() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def remove(self, ctx, role : discord.Role): | |
"""Remove a role from the config.""" | |
if role.id in await self.profiles._get_guild_roles(ctx.guild): | |
await self.profiles._remove_guild_role(ctx.guild, role.id) | |
await ctx.send(_("Role deleted.")) | |
else: | |
await ctx.send(_("Remove a role from the list.")) | |
@roles.command() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def show(self, ctx): | |
"""Show the list of roles in the order which you get them from experience.""" | |
emb = discord.Embed() | |
emb.title = _("List of roles configured for this server.") | |
emb.description= _("Guaranteed 100% almost no bugs.") | |
roles = await self.profiles._get_guild_roles(ctx.guild) | |
if len(roles) == 0: | |
await ctx.send(_("No roles yet configured for this guild !")) | |
return | |
for k,v in roles.items(): | |
try: | |
emb.add_field(name=str(k), value=discord.utils.get(ctx.guild.roles, id=v).name) | |
except: | |
# role no longer exists | |
pass | |
await ctx.send(embed=emb) | |
@whitelist.command(name="add") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def _add(self, ctx, channel : discord.TextChannel = None): | |
"""Add a channel to the whitelist.""" | |
if channel is None: | |
channel = ctx.channel | |
if channel.id not in await self.profiles._get_guild_channels(ctx.guild): | |
await self.profiles._add_guild_channel(ctx.guild, channel.id) | |
await ctx.send(_("Channel added")) | |
else: | |
await ctx.send(_("Channel already whitelisted")) | |
@whitelist.command(name="toggle") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def toggle(self, ctx): | |
"""Toggle whitelist on/off.""" | |
new = await self.profiles._toggle_whitelist(ctx.guild) | |
verb = _("activated.") if new else _("deactivated.") | |
await ctx.send(_("Whitelist is {verb}").format(verb=verb)) | |
@whitelist.command(name="remove") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def _remove(self, ctx, channel : discord.TextChannel = None): | |
"""Delete a channel from the whitelist.""" | |
if channel is None: | |
channel = ctx.channel | |
if channel.id not in await self.profiles._get_guild_channels(ctx.guild): | |
await ctx.send(_("This channel isn't whitelisted.")) | |
else: | |
await self.profiles._remove_guild_channel(ctx.guild, channel.id) | |
await ctx.send(_("Channel deleted")) | |
@whitelist.command(name="show") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def _show(self, ctx): | |
"""Show the list of channels configured to allow earning experience.""" | |
emb = discord.Embed() | |
emb.title = _("List of channels configured to allow earning experience on this server.") | |
emb.description = _("More or less, it's not an exact science") | |
channels = await self.profiles._get_guild_channels(ctx.guild) | |
if not len(channels): | |
return await ctx.send(_("No channels configured")) | |
emb.add_field(name="Channels:", value="\n".join([ctx.guild.get_channel(x).mention for x in channels])) | |
await ctx.send(embed=emb) | |
@blacklist.command(name="add") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def __add(self, ctx, channel : discord.TextChannel = None): | |
"""Add a channel to the blacklist.""" | |
if channel is None: | |
channel = ctx.channel | |
if channel.id not in await self.profiles._get_guild_blchannels(ctx.guild): | |
await self.profiles._add_guild_blacklist(ctx.guild, channel.id) | |
await ctx.send(_("Channel blacklisted")) | |
else: | |
await ctx.send(_("Channel already blacklisted")) | |
@blacklist.command(name="toggle") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def _toggle(self, ctx): | |
"""Toggle blacklist on/off.""" | |
new = await self.profiles._toggle_blacklist(ctx.guild) | |
verb = _("activated.") if new else _("deactivated.") | |
await ctx.send(_("Blacklist is {verb}").format(verb=verb)) | |
@blacklist.command(name="remove") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def __remove(self, ctx, channel : discord.TextChannel = None): | |
"""Remove a channel from the blacklist.""" | |
if channel is None: | |
channel = ctx.channel | |
if channel.id not in await self.profiles._get_guild_blchannels(ctx.guild): | |
await ctx.send(_("This channel isn't whitelisted.")) | |
else: | |
await self.profiles._remove_guild_blacklist(ctx.guild, channel.id) | |
await ctx.send(_("Channel deleted")) | |
@blacklist.command(name="show") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def __show(self, ctx): | |
"""Show the list of blacklisted channels.""" | |
emb = discord.Embed() | |
emb.title = _("List of blacklisted channels on this server.") | |
emb.description = _("More or less, it's not an exact science") | |
channels = await self.profiles._get_guild_blchannels(ctx.guild) | |
if not len(channels): | |
return await ctx.send(_("No channels configured")) | |
emb.add_field(name="Channels:", value="\n".join([ctx.guild.get_channel(x).mention for x in channels])) | |
await ctx.send(embed=emb) | |
@levelerset.command() | |
@commands.guild_only() | |
async def autoregister(self, ctx): | |
"""Toggle auto register of users""" | |
if await self.profiles._get_auto_register(ctx.guild): | |
await self.profiles._set_auto_register(ctx.guild, False) | |
await ctx.send(_("Auto register turned off")) | |
else: | |
await self.profiles._set_auto_register(ctx.guild, True) | |
await ctx.send(_("Auto register turned on")) | |
@levelerset.command() | |
@commands.guild_only() | |
async def cooldown(self, ctx, cooldown: float): | |
"""Modify the cooldown of xp gain, default to 60 seconds""" | |
await self.profiles._set_cooldown(ctx.guild, cooldown) | |
await ctx.send(_("Cooldown is now: ") + str(cooldown)) | |
@levelerset.command() | |
@checks.is_owner() | |
@commands.guild_only() | |
async def setlevel(self, ctx, level:int, member:discord.Member=None): | |
"""Modify an user's level""" | |
if member is None: | |
member = ctx.message.author | |
if await self.profiles._is_registered(member): | |
await self.profiles._set_exp(member, 5*((level-1)**2)+(50*(level-1)) +100) | |
else: | |
await ctx.send(_("That user is not registered.")) | |
await ctx.send(member.name + _(" Level set to ") + str(level)) | |
@levelerset.command() | |
@checks.is_owner() | |
@commands.guild_only() | |
async def setxp(self, ctx, xp:int, member:discord.Member=None): | |
"""Modify an user's xp.""" | |
if member is None: | |
member = ctx.message.author | |
if await self.profiles._is_registered(member): | |
await self.profiles._set_exp(member, xp) | |
else: | |
await ctx.send(_("That user is not registered.")) | |
await ctx.send(member.name +_("'s XP set to ") + str(xp)) | |
@levelerset.command() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def defaultbackground(self, ctx, url): | |
"""Allow you to set a default background for your server members.""" | |
bg = re.findall(r"(?:http\:|https\:)?\/\/.*\.(?:png|jpg|gif)", url) | |
if not bg: | |
await ctx.send(_("Please give a direct link to an image on format png, jpg or gif !")) | |
else: | |
background = bg[0] | |
await self.profiles._set_guild_background(ctx.guild, background) | |
await ctx.send(f"Default background set to {background}.") | |
@roles.command(name="defaultrole") | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def default_role(self, ctx, *, name): | |
"""Allow you to rename default role for your guild.""" | |
await self.profiles.data.guild(ctx.author.guild).defaultrole.set(name) | |
await ctx.send(_(f"Default role name set to {name}")) | |
@levelerset.command() | |
@checks.mod_or_permissions(manage_messages=True) | |
@commands.guild_only() | |
async def announce(self, ctx, status : bool): | |
"""Toggle whether the bot will announce levelups. | |
args are True/False.""" | |
await self.profiles.data.guild(ctx.guild).lvlup_announce.set(status) | |
await ctx.send(_("Levelup announce is now {}.").format(_("enabled") if status else _("disabled"))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
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 = 5*((lvl-2)**2)+(50*(lvl-2)) +100 | |
xp = await self.data.member(member).exp() | |
while xp < pastlvl and not lvl <= 1: | |
lvl -= 1 | |
pastlvl = 5*((lvl-1)**2)+(50*(lvl-1)) +100 | |
await self.data.member(member).level.set(lvl) | |
async def _check_exp(self, member): | |
lvl = await self.data.member(member).level() | |
lvlup = 5*((lvl-1)**2)+(50*(lvl-1)) +100 | |
xp = await self.data.member(member).exp() | |
if xp >= lvlup: | |
await self.data.member(member).level.set(lvl+1) | |
lvl += 1 | |
lvlup = 5*((lvl-1)**2)+(50*(lvl-1)) +100 | |
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): | |
roles = await self.data.guild(member.guild).roles() | |
lvl = await self.data.member(member).level() | |
for k,v in roles.items(): | |
if lvl == int(k): | |
rl = discord.utils.get(member.guild.roles, id=v) | |
if rl in member.roles: | |
return True | |
else: | |
await member.add_roles(rl) | |
return True | |
else: | |
pass | |
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 | |
async with self.data.guild(guild).roles() as rolelist: | |
rolelist[level] = roleid | |
return True | |
async def _remove_guild_role(self, guild, role): | |
async with self.data.guild(guild).roles() as rolelist: | |
del rolelist[rolelist.index(role)] | |
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_xp_for_level(self, lvl): | |
return 5 * ((lvl - 1) ** 2) + (50 * (lvl - 1)) + 100 | |
async def _get_level_exp(self, member): | |
lvl = await self.data.member(member).level() | |
return await self._get_xp_for_level(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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment