feat(runtime): project factory-2 selector 6 metadata
This commit is contained in:
7 files changed
+1856
-29
No files matched your search
@@ -536,6 +536,41 @@ MSH-часть проверки подтверждает начальный сн
|
||||
остаётся статическим выводом по RVA `AniMesh.dll+0xa460`, а последующие
|
||||
изменения в полном Control/animation tick-е не проверялись.
|
||||
|
||||
Устройство фабрики `2` через selector `6` читает `+0x174` только при текущем descriptor tag `2`,
|
||||
затем проверяет, что устройство создано фабрикой `2` и поле доступно. Значение
|
||||
должно быть конечным нормальным числом или нулём любого знака. Строки в
|
||||
`[27..35)` и `[35..43)` читаются до первого NUL: хвост игнорируется,
|
||||
ASCII-регистр не важен. После изменения пустая строка оставляет старые биты;
|
||||
пустая пара конструктора уже совпадает и не вызывает пересчёт. Проверка не
|
||||
использует список имён: нужен один корневой mesh `BULL` из `ObjectsRegistry`,
|
||||
без дочерних компонентов и записей timeline; все типизированные записи должны
|
||||
иметь tag `17`, а эффекты и таблица NDP — разбираться полностью. Число строк
|
||||
NDP произвольно, включая пустую таблицу.
|
||||
|
||||
Сканер возвращает коды выбранной начальной группы в исходном порядке. Допустимы
|
||||
`1/4/12`. `Some([])` означает, что по полному разбору данных команд нет: группа
|
||||
отсутствует, пуста или сырое беззнаковое значение индекса не меньше числа
|
||||
групп. `None` означает неподдержанный либо неполный разбор; повреждённые данные
|
||||
дают ошибку. Для выбранного opcode `4` нужны FXID-типы `2/3/4/5/7/8/9` и
|
||||
допустимые CPT-смещения внутри компонента; типы `1/6/10` остаются недоступными.
|
||||
Непредставленный ключ или число не превращаются в ноль. Если распознанный
|
||||
ресурс повреждён, новая миссия завершается ошибкой до публикации, сохраняя
|
||||
прежние мир и RNG.
|
||||
|
||||
Загрузка лицензированной AutoDemo и Rust-запрос selector `6` охватили 12
|
||||
устройств и семь пар с битовыми значениями:
|
||||
`bb_m_01=43f98000`, `bm_m_01=44228000`, `bl_l_01=436a0000`,
|
||||
`br_b_01=44c80000`, `bf_b_01=443b8000`, `bl_m_01=443b4000`,
|
||||
`bm_l_01=43340000`. Все семь значений совпали с замороженными арифметическими
|
||||
векторами. Пятнадцать изолированных вызовов selector `35` оригинальной DLL
|
||||
(включая семь однострочных BULL-таблиц) проверили арифметику при x87 control
|
||||
word `0x007f`, но не создавали полный native World. Таблица Control-устройств
|
||||
Rust по-прежнему строится при полной загрузке
|
||||
Unit DAT. CPU-проекция не воспроизводит временное создание объектов оригинала и
|
||||
его побочные эффекты FX, звука и RNG, размещение в World или следующий Control
|
||||
tick. Полное размещение объектов, игровой tick, Handler 43 и другие
|
||||
неподдержанные форматы остаются открытыми.
|
||||
|
||||
Для provider-строки Rust хранит amount `+0x08`, накопитель `+0x10`, обработанное
|
||||
количество `+0x0c`, долю `+0x14`, стадию `+0x18` и flags `+0x28` раздельно.
|
||||
Инициализатор `Control.dll+0xf940` кладёт результат selector `3` в текущее и
|
||||
|
||||
@@ -1502,7 +1502,69 @@ RVA `0x2bb9a` загружает `device+0x174` как `f32`, сохраняет
|
||||
буфер и возвращает `AL=1`/`RET 8`; другие текущие теги возвращают false.
|
||||
Наличие поля `+0x174` подтверждено для экземпляра фабрики `2`. INTO сохраняет
|
||||
исходный тип экземпляра, поэтому проверка тега descriptor отдельно не доказывает
|
||||
наличие этого поля у другой фабрики. В Rust selector `6` пока не поддержан.
|
||||
наличие этого поля у другой фабрики. Rust selector `6` сначала проверяет
|
||||
текущий descriptor tag: тег не `2` даёт `Ok(None)`; затем требуется известная
|
||||
фабрика `2` и конечное нормальное число либо ноль любого знака в `+0x174`. В
|
||||
`Control.dll` (SHA-256
|
||||
`bcb86318089028548a178b03a21accdce15df0cc85ddd91674cf3c2f55012c6e`) поле
|
||||
получает ноль в конструкторе по RVA `0x294c0`; чтение, сравнение пары строк и
|
||||
пересчёт находятся по RVA `0x2bb40`, `0x29940` и `0x296f0`.
|
||||
|
||||
Typed record хранит две ASCII C-строки в words `[27..35)` и `[35..43)`. Строка
|
||||
заканчивается на первом NUL: байты за ним игнорируются, а регистр при сравнении
|
||||
не учитывается. Если новая, изменённая пара содержит пустую строку, native
|
||||
recalc завершается до `CreateObject` и selector `35`, поэтому сохраняются
|
||||
прежние биты. Пустая пара конструктора уже совпадает с текущей и вообще не
|
||||
запускает recalc. Иначе append и первая активная запись `INTO` применяют
|
||||
результат в исходном порядке. Для нераспознанной формы поле остаётся
|
||||
недоступным; ошибка разбора распознанного, но повреждённого ресурса прерывает
|
||||
новую загрузку до публикации.
|
||||
|
||||
В общем случае native selector 35 не равен сумме сырых Max:
|
||||
`Control.dll` getter `0x0dc40` (selector 3) читает Max по `descriptor+4`, где
|
||||
указатель descriptor лежит в начале runtime provider row, затем умножает его
|
||||
на масштабы владельца `+0x660` и `+0x548`. Функция `0x13620` складывает выходы
|
||||
в порядке строк с округлением `f32`; при `row+0x24 != 0xffffffff` добавляется
|
||||
индексированный вклад. Конструктор `0xb240` задаёт runtime `row+0x24`
|
||||
служебное значение `0xffffffff`. Только в свежей форме поддержанного BULL оба
|
||||
масштаба равны `1`, а все `row+0x24` равны
|
||||
`0xffffffff`, поэтому формула сводится к NDP Max сумме.
|
||||
|
||||
Пересчёт создаёт временный объект запросом `9` через `World3D.dll+0x7cb0`.
|
||||
Загрузчик `Control.dll+0x32280` формирует для его корня входной контекст с
|
||||
полем `+0xc8 = 0xffffffff`. Для разрешённых opcode `1` и `12`, а
|
||||
также `4` только после FXID/CPT-проверки, подтверждённые callbacks сохраняют
|
||||
входы суммы: `Control.dll` RVA `0x43d0` меняет только локальные слова; в
|
||||
`AniMesh.dll` (`65659bf67f20e5be77d67a5b2f59968f61b94293143807fa59ca451c560c4f7e`)
|
||||
RVA `0x5500/0x93c0` меняют узлы и список модели, а `0x5320` не пишет её
|
||||
масштабы. Это статическая граница свежего пути, не снимок живого native World
|
||||
после всех creation callbacks.
|
||||
|
||||
Проверка opcode `4` читает только выбранные строки и принимает FXID-типы
|
||||
`2/3/4/5/7/8/9` с распознанными ASCII-ссылками и CPT offsets внутри компонента;
|
||||
типы `1/6/10`, отсутствующие ресурсы и непроверенные offsets оставляют поле
|
||||
недоступным. В `Effect.dll` (SHA-256
|
||||
`386a3e8db1ce23f61957825d633c7dae1ed40c25cab0cf10a534385fd7cee789`) проверены
|
||||
инициализаторы типов `2/3/4/5/7/8/9` по RVA `0x12d10/0x103b0/0x108c0/0x28a0/
|
||||
0x1720/0x11230`; тип `9` разделяет путь типа `3`.
|
||||
|
||||
`AssetManager::initial_control_effect_opcodes` собирает исходный порядок кодов
|
||||
выбранной начальной группы до фильтра opcode `4`. `Some([])` означает, что
|
||||
по структуре данных команд нет: группа отсутствует, пуста или её беззнаковый
|
||||
индекс не меньше числа групп. Условия отдельных строк этот читатель не
|
||||
вычисляет. `None` означает неподдержанный либо
|
||||
неполный формат, а повреждённая структура возвращает ошибку. Такая разница не
|
||||
позволяет принять неизвестный разбор за пустую сумму.
|
||||
|
||||
Ресурсные callbacks в этой цепочке привязаны также к следующим образам.
|
||||
Записи палитры и звуковые либо графические буферы имеют отдельное хранение;
|
||||
проверенные начальные вызовы не меняют входы суммы NDP.
|
||||
|
||||
| Модуль | SHA-256 | Существенные RVA |
|
||||
|---|---|---|
|
||||
| `World3D.dll` | `17e4a3089b2583a8cf2356c9db0390b1aba138356a09130d79b4e7e4791da61e` | `0x7cb0` — создание; `0x4b10/0x4cb0` — текстуры и lightmap |
|
||||
| `Ngi32.dll` | `bab9840d94f4e4e74ffc26677724fa896cf4823845504d09a9e025f80016edf5` | `0x11f80` — чтение ресурса; `0x11410` — счётчик палитры; `0xd620/0xe900` — звуковые буферы |
|
||||
| `Terrain.dll` | `af87d1b2e728a0be73c52be3b44cc196ab46da7799f25a15d40f8c9b0b425ead` | `0x166a0/0x17ac0` — получение указателя на числовое поле World |
|
||||
|
||||
FCA0 передаёт в owner query порядковый номер `i`; query `0x2bb40` находит
|
||||
устройство `i` и вызывает его reader. Уже reader `FUN_10021d00` получает provider
|
||||
|
||||
@@ -1442,6 +1442,30 @@ descriptor через `INTO`. Так разные части Control могут
|
||||
загруженной таблицы; обновление пока не подключено к игровым часам и не
|
||||
заменяет полный Control tick.
|
||||
|
||||
Устройство фабрики `2` имеет поле selector `6`, `+0x174`; конструктор задаёт ему
|
||||
ноль. Позднее Control может пересчитать его по паре строк записи и отдельному
|
||||
прототипу `BULL`. Только для поддержанной свежей формы одного корневого mesh
|
||||
`BULL` из `objects.rlb`, без дочерних компонентов, его NDP-строки сводятся к
|
||||
сумме Max; например, `[1.5, 2.25]`
|
||||
превращается в `3.75` с округлением `f32` после каждого шага:
|
||||
|
||||
```rust
|
||||
let mut total = 0.0_f32;
|
||||
for row in ndp_rows {
|
||||
total += row.max_volume;
|
||||
}
|
||||
```
|
||||
|
||||
Пустая таблица даёт ноль; физическую единицу этому числу не приписываем. Пара
|
||||
сравнивается как две C-строки до первого NUL: хвост не учитывается, регистр не
|
||||
важен. Если после изменения любая строка пуста, старое `+0x174` сохраняется;
|
||||
пустая пара конструктора не вызывает пересчёт, потому что уже совпадает. Новые
|
||||
значения применяются при добавлении и первой активной записи `INTO` в исходном
|
||||
порядке. Непредставленные входы оставляют селектор недоступным, а ошибка чтения
|
||||
узнаваемого, но повреждённого ресурса отменяет новую загрузку и сохраняет
|
||||
прежние мир и RNG. Общая формула selector 35 и условия свежей формы разобраны в
|
||||
[техническом приложении](../appendices/script-vm.md).
|
||||
|
||||
Отдельный путь объекта класса `4` умножает интервал на контактный коэффициент и
|
||||
передаёт изменение строке. В проверенном примере коэффициент `1`, интервал `2`,
|
||||
и значение строки уменьшается на `2`; этот коэффициент не является ставкой
|
||||
|
||||
Reference in new issue
Block a user