diff --git a/cogs/AutoRole.py b/cogs/AutoRole.py index b1d5d60..48ab08b 100644 --- a/cogs/AutoRole.py +++ b/cogs/AutoRole.py @@ -26,7 +26,7 @@ async def on_member_join(self, member: disnake.Member): role = guild.get_role(role_id) try: await member.add_roles(role) - emb = disnake.Embed(title=f"Привет {member.display_name}!", color=0x7788ff) + emb = disnake.Embed(title=f"Привет {member.display_name}!", color=0xCD853F) emb.description = f"Я назначила тебе роль **{role.name}** на сервере {guild.name}." await member.send(embed=emb) except disnake.errors.Forbidden: @@ -43,13 +43,13 @@ async def set_default_role(self, ctx, role: disnake.Role = None): embed = disnake.Embed( title=f"Роль {role.name} установлена как роль по умолчанию.", - color=0x7788ff + color=0xCD853F ) else: embed = disnake.Embed( title="Ошибка при установке роли по умолчанию!", description="Укажите корректную роль", - color=0x7788ff + color=0xCD853F ) await ctx.send(embed=embed, ephemeral=True) @@ -59,7 +59,7 @@ async def set_default_role_error(self, ctx, error): embed = disnake.Embed( title="Ошибка при установке роли по умолчанию!", description="У вас нет разрешения управлять ролями!", - color=0x7788ff + color=0xCD853F ) await ctx.send(embed=embed, ephemeral=True) diff --git a/cogs/admins.py b/cogs/admins.py index 137169c..3c88700 100644 --- a/cogs/admins.py +++ b/cogs/admins.py @@ -5,7 +5,6 @@ import sqlite3 import os import sys -import typing from datetime import datetime @@ -28,17 +27,22 @@ class admins(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot - - - + @commands.slash_command(name="kick", description="Выгнать пользователя с сервера.") @commands.has_permissions(kick_members=True, administrator=True) async def kick_user(self, ctx: disnake.ApplicationCommandInteraction, user: disnake.Member, reason: str = None): await user.kick(reason=reason) - embed=disnake.Embed(color=0x7788ff) - embed.add_field(name="Kick", value=f"{ctx.author.mention} кикнула {user.mention} из {ctx.guild} сервера") - await ctx.send(embed=embed, ephemeral=True) + try: + await user.send(f"Вы были кикнуты с сервера {ctx.guild.name}. Причина: {reason}") + except disnake.errors.HTTPException: + pass + embed = disnake.Embed(color=0xCD853F) + embed.add_field(name="Kick", value=f"{ctx.author.mention} кикнула {user.mention} из {ctx.guild} сервера 😔") + embed.add_field(name="Причина", value=reason if reason else "Не указана") + + await ctx.send(embed=embed, ephemeral=True) + @commands.slash_command(name='clear', description='Очистить чат') @@ -50,7 +54,7 @@ async def clear(self, ctx: disnake.ApplicationCommandInteraction, amount: int): await ctx.send('Кискис нельзя удалить больше 1000 сообщений за раз.') return deleted = await ctx.channel.purge(limit=amount) - embed=disnake.Embed(color=0x7788ff) + embed=disnake.Embed(color=0xCD853F) embed.add_field(name="Очистила чат", value=f"Удалила {len(deleted)} сообщений 😊", inline=False) await ctx.send(embed=embed, ephemeral=True) @@ -64,12 +68,16 @@ async def ban_user(self, ctx: disnake.ApplicationCommandInteraction, user: disna c.execute("SELECT user_id FROM bans WHERE user_id=?", (user.id,)) banned_user = c.fetchone() if banned_user: - embed = disnake.Embed(title="Бан", description=f"{user.mention} Этот пользователь уже забанен.", color=0x7788ff) + embed = disnake.Embed(title="Бан", description=f"{user.mention} Этот пользователь уже забанен.", color=0xCD853F) else: await user.ban(reason=reason) c.execute("INSERT INTO bans (user_id, username, reason) VALUES (?, ?, ?)", (user.id, user.name, reason)) conn.commit() - embed = disnake.Embed(title="Бан", description=f"{user.mention} Я забанила эту хамку.😤", color=0x7788ff) + embed = disnake.Embed(title="Бан", description=f"{user.mention} Я забанила эту хамку.😤", color=0xCD853F) + try: + await user.send(embed=embed) + except disnake.errors.HTTPException: + pass await ctx.send(embed=embed, ephemeral=True) @@ -82,11 +90,19 @@ async def unban_user(self, ctx: disnake.ApplicationCommandInteraction, user: dis banned_user = banned_entry.user if (banned_user.name, banned_user.discriminator) == (user_name, user_discriminator): await ctx.guild.unban(banned_user, reason=reason) + conn = sqlite3.connect('bans.db') + c = conn.cursor() c.execute("DELETE FROM bans WHERE user_id=?", (banned_user.id,)) conn.commit() - embed = disnake.Embed(title="Разбан", description=f"{banned_user.mention} был успешно разбанен.", color=0x7788ff) + embed = disnake.Embed(title="Разбан", description=f"{banned_user.mention} был успешно разбанен.", color=0xCD853F) + try: + await banned_user.send(embed=embed) + except disnake.errors.HTTPException: + pass + await ctx.send(embed=embed, ephemeral=True) return + embed = disnake.Embed(title="Ошибка", description=f"Пользователь {user.mention} не был найден в списке забаненных.", color=0xff0000) await ctx.send(embed=embed, ephemeral=True) @@ -96,7 +112,7 @@ async def unban_user(self, ctx: disnake.ApplicationCommandInteraction, user: dis @commands.has_permissions(administrator=True) async def echo(self, ctx: disnake.ApplicationCommandInteraction, channel: disnake.TextChannel, *, message: str): message = message.replace("-", "\n") - embed=disnake.Embed(color=0x7788ff) + embed=disnake.Embed(color=0xCD853F) embed.add_field(name="", value=message, inline=False) await channel.send(embed=embed) @@ -119,14 +135,14 @@ async def join(ctx: disnake.ApplicationCommandInteraction): channel = ctx.author.voice.channel await channel.connect() embed = disnake.Embed( - color=0x7788ff, + color=0xCD853F, title="Готово", description=f"Успешно подключилась к голосовому каналу {channel.name}" ) await ctx.send(embed=embed, ephemeral=True) voice_channel = ctx.author.voice.channel - embed = disnake.Embed(color=0x7788ff) + embed = disnake.Embed(color=0xCD853F) embed.add_field(name="voice", value=voice_channel.name, inline=False) await ctx.send(embed=embed, ephemeral=True) @@ -139,7 +155,7 @@ async def join(ctx: disnake.ApplicationCommandInteraction): async def leave(ctx: disnake.ApplicationCommandInteraction): if not ctx.guild.voice_client: embed = disnake.Embed( - color=0x7788ff, + color=0xCD853F, title="Ошибка", description="Я не нахожусь в голосовом канале" ) @@ -148,7 +164,7 @@ async def leave(ctx: disnake.ApplicationCommandInteraction): await ctx.guild.voice_client.disconnect() embed = disnake.Embed( - color=0x7788ff, + color=0xCD853F, title="Готово", description="Успешно отключилась от голосового канала" ) @@ -161,7 +177,7 @@ async def leave(ctx: disnake.ApplicationCommandInteraction): async def stay(ctx): if not ctx.author.voice: embed = disnake.Embed( - color=0x7788ff, + color=0xCD853F, title="Ошибка", description="Вы должны находиться в голосовом канале, чтобы использовать эту команду." ) @@ -173,14 +189,14 @@ async def stay(ctx): if voice_client and voice_client.is_connected(): await voice_client.move_to(vc) embed = disnake.Embed( - color=0x7788ff, + color=0xCD853F, title="Готово", description=f'Я останусь в голосовом канале "{vc.name}" до тех пор, пока меня не попросят выйти. Для этого напиши /leave.' ) else: voice_client = await vc.connect() embed = disnake.Embed( - color=0x7788ff, + color=0xCD853F, title="Готово", description="Удачно зашла в голосовой канал." ) @@ -199,10 +215,10 @@ async def restart(ctx: disnake.ApplicationCommandInteraction): try: os.execv(sys.executable, ['python'] + [arg for arg in sys.argv if arg != '--handle-sls']) except Exception as e: - embed = disnake.Embed(title='Ошибка при перезапуске бота', color=0x7788ff) + embed = disnake.Embed(title='Ошибка при перезапуске бота', color=0xCD853F) await ctx.send(embed=embed, ephemeral=True) else: - embed = disnake.Embed(title='Бот перезапущен успешно', color=0x7788ff) + embed = disnake.Embed(title='Бот перезапущен успешно', color=0xCD853F) await ctx.send(embed=embed, ephemeral=True) @@ -218,7 +234,7 @@ async def create_role(ctx, name: str): embed = disnake.Embed( title=f'Роль создана', description=f'Новая роль {role.mention} была создана!', - color=0x7788ff + color=0xCD853F ) await ctx.send(embed=embed, ephemeral=True) @@ -231,7 +247,7 @@ async def assign_role(ctx, role: disnake.Role, member: disnake.Member): embed = disnake.embeds.Embed( title='Роль добавлена', description=f'Кисуне {member.mention} была выдана роль {role.mention}!', - color=0x7788ff + color=0xCD853F ) await ctx.send(embed=embed, ephemeral=True) @@ -244,7 +260,7 @@ async def remove_role(ctx, role: disnake.Role, member: disnake.Member): embed = disnake.embeds.Embed( title='Роль удалена', description=f'У кисуни {member.mention} была удалена роль {role.mention}!', - color=0x7788ff + color=0xCD853F ) await ctx.send(embed=embed, ephemeral=True) @@ -257,7 +273,7 @@ async def set_nickname(self, ctx, member: disnake.Member, new_nickname: str): embed = disnake.Embed( title="Изменение никнейма :pen_ballpoint:", description=f"Никнейм участника {member.mention} был изменен на {new_nickname}.", - color=0x7788ff + color=0xCD853F ) await ctx.send(embed=embed, ephemeral=True) @@ -277,7 +293,7 @@ async def set_color_role(ctx, role: disnake.Role, color: str = None): await role.edit(color=color) - embed = disnake.Embed(title='Цвет изменен', color=0x7788ff) + embed = disnake.Embed(title='Цвет изменен', color=0xCD853F) embed.add_field(name='Роль', value=role.mention) embed.add_field(name='Цвет', value=f'#{color.value:06x}') @@ -295,7 +311,7 @@ async def set_color_role(ctx, role: disnake.Role, color: str = None): @commands.has_permissions(administrator=True) async def poll(self, ctx, *, text): await ctx.channel.purge(limit=1) - poll = disnake.Embed(description=text, colour=randint(0, 0x7788ff)) + poll = disnake.Embed(description=text, colour=randint(0, 0xCD853F)) poll.timestamp = datetime.utcnow() msg = await ctx.channel.send(embed=poll) await msg.add_reaction("✔") @@ -314,7 +330,7 @@ async def send(self, ctx, member: disnake.Member, *, text): success_embed = disnake.Embed(title="Сообщение отправлено!", description=f"Успешно отправил участнику {member.mention}", - color=0x7788ff) + color=0xCD853F) await ctx.send(embed=success_embed, ephemeral=True) def setup(bot: commands.Bot): diff --git a/cogs/chat.py b/cogs/chat.py index e4be042..4ff63f6 100644 --- a/cogs/chat.py +++ b/cogs/chat.py @@ -38,11 +38,11 @@ async def chat(self, inter, message: str): if len(full_response) <= 2000: if response.choices[0].finish_reason == 'stop' and response.choices[0].index == 0: - embed = Embed(title="ChatGPT", description=f"```{full_response}```", color=0x7788ff) + embed = Embed(title="ChatGPT", description=f"```{full_response}```", color=0xCD853F) else: - embed = Embed(title="ChatGPT", description=full_response, color=0x7788ff) + embed = Embed(title="ChatGPT", description=full_response, color=0xCD853F) else: - embed = Embed(title="ChatGPT", description=f"{full_response[:2000]}...\n\n[Описание обрезано из-за ограничения Discord на 2000 символов.]", color=0x7788ff) + embed = Embed(title="ChatGPT", description=f"{full_response[:2000]}...\n\n[Описание обрезано из-за ограничения Discord на 2000 символов.]", color=0xCD853F) if not inter.responded: await inter.send(embed=embed, ephemeral=True) diff --git a/cogs/econom.py b/cogs/econom.py index 4387761..2f188d9 100644 --- a/cogs/econom.py +++ b/cogs/econom.py @@ -39,7 +39,7 @@ async def daily(ctx: disnake.ApplicationCommandInteraction): new_balance = balance + random.randint(50, 150) c.execute('UPDATE economy SET balance = ?, last_daily = ? WHERE user_id = ?', (new_balance, int(datetime.utcnow().timestamp()), user_id)) conn.commit() - embed=disnake.Embed(color=0x7788ff) + embed=disnake.Embed(color=0xCD853F) embed.add_field(name="Poli-coins", value="Ежедневный бонус", inline=False) embed.add_field(name="Ты получил", value=f"{new_balance - balance} Poli-coins", inline=True) await ctx.send(embed=embed, ephemeral=True) @@ -55,12 +55,12 @@ async def balance(ctx: disnake.ApplicationCommandInteraction): if not row: c.execute('INSERT INTO economy (user_id, username, balance, last_daily) VALUES (?, ?, 0, 0)', (user_id, ctx.author.name)) conn.commit() - embed = disnake.Embed(color=0x7788ff) + embed = disnake.Embed(color=0xCD853F) embed.add_field(name="Ваш баланс", value="На вашем счету: 0", inline=True) await ctx.send(embed=embed, ephemeral=True) else: balance = row[0] - embed = disnake.Embed(color=0x7788ff) + embed = disnake.Embed(color=0xCD853F) embed.add_field(name="Ваш баланс", value=f"На вашем счету: {balance}", inline=True) await ctx.send(embed=embed, ephemeral=True) @@ -88,7 +88,7 @@ async def heads_or_tails(ctx: disnake.ApplicationCommandInteraction, bet: int, g c.execute('UPDATE economy SET balance = balance + ? WHERE user_id = ?', (winnings, user_id)) conn.commit() message = f"{ctx.author.mention}, Вы выиграли {winnings} Poli-coins! Результат: {result}." - color = 0x7788ff + color = 0xCD853F else: c.execute('UPDATE economy SET balance = balance - ? WHERE user_id = ?', (bet, user_id)) conn.commit() @@ -132,5 +132,7 @@ async def dice(ctx, bet: int): + + def setup(bot: commands.Bot): bot.add_cog(economy(bot)) \ No newline at end of file diff --git a/cogs/event.py b/cogs/event.py index 7c9dac4..3816c86 100644 --- a/cogs/event.py +++ b/cogs/event.py @@ -21,7 +21,7 @@ async def on_message(self, message): await self.bot.process_commands(message) msg = message.content.lower() - censored_words = ["кефир", "чифирный", "мать", "шлюха", "кефирчик", "бахмуте", "украина", "кефир выпил", "Кефирчика", "кефирчиком", "маму"] + censored_words = ["кефир", "чифирный", "мать", "шлюха", "кефирчик", "бахмуте", "украина", "кефир выпил", "Кефирчика", "кефирчиком", "Vступай V ряды ЧVК Vагнер, праvда на нашей стороне, на стороне победителей!!!"] for bad_content in msg.split(): if bad_content in censored_words: @@ -29,7 +29,7 @@ async def on_message(self, message): embed = disnake.Embed( title="", description=f"{message.author.mention}, Я удалила ваше сообщение, так как оно нарушает правила сервера! ❌", - color=0x7788ff + color=0xCD853F ) await message.channel.send(embed=embed) break @@ -41,29 +41,34 @@ async def on_slash_command_error(self, interaction: disnake.Interaction, error): if isinstance(error, commands.errors.CommandError): embed = disnake.Embed( title="Error", - color=0x7788ff, + color=0xCD853F, description=f"Команда не смогла отправить ответ\n```js\n- Error Description: {str('{')}\n{error}\n{str('}')}\n```\nЕсли вы хотите помочь в разработке бота, то вы можете отправить эту ошибку нам на [support server](https://discord.gg/EepTPBS8) в [bugs-report](https://discord.gg/wUT3czzU) канал, после чего мы это исправим.") await interaction.response.send_message(embed=embed, ephemeral=True) @commands.Cog.listener() - async def on_application_command_error(self, ctx, error): - if isinstance(error, disnake.errors.MissingPermissions): - await ctx.response.send_message("У вас недостаточно прав для использования этой команды.", ephemeral=True) + async def on_command_error(self, ctx, error): + if isinstance(error, commands.CheckFailure): + embed = disnake.Embed( + title="Ошибка доступа", + description="Эта команда доступна только для администраторов.", + color=0xCD853F + ) + await ctx.send(embed=embed, ephemeral=True) @commands.Cog.listener() async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandNotFound): - await ctx.send(embed=disnake.Embed(description=f'** {ctx.author.name}, Данной команды нет, но скоро будет.**', color=0x7788ff)) + await ctx.send(embed=disnake.Embed(description=f'** {ctx.author.name}, Данной команды нет, но скоро будет.**', color=0xCD853F)) @commands.Cog.listener() async def on_member_join(self, member): - emb = disnake.Embed(title="Привет! добро пожаловать на сервер...", color=0x7788ff) + emb = disnake.Embed(title="Привет! добро пожаловать на сервер...", color=0xCD853F) emb.add_field(name="Мои команды", value="Чтобы узнать подробнее команды напиши - /help") await member.send(embed=emb) diff --git a/cogs/help.py b/cogs/help.py index f59ae37..0216737 100644 --- a/cogs/help.py +++ b/cogs/help.py @@ -47,9 +47,9 @@ async def callback(self, interaction: disnake.Interaction): if "Модерация" in self.values: embed = disnake.Embed(color=disnake.Color.blurple()) embed.add_field(name='Модерация', value=( - '`/clear` > Очистка чата\n' - '`/embed` > Эмбед от имени бота\n' - '`/poll` > Голосование\n' + '`/clear` > Очистка чата 🗑️\n' + '`/embed` > Эмбед от имени бота 📑\n' + '`/poll` > Голосование 🗳️\n' '`/kick` > Выгнать пользователя с сервера 😠\n' '`/ban` > Забанить пользователя на сервере 🚫\n' '`/join` > Зайти в голосовой канал 🎤\n' @@ -65,6 +65,9 @@ async def callback(self, interaction: disnake.Interaction): '`/send-dm` > Отправить в лс сообщение от имени бота 💬\n' '`/voicemute` > Mute пользователя в голосовых каналах 😶\n' '`/unvoicemute` > unMute пользователя в голосовых каналах🎙️\n' + '`/mchat` > Блокировка чата пользователю 🔒\n' + '`/unmchat` > Снять блокировку чата у пользователя 🔓\n' + '`/mchatinfo` > Показать список пользователей в муте 📋\n' )) await interaction.response.edit_message(embed=embed) if "Глобальный чат" in self.values: @@ -90,6 +93,7 @@ async def callback(self, interaction: disnake.Interaction): '`/ping` > Проверка бота на работу 🏓\n' '`/nitro` > Генерирует Discord Nitro 🎁\n' '`/chat` > Спросить у ChatGPT 🤔\n' + '`/ticket` > Создать тикет для связи с администрацией 📲\n' )) await interaction.response.edit_message(embed=embed) if "Животные" in self.values: diff --git a/cogs/infobots.py b/cogs/infobots.py index fbc8c80..8bb5008 100644 --- a/cogs/infobots.py +++ b/cogs/infobots.py @@ -14,7 +14,7 @@ async def bot(self, ctx): info=disnake.Embed(title = ":robot: Информация о боте", description = f"Информация об **Polina bot**", colour=randint(0, 0xffffff)) info.add_field(name = ":bearded_person: Разработчик:", value = "`П͓̽р͓̽о͓̽в͓̽а͓̽й͓̽д͓̽е͓̽р͓̽#6666`") info.add_field(name = ":ledger: Моя библиотека:", value="Disnake", inline=False) - info.add_field(name = ":floppy_disk: Моя версия:", value = "`v3.2.5`", inline=False) + info.add_field(name = ":floppy_disk: Моя версия:", value = "`v3.5`", inline=False) info.add_field(name = "🔗 Приглашение:", value = f"[Нажми](https://discord.com/api/oauth2/authorize?client_id=1023602153694183475&permissions=8&scope=bot)", inline = True) info.add_field(name = "⚙️ Команд:", value = f"{len(self.bot.slash_commands)}") info.add_field(name = "📊 Кол-во гильдий:", value = f"{len(self.bot.guilds)}") diff --git a/cogs/logs.py b/cogs/logs.py new file mode 100644 index 0000000..f7b9eac --- /dev/null +++ b/cogs/logs.py @@ -0,0 +1,164 @@ +import disnake +from disnake.ext import commands + + +class Logs(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.Cog.listener() + async def on_ready(self): + for guild in self.bot.guilds: + overwrites = { + guild.default_role: disnake.PermissionOverwrite(read_messages=False), + guild.me: disnake.PermissionOverwrite(read_messages=True, read_message_history=True) + } + + category = disnake.utils.get(guild.categories, name="Логи") + if not category: + category = await guild.create_category("Логи") + + admin_channel = disnake.utils.get(category.text_channels, name="admin-logs") + if not admin_channel: + admin_channel = await category.create_text_channel("admin-logs", overwrites=overwrites) + + @commands.Cog.listener() + async def on_member_join(self, member): + channel = disnake.utils.get(member.guild.text_channels, name="admin-logs") + if channel: + embed = disnake.Embed(description=f"👋 Пользователь {member.mention} присоединился к серверу.", color=0xCD853F) + await channel.send(embed=embed) + + @commands.Cog.listener() + async def on_member_remove(self, member): + channel = disnake.utils.get(member.guild.text_channels, name="admin-logs") + if channel: + embed = disnake.Embed(description=f"😢 Пользователь {member.mention} покинул сервер.", color=0xCD853F) + await channel.send(embed=embed) + + @commands.Cog.listener() + async def on_member_update(self, before, after): + if before.roles != after.roles: + role_changes = [] + for role in before.roles: + if role not in after.roles: + role_changes.append(f"🔴 Убрана роль {role.mention}") + for role in after.roles: + if role not in before.roles: + role_changes.append(f"🟢 Добавлена роль {role.mention}") + if role_changes: + channel = disnake.utils.get(before.guild.text_channels, name="admin-logs") + if channel: + role_changes_str = "\n".join(role_changes) + executor = None + for role in before.roles: + if role not in after.roles: + changes = await after.guild.audit_logs(limit=1, action=disnake.AuditLogAction.member_role_update).flatten() + executor = changes[0].user.mention if changes else "Неизвестно" + break + author = after + embed = disnake.Embed(description=f"👥 Пользователь {author.mention} изменил роли:\n{role_changes_str}\n\n👤 Выполнил: {executor}", color=0xCD853F) + await channel.send(embed=embed) + + if before.display_name != after.display_name: + channel = disnake.utils.get(before.guild.text_channels, name="admin-logs") + if channel: + executor = before.guild.me.mention + author = after + embed = disnake.Embed(description=f"📝 Пользователь {author.mention} изменил никнейм: {before.display_name} -> {after.display_name}\n👤 Выполнил: {executor}", color=0xCD853F) + await channel.send(embed=embed) + + @commands.Cog.listener() + async def on_user_update(self, before, after): + if before.avatar.url != after.avatar.url: + channel = disnake.utils.get(after.mutual_guilds[0].text_channels, name="admin-logs") + if channel: + embed = disnake.Embed(description=f"📷 Пользователь {after.mention} изменил аватарку.", color=0xCD853F) + await channel.send(embed=embed) + + @commands.Cog.listener() + async def on_message_delete(self, message): + if message.guild: + channel = disnake.utils.get(message.guild.text_channels, name="admin-logs") + if channel: + author = message.author + deleted_messages = await message.channel.purge(limit=100, before=message, check=lambda m: m.author == author) + deleted_messages_content = "\n".join([f"{m.content} ({m.created_at})" for m in deleted_messages]) + embed = disnake.Embed(description=f"🗑️ Пользователь {message.author.mention} удалил сообщение:\n{message.content}\n\n📄 Количество удаленных сообщений: {len(deleted_messages)}\n\n📝 Удаленные сообщения:\n{deleted_messages_content}", color=0xCD853F) + await channel.send(embed=embed) + + log_channel = disnake.utils.get(message.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"🗑️ Пользователь {message.author.mention} удалил сообщение:\n{message.content}\n\n📄 Количество удаленных сообщений: {len(deleted_messages)}", color=0xCD853F) + await log_channel.send(embed=embed) + + @commands.Cog.listener() + async def on_voice_state_update(self, member, before, after): + if before.channel != after.channel: + channel = disnake.utils.get(member.guild.text_channels, name="admin-logs") + if channel: + if before.channel: + embed = disnake.Embed(description=f"🔊 Пользователь {member.mention} покинул голосовой канал {before.channel.name}.", color=0xCD853F) + await channel.send(embed=embed) + if after.channel: + embed = disnake.Embed(description=f"🔊 Пользователь {member.mention} присоединился к голосовому каналу {after.channel.name}.", color=0xCD853F) + await channel.send(embed=embed) + + @commands.Cog.listener() + async def on_guild_channel_create(self, channel): + if isinstance(channel, disnake.TextChannel): + log_channel = disnake.utils.get(channel.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"✅ Создан новый текстовый канал: {channel.mention}\n👤 Пользователь {channel.guild.me.mention}", color=0xCD853F) + await log_channel.send(embed=embed) + elif isinstance(channel, disnake.VoiceChannel): + log_channel = disnake.utils.get(channel.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"✅ Создан новый голосовой канал: {channel.mention}\n👤 Пользователь {channel.guild.me.mention}", color=0xCD853F) + await log_channel.send(embed=embed) + + @commands.Cog.listener() + async def on_guild_channel_delete(self, channel): + if isinstance(channel, disnake.TextChannel): + log_channel = disnake.utils.get(channel.guild.text_channels, name="admin-logs") + if log_channel: + executor = channel.guild.me.mention + embed = disnake.Embed(description=f"❌ Удален текстовый канал: {channel.mention}\n👤 Выполнил: {executor}", color=0xCD853F) + await log_channel.send(embed=embed) + elif isinstance(channel, disnake.VoiceChannel): + log_channel = disnake.utils.get(channel.guild.text_channels, name="admin-logs") + if log_channel: + executor = channel.guild.me.mention + embed = disnake.Embed(description=f"❌ Удален голосовой канал: {channel.mention}\n👤 Выполнил: {executor}", color=0xCD853F) + await log_channel.send(embed=embed) + + @commands.Cog.listener() + async def on_guild_channel_update(self, before, after): + if isinstance(before, disnake.TextChannel) and isinstance(after, disnake.TextChannel): + if before.name != after.name: + log_channel = disnake.utils.get(before.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"📝 Пользователь {before.guild.me.mention} изменил название текстового канала: {before.mention} -> {after.mention}", color=0xCD853F) + await log_channel.send(embed=embed) + + elif isinstance(before, disnake.VoiceChannel) and isinstance(after, disnake.VoiceChannel): + if before.name != after.name: + log_channel = disnake.utils.get(before.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"📝 Пользователь {before.guild.me.mention} изменил название голосового канала: {before.mention} -> {after.mention}", color=0xCD853F) + await log_channel.send(embed=embed) + + elif isinstance(before, disnake.TextChannel) and isinstance(after, disnake.VoiceChannel): + log_channel = disnake.utils.get(before.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"❗ Пользователь {before.guild.me.mention} изменил тип канала: Текстовый {before.mention} -> Голосовой {after.mention}", color=0xCD853F) + await log_channel.send(embed=embed) + + elif isinstance(before, disnake.VoiceChannel) and isinstance(after, disnake.TextChannel): + log_channel = disnake.utils.get(before.guild.text_channels, name="admin-logs") + if log_channel: + embed = disnake.Embed(description=f"❗ Пользователь {before.guild.me.mention} изменил тип канала: Голосовой {before.mention} -> Текстовый {after.mention}", color=0xCD853F) + await log_channel.send(embed=embed) + +def setup(bot): + bot.add_cog(Logs(bot)) diff --git a/cogs/mute.py b/cogs/mute.py index db2357b..460839d 100644 --- a/cogs/mute.py +++ b/cogs/mute.py @@ -37,7 +37,7 @@ async def tempmute(self, ctx, member: disnake.Member, duration: int, reason=None self.cursor.execute('INSERT OR REPLACE INTO mutes VALUES (?, ?)', (member.id, unmute_time)) self.conn.commit() - embed = disnake.Embed(title="Мут", color=0x7788ff) + embed = disnake.Embed(title="Мут", color=0xCD853F) embed.add_field(name="Пользователь", value=member.mention, inline=True) embed.add_field(name="Длительность", value=f"{duration} минут", inline=True) embed.add_field(name="Причина", value=reason, inline=True) @@ -59,7 +59,7 @@ async def unmute(self, ctx, member: disnake.Member): await member.remove_roles(mute_role) await self.unmute_member(member) - embed = disnake.Embed(title="Размут", color=0x7788ff) + embed = disnake.Embed(title="Размут", color=0xCD853F) embed.add_field(name="Пользователь", value=member.mention, inline=True) embed.set_footer(text="Был размучен 🎉") embed.set_footer(text="Polina bot © 2023 Все права защищены") @@ -97,7 +97,7 @@ async def unmute_member(self, member: disnake.Member): async def send_mute_dm(self, member, guild_name, reason, duration, admin): try: dm_channel = await member.create_dm() - embed = disnake.Embed(title="Вы получили Mute", color=0x7788ff) + embed = disnake.Embed(title="Вы получили Mute", color=0xCD853F) embed.add_field(name="Сервер", value=guild_name, inline=True) embed.add_field(name="Причина", value=reason, inline=True) unmute_datetime = datetime.datetime.now() + datetime.timedelta(minutes=duration) @@ -112,7 +112,7 @@ async def send_mute_dm(self, member, guild_name, reason, duration, admin): async def send_unmute_dm(self, member): try: dm_channel = await member.create_dm() - embed = disnake.Embed(title="Вы размучены 🎉", color=0x7788ff) + embed = disnake.Embed(title="Вы размучены 🎉", color=0xCD853F) embed.add_field(name="Сервер", value=member.guild.name, inline=True) embed.set_footer(text="Вы размучены 🎉") embed.set_footer(text="Polina bot © 2023 Все права защищены") @@ -136,10 +136,5 @@ async def on_ready(self): self.cursor.execute('DELETE FROM mutes WHERE user_id = ?', (member.id,)) self.conn.commit() - - - - - def setup(bot): - bot.add_cog(mute(bot)) + bot.add_cog(mute(bot)) \ No newline at end of file diff --git a/cogs/mutechat.py b/cogs/mutechat.py new file mode 100644 index 0000000..874d9ed --- /dev/null +++ b/cogs/mutechat.py @@ -0,0 +1,133 @@ +import disnake +import sqlite3 +from disnake.ext import commands +import typing + +class mutechat(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.slash_command(name="mchat", description="Блокировка чата пользователю") + @commands.has_permissions(administrator=True) + async def warn(self, ctx, user: disnake.Member, reason: str): + conn = sqlite3.connect('warn.db') + c = conn.cursor() + c.execute("CREATE TABLE IF NOT EXISTS bad_words (word TEXT)") + c.execute('''CREATE TABLE IF NOT EXISTS warnings (user_id INTEGER PRIMARY KEY, num_warnings INTEGER)''') + + embed = disnake.Embed(title="Пользователь получил блокировку чата!", color=0xCD853F) + embed.add_field(name="Пользователь", value=f"{user.mention}") + embed.add_field(name="Причина", value=f"`{reason}`") + embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=False) + await ctx.response.send_message(embed=embed, ephemeral=True) + + try: + role = await ctx.guild.create_role(name="mute", reason="mute отправки сообщений") + for channel in ctx.guild.channels: + await channel.set_permissions(role, send_messages=False) + await user.add_roles(role) + + dm_channel = await user.create_dm() + embed = disnake.Embed(title="Вы получили блокировку чата", color=0xff0f0f) + embed.add_field(name="Сервер", value=f"{ctx.guild.name}") + embed.add_field(name="Причина", value=f"`{reason}`") + embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=False) + await dm_channel.send(embed=embed) + + c.execute("SELECT * FROM warnings WHERE user_id=?", (user.id,)) + row = c.fetchone() + if row: + num_warnings = row[1] + 1 + c.execute("UPDATE warnings SET num_warnings=? WHERE user_id=?", (num_warnings, user.id)) + else: + c.execute("INSERT INTO warnings VALUES (?, ?)", (user.id, 1)) + + conn.commit() + c.execute("SELECT * FROM warnings WHERE user_id=?", (user.id,)) + row = c.fetchone() + if row and row[1] >= 3: + kick_embed = disnake.Embed(title="Пользователь был исключен за многочисленные нарушения :x:", color=0xCD853F) + kick_embed.add_field(name="Участник", value=f"{user.mention}") + kick_embed.add_field(name="Причина", value=f"Получено `{row[1]}` предупреждений") + await ctx.response.send_message(embed=kick_embed, ephemeral=True) + await dm_channel.send(embed=kick_embed) + await dm_channel.send(f"Вы были исключены с сервера `{ctx.guild.name}` за многочисленные нарушения.") + await user.kick(reason="Получено 3 предупреждения") + except disnake.errors.Forbidden: + await ctx.response.send_message("У меня нет прав, чтобы предупредить этого пользователя", ephemeral=True) + + + @commands.slash_command(name="unmchat", description="Снять блокировку чата у пользователя") + @commands.has_permissions(administrator=True) + async def unwarn(self, ctx, user: disnake.Member): + conn = sqlite3.connect('warn.db') + c = conn.cursor() + + c.execute("SELECT * FROM warnings WHERE user_id=?", (user.id,)) + row = c.fetchone() + if row: + num_warnings = row[1] - 1 + if num_warnings <= 0: + c.execute("DELETE FROM warnings WHERE user_id=?", (user.id,)) + else: + c.execute("UPDATE warnings SET num_warnings=? WHERE user_id=?", (num_warnings, user.id)) + conn.commit() + role = disnake.utils.get(ctx.guild.roles, name="mute") + if role: + await user.remove_roles(role) + + admin_name = ctx.author.name + admin_avatar = ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url + + embed = disnake.Embed(title="Вы были размучены в чате!", color=0xCD853F) + embed.add_field(name="Сервер", value=ctx.guild.name) + embed.add_field(name="Предупреждения", value=f"У вас осталось {num_warnings} предупреждений.") + embed.add_field(name="Размутил", value=f"Администратор: {admin_name}") + embed.set_thumbnail(url=ctx.guild.icon.url) + embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=True) + await user.send(embed=embed) + + await ctx.response.send_message(embed=disnake.Embed(title="Предупреждение снято :white_check_mark:", color=0xCD853F).add_field(name="Пользователь", value=user.mention), ephemeral=True) + else: + await ctx.response.send_message(embed=disnake.Embed(title="У пользователя нет предупреждений :x:", color=0xCD853F).add_field(name="Пользователь", value=user.mention), ephemeral=True) + + + @commands.slash_command(name="mchatinfo", description="Показать список пользователей в муте") + async def warnings(self, ctx, user: typing.Optional[disnake.Member] = None): + conn = sqlite3.connect('warn.db') + c = conn.cursor() + + c.execute('''CREATE TABLE IF NOT EXISTS warnings + (user_id INTEGER PRIMARY KEY, num_warnings INTEGER)''') + c = conn.cursor() + + c.execute("CREATE TABLE IF NOT EXISTS bad_words (word TEXT)") + if user is None: + c.execute("SELECT * FROM warnings") + rows = c.fetchall() + if rows: + embed = disnake.Embed(title="Список мутов на сервере :warning:", color=0xCD853F) + for row in rows: + user = ctx.guild.get_member(row[0]) + if user: + embed.add_field(name=f"Участник: {user.display_name}", value=f"Предупреждений: {row[1]}", inline=False) + embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=True) + else: + embed = disnake.Embed(title="На сервере нет мутов :white_check_mark:", color=0xCD853F) + embed.set_footer(text='Polina bot | ©2023', icon_url=ctx.author.avatar.url) + await ctx.response.send_message(embed=embed, ephemeral=True) + else: + c.execute("SELECT * FROM warnings WHERE user_id=?", (user.id,)) + row = c.fetchone() + if row: + embed = disnake.Embed(title=f"Предупреждения для пользователя {user.display_name}", color=0xCD853F) + embed.add_field(name="Предупреждений", value=row[1]) + embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=True) + else: + embed = disnake.Embed(title=f"У пользователя {user.display_name} нет предупреждений :white_check_mark:", color=0xCD853F) + embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=True) + await ctx.response.send_message(embed=embed, ephemeral=True) + + +def setup(bot: commands.Bot): + bot.add_cog(mutechat(bot)) diff --git a/cogs/tikets.py b/cogs/tikets.py new file mode 100644 index 0000000..4cea11d --- /dev/null +++ b/cogs/tikets.py @@ -0,0 +1,74 @@ +import disnake +from disnake.ext import commands + + +class Tickets(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.slash_command( + name="ticket", + description="Создать тикет для связи с администрацией" + ) + async def ticket(self, inter): + guild = inter.guild + user = inter.author + + embed = disnake.Embed( + title='Техподдержка', + description='Нажмите на кнопку, чтобы создать обращение в техподдержку.', + color=disnake.Color.blurple() + ) + embed.set_footer(text="Техподдержка") + + button = disnake.ui.Button(style=disnake.ButtonStyle.primary, label="Открыть тикет", custom_id="create_ticket", emoji="🎫") + view = disnake.ui.View() + view.add_item(button) + + await inter.response.send_message(embed=embed, view=view, ephemeral=True) + + @commands.Cog.listener() + async def on_button_click(self, inter): + if inter.component.custom_id == "create_ticket": + guild = inter.guild + user = inter.author + + channel_name = f'Техподдержка' + overwrites = { + guild.default_role: disnake.PermissionOverwrite(read_messages=False, send_messages=False), + guild.me: disnake.PermissionOverwrite(read_messages=True, send_messages=True), + user: disnake.PermissionOverwrite(read_messages=True, send_messages=True, manage_channels=True) + } + channel = await guild.create_text_channel(name=channel_name, overwrites=overwrites) + + embed = disnake.Embed( + title='Техподдержка', + description=f'Привет,{user.mention}! \nМодератор поможет вам в ближайшее время. \nА пока опишите вашу проблему как можно подробнее!)', + color=disnake.Color.green() + ) + embed.set_footer(text="Техподдержка") + + close_button = disnake.ui.Button(style=disnake.ButtonStyle.danger, label="Закрыть тикет", custom_id=f"close_ticket:{channel.id}", emoji="🔒") + close_view = disnake.ui.View() + close_view.add_item(close_button) + + message = await channel.send(content=f"{user.mention} создал новое обращение в техподдержку!", embed=embed, view=close_view) + await message.pin() + + await inter.response.send_message(embed=embed, ephemeral=True) + + elif inter.component.custom_id.startswith("close_ticket"): + channel_id = int(inter.component.custom_id.split(":")[1]) + channel = self.bot.get_channel(channel_id) + + if channel: + if inter.author.guild_permissions.administrator: + await channel.delete() + await inter.response.send_message(content="Тикет был закрыт.", ephemeral=True) + else: + await inter.response.send_message(content="У вас нет прав на закрытие тикета.", ephemeral=True) + else: + await inter.response.send_message(content="Канал техподдержки не найден.", ephemeral=True) + +def setup(bot): + bot.add_cog(Tickets(bot)) diff --git a/cogs/user.py b/cogs/user.py index 23cbdd7..fc024dd 100644 --- a/cogs/user.py +++ b/cogs/user.py @@ -22,7 +22,7 @@ async def profile(ctx, member:disnake.Member): roles = member.roles mention_roles = ', '.join([role.mention for role in roles]) top_role = member.top_role.mention - embed = disnake.Embed(title=f'User {member.name}', color=0x7788ff) + embed = disnake.Embed(title=f'User {member.name}', color=0xCD853F) embed.set_thumbnail(url=member.avatar.url) embed.add_field(name='ID', value=member.id, inline=True) embed.add_field(name='Nickname', value=member.nick or member.name, inline=True) @@ -67,7 +67,7 @@ async def agree_command(self, interaction: disnake.ApplicationCommandInteraction 💎Мы надеемся, что наш бот будет полезен вам. Если у вас есть вопросы или предложения по улучшению нашего бота, пожалуйста, свяжитесь с нами.💎 ''' - embed = disnake.Embed(title="Пользовательское соглашение", description=f"```{message}```", color=0x7788ff) + embed = disnake.Embed(title="Пользовательское соглашение", description=f"```{message}```", color=0xCD853F) embed.add_field(name="Polina bot 2023 © Все права защищены",value='',inline=False) await interaction.response.send_message(embed=embed, ephemeral=True) @@ -78,7 +78,7 @@ async def agree_command(self, interaction: disnake.ApplicationCommandInteraction async def calc(self, inter, example: str): example_calc = example.replace("^", "**") example_text = example.replace("**", "^") - await inter.response.send_message(embed=disnake.Embed(title='Калькулятор', description=f"{example_text} = {eval(example_calc)}", color=0x7788ff), ephemeral=True) + await inter.response.send_message(embed=disnake.Embed(title='Калькулятор', description=f"{example_text} = {eval(example_calc)}", color=0xCD853F), ephemeral=True) @@ -89,7 +89,7 @@ async def your_dick(ctx): list(range(-3, 5)) + list(range(5, 10)) * 4 + list(range(10, 15)) * 6 + list(range(15, 20)) * 2 + list(range(20, 30)) ) height = random.choice(result1) - embed = disnake.Embed(description=f"@{ctx.author.display_name}, длина твоего члена - {height} см", color=0x7788ff) + embed = disnake.Embed(description=f"@{ctx.author.display_name}, длина твоего члена - {height} см", color=0xCD853F) await ctx.response.send_message(embed=embed, ephemeral=True) random.seed() @@ -99,7 +99,7 @@ async def avatar(self, ctx, user: typing.Optional[disnake.Member] = None): if not user: user = ctx.author avatar_url = user.avatar.url - embed = disnake.Embed(title=f"Аватар {user.display_name} :frame_photo:", color=0x7788ff) + embed = disnake.Embed(title=f"Аватар {user.display_name} :frame_photo:", color=0xCD853F) embed.set_image(url=avatar_url) await ctx.send(embed=embed, ephemeral=True) @@ -111,7 +111,7 @@ async def server_info(self, ctx): mention_roles = ', '.join([role.mention for role in guild.roles]) top_role = guild.roles[-1].mention - embed = disnake.Embed(title=f"Информация о сервере {guild.name} :desktop:", color=0x7788ff) + embed = disnake.Embed(title=f"Информация о сервере {guild.name} :desktop:", color=0xCD853F) embed.set_thumbnail(url=guild.icon.url) embed.add_field(name="ID :id:", value=guild.id, inline=True) embed.add_field(name="Создан :date:", value=guild.created_at.strftime("%d.%m.%Y %H:%M:%S"), inline=True) @@ -134,7 +134,7 @@ async def shorten_url(ctx: disnake.ApplicationCommandInteraction, url: str): response = requests.get(f"https://tinyurl.com/api-create.php?url={url}") embed = disnake.Embed(title="Сокращенный URL-адрес", description=f"Ваш сокращенный URL-адрес: {response.text}", - color=0x7788ff) + color=0xCD853F) embed.set_footer(text='Polina bot | ©2023', icon_url=ctx.author.avatar.url) await ctx.response.send_message(embed=embed, ephemeral=True) @@ -148,7 +148,7 @@ async def botinfo(ctx): uptime = datetime.utcnow() - bot.user.created_at.replace(tzinfo=None) uptime_str = f"{uptime.days} дней {uptime.seconds // 3600} часа {(uptime.seconds // 60) % 60} минуты {uptime.seconds % 60} секунды" - embed = disnake.Embed(title="Pong! :ping_pong:", color=0x7788ff) + embed = disnake.Embed(title="Pong! :ping_pong:", color=0xCD853F) embed.add_field(name="Работаю 🕒", value=uptime_str + "\n", inline=False) embed.add_field(name="Задержка 🚀", value=f"{round(bot.latency * 1000)} мс\n", inline=False) embed.add_field(name="Задержка хостинга 🌐", value=f"{round(bot.ws.latency * 1000)} мс\n", inline=False) @@ -162,7 +162,7 @@ async def generate_nitro_link(self, ctx): alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" link = ''.join(random.choices(alphabet, k=16)) - embed = disnake.Embed(title="Discord Nitro", description=f"https://discord.gift/{link}", color=0x7788ff) + embed = disnake.Embed(title="Discord Nitro", description=f"https://discord.gift/{link}", color=0xCD853F) await ctx.send(embed=embed, ephemeral=True) diff --git a/cogs/weather.py b/cogs/weather.py new file mode 100644 index 0000000..9c4e23f --- /dev/null +++ b/cogs/weather.py @@ -0,0 +1,48 @@ +import disnake +from disnake.ext import commands +import requests +from disnake import utils + +class WeatherCog(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.api_key = "ba58dcebaa8a509e3c93aeddc50c3285" + self.base_url = "http://api.openweathermap.org/data/2.5/weather?" + + @commands.slash_command( + name="weather", + description="Получить информацию о погоде в заданном городе.", + ) + async def weather(self, inter, город: str): + city_name = город + complete_url = f"{self.base_url}appid={self.api_key}&q={city_name}" + + response = requests.get(complete_url) + x = response.json() + + if x["cod"] != "404": + y = x["main"] + current_temperature = y["temp"] + current_temperature_celsius = str(round(current_temperature - 273.15)) + current_pressure = y["pressure"] + current_humidity = y["humidity"] + + z = x["weather"] + + embed = disnake.Embed( + title=f"Погода в городе {city_name}", + color=0xCD853F, + timestamp=utils.utcnow(), + ) + embed.add_field(name="Температура(C)", value=f"**{current_temperature_celsius}°C**", inline=False) + embed.add_field(name="Влажность(%)", value=f"**{current_humidity}%**", inline=False) + embed.add_field(name="Атмосферное давление(гПа)", value=f"**{current_pressure}гПа**", inline=False) + embed.set_thumbnail(url="https://i.ibb.co/CMrsxdX/weather.png") + embed.set_footer(text=f"Запрошено пользователем {inter.author.display_name}") + await inter.response.send_message(embed=embed, ephemeral=True) + else: + await inter.response.send_message("Город не найден.") + + +def setup(bot): + bot.add_cog(WeatherCog(bot)) \ No newline at end of file diff --git a/req.txt b/req.txt index 1c3b153..fc29ec5 100644 --- a/req.txt +++ b/req.txt @@ -2,6 +2,7 @@ python-decouple disnake sqlite3 typing +requests DateTime asyncio aiohttp