From 33e3b67c04eee743492081420a806dd4ae67ec89 Mon Sep 17 00:00:00 2001 From: "Patrick D. Rupp" Date: Tue, 11 Mar 2025 21:31:23 +0100 Subject: [PATCH] first commit --- exclusiveroles/__init__.py | 8 ++ exclusiveroles/exclusiverole.py | 129 ++++++++++++++++++++++++++++++++ exclusiveroles/info.json | 19 +++++ 3 files changed, 156 insertions(+) create mode 100644 exclusiveroles/__init__.py create mode 100644 exclusiveroles/exclusiverole.py create mode 100644 exclusiveroles/info.json diff --git a/exclusiveroles/__init__.py b/exclusiveroles/__init__.py new file mode 100644 index 0000000..a80fc57 --- /dev/null +++ b/exclusiveroles/__init__.py @@ -0,0 +1,8 @@ +from .exclusiverole import ExclusiveRole + + +async def setup(bot): + cog = ExclusiveRole(bot) + r = bot.add_cog(cog) + if r is not None: + await r \ No newline at end of file diff --git a/exclusiveroles/exclusiverole.py b/exclusiveroles/exclusiverole.py new file mode 100644 index 0000000..978b88f --- /dev/null +++ b/exclusiveroles/exclusiverole.py @@ -0,0 +1,129 @@ +import asyncio + +import discord +from redbot.core import Config, checks, commands +from redbot.core.commands import Cog + + +class ExclusiveRole(Cog): + """ + Create roles that prevent all other exclusive roles from being added + """ + + def __init__(self, bot): + super().__init__() + self.bot = bot + self.config = Config.get_conf(self, identifier=9999114111108101) + default_guild = {"role_list": []} + + self.config.register_guild(**default_guild) + + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete""" + return + + @commands.guild_only() + @commands.group(aliases=["exclusiverole"]) + async def exclusive(self, ctx): + """Base command for managing exclusive roles""" + + pass + + @exclusive.command(name="add") + @checks.mod_or_permissions(administrator=True) + async def exclusive_add(self, ctx, role: discord.Role): + """Adds an exclusive role""" + if role.id in (await self.config.guild(ctx.guild).role_list()): + await ctx.send("That role is already exclusive") + return + + async with self.config.guild(ctx.guild).role_list() as rl: + rl.append(role.id) + + await self.check_guild(ctx.guild) + + await ctx.send("Exclusive role added") + + @exclusive.command(name="delete") + @checks.mod_or_permissions(administrator=True) + async def exclusive_delete(self, ctx, role: discord.Role): + """Deletes an exclusive role""" + if role.id not in (await self.config.guild(ctx.guild).role_list()): + await ctx.send("That role is not exclusive") + return + + async with self.config.guild(ctx.guild).role_list() as rl: + rl.remove(role.id) + + await ctx.send("Exclusive role removed") + + @exclusive.command(name="list") + @checks.mod_or_permissions(administrator=True) + async def exclusive_list(self, ctx): + """List current exclusive roles""" + role_list = await self.config.guild(ctx.guild).role_list() + guild: discord.Guild = ctx.guild + + role_list = [guild.get_role(role_id) for role_id in role_list] + out = "**Exclusive roles**\n\n" + + for role in role_list: + out += "{}\n".format(role) + + await ctx.send(out) + + async def check_guild(self, guild: discord.Guild): + role_set = set(await self.config.guild(guild).role_list()) + for member in guild.members: + try: + await self.remove_non_exclusive_roles(member, role_set=role_set) + except discord.Forbidden: + pass + + async def remove_non_exclusive_roles(self, member: discord.Member, role_set=None): + if role_set is None: + role_set = set(await self.config.guild(member.guild).role_list()) + + member_set = {role.id for role in member.roles} + + # Rolle für exklusive Rollen + exclusive_roles = {role.id for role in role_set if role.is_exclusive} # Beispiel, du kannst dies je nach Implementierung anpassen + + # Prüfen, ob bereits eine exklusive Rolle gesetzt ist + existing_exclusive_roles = member_set & exclusive_roles + + if existing_exclusive_roles: + # Entferne alle exklusiven Rollen, wenn eine andere exklusive Rolle gesetzt wird + to_remove = [discord.utils.get(member.guild.roles, id=r_id) for r_id in existing_exclusive_roles] + await member.remove_roles(*to_remove, reason="Exclusive role replaced") + + # Jetzt die neue exklusive Rolle hinzufügen, falls sie gesetzt ist + new_exclusive_role = next((role for role in role_set if role.id not in member_set), None) + if new_exclusive_role: + await member.add_roles(new_exclusive_role, reason="Exclusive role added") + + # Entferne alle nicht-exklusiven Rollen, die gesetzt sind + to_remove_non_exclusive = (member_set - role_set) - {member.guild.default_role.id} - exclusive_roles + if to_remove_non_exclusive: + to_remove_non_exclusive = [discord.utils.get(member.guild.roles, id=r_id) for r_id in to_remove_non_exclusive] + await member.remove_roles(*to_remove_non_exclusive, reason="Non-exclusive roles removed") + + + @commands.Cog.listener() + async def on_member_update(self, before: discord.Member, after: discord.Member): + if before.roles == after.roles: + return + + if await self.bot.cog_disabled_in_guild(self, after.guild): + return + + await asyncio.sleep(1) + + role_set = set(await self.config.guild(after.guild).role_list()) + member_set = {role.id for role in after.roles} + + if role_set & member_set: + try: + await self.remove_non_exclusive_roles(after, role_set=role_set) + except discord.Forbidden: + pass \ No newline at end of file diff --git a/exclusiveroles/info.json b/exclusiveroles/info.json new file mode 100644 index 0000000..5ffb78e --- /dev/null +++ b/exclusiveroles/info.json @@ -0,0 +1,19 @@ +{ + "author": [ + "Bobloy", + "p08dev" + ], + "min_bot_version": "3.4.0", + "description": "Assign roles to be exclusive, preventing other exclusive roles from being added. Normal roles are unaffected.", + "hidden": false, + "install_msg": "Thank you for installing ExclusiveRole. Get started with `[p]load exclusiverole` and `[p]help ExclusiveRole`", + "short": "Set roles to be exclusive", + "end_user_data_statement": "This cog does not store any End User Data", + "tags": [ + "p08dev", + "bobloy", + "utility", + "tools", + "roles" + ] + } \ No newline at end of file