Example #1
0
async def on_start() -> None:
    glob.http = aiohttp.ClientSession(json_serialize=orjson.dumps)

    # connect to mysql
    glob.db = cmyui.AsyncSQLPool()
    await glob.db.connect(glob.config.mysql)

    # run the sql updater
    updater = Updater(glob.version)
    await updater.run()
    await updater.log_startup()

    # create our bot & append it to the global player list.
    glob.bot = Player(id=1, name='Aika', priv=Privileges.Normal)
    glob.bot.last_recv_time = float(0x7fffffff)

    glob.players.append(glob.bot)

    # add all channels from db.
    async for chan in glob.db.iterall('SELECT * FROM channels'):
        chan['read_priv'] = Privileges(chan.pop('read_priv', 1))
        chan['write_priv'] = Privileges(chan.pop('write_priv', 2))
        glob.channels.append(Channel(**chan))

    # add all mappools from db.
    async for pool in glob.db.iterall('SELECT * FROM tourney_pools'):
        # overwrite basic types with some class types
        creator = await glob.players.get(id=pool['created_by'], sql=True)
        pool['created_by'] = creator  # replace id with player object

        pool = MapPool(**pool)
        await pool.maps_from_sql()
        glob.pools.append(pool)

    # add new donation ranks & enqueue tasks to remove current ones.
    # TODO: this system can get quite a bit better; rather than just
    # removing, it should rather update with the new perks (potentially
    # a different tier, enqueued after their current perks).

    async def rm_donor(userid: int, delay: int):
        await asyncio.sleep(delay)

        p = await glob.players.get(id=userid, sql=True)
        await p.remove_privs(Privileges.Donator)

        log(f"{p}'s donation perks have expired.", Ansi.MAGENTA)

    query = ('SELECT id, donor_end FROM users '
             'WHERE donor_end > UNIX_TIMESTAMP()')

    async for donation in glob.db.iterall(query):
        # calculate the delta between now & the exp date.
        delta = donation['donor_end'] - time.time()

        if delta > (60 * 60 * 24 * 30):
            # ignore donations expiring in over a months time;
            # the server should restart relatively often anyways.
            continue

        asyncio.create_task(rm_donor(donation['id'], delta))
Example #2
0
async def before_serving() -> None:
    """Called before the server begins serving connections."""
    # retrieve a client session to use for http connections.
    glob.http = aiohttp.ClientSession(json_serialize=orjson.dumps)

    # retrieve a pool of connections to use for mysql interaction.
    glob.db = cmyui.AsyncSQLPool()
    await glob.db.connect(glob.config.mysql)

    # run the sql & submodule updater (uses http & db).
    updater = Updater(glob.version)
    await updater.run()
    await updater.log_startup()

    # cache many global collections/objects from sql,
    # such as channels, mappools, clans, bot, etc.
    await setup_collections()

    # setup tasks for upcoming donor expiry dates.
    await bg_loops.donor_expiry()

    # setup a loop to kick inactive ghosted players.
    loop = asyncio.get_running_loop()
    loop.create_task(bg_loops.disconnect_ghosts())

    # if the surveillance webhook has a value, run
    # automatic (still very primitive) detections on
    # replays deemed by the server's configurable values.
    if glob.config.webhooks['surveillance']:
        loop.create_task(bg_loops.replay_detections())

    # reroll the bot's random status every `interval` sec.
    loop.create_task(bg_loops.reroll_bot_status(interval=300))
Example #3
0
async def acquire_mysql_db_pool(
    config: dict[str, Any],
) -> AsyncIterator[Optional[cmyui.AsyncSQLPool]]:
    db_pool = cmyui.AsyncSQLPool()
    try:
        await db_pool.connect(config)
        yield db_pool
    finally:
        await db_pool.close()
Example #4
0
async def before_serving() -> None:
    """Called before the server begins serving connections."""
    glob.loop = asyncio.get_event_loop()

    if glob.has_internet:
        # retrieve a client session to use for http connections.
        glob.http = aiohttp.ClientSession(
            json_serialize=orjson.dumps)  # type: ignore
    else:
        glob.http = None

    # retrieve a pool of connections to use for mysql interaction.
    glob.db = cmyui.AsyncSQLPool()
    await glob.db.connect(glob.config.mysql)

    # run the sql & submodule updater (uses http & db).
    # TODO: updating cmyui_pkg should run before it's import
    updater = Updater(glob.version)
    await updater.run()
    await updater.log_startup()

    # open a connection to our local geoloc database,
    # if the database file is present.
    if GEOLOC_DB_FILE.exists():
        glob.geoloc_db = geoip2.database.Reader(GEOLOC_DB_FILE)
    else:
        glob.geoloc_db = None

    # cache many global collections/objects from sql,
    # such as channels, mappools, clans, bot, etc.
    async with glob.db.pool.acquire() as conn:
        async with conn.cursor(aiomysql.DictCursor) as db_cursor:
            await setup_collections(db_cursor)

    new_coros = []

    # create a task for each donor expiring in 30d.
    new_coros.extend(await bg_loops.donor_expiry())

    # setup a loop to kick inactive ghosted players.
    new_coros.append(bg_loops.disconnect_ghosts())
    '''
    # if the surveillance webhook has a value, run
    # automatic (still very primitive) detections on
    # replays deemed by the server's configurable values.
    if glob.config.webhooks['surveillance']:
        new_coros.append(bg_loops.replay_detections())
    '''

    # reroll the bot's random status every `interval` sec.
    new_coros.append(bg_loops.reroll_bot_status(interval=300))

    for coro in new_coros:
        glob.app.add_pending_task(coro)
Example #5
0
async def before_serving() -> None:
    """Called before the server begins serving connections."""
    # retrieve a client session to use for http connections.
    glob.http = aiohttp.ClientSession(json_serialize=orjson.dumps)

    # retrieve a pool of connections to use for mysql interaction.
    glob.db = cmyui.AsyncSQLPool()
    await glob.db.connect(glob.config.mysql)

    # run the sql & submodule updater (uses http & db).
    updater = Updater(glob.version)
    await updater.run()
    await updater.log_startup()

    # cache many global collections/objects from sql,
    # such as channels, mappools, clans, bot, etc.
    await setup_collections()

    # add new donation ranks & enqueue tasks to remove current ones.
    # TODO: this system can get quite a bit better; rather than just
    # removing, it should rather update with the new perks (potentially
    # a different tier, enqueued after their current perks).
    async def rm_donor(userid: int, when: int):
        if (delta := when - time.time()) >= 0:
            await asyncio.sleep(delta)

        p = await glob.players.get(id=userid, sql=True)

        # TODO: perhaps make a `revoke_donor` method?
        await p.remove_privs(Privileges.Donator)
        await glob.db.execute(
            'UPDATE users '
            'SET donor_end = 0 '
            'WHERE id = %s', [p.id])
        await glob.db.execute(
            'DELETE FROM user_badges WHERE badgeid = 3 AND userid = %s',
            [p.id])

        if p.online:
            p.enqueue(
                packets.notification('Your supporter status has expired.'))

        log(f"{p}'s supporter status has expired.", Ansi.MAGENTA)
Example #6
0
async def run_server(loop: uvloop.Loop, addr: cmyui.Address):
    glob.version = cmyui.Version(2, 2, 8)
    glob.http = aiohttp.ClientSession(json_serialize=orjson.dumps)

    glob.db = cmyui.AsyncSQLPool()
    await glob.db.connect(loop, **glob.config.mysql)

    # Aika
    glob.bot = Player(id=1, name='Aika', priv=Privileges.Normal)
    glob.bot.ping_time = 0x7fffffff

    await glob.bot.stats_from_sql_full()  # no need to get friends
    await glob.players.add(glob.bot)

    # Add all channels from db.
    async for chan in glob.db.iterall('SELECT * FROM channels'):
        await glob.channels.add(Channel(**chan))

    async with cmyui.AsyncTCPServer(addr) as serv:
        await plog(f'Gulag v{glob.version} online!', Ansi.LIGHT_GREEN)
        async for conn in serv.listen(loop, glob.config.max_conns):
            asyncio.create_task(handle_conn(conn))
Example #7
0
async def convert_mods():
    db = cmyui.AsyncSQLPool()
    await db.connect(config.mysql)
    async for e in db.iterall("SELECT id, mods FROM scores_vn"):
        mods = mods_readable(int(e['mods']))
        if config.debug:
            print(f"Score {e['id']}: +{mods}")
        await db.execute(
            "UPDATE scores_vn SET mods_readable = %s WHERE id = %s",
            [mods, e['id']])
    async for e in db.iterall("SELECT id, mods FROM scores_rx"):
        mods = mods_readable(int(e['mods']))
        if config.debug:
            print(f"Score {e['id']}: +{mods}")
        await db.execute(
            "UPDATE scores_rx SET mods_readable = %s WHERE id = %s",
            [mods, e['id']])
    async for e in db.iterall("SELECT id, mods FROM scores_ap"):
        mods = mods_readable(int(e['mods']))
        if config.debug:
            print(f"Score {e['id']}: +{mods}")
        await db.execute(
            "UPDATE scores_ap SET mods_readable = %s WHERE id = %s",
            [mods, e['id']])
Example #8
0
async def on_start() -> None:
    glob.http = aiohttp.ClientSession(json_serialize=orjson.dumps)

    # connect to mysql
    glob.db = cmyui.AsyncSQLPool()
    await glob.db.connect(glob.config.mysql)

    # run the sql updater
    updater = Updater(glob.version)
    await updater.run()
    await updater.log_startup()

    # create our bot & append it to the global player list.
    glob.bot = Player(id=1, name='Aika', priv=Privileges.Normal)
    glob.bot.last_recv_time = float(0x7fffffff)

    glob.players.append(glob.bot)

    # TODO: this section is getting a bit gross.. :P
    # should be moved and probably refactored pretty hard.

    # add all channels from db.
    async for c_res in glob.db.iterall('SELECT * FROM channels'):
        c_res['read_priv'] = Privileges(c_res.get('read_priv', 1))
        c_res['write_priv'] = Privileges(c_res.get('write_priv', 2))
        glob.channels.append(Channel(**c_res))

    # add all mappools from db.
    async for p_res in glob.db.iterall('SELECT * FROM tourney_pools'):
        # overwrite basic types with some class types
        creator = await glob.players.get(id=p_res['created_by'], sql=True)
        p_res['created_by'] = creator  # replace id with player object

        pool = MapPool(**p_res)
        await pool.maps_from_sql()
        glob.pools.append(pool)

    # add all clans from db.
    async for c_res in glob.db.iterall('SELECT * FROM clans'):
        # fetch all members from sql
        m_res = await glob.db.fetchall(
            'SELECT id, clan_rank '
            'FROM users '
            'WHERE clan_id = %s',
            c_res['id'],
            _dict=False)

        members = set()

        for p_id, clan_rank in m_res:
            if clan_rank == 3:
                c_res['owner'] = p_id

            members.add(p_id)

        glob.clans.append(Clan(**c_res, members=members))

    # add all achievements from db.
    async for a_res in glob.db.iterall('SELECT * FROM achievements'):
        condition = eval(f'lambda score: {a_res.pop("cond")}')
        achievement = Achievement(**a_res, cond=condition)
        glob.achievements[a_res['mode']].append(achievement)
    """ bmsubmit stuff
    # get the latest set & map id offsets for custom maps.
    maps_res = await glob.db.fetch(
        'SELECT id, set_id FROM maps '
        'WHERE server = "gulag" '
        'ORDER BY id ASC LIMIT 1'
    )

    if maps_res:
        glob.gulag_maps = maps_res
    """

    # add new donation ranks & enqueue tasks to remove current ones.
    # TODO: this system can get quite a bit better; rather than just
    # removing, it should rather update with the new perks (potentially
    # a different tier, enqueued after their current perks).
    async def rm_donor(userid: int, delay: int):
        await asyncio.sleep(delay)

        p = await glob.players.get(id=userid, sql=True)
        await p.remove_privs(Privileges.Donator)

        log(f"{p}'s donation perks have expired.", Ansi.MAGENTA)

    query = ('SELECT id, donor_end FROM users '
             'WHERE donor_end > UNIX_TIMESTAMP()')

    async for donation in glob.db.iterall(query):
        # calculate the delta between now & the exp date.
        delta = donation['donor_end'] - time.time()

        if delta > (60 * 60 * 24 * 30):
            # ignore donations expiring in over a months time;
            # the server should restart relatively often anyways.
            continue

        asyncio.create_task(rm_donor(donation['id'], delta))