async def on_member_join(self, member): async with session_lock: with Session() as session: db_player = get_create(session, crud_player, obj_in=CreatePlayer( **{ "discord_id": member.id, "name": member.name, "hidden": True })) db_server = get_create(session, crud_server, obj_in=CreateServer( **{ "discord_id": member.guild.id, "name": member.guild.name, "server_exp": 0, "channel": None })) get_create(session, crud_member, obj_in=CreateMember( **{ "exp": 0, "player_uuid": db_player.uuid, "server_uuid": db_server.uuid, "level_uuid": None }))
async def register(self, ctx): """ Register yourself to be shown on bot.hellshade.fi. :param ctx: :return: """ async with ctx.message.channel.typing(): async with session_lock: with Session() as session: player = get_create( session, crud_player, obj_in=CreatePlayer( **{ "discord_id": ctx.message.author.id, "name": ctx.message.author.name, "hidden": False })) if player.hidden: crud_player.update(session, db_obj=player, obj_in={'hidden': False}) embed = discord.Embed() embed.set_author(name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) embed.title = "Success!" embed.description = f"You have successfully registered " \ f"yourself. You are now shown on " \ f"[{settings.URL}]({settings.URL})" embed.colour = Colors.success await ctx.send(embed=embed)
def get_create_ctx( ctx: Context, db: Session, crud, overrides: Optional[dict]={} ): """ Create object if it doesn't exist with context :param ctx: Discord Context :param db: Database session :param crud: Crud-object to be used :param overrides: Override data :return: object """ obj = None player_uuid = None server_uuid = None if isinstance(crud, CRUDLevel): if overrides.get('level', 1) < 1: raise ValueError('Level must be 1 or greater!') obj = crud.get_by_value(db, overrides.get('level', 1)) previous = None if overrides.get('level', 1) > 1: prev_overrides = overrides prev_overrides['levels'] -= 1 previous = get_create_ctx(ctx, db, crud, prev_overrides) if obj is None and \ (previous is not None or overrides.get('level', 1) == 1): level_dict = { 'title': overrides.get('title'), 'exp': level_exp(overrides.get('level', 1)), 'value': overrides.get('level', 1) } obj = crud_level.create(db, obj_in=CreateLevel(**level_dict)) if isinstance(crud, CRUDServer) or isinstance(crud, CRUDMember): obj = crud.get_by_discord( db, ctx.guild.id ) if obj is None: server_dict = { "discord_id": ctx.guild.id, "name": ctx.guild.name, "server_exp": overrides.get('exp', 0), "channel": overrides.get('channel_id') } obj = crud_server.create( db, obj_in=CreateServer(**server_dict) ) server_uuid = obj.uuid if isinstance(crud, CRUDPlayer) or isinstance(crud, CRUDMember): obj = crud.get_by_discord( db, ctx.message.author.id ) if obj is None: player_dict = { "discord_id": ctx.message.author.id, "name": ctx.message.author.name, "hidden": overrides.get('hidden', False) } obj = crud_player.create( db, obj_in=CreatePlayer(**player_dict) ) player_uuid = obj.uuid if isinstance(crud, CRUDMember): obj = crud_member.get_by_ids( db, player_uuid, server_uuid ) if obj is None: member_dict = { "exp": overrides.get('exp', 0), "player_uuid": player_uuid, "server_uuid": server_uuid, "level_uuid": None, } obj = crud_member.create( db, obj_in=CreateMember(**member_dict) ) return obj
async def on_message(self, message): if message.author.id != self.__bot.user.id and not message.author.bot: async with session_lock: with Session() as session: db_server = get_create( session, crud_server, obj_in=CreateServer( **{ "discord_id": message.guild.id, "name": message.guild.name, "server_exp": 0, "channel": None })) db_player = get_create( session, crud_player, obj_in=CreatePlayer( **{ "discord_id": message.author.id, "name": message.author.name, "hidden": True })) db_member = get_create( session, crud_member, obj_in=CreateMember( **{ "exp": 0, "player_uuid": db_player.uuid, "server_uuid": db_server.uuid, "level_uuid": None })) if db_member.level is not None: level_value = db_member.level.value + 1 else: level_value = 1 next_level = get_create( session, crud_level, obj_in=CreateLevel(**{ "value": level_value, "exp": level_exp(level_value) })) if db_member.exp + 25 < next_level.exp: crud_member.update(session, db_obj=db_member, obj_in={"exp": db_member.exp + 25}) else: db_member = crud_member.update( session, db_obj=db_member, obj_in={ "exp": (db_member.exp + 25 - next_level.exp), "level_uuid": next_level.uuid }) if db_member.server.channel is not None: embed = discord.Embed() embed.set_author( name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) embed.title = f"**{db_member.player.name}** " \ f"leveled up!" embed.description = f"**{db_member.player.name}" \ f"** leveled up to level " \ f"**{db_member.level.value}" \ f"** by sending messages!" embed.colour = 9942302 await self.__bot.get_channel( int(db_member.server.channel)).send(embed=embed )
async def rank(self, ctx): """ Get your current experience status on this server. :param ctx: :return: """ async with ctx.message.channel.typing(): message = "" if ctx.message.guild is None: message = "Please use this command on a server." embed = None else: async with session_lock: with Session() as session: db_server = get_create( session, crud_server, obj_in=CreateServer( **{ "discord_id": ctx.guild.id, "name": ctx.guild.name, "server_exp": 0, "channel": None })) db_player = get_create( session, crud_player, obj_in=CreatePlayer( **{ "discord_id": ctx.message.author.id, "name": ctx.message.author.name, "hidden": True })) member = get_create( session, crud_member, obj_in=CreateMember( **{ "exp": 0, "player_uuid": db_player.uuid, "server_uuid": db_server.uuid, "level_uuid": None })) if member.level is not None: next_level = get_create( session, crud_level, obj_in=CreateLevel( **{ "value": member.level.value + 1, "exp": level_exp(member.level.value + 1) })) else: next_level = get_create( session, crud_level, obj_in=CreateLevel(**{ "value": 1, "exp": level_exp(1) })) embed = discord.Embed() embed.title = f"**{member.player.name}** on " \ f"**{member.server.name}**" embed.description = f"More data can be found [here]" \ f"({settings.URL}/players/" \ f"{member.player.uuid})." embed.url = f"{settings.URL}/players/" \ f"{member.player.uuid}/server/" \ f"{member.server.uuid}" embed.timestamp = datetime.datetime.utcnow() embed.colour = Colors.success embed.set_author(name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) # embed.add_field( # name=f"**Level {next_level.value - 1}**", # value=f"Experience: **{member.exp}/{next_level.exp}**", # inline=False) # embed.add_field( # name=f"Progress: " # f"**{member.exp / next_level.exp * 100:.2f}%**", # value=f"`{progress_bar(member.exp, next_level.exp)}`") embed.set_image(url=f"{settings.URL}/api/level-image" f"?name={ctx.author.name}" f"&level={next_level.value - 1}" f"¤t_exp={member.exp}" f"&needed_exp={next_level.exp}") if message != "" and embed is None: await ctx.send(message) else: await ctx.send(embed=embed)
async def load_dump(self, ctx, filename=None): embed = discord.Embed() embed.set_author(name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) updated = [] if filename is None: filename = "/members.dump.json" try: with open(filename, "r") as dump_file: data = json.load(dump_file) except OSError: embed.colour = Colors.unauthorized embed.title = "File not found!" embed.description = "Be sure that you inserted the right " \ "filename and you have copied the file " \ "into the container!" embed.timestamp = datetime.datetime.utcnow() await ctx.send(embed=embed) return for member in data: async with session_lock: with Session() as session: player_discord_id = member["player"]["discord_id"] server_discord_id = member["server"]["discord_id"] exp = int(member["exp"]) player = self.__bot.get_user(player_discord_id) server = self.__bot.get_guild(server_discord_id) db_player = crud_player.get_by_discord( session, player_discord_id) if db_player is None: if player is None and "name" in member["player"]: name = member["player"]["name"] elif player is None and "name" not in member["player"]: name = "UNKNOWN" else: name = player.name db_player = crud_player.create( session, obj_in=CreatePlayer( **{ "discord_id": player_discord_id, "name": name, "hidden": "hidden" in member["player"] and member["player"]["hidden"] == 1 })) else: hidden = "hidden" in member["player"] and \ member["player"]["hidden"] == 1 if hidden != db_player.hidden: db_player = crud_player.update( session, db_obj=db_player, obj_in={"hidden": hidden}) db_server = crud_server.get_by_discord( session, server_discord_id) if db_server is None: if server is None and "name" in member["server"]: name = member["server"]["name"] elif server is None and "name" not in member["server"]: name = "UNKNOWN" else: name = server.name db_server = crud_server.create( session, obj_in=CreateServer( **{ "discord_id": server_discord_id, "name": name, "server_exp": 0, "channel": member["server"].get("channel") })) else: if db_server.channel != member["server"]. \ get("channel"): db_server = crud_server.update( session, db_obj=db_server, obj_in={ "channel": member["server"].get("channel") }) db_member = crud_member.get_by_ids(session, db_player.uuid, db_server.uuid) if "level_id" in member: logger.debug(member["level_id"]) if "level_id" in member and member["level_id"] != "NULL": current_level = int(member["level_id"]) else: current_level = 0 current_level, exp = process_exp(current_level, exp) if current_level > 0: db_level = get_create( session, crud_level, obj_in=CreateLevel( **{ "value": current_level, "exp": level_exp(current_level), "title": None })) level_uuid = db_level.uuid else: level_uuid = None if db_member is None: db_member = crud_member.create( session, obj_in=CreateMember( **{ "exp": exp, "player_uuid": db_player.uuid, "server_uuid": db_server.uuid, "level_uuid": level_uuid })) else: db_member = crud_member.update(session, db_obj=db_member, obj_in={ "level_uuid": level_uuid, "exp": exp }) updated.append(db_member) embed.colour = Colors.other embed.title = "Members loaded from dump file." embed.description = f"Members updated: {len(updated)}" embed.timestamp = datetime.datetime.utcnow() await ctx.send(embed=embed)
async def online_experience(self): await self.__bot.wait_until_ready() async with session_lock: with Session() as session: leveled_up = {} for member in filter(gets_exp, self.__bot.get_all_members()): player_obj = get_create(session, crud_player, obj_in=CreatePlayer( **{ "discord_id": member.id, "name": member.name, "hidden": True })) server_obj = get_create( session, crud_server, obj_in=CreateServer( **{ "discord_id": member.guild.id, "name": member.guild.name, "server_exp": 0, "channel": None })) member_obj = get_create( session, crud_member, obj_in=CreateMember( **{ "exp": 0, "player_uuid": player_obj.uuid, "server_uuid": server_obj.uuid, "level_uuid": None })) base_exp = 5 special_multi = 1 now = datetime.datetime.utcnow() # Weekend double voice experience # Between Friday 15:00 -> Sunday 23:59 (UTC) if now.weekday() > 4 or \ (now.weekday() == 4 and now.hour > 15): special_multi = 2 exp = math.ceil( special_multi * (len(member.voice.channel.members) / 4 * base_exp)) if member_obj.level is not None: next_level = crud_level.get_by_value( session, member_obj.level.value + 1) else: next_level = crud_level.get_by_value(session, 1) if next_level is None and member_obj.level is not None: member_dict = { "exp": level_exp(member_obj.level.value + 1), "value": member_obj.level.value + 1 } next_level = crud_level.create( CreateMember(**member_dict)) if member_obj.exp + exp < next_level.exp: crud_member.update( session, db_obj=member_obj, obj_in={"exp": member_obj.exp + exp}) else: member_obj = crud_member.update( session, db_obj=member_obj, obj_in={ "exp": member_obj.exp + exp - next_level.exp, "level_uuid": next_level.uuid }) if server_obj.channel is not None: if server_obj.channel in leveled_up: leveled_up[server_obj.channel]. \ append(member_obj) else: leveled_up[server_obj.channel] \ = [member_obj] crud_server.update(session, db_obj=server_obj, obj_in={ "name": member.guild.name, "server_exp": server_obj.server_exp + exp }) for channel in leveled_up: embed = discord.Embed() embed.set_author(name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) if len(leveled_up) > 1: embed.title = f"{len(leveled_up)} players leveled up!" embed.description = f"{len(leveled_up)} players " \ f"leveled up by being active on " \ f"a voice channel." else: embed.title = f"1 player leveled up!" embed.description = f"1 player leveled up by being " \ f"active on a voice channel." embed.colour = 9442302 for member in leveled_up[channel]: embed.add_field(name=member.player.name, value=f"Leveled up to " f"**Level {member.level.value}**", inline=False) await self.__bot.get_channel(int(channel)).send(embed=embed ) logger.info("Experience calculated.")