LoVisual/backend/chat-service/PLAN.md

4.3 KiB
Raw Permalink Blame History

chat-service

Подсистема 2 платформы (RPC-чат, друзья, presence, телеметрия виджетов). Сейчас реализован только GUI presence; чат и друзья позже (WebSocket). Сервис без БД: состояние в памяти, живёт секунды.

GUI presence (идея из evo GuiPresence, наш вариант)

Зачем: LoVisual-игроки видят друг у друга над рукой мини-копию открытого меню клиента (какая категория, куда наведён курсор, поиск), и знают, кто вообще пользуется LoVisual (значок у ника). Без видео и без чужих данных: только положение курсора и флаги.

Протокол

POST /presence/gui (через gateway, нужен device-токен lvd_..., gateway кладёт x-lovisual-account-id):

{ "server": "play.example.com", "mc": "<uuid игрока>", "gui": "<base64>|null", "want": ["<uuid>", "..."], "publish": true }

Ответ: { "players": [ { "mc": "<uuid>", "gui": "<base64>|null", "age": 120 } ] }, age в мс с последнего обновления.

  • Один запрос и публикует состояние вызывающего, и возвращает состояние тех, кого он видит (want, не больше 40).
  • publish = false (по умолчанию true): только чтение, вызывающий сам не появляется у других.
  • gui = null значит «меню закрыто, но LoVisual запущен» (значок у ника). Запись живёт 6 с без обновления.
  • Игроки разных серверов не видят друг друга (ключ server, нормализуется в нижний регистр, ≤64 символов).
  • Частота клиента: раз в ~350 мс при открытом меню (пачка до 8 сэмплов курсора по 100 мс), раз в 2 с при закрытом. Лимит на gateway: 6 запросов в секунду на аккаунт.

Формат gui (36 байт максимум, base64 ≤48 символов; сервис его не разбирает, только проверяет алфавит и длину)

байт значение
0 версия = 1
1 биты 0-3 категория (0..15), бит 4 открыта страница настроек, бит 5 поиск, бит 7 меню закрыто
2 индекс модуля под курсором в списке категории (255 = нет)
3 число сэмплов n (0..8)
4+4i сэмпл: x (0..255 по ширине меню), y (0..255 по высоте), бит 0 = зажата ЛКМ, прокрутка списка (0..255)

Безопасность

  • Идентичность только из заголовка gateway; прямой доступ закрыт общим секретом (как у остальных сервисов).
  • Привязка mc uuid к аккаунту: чужой аккаунт не может публиковать за занятый uuid (409), привязка снимается через 10 мин простоя; аккаунт владеет одним uuid, смена альта освобождает прежний. Это защита от подделки, не доказательство владения аккаунтом Minecraft: серверной верификации uuid нет.
  • Размер тела ≤8 КБ, payload только [A-Za-z0-9+/=], want ≤40.

Структура

src/presence/{payload.rs (валидация), store.rs (состояние + TTL + привязка), handlers.rs (sync)}; тесты: модульные в store.rs, payload.rs, интеграционные tests/presence.rs. Порт CHAT_PORT (8083), INTERNAL_KEY общий. В gateway маршрут /presence/*.

Не сделано

Просмотр видео (.watch у evo), чат и друзья (WebSocket), метрики, горизонтальное масштабирование (состояние в памяти одного процесса).