feat: Multi-guild support implementation

- Added multi-guild support with comma-separated AllowedGuildIDs config
- Per-guild embed tracking with isolated state
- Per-server action locking to prevent race conditions across guilds
- Cross-guild embed updates after power actions
- Debug logging for embed update triggers
- Fixed resource usage field formatting (brackets now properly closed)
- Updated config.ini.sample, generate_config.py for backward compatibility
- Updated README.md with multi-guild documentation
- Updated tests for multi-guild support
This commit is contained in:
k.eaven committed 2026-10-30 10:37:13 +00:00
1 parent e68b248033
commit bec06bd909
10 files changed
+802 -408

No files matched your search

+41 -11
View File
@@ -4,27 +4,47 @@ from pathlib import Path
from dotenv import load_dotenv
REQUIRED_VARS = [
'DISCORD_TOKEN',
'ALLOWED_GUILD_ID', # Legacy
'ALLOWED_GUILD_IDS', # New
'PANEL_URL',
'CLIENT_API_KEY',
'APPLICATION_API_KEY'
]
def validate_env_vars():
"""Validate that required environment variables are set and non-empty."""
required_vars = [
'DISCORD_TOKEN',
'ALLOWED_GUILD_ID',
'PANEL_URL',
'CLIENT_API_KEY',
'APPLICATION_API_KEY'
]
# Check for either legacy or new guild ID variable
has_guild_id = bool(os.getenv('ALLOWED_GUILD_ID'))
has_guild_ids = bool(os.getenv('ALLOWED_GUILD_IDS'))
missing_vars = [var for var in required_vars if not os.getenv(var)]
if not has_guild_id and not has_guild_ids:
raise ValueError(
"Missing required environment variable: ALLOWED_GUILD_IDS (or legacy ALLOWED_GUILD_ID)"
)
# Check other required vars
missing_vars = [
var for var in ['DISCORD_TOKEN', 'PANEL_URL', 'CLIENT_API_KEY', 'APPLICATION_API_KEY']
if not os.getenv(var)
]
if missing_vars:
raise ValueError(f"Missing required environment variables: {', '.join(missing_vars)}")
def get_env_config():
"""Extract configuration from environment variables."""
# Support both new ALLOWED_GUILD_IDS and legacy ALLOWED_GUILD_ID
allowed_guild_ids = os.getenv('ALLOWED_GUILD_IDS', '')
if not allowed_guild_ids:
allowed_guild_ids = os.getenv('ALLOWED_GUILD_ID', '')
return {
'Discord': {
'Token': os.getenv('DISCORD_TOKEN'),
'AllowedGuildID': os.getenv('ALLOWED_GUILD_ID')
'AllowedGuildIDs': allowed_guild_ids
},
'Pterodactyl': {
'PanelURL': os.getenv('PANEL_URL'),
@@ -43,8 +63,18 @@ def configs_match(existing_config, env_config):
if env_value is None:
# Environment variable not set, don't require match
continue
existing_value = existing_config.get(section, key, fallback=None)
if existing_value != env_value:
# For AllowedGuildIDs, also check legacy AllowedGuildID key
check_keys = [key]
if key == 'AllowedGuildIDs':
check_keys.append('AllowedGuildID')
matched = False
for check_key in check_keys:
existing_value = existing_config.get(section, check_key, fallback=None)
if existing_value == env_value:
matched = True
break
if not matched:
return False
return True