diff --git a/TODO.md b/TODO.md index 6076114..629e285 100644 --- a/TODO.md +++ b/TODO.md @@ -1,126 +1,47 @@ -# ZTorrent — TODO & Контекст улучшений +# ZTORRENT — ROADMAP & TODO -> Цель: довести ztorrent до уровня qBittorrent по функциональности и скорости. -> Ведётся автоматически — отражает актуальное состояние реализации. +> **Глобальная цель:** Довести Ztorrent до продакшен-уровня (стандарты qBittorrent и выше), сохранив консольную эстетику. --- -## Архитектура проекта +## 🚀 Глобальный план развития (Roadmap) -``` -internal/ - torrent/ - engine.go — основной движок: загрузка торрента, воркеры, координация - peerwire.go — BitTorrent wire protocol: handshake, download piece, messages - piecescheduler.go — выбор кусков (rarest-first), endgame mode - debug.go — debugf helper - tracker/ - tracker.go — HTTP + UDP announce - torrentfile/ - torrentfile.go — парсинг .torrent (bencode) - app/ - controller.go — тонкая обёртка над Engine для UI -ui/ - ui.go — Bubble Tea TUI (welcome, loading, dashboard) - styles.go — цветовая палитра -``` +### 1. Движок уровня qBittorrent (Core Engine) +- [ ] **Оптимизация I/O:** Асинхронная запись на диск (mmap / AIO), чтобы не было фризов UI при скачивании на гигабитных скоростях. +- [ ] **Продвинутый кэш:** Умное кэширование кусков в ОЗУ перед сбросом на диск. +- [ ] **Smart Ban / Anti-Leech:** Автоматический бан плохих пиров, защита от спам-хэшей и некорректных кусков. +- [ ] **Приоритизация файлов:** Возможность выбирать, какие файлы из раздачи качать первыми. + +### 2. Идеальный DHT +- [ ] **BEP 44 (Arbitrary Data):** Хранение произвольных данных в DHT. +- [ ] **Умный роутинг (Kademlia 2.0):** Динамическое поддержание "живых" нод в bucket'ах, пинги в фоне. +- [ ] **IPv6 DHT:** Поддержка поиска пиров в IPv6 сетях. +- [ ] **Локальный поиск (LSD):** Поиск пиров в локальной сети (Local Service Discovery). + +### 3. Умное логирование (Smart Logging) +- [ ] **Уровни логов (Levels):** Переход на структурированные логи (DEBUG, INFO, WARN, ERROR). +- [ ] **Фильтрация логов в UI:** Возможность прямо в TUI отфильтровать логи по "DHT", "Peers", "Disk". +- [ ] **Аналитика сессии:** Summary по итогам скачивания (сколько отброшено кусков, средняя скорость, топовые пиры). + +### 4. Эргономика UI (UX Refactoring) +- [ ] **Интерактивные таблицы:** Возможность сортировки по столбцам (по скорости, проценту скачивания). +- [ ] **Просмотр файлов внутри торрента:** Древовидная структура (`tree view`) для многофайловых торрентов. +- [ ] **Настройки "на лету":** Вызов окна настроек (`Config`) прямо из UI (лимиты скорости, порты, пути). +- [ ] **Визуализация Swarm'а:** Красивая карта пиров или график скорости (ASCII Sparklines). + +### 5. Killer-Features (Убийцы qBit) +- [ ] **Стриминг в плеер (VLC/mpv):** Скачивание торрента "на лету" (куски по порядку) с пробросом HTTP-стрима прямо в медиаплеер (нажал кнопку — фильм сразу открылся). +- [ ] **Интеграция с Telegram / Discord:** Уведомления об окончании загрузки прямо на телефон. +- [ ] **CLI Remote Control:** Возможность поднять Ztorrent как демона на сервере и управлять им через SSH/TUI удалённо по RPC. +- [ ] **Web-виджет (Read-Only):** Поднятие легковесного веб-сервера для просмотра статуса загрузок с телефона. --- -## P0 — Критичные ✅ ГОТОВО +## 🛠 Выполнено (Архив) -- [x] **Resume download** — `createOrOpenPartFile()` без O_TRUNC + SHA-1 верификация -- [x] **Keep-alive** — `keepaliveLoop()` горутина, 90с, `msgCancel=8` -- [x] **Endgame mode** — `pieceDone` broadcast + `SendCancel()` при дублировании - -## P1 — Производительность ✅ ГОТОВО - -- [x] **Adaptive pipeline** — depth 4–64, пересчёт каждые 4 блока по RTT+BW -- [x] **IPv6 compact peers** — `parsePeers6()` в tracker.go -- [x] **Rate limiting** — `rateLimitedConn`, `SetDownloadLimit`/`SetUploadLimit` -- [x] **Bitmap resume data** — `.part.bitmap` JSON, `asyncSaveBitmap()` в heartbeat - -## Баги ✅ ПОФИКШЕНО - -- [x] **`announce` пустой** — BEP 12 fallback: берём первый URL из `announce-list` - > `torrentfile.go` → `primaryAnnounce` fallback в `Open()` - -- [x] **`peerBackoff` O(n)** → O(1) через `peerIdx map[string]int` - > Добавлен `Engine.peerIdx`, `peerByKey()` helper - > Все peer-методы: `setPeerState`, `setPeerError`, `peerBackoff`, `recordPieceComplete` - -- [x] **Скорость без EWMA** → сглаживание α=0.3 в `updateSpeedLocked()` - > `downloadSpeed = 0.3*sample + 0.7*prev` - -- [x] **Reannounce блокирует heartbeat** → запускается в отдельной горутине - > `heartbeatTicker.C` → `go func() { refreshPeersFromTrackers() }()` - > Таймаут уменьшен с 20с до 15с - -## Фича ✅ РЕАЛИЗОВАНО - -- [x] **Incoming connections** — TCP listener на :6881 - > `listenIncoming()` + `handleIncoming()` в engine.go - > Handshake верификация (info_hash), регистрация в `peerIdx` - > Входящие пиры подхватываются `startWorkers` на следующем heartbeat тике - ---- - -## P2 — Долгосрочные (не начато) - -- [x] **DHT (BEP 5)** — Kademlia DHT для поиска пиров без трекера - > Новый пакет `internal/dht/` — реализовано! - -- [x] **Магнет-ссылки (BEP 9)** — `magnet:?xt=...`, ut_metadata extension - > Новый пакет `internal/magnet/` — средняя сложность - -- [x] **Seeding / upload (tit-for-tat)** — раздача после завершения - > `peerwire.go` → обработка `msgRequest`, отправка `msgPiece` - -- [x] **PEX (BEP 11)** — Peer Exchange между пирами - > Extension handshake + `ut_pex` message - ---- - -## Технические решения - -### peerIdx — O(1) peer lookup -``` -Engine.peers []PeerStatus // слайс со всеми пирами -Engine.peerIdx map[string]int // "host:port" → индекс в слайсе - -buildPeerIdx(peers) // строится при LoadTorrent и reannounce -peerByKey(key) *PeerStatus // O(1) под e.mu -``` - -### EWMA сглаживание скорости -``` -updateSpeedLocked(): - sample = delta_bytes / elapsed_sec - speed = 0.3*sample + 0.7*prev_speed // α=0.3 -``` - -### Incoming connections flow -``` -runDownload() - └── go listenIncoming(ctx, tf) - └── net.Listen(":6881") - └── for { conn = Accept() → go handleIncoming(conn) } - ├── ReadFull → verify wireProtocol + infoHash - ├── Write reply handshake - └── register peer in peerIdx - → подхватывается startWorkers на следующем heartbeat -``` - -### Resume flow -``` -createOrOpenPartFile(): - ├── если .part существует + .bitmap → verifyPieces() (быстро) - ├── если .part существует, нет bitmap → verifyAllPieces() (SHA-1 scan) - └── если .part нет → создаём новый, Truncate(size) - -heartbeat: - asyncSaveBitmap() → .part.bitmap - -завершение: - os.Remove(.part) + os.Remove(.part.bitmap) -``` +- ✅ **Magnet-ссылки (BEP 9)** и метаданные. +- ✅ **Базовый DHT (BEP 5)** с непрерывным поиском. +- ✅ **Мультитрекерность** (HTTP + UDP). +- ✅ **Resume Data / Endgame Mode / Keep-alive.** +- ✅ **Журнал (History) и Логи (Session Logs).** +- ✅ **TUI интерфейс** с глобальными оверлеями (О программе, Журнал, Логи).