예제 #1
0
    async def warn(self, ctx, target: discord.Member, *, text):
        """ Envoie un warn à l'user
		"""
        # Checks
        if check.is_role(target, self.id['ROLE']['MODER']):
            await log('WARN - target role invalide', MNT)
            return

        # Action
        action = ACTION('Warn',
                        target.id,
                        ctx.message.author.id,
                        ctx.message.created_at,
                        message=text)
        EMB = action.embed(self.client, 0xaa8800)

        # Notification aux modérateurs
        await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                      ).send(content=None, embed=EMB)
        await ctx.channel.send(':warning: {} a reçu un warn'.format(
            target.mention))

        # Envoi du warn
        await target.send(self.text['WARN'].format(text))

        # Sauvegarde du log
        action.save('src/config/moderation/data.json')
예제 #2
0
 async def cog_check(self, ctx):
     """ Les commandes de ce cog ne peuvent être utilisées que par un staff"""
     try:
         staff_role = tool.get_data('src/config/id.json')['ROLE']['STAFF']
         return check.is_role(ctx.author, staff_role)
     except:
         await log('twitter local check failed', mnt)
         return False
예제 #3
0
	async def cog_check(self, ctx):
		"""Les commandes de ce cog ne peuvent être utilisées que par un staff.
		"""
		data_ID = tool.get_data('src/config/id.json')
		try:
			return check.is_role(ctx.author, data_ID['ROLE']['STAFF'])
		except:
			await log('STAFF COG local check failed', MNT)
			return False
예제 #4
0
    async def cog_check(self, ctx):
        """	Les commandes de ce cog ne peuvent être utilisées que par un staff ou un modérateur.
			En outre, elles ne sont utilisables que dans le salon de modération
		"""
        try:
            return check.is_role(
                ctx.author, self.id['ROLE']['MODER']) and check.in_channel(
                    ctx.channel, self.id['TEXTCHANNEL']['CHECK_MODER'])
        except:
            await log('moderation local check failed', MNT)
            return False
예제 #5
0
    async def ban(self, ctx, target: discord.Member, *, text):
        """ Ban un user (message optionnel)
		"""
        # Checks
        if check.is_role(target, self.id['ROLE']['MODER']):
            await log('BAN - target role invalide', MNT)
            return
        if not check.ban_allowed(target,
                                 ctx.message.author) or not check.ban_allowed(
                                     target, ctx.guild.me):
            await log('BAN - permission de ban refusée', MNT)
            return

        # Séparation du text en message + auditlog
        message, auditlog = tool.extract_text(text)
        if not auditlog:
            await log('BAN - auditlog not given', MNT)
            return await ctx.channel.send(
                'Auditlog manquant : ?ban [message optionnel] auditlog')
        if len(auditlog) > 512:
            await log('BAN - auditlog too long (512 char max)', MNT)
            return await ctx.channel.send(
                "Auditlog trop long (`{}/512` caractères max)".format(
                    len(auditlog)))

        # ACTION
        action = ACTION('Ban',
                        target.id,
                        ctx.message.author.id,
                        ctx.message.created_at,
                        message=message,
                        reason=auditlog)
        EMB = action.embed(self.client, 0x550000)

        # Notification aux modérateurs
        await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                      ).send(content=None, embed=EMB)
        await ctx.channel.send(
            ':skull_crossbones: {} a été ban du serveur.'.format(
                target.mention))

        # Ban
        if message:
            await target.send(self.text['BAN'].format(message))
        else:
            await target.send(self.text['BAN_w_msg'])
        self.exit_lock = True
        await target.ban(reason=auditlog, delete_message_days=1)

        # Sauvegarde du log
        action.save('src/config/moderation/data.json')
예제 #6
0
    async def log(self, ctx, target: discord.User):
        """ Récupère les logs d'un user
		"""
        # Checks
        if check.is_role(target, self.id['ROLE']['MODER']):
            await log('LOG - target role invalide', MNT)
            return

        # Obtention des logs
        logs = tool.get_data('src/config/moderation/data.json')
        list_log = []
        for e in logs:
            if logs[e]['user'] == target.id:
                log = ACTION(logs[e]['lib'],
                             logs[e]['user'],
                             logs[e]['author'],
                             logs[e]['time'],
                             reason=logs[e]['reason'],
                             message=logs[e]['message'],
                             log_id=logs[e]['log_id'],
                             log_channel=logs[e]['log_channel'],
                             log_content=logs[e]['log_content'],
                             num=e)
                list_log.append(log)
        if not list_log:
            return await ctx.channel.send(
                ':x: Aucun log trouvé pour {}.'.format(target.name))

        await ctx.channel.send(':pencil: {} logs trouvés pour {}.'.format(
            len(list_log), target.name))

        # Envoi des logs
        if len(list_log) > 5:
            for log in list_log:
                EMB = log.embed(self.client, log.color)
                await ctx.author.send(content=None, embed=EMB)
            await ctx.channel.send(':mailbox: Logs expédiés.')
        else:
            for log in list_log:
                EMB = log.embed(self.client, log.color)
                await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                              ).send(content=None, embed=EMB)
예제 #7
0
    async def on_member_update(self, before, after):
        """ Notifie les mises en SDD si celles-ci ne sont pas le fait d'une commande.
			"Libère" la SDD lorsqu'il n'y a plus personne dedans (laisse un message)
		"""

        if after.roles == before.roles:
            return

        # CHANGEMENT DE ROLES
        if len(after.roles) > len(before.roles):
            add_role = True
            for item in after.roles:
                if item not in before.roles:
                    role = item
                    break
            notification = ':green_circle: {} a obtenu le rôle : {}'

        else:
            add_role = False
            for item in before.roles:
                if item not in after.roles:
                    role = item
                    break
            notification = ':red_circle: {} a perdu le rôle : {}'

        await log(notification.format(after.name, role.name), MNT)

        # ANIMATION (rôles spécifiques donnés sur autorole)
        if role.id in self.animation_role:
            await self.client.get_channel(
                self.id['TEXTCHANNEL']['LOG_ANIMATION']
            ).send(notification.format(after.mention, role.name))

        # Mise en SDD
        if not check.is_role(before, self.sdd_role) and check.is_role(
                after, self.sdd_role):
            await log('{} a été mis en SDD'.format(before.name),
                      MNT,
                      time=True)
            if self.sdd_lock:
                await log('SDD by :hole:', MNT)
                self.sdd_lock = False
                return
            if not check.auditlog_allowed(after.guild.me):
                await log('Access to auditlog denied', MNT)
                return
            await asyncio.sleep(5)
            async for entry in after.guild.audit_logs(
                    action=discord.AuditLogAction.member_role_update,
                    limit=20):
                if entry.target == after and datetime.utcnow(
                ) - entry.created_at < timedelta(seconds=10):
                    action = ACTION('MISE EN SDD', entry.target.id,
                                    entry.user.id, entry.created_at)
                    EMB = action.embed(self.client, action.color)
                    await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                                  ).send(content=None,
                                                         embed=EMB)
                    return
            return
        elif check.is_role(before, self.sdd_role) and not check.is_role(
                after, self.sdd_role):
            lost_role = [
                role for role in before.roles if role not in set(after.roles)
            ]
            await log(
                '{} a perdu le rôle {}'.format(after.name, lost_role[0].name),
                MNT)
            await log(
                '{} - {}'.format(lost_role[0].id, self.id['ROLE']['DIALO']),
                MNT)
            if lost_role[0].id in self.id['ROLE']['DIALO']:
                channel = self.client.get_channel(
                    self.id['TEXTCHANNEL']['DIALO'])
            else:
                channel = self.client.get_channel(
                    self.id['TEXTCHANNEL']['DISCU'])
            await log('Channel : {} - {}'.format(channel.id, channel.name),
                      MNT)
            await log(
                '{} : {}'.format(lost_role[0].name, [
                    '{} -'.format(user.name) for user in lost_role[0].members
                ]), MNT)

            if not lost_role[0].members:
                return await channel.send('```LIBRE```')
        else:
            return
예제 #8
0
    async def on_raw_reaction_add(self, payload):
        """ Log ou supprime un message via un emoji mis en réaction.
			Donne un rôle SDD en fonction de la place libre avec un troisième emoji
			
		NOTE
		----
		> Pour la SDD, on vérifie le nombre de personnes ayant déjà l'un des deux rôles. Si d'autres personnes ont déjà ce rôle, les nouveaux arrivants iront par défaut dans la seconde salle.
		"""
        guild = self.client.get_guild(GUILD_ID)
        author = guild.get_member(payload.user_id)
        channel = self.client.get_channel(payload.channel_id)
        msg = await channel.fetch_message(payload.message_id)

        # Checks
        if not check.is_role(author, self.id['ROLE']['MODER']):
            return
        if check.is_role(msg.author, self.id['ROLE']['MODER']):
            return

        # Emojis
        emoji = payload.emoji

        # LOG :eyes:
        if emoji.name == u"\U0001F440":
            if not check.manage_messages_allowed(
                    guild.me) or not check.manage_messages_allowed(author):
                await log('Permission to remove emoji denied', MNT)
                return
            logs = tool.get_data('src/config/moderation/data.json')
            for e in logs:
                if logs[e]['user'] == msg.author.id and logs[e][
                        'log_id'] == payload.message_id:
                    return
            action = ACTION('LOG {}'.format(emoji),
                            msg.author.id,
                            author.id,
                            msg.created_at,
                            log_id=msg.id,
                            log_channel=msg.channel.id,
                            log_content=msg.content)
            await msg.remove_reaction(emoji, author)

        # DEL :x:
        elif emoji.name == u"\U0000274C":
            if not check.manage_messages_allowed(
                    guild.me) or not check.manage_messages_allowed(author):
                await log('Permission to remove emoji denied', MNT)
                return
            action = ACTION('LOG {}'.format(emoji),
                            msg.author.id,
                            author.id,
                            msg.created_at,
                            log_id=msg.id,
                            log_channel=msg.channel.id,
                            log_content=msg.content)
            await msg.delete()


##		 SDD :hole:
#		elif emoji.name == u"\U0001F573":
#			print('hole')
#			role_dialo = guild.get_role(self.id['ROLE']['DIALO'])
#			role_discu = guild.get_role(self.id['ROLE']['DISCU'])
#			if (check.is_role(msg.author, role_discu)) or (check.is_role(msg.author, role_dialo)):
#				await log('SDD deja attribuee', MNT)
#				return
#			if not role_dialo.members:
#				if not check.change_role_allowed(role_dialo, guild.me) and not check.change_role_allowed(role_dialo, author):
#					await log('Permission to give role denied', MNT)
#					return
#				await msg.author.add_roles(role_dialo)
#				channel = self.client.get_channel(self.id['TEXTCHANNEL']['DIALO'])
#				if channel.permissions_for(guild.me).send_messages:
#					await channel.send('Bonjour {}'.format(msg.author.mention))
#				else:
#					await log('Permission to write in dialo forbidden', MNT)
#			else:
#				if not check.change_role_allowed(role_discu, guild.me) and not check.change_role_allowed(role_discu, author):
#					await log('Permission to give role denied', MNT)
#					return
#				await msg.author.add_roles(role_discu)
#				channel = self.client.get_channel(self.id['TEXTCHANNEL']['DISCU'])
#				if channel.permissions_for(guild.me).send_messages:
#					await channel.send('Bonjour {}'.format(msg.author.mention))
#				else:
#					await log('Permission to write in discu forbidden', MNT)
#
#			await msg.remove_reaction(emoji,author)
#			action = ACTION('MISE EN SDD {}'.format(emoji), msg.author.id, author.id, msg.created_at)
#			self.sdd_lock = True
        else:
            return

        # Notification dans le salon de log
        EMB = action.embed(self.client, action.color)
        await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                      ).send(content=None, embed=EMB)

        # Sauvegarde du log
        action.save('src/config/moderation/data.json')
예제 #9
0
    async def on_member_remove(self, member):
        """ Notifie les kicks / bans si ceux-ci ne sont pas dûs à une commande.
			Notifie aussi les fuites de SDD (quelqu'un quitte de lui-même le serveur avec un rôle SDD)
		
		NOTE
		----
		> L'accès à l'auditlog est défaillant et peut parfois poser problèmes (léger lag entre le kick/ban et l'entrée correspondante dans l'auditlog).
		  Pour y palier, on a mis un délai de 5s avant lecture de l'auditlog, puis on récupère les 20 dernières entrées (en supposant en cas de raid jusqu'à 20 kick / bans en 5s) pour vérifier si l'une d'entre elle correspond.
		  C'est à dire si l'entrée a été faite il y a moins de 5s, correspond à un kick / ban et concerne l'utilisateur souhaité.
		"""
        await log('{} a quitté le serveur'.format(member.name), MNT, time=True)

        # Commande utilisée:
        if self.exit_lock:
            self.exit_lock = False
            return await log('verrou actif: commande', MNT)

        guild = self.client.get_guild(GUILD_ID)
        if not check.auditlog_allowed(guild.me):
            return await log("HAL 9000 n'a pas accès à l'auditlog", MNT)
        await asyncio.sleep(5)

        # Kick
        async for entry in guild.audit_logs(action=discord.AuditLogAction.kick,
                                            limit=20):
            if datetime.utcnow() - entry.created_at > timedelta(0, 10):
                break
            if entry.target == member:
                await log("KICK manuel", MNT)
                action = ACTION('Kick',
                                entry.target.id,
                                entry.user.id,
                                entry.created_at,
                                reason=entry.reason)
                EMB = action.embed(self.client, 0x995500)
                await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                              ).send(content=None, embed=EMB)
                await self.client.get_channel(
                    self.id['TEXTCHANNEL']['MODER']
                ).send(':hammer: {} a été kick du serveur.'.format(
                    str(entry.target)))
                action.save('src/config/moderation/data.json')

                # Check SDD
                if check.is_role(member, self.sdd_role):
                    for role in member.roles:
                        if role.id == self.id['ROLE'][
                                'DISCU'] and not role.members:
                            channel = self.client.get_channel(
                                self.id['TEXTCHANNEL']['DISCU'])
                            await channel.send('```LIBRE```')
                        if role.id == self.id['ROLE'][
                                'DIALO'] and not role.members:
                            channel = self.client.get_channel(
                                self.id['TEXTCHANNEL']['DIALO'])
                            await channel.send('```LIBRE```')

                try:
                    await self.client.get_channel(
                        self.id['TEXTCHANNEL']['JOIN_REMOVE']
                    ).send('{}#{} a été kick du serveur. :hammer:'.format(
                        member.name, member.discriminator))
                except:
                    await log('ALERTE : accès restreint au salon JOIN_REMOVE')

                return

        # Ban
        async for entry in guild.audit_logs(action=discord.AuditLogAction.ban,
                                            limit=20):
            if datetime.utcnow() - entry.created_at > timedelta(0, 10):
                break
            if entry.target == member:
                await log('BAN manuel', MNT)
                action = ACTION('Ban',
                                entry.target.id,
                                entry.user.id,
                                entry.created_at,
                                reason=entry.reason)
                EMB = action.embed(self.client, 0x550000)
                await self.client.get_channel(self.id['TEXTCHANNEL']['LOG']
                                              ).send(content=None, embed=EMB)
                await self.client.get_channel(
                    self.id['TEXTCHANNEL']['MODER']
                ).send(':skull_crossbones: {} a été ban du serveur.'.format(
                    str(entry.target)))
                action.save('src/config/moderation/data.json')

                # Check SDD
                if check.is_role(member, self.sdd_role):
                    for role in member.roles:
                        if role.id == self.id['ROLE'][
                                'DISCU'] and not role.members:
                            channel = self.client.get_channel(
                                self.id['TEXTCHANNEL']['DISCU'])
                            await channel.send('```LIBRE```')
                        if role.id == self.id['ROLE'][
                                'DIALO'] and not role.members:
                            channel = self.client.get_channel(
                                self.id['TEXTCHANNEL']['DIALO'])
                            await channel.send('```LIBRE```')

                try:
                    await self.client.get_channel(
                        self.id['TEXTCHANNEL']['JOIN_REMOVE']
                    ).send('{}#{} a été ban du serveur. :skull_crossbones:'.
                           format(member.name, member.discriminator))
                except:
                    await log('ALERTE : accès restreint au salon JOIN_REMOVE')

                return

        # Départ volontaire
        await log('Départ volontaire', MNT)
        try:
            await self.client.get_channel(
                self.id['TEXTCHANNEL']['JOIN_REMOVE']
            ).send('{}#{} a quitté le serveur.'.format(member.name,
                                                       member.discriminator))
        except:
            await log('ALERTE : accès restreint au salon JOIN_REMOVE')

        if check.is_role(member, self.sdd_role):
            for role in member.roles:
                if role.id == self.id['ROLE']['DISCU'] and not role.members:
                    channel = self.client.get_channel(
                        self.id['TEXTCHANNEL']['DISCU'])
                    await channel.send('```LIBRE```')
                if role.id == self.id['ROLE']['DIALO'] and not role.members:
                    channel = self.client.get_channel(
                        self.id['TEXTCHANNEL']['DIALO'])
                    await channel.send('```LIBRE```')
            await self.client.get_channel(
                self.id['TEXTCHANNEL']['MODER']
            ).send(':no_pedestrians: {} a pris la fuite de la SDD !'.format(
                member.mention))