feat(pterodactyl): added one-way chat messages (minecraft --> discord)
Some checks failed
Actions / Lint Code (Ruff & Pylint) (pull_request) Failing after 22s
Actions / Build Documentation (MkDocs) (pull_request) Successful in 24s

This commit is contained in:
Seaswimmer 2024-02-29 16:47:20 -05:00
parent dab7343ca6
commit 9a698fbac6
Signed by: cswimr
GPG key ID: B8953EC01E5C4063

View file

@ -1,7 +1,9 @@
import json import json
import logging import logging
import re import re
from typing import Optional, Union
import aiohttp
import discord import discord
import websockets import websockets
from pydactyl import PterodactylClient, exceptions from pydactyl import PterodactylClient, exceptions
@ -22,7 +24,10 @@ class Pterodactyl(commands.Cog):
console_channel=None, console_channel=None,
startup_jar=None, startup_jar=None,
startup_arguments=None, startup_arguments=None,
power_action_in_progress=False power_action_in_progress=False,
chat_regex=r"\[(\d{2}:\d{2}:\d{2})\sINFO\]:\s<(\w+)>\s(.*)",
api_endpoint="minecraft",
chat_channel=None
) )
self.logger = logging.getLogger('red.sea.pterodactyl') self.logger = logging.getLogger('red.sea.pterodactyl')
self.client = None self.client = None
@ -84,6 +89,11 @@ class Pterodactyl(commands.Cog):
if content.startswith('['): if content.startswith('['):
await channel.send(content=content) await channel.send(content=content)
#TODO - Add pagification for long messages to prevent Discord API errors #TODO - Add pagification for long messages to prevent Discord API errors
chat_message = self.check_if_chat_message(content)
if chat_message:
info = await self.get_info(chat_message['username'])
if info is not None:
await self.send_chat_discord(info['username'], info['message'], info['avatar'])
if json.loads(message)['event'] == 'status': if json.loads(message)['event'] == 'status':
current_status = json.loads(message)['args'][0] current_status = json.loads(message)['args'][0]
@ -95,11 +105,36 @@ class Pterodactyl(commands.Cog):
websocket_credentials = client.servers.get_websocket(server_id) websocket_credentials = client.servers.get_websocket(server_id)
continue continue
def remove_ansi_escape_codes(self, text: str): def remove_ansi_escape_codes(self, text: str) -> str:
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
#NOTE - https://chat.openai.com/share/d92f9acf-d776-4fd6-a53f-b14ac15dd540 #NOTE - https://chat.openai.com/share/d92f9acf-d776-4fd6-a53f-b14ac15dd540
return ansi_escape.sub('', text) return ansi_escape.sub('', text)
def check_if_chat_message(self, text: str) -> Union[bool, dict]:
regex = self.config.chat_regex()
match: Optional[re.Match[str]] = re.match(regex, text)
if match:
return {"time": match.group(1), "username": match.group(2), "message": match.group(3)}
return False
async def get_info(self, username: str) -> Optional[dict]:
endpoint = await self.config.endpoint()
async with aiohttp.ClientSession() as session:
async with session.get(f"https://playerdb.co/api/player/{endpoint}/{username}") as response:
if response.status == 200:
return await response.json()
else:
return None
async def send_chat_discord(self, username: str, message: str, avatar_url: str) -> None:
channel = self.bot.get_channel(await self.config.chat_channel())
if channel is not None:
webhooks = await channel.webhooks()
webhook = discord.utils.get(webhooks, name="Pterodactyl Chat")
if webhook is None:
webhook = await channel.create_webhook(name="Pterodactyl Chat")
await webhook.send(content=message, username=username, avatar_url=avatar_url)
def get_task(self): def get_task(self):
return self.bot.loop.create_task(self.establish_websocket_connection(), name="Pterodactyl Websocket Connection") return self.bot.loop.create_task(self.establish_websocket_connection(), name="Pterodactyl Websocket Connection")
@ -156,3 +191,9 @@ class Pterodactyl(commands.Cog):
"""Set the channel to send console output to.""" """Set the channel to send console output to."""
await self.config.console_channel.set(channel.id) await self.config.console_channel.set(channel.id)
await ctx.send(f"Console channel set to {channel.mention}") await ctx.send(f"Console channel set to {channel.mention}")
@pterodactyl_config.command(name = "chatchannel")
async def pterodactyl_config_chat_channel(self, ctx: commands.Context, channel: discord.TextChannel):
"""Set the channel to send chat output to."""
await self.config.chat_channel.set(channel.id)
await ctx.send(f"Chat channel set to {channel.mention}")