You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

18 KiB

chatgui

1. Назначение

Десктопный GUI-чат (Telegram-подобный) со встроенным P2P uTun-узлом. Приложение объединяет полнофункциональный интерфейс обмена сообщениями и децентрализованный транспортный слой в едином процессе. Рассчитан на работу без центральных серверов — вся маршрутизация, синхронизация и доставка сообщений идут напрямую между узлами по ETCP-протоколу.

2. Архитектура

2.1. Уровни приложения

┌──────────────────────────────────────┐
│  GUI (Qt 6/5 Widgets, C++20)         │  поток GUI
│  ├─ MainWindow (QSplitter)           │
│  ├─ ChannelList / MessageList        │
│  ├─ MessageDelegate (бабблы+реакции) │
│  ├─ EmojiPanel (статика+анимация)    │
│  └─ LottieIcon / AnimTimer           │
├──────────────────────────────────────┤
│  GuiBridge (Qt signals ↔ uasync)     │  очередь событий
│  gui_bridge_post / uasync_post       │
├──────────────────────────────────────┤
│  Транспорт (C, поток uasync)         │  поток uasync
│  ├─ UtunNode (std::thread + UTUN_INSTANCE)│
│  ├─ ChatCore (отправка, БД, invite)  │
│  ├─ ChatSync (P2P синхронизация)     │
│  ├─ MemberSync (мемберы через Merkle)│
│  └─ MerkleSync (Merkle-дерево, 5 ур.)│
├──────────────────────────────────────┤
│  libutun (C, статическая библиотека) │  uasync
│  ├─ uasync (event loop, таймеры)     │
│  ├─ ETCP (надежная доставка, ACK)    │
│  ├─ SecureChannel (X25519+AES-CCM)   │
│  ├─ conn_mgr (управление подключ.)   │
│  ├─ topo_node/topo_group (BGP)       │
│  └─ ntp_time (синхронизация времени)  │
├──────────────────────────────────────┤
│  SQLite3 (WAL mode)                  │  чтение+запись
│  ├─ DbManager (C++, read-only для GUI)│
│  └─ chat_core (C, write из uasync)   │
└──────────────────────────────────────┘

2.2. Потоковая модель

Приложение работает в двух потоках:

  • Поток GUI — QApplication, все виджеты, отрисовка, QTimer для анимаций (AnimTimer 30fps). Только чтение из SQLite через DbManager.
  • Поток uasync — UTUN_INSTANCE в выделенном std::thread. Вся сеть, криптография, ETCP, синхронизация, запись в SQLite. Один uasync-экземпляр на поток (правило u_async).

Мост между потоками (gui_bridge):

  • uasync → GUI: gui_bridge_post(event_type, data, len) — сериализованные события в Qt main event loop через QMetaObject::invokeMethod с Qt::QueuedConnection. 10 типов событий: MSG_RECEIVED, CONNECT_RESULT, NEW_PEER, CHANNEL_UPDATED, MEMBERS_CHANGED, MY_NODE_ID, AUTO_CONNECT_STATUS, CHANNEL_PEERS_ONLINE, DB_READY, STATUS_REFRESH.
  • GUI → uasync: gui_bridge_post_uasync_fn(fn, arg) — выполнение функции в uasync-потоке через uasync_post. Используется для отправки сообщений, создания каналов, invite-подключений.

Всё взаимодействие с БД (INSERT/UPDATE/DELETE) выполняется только из uasync-потока. GUI читает через DbManager (read-only), синхронизация не требуется — SQLite в WAL-режиме обеспечивает одновременное чтение.

3. Ключевые компоненты

3.1. GUI-слой

MainWindow (src/mainwindow.h) — главное окно 900×600. Горизонтальный QSplitter из трёх панелей:

  • ChannelList — список каналов (QListView + QStandardItemModel), контекстное меню (invite, join, create group, settings).
  • MessageList — список сообщений канала (ChatView + QStandardItemModel), поле ввода InputBar, EmojiPanel.
  • AccountList — список участников канала (MemberListModel), онлайн-статус, имена.

Системный трей: QSystemTrayIcon + QMenu (показать/скрыть/выход). Закрытие окна сворачивает в трей.

ChatView (src/chatview.h) — QListView с фоновым изображением и drag-to-select. При движении >5px от точки нажатия стартует выделение сообщений. Ctrl+C копирует: для одного — выделенный текст, для нескольких — [time] author: text. Сигнал hoveredIndexChanged используется для активации анимаций эмодзи в MessageList.

MessageList / MessageDelegate — баббл-интерфейс сообщений:

  • Аватары (32×32, цвет зависит от node_id), бабблы со скруглёнными углами (r=10px) и хвостиком.
  • Цитаты: цветная полоса + мини-аватар + автор + текст.
  • Реакции (эмодзи) в status bar под бабблом.
  • Inline-анимированные эмодзи: при hover над сообщением — перебор кадров из LottieIcon, отрисовка поверх текста через QTextLayout.
  • Растягивающийся InputBar (QTextEdit, Enter — отправка, Shift+Enter — перевод строки).

EmojiPanel (src/emojipanel.h) — QTabWidget с категориями (смайлики, жесты, символы, анимации). Каждая категория — QGridLayout из EmojiButton (QPushButton без Q_OBJECT, hover-анимация через per-widget QTimer). Статические эмодзи — Unicode символы. Анимированные — TGS-файлы, рендерятся в EmojiButton::paintEvent.

LottieIcon (src/lottieicon.h) — загрузка и рендер TGS-анимаций:

  1. Gzip-декомпрессия через zlib (inflateInit2 с 16+MAX_WBITS)
  2. Парсинг Lottie JSON через rlottie C API (lottie_animation_from_data)
  3. Рендер кадра: lottie_animation_render → ARGB32 буфер → QImage

5 встроенных TGS-анимаций (вшиты в бинарник через chatgui.qrc): sparkles, white_flag, greeting, stop_hand, robot.

AnimTimer (src/animtimer.h) — синглтон-таймер 30fps с refcount-механизмом:

  • activate() / deactivate() увеличивают/уменьшают счётчик ссылок.
  • Срабатывает только когда есть активные анимации в видимых сообщениях.
  • Сигнал ticked обновляет кадры всех зарегистрированных LottieIcon.

Invite-ссылки (src/invite_link.h) — кодирование/декодирование приглашений в формат utun://... (base64, содержит channel_id, pubkey, список адресов). QR-коды через zxing-cpp.

3.2. Транспортный слой

UtunNode (transport/utun_node.h) — C++ обёртка над UTUN_INSTANCE:

  • Запускает выделенный std::thread с runLoop() — создаёт UTUN_INSTANCE, вызывает utun_instance_start(), входит в uasync event loop.
  • Приём сообщений: ETCP callback → QByteArray → сигнал messageReceived(uint64_t src, QByteArray data).
  • Отправка: send(dstNodeId, data) через ETCP поверх экземпляра uTun.
  • Конфигурация: NodeConfig (INI-файл), генерация X25519/Ed25519 ключей при первом запуске.
  • Включает отладку NTP-синхронизации для временных меток сообщений.

NodeConfig (transport/node_config.h) — управление INI-конфигом uTun-узла:

  • Генерация ключей (X25519 + Ed25519), сохранение/загрузка.
  • Секции [server] и [client] для подключения к другим узлам.
  • [gui] секция: путь к БД, настройки отладки.
  • ConfigUpdater — утилита для программного изменения конфиг-файлов (append/replace).

ChatCore (transport/chat_core.h) — центральный API чата в потоке uasync:

  • chat_core_submit_message — отправка сообщения: сохранение в локальную БД (таблица msg_<channel_id>), рассылка онлайн-пирам через etcp_send.
  • chat_core_create_channel — создание канала: генерация X25519/Ed25519 ключей канала, подпись Ed25519, запись в channels, членство владельца.
  • chat_core_connect_from_invite — подключение к пиру из invite-ссылки.
  • chat_core_connect_auto — авто-подключение к узлу из SQLite (topo_node), коллбэк с результатом.
  • Работа с БД: цепочка хешей (chain hash = SHA256(prev_hash || timestamp || data_hash)), список каналов, список пиров.

ChatSync (transport/chat_sync.h) — P2P синхронизация каналов:

  • ETCP-сервисы: 0x30 (chat_sync — синхронизация каналов), 0x31 (member_sync — синхронизация участников).
  • Протокол сообщений: INIT_SYNC → INIT_RESP → SEND_DATA ↔ PUSH+ACK_PUSH → SYNC_DONE.
  • Batch-загрузка: до 32 сообщений за запрос, sparse-синхронизация (до 16 диапазонов).
  • Таймаут пира: 5 секунд.
  • Auto-connect: параллельное подключение до 10 узлов, останавливается при 3 успешных. Переключение группы при смене канала.

MemberSync (transport/member_sync.h) — синхронизация участников канала на основе Merkle-деревьев:

  • Данные: таблицы peers_<channel_id>, nodes, node_addresses.
  • Хеш мембера = SHA256(node_id || x25519 || ed25519 || join_sig || join_ts || update_sig || update_ts || addrs).
  • Автоматический пересчёт дерева при добавлении/удалении/обновлении мембера.
  • Онлайн-статус: member_sync_set_online(node_id, 0/1).

MerkleSync (transport/merkle_sync.h) — универсальный протокол синхронизации на Merkle-деревьях:

  • 5-уровневое префиксное дерево над 64-битными ключами (node_id). 32 бакета на уровень (по 5 бит).
  • SHA256-хеши бакетов. Два пира обмениваются хешами, находят различающиеся бакеты, передают только их.
  • Wire-протокол: MSG_HASHES → MSG_REQUEST → MSG_BATCH, рекурсивно до совпадения хешей.
  • Таймаут 10s, 3 ретрая. Фоновая проверка консистентности (merkle_sync_bg_check).
  • Не зависит от типа данных — потребитель предоставляет три коллбэка (update_bucket_hash, get_items, apply_items). member_sync адаптирует это под мемберов каналов.

3.3. База данных

DbManager (db/db_manager.h) — C++/Qt обёртка над SQLite3 (read-only для GUI-потока):

  • Схема: channels (каналы с ключами X25519/Ed25519, подписи), msg_<channel_id> (per-channel таблицы сообщений с chain_hash), peers_<channel_id> (участники), nodes (узлы), node_addresses, accounts, ui_state, merkle_tree_hash.
  • Чтение: getChannels(), getMessages(), getChannelMembers(), loadNodeInfo(), getAccounts().
  • Методы для GUI: список каналов, сообщения с пагинацией, участники, онлайн-статус.
  • Sync-операции (курсоры): syncListChannels(), syncCount(), syncChainHashAt(), syncCursorOpen/Next/Close().
  • Проверка целостности: integrityCheckQuick() (PRAGMA quick_check), integrityCheckFull() (PRAGMA integrity_check), integrityOptimize() (PRAGMA optimize).

4. Сборка

Система сборки: CMake 3.16+ Стандарты: C++20 (GUI), C99 (транспорт/libutun) Зависимости:

  • Qt 6 (Widgets + Network) или Qt 5.15+
  • rlottie (анимированные эмодзи)
  • zlib (gzip-декомпрессия TGS)
  • OpenSSL (X25519, Ed25519, SHA256, AES-CCM)
  • zxing-cpp (QR-коды, встроен как submodule)

Структура сборки:

  • libutun/ — статическая библиотека uTun: все исходники из src/ (кроме utun.c) + lib/ (uasync, ll_queue, memory_pool, etc) + транспорт (chat_sync, member_sync, merkle_sync)
  • chatgui — финальный бинарник: GUI-исходники + транспортные C++/C файлы + SQLite3 amalgamation
  • Платформенный TUN: tun_linux.c / tun_freebsd.c / tun_windows.c
mkdir -p build && cd build
cmake .. && make -j4
./chatgui

5. Файловая структура

tools/chatgui/
├── CMakeLists.txt          # проект CMake
├── build.sh / build.bat    # скрипты сборки
├── src/                    # GUI-слой (Qt C++)
│   ├── main.cpp            # точка входа, QApplication
│   ├── mainwindow.cpp      # главное окно, трей
│   ├── channellist.cpp     # список каналов
│   ├── chatview.cpp        # QListView с фоном и drag-to-select
│   ├── messagelist.cpp     # модель сообщений, инициализация анимаций
│   ├── messagedelegate.cpp # отрисовка бабблов, цитат, реакций, эмодзи
│   ├── inputbar.cpp        # поле ввода + кнопка эмодзи
│   ├── emojipanel.cpp      # QTabWidget с категориями эмодзи
│   ├── emojitabbar.cpp     # кастомный QTabBar
│   ├── emoji.cpp           # данные эмодзи, builtinEmojiSet()
│   ├── lottieicon.cpp      # загрузка TGS, рендер через rlottie
│   ├── animtimer.cpp       # синглтон-таймер 30fps с refcount
│   ├── accountlist.cpp     # список участников канала
│   ├── memberlistmodel.cpp # модель для AccountList
│   ├── invite_link.cpp     # кодирование/декодирование utun:// ссылок
│   ├── invitedialog.cpp    # диалог приглашения
│   ├── joindialog.cpp      # диалог входа по invite-ссылке
│   ├── settingsdialog.cpp  # окно настроек
│   ├── networksettingspage.cpp # страница сетевых настроек
│   ├── databasesettingspage.cpp # настройки БД
│   ├── statuspage.cpp      # страница статуса
│   ├── creategroupdialog.cpp # создание группы
│   └── qrcode_utils.cpp    # генерация QR-кодов
├── transport/              # транспортный слой (C/C++)
│   ├── utun_node.cpp       # C++ обёртка UTUN_INSTANCE в std::thread
│   ├── node_config.cpp     # INI-конфиг узла (ключи, серверы, клиенты)
│   ├── config_updater.cpp  # утилита редактирования INI-файлов
│   ├── gui_bridge_impl.cpp # мост uasync↔Qt (10 типов событий)
│   ├── chat_core.c         # центральный API чата (отправка, БД, invite)
│   ├── chat_sync.c         # P2P синхронизация каналов (ETCP 0x30)
│   ├── member_sync.c       # синхронизация мемберов через Merkle
│   └── merkle_sync.c       # универсальный Merkle-протокол синхронизации
├── db/                     # база данных
│   ├── db_manager.h/cpp    # C++/Qt обёртка SQLite3 (read-only для GUI)
│   └── sqlite3.c/h         # SQLite3 amalgamation (из ../../lib/)
├── libutun/                # сборка статической библиотеки uTun
│   └── CMakeLists.txt      # uasync + utun = все .c из lib/ и src/
├── resources/              # ресурсы
│   ├── chatgui.qrc         # Qt resource file (TGS вшиты в бинарник)
│   └── animations/         # TGS-анимации (5 шт.)
└── doc/                    # документация
    ├── desc.txt            # описание схемы БД
    └── db_schema.md        # детальная схема таблиц SQLite