перезаход на сервер. Мут/tempmute. discord.py

Рейтинг: 0Ответов: 1Опубликовано: 27.08.2023

Я сделал команду мута (!mute @user (время) (причина)). Однако участник может обойти мут просто перезайти на сервер, как этого не допустить? Сделать так, чтобы нарушитель при попытке перезайти на сервер получал повторно роль мут на оставшееся время? Вот сама команда:

import discord
from discord.ext import commands
import re
import asyncio

class MuteCog(commands.Cog):
    def __init__(self, bot: commands.Bot) -> None:
        self.bot = bot
        self.muted_role_id = 1145116400193654804  # Роль мута
        self.mod_roles = ["Адм"]  # Роли модераторов
        self.time_pattern = re.compile(r'(\d+)([dhms])') 

    @commands.Cog.listener()
    async def on_member_join(self, member):
        muted_role = discord.utils.get(member.guild.roles, id=self.muted_role_id)
        if muted_role in member.roles:
            await self.mute_channels(member)

    @commands.command()
    async def mute(self, ctx, user: discord.Member, duration, *, reason=None) -> None:
        author = ctx.author
        if any(role.name in self.mod_roles for role in author.roles):
            muted_role = discord.utils.get(ctx.guild.roles, id=self.muted_role_id)
            await user.add_roles(muted_role)

            time_units = {'d': 'дней', 'h': 'часов', 'm': 'минут', 's': 'секунд'}
            time_args = self.time_pattern.findall(duration)
            mute_time = 0
            for value, unit in time_args:
                if unit in time_units:
                    value = int(value)
                    if unit == 'd':
                        value *= 86400
                    elif unit == 'h':
                        value *= 3600
                    elif unit == 'm':
                        value *= 60
                    mute_time += value

            await asyncio.gather(
                self.mute_channels(user),
                self.unmute_user(user, mute_time)
            )

            mute_message = (
                f'Участник {user.mention} был замутен модератором {author.mention} '
                f'на {duration} по причине {reason}'
            )
            await ctx.send(mute_message)
        else:
            await ctx.send("У вас нет прав на использование этой команды.")

    async def mute_channels(self, user):
        for channel in user.guild.channels:
            if isinstance(channel, discord.CategoryChannel):
                for text_channel in channel.text_channels:
                    await text_channel.set_permissions(user, send_messages=False)
                for voice_channel in channel.voice_channels:
                    await voice_channel.set_permissions(user, connect=False)

    async def unmute_user(self, user, mute_time):
        await asyncio.sleep(mute_time)
        muted_role = discord.utils.get(user.guild.roles, id=self.muted_role_id)
        await user.remove_roles(muted_role)
        for channel in user.guild.channels:
            if isinstance(channel, discord.CategoryChannel):
                for text_channel in channel.text_channels:
                    await text_channel.set_permissions(user, send_messages=True)
                for voice_channel in channel.voice_channels:
                    await voice_channel.set_permissions(user, connect=True)

async def setup(bot: commands.Bot) -> None:
    await bot.add_cog(MuteCog(bot))

Буду очень благодарен, ибо способа нигде не нашел!

Ответы

▲ 0

Попробуйте сохранять куда-нибудь ID пользователей, которые получили "мут", а в ивенте on_member_join сделать проверку.

Приведу простой пример, допустим, что данные хранятся в формате json в виде "user_id": True / False:

import json

import discord
from discord.ext import commands


class MuteCog(commands.Cog):
    def __init__(self, bot: commands.Bot) -> None:
        self.bot = bot

    @commands.Cog.listener()
    async def on_member_join(self, member: discord.Member):
        with open("file.json") as file:
            mutes = json.load(file)

        if mutes[str(member.id)] is True:
            role = member.guild.get_role(123456)
            
            await member.add_roles(role)

P.S. Не рекомендую использовать json для хранения данных, например попробуйте использовать sql.