diff --git a/README.md b/README.md index ef034e7..17454f5 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This bot is currently used for the SuperTuxKart Discord, but you can self host i - [x] Player searching - [x] Friends list - [x] Server list -- [ ] PokeMap +- [x] PokeMap - [ ] Addon querying - [x] Ranking info of a player diff --git a/bot.py b/bot.py index a0c67b8..6577054 100644 --- a/bot.py +++ b/bot.py @@ -22,7 +22,8 @@ extensions = ( "cogs.online", "cogs.playertrack", "cogs.core", - "cogs.misc" + "cogs.misc", + "cogs.pokemap" ) @@ -58,7 +59,7 @@ class Lina(commands.Bot): async def stkPostReq(self, target, args): """Helper function to send a POST request to STK servers.""" assert self.session is not None - log.info( + log.debug( "Sending %s to %s", args.replace(str(self.stk_token), "[REDACTED]").replace(constants.STK_PASSWORD, "[REDACTED]"), str(self.session._base_url) + target @@ -89,26 +90,19 @@ class Lina(commands.Bot): async def authSTK(self): """Authenticate to STK""" log.info(f"Trying to authenticate STK account {constants.STK_USERNAME}") - try: - loginPayload = await self.stkPostReq( - "/api/v2/user/connect", - f"username={constants.STK_USERNAME}&" - f"password={constants.STK_PASSWORD}&" - "save-session=true" - ) - except Exception: - log.exception("Unable to authenticate due to error. The bot will now shut down.") - return await self.close() - - if loginPayload.attrib["success"] == "no": - log.critical(f"Unable to login! {loginPayload.attrib['info']}") - log.critical("The bot will now shut down.") - return await self.close() + loginPayload = await self.stkPostReq( + "/api/v2/user/connect", + f"username={constants.STK_USERNAME}&" + f"password={constants.STK_PASSWORD}&" + "save-session=true" + ) self.stk_userid = loginPayload.attrib["userid"] self.stk_token = loginPayload.attrib["token"] log.info(f"STK user {loginPayload.attrib['username']} logged in successfully.") + if not self.stkPoll.is_running(): + self.stkPoll.start() @tasks.loop(minutes=1) async def stkPoll(self): @@ -120,7 +114,7 @@ class Lina(commands.Bot): ) except STKRequestError as e: if str(e) in "Session not valid. Please sign in.": - log.error("Session invalidated. Reauthenticating...") + log.warning("Session was invalidated. Reauthenticating...") await self.authSTK() else: log.error("Poll request failed: %s", e) @@ -169,6 +163,16 @@ class Lina(commands.Bot): color=self.accent_color ), ephemeral=True) + async def afterStkAuth(self): + for extension in extensions: + log.debug("Loading extension %s", extension) + try: + await self.load_extension(extension) + except Exception: + log.exception(f"Unable to load extension {extension}.") + else: + log.debug("Successfully loaded extension %s.", extension) + async def setup_hook(self): self.tree.error(self.on_app_command_error) @@ -182,25 +186,36 @@ class Lina(commands.Bot): } ) - await self.authSTK() - - for extension in extensions: - try: - await self.load_extension(extension) - except Exception: - log.exception(f"Unable to load extension {extension}.") + try: + await self.authSTK() + except Exception as e: + log.exception("STK account authentication failed. " + "See below for details.", + exc_info=e) + await self.close() + else: + await self.afterStkAuth() async def close(self): """Shut down lina""" log.info("lina is shutting down...") if hasattr(self, 'session'): - try: - await self.stkPostReq("/api/v2/user/client-quit", - f"userid={self.stk_userid}&" - f"token={self.stk_token}") - finally: - await self.session.close() + # it's important to check if the session is closed in case + # something went wrong before the session is set up + if not self.session.closed: + try: + if self.stk_userid and self.stk_token: + # send a client quit request so that internal online + # counter is deducted and mark the STK account offline + await self.stkPostReq("/api/v2/user/client-quit", + f"userid={self.stk_userid}&" + f"token={self.stk_token}") + else: + log.warning("userid and token is absent. " + "will not send client quit request.") + finally: + await self.session.close() await super().close() @@ -221,4 +236,3 @@ class Lina(commands.Bot): async def on_ready(self): log.info(f"Bot {self.user} ({self.user.id}) is ready!") - self.stkPoll.start() diff --git a/cogs/online.py b/cogs/online.py index f9ab9c0..d550882 100644 --- a/cogs/online.py +++ b/cogs/online.py @@ -115,8 +115,7 @@ class Online(commands.Cog): self.cachedSTKUsers[_["id"]] = _["username"] - log.info("Finished populating player cache.") - + log.info("Finished caching %d STK users.", len(data)) @tasks.loop(hours=2) async def syncAddons(self): diff --git a/cogs/playertrack.py b/cogs/playertrack.py index 6a9e558..2ab0707 100644 --- a/cogs/playertrack.py +++ b/cogs/playertrack.py @@ -113,7 +113,7 @@ class PlayerTrack(commands.Cog): if _id in srvCreated: - log.info("New server created: %s (%s) with id %d and address %s:%d" % ( + log.debug("New server created: %s (%s) with id %d and address %s:%d" % ( tree[0][i][0].attrib['name'], tree[0][i][0].attrib['country_code'], int(tree[0][i][0].attrib['id']), @@ -142,7 +142,7 @@ class PlayerTrack(commands.Cog): if _id in srvDeleted: - log.info("Server deleted: %s (%s) with id %d and address %s:%d" % ( + log.debug("Server deleted: %s (%s) with id %d and address %s:%d" % ( self.lastserverlist[0][i][0].attrib['name'], self.lastserverlist[0][i][0].attrib['country_code'], int(self.lastserverlist[0][i][0].attrib['id']), @@ -223,13 +223,13 @@ class PlayerTrack(commands.Cog): if serverCTrack != oldserverCTrack: if not oldserverCTrack: - log.info("Stub: Game started at %s %s - %s" % ( + log.debug("Stub: Game started at %s %s - %s" % ( serverInfo.attrib['name'], serverInfo.attrib['id'], serverCTrack )) elif not serverCTrack: - log.info( + log.debug( "Stub: Game ended at %s %s" % ( serverInfo.attrib['name'], serverInfo.attrib['id']