Added and updated repositories 2026-04-12 14:57:04

This commit is contained in:
github-actions[bot]
2026-04-12 14:57:04 +00:00
parent 3156a432f0
commit c4b56bee9b
47 changed files with 5628 additions and 2 deletions

View File

@@ -0,0 +1,456 @@
__version__ = (1, 1, 0)
# ©️ Fixyres, 2026-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.
# 🔑 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: @FModules
# meta fhsdesc: game, funny, guess, question game
# requires: curl_cffi
import html
import re
import inspect
from curl_cffi import requests
from .. import loader, utils
from telethon.tl.functions.messages import TranslateTextRequest
from telethon.tl.types import TextWithEntities
class AsyncAki:
def __init__(self, lang="en", cm=False):
self.user_lang = lang
aki_langs =[
"en", "ar", "cn", "de", "es", "fr", "il", "it",
"jp", "kr", "nl", "pl", "pt", "ru", "tr", "id"
]
if lang in aki_langs:
self.aki_lang = lang
elif lang in ["uk", "uz", "kk", "be"]:
self.aki_lang = "ru"
else:
self.aki_lang = "en"
self.cm = str(cm).lower()
self.uri = f"https://{self.aki_lang}.akinator.com"
self.session = requests.AsyncSession(impersonate="chrome120")
self.session.headers.update({
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1"
})
self.win = False
self.prog = "0.0"
self.step = "0"
self.slp = ""
self.name = None
self.desc = ""
self.photo = "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/banner.png"
self.q = ""
async def _req(self, ep, data=None):
method = "POST" if data else "GET"
url = f"{self.uri}/{ep}"
headers = {}
if data:
headers["x-requested-with"] = "XMLHttpRequest"
headers["Content-Type"] = "application/x-www-form-urlencoded"
r = await self.session.request(method, url, data=data, headers=headers)
if r.status_code != 200:
raise Exception(f"AE{r.status_code}")
try:
return r.json()
except Exception:
return r.text
async def start(self):
t = await self._req("game", {"sid": 1, "cm": self.cm})
if "technical problem" in (t if isinstance(t, str) else "").lower():
raise Exception("ATP")
ses_m = re.search(r"session['\"]\)\.val\(['\"](.+?)['\"]", t if isinstance(t, str) else str(t))
sig_m = re.search(r"signature['\"]\)\.val\(['\"](.+?)['\"]", t if isinstance(t, str) else str(t))
q_m = re.search(r'class="question-text".*?>(.+?)</p>', t if isinstance(t, str) else str(t), re.S)
if not ses_m or not sig_m or not q_m:
raise Exception("AECF")
self.ses = ses_m.group(1)
self.sig = sig_m.group(1)
self.q = html.unescape(q_m.group(1)).strip()
async def answer(self, a):
data = {
"step": self.step, "progression": self.prog, "sid": 1,
"cm": self.cm, "answer": a, "step_last_proposition": self.slp,
"session": self.ses, "signature": self.sig
}
res = await self._req("answer", data)
self._upd(res)
async def exclude(self):
data = {
"step": self.step, "progression": self.prog, "sid": 1,
"cm": self.cm, "session": self.ses, "signature": self.sig,
"forward_answer": "1"
}
try:
res = await self._req("exclude", data)
if isinstance(res, dict) and res.get("question"):
self.win = False
self.name = None
self._upd(res)
else:
self.win = False
self.name = None
self.q = None
except Exception:
self.win, self.name, self.q = False, None, None
def _upd(self, d):
if not isinstance(d, dict):
return
if d.get("id_proposition"):
self.win = True
self.name = html.unescape(d.get("name_proposition", ""))
self.desc = html.unescape(d.get("description_proposition", ""))
self.photo = d.get("photo", "https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/banner.png")
self.step = str(d.get("step", self.step))
self.slp = self.step
if "progression" in d and d["progression"] is not None:
self.prog = str(d["progression"])
elif d.get("question"):
self.win = False
self.q = html.unescape(d.get("question", ""))
self.prog = str(d.get("progression", "0"))
self.step = str(d.get("step", "0"))
self.slp = str(d.get("step_last_proposition", self.slp))
else:
self.win = False
self.name = None
self.q = None
async def close(self):
try:
if inspect.iscoroutinefunction(self.session.close):
await self.session.close()
else:
res = self.session.close()
if inspect.isawaitable(res):
await res
except Exception:
pass
@loader.tds
class Akinator(loader.Module):
'''Akinator will guess any character you have in mind, you just need to answer a couple of questions.'''
strings = {
"name": "Akinator",
"lang": "en",
"child_mode": "Child mode. If enabled, it will be easier to guess 18+ heroes.",
"start": "Start",
"text": "<b>Guess any character you have in mind, and click on the Start button.</b>",
"yes": "Yes",
"no": "No",
"idk": "I don't know",
"probably": "Probably",
"probably_not": "Probably not",
"this_is": "<b>This is <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>This is <code>{name}</code></b>",
"not_right": "Not right",
"failed": "<b>Failed to guess the character.</b>"
}
strings_ru = {
"lang": "ru",
"_cls_doc": "Акинатор угадает любого вами загаданного персонажа.",
"child_mode": "Детский режим. Сложнее отгадать 18+ героев.",
"start": "Начать",
"text": "<b>Задумайте персонажа, и нажмите начать.</b>",
"yes": "Да",
"no": "Нет",
"idk": "Не знаю",
"probably": "Возможно",
"probably_not": "Скорее нет",
"this_is": "<b>Это <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>Это <code>{name}</code></b>",
"not_right": "Это не он",
"failed": "<b>Не удалось угадать персонажа.</b>"
}
strings_ua = {
"lang": "uk",
"_cls_doc": "Акінатор вгадає будь-якого персонажа.",
"child_mode": "Дитячий режим. Складніше відгадати 18+ героїв.",
"start": "Почати",
"text": "<b>Загадайте персонажа, і натисніть почати.</b>",
"yes": "Так",
"no": "Ні",
"idk": "Не знаю",
"probably": "Можливо",
"probably_not": "Швидше ні",
"this_is": "<b>Це <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>Це <code>{name}</code></b>",
"not_right": "Це не він",
"failed": "<b>Не вдалося вгадати персонажа.</b>"
}
strings_de = {
"lang": "de",
"_cls_doc": "Akinator errät jeden Charakter, den du dir vorstellst.",
"child_mode": "Kindermodus. Wenn aktiviert, wird es schwieriger sein, 18+ Helden zu erraten.",
"start": "Start",
"text": "<b>Denk dir einen Charakter aus und klicke auf Start.</b>",
"yes": "Ja",
"no": "Nein",
"idk": "Ich weiß nicht",
"probably": "Wahrscheinlich",
"probably_not": "Wahrscheinlich nicht",
"this_is": "<b>Das ist <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>Das ist <code>{name}</code></b>",
"not_right": "Das ist er nicht",
"failed": "<b>Charakter konnte nicht erraten werden.</b>"
}
strings_fr = {
"lang": "fr",
"_cls_doc": "Akinator devinera n'importe quel personnage.",
"child_mode": "Mode enfant. Héros 18+ plus difficiles à deviner.",
"start": "Commencer",
"text": "<b>Pensez à un personnage et cliquez sur Commencer.</b>",
"yes": "Oui",
"no": "Non",
"idk": "Je ne sais pas",
"probably": "Probablement",
"probably_not": "Probablement pas",
"this_is": "<b>C'est <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>C'est <code>{name}</code></b>",
"not_right": "Ce n'est pas lui",
"failed": "<b>Impossible de deviner.</b>"
}
strings_jp = {
"lang": "ja",
"_cls_doc": "アキネーターはあなたが考えているキャラクターを当てます。",
"child_mode": "子供モード。有効にすると、18歳以上のキャラクターを推測するのが難しくなります。",
"start": "開始",
"text": "<b>キャラクターを思い浮かべて開始。</b>",
"yes": "はい",
"no": "いいえ",
"idk": "わかりません",
"probably": "おそらく",
"probably_not": "おそらく違う",
"this_is": "<b>これは <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>これは <code>{name}</code></b>",
"not_right": "違います",
"failed": "<b>推測できませんでした。</b>"
}
strings_uz = {
"lang": "uz",
"_cls_doc": "Akinator siz o'ylagan har qanday qahramonni topadi.",
"child_mode": "Bolalar rejimi. Yoqilgan bo'lsa, 18+ qahramonlarni topish qiyinroq bo'ladi.",
"start": "Boshlash",
"text": "<b>Qahramonni o'ylang va Boshlash tugmasini bosing.</b>",
"yes": "Ha",
"no": "Yo'q",
"idk": "Bilmayman",
"probably": "Ehtimol",
"probably_not": "Ehtimol yo'q",
"this_is": "<b>Bu <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>Bu <code>{name}</code></b>",
"not_right": "Bu u emas",
"failed": "<b>Qahramonni topib bo'lmadi.</b>"
}
strings_kz = {
"lang": "kk",
"_cls_doc": "Акинатор сіз ойлаған кез келген кейіпкерді табады.",
"child_mode": "Балалар режимі. Қосылған болса, 18+ кейіпкерлерді табу қиынырақ болады.",
"start": "Бастау",
"text": "<b>Кейіпкерді ойлаңыз және Бастау түймесін басыңыз.</b>",
"yes": "Иә",
"no": "Жоқ",
"idk": "Білмеймін",
"probably": "Мүмкін",
"probably_not": "Мүмкін емес",
"this_is": "<b>Бұл <code>{name}</code>\n<code>{description}</code></b>",
"this_is_no_desc": "<b>Бұл <code>{name}</code></b>",
"not_right": "Бұл ол емес",
"failed": "<b>Кейіпкерді таба алмадық.</b>"
}
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"child_mode",
False,
lambda: self.strings("child_mode"),
validator=loader.validators.Boolean()
)
)
self.games = {}
async def _tr(self, client, text, to_lang):
if not text:
return text
try:
request = TranslateTextRequest(
to_lang=to_lang,
text=[TextWithEntities(text=text, entities=[])]
)
result = await client(request)
return result.result[0].text
except Exception:
return text
@loader.command(
ru_doc="- начать игру.",
ua_doc="- почати гру.",
de_doc="- Spiel starten.",
fr_doc="- commencer le jeu.",
jp_doc="- ゲームを開始します。",
uz_doc="- o'yinni boshlash.",
kz_doc="- ойынды бастау.",
)
async def akinator(self, message):
'''- start the game.'''
try:
aki = AsyncAki(self.strings("lang"), self.config["child_mode"])
await aki.start()
self.games.setdefault(message.chat_id, {})[message.id] = aki
await self.inline.form(
text=self.strings("text"),
message=message,
photo="https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/banner.png",
reply_markup={
"text": self.strings("start"),
"callback": self._cb,
"args": (message,)
}
)
except Exception as e:
await utils.answer(message, f"<code>{e}</code>")
async def _cb(self, call, message):
aki = self.games.get(message.chat_id, {}).get(message.id)
if aki:
await self._sq(call, aki, message)
async def _sq(self, call, aki, message):
if aki.aki_lang != aki.user_lang:
question = await self._tr(message.client, aki.q, aki.user_lang)
else:
question = aki.q
markup = [[
{"text": self.strings("yes"), "callback": self._ans, "args": (0, message)},
{"text": self.strings("no"), "callback": self._ans, "args": (1, message)},
{"text": self.strings("idk"), "callback": self._ans, "args": (2, message)}
],[
{"text": self.strings("probably"), "callback": self._ans, "args": (3, message)},
{"text": self.strings("probably_not"), "callback": self._ans, "args": (4, message)}
]
]
await call.edit(
f"<b>{question}</b>",
photo="https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/banner.png",
reply_markup=markup
)
async def _show_guess(self, call, aki, message):
if aki.aki_lang != aki.user_lang:
name = await self._tr(message.client, aki.name, aki.user_lang)
desc = await self._tr(message.client, aki.desc, aki.user_lang) if aki.desc else aki.desc
else:
name = aki.name
desc = aki.desc
if desc:
text = self.strings("this_is").format(name=name, description=desc)
else:
text = self.strings("this_is_no_desc").format(name=name)
markup = [[
{"text": self.strings("yes"), "callback": self._fin, "args": (True, message, text, aki.photo)},
{"text": self.strings("not_right"), "callback": self._rej, "args": (message,)}
]
]
await call.edit(
text,
photo=aki.photo,
reply_markup=markup
)
async def _ans(self, call, answer_id, message):
aki = self.games.get(message.chat_id, {}).get(message.id)
if not aki:
return
await aki.answer(answer_id)
if aki.win:
await self._show_guess(call, aki, message)
elif getattr(aki, 'q', None):
await self._sq(call, aki, message)
else:
await self._fin(call, False, message, "", "")
async def _rej(self, call, message):
aki = self.games.get(message.chat_id, {}).get(message.id)
if not aki:
return
try:
await aki.exclude()
except Exception:
pass
if aki.win:
await self._show_guess(call, aki, message)
elif getattr(aki, 'q', None):
await self._sq(call, aki, message)
else:
await self._fin(call, False, message, "", "")
async def _fin(self, call, won, message, text, photo):
aki = self.games.get(message.chat_id, {}).pop(message.id, None)
if aki:
await aki.close()
if won:
await call.edit(text, photo=photo, reply_markup=[])
else:
await call.edit(
self.strings("failed"),
photo="https://raw.githubusercontent.com/Fixyres/FModules/refs/heads/main/assets/akinator/idk.png",
reply_markup=[]
)