This repository has been archived on 2025-02-16. You can view files and clone it, but cannot push or open issues or pull requests.
Spiffo/cogs/console.py
Corban-Lee Jones 60ad27126b
All checks were successful
Build and Push Docker Image / build (push) Successful in 23s
console reader and player join alert
2024-12-06 12:23:15 +00:00

94 lines
3.2 KiB
Python

"""
Reads and handles updates in the server console file.
"""
import re
import logging
from pathlib import Path
import aiofiles
from discord.ext import commands, tasks
CONSOLE_FILE_PATH = Path(__file__).parent.parent / "data" / "server-console.txt"
log = logging.getLogger(__name__)
class ConsoleCog(commands.Cog):
"""
Reads and handles the server-console.txt file.
"""
_last_line_number = 0
def __init__(self, bot: commands.Bot):
self.bot = bot
self.monitor_console.start()
@tasks.loop(seconds=1)
async def monitor_console(self):
"""
Check the latest version of the console log file.
"""
if not CONSOLE_FILE_PATH.exists():
self.monitor_console.cancel()
raise FileNotFoundError("Server console file doesn't exist, task cancelled.")
async with aiofiles.open(CONSOLE_FILE_PATH, "r", encoding="utf-8") as file:
await file.seek(self._last_line_number)
lines = await file.readlines()
if not lines:
log.debug("no new lines to read")
return
for line in lines:
await self.process_console_line(line.strip())
self._last_line_number = await file.tell()
async def process_console_line(self, line: str):
if "CheckModsNeedUpdate" in line:
await self.handle_mod_needs_update(line)
elif "ConnectionManager: [fully-connected]" in line:
await self.handle_player_joined(line)
elif "ConnectionManager: [disconnect]" in line:
await self.handle_player_left(line)
async def handle_mod_needs_update(self, line: str):
log.debug("mod update instruction: %s", line)
async def handle_player_joined(self, line: str):
# example
# ConnectionManager: [fully-connected] "" connection: guid=1733487070761473 ip=192.168.1.23 steam-id=76561198202697217 access=admin username="corbz" connection-type="UDPRakNet"
re_pattern = r"guid=(\d+) ip=([\d\.]+) steam-id=(\d+) access=(\w+) username=\"([^\"]+)\" connection-type=\"([^\"]+)\""
re_match = re.search(re_pattern, line)
if not re_match:
log.warning("failed to parse player data: %s", line)
return
data = {
"guid": re_match.group(1),
"ip": re_match.group(2),
"steam_id": re_match.group(3),
"access": re_match.group(4),
"username": re_match.group(5),
"connection_type": re_match.group(6),
}
channel = self.bot.get_channel(self.bot.in_game_channel_id)
channel = await self.bot.fetch_channel(self.bot.in_game_channel_id) if not channel else channel
await channel.send(content=f"Player Joined: **{data['username']}**")
async def handle_player_left(self, line: str):
# example
# ConnectionManager: [disconnect] "receive-disconnect" connection: guid=1733487070761473 ip=192.168.1.23 steam-id=76561198202697217 access=admin username="corbz" connection-type="Disconnected"
pass
async def setup(bot: commands.Bot):
cog = ConsoleCog(bot)
await bot.add_cog(cog)
log.info("Added %s cog", cog.__class__.__name__)