Compare commits

...

2 Commits

Author SHA1 Message Date
github-actions[bot]
850dd58628 Updated modules.json after parse 2026-04-14 01:57:03 2026-04-14 01:57:03 +00:00
github-actions[bot]
192adeabc3 Added and updated repositories 2026-04-14 01:56:34 2026-04-14 01:56:34 +00:00
6 changed files with 416 additions and 69 deletions

View File

@@ -100,18 +100,6 @@ class MInstaller:
return "dependency", [] return "dependency", []
async def pip(self, dependencies: List[str]) -> bool:
virtualenv = hasattr(sys, 'real_prefix') or sys.prefix != getattr(sys, 'base_prefix', sys.prefix)
flags = ["--user"] if loader.USER_INSTALL and not virtualenv else []
process = await asyncio.create_subprocess_exec(
sys.executable, "-m", "pip", "install", "-U", "-q",
"--disable-pip-version-check", "--no-warn-script-location",
*flags, *dependencies
)
return await process.wait() == 0
async def load(self, plugin: 'loader.Module', code: str, origin: str, step: int) -> Union[str, List[str]]: async def load(self, plugin: 'loader.Module', code: str, origin: str, step: int) -> Union[str, List[str]]:
if step == 0: if step == 0:
try: try:
@@ -121,7 +109,7 @@ class MInstaller:
)) ))
if dependencies: if dependencies:
if not await self.pip(dependencies): if not await plugin.install_requirements(dependencies):
return dependencies return dependencies
importlib.invalidate_caches() importlib.invalidate_caches()
return "retry" return "retry"
@@ -171,7 +159,7 @@ class MInstaller:
alternative = {"sklearn": "scikit-learn", "pil": "Pillow", "herokutl": "Heroku-TL-New"}.get(exception.name.lower(), exception.name) alternative = {"sklearn": "scikit-learn", "pil": "Pillow", "herokutl": "Heroku-TL-New"}.get(exception.name.lower(), exception.name)
dependencies = [alternative] dependencies = [alternative]
if not alternative or not await self.pip(dependencies): if not alternative or not await plugin.install_requirements(dependencies):
return dependencies return dependencies
importlib.invalidate_caches() importlib.invalidate_caches()

View File

@@ -0,0 +1,298 @@
__version__ = (1, 0, 0)
# meta developer: @FModules
# meta banner: https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/FSecurity/banner.png
# scope: hikka_min 2.0.0
# ©️ Fixyres, 2024-2030
# 🌐 https://github.com/Fixyres/FModules
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 🔑 http://www.apache.org/licenses/LICENSE-2.0
import asyncio
import aiohttp
import html
import sys
import uuid
import copy
from contextlib import suppress
from .. import loader, utils
@loader.tds
class FSecurity(loader.Module):
"""Module for automatic AI-based security checks of installed modules."""
strings = {
"name": "FSecurity",
"lang": "en",
"unavailable": "AI module check is unavailable.",
"suspicious": "AI interrupted installation of a suspicious module, reason:",
"blocked": "AI blocked module installation, reason:",
"continue": "Continue installation?"
}
strings_ru = {
"lang": "ru",
"_cls_doc": "Модуль для автоматической проверки устанавливаемых модулей через ИИ.",
"unavailable": "Проверка модуля через ИИ недоступна.",
"suspicious": "ИИ прервал установку подозрительного модуля, причина:",
"blocked": "ИИ заблокировал установку модуля, причина:",
"continue": "Продолжить установку?"
}
strings_ua = {
"lang": "ua",
"_cls_doc": "Модуль для автоматичної перевірки встановлюваних модулів через ШІ.",
"unavailable": "Перевірка модуля через ШІ недоступна.",
"suspicious": "ШІ перервав встановлення підозрілого модуля, причина:",
"blocked": "ШІ заблокував встановлення модуля, причина:",
"continue": "Продовжити встановлення?"
}
strings_de = {
"lang": "de",
"_cls_doc": "Modul zur automatischen Prüfung installierter Module mit KI.",
"unavailable": "Die KI-Modulprüfung ist nicht verfügbar.",
"suspicious": "Die KI hat die Installation eines verdächtigen Moduls unterbrochen, Grund:",
"blocked": "Die KI hat die Modulinstallation blockiert, Grund:",
"continue": "Installation fortsetzen?"
}
strings_jp = {
"lang": "jp",
"_cls_doc": "AIでインストールされるモジュールを自動チェックするモジュール。",
"unavailable": "AIモジュールのチェックが利用できません。",
"suspicious": "AIが疑わしいモジュールのインストールを中断しました、理由",
"blocked": "AIがモジュールのインストールをブロックしました、理由",
"continue": "インストールを続行しますか?"
}
strings_tr = {
"lang": "tr",
"_cls_doc": "Kurulan modülleri yapay zeka ile otomatik kontrol eden modül.",
"unavailable": "Yapay zeka modül kontrolü kullanılamıyor.",
"suspicious": "Yapay zeka şüpheli bir modülün kurulumunu durdurdu, sebep:",
"blocked": "Yapay zeka modül kurulumunu engelledi, sebep:",
"continue": "Kuruluma devam edilsin mi?"
}
strings_uz = {
"lang": "uz",
"_cls_doc": "O'rnatilayotgan modullarni AI orqali avtomatik tekshiruvchi modul.",
"unavailable": "AI modul tekshiruvi mavjud emas.",
"suspicious": "AI shubhali modul o'rnatilishini to'xtatdi, sabab:",
"blocked": "AI modul o'rnatilishini blokladi, sabab:",
"continue": "O'rnatishni davom ettirasizmi?"
}
strings_kz = {
"lang": "kz",
"_cls_doc": "Орнатылатын модульдерді ЖИ арқылы автоматты тексеретін модуль.",
"unavailable": "AI модульін тексеру қолжетімсіз.",
"suspicious": "AI күдікті модульді орнатуды тоқтатты, себебі:",
"blocked": "AI модульді орнатуды бұғаттады, себебі:",
"continue": "Орнатуды жалғастырасыз ба?"
}
def __init__(self):
self.tasks = {}
self.oreg = None
self.oload = None
async def client_ready(self, client, db):
self.core = self.lookup("loader")
self.modules = self.core.allmodules
self.patch()
async def on_unload(self):
self.unpatch()
async def check(self, code):
try:
form = aiohttp.FormData()
form.add_field('file', code.encode('utf-8'), filename='module.py', content_type='text/x-python')
form.add_field('lang', self.strings("lang") or "en")
async with aiohttp.ClientSession() as session:
async with session.post("https://api.fixyres.com/check", data=form, timeout=30) as resp:
if resp.status != 200:
return False
return await resp.json()
except Exception:
return False
def format(self, state, reason=""):
if state == "unavailable":
return f'<b>{self.strings("unavailable")}</b>\n<b>{self.strings("continue")}</b>'
if state == "suspicious":
return f'<b>{self.strings("suspicious")}</b>\n<blockquote expandable>{utils.escape_html(reason)}</blockquote>\n<b>{self.strings("continue")}</b>'
return f'<b>{self.strings("blocked")}</b>\n<blockquote expandable>{utils.escape_html(reason)}</blockquote>'
def buttons(self, task):
return [[
{"text": "", "callback": self.confirm, "args": (task, "yes")},
{"text": "", "callback": self.confirm, "args": (task, "no")}
]]
def patch(self):
if not self.oreg:
self.oreg = getattr(self.modules, "register_module")
if not self.oload:
self.oload = self.core.load_module
original = self.oload
async def load(_, *args, **kwargs):
base = utils.answer
async def answer(message, response, *a, **k):
if isinstance(response, str) and "😖</tg-emoji>" in response:
body = response.split("😖</tg-emoji>", 1)[1].strip()
if body in {"", "<b></b>", "<b> </b>"}:
with suppress(Exception):
if hasattr(message, "delete"):
await message.delete()
return message
if body.startswith("<b>") and body.endswith("</b>"):
decoded = html.unescape(body[3:-4])
response = response.split("😖</tg-emoji>", 1)[0] + f'😖</tg-emoji> {decoded}' if decoded else response.split("😖</tg-emoji>", 1)[0] + '😖</tg-emoji>'
return await base(message, response, *a, **k)
utils.answer = answer
try:
return await original(*args, **kwargs)
finally:
if utils.answer is answer:
utils.answer = base
self.core.load_module = load.__get__(self.core, self.core.__class__)
self.modules.register_module = self.register
def unpatch(self):
if self.oreg:
self.modules.register_module = self.oreg
if getattr(self, "core", None) and self.oload:
self.core.load_module = self.oload
def context(self):
frame = sys._getframe()
msg = None
fmsg = None
autoload = False
while frame:
locals = frame.f_locals
if (
frame.f_code.co_name == "load_module"
and locals.get("self") is self.core
and 'message' in locals
and hasattr(locals['message'], 'edit')
):
msg = locals['message']
fmsg = locals.get('msg')
break
if (
frame.f_code.co_name in {"_register_modules", "register_all"}
and locals.get("self") is self.modules
):
autoload = True
frame = frame.f_back
return msg, fmsg, autoload
def target_chat(self, msg=None, fmsg=None):
if msg:
with suppress(Exception):
target = copy.copy(msg)
if fmsg:
target.reply_to_msg_id = fmsg.id
elif not getattr(target, 'reply_to_msg_id', None):
target.reply_to_msg_id = target.id
return target
return None
async def register(self, spec, name, origin="<core>", save_fs=False):
if origin != "<core>" and name != self.__module__:
code = ""
if hasattr(spec.loader, "data") and spec.loader.data:
code = spec.loader.data
if isinstance(code, bytes):
code = code.decode("utf-8", errors="ignore")
elif origin and origin.endswith(".py"):
with suppress(Exception):
with open(origin, "r", encoding="utf-8") as f:
code = f.read()
if code:
check = await self.check(code)
if check is not True:
msg, fmsg, autoload = self.context()
target = self.target_chat(msg, fmsg)
if isinstance(check, dict):
status = check.get("level", "blocked")
reason = check.get("reason", "")
else:
status = "unavailable"
reason = ""
if autoload:
return await self.oreg(spec, name, origin, save_fs=save_fs)
if not msg or not target:
raise loader.LoadError("")
if msg:
with suppress(Exception):
msg.out = False
if status == "blocked":
text = self.format("blocked", reason)
raise loader.LoadError(text)
task = str(uuid.uuid4())
event = asyncio.Event()
self.tasks[task] = {"event": event, "decision": False}
try:
form = await self.inline.form(
text=self.format(status, reason),
message=target,
reply_markup=self.buttons(task)
)
if not form:
raise loader.LoadError(reason)
await asyncio.wait_for(event.wait(), timeout=60.0)
if not self.tasks.pop(task)["decision"]:
with suppress(Exception):
await form.delete()
raise loader.LoadError("")
except asyncio.TimeoutError:
self.tasks.pop(task, None)
with suppress(Exception):
await form.delete()
raise loader.LoadError("")
except loader.LoadError:
raise
except Exception:
raise loader.LoadError("")
return await self.oreg(spec, name, origin, save_fs=save_fs)
async def confirm(self, call, task, action):
if task in self.tasks:
self.tasks[task]["decision"] = (action == "yes")
self.tasks[task]["event"].set()
with suppress(Exception):
await call.delete()

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View File

@@ -1,9 +1,8 @@
#Midga3 #Midga3
#Placeholder system is the best #Placeholder system is the best
# meta banner: https://github.com/Midga3/heroku-modules/blob/main/new_module.jpg?raw=true
# meta developer: @midga3_modules # meta developer: @midga3_modules
__version__ = (1, 0, 0) __version__ = (1, 1, 2)
import logging import logging
import aiohttp import aiohttp
@@ -17,13 +16,20 @@ class PingEmoji(loader.Module):
strings = { strings = {
"name": "PingEmoji" "name": "PingEmoji"
} }
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"emoji",
"<tg-emoji emoji-id=5276307163529092252>🔴</tg-emoji>",
"Ping Emoji",
)
)
async def client_ready(self, client, db): async def client_ready(self, client, db):
self._client = client self._client = client
utils.register_placeholder("ping_emoji", self.get_emoji) utils.register_placeholder("ping_emoji", self.get_emoji)
async def get_emoji(self, data): async def get_emoji(self, data):
if data['ping'] > 300: if data['ping'] > 300:
return "<tg-emoji emoji-id=5276307163529092252>🔴</tg-emoji>" return self.config['emoji']
else: else:
return "" return ""

View File

@@ -26,7 +26,7 @@ from typing import Optional, Dict, Any
from collections import OrderedDict from collections import OrderedDict
from .. import loader, utils, validators from .. import loader, utils, validators
from herokutl.tl.functions.users import GetFullUserRequest from telethon.tl.functions.users import GetFullUserRequest
from herokutl.tl.functions.payments import GetStarsStatusRequest from herokutl.tl.functions.payments import GetStarsStatusRequest
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -118,21 +118,23 @@ class PlaceholdersMod(loader.Module):
) )
self.cache = LRUCache(max_size=100, ttl=300) self.cache = LRUCache(max_size=100, ttl=300)
async def client_ready(self): async def client_ready(self, client, db):
self._client = client
self.session = aiohttp.ClientSession() self.session = aiohttp.ClientSession()
self.me = await self._client.get_me() self.me = await client.get_me()
self.full_me = await self._client(GetFullUserRequest(self.me)) self.full_me = await client(GetFullUserRequest(self.me))
try: try:
stars_status = await self._client(GetStarsStatusRequest(entity="me")) stars_status = await self._client(GetStarsStatusRequest(entity='me'))
self.stars_balance = stars_status.balance self.stars_balance = stars_status.balance
except Exception: except:
self.stars_balance = 0 self.stars_balance = 0
self.tz = timezone(timedelta(hours=self.config["timezone"])) self.tz = timezone(timedelta(hours=self.config["timezone"]))
self.weekdays_ru = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"] self.weekdays_ru = ["Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"]
# Регистрация плейсхолдеров
self._register_placeholders() self._register_placeholders()
def _register_placeholders(self): def _register_placeholders(self):
@@ -199,30 +201,18 @@ class PlaceholdersMod(loader.Module):
utils.register_placeholder(name, func, desc) utils.register_placeholder(name, func, desc)
async def get_premium_check(self): async def get_premium_check(self):
if not getattr(self.me, "premium", False): if not self.me.premium:
return "Нет Premium" return "Нет Premium"
# premium_until отсутствует в публичном MTProto API herokutl/Telethon — until = self.full_me.full_user.premium_until
# пробуем достать его, но не падаем если поля нет if not until or until < time.time():
until = None return "Премиум закончился"
try:
until = getattr(self.full_me.full_user, "premium_until", None)
# Иногда это datetime, иногда unix timestamp (int)
if isinstance(until, datetime):
until = until.timestamp()
except Exception:
until = None
if not until:
return "✅ Premium активен"
if until < time.time():
return "⚠️ Премиум истёк"
end_date = datetime.fromtimestamp(until, tz=self.tz) end_date = datetime.fromtimestamp(until, tz=self.tz)
days_left = (end_date.date() - datetime.now(self.tz).date()).days days_left = (end_date.date() - datetime.now(self.tz).date()).days
formatted = end_date.strftime("%d.%m.%Y") formatted = end_date.strftime("%d.%m.%Y")
return f"✅ до {formatted} (ещё {days_left} дн.)" return f"{formatted} (Осталось {days_left} дней)"
async def get_username(self): async def get_username(self):
return f"@{self.me.username}" if self.me.username else "Нет" return f"@{self.me.username}" if self.me.username else "Нет"
@@ -245,8 +235,10 @@ class PlaceholdersMod(loader.Module):
async def get_dc_id(self): async def get_dc_id(self):
return str(self.me.dc_id if hasattr(self.me, "dc_id") else "Неизвестно") return str(self.me.dc_id if hasattr(self.me, "dc_id") else "Неизвестно")
async def get_stars(self): async def get_stars(self):
return f"{self.stars_balance:,}".replace(",", " ") if self.stars_balance else "0" result = await self.client(GetStarsStatusRequest("me"))
stars = result.balance.amount if result and result.balance else 0
return f"{stars:,}".replace(",", " ") if stars else "0"
async def get_usd_to_rub(self): async def get_usd_to_rub(self):
cache_key = "usd_rub" cache_key = "usd_rub"
@@ -261,7 +253,7 @@ class PlaceholdersMod(loader.Module):
result = f"1 USD ≈ {rate:.2f} RUB" result = f"1 USD ≈ {rate:.2f} RUB"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
try: try:
async with self.session.get("https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.json") as resp: async with self.session.get("https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.json") as resp:
data = await resp.json() data = await resp.json()
@@ -269,7 +261,7 @@ class PlaceholdersMod(loader.Module):
result = f"1 USD ≈ {rate:.2f} RUB" result = f"1 USD ≈ {rate:.2f} RUB"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
return "Курс USD недоступен" return "Курс USD недоступен"
async def get_rub_to_usd(self): async def get_rub_to_usd(self):
@@ -278,7 +270,7 @@ class PlaceholdersMod(loader.Module):
try: try:
rate = float(usd_rub.split("")[1].strip().split()[0]) rate = float(usd_rub.split("")[1].strip().split()[0])
return f"1 RUB ≈ {1/rate:.4f} USD" return f"1 RUB ≈ {1/rate:.4f} USD"
except Exception: except:
pass pass
return "Курс RUB недоступен" return "Курс RUB недоступен"
@@ -301,7 +293,7 @@ class PlaceholdersMod(loader.Module):
result = f"1 TON ≈ {rate:.2f} RUB" result = f"1 TON ≈ {rate:.2f} RUB"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
return "Курс TON недоступен" return "Курс TON недоступен"
async def get_rub_to_ton(self): async def get_rub_to_ton(self):
@@ -310,7 +302,7 @@ class PlaceholdersMod(loader.Module):
try: try:
rate = float(ton_rub.split("")[1].strip().split()[0]) rate = float(ton_rub.split("")[1].strip().split()[0])
return f"1 RUB ≈ {1/rate:.6f} TON" return f"1 RUB ≈ {1/rate:.6f} TON"
except Exception: except:
pass pass
return "Курс недоступен" return "Курс недоступен"
@@ -327,7 +319,7 @@ class PlaceholdersMod(loader.Module):
result = f"1 BTC ≈ {rate:,.0f} RUB" result = f"1 BTC ≈ {rate:,.0f} RUB"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
return "Курс BTC недоступен" return "Курс BTC недоступен"
async def get_eth_to_rub(self): async def get_eth_to_rub(self):
@@ -343,7 +335,7 @@ class PlaceholdersMod(loader.Module):
result = f"1 ETH ≈ {rate:,.0f} RUB" result = f"1 ETH ≈ {rate:,.0f} RUB"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
return "Курс ETH недоступен" return "Курс ETH недоступен"
async def get_stars_to_rub(self): async def get_stars_to_rub(self):
@@ -373,7 +365,7 @@ class PlaceholdersMod(loader.Module):
sent_gb = net.bytes_sent // (1024**3) sent_gb = net.bytes_sent // (1024**3)
recv_gb = net.bytes_recv // (1024**3) recv_gb = net.bytes_recv // (1024**3)
return f"{sent_gb} GB │ ↓ {recv_gb} GB" return f"{sent_gb} GB │ ↓ {recv_gb} GB"
except Exception: except:
return "↑ 0 GB │ ↓ 0 GB" return "↑ 0 GB │ ↓ 0 GB"
async def get_speedtest(self): async def get_speedtest(self):
@@ -405,7 +397,7 @@ class PlaceholdersMod(loader.Module):
result = f"{speed_mbps:.1f} Mbps" result = f"{speed_mbps:.1f} Mbps"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
continue continue
return "Тест скорости недоступен" return "Тест скорости недоступен"
@@ -426,7 +418,7 @@ class PlaceholdersMod(loader.Module):
used_gb = usage.used // (1024**3) used_gb = usage.used // (1024**3)
total_gb = usage.total // (1024**3) total_gb = usage.total // (1024**3)
return f"{used_gb} GB / {total_gb} GB ({percent:.1f}%)" return f"{used_gb} GB / {total_gb} GB ({percent:.1f}%)"
except Exception: except:
return "Диск недоступен" return "Диск недоступен"
async def get_local_ip(self): async def get_local_ip(self):
@@ -436,7 +428,7 @@ class PlaceholdersMod(loader.Module):
ip = s.getsockname()[0] ip = s.getsockname()[0]
s.close() s.close()
return ip return ip
except Exception: except:
return "Неизвестно" return "Неизвестно"
async def get_user_hostname(self): async def get_user_hostname(self):
@@ -507,7 +499,7 @@ class PlaceholdersMod(loader.Module):
} }
self.cache.set(cache_key, weather_data) self.cache.set(cache_key, weather_data)
return weather_data return weather_data
except Exception: except:
pass pass
default = { default = {
@@ -595,7 +587,7 @@ class PlaceholdersMod(loader.Module):
result = f"🎵 {stats['playcount']} скробблов" result = f"🎵 {stats['playcount']} скробблов"
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
pass pass
return "Статистика недоступна" return "Статистика недоступна"
@@ -637,14 +629,10 @@ class PlaceholdersMod(loader.Module):
} }
self.cache.set(cache_key, result) self.cache.set(cache_key, result)
return result return result
except Exception: except:
pass pass
return None return None
async def on_unload(self): async def on_unload(self):
utils.unregister_placeholders(self.__class__.__name__) await self.session.close()
try:
await self.session.close()
except Exception:
pass

View File

@@ -8310,6 +8310,73 @@
"has_on_unload": true, "has_on_unload": true,
"class_cmd_names": {} "class_cmd_names": {}
}, },
"Fixyres/FModules/FSecurity.py": {
"name": "FSecurity",
"description": "Module for automatic AI-based security checks of installed modules.",
"cls_doc": {
"ru": "Модуль для автоматической проверки устанавливаемых модулей через ИИ.",
"ua": "Модуль для автоматичної перевірки встановлюваних модулів через ШІ.",
"de": "Modul zur automatischen Prüfung installierter Module mit KI.",
"jp": "AIでインストールされるモジュールを自動チェックするモジュール。",
"tr": "Kurulan modülleri yapay zeka ile otomatik kontrol eden modül.",
"uz": "O'rnatilayotgan modullarni AI orqali avtomatik tekshiruvchi modul.",
"kz": "Орнатылатын модульдерді ЖИ арқылы автоматты тексеретін модуль."
},
"meta": {
"pic": null,
"banner": "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/FSecurity/banner.png",
"developer": "@FModules"
},
"commands": [],
"new_commands": [],
"inline_handlers": [],
"strings": {
"name": "FSecurity",
"lang": "en",
"unavailable": "AI module check is unavailable.",
"suspicious": "AI interrupted installation of a suspicious module, reason:",
"blocked": "AI blocked module installation, reason:",
"continue": "Continue installation?",
"lang_ru": "ru",
"unavailable_ru": "Проверка модуля через ИИ недоступна.",
"suspicious_ru": "ИИ прервал установку подозрительного модуля, причина:",
"blocked_ru": "ИИ заблокировал установку модуля, причина:",
"continue_ru": "Продолжить установку?",
"lang_ua": "ua",
"unavailable_ua": "Перевірка модуля через ШІ недоступна.",
"suspicious_ua": "ШІ перервав встановлення підозрілого модуля, причина:",
"blocked_ua": "ШІ заблокував встановлення модуля, причина:",
"continue_ua": "Продовжити встановлення?",
"lang_de": "de",
"unavailable_de": "Die KI-Modulprüfung ist nicht verfügbar.",
"suspicious_de": "Die KI hat die Installation eines verdächtigen Moduls unterbrochen, Grund:",
"blocked_de": "Die KI hat die Modulinstallation blockiert, Grund:",
"continue_de": "Installation fortsetzen?",
"lang_jp": "jp",
"unavailable_jp": "AIモジュールのチェックが利用できません。",
"suspicious_jp": "AIが疑わしいモジュールのインストールを中断しました、理由",
"blocked_jp": "AIがモジュールのインストールをブロックしました、理由",
"continue_jp": "インストールを続行しますか?",
"lang_tr": "tr",
"unavailable_tr": "Yapay zeka modül kontrolü kullanılamıyor.",
"suspicious_tr": "Yapay zeka şüpheli bir modülün kurulumunu durdurdu, sebep:",
"blocked_tr": "Yapay zeka modül kurulumunu engelledi, sebep:",
"continue_tr": "Kuruluma devam edilsin mi?",
"lang_uz": "uz",
"unavailable_uz": "AI modul tekshiruvi mavjud emas.",
"suspicious_uz": "AI shubhali modul o'rnatilishini to'xtatdi, sabab:",
"blocked_uz": "AI modul o'rnatilishini blokladi, sabab:",
"continue_uz": "O'rnatishni davom ettirasizmi?",
"lang_kz": "kz",
"unavailable_kz": "AI модульін тексеру қолжетімсіз.",
"suspicious_kz": "AI күдікті модульді орнатуды тоқтатты, себебі:",
"blocked_kz": "AI модульді орнатуды бұғаттады, себебі:",
"continue_kz": "Орнатуды жалғастырасыз ба?"
},
"has_on_load": false,
"has_on_unload": true,
"class_cmd_names": {}
},
"Fixyres/FModules/BSR.py": { "Fixyres/FModules/BSR.py": {
"name": "BSR", "name": "BSR",
"description": "Module for finding nearby game rooms in BrawlStars.", "description": "Module for finding nearby game rooms in BrawlStars.",
@@ -84526,7 +84593,7 @@
"cls_doc": {}, "cls_doc": {},
"meta": { "meta": {
"pic": null, "pic": null,
"banner": "https://github.com/Midga3/heroku-modules/blob/main/new_module.jpg?raw=true", "banner": null,
"developer": "@midga3_modules" "developer": "@midga3_modules"
}, },
"commands": [], "commands": [],
@@ -84951,7 +85018,7 @@
} }
}, },
"meta": { "meta": {
"total_modules": 1057, "total_modules": 1058,
"generated_at": "2026-04-12T17:39:10.030299" "generated_at": "2026-04-14T01:57:03.389942"
} }
} }