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
8 changed files with 396 additions and 51 deletions

View File

@@ -7,7 +7,7 @@ __version__ = (1, 0, 0)
# 🔑 http://www.apache.org/licenses/LICENSE-2.0
# meta banner: https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/BSR/banner.png
# meta developer: @NFModules
# meta developer: @FModules
# meta fhsdesc: brawlstars, game, funny
from .. import loader, utils

View File

@@ -1,6 +1,6 @@
__version__ = (9, 3, 9)
# meta developer: @NFModules
# meta developer: @FModules
# meta pic: https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/FHeta/logo.png
# meta banner: https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/FHeta/logo.png
# scope: hikka_min 2.0.0
@@ -333,8 +333,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Error, module tried to overwrite built-in module!",
"dependency": "✘ Dependencies installation error! {deps}",
"docdevs": "Use only modules from official Heroku developers when searching?",
"doctheme": "Theme for emojis.",
"channel": "This is the channel with all updates in FHeta!"
"doctheme": "Theme for emojis."
}
strings_ru = {
@@ -366,8 +365,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Ошибка, модуль пытался перезаписать встроенный модуль!",
"dependency": "✘ Ошибка установки зависимостей! {deps}",
"docdevs": "Использовать только модули от официальных разработчиков Heroku при поиске?",
"doctheme": "Тема для эмодзи.",
"channel": "Это канал со всеми обновлениями в FHeta!"
"doctheme": "Тема для эмодзи."
}
strings_ua = {
@@ -399,8 +397,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Помилка, модуль намагався перезаписати вбудований модуль!",
"dependency": "✘ Помилка встановлення залежностей! {deps}",
"docdevs": "Використовувати тільки модулі від офіційних розробників Heroku при пошуку?",
"doctheme": "Тема для емодзі.",
"channel": "Це канал з усіма оновленнями в FHeta!"
"doctheme": "Тема для емодзі."
}
strings_kz = {
@@ -432,8 +429,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Қате, модуль кіріктірілген модульді қайта жазуға тырысты!",
"dependency": "✘ Тәуелділіктерді орнату қатесі! {deps}",
"docdevs": "Іздеу кезінде тек ресми Heroku әзірлеушілерінің модульдерін пайдалану керек пе?",
"doctheme": "Эмодзилер үшін тақырып.",
"channel": "Бұл FHeta-дағы барлық жаңартулары бар арна!"
"doctheme": "Эмодзилер үшін тақырып."
}
strings_uz = {
@@ -465,8 +461,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Xatolik, modul o'rnatilgan modulni qayta yozishga harakat qildi!",
"dependency": "✘ Bog'liqliklarni o'rnatish xatosi! {deps}",
"docdevs": "Qidiruv paytida faqat rasmiy Heroku ishlab chiquvchilarining modullaridan foydalanish kerakmi?",
"doctheme": "Emojilar uchun mavzu.",
"channel": "Bu FHeta-dagi barcha yangilanishlari bo'lgan kanal!"
"doctheme": "Emojilar uchun mavzu."
}
strings_fr = {
@@ -498,8 +493,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Erreur, le module a tenté d'écraser le module intégré!",
"dependency": "✘ Erreur d'installation des dépendances! {deps}",
"docdevs": "Utiliser uniquement les modules des développeurs Heroku officiels lors de la recherche?",
"doctheme": "Thème pour les emojis.",
"channel": "Voici le canal avec toutes les mises à jour dans FHeta!"
"doctheme": "Thème pour les emojis."
}
strings_de = {
@@ -531,8 +525,7 @@ class FHeta(loader.Module):
"overwrite": "✘ Fehler, Modul hat versucht, das integrierte Modul zu überschreiben!",
"dependency": "✘ Fehler bei der Installation von Abhängigkeiten! {deps}",
"docdevs": "Nur Module von offiziellen Heroku-Entwicklern bei der Suche verwenden?",
"doctheme": "Thema für Emojis.",
"channel": "Dies ist der Kanal mit allen Updates in FHeta!"
"doctheme": "Thema für Emojis."
}
strings_jp = {
@@ -564,8 +557,7 @@ class FHeta(loader.Module):
"overwrite": "✘ エラー、モジュールが組み込みモジュールを上書きしようとしました!",
"dependency": "✘ 依存関係のインストールエラー! {deps}",
"docdevs": "検索時に公式Heroku開発者のモジュールのみを使用しますか",
"doctheme": "絵文字のテーマ。",
"channel": "これはFHetaのすべての更新を含むチャンネルです"
"doctheme": "絵文字のテーマ。"
}
THEMES = {
@@ -660,11 +652,6 @@ class FHeta(loader.Module):
self.installer = MInstaller()
self.ui = FHetaUI(self)
await self.request_join(
"NFHeta_Updates",
f"{self.ui.emoji('channel')} {self.strings('channel')}"
)
self.api.token = self.token
router = None
@@ -717,20 +704,13 @@ class FHeta(loader.Module):
self.api.token = self.token
except Exception:
pass
asyncio.create_task(self.sync())
@loader.loop(interval=1, autostart=True)
async def sync(self):
ll = None
while True:
try:
cl = self.strings["lang"]
if cl != ll:
await self.api.send("dataset", user_id=self.identifier, lang=cl)
ll = cl
except Exception:
pass
await asyncio.sleep(1)
now = self.strings["lang"]
if now != getattr(self, "past_lang", None):
await self.api.send("dataset", params={"user_id": getattr(self, "identifier", 0), "lang": now})
self.past_lang = now
async def answer(self, callback: Union[CallbackQuery, ChosenInlineResult], text: Optional[str] = None, alert: bool = False) -> None:
try:
@@ -880,7 +860,7 @@ class FHeta(loader.Module):
return {
"title": self.strings["prompt"],
"description": self.strings["hint"],
"message": f"{self.ui.emoji('error')} <b>{self.strings['noquery'].format(prefix=f'<code>@{self.inline.bot_username} ')}</code></b>",
"message": f"{self.ui.emoji('error')} <b>{self.strings['prompt']}</b>",
"thumb": "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/FHeta/magnifying_glass.png"
}
@@ -898,7 +878,7 @@ class FHeta(loader.Module):
return {
"title": self.strings["retry"],
"description": self.strings["hint"],
"message": f"{self.ui.emoji('error')} <b>{self.strings['notfound'].format(query=f'<code>{utils.escape_html(query)}</code>')}</b>",
"message": f"{self.ui.emoji('error')} <b>{self.strings['notfound'].format(query=utils.escape_html(query))}</b>",
"thumb": "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/FHeta/try_other_query.png"
}
@@ -949,18 +929,18 @@ class FHeta(loader.Module):
query = utils.get_args_raw(message)
if not query:
return await utils.answer(message, f"{self.ui.emoji('error')} <b>{self.strings['noquery'].format(prefix=f'<code>{self.get_prefix()}')}</code></b>")
return await utils.answer(message, f"{self.ui.emoji('error')} <b>{self.strings['noquery'].format(prefix=self.get_prefix())}</b>")
if len(query) > 168:
return await utils.answer(message, f"{self.ui.emoji('warn')} <b>{self.strings['toolong']}</b>")
message = await utils.answer(message, f"{self.ui.emoji('search')} <b>{self.strings['search'].format(query=f'<code>{utils.escape_html(query)}</code>')}</b>")
message = await utils.answer(message, f"{self.ui.emoji('search')} <b>{self.strings['search'].format(query=utils.escape_html(query))}</b>")
modules = await self.api.fetch("search", query=query, inline="false", token=self.token, user_id=self.identifier, ood=str(self.config["only_official_developers"]).lower())
if not modules or not isinstance(modules, list):
return await utils.answer(message, f"{self.ui.emoji('error')} <b>{self.strings['notfound'].format(query=f'<code>{utils.escape_html(query)}</code>')}</b>")
return await utils.answer(message, f"{self.ui.emoji('error')} <b>{self.strings['notfound'].format(query=utils.escape_html(query))}</b>")
data = modules[0]
buttons = self.ui.buttons(data.get("install", ""), data, 0, modules, query)
form = await self.inline.form("", message, reply_markup=buttons, silent=True)

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

View File

@@ -7,7 +7,7 @@ __version__ = (1, 0, 0)
# 🔑 http://www.apache.org/licenses/LICENSE-2.0
# meta banner: https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/SCD/banner.png
# meta developer: @NFModules
# meta developer: @FModules
# requires: curl_cffi

View File

@@ -7,7 +7,7 @@ __version__ = (1, 1, 0)
# 🔑 http://www.apache.org/licenses/LICENSE-2.0
# meta banner: https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/banner.png
# meta developer: @NFModules
# meta developer: @FModules
# meta fhsdesc: game, funny, guess, question game
# requires: curl_cffi

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View File

@@ -381,7 +381,7 @@ class Limoka(loader.Module):
"404": "<blockquote><tg-emoji emoji-id=5210952531676504517>❌</tg-emoji> <b>Not found by query: <i>{query}</i></b></blockquote>",
"noargs": "<blockquote><tg-emoji emoji-id=5210952531676504517>❌</tg-emoji> <b>No args</b></blockquote>",
"?": "<blockquote><tg-emoji emoji-id=5951895176908640647>🔎</tg-emoji> Request too short / not found</blockquote>",
"no_info": "No information",
"no_info": "<blockquote>No information</blockquote>",
"facts": [
"<blockquote><tg-emoji emoji-id=5472193350520021357>🛡</tg-emoji> The limoka catalog is carefully moderated!</blockquote>",
"<blockquote><tg-emoji emoji-id=5940434198413184876>🚀</tg-emoji> Limoka performance allows you to search for modules quickly!</blockquote>",
@@ -493,7 +493,7 @@ class Limoka(loader.Module):
"404": "<blockquote><tg-emoji emoji-id=5210952531676504517>❌</tg-emoji> <b>Не найдено по запросу: <i>{query}</i></b></blockquote>",
"noargs": "<blockquote><tg-emoji emoji-id=5210952531676504517>❌</tg-emoji> <b>Нет аргументов</b></blockquote>",
"?": "<blockquote><tg-emoji emoji-id=5951895176908640647>🔎</tg-emoji> Запрос слишком короткий / не найден</blockquote>",
"no_info": "Нет информации",
"no_info": "<blockquote>Нет информации</blockquote>",
"facts": [
"<blockquote><tg-emoji emoji-id=5472193350520021357>🛡</tg-emoji> Каталог Limoka тщательно модерируется!</blockquote>",
"<blockquote><tg-emoji emoji-id=5940434198413184876>🚀</tg-emoji> Limoka позволяет искать модули с невероятной скоростью!</blockquote>",

View File

@@ -8310,6 +8310,73 @@
"has_on_unload": true,
"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": {
"name": "BSR",
"description": "Module for finding nearby game rooms in BrawlStars.",
@@ -8325,7 +8392,7 @@
"meta": {
"pic": null,
"banner": "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/BSR/banner.png",
"developer": "@NFModules",
"developer": "@FModules",
"fhsdesc": "brawlstars, game, funny"
},
"commands": [
@@ -8427,7 +8494,7 @@
"meta": {
"pic": null,
"banner": "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/SCD/banner.png",
"developer": "@NFModules"
"developer": "@FModules"
},
"commands": [
{
@@ -8504,7 +8571,7 @@
"meta": {
"pic": null,
"banner": "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/banner.png",
"developer": "@NFModules",
"developer": "@FModules",
"fhsdesc": "game, funny, guess, question game"
},
"commands": [
@@ -84951,7 +85018,7 @@
}
},
"meta": {
"total_modules": 1057,
"generated_at": "2026-04-16T02:02:10.912643"
"total_modules": 1058,
"generated_at": "2026-04-14T01:57:03.389942"
}
}