Files
2026-10-18 15:44:55 +03:00

185 lines
7.4 KiB
Python

import login
import answers
import sys
from nio import (
MatrixRoom,
RoomMessageText,
InviteMemberEvent,
MegolmEvent,
KeyVerificationStart,
KeyVerificationKey,
KeyVerificationMac,
KeyVerificationCancel,
LocalProtocolError,
ToDeviceError
)
WELCOME_MSG = "Добро пожаловать ко мне, УЕБОТУ! АХАХА\n" \
"И так, вот что я умею:\n" \
"1. Сервер — Данные об использовании сервера.\n" \
"2. Погода в <город> — Погода в городе.=(тестово).\n" \
"3. SCP — Выдача случайного объекта фонда для чтения.\n" \
"4. SCP классы — Описание классов.\n" \
"5. Помощь — Это меню.\n\n" \
"Можете писать слова(Пример: Сервер) или цифрой(Пример: 1)."
client = None
async def message_callback(room: MatrixRoom, event: RoomMessageText):
print(f"[DEBUG] Открытое сообщение от {event.sender}.")
if event.sender == client.user_id:
return
content = None
if event.body.lower() == "сервер" or event.body == "1":
content = answers.system_request()
elif event.body.lower() == "погода" or event.body == "2":
content = answers.weather_request()
elif event.body.lower() == "scp" or event.body == "3":
content = answers.scp_request()
elif event.body.lower() == "scp классы" or event.body == "4":
content = answers.scp_classed()
else:
content = answers.unknown_request()
content += answers.help_request()
await send_message(room, content)
async def megolm_callback(room: MatrixRoom, event: MegolmEvent):
try:
decrypted = await client.decrypt_event(event)
except Exception as e:
print(f"[ERROR] Расшифровка не удалась: {e}")
return
if isinstance(decrypted, RoomMessageText):
print(f"[DEBUG] Расшифровано: {decrypted.body}")
if decrypted.sender == client.user_id:
return
await send_message(room, decrypted.body)
else:
print(f"[DEBUG] Расшифровано, но не текст: {type(decrypted).__name__}")
async def invite_callback(room: MatrixRoom, event: InviteMemberEvent):
print(f"[INFO] Приглашение в комнату {room.room_id}")
await client.join(room.room_id)
await send_message(room, WELCOME_MSG)
async def trust_user_devices(user_id: str, device_ids=None):
"""Доверие устройствам пользователя (локально, без интерактивной верификации)."""
if user_id == client.user_id:
return
if user_id not in client.device_store:
print(f"[WARN] Устройства {user_id} пока не известны.")
return
devices = client.device_store[user_id]
trusted = 0
for device_id, olm_device in devices.items():
if device_ids and device_id not in device_ids:
continue
try:
client.verify_device(olm_device)
print(f"[OK] Доверено устройство {device_id} пользователя {user_id}.")
trusted += 1
except Exception as e:
print(f"[ERROR] Не удалось доверить {device_id}: {e}")
if trusted == 0:
print(f"[WARN] Ни одно устройство {user_id} не было доверено.")
async def send_message(room: MatrixRoom, text: str):
CHUNK = 5000
if len(text) > CHUNK:
start = 0
end = 0
while start < len(text):
end = start + CHUNK
if end < len(text):
while text[end] != ".":
end -= 1
end += 1
chunk = text[start:end]
await client.room_send(
room_id = room.room_id,
message_type = "m.room.message",
content = {"msgtype" : "m.text", "body" : chunk},
ignore_unverified_devices = True
)
start = end
print(start)
else:
await client.room_send(
room_id = room.room_id,
message_type = "m.room.message",
content = {"msgtype" : "m.text", "body" : text},
ignore_unverified_devices = True
)
async def after_first_sync():
print("[INFO] Ожидание первого синка...")
await client.synced.wait()
print("[INFO] Первый синк выполнен. Доверяем устройствам...")
for user_id in login.TRUST_USERS:
await trust_user_devices(user_id)
async def to_device_callback(event):
"""Автоматически принимает и подтверждает SAS-верификацию от доверенных пользователей."""
try:
if isinstance(event, KeyVerificationStart):
if event.sender not in login.TRUST_USERS:
print(f"[WARN] Верификация от недоверенного пользователя {event.sender}, игнорируем.")
return
if "emoji" not in event.short_authentication_string:
print(f"[WARN] Устройство {event.sender} не поддерживает эмодзи-верификацию.")
return
print(f"[INFO] Принимаем запрос на верификацию от {event.sender}...")
resp = await client.accept_key_verification(event.transaction_id)
if isinstance(resp, ToDeviceError):
print(f"[ERROR] accept_key_verification: {resp}")
return
sas = client.key_verifications[event.transaction_id]
todevice_msg = sas.share_key()
resp = await client.to_device(todevice_msg)
if isinstance(resp, ToDeviceError):
print(f"[ERROR] to_device (share_key): {resp}")
elif isinstance(event, KeyVerificationKey):
sas = client.key_verifications[event.transaction_id]
print(f"[INFO] Эмодзи: {sas.get_emoji()}")
# Автоматически подтверждаем совпадение
resp = await client.confirm_short_auth_string(event.transaction_id)
if isinstance(resp, ToDeviceError):
print(f"[ERROR] confirm_short_auth_string: {resp}")
else:
print("[INFO] SAS подтверждён автоматически.")
elif isinstance(event, KeyVerificationMac):
sas = client.key_verifications[event.transaction_id]
try:
todevice_msg = sas.get_mac()
except LocalProtocolError as e:
print(f"[WARN] Верификация прервана: {e}")
return
resp = await client.to_device(todevice_msg)
if isinstance(resp, ToDeviceError):
print(f"[ERROR] to_device (mac): {resp}")
else:
print(f"[OK] Верификация с {event.sender} завершена. "
f"Доверенные устройства: {sas.verified_devices}")
elif isinstance(event, KeyVerificationCancel):
print(f"[INFO] Верификация отменена: {event.reason}")
except Exception as e:
print(f"[ERROR] to_device_callback: {e}")