EveCogs/wormhole/commands/bridge.py
Viktor AI 4bc143b26f fix: group all commands under 'wh' parent — no more flat wh-xxx commands
Commands now show as 'wh create', 'wh staff add', 'wh set relaymode'
instead of 'wh-create', 'wh-staff add', 'wh-set relaymode'.

- Added commands/_base.py with root 'wh' group and all 20 subgroup stubs
- All 13 command mixins inherit from WormholeBase
- Decorators changed: @commands.hybrid_command(name='wh-X') → @WormholeBase.wh.command(name='X')
- Subgroup commands: @wh_X.command() → @WormholeBase.wh_X.command()
- Removed duplicate 'wh' group from core.py (now in _base.py)
- Fixed alias: 'wh-color' → 'color' for colour command
2026-05-14 19:24:37 +00:00

102 lines
4.7 KiB
Python

"""Bridge commands — cross-network bridging and mirror channels."""
from __future__ import annotations
import discord
from redbot.core import commands
from ..models.permissions import Role, requires_role
from ..utils import ok_embed, err_embed, info_embed, COLOUR_INFO
from ._base import WormholeBase
class BridgeCommands(WormholeBase):
"""Mixin — network bridging and mirror channels."""
@WormholeBase.wh_bridge.command(name="link")
@requires_role(Role.OWNER)
async def wh_bridge_link(self, ctx: commands.Context, source: str, target: str) -> None:
"""Bridge messages from one network to another (one-way)."""
nd_src = await self._net(source)
nd_tgt = await self._net(target)
if not nd_src:
return await ctx.send(embed=err_embed(f"Network `{source}` not found."))
if not nd_tgt:
return await ctx.send(embed=err_embed(f"Network `{target}` not found."))
async with self.config.networks() as ns:
bridge_to = ns[source].setdefault("bridge_to", [])
if target not in bridge_to:
bridge_to.append(target)
bridge_from = ns[target].setdefault("bridge_from", [])
if source not in bridge_from:
bridge_from.append(source)
await ctx.send(embed=ok_embed(f"Bridge: `{source}` → `{target}` (one-way)."))
await self._audit(source, "bridge_link", str(ctx.author), target)
@WormholeBase.wh_bridge.command(name="unlink")
@requires_role(Role.OWNER)
async def wh_bridge_unlink(self, ctx: commands.Context, source: str, target: str) -> None:
"""Remove a bridge."""
async with self.config.networks() as ns:
if source in ns:
bt = ns[source].get("bridge_to", [])
if target in bt:
bt.remove(target)
if target in ns:
bf = ns[target].get("bridge_from", [])
if source in bf:
bf.remove(source)
await ctx.send(embed=ok_embed(f"Bridge `{source}` → `{target}` removed."))
await self._audit(source, "bridge_unlink", str(ctx.author), target)
@WormholeBase.wh_bridge.command(name="list")
async def wh_bridge_list(self, ctx: commands.Context, name: str) -> None:
"""List bridges for a network."""
nd = await self._net(name)
if not nd:
return await ctx.send(embed=err_embed(f"Network `{name}` not found."))
lines = []
for t in nd.get("bridge_to", []):
lines.append(f"➡️ `{name}` → `{t}`")
for f in nd.get("bridge_from", []):
lines.append(f"⬅️ `{f}` → `{name}`")
if not lines:
lines.append("No bridges configured.")
await ctx.send(embed=info_embed("\n".join(lines), title=f"🌉 Bridges — {name}"))
# ── Mirror channels ────────────────────────────────────────────────────
@WormholeBase.wh_mirror.command(name="add")
@requires_role(Role.ADMIN)
async def wh_mirror_add(self, ctx: commands.Context, name: str, channel: discord.TextChannel) -> None:
"""Add a mirror channel."""
async with self.config.networks() as ns:
mirrors = ns[name].setdefault("mirror_channels", [])
if channel.id not in mirrors:
mirrors.append(channel.id)
await ctx.send(embed=ok_embed(f"{channel.mention} added as mirror for `{name}`."))
@WormholeBase.wh_mirror.command(name="remove", aliases=["rm"])
@requires_role(Role.ADMIN)
async def wh_mirror_rm(self, ctx: commands.Context, name: str, channel: discord.TextChannel) -> None:
"""Remove a mirror channel."""
async with self.config.networks() as ns:
mirrors = ns[name].get("mirror_channels", [])
if channel.id in mirrors:
mirrors.remove(channel.id)
await ctx.send(embed=ok_embed(f"{channel.mention} removed from mirrors for `{name}`."))
@WormholeBase.wh_mirror.command(name="list")
async def wh_mirror_list(self, ctx: commands.Context, name: str) -> None:
"""List mirror channels."""
nd = await self._net(name)
if not nd:
return await ctx.send(embed=err_embed(f"Network `{name}` not found."))
mirrors = nd.get("mirror_channels", [])
if not mirrors:
return await ctx.send(embed=info_embed("No mirror channels."))
lines = []
for ch_id in mirrors:
ch = self.bot.get_channel(ch_id)
lines.append(f"• {ch.mention if ch else ch_id}")
await ctx.send(embed=info_embed("\n".join(lines), title=f"🪞 Mirrors — {name}"))