console reader and player join alert
All checks were successful
Build and Push Docker Image / build (push) Successful in 23s
All checks were successful
Build and Push Docker Image / build (push) Successful in 23s
This commit is contained in:
parent
7a18ebc22d
commit
60ad27126b
2
bot.py
2
bot.py
@ -27,10 +27,12 @@ class DiscordBot(commands.Bot):
|
|||||||
Represents a Discord bot.
|
Represents a Discord bot.
|
||||||
Contains controls to interact with the bot via the Discord API.
|
Contains controls to interact with the bot via the Discord API.
|
||||||
"""
|
"""
|
||||||
|
in_game_channel_id: int
|
||||||
rcon_details: dict
|
rcon_details: dict
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(command_prefix="-", intents=Intents.all())
|
super().__init__(command_prefix="-", intents=Intents.all())
|
||||||
|
self.in_game_channel_id = int(getenv("SPIFFO__DISCORD_CHANNEL_ID"))
|
||||||
self.rcon_details = {
|
self.rcon_details = {
|
||||||
"host": getenv("SPIFFO__RCON_HOST"),
|
"host": getenv("SPIFFO__RCON_HOST"),
|
||||||
"port": getenv("SPIFFO__RCON_PORT"),
|
"port": getenv("SPIFFO__RCON_PORT"),
|
||||||
|
93
cogs/console.py
Normal file
93
cogs/console.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
"""
|
||||||
|
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__)
|
@ -1,3 +1,4 @@
|
|||||||
|
aiofiles==24.1.0
|
||||||
aiohappyeyeballs==2.4.4
|
aiohappyeyeballs==2.4.4
|
||||||
aiohttp==3.11.9
|
aiohttp==3.11.9
|
||||||
aiosignal==1.3.1
|
aiosignal==1.3.1
|
||||||
|
Reference in New Issue
Block a user