Exemplo n.º 1
0
 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
                            }))
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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
                                                                    )
Exemplo n.º 5
0
    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"&current_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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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.")