added community voting and fixed bugs

This commit is contained in:
Subinacls
2026-06-09 06:50:38 -04:00
parent 9ca7d35ce0
commit a789fb131f
7 changed files with 997 additions and 97 deletions
+67 -4
View File
@@ -21,8 +21,16 @@ from utils.config import (
remove_isolated_user,
get_isolated_users,
increment_absolution_points,
get_keywords,
add_keyword_points,
clear_votes,
)
from cogs.moderation import (
get_or_create_xcom_role,
get_or_create_xcom_channel,
VOTE_XCOM_THRESHOLD,
VOTE_RESET_DAYS,
)
from cogs.moderation import get_or_create_xcom_role, get_or_create_xcom_channel
# Simple in-memory rate limiting for flood detection (user_id -> deque of timestamps)
USER_MESSAGE_TIMES: Dict[int, Deque[datetime]] = defaultdict(lambda: deque(maxlen=20))
@@ -94,14 +102,71 @@ class ExcommunicadoBot(commands.Bot):
if xcom_channel_id:
ch = message.guild.get_channel(xcom_channel_id)
if ch:
content = message.content or "*(no text content)*"
prefix = f"**[{message.channel.name}]** {message.author.mention}: "
# Discord hard limit is 2000 chars; truncate to stay under it
max_content = 2000 - len(prefix) - 1
if len(content) > max_content:
content = content[: max_content - 1] + ""
await ch.send(
f"**[{message.channel.name}]** {message.author.mention}: {message.content}"
prefix + content,
allowed_mentions=discord.AllowedMentions.none(),
)
except Exception:
pass
return # do not count floods or process commands from isolated users
now = datetime.now(timezone.utc)
# --- Admin-curated keyword / key-phrase auto-scoring ---
# Captures critical abuse (e.g. trading cracked software/games, illegal
# materials) even when no admin is online. Staff/owner are immune.
author = message.author
is_staff = isinstance(author, discord.Member) and (
author.guild_permissions.manage_roles
or author.guild_permissions.administrator
or author.id == message.guild.owner_id
)
keywords = guild_data.get("keywords", {})
if keywords and not is_staff and message.content:
content_low = message.content.lower()
matched_weight = 0
matched_terms = []
for phrase, info in keywords.items():
if phrase and phrase in content_low:
matched_weight += int(info.get("weight", 1))
matched_terms.append(info.get("display", phrase))
if matched_weight > 0:
try:
result = add_keyword_points(
message.guild.id, author.id, matched_weight, reset_days=VOTE_RESET_DAYS
)
print(
f"[KEYWORD] {author} matched {matched_terms} (+{matched_weight}) "
f"-> score {result['score']} in {message.guild.name}"
)
me = message.guild.me
can_manage = me is not None and author.top_role < me.top_role
if result["score"] >= VOTE_XCOM_THRESHOLD and can_manage:
cog = self.get_cog("ModerationCog")
if cog is not None:
reason = "Auto-flagged keywords: " + ", ".join(matched_terms[:5])
channel, already = await cog._perform_xcom(
message.guild, author, reason, "keyword auto-detect"
)
clear_votes(message.guild.id, author.id)
log_embed = discord.Embed(
title="🚩 Keyword Auto-XCOM",
description=f"{author.mention} ({author.id}) was auto-XCOM'd into {channel.mention} after matching flagged keywords.",
color=discord.Color.dark_red(),
timestamp=now,
)
log_embed.add_field(name="Matched", value=", ".join(matched_terms[:10]) or "", inline=False)
await self.log_action(message.guild, log_embed)
return
except Exception as kw_err:
print(f"[KEYWORD] Auto-XCOM failed: {kw_err}")
times = USER_MESSAGE_TIMES[message.author.id]
times.append(now)
@@ -130,8 +195,6 @@ class ExcommunicadoBot(commands.Bot):
except Exception as flood_err:
print(f"[FLOOD] Auto-XCOM failed: {flood_err}")
await self.process_commands(message)
async def log_action(self, guild: discord.Guild, embed: discord.Embed) -> None:
"""Send log to configured log channel if set."""
if self.log_channel_id: