Compare commits

...

3 commits

Author SHA1 Message Date
7b859e07e9
docs(pterodactyl): added documentation for the topic subcommand
All checks were successful
Actions / Build Documentation (MkDocs) (push) Successful in 25s
Actions / Lint Code (Ruff & Pylint) (push) Successful in 30s
2024-03-14 16:34:54 -04:00
5f4cb88ea8
fix(pterodactyl): fixed incorrect placeholder name and fixed broken get_topic method 2024-03-14 16:34:41 -04:00
4135cd4f98
feat(pterodactyl): added support for changing channel topics 2024-03-14 16:26:31 -04:00
4 changed files with 120 additions and 0 deletions

View file

@ -136,6 +136,41 @@ This option determines which server's websocket to connect to. See [Getting Star
Default value: `None` Default value: `None`
## `topic`
### `host`
This option determines the hostname of your server that will be used to retrieve server information.
### `port`
This option determines the port of your server that will be used to retrieve server information.
Default value: `25565`
### `text`
This option determines what the channel topic will be set to.
Available placeholders:
- `.$H` - replaced with the server's hostname
- `.$O` - replaced with the server's port
Available with a Minecraft server:
- `.$I` - replaced with the server's ip address
- `.$M` - replaced with maximum player count
- `.$P` - replaced with current online player count
- `.$V` - replaced with the server's current version
- `.$D` - replaced with the server's description / message of the day
Default value:
```
Server IP: .$H\nServer Players: .$P/.$M
```
## `url` ## `url`
This option determines what panel the cog will send requests to. See [Getting Started](getting-started.md#getting-server-information) for more information on this. This option determines what panel the cog will send requests to. See [Getting Started](getting-started.md#getting-server-information) for more information on this.

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",
"O": 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.update({
"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.update({
"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)
- `.$O` (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."""