Added and updated repositories 2025-08-10 01:17:09

This commit is contained in:
github-actions[bot]
2025-08-10 01:17:09 +00:00
parent b19923995a
commit 92d4a11003
33 changed files with 2983 additions and 32 deletions

170
cryptexctl/modules-mirror/.gitignore vendored Normal file
View File

@@ -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/

View File

@@ -0,0 +1,2 @@
# modules

View File

@@ -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()

View File

@@ -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()

View File

@@ -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, "Не удалось установить аватарку.")

View File

@@ -0,0 +1,11 @@
actually
avaclone
premium_emoji_id
randomtrack
zovmodule
овощерезка
сланцы2
notesmod
SomethingCreatingScriptErrors
forgotboard
komarumod

View File

@@ -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("<b>Нет доступных GIF-ов в канале!</b>")
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()

View File

@@ -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}")

View File

@@ -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, "❌ Это не премиум-эмодзи.")

View File

@@ -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}")

View File

@@ -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)

View File

@@ -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}")

View File

@@ -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()

View File

@@ -2,8 +2,6 @@
# https://github.com/all-licenses/GNU-General-Public-License-v3.0 # https://github.com/all-licenses/GNU-General-Public-License-v3.0
# meta developer: @PyModule # meta developer: @PyModule
import json
import os
from telethon.tl.types import Message from telethon.tl.types import Message
from .. import loader from .. import loader
@@ -12,27 +10,19 @@ class ChannelAdapterMod(loader.Module):
"""Модуль для добавления переходника в сообщения каналов""" """Модуль для добавления переходника в сообщения каналов"""
strings = {"name": "ChannelAdapter"} 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): async def client_ready(self, client, db):
self.client = client self.client = client
self.db = db self.db = db
if not self.adapters: if not self.db.get(__name__, "adapters"):
self.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() @loader.command()
async def addadaptercmd(self, message: Message): async def addadaptercmd(self, message: Message):
@@ -49,11 +39,13 @@ class ChannelAdapterMod(loader.Module):
await message.edit("<emoji document_id=6030563507299160824>❗️</emoji> <b>Укажите текст переходника.</b>") await message.edit("<emoji document_id=6030563507299160824>❗️</emoji> <b>Укажите текст переходника.</b>")
return return
self.adapters[chat_id] = adapter_text adapters = self.get_adapters()
self.save_adapters() adapters[chat_id] = adapter_text
self.save_adapters(adapters)
await message.edit(f"<emoji document_id=5774022692642492953>✅</emoji> <b>Переходник добавлен для канала:</b> <code>{chat_id}</code> - {adapter_text}") await message.edit(f"<emoji document_id=5774022692642492953>✅</emoji> <b>Переходник добавлен для канала:</b> <code>{chat_id}</code> - {adapter_text}")
@loader.command()
async def deladaptercmd(self, message: Message): async def deladaptercmd(self, message: Message):
"""[CHANNEL ID] - Удалить переходник для канала.""" """[CHANNEL ID] - Удалить переходник для канала."""
args = message.raw_text.split() args = message.raw_text.split()
@@ -62,37 +54,40 @@ class ChannelAdapterMod(loader.Module):
return return
chat_id = args[1] chat_id = args[1]
adapters = self.get_adapters()
if chat_id not in self.adapters: if chat_id not in adapters:
await message.edit("<emoji document_id=5774077015388852135>❌</emoji> <b>Этот канал не найден в списке.</b>") await message.edit("<emoji document_id=5774077015388852135>❌</emoji> <b>Этот канал не найден в списке.</b>")
return return
del self.adapters[chat_id] del adapters[chat_id]
self.save_adapters() self.save_adapters(adapters)
await message.edit(f"<emoji document_id=5774022692642492953>✅</emoji> <b>Переходник для канала <code>{chat_id}</code> удалён.</b>") await message.edit(f"<emoji document_id=5774022692642492953>✅</emoji> <b>Переходник для канала <code>{chat_id}</code> удалён.</b>")
@loader.command()
async def listadapterscmd(self, message: Message): async def listadapterscmd(self, message: Message):
"""- Показать список всех переходников.""" """- Показать список всех переходников."""
if not self.adapters: adapters = self.get_adapters()
if not adapters:
await message.edit("<emoji document_id=5774077015388852135>❌</emoji> <b>Нет сохранённых переходников.</b>") await message.edit("<emoji document_id=5774077015388852135>❌</emoji> <b>Нет сохранённых переходников.</b>")
return return
text = "<blockquote><emoji document_id=5253959125838090076>👁</emoji> <b>Список сохранённых переходников</b></blockquote>\n\n\n" text = "<blockquote><emoji document_id=5253959125838090076>👁</emoji> <b>Список сохранённых переходников</b></blockquote>\n\n\n"
for chat_id, adapter_text in self.adapters.items(): for chat_id, adapter_text in adapters.items():
text += f"<emoji document_id=6032924188828767321></emoji> <b><code>{chat_id}</code>:</b> {adapter_text}\n\n" text += f"<emoji document_id=6032924188828767321></emoji> <b><code>{chat_id}</code>:</b> {adapter_text}\n\n"
await message.edit(text) await message.edit(text)
@loader.command()
async def clearadapterscmd(self, message: Message): async def clearadapterscmd(self, message: Message):
"""- Удалить все переходники.""" """- Удалить все переходники."""
if not self.adapters: adapters = self.get_adapters()
if not adapters:
await message.edit("<emoji document_id=5774077015388852135>❌</emoji> <b>Нет переходников для удаления.</b>") await message.edit("<emoji document_id=5774077015388852135>❌</emoji> <b>Нет переходников для удаления.</b>")
return return
self.adapters = {} self.db.set(__name__, "adapters", {})
self.save_adapters()
await message.edit("<emoji document_id=5774022692642492953>✅</emoji> <b>Все адаптеры были удалены.</b>") await message.edit("<emoji document_id=5774022692642492953>✅</emoji> <b>Все адаптеры были удалены.</b>")
async def watcher(self, message: Message): async def watcher(self, message: Message):
@@ -100,7 +95,8 @@ class ChannelAdapterMod(loader.Module):
if not message or not message.out: if not message or not message.out:
return return
adapter_text = self.adapters.get(str(message.chat_id), None) adapters = self.get_adapters()
adapter_text = adapters.get(str(message.chat_id), None)
if not adapter_text: if not adapter_text:
return return

171
mead0wsss/mead0wsMods/.gitignore vendored Normal file
View File

@@ -0,0 +1,171 @@
# 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/
# PyPI configuration file
.pypirc

View File

@@ -0,0 +1,113 @@
__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/yCcx.jpg
from telethon import events
from .. import loader, utils
@loader.tds
class AutoFormatting(loader.Module):
"""Модуль для автоматического форматирования вашего текста в чате."""
strings = {"name": "AutoFormatting"}
def __init__(self):
self.styles = {
"bold": False,
"italic": False,
"mono": False,
"underline": False,
"strikethrough": False,
"center": False
}
async def format_message(self, message):
content = message.text
if not content:
return
for style, enabled in self.styles.items():
if enabled:
tags = {
"bold": "b",
"italic": "i",
"mono": "code",
"underline": "u",
"strikethrough": "s",
"center": "center"
}
content = f"<{tags[style]}>{content}</{tags[style]}>"
await message.edit(content, parse_mode="HTML")
def reset_styles(self):
for style in self.styles:
self.styles[style] = False
@loader.command()
async def bold(self, message):
"""Включает или отключает жирный текст."""
self.styles["bold"] = not self.styles["bold"]
status = "включен" if self.styles["bold"] else "выключен"
await utils.answer(message, f"🪐 <b>Жирный текст</b> {status} ʕ·ᴥ·ʔ", parse_mode="HTML")
@loader.command()
async def italic(self, message):
"""Включает или отключает курсив."""
self.styles["italic"] = not self.styles["italic"]
status = "включен" if self.styles["italic"] else "выключен"
await utils.answer(message, f"🪐 <i>Курсив</i> {status} ʕ·ᴥ·ʔ", parse_mode="HTML")
@loader.command()
async def mono(self, message):
"""Включает или отключает моноширинный текст."""
self.styles["mono"] = not self.styles["mono"]
status = "включен" if self.styles["mono"] else "выключен"
await utils.answer(message, f"🪐 <code>Моноширинный текст</code> {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"🪐 <u>Подчеркивание</u> {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"🪐 <s>Зачеркивание</s> {status} ʕ·ᴥ·ʔ", parse_mode="HTML")
@loader.command()
async def off(self, message):
"""Отключает все стили."""
self.reset_styles()
await utils.answer(message, "🪐 Все стили выключены ʕ·ᴥ·ʔ", parse_mode="HTML")
@loader.command()
async def on(self, message):
"""Включает стиль по умолчанию (жирный текст)."""
self.reset_styles()
self.styles["bold"] = True
await utils.answer(message, "🪐 Стиль по умолчанию (жирный текст) включен ʕ·ᴥ·ʔ", parse_mode="HTML")
@loader.watcher(out=True)
async def message_watcher(self, message):
commands = ["bold", "italic", "mono", "underline", "strikethrough", "off", "on"]
if message.text.split()[0] in commands:
return
if any(self.styles.values()):
await self.format_message(message)

View File

@@ -0,0 +1,92 @@
__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/GgLO.png
import requests
from .. import loader, utils
from telethon import events
@loader.tds
class AutomaticTranslator(loader.Module):
"""Модуль для автоматического перевода сообщений на язык. Создан ради забавы."""
strings = {"name": "AutomaticTranslator"}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"target_language",
"",
lambda: "Язык, на который будет производиться перевод (например, 'English').",
validator=loader.validators.String()
),
loader.ConfigValue(
"enabled",
True,
lambda: "Включить или выключить автоматический перевод.",
validator=loader.validators.Boolean()
)
)
self.ignore_commands = ['off', 'on', 'cfg']
async def translate_text(self, text, target_language):
api_key = 'Bearer sk-l4HU4KwZt6bF8gOwwKCOMpfpIKvR9YhDHvTFIGJ6tJ5rPKXE'
data = {
"model": "deepseek-v3",
"messages": [
{"role": "user", "content": f"Please translate the following text to {target_language}, no extra text, just translation: {text}"}
]
}
response = requests.post("https://cablyai.com/v1/chat/completions", headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json',
}, json=data)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
return None
@loader.command()
async def oncmd(self, event):
"""Включить автоматический перевод."""
self.config["enabled"] = True
await event.edit("✅ Автоматический перевод включен.")
@loader.command()
async def offcmd(self, event):
"""Выключить автоматический перевод."""
self.config["enabled"] = False
await event.edit("❌ Автоматический перевод выключен.")
@loader.watcher(out=True)
async def message_watcher(self, message):
if not self.config["enabled"]:
return
if message.raw_text.startswith(tuple(self.ignore_commands)):
return
target_language = self.config["target_language"]
if not target_language:
return
translated_text = await self.translate_text(message.raw_text, target_language)
if translated_text:
await message.edit(translated_text)
else:
await message.edit("❌ Ошибка при переводе сообщения.")
# артемко лох

View File

@@ -0,0 +1,98 @@
# -- version --
__version__ = (1, 0, 0)
# -- version --
# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
# © Copyright 2025
# ✈ https://t.me/mead0wssMods
# meta developer: @mead0wssMods
# scope: heroku_only
import herokutl
from .. import loader, utils
import aiohttp
@loader.tds
class DDNetPlayerTime(loader.Module):
"""Получение статистики отыгранного времени игрока DDNet с ddstats.tw"""
strings = {
"name": "DDNetPT",
"no_args": "<emoji document_id=5980953710157632545>❌</emoji><b> Укажите ник игрока!</b>",
"api_error_or_player_not_found": "<emoji document_id=5980953710157632545>❌</emoji><b> Возможно данный игрок не найден либо ошибка на стороне API</b>",
}
async def client_ready(self, client, db):
self.client = client
@loader.command()
async def ddpt(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["api_error_or_player_not_found"])
return
data = await resp.json()
response = ""
gametypes = data.get("most_played_gametypes", [])
if gametypes:
gametypes_str = []
for gt in gametypes:
hours = round(gt.get("seconds_played", 0) / 3600)
gametypes_str.append(f"{gt.get('key', '?')} - <code>{hours}ч</code>")
response += f"<b><emoji document_id=6032693626394382504>👤</emoji> Игрок: <code>{args}</code>\n\n<emoji document_id=5908961403917570106>📌</emoji> Тип:\n<blockquote>" + "\n".join(gametypes_str) + "</blockquote>\n\n</b>"
# мапы
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', '?')} - <code>{hours}ч</code>")
response += "<b><emoji document_id=5985479497586053461>🗺</emoji> Карта:\n<blockquote>" + "\n".join(maps_str) + "</blockquote>\n\n</b>"
# категории
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', '?')} - <code>{hours}ч</code>")
response += "<b><emoji document_id=5924720918826848520>📦</emoji> Категория:\n<blockquote>" + "\n".join(categories_str) + "</blockquote>\n\n</b>"
# время
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 += "<b><emoji document_id=5870729937215819584>⏰️</emoji> Время:\n<blockquote>"
response += f"Общее время игры - <code>{total_hours}ч</code>\n"
response += f"Дата начала игры - <code>{start_date}</code>\n"
response += f"Среднее время игры - <code>{avg_hours}ч</code>"
response += "</blockquote></b>"
await utils.answer(message, response)
except Exception as e:
await utils.answer(message, f"{self.strings['api_error_or_player_not_found']}: {str(e)}")
# ебеший-ленеивый говнокод

View File

@@ -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: "<emoji document_id=5282901420092184370>🇦🇫</emoji>", 8: "<emoji document_id=5282802257887252454>🇦🇱</emoji>", 12: "<emoji document_id=5269400778807720624>🇩🇿</emoji>", 16: "<emoji document_id=5285286810568643037>🇦🇸</emoji>", 20: "<emoji document_id=5285054504377537713>🇦🇩</emoji>", 24: "<emoji document_id=5221978936791017415>🇦🇴</emoji>", 28: "<emoji document_id=5233687283927892876>🇦🇬</emoji>", 32: "<emoji document_id=5280670931906213487>🇦🇷</emoji>", 51: "<emoji document_id=5271787444889466595>🇦🇲</emoji>",
52: "<emoji document_id=5222119223307807441>🇧🇧</emoji>", 56: "<emoji document_id=5280641133423112676>🇧🇪</emoji>", 68: "<emoji document_id=5382315288630934648>🇧🇴</emoji>", 76: "<emoji document_id=5280669682070731606>🇧🇷</emoji>", 84: "<emoji document_id=5231366665853224722>🇧🇿</emoji>", 96: "<emoji document_id=5285233604513781328>🇧🇳</emoji>", 100: "<emoji document_id=5282791606368352462>🇧🇬</emoji>", 108: "<emoji document_id=5357542359649237058>🇧🇮</emoji>", 112: "<emoji document_id=5280512271519331866>🇧🇾</emoji>",
116: "<emoji document_id=5280485724326474894>🇰🇭</emoji>", 120: "<emoji document_id=5474681124426884947>🇨🇲</emoji>", 124: "<emoji document_id=5280518567941387930>🇨🇦</emoji>", 136: "<emoji document_id=5454177075109839093>🇰🇾</emoji>", 140: "<emoji document_id=5422628135139031178>🇨🇫</emoji>", 148: "<emoji document_id=6323390224307062186>🇹🇩</emoji>", 152: "<emoji document_id=5384575377731499598>🇨🇱</emoji>", 156: "<emoji document_id=5281004590735569964>🇨🇳</emoji>",
170: "<emoji document_id=5384497205031746451>🇨🇴</emoji>", 174: "<emoji document_id=5422342777511886475>🇰🇲</emoji>", 178: "<emoji document_id=5422479718249151727>🇨🇬</emoji>", 180: "<emoji document_id=5269407491841603689>🇨🇩</emoji>", 184: "<emoji document_id=5283150313446985843>🇨🇰</emoji>", 188: "<emoji document_id=5269494559418629149>🇨🇷</emoji>", 191: "<emoji document_id=5281017995328500960>🇭🇷</emoji>", 192: "<emoji document_id=5357035553508308603>🇨🇺</emoji>",
196: "<emoji document_id=5246826422110018275>🇨🇾</emoji>", 203: "<emoji document_id=5280658931767587282>🇨🇿</emoji>", 208: "<emoji document_id=5280545188148688356>🇩🇰</emoji>", 212: "<emoji document_id=5231486851923069595>🇩🇲</emoji>", 214: "<emoji document_id=5427236235615683748>🇩🇴</emoji>", 218: "<emoji document_id=5359624993586034294>🇪🇨</emoji>", 222: "<emoji document_id=6323151583039194562>🇸🇻</emoji>", 231: "<emoji document_id=5269679685393989166>🇪🇹</emoji>",
232: "<emoji document_id=5420548035232937623>🇪🇷</emoji>", 233: "<emoji document_id=5280988244090043228>🇪🇪</emoji>", 234: "<emoji document_id=5454214681843481342>🇫🇰</emoji>", 238: "<emoji document_id=5285146695850546991>🇫🇯</emoji>", 242: "<emoji document_id=5280618189707820243>🇫🇮</emoji>", 246: "<emoji document_id=5280726985524393568>🇫🇷</emoji>", 250: "<emoji document_id=5280726985524393568>🇫🇷</emoji>", 254: "<emoji document_id=5233523014313720667>🇬🇫</emoji>",
258: "<emoji document_id=5285088988669956602>🇵🇫</emoji>", 260: "<emoji document_id=6323541720688494392>🇹🇫</emoji>", 262: "<emoji document_id=5458586718032634511>🇩🇯</emoji>", 266: "<emoji document_id=5408983586680350780>🇬🇦</emoji>", 268: "<emoji document_id=5282892108603077166>🇬🇪</emoji>", 270: "<emoji document_id=5420472705801536529>🇬🇲</emoji>", 276: "<emoji document_id=5280891993872938632>🇩🇪</emoji>", 288: "<emoji document_id=5188676065320511388>🇬🇭</emoji>",
292: "<emoji document_id=5285097376741085100>🇬🇮</emoji>", 300: "<emoji document_id=5280778658275933332>🇬🇷</emoji>", 304: "<emoji document_id=5283030741557467798>🇬🇱</emoji>", 308: "<emoji document_id=5467787680441976258>🇬🇩</emoji>", 312: "<emoji document_id=5467664243081886165>🇬🇵</emoji>", 316: "<emoji document_id=5283243058970777502>🇬🇺</emoji>", 320: "<emoji document_id=5280645643138774246>🇬🇹</emoji>", 324: "<emoji document_id=5408977500711691863>🇬🇳</emoji>",
328: "<emoji document_id=5420413662886117194>🇬🇾</emoji>", 332: "<emoji document_id=5357490485034236365>🇭🇹</emoji>", 336: "<emoji document_id=6321134039331767912>🇻🇦</emoji>", 340: "<emoji document_id=5224205572391315540>🇭🇳</emoji>", 344: "<emoji document_id=5280508169825564450>🇭🇰</emoji>", 348: "<emoji document_id=5280899741993940546>🇭🇺</emoji>", 352: "<emoji document_id=5280963298919984867>🇮🇸</emoji>", 356: "<emoji document_id=5280846712032736842>🇮🇳</emoji>",
360: "<emoji document_id=5280650659660575583>🇮🇩</emoji>", 364: "<emoji document_id=5386769637868321283>🇮🇷</emoji>", 368: "<emoji document_id=5282728427399434847>🇮🇶</emoji>", 372: "<emoji document_id=5418148690407736295>🇮🇪</emoji>", 376: "<emoji document_id=5280470756365449120>🇮🇱</emoji>", 380: "<emoji document_id=5280980882516097940>🇮🇹</emoji>", 384: "<emoji document_id=5411283953984218884>🇨🇮</emoji>", 388: "<emoji document_id=5420144630429667484>🇯🇲</emoji>",
392: "<emoji document_id=5280646033980798168>🇯🇵</emoji>", 400: "<emoji document_id=5280969006931523664>🇯🇴</emoji>", 404: "<emoji document_id=5269725950781699509>🇰🇪</emoji>", 408: "<emoji document_id=5283148599755034836>🇰🇵</emoji>", 410: "<emoji document_id=5281027160788711973>🇰🇷</emoji>", 414: "<emoji document_id=5285528436838802863>🇰🇼</emoji>", 417: "<emoji document_id=5280796211807271247>🇰🇬</emoji>", 418: "<emoji document_id=5382259381041642498>🇱🇦</emoji>",
422: "<emoji document_id=5281005170556155877>🇱🇧</emoji>", 426: "<emoji document_id=5422515422312281871>🇱🇸</emoji>", 428: "<emoji document_id=5280520440547128580>🇱🇻</emoji>", 430: "<emoji document_id=5422520224085720580>🇱🇷</emoji>", 434: "<emoji document_id=5222284437814783192>🇱🇾</emoji>", 438: "<emoji document_id=5283163589190897118>🇱🇮</emoji>", 440: "<emoji document_id=5281003469749104420>🇱🇹</emoji>", 442: "<emoji document_id=5280820753250399387>🇱🇺</emoji>",
446: "<emoji document_id=5282872089760517576>🇲🇴</emoji>", 450: "<emoji document_id=5429165814097913547>🇲🇬</emoji>", 454: "<emoji document_id=5341341330691863561>🇲🇼</emoji>", 458: "<emoji document_id=5282889303989434607>🇲🇾</emoji>", 462: "<emoji document_id=5282867081828653253>🇲🇻</emoji>", 466: "<emoji document_id=5411259459785730007>🇲🇱</emoji>", 470: "<emoji document_id=5195440776250671226>🇲🇹</emoji>", 474: "<emoji document_id=5470045239806802915>🇲🇶</emoji>",
478: "<emoji document_id=5422465115360345921>🇲🇷</emoji>", 480: "<emoji document_id=5269757084999628216>🇲🇺</emoji>", 484: "<emoji document_id=5462978261963263384>🇲🇽</emoji>", 492: "<emoji document_id=5283030548283937651>🇲🇨</emoji>", 496: "<emoji document_id=5406717720848778045>🇲🇳</emoji>", 498: "<emoji document_id=5280508998754250814>🇲🇩</emoji>", 499: "<emoji document_id=5280868599186077859>🇲🇪</emoji>", 504: "<emoji document_id=5260720207520867861>🇲🇦</emoji>",
508: "<emoji document_id=5429106139822303027>🇲🇿</emoji>", 512: "<emoji document_id=5283013153666389024>🇴🇲</emoji>", 516: "<emoji document_id=5420229786746239476>🇳🇦</emoji>", 520: "<emoji document_id=5283007995410667003>🇳🇷</emoji>", 524: "<emoji document_id=5283265805117577131>🇳🇵</emoji>", 528: "<emoji document_id=5280870488971685714>🇳🇱</emoji>", 531: "<emoji document_id=5233622988267472134>🇨🇼</emoji>", 533: "<emoji document_id=5231044964212817289>🇦🇼</emoji>",
534: "<emoji document_id=6323585499290142513>🇸🇽</emoji>", 540: "<emoji document_id=5282787285631258647>🇳🇨</emoji>", 554: "<emoji document_id=5283051267206172487>🇳🇿</emoji>", 558: "<emoji document_id=5280902791420718943>🇳🇮</emoji>", 562: "<emoji document_id=5339240099546673885>🇳🇪</emoji>", 566: "<emoji document_id=5411334930951073814>🇳🇬</emoji>", 570: "<emoji document_id=5285220307295031557>🇳🇺</emoji>", 574: "<emoji document_id=5285358304594250788>🇳🇫</emoji>",
578: "<emoji document_id=5280484839563212351>🇳🇴</emoji>", 580: "<emoji document_id=5282931570762601926>🇲🇵</emoji>", 583: "<emoji document_id=5231007765501067757>🇫🇲</emoji>", 584: "<emoji document_id=5283221498234949429>🇲🇭</emoji>", 585: "<emoji document_id=5222244507503833341>🇵🇼</emoji>", 586: "<emoji document_id=5280888059682894718>🇵🇰</emoji>", 591: "<emoji document_id=5269271835299560112>🇵🇦</emoji>", 598: "<emoji document_id=5283029023570548518>🇵🇬</emoji>",
600: "<emoji document_id=5426992955783134297>🇵🇾</emoji>", 604: "<emoji document_id=5384282890458641680>🇵🇪</emoji>", 608: "<emoji document_id=5280749714491323863>🇵🇭</emoji>", 612: "<emoji document_id=5283000303124239264>🇵🇳</emoji>", 616: "<emoji document_id=5281026263140545634>🇵🇱</emoji>", 620: "<emoji document_id=5280644320288847664>🇵🇹</emoji>", 624: "<emoji document_id=5429574437286454077>🇬🇼</emoji>", 626: "<emoji document_id=6323296525300532878>🇹🇱</emoji>",
630: "<emoji document_id=5280574832012980688>🇵🇷</emoji>", 634: "<emoji document_id=5280777271001493687>🇶🇦</emoji>", 638: "<emoji document_id=6323079745416202005>🇷🇪</emoji>", 642: "<emoji document_id=6323204514216150852>🇷🇴</emoji>", 643: "<emoji document_id=5271720529298998083>🇷🇺</emoji>", 646: "<emoji document_id=6323209539327886855>🇷🇼</emoji>", 652: "<emoji document_id=5233616700435348314>🇧🇱</emoji>", 654: "<emoji document_id=6323458552941774129>🇸🇭</emoji>",
659: "<emoji document_id=5231087492978982103>🇰🇳</emoji>", 662: "<emoji document_id=5222280134257551597>🇱🇨</emoji>", 663: "🇲🇫", 666: "<emoji document_id=5231258308123313128>🇵🇲</emoji>", 670: "<emoji document_id=6323388948701775579>🇻🇨</emoji>", 674: "<emoji document_id=6323376317202957753>🇸🇲</emoji>", 678: "<emoji document_id=6320979540768196479>🇸🇹</emoji>", 682: "<emoji document_id=6323493926292424101>🇸🇦</emoji>",
686: "<emoji document_id=6320811418568361413>🇸🇳</emoji>", 688: "<emoji document_id=6323476999826310994>🇷🇸</emoji>", 690: "<emoji document_id=6321207715200763481>🇸🇨</emoji>", 694: "<emoji document_id=6323487479546512920>🇸🇱</emoji>", 702: "<emoji document_id=5280575772610803538>🇸🇬</emoji>", 703: "<emoji document_id=5280878928582423790>🇸🇰</emoji>", 705: "<emoji document_id=5280794605489503727>🇸🇮</emoji>", 706: "<emoji document_id=6323463621003183505>🇸🇴</emoji>",
710: "<emoji document_id=5280753120400387794>🇿🇦</emoji>", 716: "<emoji document_id=6323177576181270239>🇿🇼</emoji>", 724: "<emoji document_id=5280990636386825168>🇪🇸</emoji>", 736: "<emoji document_id=6323465695472388250>🇸🇩</emoji>", 737: "<emoji document_id=6321019913460779018>🇸🇸</emoji>", 740: "<emoji document_id=6323299484532999421>🇸🇷</emoji>", 748: "<emoji document_id=6321242508730828949>🇸🇿</emoji>", 752: "<emoji document_id=5280612481696282548>🇸🇪</emoji>",
756: "<emoji document_id=5280496161097005481>🇨🇭</emoji>", 760: "<emoji document_id=5384406040055920734>🇸🇾</emoji>", 762: "<emoji document_id=6323529454261896950>🇹🇯</emoji>", 764: "<emoji document_id=5280516132694931619>🇹🇭</emoji>", 768: "<emoji document_id=6323591757057492818>🇹🇬</emoji>", 772: "<emoji document_id=6320884540386576371>🇹🇰</emoji>", 776: "<emoji document_id=6323459330330855189>🇹🇴</emoji>", 780: "<emoji document_id=6323273787743668306>🇹🇹</emoji>",
784: "<emoji document_id=5280621904854528308>🇦🇪</emoji>", 788: "<emoji document_id=6323420903258457844>🇹🇳</emoji>", 792: "<emoji document_id=5280789515953255080>🇹🇷</emoji>", 795: "<emoji document_id=6323414482282350254>🇹🇲</emoji>", 796: "<emoji document_id=6323068728825087940>🇹🇨</emoji>", 798: "<emoji document_id=6321269455355643417>🇹🇻</emoji>", 800: "<emoji document_id=6323467039797150870>🇺🇬</emoji>", 804: "<emoji document_id=5280497565551311161>🇺🇦</emoji>",
818: "<emoji document_id=5355240729624982413>🇪🇬</emoji>", 826: "<emoji document_id=5280608440132057367>🇬🇧</emoji>", 831: "<emoji document_id=5285175008274960955>🇬🇬</emoji>", 832: "<emoji document_id=5283002721190826424>🇯🇪</emoji>", 833: "<emoji document_id=5282747346730375058>🇮🇲</emoji>", 840: "<emoji document_id=5280652115654494137>🇺🇸</emoji>", 854: "<emoji document_id=5474323070183285988>🇧🇫</emoji>", 858: "<emoji document_id=6323182231925819139>🇺🇾</emoji>",
860: "<emoji document_id=5280544719997253484>🇺🇿</emoji>", 862: "<emoji document_id=6323244040800175517>🇻🇪</emoji>", 876: "<emoji document_id=6323428208997828313>🇼🇫</emoji>", 882: "<emoji document_id=6323227281837786699>🇼🇸</emoji>", 887: "<emoji document_id=6323263256483858365>🇾🇪</emoji>", 894: "<emoji document_id=6323614928406054835>🇿🇲</emoji>", 90: "<emoji document_id=6323197496239588762>🇸🇧</emoji>", 92: "<emoji document_id=6321258954160604865>🇻🇬</emoji>",
104: "<emoji document_id=5283227558433806137>🇲🇲</emoji>", 132: "<emoji document_id=5233184244473283152>🇨🇻</emoji>", 144: "<emoji document_id=5445234523702844364>🇱🇰</emoji>", 162: "<emoji document_id=5377505921691828576>🇽🇰</emoji>", 166: "<emoji document_id=5283031196823998792>🇨🇨</emoji>",
}
@loader.tds
class DDNetStats(loader.Module):
"""Модуль для просмотра статистики игрока DDNet через ddstats.tw"""
strings = {
"name": "DDNetStats",
"no_args": "<emoji document_id=5980953710157632545>❌</emoji> <b>Укажите ник игрока!</b>",
"not_found": "<emoji document_id=5980953710157632545>❌</emoji> <b>Игрок не найден или ошибка API.</b>",
}
async def client_ready(self, client, db):
self.client = client
@loader.command()
async def ddstats(self, message):
"""<ник> — Показать статистику игрока DDNet"""
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"<b><emoji document_id=6032693626394382504>👤</emoji> Игрок: <code>{name}</code>\n\n"
f"<emoji document_id=5908961403917570106>📌</emoji> Профиль:\n"
f"<blockquote><b>Поинты:</b> <code>{points}</code>\n"
f"<b>Клан:</b> <code>{clan}</code>\n"
f"<b>Флаг:</b> {flag}\n"
f"<b>Скин:</b> <code>{skin}</code>\n"
f"<b>Дата информации:</b> <code>{last_seen}</code>\n"
"</blockquote>\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} - <code>{finished}/{total}</code>")
response += (
"<b><emoji document_id=5924720918826848520>📦</emoji> Прогресс по категориям:\n<blockquote expandable>"
+ "\n".join(completion_str) +
"</blockquote>\n\n</b>"
)
# ласт активность
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} (<code>{hours}мин.</code>)")
response += (
"<b><emoji document_id=5870729937215819584>⏰️</emoji> Последняя активность:\n<blockquote expandable>"
+ "\n".join(recent_str) +
"</blockquote>\n\n</b>"
)
# напарники
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} - <code>{team_rank} (ранг)</code>")
response += (
"<b><emoji document_id=6032693626394382504>👥</emoji> Любимые напарники:\n<blockquote expandable>"
+ "\n".join(teammates_str) +
"</blockquote>\n\n</b>"
)
# карты
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} - <code>{hours}ч</code>")
response += (
"<b><emoji document_id=5985479497586053461>🗺</emoji>Карты:\n<blockquote expandable>"
+ "\n".join(maps_str) +
"</blockquote>\n\n</b>"
)
# режимы
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} - <code>{hours}ч</code>")
response += (
"<b><emoji document_id=5908961403917570106>🎯</emoji>Режимы:\n<blockquote expandable>"
+ "\n".join(gametypes_str) +
"</blockquote>\n\n</b>"
)
# вся активность
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 += (
"<b><emoji document_id=5870729937215819584>📈</emoji> Общая активность:\n<blockquote expandable>"
f"Общее время: <code>{total_hours}ч</code>\n"
f"Среднее время игры: <code>{avg_hours}ч</code>\n"
f"Начал играть: <code>{start_date}</code>"
"</blockquote></b>"
)
await utils.answer(message, response)
except Exception as e:
await utils.answer(message, f"<emoji document_id=5980953710157632545>❌</emoji> <b>Ошибка:</b> <code>{str(e)}</code>")
@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"<b><emoji document_id=6032693626394382504>👤</emoji> Игрок: <code>{name}</code>\n\n"
f"<emoji document_id=5908961403917570106>📌</emoji> Профиль:\n"
f"<blockquote><b>Поинты:</b> <code>{points}</code>\n"
f"<b>Клан:</b> <code>{clan}</code>\n"
f"<b>Флаг:</b> {flag}\n"
f"<b>Скин:</b> <code>{skin}</code>\n"
f"<b>Дата информации:</b> <code>{last_seen}</code>\n"
"</blockquote>\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 += (
"<b><emoji document_id=5870729937215819584>📈</emoji> Общая активность:\n<blockquote expandable>"
f"Общее время: <code>{total_hours}ч</code>\n"
f"Среднее время игры: <code>{avg_hours}ч</code>\n"
f"Начал играть: <code>{start_date}</code>"
"</blockquote></b>"
)
await utils.answer(message, response)
except Exception as e:
await utils.answer(message, f"<emoji document_id=5980953710157632545>❌</emoji> <b>Ошибка:</b> <code>{str(e)}</code>")

View File

@@ -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("❌ Обновление статуса выключено.")

View File

@@ -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))

View File

@@ -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

View File

@@ -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"<b>Информация об моем 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}</b>", parse_mode="html")
else:
await event.reply("❌ Ошибка при запросе к FACEIT API")

View File

@@ -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('😄 Выжил! Остаюсь в чате.')

View File

@@ -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": "<emoji document_id=4958526153955476488>❌</emoji> Используйте в формате: <code>.sendgift @username текст</code>",
"checking_user": "<emoji document_id=5206634672204829887>🔍</emoji> Проверка пользователя...",
"user_not_found": "<emoji document_id=4958526153955476488>❌</emoji> Пользователь не найден",
"gift_menu": "<emoji document_id=5931696400982088015>🎁</emoji> Выберите подарок.\n\n<emoji document_id=6032693626394382504>👤</emoji> Пользователь: {}\n<emoji document_id=5873153278023307367>📄</emoji> Текст: {}",
"sending_gift": "<emoji document_id=5201691993775818138>🛫</emoji> Отправка подарка...",
"gift_sent": "<emoji document_id=5021905410089550576>✅</emoji> Подарок успешно отправлен!",
"not_enough_stars": "<emoji document_id=4958526153955476488>❌</emoji> Недостаточно звезд для отправки подарка {}!",
}
gifts = [
[
{"id": 5170145012310081615, "stars": 15, "emoji": "❤️", "name": "Сердце"},
{"id": 5170233102089322756, "stars": 15, "emoji": "🧸", "name": "Мишка"},
{"id": 5170250947678437525, "stars": 25, "emoji": "🎁", "name": "Подарок"},
],
[
{"id": 5168103777563050263, "stars": 25, "emoji": "🌹", "name": "Роза"},
{"id": 5170144170496491616, "stars": 50, "emoji": "🎂", "name": "Тортик"},
{"id": 5170314324215857265, "stars": 50, "emoji": "💐", "name": "Цветы"},
],
[
{"id": 5170564780938756245, "stars": 50, "emoji": "🚀", "name": "Ракета"},
{"id": 5168043875654172773, "stars": 100, "emoji": "🏆", "name": "Кубок"},
{"id": 5170690322832818290, "stars": 100, "emoji": "💍", "name": "Кольцо"},
]
]
async def client_ready(self, client, db):
self.client = client
@loader.command()
async def sendgift(self, message):
"""Отправить подарок пользователю"""
args = utils.get_args_raw(message)
if not args:
await utils.answer(message, self.strings["usage"])
return
parts = args.split(maxsplit=1)
if len(parts) < 1:
await utils.answer(message, self.strings["usage"])
return
username = parts[0]
text = parts[1] if len(parts) > 1 else ""
if username.startswith('@'):
username = username[1:]
msg = await utils.answer(message, self.strings["checking_user"])
try:
user = await self.client.get_entity(username)
except Exception as e:
logging.error(f"User not found: {e}")
await utils.answer(msg, self.strings["user_not_found"])
return
buttons = []
for row in self.gifts:
btn_row = []
for gift in row:
btn_row.append({
"text": gift["emoji"],
"callback": self._send_gift,
"args": (user.id, gift["id"], text, gift["emoji"], msg.id),
})
buttons.append(btn_row)
await utils.answer(
msg,
self.strings["gift_menu"].format(
f"@{user.username}" if user.username else user.first_name,
text if text else "-"
),
reply_markup=buttons
)
async def _send_gift(self, call, user_id, gift_id, text, gift_emoji, msg_id):
try:
await call.edit(
self.strings["sending_gift"],
reply_markup=None
)
user = await self.client.get_input_entity(user_id)
inv = InputInvoiceStarGift(
user,
gift_id,
message=TextWithEntities(text, []) if text else TextWithEntities("", [])
)
form = await self.client(GetPaymentFormRequest(inv))
result = await self.client(SendStarsFormRequest(form.form_id, inv))
await call.edit(self.strings["gift_sent"])
except BadRequestError as e:
if "BALANCE_TOO_LOW" in str(e):
await call.edit(
self.strings["not_enough_stars"].format(gift_emoji),
reply_markup=None
)
else:
logging.error(f"Error sending gift: {e}")
await call.edit(
f"❌ Ошибка при отправке подарка: {str(e)}",
reply_markup=None
)
except Exception as e:
logging.error(f"Error sending gift: {e}")
await call.edit(
f"❌ Ошибка при отправке подарка: {str(e)}",
reply_markup=None
)
# эрон Дон Дон

View File

@@ -0,0 +1,119 @@
__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/B0ze.png
import aiohttp
import asyncio
from telethon import events
from .. import loader, utils
@loader.tds
class SteamProfile(loader.Module):
"""Модуль для получения информации о пользователях Steam."""
strings = {"name": "Steam Profile"}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"api_key",
"",
lambda: "Ваш API ключ Steam (https://steamcommunity.com/dev/apikey)",
validator=loader.validators.Hidden(),
),
loader.ConfigValue(
"show_games",
True,
lambda: "Показ игр пользователя (True/False)",
validator=loader.validators.Boolean(),
),
)
async def steamprofilecmd(self, event):
"""Получить информацию об пользователе Steam."""
args = utils.get_args_raw(event)
if not args:
await event.edit("❌ Укажите никнейм Steam после команды.")
return
api_key = self.config.get("api_key")
if not api_key:
await event.edit("❌ API KEY неуказан в cfg! (https://steamcommunity.com/dev/apikey)")
return
persona_name = args.strip()
await event.edit("⏱️ Получаю информацию...")
await asyncio.sleep(5)
steam_id = await self.get_steam_id(api_key, persona_name)
if steam_id:
player_info = await self.get_player_info(api_key, steam_id)
owned_games = await self.get_owned_games(api_key, steam_id)
if player_info is None or 'response' not in player_info or 'players' not in player_info['response']:
await event.edit("❌ Ошибка: Не удалось получить информацию о пользователе.")
return
response_message = await self.send_profile_info(event, player_info, owned_games)
await event.edit(response_message)
else:
await event.edit("❌ Ошибка: Никнейм не найден.")
async def get_steam_id(self, api_key, persona_name):
url = f"https://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key={api_key}&vanityurl={persona_name}"
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
data = await response.json()
if data['response']['success'] == 1:
return data['response']['steamid']
return None
async def get_player_info(self, api_key, steam_id):
url = f"https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={api_key}&steamids={steam_id}"
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
return await response.json()
return None
async def get_owned_games(self, api_key, steam_id):
url = f"https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key={api_key}&steamid={steam_id}&include_appinfo=true&include_played_free_games=true"
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
return await response.json()
return None
async def send_profile_info(self, event, player_info, owned_games):
if player_info is None or 'response' not in player_info or 'players' not in player_info['response']:
return "❌ Нет информации о пользователе."
player = player_info['response']['players'][0]
response = f"<b>Информация о пользователе:</b>\n"
response += f"👤 Ник: {player['personaname']}\n"
response += f"🔗 URL: {player['profileurl']}\n"
response += f"🧑 Настоящее имя: {player.get('realname', 'Не указано')}\n"
response += f"🔒 Видимость профиля: {'Открытый' if player['communityvisibilitystate'] == 3 else 'Закрытый'}\n"
response += f"💬 Статус: {'Онлайн' if player['personastate'] == 1 else 'Оффлайн'}\n"
response += f"🌍 Страна: {player.get('loccountrycode', 'Не указано')}\n"
response += f"🖼️ Аватарка: {player['avatarfull']}\n\n"
if self.config.get("show_games") and owned_games and 'games' in owned_games['response']:
response += "<b>Показ игр пользователя:</b>\n"
for game in owned_games['response']['games']:
hours_played = game['playtime_forever'] / 60
response += f" - {game['name']} (Время игры: {hours_played:.2f} часов)\n"
return response if response else "❌ Нет информации о пользователе."

View File

@@ -0,0 +1,271 @@
__version__ = (1, 0, 0)
# ███╗░░░███╗███████╗░█████╗░██████╗░░█████╗░░██╗░░░░░░░██╗░██████╗░██████╗
# ████╗░████║██╔════╝██╔══██╗██╔══██╗██╔══██╗░██║░░██╗░░██║██╔════╝██╔════╝
# ██╔████╔██║█████╗░░███████║██║░░██║██║░░██║░╚██╗████╗██╔╝╚█████╗░╚█████╗░
# ██║╚██╔╝██║██╔══╝░░██╔══██║██║░░██║██║░░██║░░████╔═████║░░╚═══██╗░╚═══██╗
# ██║░╚═╝░██║███████╗██║░░██║██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██████╔╝██████╔╝
# ╚═╝░░░░░╚═╝╚══════╝╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═════╝░╚═════╝░
# © Copyright 2025
# ✈ https://t.me/mead0wssMods
# scope: hikka_only
# scope: hikka_min 1.3.3
# meta developer: @mead0wssMods
import aiohttp
from .. import loader, utils
@loader.tds
class TwitchMod(loader.Module):
"""Модуль для работы с Twitch"""
strings = {"name": "Twitch"}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"CLIENT_ID",
"",
lambda: "Client ID из Twitch Dev Console [https://dev.twitch.tv/console/]",
validator=loader.validators.Hidden()
),
loader.ConfigValue(
"ACCESS_TOKEN",
"",
lambda: "Access Token с scope user:read:follows [https://twitchtokengenerator.com/]",
validator=loader.validators.Hidden()
),
loader.ConfigValue(
"TARGET_USERNAME",
"",
lambda: "Ваш никнейм пользователя Twitch [https://www.twitch.tv/",
validator=loader.validators.Hidden()
),
)
self.session = aiohttp.ClientSession()
async def client_ready(self, client, db):
self._client = client
async def get_user_id(self, username=None):
"""Получаем ID пользователя"""
url = "https://api.twitch.tv/helix/users"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"login": username or self.config["TARGET_USERNAME"]}
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data["data"][0]["id"] if data.get("data") else None
async def get_all_followed(self, user_id):
"""Получаем всех подписанных стримеров"""
url = "https://api.twitch.tv/helix/channels/followed"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"user_id": user_id}
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data.get("data", [])
async def get_live_streams(self, logins=None, game_id=None, limit=100):
"""Получаем онлайн стримы"""
url = "https://api.twitch.tv/helix/streams"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"first": limit}
if logins:
params["user_login"] = logins[:100]
if game_id:
params["game_id"] = game_id
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data.get("data", [])
async def get_top_games(self, limit=10):
"""Получаем топ игр"""
url = "https://api.twitch.tv/helix/games/top"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"first": limit}
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data.get("data", [])
async def search_games(self, query):
"""Поиск игр по названию"""
url = "https://api.twitch.tv/helix/search/categories"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"query": query}
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data.get("data", [])
async def get_channel_info(self, broadcaster_id):
"""Получаем информацию о канале"""
url = "https://api.twitch.tv/helix/channels"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"broadcaster_id": broadcaster_id}
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data.get("data", [{}])[0]
async def get_channel_followers(self, broadcaster_id):
"""Получаем количество фолловеров канала"""
url = "https://api.twitch.tv/helix/channels/followers"
headers = {
"Client-ID": self.config["CLIENT_ID"],
"Authorization": f"Bearer {self.config['ACCESS_TOKEN']}"
}
params = {"broadcaster_id": broadcaster_id, "first": 1}
async with self.session.get(url, headers=headers, params=params) as resp:
data = await resp.json()
return data.get("total", 0)
@loader.command()
async def followed(self, message):
"""Показать всех подписанных стримеров"""
user_id = await self.get_user_id()
if not user_id:
await utils.answer(message, "<emoji document_id=5019523782004441717>❌</emoji> Пользователь не найден!")
return
followed = await self.get_all_followed(user_id)
if not followed:
await utils.answer(message, "<emoji document_id=5190748314026385859>🤷‍♂️</emoji> Нет подписок")
return
text = "<emoji document_id=4999434394599948988>🎮</emoji> Каналы на которые зафолловлен:\n\n"
for channel in followed[:25]:
followers_count = await self.get_channel_followers(channel["broadcaster_id"])
text += (f"<emoji document_id=5944753741512052670>📷</emoji> <b><a href='https://twitch.tv/{channel['broadcaster_login']}'>"
f"{channel['broadcaster_name']}</a></b> [<emoji document_id=6032609071373226027>👥</emoji> <code>{followers_count}</code> Фолловеров]\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, "<emoji document_id=5019523782004441717>❌</emoji> Пользователь не найден!")
return
followed = await self.get_all_followed(user_id)
if not followed:
await utils.answer(message, "<emoji document_id=5190748314026385859>🤷‍♂️</emoji> Нет подписок")
return
logins = [channel["broadcaster_login"] for channel in followed]
live_streams = await self.get_live_streams(logins[:100])
if not live_streams:
await utils.answer(message, "<emoji document_id=4926956800005112527>🔴</emoji> Сейчас никто не стримит")
return
text = "<emoji document_id=4999434394599948988>🎮</emoji> Стримеры ведущие трансляцию:\n"
for stream in live_streams:
channel_info = await self.get_channel_info(stream["user_id"])
followers_count = await self.get_channel_followers(stream["user_id"])
text += (f'\n<b><emoji document_id=5879770735999717115>👤</emoji> <a href="https://twitch.tv/{stream["user_login"]}">{stream["user_name"]}</a></b>'
f'<b><blockquote><emoji document_id=5348214678524805365>🎮</emoji> {stream["game_name"]}\n'
f'<emoji document_id=6037397706505195857>👁</emoji> <code>{stream["viewer_count"]}</code> зрителей\n'
f'<emoji document_id=6032609071373226027>👥</emoji> <code>{followers_count}</code> фолловеров\n'
f'<emoji document_id=5879785854284599288></emoji> {stream["title"]}\n</blockquote></b>')
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, "<emoji document_id=5019523782004441717>❌</emoji> Укажите ник стримера")
return
user_id = await self.get_user_id(args)
if not user_id:
await utils.answer(message, f"<emoji document_id=5019523782004441717>❌</emoji> Стример {args} не найден")
return
channel_info = await self.get_channel_info(user_id)
followers_count = await self.get_channel_followers(user_id)
text = (f"<emoji document_id=4999434394599948988>🎮</emoji> <b>Информация о:</b>\n\n <b><emoji document_id=5879770735999717115>👤</emoji> <a href='https://twitch.tv/{args}'>{args}</a></b>:\n"
f"<b><blockquote><emoji document_id=6032609071373226027>👥</emoji> Фолловеров: <code>{followers_count}</code>\n"
f"<emoji document_id=5879785854284599288></emoji> Описание стрима (пусто = офф): <code>{channel_info.get('title', 'Нет описания')}</code>\n"
f"<blockquote><emoji document_id=5348214678524805365>🎮</emoji> Игра на стриме: <code>{channel_info.get('game_name', 'Не указана')}</code> \n"
f"<emoji document_id=6028171274939797252>🔗</emoji> Ссылка: https://twitch.tv/{args}</b></blockquote>")
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, "<emoji document_id=5019523782004441717>❌</emoji> Не удалось получить список игр")
return
text = "<emoji document_id=4999434394599948988>🎮</emoji> Топ игр на Twitch:\n\n"
text += "\n".join(
f"<b><blockquote>{i+1}. {game['name']} (ID: <code>{game['id']}</code>)</blockquote></b>"
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, "<emoji document_id=5019523782004441717>❌</emoji> Укажите название игры")
return
games = await self.search_games(args)
if not games:
await utils.answer(message, f"<emoji document_id=5019523782004441717>❌</emoji> Игра '{args}' не найдена")
return
game = games[0]
streams = await self.get_live_streams(game_id=game["id"])
text = (f"<emoji document_id=5348214678524805365>🎮</emoji> Игра: {game['name']}\n"
f"<emoji document_id=6028171274939797252>🔗</emoji> Изображение: {game['box_art_url'].replace('{width}x{height}', '300x400')}\n\n")
if streams:
text += f"<emoji document_id=4999434394599948988>🎮</emoji> Топ стримов ({len(streams)} онлайн):\n\n"
for stream in streams[:5]:
followers_count = await self.get_channel_followers(stream["user_id"])
text += (f'<b><emoji document_id=5879770735999717115>👤</emoji> <a href="https://twitch.tv/{stream["user_login"]}">{stream["user_name"]}</a>\n'
f'<blockquote><emoji document_id=6037397706505195857>👁</emoji> <code>{stream["viewer_count"]}</code> зрителей\n'
f'<emoji document_id=6032609071373226027>👥</emoji> <code>{followers_count}</code> фолловеров\n'
f'<emoji document_id=5879785854284599288></emoji>{stream["title"]}\n</blockquote></b>')
else:
text += "Сейчас никто не стримит эту игру"
await utils.answer(message, text)

View File

@@ -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": "<emoji document_id=5307779382499090971>🫥</emoji> <b>Uploading file...</b>",
"reply_to_file": "<emoji document_id=4958526153955476488>❌</emoji> <b>Reply to file!</b>",
"uploaded": "<emoji document_id=5278611606756942667>❤️</emoji> <b>Successful! File uploaded!</b>\n\n<emoji document_id=5278305362703835500>🔗</emoji> <b>URL:</b> <code>{}</code>",
"error": "<emoji document_id=4958526153955476488>❌</emoji> <b>Error while uploading: {}</b>"
}
# стринги (не мои)
strings_ru = {
"name": "tmpfiles",
"uploading": "<emoji document_id=5307779382499090971>🫥</emoji> <b>Загружаю файл...</b>",
"reply_to_file": "<emoji document_id=4958526153955476488>❌</emoji> <b>Ответьте на файл!</b>",
"uploaded": "<emoji document_id=5278611606756942667>❤️</emoji> <b>Файл успешно загружен!</b>\n\n<emoji document_id=5278305362703835500>🔗</emoji> <b>URL:</b> <code>{}</code>",
"error": "<emoji document_id=4958526153955476488>❌</emoji> <b>Ошибка при загрузке: {}</b>"
}
async def _get_file(self, message): # helper
"""Helper to get file from message"""
reply = await message.get_reply_message()
if not reply:
await utils.answer(message, self.strings["reply_to_file"])
return None
if reply.media:
file = io.BytesIO(await self.client.download_media(reply.media, bytes))
if hasattr(reply.media, "document"):
file.name = reply.file.name or f"file_{reply.file.id}"
else:
file.name = f"file_{reply.id}.jpg"
else:
file = io.BytesIO(bytes(reply.raw_text, "utf-8"))
file.name = "text.txt"
return file
@loader.command(
ru_doc = "Загрузка ваших файлов на tmpfiles.org", #loader
en_doc = "Uploading your files to tmpfiles.org"
)
async def tmpfilescmd(self, message): # upload files
await utils.answer(message, self.strings["uploading"])
file = await self._get_file(message)
if not file:
return
try:
response = requests.post(
"https://tmpfiles.org/api/v1/upload", # requests
files={"file": file}
)
if response.ok:
data = json.loads(response.text)
url = data["data"]["url"]
await utils.answer(message, self.strings["uploaded"].format(url))
else:
await utils.answer(message, self.strings["error"].format(response.status_code))
except Exception as e:
await utils.answer(message, self.strings["error"].format(str(e)))
# Структура модуля (да и сама логика) взята с K:Uploader <3

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

View File

@@ -1,6 +1,7 @@
caliases caliases
deleter deleter
privacy privacy
sdsaver
tidal tidal
warpigs warpigs
yamusic yamusic

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,120 @@
__version__ = (1, 0, 0)
# █▄▀ ▄▀█ █▀▄▀█ █▀▀ █▄▀ █ █ █▀█ █▀█
# █ █ █▀█ █ ▀ █ ██▄ █ █ ▀▄▄▀ █▀▄ █▄█ ▄
# © Copyright 2025
# ✈ https://t.me/kamekuro
# 🔒 Licensed under CC-BY-NC-ND 4.0 unless otherwise specified.
# 🌐 https://creativecommons.org/licenses/by-nc-nd/4.0
# + attribution
# + non-commercial
# + no-derivatives
# You CANNOT edit, distribute or redistribute this file without direct permission from the author.
# meta banner: https://raw.githubusercontent.com/kamekuro/hikka-mods/main/banners/sdsaver.png
# meta pic: https://raw.githubusercontent.com/kamekuro/hikka-mods/main/icons/sdsaver.png
# meta developer: @kamekuro_hmods
# scope: hikka_min 1.7.0
import aiohttp
import asyncio
import io
import json
import logging
import random
import requests
import string
import aiogram
import telethon
from .. import loader, utils
logger = logging.getLogger(__name__)
@loader.tds
class SDSaverMod(loader.Module):
"""The module for automatically saving self-destructing media"""
strings = {
"name": "SDSaver",
"sdmode_on": "<emoji document_id=5769230088960741619>🔥</emoji> <b>Automatic saving self-destructing media is enabled</b>",
"sdmode_off": "<emoji document_id=5769230088960741619>🔥</emoji> <b>Automatic saving self-destructing media is disabled</b>",
"sd": "🔥 <b><a href=\"{link}\">{name}</a> sent self-destructing media:</b>\n{caption}"
}
strings_ru = {
"_cls_doc": "Модуль для автоматического сохранения самоуничтожающихся медиа",
"sdmode_on": "<emoji document_id=5769230088960741619>🔥</emoji> <b>Автоматическое сохранение самоуничтожающихся медиа включено</b>",
"sdmode_off": "<emoji document_id=5769230088960741619>🔥</emoji> <b>Автоматическое сохранение самоуничтожающихся медиа выключено</b>",
"sd": "🔥 <b><a href=\"{link}\">{name}</a> отправил(а) самоуничтожающееся медиа:</b>\n{caption}"
}
async def client_ready(self, client, db):
self._client = client
self._db = db
channel, _ = await utils.asset_channel(
self._client,
"heroku-sd",
"Self-destruction media will appear there",
invite_bot=True,
avatar="https://i.pinimg.com/originals/6c/1e/cf/6c1ecf3afca663a9ebc0b18788b337ee.jpg",
_folder="heroku",
)
self._channel = int(f"-100{channel.id}")
@loader.command(
ru_doc="👉 Включить/Выключить автоматическое сохранение самоуничтожающихся медиа"
)
async def sdmodecmd(self, message: telethon.types.Message):
"""👉 Enable/Disable automatic saving self-destructing media"""
need_mode = not self.get("save_sd", True)
self.set("save_sd", need_mode)
await utils.answer(
message, self.strings(f"sdmode_{'on' if need_mode else 'off'}")
)
@loader.watcher("in", only_messages=True)
async def watcher(self, message: telethon.types.Message):
if (
not self.get("save_sd", True)
) or (
not message.media
) or (
not getattr(message.media, "ttl_seconds", None)
):
return
try:
sender = await self.client.get_entity(message.sender_id, exp=0)
except Exception:
sender = await message.get_sender()
media = await self.client.download_media(message.media, bytes)
args = {
"chat_id": self._channel,
"caption": self.strings("sd").format(
link=utils.get_entity_url(sender),
name=utils.escape_html(telethon.utils.get_display_name(sender)),
caption=message.text if message.text else ''
)
}
if message.photo:
args['photo'] = aiogram.types.BufferedInputFile(media, "sd.png")
method = self.inline.bot.send_photo
if message.video or message.video_note:
args['video'] = aiogram.types.BufferedInputFile(media, "sd.mp4")
method = self.inline.bot.send_video
if message.voice:
args['voice'] = aiogram.types.BufferedInputFile(media, "sd.ogg")
method = self.inline.bot.send_voice
await method(**args)