62 lines
1.7 KiB
Python
62 lines
1.7 KiB
Python
|
|
import logging
|
||
|
|
import time
|
||
|
|
from collections import defaultdict
|
||
|
|
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
|
||
|
|
DEFAULT_RATE_LIMIT_WINDOW = 10
|
||
|
|
DEFAULT_RATE_LIMIT_MAX = 5
|
||
|
|
|
||
|
|
_sender_timestamps: dict[str, list[float]] = defaultdict(list)
|
||
|
|
|
||
|
|
|
||
|
|
def check_mc_allowlist(sender_name: str, allow_from: list[str]) -> bool:
|
||
|
|
if not allow_from:
|
||
|
|
return True
|
||
|
|
return sender_name.lower() in [name.lower() for name in allow_from]
|
||
|
|
|
||
|
|
|
||
|
|
def is_mc_mentioned(content: str, bot_username: str) -> bool:
|
||
|
|
return bot_username.lower() in content.lower()
|
||
|
|
|
||
|
|
|
||
|
|
def check_rate_limit(
|
||
|
|
sender_id: str,
|
||
|
|
window: float = DEFAULT_RATE_LIMIT_WINDOW,
|
||
|
|
max_msgs: int = DEFAULT_RATE_LIMIT_MAX,
|
||
|
|
) -> bool:
|
||
|
|
now = time.monotonic()
|
||
|
|
timestamps = _sender_timestamps[sender_id]
|
||
|
|
|
||
|
|
cutoff = now - window
|
||
|
|
while timestamps and timestamps[0] < cutoff:
|
||
|
|
timestamps.pop(0)
|
||
|
|
|
||
|
|
if len(timestamps) >= max_msgs:
|
||
|
|
return False
|
||
|
|
|
||
|
|
timestamps.append(now)
|
||
|
|
|
||
|
|
if len(_sender_timestamps) > 500:
|
||
|
|
stale = [k for k, v in _sender_timestamps.items() if not v]
|
||
|
|
for k in stale:
|
||
|
|
del _sender_timestamps[k]
|
||
|
|
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def resolve_mc_group_policy(account) -> str:
|
||
|
|
return getattr(account, "group_policy", "mention") or "mention"
|
||
|
|
|
||
|
|
|
||
|
|
def collect_mc_security_warnings(account) -> list[str]:
|
||
|
|
warnings = []
|
||
|
|
if account.auth_mode == "offline":
|
||
|
|
warnings.append(
|
||
|
|
"Minecraft is in offline mode — player UUIDs are not cryptographically verified. "
|
||
|
|
"allow_from only matches by username."
|
||
|
|
)
|
||
|
|
if account.group_policy == "always":
|
||
|
|
warnings.append("Minecraft group policy is 'always' — bot will respond to all public chat messages")
|
||
|
|
return warnings
|