From c88edf1fddef5a7cde2717b1ec90071b4e0f6dc7 Mon Sep 17 00:00:00 2001 From: frarol96 Date: Sun, 10 Aug 2025 15:11:57 +0000 Subject: [PATCH] Delete modules/reaction_role/reaction_role.py --- modules/reaction_role/reaction_role.py | 219 ------------------------- 1 file changed, 219 deletions(-) delete mode 100644 modules/reaction_role/reaction_role.py diff --git a/modules/reaction_role/reaction_role.py b/modules/reaction_role/reaction_role.py deleted file mode 100644 index 74aa428..0000000 --- a/modules/reaction_role/reaction_role.py +++ /dev/null @@ -1,219 +0,0 @@ -import discord -from discord.ext import commands -from modules.common.emoji_accept import is_accept - -CHECKMARK = '✅' - -class ReactionRoleCog(commands.Cog): - """ - Records agreements and manages Full Access. - Nickname flow: - • Add accept on nickname message -> mark agreed + pending (idempotent) and open ONE review - • Remove accept on nickname message -> clear only if user has no accept reactions left - Full Access: granted when Rules ✅ + RoE ✅ + Nickname *claimed* (pending or verified). - Revoked when any of the three is missing. - """ - - def __init__(self, bot): - self.bot = bot - cfg = bot.config['DEFAULT'] - - def _i(key): - try: - v = cfg.get(key) - return int(v) if v else 0 - except Exception: - return 0 - - self.rules_msg_id = _i('rules_message_id') - self.engage_msg_id = _i('engagement_message_id') - self.nick_msg_id = _i('nickname_message_id') - self.rules_role = _i('rules_role_id') - self.engage_role = _i('engagement_role_id') - self.full_access_role = _i('full_access_role_id') - - # ---- helpers ---- - def _has_rules(self, member_id: int) -> bool: - return member_id in self.bot.data_manager.get('agreed_rules') - - def _has_engage(self, member_id: int) -> bool: - return member_id in self.bot.data_manager.get('agreed_engagement') - - def _has_nick_claim(self, member_id: int) -> bool: - """Claimed = agreed_nickname; pending/verified tracked separately.""" - return member_id in self.bot.data_manager.get('agreed_nickname') - - async def maybe_apply_full_access(self, member: discord.Member): - """Grant when Rules+RoE+Nickname *claimed*; revoke when any missing.""" - guild = member.guild - role = guild.get_role(self.full_access_role) if self.full_access_role else None - if not role: - return - - has_all = self._has_rules(member.id) and self._has_engage(member.id) and self._has_nick_claim(member.id) - try: - if has_all and role not in member.roles: - await member.add_roles(role, reason="All agreements completed (nickname may be pending)") - elif not has_all and role in member.roles: - await member.remove_roles(role, reason="Agreements incomplete or nickname unclaimed") - except discord.Forbidden: - pass - except Exception: - pass - - # Best-effort: refresh user card - cards = self.bot.get_cog('UserCardsCog') - if cards: - try: - await cards.refresh_card(member) - except Exception: - pass - - async def _get_member(self, guild: discord.Guild, user_id: int): - if not guild: - return None - m = guild.get_member(user_id) - if m is None: - try: - m = await guild.fetch_member(user_id) - except Exception: - return None - return m - - async def _user_has_any_accept(self, guild: discord.Guild, channel_id: int, message_id: int, user_id: int) -> bool: - """Return True if the user still has at least one 'accept' reaction on the message.""" - try: - ch = guild.get_channel(channel_id) - if not ch: - return False - msg = await ch.fetch_message(message_id) - for rxn in msg.reactions: - if is_accept(rxn.emoji): - async for u in rxn.users(limit=None): - if u.id == user_id: - return True - return False - except Exception: - return False - - # ---- commands (hybrid = prefix + slash) ---- - @commands.hybrid_command(name='nick_same', description='Claim that your global display name matches your in-game name (triggers mod review)') - async def nick_same(self, ctx: commands.Context): - member = ctx.author if isinstance(ctx.author, discord.Member) else None - if not member or not ctx.guild: - return await ctx.reply("Use this in a server.", ephemeral=True) - - dm = self.bot.data_manager - if member.id not in dm.get('agreed_nickname'): - dm.add('agreed_nickname', int(member.id)) - # Mark pending (clear verified if present) - dm.remove('nick_verified', lambda x: x == member.id) - newly_pending = False - if member.id not in dm.get('nick_claim_pending'): - dm.add('nick_claim_pending', int(member.id)) - newly_pending = True - - # Open/refresh a review with NickNudge (only on first transition to pending) - if newly_pending: - nn = self.bot.get_cog('NickNudgeCog') - if nn and hasattr(nn, 'start_nick_review'): - try: - await nn.start_nick_review(ctx.guild, member, source="nick_same") - except Exception: - pass - - await self.maybe_apply_full_access(member) - await ctx.reply("Thanks — your nickname claim was sent for moderator review.", ephemeral=True) - - # ---- listeners ---- - @commands.Cog.listener() - async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): - if not payload.guild_id or not is_accept(payload.emoji): - return - guild = self.bot.get_guild(payload.guild_id) - member = await self._get_member(guild, payload.user_id) - if not member or member.bot: - return - - dm = self.bot.data_manager - try: - if payload.message_id == self.rules_msg_id: - role = guild.get_role(self.rules_role) - if role: - await member.add_roles(role, reason="Agreed to rules") - if member.id not in dm.get('agreed_rules'): - dm.add('agreed_rules', int(member.id)) - - elif payload.message_id == self.engage_msg_id: - role = guild.get_role(self.engage_role) - if role: - await member.add_roles(role, reason="Agreed to engagement") - if member.id not in dm.get('agreed_engagement'): - dm.add('agreed_engagement', int(member.id)) - - elif payload.message_id == self.nick_msg_id: - # Claim nickname via reaction -> mark agreed + pending (idempotent) - newly_pending = False - if member.id not in dm.get('agreed_nickname'): - dm.add('agreed_nickname', int(member.id)) - dm.remove('nick_verified', lambda x: x == member.id) - if member.id not in dm.get('nick_claim_pending'): - dm.add('nick_claim_pending', int(member.id)) - newly_pending = True - - # Only open a review when we just transitioned to pending - if newly_pending: - nn = self.bot.get_cog('NickNudgeCog') - if nn and hasattr(nn, 'start_nick_review'): - try: - await nn.start_nick_review(guild, member, source="claim") - except Exception: - pass - else: - return - except Exception: - pass - - await self.maybe_apply_full_access(member) - - @commands.Cog.listener() - async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent): - if not payload.guild_id or not is_accept(payload.emoji): - return - guild = self.bot.get_guild(payload.guild_id) - member = await self._get_member(guild, payload.user_id) - if not member or member.bot: - return - - dm = self.bot.data_manager - try: - if payload.message_id == self.rules_msg_id: - dm.remove('agreed_rules', lambda x: x == member.id) - role = guild.get_role(self.rules_role) - if role: - await member.remove_roles(role, reason="Rules un-ticked") - - elif payload.message_id == self.engage_msg_id: - dm.remove('agreed_engagement', lambda x: x == member.id) - role = guild.get_role(self.engage_role) - if role: - await member.remove_roles(role, reason="Engagement un-ticked") - - elif payload.message_id == self.nick_msg_id: - # Clear only if the user has NO accept reactions left on the message - still_has_accept = await self._user_has_any_accept( - guild, payload.channel_id, payload.message_id, member.id - ) - if not still_has_accept: - dm.remove('agreed_nickname', lambda x: x == member.id) - dm.remove('nick_claim_pending', lambda x: x == member.id) - dm.remove('nick_verified', lambda x: x == member.id) - else: - return - except Exception: - pass - - await self.maybe_apply_full_access(member) - -async def setup(bot): - await bot.add_cog(ReactionRoleCog(bot))