feat(pterodactyl): added support for changing channel topics

This commit is contained in:
Seaswimmer 2024-03-14 16:26:31 -04:00
parent d6bccf20e9
commit 4135cd4f98
Signed by: cswimr
GPG key ID: B8953EC01E5C4063
3 changed files with 85 additions and 0 deletions

View file

@ -14,6 +14,9 @@ def register_config(config_obj: Config) -> None:
leave_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: ([^<\n]+) left the game$", leave_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: ([^<\n]+) left the game$",
achievement_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: (.*) has (made the advancement|completed the challenge) \[(.*)\]$", achievement_regex=r"^\[\d{2}:\d{2}:\d{2} INFO\]: (.*) has (made the advancement|completed the challenge) \[(.*)\]$",
chat_command='tellraw @a ["",{"text":".$N ","color":".$C","insertion":"<@.$I>","hoverEvent":{"action":"show_text","contents":"Shift click to mention this user inside Discord"}},{"text":"(DISCORD):","color":"blue","clickEvent":{"action":"open_url","value":".$V"},"hoverEvent":{"action":"show_text","contents":"Click to join the Discord Server"}},{"text":" .$M","color":"white"}]', # noqa: E501 chat_command='tellraw @a ["",{"text":".$N ","color":".$C","insertion":"<@.$I>","hoverEvent":{"action":"show_text","contents":"Shift click to mention this user inside Discord"}},{"text":"(DISCORD):","color":"blue","clickEvent":{"action":"open_url","value":".$V"},"hoverEvent":{"action":"show_text","contents":"Click to join the Discord Server"}},{"text":" .$M","color":"white"}]', # noqa: E501
topic='Server IP: .$H\nServer Players: .$P/.$M',
topic_hostname=None,
topic_port=25565,
api_endpoint="minecraft", api_endpoint="minecraft",
chat_channel=None, chat_channel=None,
startup_msg='Server started!', startup_msg='Server started!',

View file

@ -0,0 +1,10 @@
import aiohttp
async def get_status(host, port = 25565) -> tuple[bool, dict]:
async with aiohttp.ClientSession() as session:
async with session.get(f'https://api.mcsrvstat.us/2/{host}:{port}') as response:
response = await response.json()
if response['online']:
return (True, response)
return (False, response)

View file

@ -4,6 +4,7 @@ from typing import Mapping, Optional, Union
import discord import discord
import websockets import websockets
from discord.ext import tasks
from pydactyl import PterodactylClient from pydactyl import PterodactylClient
from redbot.core import app_commands, commands from redbot.core import app_commands, commands
from redbot.core.app_commands import Choice from redbot.core.app_commands import Choice
@ -11,6 +12,7 @@ from redbot.core.bot import Red
from redbot.core.utils.chat_formatting import box, error from redbot.core.utils.chat_formatting import box, error
from redbot.core.utils.views import ConfirmView from redbot.core.utils.views import ConfirmView
from pterodactyl import mcsrvstatus
from pterodactyl.config import config, register_config from pterodactyl.config import config, register_config
from pterodactyl.logger import logger from pterodactyl.logger import logger
@ -56,6 +58,16 @@ class Pterodactyl(commands.Cog):
else: else:
logger.info("Retry limit reached. Stopping task.") logger.info("Retry limit reached. Stopping task.")
@tasks.loop(minutes=6)
async def update_topic(self):
topic = await self.get_topic()
console = self.bot.get_channel(await config.console_channel())
chat = self.bot.get_channel(await config.chat_channel())
if console:
await console.edit(topic=topic)
if chat:
await chat.edit(topic=topic)
@commands.Cog.listener() @commands.Cog.listener()
async def on_message_without_command(self, message: discord.Message) -> None: async def on_message_without_command(self, message: discord.Message) -> None:
if message.channel.id == await config.console_channel() and message.author.bot is False: if message.channel.id == await config.console_channel() and message.author.bot is False:
@ -83,6 +95,34 @@ class Pterodactyl(commands.Cog):
self.retry_counter = 0 self.retry_counter = 0
self.task = self.get_task() self.task = self.get_task()
async def get_topic(self) -> str:
topic: str = await config.topic()
placeholders = {
"H": await config.topic_hostname() or "unset",
"P": str(await config.topic_port()),
}
if await config.api_endpoint() == "minecraft":
status, response = await mcsrvstatus.get_status(await config.topic_ip(), await config.topic_port())
if status:
placeholders += {
"I": response['ip'],
"M": str(response['players']['max']),
"P": str(response['players']['online']),
"V": response['version'],
"D": response['motd']['clean'][0] if response['motd']['clean'] else "unset",
}
else:
placeholders += {
"I": response['ip'],
"M": "0",
"P": "0",
"V": "Server Offline",
"D": "Server Offline",
}
for key, value in placeholders.items():
topic = topic.replace('.$' + key, value)
return topic
async def get_chat_command(self, message: discord.Message) -> str: async def get_chat_command(self, message: discord.Message) -> str:
command: str = await config.chat_command() command: str = await config.chat_command()
placeholders = { placeholders = {
@ -286,6 +326,38 @@ class Pterodactyl(commands.Cog):
await config.invite.set(invite) await config.invite.set(invite)
await ctx.send(f"Invite link set to {invite}") await ctx.send(f"Invite link set to {invite}")
@pterodactyl_config.group(name = "topic")
async def pterodactyl_config_topic(self, ctx: commands.Context):
"""Set the topic for the console and chat channels."""
@pterodactyl_config_topic.command(name = "host", aliases = ["hostname", "ip"])
async def pterodactyl_config_topic_host(self, ctx: commands.Context, host: str) -> None:
"""Set the hostname or IP address of your server."""
await config.topic_hostname.set(host)
await ctx.send(f"Hostname/IP set to {host}")
@pterodactyl_config_topic.command(name = "port")
async def pterodactyl_config_topic_port(self, ctx: commands.Context, port: int) -> None:
"""Set the port of your server."""
await config.topic_port.set(port)
await ctx.send(f"Port set to {port}")
@pterodactyl_config_topic.command(name = "text")
async def pterodactyl_config_topic_text(self, ctx: commands.Context, *, text: str) -> None:
"""Set the text for the console and chat channels.
Available placeholders:
- `.$H` (hostname)
- `.$P` (port)
Available for Minecraft servers:
- `.$I` (ip)
- `.$M` (max players)
- `.$P` (players online)
- `.$V` (version)
- `.$D` (description / Message of the Day)"""
await config.topic.set(text)
await ctx.send(f"Topic set to:\n{box(text, 'yaml')}")
@pterodactyl_config.group(name = "chat") @pterodactyl_config.group(name = "chat")
async def pterodactyl_config_chat(self, ctx: commands.Context): async def pterodactyl_config_chat(self, ctx: commands.Context):
"""Configure chat settings.""" """Configure chat settings."""