Initial commit — Wormhole v3.0.0: advanced cross-server relay cog

Features:
- Named wormhole networks with full per-network config
- Webhook relay with custom avatar/name modes (user, server, both, custom)
- Message edit, delete, reply, reaction, thread & sticker sync
- Staff system (owner + staff) with granular permissions
- Moderation: user ban/mute, server ban/mute, allowlist
- Word & regex content filters with auto-delete
- Token-bucket rate limiting per user per network
- Per-network logging channel
- Statistics dashboard
- NSFW gating, freeze/pause, silent mode
- Custom network icon, description, accent colour
- Server nickname overrides
- Ownership transfer
- Thread support
- Embed forwarding
- Professional README, info.json, LICENSE
This commit is contained in:
everestmcarthur 2026-05-07 21:53:21 +00:00
commit 6ca37b9ba1
7 changed files with 1716 additions and 0 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 everestmcarthur
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

78
README.md Normal file
View file

@ -0,0 +1,78 @@
# EveCogs
> A curated collection of advanced, professional-grade cogs for [Red-DiscordBot](https://github.com/Cog-Creators/Red-DiscordBot).
---
## 📦 Installation
```
[p]repo add EveCogs https://github.com/everestmcarthur/EveCogs
[p]cog install EveCogs <cog_name>
[p]load <cog_name>
```
---
## 🌀 Wormhole
**The most advanced cross-server relay system for Red-DiscordBot.**
Connect channels across unlimited servers into named networks. Every message, edit, delete, reaction, reply, sticker, embed, and file is relayed in real-time via webhooks — with full moderation, staff roles, filters, rate-limiting, and per-network customisation.
### Highlights
| Feature | Description |
|---|---|
| **Named Networks** | Create unlimited named networks — each with its own config, staff, and channels |
| **Webhook Relay** | Messages appear under the sender's name and avatar (or server icon, or custom) |
| **Edit & Delete Sync** | Edits and deletes propagate across every linked channel instantly |
| **Reply Context** | Replies include a preview of the referenced message |
| **Reaction Sync** | Reactions mirror across channels |
| **Sticker & Embed Forwarding** | Stickers, rich embeds, and file attachments are all relayed |
| **Staff System** | Network owner + unlimited staff with moderation access |
| **User Ban / Mute** | Ban or mute individual users from the network |
| **Server Ban / Mute** | Block or silence entire servers |
| **Server Allowlist** | Restrict which servers may join a network |
| **Word & Regex Filters** | Auto-delete messages that match filters before relay |
| **Rate Limiting** | Token-bucket per-user per-network spam protection |
| **Logging Channel** | Designate a channel to receive moderation logs |
| **Custom Identity** | Name mode (user / server / both / custom template), image mode, custom icon |
| **Server Nicknames** | Override how your server's name appears on the network |
| **Freeze / Pause** | Temporarily halt all relay on a network |
| **Silent Mode** | Suppress join/leave announcements |
| **NSFW Gating** | Block relay from NSFW channels |
| **Thread Support** | Optionally relay messages from threads |
| **Ownership Transfer** | Hand a network to another user |
| **Statistics** | Track total messages relayed, channels linked, and more |
### Quick Start
```
[p]wh create my-network A cool global chat
[p]wh open my-network (run in each channel you want linked)
[p]wh set webhooks my-network true
[p]wh set name-mode my-network both
[p]wh info my-network
[p]wh help
```
### Command Overview
| Group | Commands |
|---|---|
| `[p]wh` | `create`, `delete`, `open`, `close`, `list`, `info`, `stats`, `transfer`, `help` |
| `[p]wh set` | `webhooks`, `name-mode`, `image-mode`, `custom-icon`, `custom-name`, `description`, `colour`, `ratelimit`, `log-channel`, `nickname`, `freeze`, `silent`, `nsfw-gate`, `sync-edits`, `sync-deletes`, `sync-reactions`, `sync-replies`, `sync-stickers`, `sync-threads`, `forward-embeds` |
| `[p]wh staff` | `add`, `remove`, `list` |
| `[p]wh mod` | `ban`, `unban`, `mute`, `unmute`, `ban-server`, `unban-server`, `mute-server`, `unmute-server`, `allowlist-add`, `allowlist-remove` |
| `[p]wh filter` | `add-word`, `remove-word`, `add-regex`, `remove-regex`, `list` |
---
## 📄 License
MIT — do whatever you want.
---
*Made with ❤️ by everestmcarthur*

6
info.json Normal file
View file

@ -0,0 +1,6 @@
{
"author": ["everestmcarthur"],
"description": "EveCogs — a curated collection of advanced, professional-grade cogs for Red-DiscordBot.",
"install_msg": "Thank you for installing **EveCogs**! Browse available cogs with `[p]cog list` and install what you need.",
"short": "Advanced cogs for Red-DiscordBot"
}

6
wormhole/__init__.py Normal file
View file

@ -0,0 +1,6 @@
from .wormhole import Wormhole
async def setup(bot):
cog = Wormhole(bot)
await bot.add_cog(cog)

18
wormhole/info.json Normal file
View file

@ -0,0 +1,18 @@
{
"author": ["everestmcarthur"],
"description": "Wormhole — an advanced cross-server/cross-channel communication relay with named networks, moderation, staff roles, message sync (edits/deletes/replies/reactions), per-network customisation, logging, statistics, filters, rate-limiting, and much more.",
"install_msg": "Thanks for installing **Wormhole**! Run `[p]wh help` to get started.",
"short": "Advanced cross-server relay with networks, moderation & full sync",
"end_user_data_statement": "This cog stores user IDs, guild IDs, channel IDs, and message-mapping data required for relay functionality. No message content is stored persistently.",
"min_bot_version": "3.5.0",
"min_python_version": [3, 9, 0],
"tags": [
"wormhole",
"relay",
"bridge",
"cross-server",
"network",
"moderation",
"webhook"
]
}

113
wormhole/utils.py Normal file
View file

@ -0,0 +1,113 @@
"""Utility helpers for Wormhole cog."""
from __future__ import annotations
import re
import time
from collections import defaultdict
from typing import Optional
import discord
# ── Colour palette ──────────────────────────────────────────────────────────
COLOUR_OK = discord.Colour.from_rgb(87, 242, 135) # green
COLOUR_WARN = discord.Colour.from_rgb(254, 231, 92) # yellow
COLOUR_ERR = discord.Colour.from_rgb(237, 66, 69) # red
COLOUR_INFO = discord.Colour.from_rgb(88, 101, 242) # blurple
COLOUR_NEUTRAL = discord.Colour.from_rgb(114, 137, 218) # light blurple
# ── Cooldown bucket ────────────────────────────────────────────────────────
class CooldownBucket:
"""Per-user per-network token-bucket rate limiter."""
def __init__(self, rate: int = 5, per: float = 10.0):
self.rate = rate
self.per = per
self._buckets: dict[str, list[float]] = defaultdict(list)
def is_rate_limited(self, user_id: int, network: str) -> bool:
key = f"{network}:{user_id}"
now = time.monotonic()
bucket = self._buckets[key]
# Purge old timestamps
self._buckets[key] = [t for t in bucket if now - t < self.per]
if len(self._buckets[key]) >= self.rate:
return True
self._buckets[key].append(now)
return False
def update(self, rate: int, per: float):
self.rate = rate
self.per = per
# ── Filter helpers ──────────────────────────────────────────────────────────
def check_filters(content: str, word_filters: list[str], regex_filters: list[str]) -> Optional[str]:
"""Return the first matched filter pattern, or None if clean."""
lowered = content.lower()
for word in word_filters:
if word.lower() in lowered:
return word
for pattern in regex_filters:
try:
if re.search(pattern, content, re.IGNORECASE):
return pattern
except re.error:
continue
return None
# ── Embed builders ──────────────────────────────────────────────────────────
def make_embed(
title: str = "",
description: str = "",
colour: discord.Colour = COLOUR_INFO,
**kwargs,
) -> discord.Embed:
em = discord.Embed(title=title, description=description, colour=colour, **kwargs)
return em
def ok_embed(description: str, title: str = "✅ Success") -> discord.Embed:
return make_embed(title=title, description=description, colour=COLOUR_OK)
def err_embed(description: str, title: str = "❌ Error") -> discord.Embed:
return make_embed(title=title, description=description, colour=COLOUR_ERR)
def warn_embed(description: str, title: str = "⚠️ Warning") -> discord.Embed:
return make_embed(title=title, description=description, colour=COLOUR_WARN)
def info_embed(description: str, title: str = "ℹ️ Info") -> discord.Embed:
return make_embed(title=title, description=description, colour=COLOUR_INFO)
# ── Formatting helpers ──────────────────────────────────────────────────────
def truncate(text: str, length: int = 2000) -> str:
if len(text) <= length:
return text
return text[: length - 3] + "..."
def human_timedelta(seconds: float) -> str:
m, s = divmod(int(seconds), 60)
h, m = divmod(m, 60)
d, h = divmod(h, 24)
parts = []
if d:
parts.append(f"{d}d")
if h:
parts.append(f"{h}h")
if m:
parts.append(f"{m}m")
if s or not parts:
parts.append(f"{s}s")
return " ".join(parts)

1474
wormhole/wormhole.py Normal file

File diff suppressed because it is too large Load diff