feat(pterodactyl): added support for changing channel topics
This commit is contained in:
parent
d6bccf20e9
commit
4135cd4f98
3 changed files with 85 additions and 0 deletions
|
@ -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!',
|
||||||
|
|
10
pterodactyl/mcsrvstatus.py
Normal file
10
pterodactyl/mcsrvstatus.py
Normal 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)
|
|
@ -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."""
|
||||||
|
|
Loading…
Reference in a new issue