0.5.1.2.a4
- Minor patch to prevent non-initiated members from claiming crew roles
This commit is contained in:
		
							parent
							
								
									9b94280e8b
								
							
						
					
					
						commit
						ac9953fed6
					
				
							
								
								
									
										2
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								bot.py
									
									
									
									
									
								
							@ -9,7 +9,7 @@ from modules.common.boot_notice import post_boot_notice
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Version consists of:
 | 
					# Version consists of:
 | 
				
			||||||
# Major.Enhancement.Minor.Patch.Test  (Test is alphanumeric; doesn’t trigger auto update)
 | 
					# Major.Enhancement.Minor.Patch.Test  (Test is alphanumeric; doesn’t trigger auto update)
 | 
				
			||||||
VERSION = "0.5.1.2.a3"
 | 
					VERSION = "0.5.1.2.a4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ---------- Env loading ----------
 | 
					# ---------- Env loading ----------
 | 
				
			||||||
load_dotenv()
 | 
					load_dotenv()
 | 
				
			||||||
 | 
				
			|||||||
@ -86,6 +86,7 @@ class ReactionRoleCog(commands.Cog):
 | 
				
			|||||||
    - Debounced nickname review to avoid duplicates when users add multiple accept emojis.
 | 
					    - Debounced nickname review to avoid duplicates when users add multiple accept emojis.
 | 
				
			||||||
    - Fedaykin role is removed when the user unreacts the Fedaykin emoji.
 | 
					    - Fedaykin role is removed when the user unreacts the Fedaykin emoji.
 | 
				
			||||||
    - Settings are reloaded dynamically on each event (hot-apply without restart).
 | 
					    - Settings are reloaded dynamically on each event (hot-apply without restart).
 | 
				
			||||||
 | 
					    - NEW: Only users with Full Access may claim/request crew roles.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, bot):
 | 
					    def __init__(self, bot):
 | 
				
			||||||
@ -262,6 +263,25 @@ class ReactionRoleCog(commands.Cog):
 | 
				
			|||||||
        except Exception:
 | 
					        except Exception:
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _has_full_initiated(self, member: discord.Member) -> bool:
 | 
				
			||||||
 | 
					        """User must have Full Access role to claim/request crew roles."""
 | 
				
			||||||
 | 
					        if not member or not isinstance(member.guild, discord.Guild):
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        role = member.guild.get_role(self.full_access_role) if self.full_access_role else None
 | 
				
			||||||
 | 
					        return bool(role and role in member.roles)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def _remove_reaction_silent(self, guild: discord.Guild, channel_id: int, message_id: int,
 | 
				
			||||||
 | 
					                                      emoji: discord.PartialEmoji | discord.Emoji | str, member: discord.Member):
 | 
				
			||||||
 | 
					        """Best-effort: remove a reaction without messaging the user."""
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            ch = guild.get_channel(channel_id)
 | 
				
			||||||
 | 
					            if not isinstance(ch, (discord.TextChannel, discord.Thread)):
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            msg = await ch.fetch_message(message_id)
 | 
				
			||||||
 | 
					            await msg.remove_reaction(emoji, member)
 | 
				
			||||||
 | 
					        except Exception:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def maybe_apply_full_access(self, member: discord.Member):
 | 
					    async def maybe_apply_full_access(self, member: discord.Member):
 | 
				
			||||||
        """Grant when Rules+RoE+Nickname *claimed*; revoke when any missing."""
 | 
					        """Grant when Rules+RoE+Nickname *claimed*; revoke when any missing."""
 | 
				
			||||||
        guild = member.guild
 | 
					        guild = member.guild
 | 
				
			||||||
@ -426,6 +446,10 @@ class ReactionRoleCog(commands.Cog):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async def _post_fedaykin_card(self, guild: discord.Guild, member: discord.Member, hub_id: int) -> bool:
 | 
					    async def _post_fedaykin_card(self, guild: discord.Guild, member: discord.Member, hub_id: int) -> bool:
 | 
				
			||||||
        """Post the Fedaykin approval card; return True if posted somewhere. While headless, queue pending only."""
 | 
					        """Post the Fedaykin approval card; return True if posted somewhere. While headless, queue pending only."""
 | 
				
			||||||
 | 
					        # Require Full Access to even request Fedaykin
 | 
				
			||||||
 | 
					        if not self._has_full_initiated(member):
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # If headless or effectively headless (no Head members): queue silently
 | 
					        # If headless or effectively headless (no Head members): queue silently
 | 
				
			||||||
        if self._fedaykin_headless or not self._has_fedaykin_head(guild):
 | 
					        if self._fedaykin_headless or not self._has_fedaykin_head(guild):
 | 
				
			||||||
            await self._queue_pending(guild, member, reason="headless_runtime")
 | 
					            await self._queue_pending(guild, member, reason="headless_runtime")
 | 
				
			||||||
@ -737,6 +761,11 @@ class ReactionRoleCog(commands.Cog):
 | 
				
			|||||||
        # ----- Crew roles hub (custom emoji toggles + Fedaykin request) -----
 | 
					        # ----- Crew roles hub (custom emoji toggles + Fedaykin request) -----
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if self.crew_msg_id and payload.message_id == self.crew_msg_id and payload.emoji.id:
 | 
					            if self.crew_msg_id and payload.message_id == self.crew_msg_id and payload.emoji.id:
 | 
				
			||||||
 | 
					                # Gate: must have Full Access to claim/request crew roles
 | 
				
			||||||
 | 
					                if not self._has_full_initiated(member):
 | 
				
			||||||
 | 
					                    await self._remove_reaction_silent(guild, payload.channel_id, payload.message_id, payload.emoji, member)
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Harvester / Escort
 | 
					                # Harvester / Escort
 | 
				
			||||||
                if payload.emoji.id == self.emoji_harvest_id and self.role_harvest_id:
 | 
					                if payload.emoji.id == self.emoji_harvest_id and self.role_harvest_id:
 | 
				
			||||||
                    role = guild.get_role(self.role_harvest_id)
 | 
					                    role = guild.get_role(self.role_harvest_id)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user