gmod-rs/docs/RECON.md
Niko Marmeladkov d6b213cecc formats: VVD/VTX — меш-данные моделей (вершины, fixup, LOD-дерево)
- VVD (IDSV v4): заголовок 64 байта, mstudiovertex_t 48 байт (веса/кости/позиция/нормаль/UV),
  тангенты, таблица fixup
- VTX (packed): BodyPart→Model→LOD→Mesh→StripGroup→Strip, валидация индексов и смещений;
  смещения вложенных структур относительны своей структуры
- fs inspect: для .mdl показывает VVD/VTX-статистику и сверку checksum
- тесты: oildrum (270 вершин/756 индексов), 51 пара VVD/VTX с совпадающим checksum
- docs: прогресс M1 (остался ANIM, PCF/PHY/SND, GMA/mount.cfg)
2026-10-11 23:15:46 +03:00

113 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Разведка (снято 2026-10-11)
## 1. Окружение разработки
- OS: Linux x86_64 · CPU: 16 ядер · RAM: 31 ГБ (доступно ~17) · Swap: 8 ГБ
- GPU: NVIDIA RTX 3060 (GA106) → Vulkan через wgpu
- Rust: 1.97.1 (cargo 1.97.1)
- Домашний каталог: `/home/niko`
## 2. Каталоги
- `~/garrysmod-rs` — **корень проекта** (на момент разведки пустой; сессия переведена сюда)
- `~/source-rs` — пустой, не используется (оставлен как есть)
## 3. Целевой сервер: ClassicBox
- Адрес: `194.147.90.27:24215`
- A2S-инфо (2026-10-11): имя `ClassicBox`, карта `gm_mobenix_v3_final`, игра `garrysmod`,
тип `Sandbox`, **36/46 игроков**, Linux DS, VAC=1 (`\x01`), теги:
`gm:sandbox gmc:other loc:ru ver:260917`
- Вывод для плана: цель по нагрузке — 46–64 живых игрока и типичный сандбокс-набор
(пропы, констрейны, PAC3/Starfall у игроков), открытая карта.
## 4. Локальные ассеты и полигон
- **GMod Dedicated Server:** `~/gmod_server/server`
- `garrysmod/garrysmod_{000,001,002}.vpk` (~772 МБ) + `fallbacks_*.vpk` (~104 МБ)
- `sourceengine/*` (hl2_* vpk), `platform/*`
- `garrysmod/mount.cfg`, `gameinfo.txt` — порядок монтирования и mounts
- `srcds_linux` — локальный сервер для автотестов (sv_lan)
- `garrysmod.ver`: `260508 prerelease`
- **Steam-клиент GMod:** `~/.local/share/Steam/steamapps/common/GarrysMod` — заглушка
~32 КБ (полного клиентского контента нет). Для рендера используем DS-ассеты.
- **Workshop:** `~/.local/share/Steam/steamapps/workshop/content/4000` — пусто.
## 5. Инструменты пользователя
- `~/glua-steal` (исходники, C++) и `~/gluasteal` (рабочий каталог с `config.toml`) —
дампер клиентского/шаренного Lua с серверов, исполнитель Lua, блокировщик файлов.
Полезен как:
- источник тест-корпуса Lua (дампить ClassicBox);
- источник требований к защите путей при загрузке файлов с сервера.
Лицензию glua-steal отдельно проверить перед заимствованием идей (код не копируем).
## 6. Референс-проекты
| Проект | Что даёт | Ограничения |
|---|---|---|
| SourceDotNET/Source.NET | Структура Stage-слоёв Source; рабочий сетевой стек и подключение к реальным GMod-серверам; зачатки Lua | C#, GL46, только UnlitGeneric, физика Jitter-враппер, **нет анимаций**, Source 1 SDK License |
| Leystryku/leysourceengineclient | Базовый сетевой протокол для внешних клиентов | — |
| ValveSoftware/source-sdk-2013 | Спецификация: net_chan, dt_*, studio, шейдеры, VGUI, предсказание | Лицензия SDK (только для модов Source) — берём как спеку |
| nillerusr/source-engine | Кроссплатформенный порт: Linux-специфика, шейдерные переводы | SDK-лицензия |
| wiki.facepunch.com/gmod | Lua API и поведение движка | — |
| gluasteal | Требования к безопасности загрузки файлов | проверить лицензию |
## 7. Ключевые факты о GMod, влияющие на план
- Клиент исторически 32-битный (есть 64-битная бета) → у нас сразу x86_64.
- Lua: LuaJIT (семантика 5.1).
- PAC3/Starfall — аддоны внутри GMod Lua (Starfall несёт свой интерпретатор) →
наша задача = движковый API + sandbox; их логику не переписываем.
- Скачиваемые с сервера файлы: Lua + контент; LZMA-сжатие (уточнить capture'ами в M2).
- Сервер может требовать Steam-тикет (ClassicBox VAC=1) → steamworks-rs с M2,
fallback noSteam конваром.
- В DS-установке есть базовые lua-файлы игры — референс порядка bootstrap Lua-рантайма.
## 8. Лицензии и правовая позиция
- Цель проекта — личный клиент для игры на серверах; ассеты берутся из локальных
установок пользователя и не распространяются.
- Source SDK 2013 и Source.NET — Source 1 SDK License: код не копируем,
используем как спецификацию форматов и поведения.
- Наш код — собственный (clean-room по форматам/поведению).
## 9. Тестовый контур
| Контур | Использование |
|---|---|
| Локальный `srcds_linux` (`~/gmod_server/server`) | Контролируемые сценарии, синтетика (2000 пропов, 500 констрейнов) |
| Packet dump/replay | Воспроизведение прод-нагрузки без сервера |
| ClassicBox (live) | Финальные проверки (36–46 игроков), аккуратно и по делу |
| Fuzz-стенды | vpk/bsp/mdl/vtf/pcf/сеть — cargo-fuzz |
## 10. Заметки спринта 0 (обновляется по ходу)
- VPK в установке: 9 `*_dir.vpk` (77 933 записи, 41 архив) — garrysmod (v2, 15 324 записи),
fallbacks, hl2_{textures,misc,sound_misc,sound_vo_english}, content_hl2, content_cstrike,
platform_misc. CS:S-контент присутствует (важно для gm_mobenix).
- Формат VPK сверен с ValvePak (VRF): терминаторы, preload, встроенные данные,
внешние архивы `<stem>_NNN.vpk`; парсер bounded и fuzz-устойчив.
- `fs doctor`: 0 ошибок CRC на выборке; `fs cat` читает MDL (IDST) и текстовые файлы из VPK.
- Клиент: SDL3 (собран из исходников, feature `build-from-source`) + wgpu 30.
Запуск проверен: NVIDIA RTX 3060, Vulkan, ~58–63 FPS (vsync), чистое завершение по `--frames`.
- wgpu 30: API проверено по примеру sdl3-rs (`raw-window-handle-with-wgpu`);
заголовок окна обновляется через `sdl3::sys` (метод крейта требует `&mut Window`).
- BSP v20: структуры `dnode_t`/`dleaf_t` на диске выровнены до 32 байт (хвостовой
паддинг) — иначе поля читаются как мусор; `dnode_t.children` — `int[2]`, не `short`.
- gm_construct: геометрия валидна (14 079 вершин, 9 460 граней, 4 988 узлов),
pakfile — ZIP 3.8 МБ, 599 записей (CRC проверен на выборке).
- VTF brickfloor001a.vtf: 7.1, DXT1 512×512, 10 мипов, миниатюра 16×16;
раскладка данных совпадает с размером файла до байта; декод мипа 0 и миниатюры — ок.
- По 200 случайных VTF и VMT из VPK разбираются без единой ошибки.
- Полезные открытые референсы форматов (используем как спецификации, не код):
`vformats` (KV/VMT/VTF/PHY/GMA/SND), `source-vtf` (VTF 7.x), ValvePak (VPK), glua-steal.
- MDL: базовый studiohdr_t = 408 байт (все версии); у v48+ за заголовком лежит
studiohdr2_t (256 байт, `studiohdr2index=408`), данные костей начинаются после него.
Смещения полей совпадают у v44–v48 (проверено на 53 моделях: v44 — 47, v45 — 1, v48 — 5,
`length == размер файла` у всех).
- VVD: заголовок 64 байта (`IDSV` v4), вершина mstudiovertex_t = 48 байт.
- VTX: структуры packed (`#pragma pack(1)`); **смещения вложенных структур отсчитываются
от своей структуры**, а не от начала файла (только `bodyPartOffset` — от файла).
Проверено: oildrum001 — 270 вершин / 756 индексов / 1 стрип; 51 пара VVD/VTX — checksum совпадает.
- `fs inspect` для модели показывает кости/аттачменты/текстуры/keyvalues и меш-статистику.