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