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))
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))
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()
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)
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)
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))
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']])
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))