async def on_message(self, message: discord.Message): if not hasattr(message.channel, "guild") or message.channel.guild is None: return ctx: commands.Context = await self.bot.get_context(message) guild = message.guild is_mod = Permissioncheckers.is_mod(ctx) if message.author == guild.me or is_mod or message.author.id in Configuration.getConfigVar(guild.id, "IGNORED_USERS"): return guilds = Configuration.getConfigVar(message.guild.id, "INVITE_WHITELIST") if len(guilds) is not 0: codes = INVITE_MATCHER.findall(message.content) for code in codes: try: invite:discord.Invite = await self.bot.get_invite(code) except discord.NotFound: pass except KeyError: await message.delete() clean_message = await clean_content().convert(ctx, message.content) clean_name = Utils.clean_user(message.author) await GearbotLogging.log_to_minor_log(message.guild, f":no_entry_sign: {Translator.translate('censored_invite', ctx.guild.id, user=clean_name, code=code, message=clean_message, server_name='DM group')}") else: if invite.guild is None or (not invite.guild.id in guilds and invite.guild.id != guild.id): await message.delete() clean_message = await clean_content().convert(ctx ,message.content) clean_name = Utils.clean_user(message.author) await GearbotLogging.log_to_minor_log(message.guild, f":no_entry_sign: {Translator.translate('censored_invite', ctx.guild.id, user=clean_name, code=code, message=clean_message, server_name=invite.guild.name)}")
async def on_message(self, message: discord.Message): if message.author.bot or message.webhook_id is not None: return if message.author.id in Configuration.get_persistent_var( "user_blocklist", []): return if not hasattr(message.channel, "guild") or message.channel.guild is None: return me = message.guild.me if me is None: message.guild.fetch_member(self.bot.user.id) permissions = message.channel.permissions_for(me) if not (permissions.read_messages and permissions.send_messages and permissions.embed_links): return role_list = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "ROLES") role_required = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "ROLE_REQUIRED") channel_list = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "CHANNELS") channels_ignored = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "CHANNELS_IGNORED") mod_bypass = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "MOD_BYPASS") is_mod = message.author is not None and Permissioncheckers.is_mod( message.author) if (message.channel.id in channel_list) is channels_ignored and not ( is_mod and mod_bypass): return has_role = False if message.author is not None and hasattr(message.author, "roles"): for role in message.author.roles: if role.id in role_list: has_role = True break if has_role is not role_required and not (is_mod and mod_bypass): return prefix = Configuration.get_var(message.guild.id, "GENERAL", "PREFIX") if message.content.startswith(prefix, 0) and message.guild.id in self.commands: for trigger in self.commands[message.guild.id]: if message.content.lower() == prefix + trigger or ( message.content.lower().startswith( trigger, len(prefix)) and message.content.lower()[len(prefix + trigger)] == " "): command_content = self.commands[ message.guild.id][trigger].replace("@", "@\u200b") await message.channel.send(command_content) self.bot.custom_command_count += 1
def assemble_guild_info(bot, member): return { "guild_info": server_info.server_info_raw(bot, member.guild), "user_perms": { "user_dash_perms": get_guild_perms(member), "user_level": Permissioncheckers.user_lvl(member) } }
def is_exempt(guild_id, member: Member): if not hasattr(member, "roles"): return False config = Configuration.get_var(guild_id, "ANTI_SPAM") for role in member.roles: if role.id in config["EXEMPT_ROLES"]: return True return member.id in config["EXEMPT_USERS"] or Permissioncheckers.is_mod(member)
def check(guild, value, preview, user, *_): user_lvl = Permissioncheckers.user_lvl(user) new_upper = min(upper, user_lvl) new_lower = lower if other_min is not None: new_lower = max(lower, preview[other_min]) return check_number_range(new_lower, new_upper)(guild, value, preview, user)
async def on_message(self, message: discord.Message): if message.author.bot or message.webhook_id is not None: return if not hasattr(message.channel, "guild") or message.channel.guild is None: return me = message.guild.me if me is None: me = Utils.get_member(self.bot, message.guild, self.bot.user.id) permissions = message.channel.permissions_for(me) if me is None: return if not (permissions.read_messages and permissions.send_messages and permissions.embed_links): return role_list = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "ROLES") role_required = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "ROLE_REQUIRED") channel_list = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "CHANNELS") channels_ignored = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "CHANNELS_IGNORED") mod_bypass = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "MOD_BYPASS") is_mod = message.author is not None and Permissioncheckers.is_mod(message.author) if (message.channel.id in channel_list) is channels_ignored and not (is_mod and mod_bypass): return has_role = False if message.author is not None and hasattr(message.author, "roles"): for role in message.author.roles: if role.id in role_list: has_role = True break if has_role is not role_required and not (is_mod and mod_bypass): return prefix = Configuration.get_var(message.guild.id, "GENERAL", "PREFIX") if message.content.startswith(prefix, 0) and message.guild.id in self.commands: for trigger in self.commands[message.guild.id]: if message.content.lower() == prefix + trigger or ( message.content.lower().startswith(trigger, len(prefix)) and message.content.lower()[len(prefix + trigger)] == " "): info = self.commands[message.guild.id][trigger] images = IMAGE_MATCHER.findall(info.content) image = None if len(images) == 1: image = images[0] description = info.content.replace(image, "") else: description = info.content embed = Embed(description=description) if info.created_by is not None: creator = await Utils.get_user(info.created_by) embed.set_footer(text=f"Created by {str(creator)} ({info.created_by})", icon_url=creator.avatar_url) if image is not None: embed.set_image(url=image) await message.channel.send(embed=embed) self.bot.custom_command_count += 1
async def add_command_override(self, ctx, command: str, perm_lvl: int): command_object = self.bot.get_command(command) if command_object is not None: cog = command_object.instance cog_name = command_object.cog_name if not hasattr(cog, "permissions"): await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('command_core_cog_no_override', ctx, command=command, cog_name=cog_name)}" ) elif perm_lvl in range(7): perm_dict = Permissioncheckers.get_perm_dict( command.split(" "), cog.permissions) if perm_lvl < perm_dict["min"]: lvl = cog.permissions['min'] await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('command_min_perm_violation', ctx, command=command, min_lvl=lvl, min_lvl_name=Translator.translate(f'perm_lvl_{lvl}', ctx))}" ) elif perm_lvl > perm_dict["max"]: lvl = cog.permissions['max'] await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('command_max_perm_violation', ctx, command=command, max_lvl=lvl, max_lvl_name=Translator.translate(f'perm_lvl_{lvl}', ctx))}" ) else: overrides = Configuration.getConfigVar( ctx.guild.id, "PERM_OVERRIDES") if cog_name not in overrides: overrides[cog_name] = { "required": perm_lvl, "commands": {}, "people": [] } override = overrides[cog_name] parts = command.split(" ") while len(parts) > 0: part = parts.pop(0) if not part in override["commands"]: override["commands"][part] = override = { "required": -1, "commands": {}, "people": [] } else: override = override["commands"][part] override["required"] = perm_lvl Configuration.saveConfig(ctx.guild.id) await ctx.send( f"{Emoji.get_chat_emoji('YES')} {Translator.translate('command_override_confirmation', ctx, command=command, perm_lvl=perm_lvl, perm_lvl_name=Translator.translate(f'perm_lvl_{perm_lvl}', ctx))}" ) else: await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('invalid_override_lvl', ctx)}" ) else: await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('command_not_found', ctx)}" )
async def check_message(self, message: discord.Message): if message.guild is None or \ message.webhook_id is not None or \ message.author == message.guild.me: return ctx = await self.bot.get_context(message) if Permissioncheckers.get_user_lvl(ctx.guild, ctx.author) >= 2: return blacklist = Configuration.get_var(message.guild.id, "CENSORING", "TOKEN_BLACKLIST") word_blacklist = Configuration.get_var(message.guild.id, "CENSORING", "WORD_BLACKLIST") guilds = Configuration.get_var(message.guild.id, "CENSORING", "INVITE_WHITELIST") content = message.content.replace('\\', '') decoded_content = parse.unquote(content) censored = False if len(guilds) is not 0: codes = INVITE_MATCHER.findall(decoded_content) for code in codes: try: invite: discord.Invite = await self.bot.fetch_invite(code) except discord.NotFound: await self.censor_invite(ctx, code, "INVALID INVITE") except KeyError: await self.censor_invite(ctx, code, "DM group") censored = True else: if invite.guild is None or ( not invite.guild.id in guilds and invite.guild.id != message.guild.id): await self.censor_invite(ctx, code, invite.guild.name) censored = True if not censored: content = content.lower() for bad in (w.lower() for w in blacklist): if bad in content: await self.censor_message(message, bad) break if not censored and len(word_blacklist) > 0: if ctx.guild.id not in self.regexes: regex = re.compile( r"\b(" + '|'.join(re.escape(word) for word in word_blacklist) + r")\b", re.IGNORECASE) self.regexes[ctx.guild.id] = regex else: regex = self.regexes[ctx.guild.id] match = regex.findall(message.content) if len(match): await self.censor_message(message, match[0], "_word")
def gen_command_listing(bot, cog, command, code): try: perm_lvl = Permissioncheckers.get_perm_dict( command.qualified_name.split(' '), cog.permissions)['required'] listing = f"| | | {Translator.translate_by_code(command.short_doc, code)} |\n" listing += f"|{command.qualified_name}|{Translator.translate_by_code(f'perm_lvl_{perm_lvl}', code)} ({perm_lvl})| |\n" signature = bot.help_command.get_command_signature(command).replace( "|", "Ç€") listing += f"| | |{Translator.translate_by_code('example', code)}: ``{signature}``|\n" except Exception as ex: GearbotLogging.error(command.qualified_name) raise ex return listing
async def remove_command_override(self, ctx, command:str): command = command.lower() command_object = self.bot.get_command(command) if command_object is not None: cog_name = command_object.cog_name overrides = Configuration.get_var(ctx.guild.id, "PERM_OVERRIDES") found = False if cog_name in overrides: override = Permissioncheckers.get_perm_dict(command_object.qualified_name.split(" "), overrides[cog_name], True) if override is not None: found = True override["required"] = -1 Configuration.save(ctx.guild.id) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('command_override_removed', ctx, command=command)}") if not found: await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('command_override_not_found', ctx, command=command)}")
async def remove_lvl4(self, ctx, command: str, person: discord.Member): command_object = self.bot.get_command(command) if command_object is not None: cog_name = command_object.cog_name overrides = Configuration.get_var(ctx.guild.id, "PERM_OVERRIDES") found = False if cog_name in overrides: lvl4_list = Permissioncheckers.get_perm_dict(command.split(" "), overrides[cog_name], strict=True) if lvl4_list is not None and person.id in lvl4_list["people"]: found = True if found: lvl4_list["people"].remove(person.id) await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('lvl4_removed', ctx, member=person, command=command)}") Configuration.save(ctx.guild.id) else: await ctx.send( f"{Emoji.get_chat_emoji('NO')} {Translator.translate('did_not_have_lvl4', ctx, member=person, command=command)}")
async def censor_invite(self, ctx, code, server_name): # Allow for users with a trusted role, or trusted users, to post invite links if Configuration.get_var( ctx.guild.id, "CENSORING", "ALLOW_TRUSTED_BYPASS") and Permissioncheckers.is_trusted( ctx.author): return ctx.bot.data["message_deletes"].add(ctx.message.id) clean_message = await clean_content().convert(ctx, ctx.message.content) clean_name = Utils.clean_user(ctx.message.author) try: await ctx.message.delete() GearbotLogging.log_key(ctx.guild.id, 'censored_invite', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=ctx.message.author.id, channel=ctx.message.channel.mention) except discord.NotFound: # we failed? guess we lost the race, log anyways GearbotLogging.log_key(ctx.guild.id, 'invite_censor_fail', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=ctx.message.author.id, channel=ctx.message.channel.mention) if ctx.message.id in ctx.bot.data["message_deletes"]: ctx.bot.data["message_deletes"].remove(ctx.message.id) except discord.Forbidden: GearbotLogging.log_key(ctx.guild.id, 'invite_censor_forbidden', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=ctx.message.author.id, channel=ctx.message.channel.mention) if ctx.message.id in ctx.bot.data["message_deletes"]: ctx.bot.data["message_deletes"].remove(ctx.message.id) self.bot.dispatch("user_censored", ctx.message)
async def censor_invite(self, member, message_id, channel, code, server_name, content): # Allow for users with a trusted role, or trusted users, to post invite links if Configuration.get_var(member.guild.id, "CENSORING", "ALLOW_TRUSTED_BYPASS" ) and Permissioncheckers.is_trusted(member): return self.bot.data["message_deletes"].add(message_id) clean_message = await Utils.clean(content, member.guild) clean_name = Utils.clean_user(member) try: await channel.delete_messages([discord.Object(message_id)]) GearbotLogging.log_key(member.guild.id, 'censored_invite', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=member.id, channel=channel.mention) except discord.NotFound: # we failed? guess we lost the race, log anyways GearbotLogging.log_key(member.guild.id, 'invite_censor_fail', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=member.id, channel=channel.mention) if message_id in self.bot.data["message_deletes"]: self.bot.data["message_deletes"].remove(message_id) except discord.Forbidden: GearbotLogging.log_key(member.guild.id, 'invite_censor_forbidden', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=member.id, channel=channel.mention) if message_id in self.bot.data["message_deletes"]: self.bot.data["message_deletes"].remove(message_id)
def get_guild_perms(member): if member is None: return 0 mappings = { "ACCESS": DASH_PERMS.ACCESS, "INFRACTION": DASH_PERMS.VIEW_INFRACTIONS, "VIEW_CONFIG": DASH_PERMS.VIEW_CONFIG, "ALTER_CONFIG": DASH_PERMS.ALTER_CONFIG } permission = 0 user_lvl = Permissioncheckers.user_lvl(member) for k, v in mappings.items(): if user_lvl >= Configuration.get_var(member.guild.id, "DASH_SECURITY", k): permission |= v return permission
def gen_command_listing2(bot, cog, command): command_listing = dict() try: perm_lvl = Permissioncheckers.get_perm_dict( command.qualified_name.split(' '), cog.permissions)['required'] command_listing["commandlevel"] = perm_lvl command_listing["description"] = command.short_doc command_listing["aliases"] = command.aliases example = bot.help_command.get_command_signature(command).strip() parts = str(example).split(' ') parts[0] = ''.join(parts[0][1:]) for i in range(0, len(parts)): if "[" == parts[i][0] and "|" in parts[i]: parts[i] = ''.join(parts[i].split('|')[0][1:]) command_listing["example"] = '!' + ' '.join(parts) command_listing["subcommands"] = {} return command_listing except Exception as ex: GearbotLogging.error(command.qualified_name) raise ex
async def censor_message(self, message_id, content, channel, member, bad, key="", edit=False, reply="", attachments=""): if Configuration.get_var(member.guild.id, "CENSORING", "ALLOW_TRUSTED_CENSOR_BYPASS" ) and Permissioncheckers.is_trusted(member): return e = '_edit' if edit else '' clean_message = await Utils.clean(content, channel.guild, markdown=False) reply_str = "" if reply is not None: reply_str = f"\n**{Translator.translate('in_reply_to', member.guild.id)}: **<{assemble_jumplink(member.guild.id, channel.id, reply)}>" if attachments is None: attachments = await LoggedAttachment.filter(message=message_id) if len(attachments) > 0: attachments_str = f"**{Translator.translate('attachments', member.guild.id, count=len(attachments))}:** " attachments_str += ', '.join( Utils.assemble_attachment( channel.id, attachment.id, attachment.filename if hasattr( attachment, "filename") else attachment.name) for attachment in attachments) else: attachments_str = "" clean_message = Utils.trim_message( clean_message, 1600 - len(attachments_str) - len(reply_str)) if channel.permissions_for(channel.guild.me).manage_messages: try: self.bot.data["message_deletes"].add(message_id) await channel.delete_messages([discord.Object(message_id)]) except discord.NotFound as ex: pass else: GearbotLogging.log_key(channel.guild.id, f'censored_message{key}{e}', user=member, user_id=member.id, message=clean_message, sequence=bad, channel=channel.mention, reply=reply_str, attachments=attachments_str) else: GearbotLogging.log_key( channel.guild.id, f'censored_message_failed{key}{e}', user=member, user_id=member.id, message=clean_message, sequence=bad, link='https://discord.com/channels/{0}/{1}/{2}'.format( channel.guild.id, channel.id, message_id), reply=reply_str, attachments=attachments_str) self.bot.dispatch( "user_censored", messageholder(message_id, member, channel, channel.guild))
async def censor_message(self, message: discord.Message): if message.guild is None or \ message.webhook_id is not None or \ message.author == message.guild.me: return ctx = await self.bot.get_context(message) if Permissioncheckers.get_user_lvl(ctx) >= 2: return blacklist = Configuration.get_var(message.guild.id, "WORD_BLACKLIST") max_mentions = Configuration.get_var(message.guild.id, "MAX_MENTIONS") guilds = Configuration.get_var(message.guild.id, "INVITE_WHITELIST") content = message.content.replace('\\', '') decoded_content = parse.unquote(content) censored = False if len(guilds) is not 0: codes = INVITE_MATCHER.findall(decoded_content) for code in codes: try: invite: discord.Invite = await self.bot.fetch_invite(code) except discord.NotFound: await censor_invite(ctx, code, "INVALID INVITE") except KeyError: await censor_invite(ctx, code, "DM group") censored = True else: if invite.guild is None or ( not invite.guild.id in guilds and invite.guild.id != message.guild.id): await censor_invite(ctx, code, invite.guild.name) censored = True if not censored: content = content.lower() for bad in (w.lower() for w in blacklist): if bad in content: if message.channel.permissions_for( message.guild.me).manage_messages: try: self.bot.data["message_deletes"].add(message.id) await message.delete() except discord.NotFound as ex: pass # lost the race with another bot? else: clean_message = await clean_content().convert( ctx, message.content) GearbotLogging.log_to( ctx.guild.id, 'censored_message', user=message.author, user_id=message.author.id, message=clean_message, sequence=bad, channel=message.channel.mention) else: clean_message = await clean_content().convert( ctx, message.content) GearbotLogging.log_to(ctx.guild.id, 'censor_message_failed', user=message.author, user_id=message.author.id, message=clean_message, sequence=bad, link=message.jump_url) mentions = len(message.mentions) + len(message.role_mentions) if mentions > max_mentions > 4: self.bot.data["forced_exits"].add(message.author.id) reason = Translator.translate('autoban_too_many_mentions', message.guild.id, count=mentions) if message.guild.me.guild_permissions.ban_members: await message.guild.ban(message.author, reason=reason) else: self.bot.data["forced_exits"].remove(message.author.id) GearbotLogging.log_to(message.guild.id, 'automod_ban_failed', user=message.author, user_id=message.author.id, reason=reason)
async def censor_message(self, message: discord.Message): ctx = await self.bot.get_context(message) if message.guild is None or \ message.webhook_id is not None or \ message.author == message.guild.me or \ not Configuration.get_var(message.guild.id, "CENSOR_MESSAGES") or \ Permissioncheckers.get_user_lvl(ctx) >= 2: return blacklist = Configuration.get_var(message.guild.id, "WORD_BLACKLIST") max_mentions = Configuration.get_var(message.guild.id, "MAX_MENTIONS") guilds = Configuration.get_var(message.guild.id, "INVITE_WHITELIST") content = message.content.replace('\\', '') censored = False if len(guilds) is not 0: codes = INVITE_MATCHER.findall(content) for code in codes: try: invite: discord.Invite = await self.bot.get_invite(code) except discord.NotFound: await censor_invite(ctx, code, "INVALID INVITE") except KeyError: await censor_invite(ctx, code, "DM group") censored = True else: if invite.guild is None or (not invite.guild.id in guilds and invite.guild.id != message.guild.id): await censor_invite(ctx, code, invite.guild.name) censored = True if not censored: content = content.lower() for bad in (w.lower() for w in blacklist): if bad in content: if message.channel.permissions_for(message.guild.me).manage_messages: try: self.bot.data["message_deletes"].add(message.id) await message.delete() except discord.NotFound as ex: pass # lost the race with another bot? else: clean_message = await clean_content().convert(ctx, message.content) GearbotLogging.log_to(ctx.guild.id, "CENSORED_MESSAGES", f":no_entry_sign: {Translator.translate('censored_message', ctx.guild.id, user=message.author, user_id=message.author.id, message=clean_message, sequence=bad, channel=message.channel.mention)}") else: clean_message = await clean_content().convert(ctx, message.content) GearbotLogging.log_to(ctx.guild.id, "CENSORED_MESSAGES", f":no_entry_sign: {Translator.translate('censor_message_failed', ctx.guild.id, user=message.author, user_id=message.author.id, message=clean_message, sequence=bad, link=message.jump_url)}") mentions = len(message.mentions) + len(message.role_mentions) if mentions > max_mentions > 4: self.bot.data["forced_exits"].add(message.author.id) reason = Translator.translate('autoban_too_many_mentions', message.guild.id, count=mentions) if message.guild.me.guild_permissions.ban_members: await message.guild.ban(message.author, reason=reason) Infraction.update(active=False).where( (Infraction.user_id == message.author.id) & (Infraction.type == "Unban") & (Infraction.guild_id == ctx.guild.id)).execute() InfractionUtils.add_infraction(message.guild.id, message.author.id, self.bot.user.id, "AUTOBAN", reason) GearbotLogging.log_to(ctx.guild.id, "MOD_ACTIONS", f":door: {Translator.translate('ban_log', ctx.guild.id, user=message.author, user_id=message.author.id, moderator=self.bot.user, moderator_id=self.bot.user.id, reason=reason)}") else: self.bot.data["forced_exits"].remove(message.author.id) translated = Translator.translate('automod_ban_failed', message.guild.id, user=message.author, user_id=message.author.id, reason=reason) GearbotLogging.log_to(message.guild.id, "MOD_ACTIONS", f"{Emoji.get_chat_emoji('WARNING')} {translated}")
async def cog_check(self, ctx): return Permissioncheckers.check_permission(ctx)
async def check_message(self, message: discord.Message): if message.guild is None or \ message.webhook_id is not None or \ message.author == message.guild.me: return ctx = await self.bot.get_context(message) if Permissioncheckers.get_user_lvl(ctx.guild, ctx.author) >= 2: return censorlist = Configuration.get_var(message.guild.id, "CENSORING", "TOKEN_CENSORLIST") word_censorlist = Configuration.get_var(message.guild.id, "CENSORING", "WORD_CENSORLIST") guilds = Configuration.get_var(message.guild.id, "CENSORING", "ALLOWED_INVITE_LIST") domain_list = Configuration.get_var(message.guild.id, "CENSORING", "DOMAIN_LIST") domains_allowed = Configuration.get_var(message.guild.id, "CENSORING", "DOMAIN_LIST_ALLOWED") content = message.content.replace('\\', '') decoded_content = parse.unquote(content) censored = False if len(guilds) is not 0: codes = INVITE_MATCHER.findall(decoded_content) for code in codes: try: invite: discord.Invite = await self.bot.fetch_invite(code) except discord.NotFound: await self.censor_invite(ctx, code, "INVALID INVITE") return if invite.guild is None: await self.censor_invite(ctx, code, "DM group") censored = True else: if invite.guild is None or ( not invite.guild.id in guilds and invite.guild.id != message.guild.id): await self.censor_invite(ctx, code, invite.guild.name) censored = True if not censored: content = content.lower() for bad in (w.lower() for w in censorlist): if bad in content: await self.censor_message(message, bad) censored = True break if not censored and len(word_censorlist) > 0: if ctx.guild.id not in self.regexes: regex = re.compile( r"\b(" + '|'.join(re.escape(word) for word in word_censorlist) + r")\b", re.IGNORECASE) self.regexes[ctx.guild.id] = regex else: regex = self.regexes[ctx.guild.id] match = regex.findall(message.content) if len(match): await self.censor_message(message, match[0], "_word") censored = True if not censored and len(domain_list) > 0: link_list = URL_MATCHER.findall(message.content) for link in link_list: url = urlparse(link) domain = url.hostname if (domain in domain_list) is not domains_allowed: await self.censor_message(message, url.hostname, "_domain_blocked") print(domain)
async def cog_check(self, ctx): return Permissioncheckers.check_permission( ctx.command, ctx.guild, ctx.author) or ctx.channel.permissions_for( ctx.author).manage_emojis
async def __local_check(self, ctx: commands.Context): return Permissioncheckers.check_permission(ctx)
async def __local_check(self, ctx): return Permissioncheckers.check_permission(ctx) or ctx.channel.permissions_for(ctx.author).manage_emojis
async def check_message(self, member, content, channel, message_id): if Permissioncheckers.get_user_lvl(member.guild, member) >= 2: return censorlist = Configuration.get_var(member.guild.id, "CENSORING", "TOKEN_CENSORLIST") word_censorlist = Configuration.get_var(member.guild.id, "CENSORING", "WORD_CENSORLIST") guilds = Configuration.get_var(member.guild.id, "CENSORING", "ALLOWED_INVITE_LIST") domain_list = Configuration.get_var(member.guild.id, "CENSORING", "DOMAIN_LIST") domains_allowed = Configuration.get_var(member.guild.id, "CENSORING", "DOMAIN_LIST_ALLOWED") full_message_list = Configuration.get_var(member.guild.id, "CENSORING", "FULL_MESSAGE_LIST") censor_emoji_message = Configuration.get_var( member.guild.id, "CENSORING", "CENSOR_EMOJI_ONLY_MESSAGES") content = content.replace('\\', '') decoded_content = parse.unquote(content) if len(guilds) is not 0: codes = INVITE_MATCHER.findall(decoded_content) for code in codes: try: invite: discord.Invite = await self.bot.fetch_invite(code) except discord.NotFound: await self.censor_invite(member, message_id, channel, code, "INVALID INVITE", content) return if invite.guild is None: await self.censor_invite(member, message_id, channel, code, "DM group", content) return else: if invite.guild is None or ( not invite.guild.id in guilds and invite.guild.id != member.guild.id): await self.censor_invite(member, message_id, channel, code, invite.guild.name, content) return content = content.lower() if content in full_message_list: await self.censor_message(message_id, content, channel, member, "", "_content") return for bad in (w.lower() for w in censorlist): if bad in content: await self.censor_message(message_id, content, channel, member, bad) return if len(word_censorlist) > 0: if channel.guild.id not in self.regexes: regex = re.compile( r"\b(" + '|'.join(re.escape(word) for word in word_censorlist) + r")\b", re.IGNORECASE) self.regexes[channel.guild.id] = regex else: regex = self.regexes[channel.guild.id] match = regex.findall(content) if len(match): await self.censor_message(message_id, content, channel, member, match[0], "_word") return if len(domain_list) > 0: link_list = URL_MATCHER.findall(content) for link in link_list: url = urlparse(link) domain = url.hostname if (domain in domain_list) is not domains_allowed: await self.censor_message(message_id, content, channel, member, url.hostname, "_domain_blocked") return if censor_emoji_message and content is not None and len(content) > 0: new_content = ''.join(c for c in content if c not in emoji.UNICODE_EMOJI) new_content = re.sub(EMOJI_REGEX, '', new_content) if new_content == '': await self.censor_message(message_id, content, channel, member, '', "_emoji_only") return
async def cog_check(self, ctx): return hasattr(ctx.author, '_roles') and Permissioncheckers.check_permission( ctx.command, ctx.guild, ctx.author, self.bot) or ctx.channel.permissions_for( ctx.author).manage_emojis
async def censor_invite(self, member, message_id, channel, code, server_name, content, edit, reply, attachments): # Allow for users with a trusted role, or trusted users, to post invite links if Configuration.get_var(member.guild.id, "CENSORING", "ALLOW_TRUSTED_BYPASS" ) and Permissioncheckers.is_trusted(member): return e = '_edit' if edit else '' self.bot.data["message_deletes"].add(message_id) clean_message = await Utils.clean(content, member.guild) clean_name = Utils.clean_user(member) reply_str = "" if reply is not None: reply_str = f"\n**{Translator.translate('in_reply_to', member.guild.id)}: **<{assemble_jumplink(member.guild.id, channel.id, reply)}>" if attachments is None: attachments = await LoggedAttachment.filter(message=message_id) if len(attachments) > 0: attachments_str = f"**{Translator.translate('attachments', member.guild.id, count=len(attachments))}:** " attachments_str += ', '.join( Utils.assemble_attachment( channel.id, attachment.id, attachment.filename if hasattr( attachment, "filename") else attachment.name) for attachment in attachments) else: attachments_str = "" clean_message = Utils.trim_message( clean_message, 1600 - len(attachments_str) - len(reply_str)) try: await channel.delete_messages([discord.Object(message_id)]) GearbotLogging.log_key(member.guild.id, f'censored_invite{e}', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=member.id, channel=channel.mention, attachments=attachments_str, reply=reply_str) except discord.NotFound: # we failed? guess we lost the race, log anyways GearbotLogging.log_key(member.guild.id, f'invite_censor_fail{e}', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=member.id, channel=channel.mention, attachments=attachments_str, reply=reply_str) if message_id in self.bot.data["message_deletes"]: self.bot.data["message_deletes"].remove(message_id) except discord.Forbidden: GearbotLogging.log_key(member.guild.id, f'invite_censor_forbidden{e}', user=clean_name, code=code, message=clean_message, server_name=server_name, user_id=member.id, channel=channel.mention, attachments=attachments_str, reply=reply_str) if message_id in self.bot.data["message_deletes"]: self.bot.data["message_deletes"].remove(message_id) self.bot.dispatch( "user_censored", messageholder(message_id, member, channel, channel.guild))
async def censor_message(self, message: discord.Message): if message.guild is None or \ message.webhook_id is not None or \ message.author == message.guild.me: return ctx = await self.bot.get_context(message) if Permissioncheckers.get_user_lvl(ctx.guild, ctx.author) >= 2: return blacklist = Configuration.get_var(message.guild.id, "CENSORING", "WORD_BLACKLIST") guilds = Configuration.get_var(message.guild.id, "CENSORING", "INVITE_WHITELIST") content = message.content.replace('\\', '') decoded_content = parse.unquote(content) censored = False if len(guilds) is not 0: codes = INVITE_MATCHER.findall(decoded_content) for code in codes: try: invite: discord.Invite = await self.bot.fetch_invite(code) except discord.NotFound: await self.censor_invite(ctx, code, "INVALID INVITE") except KeyError: await self.censor_invite(ctx, code, "DM group") censored = True else: if invite.guild is None or ( not invite.guild.id in guilds and invite.guild.id != message.guild.id): await self.censor_invite(ctx, code, invite.guild.name) censored = True if not censored: content = content.lower() for bad in (w.lower() for w in blacklist): if bad in content: if message.channel.permissions_for( message.guild.me).manage_messages: try: self.bot.data["message_deletes"].add(message.id) await message.delete() except discord.NotFound as ex: break # lost the race with another bot? else: clean_message = await clean_content().convert( ctx, message.content) GearbotLogging.log_key( ctx.guild.id, 'censored_message', user=message.author, user_id=message.author.id, message=clean_message, sequence=bad, channel=message.channel.mention) self.bot.dispatch("user_censored", ctx.message) break else: clean_message = await clean_content().convert( ctx, message.content) GearbotLogging.log_key(ctx.guild.id, 'censor_message_failed', user=message.author, user_id=message.author.id, message=clean_message, sequence=bad, link=message.jump_url) self.bot.dispatch("user_censored", ctx.message)
async def cog_check(self, ctx): return Permissioncheckers.check_permission(ctx.command, ctx.guild, ctx.author)
async def __local_check(self, ctx): return Permissioncheckers.check_permission(ctx)
async def check_message(self, member, content, channel, message_id, edit, reply, attachments): if Permissioncheckers.get_user_lvl(member.guild, member) >= 2: return censorlist = Configuration.get_var(member.guild.id, "CENSORING", "TOKEN_CENSORLIST") word_censorlist = Configuration.get_var(member.guild.id, "CENSORING", "WORD_CENSORLIST") guilds = Configuration.get_var(member.guild.id, "CENSORING", "ALLOWED_INVITE_LIST") domain_list = Configuration.get_var(member.guild.id, "CENSORING", "DOMAIN_LIST") domains_allowed = Configuration.get_var(member.guild.id, "CENSORING", "DOMAIN_LIST_ALLOWED") full_message_list = Configuration.get_var(member.guild.id, "CENSORING", "FULL_MESSAGE_LIST") censor_emoji_message = Configuration.get_var( member.guild.id, "CENSORING", "CENSOR_EMOJI_ONLY_MESSAGES") content = content.replace('\\', '') if Configuration.get_var(member.guild.id, "CENSORING", "IGNORE_IDS"): content = re.sub(r'(<(?:@|#|@&|@!)[0-9]{15,20}>)', '', content) content = re.sub(r'<a?:[^: \n]+:([0-9]{15,20})>', '', content) content = re.sub( r"(https://(?:canary|ptb)?\.?discord(?:app)?.com/channels/\d{15,20}/\d{15,20}/\d{15,20})", '', content) decoded_content = parse.unquote(content) if len(guilds) != 0: codes = INVITE_MATCHER.findall(decoded_content) for code in codes: try: invite: disnake.Invite = await self.bot.fetch_invite(code) except disnake.NotFound: await self.censor_invite(member, message_id, channel, code, "INVALID INVITE", content, edit, reply, attachments) return if invite.guild is None: await self.censor_invite(member, message_id, channel, code, "DM group", content, edit, reply, attachments) return else: if invite.guild is None or ( not invite.guild.id in guilds and invite.guild.id != member.guild.id): await self.censor_invite(member, message_id, channel, code, invite.guild.name, content, edit, reply, attachments) return content = content.lower() if content in full_message_list: await self.censor_message(message_id, content, channel, member, "", "_content", edit=edit, reply=reply, attachments=attachments) return for bad in (w.lower() for w in censorlist): if bad in content: await self.censor_message(message_id, content, channel, member, bad, edit=edit, reply=reply, attachments=attachments) return if len(word_censorlist) > 0: if channel.guild.id not in self.regexes: regex = re.compile( r"(:?\b| )(" + '|'.join(re.escape(word) for word in word_censorlist) + r")(:?\b| )", re.IGNORECASE | re.MULTILINE) self.regexes[channel.guild.id] = regex else: regex = self.regexes[channel.guild.id] match = regex.findall(content) if len(match) > 0: m = match[0] if isinstance(m, tuple): m = m[1] await self.censor_message(message_id, content, channel, member, m, "_word", edit=edit, reply=reply, attachments=attachments) return if len(domain_list) > 0: link_list = URL_MATCHER.findall(content) for link in link_list: url = urlparse(link) domain = url.hostname if (domain in domain_list) is not domains_allowed: await self.censor_message(message_id, content, channel, member, url.hostname, "_domain_blocked", edit=edit, reply=reply, attachments=attachments) return if censor_emoji_message and content is not None and len(content) > 0: new_content = ''.join(c for c in content if c not in emoji.UNICODE_EMOJI) new_content = re.sub(EMOJI_REGEX, '', new_content) if new_content == '': await self.censor_message(message_id, content, channel, member, '', "_emoji_only", edit=edit, reply=reply, attachments=attachments) return