diff --git a/cryptexctl/modules-mirror/.gitignore b/cryptexctl/modules-mirror/.gitignore
new file mode 100644
index 0000000..0dbf2f2
--- /dev/null
+++ b/cryptexctl/modules-mirror/.gitignore
@@ -0,0 +1,170 @@
+# ---> Python
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# UV
+# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+#uv.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
diff --git a/cryptexctl/modules-mirror/README.md b/cryptexctl/modules-mirror/README.md
new file mode 100644
index 0000000..82e4c2d
--- /dev/null
+++ b/cryptexctl/modules-mirror/README.md
@@ -0,0 +1,2 @@
+# modules
+
diff --git a/cryptexctl/modules-mirror/SomethingCreatingScriptErrors.py b/cryptexctl/modules-mirror/SomethingCreatingScriptErrors.py
new file mode 100644
index 0000000..91f0a17
--- /dev/null
+++ b/cryptexctl/modules-mirror/SomethingCreatingScriptErrors.py
@@ -0,0 +1,53 @@
+__version__ = (0, 0, 2)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# something.py
+# meta developer: @systemxplore
+# scope: hikka_only
+from telethon.tl.functions.messages import SendMediaRequest
+from telethon.tl.types import InputMediaPhotoExternal
+from .. import loader, utils
+
+
+@loader.tds
+class ScriptErrorMod(loader.Module):
+ strings = {"name": "ScriptErrorSender"}
+
+ async def client_ready(self, client, db):
+ self.client = client
+
+ @loader.command()
+ async def скриптовыеошибки(self, message):
+ image_url = "https://0x0.st/s/57tTFWzUT0tc4HmuG75z_Q/XnMz.jpg"
+ caption = "⚠️Что-то создает скриптовые ошибки"
+
+ reply_to = await message.get_reply_message()
+
+ try:
+ await self.client(
+ SendMediaRequest(
+ peer=message.chat_id,
+ media=InputMediaPhotoExternal(url=image_url),
+ message=caption,
+ reply_to_msg_id=reply_to.id if reply_to else None
+ )
+ )
+ except Exception as e:
+ await utils.answer(message, f"⚠️Что-то создает скриптовые ошибки")
+
+ # Удаляем команду после выполнения
+ await message.delete()
diff --git a/cryptexctl/modules-mirror/actually.py b/cryptexctl/modules-mirror/actually.py
new file mode 100644
index 0000000..5fc8f71
--- /dev/null
+++ b/cryptexctl/modules-mirror/actually.py
@@ -0,0 +1,44 @@
+__version__ = (2, 0, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# actually.py
+# meta developer: @systemxplore
+# scope: hikka_only
+# scope: hikka_min 1.6.3
+from .. import loader, utils
+
+class ActuallyMod(loader.Module):
+ """ehm, actually🤓️."""
+ strings = {
+ "name": "Actually",
+ "example_usage": "Используйте: .actually ur text"
+ }
+
+ @loader.command()
+ async def actually(self, message):
+ """ehm, actually'"""
+ args = utils.get_args_raw(message)
+ if not args:
+ await utils.answer(message, self.strings["example_usage"])
+ return
+
+ # Формируем ответ
+ formatted_text = f"ehm,actually {args} {'🤓' * 10}"
+
+ # Отправляем текст и удаляем команду
+ await message.respond(formatted_text)
+ await message.delete()
diff --git a/cryptexctl/modules-mirror/avaclone.py b/cryptexctl/modules-mirror/avaclone.py
new file mode 100644
index 0000000..1a7a751
--- /dev/null
+++ b/cryptexctl/modules-mirror/avaclone.py
@@ -0,0 +1,101 @@
+__version__ = (1, 1, 2)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# avaclone.py
+# meta developer: @systemxplore
+# scope: hikka_only
+# scope: hikka_min 1.6.3
+
+import asyncio
+from telethon.tl.functions.photos import UploadProfilePhotoRequest
+from telethon.errors.rpcerrorlist import PhotoCropSizeSmallError, FilePartsInvalidError
+from telethon.tl.types import InputFile
+from .. import loader, utils
+
+class AvaCloneMod(loader.Module):
+ """Устанавливает фото/видео/гиф аватарку многократно.\nОсторожно: возможен бан или флудвейт."""
+ strings = {"name": "AvaClone"}
+
+ @loader.command()
+ async def avaclone(self, message):
+ """
+ Устанавливает аватарку указанное количество раз.
+ Используйте: .avaclone <количество> [ответ на файл/ссылка]
+ """
+ args = utils.get_args(message)
+ if len(args) < 1:
+ await utils.answer(message, "Укажите количество раз и прикрепите файл.")
+ return
+
+ try:
+ count = int(args[0])
+ if count <= 0:
+ raise ValueError
+ except ValueError:
+ await utils.answer(message, "Некорректное количество раз.")
+ return
+
+ reply = await message.get_reply_message()
+ media = None
+
+ if reply and reply.media:
+ media = await self.client.download_media(reply.media)
+ elif len(args) > 1:
+ media = args[1]
+ else:
+ await utils.answer(message, "Ответьте на файл или укажите ссылку на файл.")
+ return
+
+ extension = media.split(".")[-1].lower()
+ if extension not in ["jpg", "jpeg", "png", "gif", "mp4"]:
+ await utils.answer(message, "❌ Формат не поддерживается. Используйте JPG, PNG, GIF или MP4.")
+ return
+
+ success_count = 0
+ for i in range(count):
+ try:
+ uploaded_file = await self.client.upload_file(media)
+ if extension in ["gif", "mp4"]:
+ await self.client(UploadProfilePhotoRequest(
+ file=InputFile(
+ id=uploaded_file.id,
+ parts=uploaded_file.parts,
+ name=media,
+ md5_checksum=uploaded_file.md5_checksum
+ )
+ ))
+ else:
+ await self.client(UploadProfilePhotoRequest(file=uploaded_file))
+ success_count += 1
+ await asyncio.sleep(2)
+ except PhotoCropSizeSmallError:
+ await utils.answer(message, "❌ Файл слишком маленький.")
+ break
+ except FilePartsInvalidError:
+ await utils.answer(message, "❌ Неверный файл.")
+ break
+ except Exception as e:
+ await utils.answer(message, f"Ошибка: {e}")
+ break
+
+ if success_count > 0:
+ await utils.answer(
+ message,
+ f"✅ Установлено {success_count} раз(а). Возможен флудвейт, подождите 3 минуты перед следующим использованием."
+ )
+ else:
+ await utils.answer(message, "❌ Не удалось установить аватарку.")
\ No newline at end of file
diff --git a/cryptexctl/modules-mirror/full.txt b/cryptexctl/modules-mirror/full.txt
new file mode 100644
index 0000000..71df64a
--- /dev/null
+++ b/cryptexctl/modules-mirror/full.txt
@@ -0,0 +1,11 @@
+actually
+avaclone
+premium_emoji_id
+randomtrack
+zovmodule
+овощерезка
+сланцы2
+notesmod
+SomethingCreatingScriptErrors
+forgotboard
+komarumod
\ No newline at end of file
diff --git a/cryptexctl/modules-mirror/komarumod.py b/cryptexctl/modules-mirror/komarumod.py
new file mode 100644
index 0000000..08db613
--- /dev/null
+++ b/cryptexctl/modules-mirror/komarumod.py
@@ -0,0 +1,33 @@
+__version__ = (2, 0, 0)
+# meta developer: @wmodules
+
+from .. import loader, utils
+import random
+from telethon.tl.types import InputMessagesFilterGif
+
+class KomaruMod(loader.Module):
+ """Достает рандомную гифку из @komarugif\n канал заменил @systemxplore, оригинальный разработчик: @wmodules"""
+
+ strings = {"name": "KomaruMod v2"}
+
+ async def client_ready(self, client, db):
+ self.client = client
+
+ async def komarugifcmd(self, message):
+ """Рандомная гифка"""
+ channel = "@komarugif"
+ gifs = [msg async for msg in self.client.iter_messages(channel, filter=InputMessagesFilterGif)]
+ if not gifs:
+ await message.edit("Нет доступных GIF-ов в канале!")
+ return
+
+ random_gif = random.choice(gifs)
+ reply_to = message.reply_to_msg_id
+
+ await self.client.send_file(
+ message.chat_id,
+ random_gif,
+ reply_to=reply_to
+ )
+
+ await message.delete()
diff --git a/cryptexctl/modules-mirror/notesmod.py b/cryptexctl/modules-mirror/notesmod.py
new file mode 100644
index 0000000..c77a981
--- /dev/null
+++ b/cryptexctl/modules-mirror/notesmod.py
@@ -0,0 +1,109 @@
+__version__ = (1, 0, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# notesmod.py
+# meta developer: @systemxplore
+# scope: hikka_only
+import os
+from .. import loader, utils
+
+
+@loader.tds
+class NotesFileMod(loader.Module):
+ """Модуль для заметок с хранением в файлах"""
+ strings = {"name": "NotesFile"}
+
+ def __init__(self):
+ self.notes_dir = "notes"
+
+ async def client_ready(self, client, db):
+ self.client = client
+
+ if not os.path.exists(self.notes_dir):
+ os.makedirs(self.notes_dir)
+
+ @loader.command()
+ async def noteadd(self, message):
+ """
+ Добавить заметку.
+ Использование: .noteadd #tag <текст>
+ """
+ args = utils.get_args_raw(message)
+ if not args.startswith("#"):
+ await utils.answer(message, "❌ Укажите тег заметки, начиная с `#`.")
+ return
+
+ try:
+ tag, text = args.split(" ", 1)
+ except ValueError:
+ await utils.answer(message, "❌ Укажите текст заметки после тега.")
+ return
+
+ note_file = os.path.join(self.notes_dir, f"{tag[1:]}.txt")
+ with open(note_file, "w", encoding="utf-8") as f:
+ f.write(text)
+
+ await utils.answer(message, f"✅ Заметка `{tag}` сохранена.")
+
+ @loader.command()
+ async def notedelete(self, message):
+ """
+ Удалить заметку.
+ Использование: .notedelete #tag
+ """
+ tag = utils.get_args_raw(message)
+ if not tag.startswith("#"):
+ await utils.answer(message, "❌ Укажите тег заметки, начиная с `#`.")
+ return
+
+ note_file = os.path.join(self.notes_dir, f"{tag[1:]}.txt")
+ if os.path.exists(note_file):
+ os.remove(note_file)
+ await utils.answer(message, f"✅ Заметка `{tag}` удалена.")
+ else:
+ await utils.answer(message, f"❌ Заметка `{tag}` не найдена.")
+
+ @loader.command()
+ async def noteview(self, message):
+ """
+ Просмотреть заметку.
+ Использование: .noteview #tag
+ """
+ tag = utils.get_args_raw(message)
+ if not tag.startswith("#"):
+ await utils.answer(message, "❌ Укажите тег заметки, начиная с `#`.")
+ return
+
+ note_file = os.path.join(self.notes_dir, f"{tag[1:]}.txt")
+ if os.path.exists(note_file):
+ with open(note_file, "r", encoding="utf-8") as f:
+ text = f.read()
+ await utils.answer(message, f"📝 Заметка `{tag}`:\n\n{text}")
+ else:
+ await utils.answer(message, f"❌ Заметка `{tag}` не найдена.")
+
+ @loader.command()
+ async def notelist(self, message):
+ """
+ Показать список всех заметок.
+ """
+ files = os.listdir(self.notes_dir)
+ if not files:
+ await utils.answer(message, "📋 Нет сохранённых заметок.")
+ else:
+ notes_list = "\n".join(f"• `#{os.path.splitext(file)[0]}`" for file in files)
+ await utils.answer(message, f"📋 Список заметок:\n\n{notes_list}")
diff --git a/cryptexctl/modules-mirror/premium_emoji_id.py b/cryptexctl/modules-mirror/premium_emoji_id.py
new file mode 100644
index 0000000..4910b39
--- /dev/null
+++ b/cryptexctl/modules-mirror/premium_emoji_id.py
@@ -0,0 +1,58 @@
+__version__ = (1, 0, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# premium_emoji_id.py
+# meta developer: @systemxplore
+# scope: hikka_only
+
+from telethon.tl.types import MessageEntityCustomEmoji
+from .. import loader, utils
+
+class GetPremiumEmojiID(loader.Module):
+ """Получение ID премиум-эмодзи"""
+ strings = {"name": "PremiumEmojiID"}
+
+ @loader.command()
+ async def getemoji_id(self, message):
+ """
+ Получает ID премиум-эмодзи из сообщения
+ Использование: .getemoji_id <эмодзи>
+ """
+ args = utils.get_args_raw(message)
+ if not args:
+ await utils.answer(
+ message, "❌ Пожалуйста, добавьте премиум-эмодзи после команды."
+ )
+ return
+
+ entities = message.entities
+ if not entities:
+ await utils.answer(message, "❌ Эмодзи не найдено.")
+ return
+
+ for entity in entities:
+ if isinstance(entity, MessageEntityCustomEmoji):
+ emoji_id = entity.document_id
+ await utils.answer(
+ message,
+ f"✅ Найден премиум-эмодзи:\n\n"
+ f"💎 ID: `{emoji_id}`\n\n"
+ f"Теперь вы можете использовать его в своих модулях!",
+ )
+ return
+
+ await utils.answer(message, "❌ Это не премиум-эмодзи.")
diff --git a/cryptexctl/modules-mirror/randomtrack.py b/cryptexctl/modules-mirror/randomtrack.py
new file mode 100644
index 0000000..748ce12
--- /dev/null
+++ b/cryptexctl/modules-mirror/randomtrack.py
@@ -0,0 +1,75 @@
+__version__ = (1, 1, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# randomtrack.py
+# meta developer: @systemxplore
+# scope: hikka_only
+# scope: hikka_min 1.6.3
+
+import random
+from telethon.tl.functions.messages import GetHistoryRequest
+from telethon.tl.types import Message, MessageMediaDocument
+from .. import loader, utils
+
+class RandomTrackMod(loader.Module):
+ """Отправляет случайный трек из указанного канала."""
+ strings = {"name": "RandomTrack"}
+
+ def __init__(self):
+ self.config = loader.ModuleConfig(
+ "MUSIC_CHANNEL_ID", 0, # ID канала с музыкой
+ lambda: "ID вашего канала с музыкой. Например: 123456789"
+ )
+
+ async def get_random_track(self, channel_id):
+ """Получает случайный трек из указанного канала по ID."""
+ try:
+ history = await self.client(GetHistoryRequest(
+ peer=channel_id,
+ limit=100, # Загружает последние 100 сообщений
+ offset_date=None,
+ offset_id=0,
+ add_offset=0,
+ max_id=0,
+ min_id=0,
+ hash=0,
+ ))
+
+ tracks = [
+ msg for msg in history.messages
+ if isinstance(msg, Message) and isinstance(msg.media, MessageMediaDocument)
+ and msg.media.document.mime_type.startswith("audio")
+ ]
+ return random.choice(tracks) if tracks else None
+ except Exception as e:
+ return f"Ошибка при получении трека: {e}"
+
+ @loader.command()
+ async def randomtrack(self, message):
+ """
+ Отправляет случайный трек из вашего канала.
+ """
+ channel_id = self.config["MUSIC_CHANNEL_ID"]
+ if not channel_id:
+ await utils.answer(message, "❌ Укажите ID канала с музыкой в .config")
+ return
+
+ track = await self.get_random_track(channel_id)
+ if isinstance(track, Message):
+ await self.client.send_file(message.chat_id, track.media, caption=track.message or "")
+ else:
+ await utils.answer(message, f"❌ Не удалось получить трек. Причина: {track}")
\ No newline at end of file
diff --git a/cryptexctl/modules-mirror/zovmodule.py b/cryptexctl/modules-mirror/zovmodule.py
new file mode 100644
index 0000000..1211baa
--- /dev/null
+++ b/cryptexctl/modules-mirror/zovmodule.py
@@ -0,0 +1,95 @@
+__version__ = (2, 1, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# leeter.py
+# meta developer: @systemxplore
+# scope: hikka_only
+# scope: hikka_min 1.6.3
+from .. import loader, utils
+
+class LeeterMod(loader.Module):
+ """Тут либо гойда либо зов\nлибо ZOVишь либо leetируешь"""
+ strings = {
+ "name": "zover",
+ "enabled": "✅ Leeter включен.",
+ "disabled": "❌ Leeter выключен.",
+ "mode_leet": "⚙️ Режим установлен: Leet",
+ "mode_replace": "⚙️ Режим установлен: ZOV"
+ } # Исправлено: убрана лишняя закрывающая скобка
+
+ def __init__(self):
+ self.config = loader.ModuleConfig(
+ "MODE", "leet", # Возможные значения: "leet" или "replace"
+ lambda: "Режим обработки сообщений: 'leet' для leet-стиля или 'replace' для zov."
+ )
+ self.active = False
+
+ async def client_ready(self, client, db):
+ self.client = client
+
+ @loader.command()
+ async def leeter(self, message):
+ """Включить/выключить обработку сообщений."""
+ self.active = not self.active
+ status = self.strings["enabled"] if self.active else self.strings["disabled"]
+ await utils.answer(message, status)
+
+ @loader.command()
+ async def zovmode(self, message):
+ """Переключить режим: leet или zov."""
+ new_mode = "leet" if self.config["MODE"] == "replace" else "replace"
+ self.config["MODE"] = new_mode
+ mode_message = self.strings["mode_leet"] if new_mode == "leet" else self.strings["mode_replace"]
+ await utils.answer(message, mode_message)
+
+ async def watcher(self, message):
+ """Обрабатывает все ваши сообщения."""
+ if not self.active or not message.out:
+ return
+
+ text = message.raw_text
+ if self.config["MODE"] == "leet":
+ # Преобразование в leet-стиль
+ text = self.to_leet(text)
+ elif self.config["MODE"] == "replace":
+ # Замена z-Z, v-V, o-O
+ text = self.replace_chars(text)
+
+ # Редактируем сообщение с преобразованным текстом
+ await message.edit(text)
+
+ def to_leet(self, text):
+ """Преобразует текст в leet-стиль."""
+ leet_map = {
+ 'а': '4', 'б': '6', 'в': '8', 'г': 'r', 'д': 'D', 'е': '3', 'ё': 'E',
+ 'ж': '>|<', 'з': '3', 'и': 'u', 'й': 'u`', 'к': 'K', 'л': 'JI',
+ 'м': 'M', 'н': 'H', 'о': '0', 'п': 'n', 'р': 'P', 'с': 'C',
+ 'т': '7', 'у': 'Y', 'ф': 'F', 'х': 'X', 'ц': 'U,', 'ч': '4',
+ 'ш': 'W', 'щ': 'W,', 'ъ': "'", 'ы': 'bl', 'ь': "'", 'э': '3',
+ 'ю': '10', 'я': '9',
+ 'a': '4', 'b': '8', 'c': '<', 'd': '[)', 'e': '3', 'f': '|=',
+ 'g': '6', 'h': '#', 'i': '1', 'j': '_|', 'k': '|<', 'l': '1',
+ 'm': '^^', 'n': '^/', 'o': '0', 'p': '|2', 'q': 'O_', 'r': '12',
+ 's': '5', 't': '7', 'u': '|_|', 'v': '\\/', 'w': '\\/\\/', 'x': '%',
+ 'y': '`/', 'z': '2'
+ }
+ return ''.join(leet_map.get(char.lower(), char) for char in text)
+
+ def replace_chars(self, text):
+ """Заменяет z-Z, v-V, o-O в тексте."""
+ replace_map = {'з': 'Z', 'З': 'Z', 'в': 'V', 'В': 'V', 'о': 'O', 'О': 'O'}
+ return ''.join(replace_map.get(char, char) for char in text)
diff --git a/cryptexctl/modules-mirror/овощерезка.py b/cryptexctl/modules-mirror/овощерезка.py
new file mode 100644
index 0000000..c7888e5
--- /dev/null
+++ b/cryptexctl/modules-mirror/овощерезка.py
@@ -0,0 +1,70 @@
+__version__ = (1, 4, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# овощерезка.py
+# meta developer: @systemxplore
+# scope: hikka_only
+# scope: hikka_min 1.6.3
+
+import random
+from telethon.tl.functions.messages import GetHistoryRequest
+from telethon.tl.types import Message, MessageMediaPhoto
+from .. import loader, utils
+
+class RandomPostMod(loader.Module):
+ """Отправляет случайный пост из p2 или pixelgang с картинками."""
+ strings = {"name": "Овощерезка"}
+
+ def __init__(self):
+ self.config = loader.ModuleConfig(
+ "POSTS_LIMIT", 50, # Количество постов для загрузки
+ lambda: "Количество постов для загрузки из каналов."
+ )
+
+ async def get_random_post(self, channel):
+ """Вгетаем фоточке из канала"""
+ try:
+ history = await self.client(GetHistoryRequest(
+ peer=channel,
+ limit=self.config["POSTS_LIMIT"], # Количество постов из .config
+ offset_date=None,
+ offset_id=0,
+ add_offset=0,
+ max_id=0,
+ min_id=0,
+ hash=0,
+ ))
+ messages = [
+ msg for msg in history.messages
+ if isinstance(msg, Message) and isinstance(msg.media, MessageMediaPhoto)
+ ]
+ return random.choice(messages) if messages else None
+ except Exception as e:
+ return f"Ошибка при получении поста: {e}"
+
+ @loader.command()
+ async def овощерезка(self, message):
+ """
+ Отправляет случайный мемасек из p2 или pixelgang
+ """
+ channel = random.choice(["pocobytes", "pixelgang"]) # Случайный выбор канала
+ post = await self.get_random_post(channel)
+
+ if isinstance(post, Message):
+ await self.client.send_file(message.chat_id, post.media, caption=post.message or "")
+ else:
+ await utils.answer(message, f"❌ Не удалось получить пост. Причина: {post}")
\ No newline at end of file
diff --git a/cryptexctl/modules-mirror/сланцы2.py b/cryptexctl/modules-mirror/сланцы2.py
new file mode 100644
index 0000000..36444fb
--- /dev/null
+++ b/cryptexctl/modules-mirror/сланцы2.py
@@ -0,0 +1,56 @@
+__version__ = (1, 1, 0)
+#
+# 88
+# ,d ,d 88
+# 88 88 88
+# ,adPPYba, 8b,dPPYba, 8b d8 8b,dPPYba, MM88MMM ,adPPYba, 8b, ,d8 ,adPPYba, MM88MMM 88
+# a8" "" 88P' "Y8 `8b d8' 88P' "8a 88 a8P_____88 `Y8, ,8P' a8" "" 88 88
+# 8b 88 `8b d8' 88 d8 88 8PP""""""" )888( 8b 88 88
+# "8a, ,aa 88 `8b,d8' 88b, ,a8" 88, "8b, ,aa ,d8" "8b, "8a, ,aa 88, 88
+# `"Ybbd8"' 88 Y88' 88`YbbdP"' "Y888 `"Ybbd8"' 8P' `Y8 `"Ybbd8"' "Y888 88
+# d8' 88
+# d8' 88
+# © Copyright 2024
+# https://t.me/cryptexctl
+#
+# 🔒 Licensed under the GNU AGPLv3
+# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
+# сланцы.py
+# meta developer: @systemxplore
+# scope: hikka_only
+# scope: hikka_min 1.6.3
+import os
+import requests
+from .. import loader, utils
+
+class SlantsyMod(loader.Module):
+ """АХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\n"""
+ strings = {
+ "name": "Сланцы",
+ }
+
+ def __init__(self):
+ # Путь, куда будет загружена картинка
+ self.image_path = "сланцы.jpeg"
+ self.image_url = "https://0x0.st/Xd9E.jpeg"
+
+ async def client_ready(self, client, db):
+ self.client = client
+ self.download_image()
+
+ def download_image(self):
+ """Скачивает изображение и сохраняет его на диск."""
+ if not os.path.exists(self.image_path): # Проверяем, есть ли файл
+ response = requests.get(self.image_url)
+ with open(self.image_path, 'wb') as file:
+ file.write(response.content)
+ print(f"✅ Картинка успешно загружена: {self.image_path}")
+ else:
+ print(f"🖼️ Картинка уже существует: {self.image_path}")
+
+ @loader.command()
+ async def этосланцычат(self, message):
+ """АХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\nАХХХ ЭТО ГОРЯЩИЕ СЛАНЦЫ ЧААТ\n"""
+ await self.client.send_file(message.chat_id, self.image_path)
+ # Удаляем сообщение с командой
+ await message.delete()
diff --git a/fiksofficial/python-modules/channeladapter.py b/fiksofficial/python-modules/channeladapter.py
index 3234a37..59300aa 100644
--- a/fiksofficial/python-modules/channeladapter.py
+++ b/fiksofficial/python-modules/channeladapter.py
@@ -2,8 +2,6 @@
# https://github.com/all-licenses/GNU-General-Public-License-v3.0
# meta developer: @PyModule
-import json
-import os
from telethon.tl.types import Message
from .. import loader
@@ -12,27 +10,19 @@ class ChannelAdapterMod(loader.Module):
"""Модуль для добавления переходника в сообщения каналов"""
strings = {"name": "ChannelAdapter"}
- def __init__(self):
- self.adapters_file = "adapters.json"
- self.adapters = self.load_adapters()
-
- def load_adapters(self):
- """Загружает адаптеры из файла, если он существует."""
- if os.path.exists(self.adapters_file):
- with open(self.adapters_file, "r", encoding="utf-8") as f:
- return json.load(f)
- return {}
-
- def save_adapters(self):
- """Сохраняет адаптеры в файл."""
- with open(self.adapters_file, "w", encoding="utf-8") as f:
- json.dump(self.adapters, f, ensure_ascii=False, indent=4)
-
async def client_ready(self, client, db):
self.client = client
self.db = db
- if not self.adapters:
- self.adapters = {}
+ if not self.db.get(__name__, "adapters"):
+ self.db.set(__name__, "adapters", {})
+
+ def get_adapters(self):
+ """Получает адаптеры из базы данных"""
+ return self.db.get(__name__, "adapters", {})
+
+ def save_adapters(self, adapters):
+ """Сохраняет адаптеры в базу данных"""
+ self.db.set(__name__, "adapters", adapters)
@loader.command()
async def addadaptercmd(self, message: Message):
@@ -49,11 +39,13 @@ class ChannelAdapterMod(loader.Module):
await message.edit("{chat_id} - {adapter_text}")
+ @loader.command()
async def deladaptercmd(self, message: Message):
"""[CHANNEL ID] - Удалить переходник для канала."""
args = message.raw_text.split()
@@ -62,37 +54,40 @@ class ChannelAdapterMod(loader.Module):
return
chat_id = args[1]
+ adapters = self.get_adapters()
- if chat_id not in self.adapters:
+ if chat_id not in adapters:
await message.edit("{chat_id} удалён.")
+ @loader.command()
async def listadapterscmd(self, message: Message):
"""- Показать список всех переходников."""
- if not self.adapters:
+ adapters = self.get_adapters()
+ if not adapters:
await message.edit("
\n\n\n" - for chat_id, adapter_text in self.adapters.items(): + for chat_id, adapter_text in adapters.items(): text += f"👁 Список сохранённых переходников
{chat_id}: {adapter_text}\n\n"
await message.edit(text)
+ @loader.command()
async def clearadapterscmd(self, message: Message):
"""- Удалить все переходники."""
- if not self.adapters:
+ adapters = self.get_adapters()
+ if not adapters:
await message.edit("Моноширинный текст {status} ʕ·ᴥ·ʔ", parse_mode="HTML")
+
+ @loader.command()
+ async def underline(self, message):
+ """Включает или отключает подчеркивание."""
+ self.styles["underline"] = not self.styles["underline"]
+ status = "включен" if self.styles["underline"] else "выключен"
+ await utils.answer(message, f"🪐 Подчеркивание {status} ʕ·ᴥ·ʔ", parse_mode="HTML")
+
+ @loader.command()
+ async def strikethrough(self, message):
+ """Включает или отключает зачеркивание."""
+ self.styles["strikethrough"] = not self.styles["strikethrough"]
+ status = "включен" if self.styles["strikethrough"] else "выключен"
+ await utils.answer(message, f"🪐 {hours}ч")
+
+ response += f"{args}\n\n" + "\n".join(gametypes_str) + "\n\n" + + # мапы + maps = data.get("most_played_maps", []) + if maps: + maps_str = [] + for m in maps: + hours = round(m.get("seconds_played", 0) / 3600) + maps_str.append(f"{m.get('map_name', '?')} -
{hours}ч")
+
+ response += "" + "\n".join(maps_str) + "\n\n" + + # категории + categories = data.get("most_played_categories", []) + if categories: + categories_str = [] + for cat in categories: + hours = round(cat.get("seconds_played", 0) / 3600) + categories_str.append(f"{cat.get('key', '?')} -
{hours}ч")
+
+ response += "" + "\n".join(categories_str) + "\n\n" + + # время + general = data.get("general_activity", {}) + if general: + total_hours = round(general.get("total_seconds_played", 0) / 3600) + avg_hours = round(general.get("average_seconds_played", 0) / 3600) + start_date = general.get("start_of_playtime", "?") + response += "
" + response += f"Общее время игры -" + + await utils.answer(message, response) + + except Exception as e: + await utils.answer(message, f"{self.strings['api_error_or_player_not_found']}: {str(e)}") + +# ебеший-ленеивый говнокод diff --git a/mead0wsss/mead0wsMods/DDNetStats.py b/mead0wsss/mead0wsMods/DDNetStats.py new file mode 100644 index 0000000..2f5fcbf --- /dev/null +++ b/mead0wsss/mead0wsMods/DDNetStats.py @@ -0,0 +1,264 @@ +# -- version -- +__version__ = (1, 0, 0) +# -- version -- + + +# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗ +# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝ +# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░ +# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗ +# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝ +# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░ +# © Copyright 2025 (!!! НА ВСЕ МОДУЛИ ДЕЙСТВУЕТ ЛИЦЕНЗИЯ !!!) +# ✈ https://t.me/mead0wssMods + + +# meta developer: @mead0wssMods +# scope: heroku_only + +import aiohttp +from .. import loader, utils + +# флаги +COUNTRY_FLAGS = { + 4: "{total_hours}ч\n" + response += f"Дата начала игры -{start_date}\n" + response += f"Среднее время игры -{avg_hours}ч" + response += "
{name}\n\n"
+ f"Поинты:\n" + ) + + # прогресс по категориям + completion = data.get("completion_progress", []) + if completion: + completion_str = [] + for cat in completion: + category = cat.get("category", "Неизвестно") + finished = cat.get("maps_finished", 0) + total = cat.get("maps_total", 0) + completion_str.append(f"{category} -{points}\n" + f"Клан:{clan}\n" + f"Флаг: {flag}\n" + f"Скин:{skin}\n" + f"Дата информации:{last_seen}\n" + "
{finished}/{total}")
+
+ response += (
+ "" + + "\n".join(completion_str) + + "\n\n" + ) + + # ласт активность + recent = data.get("recent_activity", []) + if recent: + recent_str = [] + for act in recent: + date = act.get("date", "—") + map_name = act.get("map_name", "—") + hours = round(act.get("seconds_played", 0) / 60) + recent_str.append(f"{date} - {map_name} (
{hours}мин.)")
+
+ response += (
+ "" + + "\n".join(recent_str) + + "\n\n" + ) + + # напарники + teammates = data.get("favourite_teammates", []) + if teammates: + teammates_str = [] + for mate in teammates: + mate_name = mate.get("name", "—") + team_rank = mate.get("ranks_together", "—") + teammates_str.append(f"{mate_name} -
{team_rank} (ранг)")
+
+ response += (
+ "" + + "\n".join(teammates_str) + + "\n\n" + ) + + # карты + maps = data.get("most_played_maps", []) + if maps: + maps_str = [] + for m in maps: + map_name = m.get("map_name", "-") + hours = round(m.get("seconds_played", 0) / 3600) + maps_str.append(f"{map_name} -
{hours}ч")
+
+ response += (
+ "" + + "\n".join(maps_str) + + "\n\n" + ) + + # режимы + gametypes = data.get("most_played_gametypes", []) + if gametypes: + gametypes_str = [] + for gt in gametypes: + key = gt.get("key", "—") + hours = round(gt.get("seconds_played", 0) / 3600) + gametypes_str.append(f"{key} -
{hours}ч")
+
+ response += (
+ "" + + "\n".join(gametypes_str) + + "\n\n" + ) + + # вся активность + general = data.get("general_activity", {}) + if general: + total_hours = round(general.get("total_seconds_played", 0) / 3600) + avg_hours = round(general.get("average_seconds_played", 0) / 3600) + start_date = general.get("start_of_playtime", "—") + response += ( + "
" + f"Общее время:" + ) + await utils.answer(message, response) + except Exception as e: + await utils.answer(message, f"{total_hours}ч\n" + f"Среднее время игры:{avg_hours}ч\n" + f"Начал играть:{start_date}" + "
{str(e)}")
+
+ @loader.command()
+ async def ddstatsred(self, message):
+ """<ник> - Упрощенная версия"""
+ args = utils.get_args_raw(message)
+ if not args:
+ await utils.answer(message, self.strings["no_args"])
+ return
+
+ try:
+ async with aiohttp.ClientSession() as session:
+ async with session.get(f"https://ddstats.tw/player/json?player={args}") as resp:
+ if resp.status != 200:
+ await utils.answer(message, self.strings["not_found"])
+ return
+ data = await resp.json()
+ if "error" in data and data["error"] == "player not found":
+ await utils.answer(message, self.strings["not_found"])
+ return
+
+ response = ""
+ # профиль
+ profile_list = data.get("recent_player_info", [])
+ profile2 = data.get("profile", {})
+ if profile_list and profile2:
+ profile = profile_list[0]
+ name = profile.get("name", args)
+ points = profile2.get("points", "—")
+ clan = profile.get("clan", "—")
+ country_id = profile.get("country", -1)
+ flag = COUNTRY_FLAGS.get(country_id, "-")
+ skin = profile.get("skin_name", "—")
+ last_seen = profile.get("last_seen", "-")
+
+ response += (
+ f"{name}\n\n"
+ f"Поинты:\n" + ) + + # вся активность + general = data.get("general_activity", {}) + if general: + total_hours = round(general.get("total_seconds_played", 0) / 3600) + avg_hours = round(general.get("average_seconds_played", 0) / 3600) + start_date = general.get("start_of_playtime", "—") + + response += ( + "{points}\n" + f"Клан:{clan}\n" + f"Флаг: {flag}\n" + f"Скин:{skin}\n" + f"Дата информации:{last_seen}\n" + "
" + f"Общее время:" + ) + + await utils.answer(message, response) + except Exception as e: + await utils.answer(message, f"{total_hours}ч\n" + f"Среднее время игры:{avg_hours}ч\n" + f"Начал играть:{start_date}" + "
{str(e)}")
diff --git a/mead0wsss/mead0wsMods/FaceitStatus.py b/mead0wsss/mead0wsMods/FaceitStatus.py
new file mode 100644
index 0000000..69ac08e
--- /dev/null
+++ b/mead0wsss/mead0wsMods/FaceitStatus.py
@@ -0,0 +1,95 @@
+__version__ = (1, 0, 0)
+
+# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
+# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
+# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
+# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
+# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
+# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
+# © Copyright 2025
+# ✈ https://t.me/mead0wssMods
+
+# scope: hikka_only
+# scope: hikka_min 1.3.3
+# meta developer: @mead0wssMods
+# meta banner: https://x0.at/tYLF.png
+
+import requests
+from .. import loader, utils
+from aiohttp import ClientSession
+import logging
+
+@loader.tds
+class FaceitStatus(loader.Module):
+ """Модуль для установки статуса в зависимости от уровня FACEIT CS 2"""
+ strings = {"name": "FaceitStatus"}
+
+ def __init__(self):
+ self.config = loader.ModuleConfig(
+ loader.ConfigValue(
+ "nickname",
+ "",
+ lambda: "Никнейм Faceit для получения информации",
+ validator=loader.validators.String()
+ ),
+ loader.ConfigValue(
+ "enabled",
+ False,
+ lambda: "Включить или выключить обновление статуса.",
+ validator=loader.validators.Boolean()
+ )
+ )
+
+ self.faceit_level_emojis = {
+ 1: 5472218969999941969,
+ 2: 5472420816282983721,
+ 3: 5474655053975396078,
+ 4: 5474457803307359926,
+ 5: 5474321889067276806,
+ 6: 5471974427447009199,
+ 7: 5474505554753756989,
+ 8: 5474586712455782018,
+ 9: 5474493773658462333,
+ 10: 5474608393450691188,
+ }
+
+ async def client_ready(self):
+ if self.config["enabled"]:
+ self.update_status_loop.start()
+
+ @loader.loop(interval=60)
+ async def update_status_loop(self):
+ await self.update_status()
+
+ async def update_status(self):
+ nickname = self.config["nickname"]
+ if not nickname:
+ return
+
+ async with ClientSession() as session:
+ async with session.get(f"https://api.faceit.com/users/v1/nicknames/{nickname}") as response:
+ if response.status == 200:
+ payload = await response.json()
+ faceit_lvl = payload.get("payload", {}).get("games", {}).get("cs2", {}).get("skill_level")
+
+ if faceit_lvl in self.faceit_level_emojis:
+ emoji_id = self.faceit_level_emojis[faceit_lvl]
+ await self._client.set_status(emoji_id)
+ else:
+ logging.error("Ошибка при запросе к FACEIT API: %s", response.status)
+
+ @loader.command()
+ async def on_faccmd(self, event):
+ """Включить обновление статуса."""
+ self.config["enabled"] = True
+ await self.update_status()
+ self.update_status_loop.start()
+ await event.edit("✅ Обновление статуса включено.")
+
+ @loader.command()
+ async def off_faccmd(self, event):
+ """Выключить обновление статуса."""
+ self.config["enabled"] = False
+ self.update_status_loop.stop()
+ await event.edit("❌ Обновление статуса выключено.")
+
diff --git a/mead0wsss/mead0wsMods/InfoPresets.py b/mead0wsss/mead0wsMods/InfoPresets.py
new file mode 100644
index 0000000..5746a5a
--- /dev/null
+++ b/mead0wsss/mead0wsMods/InfoPresets.py
@@ -0,0 +1,345 @@
+__version__ = (1, 1, 0)
+
+# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
+# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
+# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
+# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
+# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
+# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
+# © Copyright 2025
+# ✈ https://t.me/mead0wssMods
+
+# scope: heroku_only
+# meta developer: @mead0wssMods
+# meta banner: https://x0.at/GHOP.png
+
+import json
+import os
+from telethon.tl.types import Message
+from ..inline.types import InlineCall
+from .. import loader, utils
+import logging
+
+logger = logging.getLogger(__name__)
+
+@loader.tds
+class InfoPresets(loader.Module):
+ """Управление пресетами для HerokuInfo"""
+ strings = {
+ "name": "InfoPresets",
+ "preset_exists": "🚫 Пресет с таким именем уже существует!",
+ "preset_created": "✅ Пресет '{}' создан. Теперь настройте параметры.",
+ "file_created": "✅ Файл InfoPresets.json создан",
+ "param_set": "✅ Параметр '{}' установлен в '{}' для пресета '{}'",
+ "preset_not_found": "🚫 Пресет '{}' не найден!",
+ "preset_deleted": "✅ Пресет '{}' удален",
+ "no_presets": "🚫 Нет сохраненных пресетов",
+ "preset_loaded": "✅ Пресет '{}' загружен",
+ "enter_value": "✍️ Введите значение для параметра '{}':",
+ "invalid_bool": "🚫 Значение должно быть True или False",
+ "param_not_set": "🚫 Параметр '{}' не установлен в пресете '{}'",
+ "config_menu": "⚙️ Настройка пресета '{}'\nВыберите параметр:",
+ "file_deleted": "✅ Файл с пресетами удален",
+ "file_not_found": "🚫 Файл с пресетами не найден",
+ "preset_list": "📋 Список пресетов:\n\n{}",
+ "preset_info": "🔹 {}:\n{}",
+ "param_info": " • {}: {}",
+ "done": "✅ Готово",
+ "cancel": "❌ Отмена",
+ "form_expired": "⏳ Время действия формы истекло, создайте новую"
+ }
+
+ async def client_ready(self, client, db):
+ self._client = client
+ self.db = db
+ self.presets_file = "InfoPresets.json"
+ self.ensure_presets_file()
+ self._waiting_param = {}
+ self._active_forms = {}
+
+ def ensure_presets_file(self):
+ if not os.path.exists(self.presets_file):
+ with open(self.presets_file, "w", encoding="utf-8") as f:
+ json.dump({}, f)
+
+ async def createprcmd(self, message: Message):
+ """Создать новый пресет."""
+ args = utils.get_args_raw(message)
+ if not args:
+ return
+
+ with open(self.presets_file, "r+", encoding="utf-8") as f:
+ try:
+ presets = json.load(f)
+ except json.JSONDecodeError:
+ presets = {}
+
+ if args in presets:
+ await utils.answer(message, self.strings["preset_exists"])
+ return
+
+ presets[args] = {}
+ f.seek(0)
+ json.dump(presets, f, indent=4)
+ f.truncate()
+
+ await self.edit_preset(message, args)
+
+ async def edit_preset(self, message: Message, preset_name: str):
+ """Редактирование пресета с инлайн-кнопками"""
+ buttons = [
+ [
+ {"text": "✏️ custom_message", "callback": self._param_callback, "args": (preset_name, "custom_message")},
+ {"text": "🖼️ pp_to_banner", "callback": self._param_callback, "args": (preset_name, "pp_to_banner")}
+ ],
+ [
+ {"text": "🔗 banner_url", "callback": self._param_callback, "args": (preset_name, "banner_url")},
+ {"text": "⚙️ show_heroku", "callback": self._param_callback, "args": (preset_name, "show_heroku")}
+ ],
+ [
+ {"text": self.strings["done"], "callback": self._done_callback, "args": (preset_name,)}
+ ]
+ ]
+
+ form = await self.inline.form(
+ message=message,
+ text=self.strings["config_menu"].format(preset_name),
+ reply_markup=buttons,
+ silent=True
+ )
+
+ self._active_forms[preset_name] = {
+ "form": form,
+ "chat_id": message.chat_id,
+ "user_id": message.sender_id
+ }
+
+ async def _param_callback(self, call: InlineCall, preset_name: str, param: str):
+ """Обработчик выбора параметра"""
+ if preset_name not in self._active_forms:
+ await call.answer(self.strings["form_expired"])
+ return
+
+ form_info = self._active_forms[preset_name]
+
+ await call.edit(
+ self.strings["enter_value"].format(param),
+ reply_markup=[
+ [{"text": self.strings["cancel"], "callback": self._cancel_callback, "args": (preset_name,)}]
+ ]
+ )
+
+ self._waiting_param = {
+ "user_id": call.from_user.id,
+ "chat_id": form_info["chat_id"],
+ "preset_name": preset_name,
+ "param": param,
+ "form_info": form_info
+ }
+
+ async def _cancel_callback(self, call: InlineCall, preset_name: str):
+ """Обработчик отмены"""
+ if preset_name not in self._active_forms:
+ await call.answer(self.strings["form_expired"])
+ return
+
+ form_info = self._active_forms[preset_name]
+
+ try:
+ await form_info["form"].edit(
+ self.strings["config_menu"].format(preset_name),
+ reply_markup=[
+ [
+ {"text": "✏️ custom_message", "callback": self._param_callback, "args": (preset_name, "custom_message")},
+ {"text": "🖼️ pp_to_banner", "callback": self._param_callback, "args": (preset_name, "pp_to_banner")}
+ ],
+ [
+ {"text": "🔗 banner_url", "callback": self._param_callback, "args": (preset_name, "banner_url")},
+ {"text": "⚙️ show_heroku", "callback": self._param_callback, "args": (preset_name, "show_heroku")}
+ ],
+ [
+ {"text": self.strings["done"], "callback": self._done_callback, "args": (preset_name,)}
+ ]
+ ]
+ )
+ except Exception as e:
+ logger.error(f"Failed to edit form on cancel: {e}")
+
+ self._waiting_param = {}
+
+ async def _done_callback(self, call: InlineCall, preset_name: str):
+ """Обработчик завершения"""
+ if preset_name in self._active_forms:
+ try:
+ await call.delete()
+ except:
+ pass
+ del self._active_forms[preset_name]
+ self._waiting_param = {}
+
+ async def watcher(self, message: Message):
+ """Обработчик ввода значений параметров"""
+ if not self._waiting_param or not isinstance(self._waiting_param, dict):
+ return
+
+ if not isinstance(message, Message) or not message.message or not hasattr(message, "raw_text"):
+ return
+
+ waiting_chat_id = self._waiting_param.get("chat_id")
+ waiting_user_id = self._waiting_param.get("user_id")
+
+ if (not waiting_chat_id or not waiting_user_id or
+ message.chat_id != waiting_chat_id or
+ message.sender_id != waiting_user_id):
+ return
+
+ preset_name = self._waiting_param.get("preset_name")
+ param = self._waiting_param.get("param")
+ form_info = self._waiting_param.get("form_info")
+
+ if not all([preset_name, param, form_info]):
+ self._waiting_param = {}
+ return
+
+ value = message.raw_text.strip()
+
+ if param in ["pp_to_banner", "show_heroku"]:
+ if value.lower() not in ["true", "false"]:
+ return
+ value = value.lower() == "true"
+
+ try:
+ with open(self.presets_file, "r+", encoding="utf-8") as f:
+ presets = json.load(f)
+ if preset_name not in presets:
+ return
+
+ presets[preset_name][param] = value
+ f.seek(0)
+ json.dump(presets, f, indent=4)
+ f.truncate()
+
+ await utils.answer(message, self.strings["param_set"].format(param, value, preset_name))
+
+ try:
+ await form_info["form"].edit(
+ self.strings["config_menu"].format(preset_name),
+ reply_markup=[
+ [
+ {"text": "✏️ custom_message", "callback": self._param_callback, "args": (preset_name, "custom_message")},
+ {"text": "🖼️ pp_to_banner", "callback": self._param_callback, "args": (preset_name, "pp_to_banner")}
+ ],
+ [
+ {"text": "🔗 banner_url", "callback": self._param_callback, "args": (preset_name, "banner_url")},
+ {"text": "⚙️ show_heroku", "callback": self._param_callback, "args": (preset_name, "show_heroku")}
+ ],
+ [
+ {"text": self.strings["done"], "callback": self._done_callback, "args": (preset_name,)}
+ ]
+ ]
+ )
+ except Exception as e:
+ logger.error(f"Failed to edit form: {e}")
+
+ except Exception as e:
+ logger.exception("Error saving parameter")
+
+ finally:
+ self._waiting_param = {}
+
+ async def delprcmd(self, message: Message):
+ """Удалить пресет."""
+ args = utils.get_args_raw(message)
+ if not args:
+ return
+
+ with open(self.presets_file, "r+", encoding="utf-8") as f:
+ presets = json.load(f)
+ if args not in presets:
+ return
+
+ del presets[args]
+ f.seek(0)
+ json.dump(presets, f, indent=4)
+ f.truncate()
+
+ await utils.answer(message, self.strings["preset_deleted"].format(args))
+
+ async def delfileprcmd(self, message: Message):
+ """Удалить файл с пресетами."""
+ if not os.path.exists(self.presets_file):
+ return
+
+ os.remove(self.presets_file)
+ self.ensure_presets_file()
+ await utils.answer(message, self.strings["file_deleted"])
+
+ async def uploadprcmd(self, message: Message):
+ """Загрузить файл с пресетами."""
+ if not os.path.exists(self.presets_file):
+ return
+
+ with open(self.presets_file, "r", encoding="utf-8") as f:
+ presets = json.load(f)
+ if not presets:
+ return
+
+ await self._client.send_file(
+ message.chat_id,
+ self.presets_file,
+ caption="📁 Файл с пресетами"
+ )
+ await message.delete()
+
+ async def listprcmd(self, message: Message):
+ """Показать список всех пресетов."""
+ if not os.path.exists(self.presets_file):
+ return
+
+ with open(self.presets_file, "r", encoding="utf-8") as f:
+ try:
+ presets = json.load(f)
+ except json.JSONDecodeError:
+ return
+
+ if not presets:
+ return
+
+ result = []
+ for preset_name, params in presets.items():
+ param_lines = []
+ for param, value in params.items():
+ param_lines.append(self.strings["param_info"].format(param, value))
+ result.append(self.strings["preset_info"].format(
+ preset_name, "\n".join(param_lines) if param_lines else "⏺ Нет параметров"
+ ))
+
+ await utils.answer(
+ message,
+ self.strings["preset_list"].format("\n\n".join(result))
+ )
+
+ async def loadprcmd(self, message: Message):
+ """Загрузить пресет."""
+ args = utils.get_args_raw(message)
+ if not args:
+ return
+
+ with open(self.presets_file, "r", encoding="utf-8") as f:
+ presets = json.load(f)
+ if args not in presets:
+ return
+
+ preset = presets[args]
+ heroku_info = self.lookup("HerokuInfo")
+
+ if not heroku_info:
+ return
+
+ for param, value in preset.items():
+ if param in heroku_info.config:
+ heroku_info.config[param] = value
+ else:
+ logger.warning(f"Параметр {param} не найден в конфиге HerokuInfo")
+
+ await utils.answer(message, self.strings["preset_loaded"].format(args))
diff --git a/mead0wsss/mead0wsMods/LICENSE.md b/mead0wsss/mead0wsMods/LICENSE.md
new file mode 100644
index 0000000..0630d5f
--- /dev/null
+++ b/mead0wsss/mead0wsMods/LICENSE.md
@@ -0,0 +1,20 @@
+Proprietary License Agreement
+
+Copyright (c) 2025-2030 mead0wss (Maxim Trous)
+
+Permission is hereby granted to any person obtaining a copy of this software and associated documentation files (the "Software"), to use the Software for personal and non-commercial purposes, subject to the following conditions:
+
+1. The Software may not be modified, altered, or otherwise changed in any way without the explicit written permission of the author.
+
+2. Redistribution of the Software, in original or modified form, is strictly prohibited without the explicit written permission of the author.
+
+3. The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. In no event shall the author or copyright holder be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Software or the use or other dealings in the Software.
+
+4. Any use of the Software must include the above copyright notice and this permission notice in all copies or substantial portions of the Software.
+
+5. By using the Software, you agree to be bound by the terms and conditions of this license.
+
+For any inquiries or requests for permissions, please contact in Telegram @maximtrous or mead0wss.xyz@gmail.com.
+
+Maxim
+25.03.2025
diff --git a/mead0wsss/mead0wsMods/MyFACEIT.py b/mead0wsss/mead0wsMods/MyFACEIT.py
new file mode 100644
index 0000000..54e76b3
--- /dev/null
+++ b/mead0wsss/mead0wsMods/MyFACEIT.py
@@ -0,0 +1,99 @@
+__version__ = (1, 0, 0)
+
+# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
+# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
+# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
+# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
+# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
+# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
+# © Copyright 2025
+# ✈ https://t.me/mead0wssMods
+
+# scope: hikka_only
+# scope: hikka_min 1.3.3
+# meta developer: @mead0wssMods
+# meta banner: https://x0.at/Hu25.jpg
+
+
+import requests
+from telethon import events
+from .. import loader, utils
+from aiohttp import ClientSession
+import json
+
+@loader.tds
+class MyFACEIT(loader.Module):
+ """Модуль для получения информации о своем профиле FACEIT"""
+ strings = {"name": "MyFACEIT"}
+
+ def __init__(self):
+ self.config = loader.ModuleConfig(
+ loader.ConfigValue(
+ "nickname",
+ "",
+ lambda: "Никнейм Faceit для получения информации",
+ validator=loader.validators.String()
+ ),
+ )
+
+ async def myfaceitcmd(self, event):
+ """- Показать информацию об своем FACEIT профиле."""
+ nickname = self.config["nickname"]
+
+ if not nickname:
+ await event.reply("❌ Никнейм Faceit не указан в .cfg!")
+ return
+
+ async with ClientSession() as session:
+ async with session.get(f"https://api.faceit.com/users/v1/nicknames/{nickname}") as response:
+ if response.status == 200:
+ payload = await response.json()
+ payload = payload.get("payload", {})
+
+ gender = payload.get("gender")
+ user_type = payload.get("user_type")
+ ID = payload.get("id")
+ country = payload.get("country")
+ region = payload.get("games", {}).get("cs2", {}).get("region")
+ elo = payload.get("games", {}).get("cs2", {}).get("faceit_elo")
+ faceit_lvl_c2 = payload.get("games", {}).get("cs2", {}).get("skill_level")
+ twitch_id = payload.get("streaming", {}).get("twitch_id")
+ steam_nickname = payload.get("platforms", {}).get("steam", {}).get("nickname")
+
+ if gender == "male":
+ gender = "Мужчина"
+ elif gender == "Female":
+ gender = "Женщина"
+ else:
+ gender = "*неуказано*"
+
+ if user_type == "user":
+ user_type = "Пользователь"
+ else:
+ user_type = "*неуказано*"
+
+ country_flags = {
+ "ru": "🇷🇺",
+ "eu": "🇪🇺",
+ "us": "🇺🇸",
+ "br": "🇧🇷",
+ "cn": "🇨🇳",
+ "kr": "🇰🇷",
+ "jp": "🇯🇵",
+ "au": "🇦🇺",
+ "ca": "🇨🇦",
+ "gb": "🇬🇧",
+ "de": "🇩🇪",
+ "fr": "🇫🇷",
+ "es": "🇪🇸",
+ "it": "🇮🇹",
+ "pl": "🇵🇱",
+ "tr": "🇹🇷",
+ }
+
+ country_flag = country_flags.get(country.lower(), "")
+ region_flag = country_flags.get(region.lower(), "")
+
+ await event.edit(f"Информация об моем FACEIT профиле:\n\n🎮 Ник: {nickname}\n\n🚻 Пол: {gender}\n\n🔍 Тип: {user_type}\n\n🆔 Faceit ID: {ID}\n\n🌍 Страна: {country_flag}\n\n🌐 Регион: {region_flag}\n\n📊 Количество ELO: {elo}\n\n⭐️ Faceit LVL: {faceit_lvl_c2}\n\n📺 Twitch ID: {twitch_id}\n\n💻 Steam: {steam_nickname}", parse_mode="html")
+ else:
+ await event.reply("❌ Ошибка при запросе к FACEIT API")
diff --git a/mead0wsss/mead0wsMods/RussianRoulette.py b/mead0wsss/mead0wsMods/RussianRoulette.py
new file mode 100644
index 0000000..28d7dc2
--- /dev/null
+++ b/mead0wsss/mead0wsMods/RussianRoulette.py
@@ -0,0 +1,37 @@
+__version__ = (1, 0, 0)
+
+# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
+# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
+# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
+# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
+# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
+# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
+# © Copyright 2025
+# ✈ https://t.me/mead0wssMods
+
+# scope: hikka_only
+# scope: hikka_min 1.3.3
+# meta developer: @mead0wssMods
+# meta banner: https://x0.at/N3nB.jpg
+
+from telethon.tl.functions.channels import LeaveChannelRequest
+import asyncio
+import random
+from .. import loader, utils
+
+@loader.tds
+class RouletteMod(loader.Module):
+ """Модуль для игры в Русскую рулетку. При поражении выкидывает с чата."""
+ strings = {"name": "Roulette"}
+
+ async def roulettecmd(self, message):
+ """Начать игру в Русскую рулетку"""
+ await message.edit('😶🔫 Прикладываю пистолет к виску и медленно нажимаю курок...')
+ await asyncio.sleep(2)
+
+ choice = random.choice([1, 2])
+ if choice == 1:
+ await message.edit('😵 Смерть... Всем пока!')
+ await message.client(LeaveChannelRequest(message.chat_id))
+ else:
+ await message.edit('😄 Выжил! Остаюсь в чате.')
diff --git a/mead0wsss/mead0wsMods/SenderGifts.py b/mead0wsss/mead0wsMods/SenderGifts.py
new file mode 100644
index 0000000..e56dd86
--- /dev/null
+++ b/mead0wsss/mead0wsMods/SenderGifts.py
@@ -0,0 +1,137 @@
+# -- version --
+__version__ = (1, 0, 0)
+# -- version --
+
+
+# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
+# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
+# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
+# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
+# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
+# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
+# © Copyright 2025
+# ✈ https://t.me/mead0wssMods
+
+
+# meta developer: @mead0wssMods x @nullmod
+# scope: heroku_only
+
+from .. import loader, utils
+from herokutl.tl.functions.payments import GetPaymentFormRequest, SendStarsFormRequest
+from herokutl.tl.types import InputInvoiceStarGift, TextWithEntities
+from herokutl.errors.rpcerrorlist import BadRequestError
+import logging
+
+@loader.tds
+class SenderGifts(loader.Module):
+ """Модуль для отправки подарков"""
+
+ strings = {
+ "name": "SenderGifts",
+ "usage": ".sendgift @username текст",
+ "checking_user": "{followers_count} Фолловеров]\n")
+
+ if len(followed) > 25:
+ text += f"\n...и еще {len(followed) - 25} стримеров"
+
+ await utils.answer(message, text)
+
+ @loader.command()
+ async def streams(self, message):
+ """Показать онлайн стримы"""
+ user_id = await self.get_user_id()
+ if not user_id:
+ await utils.answer(message, "') + + await utils.answer(message, text) + + @loader.command() + async def streamer(self, message): + """Информация о стримере""" + args = utils.get_args_raw(message) + if not args: + await utils.answer(message, "🎮 {stream["game_name"]}\n' + f'👁 {stream["viewer_count"]}зрителей\n' + f'👥 {followers_count}фолловеров\n' + f'ℹ️ {stream["title"]}\n
") + + await utils.answer(message, text) + + @loader.command() + async def topgames(self, message): + """Топ игр на Twitch""" + games = await self.get_top_games(10) + if not games: + await utils.answer(message, "👥 Фолловеров:{followers_count}\n" + f"ℹ️ Описание стрима (пусто = офф):{channel_info.get('title', 'Нет описания')}\n" + f"🎮 Игра на стриме:{channel_info.get('game_name', 'Не указана')}\n" + f"🔗 Ссылка: https://twitch.tv/{args}
{i+1}. {game['name']} (ID: {game['id']})"
+ for i, game in enumerate(games))
+
+ await utils.answer(message, text)
+
+ @loader.command()
+ async def game(self, message):
+ """Поиск игры и стримы по ней"""
+ args = utils.get_args_raw(message)
+ if not args:
+ await utils.answer(message, "') + else: + text += "Сейчас никто не стримит эту игру" + + await utils.answer(message, text) diff --git a/mead0wsss/mead0wsMods/tmpfiles.py b/mead0wsss/mead0wsMods/tmpfiles.py new file mode 100644 index 0000000..9154469 --- /dev/null +++ b/mead0wsss/mead0wsMods/tmpfiles.py @@ -0,0 +1,96 @@ +# -- version -- +__version__ = (1, 0, 0) +# -- version -- + + +# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗ +# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝ +# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░ +# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗ +# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝ +# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░ +# © Copyright 2025 +# ✈ https://t.me/mead0wssMods + + +# meta developer: @mead0wssMods + + + +# -- main -- +from .. import loader, utils +import io +import requests +import json +# -- main -- + + + +@loader.tds +class tmpfilesMod(loader.Module): # initialization + """Модуль для загрузки файлов на tmpfiles.org""" + + strings = { + "name": "tmpfiles", + "uploading": "👁 {stream["viewer_count"]}зрителей\n' + f'👥 {followers_count}фолловеров\n' + f'ℹ️ {stream["title"]}\n
{}",
+ "error": "{}",
+ "error": "