- 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)
113 lines
8.9 KiB
Markdown
113 lines
8.9 KiB
Markdown
# Разведка (снято 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 и меш-статистику.
|