76 lines
6.4 KiB
Markdown
76 lines
6.4 KiB
Markdown
# Заметки по разработке stegterm
|
||
|
||
Чистое описание того, что есть — в README.md/README.ru.md (отдельного
|
||
ARCHITECTURE.md для проекта такого размера не заводил — три пакета и
|
||
один экран, README уже покрывает структуру).
|
||
|
||
Этот файл — то, что не годится в README, потому что описывает не «как
|
||
устроено», а «на что обратить внимание» и «откуда это унаследовано».
|
||
Весь код (и здесь, и в родительском burterm, откуда это выделено)
|
||
писался в среде без сети и без установленного Go — ни разу не проходил
|
||
через компилятор.
|
||
|
||
## Происхождение
|
||
|
||
Код `internal/stego` и `internal/audio` перенесён из burterm без
|
||
изменений в логике — только module path в импортах. `internal/tui`
|
||
переписан с нуля под односкреенный интерфейс (в burterm это была
|
||
одна из 14 вкладок с общей корневой моделью на все вкладки сразу;
|
||
здесь — тонкая обёртка `Model` вокруг того же `stegoModel`, без
|
||
таб-бара, без переключения между экранами).
|
||
|
||
## Реальный баг, найденный при разработке (до переноса)
|
||
|
||
**Задвоенное объявление `ifft`/`instantaneousFrequency`.** При
|
||
добавлении SSTV-декодера в дереве оказался файл `hilbert.go`,
|
||
дублирующий функции уже написанного `sstv.go` с другой сигнатурой —
|
||
гарантированная ошибка компиляции. Как он возник — не установлено;
|
||
удалён, вся логика осталась в `sstv.go`, проверено на отсутствие
|
||
повторных объявлений по всему пакету `audio`.
|
||
|
||
## Непроверенные места (по убыванию вероятности проблем)
|
||
|
||
1. **`go.mod`: версии `bubbles`/`bubbletea`/`lipgloss`** — указаны по
|
||
памяти (та же версия, что использовалась в burterm на момент
|
||
выделения этого кода), `go mod tidy` может подтянуть другие,
|
||
`go.sum` пересоберётся с нуля.
|
||
2. **bubbles API** — `Focus()` у `textinput` в некоторых версиях
|
||
возвращает `tea.Cmd`, в некоторых — нет.
|
||
3. **Kitty graphics protocol** (`internal/stego/kitty.go`) —
|
||
единственное место, где неопределённость не в компиляции, а в
|
||
визуальном поведении: что произойдёт, когда bubbletea в alt-screen
|
||
режиме перерисует экран поверх уже показанной картинки, предсказать
|
||
без реального терминала нельзя. Отсюда клавиша `ctrl+v` — передать
|
||
escape-код заново.
|
||
4. **Калибровка SSTV Robot36** (`internal/audio/sstv.go`) — тайминги
|
||
строк (`robot36SyncMs`, `robot36YMs` и т.д.) взяты по опубликованным
|
||
спецификациям, без эталонной записи для сверки. Это качественно
|
||
другой риск, чем у спектрограммы: спектрограмма не требует точной
|
||
калибровки (громче = ярче, любой вход даёт осмысленный результат),
|
||
SSTV — требует, иначе на выходе шум/диагональные полосы вместо
|
||
картинки. Авто-детект VIS-заголовка не реализован — режим (пока
|
||
только Robot36) заложен в код напрямую, без выбора в UI.
|
||
5. **Бюджет высоты `View()` не проверен построчно.** В отличие от
|
||
burterm (где после нескольких провалов этот вопрос был разобран
|
||
построчно для каждой вкладки — см. историю в NOTES.md burterm),
|
||
здесь `stegoModel.SetSize` вообще не использует высоту для
|
||
раскладки (только ширину, для решения "две колонки или один
|
||
столбец") — то есть класс бага "рамка/футер выталкивают верх экрана
|
||
за пределы видимой области" сюда не переносится по конструкции. Но
|
||
само по себе это не проверено на реальном терминале, просто риск
|
||
принципиально другого рода (максимум — обрежется низ длинного
|
||
контента, а не потеряется верх экрана целиком).
|
||
|
||
## Известные ограничения — сознательный выбор, не недоделка
|
||
|
||
- **Только WAV**, не MP3/FLAC — сжатие с потерями убивает как раз ту
|
||
мелкую структуру спектра, в которую в CTF прячут сообщения.
|
||
- **Только Robot36** из всех SSTV-режимов — самый частый в CTF-задачах
|
||
и достаточно документированный, чтобы взяться за него первым. Другие
|
||
режимы (Martin, Scottie, PD) потребовали бы свой набор таймингов и
|
||
свою калибровку — тот же риск, что и с Robot36, умноженный на число
|
||
режимов.
|
||
- **Поля "второе изображение" (для XOR) и "длина LSB-извлечения"
|
||
всегда на экране**, даже в режиме аудио, где не используются —
|
||
условный layout ради их скрытия усложнил бы `View()` заметнее, чем
|
||
стоит того.
|