"""Cog: komendy Discord -> Conan (przez RCON). To jest dowód, że most jest DWUKIERUNKOWY: komenda napisana na Discordzie wywołuje efekt w grze (np. !say -> broadcast widoczny dla wszystkich graczy). Komendy modyfikujące grę są bramkowane rolą GM (GM_ROLE_ID). """ from __future__ import annotations import logging import discord from discord.ext import commands log = logging.getLogger("to_conan") def is_gm(): async def predicate(ctx: commands.Context) -> bool: role_id = ctx.bot.cfg.gm_role_id ok = any(r.id == role_id for r in getattr(ctx.author, "roles", [])) if not ok: await ctx.reply("⛔ Tylko GM.", mention_author=False) return ok return commands.check(predicate) class ToConan(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot @commands.command(name="say") @is_gm() async def say(self, ctx: commands.Context, *, message: str): """Discord -> Conan: ogłoszenie widoczne dla wszystkich graczy w grze.""" resp = await self.bot.rcon.command(f"broadcast {message}") await ctx.reply(f"✅ Wysłano do gry. (serwer: `{resp.strip() or 'OK'}`)", mention_author=False) @commands.command(name="players") @is_gm() async def players(self, ctx: commands.Context): """Lista graczy online (RCON listplayers).""" resp = await self.bot.rcon.command("listplayers") await ctx.reply(f"```\n{resp.strip() or 'brak danych'}\n```", mention_author=False) @commands.command(name="kick") @is_gm() async def kick(self, ctx: commands.Context, *, who: str): """Wyrzuć gracza (po nazwie/charname — zależnie od wersji serwera).""" resp = await self.bot.rcon.command(f"kick {who}") await ctx.reply(f"👢 `{resp.strip() or 'OK'}`", mention_author=False) @commands.command(name="rcon") @is_gm() async def raw_rcon(self, ctx: commands.Context, *, cmd: str): """Surowa komenda RCON (dla zaawansowanych GM). Używaj ostrożnie.""" resp = await self.bot.rcon.command(cmd) await ctx.reply(f"```\n{resp.strip() or 'OK'}\n```", mention_author=False) # --- HOOK pod przyszły mod mostu (Chat V2 API) --- @commands.command(name="ogłoś", aliases=["oglos", "rp"]) @is_gm() async def rp_announce(self, ctx: commands.Context, nadawca: str, *, message: str): """Wiadomość RP 'z nadawcą' (np. ogłoszenie w imieniu Króla Khasara). Na samym RCON realizujemy to jako sformatowany broadcast. Gdy dodasz własny mod na Chat V2 API z dedykowaną komendą czatu, podmień tę linię na wywołanie tej komendy (np. 'tot_rp_say '). """ resp = await self.bot.rcon.command(f"broadcast [{nadawca}]: {message}") await ctx.reply(f"📜 Ogłoszono jako **{nadawca}**.", mention_author=False) async def setup(bot: commands.Bot): await bot.add_cog(ToConan(bot))