diff --git a/src/common/tools.py b/src/common/tools.py index 9ad93c8..7630023 100644 --- a/src/common/tools.py +++ b/src/common/tools.py @@ -28,17 +28,27 @@ class Tools: except (TypeError, ValueError): elements = [] + # Парсер MAX 26.15.3 (defpackage.u6h.Q) ждёт в сообщении следующие + # поля. Отсутствие любого ломает разбор msgpack-схемы, и клиент + # тихо роняет всю историю чата: + # id, cid, chatId, time, type, sender, text, attaches, elements, + # link, reactionInfo, updateTime, status, options + # Список вытащен дизассемблированием Q() через dexdump. message = { "id": row.get("id") if protocol_type == "mobile" else str(row.get("id")), "cid": int(row.get("cid") or 0), + "chatId": int(row.get("chat_id") or 0), "time": int(row.get("time")), - "type": row.get("type"), + "type": row.get("type") or "USER", # ENUM: USER/CHANNEL/CHANNEL_ADMIN/GROUP "sender": row.get("sender"), "text": row.get("text") or "", "attaches": attaches if isinstance(attaches, list) else [], "elements": elements if isinstance(elements, list) else [], "reactionInfo": {}, "link": {}, + "updateTime": int(row.get("update_time") or row.get("time") or 0), + "status": int(row.get("status") or 0), + "options": int(row.get("options") or 0), } return message diff --git a/src/oneme/processors/auth.py b/src/oneme/processors/auth.py index 4120200..da646c1 100644 --- a/src/oneme/processors/auth.py +++ b/src/oneme/processors/auth.py @@ -603,24 +603,11 @@ class AuthProcessors(BaseProcessor): username=user.get("username"), ) - # Список ID чатов до того как generate_chats затрёт переменную - chat_ids_for_history = list(chats) - # Генерируем список чатов chats = await self.tools.generate_chats( chats, self.db_pool, user.get("id"), protocol_type=self.type ) - # Bootstrap-история: карта {chatId: [messages]}. - # Без неё десктопный MAX считает, что локальная история уже - # синхронизирована, и не запрашивает CHAT_HISTORY (49). - bootstrap_messages = await self.tools.collect_bootstrap_history( - chat_ids_for_history, - self.db_pool, - user.get("id"), - protocol_type=self.type, - ) - # Генерируем список контактов contacts = await self.tools.collect_user_contacts( user.get("id"), self.db_pool, self.config.avatar_base_url @@ -634,8 +621,8 @@ class AuthProcessors(BaseProcessor): payload = { "profile": profile, "chats": chats, - "chatMarker": int(time.time() * 1000), - "messages": bootstrap_messages, + "chatMarker": 0, + "messages": {}, "contacts": contacts, "presence": presence, "config": { diff --git a/src/oneme/processors/history.py b/src/oneme/processors/history.py index a5e8aaf..69fb1dd 100644 --- a/src/oneme/processors/history.py +++ b/src/oneme/processors/history.py @@ -74,9 +74,16 @@ class HistoryProcessors(BaseProcessor): # Сортируем сообщения по времени messages.sort(key=lambda x: x["time"]) - # Формируем ответ + # Формируем ответ. + # Парсер a23 в MAX-клиенте ждёт ВСЕГДА все 5 полей (messages, + # forward, backward, pos, total). Если каких-то нет — клиент + # бросает соединение и история не отображается. payload = { - "messages": messages + "messages": messages, + "forward": 0, # сколько ещё доступно вперёд + "backward": 0, # сколько ещё доступно назад + "pos": 0, # позиция курсора + "total": len(messages), # всего в чате (примерно) } # Собираем пакет