From 57500622172d331bc470515f0452a674fdd796a4 Mon Sep 17 00:00:00 2001 From: bobloy Date: Thu, 13 Sep 2018 13:27:59 -0400 Subject: [PATCH 1/3] Exclusive Role initial commit --- exclusiverole/__init__.py | 5 ++ exclusiverole/exclusiverole.py | 84 ++++++++++++++++++++++++++++++++++ exclusiverole/info.json | 22 +++++++++ 3 files changed, 111 insertions(+) create mode 100644 exclusiverole/__init__.py create mode 100644 exclusiverole/exclusiverole.py create mode 100644 exclusiverole/info.json diff --git a/exclusiverole/__init__.py b/exclusiverole/__init__.py new file mode 100644 index 0000000..8797845 --- /dev/null +++ b/exclusiverole/__init__.py @@ -0,0 +1,5 @@ +from .exclusiverole import ExclusiveRole + + +def setup(bot): + bot.add_cog(ExclusiveRole(bot)) diff --git a/exclusiverole/exclusiverole.py b/exclusiverole/exclusiverole.py new file mode 100644 index 0000000..c6bfd8b --- /dev/null +++ b/exclusiverole/exclusiverole.py @@ -0,0 +1,84 @@ +import discord +from redbot.core import Config, checks, commands + + +class ExclusiveRole: + """ + Custom commands + Creates commands used to display text and adjust roles + """ + + def __init__(self, bot): + self.bot = bot + self.config = Config.get_conf(self, identifier=9999114111108101) + default_guild = { + "role_set": set() + } + + self.config.register_guild(**default_guild) + + @commands.group(no_pm=True) + async def exclusive(self, ctx): + """Base command for managing exclusive roles""" + + if not ctx.invoked_subcommand: + 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_set() as rs: + rs.add(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_set() as rs: + rs.remove(role.id) + + await ctx.send("Exclusive role removed") + + async def check_guild(self, guild: discord.Guild): + role_set = await self.config.guild(guild).role_set() + 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 = await self.config.guild(member.guild).role_set() + + member_set = set([role.id for role in member.roles]) + to_remove = member_set - role_set + + if to_remove and member_set & role_set: + await member.remove_roles(*to_remove, "Exclusive roles") + + async def on_member_update(self, before: discord.Member, after: discord.Member): + if before.roles == after.roles: + return + + role_set = await self.config.guild(after.guild).role_set() + member_set = set([role.id for role in after.roles]) + + if role_set & member_set and member_set - role_set: + try: + await self.remove_non_exclusive_roles(after, role_set=role_set) + except discord.Forbidden: + pass diff --git a/exclusiverole/info.json b/exclusiverole/info.json new file mode 100644 index 0000000..d5f7b8c --- /dev/null +++ b/exclusiverole/info.json @@ -0,0 +1,22 @@ +{ + "author": [ + "Bobloy" + ], + "bot_version": [ + 3, + 0, + 0 + ], + "description": "Assign roles to be exclusive, preventing other roles from being added", + "hidden": false, + "install_msg": "Thank you for installing ExclusiveRole. Get started with `[p]help ExclusiveRole`", + "requirements": [], + "short": "Set roles to be exclusive", + "tags": [ + "fox", + "bobloy", + "utility", + "tools", + "roles" + ] +} \ No newline at end of file From eb21a2fa199e9a5e4d6f1bd0810f894ac92043f0 Mon Sep 17 00:00:00 2001 From: bobloy Date: Thu, 13 Sep 2018 14:09:37 -0400 Subject: [PATCH 2/3] proper checking of @everyone, no accidental str role, use list instead of set for data storage --- exclusiverole/exclusiverole.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/exclusiverole/exclusiverole.py b/exclusiverole/exclusiverole.py index c6bfd8b..3ea2b54 100644 --- a/exclusiverole/exclusiverole.py +++ b/exclusiverole/exclusiverole.py @@ -1,3 +1,5 @@ +import asyncio + import discord from redbot.core import Config, checks, commands @@ -12,12 +14,12 @@ class ExclusiveRole: self.bot = bot self.config = Config.get_conf(self, identifier=9999114111108101) default_guild = { - "role_set": set() + "role_list": [] } self.config.register_guild(**default_guild) - @commands.group(no_pm=True) + @commands.group(no_pm=True, aliases=["exclusiverole"]) async def exclusive(self, ctx): """Base command for managing exclusive roles""" @@ -32,8 +34,8 @@ class ExclusiveRole: await ctx.send("That role is already exclusive") return - async with self.config.guild(ctx.guild).role_set() as rs: - rs.add(role.id) + async with self.config.guild(ctx.guild).role_list() as rl: + rl.append(role.id) await self.check_guild(ctx.guild) @@ -47,13 +49,13 @@ class ExclusiveRole: await ctx.send("That role is not exclusive") return - async with self.config.guild(ctx.guild).role_set() as rs: - rs.remove(role.id) + async with self.config.guild(ctx.guild).role_list() as rl: + rl.remove(role.id) await ctx.send("Exclusive role removed") async def check_guild(self, guild: discord.Guild): - role_set = await self.config.guild(guild).role_set() + 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) @@ -62,22 +64,25 @@ class ExclusiveRole: async def remove_non_exclusive_roles(self, member: discord.Member, role_set=None): if role_set is None: - role_set = await self.config.guild(member.guild).role_set() + role_set = set(await self.config.guild(member.guild).role_list()) member_set = set([role.id for role in member.roles]) - to_remove = member_set - role_set + to_remove = (member_set - role_set) - {member.guild.default_role.id} if to_remove and member_set & role_set: - await member.remove_roles(*to_remove, "Exclusive roles") + to_remove = [discord.utils.get(member.guild.roles, id=id) for id in to_remove] + await member.remove_roles(*to_remove, reason="Exclusive roles") async def on_member_update(self, before: discord.Member, after: discord.Member): if before.roles == after.roles: return - role_set = await self.config.guild(after.guild).role_set() + await asyncio.sleep(1) + + role_set = set(await self.config.guild(after.guild).role_list()) member_set = set([role.id for role in after.roles]) - if role_set & member_set and member_set - role_set: + if role_set & member_set: try: await self.remove_non_exclusive_roles(after, role_set=role_set) except discord.Forbidden: From 3cb49ff1719850ec36c2c2d00d87af32a8e5fbd1 Mon Sep 17 00:00:00 2001 From: bobloy Date: Thu, 13 Sep 2018 14:12:06 -0400 Subject: [PATCH 3/3] exclusive readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a881a3..ce3bc62 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Cog Function | ccrole | **Beta** |
Create custom commands that also assign rolesMay have some bugs, please create an issue if you find any
| | chatter | **Alpha** |
Chat-bot trained to talk like your guildMissing some key features, but currently functional
| | coglint | **Alpha** |
Error check code in python syntax posted to discordWorks, but probably needs more turning to work for cogs
| +| exclusiverole | **Alpha** |
Prevent certain roles from getting any other rolesFully functional, but pretty simple
| | fight | **Incomplete** |
Organize bracket tournaments within discordStill in-progress, a massive project
| | flag | **Alpha** |
Create temporary marks on users that expire after specified timePorted, will not import old data. Please report bugs
| | forcemention | **Alpha** |
Mentions unmentionable rolesVery simple cog, mention doesn't persist
|